Skip to content

Commit c689ccc

Browse files
update README for ecc macros
1 parent 6f58570 commit c689ccc

File tree

2 files changed

+124
-3
lines changed

2 files changed

+124
-3
lines changed

extensions/ecc/sw-macros/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ openvm_ecc_guest::sw_macros::sw_init! {
3131

3232
pub fn main() {
3333
setup_all_moduli();
34-
setup_all_curves();
34+
setup_all_sw_curves();
3535
// ...
3636
}
3737
```
@@ -87,13 +87,13 @@ pub fn setup_sw_Secp256k1Point() {
8787
// ...
8888
}
8989
}
90-
pub fn setup_all_curves() {
90+
pub fn setup_all_sw_curves() {
9191
setup_sw_Secp256k1Point();
9292
// other setups
9393
}
9494
```
9595

96-
3. Again, the `setup` function for every used curve must be called before any other instructions for that curve. If all curves are used, one can call `setup_all_curves()` to setup all of them.
96+
3. Again, the `setup` function for every used curve must be called before any other instructions for that curve. If all curves are used, one can call `setup_all_sw_curves()` to setup all of them.
9797

9898
4. The order of the items in `sw_init!` **must match** the order of the moduli in the chip configuration -- more specifically, in the modular extension parameters (the order of `CurveConfig`s in `WeierstrassExtension::supported_curves`, which is usually defined with the whole `app_vm_config` in the `openvm.toml` file).
9999

extensions/ecc/te-macros/README.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# `openvm-ecc-te-macros`
2+
3+
Procedural macros for use in guest program to generate short twisted Edwards elliptic curve struct with custom intrinsics for compile-time modulus.
4+
5+
The workflow of this macro is very similar to the [`openvm-algebra-moduli-macros`](../moduli-macros/README.md) crate. We recommend reading it first.
6+
7+
## Example
8+
9+
```rust
10+
// ...
11+
12+
moduli_declare! {
13+
Ed25519Coord { modulus = "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED" },
14+
Ed25519Scalar { modulus = "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED" },
15+
}
16+
17+
// Note that from_const_bytes is little endian
18+
pub const CURVE_A: Ed25519Coord = Ed25519Coord::from_const_bytes(hex!(
19+
"ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F"
20+
));
21+
pub const CURVE_D: Ed25519Coord = Ed25519Coord::from_const_bytes(hex!(
22+
"A3785913CA4DEB75ABD841414D0A700098E879777940C78C73FE6F2BEE6C0352"
23+
));
24+
25+
sw_declare! {
26+
Ed25519Point { mod_type = Ed25519Coord, a = CURVE_A, d = CURVE_D },
27+
}
28+
29+
openvm_algebra_guest::moduli_macros::moduli_init! {
30+
"0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
31+
"0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
32+
}
33+
34+
openvm_ecc_guest::te_macros::te_init! {
35+
Ed25519Point,
36+
}
37+
38+
pub fn main() {
39+
setup_all_moduli();
40+
setup_all_te_curves();
41+
// ...
42+
}
43+
```
44+
45+
## Full story
46+
47+
Again, the principle is the same as in the [`openvm-algebra-moduli-macros`](../moduli-macros/README.md) crate. Here we emphasize the core differences.
48+
49+
The crate provides two macros: `te_declare!` and `te_init!`. The signatures are:
50+
51+
- `te_declare!` receives comma-separated list of moduli classes descriptions. Each description looks like `TeStruct { mod_type = ModulusName, a = a_expr, d = d_expr }`. Here `ModulusName` is the name of any struct that implements `trait IntMod` -- in particular, the ones created by `moduli_declare!` do. Parameters `a` and `d` correspond to the coefficients of the equation defining the curve. They **must be compile-time constants**. Both the parameters `a` and `d` are required.
52+
53+
- `te_init!` receives comma-separated list of struct names. The struct name must exactly match the name in `te_declare!` -- type defs are not allowed (see point 5 below).
54+
55+
What happens under the hood:
56+
57+
1. `te_declare!` macro creates a struct with two field `x` and `y` of type `mod_type`. This struct denotes a point on the corresponding elliptic curve. In the example it would be
58+
59+
```rust
60+
struct Ed25519Point {
61+
x: Ed25519Coord,
62+
y: Ed25519Coord,
63+
}
64+
```
65+
66+
Similar to `moduli_declare!`, this macro also creates extern functions for arithmetic operations -- but in this case they are named after the te type, not after any hexadecimal (since the macro has no way to obtain it from the name of the modulus type anyway):
67+
68+
```rust
69+
extern "C" {
70+
fn te_add_extern_func_Ed25519Point(rd: usize, rs1: usize, rs2: usize);
71+
fn hint_decompress_extern_func_Ed25519Point(rs1: usize, rs2: usize);
72+
}
73+
```
74+
75+
2. Again, `te_init!` macro implements these extern functions and defines the setup functions for the te struct.
76+
77+
```rust
78+
#[cfg(target_os = "zkvm")]
79+
mod openvm_intrinsics_ffi_2 {
80+
use :openvm_ecc_guest::{OPCODE, TE_FUNCT3, TeBaseFunct7};
81+
82+
#[no_mangle]
83+
extern "C" fn te_add_extern_func_Ed25519Point(rd: usize, rs1: usize, rs2: usize) {
84+
// ...
85+
}
86+
// other externs
87+
}
88+
#[allow(non_snake_case)]
89+
pub fn setup_te_Ed25519Point() {
90+
#[cfg(target_os = "zkvm")]
91+
{
92+
// ...
93+
}
94+
}
95+
pub fn setup_all_te_curves() {
96+
setup_te_Ed25519Point();
97+
// other setups
98+
}
99+
```
100+
101+
3. Again, the `setup` function for every used curve must be called before any other instructions for that curve. If all curves are used, one can call `setup_all_te_curves()` to setup all of them.
102+
103+
4. The order of the items in `te_init!` **must match** the order of the moduli in the chip configuration -- more specifically, in the modular extension parameters (the order of `CurveConfig`s in `TwistedEdwardsExtension::supported_curves`, which is usually defined with the whole `app_vm_config` in the `openvm.toml` file).
104+
105+
5. Note that, due to the nature of function names, the name of the struct used in `te_init!` must be the same as in `te_declare!`. To illustrate, the following code will **fail** to compile:
106+
107+
```rust
108+
// ...
109+
110+
te_declare! {
111+
Ed25519Point { mod_type = Ed25519Coord, a = CURVE_A, d = CURVE_D },
112+
}
113+
114+
pub type Te = Ed25519Point;
115+
116+
te_init! {
117+
Te,
118+
}
119+
```
120+
121+
The reason is that, for example, the function `sw_add_extern_func_Secp256k1Point` remains unimplemented, but we implement `sw_add_extern_func_Sw`.

0 commit comments

Comments
 (0)