Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benchmarks/guest/ecrecover/openvm_init.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// This file is automatically generated by cargo openvm. Do not rename or edit.
openvm_algebra_guest::moduli_macros::moduli_init! { "115792089237316195423570985008687907853269984665640564039457584007908834671663", "115792089237316195423570985008687907852837564279074904382605163141518161494337" }
openvm_ecc_guest::sw_macros::sw_init! { Secp256k1Point }
openvm_ecc_guest::sw_macros::sw_init! { "Secp256k1Point" }
4 changes: 2 additions & 2 deletions benchmarks/guest/kitchen-sink/openvm_init.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// This file is automatically generated by cargo openvm. Do not rename or edit.
openvm_algebra_guest::moduli_macros::moduli_init! { "1000000000000000003", "115792089237316195423570985008687907853269984665640564039457584007908834671663", "115792089237316195423570985008687907852837564279074904382605163141518161494337", "115792089210356248762697446949407573530086143415290314195533631308867097853951", "115792089210356248762697446949407573529996955224135760342422259061068512044369", "21888242871839275222246405745257275088696311157297823662689037894645226208583", "21888242871839275222246405745257275088548364400416034343698204186575808495617", "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787", "52435875175126190479447740508185965837690552500527637822603658699938581184513", "2305843009213693951", "7" }
openvm_algebra_guest::complex_macros::complex_init! { Bn254Fp2 { mod_idx = 5 }, Bls12_381Fp2 { mod_idx = 7 } }
openvm_ecc_guest::sw_macros::sw_init! { Secp256k1Point, P256Point, Bn254G1Affine, Bls12_381G1Affine }
openvm_algebra_guest::complex_macros::complex_init! { "Bn254Fp2" { mod_idx = 5 }, "Bls12_381Fp2" { mod_idx = 7 } }
openvm_ecc_guest::sw_macros::sw_init! { "Secp256k1Point", "P256Point", "Bn254G1Affine", "Bls12_381G1Affine" }
4 changes: 2 additions & 2 deletions benchmarks/guest/pairing/openvm_init.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// This file is automatically generated by cargo openvm. Do not rename or edit.
openvm_algebra_guest::moduli_macros::moduli_init! { "21888242871839275222246405745257275088696311157297823662689037894645226208583", "21888242871839275222246405745257275088548364400416034343698204186575808495617" }
openvm_algebra_guest::complex_macros::complex_init! { Bn254Fp2 { mod_idx = 0 } }
openvm_ecc_guest::sw_macros::sw_init! { Bn254G1Affine }
openvm_algebra_guest::complex_macros::complex_init! { "Bn254Fp2" { mod_idx = 0 } }
openvm_ecc_guest::sw_macros::sw_init! { "Bn254G1Affine" }
2 changes: 1 addition & 1 deletion book/src/custom-extensions/algebra.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ moduli_init! {
"21888242871839275222246405745257275088696311157297823662689037894645226208583"
}
complex_init! {
Bn254Fp2 { mod_idx = 0 },
"Bn254Fp2" { mod_idx = 0 },
}
*/
```
Expand Down
2 changes: 1 addition & 1 deletion book/src/custom-extensions/ecc.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ This creates `Bls12_381G1Affine` and `P256Affine` structs which implement the `G
openvm::init!();
/* This expands to
sw_init! {
Bls12_381G1Affine, P256Affine,
"Bls12_381G1Affine", "P256Affine",
}
*/
```
Expand Down
2 changes: 1 addition & 1 deletion docs/specs/ISA.md
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ r32_ec_point(a) -> EcPoint {
| EC_ADD_NE\<C\> | `a,b,c,1,2` | Set `r32_ec_point(a) = r32_ec_point(b) + r32_ec_point(c)` (curve addition). Assumes that `r32_ec_point(b), r32_ec_point(c)` both lie on the curve and are not the identity point. Further assumes that `r32_ec_point(b).x, r32_ec_point(c).x` are not equal in the coordinate field. |
| SETUP_EC_ADD_NE\<C\> | `a,b,c,1,2` | `assert(r32_ec_point(b).x == C::MODULUS)` in the chip for EC ADD. For the sake of implementation convenience it also writes something (can be anything) into `[r32{0}(a): 2*C::COORD_SIZE]_2`. It is required for proper functionality that `assert(r32_ec_point(b).x != r32_ec_point(c).x)` |
| EC_DOUBLE\<C\> | `a,b,_,1,2` | Set `r32_ec_point(a) = 2 * r32_ec_point(b)`. This doubles the input point. Assumes that `r32_ec_point(b)` lies on the curve and is not the identity point. |
| SETUP_EC_DOUBLE\<C\> | `a,b,_,1,2` | `assert(r32_ec_point(b).x == C::MODULUS)` in the chip for EC DOUBLE. For the sake of implementation convenience it also writes something (can be anything) into `[r32{0}(a): 2*C::COORD_SIZE]_2`. It is required for proper functionality that `assert(r32_ec_point(b).y != 0 mod C::MODULUS)` |
| SETUP_EC_DOUBLE\<C\> | `a,b,_,1,2` | `assert(r32_ec_point(b).x == C::MODULUS && r32_ec_point(b).y == C::A)` in the chip for EC DOUBLE. For the sake of implementation convenience it also writes something (can be anything) into `[r32{0}(a): 2*C::COORD_SIZE]_2`. It is required for proper functionality that `assert(r32_ec_point(b).y != 0 mod C::MODULUS)` |

### Pairing Extension

Expand Down
4 changes: 2 additions & 2 deletions docs/specs/RISCV.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ the guest must take care to validate all data and account for behavior in cases
|--------------|-----|-------------|---------|--------|------------------------------------------------------------------------------------------------------------------------------|
| nativestorew | R | 0001011 | 111 | 0x2 | Stores the 4-byte word `rs1` at address `rd` in native address space. The address `rd` must be aligned to a 4-byte boundary. |

`nativestorew` connects RV32 address space and native address space. We put it in RV32 extension because its
`nativestorew` connects RV32 address space and native address space. We put it in RV32 extension because its
implementation is here. But we use `funct3 = 111` because the native extension has an available slot.

## Keccak Extension
Expand Down Expand Up @@ -182,7 +182,7 @@ The elliptic curve extension supports arithmetic over short Weierstrass curves,
| --------------- | --- | ----------- | ------ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| sw_add_ne\<C\> | R | 0101011 | 001 | `idx*8` | `EcPoint([rd:2*C::COORD_SIZE]_2) = EcPoint([rs1:2*C::COORD_SIZE]_2) + EcPoint([rs2:2*C::COORD_SIZE]_2)`. Assumes that input affine points are not identity and do not have same x-coordinate. |
| sw_double\<C\> | R | 0101011 | 001 | `idx*8+1` | `EcPoint([rd:2*C::COORD_SIZE]_2) = 2 * EcPoint([rs1:2*C::COORD_SIZE]_2)`. Assumes that input affine point is not identity. `rs2` is unused and must be set to `x0`. |
| setup\<C\> | R | 0101011 | 001 | `idx*8+2` | `assert([rs1: C::COORD_SIZE]_2 == C::MODULUS)` in the chip defined by the register index of `rs2`. For the sake of implementation convenience it also writes an unconstrained value into `[rd: 2*C::COORD_SIZE]_2`. If `ind(rs2) != 0`, then this instruction is setup for `sw_add_ne`. Otherwise it is setup for `sw_double`. When `ind(rs2) != 0` (add_ne), it is required for proper functionality that `[rs2: C::COORD_SIZE]_2 != [rs1: C::COORD_SIZE]_2`; otherwise (double), it is required that `[rs1 + C::COORD_SIZE: C::COORD_SIZE]_2 != C::Fp::ZERO` |
| setup\<C\> | R | 0101011 | 001 | `idx*8+2` | If `ind(rs2) != 0`, then this instruction is setup for `sw_add_ne`. Otherwise it is setup for `sw_double`. If setup for `sw_add_ne`, it checks `assert([rs1: C::COORD_SIZE]_2 == C::MODULUS)`, and if setup for `sw_double`, checks `assert([rs1: 2*C::COORD_SIZE]_2 == [C::MODULUS, CURVE_A])`. For the sake of implementation convenience it also writes an unconstrained value into `[rd: 2*C::COORD_SIZE]_2`. When `ind(rs2) != 0` (add_ne), it is required for proper functionality that `[rs2: C::COORD_SIZE]_2 != [rs1: C::COORD_SIZE]_2`; otherwise (double), it is required that `[rs1 + C::COORD_SIZE: C::COORD_SIZE]_2 != C::Fp::ZERO` |

Since `funct7` is 7-bits, up to 16 curves can be supported simultaneously. We use `idx*8` to leave some room for future expansion.

Expand Down
5 changes: 5 additions & 0 deletions examples/algebra/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@ num-bigint = { version = "0.4.6", features = ["serde"] }

[features]
default = []

# remove this if copying example outside of monorepo
[patch."https://github.com/openvm-org/openvm.git"]
openvm = { path = "../../crates/toolchain/openvm" }
openvm-algebra-guest = { path = "../../extensions/algebra/guest" }
2 changes: 1 addition & 1 deletion examples/algebra/openvm_init.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// This file is automatically generated by cargo openvm. Do not rename or edit.
openvm_algebra_guest::moduli_macros::moduli_init! { "998244353", "1000000007" }
openvm_algebra_guest::complex_macros::complex_init! { Complex1 { mod_idx = 0 }, Complex2 { mod_idx = 1 } }
openvm_algebra_guest::complex_macros::complex_init! { "Complex1" { mod_idx = 0 }, "Complex2" { mod_idx = 1 } }
2 changes: 1 addition & 1 deletion examples/algebra/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ moduli_init! {
// The order of these structs does not matter,
// given that we specify the `mod_idx` parameters properly.
openvm_algebra_complex_macros::complex_init! {
Complex1 { mod_idx = 0 }, Complex2 { mod_idx = 1 },
"Complex1" { mod_idx = 0 }, "Complex2" { mod_idx = 1 },
}
*/

Expand Down
2 changes: 1 addition & 1 deletion examples/ecc/openvm_init.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// This file is automatically generated by cargo openvm. Do not rename or edit.
openvm_algebra_guest::moduli_macros::moduli_init! { "115792089237316195423570985008687907853269984665640564039457584007908834671663", "115792089237316195423570985008687907852837564279074904382605163141518161494337" }
openvm_ecc_guest::sw_macros::sw_init! { Secp256k1Point }
openvm_ecc_guest::sw_macros::sw_init! { "Secp256k1Point" }
4 changes: 1 addition & 3 deletions examples/ecc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ openvm_algebra_guest::moduli_macros::moduli_init! {
"0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141"
}

openvm_ecc_guest::sw_macros::sw_init! {
Secp256k1Point,
}
openvm_ecc_guest::sw_macros::sw_init! { "Secp256k1Point" }
*/
// ANCHOR_END: init

Expand Down
2 changes: 1 addition & 1 deletion examples/pairing/openvm_init.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// This file is automatically generated by cargo openvm. Do not rename or edit.
openvm_algebra_guest::moduli_macros::moduli_init! { "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787" }
openvm_algebra_guest::complex_macros::complex_init! { Bls12_381Fp2 { mod_idx = 0 } }
openvm_algebra_guest::complex_macros::complex_init! { "Bls12_381Fp2" { mod_idx = 0 } }
2 changes: 1 addition & 1 deletion examples/pairing/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ openvm_algebra_moduli_macros::moduli_init! {
}

openvm_algebra_complex_macros::complex_init! {
Bls12_381Fp2 { mod_idx = 0 },
"Bls12_381Fp2" { mod_idx = 0 },
}
*/
// ANCHOR_END: init
Expand Down
2 changes: 1 addition & 1 deletion extensions/algebra/circuit/src/fp2_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl Fp2Extension {
.iter()
.map(|(name, modulus)| {
format!(
"{} {{ mod_idx = {} }}",
"\"{}\" {{ mod_idx = {} }}",
name,
get_index_of_modulus(modulus, modular_config)
)
Expand Down
6 changes: 3 additions & 3 deletions extensions/algebra/complex-macros/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ openvm_algebra_moduli_macros::moduli_init!(
);

openvm_algebra_complex_macros::complex_init! {
Complex { mod_idx = 0 },
"Complex" { mod_idx = 0 },
}
*/

Expand All @@ -39,7 +39,7 @@ The crate provides two macros: `complex_declare!` and `complex_init!`. The signa

- `complex_declare!` receives comma-separated list of moduli classes descriptions. Each description looks like `ComplexStruct { mod_type = ModulusName }`. Here `ModulusName` is the name of any struct that implements `trait IntMod` -- in particular, the ones created by `moduli_declare!` do, and `ComplexStruct` is the name for the complex arithmetic struct to create.

- `complex_init!` receives comma-separated list of struct descriptions. Each description looks like `ComplexStruct { mod_idx = idx }`. Here `ComplexStruct` is the name of the complex struct used in `complex_declare!`, and `idx` is the index of the modulus **in the `moduli_init!` macro**.
- `complex_init!` receives comma-separated list of struct descriptions. Each description looks like `"ComplexStruct" { mod_idx = idx }`. Here `ComplexStruct` is the name of the complex struct used in `complex_declare!`, and `idx` is the index of the modulus **in the `moduli_init!` macro**.

What happens under the hood:

Expand Down Expand Up @@ -96,7 +96,7 @@ complex_declare! {
pub type Fp2 = Bn254Fp2;

complex_init! {
Fp2 { mod_idx = 0 },
"Fp2" { mod_idx = 0 },
}
```

Expand Down
42 changes: 38 additions & 4 deletions extensions/algebra/complex-macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
extern crate proc_macro;

use openvm_macros_common::MacroArgs;
use openvm_macros_common::{MacroArgs, Param};
use proc_macro::TokenStream;
use syn::{
parse::{Parse, ParseStream},
parse_macro_input, Expr, ExprPath, Path, Token,
parse_macro_input,
punctuated::Punctuated,
Expr, ExprPath, LitStr, Path, Token,
};

/// This macro is used to declare the complex extension fields.
Expand Down Expand Up @@ -529,6 +531,38 @@ pub fn complex_declare(input: TokenStream) -> TokenStream {
TokenStream::from_iter(output)
}

// Override the MacroArgs struct to use LitStr for item names instead of Ident.
// This removes the need to import the complex struct when using the complex_init macro.
struct ComplexInitArgs {
pub items: Vec<ComplexInitItem>,
}

struct ComplexInitItem {
pub name: LitStr,
pub params: Punctuated<Param, Token![,]>,
}

impl Parse for ComplexInitArgs {
fn parse(input: ParseStream) -> syn::Result<Self> {
Ok(ComplexInitArgs {
items: input
.parse_terminated(ComplexInitItem::parse, Token![,])?
.into_iter()
.collect(),
})
}
}

impl Parse for ComplexInitItem {
fn parse(input: ParseStream) -> syn::Result<Self> {
let name = input.parse()?;
let content;
syn::braced!(content in input);
let params = content.parse_terminated(Param::parse, Token![,])?;
Ok(ComplexInitItem { name, params })
}
}

/// This macro is used to initialize the complex extension fields.
/// It must be called after `moduli_init!` is called.
///
Expand All @@ -543,14 +577,14 @@ pub fn complex_declare(input: TokenStream) -> TokenStream {
/// the `moduli_init!` macro (not `moduli_declare!`).
#[proc_macro]
pub fn complex_init(input: TokenStream) -> TokenStream {
let MacroArgs { items } = parse_macro_input!(input as MacroArgs);
let ComplexInitArgs { items } = parse_macro_input!(input as ComplexInitArgs);

let mut externs = Vec::new();

let span = proc_macro::Span::call_site();

for (complex_idx, item) in items.into_iter().enumerate() {
let struct_name = item.name.to_string();
let struct_name = item.name.value();
let struct_name = syn::Ident::new(&struct_name, span.into());
let mut intmod_idx: Option<usize> = None;
for param in item.params {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// This file is automatically generated by cargo openvm. Do not rename or edit.
openvm_algebra_guest::moduli_macros::moduli_init! { "998244353", "1000000007", "1000000009", "987898789" }
openvm_algebra_guest::complex_macros::complex_init! { Complex2 { mod_idx = 2 } }
openvm_algebra_guest::complex_macros::complex_init! { "Complex2" { mod_idx = 2 } }
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// This file is automatically generated by cargo openvm. Do not rename or edit.
openvm_algebra_guest::moduli_macros::moduli_init! { "115792089237316195423570985008687907853269984665640564039457584007908834671663" }
openvm_algebra_guest::complex_macros::complex_init! { Complex { mod_idx = 0 } }
openvm_algebra_guest::complex_macros::complex_init! { "Complex" { mod_idx = 0 } }
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// This file is automatically generated by cargo openvm. Do not rename or edit.
openvm_algebra_guest::moduli_macros::moduli_init! { "998244353", "1000000007" }
openvm_algebra_guest::complex_macros::complex_init! { Complex1 { mod_idx = 0 }, Complex2 { mod_idx = 1 } }
openvm_algebra_guest::complex_macros::complex_init! { "Complex1" { mod_idx = 0 }, "Complex2" { mod_idx = 1 } }
2 changes: 1 addition & 1 deletion extensions/ecc/circuit/src/weierstrass_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl WeierstrassExtension {
let supported_curves = self
.supported_curves
.iter()
.map(|curve_config| curve_config.struct_name.to_string())
.map(|curve_config| format!("\"{}\"", curve_config.struct_name))
.collect::<Vec<String>>()
.join(", ");

Expand Down
6 changes: 3 additions & 3 deletions extensions/ecc/sw-macros/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ openvm_algebra_guest::moduli_macros::moduli_init! {
}

openvm_ecc_guest::sw_macros::sw_init! {
Secp256k1Point,
"Secp256k1Point",
}
*/

Expand All @@ -45,7 +45,7 @@ The crate provides two macros: `sw_declare!` and `sw_init!`. The signatures are:

- `sw_declare!` receives comma-separated list of moduli classes descriptions. Each description looks like `SwStruct { mod_type = ModulusName, a = a_expr, b = b_expr }`. Here `ModulusName` is the name of a struct that implements `trait IntMod` -- in particular, the ones created by `moduli_declare!` do -- and has `NUM_LIMBS` divisible by 4. Parameters `a` and `b` correspond to the coefficients of the equation defining the curve. They **must be compile-time constants**. The parameter `a` may be omitted, in which case it defaults to `0` (or, more specifically, to `<ModulusName as IntMod>::ZERO`). The parameter `b` is required.

- `sw_init!` receives comma-separated list of struct names. The struct name must exactly match the name in `sw_declare!` -- type defs are not allowed (see point 5 below).
- `sw_init!` receives comma-separated list of struct names as string literals. Each struct name must exactly match the name in `sw_declare!` -- type defs are not allowed (see point 5 below).

What happens under the hood:

Expand Down Expand Up @@ -107,7 +107,7 @@ sw_declare! {
pub type Sw = Secp256k1Point;

sw_init! {
Sw,
"Sw",
}
```

Expand Down
Loading
Loading