diff --git a/README.md b/README.md index e945b681..61e14416 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,11 @@ use dep::bignum::BigNum; // Define (compile-time) BigNum type // number of limbs, number of bits of modulus, parameter set -type U256 = BigNum<3, 257, U256Params>; +// implement the BigNum trait for the custom bignum type +#[derive_bignum_impl(3, 257, quote {U256_PARAMS})] +pub struct U256 { + limbs: [u128; 3], +} ``` ### Quick example: Addition in U256 @@ -102,17 +106,37 @@ fn main() { ### `BigNum` / `RuntimeBigNum` definition -A BigNum is a number modulo `modulus` and is represented as an array of 120-bit limbs in little endian format. When the `modulus` is known at compile-time, use this type: +A BigNum is a number modulo `modulus` and is represented as an array of 120-bit limbs in little endian format. When the `modulus` is known at compile-time, use `BigNum` type. For instance, to build a 5-limb bignum, you can use the following definition: ```rust -pub struct BigNum { - pub limbs: [Field; N], +pub struct MyBignum { + pub limbs: [Field; 5], } ``` +The `BigNum` trait can be implemented for this type by using the `derive_bignum_impl` macro. + +```rust +pub(crate) comptime fn derive_bignum_impl( + strukt: TypeDefinition, + N: u32, + MOD_BITS: u32, + params: Quoted, +) -> Quoted +``` + - `N` is the number of limbs needed to represent the number. Each limb is a `Field`, which contains max 120 bits. The field type has 254 bits of space and by only using 120 bits, there is space for multiplications and additions without overflowing. - `MOD_BITS` is the number of bits needed to represent the modulus. - `Params` is a parameter set (`BigNumParams`) associated with the big number. More information below. +To implement the trait for your bignum type, you need to provide the number of limbs and the number of bits of the modulus and the parameters. + +```rust +#[derive_bignum_impl(4, 377, quote {BLS12_377_Fq_PARAMS})] +pub struct MyBignum { + pub limbs: [Field; 4], +} +``` + The actual value of a BigNum can be calculated by multiplying each limb by an increasing power of $2^{120}$. For example `[1,20,300]` represents $1 \cdot 2^{120\cdot0} + 20 \cdot 2^{120 \cdot 1} + 300 \cdot 2^{120 \cdot 2}$. We say that the BigNum is represented in radix- $2^{120}$. When `modulus` is known at runtime, the type is slightly different, but the representation of the actual number in limbs works the same way: @@ -137,7 +161,7 @@ To define a `BigNum` or `RuntimeBigNum`, you need to provide a `BigNumParams`. F - `double_modulus` is derived via the method `compute_double_modulus` in `runtime_bignum.nr`. If you want to provide this value as a compile-time constant (see `fields/bn254Fq.nr` for an example), follow the algorithm `compute_double_modulus` as this parameter is _not_ structly 2 \* modulus. Each limb except the most significant limb borrows 2^120 from the next most significant limb. This ensure that when performing limb subtractions `double_modulus.limbs[i] - x.limbs[i]`, we know that the result will not underflow -- `has_multiplicative_inverse`, a boolean indicating whether the elements have a multiplicative inverse or not +- `has_multiplicative_inverse`, a boolean indicating whether all elements have a multiplicative inverse, i.e. whether modulus is a prime. ## `BigNum` / `RuntimeBigNum` methods @@ -192,12 +216,25 @@ Constrained arithmetic operations. These perform the expected arithmetic operati These methods can be used using operators (`+`, `-`, `*`, `/`). +`derive_bignum_impl` will also implement conversions from a native `Field` type. For example, if you have a `Field` type `Fq`, you can convert it to your `BigNum` type `MyBigNum` by using the following syntax: + +```rust +let a: Field = 10; +let my_bignum: Fq = Fq::from(a); +``` +We also support comparison operators (`==`, `!=`, `>`, `>=`, `<`, `<=`) for `BigNum` types. + + > **Note:** `div`, `udiv` and `umod` are expensive due to requiring modular exponentiations during witness computation. It is worth modifying witness generation algorithms to minimize the number of modular exponentiations required. (for example, using batch inverses) Other constrained functions: -- `new`, returns a bignum with value 0 +- `zero`, returns a bignum with value 0 - `one`, returns a bignum with value 1 - `modulus`, returns `modulus` from the parameters +- `from_limbs`, returns a bignum from an array of limbs +- `from_slice`, returns a bignum from a slice of limbs +- `get_limbs`, returns the limbs of the bignum +- `set_limb(idx, value)`, set limbs `idx` to new value - `modulus_bits`, returns nr of bits from the parameters - `num_limbs`, returns N, the number of limbs needed to represent the bignum for the current parameters - `evaluate_quadratic_expression`, more explanation below @@ -205,11 +242,9 @@ Other constrained functions: - `validate_in_field(val)`, validates `val` < `modulus` - `assert_is_not_equal`, assert 2 bignums are distinct - `eq`, also available with operator `==` -- `get(idx)`, return value of limbs `idx` (this is a field) -- `set_limb(idx, value)`, set limbs `idx` to new value - `conditional_select(lhs, rhs, predicate)`, if `predicate` is 0 returns `lhs`, else if `predicate` is 1 returns `rhs` - `to_le_bytes`, returns the little-endian byte representation of a bignum - +- `from_be_bytes`, returns a bignum from a big-endian byte array ### `evaluate_quadratic_expression` For a lower gatecount and thus better performance perform multiple unconstrained arithmetic operations and then constrain them at once using `evaluate_quadratic_expression`. @@ -278,10 +313,7 @@ In the base field of Ed25519, which is the integers mod $2^{255}-19$, perform si ```rust use dep::bignum::BigNum; -use dep::bignum::fields::ed25519Fq::ED25519_Fq_Params; - -// Prime field mod 2^255-19 -type Fq = BigNum<3, 255, ED25519_Fq_Params>; +use dep::bignum::fields::ed25519Fq::ED25519_Fq as Fq; // Check that (x1 * x2) + x3 equals `expected` fn main(x1: Fq, x2: Fq, x3: Fq, expected: Fq) { @@ -325,11 +357,9 @@ BigNum supports operations over unsigned integers, with predefined types for 256 All arithmetic operations are supported including integer div and mod functions (make sure to use udiv, umod). Bit shifts and comparison operators are not yet implemented. ```rust -use dep::bignum::fields::U256::U256Params; +use dep::bignum::fields::U256; use dep::bignum::BigNum; -type U256 = BigNum<3, 257, U256Params>; - fn foo(x: U256, y: U256) -> U256 { x.udiv(y) } @@ -357,15 +387,9 @@ Feature requests and/or pull requests welcome for missing fields you need. ### Create a new parameter set for custom modulus -TODO: the paramgen tool is not up to date for `BigNum` version >= `0.4`, an issue has been created for this [here](https://github.com/noir-lang/noir-bignum-paramgen/issues/4). This section should be adjusted after this fix. - The easiest way to generate everything you need for a parameter set is to use [this tool](https://github.com/noir-lang/noir-bignum-paramgen). -For example, after cloning and building the tool, for a `modulus` of 1024 bits for RSA run `./target/release/paramgen instance RSA1024_example > out.txt`. This prints the parameter set to `out.txt`. Since this is not a field, also add: -```rust -fn has_multiplicative_inverse() -> bool { false } -``` -to the traits implementations for the parameter set. +For example, after cloning and building the tool, for a `modulus` of 1024 bits for RSA run `./target/release/paramgen instance RSA1024_example > out.txt`. This prints the parameter set to `out.txt`. #### Provide parameters for runtime known modulus diff --git a/src/benchmarks/bignum_benchmarks.nr b/src/benchmarks/bignum_benchmarks.nr index 0e330bec..565f1f1b 100644 --- a/src/benchmarks/bignum_benchmarks.nr +++ b/src/benchmarks/bignum_benchmarks.nr @@ -1,18 +1,13 @@ -use crate::bignum::{BigNum, BigNumTrait}; -use crate::fields::bls12_381Fq::BLS12_381_Fq; -use crate::fields::bn254Fq::BN254_Fq; -use crate::fields::U2048::U2048; -use crate::fields::U256::U256; - -comptime fn make_bench(_m: Module, N: u32, MOD_BITS: u32, params: Quoted) -> Quoted { - let module_name = _m.name(); +use crate::fields::{bls12_381Fq::BLS12_381_Fq, bn254Fq::BN254_Fq, U2048::U2048, U256::U256}; + +comptime fn make_bench(m: Module, params: Quoted) -> Quoted { + let module_name = m.name(); let add_bench_name = f"add_{module_name}".quoted_contents(); let sub_bench_name = f"sub_{module_name}".quoted_contents(); let mul_bench_name = f"mul_{module_name}".quoted_contents(); let div_bench_name = f"div_{module_name}".quoted_contents(); let udiv_mod_bench_name = f"udiv_mod_{module_name}".quoted_contents(); let udiv_bench_name = f"udiv_{module_name}".quoted_contents(); - let from_field_bench_name = f"from_field_{module_name}".quoted_contents(); let validate_in_field_bench_name = f"validate_in_field_{module_name}".quoted_contents(); let evaluate_quadratic_expression_3_elements_bench_name = f"evaluate_quadratic_expression_3_elements_{module_name}".quoted_contents(); @@ -22,95 +17,94 @@ comptime fn make_bench(_m: Module, N: u32, MOD_BITS: u32, params: Quoted) -> Quo let from_be_bytes_bench_name = f"from_be_bytes_{module_name}".quoted_contents(); let to_le_bytes_bench_name = f"to_le_bytes_{module_name}".quoted_contents(); let from_le_bytes_bench_name = f"from_le_bytes_{module_name}".quoted_contents(); - let BigNumTrait = quote { crate::bignum::BigNumTrait }; let BigNum = quote { crate::bignum::BigNum }; - let BigNumTrait = quote { crate::bignum::BigNumTrait }; + let from_field_bench_name = f"from_field_{module_name}".quoted_contents(); + let typ = params.as_type(); quote { #[export] - fn $add_bench_name(a: $BigNum<$N, $MOD_BITS, $params>, b: $BigNum<$N, $MOD_BITS, $params>) -> $BigNum<$N, $MOD_BITS, $params> { + fn $add_bench_name(a: $typ, b: $typ) -> $typ { a + b } #[export] - fn $sub_bench_name(a: $BigNum<$N, $MOD_BITS, $params>, b: $BigNum<$N, $MOD_BITS, $params>) -> $BigNum<$N, $MOD_BITS, $params> { + fn $sub_bench_name(a: $typ, b: $typ) -> $typ { a - b } #[export] - fn $mul_bench_name(a: $BigNum<$N, $MOD_BITS, $params>, b: $BigNum<$N, $MOD_BITS, $params>) -> $BigNum<$N, $MOD_BITS, $params> { + fn $mul_bench_name(a: $typ, b: $typ) -> $typ { a * b } #[export] - fn $div_bench_name(a: $BigNum<$N, $MOD_BITS, $params>, b: $BigNum<$N, $MOD_BITS, $params>) -> $BigNum<$N, $MOD_BITS, $params> { + fn $div_bench_name(a: $typ, b: $typ) -> $typ { a / b } #[export] - fn $udiv_mod_bench_name(a: $BigNum<$N, $MOD_BITS, $params>, b: $BigNum<$N, $MOD_BITS, $params>) -> ($BigNum<$N, $MOD_BITS, $params>, $BigNum<$N, $MOD_BITS, $params>) { - $BigNumTrait::udiv_mod(a, b) + fn $udiv_mod_bench_name(a: $typ, b: $typ) -> ($typ, $typ) { + $BigNum::udiv_mod(a, b) } #[export] - fn $udiv_bench_name(a: $BigNum<$N, $MOD_BITS, $params>, b: $BigNum<$N, $MOD_BITS, $params>) -> $BigNum<$N, $MOD_BITS, $params> { - $BigNumTrait::udiv(a, b) - } - - #[export] - fn $from_field_bench_name(a: Field) -> $BigNum<$N, $MOD_BITS, $params> { - $BigNum::from(a) + fn $udiv_bench_name(a: $typ, b: $typ) -> $typ { + $BigNum::udiv(a, b) } #[export] - fn $validate_in_field_bench_name(a: $BigNum<$N, $MOD_BITS, $params>) { - $BigNumTrait::validate_in_field(a) + fn $validate_in_field_bench_name(a: $typ) { + $BigNum::validate_in_field(a) } #[export] fn $evaluate_quadratic_expression_3_elements_bench_name( - lhs: [[$BigNum<$N, $MOD_BITS, $params>; 3]; 3], + lhs: [[$typ; 3]; 3], lhs_flags: [[bool; 3]; 3], - rhs: [[$BigNum<$N, $MOD_BITS, $params>; 3]; 3], + rhs: [[$typ; 3]; 3], rhs_flags: [[bool; 3]; 3], - add: [$BigNum<$N, $MOD_BITS, $params>; 3], + add: [$typ; 3], add_flags: [bool; 3], ) { - $BigNumTrait::evaluate_quadratic_expression(lhs, lhs_flags, rhs, rhs_flags, add, add_flags) + $BigNum::evaluate_quadratic_expression(lhs, lhs_flags, rhs, rhs_flags, add, add_flags) } #[export] fn $evaluate_quadratic_expression_12_elements_bench_name( - lhs: [[$BigNum<$N, $MOD_BITS, $params>; 3]; 12], + lhs: [[$typ; 3]; 12], lhs_flags: [[bool; 3]; 12], - rhs: [[$BigNum<$N, $MOD_BITS, $params>; 3]; 12], + rhs: [[$typ; 3]; 12], rhs_flags: [[bool; 3]; 12], - add: [$BigNum<$N, $MOD_BITS, $params>; 3], + add: [$typ; 3], add_flags: [bool; 3], ) { - $BigNumTrait::evaluate_quadratic_expression(lhs, lhs_flags, rhs, rhs_flags, add, add_flags) + $BigNum::evaluate_quadratic_expression(lhs, lhs_flags, rhs, rhs_flags, add, add_flags) } - - #[export] - fn $to_be_bytes_bench_name(a: $BigNum<$N, $MOD_BITS, $params>) -> [u8; ($MOD_BITS+7) / 8] { - $BigNum::<$N, $MOD_BITS, $params> ::to_be_bytes(a) - } - - #[export] - fn $from_be_bytes_bench_name(a: [u8; ($MOD_BITS+7) / 8]) -> $BigNum<$N, $MOD_BITS, $params> { - $BigNum::<$N, $MOD_BITS, $params> ::from_be_bytes(a) - } - + #[export] - fn $to_le_bytes_bench_name(a: $BigNum<$N, $MOD_BITS, $params>) -> [u8; ($MOD_BITS+7) / 8] { - $BigNum::<$N, $MOD_BITS, $params> ::to_le_bytes(a) + fn $from_field_bench_name(a: Field) -> $typ { + $typ::from(a) } - #[export] - fn $from_le_bytes_bench_name(a: [u8; ($MOD_BITS+7) / 8]) -> $BigNum<$N, $MOD_BITS, $params> { - $BigNum::<$N, $MOD_BITS, $params> ::from_le_bytes(a) - } - + // #[export] + // fn $to_be_bytes_bench_name(a: $typ) -> [u8; ($MOD_BITS+7) / 8] { + // $BigNum::to_be_bytes(a) + // } + + // #[export] + // fn $from_be_bytes_bench_name(a: [u8; ($MOD_BITS+7) / 8]) -> $typ { + // $BigNum::from_be_bytes(a) + // } + + // #[export] + // fn $to_le_bytes_bench_name(a: $typ) -> [u8; ($MOD_BITS+7) / 8] { + // $BigNum::to_le_bytes(a) + // } + + // #[export] + // fn $from_le_bytes_bench_name(a: [u8; ($MOD_BITS+7) / 8]) -> $typ { + // $BigNum::from_le_bytes(a) + // } } } @@ -119,27 +113,14 @@ comptime fn make_bench(_m: Module, N: u32, MOD_BITS: u32, params: Quoted) -> Quo // type U256 // type BLS12_381Fq // type U2048 -#[make_bench(3, 254, quote { BN254_Fq_Params })] -pub mod BN254_Fq_Bench { - use crate::bignum::BigNumTrait; - use crate::fields::bn254Fq::BN254_Fq_Params; -} +#[make_bench(quote { BN254_Fq })] +mod BN254_Fq_Bench {} -#[make_bench(3, 257, quote { U256Params })] -pub mod U256_Bench { - use crate::bignum::BigNumTrait; - use crate::fields::U256::U256Params; -} +#[make_bench(quote { U256 })] +mod U256_Bench {} -#[make_bench(4, 381, quote { BLS12_381_Fq_Params })] -pub mod BLS12_381Fq_Bench { +#[make_bench(quote { BLS12_381_Fq })] +mod BLS12_381Fq_Bench {} - use crate::bignum::BigNumTrait; - use crate::fields::bls12_381Fq::BLS12_381_Fq_Params; -} - -#[make_bench(18, 2049, quote { U2048Params })] -pub mod U2048_Bench { - use crate::bignum::BigNumTrait; - use crate::fields::U2048::U2048Params; -} +#[make_bench(quote { U2048 })] +mod U2048_Bench {} diff --git a/src/bignum.nr b/src/bignum.nr index f3f47c28..e57355e5 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -1,35 +1,29 @@ -use crate::utils::map::map; +use crate::fns::constrained_ops::limbs_to_field; +use crate::params::BigNumParams; use std::cmp::Ordering; - -use crate::params::BigNumParamsGetter; - -use crate::fns::{ - constrained_ops::{ - add, assert_is_not_equal, cmp, conditional_select, derive_from_seed, div, eq, from_field, - is_zero, limbs_to_field, mul, neg, sub, udiv, udiv_mod, umod, validate_in_field, - validate_in_range, - }, - expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, - serialization::{from_be_bytes, from_le_bytes, to_be_bytes, to_le_bytes}, - unconstrained_ops::{ - __add, __batch_invert, __batch_invert_slice, __derive_from_seed, __div, __eq, __invmod, - __is_zero, __mul, __neg, __pow, __sub, __tonelli_shanks_sqrt, __udiv_mod, - }, -}; use std::ops::{Add, Div, Mul, Neg, Sub}; -pub struct BigNum { - pub limbs: [u128; N], -} // We aim to avoid needing to add a generic parameter to this trait, for this reason we do not allow // accessing the limbs of the bignum except through slices. -pub trait BigNumTrait: Neg + Add + Sub + Mul + Div + Eq { +pub trait BigNum: Neg + Add + Sub + Mul + Div + Eq { + let N: u32; let MOD_BITS: u32; - // TODO: this crashes the compiler? v0.32 - // fn default() -> Self { std::default::Default::default () } + + fn params() -> BigNumParams; + fn modulus_bits(_: Self) -> u32 { + BigNum::MOD_BITS + } + fn num_limbs(_: Self) -> u32 { + BigNum::N + } + fn modulus() -> Self; + fn new() -> Self; fn zero() -> Self; fn one() -> Self; + fn from_limbs(limbs: [u128; N]) -> Self; + fn get_limbs(self) -> [u128; N]; + fn set_limb(self: &mut Self, idx: u32, value: u128); fn derive_from_seed(seed: [u8; SeedBytes]) -> Self; unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self; fn from_slice(limbs: [u128]) -> Self; @@ -38,15 +32,21 @@ pub trait BigNumTrait: Neg + Add + Sub + Mul + Div + Eq { fn from_le_bytes(x: [u8; (MOD_BITS + 7) / 8]) -> Self; fn to_le_bytes(self) -> [u8; (MOD_BITS + 7) / 8]; - fn modulus() -> Self; - fn modulus_bits(self) -> u32; - fn num_limbs(self) -> u32; - fn get_limbs_slice(self) -> [u128]; - fn get_limb(self, idx: u32) -> u128; - fn set_limb(&mut self, idx: u32, value: u128); + fn get_limbs_slice(self) -> [u128] { + self.get_limbs().as_slice() + } + + fn get_limb(self: Self, idx: u32) -> u128 { + self.get_limbs()[idx] + } + + unconstrained fn __eq(self: Self, other: Self) -> bool { + crate::fns::unconstrained_ops::__eq(self.get_limbs(), other.get_limbs()) + } - unconstrained fn __eq(self, other: Self) -> bool; - unconstrained fn __is_zero(self) -> bool; + unconstrained fn __is_zero(self: Self) -> bool { + crate::fns::unconstrained_ops::__is_zero(self.get_limbs()) + } unconstrained fn __neg(self) -> Self; unconstrained fn __add(self, other: Self) -> Self; @@ -80,7 +80,15 @@ pub trait BigNumTrait: Neg + Add + Sub + Mul + Div + Eq { add_flags: [bool; ADD_N], ); - fn assert_is_not_equal(self, other: Self); + fn assert_is_not_equal(self: Self, other: Self) { + let params = Self::params(); + crate::fns::constrained_ops::assert_is_not_equal( + params, + self.get_limbs(), + other.get_limbs(), + ); + } + fn validate_in_range(self); fn validate_in_field(self); @@ -92,335 +100,301 @@ pub trait BigNumTrait: Neg + Add + Sub + Mul + Div + Eq { fn is_zero(self) -> bool; } -impl std::convert::From for BigNum -where - Params: BigNumParamsGetter, -{ - fn from(input: Field) -> Self { - Self { limbs: from_field::(input) } - } -} - -impl Neg for BigNum -where - Params: BigNumParamsGetter, -{ - fn neg(self) -> Self { - let params = Params::get_params(); - Self { limbs: neg::<_, MOD_BITS>(params, self.limbs) } - } -} - -impl BigNumTrait for BigNum -where - Params: BigNumParamsGetter, -{ - let MOD_BITS: u32 = MOD_BITS; - #[deprecated("`BigNum::zero()` is preferred")] - fn new() -> Self { - Self::zero() - } - - fn zero() -> Self { - Self { limbs: [0; N] } - } - - fn one() -> Self { - let mut result = BigNum::zero(); - result.limbs[0] = 1; - result - } - - fn derive_from_seed(seed: [u8; SeedBytes]) -> Self { - let params = Params::get_params(); - Self { limbs: derive_from_seed::<_, MOD_BITS, _>(params, seed) } - } - - unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self { - let params = Params::get_params(); - Self { limbs: __derive_from_seed::<_, MOD_BITS, _>(params, seed) } - } - - fn from_slice(limbs: [u128]) -> Self { - Self { limbs: limbs.as_array() } - } - - fn from_be_bytes(x: [u8; (MOD_BITS + 7) / 8]) -> Self { - Self { limbs: from_be_bytes::<_, MOD_BITS>(x) } - } - - fn to_be_bytes(self) -> [u8; (MOD_BITS + 7) / 8] { - to_be_bytes::<_, MOD_BITS>(self.limbs) - } - - fn from_le_bytes(x: [u8; (MOD_BITS + 7) / 8]) -> Self { - Self { limbs: from_le_bytes::<_, MOD_BITS>(x) } - } - - fn to_le_bytes(self) -> [u8; (MOD_BITS + 7) / 8] { - to_le_bytes::<_, MOD_BITS>(self.limbs) - } - - fn modulus() -> Self { - Self { limbs: Params::get_params().modulus } - } +// we need macros that implement the BigNum, Default, From, Neg, Add, Sub, Mul, Div, Eq, Ord traits for each bignum type +pub(crate) comptime fn derive_bignum_impl( + strukt: TypeDefinition, + N: u32, + MOD_BITS: u32, + params: Quoted, +) -> Quoted { + // let BigNum = quote { crate::bignum::BigNum }; + let From = quote { std::convert::From }; + let Neg = quote { std::ops::Neg }; + let Add = quote { std::ops::Add }; + let Sub = quote { std::ops::Sub }; + let Mul = quote { std::ops::Mul }; + let Div = quote { std::ops::Div }; + let Eq = quote { std::cmp::Eq }; + let Ord = quote { std::cmp::Ord }; + let BigNum = quote { crate::bignum::BigNum }; + let constrained_ops = quote { crate::fns::constrained_ops }; + let unconstrained_ops = quote { crate::fns::unconstrained_ops }; + let Ordering = quote { std::cmp::Ordering }; + let utils = quote { crate::utils }; + let typ = strukt.as_type(); + let serialization = quote { crate::fns::serialization }; + let expressions = quote { crate::fns::expressions }; + quote { + + // implement BigNum for BigNum + impl $BigNum for $typ { + let N: u32 = $N; + let MOD_BITS: u32 = $MOD_BITS; + + fn modulus() -> Self { + Self { limbs: Self::params().modulus } + } + + fn new() -> Self { + Self {limbs: [0; $N]} + } + + fn params() -> crate::params::BigNumParams<$N, $MOD_BITS> { + $params + } + + fn from_limbs(limbs: [u128; $N]) -> Self { + Self { limbs } + } + + fn get_limbs(self: Self) -> [u128; $N] { + self.limbs + } + + fn set_limb(self: &mut Self, idx: u32, value: u128) { + self.limbs[idx] = value; + } + + fn zero() -> Self { + Self { limbs: [0; $N] } + } + + fn one() -> Self { + let mut limbs = [0; $N]; + limbs[0] = 1; + Self { limbs } + } + + fn derive_from_seed(seed: [u8; SeedBytes]) -> Self { + let params = Self::params(); + $typ::from_limbs($constrained_ops::derive_from_seed::<_, $MOD_BITS, _>(params, seed)) + } + + unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self { + let params = Self::params(); + Self { limbs: $unconstrained_ops::__derive_from_seed::<_, $MOD_BITS, _>(params, seed) } + } + + fn from_slice(limbs: [u128]) -> Self { + Self { limbs: limbs.as_array() } + } + + fn from_be_bytes(x: [u8; ($MOD_BITS + 7) / 8]) -> Self { + Self { limbs: $serialization::from_be_bytes::<_, $MOD_BITS>(x) } + } + + fn to_be_bytes(self) -> [u8; ($MOD_BITS + 7) / 8] { + $serialization::to_be_bytes::<_, $MOD_BITS>(self.limbs) + } + + fn from_le_bytes(x: [u8; ($MOD_BITS + 7) / 8]) -> Self { + Self { limbs: $serialization::from_le_bytes::<_, $MOD_BITS>(x) } + } + + fn to_le_bytes(self) -> [u8; ($MOD_BITS + 7) / 8] { + $serialization::to_le_bytes::<_, $MOD_BITS>(self.limbs) + } + + unconstrained fn __neg(self: Self) -> Self { + let params = Self::params(); + Self {limbs: $unconstrained_ops::__neg(params, self.get_limbs())} + } + + unconstrained fn __add(self: Self, other: Self) -> Self { + let params = Self::params(); + Self {limbs: $unconstrained_ops::__add(params, self.get_limbs(), other.get_limbs())} + } + + unconstrained fn __sub(self: Self, other: Self) -> Self { + let params = Self::params(); + Self {limbs: $unconstrained_ops::__sub(params, self.get_limbs(), other.get_limbs())} + } + + unconstrained fn __mul(self: Self, other: Self) -> Self { + let params = Self::params(); + Self {limbs: $unconstrained_ops::__mul(params, self.get_limbs(), other.get_limbs())} + } + + unconstrained fn __div(self: Self, divisor: Self) -> Self { + let params = Self::params(); + Self {limbs: $unconstrained_ops::__div(params, self.get_limbs(), divisor.get_limbs())} + } + + unconstrained fn __udiv_mod(self: Self, divisor: Self) -> (Self, Self) { + let (q, r) = $unconstrained_ops::__udiv_mod(self.get_limbs(), divisor.get_limbs()); + (Self{limbs: q}, Self{limbs: r}) + } + + unconstrained fn __invmod(self: Self) -> Self { + let params = Self::params(); + assert(params.has_multiplicative_inverse); + Self {limbs: $unconstrained_ops::__invmod(params, self.get_limbs())} + } + + unconstrained fn __pow(self: Self, exponent: Self) -> Self { + let params = Self::params(); + Self {limbs: $unconstrained_ops::__pow(params, self.get_limbs(), exponent.get_limbs())} + } + + unconstrained fn __batch_invert(x: [Self; M]) -> [Self; M] { + let params = Self::params(); + assert(params.has_multiplicative_inverse); + $unconstrained_ops::__batch_invert::<_, $MOD_BITS, _>(params, x.map(|bn: Self| bn.get_limbs())).map(|limbs| { + Self {limbs: limbs} + }) + } + + unconstrained fn __batch_invert_slice(x: [Self]) -> [Self] { + let params = Self::params(); + assert(params.has_multiplicative_inverse); + $unconstrained_ops::__batch_invert_slice::<_, $MOD_BITS>(params, x.map(|bn: Self| bn.get_limbs())).map(|limbs| { + Self {limbs: limbs} + }) + } + + unconstrained fn __tonelli_shanks_sqrt(self: Self) -> std::option::Option { + let params = Self::params(); + let maybe_limbs = $unconstrained_ops::__tonelli_shanks_sqrt(params, self.get_limbs()); + maybe_limbs.map(|limbs| Self {limbs: limbs}) + } + + unconstrained fn __compute_quadratic_expression( + lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], + lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], + rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], + rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], + linear_terms: [Self; ADD_N], + linear_flags: [bool; ADD_N], + ) -> (Self, Self) { + let params = Self::params(); + let (q_limbs, r_limbs) = $expressions::__compute_quadratic_expression::<_, $MOD_BITS, _, _, _, _>( + params, + $utils::map::map(lhs_terms, |bns| $utils::map::map(bns, |bn: Self| bn.get_limbs())), + lhs_flags, + $utils::map::map(rhs_terms, |bns| $utils::map::map(bns, |bn: Self| bn.get_limbs())), + rhs_flags, + $utils::map::map(linear_terms, |bn: Self| bn.get_limbs()), + linear_flags, + ); + (Self {limbs: q_limbs}, Self {limbs: r_limbs}) + } + + fn evaluate_quadratic_expression( + lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], + lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], + rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], + rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], + linear_terms: [Self; ADD_N], + linear_flags: [bool; ADD_N], + ) { + let params = Self::params(); + $expressions::evaluate_quadratic_expression::<_, $MOD_BITS, _, _, _, _>( + params, + $utils::map::map(lhs_terms, |bns| $utils::map::map(bns, |bn: Self| bn.get_limbs())), + lhs_flags, + $utils::map::map(rhs_terms, |bns| $utils::map::map(bns, |bn: Self| bn.get_limbs())), + rhs_flags, + $utils::map::map(linear_terms, |bn: Self| bn.get_limbs()), + linear_flags, + ) + } + + fn validate_in_field(self: Self) { + let params = Self::params(); + $constrained_ops::validate_in_field::<_, $MOD_BITS>(params, self.get_limbs()); + } + + fn validate_in_range(self: Self) { + $constrained_ops::validate_in_range::<_, _, $MOD_BITS>(self.get_limbs()); + } + + fn udiv_mod(self: Self, divisor: Self) -> (Self, Self) { + let params = Self::params(); + let (q, r) = $constrained_ops::udiv_mod::<_, $MOD_BITS>(params, self.get_limbs(), divisor.get_limbs()); + (Self {limbs: q}, Self {limbs: r}) + } + + fn udiv(self: Self, divisor: Self) -> Self { + let params = Self::params(); + Self {limbs: $constrained_ops::udiv::<_, $MOD_BITS>(params, self.get_limbs(), divisor.get_limbs())} + } + + fn umod(self: Self, divisor: Self) -> Self { + let params = Self::params(); + Self {limbs: $constrained_ops::umod::<_, $MOD_BITS>(params, self.get_limbs(), divisor.get_limbs())} + } + + fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self { + Self {limbs: $constrained_ops::conditional_select(lhs.get_limbs(), rhs.get_limbs(), predicate)} + } + + fn is_zero(self: Self) -> bool { + $constrained_ops::is_zero::<_, $MOD_BITS>(self.get_limbs()) + } + } + + // implement Default for BigNum + impl Default for $typ { + fn default() -> Self { + $typ::from_limbs([0; $N]) + } + } + + impl $From for $typ { + fn from(input: Field) -> Self { + $typ { limbs: $constrained_ops::from_field::<$N, $MOD_BITS>(input) } + } + } + + impl $Neg for $typ { + fn neg(self) -> Self { + $typ { limbs: $constrained_ops::neg::<$N, $MOD_BITS>($params, self.limbs) } + } + } + + impl $Add for $typ { + fn add(self, other: Self) -> Self { + $typ { limbs: $constrained_ops::add::<$N, $MOD_BITS>($params, self.limbs, other.limbs) } + } + } + + impl $Sub for $typ { + fn sub(self, other: Self) -> Self { + $typ { limbs: $constrained_ops::sub::<$N, $MOD_BITS>($params, self.limbs, other.limbs) } + } + } + + impl $Mul for $typ { + fn mul(self, other: Self) -> Self { + $typ { limbs: $constrained_ops::mul::<$N, $MOD_BITS>($params, self.limbs, other.limbs) } + } + } + + impl $Div for $typ { + fn div(self, other: Self) -> Self { + $typ { limbs: $constrained_ops::div::<$N, $MOD_BITS>($params, self.limbs, other.limbs) } + } + } + + impl $Eq for $typ { + fn eq(self, other: Self) -> bool { + $constrained_ops::eq::<$N, $MOD_BITS>($params, self.limbs, other.limbs) + } + } + + impl $Ord for $typ { + fn cmp(self, other: Self) -> $Ordering { + $constrained_ops::cmp::<$N, $MOD_BITS>(self.limbs, other.limbs) + } + } - fn modulus_bits(_: Self) -> u32 { - MOD_BITS - } - - fn num_limbs(_: Self) -> u32 { - N - } - - fn get_limbs_slice(self) -> [u128] { - self.limbs - } - - fn get_limb(self, idx: u32) -> u128 { - self.limbs[idx] - } - - fn set_limb(&mut self, idx: u32, value: u128) { - self.limbs[idx] = value; - } - - unconstrained fn __eq(self, other: Self) -> bool { - __eq(self.limbs, other.limbs) - } - - unconstrained fn __is_zero(self) -> bool { - __is_zero(self.limbs) - } - - unconstrained fn __neg(self) -> Self { - let params = Params::get_params(); - Self { limbs: __neg(params, self.limbs) } - } - - unconstrained fn __add(self, other: Self) -> Self { - let params = Params::get_params(); - Self { limbs: __add(params, self.limbs, other.limbs) } - } - - unconstrained fn __sub(self, other: Self) -> Self { - let params = Params::get_params(); - Self { limbs: __sub(params, self.limbs, other.limbs) } - } - - unconstrained fn __mul(self, other: Self) -> Self { - let params = Params::get_params(); - Self { limbs: __mul::<_, MOD_BITS>(params, self.limbs, other.limbs) } - } - - unconstrained fn __div(self, divisor: Self) -> Self { - let params = Params::get_params(); - Self { limbs: __div::<_, MOD_BITS>(params, self.limbs, divisor.limbs) } - } - - unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self) { - let (q, r) = __udiv_mod(self.limbs, divisor.limbs); - (Self { limbs: q }, Self { limbs: r }) - } - - unconstrained fn __invmod(self) -> Self { - let params = Params::get_params(); - assert(params.has_multiplicative_inverse); - Self { limbs: __invmod::<_, MOD_BITS>(params, self.limbs) } - } - - unconstrained fn __pow(self, exponent: Self) -> Self { - let params = Params::get_params(); - Self { limbs: __pow::<_, MOD_BITS>(params, self.limbs, exponent.limbs) } - } - - unconstrained fn __batch_invert(x: [Self; M]) -> [Self; M] { - let params = Params::get_params(); - assert(params.has_multiplicative_inverse); - __batch_invert::<_, MOD_BITS, _>(params, x.map(|bn: Self| bn.limbs)).map(|limbs| { - Self { limbs } - }) - } - - unconstrained fn __batch_invert_slice(x: [Self]) -> [Self] { - let params = Params::get_params(); - assert(params.has_multiplicative_inverse); - __batch_invert_slice::<_, MOD_BITS>(params, x.map(|bn: Self| bn.limbs)).map(|limbs| { - Self { limbs } - }) - } - - unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option { - let params = Params::get_params(); - let maybe_limbs = __tonelli_shanks_sqrt(params, self.limbs); - maybe_limbs.map(|limbs| Self { limbs }) - } - - unconstrained fn __compute_quadratic_expression( - lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], - lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], - rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], - rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], - linear_terms: [Self; ADD_N], - linear_flags: [bool; ADD_N], - ) -> (Self, Self) { - let params = Params::get_params(); - let (q_limbs, r_limbs) = __compute_quadratic_expression::<_, MOD_BITS, _, _, _, _>( - params, - map(lhs_terms, |bns| map(bns, |bn: Self| bn.limbs)), - lhs_flags, - map(rhs_terms, |bns| map(bns, |bn: Self| bn.limbs)), - rhs_flags, - map(linear_terms, |bn: Self| bn.limbs), - linear_flags, - ); - (Self { limbs: q_limbs }, Self { limbs: r_limbs }) - } - - fn evaluate_quadratic_expression( - lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], - lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], - rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], - rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], - linear_terms: [Self; ADD_N], - linear_flags: [bool; ADD_N], - ) { - let params = Params::get_params(); - evaluate_quadratic_expression::<_, MOD_BITS, _, _, _, _>( - params, - map(lhs_terms, |bns| map(bns, |bn: Self| bn.limbs)), - lhs_flags, - map(rhs_terms, |bns| map(bns, |bn: Self| bn.limbs)), - rhs_flags, - map(linear_terms, |bn: Self| bn.limbs), - linear_flags, - ) - } - - fn validate_in_field(self: Self) { - let params = Params::get_params(); - validate_in_field::<_, MOD_BITS>(params, self.limbs); - } - - fn validate_in_range(self) { - validate_in_range::<_, _, MOD_BITS>(self.limbs); - } - - fn assert_is_not_equal(self, other: Self) { - let params = Params::get_params(); - assert_is_not_equal(params, self.limbs, other.limbs); - } - - fn udiv_mod(self, divisor: Self) -> (Self, Self) { - let params = Params::get_params(); - let (q, r) = udiv_mod::<_, MOD_BITS>(params, self.limbs, divisor.limbs); - (Self { limbs: q }, Self { limbs: r }) - } - - fn udiv(self, divisor: Self) -> Self { - let params = Params::get_params(); - Self { limbs: udiv::<_, MOD_BITS>(params, self.limbs, divisor.limbs) } - } - - fn umod(self, divisor: Self) -> Self { - let params = Params::get_params(); - Self { limbs: umod::<_, MOD_BITS>(params, self.limbs, divisor.limbs) } - } - - fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self { - Self { limbs: conditional_select(lhs.limbs, rhs.limbs, predicate) } - } - - fn is_zero(self) -> bool { - is_zero::(self.limbs) - } -} - -impl Default for BigNum -where - Params: BigNumParamsGetter, -{ - fn default() -> Self { - Self::zero() - } -} - -impl std::ops::Add for BigNum -where - Params: BigNumParamsGetter, -{ - // Note: this method is expensive! Try to craft quadratic relations and directly evaluate them - // via evaluate_quadratic_expression - fn add(self, other: Self) -> Self { - let params = Params::get_params(); - Self { limbs: add::<_, MOD_BITS>(params, self.limbs, other.limbs) } - } -} - -impl std::ops::Sub for BigNum -where - Params: BigNumParamsGetter, -{ - // Note: this method is expensive! Try to craft quadratic relations and directly evaluate them - // via evaluate_quadratic_expression - fn sub(self, other: Self) -> Self { - let params = Params::get_params(); - Self { limbs: sub::<_, MOD_BITS>(params, self.limbs, other.limbs) } - } -} - -impl std::ops::Mul for BigNum -where - Params: BigNumParamsGetter, -{ - // Note: this method is expensive! Try to craft quadratic relations and directly evaluate them - // via evaluate_quadratic_expression - // e.g. performing a sum of multiple multiplications and additions via `evaluate_quadratic_expression` - // will create much fewer constraints than calling `mul` and `add` directly - fn mul(self, other: Self) -> Self { - let params = Params::get_params(); - Self { limbs: mul::<_, MOD_BITS>(params, self.limbs, other.limbs) } - } -} - -impl std::ops::Div for BigNum -where - Params: BigNumParamsGetter, -{ - // Note: this method is expensive! Witness computation is extremely expensive as it requires modular exponentiation - fn div(self, other: Self) -> Self { - let params = Params::get_params(); - Self { limbs: div::<_, MOD_BITS>(params, self.limbs, other.limbs) } - } -} - -impl std::cmp::Eq for BigNum -where - Params: BigNumParamsGetter, -{ - fn eq(self, other: Self) -> bool { - let params = Params::get_params(); - eq::<_, MOD_BITS>(params, self.limbs, other.limbs) - } -} - -impl std::cmp::Ord for BigNum -where - Params: BigNumParamsGetter, -{ - fn cmp(self, other: Self) -> Ordering { - cmp::<_, MOD_BITS>(self.limbs, other.limbs) } } -/// `to_field` converts a BigNum to a Field, conditioned on the bignum fitting in a field element -/// -/// we have opted to not add this to the BigNumTrait as it might lead to bad usage of it -/// i.e. using this function with modulus larger than the Grumpkin modulus would lead to runtime errors, if the bignum is not deliberately picked to be in range, e.g. the bignum is the output of a hash function. -/// for such use cases we advise developers to use comptime assertions to ensure the modulus is not larger than the Grumpkin modulus -pub fn to_field(input: BigNum) -> Field +pub fn to_field(bn: T) -> Field where - Params: BigNumParamsGetter, + T: BigNum, { - limbs_to_field(Params::get_params(), input.limbs) + let params = T::params(); + limbs_to_field::(params, bn.get_limbs()) } diff --git a/src/fields/U1024.nr b/src/fields/U1024.nr index b92c5fc5..99ddd474 100644 --- a/src/fields/U1024.nr +++ b/src/fields/U1024.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct U1024Params {} - -pub type U1024 = BigNum<9, 1025, U1024Params>; - -impl BigNumParamsGetter<9, 1025> for U1024Params { - fn get_params() -> BigNumParams<9, 1025> { - U1024_PARAMS - } -} pub global U1024_PARAMS: BigNumParams<9, 1025> = BigNumParams { has_multiplicative_inverse: false, @@ -28,3 +18,8 @@ pub global U1024_PARAMS: BigNumParams<9, 1025> = BigNumParams { ], redc_param: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x400000000000000000], }; + +#[derive_bignum_impl(9, 1025, quote {U1024_PARAMS})] +pub struct U1024 { + limbs: [u128; 9], +} diff --git a/src/fields/U2048.nr b/src/fields/U2048.nr index 7f61b19f..8773cc2a 100644 --- a/src/fields/U2048.nr +++ b/src/fields/U2048.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct U2048Params {} - -pub type U2048 = BigNum<18, 2049, U2048Params>; - -impl BigNumParamsGetter<18, 2049> for U2048Params { - fn get_params() -> BigNumParams<18, 2049> { - U2048_PARAMS - } -} pub global U2048_PARAMS: BigNumParams<18, 2049> = BigNumParams { has_multiplicative_inverse: false, @@ -43,3 +33,8 @@ pub global U2048_PARAMS: BigNumParams<18, 2049> = BigNumParams { 0x00, 0x00, 0x4000, ], }; + +#[derive_bignum_impl(18, 2049, quote {U2048_PARAMS})] +pub struct U2048 { + limbs: [u128; 18], +} diff --git a/src/fields/U256.nr b/src/fields/U256.nr index e556ba7a..64e50625 100644 --- a/src/fields/U256.nr +++ b/src/fields/U256.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct U256Params {} - -pub type U256 = BigNum<3, 257, U256Params>; - -impl BigNumParamsGetter<3, 257> for U256Params { - fn get_params() -> BigNumParams<3, 257> { - U256_PARAMS - } -} pub global U256_PARAMS: BigNumParams<3, 257> = BigNumParams { has_multiplicative_inverse: false, @@ -22,3 +12,8 @@ pub global U256_PARAMS: BigNumParams<3, 257> = BigNumParams { ], redc_param: [0x00, 0x00, 0x400000], }; + +#[derive_bignum_impl(3, 257, quote {U256_PARAMS})] +pub struct U256 { + limbs: [u128; 3], +} diff --git a/src/fields/U384.nr b/src/fields/U384.nr index fcbc1ab8..8a93f93f 100644 --- a/src/fields/U384.nr +++ b/src/fields/U384.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct U384Params {} - -pub type U384 = BigNum<4, 385, U384Params>; - -impl BigNumParamsGetter<4, 385> for U384Params { - fn get_params() -> BigNumParams<4, 385> { - U384_PARAMS - } -} pub global U384_PARAMS: BigNumParams<4, 385> = BigNumParams { has_multiplicative_inverse: false, @@ -23,3 +13,8 @@ pub global U384_PARAMS: BigNumParams<4, 385> = BigNumParams { ], redc_param: [0x00, 0x00, 0x00, 0x40000000], }; + +#[derive_bignum_impl(4, 385, quote {U384_PARAMS})] +pub struct U384 { + limbs: [u128; 4], +} diff --git a/src/fields/U4096.nr b/src/fields/U4096.nr index 87e8beb4..e893ab1f 100644 --- a/src/fields/U4096.nr +++ b/src/fields/U4096.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct U4096Params {} - -pub type U4096 = BigNum<35, 4097, U4096Params>; - -impl BigNumParamsGetter<35, 4097> for U4096Params { - fn get_params() -> BigNumParams<35, 4097> { - U4096_PARAMS - } -} pub global U4096_PARAMS: BigNumParams<35, 4097> = BigNumParams { has_multiplicative_inverse: false, @@ -62,3 +52,8 @@ pub global U4096_PARAMS: BigNumParams<35, 4097> = BigNumParams { 0x00, 0x00, 0x00, 0x00, 0x400000, ], }; + +#[derive_bignum_impl(35, 4097, quote {U4096_PARAMS})] +pub struct U4096 { + limbs: [u128; 35], +} diff --git a/src/fields/U512.nr b/src/fields/U512.nr index b86f064f..589456e4 100644 --- a/src/fields/U512.nr +++ b/src/fields/U512.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct U512Params {} - -pub type U512 = BigNum<5, 513, U512Params>; - -impl BigNumParamsGetter<5, 513> for U512Params { - fn get_params() -> BigNumParams<5, 513> { - U512_PARAMS - } -} pub global U512_PARAMS: BigNumParams<5, 513> = BigNumParams { has_multiplicative_inverse: false, @@ -24,3 +14,8 @@ pub global U512_PARAMS: BigNumParams<5, 513> = BigNumParams { ], redc_param: [0x00, 0x00, 0x00, 0x00, 0x4000000000], }; + +#[derive_bignum_impl(5, 513, quote {U512_PARAMS})] +pub struct U512 { + limbs: [u128; 5], +} diff --git a/src/fields/U768.nr b/src/fields/U768.nr index bb7d54a8..479b6bcd 100644 --- a/src/fields/U768.nr +++ b/src/fields/U768.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct U768Params {} - -pub type U768 = BigNum<7, 769, U768Params>; - -impl BigNumParamsGetter<7, 769> for U768Params { - fn get_params() -> BigNumParams<7, 769> { - U768_PARAMS - } -} pub global U768_PARAMS: BigNumParams<7, 769> = BigNumParams { has_multiplicative_inverse: false, @@ -26,3 +16,8 @@ pub global U768_PARAMS: BigNumParams<7, 769> = BigNumParams { ], redc_param: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40000000000000], }; + +#[derive_bignum_impl(7, 769, quote {U768_PARAMS})] +pub struct U768 { + limbs: [u128; 7], +} diff --git a/src/fields/U8192.nr b/src/fields/U8192.nr index ed6612ce..39d81873 100644 --- a/src/fields/U8192.nr +++ b/src/fields/U8192.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct U8192Params {} - -pub type U8192 = BigNum<35, 4097, U8192Params>; - -impl BigNumParamsGetter<69, 8193> for U8192Params { - fn get_params() -> BigNumParams<69, 8193> { - U8192_PARAMS - } -} global U8192_PARAMS: BigNumParams<69, 8193> = BigNumParams { has_multiplicative_inverse: false, @@ -228,3 +218,8 @@ global U8192_PARAMS: BigNumParams<69, 8193> = BigNumParams { 0x4000000000, ], }; + +#[derive_bignum_impl(69, 8193, quote {U8192_PARAMS})] +pub struct U8192 { + limbs: [u128; 69], +} diff --git a/src/fields/bls12_377Fq.nr b/src/fields/bls12_377Fq.nr index 19358559..1360c57b 100644 --- a/src/fields/bls12_377Fq.nr +++ b/src/fields/bls12_377Fq.nr @@ -17,18 +17,8 @@ //! * G2 curve equation: y^2 = x^3 + B, where //! * B = Fq2(0, 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906) use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct BLS12_377_Fq_Params {} - -pub type BLS12_377_Fq = BigNum<4, 377, BLS12_377_Fq_Params>; - -impl BigNumParamsGetter<4, 377> for BLS12_377_Fq_Params { - fn get_params() -> BigNumParams<4, 377> { - BLS12_377_Fq_PARAMS - } -} pub global BLS12_377_Fq_PARAMS: BigNumParams<4, 377> = BigNumParams { has_multiplicative_inverse: true, @@ -51,3 +41,8 @@ pub global BLS12_377_Fq_PARAMS: BigNumParams<4, 377> = BigNumParams { 0x261508, ], }; + +#[derive_bignum_impl(4, 377, quote {BLS12_377_Fq_PARAMS})] +pub struct BLS12_377_Fq { + limbs: [u128; 4], +} diff --git a/src/fields/bls12_377Fr.nr b/src/fields/bls12_377Fr.nr index 8b098c41..49d7bb87 100644 --- a/src/fields/bls12_377Fr.nr +++ b/src/fields/bls12_377Fr.nr @@ -18,18 +18,8 @@ //! * B = Fq2(0, 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906) use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct BLS12_377_Fr_Params {} - -pub type BLS12_377_Fr = BigNum<3, 253, BLS12_377_Fr_Params>; - -impl BigNumParamsGetter<3, 253> for BLS12_377_Fr_Params { - fn get_params() -> BigNumParams<3, 253> { - BLS12_377_Fr_PARAMS - } -} pub global BLS12_377_Fr_PARAMS: BigNumParams<3, 253> = BigNumParams { has_multiplicative_inverse: true, @@ -41,3 +31,8 @@ pub global BLS12_377_Fr_PARAMS: BigNumParams<3, 253> = BigNumParams { ], redc_param: [0xa180b8d69e258f5204c21151e79ea1, 0x91ec40b2c9ee4e51e49faa80548fd0, 0x036d94], }; + +#[derive_bignum_impl(3, 253, quote {BLS12_377_Fr_PARAMS})] +pub struct BLS12_377_Fr { + limbs: [u128; 3], +} diff --git a/src/fields/bls12_381Fq.nr b/src/fields/bls12_381Fq.nr index dd2a4825..5d35babd 100644 --- a/src/fields/bls12_381Fq.nr +++ b/src/fields/bls12_381Fq.nr @@ -15,18 +15,8 @@ //! * G1 curve equation: y^2 = x^3 + 4 //! * G2 curve equation: y^2 = x^3 + Fq2(4, 4) use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct BLS12_381_Fq_Params {} - -pub type BLS12_381_Fq = BigNum<4, 381, BLS12_381_Fq_Params>; - -impl BigNumParamsGetter<4, 381> for BLS12_381_Fq_Params { - fn get_params() -> BigNumParams<4, 381> { - BLS12_381_Fq_PARAMS - } -} pub global BLS12_381_Fq_PARAMS: BigNumParams<4, 381> = BigNumParams { has_multiplicative_inverse: true, @@ -49,3 +39,8 @@ pub global BLS12_381_Fq_PARAMS: BigNumParams<4, 381> = BigNumParams { 0x02760d74, ], }; + +#[derive_bignum_impl(4, 381, quote {BLS12_381_Fq_PARAMS})] +pub struct BLS12_381_Fq { + limbs: [u128; 4], +} diff --git a/src/fields/bls12_381Fr.nr b/src/fields/bls12_381Fr.nr index 03b9db74..3f51dd1b 100644 --- a/src/fields/bls12_381Fr.nr +++ b/src/fields/bls12_381Fr.nr @@ -15,18 +15,8 @@ //! * G1 curve equation: y^2 = x^3 + 4 //! * G2 curve equation: y^2 = x^3 + Fq2(4, 4) use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct BLS12_381_Fr_Params {} - -pub type BLS12_381_Fr = BigNum<3, 255, BLS12_381_Fr_Params>; - -impl BigNumParamsGetter<3, 255> for BLS12_381_Fr_Params { - fn get_params() -> BigNumParams<3, 255> { - BLS12_381_Fr_PARAMS - } -} pub global BLS12_381_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, @@ -38,3 +28,8 @@ pub global BLS12_381_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { ], redc_param: [0x10fad2f92eb5c509cde80830358e4c, 0x53b7fb78ddf0e2d772dc1f823b4d94, 0x08d542], }; + +#[derive_bignum_impl(3, 255, quote {BLS12_381_Fr_PARAMS})] +pub struct BLS12_381_Fr { + limbs: [u128; 3], +} diff --git a/src/fields/bn254Fq.nr b/src/fields/bn254Fq.nr index ce04241f..5444b3b6 100644 --- a/src/fields/bn254Fq.nr +++ b/src/fields/bn254Fq.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct BN254_Fq_Params {} - -pub type BN254_Fq = BigNum<3, 254, BN254_Fq_Params>; - -impl BigNumParamsGetter<3, 254> for BN254_Fq_Params { - fn get_params() -> BigNumParams<3, 254> { - BN254_Fq_PARAMS - } -} pub global BN254_Fq_PARAMS: BigNumParams<3, 254> = BigNumParams { has_multiplicative_inverse: true, @@ -22,3 +12,8 @@ pub global BN254_Fq_PARAMS: BigNumParams<3, 254> = BigNumParams { ], redc_param: [0x65e1767cd4c086f3aed8a19bf90e51, 0x462623a04a7ab074a5868073013ae9, 0x054a47], }; + +#[derive_bignum_impl(3, 254, quote {BN254_Fq_PARAMS})] +pub struct BN254_Fq { + limbs: [u128; 3], +} diff --git a/src/fields/ed25519Fq.nr b/src/fields/ed25519Fq.nr index e3275d8f..6529ae66 100644 --- a/src/fields/ed25519Fq.nr +++ b/src/fields/ed25519Fq.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct ED25519_Fq_Params {} - -pub type ED25519_Fq = BigNum<3, 255, ED25519_Fq_Params>; - -impl BigNumParamsGetter<3, 255> for ED25519_Fq_Params { - fn get_params() -> BigNumParams<3, 255> { - ED25519_Fq_PARAMS - } -} pub global ED25519_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, @@ -22,3 +12,8 @@ pub global ED25519_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { ], redc_param: [0x0130, 0x00, 0x080000], }; + +#[derive_bignum_impl(3, 255, quote {ED25519_Fq_PARAMS})] +pub struct ED25519_Fq { + limbs: [u128; 3], +} diff --git a/src/fields/ed25519Fr.nr b/src/fields/ed25519Fr.nr index d8d111b0..f095ca66 100644 --- a/src/fields/ed25519Fr.nr +++ b/src/fields/ed25519Fr.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct ED25519_Fr_Params {} - -pub type ED25519_Fr = BigNum<3, 255, ED25519_Fr_Params>; - -impl BigNumParamsGetter<3, 255> for ED25519_Fr_Params { - fn get_params() -> BigNumParams<3, 255> { - ED25519_Fr_PARAMS - } -} pub global ED25519_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, @@ -22,3 +12,8 @@ pub global ED25519_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { ], redc_param: [0x4188574218ca69fb673968c28b04c6, 0xfffffffffffffffffffffffffffac8, 0x03ffff], }; + +#[derive_bignum_impl(3, 255, quote {ED25519_Fr_PARAMS})] +pub struct ED25519_Fr { + limbs: [u128; 3], +} diff --git a/src/fields/mnt4_753Fq.nr b/src/fields/mnt4_753Fq.nr index e9e77d91..e36364da 100644 --- a/src/fields/mnt4_753Fq.nr +++ b/src/fields/mnt4_753Fq.nr @@ -20,18 +20,8 @@ //! * NON_RESIDUE = 13 is the quadratic non-residue used to conpub struct the //! extension field Fq2 use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct MNT4_753_Fq_Params {} - -pub type MNT4_753_Fq = BigNum<7, 753, MNT4_753_Fq_Params>; - -impl BigNumParamsGetter<7, 753> for MNT4_753_Fq_Params { - fn get_params() -> BigNumParams<7, 753> { - MNT4_753_Fq_PARAMS - } -} pub global MNT4_753_Fq_PARAMS: BigNumParams<7, 753> = BigNumParams { has_multiplicative_inverse: true, @@ -63,3 +53,8 @@ pub global MNT4_753_Fq_PARAMS: BigNumParams<7, 753> = BigNumParams { 0x242f916cfa, ], }; + +#[derive_bignum_impl(7, 753, quote {MNT4_753_Fq_PARAMS})] +pub struct MNT4_753_Fq { + limbs: [u128; 7], +} diff --git a/src/fields/mnt4_753Fr.nr b/src/fields/mnt4_753Fr.nr index 616c7574..b29de436 100644 --- a/src/fields/mnt4_753Fr.nr +++ b/src/fields/mnt4_753Fr.nr @@ -20,18 +20,8 @@ //! * NON_RESIDUE = 13 is the quadratic non-residue used to conpub struct the //! extension field Fq2 use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct MNT4_753_Fr_Params {} - -pub type MNT4_753_Fr = BigNum<7, 753, MNT4_753_Fr_Params>; - -impl BigNumParamsGetter<7, 753> for MNT4_753_Fr_Params { - fn get_params() -> BigNumParams<7, 753> { - MNT4_753_Fr_PARAMS - } -} pub global MNT4_753_Fr_PARAMS: BigNumParams<7, 753> = BigNumParams { has_multiplicative_inverse: true, @@ -63,3 +53,8 @@ pub global MNT4_753_Fr_PARAMS: BigNumParams<7, 753> = BigNumParams { 0x242f916cfa, ], }; + +#[derive_bignum_impl(7, 753, quote {MNT4_753_Fr_PARAMS})] +pub struct MNT4_753_Fr { + limbs: [u128; 7], +} diff --git a/src/fields/mnt6_753Fq.nr b/src/fields/mnt6_753Fq.nr index f33d9a82..78e26403 100644 --- a/src/fields/mnt6_753Fq.nr +++ b/src/fields/mnt6_753Fq.nr @@ -20,18 +20,8 @@ //! * NON_RESIDUE = 11 is the cubic non-residue used to conpub struct the //! extension field Fq3 use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct MNT6_753_Fq_Params {} - -pub type MNT6_753_Fq = BigNum<7, 753, MNT6_753_Fq_Params>; - -impl BigNumParamsGetter<7, 753> for MNT6_753_Fq_Params { - fn get_params() -> BigNumParams<7, 753> { - MNT6_753_Fq_PARAMS - } -} pub global MNT6_753_Fq_PARAMS: BigNumParams<7, 753> = BigNumParams { has_multiplicative_inverse: true, @@ -63,3 +53,8 @@ pub global MNT6_753_Fq_PARAMS: BigNumParams<7, 753> = BigNumParams { 0x242f916cfa, ], }; + +#[derive_bignum_impl(7, 753, quote {MNT6_753_Fq_PARAMS})] +pub struct MNT6_753_Fq { + limbs: [u128; 7], +} diff --git a/src/fields/mnt6_753Fr.nr b/src/fields/mnt6_753Fr.nr index 0008d213..e00437d7 100644 --- a/src/fields/mnt6_753Fr.nr +++ b/src/fields/mnt6_753Fr.nr @@ -20,18 +20,8 @@ //! * NON_RESIDUE = 11 is the cubic non-residue used to conpub struct the //! extension field Fq3 use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct MNT6_753_Fr_Params {} - -pub type MNT6_753_Fr = BigNum<7, 753, MNT6_753_Fr_Params>; - -impl BigNumParamsGetter<7, 753> for MNT6_753_Fr_Params { - fn get_params() -> BigNumParams<7, 753> { - MNT6_753_Fr_PARAMS - } -} pub global MNT6_753_Fr_PARAMS: BigNumParams<7, 753> = BigNumParams { has_multiplicative_inverse: true, @@ -63,3 +53,8 @@ pub global MNT6_753_Fr_PARAMS: BigNumParams<7, 753> = BigNumParams { 0x242f916cfa, ], }; + +#[derive_bignum_impl(7, 753, quote {MNT6_753_Fr_PARAMS})] +pub struct MNT6_753_Fr { + limbs: [u128; 7], +} diff --git a/src/fields/pallasFq.nr b/src/fields/pallasFq.nr index b052fead..9317ed59 100644 --- a/src/fields/pallasFq.nr +++ b/src/fields/pallasFq.nr @@ -14,18 +14,8 @@ //! * Valuation(q - 1, 2) = 32 //! * Valuation(r - 1, 2) = 32 use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct Pallas_Fq_Params {} - -pub type Pallas_Fq = BigNum<3, 255, Pallas_Fq_Params>; - -impl BigNumParamsGetter<3, 255> for Pallas_Fq_Params { - fn get_params() -> BigNumParams<3, 255> { - Pallas_Fq_PARAMS - } -} pub global Pallas_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, @@ -37,3 +27,8 @@ pub global Pallas_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { ], redc_param: [0x59c0fdacc1b919b4b3c4bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff], }; + +#[derive_bignum_impl(3, 255, quote {Pallas_Fq_PARAMS})] +pub struct Pallas_Fq { + limbs: [u128; 3], +} diff --git a/src/fields/pallasFr.nr b/src/fields/pallasFr.nr index a4b3a663..7b7ac9b6 100644 --- a/src/fields/pallasFr.nr +++ b/src/fields/pallasFr.nr @@ -14,18 +14,8 @@ //! * Valuation(q - 1, 2) = 32 //! * Valuation(r - 1, 2) = 32 use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct Pallas_Fr_Params {} - -pub type Pallas_Fr = BigNum<3, 255, Pallas_Fr_Params>; - -impl BigNumParamsGetter<3, 255> for Pallas_Fr_Params { - fn get_params() -> BigNumParams<3, 255> { - Pallas_Fr_PARAMS - } -} pub global Pallas_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, @@ -37,3 +27,8 @@ pub global Pallas_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { ], redc_param: [0x59c0fd9ad5c89cee4537bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff], }; + +#[derive_bignum_impl(3, 255, quote {Pallas_Fr_PARAMS})] +pub struct Pallas_Fr { + limbs: [u128; 3], +} diff --git a/src/fields/secp256k1Fq.nr b/src/fields/secp256k1Fq.nr index f30a3392..514da1eb 100644 --- a/src/fields/secp256k1Fq.nr +++ b/src/fields/secp256k1Fq.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct Secp256k1_Fq_Params {} - -pub type Secp256k1_Fq = BigNum<3, 256, Secp256k1_Fq_Params>; - -impl BigNumParamsGetter<3, 256> for Secp256k1_Fq_Params { - fn get_params() -> BigNumParams<3, 256> { - Secp256k1_Fq_PARAMS - } -} pub global Secp256k1_Fq_PARAMS: BigNumParams<3, 256> = BigNumParams { has_multiplicative_inverse: true, @@ -22,3 +12,8 @@ pub global Secp256k1_Fq_PARAMS: BigNumParams<3, 256> = BigNumParams { ], redc_param: [0x1000003d10, 0x00, 0x100000], }; + +#[derive_bignum_impl(3, 256, quote {Secp256k1_Fq_PARAMS})] +pub struct Secp256k1_Fq { + limbs: [u128; 3], +} diff --git a/src/fields/secp256k1Fr.nr b/src/fields/secp256k1Fr.nr index 1e7055a9..2e3cd273 100644 --- a/src/fields/secp256k1Fr.nr +++ b/src/fields/secp256k1Fr.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct Secp256k1_Fr_Params {} - -pub type Secp256k1_Fr = BigNum<3, 256, Secp256k1_Fr_Params>; - -impl BigNumParamsGetter<3, 256> for Secp256k1_Fr_Params { - fn get_params() -> BigNumParams<3, 256> { - Secp256k1_Fr_PARAMS - } -} pub global Secp256k1_Fr_PARAMS: BigNumParams<3, 256> = BigNumParams { has_multiplicative_inverse: true, @@ -22,3 +12,8 @@ pub global Secp256k1_Fr_PARAMS: BigNumParams<3, 256> = BigNumParams { ], redc_param: [0x1231950b75fc4402da1732fc9bec09, 0x1455, 0x100000], }; + +#[derive_bignum_impl(3, 256, quote {Secp256k1_Fr_PARAMS})] +pub struct Secp256k1_Fr { + limbs: [u128; 3], +} diff --git a/src/fields/secp256r1Fq.nr b/src/fields/secp256r1Fq.nr index f69cea99..57df8e8b 100644 --- a/src/fields/secp256r1Fq.nr +++ b/src/fields/secp256r1Fq.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct Secp256r1_Fq_Params {} - -pub type Secp256r1_Fq = BigNum<3, 256, Secp256r1_Fq_Params>; - -impl BigNumParamsGetter<3, 256> for Secp256r1_Fq_Params { - fn get_params() -> BigNumParams<3, 256> { - Secp256r1_Fq_PARAMS - } -} pub global Secp256r1_Fq_PARAMS: BigNumParams<3, 256> = BigNumParams { has_multiplicative_inverse: true, @@ -22,3 +12,8 @@ pub global Secp256r1_Fq_PARAMS: BigNumParams<3, 256> = BigNumParams { ], redc_param: [0xffffeffffffff00000000000000030, 0x0fffffffffffffffefffffffefff, 0x100000], }; + +#[derive_bignum_impl(3, 256, quote {Secp256r1_Fq_PARAMS})] +pub struct Secp256r1_Fq { + limbs: [u128; 3], +} diff --git a/src/fields/secp256r1Fr.nr b/src/fields/secp256r1Fr.nr index 3ead4409..7a60ad0e 100644 --- a/src/fields/secp256r1Fr.nr +++ b/src/fields/secp256r1Fr.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct Secp256r1_Fr_Params {} - -pub type Secp256r1_Fr = BigNum<3, 256, Secp256r1_Fr_Params>; - -impl BigNumParamsGetter<3, 256> for Secp256r1_Fr_Params { - fn get_params() -> BigNumParams<3, 256> { - Secp256r1_Fr_PARAMS - } -} pub global Secp256r1_Fr_PARAMS: BigNumParams<3, 256> = BigNumParams { has_multiplicative_inverse: true, @@ -22,3 +12,8 @@ pub global Secp256r1_Fr_PARAMS: BigNumParams<3, 256> = BigNumParams { ], redc_param: [0x90552df1a6c21012ffd85eedf9bfe6, 0x0fffffffffffffffeffffffff431, 0x100000], }; + +#[derive_bignum_impl(3, 256, quote {Secp256r1_Fr_PARAMS})] +pub struct Secp256r1_Fr { + limbs: [u128; 3], +} diff --git a/src/fields/secp384r1Fq.nr b/src/fields/secp384r1Fq.nr index 2f0f9204..5cf0c083 100644 --- a/src/fields/secp384r1Fq.nr +++ b/src/fields/secp384r1Fq.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct Secp384r1_Fq_Params {} - -pub type Secp384r1_Fq = BigNum<4, 384, Secp384r1_Fq_Params>; - -impl BigNumParamsGetter<4, 384> for Secp384r1_Fq_Params { - fn get_params() -> BigNumParams<4, 384> { - Secp384r1_Fq_PARAMS - } -} pub global Secp384r1_Fq_PARAMS: BigNumParams<4, 384> = BigNumParams { has_multiplicative_inverse: true, @@ -28,3 +18,8 @@ pub global Secp384r1_Fq_PARAMS: BigNumParams<4, 384> = BigNumParams { ], redc_param: [0x0ffffffffffffffff000000010, 0x1000, 0x00, 0x10000000], }; + +#[derive_bignum_impl(4, 384, quote {Secp384r1_Fq_PARAMS})] +pub struct Secp384r1_Fq { + limbs: [u128; 4], +} diff --git a/src/fields/secp384r1Fr.nr b/src/fields/secp384r1Fr.nr index af18afce..7b0ee711 100644 --- a/src/fields/secp384r1Fr.nr +++ b/src/fields/secp384r1Fr.nr @@ -1,16 +1,6 @@ use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct Secp384r1_Fr_Params {} - -pub type Secp384r1_Fr = BigNum<4, 384, Secp384r1_Fr_Params>; - -impl BigNumParamsGetter<4, 384> for Secp384r1_Fr_Params { - fn get_params() -> BigNumParams<4, 384> { - Secp384r1_Fr_PARAMS - } -} pub global Secp384r1_Fr_PARAMS: BigNumParams<4, 384> = BigNumParams { has_multiplicative_inverse: true, @@ -28,3 +18,8 @@ pub global Secp384r1_Fr_PARAMS: BigNumParams<4, 384> = BigNumParams { ], redc_param: [0x5f24db74f58851313e695333ad68d0, 0x0389cb27e0bc8d220a7e, 0x00, 0x10000000], }; + +#[derive_bignum_impl(4, 384, quote {Secp384r1_Fr_PARAMS})] +pub struct Secp384r1_Fr { + limbs: [u128; 4], +} diff --git a/src/fields/vestaFq.nr b/src/fields/vestaFq.nr index 72d4b61f..25c4a408 100644 --- a/src/fields/vestaFq.nr +++ b/src/fields/vestaFq.nr @@ -15,18 +15,8 @@ //! * Valuation(q - 1, 2) = 32 //! * Valuation(r - 1, 2) = 32 use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct Vesta_Fq_Params {} - -pub type Vesta_Fq = BigNum<3, 255, Vesta_Fq_Params>; - -impl BigNumParamsGetter<3, 255> for Vesta_Fq_Params { - fn get_params() -> BigNumParams<3, 255> { - Vesta_Fq_PARAMS - } -} pub global Vesta_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, @@ -38,3 +28,8 @@ pub global Vesta_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { ], redc_param: [0x59c0fd9ad5c89cee4537bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff], }; + +#[derive_bignum_impl(3, 255, quote {Vesta_Fq_PARAMS})] +pub struct Vesta_Fq { + limbs: [u128; 3], +} diff --git a/src/fields/vestaFr.nr b/src/fields/vestaFr.nr index 044163d3..dd984f8f 100644 --- a/src/fields/vestaFr.nr +++ b/src/fields/vestaFr.nr @@ -15,18 +15,8 @@ //! * Valuation(q - 1, 2) = 32 //! * Valuation(r - 1, 2) = 32 use crate::bignum::BigNum; +use crate::bignum::derive_bignum_impl; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; - -pub struct Vesta_Fr_Params {} - -pub type Vesta_Fr = BigNum<3, 255, Vesta_Fr_Params>; - -impl BigNumParamsGetter<3, 255> for Vesta_Fr_Params { - fn get_params() -> BigNumParams<3, 255> { - Vesta_Fr_PARAMS - } -} pub global Vesta_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, @@ -38,3 +28,8 @@ pub global Vesta_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { ], redc_param: [0x59c0fdacc1b919b4b3c4bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff], }; + +#[derive_bignum_impl(3, 255, quote {Vesta_Fr_PARAMS})] +pub struct Vesta_Fr { + limbs: [u128; 3], +} diff --git a/src/lib.nr b/src/lib.nr index b458a7b2..32fc152a 100644 --- a/src/lib.nr +++ b/src/lib.nr @@ -1,7 +1,6 @@ mod bignum; mod runtime_bignum; -mod tests; -mod benchmarks; + mod constants; // Pre-defined fields and bignums for people to use: @@ -14,8 +13,11 @@ pub mod params; pub(crate) mod fns; pub(crate) mod utils; +mod benchmarks; +mod tests; + // Re-export the main structs so that users don't have to specify the paths -pub use bignum::{BigNum, BigNumTrait}; +pub use bignum::BigNum; pub use runtime_bignum::RuntimeBigNum; // Re-export the pre-defined bignum types, for easier access: diff --git a/src/params.nr b/src/params.nr index a3e70e3b..d596f4a5 100644 --- a/src/params.nr +++ b/src/params.nr @@ -12,11 +12,6 @@ pub struct BigNumParams { pub redc_param: [u128; N], } -// To be implemented by the user for any BigNum they define, or within the predefined BigNums in the `fields/` dir. -pub trait BigNumParamsGetter { - fn get_params() -> BigNumParams; -} - impl BigNumParams { pub fn new( has_multiplicative_inverse: bool, diff --git a/src/tests/bignum_test.nr b/src/tests/bignum_test.nr index b9868300..c729dbfa 100644 --- a/src/tests/bignum_test.nr +++ b/src/tests/bignum_test.nr @@ -1,14 +1,13 @@ use crate::bignum::BigNum; -use crate::bignum::BigNumTrait; +use crate::bignum::derive_bignum_impl; use crate::bignum::to_field; use crate::fns::unconstrained_helpers::__helper_add; use crate::params::BigNumParams; -use crate::params::BigNumParamsGetter; use crate::fields::bls12_381Fq::BLS12_381_Fq; use crate::fields::bls12_381Fr::BLS12_381_Fr; -use crate::fields::bn254Fq::{BN254_Fq, BN254_Fq_Params}; +use crate::fields::bn254Fq::BN254_Fq; use crate::fields::U256::U256; struct Test2048Params {} @@ -83,27 +82,22 @@ global TEST_2048_PARAMS: BigNumParams<18, 2048> = BigNumParams { ], }; -impl BigNumParamsGetter<18, 2048> for Test2048Params { - fn get_params() -> BigNumParams<18, 2048> { - TEST_2048_PARAMS - } +#[derive_bignum_impl(18, 2048, quote {TEST_2048_PARAMS})] +pub struct BN2048 { + limbs: [u128; 18], } -type BN2048 = BigNum<18, 2048, Test2048Params>; - /** * @brief this example was failing - sanity test to validate it now works **/ #[test] fn test_bls_reduction() { - let X1 = BLS12_381_Fq { - limbs: [ - 0x55e83ff97a1aeffb3af00adb22c6bb, - 0x8c4f9774b905a14e3a3f171bac586c, - 0xa73197d7942695638c4fa9ac0fc368, - 0x17f1d3, - ], - }; + let X1 = BLS12_381_Fq::from_limbs([ + 0x55e83ff97a1aeffb3af00adb22c6bb, + 0x8c4f9774b905a14e3a3f171bac586c, + 0xa73197d7942695638c4fa9ac0fc368, + 0x17f1d3, + ]); X1.validate_in_field(); // Safety: test code let mut (_, XX_mul_3): (BLS12_381_Fq, BLS12_381_Fq) = unsafe { @@ -122,13 +116,13 @@ fn test_bls_reduction() { #[test] fn test_derive_from_seed() { let seed = [1, 2, 3, 4]; - let result_bn = BN254_Fq::derive_from_seed(seed); + let result_bn: BN254_Fq = BigNum::derive_from_seed(seed); result_bn.validate_in_field(); } fn test_eq() where - BN: BigNumTrait, + BN: BigNum, { let a = BN::derive_from_seed([1, 2, 3, 4]); let b = BN::derive_from_seed([1, 2, 3, 4]); @@ -141,7 +135,7 @@ where fn test_is_zero() where - BN: BigNumTrait, + BN: BigNum, { let a = BN::derive_from_seed([1, 2, 3, 4]); let zero = BN::zero(); @@ -154,7 +148,7 @@ where // // // 929 gates for a 2048 bit mul fn test_mul() where - BN: BigNumTrait, + BN: BigNum, { let a: BN = BN::derive_from_seed([1, 2, 3, 4]); let b: BN = BN::derive_from_seed([4, 5, 6, 7]); @@ -165,7 +159,7 @@ where fn test_add() where - BN: BigNumTrait, + BN: BigNum, { let a = BN::derive_from_seed([1, 2, 3, 4]); let b: BN = BN::derive_from_seed([4, 5, 6, 7]); @@ -193,7 +187,7 @@ where fn test_div() where - BN: BigNumTrait, + BN: BigNum, { let a = BN::derive_from_seed([1, 2, 3, 4]); let b = BN::derive_from_seed([4, 5, 6, 7]); @@ -204,7 +198,7 @@ where fn test_invmod() where - BN: BigNumTrait, + BN: BigNum, { let u = BN::derive_from_seed([1, 2, 3, 4]); // Safety: test code @@ -217,7 +211,7 @@ where fn assert_is_not_equal() where - BN: BigNumTrait, + BN: BigNum, { let a = BN::derive_from_seed([1, 2, 3, 4]); let b = BN::derive_from_seed([4, 5, 6, 7]); @@ -227,7 +221,7 @@ where fn assert_is_not_equal_fail() where - BN: BigNumTrait, + BN: BigNum, { let a = BN::derive_from_seed([1, 2, 3, 4]); let b = BN::derive_from_seed([1, 2, 3, 4]); @@ -237,7 +231,7 @@ where fn assert_is_not_equal_overloaded_lhs_fail() where - BN: BigNumTrait, + BN: BigNum, { let a = BN::derive_from_seed([1, 2, 3, 4]); let b = BN::derive_from_seed([1, 2, 3, 4]); @@ -253,7 +247,7 @@ where fn assert_is_not_equal_overloaded_rhs_fail() where - BN: BigNumTrait, + BN: BigNum, { let a = BN::derive_from_seed([1, 2, 3, 4]); let b = BN::derive_from_seed([1, 2, 3, 4]); @@ -269,7 +263,7 @@ where fn assert_is_not_equal_overloaded_fail() where - BN: BigNumTrait, + BN: BigNum, { let a = BN::derive_from_seed([1, 2, 3, 4]); let b = BN::derive_from_seed([1, 2, 3, 4]); @@ -288,7 +282,6 @@ where #[test] fn test_eq_BN() { - // let stub = BN254_Fq::new(); test_eq::<3, BN254_Fq>(); } @@ -303,12 +296,12 @@ fn test_add_BN() { let mut b = BN254_Fq::modulus(); let mut expected = BN254_Fq::modulus(); - a.limbs[0] -= 1; + a.set_limb(0, a.get_limb(0) - 1); - b.limbs[0] -= 1; + b.set_limb(0, b.get_limb(0) - 1); - let mut expected: BN254_Fq = BigNum::modulus(); - expected.limbs[0] -= 2; + let mut expected: BN254_Fq = BN254_Fq::modulus(); + expected.set_limb(0, expected.get_limb(0) - 2); let c = a + b; assert(c == expected); @@ -316,10 +309,10 @@ fn test_add_BN() { #[test] fn test_add_test_BN_wrap_around() { - let mut a: BN254_Fq = BigNum::modulus(); - let mut b: BN254_Fq = BN254_Fq { limbs: [3, 0, 0] }; + let mut a: BN254_Fq = BN254_Fq::modulus(); + let mut b: BN254_Fq = BN254_Fq::from_limbs([3, 0, 0]); let mut expected: BN254_Fq = BN254_Fq::one(); - a.limbs[0] -= 2; + a.set_limb(0, a.get_limb(0) - 2); let c = a + b; @@ -332,14 +325,14 @@ fn test_sub_test_BN() { let mut a = BN254_Fq::zero(); let mut b = BN254_Fq::one(); let mut expected = BN254_Fq::modulus(); - expected.limbs[0] -= 1; // p - 1 + expected.set_limb(0, expected.get_limb(0) - 1); // p - 1 let result = a - b; assert(result == expected); } #[test] fn test_eq_wrap() { - let a: BN254_Fq = BigNum::modulus(); + let a: BN254_Fq = BN254_Fq::modulus(); let b = BN254_Fq::zero(); assert(a == b); } @@ -351,7 +344,7 @@ fn test_sub_modulus_limit() { // 0 - p = 0 let mut a = BN254_Fq::zero(); let mut b = BN254_Fq::modulus(); - let mut expected = BigNum::zero(); + let mut expected = BN254_Fq::zero(); let result = a - b; assert(result == expected); @@ -362,8 +355,8 @@ fn test_sub_modulus_underflow() { // 0 - (p + 1) is smaller than p and should produce unsatisfiable constraints let mut a = BN254_Fq::zero(); let mut b = BN254_Fq::modulus(); - b.limbs[0] += 1; - let mut expected = BigNum::one(); + b.set_limb(0, b.get_limb(0) + 1); + let mut expected = BN254_Fq::one(); let result = a - b; assert(result == expected); @@ -374,11 +367,11 @@ fn test_add_modulus_limit() { // p + 2^{254} - 1 should be the maximum allowed value fed into an add operation // when adding, if the result overflows the modulus, we conditionally subtract the modulus, producing 2^{254} - 1 // this is the largest value that will satisfy the range check applied when constructing a bignum - let p: [u128; 3] = BN254_Fq_Params::get_params().modulus; + let p: [u128; 3] = BN254_Fq::params().modulus; let two_pow_254_minus_1: [u128; 3] = [0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x3fff]; - let a = BN254_Fq { limbs: p }; - let b = BN254_Fq { limbs: two_pow_254_minus_1 }; + let a = BN254_Fq::from_limbs(p); + let b = BN254_Fq::from_limbs(two_pow_254_minus_1); let result = a + b; assert(result == b); } @@ -387,13 +380,13 @@ fn test_add_modulus_limit() { fn test_add_modulus_overflow() { //(2^{254} - 1) + (p - 1) = 2^{254} + p // after subtracting modulus, result is 2^{254} will does not satisfy the range check applied when constructing a BigNum - let p: [u128; 3] = BN254_Fq_Params::get_params().modulus; + let p: [u128; 3] = BN254_Fq::params().modulus; let two_pow_254_minus_1: [u128; 3] = [0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x3fff]; let one = [1, 0, 0]; // Safety: test code - let a = BN254_Fq { limbs: unsafe { __helper_add(p, one) } }; - let b = BN254_Fq { limbs: two_pow_254_minus_1 }; + let a = BN254_Fq::from_limbs(unsafe { __helper_add(p, one) }); + let b = BN254_Fq::from_limbs(two_pow_254_minus_1); let result = a + b; assert(result == b); } @@ -561,107 +554,107 @@ fn test_udiv_mod_U256() { #[test] fn test_1_udiv_mod_2() { - let _0: U256 = BigNum::zero(); - let _1: U256 = BigNum::one(); + let _0: U256 = U256::zero(); + let _1: U256 = U256::one(); assert(_1.udiv_mod(_1 + _1) == (_0, _1)); } #[test] fn test_20_udiv_mod_11() { - let _1: U256 = BigNum::one(); - let _2_POW_120: U256 = BigNum::from_slice([0, 1, 0]); - let _2_POW_121: U256 = BigNum::from_slice([0, 2, 0]); + let _1: U256 = U256::one(); + let _2_POW_120: U256 = U256::from_slice([0, 1, 0]); + let _2_POW_121: U256 = U256::from_slice([0, 2, 0]); assert(_2_POW_121.udiv_mod(_2_POW_120 + _1) == (_1, _2_POW_120 - _1)); } -// // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril -// #[test] -// fn test_div_2048() { -// let stub: BN2048 = BigNum::new(); -// test_div(stub); -// } +// // // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril +// // #[test] +// // fn test_div_2048() { +// // let stub: BN2048 = BigNum::new(); +// // test_div(stub); +// // } + +// // // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril +// // #[test] +// // fn test_invmod_2048() { +// // let stub: BN2048 = BigNum::new(); +// // test_invmod(stub); +// // } -// // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril // #[test] -// fn test_invmod_2048() { -// let stub: BN2048 = BigNum::new(); -// test_invmod(stub); +// fn test_2048_bit_quadratic_expression() { +// let a: [u128; 18] = [ +// 0x000000000000000000000000000000000083684820ff40795b8d9f1be2220cba, +// 0x0000000000000000000000000000000000d4924fbdc522b07b6cd0ef5508fd66, +// 0x0000000000000000000000000000000000d48f6c43c5930f3d70d6db09a48f4a, +// 0x0000000000000000000000000000000000e7f72b2c0756704bea85be38352b34, +// 0x00000000000000000000000000000000008337197826e2e9ea000ed5b05d5ac5, +// 0x000000000000000000000000000000000040680101b43f6d17de8e3507f3d820, +// 0x00000000000000000000000000000000000c6ba0cdcf77cff1c10355ea48d387, +// 0x0000000000000000000000000000000000e51717a72902214a9dbeb90e4f225f, +// 0x0000000000000000000000000000000000c1bd5bec78406b691f71cbcddb4574, +// 0x00000000000000000000000000000000001ce5e532cfb306d7b52e7d9f1aa442, +// 0x000000000000000000000000000000000019575932f75ddf00595b22782e1ba2, +// 0x0000000000000000000000000000000000d630b3fbf0a9e55861e4399900feb9, +// 0x0000000000000000000000000000000000d6b37aeb2daa8d2e2f7e29b0f7752a, +// 0x0000000000000000000000000000000000e9cacdd93406256b9eb46b73948849, +// 0x00000000000000000000000000000000001400e1f0a38695db66993fe042c48b, +// 0x0000000000000000000000000000000000e1d829cb4fa8cabb7d0265efbd8527, +// 0x000000000000000000000000000000000055f1a92a5dd099ef2bcd89ac175b52, +// 0x00000000000000000000000000000000000000000000000000000000000000fc, +// ]; +// let b: [u128; 18] = [ +// 0x0000000000000000000000000000000000c5694493e9bcc76e68dfcf73e0fde1, +// 0x0000000000000000000000000000000000ede5e4b8b3e0dec1f4705c35521620, +// 0x00000000000000000000000000000000007aa800bab1b33eda0f07695af6c583, +// 0x000000000000000000000000000000000045892edea2c02bf0b8b1d2d9a4ebcc, +// 0x00000000000000000000000000000000004dffb06bf396f3d0a5b67cff714bdd, +// 0x00000000000000000000000000000000004d691db495235e1e032f1ef3e90274, +// 0x0000000000000000000000000000000000d92c069d0f2675b2f46cb497aa62d4, +// 0x00000000000000000000000000000000003d3f23584f113cef1a4b8b7d183f5c, +// 0x0000000000000000000000000000000000289ba11d897837f9cec57dcc430bfc, +// 0x0000000000000000000000000000000000765dc64f6ed4a6efd7b26c38f79e59, +// 0x00000000000000000000000000000000008edf31fabf5c330ecf7f92fb6487cd, +// 0x000000000000000000000000000000000053392f8b14dd78af702b3be2e0d557, +// 0x000000000000000000000000000000000034abf357bfd56e9786a7e47ed9a5ae, +// 0x0000000000000000000000000000000000a9ebb234064c8ab10d4e7900d4b973, +// 0x00000000000000000000000000000000002a6850cce14a20463913002ddc0fa6, +// 0x0000000000000000000000000000000000a97e3b06586bfa62325ef7557ab536, +// 0x0000000000000000000000000000000000b942b0d26e5be2e08cd425107c59f7, +// 0x0000000000000000000000000000000000000000000000000000000000000031, +// ]; +// let c_expected: [u128; 18] = [ +// 0x00000000000000000000000000000000004518a874adebbcf963fed876dfcf78, +// 0x00000000000000000000000000000000002b1535070c2deca63e2dc7145a9997, +// 0x0000000000000000000000000000000000d9b738665a290c09f09202043d9387, +// 0x0000000000000000000000000000000000c88853b11034fe12661eb7a5e41ca7, +// 0x0000000000000000000000000000000000357cc4053e7eb127abc2c1430972a1, +// 0x0000000000000000000000000000000000224df5e1be31a51562f8574027a992, +// 0x000000000000000000000000000000000070ad9287e6326d534f1d2835e159ad, +// 0x00000000000000000000000000000000000efa138f75f20b5117955e15bbb447, +// 0x0000000000000000000000000000000000d9f45c310be1865ad23fbcdeb1d93f, +// 0x00000000000000000000000000000000004f74ca4cf3df59a83f2df796fc9beb, +// 0x0000000000000000000000000000000000ed1801428ebf7db771deb45f4311eb, +// 0x00000000000000000000000000000000002ded3b46e3a84cda43157d4d927162, +// 0x00000000000000000000000000000000009bcd6ac8f90601a44a84a026d4b383, +// 0x0000000000000000000000000000000000ab098478b39031a1de85062fd5712b, +// 0x00000000000000000000000000000000004432a79276f4375ff3ec2ced8b6cf6, +// 0x0000000000000000000000000000000000a0922d75e96e3f9e31c0cbbcbd708a, +// 0x00000000000000000000000000000000004013822c9e9aa5b5b1e9c33e4332b7, +// 0x0000000000000000000000000000000000000000000000000000000000000058, +// ]; + +// let a_bn: BN2048 = BigNum { limbs: a }; +// let b_bn: BN2048 = BigNum { limbs: b }; +// // Safety: test code +// let c_bn = unsafe { a_bn.__mul(b_bn) }; +// assert(c_bn.limbs == c_expected); + +// a_bn.validate_in_range(); + +// BigNum::evaluate_quadratic_expression([[a_bn]], [[false]], [[b_bn]], [[false]], [c_bn], [true]); // } -#[test] -fn test_2048_bit_quadratic_expression() { - let a: [u128; 18] = [ - 0x000000000000000000000000000000000083684820ff40795b8d9f1be2220cba, - 0x0000000000000000000000000000000000d4924fbdc522b07b6cd0ef5508fd66, - 0x0000000000000000000000000000000000d48f6c43c5930f3d70d6db09a48f4a, - 0x0000000000000000000000000000000000e7f72b2c0756704bea85be38352b34, - 0x00000000000000000000000000000000008337197826e2e9ea000ed5b05d5ac5, - 0x000000000000000000000000000000000040680101b43f6d17de8e3507f3d820, - 0x00000000000000000000000000000000000c6ba0cdcf77cff1c10355ea48d387, - 0x0000000000000000000000000000000000e51717a72902214a9dbeb90e4f225f, - 0x0000000000000000000000000000000000c1bd5bec78406b691f71cbcddb4574, - 0x00000000000000000000000000000000001ce5e532cfb306d7b52e7d9f1aa442, - 0x000000000000000000000000000000000019575932f75ddf00595b22782e1ba2, - 0x0000000000000000000000000000000000d630b3fbf0a9e55861e4399900feb9, - 0x0000000000000000000000000000000000d6b37aeb2daa8d2e2f7e29b0f7752a, - 0x0000000000000000000000000000000000e9cacdd93406256b9eb46b73948849, - 0x00000000000000000000000000000000001400e1f0a38695db66993fe042c48b, - 0x0000000000000000000000000000000000e1d829cb4fa8cabb7d0265efbd8527, - 0x000000000000000000000000000000000055f1a92a5dd099ef2bcd89ac175b52, - 0x00000000000000000000000000000000000000000000000000000000000000fc, - ]; - let b: [u128; 18] = [ - 0x0000000000000000000000000000000000c5694493e9bcc76e68dfcf73e0fde1, - 0x0000000000000000000000000000000000ede5e4b8b3e0dec1f4705c35521620, - 0x00000000000000000000000000000000007aa800bab1b33eda0f07695af6c583, - 0x000000000000000000000000000000000045892edea2c02bf0b8b1d2d9a4ebcc, - 0x00000000000000000000000000000000004dffb06bf396f3d0a5b67cff714bdd, - 0x00000000000000000000000000000000004d691db495235e1e032f1ef3e90274, - 0x0000000000000000000000000000000000d92c069d0f2675b2f46cb497aa62d4, - 0x00000000000000000000000000000000003d3f23584f113cef1a4b8b7d183f5c, - 0x0000000000000000000000000000000000289ba11d897837f9cec57dcc430bfc, - 0x0000000000000000000000000000000000765dc64f6ed4a6efd7b26c38f79e59, - 0x00000000000000000000000000000000008edf31fabf5c330ecf7f92fb6487cd, - 0x000000000000000000000000000000000053392f8b14dd78af702b3be2e0d557, - 0x000000000000000000000000000000000034abf357bfd56e9786a7e47ed9a5ae, - 0x0000000000000000000000000000000000a9ebb234064c8ab10d4e7900d4b973, - 0x00000000000000000000000000000000002a6850cce14a20463913002ddc0fa6, - 0x0000000000000000000000000000000000a97e3b06586bfa62325ef7557ab536, - 0x0000000000000000000000000000000000b942b0d26e5be2e08cd425107c59f7, - 0x0000000000000000000000000000000000000000000000000000000000000031, - ]; - let c_expected: [u128; 18] = [ - 0x00000000000000000000000000000000004518a874adebbcf963fed876dfcf78, - 0x00000000000000000000000000000000002b1535070c2deca63e2dc7145a9997, - 0x0000000000000000000000000000000000d9b738665a290c09f09202043d9387, - 0x0000000000000000000000000000000000c88853b11034fe12661eb7a5e41ca7, - 0x0000000000000000000000000000000000357cc4053e7eb127abc2c1430972a1, - 0x0000000000000000000000000000000000224df5e1be31a51562f8574027a992, - 0x000000000000000000000000000000000070ad9287e6326d534f1d2835e159ad, - 0x00000000000000000000000000000000000efa138f75f20b5117955e15bbb447, - 0x0000000000000000000000000000000000d9f45c310be1865ad23fbcdeb1d93f, - 0x00000000000000000000000000000000004f74ca4cf3df59a83f2df796fc9beb, - 0x0000000000000000000000000000000000ed1801428ebf7db771deb45f4311eb, - 0x00000000000000000000000000000000002ded3b46e3a84cda43157d4d927162, - 0x00000000000000000000000000000000009bcd6ac8f90601a44a84a026d4b383, - 0x0000000000000000000000000000000000ab098478b39031a1de85062fd5712b, - 0x00000000000000000000000000000000004432a79276f4375ff3ec2ced8b6cf6, - 0x0000000000000000000000000000000000a0922d75e96e3f9e31c0cbbcbd708a, - 0x00000000000000000000000000000000004013822c9e9aa5b5b1e9c33e4332b7, - 0x0000000000000000000000000000000000000000000000000000000000000058, - ]; - - let a_bn: BN2048 = BigNum { limbs: a }; - let b_bn: BN2048 = BigNum { limbs: b }; - // Safety: test code - let c_bn = unsafe { a_bn.__mul(b_bn) }; - assert(c_bn.limbs == c_expected); - - a_bn.validate_in_range(); - - BigNum::evaluate_quadratic_expression([[a_bn]], [[false]], [[b_bn]], [[false]], [c_bn], [true]); -} - #[test] fn test_expressions() { let x: [u128; 6] = [ @@ -673,41 +666,34 @@ fn test_expressions() { 0, ]; - let y = BN254_Fq { limbs: [0x1, 0x1, 0x0] }; - let z = BN254_Fq { limbs: [0x2, 0x2, 0x0] }; + let y = BN254_Fq::from_limbs([0x1, 0x1, 0x0]); + let z = BN254_Fq::from_limbs([0x2, 0x2, 0x0]); // Safety: test code let yy = unsafe { y.__add(y) }; - assert(yy.limbs == z.limbs); + assert(yy.get_limbs() == z.get_limbs()); - let uu = BN254_Fq { - limbs: [ - 0x0000000000000000000000000000000000b4a832748da6ad742a1fd81b787643, - 0x00000000000000000000000000000000009575f594e04080471712c1d7f18e89, - 0x000000000000000000000000000000000000000000000000000000000000063, - ], - }; - let vv = BN254_Fq { - limbs: [ - 0x0000000000000000000000000000000000b4aec2748da6ad742a1fd81b787643, - 0x00000000000000000000000000000000009575f594e0408047171a01d7f18e89, - 0x0000000000000000000000000000000000000000000000000000000000000062, - ], - }; - let w = BN254_Fq { - limbs: [ - 0x0000000000000000000000000000000000b4a832748da6ad742a1fd81b787643, - 0x00000000000000000000000000000000009575f594e04080471712c1d7f18e89, - 0x0000000000000000000000000000000000000000000000000000000000001f93, - ], - }; - let x = BN254_Fq { - limbs: [ - 0x0000000000000000000000000000000000b4aec2748da6ad742a1fd81b787643, - 0x00000000000000000000000000000000009575f594e0408047171a01d7f18e89, - 0x0000000000000000000000000000000000000000000000000000000000000f93, - ], - }; + let uu = BN254_Fq::from_limbs([ + 0x0000000000000000000000000000000000b4a832748da6ad742a1fd81b787643, + 0x00000000000000000000000000000000009575f594e04080471712c1d7f18e89, + 0x000000000000000000000000000000000000000000000000000000000000063, + ]); + let vv = BN254_Fq::from_limbs([ + 0x0000000000000000000000000000000000b4aec2748da6ad742a1fd81b787643, + 0x00000000000000000000000000000000009575f594e0408047171a01d7f18e89, + 0x0000000000000000000000000000000000000000000000000000000000000062, + ]); + + let w = BN254_Fq::from_limbs([ + 0x0000000000000000000000000000000000b4a832748da6ad742a1fd81b787643, + 0x00000000000000000000000000000000009575f594e04080471712c1d7f18e89, + 0x0000000000000000000000000000000000000000000000000000000000001f93, + ]); + let x = BN254_Fq::from_limbs([ + 0x0000000000000000000000000000000000b4aec2748da6ad742a1fd81b787643, + 0x00000000000000000000000000000000009575f594e0408047171a01d7f18e89, + 0x0000000000000000000000000000000000000000000000000000000000000f93, + ]); // Safety: test code let wx = unsafe { w.__mul(x) }; // Safety: test code @@ -735,7 +721,7 @@ fn test_expressions() { ); let wx_constrained = w * x; - assert(wx_constrained.limbs == wx.limbs); + assert(wx_constrained.get_limbs() == wx.get_limbs()); } #[test] @@ -749,8 +735,11 @@ fn test_from_field_1_digit() { fn test_from_field_2_digits() { let field: Field = 762576765071760201410184025311678064293966151975347778787092903729041075; let result = BN254_Fq::from(field); - let expected: BN254_Fq = - BigNum { limbs: [0xe88ed97f8f707abd3fa65763c80eb3, 0x6e7d8b5586595aa1fb2ee04d5cb4f5, 0x0] }; + let expected: BN254_Fq = BN254_Fq::from_limbs([ + 0xe88ed97f8f707abd3fa65763c80eb3, + 0x6e7d8b5586595aa1fb2ee04d5cb4f5, + 0x0, + ]); assert(result == expected); } @@ -758,32 +747,37 @@ fn test_from_field_2_digits() { fn test_from_field_3_digits() { let field: Field = -1; let result = BN254_Fq::from(field); - let expected = BN254_Fq { - limbs: [0x33e84879b9709143e1f593f0000000, 0x4e72e131a029b85045b68181585d28, 0x3064], - }; + let expected: BN254_Fq = BN254_Fq::from_limbs([ + 0x33e84879b9709143e1f593f0000000, + 0x4e72e131a029b85045b68181585d28, + 0x3064, + ]); assert(result == expected); } #[test] fn test_do_nothing() { - let a: BN254_Fq = BN254_Fq { limbs: [1, 2, 0] }; - let b: BN254_Fq = BN254_Fq { limbs: [1, 2, 0] }; + let a: BN254_Fq = BN254_Fq::from_limbs([1, 2, 0]); + let b: BN254_Fq = BN254_Fq::from_limbs([1, 2, 0]); // Safety: test code - let c = unsafe { __helper_add(a.limbs, b.limbs) }; + let c = unsafe { __helper_add(a.get_limbs(), b.get_limbs()) }; // Safety: test code let d = unsafe { a.__add(b) }; let e = a + b; - assert(c == d.limbs); - assert(c == e.limbs); + assert(c == d.get_limbs()); + assert(c == e.get_limbs()); } #[test] fn test_from_field_3_digits_BLS381() { let field: Field = -1; let result = BLS12_381_Fq::from(field); - let expected = BLS12_381_Fq { - limbs: [0x33e84879b9709143e1f593f0000000, 0x4e72e131a029b85045b68181585d28, 0x3064, 0x0], - }; + let expected = BLS12_381_Fq::from_limbs([ + 0x33e84879b9709143e1f593f0000000, + 0x4e72e131a029b85045b68181585d28, + 0x3064, + 0x0, + ]); assert(result == expected); } @@ -798,7 +792,7 @@ fn test_to_field_one() { #[test] fn test_to_field_one_digit() { let field: Field = 1066513542066841864585910935480267774; - let bn = BN254_Fq { limbs: [0xcd672d695ef3129e4c40867a7173fe, 0x0, 0x0] }; + let bn = BN254_Fq::from_limbs([0xcd672d695ef3129e4c40867a7173fe, 0x0, 0x0]); let result = to_field(bn); assert(result == field); } @@ -806,9 +800,11 @@ fn test_to_field_one_digit() { #[test] fn test_to_field_two_digits() { let field: Field = 697955470585821007263499235110798476786097877002667034107578965871052378; - let bn = BN254_Fq { - limbs: [0x5a10b956d41840745e0a9f6e34465a, 0x65209b74583b912262843211905e41, 0x0], - }; + let bn = BN254_Fq::from_limbs([ + 0x5a10b956d41840745e0a9f6e34465a, + 0x65209b74583b912262843211905e41, + 0x0, + ]); let result = to_field(bn); assert(result == field); } @@ -816,49 +812,58 @@ fn test_to_field_two_digits() { #[test] fn test_to_field_three_digits() { let field: Field = 2330301921655783950764183713945533646391233209687308929386184468126823563744; - let bn = BN254_Fq { - limbs: [0x862cf8ea69d6c70c9cc8d8871b41e0, 0xe7763528201566c2fc8d93973cf1b4, 0x526], - }; + let bn = BN254_Fq::from_limbs([ + 0x862cf8ea69d6c70c9cc8d8871b41e0, + 0xe7763528201566c2fc8d93973cf1b4, + 0x526, + ]); let result = to_field(bn); assert(result == field); } #[test(should_fail_with = "BigNum::validate_gt check fails")] fn test_to_field_three_digits_overflow() { - let bn = BN254_Fq { - limbs: [0x4e6405505a33bb9b9c0563df2bd59a, 0x48dbe03a9bb4865ba961e41ef9dded, 0x3a36], - }; + let bn = BN254_Fq::from_limbs([ + 0x4e6405505a33bb9b9c0563df2bd59a, + 0x48dbe03a9bb4865ba961e41ef9dded, + 0x3a36, + ]); let _ = to_field(bn); } #[test(should_fail_with = "BigNum::validate_gt check fails")] fn test_to_field_too_many_digits() { - let bn = BLS12_381_Fq { - limbs: [0xea1742447ee9d92f9f18e1c80a481e, 0x3d89ad3d3ae85f3f482a08435c93ec, 0x1e9f, 0x1], - }; + let bn = BLS12_381_Fq::from_limbs([ + 0xea1742447ee9d92f9f18e1c80a481e, + 0x3d89ad3d3ae85f3f482a08435c93ec, + 0x1e9f, + 0x1, + ]); let _ = to_field(bn); } #[test] fn test_from_to_field_1() { let a = 20192735083400333763152317277081729935089452774154199134677444560763605803197; - let b = BN254_Fq::from(a); + let b: BN254_Fq = BN254_Fq::from(a); let c = to_field(b); assert(c == a); } #[test] fn test_from_to_field_fuzz(a: Field) { - let b = BLS12_381_Fq::from(a); + let b: BLS12_381_Fq = BLS12_381_Fq::from(a); let c = to_field(b); assert(c == a); } #[test] fn test_to_from_field_1() { - let a = BN254_Fq { - limbs: [0x3c768db7732ea1b536c06ae66bce70, 0xb9936c1401d91e7e9e1138375650b4, 0x8c8], - }; + let a = BN254_Fq::from_limbs([ + 0x3c768db7732ea1b536c06ae66bce70, + 0xb9936c1401d91e7e9e1138375650b4, + 0x8c8, + ]); let b = to_field(a); let c = BN254_Fq::from(b); assert(a == c); @@ -866,9 +871,12 @@ fn test_to_from_field_1() { #[test] fn test_to_from_field_2() { - let a = BLS12_381_Fq { - limbs: [0xd7562bf2b1fe13d458685c96a46d28, 0x2079950acd45bb43a9beeba69d5dc9, 0x18ca, 0x0], - }; + let a = BLS12_381_Fq::from_limbs([ + 0xd7562bf2b1fe13d458685c96a46d28, + 0x2079950acd45bb43a9beeba69d5dc9, + 0x18ca, + 0x0, + ]); let b = to_field(a); let c = BLS12_381_Fq::from(b); assert(a == c); @@ -876,7 +884,7 @@ fn test_to_from_field_2() { unconstrained fn test_batch_inversion(fields: [BN; N]) where - BN: BigNumTrait, + BN: BigNum, { let inverted_fields = BN::__batch_invert(fields); for i in 0..N { @@ -892,7 +900,7 @@ unconstrained fn test_batch_inversion_BN381(seeds: [[u8; 2]; 3]) { unconstrained fn test_batch_inversion_slice(fields: [BN]) where - BN: BigNumTrait, + BN: BigNum, { let inverted_fields = BN::__batch_invert_slice(fields); assert_eq(fields.len(), inverted_fields.len()); @@ -916,59 +924,59 @@ unconstrained fn test_batch_inversion_BN381_regression(seeds: [[u8; 2]; 5]) { #[test] fn test_sub_underflow_regression() { let limbs = [605231426910671071918217543292637230, 925169190305713195541137574269511054, 4915]; - let a = BLS12_381_Fr { limbs: limbs }; - let b = BLS12_381_Fr { limbs: limbs }; + let a = BLS12_381_Fr::from_limbs(limbs); + let b = BLS12_381_Fr::from_limbs(limbs); let c = b - a; - assert(c.limbs == [0, 0, 0]); + assert(c.get_limbs() == [0, 0, 0]); } #[test] fn test_cmp_BN() { - let mut a: BN254_Fq = BigNum::modulus(); - let mut b: BN254_Fq = BigNum::modulus(); + let mut a: BN254_Fq = BN254_Fq::modulus(); + let mut b: BN254_Fq = BN254_Fq::modulus(); - a.limbs[0] -= 2; - b.limbs[0] -= 1; + a.set_limb(0, a.get_limb(0) - 2); + b.set_limb(0, b.get_limb(0) - 1); assert(a < b); } #[test(should_fail_with = "Failed constraint")] fn test_cmp_BN_fail() { - let mut a: BN254_Fq = BigNum::modulus(); - let mut b: BN254_Fq = BigNum::modulus(); + let mut a: BN254_Fq = BN254_Fq::modulus(); + let mut b: BN254_Fq = BN254_Fq::modulus(); - a.limbs[0] -= 1; - b.limbs[0] -= 2; + a.set_limb(0, a.get_limb(0) - 1); + b.set_limb(0, b.get_limb(0) - 2); assert(a < b); } #[test] fn test_cmp_BN_2() { - let mut a: BN254_Fq = BigNum::modulus(); - let mut b: BN254_Fq = BigNum::modulus(); + let mut a: BN254_Fq = BN254_Fq::modulus(); + let mut b: BN254_Fq = BN254_Fq::modulus(); - a.limbs[0] -= 1; - b.limbs[0] -= 2; + a.set_limb(0, a.get_limb(0) - 1); + b.set_limb(0, b.get_limb(0) - 2); assert(a > b); } #[test(should_fail_with = "Failed constraint")] fn test_cmp_BN_fail_2() { - let mut a: BN254_Fq = BigNum::modulus(); - let mut b: BN254_Fq = BigNum::modulus(); + let mut a: BN254_Fq = BN254_Fq::modulus(); + let mut b: BN254_Fq = BN254_Fq::modulus(); - a.limbs[0] -= 2; - b.limbs[0] -= 1; + a.set_limb(0, a.get_limb(0) - 2); + b.set_limb(0, b.get_limb(0) - 1); assert(a > b); } #[test] fn test_cmp_BN_fuzz(seed: [u8; 5]) { - let mut a: BN254_Fq = BigNum::derive_from_seed(seed); + let mut a: BN254_Fq = BN254_Fq::derive_from_seed(seed); let modulus_sub_1_div_2 = (BN254_Fq::modulus() - BN254_Fq::one()) / BN254_Fq::from(2); a = if a > modulus_sub_1_div_2 { -a } else { a }; @@ -991,14 +999,11 @@ fn fuzz_to_be_bytes(seed: [u8; 5]) { assert(a == b); } -struct SecP224r1_Params {} -type SecP224r1 = BigNum<2, 224, SecP224r1_Params>; - -impl BigNumParamsGetter<2, 224> for SecP224r1_Params { - fn get_params() -> BigNumParams<2, 224> { - SecP224r1_PARAMS - } +#[derive_bignum_impl(2, 224, quote {SecP224r1_PARAMS})] +struct SecP224r1 { + limbs: [u128; 2], } + global SecP224r1_PARAMS: BigNumParams<2, 224> = BigNumParams { has_multiplicative_inverse: true, modulus: [0xffffff000000000000000000000001, 0xffffffffffffffffffffffffff], diff --git a/src/tests/runtime_bignum_test.nr b/src/tests/runtime_bignum_test.nr index 64fe485f..33cf6681 100644 --- a/src/tests/runtime_bignum_test.nr +++ b/src/tests/runtime_bignum_test.nr @@ -1,10 +1,9 @@ +use crate::fields::bn254Fq::BN254_Fq_PARAMS; use crate::fns::constrained_ops::{sub, udiv}; use crate::fns::unconstrained_helpers::__barrett_reduction; -use crate::params::{BigNumParams, BigNumParamsGetter}; +use crate::params::BigNumParams; use crate::runtime_bignum::RuntimeBigNum; -use crate::fields::bn254Fq::BN254_Fq_Params; - global TEST_2048_PARAMS: BigNumParams<18, 2048> = BigNumParams { has_multiplicative_inverse: false, modulus: [ @@ -69,24 +68,10 @@ global TEST_2048_PARAMS: BigNumParams<18, 2048> = BigNumParams { ], }; -pub(crate) struct Test2048Params {} - -// See https://github.com/noir-lang/noir/issues/6172 -#[test] -fn silence_warning() { - let _ = Test2048Params {}; -} - -impl BigNumParamsGetter<18, 2048> for Test2048Params { - fn get_params() -> BigNumParams<18, 2048> { - TEST_2048_PARAMS - } -} - /** * @brief experimenting with macro madness and code generation to make some tests that apply to multiple BigNum parametrisations! **/ -comptime fn make_test(_m: Module, N: u32, MOD_BITS: u32, typ: Quoted) -> Quoted { +comptime fn make_test(_m: Module, N: u32, MOD_BITS: u32, params: Quoted) -> Quoted { let RuntimeBigNum = quote { crate::RuntimeBigNum }; let __helper_add = quote { crate::fns::unconstrained_helpers::__helper_add }; let __helper_sub = quote { crate::fns::unconstrained_helpers::__helper_sub }; @@ -97,7 +82,7 @@ comptime fn make_test(_m: Module, N: u32, MOD_BITS: u32, typ: Quoted) -> Quoted quote { #[test] fn test_add() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; let a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); let b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [4, 5, 6, 7]); @@ -122,7 +107,7 @@ fn test_add() { #[test] fn test_sub() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; // 0 - 1 should equal p - 1 let mut a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::zero(params); @@ -138,7 +123,7 @@ fn test_sub() { #[test] fn test_sub_modulus_limit() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; // if we underflow, maximum result should be ... // 0 - 1 = o-1 // 0 - p = 0 @@ -153,7 +138,7 @@ fn test_sub_modulus_limit() { #[test(should_fail_with = "call to assert_max_bit_size")] fn test_sub_modulus_underflow() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; // 0 - (p + 1) is smaller than p and should produce unsatisfiable constraints let mut a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::zero(params); @@ -168,7 +153,7 @@ fn test_sub_modulus_underflow() { #[test] fn test_add_modulus_limit() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; // p + 2^{modulus_bits()} - 1 should be the maximum allowed value fed into an add operation // when adding, if the result overflows the modulus, we conditionally subtract the modulus, producing 2^{254} - 1 @@ -188,7 +173,7 @@ fn test_add_modulus_limit() { #[test(should_fail_with = "call to assert_max_bit_size")] fn test_add_modulus_overflow() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; let p: [u128; $N] = params.modulus; // Safety: test code @@ -207,7 +192,7 @@ fn test_add_modulus_overflow() { #[test] fn test_mul() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; let a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); let b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [4, 5, 6, 7]); @@ -219,7 +204,7 @@ fn test_mul() { #[test] fn test_quadratic_expression() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; for i in 0..32 { let X1: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [i as u8, 2, 3, 4]); @@ -267,7 +252,7 @@ fn test_quadratic_expression() { #[test] fn assert_is_not_equal() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; let a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); let b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [4, 5, 6, 7]); @@ -277,7 +262,7 @@ fn assert_is_not_equal() { #[test(should_fail_with = "asssert_is_not_equal fail")] fn assert_is_not_equal_fail() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; let a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); let b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); @@ -287,7 +272,7 @@ fn assert_is_not_equal_fail() { #[test(should_fail_with = "asssert_is_not_equal fail")] fn assert_is_not_equal_overloaded_lhs_fail() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; let a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); let b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); @@ -304,7 +289,7 @@ fn assert_is_not_equal_overloaded_lhs_fail() { #[test(should_fail_with = "asssert_is_not_equal fail")] fn assert_is_not_equal_overloaded_rhs_fail() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; let a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); let b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); @@ -321,7 +306,7 @@ fn assert_is_not_equal_overloaded_rhs_fail() { #[test(should_fail_with = "asssert_is_not_equal fail")] fn assert_is_not_equal_overloaded_fail() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; let a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); let b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); @@ -343,7 +328,7 @@ fn assert_is_not_equal_overloaded_fail() { #[test] fn test_derive() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; // let a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, "hello".as_bytes()); let a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); @@ -353,7 +338,7 @@ fn test_derive() #[test] fn test_eq() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; let a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); let b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); @@ -375,7 +360,7 @@ fn test_eq() { #[test] fn test_is_zero() { - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; let a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::zero(params); let b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, [1, 2, 3, 4]); @@ -386,8 +371,8 @@ fn test_is_zero() { #[test] fn test_cmp() { - let modulus = $typ ::get_params().modulus; - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; + let modulus = params.modulus; let mut a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum { limbs: modulus, params }; let mut b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum { limbs: modulus, params }; @@ -398,8 +383,8 @@ fn test_cmp() { #[test(should_fail_with = "Failed constraint")] fn test_cmp_BN_fail() { - let modulus = $typ ::get_params().modulus; - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; + let modulus = params.modulus; let mut a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum { limbs: modulus, params }; let mut b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum { limbs: modulus, params }; @@ -412,8 +397,8 @@ fn test_cmp_BN_fail() { #[test] fn test_cmp_BN_2() { - let modulus = $typ ::get_params().modulus; - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; + let modulus = params.modulus; let mut a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum { limbs: modulus, params }; let mut b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum { limbs: modulus, params }; @@ -425,8 +410,8 @@ fn test_cmp_BN_2() { #[test(should_fail_with = "Failed constraint")] fn test_cmp_BN_fail_2() { - let modulus = $typ ::get_params().modulus; - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; + let modulus = params.modulus; let mut a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum { limbs: modulus, params }; let mut b: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum { limbs: modulus, params }; @@ -438,7 +423,7 @@ fn test_cmp_BN_fail_2() { #[test] fn test_cmp_fuzz(seed: [u8; 2]){ - let params = $typ ::get_params(); + let params: crate::params::BigNumParams<_,_> = $params; let modulus = params.modulus; let mut a: $RuntimeBigNum<$N, $MOD_BITS> = $RuntimeBigNum::derive_from_seed(params, seed); let mut half_modulus = $RuntimeBigNum::zero(params); @@ -467,40 +452,26 @@ fn test_cmp_fuzz(seed: [u8; 2]){ } } -#[make_test(3, 254, quote {crate::fields::bn254Fq::BN254_Fq_Params})] -pub mod BNTests { - use crate::params::BigNumParamsGetter; -} +#[make_test(3, 254, quote {crate::fields::bn254Fq::BN254_Fq_PARAMS})] +pub mod BNTests {} -#[make_test(3, 256, quote {crate::fields::secp256k1Fq::Secp256k1_Fq_Params})] -pub mod Secp256K1FqTests { - use crate::params::BigNumParamsGetter; -} +#[make_test(3, 256, quote {crate::fields::secp256k1Fq::Secp256k1_Fq_PARAMS})] +pub mod Secp256K1FqTests {} -#[make_test(4, 381, quote {crate::fields::bls12_381Fq::BLS12_381_Fq_Params})] -pub mod BLS12_381FqTests { - use crate::params::BigNumParamsGetter; -} +#[make_test(4, 381, quote {crate::fields::bls12_381Fq::BLS12_381_Fq_PARAMS})] +pub mod BLS12_381FqTests {} -#[make_test(18, 2048, quote {super::Test2048Params})] -pub mod Test2048Tests { - use crate::params::BigNumParamsGetter; -} +#[make_test(18, 2048, quote {super::TEST_2048_PARAMS})] +pub mod Test2048Tests {} -#[make_test(3, 255, quote {crate::fields::bls12_381Fr::BLS12_381_Fr_Params})] -pub mod BLS12_381_Fr_ParamsTests { - use crate::params::BigNumParamsGetter; -} +#[make_test(3, 255, quote {crate::fields::bls12_381Fr::BLS12_381_Fr_PARAMS})] +pub mod BLS12_381_Fr_ParamsTests {} -#[make_test(4, 377, quote {crate::fields::bls12_377Fq::BLS12_377_Fq_Params})] -pub mod BLS12_377_Fq_ParamsTests { - use crate::params::BigNumParamsGetter; -} +#[make_test(4, 377, quote {crate::fields::bls12_377Fq::BLS12_377_Fq_PARAMS})] +pub mod BLS12_377_Fq_ParamsTests {} -#[make_test(3, 253, quote {crate::fields::bls12_377Fr::BLS12_377_Fr_Params})] -pub mod BLS12_377_Fr_ParamsTests { - use crate::params::BigNumParamsGetter; -} +#[make_test(3, 253, quote {crate::fields::bls12_377Fr::BLS12_377_Fr_PARAMS})] +pub mod BLS12_377_Fr_ParamsTests {} // 98760 // 99689 @@ -526,13 +497,13 @@ unconstrained fn test_invmod(params: BigNumParams #[test] fn test_div_BN() { - let params = BN254_Fq_Params::get_params(); + let params = BN254_Fq_PARAMS; test_div(params); } #[test] fn test_invmod_BN() { - let params = BN254_Fq_Params::get_params(); + let params = BN254_Fq_PARAMS; // Safety: test code unsafe { test_invmod(params) }; } @@ -635,7 +606,7 @@ fn test_2048_bit_quadratic_expression() { #[test] fn test_sqrt_BN() { - let params = BN254_Fq_Params::get_params(); + let params = BN254_Fq_PARAMS; let x = RuntimeBigNum { limbs: [9, 0, 0], params }; diff --git a/src/utils/msb.nr b/src/utils/msb.nr index 3452eacd..6f8be366 100644 --- a/src/utils/msb.nr +++ b/src/utils/msb.nr @@ -20,7 +20,9 @@ pub unconstrained fn get_msb64(x: u64) -> u32 { v |= v >> 8; v |= v >> 16; v |= v >> 32; - MUL_DE_BRUIJN_BIT[(std::wrapping_mul(v, 0x6c04f118e9966f6b)) >> 57] + let index = (std::wrapping_mul(v, 0x6c04f118e9966f6b)) >> 57; + (index as Field).assert_max_bit_size::<32>(); + MUL_DE_BRUIJN_BIT[index as u32] } // 1100