From ac85d3dbf4d01df330aa12072c9f2b5b08c7fb59 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Thu, 3 Oct 2024 11:01:11 +0100 Subject: [PATCH 01/29] refactor --- src/bignum.nr | 340 +++++++ src/bignum_test.nr | 325 +++---- src/constrained_ops.nr | 308 +++++++ src/expressions.nr | 412 +++++++++ src/fields/U1024.nr | 59 +- src/fields/U2048.nr | 59 +- src/fields/U256.nr | 60 +- src/fields/U384.nr | 59 +- src/fields/U4096.nr | 59 +- src/fields/U512.nr | 41 +- src/fields/U768.nr | 59 +- src/fields/U8192.nr | 59 +- src/fields/bls12_377Fq.nr | 51 +- src/fields/bls12_377Fr.nr | 53 +- src/fields/bls12_381Fq.nr | 53 +- src/fields/bls12_381Fr.nr | 53 +- src/fields/bn254Fq.nr | 53 +- src/fields/ed25519Fq.nr | 53 +- src/fields/ed25519Fr.nr | 53 +- src/fields/mnt4_753Fq.nr | 53 +- src/fields/mnt4_753Fr.nr | 53 +- src/fields/mnt6_753Fq.nr | 53 +- src/fields/mnt6_753Fr.nr | 53 +- src/fields/mod.nr | 43 +- src/fields/pallasFq.nr | 53 +- src/fields/pallasFr.nr | 53 +- src/fields/secp256k1Fq.nr | 53 +- src/fields/secp256k1Fr.nr | 53 +- src/fields/secp256r1Fq.nr | 53 +- src/fields/secp256r1Fr.nr | 53 +- src/fields/secp384r1Fq.nr | 53 +- src/fields/secp384r1Fr.nr | 53 +- src/fields/vestaFq.nr | 53 +- src/fields/vestaFr.nr | 53 +- src/lib.nr | 325 +------ src/params.nr | 85 ++ src/runtime_bignum.nr | 1673 +++++----------------------------- src/runtime_bignum_test.nr | 453 ++++----- src/serialization.nr | 66 ++ src/unconstrained_helpers.nr | 223 +++++ src/unconstrained_ops.nr | 290 ++++++ src/utils/map.nr | 12 + src/utils/mod.nr | 9 +- 43 files changed, 3098 insertions(+), 3032 deletions(-) create mode 100644 src/bignum.nr create mode 100644 src/constrained_ops.nr create mode 100644 src/expressions.nr create mode 100644 src/params.nr create mode 100644 src/serialization.nr create mode 100644 src/unconstrained_helpers.nr create mode 100644 src/unconstrained_ops.nr create mode 100644 src/utils/map.nr diff --git a/src/bignum.nr b/src/bignum.nr new file mode 100644 index 00000000..d27905e4 --- /dev/null +++ b/src/bignum.nr @@ -0,0 +1,340 @@ +use crate::utils::map::map; + +use crate::params::BigNumParamsTrait; +use crate::constrained_ops::{ + conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, neg, add, sub, + mul, div, udiv_mod, udiv, umod +}; +use crate::unconstrained_ops::{ + __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, + __batch_invert, __batch_invert_slice +}; +use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}; +use crate::serialization::{from_be_bytes, to_le_bytes}; + +pub struct BigNum { + limbs: [Field; N] +} + +pub(crate) trait BigNumTrait { + // TODO: this crashes the compiler? v0.32 + // fn default() -> Self { std::default::Default::default () } + fn new() -> Self; + fn one() -> Self; + unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self; + fn from_slice(limbs: [Field]) -> Self; + fn from_array(limbs: [Field; N]) -> Self; + fn from_be_bytes(x: [u8; NBytes]) -> Self; + fn to_le_bytes(self) -> [u8; NBytes]; + + fn modulus() -> Self; + fn modulus_bits() -> u32; + fn num_limbs() -> u32; + // fn get(self) -> [Field]; + fn get_limbs(self) -> [Field; N]; + fn get_limb(self, idx: u32) -> Field; + fn set_limb(&mut self, idx: u32, value: Field); + + unconstrained fn __eq(self, other: Self) -> bool; + unconstrained fn __is_zero(self) -> bool; + + unconstrained fn __neg(self) -> Self; + unconstrained fn __add(self, other: Self) -> Self; + unconstrained fn __sub(self, other: Self) -> Self; + unconstrained fn __mul(self, other: Self) -> Self; + unconstrained fn __div(self, other: Self) -> Self; + unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self); + unconstrained fn __invmod(self) -> Self; + unconstrained fn __pow(self, exponent: Self) -> Self; + + unconstrained fn __batch_invert(to_invert: [Self; M]) -> [Self; M]; + unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; + + unconstrained fn __compute_quadratic_expression( + lhs: [[Self; LHS_N]; NUM_PRODUCTS], + lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], + rhs: [[Self; RHS_N]; NUM_PRODUCTS], + rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], + add: [Self; ADD_N], + add_flags: [bool; ADD_N] + ) -> (Self, Self); + + fn evaluate_quadratic_expression( + lhs: [[Self; LHS_N]; NUM_PRODUCTS], + lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], + rhs: [[Self; RHS_N]; NUM_PRODUCTS], + rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], + add: [Self; ADD_N], + add_flags: [bool; ADD_N] + ); + + fn eq(self, other: Self) -> bool { self == other } + fn assert_is_not_equal(self, other: Self); + fn validate_in_range(self); + fn validate_in_field(self); + + fn neg(self) -> Self; + fn add(self, other: Self) -> Self { self + other } + fn sub(self, other: Self) -> Self { self - other } + fn mul(self, other: Self) -> Self { self * other } + fn div(self, other: Self) -> Self { self / other } + fn udiv_mod(self, divisor: Self) -> (Self, Self); + fn udiv(self, divisor: Self) -> Self; + fn umod(self, divisor: Self) -> Self; + + fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; +} + +impl BigNumTrait for BigNum where Params: BigNumParamsTrait { + + fn new() -> Self { + Self { limbs: [0; N] } + } + + fn one() -> Self { + let mut result = BigNum::new(); + result.limbs[0] = 1; + result + } + + unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self { + let params = Params::get_params(); + Self { limbs: __derive_from_seed(params, seed) } + } + + fn from_slice(limbs: [Field]) -> Self { + Self { limbs: limbs.as_array() } + } + + fn from_array(limbs: [Field; N]) -> Self { + Self { limbs } + } + + fn from_be_bytes(x: [u8; NBytes]) -> Self { + let params = Params::get_params(); + Self { limbs: from_be_bytes(params, x) } + } + + fn to_le_bytes(self) -> [u8; NBytes] { + let params = Params::get_params(); + to_le_bytes(params, self.limbs) + } + + fn modulus() -> Self { + Self { limbs: Params::get_params().modulus } + } + + fn modulus_bits() -> u32 { + let modulus_bits_getter = Params::get_params().modulus_bits_getter; + modulus_bits_getter() + } + + fn num_limbs() -> u32 { + N + } + + // fn get(self) -> [Field] { + // self.get_limbs() + // } + + fn get_limbs(self) -> [Field; N] { + self.limbs + } + + fn get_limb(self, idx: u32) -> Field { + self.limbs[idx] + } + + fn set_limb(&mut self, idx: u32, value: Field) { + 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::from_array(__neg(params, self.limbs)) + } + + unconstrained fn __add(self, other: Self) -> Self { + let params = Params::get_params(); + Self::from_array(__add(params, self.limbs, other.limbs)) + } + + unconstrained fn __sub(self, other: Self) -> Self { + let params = Params::get_params(); + Self::from_array(__sub(params, self.limbs, other.limbs)) + } + + unconstrained fn __mul(self, other: Self) -> Self { + let params = Params::get_params(); + Self::from_array(__mul(params, self.limbs, other.limbs)) + } + + unconstrained fn __div(self, divisor: Self) -> Self { + let params = Params::get_params(); + Self::from_array(__div(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(params, self.limbs) } + } + + unconstrained fn __pow(self, exponent: Self) -> Self { + let params = Params::get_params(); + Self { limbs: __pow(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(params, x.map(|bn| Self::get_limbs(bn))).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(params, x.map(|bn| Self::get_limbs(bn))).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( + params, + lhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + lhs_flags, + rhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + rhs_flags, + linear_terms.map(|bn| Self::get_limbs(bn)), + 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( + params, + lhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + lhs_flags, + rhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + rhs_flags, + linear_terms.map(|bn| Self::get_limbs(bn)), + linear_flags + ) + } + + fn validate_in_field(self: Self) { + let params = Params::get_params(); + validate_in_field(params, self.limbs); + } + + fn validate_in_range(self) { + let params = Params::get_params(); + validate_in_range(params, 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 neg(self) -> Self { + let params = Params::get_params(); + Self { limbs: neg(params, self.limbs) } + } + + fn udiv_mod(self, divisor: Self) -> (Self, Self) { + let params = Params::get_params(); + let (q, r) = udiv_mod(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(params, self.limbs, divisor.limbs) } + } + + fn umod(self, divisor: Self) -> Self { + let params = Params::get_params(); + Self { limbs: umod(params, self.limbs, divisor.limbs) } + } + + fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self { + Self { limbs: conditional_select(lhs.limbs, rhs.limbs, predicate) } + } +} + +// impl BigNumTrait for BigNum where Params: BigNumParamsTrait {} + +impl std::ops::Add for BigNum where Params: BigNumParamsTrait { + // 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(params, self.limbs, other.limbs) } + } +} + +impl std::ops::Sub for BigNum where Params: BigNumParamsTrait { + // 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(params, self.limbs, other.limbs) } + } +} + +impl std::ops::Mul for BigNum where Params: BigNumParamsTrait { + // 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(params, self.limbs, other.limbs) } + } +} + +impl std::ops::Div for BigNum where Params: BigNumParamsTrait { + // 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(params, self.limbs, other.limbs) } + } +} + +impl std::cmp::Eq for BigNum where Params: BigNumParamsTrait { + fn eq(self, other: Self) -> bool { + let params = Params::get_params(); + eq(params, self.limbs, other.limbs) + } +} + diff --git a/src/bignum_test.nr b/src/bignum_test.nr index c74875b0..146afa0e 100644 --- a/src/bignum_test.nr +++ b/src/bignum_test.nr @@ -1,13 +1,13 @@ -use crate::BigNum; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; -use crate::BigNumParamsTrait as BigNumParamsTrait; - use crate::utils::u60_representation::U60Repr; -use crate::fields::bn254Fq::BNParams; -use crate::fields::U256::U256Params; -use crate::runtime_bignum::BigNumInstance; -use crate::BigNumTrait; +use crate::bignum::BigNum; +use crate::bignum::BigNumTrait; + +use crate::params::BigNumParams; +use crate::params::BigNumParamsTrait; + +use crate::fields::bn254Fq::BN254_Fq_Params; +use crate::fields::U256::U256Params; struct Test2048Params{} @@ -17,13 +17,11 @@ fn silence_warning() { let _ = Test2048Params {}; } -impl RuntimeBigNumParamsTrait<18> for Test2048Params { - fn modulus_bits() -> u32 { - 2048 - } -} impl BigNumParamsTrait<18> for Test2048Params { - fn get_instance() -> BigNumInstance<18, Self> { + fn get_params() -> BigNumParams<18> { + let has_multiplicative_inverse = false; + let modulus_bits_getter = || 2048; + // let modulus_bits = 2048; let modulus: [Field; 18] = [ 0x0000000000000000000000000000000000c0a197a5ae0fcdceb052c9732614fe, 0x0000000000000000000000000000000000656ae034423283422243918ab83be3, @@ -44,26 +42,6 @@ impl BigNumParamsTrait<18> for Test2048Params { 0x00000000000000000000000000000000009c1fdb18907711bfe3e3c1cf918395, 0x00000000000000000000000000000000000000000000000000000000000000b8 ]; - // fn double_modulus() -> [Field; 18] {[ - // 0x000000000000000000000000000000000181432f4b5c1f9b9d60a592e64c29fc, - // 0x0000000000000000000000000000000001cad5c06884650684448723157077c6, - // 0x0000000000000000000000000000000001d7eb21b4914f820e16fab557558cef, - // 0x0000000000000000000000000000000001199c73ea604716c0de49652dc57b51, - // 0x000000000000000000000000000000000103c3fdf37738387d5b31e44de37f3f, - // 0x00000000000000000000000000000000015b183902dc25c1da26f20abc6e757d, - // 0x00000000000000000000000000000000019d7d01c8e9eea7553a28c3886a247a, - // 0x00000000000000000000000000000000015dcb4319ddbdf11a22b5172782cf5a, - // 0x00000000000000000000000000000000014d17507894cb8860e84ff892bb3c88, - // 0x0000000000000000000000000000000001ba4eef24d090ccf6fbef3e684c73a7, - // 0x0000000000000000000000000000000001e8aa0e992d0ab9400d0cd1dfcfb47a, - // 0x0000000000000000000000000000000001bbb74d6617782d17f674244be4faca, - // 0x0000000000000000000000000000000001b23fd8909e6ce0ea4826779ade84af, - // 0x0000000000000000000000000000000001b2c836eacecd5dd7cccf03ba03a0c3, - // 0x0000000000000000000000000000000001b178bd5fe962cbc2857f3c4901dd75, - // 0x0000000000000000000000000000000001ccf472c9e11c0dbeee59cc964534e3, - // 0x0000000000000000000000000000000001383fb63120ee237fc7c7839f230729, - // 0x0000000000000000000000000000000000000000000000000000000000000170 - // ]} let redc_param: [Field; 18] = [ 0x000000000000000000000000000000000091697def7100cd5cf8d890b4ef2ec3, 0x00000000000000000000000000000000006765ba8304214dac764d3f4adc3185, @@ -84,24 +62,32 @@ impl BigNumParamsTrait<18> for Test2048Params { 0x0000000000000000000000000000000000ff4e42304e60fb3a54fca735499f2c, 0x0000000000000000000000000000000000000000000000000000000000000162 ]; - BigNumInstance::new(modulus, redc_param) - } - fn modulus_bits() -> u32 { - 2048 + BigNumParams::new( + has_multiplicative_inverse, + modulus_bits_getter, + modulus, + redc_param + ) } } -type Fq = BigNum<3, BNParams>; +type Fq = BigNum<3, BN254_Fq_Params>; -fn test_eq(_: BigNum, __: [Field; N]) where BigNum: BigNumTrait { - let a = BigNum::__derive_from_seed([1, 2, 3, 4]); - let b = BigNum::__derive_from_seed([1, 2, 3, 4]); - let c = BigNum::__derive_from_seed([2, 2, 3, 4]); +fn test_eq() where BN: BigNumTrait { + let a = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; + let b = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; + let c = unsafe { + BN::__derive_from_seed([2, 2, 3, 4]) + }; - let modulus = BigNum::modulus(); - let t0: U60Repr = (U60Repr::from(modulus.get().as_array())); - let t1: U60Repr = (U60Repr::from(b.get().as_array())); - let b_plus_modulus: BigNum = BigNum::from(U60Repr::into(t0 + t1).as_slice()); + let modulus = BN::modulus(); + let t0: U60Repr = (U60Repr::from(modulus.get_limbs())); + let t1: U60Repr = (U60Repr::from(b.get_limbs())); + let b_plus_modulus = BN::from_array(U60Repr::into(t0 + t1)); assert(a.eq(b) == true); assert(a.eq(b_plus_modulus) == true); assert(c.eq(b) == false); @@ -113,7 +99,7 @@ fn test_eq(_: BigNum, __: [Field; N]) where BigNum: BigNumTr // let b = BigNum::__derive_from_seed([1, 2, 3, 4]); // let c = BigNum::__derive_from_seed([2, 2, 3, 4]); -// let modulus: BigNum = Params::get_instance().modulus(); +// let modulus: BigNum = Params::get_params().modulus(); // let t0: U60Repr = (U60Repr::from(modulus.limbs)); // let t1: U60Repr = (U60Repr::from(b.limbs)); // let b_plus_modulus: BigNum = BigNum { limbs: U60Repr::into(t0 + t1) }; @@ -127,19 +113,27 @@ fn test_eq(_: BigNum, __: [Field; N]) where BigNum: BigNumTr // // // 98760 // // // 99689 // // // 929 gates for a 2048 bit mul -fn test_mul(_: BigNum) where BigNum: BigNumTrait + std::ops::Mul + std::ops::Add { - let a: BigNum = BigNum::__derive_from_seed([1, 2, 3, 4]); - let b: BigNum = BigNum::__derive_from_seed([4, 5, 6, 7]); +fn test_mul() where BN: BigNumTrait + std::ops::Mul + std::ops::Add { + let a: BN = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; + let b: BN = unsafe { + BN::__derive_from_seed([4, 5, 6, 7]) + }; let c = (a + b) * (a + b); let d = (a * a) + (b * b) + (a * b) + (a * b); assert(c.eq(d)); } -fn test_add(_: BigNum) where BigNum: BigNumTrait + std::ops::Add + std::ops::Mul + std::cmp::Eq { - let a = BigNum::__derive_from_seed([1, 2, 3, 4]); - let b: BigNum = BigNum::__derive_from_seed([4, 5, 6, 7]); - let one = BigNum::one(); +fn test_add() where BN: BigNumTrait + std::ops::Add + std::ops::Mul + std::cmp::Eq { + let a = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; + let b: BN = unsafe { + BN::__derive_from_seed([4, 5, 6, 7]) + }; + let one = BN::one(); a.validate_in_range(); a.validate_in_field(); b.validate_in_range(); @@ -149,7 +143,7 @@ fn test_add(_: BigNum) where BigNum: BigNumTrait + std::ops::Add + std:: let d = (a + b) * (one + one); assert(c == (d)); let e = one + one; - let limbs = e.get(); + let limbs = e.get_limbs(); let mut first: bool = true; for limb in limbs { if first { @@ -161,80 +155,110 @@ fn test_add(_: BigNum) where BigNum: BigNumTrait + std::ops::Add + std:: } } -fn test_div(_: BigNum) where BigNum: BigNumTrait + std::ops::Div + std::ops::Mul + std::ops::Add + std::cmp::Eq { - let a = BigNum::__derive_from_seed([1, 2, 3, 4]); - let b = BigNum::__derive_from_seed([4, 5, 6, 7]); +fn test_div() where BN: BigNumTrait + std::ops::Div + std::ops::Mul + std::ops::Add + std::cmp::Eq { + let a = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; + let b = unsafe { + BN::__derive_from_seed([4, 5, 6, 7]) + }; let c = a / b; assert((b * c) == (a)); } -fn test_invmod(_: BigNum) where BigNum: BigNumTrait + std::cmp::Eq { - let u = BigNum::__derive_from_seed([1, 2, 3, 4]); +fn test_invmod() where BN: BigNumTrait + std::cmp::Eq { + let u = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; for _ in 0..1 { - let v = u.__invmod(); - let result = u.__mul(v); - let expected = BigNum::one(); + let v = unsafe { + u.__invmod() + }; + let result = unsafe { + u.__mul(v) + }; + let expected = BN::one(); assert(result == expected); } } -fn assert_is_not_equal(_: BigNum) where BigNum: BigNumTrait { - let a = BigNum::__derive_from_seed([1, 2, 3, 4]); - let b = BigNum::__derive_from_seed([4, 5, 6, 7]); +fn assert_is_not_equal() where BN: BigNumTrait { + let a = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; + let b = unsafe { + BN::__derive_from_seed([4, 5, 6, 7]) + }; a.assert_is_not_equal(b); } -fn assert_is_not_equal_fail(_: BigNum) where BigNum: BigNumTrait { - let a = BigNum::__derive_from_seed([1, 2, 3, 4]); - let b = BigNum::__derive_from_seed([1, 2, 3, 4]); +fn assert_is_not_equal_fail() where BN: BigNumTrait { + let a = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; + let b = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; a.assert_is_not_equal(b); } -fn assert_is_not_equal_overloaded_lhs_fail(_: BigNum, __: [Field; N]) where BigNum: BigNumTrait { - let a = BigNum::__derive_from_seed([1, 2, 3, 4]); - let b = BigNum::__derive_from_seed([1, 2, 3, 4]); +fn assert_is_not_equal_overloaded_lhs_fail() where BN: BigNumTrait { + let a = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; + let b = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; - let modulus = BigNum::modulus(); + let modulus = BN::modulus(); - let t0: U60Repr = U60Repr::from(a.get().as_array()); - let t1: U60Repr = U60Repr::from(modulus.get().as_array()); - let a_plus_modulus: BigNum = BigNum::from(U60Repr::into(t0 + t1).as_slice()); + let t0: U60Repr = U60Repr::from(a.get_limbs()); + let t1: U60Repr = U60Repr::from(modulus.get_limbs()); + let a_plus_modulus = BN::from_array(U60Repr::into(t0 + t1)); a_plus_modulus.assert_is_not_equal(b); } -fn assert_is_not_equal_overloaded_rhs_fail(_: BigNum, __: [Field; N]) where BigNum: BigNumTrait { - let a = BigNum::__derive_from_seed([1, 2, 3, 4]); - let b = BigNum::__derive_from_seed([1, 2, 3, 4]); +fn assert_is_not_equal_overloaded_rhs_fail() where BN: BigNumTrait { + let a = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; + let b = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; - let modulus = BigNum::modulus(); + let modulus = BN::modulus(); - let t0: U60Repr = U60Repr::from(b.get().as_array()); - let t1: U60Repr = U60Repr::from(modulus.get().as_array()); - let b_plus_modulus: BigNum = BigNum::from(U60Repr::into(t0 + t1).as_slice()); + let t0: U60Repr = U60Repr::from(b.get_limbs()); + let t1: U60Repr = U60Repr::from(modulus.get_limbs()); + let b_plus_modulus = BN::from_array(U60Repr::into(t0 + t1)); a.assert_is_not_equal(b_plus_modulus); } -fn assert_is_not_equal_overloaded_fail(_: BigNum, __: [Field; N]) where BigNum: BigNumTrait { - let a = BigNum::__derive_from_seed([1, 2, 3, 4]); - let b = BigNum::__derive_from_seed([1, 2, 3, 4]); +fn assert_is_not_equal_overloaded_fail() where BN: BigNumTrait { + let a = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; + let b = unsafe { + BN::__derive_from_seed([1, 2, 3, 4]) + }; - let modulus = BigNum::modulus(); + let modulus = BN::modulus(); - let t0: U60Repr = U60Repr::from(a.get().as_array()); - let t1: U60Repr = U60Repr::from(b.get().as_array()); - let t2: U60Repr = U60Repr::from(modulus.get().as_array()); - let a_plus_modulus: BigNum = BigNum::from(U60Repr::into(t0 + t2).as_slice()); - let b_plus_modulus: BigNum = BigNum::from(U60Repr::into(t1 + t2).as_slice()); + let t0: U60Repr = U60Repr::from(a.get_limbs()); + let t1: U60Repr = U60Repr::from(b.get_limbs()); + let t2: U60Repr = U60Repr::from(modulus.get_limbs()); + let a_plus_modulus: BN = BN::from_array(U60Repr::into(t0 + t2)); + let b_plus_modulus: BN = BN::from_array(U60Repr::into(t1 + t2)); a_plus_modulus.assert_is_not_equal(b_plus_modulus); } #[test] fn test_eq_BN() { - let stub: BigNum<3, BNParams> = BigNum::new(); - test_eq(stub, [0; 3]); + // let stub: BigNum<3, BN254_Fq_Params> = BigNum::new(); + test_eq::<3, BigNum<3, BN254_Fq_Params>>(); } #[test] fn test_add_BN() { @@ -292,7 +316,7 @@ 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 : U60Repr<3, 2> = U60Repr::from(BNParams::get_instance().modulus().get().as_array()); + let p : U60Repr<3, 2> = U60Repr::from(BN254_Fq_Params::get_params().modulus); let two_pow_254_minus_1: U60Repr<3, 2> = U60Repr::from([0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x3fff]); let a: Fq = BigNum { limbs: U60Repr::into(p) }; let b: Fq = BigNum { limbs: U60Repr::into(two_pow_254_minus_1) }; @@ -304,7 +328,7 @@ 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 : U60Repr<3, 2> = U60Repr::from(BNParams::get_instance().modulus().get().as_array()); + let p : U60Repr<3, 2> = U60Repr::from(BN254_Fq_Params::get_params().modulus); let two_pow_254_minus_1: U60Repr<3, 2> = U60Repr::from([0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x3fff]); let one = U60Repr::from([1, 0, 0]); let a: Fq = BigNum { limbs: U60Repr::into(p + one) }; @@ -315,164 +339,143 @@ fn test_add_modulus_overflow() { #[test] fn test_mul_BN() { - let stub: BigNum<3, BNParams> = BigNum::new(); - test_mul(stub); + test_mul::<3, BigNum<3, BN254_Fq_Params>>(); } #[test] fn test_add_BN2() { - let stub: BigNum<3, BNParams> = BigNum::new(); - test_add(stub); + test_add::<3, BigNum<3, BN254_Fq_Params>>(); } #[test] fn test_div_BN() { - let stub: BigNum<3, BNParams> = BigNum::new(); - test_div(stub); + test_div::<3, BigNum<3, BN254_Fq_Params>>(); } #[test] fn test_invmod_BN() { - let stub: BigNum<3, BNParams> = BigNum::new(); - test_invmod(stub); + test_invmod::<3, BigNum<3, BN254_Fq_Params>>(); } #[test] fn test_assert_is_not_equal_BN() { - let stub: BigNum<3, BNParams> = BigNum::new(); - assert_is_not_equal(stub); + assert_is_not_equal::<3, BigNum<3, BN254_Fq_Params>>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_fail_BN() { - let stub: BigNum<3, BNParams> = BigNum::new(); - assert_is_not_equal_fail(stub); + assert_is_not_equal_fail::<3, BigNum<3, BN254_Fq_Params>>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_lhs_fail_BN() { - let stub: BigNum<3, BNParams> = BigNum::new(); - assert_is_not_equal_overloaded_lhs_fail(stub, [0; 3]); + assert_is_not_equal_overloaded_lhs_fail::<3, BigNum<3, BN254_Fq_Params>>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_rhs_fail_BN() { - let stub: BigNum<3, BNParams> = BigNum::new(); - assert_is_not_equal_overloaded_rhs_fail(stub, [0; 3]); + assert_is_not_equal_overloaded_rhs_fail::<3, BigNum<3, BN254_Fq_Params>>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_fail_BN() { - let stub: BigNum<3, BNParams> = BigNum::new(); - assert_is_not_equal_overloaded_fail(stub, [0; 3]); + assert_is_not_equal_overloaded_fail::<3, BigNum<3, BN254_Fq_Params>>(); } #[test] fn test_eq_2048() { - let stub: BigNum<18, Test2048Params> = BigNum::new(); - test_eq(stub, [0; 18]); + test_eq::<18, BigNum<18, Test2048Params>>(); } #[test] fn test_mul_2048() { - let stub: BigNum<18, Test2048Params> = BigNum::new(); - test_mul(stub); + test_mul::<18, BigNum<18, Test2048Params>>(); } #[test] fn test_add_2048() { - let stub: BigNum<18, Test2048Params> = BigNum::new(); - test_add(stub); + test_add::<18, BigNum<18, Test2048Params>>(); } #[test] fn test_assert_is_not_equal_2048() { - let stub: BigNum<18, Test2048Params> = BigNum::new(); - assert_is_not_equal(stub); + assert_is_not_equal::<18, BigNum<18, Test2048Params>>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_fail_2048() { - let stub: BigNum<18, Test2048Params> = BigNum::new(); - assert_is_not_equal_fail(stub); + assert_is_not_equal_fail::<18, BigNum<18, Test2048Params>>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_lhs_fail_2048() { - let stub: BigNum<18, Test2048Params> = BigNum::new(); - assert_is_not_equal_overloaded_lhs_fail(stub, [0; 18]); + assert_is_not_equal_overloaded_lhs_fail::<18, BigNum<18, Test2048Params>>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_rhs_fail_2048() { - let stub: BigNum<18, Test2048Params> = BigNum::new(); - assert_is_not_equal_overloaded_rhs_fail(stub, [0; 18]); + assert_is_not_equal_overloaded_rhs_fail::<18, BigNum<18, Test2048Params>>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_fail_2048() { - let stub: BigNum<18, Test2048Params> = BigNum::new(); - assert_is_not_equal_overloaded_fail(stub, [0; 18]); + assert_is_not_equal_overloaded_fail::<18, BigNum<18, Test2048Params>>(); } #[test] fn test_eq_U256() { - let stub: BigNum<3, U256Params> = BigNum::new(); - test_eq(stub, [0; 3]); + test_eq::<3, BigNum<3, U256Params>>(); } #[test] fn test_mul_U256() { - let stub: BigNum<3, U256Params> = BigNum::new(); - test_mul(stub); + test_mul::<3, BigNum<3, U256Params>>(); } #[test] fn test_add_U256() { - let stub: BigNum<3, U256Params> = BigNum::new(); - test_add(stub); + test_add::<3, BigNum<3, U256Params>>(); } #[test] fn test_assert_is_not_equal_U256() { - let stub: BigNum<3, U256Params> = BigNum::new(); - assert_is_not_equal(stub); + assert_is_not_equal::<3, BigNum<3, U256Params>>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_fail_U256() { - let stub: BigNum<3, U256Params> = BigNum::new(); - assert_is_not_equal_fail(stub); + assert_is_not_equal_fail::<3, BigNum<3, U256Params>>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_lhs_fail_U256() { - let stub: BigNum<3, U256Params> = BigNum::new(); - assert_is_not_equal_overloaded_lhs_fail(stub, [0; 3]); + assert_is_not_equal_overloaded_lhs_fail::<3, BigNum<3, U256Params>>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_rhs_fail_U256() { - let stub: BigNum<3, U256Params> = BigNum::new(); - assert_is_not_equal_overloaded_rhs_fail(stub, [0; 3]); + assert_is_not_equal_overloaded_rhs_fail::<3, BigNum<3, U256Params>>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_fail_U256() { - let stub: BigNum<18, Test2048Params> = BigNum::new(); - assert_is_not_equal_overloaded_fail(stub, [0; 18]); + assert_is_not_equal_overloaded_fail::<3, BigNum<3, U256Params>>(); } type U256 = BigNum<3, U256Params>; #[test] fn test_udiv_mod_U256() { - let a: U256 = BigNum::__derive_from_seed([1, 2, 3, 4]); + let a: U256 = unsafe { + BigNum::__derive_from_seed([1, 2, 3, 4]) + }; let b: U256 = BigNum::from_array([12, 0, 0]); let (q, r) = a.udiv_mod(b); // let qb = q.__mul(b); - let product = q.__mul(b).__add(r); + let product = unsafe { + q.__mul(b).__add(r) + }; assert(product.eq(a)); } @@ -555,7 +558,9 @@ fn test_2048_bit_quadratic_expression() { let a_bn: BigNum<18, Test2048Params> = BigNum { limbs: a }; let b_bn: BigNum<18, Test2048Params> = BigNum { limbs: b }; - let c_bn = a_bn.__mul(b_bn); + let c_bn = unsafe { + a_bn.__mul(b_bn) + }; assert(c_bn.limbs == c_expected); a_bn.validate_in_range(); @@ -584,7 +589,9 @@ fn test_expressions() { 0x0 ] }; - let yy = y.__add(y); + let yy = unsafe { + y.__add(y) + }; assert(yy.limbs == z.limbs); @@ -616,10 +623,18 @@ fn test_expressions() { 0x0000000000000000000000000000000000000000000000000000000000000f93 ] }; - let wx = w.__mul(x); - let uv = uu.__mul(vv); - let y = (uv.__add(wx)).__neg(); - let z = uv.__add(wx); + let wx = unsafe { + w.__mul(x) + }; + let uv = unsafe { + uu.__mul(vv) + }; + let y = unsafe { + (uv.__add(wx)).__neg() + }; + let z = unsafe { + uv.__add(wx) + }; BigNum::evaluate_quadratic_expression( [[uu], [w]], diff --git a/src/constrained_ops.nr b/src/constrained_ops.nr new file mode 100644 index 00000000..3021eb49 --- /dev/null +++ b/src/constrained_ops.nr @@ -0,0 +1,308 @@ +use crate::params::BigNumParams as P; + +use crate::unconstrained_helpers::{ + __validate_in_field_compute_borrow_flags, __validate_gt_remainder, __neg_with_flags, + __add_with_flags, __sub_with_flags +}; +use crate::unconstrained_ops::{__mul, __div, __udiv_mod}; +use crate::expressions::evaluate_quadratic_expression; + +/** +* @brief conditional_select given the value of `predicate` return either `self` (if 0) or `other` (if 1) +* @description should be cheaper than using an IF statement (TODO: check!) +**/ +pub(crate) fn conditional_select(lhs: [Field; N], rhs: [Field; N], predicate: bool) -> [Field; N] { + let mut result: [Field; N] = lhs; + for i in 0..N { + result[i] = (lhs[i] - rhs[i]) * predicate as Field + rhs[i]; + } + result +} + +/** + * @brief Validate self != other + * @details If A == B, then A == B mod N. + * We can efficiently evaluate A == B mod N where N = circuit modulus + * This method is *sound*, but not *complete* (i.e. A != B but A == B mod N) + * However the probability of an honest Prover being unable to satisfy this check is tiny! + * (todo: compute how tiny) + **/ +pub(crate) fn assert_is_not_equal(params: P, lhs: [Field; N], rhs: [Field; N]) { + let mut l: Field = 0; + let mut r: Field = 0; + let mut modulus_mod_n: Field = 0; + let two_pow_120: Field = 0x1000000000000000000000000000000; + let modulus = params.modulus; + for i in 0..N { + l *= two_pow_120; + r *= two_pow_120; + modulus_mod_n *= two_pow_120; + l += lhs[N - i - 1]; + r += rhs[N - i - 1] ; + modulus_mod_n += modulus[N - i - 1]; + } + + // lhs can be either X mod N or P + X mod N + // rhs can be either Y mod N or P + Y mod N + // If lhs - rhs = 0 mod P then lhs - rhs = 0, P or -P mod N + let mut diff = l - r; + let mut target = diff * (diff + modulus_mod_n) * (diff - modulus_mod_n); + assert(target != 0, "asssert_is_not_equal fail"); +} + +pub(crate) fn eq(params: P, lhs: [Field; N], rhs: [Field; N]) -> bool { + let diff = sub(params, lhs, rhs); + // if self == other, possible values of `diff` will be `p` or `0` + // (the subtract operator constrains diff to be < ceil(log(p))) + // TODO: can do this more efficiently via witngen in unconstrained functions? + let mut is_equal_modulus: bool = true; + let mut is_equal_zero: bool = true; + for i in 0..N { + is_equal_modulus = is_equal_modulus & (diff[i] == params.modulus[i]); + is_equal_zero = is_equal_zero & (diff[i] == 0); + } + is_equal_modulus | is_equal_zero +} + +pub(crate) fn validate_in_field(params: P, val: [Field; N]) { + // N.B. need to combine with validate_in_range if `self` limbs have not been range constrained + let mut p_minus_self: [Field; N] = [0; N]; + let modulus: [Field; N] = params.modulus; + for i in 0..N { + p_minus_self[i] = modulus[i] - val[i]; + } + let borrow_flags = unsafe { + __validate_in_field_compute_borrow_flags(params, val) + }; + let two_pow_120: Field = 0x1000000000000000000000000000000; + p_minus_self[0] += borrow_flags[0] as Field * two_pow_120; + for i in 1..N - 1 { + p_minus_self[i] += (borrow_flags[i] as Field * two_pow_120 - borrow_flags[i-1] as Field); + } + p_minus_self[N - 1] -= borrow_flags[N - 2] as Field; + let mut compare = val; + compare = p_minus_self; + validate_in_range(params, compare); +} + +/** +* @brief Validate a BigNum instance is correctly range constrained to contain no more than Params::modulus_bits() +**/ +pub(crate) fn validate_in_range(params: P, limbs: [Field; N]) { + for i in 0..(N - 1) { + limbs[i].assert_max_bit_size(120); + } + let modulus_bits_getter = params.modulus_bits_getter; + let final_limb_bits = modulus_bits_getter() - ((N - 1) * 120); + limbs[N - 1].assert_max_bit_size(final_limb_bits as u32); +} + +/** +* @brief validate quotient produced from `evaluate_quadratic_expression` is well-formed +* @description because the inputs into evaluate_quadratic_expression may cause the quotient to extend beyond `Params::modulus_bits`. +* We allow the quotient to extend 6 bits beyond Params::modulus_bits() +* Why is this? +* several factors: 1. quotient * modulus , limbs cannot overflow field boundary (254 bits) +* 2. in `evaluate_quadratic_expression`, we require that for `expression - quotient * modulus`, +* limbs cannot exceed 246 bits (246 magic number due to a higher number adding extra range check gates) +* because of factor 2 and the fact that modulus limbs are 120 bits, quotient limbs cannot be >126 bits +* +* Note: doesn't this mean that final_limb_bits should be constrained to be 126 bits, not modulus_bits() - ((N - 1) * 120) + 6? +* TODO: think about this more! we want the range constraint we apply to be as small as allowable as this is more efficient +**/ +pub(crate) fn validate_quotient_in_range(params: P, limbs: [Field; N]) { + for i in 0..(N) { + limbs[i].assert_max_bit_size(120); + } + // Note: replace magic number 6 with definition + let modulus_bits_getter = params.modulus_bits_getter; + let final_limb_bits = modulus_bits_getter() - ((N - 1) * 120) + 6; + limbs[N - 1].assert_max_bit_size(final_limb_bits as u32); +} + +// validate that lhs - rhs does not underflow i.e. lhs > rhs +pub(crate) fn validate_gt(params: P, lhs: [Field; N], rhs: [Field; N]) { + // so we do... p - x - r = 0 and there might be borrow flags + + // a - b = r + // p + a - b - r = 0 + let (result, carry_flags, borrow_flags) = unsafe { + __validate_gt_remainder(lhs, rhs) + }; + + validate_in_range(params, result); + + let borrow_shift = 0x1000000000000000000000000000000; + let carry_shift = 0x1000000000000000000000000000000; + + let mut addend: [Field; N] = [0; N]; + let result_limb = lhs[0] - rhs[0] + addend[0] - result[0] - 1 + (borrow_flags[0] as Field * borrow_shift) + - (carry_flags[0] as Field * carry_shift); + assert(result_limb == 0); + for i in 1..N - 1 { + let result_limb = lhs[i] - rhs[i] + addend[i] - result[i] - borrow_flags[i - 1] as Field + + carry_flags[i - 1] as Field + + ((borrow_flags[i] as Field - carry_flags[i] as Field) * borrow_shift); + assert(result_limb == 0); + } + let result_limb = lhs[N - 1] - rhs[N - 1] + addend[N - 1] - result[N - 1] - borrow_flags[N - 2] as Field + + carry_flags[N - 2] as Field; + assert(result_limb == 0); +} + +pub(crate) fn neg(params: P, val: [Field; N]) -> [Field; N] { + // so we do... p - x - r = 0 and there might be borrow flags + let (result, borrow_flags) = unsafe { + __neg_with_flags(params, val) + }; + validate_in_range(params, result); + let modulus = params.modulus; + let borrow_shift = 0x1000000000000000000000000000000; + let result_limb = modulus[0] - val[0] - result[0] + (borrow_flags[0] as Field * borrow_shift); + assert(result_limb == 0); + for i in 1..N - 1 { + let result_limb = modulus[i] - val[i] - result[i] - borrow_flags[i - 1] as Field + + (borrow_flags[i] as Field * borrow_shift); + assert(result_limb == 0); + } + let result_limb = modulus[N - 1] - val[N - 1] - result[N - 1] - borrow_flags[N - 2] as Field; + assert(result_limb == 0); + result +} + +pub(crate) fn add(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { + // so we do... p - x - r = 0 and there might be borrow flags + let (result, carry_flags, borrow_flags, overflow_modulus) = unsafe { + __add_with_flags(params, lhs, rhs) + }; + validate_in_range(params, result); + let modulus = params.modulus; + let borrow_shift = 0x1000000000000000000000000000000; + let carry_shift = 0x1000000000000000000000000000000; + + let mut subtrahend: [Field; N] = [0; N]; + if (overflow_modulus) { + subtrahend = modulus; + } + let result_limb = lhs[0] + rhs[0] - subtrahend[0] - result[0] + (borrow_flags[0] as Field * borrow_shift) + - (carry_flags[0] as Field * carry_shift); + assert(result_limb == 0); + for i in 1..N - 1 { + let result_limb = lhs[i] + rhs[i] - subtrahend[i] - result[i] - borrow_flags[i - 1] as Field + + carry_flags[i - 1] as Field + + ((borrow_flags[i] as Field - carry_flags[i] as Field) * borrow_shift); + assert(result_limb == 0); + } + let result_limb = lhs[N - 1] + rhs[N - 1] - subtrahend[N - 1] - result[N - 1] - borrow_flags[N - 2] as Field + + carry_flags[N - 2] as Field; + assert(result_limb == 0); + result +} + +pub(crate) fn sub(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { + // so we do... p - x - r = 0 and there might be borrow flags + + // a - b = r + // p + a - b - r = 0 + let (result, carry_flags, borrow_flags, underflow) = unsafe { + __sub_with_flags(params, lhs, rhs) + }; + validate_in_range(params, result); + let modulus = params.modulus; + let borrow_shift = 0x1000000000000000000000000000000; + let carry_shift = 0x1000000000000000000000000000000; + + let mut addend: [Field; N] = [0; N]; + if (underflow) { + addend = modulus; + } + let result_limb = lhs[0] - rhs[0] + addend[0] - result[0] + (borrow_flags[0] as Field * borrow_shift) + - (carry_flags[0] as Field * carry_shift); + assert(result_limb == 0); + for i in 1..N - 1 { + let result_limb = lhs[i] - rhs[i] + addend[i] - result[i] - borrow_flags[i - 1] as Field + + carry_flags[i - 1] as Field + + ((borrow_flags[i] as Field - carry_flags[i] as Field) * borrow_shift); + assert(result_limb == 0); + } + let result_limb = lhs[N - 1] - rhs[N - 1] + addend[N - 1] - result[N - 1] - borrow_flags[N - 2] as Field + + carry_flags[N - 2] as Field; + assert(result_limb == 0); + result +} + +// 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 +pub(crate) fn mul(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { + let result = unsafe { + __mul(params, lhs, rhs) + }; + evaluate_quadratic_expression(params, [[lhs]], [[false]], [[rhs]], [[false]], [result], [true]); + result +} + +// Note: this method is expensive! Witness computation is extremely expensive as it requires modular exponentiation +pub(crate) fn div(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { + assert( + params.has_multiplicative_inverse, "BigNum has no multiplicative inverse. Use udiv for unsigned integer division" + ); + let result = unsafe { + __div(params, lhs, rhs) + }; + evaluate_quadratic_expression(params, [[result]], [[false]], [[rhs]], [[false]], [lhs], [true]); + result +} + +/** +* @brief udiv_mod performs integer division between numerator, divisor +* +* i.e. 1. floor(numerator / divisor) = quotient +* 2. numerator % divisor = remainder +* 3. divisor * quotient + remainder = numerator +**/ +pub(crate) fn udiv_mod( + params: P, + numerator: [Field; N], + divisor: [Field; N] +) -> ([Field; N], [Field; N]) { + let (quotient, remainder) = unsafe { + __udiv_mod(numerator, divisor) + }; + + // self / divisor = quotient rounded + // quotient * divisor + remainder - self = 0 + evaluate_quadratic_expression( + params, + [[quotient]], + [[false]], + [[divisor]], + [[false]], + [numerator, remainder], + [true, false] + ); + // we need (remainder < divisor) + // implies (divisor - remainder > 0) + validate_gt(params, divisor, remainder); + (quotient, remainder) +} + +/** +* @brief udiv_mod performs integer division between numerator, divisor +* +* i.e. return param is floor(numerator / divisor) +**/ +pub(crate) fn udiv(params: P, numerator: [Field; N], divisor: [Field; N]) -> [Field; N] { + udiv_mod(params, numerator, divisor).0 +} + +/** +* @brief udiv_mod performs integer modular reduction +* +* i.e. 1. numerator % divisor = return value +**/ +pub(crate) fn umod(params: P, numerator: [Field; N], divisor: [Field; N]) -> [Field; N] { + udiv_mod(params, numerator, divisor).1 +} + diff --git a/src/expressions.nr b/src/expressions.nr new file mode 100644 index 00000000..a2ef3e03 --- /dev/null +++ b/src/expressions.nr @@ -0,0 +1,412 @@ +use crate::utils::split_bits; + +use crate::params::BigNumParams as P; +use crate::constrained_ops::validate_quotient_in_range; +use crate::unconstrained_helpers::__barrett_reduction; + +/** +* @brief Given a degree-2 BigNum expression that is equal to 0 mod p, compute the quotient and borrow flags +* @description The expression is of the form: +* +* \sum_{i=0}^{NUM_PRODUCTS - 1} ((\sum_{j=0}^{LHS_N-1}lhs[i][j]) * (\sum_{j=0}^{RHS_N-1}rhs[i][j])) + \sum_{i=0}^{ADD_N - 1}linear_terms[i] = quotient * modulus +* +* The intent is to capture an arbitrary degree-2 expression within the limitations of Noir (no efficient dynamically-sized vectors) +* +* When performing BigNum arithmetic, we want to represent desired BigNum operations in a way that minimizes the number of modular reductions that are required. +* This can be achieved by minimizing the number of degree-2 relations required. +* +* The borrow flags describe whether individual Field limbs will underflow when evaluating the above relation. +* For example, when computing the product a * b - q * p = 0, it is possible that: +* 1. a[0]*b[0] - p[0]*q[0] = -2^{120} +* 2. a[0]*b[1] + a[1]*b[0] - p[0]*q[1] - p[1]*q[0] = 1 +* In the above example, the value represented by these two limbs is zero despite each limb being nonzero. +* In this case, to correctly constrain the result, we must add (at least) 2^{120} from the first limb and subtract 1 from the second. +* +* @param lhs_terms a 2D array of BigNum +* @param lhs_flags a 2D array of sign flags +* @param rhs_terms a 2D array of BigNum +* @param rhs_flags a 2D array of sign flags +* @param linear_terms an array of BigNum +* @param linear_flags an array of sign flags +**/ +unconstrained fn __compute_quadratic_expression_with_borrow_flags< + let N: u32, + let LHS_N: u32, + let RHS_N: u32, + let NUM_PRODUCTS: u32, + let ADD_N: u32 +>( + params: P, + lhs_terms: [[[Field; N]; LHS_N]; NUM_PRODUCTS], + lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], + rhs_terms: [[[Field; N]; RHS_N]; NUM_PRODUCTS], + rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], + linear_terms: [[Field; N]; ADD_N], + linear_flags: [bool; ADD_N] +) -> ([Field; N], [Field; N], [Field; 2 * N]) { + // TODO, validate we do not overflow N2 when multiplying and N when adding + + let mut mulout_p = __compute_quadratic_expression_product( + params, + lhs_terms, + lhs_flags, + rhs_terms, + rhs_flags, + linear_terms, + linear_flags + ); + let mut mulout_n: [Field; 2 * N] = [0; 2 * N]; + let mut relation_result: [Field; 2 * N] = split_bits::__normalize_limbs(mulout_p, 2 * N); + + let modulus: [Field; N] = params.modulus; + let modulus_bits_getter = params.modulus_bits_getter; + let (quotient, remainder) = __barrett_reduction( + relation_result, + params.redc_param, + modulus_bits_getter(), + modulus, + params.modulus_u60_x4 + ); + assert(remainder == [0; N]); + + for i in 0..N { + for j in 0..N { + mulout_n[i + j] += quotient[i] * modulus[j]; + } + } + + // compute borrow flags from mulout_p and mulout_n + let mut borrow_flags: [Field; 2 * N] = [0; 2 * N]; + let borrow_shift: Field = 0x40000000000000000000000000000000000000000000000000000000000000; // 2^{246} + let borrow_carry: Field = 0x40000000000000000000000000000000; // 2^{246 - 120} = 2^{126} + let two_pow_120: Field = 0x1000000000000000000000000000000; + let downshift: Field = 1 / two_pow_120; + + // determine whether we need to borrow from more significant limbs. + // initial limb is "simple" comparison operation + // TODO: check how expensive `lt` operator is w.r.t. witness generation + borrow_flags[0] = mulout_p[0].lt(mulout_n[0]) as Field; + // we have 2N - 2 borrow flags. The number of limbs from our product computation is 2N - 1 + // and there is nothing to borrow against for the final limb. + let mut hi_bits = (mulout_p[0] - mulout_n[0] + (borrow_flags[0] * borrow_shift)) * downshift; + for i in 1..(N + N - 2) { + // compute the contribution from limb `i-1` that gets added into limb `i`, and add into limb `i` + // let hi_bits = (mulout_p.get(i - 1) - mulout_n.get(i - 1) + (borrow_flags.get(i - 1) * borrow_shift)) + // * downshift; + mulout_p[i] += hi_bits; + + // determine whether negative limb values are greater than positive limb values + let underflow: Field = mulout_p[i].lt(mulout_n[i] + (borrow_flags[i - 1] * borrow_carry)) as Field; + borrow_flags[i] = underflow; + + hi_bits = (mulout_p[i] - mulout_n[i] + (borrow_flags[i] * borrow_shift) + - (borrow_flags[i - 1] * borrow_carry)) * downshift; + } + + (quotient, remainder, borrow_flags) +} + +/** +* @brief Computes the result of a linear combination of (possibly negative) BigNum values (unconstrained) +**/ +// NOTE: modulus2 is structured such that all limbs will be greater than 0, even when subtracting. +// To do this, when computing `p - x`, we ensure that each limb in `p` is greater than each limb in `x`. +// We know that, for a valid bignum element, the limbs in `x` will be <2^{120} +// Therefore each of the limbs in `p` (except the most significant) will borrow 2^{120} from the more significant limb. +// Finally, to ensure we do not underflow in the most significant limb, we use `2p` instead of `p` +unconstrained fn __add_linear_expression( + params: P, + x: [[Field; N]; M], + flags: [bool; M] +) -> ([Field; N]) { + // TODO, validate we do not overflow N2 when multiplying and N when adding + let mut sum: [Field; N] = [0; N]; + // TODO: ugly! Will fail if input array is empty + let modulus2: [Field; N] = params.double_modulus; + for i in 0..M { + if (flags[i]) { + for j in 0..N { + sum[j] = sum[j] + modulus2[j] - x[i][j]; + assert(x[i][j].lt(modulus2[j])); + } + } else { + for j in 0..N { + sum[j] = sum[j] + x[i][j]; + } + } + } + // problem if we normalize when used in computing quotient + sum +} + +/** +* @brief computes the limb products of a quadratic expression +* @details see __compute_quadratic_expression_with_borrow_flags for full description +**/ +unconstrained fn __compute_quadratic_expression_product< + let N: u32, + let LHS_N: u32, + let RHS_N: u32, + let NUM_PRODUCTS: u32, + let ADD_N: u32 +>( + params: P, + lhs_terms: [[[Field; N]; LHS_N]; NUM_PRODUCTS], + lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], + rhs_terms: [[[Field; N]; RHS_N]; NUM_PRODUCTS], + rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], + linear_terms: [[Field; N]; ADD_N], + linear_flags: [bool; ADD_N] +) -> [Field; 2 * N] { + // TODO, validate we do not overflow N2 when multiplying and N when adding + let mut lhs: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS]; + let mut rhs: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS]; + let mut add: [Field; N] = [0; N]; + + for i in 0..NUM_PRODUCTS { + lhs[i] = __add_linear_expression(params, lhs_terms[i], lhs_flags[i]); + rhs[i] = __add_linear_expression(params, rhs_terms[i], rhs_flags[i]); + } + + let add: [Field; N] = __add_linear_expression(params, linear_terms, linear_flags); + + let mut mulout: [Field; 2 * N] = [0; 2 * N]; + + for i in 0..N { + for j in 0..N { + for k in 0..NUM_PRODUCTS { + mulout[i + j] += (lhs[k][i] * rhs[k][j]); + } + } + mulout[i] += add[i]; + } + mulout +} + +/** +* @brief computes the quotient/remainder of a quadratic expression +* @details see __compute_quadratic_expression_with_borrow_flags for full description +**/ +unconstrained pub(crate) fn __compute_quadratic_expression< + let N: u32, + let LHS_N: u32, + let RHS_N: u32, + let NUM_PRODUCTS: u32, + let ADD_N: u32 +>( + params: P, + lhs_terms: [[[Field; N]; LHS_N]; NUM_PRODUCTS], + lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], + rhs_terms: [[[Field; N]; RHS_N]; NUM_PRODUCTS], + rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], + linear_terms: [[Field; N]; ADD_N], + linear_flags: [bool; ADD_N] +) -> ([Field; N], [Field; N]) { + // TODO, validate we do not overflow N2 when multiplying and N when adding + let mulout = __compute_quadratic_expression_product( + params, + lhs_terms, + lhs_flags, + rhs_terms, + rhs_flags, + linear_terms, + linear_flags + ); + let mut relation_result: [Field; 2 * N] = split_bits::__normalize_limbs(mulout, 2 * N); + + // TODO: ugly! Will fail if input slice is empty + let modulus_bits_getter = params.modulus_bits_getter; + let k = modulus_bits_getter(); + + let (quotient, remainder) = __barrett_reduction( + relation_result, + params.redc_param, + k, + params.modulus, + params.modulus_u60_x4 + ); + + let mut q = quotient; + let mut r = remainder; + (q, r) +} + +/** +* @brief Constrain a degree-2 BigNum expression to be equal to 0 modulo self.modulus +* @description The expression is of the form (when evaluated as an integer relation): +* +* \sum_{i=0}^{NUM_PRODUCTS - 1} ((\sum_{j=0}^{LHS_N-1}lhs[i][j]) * (\sum_{j=0}^{RHS_N-1}rhs[i][j])) + \sum_{i=0}^{ADD_N - 1}linear_terms[i] - quotient * modulus = 0 +* +* The intent is to capture an arbitrary degree-2 expression within the limitations of Noir (no efficient dynamically-sized vectors) +* +* Note: this method requires the remainder term of the expression to be ZERO +* When performing BigNum arithmetic, we want to represent desired BigNum operations in a way that minimizes the number of modular reductions that are required. +* This can be achieved by minimizing the number of degree-2 relations required. +* +* The expensive parts of this algorithm are the following: +* 1. evaluating the limb products required to compute `lhs * rhs` +* 2. applying range constraints to validate the result is 0 +* +* Range constraints are needed for the following reason: +* When evaluating the above expression over N-limb BigNum objects, the result will consist of 2N - 1 limbs. +* Each limb will be in the range [0, ..., 2^{240 + twiddle_factor} - 1] (twiddle_factor needs to be less than 6). +* Because of the subtractions, the limbs may underflow and represent NEGATIVE values. +* To account for this, we allow the Prover to borrow values from more significant limbs and add them into less significant limbs +* (explicitly, we can borrow 2^{126} from limb `i + 1` to add `2^{246}` into `i`). +* To ensure this has been done correctly, we validate that the borrow-adjusted limbs are all-zero for the first 120 bits. +* We do *this* by multiplying the borrow-adjusted limbs by 1 / 2^{120} modulo CircutModulus, and we validate the result is in the range [0, ..., 2^{126} - 1]. +* TODO: explain why this check works. It's statistically sound but not perfectly sound. Chance of the check failing is ~1 in 2^{120} +* I believe this is the most efficient way of performing the zero-check for this relation as it only requires `2N - 2` 126-bit range checks. +* TODO: explain why we apply a 126-bit range check, this feels like a magic number +* (it is. we could go higher, up to the number of bits in the CircuitModulus - 121, but 126 *should be* sufficient and is much cheaper) +* TODO: apply checks in this method to validate twiddle_factor does not exceed 6 +* +* @param lhs_terms a 2D array of BigNum +* @param lhs_flags a 2D array of sign flags +* @param rhs_terms a 2D array of BigNum +* @param rhs_flags a 2D array of sign flags +* @param linear_terms an array of BigNum +* @param linear_flags an array of sign flags +**/ +pub(crate) fn evaluate_quadratic_expression< + let N: u32, + let LHS_N: u32, + let RHS_N: u32, + let NUM_PRODUCTS: u32, + let ADD_N: u32 +>( + params: P, + lhs_terms: [[[Field; N]; LHS_N]; NUM_PRODUCTS], + lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], + rhs_terms: [[[Field; N]; RHS_N]; NUM_PRODUCTS], + rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], + linear_terms: [[Field; N]; ADD_N], + linear_flags: [bool; ADD_N] +) { + // use an unconstrained function to compute the value of the quotient + let (quotient, _, borrow_flags): ([Field; N], [Field; N], [Field; 2 * N]) = unsafe { + __compute_quadratic_expression_with_borrow_flags( + params, + lhs_terms, + lhs_flags, + rhs_terms, + rhs_flags, + linear_terms, + linear_flags + ) + }; + // constrain the quotient to be in the range [0, ..., 2^{m} - 1], where `m` is log2(modulus) rounded up. + // Additionally, validate quotient limbs are also in the range [0, ..., 2^{120} - 1] + validate_quotient_in_range(params, quotient); + // TODO, validate we do not overflow N2 when multiplying and N when adding + // (should be a compile-time check...unconstrained function?) + + // Compute the linear sums that represent lhs_1, rhs_1, lhs_2, rhs_2, add + let mut t0: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS]; + let mut t1: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS]; + let mut t4: [Field; N] = [0; N]; + + // TODO: this is super nasty as it requires a multiplication + let double_modulus: [Field; N] = params.double_modulus; + for k in 0..NUM_PRODUCTS { + for i in 0..N { + for j in 0..LHS_N { + // note: if is_negative is not known at comptime this is very expensive + if (lhs_flags[k][j]) { + t0[k][i] -= lhs_terms[k][j][i]; + t0[k][i] += double_modulus[i]; + } else { + t0[k][i] += lhs_terms[k][j][i]; + } + } + for j in 0..RHS_N { + if (rhs_flags[k][j]) { + t1[k][i] -= rhs_terms[k][j][i]; + t1[k][i] += double_modulus[i]; + } else { + t1[k][i] += rhs_terms[k][j][i]; + } + } + } + } + for i in 0..N { + for j in 0..ADD_N { + if (linear_flags[j]) { + t4[i] -= linear_terms[j][i]; + t4[i] += double_modulus[i]; + } else { + t4[i] += linear_terms[j][i]; + } + } + } + + // We want to evaluate that t0 * t1 + t2 * t3 + t4 - Quotient * Modulus = 0, evaluated over the integers + // For this we need to be able to borrow values from more-significant limbs into less-significant limbs, + // so that we can ensure that no limbs will underflow for an honest Prover + let mut product_limbs: [Field; 2 * N] = [0; 2 * N]; + + // Compute the product t0 * t1 + t2 * t3 + t4 - Quotient * Modulus + // TODO: this is super nasty as it requires a multiplication + for i in 0..N { + for j in 0..N { + for k in 0..NUM_PRODUCTS { + if k == 0 { + let new_term = t0[k][i] * t1[k][j] - quotient[i] * params.modulus[j]; + std::as_witness(new_term); // width-4 optimization (n.b. might not be optimal if t2, t3 input arrays are nonzero) + product_limbs[i + j] += new_term; + } else { + product_limbs[i + j] += t0[k][i] * t1[k][j]; + } + } + if (NUM_PRODUCTS == 0) { + product_limbs[i + j] -= quotient[i] * params.modulus[j]; + } + } + product_limbs[i] += t4[i]; + } + + // each limb product represents the sum of 120-bit products. + // by setting the borrow value to 2^246 we are restricting this method's completeness to expressions + // where no more than 64 limb products are summed together. + // TODO: check in unconstrained function that this condition is satisfied + // TODO: define trade-offs regarding the value of borrow_shift + // (the larger the value, the greater the range check that is required on product_limbs) + // (126-bit range check is a sweet spot for the barretenberg backend as it decomposes into 9 14-bit range checks) + // (the barretenberg backend can evaluate these in 5.25 gates. 127 bits costs 6.5 gates) + let borrow_shift: Field = 0x40000000000000000000000000000000000000000000000000000000000000; // 2^{246} + let borrow_carry: Field = 0x40000000000000000000000000000000; // 2^{246 - 120} = 2^{126} + + // N.B. borrow_flags is `Field` type because making it `bool` would apply boolean constraints to all `N2` array entries. + // We only use `N2 - 2` borrow flags so applying 1-bit range checks on the array elements we use is more efficient. + // TODO: Once it is possible to perform arithmetic on generics we can use `borrow_flags: [bool;N+N-2]` to avoid this issue + borrow_flags[0].assert_max_bit_size(1); + product_limbs[0] += borrow_flags[0] * borrow_shift; + for i in 1..(N + N - 2) { + borrow_flags[i].assert_max_bit_size(1); + product_limbs[i] += + (borrow_flags[i] * borrow_shift - borrow_flags[i - 1] * borrow_carry); + } + product_limbs[N + N - 2] -= borrow_flags[N + N - 3] * borrow_carry; + + // Final step: Validate `product_limbs` represents the integer value `0` + // Each element `i` in `product_limbs` overlaps in bitrange with element `i+1`, EXCEPT for the low 120 bits + // i.e. we need to do the following for each limb `i`: + // 1. validate the limb's low-120 bits equals zero + // 2. compute the limb "carry" by right-shifting by 2^{120} + // 3. add the carry into limb `i+1` + // We can efficiently do all of the above by multiplying the limb by 2^{-120} and constraining the result to be <2^{126} + // (if the low 120 bits are nonzero the result will underflow and product a large value that cannot be range constrained) + // (the probability of an underflow value satisfying a 126-bit range constraint is approx. 2^{k - 126}, + // where k is the number of bits in the prime field) + // We then add the result into the next limb and repeat. + let hi_shift: Field = 0x1000000000000000000000000000000; + let hi_downshift: Field = 1 / hi_shift; + for i in 0..N + N - 2 { + product_limbs[i] *= hi_downshift; + std::as_witness(product_limbs[i]); + product_limbs[i].assert_max_bit_size(126); // N.B. is this sufficient? going beyond 126 costs us 1 gate per limb + product_limbs[i + 1] += product_limbs[i]; + } + // the most significant limb has no limb to "carry" values into - the entire limb must equal zero + assert(product_limbs[N + N - 2] == 0); +} diff --git a/src/fields/U1024.nr b/src/fields/U1024.nr index a024bbbe..aedfd269 100644 --- a/src/fields/U1024.nr +++ b/src/fields/U1024.nr @@ -1,41 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U1024Params {} -impl RuntimeBigNumParamsTrait<9> for U1024Params { - fn modulus_bits() -> u32 { - 1025 - } - fn has_multiplicative_inverse() -> bool { - false - } -} +global U1024_PARAMS: BigNumParams<9> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 1025, + modulus: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000000000000000 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffffffffffff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x040000000000000000 + ] +}; + +struct U1024Params {} + impl BigNumParamsTrait<9> for U1024Params { - fn get_instance() -> BigNumInstance<9, Self> { - U1024_Instance - } - fn modulus_bits() -> u32 { - 1025 - } - fn has_multiplicative_inverse() -> bool { - false + fn get_params() -> BigNumParams<9> { + U1024_PARAMS } } -global U1024_Instance: BigNumInstance<9, U1024Params> = BigNumInstance { - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000000000000000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffffffffffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x040000000000000000 - ] -}; diff --git a/src/fields/U2048.nr b/src/fields/U2048.nr index 3394e44f..a677b974 100644 --- a/src/fields/U2048.nr +++ b/src/fields/U2048.nr @@ -1,41 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U2048Params {} -impl RuntimeBigNumParamsTrait<18> for U2048Params { - fn modulus_bits() -> u32 { - 2049 - } - fn has_multiplicative_inverse() -> bool { - false - } -} +global U2048_PARAMS: BigNumParams<18> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 2049, + modulus: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0400 + ] +}; + +struct U2048Params {} + impl BigNumParamsTrait<18> for U2048Params { - fn get_instance() -> BigNumInstance<18, Self> { - U2048_Instance - } - fn modulus_bits() -> u32 { - 2049 - } - fn has_multiplicative_inverse() -> bool { - false + fn get_params() -> BigNumParams<18> { + U2048_PARAMS } } -global U2048_Instance: BigNumInstance<18, U2048Params> = BigNumInstance { - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0400 - ] -}; diff --git a/src/fields/U256.nr b/src/fields/U256.nr index 258ef2e5..10951b32 100644 --- a/src/fields/U256.nr +++ b/src/fields/U256.nr @@ -1,40 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U256Params {} -impl RuntimeBigNumParamsTrait<3> for U256Params { - fn modulus_bits() -> u32 { - 257 - } - fn has_multiplicative_inverse() -> bool { - false - } -} +global U256_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 257, + modulus: [ + 0x00, 0x00, 0x010000 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0x01ffff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x040000 + ] +}; + +pub struct U256Params {} + impl BigNumParamsTrait<3> for U256Params { - fn get_instance() -> BigNumInstance<3, Self> { - U256_Instance - } - fn modulus_bits() -> u32 { - 257 - } - fn has_multiplicative_inverse() -> bool { - false + fn get_params() -> BigNumParams<3> { + U256_PARAMS } } -global U256_Instance: BigNumInstance<3, U256Params> = BigNumInstance { - modulus: [ - 0x00, 0x00, 0x010000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0x01ffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x040000 - ] -}; + diff --git a/src/fields/U384.nr b/src/fields/U384.nr index b827d680..59a47181 100644 --- a/src/fields/U384.nr +++ b/src/fields/U384.nr @@ -1,41 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U384_Params {} -impl RuntimeBigNumParamsTrait<4> for U384_Params { - fn modulus_bits() -> u32 { - 385 - } - fn has_multiplicative_inverse() -> bool { - false - } -} +global U384_PARAMS: BigNumParams<4> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 385, + modulus: [ + 0x00, 0x00, 0x00, 0x01000000 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x00, 0x04000000 + ] +}; + +struct U384_Params {} + impl BigNumParamsTrait<4> for U384_Params { - fn get_instance() -> BigNumInstance<4, Self> { - U384_Instance - } - fn modulus_bits() -> u32 { - 385 - } - fn has_multiplicative_inverse() -> bool { - false + fn get_params() -> BigNumParams<4> { + U384_PARAMS } } -global U384_Instance: BigNumInstance<4, U384_Params> = BigNumInstance { - modulus: [ - 0x00, 0x00, 0x00, 0x01000000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x04000000 - ] -}; diff --git a/src/fields/U4096.nr b/src/fields/U4096.nr index 806e2a5d..88b84fc2 100644 --- a/src/fields/U4096.nr +++ b/src/fields/U4096.nr @@ -1,41 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U4096Params {} -impl RuntimeBigNumParamsTrait<35> for U4096Params { - fn modulus_bits() -> u32 { - 4097 - } - fn has_multiplicative_inverse() -> bool { - false - } -} +global U4096_PARAMS: BigNumParams<35> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 4097, + modulus: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x040000 + ] +}; + +struct U4096Params {} + impl BigNumParamsTrait<35> for U4096Params { - fn get_instance() -> BigNumInstance<35, Self> { - U4096_Instance - } - fn modulus_bits() -> u32 { - 4097 - } - fn has_multiplicative_inverse() -> bool { - false + fn get_params() -> BigNumParams<35> { + U4096_PARAMS } } -global U4096_Instance: BigNumInstance<35, U4096Params> = BigNumInstance { - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x040000 - ] -}; diff --git a/src/fields/U512.nr b/src/fields/U512.nr index b49c20bc..4aa93f3c 100644 --- a/src/fields/U512.nr +++ b/src/fields/U512.nr @@ -1,32 +1,10 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -// a / b = c - -// b * c + (rem < modulus) = a -pub struct U512Params {} -impl RuntimeBigNumParamsTrait<5> for U512Params { - fn modulus_bits() -> u32 { - 513 - } - fn has_multiplicative_inverse() -> bool { - false - } -} -impl BigNumParamsTrait<5> for U512Params { - fn get_instance() -> BigNumInstance<5, Self> { - U512_Instance - } - fn modulus_bits() -> u32 { - 513 - } - fn has_multiplicative_inverse() -> bool { - false - } -} -global U512_Instance: BigNumInstance<5, U512Params> = BigNumInstance { +global U512_PARAMS: BigNumParams<5> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 513, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x0100000000 ], @@ -41,3 +19,12 @@ global U512_Instance: BigNumInstance<5, U512Params> = BigNumInstance { 0x00, 0x00, 0x00, 0x00, 0x0400000000 ] }; + +struct U512Params {} + +impl BigNumParamsTrait<5> for U512Params { + fn get_params() -> BigNumParams<5> { + U512_PARAMS + } +} + diff --git a/src/fields/U768.nr b/src/fields/U768.nr index b5a41ec7..98223e1a 100644 --- a/src/fields/U768.nr +++ b/src/fields/U768.nr @@ -1,41 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U768Params {} -impl RuntimeBigNumParamsTrait<13> for U768Params { - fn modulus_bits() -> u32 { - 1537 - } - fn has_multiplicative_inverse() -> bool { - false - } -} +global U768_PARAMS: BigNumParams<13> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 1537, + modulus: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000000000000000000000 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffffffffffffffffffff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1000000000]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1000000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04000000000000000000000000 + ] +}; + +struct U768Params {} + impl BigNumParamsTrait<13> for U768Params { - fn get_instance() -> BigNumInstance<13, Self> { - U768_Instance - } - fn modulus_bits() -> u32 { - 1537 - } - fn has_multiplicative_inverse() -> bool { - false + fn get_params() -> BigNumParams<13> { + U768_PARAMS } } -global U768_Instance: BigNumInstance<13, U768Params> = BigNumInstance { - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000000000000000000000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffffffffffffffffffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1000000000]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1000000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04000000000000000000000000 - ] -}; diff --git a/src/fields/U8192.nr b/src/fields/U8192.nr index 089e16bb..5c4951b2 100644 --- a/src/fields/U8192.nr +++ b/src/fields/U8192.nr @@ -1,41 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U8192Params {} -impl RuntimeBigNumParamsTrait<69> for U8192Params { - fn modulus_bits() -> u32 { - 8193 - } - fn has_multiplicative_inverse() -> bool { - false - } -} +global U8192_PARAMS: BigNumParams<69> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 8193, + modulus: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0400000000 + ] +}; + +struct U8192Params {} + impl BigNumParamsTrait<69> for U8192Params { - fn get_instance() -> BigNumInstance<69, Self> { - U8192_Instance - } - fn modulus_bits() -> u32 { - 8193 - } - fn has_multiplicative_inverse() -> bool { - false + fn get_params() -> BigNumParams<69> { + U8192_PARAMS } } -global U8192_Instance: BigNumInstance<69, U8192Params> = BigNumInstance { - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0400000000 - ] -}; diff --git a/src/fields/bls12_377Fq.nr b/src/fields/bls12_377Fq.nr index 7c13ca1b..7d876a83 100644 --- a/src/fields/bls12_377Fq.nr +++ b/src/fields/bls12_377Fq.nr @@ -16,38 +16,33 @@ //! * G1 curve equation: y^2 = x^3 + 1 //! * G2 curve equation: y^2 = x^3 + B, where //! * B = Fq2(0, 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906) -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; +global BLS12_377_Fq_PARAMS: BigNumParams<4> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 377, + modulus: [ + 0x0b5d44300000008508c00000000001, 0xd9f300f5138f1ef3622fba09480017, 0x4617c510eac63b05c06ca1493b1a22, 0x01ae3a + ], + double_modulus: [ + 0x0116ba88600000010a11800000000002, 0x01b3e601ea271e3de6c45f741290002d, 0x018c2f8a21d58c760b80d94292763444, 0x035c73 + ], + modulus_u60: U60Repr { limbs: [ + 0x0508c00000000001, 0xb5d44300000008, 0x03622fba09480017, 0x0d9f300f5138f1ef, 0x05c06ca1493b1a22, 0x04617c510eac63b0, 0x01ae3a, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0508c00000000001, 0xb5d44300000008, 0x03622fba09480017, 0x0d9f300f5138f1ef, 0x05c06ca1493b1a22, 0x04617c510eac63b0, 0x01ae3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xed687789c42a591f9fd58c5e4daffc, 0xd0de6776b1a06af2d488d85a6d02d0, 0x8d0cc4060e976c3ca0582ef4f73bba, 0x026150 + ] +}; + pub struct BLS12_377_Fq_Params {} -impl RuntimeBigNumParamsTrait<4> for BLS12_377_Fq_Params { - fn modulus_bits() -> u32 { - 377 - } -} + impl BigNumParamsTrait<4> for BLS12_377_Fq_Params { - fn get_instance() -> BigNumInstance<4, Self> { - BLS12_377_Fq_Instance - } - fn modulus_bits() -> u32 { - 377 + fn get_params() -> BigNumParams<4> { + BLS12_377_Fq_PARAMS } } -global BLS12_377_Fq_Instance: BigNumInstance<4, BLS12_377_Fq_Params> = BigNumInstance { - modulus: [ - 0x0b5d44300000008508c00000000001, 0xd9f300f5138f1ef3622fba09480017, 0x4617c510eac63b05c06ca1493b1a22, 0x01ae3a - ], - double_modulus: [ - 0x0116ba88600000010a11800000000002, 0x01b3e601ea271e3de6c45f741290002d, 0x018c2f8a21d58c760b80d94292763444, 0x035c73 - ], - modulus_u60: U60Repr { limbs: [ - 0x0508c00000000001, 0xb5d44300000008, 0x03622fba09480017, 0x0d9f300f5138f1ef, 0x05c06ca1493b1a22, 0x04617c510eac63b0, 0x01ae3a, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0508c00000000001, 0xb5d44300000008, 0x03622fba09480017, 0x0d9f300f5138f1ef, 0x05c06ca1493b1a22, 0x04617c510eac63b0, 0x01ae3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xed687789c42a591f9fd58c5e4daffc, 0xd0de6776b1a06af2d488d85a6d02d0, 0x8d0cc4060e976c3ca0582ef4f73bba, 0x026150 - ] -}; diff --git a/src/fields/bls12_377Fr.nr b/src/fields/bls12_377Fr.nr index c44c18cf..572e9358 100644 --- a/src/fields/bls12_377Fr.nr +++ b/src/fields/bls12_377Fr.nr @@ -16,38 +16,33 @@ //! * G1 curve equation: y^2 = x^3 + 1 //! * G2 curve equation: y^2 = x^3 + B, where //! * B = Fq2(0, 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906) -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct BLS12_377_Fr_Params {} -impl RuntimeBigNumParamsTrait<3> for BLS12_377_Fr_Params { - fn modulus_bits() -> u32 { - 253 - } -} +global BLS12_377_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 253, + modulus: [ + 0xaa76fed00000010a11800000000001, 0x655e9a2ca55660b44d1e5c37b00159, 0x12ab + ], + double_modulus: [ + 0x0154edfda00000021423000000000002, 0x01cabd34594aacc1689a3cb86f6002b2, 0x2555 + ], + modulus_u60: U60Repr { limbs: [ + 0x0a11800000000001, 0x0aa76fed00000010, 0x044d1e5c37b00159, 0x0655e9a2ca55660b, 0x12ab, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0a11800000000001, 0x0aa76fed00000010, 0x044d1e5c37b00159, 0x0655e9a2ca55660b, 0x12ab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x0a180b8d69e258f5204c21151e79ea, 0x491ec40b2c9ee4e51e49faa80548fd, 0x36d9 + ] +}; + +struct BLS12_377_Fr_Params {} + impl BigNumParamsTrait<3> for BLS12_377_Fr_Params { - fn get_instance() -> BigNumInstance<3, Self> { - BLS12_377_Fr_Instance - } - fn modulus_bits() -> u32 { - 253 + fn get_params() -> BigNumParams<3> { + BLS12_377_Fr_PARAMS } } -global BLS12_377_Fr_Instance: BigNumInstance<3, BLS12_377_Fr_Params> = BigNumInstance { - modulus: [ - 0xaa76fed00000010a11800000000001, 0x655e9a2ca55660b44d1e5c37b00159, 0x12ab - ], - double_modulus: [ - 0x0154edfda00000021423000000000002, 0x01cabd34594aacc1689a3cb86f6002b2, 0x2555 - ], - modulus_u60: U60Repr { limbs: [ - 0x0a11800000000001, 0x0aa76fed00000010, 0x044d1e5c37b00159, 0x0655e9a2ca55660b, 0x12ab, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0a11800000000001, 0x0aa76fed00000010, 0x044d1e5c37b00159, 0x0655e9a2ca55660b, 0x12ab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x0a180b8d69e258f5204c21151e79ea, 0x491ec40b2c9ee4e51e49faa80548fd, 0x36d9 - ] -}; diff --git a/src/fields/bls12_381Fq.nr b/src/fields/bls12_381Fq.nr index f788c44f..fea750f9 100644 --- a/src/fields/bls12_381Fq.nr +++ b/src/fields/bls12_381Fq.nr @@ -14,38 +14,33 @@ //! * valuation(r - 1, 2) = 32 //! * G1 curve equation: y^2 = x^3 + 4 //! * G2 curve equation: y^2 = x^3 + Fq2(4, 4) -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct BLS12_381_Fq_Params {} -impl RuntimeBigNumParamsTrait<4> for BLS12_381_Fq_Params { - fn modulus_bits() -> u32 { - 381 - } -} +global BLS12_381_Fq_PARAMS: BigNumParams<4> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 381, + modulus: [ + 0xabfffeb153ffffb9feffffffffaaab, 0x4b84f38512bf6730d2a0f6b0f6241e, 0xea397fe69a4b1ba7b6434bacd76477, 0x1a0111 + ], + double_modulus: [ + 0x0157fffd62a7ffff73fdffffffff5556, 0x019709e70a257ece61a541ed61ec483c, 0x01d472ffcd3496374f6c869759aec8ed, 0x340222 + ], + modulus_u60: U60Repr { limbs: [ + 0x09feffffffffaaab, 0x0abfffeb153ffffb, 0xd2a0f6b0f6241e, 0x04b84f38512bf673, 0x07b6434bacd76477, 0x0ea397fe69a4b1ba, 0x1a0111, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x09feffffffffaaab, 0x0abfffeb153ffffb, 0xd2a0f6b0f6241e, 0x04b84f38512bf673, 0x07b6434bacd76477, 0x0ea397fe69a4b1ba, 0x1a0111, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x65c59e8163c701ec4f881fd59646e8, 0x09d07fda82a52f7d1dc780a19de74e, 0x4bcf32791738a0406c331e9ae8a46e, 0x2760d7 + ] +}; + +struct BLS12_381_Fq_Params {} + impl BigNumParamsTrait<4> for BLS12_381_Fq_Params { - fn get_instance() -> BigNumInstance<4, Self> { - BLS12_381_Fq_Instance - } - fn modulus_bits() -> u32 { - 381 + fn get_params() -> BigNumParams<4> { + BLS12_381_Fq_PARAMS } } -global BLS12_381_Fq_Instance: BigNumInstance<4, BLS12_381_Fq_Params> = BigNumInstance { - modulus: [ - 0xabfffeb153ffffb9feffffffffaaab, 0x4b84f38512bf6730d2a0f6b0f6241e, 0xea397fe69a4b1ba7b6434bacd76477, 0x1a0111 - ], - double_modulus: [ - 0x0157fffd62a7ffff73fdffffffff5556, 0x019709e70a257ece61a541ed61ec483c, 0x01d472ffcd3496374f6c869759aec8ed, 0x340222 - ], - modulus_u60: U60Repr { limbs: [ - 0x09feffffffffaaab, 0x0abfffeb153ffffb, 0xd2a0f6b0f6241e, 0x04b84f38512bf673, 0x07b6434bacd76477, 0x0ea397fe69a4b1ba, 0x1a0111, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x09feffffffffaaab, 0x0abfffeb153ffffb, 0xd2a0f6b0f6241e, 0x04b84f38512bf673, 0x07b6434bacd76477, 0x0ea397fe69a4b1ba, 0x1a0111, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x65c59e8163c701ec4f881fd59646e8, 0x09d07fda82a52f7d1dc780a19de74e, 0x4bcf32791738a0406c331e9ae8a46e, 0x2760d7 - ] -}; diff --git a/src/fields/bls12_381Fr.nr b/src/fields/bls12_381Fr.nr index 89b4a1dd..6f968dd8 100644 --- a/src/fields/bls12_381Fr.nr +++ b/src/fields/bls12_381Fr.nr @@ -14,37 +14,32 @@ //! * valuation(r - 1, 2) = 32 //! * G1 curve equation: y^2 = x^3 + 4 //! * G2 curve equation: y^2 = x^3 + Fq2(4, 4) -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct BLS12_381_Fr_Params {} -impl RuntimeBigNumParamsTrait<3> for BLS12_381_Fr_Params { - fn modulus_bits() -> u32 { - 255 - } -} +global BLS12_381_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 255, + modulus: [ + 0xbda402fffe5bfeffffffff00000001, 0xa753299d7d483339d80809a1d80553, 0x73ed + ], + double_modulus: [ + 0x017b4805fffcb7fdfffffffe00000002, 0x014ea6533afa906673b0101343b00aa6, 0xe7da + ], + modulus_u60: U60Repr { limbs: [ + 0x0fffffff00000001, 0x0bda402fffe5bfef, 0x09d80809a1d80553, 0x0a753299d7d48333, 0x73ed, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0fffffff00000001, 0x0bda402fffe5bfef, 0x09d80809a1d80553, 0x0a753299d7d48333, 0x73ed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x410fad2f92eb5c509cde80830358e4, 0x253b7fb78ddf0e2d772dc1f823b4d9, 0x8d54 + ] +}; + +struct BLS12_381_Fr_Params {} impl BigNumParamsTrait<3> for BLS12_381_Fr_Params { - fn get_instance() -> BigNumInstance<3, Self> { - BLS12_381_Fr_Instance - } - fn modulus_bits() -> u32 { - 255 + fn get_params() -> BigNumParams<3> { + BLS12_381_Fr_PARAMS } } -global BLS12_381_Fr_Instance: BigNumInstance<3, BLS12_381_Fr_Params> = BigNumInstance { - modulus: [ - 0xbda402fffe5bfeffffffff00000001, 0xa753299d7d483339d80809a1d80553, 0x73ed - ], - double_modulus: [ - 0x017b4805fffcb7fdfffffffe00000002, 0x014ea6533afa906673b0101343b00aa6, 0xe7da - ], - modulus_u60: U60Repr { limbs: [ - 0x0fffffff00000001, 0x0bda402fffe5bfef, 0x09d80809a1d80553, 0x0a753299d7d48333, 0x73ed, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0fffffff00000001, 0x0bda402fffe5bfef, 0x09d80809a1d80553, 0x0a753299d7d48333, 0x73ed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x410fad2f92eb5c509cde80830358e4, 0x253b7fb78ddf0e2d772dc1f823b4d9, 0x8d54 - ] -}; + diff --git a/src/fields/bn254Fq.nr b/src/fields/bn254Fq.nr index 0d40eba2..61a4d7f9 100644 --- a/src/fields/bn254Fq.nr +++ b/src/fields/bn254Fq.nr @@ -1,36 +1,29 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct BNParams {} -impl RuntimeBigNumParamsTrait<3> for BNParams { - fn modulus_bits() -> u32 { - 254 - } -} - -global BN254INSTANCE: BigNumInstance<3, BNParams> = BigNumInstance { - modulus: [ - 0x816a916871ca8d3c208c16d87cfd47, 0x4e72e131a029b85045b68181585d97, 0x3064 - ], - double_modulus: [ - 0x0102d522d0e3951a7841182db0f9fa8e, 0x019ce5c263405370a08b6d0302b0bb2e, 0x60c7 - ], - modulus_u60: U60Repr { limbs: [ - 0x0c208c16d87cfd47, 0x0816a916871ca8d3, 0x45b68181585d97, 0x04e72e131a029b85, 0x3064, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0c208c16d87cfd47, 0x0816a916871ca8d3, 0x45b68181585d97, 0x04e72e131a029b85, 0x3064, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x965e1767cd4c086f3aed8a19bf90e5, 0x7462623a04a7ab074a5868073013ae, 0x54a4 - ] +global BN254_Fq_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 254, + modulus: [ + 0x816a916871ca8d3c208c16d87cfd47, 0x4e72e131a029b85045b68181585d97, 0x3064 + ], + double_modulus: [ + 0x0102d522d0e3951a7841182db0f9fa8e, 0x019ce5c263405370a08b6d0302b0bb2e, 0x60c7 + ], + modulus_u60: U60Repr { limbs: [ + 0x0c208c16d87cfd47, 0x0816a916871ca8d3, 0x45b68181585d97, 0x04e72e131a029b85, 0x3064, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0c208c16d87cfd47, 0x0816a916871ca8d3, 0x45b68181585d97, 0x04e72e131a029b85, 0x3064, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x965e1767cd4c086f3aed8a19bf90e5, 0x7462623a04a7ab074a5868073013ae, 0x54a4 + ] }; -impl BigNumParamsTrait<3> for BNParams { - fn get_instance() -> BigNumInstance<3, Self> { - BN254INSTANCE - } - fn modulus_bits() -> u32 { - 254 +pub struct BN254_Fq_Params {} + +impl BigNumParamsTrait<3> for BN254_Fq_Params { + fn get_params() -> BigNumParams<3> { + BN254_Fq_PARAMS } } diff --git a/src/fields/ed25519Fq.nr b/src/fields/ed25519Fq.nr index cf7cb667..e610153f 100644 --- a/src/fields/ed25519Fq.nr +++ b/src/fields/ed25519Fq.nr @@ -1,35 +1,30 @@ -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; -use crate::BigNumParamsTrait as BigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct ED25519_Fq_Params {} -impl RuntimeBigNumParamsTrait<3> for ED25519_Fq_Params { - fn modulus_bits() -> u32 { - 255 - } -} +global ED25519_Fq_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 255, + modulus: [ + 0xffffffffffffffffffffffffffffed, 0xffffffffffffffffffffffffffffff, 0x7fff + ], + double_modulus: [ + 0x01ffffffffffffffffffffffffffffda, 0x01fffffffffffffffffffffffffffffe, 0xfffe + ], + modulus_u60: U60Repr { limbs: [ + 0x0fffffffffffffed, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x7fff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0fffffffffffffed, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x7fff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x13, 0x00, 0x8000 + ] +}; + +struct ED25519_Fq_Params {} + impl BigNumParamsTrait<3> for ED25519_Fq_Params { - fn get_instance() -> BigNumInstance<3, Self> { - ED25519_Fq_Instance - } - fn modulus_bits() -> u32 { - 255 + fn get_params() -> BigNumParams<3> { + ED25519_Fq_PARAMS } } -global ED25519_Fq_Instance: BigNumInstance<3, ED25519_Fq_Params> = BigNumInstance { - modulus: [ - 0xffffffffffffffffffffffffffffed, 0xffffffffffffffffffffffffffffff, 0x7fff - ], - double_modulus: [ - 0x01ffffffffffffffffffffffffffffda, 0x01fffffffffffffffffffffffffffffe, 0xfffe - ], - modulus_u60: U60Repr { limbs: [ - 0x0fffffffffffffed, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x7fff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0fffffffffffffed, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x7fff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x13, 0x00, 0x8000 - ] -}; diff --git a/src/fields/ed25519Fr.nr b/src/fields/ed25519Fr.nr index 26734582..9df6e099 100644 --- a/src/fields/ed25519Fr.nr +++ b/src/fields/ed25519Fr.nr @@ -1,35 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct ED25519_Fr_Params {} -impl RuntimeBigNumParamsTrait<3> for ED25519_Fr_Params { - fn modulus_bits() -> u32 { - 253 - } -} +global ED25519_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 253, + modulus: [ + 0xdef9dea2f79cd65812631a5cf5d3ed, 0x14, 0x1000 + ], + double_modulus: [ + 0x01bdf3bd45ef39acb024c634b9eba7da, 0x01000000000000000000000000000028, 0x1fff + ], + modulus_u60: U60Repr { limbs: [ + 0x0812631a5cf5d3ed, 0x0def9dea2f79cd65, 0x14, 0x00, 0x1000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0812631a5cf5d3ed, 0x0def9dea2f79cd65, 0x14, 0x00, 0x1000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x84188574218ca69fb673968c28b04c, 0xffffffffffffffffffffffffffffac, 0x3fff + ] +}; + +struct ED25519_Fr_Params {} + impl BigNumParamsTrait<3> for ED25519_Fr_Params { - fn get_instance() -> BigNumInstance<3, Self> { - ED25519_Fr_Instance - } - fn modulus_bits() -> u32 { - 253 + fn get_params() -> BigNumParams<3> { + ED25519_Fr_PARAMS } } -global ED25519_Fr_Instance: BigNumInstance<3, ED25519_Fr_Params> = BigNumInstance { - modulus: [ - 0xdef9dea2f79cd65812631a5cf5d3ed, 0x14, 0x1000 - ], - double_modulus: [ - 0x01bdf3bd45ef39acb024c634b9eba7da, 0x01000000000000000000000000000028, 0x1fff - ], - modulus_u60: U60Repr { limbs: [ - 0x0812631a5cf5d3ed, 0x0def9dea2f79cd65, 0x14, 0x00, 0x1000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0812631a5cf5d3ed, 0x0def9dea2f79cd65, 0x14, 0x00, 0x1000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x84188574218ca69fb673968c28b04c, 0xffffffffffffffffffffffffffffac, 0x3fff - ] -}; diff --git a/src/fields/mnt4_753Fq.nr b/src/fields/mnt4_753Fq.nr index d2b4df2c..00c84564 100644 --- a/src/fields/mnt4_753Fq.nr +++ b/src/fields/mnt4_753Fq.nr @@ -19,38 +19,33 @@ //! * B = Fq2(0, b * NON_RESIDUE) //! * NON_RESIDUE = 13 is the quadratic non-residue used to conpub struct the //! extension field Fq2 -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct MNT4_753_Fq_Params {} -impl RuntimeBigNumParamsTrait<7> for MNT4_753_Fq_Params { - fn modulus_bits() -> u32 { - 753 - } -} +global MNT4_753_Fq_PARAMS: BigNumParams<7> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 753, + modulus: [ + 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 + ], + double_modulus: [ + 0x013aa8a459ba233ebd20c7bc48bd0002, 0x0199d2ece4a948c71020e335884be1c6, 0x01ede4300b3b701e1b4b96a6fc70d0b4, 0x01d141db1b33a249b342b5ef3b622fcd, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 + ], + modulus_u60: U60Repr { limbs: [ + 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x45dcc95da918349f4965a2aee8fd75, 0x282372b75580c27c4d1f1f57a96a11, 0xd58326e3c0552419849e3c7171d852, 0xa300e0ede1965cbf72f0aa9bf03479, 0x67fb932cae2aba9a5d17c1ff73538b, 0xa82727c6eaef38056aaa0aaedb0574, 0x0242f916cf + ] +}; + +struct MNT4_753_Fq_Params {} + impl BigNumParamsTrait<7> for MNT4_753_Fq_Params { - fn get_instance() -> BigNumInstance<7, Self> { - MNT4_753_Fq_Instance - } - fn modulus_bits() -> u32 { - 753 + fn get_params() -> BigNumParams<7> { + MNT4_753_Fq_PARAMS } } -global MNT4_753_Fq_Instance: BigNumInstance<7, MNT4_753_Fq_Params> = BigNumInstance { - modulus: [ - 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 - ], - double_modulus: [ - 0x013aa8a459ba233ebd20c7bc48bd0002, 0x0199d2ece4a948c71020e335884be1c6, 0x01ede4300b3b701e1b4b96a6fc70d0b4, 0x01d141db1b33a249b342b5ef3b622fcd, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 - ], - modulus_u60: U60Repr { limbs: [ - 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x45dcc95da918349f4965a2aee8fd75, 0x282372b75580c27c4d1f1f57a96a11, 0xd58326e3c0552419849e3c7171d852, 0xa300e0ede1965cbf72f0aa9bf03479, 0x67fb932cae2aba9a5d17c1ff73538b, 0xa82727c6eaef38056aaa0aaedb0574, 0x0242f916cf - ] -}; diff --git a/src/fields/mnt4_753Fr.nr b/src/fields/mnt4_753Fr.nr index 4142fe87..68a9d50a 100644 --- a/src/fields/mnt4_753Fr.nr +++ b/src/fields/mnt4_753Fr.nr @@ -19,38 +19,33 @@ //! * B = Fq2(0, b * NON_RESIDUE) //! * NON_RESIDUE = 13 is the quadratic non-residue used to conpub struct the //! extension field Fq2 -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct MNT4_753_Fr_Params {} -impl RuntimeBigNumParamsTrait<7> for MNT4_753_Fr_Params { - fn modulus_bits() -> u32 { - 753 - } -} +global MNT4_753_Fr_PARAMS: BigNumParams<7> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 753, + modulus: [ + 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 + ], + double_modulus: [ + 0x0141322e1f42749fb20eedc480000002, 0x01f2ec69327549ad8703787e00af2e9c, 0x015190b353367dd7952852424c6d73be, 0x01d141db1b33a249b342b5ef3b64d8b7, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 + ], + modulus_u60: U60Repr { limbs: [ + 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xa2dae11d15867718ec70f5ff059bba, 0x276d65fe7e00ba391da260f2623ff9, 0x8140a086edaa60c58eb476bdedcb35, 0xa300e0ede1965cbf72f0aa9bee8120, 0x67fb932cae2aba9a5d17c1ff73538b, 0xa82727c6eaef38056aaa0aaedb0574, 0x0242f916cf + ] +}; + +struct MNT4_753_Fr_Params {} + impl BigNumParamsTrait<7> for MNT4_753_Fr_Params { - fn get_instance() -> BigNumInstance<7, Self> { - MNT4_753_Fr_Instance - } - fn modulus_bits() -> u32 { - 753 + fn get_params() -> BigNumParams<7> { + MNT4_753_Fr_PARAMS } } -global MNT4_753_Fr_Instance: BigNumInstance<7, MNT4_753_Fr_Params> = BigNumInstance { - modulus: [ - 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 - ], - double_modulus: [ - 0x0141322e1f42749fb20eedc480000002, 0x01f2ec69327549ad8703787e00af2e9c, 0x015190b353367dd7952852424c6d73be, 0x01d141db1b33a249b342b5ef3b64d8b7, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 - ], - modulus_u60: U60Repr { limbs: [ - 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xa2dae11d15867718ec70f5ff059bba, 0x276d65fe7e00ba391da260f2623ff9, 0x8140a086edaa60c58eb476bdedcb35, 0xa300e0ede1965cbf72f0aa9bee8120, 0x67fb932cae2aba9a5d17c1ff73538b, 0xa82727c6eaef38056aaa0aaedb0574, 0x0242f916cf - ] -}; diff --git a/src/fields/mnt6_753Fq.nr b/src/fields/mnt6_753Fq.nr index c581c569..2ed18388 100644 --- a/src/fields/mnt6_753Fq.nr +++ b/src/fields/mnt6_753Fq.nr @@ -19,38 +19,33 @@ //! * B = Fq3(b * NON_RESIDUE, 0, 0) //! * NON_RESIDUE = 11 is the cubic non-residue used to conpub struct the //! extension field Fq3 -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct MNT6_753_Fq_Params {} -impl RuntimeBigNumParamsTrait<7> for MNT6_753_Fq_Params { - fn modulus_bits() -> u32 { - 753 - } -} +global MNT6_753_Fq_PARAMS: BigNumParams<7> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 753, + modulus: [ + 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 + ], + double_modulus: [ + 0x0141322e1f42749fb20eedc480000002, 0x01f2ec69327549ad8703787e00af2e9c, 0x015190b353367dd7952852424c6d73be, 0x01d141db1b33a249b342b5ef3b64d8b7, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 + ], + modulus_u60: U60Repr { limbs: [ + 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xa2dae11d15867718ec70f5ff059bba, 0x276d65fe7e00ba391da260f2623ff9, 0x8140a086edaa60c58eb476bdedcb35, 0xa300e0ede1965cbf72f0aa9bee8120, 0x67fb932cae2aba9a5d17c1ff73538b, 0xa82727c6eaef38056aaa0aaedb0574, 0x0242f916cf + ] +}; + +struct MNT6_753_Fq_Params {} + impl BigNumParamsTrait<7> for MNT6_753_Fq_Params { - fn get_instance() -> BigNumInstance<7, Self> { - MNT6_753_Fq_Instance - } - fn modulus_bits() -> u32 { - 753 + fn get_params() -> BigNumParams<7> { + MNT6_753_Fq_PARAMS } } -global MNT6_753_Fq_Instance: BigNumInstance<7, MNT6_753_Fq_Params> = BigNumInstance { - modulus: [ - 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 - ], - double_modulus: [ - 0x0141322e1f42749fb20eedc480000002, 0x01f2ec69327549ad8703787e00af2e9c, 0x015190b353367dd7952852424c6d73be, 0x01d141db1b33a249b342b5ef3b64d8b7, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 - ], - modulus_u60: U60Repr { limbs: [ - 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xa2dae11d15867718ec70f5ff059bba, 0x276d65fe7e00ba391da260f2623ff9, 0x8140a086edaa60c58eb476bdedcb35, 0xa300e0ede1965cbf72f0aa9bee8120, 0x67fb932cae2aba9a5d17c1ff73538b, 0xa82727c6eaef38056aaa0aaedb0574, 0x0242f916cf - ] -}; diff --git a/src/fields/mnt6_753Fr.nr b/src/fields/mnt6_753Fr.nr index cb83e360..7f88e572 100644 --- a/src/fields/mnt6_753Fr.nr +++ b/src/fields/mnt6_753Fr.nr @@ -19,38 +19,33 @@ //! * B = Fq3(b * NON_RESIDUE, 0, 0) //! * NON_RESIDUE = 11 is the cubic non-residue used to conpub struct the //! extension field Fq3 -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct MNT6_753_Fr_Params {} -impl RuntimeBigNumParamsTrait<7> for MNT6_753_Fr_Params { - fn modulus_bits() -> u32 { - 753 - } -} +global MNT6_753_Fr_PARAMS: BigNumParams<7> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 753, + modulus: [ + 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 + ], + double_modulus: [ + 0x013aa8a459ba233ebd20c7bc48bd0002, 0x0199d2ece4a948c71020e335884be1c6, 0x01ede4300b3b701e1b4b96a6fc70d0b4, 0x01d141db1b33a249b342b5ef3b622fcd, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 + ], + modulus_u60: U60Repr { limbs: [ + 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x45dcc95da918349f4965a2aee8fd75, 0x282372b75580c27c4d1f1f57a96a11, 0xd58326e3c0552419849e3c7171d852, 0xa300e0ede1965cbf72f0aa9bf03479, 0x67fb932cae2aba9a5d17c1ff73538b, 0xa82727c6eaef38056aaa0aaedb0574, 0x0242f916cf + ] +}; + +struct MNT6_753_Fr_Params {} + impl BigNumParamsTrait<7> for MNT6_753_Fr_Params { - fn get_instance() -> BigNumInstance<7, Self> { - MNT6_753_Fr_Instance - } - fn modulus_bits() -> u32 { - 753 + fn get_params() -> BigNumParams<7> { + MNT6_753_Fr_PARAMS } } -global MNT6_753_Fr_Instance: BigNumInstance<7, MNT6_753_Fr_Params> = BigNumInstance { - modulus: [ - 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 - ], - double_modulus: [ - 0x013aa8a459ba233ebd20c7bc48bd0002, 0x0199d2ece4a948c71020e335884be1c6, 0x01ede4300b3b701e1b4b96a6fc70d0b4, 0x01d141db1b33a249b342b5ef3b622fcd, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 - ], - modulus_u60: U60Repr { limbs: [ - 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x45dcc95da918349f4965a2aee8fd75, 0x282372b75580c27c4d1f1f57a96a11, 0xd58326e3c0552419849e3c7171d852, 0xa300e0ede1965cbf72f0aa9bf03479, 0x67fb932cae2aba9a5d17c1ff73538b, 0xa82727c6eaef38056aaa0aaedb0574, 0x0242f916cf - ] -}; diff --git a/src/fields/mod.nr b/src/fields/mod.nr index db44ec3d..b2b8802c 100644 --- a/src/fields/mod.nr +++ b/src/fields/mod.nr @@ -28,42 +28,9 @@ pub mod U2048; pub mod U4096; pub mod U8192; -pub use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::bignum::BigNum; +use bn254Fq::BN254_Fq_Params; + +// example typedef when using a defined bignum instance +type Fq = BigNum<3, BN254_Fq_Params>; -/** - * @brief Parameter definitions for generic fields of varying bit lengths - * (these can be used when defining modular fields where the - * modulus is a witness value and cannot be predefined - * e.g. 2048-bit RSA) - **/ -pub struct Params512 {} -impl RuntimeBigNumParamsTrait<5> for Params512 { - fn modulus_bits() -> u32 { - 512 - } -} -pub struct Params768 {} -impl RuntimeBigNumParamsTrait<7> for Params768 { - fn modulus_bits() -> u32 { - 768 - } -} -pub struct Params1024 {} -impl RuntimeBigNumParamsTrait<9> for Params1024 { - fn modulus_bits() -> u32 { - 1024 - } -} -pub struct Params2048 {} -impl RuntimeBigNumParamsTrait<18> for Params2048 { - fn modulus_bits() -> u32 { - 2048 - } -} -pub struct Params4096 {} -impl RuntimeBigNumParamsTrait<35> for Params4096 { - fn modulus_bits() -> u32 { - 4096 - } -} diff --git a/src/fields/pallasFq.nr b/src/fields/pallasFq.nr index af652727..06023e1a 100644 --- a/src/fields/pallasFq.nr +++ b/src/fields/pallasFq.nr @@ -13,38 +13,33 @@ //! * Curve equation: y^2 = x^3 + 5 //! * Valuation(q - 1, 2) = 32 //! * Valuation(r - 1, 2) = 32 -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Pallas_Fq_Params {} -impl RuntimeBigNumParamsTrait<3> for Pallas_Fq_Params { - fn modulus_bits() -> u32 { - 255 - } -} +global Pallas_Fq_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 255, + modulus: [ + 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 + ], + double_modulus: [ + 0x018d31f81299f237325a61da00000002, 0x01000000000000000000000000000043, 0x7fff + ], + modulus_u60: U60Repr { limbs: [ + 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xe59c0fdacc1b919b4b3c4bfffffffc, 0xffffffffffffffffffffffffffff76, 0xffff + ] +}; + +struct Pallas_Fq_Params {} + impl BigNumParamsTrait<3> for Pallas_Fq_Params { - fn get_instance() -> BigNumInstance<3, Self> { - Pallas_Fq_Instance - } - fn modulus_bits() -> u32 { - 255 + fn get_params() -> BigNumParams<3> { + Pallas_Fq_PARAMS } } -global Pallas_Fq_Instance: BigNumInstance<3, Pallas_Fq_Params> = BigNumInstance { - modulus: [ - 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 - ], - double_modulus: [ - 0x018d31f81299f237325a61da00000002, 0x01000000000000000000000000000043, 0x7fff - ], - modulus_u60: U60Repr { limbs: [ - 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xe59c0fdacc1b919b4b3c4bfffffffc, 0xffffffffffffffffffffffffffff76, 0xffff - ] -}; diff --git a/src/fields/pallasFr.nr b/src/fields/pallasFr.nr index e3960d94..19946f83 100644 --- a/src/fields/pallasFr.nr +++ b/src/fields/pallasFr.nr @@ -13,38 +13,33 @@ //! * Curve equation: y^2 = x^3 + 5 //! * Valuation(q - 1, 2) = 32 //! * Valuation(r - 1, 2) = 32 -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Pallas_Fr_Params {} -impl RuntimeBigNumParamsTrait<3> for Pallas_Fr_Params { - fn modulus_bits() -> u32 { - 255 - } -} +global Pallas_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 255, + modulus: [ + 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 + ], + double_modulus: [ + 0x018d31f8132951bb188dd64200000002, 0x01000000000000000000000000000043, 0x7fff + ], + modulus_u60: U60Repr { limbs: [ + 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xe59c0fd9ad5c89cee4537bfffffffc, 0xffffffffffffffffffffffffffff76, 0xffff + ] +}; + +struct Pallas_Fr_Params {} + impl BigNumParamsTrait<3> for Pallas_Fr_Params { - fn get_instance() -> BigNumInstance<3, Self> { - Pallas_Fr_Instance - } - fn modulus_bits() -> u32 { - 255 + fn get_params() -> BigNumParams<3> { + Pallas_Fr_PARAMS } } -global Pallas_Fr_Instance: BigNumInstance<3, Pallas_Fr_Params> = BigNumInstance { - modulus: [ - 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 - ], - double_modulus: [ - 0x018d31f8132951bb188dd64200000002, 0x01000000000000000000000000000043, 0x7fff - ], - modulus_u60: U60Repr { limbs: [ - 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xe59c0fd9ad5c89cee4537bfffffffc, 0xffffffffffffffffffffffffffff76, 0xffff - ] -}; diff --git a/src/fields/secp256k1Fq.nr b/src/fields/secp256k1Fq.nr index 1f3741e3..9f11555a 100644 --- a/src/fields/secp256k1Fq.nr +++ b/src/fields/secp256k1Fq.nr @@ -1,35 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Secp256k1_Fq_Params {} -impl RuntimeBigNumParamsTrait<3> for Secp256k1_Fq_Params { - fn modulus_bits() -> u32 { - 256 - } -} +global Secp256k1_Fq_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 256, + modulus: [ + 0xfffffffffffffffffffffefffffc2f, 0xffffffffffffffffffffffffffffff, 0xffff + ], + double_modulus: [ + 0x01fffffffffffffffffffffdfffff85e, 0x01fffffffffffffffffffffffffffffe, 0x01fffe + ], + modulus_u60: U60Repr { limbs: [ + 0x0ffffffefffffc2f, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0ffffffefffffc2f, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x01000003d1, 0x00, 0x010000 + ] +}; + +struct Secp256k1_Fq_Params {} + impl BigNumParamsTrait<3> for Secp256k1_Fq_Params { - fn get_instance() -> BigNumInstance<3, Self> { - Secp256k1_Fq_Instance - } - fn modulus_bits() -> u32 { - 256 + fn get_params() -> BigNumParams<3> { + Secp256k1_Fq_PARAMS } } -global Secp256k1_Fq_Instance: BigNumInstance<3, Secp256k1_Fq_Params> = BigNumInstance { - modulus: [ - 0xfffffffffffffffffffffefffffc2f, 0xffffffffffffffffffffffffffffff, 0xffff - ], - double_modulus: [ - 0x01fffffffffffffffffffffdfffff85e, 0x01fffffffffffffffffffffffffffffe, 0x01fffe - ], - modulus_u60: U60Repr { limbs: [ - 0x0ffffffefffffc2f, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0ffffffefffffc2f, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x01000003d1, 0x00, 0x010000 - ] -}; diff --git a/src/fields/secp256k1Fr.nr b/src/fields/secp256k1Fr.nr index 6d604ead..0ce1a703 100644 --- a/src/fields/secp256k1Fr.nr +++ b/src/fields/secp256k1Fr.nr @@ -1,35 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Secp256k1_Fr_Params {} -impl RuntimeBigNumParamsTrait<3> for Secp256k1_Fr_Params { - fn modulus_bits() -> u32 { - 256 - } -} +global Secp256k1_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 256, + modulus: [ + 0xaedce6af48a03bbfd25e8cd0364141, 0xfffffffffffffffffffffffffffeba, 0xffff + ], + double_modulus: [ + 0x015db9cd5e9140777fa4bd19a06c8282, 0x01fffffffffffffffffffffffffffd74, 0x01fffe + ], + modulus_u60: U60Repr { limbs: [ + 0x0fd25e8cd0364141, 0x0aedce6af48a03bb, 0x0ffffffffffffeba, 0x0fffffffffffffff, 0xffff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0fd25e8cd0364141, 0x0aedce6af48a03bb, 0x0ffffffffffffeba, 0x0fffffffffffffff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x51231950b75fc4402da1732fc9bec0, 0x0145, 0x010000 + ] +}; + +struct Secp256k1_Fr_Params {} + impl BigNumParamsTrait<3> for Secp256k1_Fr_Params { - fn get_instance() -> BigNumInstance<3, Self> { - Secp256k1_Fr_Instance - } - fn modulus_bits() -> u32 { - 256 + fn get_params() -> BigNumParams<3> { + Secp256k1_Fr_PARAMS } } -global Secp256k1_Fr_Instance: BigNumInstance<3, Secp256k1_Fr_Params> = BigNumInstance { - modulus: [ - 0xaedce6af48a03bbfd25e8cd0364141, 0xfffffffffffffffffffffffffffeba, 0xffff - ], - double_modulus: [ - 0x015db9cd5e9140777fa4bd19a06c8282, 0x01fffffffffffffffffffffffffffd74, 0x01fffe - ], - modulus_u60: U60Repr { limbs: [ - 0x0fd25e8cd0364141, 0x0aedce6af48a03bb, 0x0ffffffffffffeba, 0x0fffffffffffffff, 0xffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0fd25e8cd0364141, 0x0aedce6af48a03bb, 0x0ffffffffffffeba, 0x0fffffffffffffff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x51231950b75fc4402da1732fc9bec0, 0x0145, 0x010000 - ] -}; diff --git a/src/fields/secp256r1Fq.nr b/src/fields/secp256r1Fq.nr index 2023f04a..56fb42d5 100644 --- a/src/fields/secp256r1Fq.nr +++ b/src/fields/secp256r1Fq.nr @@ -1,35 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Secp256r1_Fq_Params {} -impl RuntimeBigNumParamsTrait<3> for Secp256r1_Fq_Params { - fn modulus_bits() -> u32 { - 256 - } -} +global Secp256r1_Fq_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 256, + modulus: [ + 0xffffffffffffffffffffffff, 0xffff00000001000000000000000000, 0xffff + ], + double_modulus: [ + 0x01000001fffffffffffffffffffffffe, 0x01fffe00000001ffffffffffffffffff, 0x01fffe + ], + modulus_u60: U60Repr { limbs: [ + 0x0fffffffffffffff, 0x0fffffffff, 0x00, 0x0ffff00000001000, 0xffff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0fffffffffffffff, 0x0fffffffff, 0x00, 0x0ffff00000001000, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xfffffeffffffff0000000000000003, 0xfffffffffffffffefffffffeff, 0x010000 + ] +}; + +struct Secp256r1_Fq_Params {} + impl BigNumParamsTrait<3> for Secp256r1_Fq_Params { - fn get_instance() -> BigNumInstance<3, Self> { - Secp256r1_Fq_Instance - } - fn modulus_bits() -> u32 { - 256 + fn get_params() -> BigNumParams<3> { + Secp256r1_Fq_PARAMS } } -global Secp256r1_Fq_Instance: BigNumInstance<3, Secp256r1_Fq_Params> = BigNumInstance { - modulus: [ - 0xffffffffffffffffffffffff, 0xffff00000001000000000000000000, 0xffff - ], - double_modulus: [ - 0x01000001fffffffffffffffffffffffe, 0x01fffe00000001ffffffffffffffffff, 0x01fffe - ], - modulus_u60: U60Repr { limbs: [ - 0x0fffffffffffffff, 0x0fffffffff, 0x00, 0x0ffff00000001000, 0xffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0fffffffffffffff, 0x0fffffffff, 0x00, 0x0ffff00000001000, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xfffffeffffffff0000000000000003, 0xfffffffffffffffefffffffeff, 0x010000 - ] -}; diff --git a/src/fields/secp256r1Fr.nr b/src/fields/secp256r1Fr.nr index e028721b..7b1cc7b9 100644 --- a/src/fields/secp256r1Fr.nr +++ b/src/fields/secp256r1Fr.nr @@ -1,35 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Secp256r1_Fr_Params {} -impl RuntimeBigNumParamsTrait<3> for Secp256r1_Fr_Params { - fn modulus_bits() -> u32 { - 256 - } -} +global Secp256r1_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 256, + modulus: [ + 0xe6faada7179e84f3b9cac2fc632551, 0xffff00000000ffffffffffffffffbc, 0xffff + ], + double_modulus: [ + 0x01cdf55b4e2f3d09e7739585f8c64aa2, 0x01fffe00000001ffffffffffffffff78, 0x01fffe + ], + modulus_u60: U60Repr { limbs: [ + 0x03b9cac2fc632551, 0x0e6faada7179e84f, 0x0fffffffffffffbc, 0x0ffff00000000fff, 0xffff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x03b9cac2fc632551, 0x0e6faada7179e84f, 0x0fffffffffffffbc, 0x0ffff00000000fff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x190552df1a6c21012ffd85eedf9bfe, 0xfffffffffffffffeffffffff43, 0x010000 + ] +}; + +struct Secp256r1_Fr_Params {} + impl BigNumParamsTrait<3> for Secp256r1_Fr_Params { - fn get_instance() -> BigNumInstance<3, Self> { - Secp256r1_Fr_Instance - } - fn modulus_bits() -> u32 { - 256 + fn get_params() -> BigNumParams<3> { + Secp256r1_Fr_PARAMS } } -global Secp256r1_Fr_Instance: BigNumInstance<3, Secp256r1_Fr_Params> = BigNumInstance { - modulus: [ - 0xe6faada7179e84f3b9cac2fc632551, 0xffff00000000ffffffffffffffffbc, 0xffff - ], - double_modulus: [ - 0x01cdf55b4e2f3d09e7739585f8c64aa2, 0x01fffe00000001ffffffffffffffff78, 0x01fffe - ], - modulus_u60: U60Repr { limbs: [ - 0x03b9cac2fc632551, 0x0e6faada7179e84f, 0x0fffffffffffffbc, 0x0ffff00000000fff, 0xffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x03b9cac2fc632551, 0x0e6faada7179e84f, 0x0fffffffffffffbc, 0x0ffff00000000fff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x190552df1a6c21012ffd85eedf9bfe, 0xfffffffffffffffeffffffff43, 0x010000 - ] -}; diff --git a/src/fields/secp384r1Fq.nr b/src/fields/secp384r1Fq.nr index ccb39ef5..22814829 100644 --- a/src/fields/secp384r1Fq.nr +++ b/src/fields/secp384r1Fq.nr @@ -1,35 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Secp384r1_Fq_Params {} -impl RuntimeBigNumParamsTrait<4> for Secp384r1_Fq_Params { - fn modulus_bits() -> u32 { - 384 - } -} +global Secp384r1_Fq_PARAMS: BigNumParams<4> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 384, + modulus: [ + 0xffffff0000000000000000ffffffff, 0xfffffffffffffffffffffffffffeff, 0xffffffffffffffffffffffffffffff, 0xffffff + ], + double_modulus: [ + 0x01fffffe0000000000000001fffffffe, 0x01fffffffffffffffffffffffffffdfe, 0x01fffffffffffffffffffffffffffffe, 0x01fffffe + ], + modulus_u60: U60Repr { limbs: [ + 0xffffffff, 0x0ffffff000000000, 0x0ffffffffffffeff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0xffffffff, 0x0ffffff000000000, 0x0ffffffffffffeff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xffffffffffffffff00000001, 0x0100, 0x00, 0x01000000 + ] +}; + +struct Secp384r1_Fq_Params {} + impl BigNumParamsTrait<4> for Secp384r1_Fq_Params { - fn get_instance() -> BigNumInstance<4, Self> { - Secp384r1_Fq_Instance - } - fn modulus_bits() -> u32 { - 384 + fn get_params() -> BigNumParams<4> { + Secp384r1_Fq_PARAMS } } -global Secp384r1_Fq_Instance: BigNumInstance<4, Secp384r1_Fq_Params> = BigNumInstance { - modulus: [ - 0xffffff0000000000000000ffffffff, 0xfffffffffffffffffffffffffffeff, 0xffffffffffffffffffffffffffffff, 0xffffff - ], - double_modulus: [ - 0x01fffffe0000000000000001fffffffe, 0x01fffffffffffffffffffffffffffdfe, 0x01fffffffffffffffffffffffffffffe, 0x01fffffe - ], - modulus_u60: U60Repr { limbs: [ - 0xffffffff, 0x0ffffff000000000, 0x0ffffffffffffeff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0xffffffff, 0x0ffffff000000000, 0x0ffffffffffffeff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xffffffffffffffff00000001, 0x0100, 0x00, 0x01000000 - ] -}; diff --git a/src/fields/secp384r1Fr.nr b/src/fields/secp384r1Fr.nr index 6ed9764d..76d95078 100644 --- a/src/fields/secp384r1Fr.nr +++ b/src/fields/secp384r1Fr.nr @@ -1,35 +1,30 @@ -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Secp384r1_Fr_Params {} -impl RuntimeBigNumParamsTrait<4> for Secp384r1_Fr_Params { - fn modulus_bits() -> u32 { - 384 - } -} +global Secp384r1_Fr_PARAMS: BigNumParams<4> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 384, + modulus: [ + 0x1a0db248b0a77aecec196accc52973, 0xffffffffffffc7634d81f4372ddf58, 0xffffffffffffffffffffffffffffff, 0xffffff + ], + double_modulus: [ + 0x01341b6491614ef5d9d832d5998a52e6, 0x01ffffffffffff8ec69b03e86e5bbeaf, 0x01fffffffffffffffffffffffffffffe, 0x01fffffe + ], + modulus_u60: U60Repr { limbs: [ + 0x0cec196accc52973, 0x01a0db248b0a77ae, 0x034d81f4372ddf58, 0x0ffffffffffffc76, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0cec196accc52973, 0x01a0db248b0a77ae, 0x034d81f4372ddf58, 0x0ffffffffffffc76, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xe5f24db74f58851313e695333ad68d, 0x389cb27e0bc8d220a7, 0x00, 0x01000000 + ] +}; + +struct Secp384r1_Fr_Params {} + impl BigNumParamsTrait<4> for Secp384r1_Fr_Params { - fn get_instance() -> BigNumInstance<4, Self> { - Secp384r1_Fr_Instance - } - fn modulus_bits() -> u32 { - 384 + fn get_params() -> BigNumParams<4> { + Secp384r1_Fr_PARAMS } } -global Secp384r1_Fr_Instance: BigNumInstance<4, Secp384r1_Fr_Params> = BigNumInstance { - modulus: [ - 0x1a0db248b0a77aecec196accc52973, 0xffffffffffffc7634d81f4372ddf58, 0xffffffffffffffffffffffffffffff, 0xffffff - ], - double_modulus: [ - 0x01341b6491614ef5d9d832d5998a52e6, 0x01ffffffffffff8ec69b03e86e5bbeaf, 0x01fffffffffffffffffffffffffffffe, 0x01fffffe - ], - modulus_u60: U60Repr { limbs: [ - 0x0cec196accc52973, 0x01a0db248b0a77ae, 0x034d81f4372ddf58, 0x0ffffffffffffc76, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0cec196accc52973, 0x01a0db248b0a77ae, 0x034d81f4372ddf58, 0x0ffffffffffffc76, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xe5f24db74f58851313e695333ad68d, 0x389cb27e0bc8d220a7, 0x00, 0x01000000 - ] -}; diff --git a/src/fields/vestaFq.nr b/src/fields/vestaFq.nr index fbbefe93..202eb2be 100644 --- a/src/fields/vestaFq.nr +++ b/src/fields/vestaFq.nr @@ -14,38 +14,33 @@ //! * Curve equation: y^2 = x^3 + 5 //! * Valuation(q - 1, 2) = 32 //! * Valuation(r - 1, 2) = 32 -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Vesta_Fq_Params {} -impl RuntimeBigNumParamsTrait<3> for Vesta_Fq_Params { - fn modulus_bits() -> u32 { - 255 - } -} +global Vesta_Fq_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 255, + modulus: [ + 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 + ], + double_modulus: [ + 0x018d31f8132951bb188dd64200000002, 0x01000000000000000000000000000043, 0x7fff + ], + modulus_u60: U60Repr { limbs: [ + 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xe59c0fd9ad5c89cee4537bfffffffc, 0xffffffffffffffffffffffffffff76, 0xffff + ] +}; + +struct Vesta_Fq_Params {} + impl BigNumParamsTrait<3> for Vesta_Fq_Params { - fn get_instance() -> BigNumInstance<3, Self> { - Vesta_Fq_Instance - } - fn modulus_bits() -> u32 { - 255 + fn get_params() -> BigNumParams<3> { + Vesta_Fq_PARAMS } } -global Vesta_Fq_Instance: BigNumInstance<3, Vesta_Fq_Params> = BigNumInstance { - modulus: [ - 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 - ], - double_modulus: [ - 0x018d31f8132951bb188dd64200000002, 0x01000000000000000000000000000043, 0x7fff - ], - modulus_u60: U60Repr { limbs: [ - 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xe59c0fd9ad5c89cee4537bfffffffc, 0xffffffffffffffffffffffffffff76, 0xffff - ] -}; diff --git a/src/fields/vestaFr.nr b/src/fields/vestaFr.nr index d5ef72b1..46e6560b 100644 --- a/src/fields/vestaFr.nr +++ b/src/fields/vestaFr.nr @@ -14,38 +14,33 @@ //! * Curve equation: y^2 = x^3 + 5 //! * Valuation(q - 1, 2) = 32 //! * Valuation(r - 1, 2) = 32 -use crate::BigNumParamsTrait; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; +use crate::params::BigNumParamsTrait; +use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Vesta_Fr_Params {} -impl RuntimeBigNumParamsTrait<3> for Vesta_Fr_Params { - fn modulus_bits() -> u32 { - 255 - } -} +global Vesta_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 255, + modulus: [ + 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 + ], + double_modulus: [ + 0x018d31f81299f237325a61da00000002, 0x01000000000000000000000000000043, 0x7fff + ], + modulus_u60: U60Repr { limbs: [ + 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xe59c0fdacc1b919b4b3c4bfffffffc, 0xffffffffffffffffffffffffffff76, 0xffff + ] +}; + +struct Vesta_Fr_Params {} + impl BigNumParamsTrait<3> for Vesta_Fr_Params { - fn get_instance() -> BigNumInstance<3, Self> { - Vesta_Fr_Instance - } - fn modulus_bits() -> u32 { - 255 + fn get_params() -> BigNumParams<3> { + Vesta_Fr_PARAMS } } -global Vesta_Fr_Instance: BigNumInstance<3, Vesta_Fr_Params> = BigNumInstance { - modulus: [ - 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 - ], - double_modulus: [ - 0x018d31f81299f237325a61da00000002, 0x01000000000000000000000000000043, 0x7fff - ], - modulus_u60: U60Repr { limbs: [ - 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xe59c0fdacc1b919b4b3c4bfffffffc, 0xffffffffffffffffffffffffffff76, 0xffff - ] -}; diff --git a/src/lib.nr b/src/lib.nr index de450e49..0a315506 100644 --- a/src/lib.nr +++ b/src/lib.nr @@ -1,311 +1,18 @@ -pub(crate) mod utils; +mod utils; +mod fields; + +// Structs +mod params; +mod bignum; +mod runtime_bignum; + +// Functions on structs +mod unconstrained_ops; +mod constrained_ops; +mod unconstrained_helpers; +mod expressions; +mod serialization; + +// Tests mod bignum_test; -pub mod fields; -pub(crate) mod runtime_bignum; mod runtime_bignum_test; - -pub use crate::utils::u60_representation::U60Repr; -pub use crate::runtime_bignum::BigNumInstance as RuntimeBigNumInstance; -pub use crate::runtime_bignum::BigNumInstanceTrait as RuntimeBigNumInstanceTrait; -pub use crate::runtime_bignum::BigNumParamsTrait as RuntimeBigNumParamsTrait; -pub use crate::runtime_bignum::BigNumTrait as RuntimeBigNumTrait; - -pub struct BigNum { - limbs: [Field; N] -} - -/** - * @brief BigNumParamsTrait defines a "field" with which to parametrise BigNum. - * @description The "field" does not need to be prime, any value *should* work (TODO: test!) -**/ -// -// trait BigNumParamsTrait where Params: RuntimeBigNumParamsTrait, RuntimeBigNumInstance: RuntimeBigNumInstanceTrait> { -trait BigNumParamsTrait where Self: RuntimeBigNumParamsTrait { - - fn get_instance() -> RuntimeBigNumInstance where Self: RuntimeBigNumParamsTrait;// ; - - /** - * @brief modulus_bits = log2(modulus) rounded up - **/ - fn modulus_bits() -> u32; - - fn has_multiplicative_inverse() -> bool { true } -} - -trait BigNumTrait where BigNumTrait: std::ops::Add + std::ops::Sub + std::ops::Mul + std::ops::Div + std::ops::Eq + RuntimeBigNumTrait { - // TODO: this crashes the compiler? v0.32 - // fn default() -> Self { std::default::Default::default () } - fn from(limbs: [Field]) -> Self { RuntimeBigNumTrait::from(limbs) } - fn new() -> Self { RuntimeBigNumTrait::new() } - fn one() -> Self { RuntimeBigNumTrait::one() } - fn modulus() -> Self; - fn modulus_bits(self) -> u32; - fn num_limbs(self) -> u32; - fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self; - fn __pow(self, exponent: Self) -> Self; - fn __neg(self) -> Self; - fn __add(self, other: Self) -> Self; - fn __sub(self, other: Self) -> Self; - fn __mul(self, other: Self) -> Self; - fn __div(self, other: Self) -> Self; - fn __udiv_mod(self, divisor: Self) -> (Self, Self); - fn __invmod(self) -> Self; - fn __batch_invert(to_invert: [Self; M]) -> [Self; M]; - fn __is_zero(self) -> bool { RuntimeBigNumTrait::__is_zero(self) } - fn __eq(self, other: Self) -> bool { RuntimeBigNumTrait::__eq(self, other) } - fn __compute_quadratic_expression(lhs: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs: [[Self; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], add: [Self; ADD_N], add_flags: [bool; ADD_N]) -> (Self, Self); - fn evaluate_quadratic_expression(lhs: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs: [[Self; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], add: [Self; ADD_N], add_flags: [bool; ADD_N]); - fn validate_in_range(self){ RuntimeBigNumTrait::validate_in_range(self) } - fn validate_in_field(self); - fn assert_is_not_equal(self, other: Self); - fn neg(self) -> Self; - fn add(self, other: Self) -> Self { self + other } - fn sub(self, other: Self) -> Self { self - other } - fn mul(self, other: Self) -> Self { self * other } - fn div(self, other: Self) -> Self { self / other } - fn udiv_mod(self, divisor: Self) -> (Self, Self); - fn udiv(self, divisor: Self) -> Self; - fn umod(self, divisor: Self) -> Self; - fn eq(self, other: Self) -> bool { self == other } - fn get(self) -> [Field] { RuntimeBigNumTrait::get(self) } - fn get_limb(self, idx: u64) -> Field { RuntimeBigNumTrait::get_limb(self, idx) } - fn set_limb(&mut self, idx: u32, value: Field) { RuntimeBigNumTrait::set_limb(self, idx, value) } - fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self { RuntimeBigNumTrait::conditional_select(lhs, rhs, predicate) } - fn to_le_bytes(self) -> [u8; X] { RuntimeBigNumTrait::to_le_bytes(self) } -} - -impl BigNumTrait for BigNum where Params: BigNumParamsTrait + RuntimeBigNumParamsTrait { - - // Weird compiler issue where if we do not pass `Self` as a parameter to these methods, - // then a generic struct that conforms to BigNumTrait cannot access these methods? - // the Params: BigNumParamsTrait needs to be satisfied, but the BigNumTrait has no knowledge of BigNumParamsTrait? - // but...passing in a Self parameter seems to fix. really weird - fn modulus_bits(_: Self) -> u32 { - let r: u32 = Params::modulus_bits(); - r - } - fn num_limbs(_: Self) -> u32 { - N - } - - fn modulus() -> Self { - Params::get_instance().modulus() - } - - // #################################################################################################################### - // #################################################################################################################### - // ### C O N S T R U C T O R S - // #################################################################################################################### - // #################################################################################################################### - // fn new() -> Self { - // BigNum { limbs: [0; N] } - // } - - // fn one() -> Self { - // let mut result = BigNum::new(); - // result.limbs[0] = 1; - // result - // } - - // #################################################################################################################### - // #################################################################################################################### - // ### U N C O N S T R A I N E D F U N C T I O N S - // ### NOTE: these functions call unconstrained internal implementations because trait impl modifiers are not supported - // #################################################################################################################### - // #################################################################################################################### - fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self { - Params::get_instance().__derive_from_seed(seed) - } - - fn __neg(self) -> Self { - Params::get_instance().__neg(self) - } - - fn __add(self, rhs: Self) -> Self { - Params::get_instance().__add(self, rhs) - } - - fn __sub(self, rhs: Self) -> Self { - Params::get_instance().__sub(self, rhs) - } - - fn __mul(self, rhs: Self) -> Self { - Params::get_instance().__mul(self, rhs) - } - - fn __div(self, rhs: Self) -> Self { - Params::get_instance().__div(self, rhs) - } - - fn __batch_invert(x: [Self; M]) -> [Self; M] { - assert(Params::has_multiplicative_inverse()); - Params::get_instance().__batch_invert(x) - } - - fn __invmod(self) -> Self { - assert(Params::has_multiplicative_inverse()); - Params::get_instance().__invmod(self) - } - - fn __pow(self, exponent: Self) -> Self { - Params::get_instance().__pow(self, exponent) - } - - 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) { - Params::get_instance().__compute_quadratic_expression( - lhs_terms, - lhs_flags, - rhs_terms, - rhs_flags, - linear_terms, - linear_flags - ) - } - - // #################################################################################################################### - // #################################################################################################################### - // ### C O N S T R A I N E D F U N C T I O N S - // #################################################################################################################### - // #################################################################################################################### - - /** - * @brief Constrain a degree-2 BigNum expression to be equal to 0 modulo Params::modulus() - * @description The expression is of the form (when evaluated as an integer relation): - * - * \sum_{i=0}^{NUM_PRODUCTS - 1} ((\sum_{j=0}^{LHS_N-1}lhs[i][j]) * (\sum_{j=0}^{RHS_N-1}rhs[i][j])) + \sum_{i=0}^{ADD_N - 1}linear_terms[i] - quotient * modulus = 0 - * - * The intent is to capture an arbitrary degree-2 expression within the limitations of Noir (no efficient dynamically-sized vectors) - * - * Note: this method requires the remainder term of the expression to be ZERO - * When performing BigNum arithmetic, we want to represent desired BigNum operations in a way that minimizes the number of modular reductions that are required. - * This can be achieved by minimizing the number of degree-2 relations required. - * - * The expensive parts of this algorithm are the following: - * 1. evaluating the limb products required to compute `lhs * rhs` - * 2. applying range constraints to validate the result is 0 - * - * Range constraints are needed for the following reason: - * When evaluating the above expression over N-limb BigNum objects, the result will consist of 2N - 1 limbs. - * Each limb will be in the range [0, ..., 2^{240 + twiddle_factor} - 1] (twiddle_factor needs to be less than 6). - * Because of the subtractions, the limbs may underflow and represent NEGATIVE values. - * To account for this, we allow the Prover to borrow values from more significant limbs and add them into less significant limbs - * (explicitly, we can borrow 2^{126} from limb `i + 1` to add `2^{246}` into `i`). - * To ensure this has been done correctly, we validate that the borrow-adjusted limbs are all-zero for the first 120 bits. - * We do *this* by multiplying the borrow-adjusted limbs by 1 / 2^{120} modulo CircutModulus, and we validate the result is in the range [0, ..., 2^{126} - 1]. - * TODO: explain why this check works. It's statistically sound but not perfectly sound. Chance of the check failing is ~1 in 2^{120} - * I believe this is the most efficient way of performing the zero-check for this relation as it only requires `2N - 2` 126-bit range checks. - * TODO: explain why we apply a 126-bit range check, this feels like a magic number - * (it is. we could go higher, up to the number of bits in the CircuitModulus - 121, but 126 *should be* sufficient and is much cheaper) - * TODO: apply checks in this method to validate twiddle_factor does not exceed 6 - * - * @param lhs_terms a 2D array of BigNum - * @param lhs_flags a 2D array of sign flags - * @param rhs_terms a 2D array of BigNum - * @param rhs_flags a 2D array of sign flags - * @param linear_terms an array of BigNum - * @param linear_flags an array of sign flags - **/ - 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] - ) { - Params::get_instance().evaluate_quadratic_expression( - lhs_terms, - lhs_flags, - rhs_terms, - rhs_flags, - linear_terms, - linear_flags - ) - } - - fn validate_in_field(self: Self) { - Params::get_instance().validate_in_field(self); - } - - /** - * @brief Validate self != other - * @details If A == B, then A == B mod N. - * We can efficiently evaluate A == B mod N where N = circuit modulus - * This method is *sound*, but not *complete* (i.e. A != B but A == B mod N) - * However the probability of an honest Prover being unable to satisfy this check is tiny! - * (todo: compute how tiny) - **/ - fn assert_is_not_equal(self, other: Self) { - Params::get_instance().assert_is_not_equal(self, other); - } - - fn neg(self) -> Self { - Params::get_instance().neg(self) - } - - fn __udiv_mod(self, divisor: Self) -> (Self, Self) { - Params::get_instance().__udiv_mod(self, divisor) - } - - fn udiv_mod(self, divisor: Self) -> (Self, Self) { - Params::get_instance().udiv_mod(self, divisor) - } - - fn udiv(self, divisor: Self) -> Self { - Params::get_instance().udiv(self, divisor) - } - - fn umod(self, divisor: Self) -> Self { - Params::get_instance().umod(self, divisor) - } -} - -impl BigNum where Params: BigNumParamsTrait + RuntimeBigNumParamsTrait {} - -impl std::ops::Add for BigNum where Params: BigNumParamsTrait + RuntimeBigNumParamsTrait { - // Note: this method is expensive! Try to craft quadratic relations and directly evaluate them - // via evaluate_quadratic_expression - fn add(self, other: Self) -> Self { - Params::get_instance().add(self, other) - } -} - -impl std::ops::Sub for BigNum where Params: BigNumParamsTrait + RuntimeBigNumParamsTrait { - // Note: this method is expensive! Try to craft quadratic relations and directly evaluate them - // via evaluate_quadratic_expression - fn sub(self, other: Self) -> Self { - Params::get_instance().sub(self, other) - } -} - -impl std::ops::Mul for BigNum where Params: BigNumParamsTrait + RuntimeBigNumParamsTrait { - // 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 { - Params::get_instance().mul(self, other) - } -} - -impl std::ops::Div for BigNum where Params: BigNumParamsTrait + RuntimeBigNumParamsTrait { - // Note: this method is expensive! Witness computation is extremely expensive as it requires modular exponentiation - fn div(self, other: Self) -> Self { - Params::get_instance().div(self, other) - } -} - -impl std::cmp::Eq for BigNum where Params: BigNumParamsTrait + RuntimeBigNumParamsTrait { - - fn eq(self, other: Self) -> bool { - let bn: RuntimeBigNumInstance = Params::get_instance(); - bn.eq(self, other) - } -} diff --git a/src/params.nr b/src/params.nr new file mode 100644 index 00000000..a9c6046b --- /dev/null +++ b/src/params.nr @@ -0,0 +1,85 @@ +use crate::utils::u60_representation::U60Repr; + +pub(crate) struct BigNumParams { + has_multiplicative_inverse: bool, + + // @brief modulus_bits = log2(modulus) rounded up + // This needs to be a comptime const, so that it can be used as an argument to std::field::assert_constant() + modulus_bits_getter: fn () -> u32, + + // @brief modulus: all BigNum operations are evaluated modulo this value + modulus: [Field; N], + + // @brief modulus but represented in a U60Repr form + modulus_u60: U60Repr, + modulus_u60_x4: U60Repr, + + // @brief double_modulus: used when performing negations and subtractions + double_modulus: [Field; N], + + // @brief redc_param used for __barrett_reduction. See https://en.wikipedia.org/wiki/Barrett_reduction + redc_param: [Field; N], +} + +// To be implemented by the user, or within the prebuilt options in the `fields/` dir. +pub(crate) trait BigNumParamsTrait { + fn get_params() -> BigNumParams; +} + +// To be implemented by the user, or within the prebuilt options in the `fields/` dir. +// pub(crate) trait HasGetModulusBits { +// fn get_modulus_bits() -> u32; // This needs to be a comptime const, so that it can be used as an argument to std::field::assert_constant() +// } + +// impl HasGetModulusBits for BigNumParams {} +// impl RuntimeBigNumParamsTrait for BigNumParams {} + +impl BigNumParams { + fn new( + has_multiplicative_inverse: bool, + modulus_bits_getter: fn() -> u32, + modulus: [Field; N], + redc_param: [Field; N] + ) -> Self { + Self { + has_multiplicative_inverse, + modulus_bits_getter, + modulus, + modulus_u60: U60Repr::from(modulus), + modulus_u60_x4: U60Repr::from(modulus), + double_modulus: get_double_modulus(modulus), + redc_param + } + } +} + +fn get_double_modulus(modulus: [Field; N]) -> [Field; N] { + let TWO_POW_120: Field = 0x1000000000000000000000000000000; + let m: U60Repr = U60Repr::from(modulus); + let mut result: [Field; N] = U60Repr::into(m + m); + + result[0] += TWO_POW_120; + for i in 1..N - 1 { + result[i] += (TWO_POW_120 - 1); + } + result[N - 1] -= 1; + result +} + +// /** +// * @brief BigNumParamsTrait defines a "field" with which to parametrise BigNum. +// * @description The "field" does not need to be prime, any value *should* work (TODO: test!) +// **/ +// trait BigNumParamsTrait { +// fn has_multiplicative_inverse() -> bool; +// // @brief modulus_bits = log2(modulus) rounded up +// fn modulus_bits() -> u32; +// fn modulus() -> [Field; N]; +// fn modulus_u60() -> U60Repr; +// fn modulus_u60_x4() -> U60Repr; +// // @brief double_modulus: used when performing negations and subtractions +// fn double_modulus() -> [Field; N]; +// // redc_param used for __barrett_reduction. See https://en.wikipedia.org/wiki/Barrett_reduction +// redc_param: [Field; N], +// } + diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index cd7e45e9..37280282 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -1,1551 +1,344 @@ -use crate::utils::u60_representation::U60Repr; -use crate::utils::split_bits; -use crate::BigNum; -/** - * @brief runtime_bignum::BigNumTrait defines methods available to BigNum *if* the modulus is not known at compile time. - * e.g. RSA where the modulus is a witness value as it changes for every RSA signature - * tee `lib.nr` for a trait definition where the modulus is known at compile time - **/ -pub trait BigNumTrait { - fn new() -> Self; - fn one() -> Self; - fn from(limbs: [Field]) -> Self; - fn from_be_bytes(x: [u8; NBytes]) -> Self; - fn to_le_bytes(val: Self) -> [u8; NBytes]; - fn get(self) -> [Field]; - fn get_limb(self, idx: u64) -> Field; - fn set_limb(&mut self, idx: u32, value: Field); - fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; - fn validate_in_range(self); - fn validate_quotient_in_range(self); - fn __is_zero(self) -> bool; - fn __eq(self, rhs: Self) -> bool; -} - -/** - * @brief BigNumInstanceTrait defines methods available to a runtime BigNumInstance. - * BigNumInstance wraps the modulus parameter (as well as a Barret reduction parameter), - * which is required for the majority of BigNum operations - **/ -pub trait BigNumInstanceTrait where BN: BigNumTrait { - fn modulus(self) -> BN; - fn __derive_from_seed(self, seed: [u8; SeedBytes]) -> BN; - fn eq(self, lhs: BN, rhs: BN) -> bool; - fn __neg(self, val: BN) -> BN; - fn __add(self, lhs: BN, rhs: BN) -> BN; - fn __sub(self, lhs: BN, rhs: BN) -> BN; - fn __mul(self, lhs: BN, rhs: BN) -> BN; - fn __div(self, lhs: BN, rhs: BN) -> BN; - fn __batch_invert(self, x: [BN; M]) -> [BN; M]; - fn __udiv_mod(self, numerator: BN, divisor: BN) -> (BN, BN); - fn __invmod(self, val: BN) -> BN; - fn __pow(self, val: BN, exponent: BN) -> BN; - fn __compute_quadratic_expression( - self, - lhs_terms: [[BN; LHS_N]; NUM_PRODUCTS], - lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], - rhs_terms: [[BN; RHS_N]; NUM_PRODUCTS], - rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], - linear_terms: [BN; ADD_N], - linear_flags: [bool; ADD_N] - ) -> (BN, BN); - - fn evaluate_quadratic_expression( - self, - lhs_terms: [[BN; LHS_N]; NUM_PRODUCTS], - lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], - rhs_terms: [[BN; RHS_N]; NUM_PRODUCTS], - rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], - linear_terms: [BN; ADD_N], - linear_flags: [bool; ADD_N] - ); - - fn validate_in_field(self, val: BN); - fn validate_gt(self, lhs: BN, rhs: BN); - fn assert_is_not_equal(self, lhs: BN, rhs: BN); - fn neg(self, val: BN) -> BN; - fn add(self, lhs: BN, rhs: BN) -> BN; - fn sub(self, lhs: BN, rhs: BN) -> BN; - fn mul(self, lhs: BN, rhs: BN) -> BN; - fn div(self, lhs: BN, rhs: BN) -> BN; - fn udiv_mod(self, numerator: BN, divisor: BN) -> (BN, BN); - fn udiv(self, numerator: BN, divisor: BN) -> BN; - fn umod(self, numerator: BN, divisor: BN) -> BN; - -} - -/** - * @brief BigNumParamsTrait defines a "field" with which to parametrise BigNum. - * @description The "field" does not need to be prime, any value *should* work (TODO: test!) -**/ -pub trait BigNumParamsTrait { - /** - * @brief modulus_bits = log2(modulus) rounded up - **/ - fn modulus_bits() -> u32; - - fn has_multiplicative_inverse() -> bool { true } -} - -pub struct BigNumInstance { - - /** - * @brief modulus: all BigNum operations are evaluated modulo this value - **/ - modulus: [Field; N], - - /** - * @brief modulus but represented in a U60Repr form - **/ - modulus_u60: U60Repr, - modulus_u60_x4: U60Repr, - - // /** - // * @brief double_modulus: used when performing negations and subtractions - // **/ - double_modulus: [Field; N], - // /** - // * @brief redc_param used for __barrett_reduction. See https://en.wikipedia.org/wiki/Barrett_reduction - // **/ - redc_param: [Field; N], -} - -impl BigNum { - // some strange circular dependency problem means we need to define `new` as a member of BigNumTrait as well as a definition outside of the trait - // (delete this method to see. BigNumInstance methods that use BigNum::new() error out, and I can't find a way of declaring BigNum to satisfy BigNumTrait as part of the BigNumInstance definition because BigNumInstance has no contextual knowledge of the BigNum type...) - fn new() -> Self { - BigNum { limbs: [0; N] } - } - fn one() -> BigNum { - let mut result: Self = BigNum { limbs: [0; N] }; - result.limbs[0] = 1; - result - } -} - -impl BigNumTrait for BigNum where Params: BigNumParamsTrait { - - fn new() -> Self { - BigNum::new() - } - fn one() -> Self { - BigNum::one() - } - - fn from(limbs: [Field]) -> Self { - BigNum { limbs: limbs.as_array() } - } - - /** - * @brief construct a BigNum instance out of an array of bytes in BIG ENDIAN format - * @description: each 120-bit limb represents 15 bytes, we require that the size of the byte array - * is precisely large enough to cover Params::modulus_bits() - * @param x: input byte array - **/ - fn from_be_bytes(x: [u8; NBytes]) -> BigNum { - let num_bits = NBytes * 8; - let modulus_bits = Params::modulus_bits(); - assert(num_bits >= modulus_bits); - assert(num_bits - modulus_bits < 8); - let mut result = BigNum::new(); - - let excess_bytes = N * 15 - NBytes; - let final_limb_bytes = 15 - excess_bytes; - let mut limb: Field = 0; - let mut k = 0; - for _j in 0..final_limb_bytes { - limb *= 256; - limb += x[k] as Field; - k += 1; - } - result.limbs[N - 1] = limb; - - for i in 1..N { - let mut limb: Field = 0; - for _j in 0..15 { - limb *= 256; - limb += x[k] as Field; - k += 1; - } - result.limbs[N - i - 1] = limb; - } - - // max_bits_in_most_significant_byte should be known at comptime. if not...messy! - let mut max_bits_in_most_significant_byte = 8 - (num_bits - modulus_bits); - - let most_significant_byte: Field = x[0] as Field; - - most_significant_byte.assert_max_bit_size(max_bits_in_most_significant_byte as u32); - result - } - - fn to_le_bytes(val: BigNum) -> [u8; NBytes] { - let nbytes = (Params::modulus_bits() / 8) + (Params::modulus_bits() % 8 != 0) as u32; - assert(nbytes <= NBytes); - - let mut result: [u8; NBytes] = [0; NBytes]; - for i in 0..N - 1 { - let limb_bytes: [u8; 15] = val.limbs[i].to_le_bytes(); - for j in 0..15 { - result[i * 15 + j] = limb_bytes[j]; - } - } - let last_limb_bytes: [u8; 15] = val.limbs[N - 1].to_le_bytes(); - let num_last_bytes = (NBytes - (N - 1) * 15); - for i in 0..num_last_bytes { - result[(N-1) * 15 + i] = last_limb_bytes[i]; - } - result - } - - fn get(self) -> [Field] { - self.limbs - } - fn get_limb(self, idx: u64) -> Field { - self.limbs[idx] - } - fn set_limb(&mut self, idx: u32, value: Field) { - self.limbs[idx] = value; - } - - /** - * @brief conditional_select given the value of `predicate` return either `self` (if 0) or `other` (if 1) - * @description should be cheaper than using an IF statement (TODO: check!) - **/ - fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self { - let mut result: Self = lhs; - for i in 0..N { - result.limbs[i] = (lhs.limbs[i] - rhs.limbs[i]) * predicate as Field + rhs.limbs[i]; - } - result - } - - /** - * @brief Validate a BigNum instance is correctly range constrained to contain no more than Params::modulus_bits() - **/ - fn validate_in_range(self) { - for i in 0..(N - 1) { - self.limbs[i].assert_max_bit_size(120); - } - let final_limb_bits = Params::modulus_bits() - ((N - 1) * 120); - self.limbs[N - 1].assert_max_bit_size(final_limb_bits as u32); - } - - /** - * @brief validate quotient produced from `evaluate_quadratic_expression` is well-formed - * @description because the inputs into evaluate_quadratic_expression may cause the quotient to extend beyond `Params::modulus_bits`. - * We allow the quotient to extend 6 bits beyond Params::modulus_bits() - * Why is this? - * several factors: 1. quotient * modulus , limbs cannot overflow field boundary (254 bits) - * 2. in `evaluate_quadratic_expression`, we require that for `expression - quotient * modulus`, - * limbs cannot exceed 246 bits (246 magic number due to a higher number adding extra range check gates) - * because of factor 2 and the fact that modulus limbs are 120 bits, quotient limbs cannot be >126 bits - * - * Note: doesn't this mean that final_limb_bits should be constrained to be 126 bits, not modulus_bits() - ((N - 1) * 120) + 6? - * TODO: think about this more! we want the range constraint we apply to be as small as allowable as this is more efficient - **/ - fn validate_quotient_in_range(self) { - for i in 0..(N) { - self.limbs[i].assert_max_bit_size(120); - } - // Note: replace magic number 6 with definition - let final_limb_bits = Params::modulus_bits() - ((N - 1) * 120) + 6; - self.limbs[N - 1].assert_max_bit_size(final_limb_bits as u32); - } - - fn __is_zero(self) -> bool { - self.__is_zero_impl() - } - - fn __eq(self, rhs: Self) -> bool { - self.__eq_impl(rhs) - } -} - -impl BigNum where Params: BigNumParamsTrait { - - fn from_array(limbs: [Field; N]) -> BigNum { - BigNum { limbs } - } - - unconstrained fn __is_zero_impl(self) -> bool { - let mut result: bool = true; - for i in 0..N { - result = result & (self.limbs[i] == 0); - } - result - } - - unconstrained fn __eq_impl(lhs: Self, rhs: Self) -> bool { - lhs.limbs == rhs.limbs - } +use dep::std; +use crate::utils::map::map; + +use crate::params::BigNumParams; +use crate::constrained_ops::{ + conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, neg, add, sub, + mul, div, udiv_mod, udiv, umod +}; +use crate::unconstrained_ops::{ + __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, + __batch_invert, __batch_invert_slice +}; +use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}; +use crate::serialization::{from_be_bytes, to_le_bytes}; + +pub struct RuntimeBigNum { + limbs: [Field; N], + params: BigNumParams, } -impl BigNumInstanceTrait> for BigNumInstance where Params: BigNumParamsTrait { +impl RuntimeBigNum {} - fn modulus(self) -> BigNum { - BigNum { limbs: self.modulus } - } - fn __derive_from_seed(self, seed: [u8; SeedBytes]) -> BigNum { - self.__derive_from_seed_impl(seed) - } - // #################################################################################################################### - // #################################################################################################################### - // ### U N C O N S T R A I N E D F U N C T I O N S - // ### NOTE: these functions call unconstrained internal implementations because trait impl modifiers are not supported - // #################################################################################################################### - // #################################################################################################################### +pub(crate) trait RuntimeBigNumTrait { + fn new(params: BigNumParams) -> Self; + fn one(params: BigNumParams) -> Self; + unconstrained fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; + fn from_slice(params: BigNumParams, limbs: [Field]) -> Self; + fn from_array(params: BigNumParams, limbs: [Field; N]) -> Self; + fn from_be_bytes(params: BigNumParams, x: [u8; NBytes]) -> Self; - fn __neg(self, val: BigNum) -> BigNum { - self.__neg_impl(val) - } + fn to_le_bytes(self) -> [u8; NBytes]; - fn __add(self, lhs: BigNum, rhs: BigNum) -> BigNum { - self.__add_impl(lhs, rhs) - } + fn modulus(self) -> Self; + fn modulus_bits(self) -> u32; + fn num_limbs() -> u32; + // fn get(self) -> [Field]; + fn get_limbs(self) -> [Field; N]; + fn get_limb(self, idx: u32) -> Field; + fn set_limb(&mut self, idx: u32, value: Field); - fn __sub(self, lhs: BigNum, rhs: BigNum) -> BigNum { - self.__sub_impl(lhs, rhs) - } + unconstrained fn __eq(self, other: Self) -> bool; + unconstrained fn __is_zero(self) -> bool; - fn __mul(self, lhs: BigNum, rhs: BigNum) -> BigNum { - self.__mul_impl(lhs, rhs) - } + unconstrained fn __neg(self) -> Self; + unconstrained fn __add(self, other: Self) -> Self; + unconstrained fn __sub(self, other: Self) -> Self; + unconstrained fn __mul(self, other: Self) -> Self; + unconstrained fn __div(self, other: Self) -> Self; + unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self); + unconstrained fn __invmod(self) -> Self; + unconstrained fn __pow(self, exponent: Self) -> Self; - fn __div(self, lhs: BigNum, rhs: BigNum) -> BigNum { - self.__div_impl(lhs, rhs) - } + unconstrained fn __batch_invert(x: [Self; M]) -> [Self; M]; + unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; - fn __batch_invert(self, x: [BigNum; M]) -> [BigNum; M] { - self.batch_invert_impl(x) - } - - fn __invmod(self, val: BigNum) -> BigNum { - self.__invmod_impl(val) - } - - fn __pow(self, val: BigNum, exponent: BigNum) -> BigNum { - self.__pow_impl(val, exponent) - } - - fn __compute_quadratic_expression( - self, - lhs_terms: [[BigNum; LHS_N]; NUM_PRODUCTS], + unconstrained fn __compute_quadratic_expression( + params: BigNumParams, + lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], - rhs_terms: [[BigNum; RHS_N]; NUM_PRODUCTS], + rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], - linear_terms: [BigNum; ADD_N], + linear_terms: [Self; ADD_N], linear_flags: [bool; ADD_N] - ) -> (BigNum, BigNum) { - self.__compute_quadratic_expression_impl( - lhs_terms, - lhs_flags, - rhs_terms, - rhs_flags, - linear_terms, - linear_flags - ) - } + ) -> (Self, Self); - // #################################################################################################################### - // #################################################################################################################### - // ### C O N S T R A I N E D F U N C T I O N S - // #################################################################################################################### - // #################################################################################################################### - - /** - * @brief Constrain a degree-2 BigNum expression to be equal to 0 modulo self.modulus - * @description The expression is of the form (when evaluated as an integer relation): - * - * \sum_{i=0}^{NUM_PRODUCTS - 1} ((\sum_{j=0}^{LHS_N-1}lhs[i][j]) * (\sum_{j=0}^{RHS_N-1}rhs[i][j])) + \sum_{i=0}^{ADD_N - 1}linear_terms[i] - quotient * modulus = 0 - * - * The intent is to capture an arbitrary degree-2 expression within the limitations of Noir (no efficient dynamically-sized vectors) - * - * Note: this method requires the remainder term of the expression to be ZERO - * When performing BigNum arithmetic, we want to represent desired BigNum operations in a way that minimizes the number of modular reductions that are required. - * This can be achieved by minimizing the number of degree-2 relations required. - * - * The expensive parts of this algorithm are the following: - * 1. evaluating the limb products required to compute `lhs * rhs` - * 2. applying range constraints to validate the result is 0 - * - * Range constraints are needed for the following reason: - * When evaluating the above expression over N-limb BigNum objects, the result will consist of 2N - 1 limbs. - * Each limb will be in the range [0, ..., 2^{240 + twiddle_factor} - 1] (twiddle_factor needs to be less than 6). - * Because of the subtractions, the limbs may underflow and represent NEGATIVE values. - * To account for this, we allow the Prover to borrow values from more significant limbs and add them into less significant limbs - * (explicitly, we can borrow 2^{126} from limb `i + 1` to add `2^{246}` into `i`). - * To ensure this has been done correctly, we validate that the borrow-adjusted limbs are all-zero for the first 120 bits. - * We do *this* by multiplying the borrow-adjusted limbs by 1 / 2^{120} modulo CircutModulus, and we validate the result is in the range [0, ..., 2^{126} - 1]. - * TODO: explain why this check works. It's statistically sound but not perfectly sound. Chance of the check failing is ~1 in 2^{120} - * I believe this is the most efficient way of performing the zero-check for this relation as it only requires `2N - 2` 126-bit range checks. - * TODO: explain why we apply a 126-bit range check, this feels like a magic number - * (it is. we could go higher, up to the number of bits in the CircuitModulus - 121, but 126 *should be* sufficient and is much cheaper) - * TODO: apply checks in this method to validate twiddle_factor does not exceed 6 - * - * @param lhs_terms a 2D array of BigNum - * @param lhs_flags a 2D array of sign flags - * @param rhs_terms a 2D array of BigNum - * @param rhs_flags a 2D array of sign flags - * @param linear_terms an array of BigNum - * @param linear_flags an array of sign flags - **/ fn evaluate_quadratic_expression( - self, - lhs_terms: [[BigNum; LHS_N]; NUM_PRODUCTS], + params: BigNumParams, + lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], - rhs_terms: [[BigNum; RHS_N]; NUM_PRODUCTS], + rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], - linear_terms: [BigNum; ADD_N], + linear_terms: [Self; ADD_N], linear_flags: [bool; ADD_N] - ) { - // use an unconstrained function to compute the value of the quotient - let (quotient, _, borrow_flags): (BigNum, BigNum, [Field; 2 * N]) = unsafe { - self.__compute_quadratic_expression_with_borrow_flags( - lhs_terms, - lhs_flags, - rhs_terms, - rhs_flags, - linear_terms, - linear_flags - ) - }; - // constrain the quotient to be in the range [0, ..., 2^{m} - 1], where `m` is log2(modulus) rounded up. - // Additionally, validate quotient limbs are also in the range [0, ..., 2^{120} - 1] - quotient.validate_quotient_in_range(); - // TODO, validate we do not overflow N2 when multiplying and N when adding - // (should be a compile-time check...unconstrained function?) - - // Compute the linear sums that represent lhs_1, rhs_1, lhs_2, rhs_2, add - let mut t0: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS]; - let mut t1: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS]; - let mut t4: [Field; N] = [0; N]; - - // TODO: this is super nasty as it requires a multiplication - let double_modulus: [Field; N] = self.double_modulus; - for k in 0..NUM_PRODUCTS { - for i in 0..N { - for j in 0..LHS_N { - // note: if is_negative is not known at comptime this is very expensive - if (lhs_flags[k][j]) { - t0[k][i] -= lhs_terms[k][j].limbs[i]; - t0[k][i] += double_modulus[i]; - } else { - t0[k][i] += lhs_terms[k][j].limbs[i]; - } - } - for j in 0..RHS_N { - if (rhs_flags[k][j]) { - t1[k][i] -= rhs_terms[k][j].limbs[i]; - t1[k][i] += double_modulus[i]; - } else { - t1[k][i] += rhs_terms[k][j].limbs[i]; - } - } - } - } - for i in 0..N { - for j in 0..ADD_N { - if (linear_flags[j]) { - t4[i] -= linear_terms[j].limbs[i]; - t4[i] += double_modulus[i]; - } else { - t4[i] += linear_terms[j].limbs[i]; - } - } - } - - // We want to evaluate that t0 * t1 + t2 * t3 + t4 - Quotient * Modulus = 0, evaluated over the integers - // For this we need to be able to borrow values from more-significant limbs into less-significant limbs, - // so that we can ensure that no limbs will underflow for an honest Prover - let mut product_limbs: [Field; 2 * N] = [0; 2 * N]; - - // Compute the product t0 * t1 + t2 * t3 + t4 - Quotient * Modulus - // TODO: this is super nasty as it requires a multiplication - for i in 0..N { - for j in 0..N { - for k in 0..NUM_PRODUCTS { - if k == 0 { - let new_term = t0[k][i] * t1[k][j] - quotient.limbs[i] * self.modulus[j]; - std::as_witness(new_term); // width-4 optimization (n.b. might not be optimal if t2, t3 input arrays are nonzero) - product_limbs[i + j] += new_term; - } else { - product_limbs[i + j] += t0[k][i] * t1[k][j]; - } - } - if (NUM_PRODUCTS == 0) { - product_limbs[i + j] -= quotient.limbs[i] * self.modulus[j]; - } - } - product_limbs[i] += t4[i]; - } - - // each limb product represents the sum of 120-bit products. - // by setting the borrow value to 2^246 we are restricting this method's completeness to expressions - // where no more than 64 limb products are summed together. - // TODO: check in unconstrained function that this condition is satisfied - // TODO: define trade-offs regarding the value of borrow_shift - // (the larger the value, the greater the range check that is required on product_limbs) - // (126-bit range check is a sweet spot for the barretenberg backend as it decomposes into 9 14-bit range checks) - // (the barretenberg backend can evaluate these in 5.25 gates. 127 bits costs 6.5 gates) - let borrow_shift: Field = 0x40000000000000000000000000000000000000000000000000000000000000; // 2^{246} - let borrow_carry: Field = 0x40000000000000000000000000000000; // 2^{246 - 120} = 2^{126} - - // N.B. borrow_flags is `Field` type because making it `bool` would apply boolean constraints to all `N2` array entries. - // We only use `N2 - 2` borrow flags so applying 1-bit range checks on the array elements we use is more efficient. - // TODO: Once it is possible to perform arithmetic on generics we can use `borrow_flags: [bool;N+N-2]` to avoid this issue - borrow_flags[0].assert_max_bit_size(1); - product_limbs[0] += borrow_flags[0] * borrow_shift; - for i in 1..(N + N - 2) { - borrow_flags[i].assert_max_bit_size(1); - product_limbs[i] += - (borrow_flags[i] * borrow_shift - borrow_flags[i - 1] * borrow_carry); - } - product_limbs[N + N - 2] -= borrow_flags[N + N - 3] * borrow_carry; - - // Final step: Validate `product_limbs` represents the integer value `0` - // Each element `i` in `product_limbs` overlaps in bitrange with element `i+1`, EXCEPT for the low 120 bits - // i.e. we need to do the following for each limb `i`: - // 1. validate the limb's low-120 bits equals zero - // 2. compute the limb "carry" by right-shifting by 2^{120} - // 3. add the carry into limb `i+1` - // We can efficiently do all of the above by multiplying the limb by 2^{-120} and constraining the result to be <2^{126} - // (if the low 120 bits are nonzero the result will underflow and product a large value that cannot be range constrained) - // (the probability of an underflow value satisfying a 126-bit range constraint is approx. 2^{k - 126}, - // where k is the number of bits in the prime field) - // We then add the result into the next limb and repeat. - let hi_shift: Field = 0x1000000000000000000000000000000; - let hi_downshift: Field = 1 / hi_shift; - for i in 0..N + N - 2 { - product_limbs[i] *= hi_downshift; - std::as_witness(product_limbs[i]); - product_limbs[i].assert_max_bit_size(126); // N.B. is this sufficient? going beyond 126 costs us 1 gate per limb - product_limbs[i + 1] += product_limbs[i]; - } - // the most significant limb has no limb to "carry" values into - the entire limb must equal zero - assert(product_limbs[N + N - 2] == 0); - } - - fn validate_in_field(self, val: BigNum) { - // N.B. need to combine with validate_in_range if `self` limbs have not been range constrained - let mut p_minus_self: [Field; N] = [0; N]; - let modulus: [Field; N] = self.modulus; - for i in 0..N { - p_minus_self[i] = modulus[i] - val.limbs[i]; - } - let borrow_flags = unsafe { - self.__validate_in_field_compute_borrow_flags(val) - }; - let two_pow_120: Field = 0x1000000000000000000000000000000; - p_minus_self[0] += borrow_flags[0] as Field * two_pow_120; - for i in 1..N - 1 { - p_minus_self[i] += (borrow_flags[i] as Field * two_pow_120 - borrow_flags[i-1] as Field); - } - p_minus_self[N - 1] -= borrow_flags[N - 2] as Field; - let mut compare = val; - compare.limbs = p_minus_self; - compare.validate_in_range(); - } - - /** - * @brief Validate self != other - * @details If A == B, then A == B mod N. - * We can efficiently evaluate A == B mod N where N = circuit modulus - * This method is *sound*, but not *complete* (i.e. A != B but A == B mod N) - * However the probability of an honest Prover being unable to satisfy this check is tiny! - * (todo: compute how tiny) - **/ - fn assert_is_not_equal(self, lhs: BigNum, rhs: BigNum) { - let mut l: Field = 0; - let mut r: Field = 0; - let mut modulus_mod_n: Field = 0; - let mut two_pow_120: Field = 0x1000000000000000000000000000000; - let modulus = self.modulus; - for i in 0..N { - l *= two_pow_120; - r *= two_pow_120; - modulus_mod_n *= two_pow_120; - l += lhs.limbs[N - i - 1]; - r += rhs.limbs[N - i - 1] ; - modulus_mod_n += modulus[N - i - 1]; - } - - // lhs can be either X mod N or P + X mod N - // rhs can be either Y mod N or P + Y mod N - // If lhs - rhs = 0 mod P then lhs - rhs = 0, P or -P mod N - let mut diff = l - r; - let mut target = diff * (diff + modulus_mod_n) * (diff - modulus_mod_n); - assert(target != 0, "asssert_is_not_equal fail"); - } - - fn eq(self, lhs: BigNum, rhs: BigNum) -> bool { - let diff = self.sub(lhs, rhs); - // if self == other, possible values of `diff` will be `p` or `0` - // (the subtract operator constrains diff to be < ceil(log(p))) - // TODO: can do this more efficiently via witngen in unconstrained functions? - let mut is_equal_modulus: bool = true; - let mut is_equal_zero: bool = true; - for i in 0..N { - is_equal_modulus = is_equal_modulus & (diff.limbs[i] == self.modulus[i]); - is_equal_zero = is_equal_zero & (diff.limbs[i] == 0); - } - is_equal_modulus | is_equal_zero - } - - fn neg(self, val: BigNum) -> BigNum { - // so we do... p - x - r = 0 and there might be borrow flags - let (result, borrow_flags) = unsafe { - self.__neg_with_flags(val) - }; - result.validate_in_range(); - let modulus = self.modulus; - let borrow_shift = 0x1000000000000000000000000000000; - let result_limb = modulus[0] - val.limbs[0] - result.limbs[0] + (borrow_flags[0] as Field * borrow_shift); - assert(result_limb == 0); - for i in 1..N - 1 { - let result_limb = modulus[i] - val.limbs[i] - result.limbs[i] - borrow_flags[i - 1] as Field - + (borrow_flags[i] as Field * borrow_shift); - assert(result_limb == 0); - } - let result_limb = modulus[N - 1] - val.limbs[N - 1] - result.limbs[N - 1] - borrow_flags[N - 2] as Field; - assert(result_limb == 0); - result - } - - fn add(self, lhs: BigNum, rhs: BigNum) -> BigNum { - // so we do... p - x - r = 0 and there might be borrow flags - let (result, carry_flags, borrow_flags, overflow_modulus) = unsafe { - self.__add_with_flags(lhs, rhs) - }; - result.validate_in_range(); - let modulus = self.modulus; - let borrow_shift = 0x1000000000000000000000000000000; - let carry_shift = 0x1000000000000000000000000000000; - - let mut subtrahend: [Field; N] = [0; N]; - if (overflow_modulus) { - subtrahend = modulus; - } - let result_limb = lhs.limbs[0] + rhs.limbs[0] - subtrahend[0] - result.limbs[0] - + (borrow_flags[0] as Field * borrow_shift) - - (carry_flags[0] as Field * carry_shift); - assert(result_limb == 0); - for i in 1..N - 1 { - let result_limb = lhs.limbs[i] + rhs.limbs[i] - - subtrahend[i] - - result.limbs[i] - - borrow_flags[i - 1] as Field - + carry_flags[i - 1] as Field - + ((borrow_flags[i] as Field - carry_flags[i] as Field) * borrow_shift); - assert(result_limb == 0); - } - let result_limb = lhs.limbs[N - 1] + rhs.limbs[N - 1] - - subtrahend[N - 1] - - result.limbs[N - 1] - - borrow_flags[N - 2] as Field - + carry_flags[N - 2] as Field; - assert(result_limb == 0); - result - } + ); - // validate that lhs - rhs does not underflow i.e. lhs > rhs - fn validate_gt(self, lhs: BigNum, rhs: BigNum) { - // so we do... p - x - r = 0 and there might be borrow flags + fn eq(lhs: Self, rhs: Self) -> bool { lhs == rhs } + fn assert_is_not_equal(self, other: Self); + fn validate_in_field(self); + fn validate_in_range(self); + // fn validate_gt(self, lhs: Self, rhs: Self); - // a - b = r - // p + a - b - r = 0 - let (result, carry_flags, borrow_flags) = unsafe { - self.__validate_gt_remainder(lhs, rhs) - }; + fn neg(self) -> Self; + fn add(lhs: Self, rhs: Self) -> Self { lhs + rhs } + fn sub(lhs: Self, rhs: Self) -> Self { lhs - rhs } + fn mul(lhs: Self, rhs: Self) -> Self { lhs * rhs } + fn div(lhs: Self, rhs: Self) -> Self { lhs / rhs } + fn udiv_mod(numerator: Self, divisor: Self) -> (Self, Self); + fn udiv(numerator: Self, divisor: Self) -> Self; + fn umod(numerator: Self, divisor: Self) -> Self; - result.validate_in_range(); + fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; +} - let borrow_shift = 0x1000000000000000000000000000000; - let carry_shift = 0x1000000000000000000000000000000; +impl RuntimeBigNumTrait for RuntimeBigNum { - let mut addend: [Field; N] = [0; N]; - let result_limb = lhs.limbs[0] - rhs.limbs[0] + addend[0] - result.limbs[0] - 1 - + (borrow_flags[0] as Field * borrow_shift) - - (carry_flags[0] as Field * carry_shift); - assert(result_limb == 0); - for i in 1..N - 1 { - let result_limb = lhs.limbs[i] - rhs.limbs[i] + addend[i] - result.limbs[i] - borrow_flags[i - 1] as Field - + carry_flags[i - 1] as Field - + ((borrow_flags[i] as Field - carry_flags[i] as Field) * borrow_shift); - assert(result_limb == 0); - } - let result_limb = lhs.limbs[N - 1] - rhs.limbs[N - 1] + addend[N - 1] - - result.limbs[N - 1] - - borrow_flags[N - 2] as Field - + carry_flags[N - 2] as Field; - assert(result_limb == 0); + fn new(params: BigNumParams) -> Self { + let limbs: [Field; N] = [0; N]; + Self { limbs, params } } - fn sub(self, lhs: BigNum, rhs: BigNum) -> BigNum { - // so we do... p - x - r = 0 and there might be borrow flags - - // a - b = r - // p + a - b - r = 0 - let (result, carry_flags, borrow_flags, underflow) = unsafe { - self.__sub_with_flags(lhs, rhs) - }; - result.validate_in_range(); - let modulus = self.modulus; - let borrow_shift = 0x1000000000000000000000000000000; - let carry_shift = 0x1000000000000000000000000000000; - - let mut addend: [Field; N] = [0; N]; - if (underflow) { - addend = modulus; - } - let result_limb = lhs.limbs[0] - rhs.limbs[0] + addend[0] - result.limbs[0] - + (borrow_flags[0] as Field * borrow_shift) - - (carry_flags[0] as Field * carry_shift); - assert(result_limb == 0); - for i in 1..N - 1 { - let result_limb = lhs.limbs[i] - rhs.limbs[i] + addend[i] - result.limbs[i] - borrow_flags[i - 1] as Field - + carry_flags[i - 1] as Field - + ((borrow_flags[i] as Field - carry_flags[i] as Field) * borrow_shift); - assert(result_limb == 0); - } - let result_limb = lhs.limbs[N - 1] - rhs.limbs[N - 1] + addend[N - 1] - - result.limbs[N - 1] - - borrow_flags[N - 2] as Field - + carry_flags[N - 2] as Field; - assert(result_limb == 0); - result - } - // 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, lhs: BigNum, rhs: BigNum) -> BigNum { - let result = self.__mul(lhs, rhs); - self.evaluate_quadratic_expression([[lhs]], [[false]], [[rhs]], [[false]], [result], [true]); - result - } - // Note: this method is expensive! Witness computation is extremely expensive as it requires modular exponentiation - fn div(self, lhs: BigNum, rhs: BigNum) -> BigNum { - assert( - Params::has_multiplicative_inverse(), "BigNum has no multiplicative inverse. Use udiv for unsigned integer division" - ); - let result = self.__div(lhs, rhs); - self.evaluate_quadratic_expression([[result]], [[false]], [[rhs]], [[false]], [lhs], [true]); + fn one(params: BigNumParams) -> Self { + let mut result = RuntimeBigNum::new(params); + result.limbs[0] = 1; result } - /** - * @brief __udiv_mod performs *unconstrained* integer division between numerator, divisor - * - * i.e. 1. floor(numerator / divisor) = quotient - * 2. numerator % divisor = remainder - * 3. divisor * quotient + remainder = numerator - **/ - fn __udiv_mod( - self, - numerator: BigNum, - divisor: BigNum - ) -> (BigNum, BigNum) { - self.__udiv_mod_impl(numerator, divisor) + unconstrained fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self { + Self { limbs: __derive_from_seed(params, seed), params } } - /** - * @brief udiv_mod performs integer division between numerator, divisor - * - * i.e. 1. floor(numerator / divisor) = quotient - * 2. numerator % divisor = remainder - * 3. divisor * quotient + remainder = numerator - **/ - fn udiv_mod( - self, - numerator: BigNum, - divisor: BigNum - ) -> (BigNum, BigNum) { - let (quotient, remainder) = BigNumInstance::__udiv_mod_impl(self, numerator, divisor); - // self / divisor = quotient rounded - // quotient * divisor + remainder - self = 0 - self.evaluate_quadratic_expression( - [[quotient]], - [[false]], - [[divisor]], - [[false]], - [numerator, remainder], - [true, false] - ); - // we need (remainder < divisor) - // implies (divisor - remainder > 0) - self.validate_gt(divisor, remainder); - (quotient, remainder) + fn from_slice(params: BigNumParams, limbs: [Field]) -> Self { + Self { limbs: limbs.as_array(), params } } - /** - * @brief udiv_mod performs integer division between numerator, divisor - * - * i.e. return param is floor(numerator / divisor) - **/ - fn udiv(self, numerator: BigNum, divisor: BigNum) -> BigNum { - self.udiv_mod(numerator, divisor).0 + fn from_array(params: BigNumParams, limbs: [Field; N]) -> Self { + Self { limbs, params } } - /** - * @brief udiv_mod performs integer modular reduction - * - * i.e. 1. numerator % divisor = return value - **/ - fn umod(self, numerator: BigNum, divisor: BigNum) -> BigNum { - self.udiv_mod(numerator, divisor).1 + fn from_be_bytes(params: BigNumParams, x: [u8; NBytes]) -> Self { + Self { limbs: from_be_bytes(params, x), params } } -} - -impl BigNumInstance where Params: BigNumParamsTrait { - // #################################################################################################################### - // #################################################################################################################### - // ### C O N S T R U C T O R S - // #################################################################################################################### - // #################################################################################################################### - - fn new(modulus: [Field; N], redc_param: [Field; N]) -> Self { - Self { - redc_param, - modulus, - modulus_u60: U60Repr::from(modulus), - modulus_u60_x4: U60Repr::from(modulus), - double_modulus: get_double_modulus(modulus) - } + fn to_le_bytes(self) -> [u8; NBytes] { + to_le_bytes(self.params, self.limbs) } - unconstrained fn __derive_from_seed_impl(self, seed: [u8; SeedBytes]) -> BigNum { - let mut rolling_seed = seed; - - let mut to_reduce: [Field; 2 * N] = [0; 2 * N]; - - let mut double_modulus_bits = Params::modulus_bits() * 2; - let mut double_modulus_bytes = (double_modulus_bits) / 8 + (double_modulus_bits % 8 != 0) as u32; - - let mut last_limb_bytes = double_modulus_bytes % 15; - if (last_limb_bytes == 0) { - last_limb_bytes = 15; - } - let mut last_limb_bits = double_modulus_bits % 8; - if (last_limb_bits == 0) { - last_limb_bits = 8; - } - - for i in 0..(N - 1) { - let hash: [u8; 32] = std::hash::sha256(rolling_seed); - let mut lo: Field = 0; - let mut hi: Field = 0; - for j in 0..15 { - hi *= 256; - lo *= 256; - - if (i < 2 * N - 2) { - lo += hash[j + 15] as Field; - hi += hash[j] as Field; - } - } - to_reduce[2 * i] = lo; - to_reduce[2 * i + 1] = hi; - rolling_seed[0] += 1; - } - - { - let hash: [u8; 32] = std::hash::sha256(rolling_seed); - let mut hi: Field = 0; - for j in 0..(last_limb_bytes - 1) { - hi *= 256; - hi += hash[j] as Field; - } - hi *= 256; - let last_byte = hash[last_limb_bytes - 1]; - let mask = (1 as u64 << (last_limb_bits) as u8) - 1; - let last_bits = last_byte as u64 & mask; - hi += last_bits as Field; - to_reduce[2 * N - 2] = hi; - } - - let (_, remainder) = __barrett_reduction( - to_reduce, - self.redc_param, - Params::modulus_bits(), - self.modulus, - self.modulus_u60_x4 - ); - let mut result = BigNum::new(); - result.limbs = remainder; - result + fn modulus(self) -> Self { + let params = self.params; + Self { limbs: params.modulus, params } } - // #################################################################################################################### - // #################################################################################################################### - // ### U N C O N S T R A I N E D F U N C T I O N S - // #################################################################################################################### - // #################################################################################################################### - - unconstrained fn __validate_in_field_compute_borrow_flags(self: Self, val: BigNum) -> [bool; N] { - let mut flags: [bool; N] = [false; N]; - let modulus: [Field; N] = self.modulus; - flags[0] = modulus[0].lt(val.limbs[0]); - for i in 1..N - 1 { - flags[i] = modulus[i].lt(val.limbs[i] + flags[i - 1] as Field); - } - flags + fn modulus_bits(self) -> u32 { + let getter = self.params.modulus_bits_getter; + getter() } - unconstrained fn __pow_impl( - self, - val: BigNum, - exponent: BigNum - ) -> BigNum { - let x: U60Repr = U60Repr::from(exponent.limbs); - - let num_bits = Params::modulus_bits() + 1; - - let mut accumulator: BigNum = BigNum::one(); - - for i in 0..num_bits { - accumulator = self.__mul(accumulator, accumulator); - if x.get_bit(num_bits - i - 1) { - accumulator = self.__mul(accumulator, val); - } - } - accumulator + fn num_limbs() -> u32 { + N } - unconstrained fn __mul_with_quotient( - self, - lhs: BigNum, - rhs: BigNum - ) -> (BigNum, BigNum) { - let mut mul: [Field; 2 * N] = [0; 2 * N]; - for i in 0..N { - for j in 0..N { - mul[i + j] += lhs.limbs[i] * rhs.limbs[j]; - } - } - let (q, r) = __barrett_reduction( - split_bits::__normalize_limbs(mul, 2 * N), - self.redc_param, - Params::modulus_bits(), - self.modulus, - self.modulus_u60_x4 - ); + // fn get(self) -> [Field] { + // self.get_limbs() + // } - let mut quotient = BigNum::from_array(q); - let mut remainder = BigNum::from_array(r); - (quotient, remainder) + fn get_limbs(self) -> [Field; N] { + self.limbs } - unconstrained fn __mul_impl( - self, - lhs: BigNum, - rhs: BigNum - ) -> BigNum { - let (_, b) = self.__mul_with_quotient(lhs, rhs); - b + fn get_limb(self, idx: u32) -> Field { + self.limbs[idx] } - unconstrained fn __add_impl( - self, - lhs: BigNum, - rhs: BigNum - ) -> BigNum { - let x_u60 : U60Repr = U60Repr::from(lhs.limbs); - let y_u60 : U60Repr = U60Repr::from(rhs.limbs); - - let mut z_u60 = x_u60 + y_u60; - - if z_u60.gte(self.modulus_u60) { - z_u60 = z_u60 - self.modulus_u60; - } - let mut result = BigNum::from_array(U60Repr::into(z_u60)); - result + fn set_limb(&mut self, idx: u32, value: Field) { + self.limbs[idx] = value; } - /** - * @brief given an input `x`, compute `2p - x` (unconstrained) - * - * @description we subtract the input from double the modulus, because all constrained BigNum operations - * only guarantee that the output is in the range [0, ceil(log2(p))]. - * I.E. the input may be larger than the modulus `p`. - * In order to ensure this operation does not underflow, we compute `2p - x` instead of `p - x`. - * N.B. constrained BigNum operations do not fully constrain outputs to be in the range [0, p-1] - * because such a check is expensive and usually unneccesary. - */ - unconstrained fn __neg_impl(self, val: BigNum) -> BigNum { - let f: [Field; N] = val.limbs; - let x_u60 : U60Repr = U60Repr::from(f); - let mut result = BigNum::from_array(U60Repr::into(self.modulus_u60 - x_u60)); - result + unconstrained fn __eq(self, other: Self) -> bool { + __eq(self.limbs, other.limbs) } - unconstrained fn __add_with_flags( - self, - lhs: BigNum, - rhs: BigNum - ) -> (BigNum, [bool; N], [bool; N], bool) { - let a_u60 : U60Repr = U60Repr::from(lhs.limbs); - let b_u60 : U60Repr = U60Repr::from(rhs.limbs); - let add_u60 = a_u60 + b_u60; - - let overflow = add_u60.gte(self.modulus_u60); - - let mut subtrahend_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; - let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; - - if overflow { - subtrahend_u60 = self.modulus_u60; - } - - let mut carry: u64 = 0; - let mut carry_in: u64 = 0; - let mut borrow: u64 = 0; - let mut borrow_in: u64 = 0; - let mut borrow_flags: [bool; N] = [false; N]; - let mut carry_flags: [bool; N] = [false; N]; - for i in 0..2 * N { - let mut add_term: u64 = a_u60.limbs[i] + b_u60.limbs[i] + carry_in; - carry = (add_term >= 0x1000000000000000) as u64; - add_term -= (carry as u64 * 0x1000000000000000); - result_u60.limbs[i] = add_term; - carry_in = carry as u64; - borrow = ((subtrahend_u60.limbs[i] + borrow_in) > result_u60.limbs[i]) as u64; - let sub = (borrow << 60) + result_u60.limbs[i] - subtrahend_u60.limbs[i] - borrow_in; - result_u60.limbs[i] = sub; - borrow_in = borrow; - - if ((i & 1) == 1) { - let idx = (i - 1) / 2; - if (carry & borrow == 1) { - carry = 0; - borrow = 0; - } - carry_flags[idx] = carry as bool; - borrow_flags[idx] = borrow as bool; - } - } - let mut result = BigNum::from_array(U60Repr::into(result_u60)); - - (result, carry_flags, borrow_flags, overflow) + unconstrained fn __is_zero(self) -> bool { + __is_zero(self.limbs) } - unconstrained fn __validate_gt_remainder( - _: Self, - lhs: BigNum, - rhs: BigNum - ) -> (BigNum, [bool; N], [bool; N]) { - let a_u60 : U60Repr = U60Repr::from(lhs.limbs); - let mut b_u60 : U60Repr = U60Repr::from(rhs.limbs); - - let underflow = b_u60.gte(a_u60); - b_u60 += U60Repr::one(); - assert(underflow == false, "BigNum::validate_gt check fails"); - let mut addend_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; - let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; - - let mut carry: u64 = 0; - let mut carry_in: u64 = 0; - let mut borrow: u64 = 0; - let mut borrow_in: u64 = 0; - let mut borrow_flags: [bool; N] = [false; N]; - let mut carry_flags: [bool; N] = [false; N]; - for i in 0..2 * N { - let mut add_term: u64 = a_u60.limbs[i] + addend_u60.limbs[i] + carry_in; - carry = (add_term >= 0x1000000000000000) as u64; - add_term -= (carry as u64 * 0x1000000000000000); - result_u60.limbs[i] = add_term; - carry_in = carry as u64; - borrow = ((b_u60.limbs[i] + borrow_in) > result_u60.limbs[i]) as u64; - let sub = (borrow << 60) + result_u60.limbs[i] - b_u60.limbs[i] - borrow_in; - result_u60.limbs[i] = sub; - borrow_in = borrow; - - if ((i & 1) == 1) { - if (carry & borrow == 1) { - carry = 0; - borrow = 0; - } - carry_flags[i/2] = carry as bool; - borrow_flags[i/2] = borrow as bool; - } - } - - let mut result = BigNum::from_array(U60Repr::into(result_u60)); - (result, carry_flags, borrow_flags) + unconstrained fn __neg(self) -> Self { + let params = self.params; + Self::from_array(params, __neg(params, self.limbs)) } - unconstrained fn __sub_with_flags( - self, - lhs: BigNum, - rhs: BigNum - ) -> (BigNum, [bool; N], [bool; N], bool) { - let a_u60 : U60Repr = U60Repr::from(lhs.limbs); - let b_u60 : U60Repr = U60Repr::from(rhs.limbs); - - let underflow = b_u60.gte(a_u60 + U60Repr::one()); - - let mut addend_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; - let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; - - if underflow { - addend_u60 = self.modulus_u60; - } - - let mut carry: u64 = 0; - let mut carry_in: u64 = 0; - let mut borrow: u64 = 0; - let mut borrow_in: u64 = 0; - let mut borrow_flags: [bool; N] = [false; N]; - let mut carry_flags: [bool; N] = [false; N]; - for i in 0..2 * N { - let mut add_term: u64 = a_u60.limbs[i] + addend_u60.limbs[i] + carry_in; - carry = (add_term >= 0x1000000000000000) as u64; - add_term -= (carry as u64 * 0x1000000000000000); - result_u60.limbs[i] = add_term; - carry_in = carry as u64; - borrow = ((b_u60.limbs[i] + borrow_in) > result_u60.limbs[i]) as u64; - let sub = (borrow << 60) + result_u60.limbs[i] - b_u60.limbs[i] - borrow_in; - result_u60.limbs[i] = sub; - borrow_in = borrow; - - if ((i & 1) == 1) { - if (carry & borrow == 1) { - carry = 0; - borrow = 0; - } - carry_flags[i/2] = carry as bool; - borrow_flags[i/2] = borrow as bool; - } - } - let mut result = BigNum::from_array(U60Repr::into(result_u60)); - (result, carry_flags, borrow_flags, underflow) + unconstrained fn __add(self, other: Self) -> Self { + let params = self.params; + Self::from_array(params, __add(params, self.limbs, other.limbs)) } - unconstrained fn __neg_with_flags( - self, - val: BigNum - ) -> (BigNum, [bool; N]) { - let f: [Field; N] = val.limbs; - let x_u60 : U60Repr = U60Repr::from(f); - let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; - - let mut borrow: u64 = 0; - let mut borrow_in: u64 = 0; - - let mut borrow_flags: [bool; N] = [false; N]; - for i in 0..2 * N { - borrow = ((x_u60.limbs[i] + borrow_in) > self.modulus_u60.limbs[i]) as u64; - let sub = (borrow << 60) + self.modulus_u60.limbs[i] - x_u60.limbs[i] - borrow_in; - result_u60.limbs[i] = sub; - borrow_in = borrow; - if ((i & 1) == 1) { - borrow_flags[i / 2] = borrow as bool; - } - } - let mut result = BigNum::from_array(U60Repr::into(result_u60)); - (result, borrow_flags) + unconstrained fn __sub(self, other: Self) -> Self { + let params = self.params; + Self::from_array(params, __sub(params, self.limbs, other.limbs)) } - /** - * @brief given inputs `x, y` compute 2p + x - y (unconstrained) - * @description see `__neg` for why we use 2p instead of p - **/ - unconstrained fn __sub_impl( - self, - lhs: BigNum, - rhs: BigNum - ) -> BigNum { - self.__add(lhs, self.__neg(rhs)) + unconstrained fn __mul(self, other: Self) -> Self { + let params = self.params; + Self::from_array(params, __mul(params, self.limbs, other.limbs)) } - unconstrained fn __invmod_impl(self, val: BigNum) -> BigNum { - let one: BigNum = BigNum::one(); - let one_u60: U60Repr = U60Repr::from(one.limbs); - let exponent = self.modulus_u60.sub(one_u60.add(one_u60)); - let mut result = BigNum::from_array(U60Repr::into(exponent)); - self.__pow(val, result) + unconstrained fn __div(self, divisor: Self) -> Self { + let params = self.params; + Self::from_array(params, __div(params, self.limbs, divisor.limbs)) } - unconstrained fn batch_invert_impl( - self, - x: [BigNum; M] - ) -> [BigNum; M] { - // TODO: ugly! Will fail if input slice is empty - let mut accumulator: BigNum = BigNum::one(); - let mut result: [BigNum; M] = [BigNum::new(); M]; - let mut temporaries: [BigNum] = &[]; - for i in 0..x.len() { - temporaries = temporaries.push_back(accumulator); - if (x[i].__is_zero() == false) { - accumulator = self.__mul(accumulator, x[i]); - } - } - - accumulator = self.__invmod(accumulator); - let mut T0: BigNum = BigNum::new(); - T0.limbs = [0; N]; - for i in 0..x.len() { - let idx = x.len() - 1 - i; - if (x[idx].__is_zero() == false) { - T0 = self.__mul(accumulator, temporaries[idx]); - accumulator = self.__mul(accumulator, x[idx]); - result[idx] = T0; - } - } - result + unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self) { + let params = self.params; + let (q, r) = __udiv_mod(self.limbs, divisor.limbs); + (Self { limbs: q, params }, Self { limbs: r, params }) } - unconstrained fn batch_invert_slice_impl(self, x: [BigNum]) -> [BigNum] { - // TODO: ugly! Will fail if input slice is empty - let mut accumulator: BigNum = BigNum::one(); - let mut result: [BigNum] = [BigNum::new()]; - let mut temporaries: [BigNum] = &[]; - for i in 0..x.len() { - temporaries = temporaries.push_back(accumulator); - if (x[i].__is_zero() == false) { - accumulator = self.__mul(accumulator, x[i]); - } - result = result.push_back(BigNum::new()); - } - - accumulator = self.__invmod(accumulator); - let mut T0: BigNum = BigNum::new(); - T0.limbs = [0; N]; - for i in 0..x.len() { - let idx = x.len() - 1 - i; - if (x[idx].__is_zero() == false) { - T0 = self.__mul(accumulator, temporaries[idx]); - accumulator = self.__mul(accumulator, x[idx]); - result[idx] = T0; - } - } - result + unconstrained fn __invmod(self) -> Self { + let params = self.params; + assert(params.has_multiplicative_inverse); + Self { limbs: __invmod(params, self.limbs), params } } - unconstrained fn __div_impl( - self, - numerator: BigNum, - divisor: BigNum - ) -> BigNum { - let t0 = self.__invmod(divisor); - self.__mul(numerator, t0) + unconstrained fn __pow(self, exponent: Self) -> Self { + let params = self.params; + Self { limbs: __pow(params, self.limbs, exponent.limbs), params } } - /** - * @brief Computes the result of a linear combination of (possibly negative) BigNum values (unconstrained) - **/ - // NOTE: modulus2 is structured such that all limbs will be greater than 0, even when subtracting. - // To do this, when computing `p - x`, we ensure that each limb in `p` is greater than each limb in `x`. - // We know that, for a valid bignum element, the limbs in `x` will be <2^{120} - // Therefore each of the limbs in `p` (except the most significant) will borrow 2^{120} from the more significant limb. - // Finally, to ensure we do not underflow in the most significant limb, we use `2p` instead of `p` - unconstrained fn __add_linear_expression(self, x: [BigNum; M], flags: [bool; M]) -> ([Field; N]) { - // TODO, validate we do not overflow N2 when multiplying and N when adding - let mut sum: [Field; N] = [0; N]; - // TODO: ugly! Will fail if input array is empty - let modulus2: [Field;N] = self.double_modulus; - for i in 0..M { - if (flags[i]) { - for j in 0..N { - sum[j] = sum[j] + modulus2[j] - x[i].limbs[j]; - assert(x[i].limbs[j].lt(modulus2[j])); - } - } else { - for j in 0..N { - sum[j] = sum[j] + x[i].limbs[j]; - } - } - } - // problem if we normalize when used in computing quotient - sum + unconstrained fn __batch_invert(x: [Self; M]) -> [Self; M] { + let params = x[0].params; + assert(params.has_multiplicative_inverse); + __batch_invert(params, x.map(|bn| Self::get_limbs(bn))).map(|limbs| Self { limbs, params }) } - /** - * @brief computes the limb products of a quadratic expression - * @details see __compute_quadratic_expression_with_borrow_flags for full description - **/ - unconstrained fn __compute_quadratic_expression_product( - self, - lhs_terms: [[BigNum; LHS_N]; NUM_PRODUCTS], - lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], - rhs_terms: [[BigNum; RHS_N]; NUM_PRODUCTS], - rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], - linear_terms: [BigNum; ADD_N], - linear_flags: [bool; ADD_N] - ) -> [Field; 2 * N] { - // TODO, validate we do not overflow N2 when multiplying and N when adding - let mut lhs: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS]; - let mut rhs: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS]; - let mut add: [Field; N] = [0; N]; - - for i in 0..NUM_PRODUCTS { - lhs[i] = self.__add_linear_expression(lhs_terms[i], lhs_flags[i]); - rhs[i] = self.__add_linear_expression(rhs_terms[i], rhs_flags[i]); - } - - let add: [Field; N] = self.__add_linear_expression(linear_terms, linear_flags); - - let mut mulout: [Field; 2 * N] = [0; 2 * N]; - - for i in 0..N { - for j in 0..N { - for k in 0..NUM_PRODUCTS { - mulout[i + j] += (lhs[k][i] * rhs[k][j]); - } - } - mulout[i] += add[i]; - } - mulout + unconstrained fn __batch_invert_slice(x: [Self]) -> [Self] { + let params = x[0].params; + assert(params.has_multiplicative_inverse); + __batch_invert_slice(params, x.map(|bn| Self::get_limbs(bn))).map(|limbs| Self { limbs, params }) } - /** - * @brief computes the quotient/remainder of a quadratic expression - * @details see __compute_quadratic_expression_with_borrow_flags for full description - **/ - unconstrained fn __compute_quadratic_expression_impl( - self, - lhs_terms: [[BigNum; LHS_N]; NUM_PRODUCTS], + unconstrained fn __compute_quadratic_expression( + params: BigNumParams, + lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], - rhs_terms: [[BigNum; RHS_N]; NUM_PRODUCTS], + rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], - linear_terms: [BigNum; ADD_N], + linear_terms: [Self; ADD_N], linear_flags: [bool; ADD_N] - ) -> (BigNum, BigNum) { - // TODO, validate we do not overflow N2 when multiplying and N when adding - let mulout = self.__compute_quadratic_expression_product( - lhs_terms, + ) -> (Self, Self) { + let (q_limbs, r_limbs) = __compute_quadratic_expression( + params, + lhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), lhs_flags, - rhs_terms, + rhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), rhs_flags, - linear_terms, + linear_terms.map(|bn| Self::get_limbs(bn)), linear_flags ); - let mut relation_result: [Field; 2 * N] = split_bits::__normalize_limbs(mulout, 2 * N); - - // TODO: ugly! Will fail if input slice is empty - let k = Params::modulus_bits(); - - let (quotient, remainder) = __barrett_reduction( - relation_result, - self.redc_param, - k, - self.modulus, - self.modulus_u60_x4 - ); - - let mut q = BigNum::from_array(quotient); - let mut r = BigNum::from_array(remainder); - (q, r) + (Self { limbs: q_limbs, params }, Self { limbs: r_limbs, params }) } - /** - * @brief Given a degree-2 BigNum expression that is equal to 0 mod p, compute the quotient and borrow flags - * @description The expression is of the form: - * - * \sum_{i=0}^{NUM_PRODUCTS - 1} ((\sum_{j=0}^{LHS_N-1}lhs[i][j]) * (\sum_{j=0}^{RHS_N-1}rhs[i][j])) + \sum_{i=0}^{ADD_N - 1}linear_terms[i] = quotient * modulus - * - * The intent is to capture an arbitrary degree-2 expression within the limitations of Noir (no efficient dynamically-sized vectors) - * - * When performing BigNum arithmetic, we want to represent desired BigNum operations in a way that minimizes the number of modular reductions that are required. - * This can be achieved by minimizing the number of degree-2 relations required. - * - * The borrow flags describe whether individual Field limbs will underflow when evaluating the above relation. - * For example, when computing the product a * b - q * p = 0, it is possible that: - * 1. a[0]*b[0] - p[0]*q[0] = -2^{120} - * 2. a[0]*b[1] + a[1]*b[0] - p[0]*q[1] - p[1]*q[0] = 1 - * In the above example, the value represented by these two limbs is zero despite each limb being nonzero. - * In this case, to correctly constrain the result, we must add (at least) 2^{120} from the first limb and subtract 1 from the second. - * - * @param lhs_terms a 2D array of BigNum - * @param lhs_flags a 2D array of sign flags - * @param rhs_terms a 2D array of BigNum - * @param rhs_flags a 2D array of sign flags - * @param linear_terms an array of BigNum - * @param linear_flags an array of sign flags - **/ - unconstrained fn __compute_quadratic_expression_with_borrow_flags( - self, - lhs_terms: [[BigNum; LHS_N]; NUM_PRODUCTS], + fn evaluate_quadratic_expression( + params: BigNumParams, + lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], - rhs_terms: [[BigNum; RHS_N]; NUM_PRODUCTS], + rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], - linear_terms: [BigNum; ADD_N], + linear_terms: [Self; ADD_N], linear_flags: [bool; ADD_N] - ) -> (BigNum, BigNum, [Field; 2 * N]) { - // TODO, validate we do not overflow N2 when multiplying and N when adding - - let mut mulout_p = self.__compute_quadratic_expression_product( - lhs_terms, + ) { + evaluate_quadratic_expression( + params, + lhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), lhs_flags, - rhs_terms, + rhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), rhs_flags, - linear_terms, + linear_terms.map(|bn| Self::get_limbs(bn)), linear_flags - ); - let mut mulout_n: [Field; 2 * N] = [0; 2 * N]; - let mut relation_result: [Field; 2 * N] = split_bits::__normalize_limbs(mulout_p, 2 * N); - - let modulus: [Field; N] = self.modulus; - let (quotient, remainder) = __barrett_reduction( - relation_result, - self.redc_param, - Params::modulus_bits(), - modulus, - self.modulus_u60_x4 - ); - assert(remainder == [0; N]); - - for i in 0..N { - for j in 0..N { - mulout_n[i + j] += quotient[i] * modulus[j]; - } - } - - // compute borrow flags from mulout_p and mulout_n - let mut borrow_flags: [Field; 2 * N] = [0; 2 * N]; - let borrow_shift: Field = 0x40000000000000000000000000000000000000000000000000000000000000; // 2^{246} - let borrow_carry: Field = 0x40000000000000000000000000000000; // 2^{246 - 120} = 2^{126} - let two_pow_120: Field = 0x1000000000000000000000000000000; - let downshift: Field = 1 / two_pow_120; - - // determine whether we need to borrow from more significant limbs. - // initial limb is "simple" comparison operation - // TODO: check how expensive `lt` operator is w.r.t. witness generation - borrow_flags[0] = mulout_p[0].lt(mulout_n[0]) as Field; - // we have 2N - 2 borrow flags. The number of limbs from our product computation is 2N - 1 - // and there is nothing to borrow against for the final limb. - let mut hi_bits = (mulout_p[0] - mulout_n[0] + (borrow_flags[0] * borrow_shift)) * downshift; - for i in 1..(N + N - 2) { - // compute the contribution from limb `i-1` that gets added into limb `i`, and add into limb `i` - // let hi_bits = (mulout_p.get(i - 1) - mulout_n.get(i - 1) + (borrow_flags.get(i - 1) * borrow_shift)) - // * downshift; - mulout_p[i] += hi_bits; - - // determine whether negative limb values are greater than positive limb values - let underflow: Field = mulout_p[i].lt(mulout_n[i] + (borrow_flags[i - 1] * borrow_carry)) as Field; - borrow_flags[i] = underflow; - - hi_bits = (mulout_p[i] - mulout_n[i] + (borrow_flags[i] * borrow_shift) - - (borrow_flags[i - 1] * borrow_carry)) * downshift; - } + ) + } - let mut q = BigNum::from_array(quotient); - let mut r = BigNum::from_array(remainder); - (q, r, borrow_flags) + fn validate_in_field(self: Self) { + let params = self.params; + validate_in_field(params, self.limbs); } - unconstrained fn __udiv_mod_impl( - _: Self, - numerator: BigNum, - divisor: BigNum - ) -> (BigNum, BigNum) { - let mut quotient_u60: U60Repr = U60Repr::from([0; N]); - let mut remainder_u60: U60Repr = U60Repr::from(numerator.limbs); + fn validate_in_range(self) { + let params = self.params; + validate_in_range(params, self.limbs); + } - let mut divisor_u60: U60Repr = U60Repr::from(divisor.limbs); - let b = divisor_u60; + fn assert_is_not_equal(self, other: Self) { + let params = self.params; + assert_is_not_equal(params, self.limbs, other.limbs); + } - let mut bit_difference = remainder_u60.get_msb() - divisor_u60.get_msb(); + fn neg(self) -> Self { + let params = self.params; + Self { limbs: neg(params, self.limbs), params } + } - let mut accumulator_u60: U60Repr = U60Repr::one(); - divisor_u60 = divisor_u60.shl(bit_difference); - accumulator_u60 = accumulator_u60.shl(bit_difference); + fn udiv_mod(self, divisor: Self) -> (Self, Self) { + let params = self.params; + let (q, r) = udiv_mod(params, self.limbs, divisor.limbs); + (Self { limbs: q, params }, Self { limbs: r, params }) + } - if (divisor_u60.gte(remainder_u60 + U60Repr::one())) { - divisor_u60.shr1(); - accumulator_u60.shr1(); - } - for _ in 0..(N * 120) { - if (remainder_u60.gte(b) == false) { - break; - } + fn udiv(self, divisor: Self) -> Self { + let params = self.params; + Self { limbs: udiv(params, self.limbs, divisor.limbs), params } + } - // we've shunted 'divisor' up to have the same bit length as our remainder. - // If remainder >= divisor, then a is at least '1 << bit_difference' multiples of b - if (remainder_u60.gte(divisor_u60)) { - remainder_u60 -= divisor_u60; - // we can use OR here instead of +, as - // accumulator is always a nice power of two - quotient_u60 = quotient_u60 + accumulator_u60; - } - divisor_u60.shr1(); // >>= 1; - accumulator_u60.shr1(); // >>= 1; - } + fn umod(self, divisor: Self) -> Self { + let params = self.params; + Self { limbs: umod(params, self.limbs, divisor.limbs), params } + } - ( - BigNum::from_array(U60Repr::into(quotient_u60)), BigNum::from_array(U60Repr::into(remainder_u60)) - ) + fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self { + let params = lhs.params; + Self { limbs: conditional_select(lhs.limbs, rhs.limbs, predicate), params } } } -fn get_double_modulus(modulus: [Field; N]) -> [Field; N] { - let TWO_POW_120: Field = 0x1000000000000000000000000000000; - let m: U60Repr = U60Repr::from(modulus); - let mut result: [Field; N] = U60Repr::into(m + m); - - result[0] += TWO_POW_120; - for i in 1..N - 1 { - result[i] += (TWO_POW_120 - 1); +impl std::ops::Add for RuntimeBigNum { + // 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 = self.params; + Self { limbs: add(params, self.limbs, other.limbs), params } } - result[N - 1] -= 1; - result } -unconstrained fn __barrett_reduction( - x: [Field; 2 * N], - redc_param: [Field; N], - k: u32, - modulus: [Field; N], - modulus_u60: U60Repr -) -> ([Field; N], [Field; N]) { - let mut mulout: [Field; 3 * N] = [0; 3 * N]; - for i in 0..(N + N) { - for j in 0..N { - mulout[i + j] += x[i] * redc_param[j]; - } +impl std::ops::Sub for RuntimeBigNum { + // 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 = self.params; + Self { limbs: sub(params, self.limbs, other.limbs), params } } - mulout = split_bits::__normalize_limbs(mulout, 3 * N - 1); - let mulout_u60: U60Repr = U60Repr::new(mulout); - let mut quotient_u60 = mulout_u60.shr((k + k)); +} - // N.B. we assume that the shifted quotient cannot exceed 2 times original bit size. - // (partial_quotient should be just slightly larger than the modulus, we could probably represent with a size N+1 array) - let partial_quotient_full: [Field; 3 * N] = quotient_u60.into_field_array(); - let mut partial_quotient: [Field; 2 * N] = [0; 2 * N]; - for i in 0..2 * N { - partial_quotient[i] = partial_quotient_full[i]; - } - // quotient_mul_modulus can never exceed input value `x` so can fit into size-2 array - let mut quotient_mul_modulus: [Field; 2 * N] = [0; 2 * N]; - let mut quotient_mul_modulus_normalized: [Field; 2 * N] = [0; 2 * N]; - for j in 0..N { - for i in 0..(N + N - j) { - quotient_mul_modulus[i + j] += partial_quotient[i] * modulus[j]; - } +impl std::ops::Mul for RuntimeBigNum { + // 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 = self.params; + Self { limbs: mul(params, self.limbs, other.limbs), params } } +} - for i in 0..(N + N) { - let (lo, hi) = split_bits::split_120_bits(quotient_mul_modulus[i]); - quotient_mul_modulus_normalized[i] = lo; - // TODO: what is faster, leaving this if statement in or out? - // (array is size-1 too large so we can tolerate adding 0 into max element) - if (i + 1 < N + N) { - quotient_mul_modulus[i + 1] += hi; - } +impl std::ops::Div for RuntimeBigNum { + // Note: this method is expensive! Witness computation is extremely expensive as it requires modular exponentiation + fn div(self, divisor: Self) -> Self { + let params = self.params; + Self { limbs: div(params, self.limbs, divisor.limbs), params } } - let quotient_mul_modulus_u60: U60Repr = U60Repr::new(quotient_mul_modulus_normalized); - - let x_u60 : U60Repr = U60Repr::new(x); - let mut remainder_u60 = x_u60 - quotient_mul_modulus_u60; - - if (remainder_u60.gte(modulus_u60)) { - remainder_u60 = remainder_u60 - modulus_u60; - quotient_u60.increment(); - } else {} - - let q: [Field; N] = U60Repr::into(quotient_u60); - let r: [Field; N] = U60Repr::into(remainder_u60); +} - (q, r) +impl std::cmp::Eq for RuntimeBigNum { + fn eq(self, other: Self) -> bool { + let params = self.params; + eq(params, self.limbs, other.limbs) + } } diff --git a/src/runtime_bignum_test.nr b/src/runtime_bignum_test.nr index d60eacb5..51f9d60b 100644 --- a/src/runtime_bignum_test.nr +++ b/src/runtime_bignum_test.nr @@ -1,24 +1,14 @@ -use crate::BigNum; -use crate::runtime_bignum::BigNumInstance; -use crate::runtime_bignum::BigNumParamsTrait; use crate::utils::u60_representation::U60Repr; -use crate::fields::bn254Fq::BNParams as BNParams; -struct Test2048Params {} +use crate::runtime_bignum::RuntimeBigNum; -// See https://github.com/noir-lang/noir/issues/6172 -#[test] -fn silence_warning() { - let _ = Test2048Params {}; -} +use crate::params::BigNumParams; -impl BigNumParamsTrait<18> for Test2048Params { - fn modulus_bits() -> u32 { - 2048 - } -} +use crate::fields::bn254Fq::BN254_Fq_PARAMS; -fn get_2048_BN_instance() -> BigNumInstance<18, Test2048Params> { +fn get_2048_BN_params() -> BigNumParams<18> { + let has_multiplicative_inverse = false; + let modulus_bits_getter = || 2048; let modulus: [Field; 18] = [ 0x0000000000000000000000000000000000c0a197a5ae0fcdceb052c9732614fe, 0x0000000000000000000000000000000000656ae034423283422243918ab83be3, @@ -59,349 +49,385 @@ fn get_2048_BN_instance() -> BigNumInstance<18, Test2048Params> { 0x0000000000000000000000000000000000ff4e42304e60fb3a54fca735499f2c, 0x0000000000000000000000000000000000000000000000000000000000000162 ]; - BigNumInstance::new(modulus, redc_param) + BigNumParams::new( + has_multiplicative_inverse, + modulus_bits_getter, + modulus, + redc_param + ) } -type Fq = BigNum<3, BNParams>; -// type FqInstance = BigNumInstance<3, BNParams>; -// type Fqq = BigNum<18, Test2048Params>; -// type FqqInstance = BigNumInstance<18, Test2048Params>; - -fn test_eq(BNInstance: BigNumInstance) where Params: BigNumParamsTrait { - let a: BigNum = BNInstance.__derive_from_seed([1, 2, 3, 4]); - let b: BigNum = BNInstance.__derive_from_seed([1, 2, 3, 4]); - let c: BigNum = BNInstance.__derive_from_seed([2, 2, 3, 4]); +fn test_eq(params: BigNumParams) { + let a = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let b = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let c = unsafe { + RuntimeBigNum::__derive_from_seed(params, [2, 2, 3, 4]) + }; - let modulus: BigNum = BNInstance.modulus(); + let modulus = a.modulus(); let t0: U60Repr = (U60Repr::from(modulus.limbs)); let t1: U60Repr = (U60Repr::from(b.limbs)); - let b_plus_modulus: BigNum = BigNum { limbs: U60Repr::into(t0 + t1) }; + let b_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; - assert(BNInstance.eq(a, b) == true); - assert(BNInstance.eq(a, b_plus_modulus) == true); - assert(BNInstance.eq(c, b) == false); - assert(BNInstance.eq(c, a) == false); + assert((a == b) == true); + assert((a == b_plus_modulus) == true); + assert((c == b) == false); + assert((c == a) == false); } // 98760 // 99689 // 929 gates for a 2048 bit mul -fn test_mul(BNInstance: BigNumInstance) where Params: BigNumParamsTrait { - let a: BigNum = BNInstance.__derive_from_seed([1, 2, 3, 4]); - let b: BigNum = BNInstance.__derive_from_seed([4, 5, 6, 7]); - - let c = BNInstance.mul(BNInstance.add(a, b), BNInstance.add(a, b)); - let d = BNInstance.add( - BNInstance.add( - BNInstance.add(BNInstance.mul(a, a), BNInstance.mul(b, b)), - BNInstance.mul(a, b) - ), - BNInstance.mul(a, b) - ); - assert(BNInstance.eq(c, d)); +fn test_mul(params: BigNumParams) { + let a = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let b = unsafe { + RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) + }; + + let c = (a + b) * (a + b); + let d = (a * a) + (b * b) + (a * b) + (a * b); + assert(c == d); } -fn test_add(bn: BigNumInstance) where Params: BigNumParamsTrait { - let a: BigNum = bn.__derive_from_seed([1, 2, 3, 4]); - let b: BigNum = bn.__derive_from_seed([4, 5, 6, 7]); - let one: BigNum = BigNum::one(); +fn test_add(params: BigNumParams) { + let a = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let b = unsafe { + RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) + }; + let one = RuntimeBigNum::one(params); a.validate_in_range(); - bn.validate_in_field(a); + a.validate_in_field(); b.validate_in_range(); - bn.validate_in_field(b); + b.validate_in_field(); - let mut c = bn.add(a, b); - c = bn.add(c, c); - let d = bn.mul(bn.add(a, b), bn.add(one, one)); - assert(bn.eq(c, d)); + let mut c = a + b; + c = c + c; + let d = (a + b) * (one + one); + assert(c == d); - let e = bn.add(one, one); + let e = one + one; for i in 1..N { assert(e.limbs[i] == 0); } assert(e.limbs[0] == 2); } -fn test_div(bn: BigNumInstance) where Params: BigNumParamsTrait { - let a: BigNum = bn.__derive_from_seed([1, 2, 3, 4]); - let b: BigNum = bn.__derive_from_seed([4, 5, 6, 7]); +fn test_div(params: BigNumParams) { + let a = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let b = unsafe { + RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) + }; - let c = bn.div(a, b); - assert(bn.eq(bn.mul(b, c), a)); + let c = a / b; + assert((b * c) == a); } -fn test_invmod(bn: BigNumInstance) where Params: BigNumParamsTrait { - let u: BigNum = bn.__derive_from_seed([1, 2, 3, 4]); +unconstrained fn test_invmod(params: BigNumParams) { + let u = RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]); for _ in 0..1 { - let v = bn.__invmod(u); - let result = bn.__mul(u, v); - let expected: BigNum = BigNum::one(); + let v = u.__invmod(); + let result = u.__mul(v); + let expected = RuntimeBigNum::one(params); assert(result.limbs == expected.limbs); } } -fn assert_is_not_equal(bn: BigNumInstance) where Params: BigNumParamsTrait { - let a: BigNum = bn.__derive_from_seed([1, 2, 3, 4]); - let b: BigNum = bn.__derive_from_seed([4, 5, 6, 7]); +unconstrained fn assert_is_not_equal(params: BigNumParams) { + let a = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let b = unsafe { + RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) + }; - bn.assert_is_not_equal(a, b); + a.assert_is_not_equal(b); } -fn assert_is_not_equal_fail(bn: BigNumInstance) where Params: BigNumParamsTrait { - let a: BigNum = bn.__derive_from_seed([1, 2, 3, 4]); - let b: BigNum = bn.__derive_from_seed([1, 2, 3, 4]); +unconstrained fn assert_is_not_equal_fail(params: BigNumParams) { + let a = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let b = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; - bn.assert_is_not_equal(a, b); + a.assert_is_not_equal(b); } -fn assert_is_not_equal_overloaded_lhs_fail(bn: BigNumInstance) where Params: BigNumParamsTrait { - let a: BigNum = bn.__derive_from_seed([1, 2, 3, 4]); - let b: BigNum = bn.__derive_from_seed([1, 2, 3, 4]); +fn assert_is_not_equal_overloaded_lhs_fail(params: BigNumParams) { + let a = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let b = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; - let modulus = bn.modulus(); + let modulus = params.modulus; let t0: U60Repr = U60Repr::from(a.limbs); - let t1: U60Repr = U60Repr::from(modulus.limbs); - let a_plus_modulus: BigNum = BigNum { limbs: U60Repr::into(t0 + t1) }; - bn.assert_is_not_equal(a_plus_modulus, b); + let t1: U60Repr = U60Repr::from(modulus); + let a_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; + a_plus_modulus.assert_is_not_equal(b); } -fn assert_is_not_equal_overloaded_rhs_fail(bn: BigNumInstance) where Params: BigNumParamsTrait { - let a: BigNum = bn.__derive_from_seed([1, 2, 3, 4]); - let b: BigNum = bn.__derive_from_seed([1, 2, 3, 4]); +fn assert_is_not_equal_overloaded_rhs_fail(params: BigNumParams) { + let a = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let b = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; - let modulus = bn.modulus(); + let modulus = params.modulus; let t0: U60Repr = U60Repr::from(b.limbs); - let t1: U60Repr = U60Repr::from(modulus.limbs); - let b_plus_modulus: BigNum = BigNum { limbs: U60Repr::into(t0 + t1) }; - bn.assert_is_not_equal(a, b_plus_modulus); + let t1: U60Repr = U60Repr::from(modulus); + let b_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; + a.assert_is_not_equal(b_plus_modulus); } -fn assert_is_not_equal_overloaded_fail(bn: BigNumInstance) where Params: BigNumParamsTrait { - let a: BigNum = bn.__derive_from_seed([1, 2, 3, 4]); - let b: BigNum = bn.__derive_from_seed([1, 2, 3, 4]); +fn assert_is_not_equal_overloaded_fail(params: BigNumParams) { + let a = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let b = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; - let modulus = bn.modulus(); + let modulus = params.modulus; let t0: U60Repr = U60Repr::from(a.limbs); let t1: U60Repr = U60Repr::from(b.limbs); - let t2: U60Repr = U60Repr::from(modulus.limbs); - let a_plus_modulus: BigNum = BigNum { limbs: U60Repr::into(t0 + t2) }; - let b_plus_modulus: BigNum = BigNum { limbs: U60Repr::into(t1 + t2) }; - bn.assert_is_not_equal(a_plus_modulus, b_plus_modulus); + let t2: U60Repr = U60Repr::from(modulus); + let a_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t2), params }; + let b_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t1 + t2), params }; + a_plus_modulus.assert_is_not_equal(b_plus_modulus); } #[test] fn test_eq_BN() { - let instance = BNParams::get_instance(); - test_eq(instance); + let params = BN254_Fq_PARAMS; + test_eq(params); } #[test] fn test_add_BN() { - let instance = BNParams::get_instance(); + let params = BN254_Fq_PARAMS; - let mut a: Fq = instance.modulus(); - let mut b: Fq = instance.modulus(); - let mut expected: Fq = instance.modulus(); + let mut a = RuntimeBigNum { limbs: params.modulus, params }; + let mut b = a; + let mut expected = a; a.limbs[0] -= 1; b.limbs[0] -= 1; expected.limbs[0] -= 2; - let result = instance.add(a, b); - assert(instance.eq(result, expected)); + let result = a + b; + assert(result == expected); } #[test] fn test_sub_test_BN() { - let instance = BNParams::get_instance(); + let params = BN254_Fq_PARAMS; + // 0 - 1 should equal p - 1 - let mut a: Fq = BigNum::new(); - let mut b: Fq = BigNum::one(); - let mut expected: Fq = instance.modulus(); + let mut a = RuntimeBigNum::new(params); + let mut b = RuntimeBigNum::one(params); + let mut expected = RuntimeBigNum { limbs: params.modulus, params }; expected.limbs[0] -= 1; // p - 1 - let result = instance.sub(a, b); - assert(instance.eq(result, expected)); + let result = a - b; + assert(result == expected); } #[test] fn test_sub_modulus_limit() { - let instance = BNParams::get_instance(); + let params = BN254_Fq_PARAMS; + // if we underflow, maximum result should be ... // 0 - 1 = o-1 // 0 - p = 0 - let mut a: Fq = BigNum::new(); - let mut b: Fq = instance.modulus(); - let mut expected: Fq = BigNum::new(); + let mut a= RuntimeBigNum::new(params); + let mut b= RuntimeBigNum { limbs: params.modulus, params }; + let mut expected= RuntimeBigNum::new(params); - let result = instance.sub(a, b); - assert(instance.eq(result, expected)); + let result = a - b; + assert(result == expected); } #[test(should_fail_with = "call to assert_max_bit_size")] fn test_sub_modulus_underflow() { - let instance = BNParams::get_instance(); + let params = BN254_Fq_PARAMS; // 0 - (p + 1) is smaller than p and should produce unsatisfiable constraints - let mut a: Fq = BigNum::new(); - let mut b: Fq = instance.modulus(); + let mut a = RuntimeBigNum::new(params); + let mut b = RuntimeBigNum { limbs: params.modulus, params }; b.limbs[0] += 1; - let mut expected: Fq = BigNum::one(); + let mut expected = RuntimeBigNum::one(params); - let result = instance.sub(a, b); + let result = a - b; - assert(instance.eq(result, expected)); + assert(result == expected); } #[test] fn test_add_modulus_limit() { - let instance = BNParams::get_instance(); + let params = BN254_Fq_PARAMS; + // 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 : U60Repr<3, 2> = U60Repr::from(instance.modulus().limbs); + let p : U60Repr<3, 2> = U60Repr::from(params.modulus); let two_pow_254_minus_1: U60Repr<3, 2> = U60Repr::from([0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x3fff]); - let a: Fq = BigNum { limbs: U60Repr::into(p) }; - let b: Fq = BigNum { limbs: U60Repr::into(two_pow_254_minus_1) }; - let result = instance.add(a, b); - assert(instance.eq(result, b)); + let a = RuntimeBigNum { limbs: U60Repr::into(p), params }; + let b = RuntimeBigNum { limbs: U60Repr::into(two_pow_254_minus_1), params }; + let result = a + b; + assert(result == b); } #[test(should_fail_with = "call to assert_max_bit_size")] fn test_add_modulus_overflow() { - let instance = BNParams::get_instance(); + let params = BN254_Fq_PARAMS; + //(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 : U60Repr<3, 2> = U60Repr::from(instance.modulus().limbs); + let p : U60Repr<3, 2> = U60Repr::from(params.modulus); let two_pow_254_minus_1: U60Repr<3, 2> = U60Repr::from([0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x3fff]); let one = U60Repr::from([1, 0, 0]); - let a: Fq = BigNum { limbs: U60Repr::into(p + one) }; - let b: Fq = BigNum { limbs: U60Repr::into(two_pow_254_minus_1) }; - let result = instance.add(a, b); - assert(instance.eq(result, b)); + let a = RuntimeBigNum { limbs: U60Repr::into(p + one), params }; + let b = RuntimeBigNum { limbs: U60Repr::into(two_pow_254_minus_1), params }; + let result = a + b; + assert(result == b); } #[test] fn test_mul_BN() { - let instance = BNParams::get_instance(); - test_mul(instance); + let params = BN254_Fq_PARAMS; + test_mul(params); } #[test] fn test_add_BN2() { - let instance = BNParams::get_instance(); - test_add(instance); + let params = BN254_Fq_PARAMS; + test_add(params); } #[test] fn test_div_BN() { - let instance = BNParams::get_instance(); - test_div(instance); + let params = BN254_Fq_PARAMS; + test_div(params); } #[test] -fn test_invmod_BN() { - let instance = BNParams::get_instance(); - test_invmod(instance); +unconstrained fn test_invmod_BN() { + let params = BN254_Fq_PARAMS; + test_invmod(params); } #[test] -fn test_assert_is_not_equal_BN() { - let instance = BNParams::get_instance(); - assert_is_not_equal(instance); +unconstrained fn test_assert_is_not_equal_BN() { + let params = BN254_Fq_PARAMS; + assert_is_not_equal(params); } #[test(should_fail_with = "asssert_is_not_equal fail")] -fn test_assert_is_not_equal_fail_BN() { - let instance = BNParams::get_instance(); - assert_is_not_equal_fail(instance); +unconstrained fn test_assert_is_not_equal_fail_BN() { + let params = BN254_Fq_PARAMS; + assert_is_not_equal_fail(params); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_lhs_fail_BN() { - let instance = BNParams::get_instance(); - assert_is_not_equal_overloaded_lhs_fail(instance); + let params = BN254_Fq_PARAMS; + assert_is_not_equal_overloaded_lhs_fail(params); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_rhs_fail_BN() { - let instance = BNParams::get_instance(); - assert_is_not_equal_overloaded_rhs_fail(instance); + let params = BN254_Fq_PARAMS; + assert_is_not_equal_overloaded_rhs_fail(params); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_fail_BN() { - let instance = BNParams::get_instance(); - assert_is_not_equal_overloaded_fail(instance); + let params = BN254_Fq_PARAMS; + assert_is_not_equal_overloaded_fail(params); } #[test] fn test_eq_2048() { - let instance = get_2048_BN_instance(); - test_eq(instance); + let params = get_2048_BN_params(); + test_eq(params); } #[test] fn test_mul_2048() { - let instance = get_2048_BN_instance(); - test_mul(instance); + let params = get_2048_BN_params(); + test_mul(params); } #[test] fn test_add_2048() { - let instance = get_2048_BN_instance(); - test_add(instance); + let params = get_2048_BN_params(); + test_add(params); } #[test] -fn test_assert_is_not_equal_2048() { - let instance = get_2048_BN_instance(); - assert_is_not_equal(instance); +unconstrained fn test_assert_is_not_equal_2048() { + let params = get_2048_BN_params(); + assert_is_not_equal(params); } #[test(should_fail_with = "asssert_is_not_equal fail")] -fn test_assert_is_not_equal_fail_2048() { - let instance = get_2048_BN_instance(); - assert_is_not_equal_fail(instance); +unconstrained fn test_assert_is_not_equal_fail_2048() { + let params = get_2048_BN_params(); + assert_is_not_equal_fail(params); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_lhs_fail_2048() { - let instance = get_2048_BN_instance(); - assert_is_not_equal_overloaded_lhs_fail(instance); + let params = get_2048_BN_params(); + assert_is_not_equal_overloaded_lhs_fail(params); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_rhs_fail_2048() { - let instance = get_2048_BN_instance(); - assert_is_not_equal_overloaded_rhs_fail(instance); + let params = get_2048_BN_params(); + assert_is_not_equal_overloaded_rhs_fail(params); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_fail_2048() { - let instance = get_2048_BN_instance(); - assert_is_not_equal_overloaded_fail(instance); + let params = get_2048_BN_params(); + assert_is_not_equal_overloaded_fail(params); } // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril // #[test] // fn test_div_2048() { -// let instance = get_2048_BN_instance(); -// test_div(instance); +// let params = get_2048_BN_params(); +// test_div(params); // } // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril // #[test] // fn test_invmod_2048() { -// let instance = get_2048_BN_instance(); -// test_invmod(instance); +// let params = get_2048_BN_params(); +// test_invmod(params); // } #[test] fn test_2048_bit_quadratic_expression() { - let instance = get_2048_BN_instance(); + let params = get_2048_BN_params(); let a: [Field; 18] = [ 0x000000000000000000000000000000000083684820ff40795b8d9f1be2220cba, 0x0000000000000000000000000000000000d4924fbdc522b07b6cd0ef5508fd66, @@ -463,76 +489,92 @@ fn test_2048_bit_quadratic_expression() { 0x0000000000000000000000000000000000000000000000000000000000000058 ]; - let a_bn: BigNum<18, Test2048Params> = BigNum { limbs: a }; - let b_bn: BigNum<18, Test2048Params> = BigNum { limbs: b }; - let c_bn = instance.__mul(a_bn, b_bn); - assert(c_bn.limbs == c_expected); + let a= RuntimeBigNum { limbs: a, params }; + let b = RuntimeBigNum { limbs: b, params }; + let c = a * b; + assert(c.limbs == c_expected); - a_bn.validate_in_range(); + a.validate_in_range(); - instance.evaluate_quadratic_expression([[a_bn]], [[false]], [[b_bn]], [[false]], [c_bn], [true]); + RuntimeBigNum::evaluate_quadratic_expression(params, [[a]], [[false]], [[b]], [[false]], [c], [true]); } #[test] fn test_expressions() { - let instance = BNParams::get_instance(); + let params = BN254_Fq_PARAMS; + let x: [Field; 6] = [ 0x000000000000000000000000000000000083684820ff40795b8d9f1be2220cba, 0x0000000000000000000000000000000000d4924fbdc522b07b6cd0ef5508fd66, 0x0000000000000000000000000000000000d48f6c43c5930f3d70d6db09a48f4a, 0x0000000000000000000000000000000000e7f72b2c0756704bea85be38352b34, 0x00000000000000000000000000000000000000000000000000000000b05d5ac5, 0 ]; - let y: Fq = BigNum { + let y= RuntimeBigNum { limbs: [ 0x1, 0x1, 0x0 - ] + ], params }; - let z: Fq = BigNum { + let z= RuntimeBigNum { limbs: [ 0x2, 0x2, 0x0 - ] + ], params + }; + let yy = unsafe { + y.__add(y) }; - let yy = instance.__add(y, y); assert(yy.limbs == z.limbs); - let uu: Fq = BigNum { + let uu= RuntimeBigNum { limbs: [ 0x0000000000000000000000000000000000b4a832748da6ad742a1fd81b787643, 0x00000000000000000000000000000000009575f594e04080471712c1d7f18e89, 0x000000000000000000000000000000000000000000000000000000000000063 - ] + ], + params }; - let vv: Fq = BigNum { + let vv= RuntimeBigNum { limbs: [ 0x0000000000000000000000000000000000b4aec2748da6ad742a1fd81b787643, 0x00000000000000000000000000000000009575f594e0408047171a01d7f18e89, 0x0000000000000000000000000000000000000000000000000000000000000062 - ] + ], + params }; - let w: Fq = BigNum { + let w= RuntimeBigNum { limbs: [ 0x0000000000000000000000000000000000b4a832748da6ad742a1fd81b787643, 0x00000000000000000000000000000000009575f594e04080471712c1d7f18e89, 0x0000000000000000000000000000000000000000000000000000000000001f93 - ] + ], + params }; - let x: Fq = BigNum { + let x= RuntimeBigNum { limbs: [ 0x0000000000000000000000000000000000b4aec2748da6ad742a1fd81b787643, 0x00000000000000000000000000000000009575f594e0408047171a01d7f18e89, 0x0000000000000000000000000000000000000000000000000000000000000f93 - ] + ], + params + }; + let wx = unsafe { + w.__mul(x) + }; + let uv = unsafe { + uu.__mul(vv) + }; + let y = unsafe { + (uv.__add(wx)).__neg() + }; + let z = unsafe { + uv.__add(wx) }; - let wx = instance.__mul(w, x); - let uv = instance.__mul(uu, vv); - let y = instance.__neg(instance.__add(uv, wx)); - let z = instance.__add(uv, wx); - instance.evaluate_quadratic_expression( + RuntimeBigNum::evaluate_quadratic_expression( + params, [[uu], [w]], [[false], [false]], [[vv], [x]], @@ -540,7 +582,8 @@ fn test_expressions() { [z], [true] ); - instance.evaluate_quadratic_expression( + RuntimeBigNum::evaluate_quadratic_expression( + params, [[uu], [w]], [[false], [false]], [[vv], [x]], @@ -549,6 +592,6 @@ fn test_expressions() { [false] ); - let wx_constrained = instance.mul(w, x); + let wx_constrained = w * x; assert(wx_constrained.limbs == wx.limbs); } diff --git a/src/serialization.nr b/src/serialization.nr new file mode 100644 index 00000000..bba1672f --- /dev/null +++ b/src/serialization.nr @@ -0,0 +1,66 @@ +use crate::params::BigNumParams as P; + +/** +* @brief construct a BigNum instance out of an array of bytes in BIG ENDIAN format +* @description: each 120-bit limb represents 15 bytes, we require that the size of the byte array +* is precisely large enough to cover Params::modulus_bits() +* @param x: input byte array +**/ +pub(crate) fn from_be_bytes(params: P, x: [u8; NBytes]) -> [Field; N] { + let num_bits = NBytes * 8; + let modulus_bits_getter = params.modulus_bits_getter; + let modulus_bits = modulus_bits_getter(); + assert(num_bits >= modulus_bits); + assert(num_bits - modulus_bits < 8); + let mut result = [0; N]; + + let excess_bytes = N * 15 - NBytes; + let final_limb_bytes = 15 - excess_bytes; + let mut limb: Field = 0; + let mut k = 0; + for _j in 0..final_limb_bytes { + limb *= 256; + limb += x[k] as Field; + k += 1; + } + result[N - 1] = limb; + + for i in 1..N { + let mut limb: Field = 0; + for _j in 0..15 { + limb *= 256; + limb += x[k] as Field; + k += 1; + } + result[N - i - 1] = limb; + } + + // max_bits_in_most_significant_byte should be known at comptime. if not...messy! + let mut max_bits_in_most_significant_byte = 8 - (num_bits - modulus_bits); + + let most_significant_byte: Field = x[0] as Field; + + most_significant_byte.assert_max_bit_size(max_bits_in_most_significant_byte as u32); + result +} + +pub(crate) fn to_le_bytes(params: P, val: [Field; N]) -> [u8; NBytes] { + let modulus_bits_getter = params.modulus_bits_getter; + let modulus_bits = modulus_bits_getter(); + let nbytes = (modulus_bits / 8) + (modulus_bits % 8 != 0) as u32; + assert(nbytes <= NBytes); + + let mut result: [u8; NBytes] = [0; NBytes]; + for i in 0..N - 1 { + let limb_bytes: [u8; 15] = val[i].to_le_bytes(); + for j in 0..15 { + result[i * 15 + j] = limb_bytes[j]; + } + } + let last_limb_bytes: [u8; 15] = val[N - 1].to_le_bytes(); + let num_last_bytes = (NBytes - (N - 1) * 15); + for i in 0..num_last_bytes { + result[(N-1) * 15 + i] = last_limb_bytes[i]; + } + result +} diff --git a/src/unconstrained_helpers.nr b/src/unconstrained_helpers.nr new file mode 100644 index 00000000..0d9dd581 --- /dev/null +++ b/src/unconstrained_helpers.nr @@ -0,0 +1,223 @@ +use crate::utils::u60_representation::U60Repr; +use crate::utils::split_bits; + +use crate::params::BigNumParams as P; + +unconstrained pub(crate) fn __validate_in_field_compute_borrow_flags(params: P, val: [Field; N]) -> [bool; N] { + let mut flags: [bool; N] = [false; N]; + let modulus: [Field; N] = params.modulus; + flags[0] = modulus[0].lt(val[0]); + for i in 1..N - 1 { + flags[i] = modulus[i].lt(val[i] + flags[i - 1] as Field); + } + flags +} + +unconstrained pub(crate) fn __validate_gt_remainder(lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [bool; N], [bool; N]) { + let a_u60 : U60Repr = U60Repr::from(lhs); + let mut b_u60 : U60Repr = U60Repr::from(rhs); + + let underflow = b_u60.gte(a_u60); + b_u60 += U60Repr::one(); + assert(underflow == false, "BigNum::validate_gt check fails"); + let mut addend_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; + let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; + + let mut carry: u64 = 0; + let mut carry_in: u64 = 0; + let mut borrow: u64 = 0; + let mut borrow_in: u64 = 0; + let mut borrow_flags: [bool; N] = [false; N]; + let mut carry_flags: [bool; N] = [false; N]; + for i in 0..2 * N { + let mut add_term: u64 = a_u60.limbs[i] + addend_u60.limbs[i] + carry_in; + carry = (add_term >= 0x1000000000000000) as u64; + add_term -= (carry as u64 * 0x1000000000000000); + result_u60.limbs[i] = add_term; + carry_in = carry as u64; + borrow = ((b_u60.limbs[i] + borrow_in) > result_u60.limbs[i]) as u64; + let sub = (borrow << 60) + result_u60.limbs[i] - b_u60.limbs[i] - borrow_in; + result_u60.limbs[i] = sub; + borrow_in = borrow; + + if ((i & 1) == 1) { + if (carry & borrow == 1) { + carry = 0; + borrow = 0; + } + carry_flags[i/2] = carry as bool; + borrow_flags[i/2] = borrow as bool; + } + } + + let result = U60Repr::into(result_u60); + (result, carry_flags, borrow_flags) +} + +unconstrained pub(crate) fn __neg_with_flags(params: P, val: [Field; N]) -> ([Field; N], [bool; N]) { + let x_u60 : U60Repr = U60Repr::from(val); + let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; + + let mut borrow: u64 = 0; + let mut borrow_in: u64 = 0; + + let mut borrow_flags: [bool; N] = [false; N]; + for i in 0..2 * N { + borrow = ((x_u60.limbs[i] + borrow_in) > params.modulus_u60.limbs[i]) as u64; + let sub = (borrow << 60) + params.modulus_u60.limbs[i] - x_u60.limbs[i] - borrow_in; + result_u60.limbs[i] = sub; + borrow_in = borrow; + if ((i & 1) == 1) { + borrow_flags[i / 2] = borrow as bool; + } + } + let result = U60Repr::into(result_u60); + (result, borrow_flags) +} + +unconstrained pub(crate) fn __add_with_flags(params: P, lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [bool; N], [bool; N], bool) { + let a_u60 : U60Repr = U60Repr::from(lhs); + let b_u60 : U60Repr = U60Repr::from(rhs); + let add_u60 = a_u60 + b_u60; + + let overflow = add_u60.gte(params.modulus_u60); + + let mut subtrahend_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; + let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; + + if overflow { + subtrahend_u60 = params.modulus_u60; + } + + let mut carry: u64 = 0; + let mut carry_in: u64 = 0; + let mut borrow: u64 = 0; + let mut borrow_in: u64 = 0; + let mut borrow_flags: [bool; N] = [false; N]; + let mut carry_flags: [bool; N] = [false; N]; + for i in 0..2 * N { + let mut add_term: u64 = a_u60.limbs[i] + b_u60.limbs[i] + carry_in; + carry = (add_term >= 0x1000000000000000) as u64; + add_term -= (carry as u64 * 0x1000000000000000); + result_u60.limbs[i] = add_term; + carry_in = carry as u64; + borrow = ((subtrahend_u60.limbs[i] + borrow_in) > result_u60.limbs[i]) as u64; + let sub = (borrow << 60) + result_u60.limbs[i] - subtrahend_u60.limbs[i] - borrow_in; + result_u60.limbs[i] = sub; + borrow_in = borrow; + + if ((i & 1) == 1) { + let idx = (i - 1) / 2; + if (carry & borrow == 1) { + carry = 0; + borrow = 0; + } + carry_flags[idx] = carry as bool; + borrow_flags[idx] = borrow as bool; + } + } + let result = U60Repr::into(result_u60); + + (result, carry_flags, borrow_flags, overflow) +} + +unconstrained pub(crate) fn __sub_with_flags(params: P, lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [bool; N], [bool; N], bool) { + let a_u60 : U60Repr = U60Repr::from(lhs); + let b_u60 : U60Repr = U60Repr::from(rhs); + + let underflow = b_u60.gte(a_u60 + U60Repr::one()); + + let mut addend_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; + let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; + + if underflow { + addend_u60 = params.modulus_u60; + } + + let mut carry: u64 = 0; + let mut carry_in: u64 = 0; + let mut borrow: u64 = 0; + let mut borrow_in: u64 = 0; + let mut borrow_flags: [bool; N] = [false; N]; + let mut carry_flags: [bool; N] = [false; N]; + for i in 0..2 * N { + let mut add_term: u64 = a_u60.limbs[i] + addend_u60.limbs[i] + carry_in; + carry = (add_term >= 0x1000000000000000) as u64; + add_term -= (carry as u64 * 0x1000000000000000); + result_u60.limbs[i] = add_term; + carry_in = carry as u64; + borrow = ((b_u60.limbs[i] + borrow_in) > result_u60.limbs[i]) as u64; + let sub = (borrow << 60) + result_u60.limbs[i] - b_u60.limbs[i] - borrow_in; + result_u60.limbs[i] = sub; + borrow_in = borrow; + + if ((i & 1) == 1) { + if (carry & borrow == 1) { + carry = 0; + borrow = 0; + } + carry_flags[i/2] = carry as bool; + borrow_flags[i/2] = borrow as bool; + } + } + let result = U60Repr::into(result_u60); + (result, carry_flags, borrow_flags, underflow) +} + +unconstrained pub(crate) fn __barrett_reduction( + x: [Field; 2 * N], + redc_param: [Field; N], + k: u32, + modulus: [Field; N], + modulus_u60: U60Repr +) -> ([Field; N], [Field; N]) { + let mut mulout: [Field; 3 * N] = [0; 3 * N]; + for i in 0..(N + N) { + for j in 0..N { + mulout[i + j] += x[i] * redc_param[j]; + } + } + mulout = split_bits::__normalize_limbs(mulout, 3 * N - 1); + let mulout_u60: U60Repr = U60Repr::new(mulout); + let mut quotient_u60 = mulout_u60.shr((k + k)); + + // N.B. we assume that the shifted quotient cannot exceed 2 times original bit size. + // (partial_quotient should be just slightly larger than the modulus, we could probably represent with a size N+1 array) + let partial_quotient_full: [Field; 3 * N] = quotient_u60.into_field_array(); + let mut partial_quotient: [Field; 2 * N] = [0; 2 * N]; + for i in 0..2 * N { + partial_quotient[i] = partial_quotient_full[i]; + } + // quotient_mul_modulus can never exceed input value `x` so can fit into size-2 array + let mut quotient_mul_modulus: [Field; 2 * N] = [0; 2 * N]; + let mut quotient_mul_modulus_normalized: [Field; 2 * N] = [0; 2 * N]; + for j in 0..N { + for i in 0..(N + N - j) { + quotient_mul_modulus[i + j] += partial_quotient[i] * modulus[j]; + } + } + + for i in 0..(N + N) { + let (lo, hi) = split_bits::split_120_bits(quotient_mul_modulus[i]); + quotient_mul_modulus_normalized[i] = lo; + // TODO: what is faster, leaving this if statement in or out? + // (array is size-1 too large so we can tolerate adding 0 into max element) + if (i + 1 < N + N) { + quotient_mul_modulus[i + 1] += hi; + } + } + let quotient_mul_modulus_u60: U60Repr = U60Repr::new(quotient_mul_modulus_normalized); + + let x_u60 : U60Repr = U60Repr::new(x); + let mut remainder_u60 = x_u60 - quotient_mul_modulus_u60; + + if (remainder_u60.gte(modulus_u60)) { + remainder_u60 = remainder_u60 - modulus_u60; + quotient_u60.increment(); + } else {} + + let q: [Field; N] = U60Repr::into(quotient_u60); + let r: [Field; N] = U60Repr::into(remainder_u60); + + (q, r) +} diff --git a/src/unconstrained_ops.nr b/src/unconstrained_ops.nr new file mode 100644 index 00000000..f2650abf --- /dev/null +++ b/src/unconstrained_ops.nr @@ -0,0 +1,290 @@ +use crate::utils::u60_representation::U60Repr; +use crate::utils::split_bits; + +use crate::params::BigNumParams as P; +use crate::unconstrained_helpers::__barrett_reduction; + +unconstrained pub(crate) fn __one() -> [Field; N] { + let mut limbs: [Field; N] = [0; N]; + limbs[0] = 1; + limbs +} + +unconstrained pub(crate) fn __derive_from_seed(params: P, seed: [u8; SeedBytes]) -> [Field; N] { + let mut rolling_seed = seed; + + let mut to_reduce: [Field; 2 * N] = [0; 2 * N]; + + let modulus_bits_getter = params.modulus_bits_getter; + let modulus_bits = modulus_bits_getter(); + let mut double_modulus_bits = modulus_bits * 2; + let mut double_modulus_bytes = (double_modulus_bits) / 8 + (double_modulus_bits % 8 != 0) as u32; + + let mut last_limb_bytes = double_modulus_bytes % 15; + if (last_limb_bytes == 0) { + last_limb_bytes = 15; + } + let mut last_limb_bits = double_modulus_bits % 8; + if (last_limb_bits == 0) { + last_limb_bits = 8; + } + + for i in 0..(N - 1) { + let hash: [u8; 32] = std::hash::sha256(rolling_seed); + let mut lo: Field = 0; + let mut hi: Field = 0; + for j in 0..15 { + hi *= 256; + lo *= 256; + + if (i < 2 * N - 2) { + lo += hash[j + 15] as Field; + hi += hash[j] as Field; + } + } + to_reduce[2 * i] = lo; + to_reduce[2 * i + 1] = hi; + rolling_seed[0] += 1; + } + + { + let hash: [u8; 32] = std::hash::sha256(rolling_seed); + let mut hi: Field = 0; + for j in 0..(last_limb_bytes - 1) { + hi *= 256; + hi += hash[j] as Field; + } + hi *= 256; + let last_byte = hash[last_limb_bytes - 1]; + let mask = (1 as u64 << (last_limb_bits) as u8) - 1; + let last_bits = last_byte as u64 & mask; + hi += last_bits as Field; + to_reduce[2 * N - 2] = hi; + } + let modulus_bits_getter = params.modulus_bits_getter; + let modulus_bits = modulus_bits_getter(); + let (_, remainder) = __barrett_reduction( + to_reduce, + params.redc_param, + modulus_bits, + params.modulus, + params.modulus_u60_x4 + ); + let result = remainder; + result +} + +unconstrained pub(crate) fn __eq(lhs: [Field; N], rhs: [Field; N]) -> bool { + lhs == rhs +} + +unconstrained pub(crate) fn __is_zero(limbs: [Field; N]) -> bool { + let mut result: bool = true; + for i in 0..N { + result = result & (limbs[i] == 0); + } + result +} + +/** +* @brief given an input `x`, compute `2p - x` (unconstrained) +* +* @description we subtract the input from double the modulus, because all constrained BigNum operations +* only guarantee that the output is in the range [0, ceil(log2(p))]. +* I.E. the input may be larger than the modulus `p`. +* In order to ensure this operation does not underflow, we compute `2p - x` instead of `p - x`. +* N.B. constrained BigNum operations do not fully constrain outputs to be in the range [0, p-1] +* because such a check is expensive and usually unneccesary. +*/ +unconstrained pub(crate) fn __neg(params: P, limbs: [Field; N]) -> [Field; N] { + let f: [Field; N] = limbs; + let x_u60 : U60Repr = U60Repr::from(f); + U60Repr::into(params.modulus_u60 - x_u60) +} + +unconstrained pub(crate) fn __add( + params: P, + lhs: [Field; N], + rhs: [Field; N] +) -> [Field; N] { + let x_u60 : U60Repr = U60Repr::from(lhs); + let y_u60 : U60Repr = U60Repr::from(rhs); + + let mut z_u60 = x_u60 + y_u60; + + if z_u60.gte(params.modulus_u60) { + z_u60 = z_u60 - params.modulus_u60; + } + U60Repr::into(z_u60) +} + +/** +* @brief given inputs `x, y` compute 2p + x - y (unconstrained) +* @description see `__neg` for why we use 2p instead of p +**/ +unconstrained pub(crate) fn __sub(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { + __add(params, lhs, __neg(params, rhs)) +} + +unconstrained pub(crate) fn __mul_with_quotient(params: P, lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [Field; N]) { + let mut mul: [Field; 2 * N] = [0; 2 * N]; + for i in 0..N { + for j in 0..N { + mul[i + j] += lhs[i] * rhs[j]; + } + } + let modulus_bits_getter = params.modulus_bits_getter; + let modulus_bits = modulus_bits_getter(); + let (q, r) = __barrett_reduction( + split_bits::__normalize_limbs(mul, 2 * N), + params.redc_param, + modulus_bits, + params.modulus, + params.modulus_u60_x4 + ); + + (q, r) +} + +unconstrained pub(crate) fn __mul( + params: P, + lhs: [Field; N], + rhs: [Field; N] +) -> [Field; N] { + let (_, b) = __mul_with_quotient(params, lhs, rhs); + b +} + +unconstrained pub(crate) fn __div( + params: P, + numerator: [Field; N], + divisor: [Field; N] +) -> [Field; N] { + let inv_divisor = __invmod(params, divisor); + __mul(params, numerator, inv_divisor) +} + +/** +* @brief __udiv_mod performs *unconstrained* integer division between numerator, divisor +* +* i.e. 1. floor(numerator / divisor) = quotient +* 2. numerator % divisor = remainder +* 3. divisor * quotient + remainder = numerator +**/ +unconstrained pub(crate) fn __udiv_mod(numerator: [Field; N], divisor: [Field; N]) -> ([Field; N], [Field; N]) { + let mut quotient_u60: U60Repr = U60Repr::from([0; N]); + let mut remainder_u60: U60Repr = U60Repr::from(numerator); + + let mut divisor_u60: U60Repr = U60Repr::from(divisor); + let b = divisor_u60; + + let mut bit_difference = remainder_u60.get_msb() - divisor_u60.get_msb(); + + let mut accumulator_u60: U60Repr = U60Repr::one(); + divisor_u60 = divisor_u60.shl(bit_difference); + accumulator_u60 = accumulator_u60.shl(bit_difference); + + if (divisor_u60.gte(remainder_u60 + U60Repr::one())) { + divisor_u60.shr1(); + accumulator_u60.shr1(); + } + for _ in 0..(N * 120) { + if (remainder_u60.gte(b) == false) { + break; + } + + // we've shunted 'divisor' up to have the same bit length as our remainder. + // If remainder >= divisor, then a is at least '1 << bit_difference' multiples of b + if (remainder_u60.gte(divisor_u60)) { + remainder_u60 -= divisor_u60; + // we can use OR here instead of +, as + // accumulator is always a nice power of two + quotient_u60 = quotient_u60 + accumulator_u60; + } + divisor_u60.shr1(); // >>= 1; + accumulator_u60.shr1(); // >>= 1; + } + + (U60Repr::into(quotient_u60), U60Repr::into(remainder_u60)) +} + +unconstrained pub(crate) fn __invmod(params: P, val: [Field; N]) -> [Field; N] { + let one: [Field; N] = __one::(); + let one_u60: U60Repr = U60Repr::from(one); + let exp_u60 = params.modulus_u60.sub(one_u60.add(one_u60)); + let exp = U60Repr::into(exp_u60); + __pow(params, val, exp) +} + +unconstrained pub(crate) fn __pow( + params: P, + val: [Field; N], + exponent: [Field; N] +) -> [Field; N] { + let x: U60Repr = U60Repr::from(exponent); + + let modulus_bits_getter = params.modulus_bits_getter; + let modulus_bits = modulus_bits_getter(); + let num_bits = modulus_bits + 1; + + let mut accumulator: [Field; N] = __one::(); + + for i in 0..num_bits { + accumulator = __mul(params, accumulator, accumulator); + if x.get_bit(num_bits - i - 1) { + accumulator = __mul(params, accumulator, val); + } + } + accumulator +} + +unconstrained pub(crate) fn __batch_invert(params: P, x: [[Field; N]; M]) -> [[Field; N]; M] { + // TODO: ugly! Will fail if input slice is empty + let mut accumulator: [Field; N] = __one::(); + let mut result: [[Field; N]; M] = [[0; N]; M]; + let mut temporaries: [[Field; N]] = &[]; + for i in 0..x.len() { + temporaries = temporaries.push_back(accumulator); + if (__is_zero(x[i]) == false) { + accumulator = __mul(params, accumulator, x[i]); + } + } + + accumulator = __invmod(params, accumulator); + let mut T0: [Field; N] = [0; N]; + for i in 0..x.len() { + let idx = x.len() - 1 - i; + if (__is_zero(x[idx]) == false) { + T0 = __mul(params, accumulator, temporaries[idx]); + accumulator = __mul(params, accumulator, x[idx]); + result[idx] = T0; + } + } + result +} + +unconstrained pub(crate) fn __batch_invert_slice(params: P, x: [[Field; N]]) -> [[Field; N]] { + // TODO: ugly! Will fail if input slice is empty + let mut accumulator: [Field; N] = __one::(); + let mut result: [[Field; N]] = [[0; N]]; + let mut temporaries: [[Field; N]] = &[]; + for i in 0..x.len() { + temporaries = temporaries.push_back(accumulator); + if (__is_zero(x[i]) == false) { + accumulator = __mul(params, accumulator, x[i]); + } + result = result.push_back([0; N]); + } + + accumulator = __invmod(params, accumulator); + let mut T0: [Field; N] = [0; N]; + for i in 0..x.len() { + let idx = x.len() - 1 - i; + if (__is_zero(x[idx]) == false) { + T0 = __mul(params, accumulator, temporaries[idx]); + accumulator = __mul(params, accumulator, x[idx]); + result[idx] = T0; + } + } + result +} diff --git a/src/utils/map.nr b/src/utils/map.nr new file mode 100644 index 00000000..50e3d13c --- /dev/null +++ b/src/utils/map.nr @@ -0,0 +1,12 @@ +// Copied from std::array, because I couldn't figure out how to import the `map` method of the weird trait for an array. +// And the reason I wanted direct access to it, is because I couldn't figure out how to implement a double map. +pub fn map(arr: [T; N], f: fn[Env](T) -> U) -> [U; N] { + let first_elem = f(arr[0]); + let mut ret = [first_elem; N]; + + for i in 1..arr.len() { + ret[i] = f(arr[i]); + } + + ret +} diff --git a/src/utils/mod.nr b/src/utils/mod.nr index ca761e47..3d75400e 100644 --- a/src/utils/mod.nr +++ b/src/utils/mod.nr @@ -1,4 +1,5 @@ -pub(crate) mod u60_representation; -pub(crate) mod split_bits; -pub(crate) mod u60_representation_test; -pub(crate) mod msb; +mod u60_representation; +mod split_bits; +mod u60_representation_test; +mod msb; +mod map; From b7de59442a703a8df738917a7b37d1eba93ca068 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Thu, 3 Oct 2024 11:54:04 +0100 Subject: [PATCH 02/29] silence warnings --- src/bignum.nr | 16 ++++++++-------- src/bignum_test.nr | 6 +++--- src/fields/U1024.nr | 6 +++--- src/fields/U2048.nr | 6 +++--- src/fields/U256.nr | 4 ++-- src/fields/U384.nr | 6 +++--- src/fields/U4096.nr | 6 +++--- src/fields/U512.nr | 6 +++--- src/fields/U768.nr | 6 +++--- src/fields/U8192.nr | 6 +++--- src/fields/bls12_377Fq.nr | 4 ++-- src/fields/bls12_377Fr.nr | 6 +++--- src/fields/bls12_381Fq.nr | 6 +++--- src/fields/bls12_381Fr.nr | 7 ++++--- src/fields/bn254Fq.nr | 4 ++-- src/fields/ed25519Fq.nr | 6 +++--- src/fields/ed25519Fr.nr | 6 +++--- src/fields/mnt4_753Fq.nr | 6 +++--- src/fields/mnt4_753Fr.nr | 6 +++--- src/fields/mnt6_753Fq.nr | 6 +++--- src/fields/mnt6_753Fr.nr | 6 +++--- src/fields/pallasFq.nr | 6 +++--- src/fields/pallasFr.nr | 6 +++--- src/fields/secp256k1Fq.nr | 6 +++--- src/fields/secp256k1Fr.nr | 6 +++--- src/fields/secp256r1Fq.nr | 6 +++--- src/fields/secp256r1Fr.nr | 6 +++--- src/fields/secp384r1Fq.nr | 6 +++--- src/fields/secp384r1Fr.nr | 6 +++--- src/fields/vestaFq.nr | 6 +++--- src/fields/vestaFr.nr | 6 +++--- src/params.nr | 6 +++--- src/runtime_bignum_test.nr | 5 ++--- src/utils/u60_representation_test.nr | 24 +++++++++++++++++------- 34 files changed, 118 insertions(+), 108 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index d27905e4..7b2108b9 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -1,6 +1,6 @@ use crate::utils::map::map; -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::constrained_ops::{ conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, neg, add, sub, mul, div, udiv_mod, udiv, umod @@ -85,7 +85,7 @@ pub(crate) trait BigNumTrait { fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; } -impl BigNumTrait for BigNum where Params: BigNumParamsTrait { +impl BigNumTrait for BigNum where Params: BigNumParamsGetter { fn new() -> Self { Self { limbs: [0; N] } @@ -292,9 +292,9 @@ impl BigNumTrait for BigNum where Params: BigN } } -// impl BigNumTrait for BigNum where Params: BigNumParamsTrait {} +// impl BigNumTrait for BigNum where Params: BigNumParamsGetter {} -impl std::ops::Add for BigNum where Params: BigNumParamsTrait { +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 { @@ -303,7 +303,7 @@ impl std::ops::Add for BigNum where Params: BigNu } } -impl std::ops::Sub for BigNum where Params: BigNumParamsTrait { +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 { @@ -312,7 +312,7 @@ impl std::ops::Sub for BigNum where Params: BigNu } } -impl std::ops::Mul for BigNum where Params: BigNumParamsTrait { +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` @@ -323,7 +323,7 @@ impl std::ops::Mul for BigNum where Params: BigNu } } -impl std::ops::Div for BigNum where Params: BigNumParamsTrait { +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(); @@ -331,7 +331,7 @@ impl std::ops::Div for BigNum where Params: BigNu } } -impl std::cmp::Eq for BigNum where Params: BigNumParamsTrait { +impl std::cmp::Eq for BigNum where Params: BigNumParamsGetter { fn eq(self, other: Self) -> bool { let params = Params::get_params(); eq(params, self.limbs, other.limbs) diff --git a/src/bignum_test.nr b/src/bignum_test.nr index 146afa0e..1fbb9966 100644 --- a/src/bignum_test.nr +++ b/src/bignum_test.nr @@ -4,7 +4,7 @@ use crate::bignum::BigNum; use crate::bignum::BigNumTrait; use crate::params::BigNumParams; -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::fields::bn254Fq::BN254_Fq_Params; use crate::fields::U256::U256Params; @@ -17,7 +17,7 @@ fn silence_warning() { let _ = Test2048Params {}; } -impl BigNumParamsTrait<18> for Test2048Params { +impl BigNumParamsGetter<18> for Test2048Params { fn get_params() -> BigNumParams<18> { let has_multiplicative_inverse = false; let modulus_bits_getter = || 2048; @@ -94,7 +94,7 @@ fn test_eq() where BN: BigNumTrait { assert(c.eq(a) == false); } -// fn test_eq(_: BigNum) where Params: BigNumParamsTrait + RuntimeBigNumParamsTrait { +// fn test_eq(_: BigNum) where Params: BigNumParamsGetter + RuntimeBigNumParamsTrait { // let a = BigNum::__derive_from_seed([1, 2, 3, 4]); // let b = BigNum::__derive_from_seed([1, 2, 3, 4]); // let c = BigNum::__derive_from_seed([2, 2, 3, 4]); diff --git a/src/fields/U1024.nr b/src/fields/U1024.nr index aedfd269..6dc7ffcc 100644 --- a/src/fields/U1024.nr +++ b/src/fields/U1024.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global U1024_PARAMS: BigNumParams<9> = BigNumParams { ] }; -struct U1024Params {} +pub struct U1024Params {} -impl BigNumParamsTrait<9> for U1024Params { +impl BigNumParamsGetter<9> for U1024Params { fn get_params() -> BigNumParams<9> { U1024_PARAMS } diff --git a/src/fields/U2048.nr b/src/fields/U2048.nr index a677b974..99fc3bdf 100644 --- a/src/fields/U2048.nr +++ b/src/fields/U2048.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global U2048_PARAMS: BigNumParams<18> = BigNumParams { ] }; -struct U2048Params {} +pub struct U2048Params {} -impl BigNumParamsTrait<18> for U2048Params { +impl BigNumParamsGetter<18> for U2048Params { fn get_params() -> BigNumParams<18> { U2048_PARAMS } diff --git a/src/fields/U256.nr b/src/fields/U256.nr index 10951b32..19b40cad 100644 --- a/src/fields/U256.nr +++ b/src/fields/U256.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -22,7 +22,7 @@ global U256_PARAMS: BigNumParams<3> = BigNumParams { pub struct U256Params {} -impl BigNumParamsTrait<3> for U256Params { +impl BigNumParamsGetter<3> for U256Params { fn get_params() -> BigNumParams<3> { U256_PARAMS } diff --git a/src/fields/U384.nr b/src/fields/U384.nr index 59a47181..dba9054e 100644 --- a/src/fields/U384.nr +++ b/src/fields/U384.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global U384_PARAMS: BigNumParams<4> = BigNumParams { ] }; -struct U384_Params {} +pub struct U384_Params {} -impl BigNumParamsTrait<4> for U384_Params { +impl BigNumParamsGetter<4> for U384_Params { fn get_params() -> BigNumParams<4> { U384_PARAMS } diff --git a/src/fields/U4096.nr b/src/fields/U4096.nr index 88b84fc2..441c28e0 100644 --- a/src/fields/U4096.nr +++ b/src/fields/U4096.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global U4096_PARAMS: BigNumParams<35> = BigNumParams { ] }; -struct U4096Params {} +pub struct U4096Params {} -impl BigNumParamsTrait<35> for U4096Params { +impl BigNumParamsGetter<35> for U4096Params { fn get_params() -> BigNumParams<35> { U4096_PARAMS } diff --git a/src/fields/U512.nr b/src/fields/U512.nr index 4aa93f3c..66c3f30d 100644 --- a/src/fields/U512.nr +++ b/src/fields/U512.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global U512_PARAMS: BigNumParams<5> = BigNumParams { ] }; -struct U512Params {} +pub struct U512Params {} -impl BigNumParamsTrait<5> for U512Params { +impl BigNumParamsGetter<5> for U512Params { fn get_params() -> BigNumParams<5> { U512_PARAMS } diff --git a/src/fields/U768.nr b/src/fields/U768.nr index 98223e1a..cf41ce21 100644 --- a/src/fields/U768.nr +++ b/src/fields/U768.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global U768_PARAMS: BigNumParams<13> = BigNumParams { ] }; -struct U768Params {} +pub struct U768Params {} -impl BigNumParamsTrait<13> for U768Params { +impl BigNumParamsGetter<13> for U768Params { fn get_params() -> BigNumParams<13> { U768_PARAMS } diff --git a/src/fields/U8192.nr b/src/fields/U8192.nr index 5c4951b2..d4788d3a 100644 --- a/src/fields/U8192.nr +++ b/src/fields/U8192.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global U8192_PARAMS: BigNumParams<69> = BigNumParams { ] }; -struct U8192Params {} +pub struct U8192Params {} -impl BigNumParamsTrait<69> for U8192Params { +impl BigNumParamsGetter<69> for U8192Params { fn get_params() -> BigNumParams<69> { U8192_PARAMS } diff --git a/src/fields/bls12_377Fq.nr b/src/fields/bls12_377Fq.nr index 7d876a83..5cf050aa 100644 --- a/src/fields/bls12_377Fq.nr +++ b/src/fields/bls12_377Fq.nr @@ -16,7 +16,7 @@ //! * G1 curve equation: y^2 = x^3 + 1 //! * G2 curve equation: y^2 = x^3 + B, where //! * B = Fq2(0, 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906) -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -40,7 +40,7 @@ global BLS12_377_Fq_PARAMS: BigNumParams<4> = BigNumParams { pub struct BLS12_377_Fq_Params {} -impl BigNumParamsTrait<4> for BLS12_377_Fq_Params { +impl BigNumParamsGetter<4> for BLS12_377_Fq_Params { fn get_params() -> BigNumParams<4> { BLS12_377_Fq_PARAMS } diff --git a/src/fields/bls12_377Fr.nr b/src/fields/bls12_377Fr.nr index 572e9358..6b9789f5 100644 --- a/src/fields/bls12_377Fr.nr +++ b/src/fields/bls12_377Fr.nr @@ -16,7 +16,7 @@ //! * G1 curve equation: y^2 = x^3 + 1 //! * G2 curve equation: y^2 = x^3 + B, where //! * B = Fq2(0, 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906) -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -38,9 +38,9 @@ global BLS12_377_Fr_PARAMS: BigNumParams<3> = BigNumParams { ] }; -struct BLS12_377_Fr_Params {} +pub struct BLS12_377_Fr_Params {} -impl BigNumParamsTrait<3> for BLS12_377_Fr_Params { +impl BigNumParamsGetter<3> for BLS12_377_Fr_Params { fn get_params() -> BigNumParams<3> { BLS12_377_Fr_PARAMS } diff --git a/src/fields/bls12_381Fq.nr b/src/fields/bls12_381Fq.nr index fea750f9..93e1ccab 100644 --- a/src/fields/bls12_381Fq.nr +++ b/src/fields/bls12_381Fq.nr @@ -14,7 +14,7 @@ //! * valuation(r - 1, 2) = 32 //! * G1 curve equation: y^2 = x^3 + 4 //! * G2 curve equation: y^2 = x^3 + Fq2(4, 4) -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -36,9 +36,9 @@ global BLS12_381_Fq_PARAMS: BigNumParams<4> = BigNumParams { ] }; -struct BLS12_381_Fq_Params {} +pub struct BLS12_381_Fq_Params {} -impl BigNumParamsTrait<4> for BLS12_381_Fq_Params { +impl BigNumParamsGetter<4> for BLS12_381_Fq_Params { fn get_params() -> BigNumParams<4> { BLS12_381_Fq_PARAMS } diff --git a/src/fields/bls12_381Fr.nr b/src/fields/bls12_381Fr.nr index 6f968dd8..6ccf0667 100644 --- a/src/fields/bls12_381Fr.nr +++ b/src/fields/bls12_381Fr.nr @@ -14,7 +14,7 @@ //! * valuation(r - 1, 2) = 32 //! * G1 curve equation: y^2 = x^3 + 4 //! * G2 curve equation: y^2 = x^3 + Fq2(4, 4) -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -36,8 +36,9 @@ global BLS12_381_Fr_PARAMS: BigNumParams<3> = BigNumParams { ] }; -struct BLS12_381_Fr_Params {} -impl BigNumParamsTrait<3> for BLS12_381_Fr_Params { +pub struct BLS12_381_Fr_Params {} + +impl BigNumParamsGetter<3> for BLS12_381_Fr_Params { fn get_params() -> BigNumParams<3> { BLS12_381_Fr_PARAMS } diff --git a/src/fields/bn254Fq.nr b/src/fields/bn254Fq.nr index 61a4d7f9..eaacd7f1 100644 --- a/src/fields/bn254Fq.nr +++ b/src/fields/bn254Fq.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -22,7 +22,7 @@ global BN254_Fq_PARAMS: BigNumParams<3> = BigNumParams { pub struct BN254_Fq_Params {} -impl BigNumParamsTrait<3> for BN254_Fq_Params { +impl BigNumParamsGetter<3> for BN254_Fq_Params { fn get_params() -> BigNumParams<3> { BN254_Fq_PARAMS } diff --git a/src/fields/ed25519Fq.nr b/src/fields/ed25519Fq.nr index e610153f..d8af5af6 100644 --- a/src/fields/ed25519Fq.nr +++ b/src/fields/ed25519Fq.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global ED25519_Fq_PARAMS: BigNumParams<3> = BigNumParams { ] }; -struct ED25519_Fq_Params {} +pub struct ED25519_Fq_Params {} -impl BigNumParamsTrait<3> for ED25519_Fq_Params { +impl BigNumParamsGetter<3> for ED25519_Fq_Params { fn get_params() -> BigNumParams<3> { ED25519_Fq_PARAMS } diff --git a/src/fields/ed25519Fr.nr b/src/fields/ed25519Fr.nr index 9df6e099..72be347d 100644 --- a/src/fields/ed25519Fr.nr +++ b/src/fields/ed25519Fr.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global ED25519_Fr_PARAMS: BigNumParams<3> = BigNumParams { ] }; -struct ED25519_Fr_Params {} +pub struct ED25519_Fr_Params {} -impl BigNumParamsTrait<3> for ED25519_Fr_Params { +impl BigNumParamsGetter<3> for ED25519_Fr_Params { fn get_params() -> BigNumParams<3> { ED25519_Fr_PARAMS } diff --git a/src/fields/mnt4_753Fq.nr b/src/fields/mnt4_753Fq.nr index 00c84564..14c5d641 100644 --- a/src/fields/mnt4_753Fq.nr +++ b/src/fields/mnt4_753Fq.nr @@ -19,7 +19,7 @@ //! * B = Fq2(0, b * NON_RESIDUE) //! * NON_RESIDUE = 13 is the quadratic non-residue used to conpub struct the //! extension field Fq2 -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -41,9 +41,9 @@ global MNT4_753_Fq_PARAMS: BigNumParams<7> = BigNumParams { ] }; -struct MNT4_753_Fq_Params {} +pub struct MNT4_753_Fq_Params {} -impl BigNumParamsTrait<7> for MNT4_753_Fq_Params { +impl BigNumParamsGetter<7> for MNT4_753_Fq_Params { fn get_params() -> BigNumParams<7> { MNT4_753_Fq_PARAMS } diff --git a/src/fields/mnt4_753Fr.nr b/src/fields/mnt4_753Fr.nr index 68a9d50a..ba8ae9de 100644 --- a/src/fields/mnt4_753Fr.nr +++ b/src/fields/mnt4_753Fr.nr @@ -19,7 +19,7 @@ //! * B = Fq2(0, b * NON_RESIDUE) //! * NON_RESIDUE = 13 is the quadratic non-residue used to conpub struct the //! extension field Fq2 -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -41,9 +41,9 @@ global MNT4_753_Fr_PARAMS: BigNumParams<7> = BigNumParams { ] }; -struct MNT4_753_Fr_Params {} +pub struct MNT4_753_Fr_Params {} -impl BigNumParamsTrait<7> for MNT4_753_Fr_Params { +impl BigNumParamsGetter<7> for MNT4_753_Fr_Params { fn get_params() -> BigNumParams<7> { MNT4_753_Fr_PARAMS } diff --git a/src/fields/mnt6_753Fq.nr b/src/fields/mnt6_753Fq.nr index 2ed18388..d9f03a7a 100644 --- a/src/fields/mnt6_753Fq.nr +++ b/src/fields/mnt6_753Fq.nr @@ -19,7 +19,7 @@ //! * B = Fq3(b * NON_RESIDUE, 0, 0) //! * NON_RESIDUE = 11 is the cubic non-residue used to conpub struct the //! extension field Fq3 -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -41,9 +41,9 @@ global MNT6_753_Fq_PARAMS: BigNumParams<7> = BigNumParams { ] }; -struct MNT6_753_Fq_Params {} +pub struct MNT6_753_Fq_Params {} -impl BigNumParamsTrait<7> for MNT6_753_Fq_Params { +impl BigNumParamsGetter<7> for MNT6_753_Fq_Params { fn get_params() -> BigNumParams<7> { MNT6_753_Fq_PARAMS } diff --git a/src/fields/mnt6_753Fr.nr b/src/fields/mnt6_753Fr.nr index 7f88e572..b07cacdc 100644 --- a/src/fields/mnt6_753Fr.nr +++ b/src/fields/mnt6_753Fr.nr @@ -19,7 +19,7 @@ //! * B = Fq3(b * NON_RESIDUE, 0, 0) //! * NON_RESIDUE = 11 is the cubic non-residue used to conpub struct the //! extension field Fq3 -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -41,9 +41,9 @@ global MNT6_753_Fr_PARAMS: BigNumParams<7> = BigNumParams { ] }; -struct MNT6_753_Fr_Params {} +pub struct MNT6_753_Fr_Params {} -impl BigNumParamsTrait<7> for MNT6_753_Fr_Params { +impl BigNumParamsGetter<7> for MNT6_753_Fr_Params { fn get_params() -> BigNumParams<7> { MNT6_753_Fr_PARAMS } diff --git a/src/fields/pallasFq.nr b/src/fields/pallasFq.nr index 06023e1a..4265ae55 100644 --- a/src/fields/pallasFq.nr +++ b/src/fields/pallasFq.nr @@ -13,7 +13,7 @@ //! * Curve equation: y^2 = x^3 + 5 //! * Valuation(q - 1, 2) = 32 //! * Valuation(r - 1, 2) = 32 -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -35,9 +35,9 @@ global Pallas_Fq_PARAMS: BigNumParams<3> = BigNumParams { ] }; -struct Pallas_Fq_Params {} +pub struct Pallas_Fq_Params {} -impl BigNumParamsTrait<3> for Pallas_Fq_Params { +impl BigNumParamsGetter<3> for Pallas_Fq_Params { fn get_params() -> BigNumParams<3> { Pallas_Fq_PARAMS } diff --git a/src/fields/pallasFr.nr b/src/fields/pallasFr.nr index 19946f83..e696d38f 100644 --- a/src/fields/pallasFr.nr +++ b/src/fields/pallasFr.nr @@ -13,7 +13,7 @@ //! * Curve equation: y^2 = x^3 + 5 //! * Valuation(q - 1, 2) = 32 //! * Valuation(r - 1, 2) = 32 -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -35,9 +35,9 @@ global Pallas_Fr_PARAMS: BigNumParams<3> = BigNumParams { ] }; -struct Pallas_Fr_Params {} +pub struct Pallas_Fr_Params {} -impl BigNumParamsTrait<3> for Pallas_Fr_Params { +impl BigNumParamsGetter<3> for Pallas_Fr_Params { fn get_params() -> BigNumParams<3> { Pallas_Fr_PARAMS } diff --git a/src/fields/secp256k1Fq.nr b/src/fields/secp256k1Fq.nr index 9f11555a..8615e19e 100644 --- a/src/fields/secp256k1Fq.nr +++ b/src/fields/secp256k1Fq.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global Secp256k1_Fq_PARAMS: BigNumParams<3> = BigNumParams { ] }; -struct Secp256k1_Fq_Params {} +pub struct Secp256k1_Fq_Params {} -impl BigNumParamsTrait<3> for Secp256k1_Fq_Params { +impl BigNumParamsGetter<3> for Secp256k1_Fq_Params { fn get_params() -> BigNumParams<3> { Secp256k1_Fq_PARAMS } diff --git a/src/fields/secp256k1Fr.nr b/src/fields/secp256k1Fr.nr index 0ce1a703..65474658 100644 --- a/src/fields/secp256k1Fr.nr +++ b/src/fields/secp256k1Fr.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global Secp256k1_Fr_PARAMS: BigNumParams<3> = BigNumParams { ] }; -struct Secp256k1_Fr_Params {} +pub struct Secp256k1_Fr_Params {} -impl BigNumParamsTrait<3> for Secp256k1_Fr_Params { +impl BigNumParamsGetter<3> for Secp256k1_Fr_Params { fn get_params() -> BigNumParams<3> { Secp256k1_Fr_PARAMS } diff --git a/src/fields/secp256r1Fq.nr b/src/fields/secp256r1Fq.nr index 56fb42d5..acad7082 100644 --- a/src/fields/secp256r1Fq.nr +++ b/src/fields/secp256r1Fq.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global Secp256r1_Fq_PARAMS: BigNumParams<3> = BigNumParams { ] }; -struct Secp256r1_Fq_Params {} +pub struct Secp256r1_Fq_Params {} -impl BigNumParamsTrait<3> for Secp256r1_Fq_Params { +impl BigNumParamsGetter<3> for Secp256r1_Fq_Params { fn get_params() -> BigNumParams<3> { Secp256r1_Fq_PARAMS } diff --git a/src/fields/secp256r1Fr.nr b/src/fields/secp256r1Fr.nr index 7b1cc7b9..4ed0088b 100644 --- a/src/fields/secp256r1Fr.nr +++ b/src/fields/secp256r1Fr.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global Secp256r1_Fr_PARAMS: BigNumParams<3> = BigNumParams { ] }; -struct Secp256r1_Fr_Params {} +pub struct Secp256r1_Fr_Params {} -impl BigNumParamsTrait<3> for Secp256r1_Fr_Params { +impl BigNumParamsGetter<3> for Secp256r1_Fr_Params { fn get_params() -> BigNumParams<3> { Secp256r1_Fr_PARAMS } diff --git a/src/fields/secp384r1Fq.nr b/src/fields/secp384r1Fq.nr index 22814829..9149f604 100644 --- a/src/fields/secp384r1Fq.nr +++ b/src/fields/secp384r1Fq.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global Secp384r1_Fq_PARAMS: BigNumParams<4> = BigNumParams { ] }; -struct Secp384r1_Fq_Params {} +pub struct Secp384r1_Fq_Params {} -impl BigNumParamsTrait<4> for Secp384r1_Fq_Params { +impl BigNumParamsGetter<4> for Secp384r1_Fq_Params { fn get_params() -> BigNumParams<4> { Secp384r1_Fq_PARAMS } diff --git a/src/fields/secp384r1Fr.nr b/src/fields/secp384r1Fr.nr index 76d95078..75393219 100644 --- a/src/fields/secp384r1Fr.nr +++ b/src/fields/secp384r1Fr.nr @@ -1,4 +1,4 @@ -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -20,9 +20,9 @@ global Secp384r1_Fr_PARAMS: BigNumParams<4> = BigNumParams { ] }; -struct Secp384r1_Fr_Params {} +pub struct Secp384r1_Fr_Params {} -impl BigNumParamsTrait<4> for Secp384r1_Fr_Params { +impl BigNumParamsGetter<4> for Secp384r1_Fr_Params { fn get_params() -> BigNumParams<4> { Secp384r1_Fr_PARAMS } diff --git a/src/fields/vestaFq.nr b/src/fields/vestaFq.nr index 202eb2be..0fcecf4e 100644 --- a/src/fields/vestaFq.nr +++ b/src/fields/vestaFq.nr @@ -14,7 +14,7 @@ //! * Curve equation: y^2 = x^3 + 5 //! * Valuation(q - 1, 2) = 32 //! * Valuation(r - 1, 2) = 32 -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -36,9 +36,9 @@ global Vesta_Fq_PARAMS: BigNumParams<3> = BigNumParams { ] }; -struct Vesta_Fq_Params {} +pub struct Vesta_Fq_Params {} -impl BigNumParamsTrait<3> for Vesta_Fq_Params { +impl BigNumParamsGetter<3> for Vesta_Fq_Params { fn get_params() -> BigNumParams<3> { Vesta_Fq_PARAMS } diff --git a/src/fields/vestaFr.nr b/src/fields/vestaFr.nr index 46e6560b..c0367491 100644 --- a/src/fields/vestaFr.nr +++ b/src/fields/vestaFr.nr @@ -14,7 +14,7 @@ //! * Curve equation: y^2 = x^3 + 5 //! * Valuation(q - 1, 2) = 32 //! * Valuation(r - 1, 2) = 32 -use crate::params::BigNumParamsTrait; +use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; @@ -36,9 +36,9 @@ global Vesta_Fr_PARAMS: BigNumParams<3> = BigNumParams { ] }; -struct Vesta_Fr_Params {} +pub struct Vesta_Fr_Params {} -impl BigNumParamsTrait<3> for Vesta_Fr_Params { +impl BigNumParamsGetter<3> for Vesta_Fr_Params { fn get_params() -> BigNumParams<3> { Vesta_Fr_PARAMS } diff --git a/src/params.nr b/src/params.nr index a9c6046b..bde9c676 100644 --- a/src/params.nr +++ b/src/params.nr @@ -22,7 +22,7 @@ pub(crate) struct BigNumParams { } // To be implemented by the user, or within the prebuilt options in the `fields/` dir. -pub(crate) trait BigNumParamsTrait { +pub(crate) trait BigNumParamsGetter { fn get_params() -> BigNumParams; } @@ -67,10 +67,10 @@ fn get_double_modulus(modulus: [Field; N]) -> [Field; N] { } // /** -// * @brief BigNumParamsTrait defines a "field" with which to parametrise BigNum. +// * @brief BigNumParamsGetter defines a "field" with which to parametrise BigNum. // * @description The "field" does not need to be prime, any value *should* work (TODO: test!) // **/ -// trait BigNumParamsTrait { +// trait BigNumParamsGetter { // fn has_multiplicative_inverse() -> bool; // // @brief modulus_bits = log2(modulus) rounded up // fn modulus_bits() -> u32; diff --git a/src/runtime_bignum_test.nr b/src/runtime_bignum_test.nr index 51f9d60b..61e318d8 100644 --- a/src/runtime_bignum_test.nr +++ b/src/runtime_bignum_test.nr @@ -1,10 +1,9 @@ use crate::utils::u60_representation::U60Repr; - use crate::runtime_bignum::RuntimeBigNum; - use crate::params::BigNumParams; +use crate::fields::bn254Fq::BN254_Fq_Params; -use crate::fields::bn254Fq::BN254_Fq_PARAMS; +global BN254_Fq_PARAMS = BN254_Fq_Params::get_params(); fn get_2048_BN_params() -> BigNumParams<18> { let has_multiplicative_inverse = false; diff --git a/src/utils/u60_representation_test.nr b/src/utils/u60_representation_test.nr index f32c1133..3029fed1 100644 --- a/src/utils/u60_representation_test.nr +++ b/src/utils/u60_representation_test.nr @@ -1,7 +1,7 @@ use crate::utils::u60_representation::U60Repr; #[test] -fn test_conversion() { +unconstrained fn test_conversion() { let p = 0xffffffffffffffffffffffffffffff; // 2^120 - 1 let expected: [Field; 3 * 2] = [p, p - 1, p - 2, p - 3, p - 4, p - 5]; let u60repr: U60Repr<3, 4> = U60Repr::new(expected); @@ -19,10 +19,14 @@ fn test_shr() { // 120 bits of 01010101 (repeating) let Y = 0x555555555555555555555555555555; let input: [Field; 6] = [X, X, X, X, X, X]; - let u60repr: U60Repr<3, 6> = U60Repr::new(input); + let u60repr: U60Repr<3, 6> = unsafe { + U60Repr::new(input) + }; let result = u60repr.shr(121); - let expected: U60Repr<3, 6> = U60Repr::new([Y, Y, Y, Y, Y, 0]); + let expected: U60Repr<3, 6> = unsafe { + U60Repr::new([Y, Y, Y, Y, Y, 0]) + }; assert(result == expected); let noshift = u60repr.shr(0); @@ -36,10 +40,14 @@ fn test_shl() { // 120 bits of 01010101 (repeating) let Y = 0x555555555555555555555555555555; let input: [Field; 6] = [Y, Y, Y, Y, Y, Y]; - let u60repr: U60Repr<3, 6> = U60Repr::new(input); + let u60repr: U60Repr<3, 6> = unsafe { + U60Repr::new(input) + }; let result = u60repr.shl(121); - let expected: U60Repr<3, 6> = U60Repr::new([0, X, X, X, X, X, X, 0, 0]); + let expected: U60Repr<3, 6> = unsafe { + U60Repr::new([0, X, X, X, X, X, X, 0, 0]) + }; assert(result == expected); let noshift = u60repr.shr(0); @@ -51,7 +59,9 @@ fn test_get_bit() { // 0x8000 = b1000000000000000 (16th bit is high) // 256th bit of input should be high let input: [Field; 6] = [0, 0, 0x8000, 0, 0, 0]; - let u60repr: U60Repr<3, 6> = U60Repr::new(input); + let u60repr: U60Repr<3, 6> = unsafe { + U60Repr::new(input) + }; for i in 0..720 { if i == 255 { assert(u60repr.get_bit(i) == true); @@ -62,7 +72,7 @@ fn test_get_bit() { } #[test] -fn test_gte() { +unconstrained fn test_gte() { let p = 0xffffffffffffffffffffffffffffff; // 2^120 - 1 let input: [Field; 6] = [p, p - 1, p - 2, p - 3, p - 4, p - 5]; let lhs: U60Repr<3, 6> = U60Repr::new(input); From 1bdce7449e608b1f11c22453cc4658604e37a31b Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Thu, 3 Oct 2024 12:03:57 +0100 Subject: [PATCH 03/29] silence more warnings --- src/lib.nr | 20 ++++++++++---------- src/utils/mod.nr | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/lib.nr b/src/lib.nr index 0a315506..e55bdbbb 100644 --- a/src/lib.nr +++ b/src/lib.nr @@ -1,17 +1,17 @@ -mod utils; -mod fields; +pub(crate) mod utils; +pub mod fields; // Structs -mod params; -mod bignum; -mod runtime_bignum; +pub mod params; +pub mod bignum; +pub mod runtime_bignum; // Functions on structs -mod unconstrained_ops; -mod constrained_ops; -mod unconstrained_helpers; -mod expressions; -mod serialization; +pub(crate) mod unconstrained_ops; +pub(crate) mod constrained_ops; +pub(crate) mod unconstrained_helpers; +pub(crate) mod expressions; +pub(crate) mod serialization; // Tests mod bignum_test; diff --git a/src/utils/mod.nr b/src/utils/mod.nr index 3d75400e..e419cfce 100644 --- a/src/utils/mod.nr +++ b/src/utils/mod.nr @@ -1,5 +1,5 @@ -mod u60_representation; -mod split_bits; -mod u60_representation_test; -mod msb; -mod map; +pub(crate) mod u60_representation; +pub(crate) mod split_bits; +pub(crate) mod u60_representation_test; +pub(crate) mod msb; +pub(crate) mod map; From 523f2e652a7bf8a97656b9430c005e25716e9d05 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Thu, 3 Oct 2024 15:45:54 +0100 Subject: [PATCH 04/29] rebase & silence warnings --- src/fields/mod.nr | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/fields/mod.nr b/src/fields/mod.nr index b2b8802c..5031c4a6 100644 --- a/src/fields/mod.nr +++ b/src/fields/mod.nr @@ -28,9 +28,12 @@ pub mod U2048; pub mod U4096; pub mod U8192; -use crate::bignum::BigNum; -use bn254Fq::BN254_Fq_Params; -// example typedef when using a defined bignum instance -type Fq = BigNum<3, BN254_Fq_Params>; + +// example typedef when using a defined bignum instance: +// +// use crate::bignum::BigNum; +// use bn254Fq::BN254_Fq_Params; +// +// type Fq = BigNum<3, BN254_Fq_Params>; From 1ff683c18a24205937b3318fd2d8540959e98345 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Thu, 3 Oct 2024 15:47:12 +0100 Subject: [PATCH 05/29] fmt --- src/fields/mod.nr | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/fields/mod.nr b/src/fields/mod.nr index 5031c4a6..14c73f80 100644 --- a/src/fields/mod.nr +++ b/src/fields/mod.nr @@ -28,8 +28,6 @@ pub mod U2048; pub mod U4096; pub mod U8192; - - // example typedef when using a defined bignum instance: // // use crate::bignum::BigNum; From a2240641d0db271a4f0cab0a75df3f66a6b44094 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:18:31 +0100 Subject: [PATCH 06/29] Update src/runtime_bignum.nr --- src/runtime_bignum.nr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index 37280282..4cf9fa6e 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -18,7 +18,6 @@ pub struct RuntimeBigNum { params: BigNumParams, } -impl RuntimeBigNum {} pub(crate) trait RuntimeBigNumTrait { fn new(params: BigNumParams) -> Self; From d8f794e5af37ea595b11107962365bb4b0bbe837 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:18:37 +0100 Subject: [PATCH 07/29] Update src/utils/map.nr --- src/utils/map.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/map.nr b/src/utils/map.nr index 50e3d13c..9d95e2d1 100644 --- a/src/utils/map.nr +++ b/src/utils/map.nr @@ -1,6 +1,6 @@ // Copied from std::array, because I couldn't figure out how to import the `map` method of the weird trait for an array. // And the reason I wanted direct access to it, is because I couldn't figure out how to implement a double map. -pub fn map(arr: [T; N], f: fn[Env](T) -> U) -> [U; N] { +pub(crate) fn map(arr: [T; N], f: fn[Env](T) -> U) -> [U; N] { let first_elem = f(arr[0]); let mut ret = [first_elem; N]; From 8d246671e96bf51de72a95450bcdf793e4cf5353 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Mon, 21 Oct 2024 11:51:15 +0100 Subject: [PATCH 08/29] reduce constraint counts --- src/params.nr | 30 +------ src/runtime_bignum.nr | 134 ++++++++++++++++++++++---------- src/utils/u60_representation.nr | 4 +- 3 files changed, 95 insertions(+), 73 deletions(-) diff --git a/src/params.nr b/src/params.nr index bde9c676..61c198b5 100644 --- a/src/params.nr +++ b/src/params.nr @@ -21,21 +21,13 @@ pub(crate) struct BigNumParams { redc_param: [Field; N], } -// To be implemented by the user, or within the prebuilt options in the `fields/` dir. +// To be implemented by the user for any BigNum they define, or within the predefined BigNums in the `fields/` dir. pub(crate) trait BigNumParamsGetter { fn get_params() -> BigNumParams; } -// To be implemented by the user, or within the prebuilt options in the `fields/` dir. -// pub(crate) trait HasGetModulusBits { -// fn get_modulus_bits() -> u32; // This needs to be a comptime const, so that it can be used as an argument to std::field::assert_constant() -// } - -// impl HasGetModulusBits for BigNumParams {} -// impl RuntimeBigNumParamsTrait for BigNumParams {} - impl BigNumParams { - fn new( + pub fn new( has_multiplicative_inverse: bool, modulus_bits_getter: fn() -> u32, modulus: [Field; N], @@ -65,21 +57,3 @@ fn get_double_modulus(modulus: [Field; N]) -> [Field; N] { result[N - 1] -= 1; result } - -// /** -// * @brief BigNumParamsGetter defines a "field" with which to parametrise BigNum. -// * @description The "field" does not need to be prime, any value *should* work (TODO: test!) -// **/ -// trait BigNumParamsGetter { -// fn has_multiplicative_inverse() -> bool; -// // @brief modulus_bits = log2(modulus) rounded up -// fn modulus_bits() -> u32; -// fn modulus() -> [Field; N]; -// fn modulus_u60() -> U60Repr; -// fn modulus_u60_x4() -> U60Repr; -// // @brief double_modulus: used when performing negations and subtractions -// fn double_modulus() -> [Field; N]; -// // redc_param used for __barrett_reduction. See https://en.wikipedia.org/wiki/Barrett_reduction -// redc_param: [Field; N], -// } - diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index 4cf9fa6e..0387dcee 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -18,11 +18,12 @@ pub struct RuntimeBigNum { params: BigNumParams, } - +// All functions prefixed `__` are unconstrained! +// They're not actually decorated as `unconstrained` because to return the `params` (as part of Self) from an `unconstrained` fn would cause range constraints. Instead, each `__` fn wraps a call to an unconstrained fn, so that the already-range-constrained `params` can be inserted into Self after the unconstrained call. pub(crate) trait RuntimeBigNumTrait { fn new(params: BigNumParams) -> Self; fn one(params: BigNumParams) -> Self; - unconstrained fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; + fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; fn from_slice(params: BigNumParams, limbs: [Field]) -> Self; fn from_array(params: BigNumParams, limbs: [Field; N]) -> Self; fn from_be_bytes(params: BigNumParams, x: [u8; NBytes]) -> Self; @@ -40,19 +41,19 @@ pub(crate) trait RuntimeBigNumTrait { unconstrained fn __eq(self, other: Self) -> bool; unconstrained fn __is_zero(self) -> bool; - unconstrained fn __neg(self) -> Self; - unconstrained fn __add(self, other: Self) -> Self; - unconstrained fn __sub(self, other: Self) -> Self; - unconstrained fn __mul(self, other: Self) -> Self; - unconstrained fn __div(self, other: Self) -> Self; - unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self); - unconstrained fn __invmod(self) -> Self; - unconstrained fn __pow(self, exponent: Self) -> Self; + fn __neg(self) -> Self; + fn __add(self, other: Self) -> Self; + fn __sub(self, other: Self) -> Self; + fn __mul(self, other: Self) -> Self; + fn __div(self, other: Self) -> Self; + fn __udiv_mod(self, divisor: Self) -> (Self, Self); + fn __invmod(self) -> Self; + fn __pow(self, exponent: Self) -> Self; - unconstrained fn __batch_invert(x: [Self; M]) -> [Self; M]; + fn __batch_invert(x: [Self; M]) -> [Self; M]; unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; - unconstrained fn __compute_quadratic_expression( + fn __compute_quadratic_expression( params: BigNumParams, lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], @@ -103,8 +104,12 @@ impl RuntimeBigNumTrait for RuntimeBigNum { result } - unconstrained fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self { - Self { limbs: __derive_from_seed(params, seed), params } + // UNCONSTRAINED! (Hence `__` prefix). + fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self { + let limbs = unsafe { + __derive_from_seed(params, seed) + }; + Self { limbs, params } } fn from_slice(params: BigNumParams, limbs: [Field]) -> Self { @@ -161,61 +166,102 @@ impl RuntimeBigNumTrait for RuntimeBigNum { __is_zero(self.limbs) } - unconstrained fn __neg(self) -> Self { + // UNCONSTRAINED! (Hence `__` prefix). + fn __neg(self) -> Self { let params = self.params; - Self::from_array(params, __neg(params, self.limbs)) + let limbs = unsafe { + __neg(params, self.limbs) + }; + Self { params, limbs } } - unconstrained fn __add(self, other: Self) -> Self { + // UNCONSTRAINED! (Hence `__` prefix). + fn __add(self, other: Self) -> Self { let params = self.params; - Self::from_array(params, __add(params, self.limbs, other.limbs)) + let limbs = unsafe { + __add(params, self.limbs, other.limbs) + }; + Self { params, limbs } } - unconstrained fn __sub(self, other: Self) -> Self { + // UNCONSTRAINED! (Hence `__` prefix). + fn __sub(self, other: Self) -> Self { let params = self.params; - Self::from_array(params, __sub(params, self.limbs, other.limbs)) + let limbs = unsafe { + __sub(params, self.limbs, other.limbs) + }; + Self { params, limbs } } - unconstrained fn __mul(self, other: Self) -> Self { + // UNCONSTRAINED! (Hence `__` prefix). + fn __mul(self, other: Self) -> Self { let params = self.params; - Self::from_array(params, __mul(params, self.limbs, other.limbs)) + let limbs = unsafe { + __mul(params, self.limbs, other.limbs) + }; + Self { params, limbs } } - unconstrained fn __div(self, divisor: Self) -> Self { + // UNCONSTRAINED! (Hence `__` prefix). + fn __div(self, divisor: Self) -> Self { let params = self.params; - Self::from_array(params, __div(params, self.limbs, divisor.limbs)) + let limbs = unsafe { + __div(params, self.limbs, divisor.limbs) + }; + Self { params, limbs } } - unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self) { + // UNCONSTRAINED! (Hence `__` prefix). + fn __udiv_mod(self, divisor: Self) -> (Self, Self) { let params = self.params; - let (q, r) = __udiv_mod(self.limbs, divisor.limbs); + let (q, r) = unsafe { + __udiv_mod(self.limbs, divisor.limbs) + }; (Self { limbs: q, params }, Self { limbs: r, params }) } - unconstrained fn __invmod(self) -> Self { + // UNCONSTRAINED! (Hence `__` prefix). + fn __invmod(self) -> Self { let params = self.params; assert(params.has_multiplicative_inverse); - Self { limbs: __invmod(params, self.limbs), params } + let limbs = unsafe { + __invmod(params, self.limbs) + }; + Self { limbs, params } } - unconstrained fn __pow(self, exponent: Self) -> Self { + // UNCONSTRAINED! (Hence `__` prefix). + fn __pow(self, exponent: Self) -> Self { let params = self.params; - Self { limbs: __pow(params, self.limbs, exponent.limbs), params } + let limbs = unsafe { + __pow(params, self.limbs, exponent.limbs) + }; + Self { limbs, params } } - unconstrained fn __batch_invert(x: [Self; M]) -> [Self; M] { + // UNCONSTRAINED! (Hence `__` prefix). + fn __batch_invert(x: [Self; M]) -> [Self; M] { let params = x[0].params; assert(params.has_multiplicative_inverse); - __batch_invert(params, x.map(|bn| Self::get_limbs(bn))).map(|limbs| Self { limbs, params }) + let all_limbs = unsafe { + __batch_invert(params, x.map(|bn| Self::get_limbs(bn))) + }; + all_limbs.map(|limbs| Self { limbs, params }) } + // Note: can't return a slice from this unconstrained to a constrained function. unconstrained fn __batch_invert_slice(x: [Self]) -> [Self] { let params = x[0].params; assert(params.has_multiplicative_inverse); - __batch_invert_slice(params, x.map(|bn| Self::get_limbs(bn))).map(|limbs| Self { limbs, params }) + let all_limbs = unsafe { + let inv_slice = __batch_invert_slice(params, x.map(|bn| Self::get_limbs(bn))); + inv_slice.as_array() + }; + all_limbs.map(|limbs| Self { limbs, params }) } - unconstrained fn __compute_quadratic_expression( + // UNCONSTRAINED! (Hence `__` prefix). + fn __compute_quadratic_expression( params: BigNumParams, lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], @@ -224,15 +270,17 @@ impl RuntimeBigNumTrait for RuntimeBigNum { linear_terms: [Self; ADD_N], linear_flags: [bool; ADD_N] ) -> (Self, Self) { - let (q_limbs, r_limbs) = __compute_quadratic_expression( - params, - lhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), - lhs_flags, - rhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), - rhs_flags, - linear_terms.map(|bn| Self::get_limbs(bn)), - linear_flags - ); + let (q_limbs, r_limbs) = unsafe { + __compute_quadratic_expression( + params, + lhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + lhs_flags, + rhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + rhs_flags, + linear_terms.map(|bn| Self::get_limbs(bn)), + linear_flags + ) + }; (Self { limbs: q_limbs, params }, Self { limbs: r_limbs, params }) } diff --git a/src/utils/u60_representation.nr b/src/utils/u60_representation.nr index 21d3b896..61a29b54 100644 --- a/src/utils/u60_representation.nr +++ b/src/utils/u60_representation.nr @@ -78,7 +78,7 @@ impl std::cmp::Eq for U60Repr impl U60Repr { - unconstrained fn new(x: [Field; N * NumFieldSegments]) -> Self { + unconstrained pub fn new(x: [Field; N * NumFieldSegments]) -> Self { let mut result: Self = U60Repr { limbs: [0; N * NumSegments] }; for i in 0..(N * NumFieldSegments) { let (lo, hi) = split_bits::split_60_bits(x[i]); @@ -88,7 +88,7 @@ impl U60Repr { result } - unconstrained fn one() -> Self { + unconstrained pub fn one() -> Self { let mut result: Self = U60Repr { limbs: [0; N * NumSegments] }; result.limbs[0] = 1; result From 8bb7304844336f9cb1875fe460cadd568970326d Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Mon, 21 Oct 2024 17:22:14 +0100 Subject: [PATCH 09/29] update in line w/ Zac's changes, incl macro tests --- src/bignum.nr | 20 +- src/bignum_test.nr | 93 +++-- src/constrained_ops.nr | 132 ++++++- src/expressions.nr | 14 +- src/fields/U1024.nr | 35 +- src/fields/U2048.nr | 36 +- src/fields/U256.nr | 35 +- src/fields/U384.nr | 35 +- src/fields/U4096.nr | 35 +- src/fields/U512.nr | 22 +- src/fields/U768.nr | 40 +- src/fields/U8192.nr | 35 +- src/fields/bls12_377Fq.nr | 39 +- src/fields/bls12_377Fr.nr | 36 +- src/fields/bls12_381Fq.nr | 35 +- src/fields/bls12_381Fr.nr | 35 +- src/fields/bn254Fq.nr | 36 +- src/fields/ed25519Fq.nr | 35 +- src/fields/ed25519Fr.nr | 35 +- src/fields/mnt4_753Fq.nr | 39 +- src/fields/mnt4_753Fr.nr | 37 +- src/fields/mnt6_753Fq.nr | 37 +- src/fields/mnt6_753Fr.nr | 37 +- src/fields/pallasFq.nr | 37 +- src/fields/pallasFr.nr | 37 +- src/fields/secp256k1Fq.nr | 35 +- src/fields/secp256k1Fr.nr | 35 +- src/fields/secp256r1Fq.nr | 35 +- src/fields/secp256r1Fr.nr | 35 +- src/fields/secp384r1Fq.nr | 35 +- src/fields/secp384r1Fr.nr | 35 +- src/fields/vestaFq.nr | 36 +- src/fields/vestaFr.nr | 35 +- src/runtime_bignum.nr | 22 +- src/runtime_bignum_test.nr | 692 ++++++++++++++++------------------- src/unconstrained_helpers.nr | 188 +++++++++- src/unconstrained_ops.nr | 47 ++- src/utils/map.nr | 5 +- 38 files changed, 1260 insertions(+), 982 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index 7b2108b9..b5a0fdbe 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -2,7 +2,7 @@ use crate::utils::map::map; use crate::params::BigNumParamsGetter; use crate::constrained_ops::{ - conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, neg, add, sub, + derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, neg, add, sub, mul, div, udiv_mod, udiv, umod }; use crate::unconstrained_ops::{ @@ -21,6 +21,7 @@ pub(crate) trait BigNumTrait { // fn default() -> Self { std::default::Default::default () } fn new() -> Self; fn one() -> Self; + fn derive_from_seed(seed: [u8; SeedBytes]) -> Self; unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self; fn from_slice(limbs: [Field]) -> Self; fn from_array(limbs: [Field; N]) -> Self; @@ -97,6 +98,11 @@ impl BigNumTrait for BigNum where Params: BigN result } + fn derive_from_seed(seed: [u8; SeedBytes]) -> Self { + let params = Params::get_params(); + Self { limbs: derive_from_seed(params, seed) } + } + unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self { let params = Params::get_params(); Self { limbs: __derive_from_seed(params, seed) } @@ -221,11 +227,11 @@ impl BigNumTrait for BigNum where Params: BigN let params = Params::get_params(); let (q_limbs, r_limbs) = __compute_quadratic_expression( params, - lhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + map(lhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), lhs_flags, - rhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + map(rhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), rhs_flags, - linear_terms.map(|bn| Self::get_limbs(bn)), + map(linear_terms, |bn| Self::get_limbs(bn)), linear_flags ); (Self { limbs: q_limbs }, Self { limbs: r_limbs }) @@ -242,11 +248,11 @@ impl BigNumTrait for BigNum where Params: BigN let params = Params::get_params(); evaluate_quadratic_expression( params, - lhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + map(lhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), lhs_flags, - rhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + map(rhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), rhs_flags, - linear_terms.map(|bn| Self::get_limbs(bn)), + map(linear_terms, |bn| Self::get_limbs(bn)), linear_flags ) } diff --git a/src/bignum_test.nr b/src/bignum_test.nr index 1fbb9966..15243613 100644 --- a/src/bignum_test.nr +++ b/src/bignum_test.nr @@ -8,6 +8,7 @@ use crate::params::BigNumParamsGetter; use crate::fields::bn254Fq::BN254_Fq_Params; use crate::fields::U256::U256Params; +use crate::fields::bls12_381Fq::BLS12_381_Fq_Params; struct Test2048Params{} @@ -17,62 +18,56 @@ fn silence_warning() { let _ = Test2048Params {}; } +global TEST_2048_PARAMS: BigNumParams<18> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 2048, + modulus: [ + 0xc0a197a5ae0fcdceb052c9732614fe, 0x656ae034423283422243918ab83be3, 0x6bf590da48a7c1070b7d5aabaac678, 0x0cce39f530238b606f24b296e2bda9, 0x01e1fef9bb9c1c3ead98f226f1bfa0, 0xad8c1c816e12e0ed1379055e373abf, 0xcebe80e474f753aa9d1461c435123d, 0xaee5a18ceedef88d115a8b93c167ad, 0x268ba83c4a65c4307427fc495d9e44, 0xdd2777926848667b7df79f342639d4, 0xf455074c96855ca0068668efe7da3d, 0x5ddba6b30bbc168bfb3a1225f27d65, 0x591fec484f36707524133bcd6f4258, 0x59641b756766aeebe66781dd01d062, 0x58bc5eaff4b165e142bf9e2480eebb, 0x667a3964f08e06df772ce64b229a72, 0x9c1fdb18907711bfe3e3c1cf918395, 0xb8 + ], + double_modulus: [ + 0x0181432f4b5c1f9b9d60a592e64c29fc, 0x01cad5c06884650684448723157077c6, 0x01d7eb21b4914f820e16fab557558cef, 0x01199c73ea604716c0de49652dc57b51, 0x0103c3fdf37738387d5b31e44de37f3f, 0x015b183902dc25c1da26f20abc6e757d, 0x019d7d01c8e9eea7553a28c3886a247a, 0x015dcb4319ddbdf11a22b5172782cf5a, 0x014d17507894cb8860e84ff892bb3c88, 0x01ba4eef24d090ccf6fbef3e684c73a7, 0x01e8aa0e992d0ab9400d0cd1dfcfb47a, 0x01bbb74d6617782d17f674244be4faca, 0x01b23fd8909e6ce0ea4826779ade84af, 0x01b2c836eacecd5dd7cccf03ba03a0c3, 0x01b178bd5fe962cbc2857f3c4901dd75, 0x01ccf472c9e11c0dbeee59cc964534e3, 0x01383fb63120ee237fc7c7839f230729, 0x0170 + ], + modulus_u60: U60Repr { limbs: [ + 0x0eb052c9732614fe, 0x0c0a197a5ae0fcdc, 0x022243918ab83be3, 0x0656ae0344232834, 0x070b7d5aabaac678, 0x06bf590da48a7c10, 0x6f24b296e2bda9, 0xcce39f530238b6, 0x0ead98f226f1bfa0, 0x1e1fef9bb9c1c3, 0x0d1379055e373abf, 0x0ad8c1c816e12e0e, 0x0a9d1461c435123d, 0x0cebe80e474f753a, 0x0d115a8b93c167ad, 0x0aee5a18ceedef88, 0x7427fc495d9e44, 0x0268ba83c4a65c43, 0x0b7df79f342639d4, 0x0dd2777926848667, 0x068668efe7da3d, 0x0f455074c96855ca, 0x0bfb3a1225f27d65, 0x05ddba6b30bbc168, 0x0524133bcd6f4258, 0x0591fec484f36707, 0x0be66781dd01d062, 0x059641b756766aee, 0x0142bf9e2480eebb, 0x058bc5eaff4b165e, 0x0f772ce64b229a72, 0x0667a3964f08e06d, 0x0fe3e3c1cf918395, 0x09c1fdb18907711b, 0xb8, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0eb052c9732614fe, 0x0c0a197a5ae0fcdc, 0x022243918ab83be3, 0x0656ae0344232834, 0x070b7d5aabaac678, 0x06bf590da48a7c10, 0x6f24b296e2bda9, 0xcce39f530238b6, 0x0ead98f226f1bfa0, 0x1e1fef9bb9c1c3, 0x0d1379055e373abf, 0x0ad8c1c816e12e0e, 0x0a9d1461c435123d, 0x0cebe80e474f753a, 0x0d115a8b93c167ad, 0x0aee5a18ceedef88, 0x7427fc495d9e44, 0x0268ba83c4a65c43, 0x0b7df79f342639d4, 0x0dd2777926848667, 0x068668efe7da3d, 0x0f455074c96855ca, 0x0bfb3a1225f27d65, 0x05ddba6b30bbc168, 0x0524133bcd6f4258, 0x0591fec484f36707, 0x0be66781dd01d062, 0x059641b756766aee, 0x0142bf9e2480eebb, 0x058bc5eaff4b165e, 0x0f772ce64b229a72, 0x0667a3964f08e06d, 0x0fe3e3c1cf918395, 0x09c1fdb18907711b, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x1697def7100cd5cf8d890b4ef2ec3f, 0x765ba8304214dac764d3f4adc31859, 0x8404bd14d927ea230e60d4bebf9406, 0xc4d53a23bacc251ecbfc4b7ba5a0b4, 0x3eaf3499474a6f5b2fff83f1259c87, 0xbff4c737b97281f1a5f2384a8c16d9, 0x1b4cf2f55358476b53237829990555, 0xe7a804e8eacfe3a2a5673bc3885b86, 0xabadeae4282906c817adf70eab4ae1, 0x66f7df257fe2bf27f0809aceed9b0e, 0xd90fb7428901b8bed11f6b81e36bf1, 0x36e6ba885c60b7024c563605df7e07, 0x2b7c58d2fb5d2c8478963ae6d4a44f, 0x6ee761de26635f114ccc3f7d74f855, 0x3fb726a10cf2220897513f05243de3, 0x43a26bbd732496eb4d828591b8056e, 0xf4e42304e60fb3a54fca735499f2cf, 0x162f + ] +}; + impl BigNumParamsGetter<18> for Test2048Params { fn get_params() -> BigNumParams<18> { - let has_multiplicative_inverse = false; - let modulus_bits_getter = || 2048; - // let modulus_bits = 2048; - let modulus: [Field; 18] = [ - 0x0000000000000000000000000000000000c0a197a5ae0fcdceb052c9732614fe, - 0x0000000000000000000000000000000000656ae034423283422243918ab83be3, - 0x00000000000000000000000000000000006bf590da48a7c1070b7d5aabaac678, - 0x00000000000000000000000000000000000cce39f530238b606f24b296e2bda9, - 0x000000000000000000000000000000000001e1fef9bb9c1c3ead98f226f1bfa0, - 0x0000000000000000000000000000000000ad8c1c816e12e0ed1379055e373abf, - 0x0000000000000000000000000000000000cebe80e474f753aa9d1461c435123d, - 0x0000000000000000000000000000000000aee5a18ceedef88d115a8b93c167ad, - 0x0000000000000000000000000000000000268ba83c4a65c4307427fc495d9e44, - 0x0000000000000000000000000000000000dd2777926848667b7df79f342639d4, - 0x0000000000000000000000000000000000f455074c96855ca0068668efe7da3d, - 0x00000000000000000000000000000000005ddba6b30bbc168bfb3a1225f27d65, - 0x0000000000000000000000000000000000591fec484f36707524133bcd6f4258, - 0x000000000000000000000000000000000059641b756766aeebe66781dd01d062, - 0x000000000000000000000000000000000058bc5eaff4b165e142bf9e2480eebb, - 0x0000000000000000000000000000000000667a3964f08e06df772ce64b229a72, - 0x00000000000000000000000000000000009c1fdb18907711bfe3e3c1cf918395, - 0x00000000000000000000000000000000000000000000000000000000000000b8 - ]; - let redc_param: [Field; 18] = [ - 0x000000000000000000000000000000000091697def7100cd5cf8d890b4ef2ec3, - 0x00000000000000000000000000000000006765ba8304214dac764d3f4adc3185, - 0x000000000000000000000000000000000048404bd14d927ea230e60d4bebf940, - 0x00000000000000000000000000000000007c4d53a23bacc251ecbfc4b7ba5a0b, - 0x000000000000000000000000000000000093eaf3499474a6f5b2fff83f1259c8, - 0x00000000000000000000000000000000005bff4c737b97281f1a5f2384a8c16d, - 0x000000000000000000000000000000000061b4cf2f55358476b5323782999055, - 0x00000000000000000000000000000000001e7a804e8eacfe3a2a5673bc3885b8, - 0x0000000000000000000000000000000000eabadeae4282906c817adf70eab4ae, - 0x0000000000000000000000000000000000166f7df257fe2bf27f0809aceed9b0, - 0x00000000000000000000000000000000007d90fb7428901b8bed11f6b81e36bf, - 0x0000000000000000000000000000000000f36e6ba885c60b7024c563605df7e0, - 0x000000000000000000000000000000000052b7c58d2fb5d2c8478963ae6d4a44, - 0x000000000000000000000000000000000036ee761de26635f114ccc3f7d74f85, - 0x0000000000000000000000000000000000e3fb726a10cf2220897513f05243de, - 0x0000000000000000000000000000000000f43a26bbd732496eb4d828591b8056, - 0x0000000000000000000000000000000000ff4e42304e60fb3a54fca735499f2c, - 0x0000000000000000000000000000000000000000000000000000000000000162 - ]; - BigNumParams::new( - has_multiplicative_inverse, - modulus_bits_getter, - modulus, - redc_param - ) + TEST_2048_PARAMS } } type Fq = BigNum<3, BN254_Fq_Params>; +/** + * @brief this example was failing - sanity test to validate it now works + **/ +#[test] +fn test_bls_reduction() { + let X1: BigNum<4, BLS12_381_Fq_Params> = BigNum { + limbs: [ + 0x55e83ff97a1aeffb3af00adb22c6bb, 0x8c4f9774b905a14e3a3f171bac586c, 0xa73197d7942695638c4fa9ac0fc368, 0x17f1d3 + ] + }; + X1.validate_in_field(); + let mut (_, XX_mul_3): (BigNum<4, BLS12_381_Fq_Params>, BigNum<4, BLS12_381_Fq_Params> ) = unsafe { + BigNum::__compute_quadratic_expression( + [[X1, X1, X1]], + [[false, false, false]], + [[X1]], + [[false]], + [], + [] + ) + }; + XX_mul_3.validate_in_field(); +} + fn test_eq() where BN: BigNumTrait { let a = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) diff --git a/src/constrained_ops.nr b/src/constrained_ops.nr index 3021eb49..d2580413 100644 --- a/src/constrained_ops.nr +++ b/src/constrained_ops.nr @@ -7,6 +7,135 @@ use crate::unconstrained_helpers::{ use crate::unconstrained_ops::{__mul, __div, __udiv_mod}; use crate::expressions::evaluate_quadratic_expression; +/** + * In this file: + * + * conditional_select + * assert_is_not_equal + * eq + * validate_in_field + * validate_in_range + * validate_quotient_in_range + * validate_gt + * neg + * add + * sub + * mul + * div + * udiv_mod + * udiv + * umod + */ + +/** +* @brief given an input seed, generate a pseudorandom BigNum value +* @details we hash the input seed into `modulus_bits * 2` bits of entropy, +* which is then reduced into a BigNum value +* We use a hash function that can be modelled as a random oracle +* This function *should* produce an output that is a uniformly randomly distributed value modulo BigNum::modulus() +**/ +pub(crate) fn derive_from_seed(params: P, seed: [u8; SeedBytes]) -> [Field; N] { + let mut rolling_seed: [u8; SeedBytes + 1] = [0; SeedBytes + 1]; + for i in 0..SeedBytes { + rolling_seed[i] = seed[i]; + assert_eq(rolling_seed[i], seed[i]); + } + + let mut hash_buffer: [u8; N * 2 * 15] = [0; N * 2 * 15]; + + let mut rolling_hash_fields: [Field; (SeedBytes / 31) + 1] = [0; (SeedBytes / 31) + 1]; + let mut seed_ptr = 0; + for i in 0..(SeedBytes / 31) + 1 { + let mut packed: Field = 0; + for _ in 0..31 { + if (seed_ptr < SeedBytes) { + packed *= 256; + packed += seed[seed_ptr] as Field; + seed_ptr += 1; + } + } + rolling_hash_fields[i] = packed; + } + + let compressed = std::hash::poseidon2::Poseidon2::hash(rolling_hash_fields, (SeedBytes / 31) + 1); + let mut rolling_hash: [Field; 2] = [compressed, 0]; + let num_hashes = (30 * N) / 32 + (((30 * N) % 32) != 0) as u32; + for i in 0..num_hashes - 1 { + let hash: Field = std::hash::poseidon2::Poseidon2::hash(rolling_hash, 2); + let hash: [u8; 32] = hash.to_le_bytes(); + for j in 0..30 { + hash_buffer[i * 30 + j] = hash[j]; + } + rolling_hash[1] += 1; + } + { + let hash: Field = std::hash::poseidon2::Poseidon2::hash(rolling_hash, 2); + let hash: [u8; 32] = hash.to_le_bytes(); + let remaining_bytes = 30 * N - (num_hashes - 1) * 30; + for j in 0..remaining_bytes { + hash_buffer[(num_hashes - 1) * 30 + j] = hash[j]; + } + } + + let modulus_bits_getter = params.modulus_bits_getter; + let modulus_bits = modulus_bits_getter(); + let num_bits = modulus_bits * 2; + let num_bytes = num_bits / 8 + ((num_bits % 8) != 0) as u32; + + let bits_in_last_byte = num_bits as u8 % 8; + let last_byte_mask = (1 as u8 << bits_in_last_byte) - 1; + hash_buffer[num_bytes - 1] = hash_buffer[num_bytes - 1] & last_byte_mask; + + let num_bigfield_chunks = (2 * N) / (N - 1) + (((2 * N) % (N - 1)) != 0) as u32; + let mut byte_ptr = 0; + + // we want to convert our byte array into bigfield chunks + // each chunk has at most N-1 limbs + // to determine the exact number of chunks, we need the `!=` or `>` operator which is not avaiable when defining array sizes + // so we overestimate at 4 + // e.g. if N = 20, then we have 40 limbs we want to reduce, but each bigfield chunk is 19 limbs, so we need 3 + // if N = 2, we have 4 limbs we want to reduce but each bigfield chunk is only 1 limb, so we need 4 + // max possible number of chunks is therefore 4 + + let mut bigfield_chunks: [[Field; N]; 4] = [[0; N]; 4]; + for k in 0..num_bigfield_chunks { + let mut bigfield_limbs: [Field; N] = [0; N]; + let mut num_filled_bytes = (k * 30); + let mut num_remaining_bytes = num_bytes - num_filled_bytes; + let mut num_remaining_limbs = (num_remaining_bytes / 15) + (num_remaining_bytes % 15 > 0) as u32; + let mut more_than_N_minus_one_limbs = (num_remaining_limbs > (N - 1)) as u32; + let mut num_limbs_in_bigfield = more_than_N_minus_one_limbs * (N - 1) + + num_remaining_limbs * (1 - more_than_N_minus_one_limbs); + + for j in 0..num_limbs_in_bigfield { + let mut limb: Field = 0; + for _ in 0..15 { + let need_more_bytes = (byte_ptr < num_bytes); + let mut byte = hash_buffer[byte_ptr]; + limb *= (256 * need_more_bytes as Field + (1 - need_more_bytes as Field)); + limb += byte as Field * need_more_bytes as Field; + byte_ptr += need_more_bytes as u32; + } + bigfield_limbs[num_limbs_in_bigfield - 1 - j] = limb; + } + bigfield_chunks[num_bigfield_chunks - 1 - k] = bigfield_limbs; + } + + let mut bigfield_rhs_limbs: [Field; N] = [0; N]; + bigfield_rhs_limbs[N-1] = 1; + validate_in_range(params, bigfield_rhs_limbs); + + let mut result: [Field; N] = [0; N]; + + for i in 0..num_bigfield_chunks { + let bigfield_lhs_limbs = bigfield_chunks[i]; + + result = mul(params, result, bigfield_rhs_limbs); + result = add(params, result, bigfield_lhs_limbs); + } + result +} + /** * @brief conditional_select given the value of `predicate` return either `self` (if 0) or `other` (if 1) * @description should be cheaper than using an IF statement (TODO: check!) @@ -93,7 +222,8 @@ pub(crate) fn validate_in_range(params: P, limbs: [Field; N]) { limbs[i].assert_max_bit_size(120); } let modulus_bits_getter = params.modulus_bits_getter; - let final_limb_bits = modulus_bits_getter() - ((N - 1) * 120); + let modulus_bits = modulus_bits_getter(); + let final_limb_bits = modulus_bits - ((N - 1) * 120); limbs[N - 1].assert_max_bit_size(final_limb_bits as u32); } diff --git a/src/expressions.nr b/src/expressions.nr index a2ef3e03..e2821113 100644 --- a/src/expressions.nr +++ b/src/expressions.nr @@ -4,6 +4,16 @@ use crate::params::BigNumParams as P; use crate::constrained_ops::validate_quotient_in_range; use crate::unconstrained_helpers::__barrett_reduction; +/** + * In this file: + * + * __compute_quadratic_expression_with_borrow_flags + * __add_linear_expression + * __compute_quadratic_expression_product + * __compute_quadratic_expression + * evaluate_quadratic_expression + */ + /** * @brief Given a degree-2 BigNum expression that is equal to 0 mod p, compute the quotient and borrow flags * @description The expression is of the form: @@ -127,7 +137,7 @@ unconstrained fn __add_linear_expression( if (flags[i]) { for j in 0..N { sum[j] = sum[j] + modulus2[j] - x[i][j]; - assert(x[i][j].lt(modulus2[j])); + // assert(x[i][j].lt(modulus2[j])); } } else { for j in 0..N { @@ -214,6 +224,8 @@ unconstrained pub(crate) fn __compute_quadratic_expression< ); let mut relation_result: [Field; 2 * N] = split_bits::__normalize_limbs(mulout, 2 * N); + // size 4 + // a[3] * b[3] = a[6] = 7 // TODO: ugly! Will fail if input slice is empty let modulus_bits_getter = params.modulus_bits_getter; let k = modulus_bits_getter(); diff --git a/src/fields/U1024.nr b/src/fields/U1024.nr index 6dc7ffcc..c5aef12d 100644 --- a/src/fields/U1024.nr +++ b/src/fields/U1024.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global U1024_PARAMS: BigNumParams<9> = BigNumParams { - has_multiplicative_inverse: false, - modulus_bits_getter: || 1025, - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000000000000000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffffffffffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x040000000000000000 - ] -}; - pub struct U1024Params {} impl BigNumParamsGetter<9> for U1024Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<9> for U1024Params { } } +global U1024_PARAMS: BigNumParams<9> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 1025, + modulus: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000000000000000 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffffffffffff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x400000000000000000 + ] +}; diff --git a/src/fields/U2048.nr b/src/fields/U2048.nr index 99fc3bdf..2fac1524 100644 --- a/src/fields/U2048.nr +++ b/src/fields/U2048.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global U2048_PARAMS: BigNumParams<18> = BigNumParams { - has_multiplicative_inverse: false, - modulus_bits_getter: || 2049, - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0400 - ] -}; - pub struct U2048Params {} impl BigNumParamsGetter<18> for U2048Params { @@ -28,3 +10,21 @@ impl BigNumParamsGetter<18> for U2048Params { } } +global U2048_PARAMS: BigNumParams<18> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 2049, + modulus: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4000 + ] +}; + diff --git a/src/fields/U256.nr b/src/fields/U256.nr index 19b40cad..65f71be3 100644 --- a/src/fields/U256.nr +++ b/src/fields/U256.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global U256_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: false, - modulus_bits_getter: || 257, - modulus: [ - 0x00, 0x00, 0x010000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0x01ffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x040000 - ] -}; - pub struct U256Params {} impl BigNumParamsGetter<3> for U256Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<3> for U256Params { } } +global U256_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 257, + modulus: [ + 0x00, 0x00, 0x010000 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0x01ffff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x400000 + ] +}; diff --git a/src/fields/U384.nr b/src/fields/U384.nr index dba9054e..c076695c 100644 --- a/src/fields/U384.nr +++ b/src/fields/U384.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global U384_PARAMS: BigNumParams<4> = BigNumParams { - has_multiplicative_inverse: false, - modulus_bits_getter: || 385, - modulus: [ - 0x00, 0x00, 0x00, 0x01000000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x04000000 - ] -}; - pub struct U384_Params {} impl BigNumParamsGetter<4> for U384_Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<4> for U384_Params { } } +global U384_PARAMS: BigNumParams<4> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 385, + modulus: [ + 0x00, 0x00, 0x00, 0x01000000 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x00, 0x40000000 + ] +}; diff --git a/src/fields/U4096.nr b/src/fields/U4096.nr index 441c28e0..06335a1d 100644 --- a/src/fields/U4096.nr +++ b/src/fields/U4096.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global U4096_PARAMS: BigNumParams<35> = BigNumParams { - has_multiplicative_inverse: false, - modulus_bits_getter: || 4097, - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x040000 - ] -}; - pub struct U4096Params {} impl BigNumParamsGetter<35> for U4096Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<35> for U4096Params { } } +global U4096_PARAMS: BigNumParams<35> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 4097, + modulus: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x400000 + ] +}; diff --git a/src/fields/U512.nr b/src/fields/U512.nr index 66c3f30d..2b91b00b 100644 --- a/src/fields/U512.nr +++ b/src/fields/U512.nr @@ -2,9 +2,17 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; +pub struct U512Params {} + +impl BigNumParamsGetter<5> for U512Params { + fn get_params() -> BigNumParams<5> { + U512_PARAMS + } +} + global U512_PARAMS: BigNumParams<5> = BigNumParams { - has_multiplicative_inverse: false, - modulus_bits_getter: || 513, + has_multiplicative_inverse: false, + modulus_bits_getter: || 513, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x0100000000 ], @@ -16,15 +24,7 @@ global U512_PARAMS: BigNumParams<5> = BigNumParams { modulus_u60_x4: U60Repr { limbs: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x0400000000 + 0x00, 0x00, 0x00, 0x00, 0x4000000000 ] }; -pub struct U512Params {} - -impl BigNumParamsGetter<5> for U512Params { - fn get_params() -> BigNumParams<5> { - U512_PARAMS - } -} - diff --git a/src/fields/U768.nr b/src/fields/U768.nr index cf41ce21..087af311 100644 --- a/src/fields/U768.nr +++ b/src/fields/U768.nr @@ -2,29 +2,29 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global U768_PARAMS: BigNumParams<13> = BigNumParams { - has_multiplicative_inverse: false, - modulus_bits_getter: || 1537, - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000000000000000000000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffffffffffffffffffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1000000000]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1000000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04000000000000000000000000 - ] -}; - pub struct U768Params {} -impl BigNumParamsGetter<13> for U768Params { - fn get_params() -> BigNumParams<13> { +impl BigNumParamsGetter<7> for U768Params { + fn get_params() -> BigNumParams<7> { U768_PARAMS } } +global U768_PARAMS: BigNumParams<7> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 769, + modulus: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000000000 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffffffff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000000000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40000000000000 + ] +}; + diff --git a/src/fields/U8192.nr b/src/fields/U8192.nr index d4788d3a..91702ec3 100644 --- a/src/fields/U8192.nr +++ b/src/fields/U8192.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global U8192_PARAMS: BigNumParams<69> = BigNumParams { - has_multiplicative_inverse: false, - modulus_bits_getter: || 8193, - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0400000000 - ] -}; - pub struct U8192Params {} impl BigNumParamsGetter<69> for U8192Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<69> for U8192Params { } } +global U8192_PARAMS: BigNumParams<69> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 8193, + modulus: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000 + ], + double_modulus: [ + 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffff + ], + modulus_u60: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4000000000 + ] +}; diff --git a/src/fields/bls12_377Fq.nr b/src/fields/bls12_377Fq.nr index 5cf050aa..4fb833ef 100644 --- a/src/fields/bls12_377Fq.nr +++ b/src/fields/bls12_377Fq.nr @@ -1,5 +1,5 @@ //! Blurb sourced from https://github.com/arkworks-rs -//! This library implements the base field of the BLS12_377 curve generated in [[BCGMMW20, "Zexe"]](https://eprint.iacr.org/2018/962). +//! This library implements the base field of the BLS12_377 curve generated in [[BCGMMW20, "Zexe"]]((https://eprint.iacr.org/2018/962). //! The name denotes that it is a Barreto--Lynn--Scott curve of embedding degree //! 12, defined over a 377-bit (prime) field. The main feature of this curve is //! that both the scalar field and the base field are highly 2-adic. @@ -20,25 +20,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global BLS12_377_Fq_PARAMS: BigNumParams<4> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 377, - modulus: [ - 0x0b5d44300000008508c00000000001, 0xd9f300f5138f1ef3622fba09480017, 0x4617c510eac63b05c06ca1493b1a22, 0x01ae3a - ], - double_modulus: [ - 0x0116ba88600000010a11800000000002, 0x01b3e601ea271e3de6c45f741290002d, 0x018c2f8a21d58c760b80d94292763444, 0x035c73 - ], - modulus_u60: U60Repr { limbs: [ - 0x0508c00000000001, 0xb5d44300000008, 0x03622fba09480017, 0x0d9f300f5138f1ef, 0x05c06ca1493b1a22, 0x04617c510eac63b0, 0x01ae3a, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0508c00000000001, 0xb5d44300000008, 0x03622fba09480017, 0x0d9f300f5138f1ef, 0x05c06ca1493b1a22, 0x04617c510eac63b0, 0x01ae3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xed687789c42a591f9fd58c5e4daffc, 0xd0de6776b1a06af2d488d85a6d02d0, 0x8d0cc4060e976c3ca0582ef4f73bba, 0x026150 - ] -}; - -pub struct BLS12_377_Fq_Params {} +pub struct BLS12_377_Fq_Params {} impl BigNumParamsGetter<4> for BLS12_377_Fq_Params { fn get_params() -> BigNumParams<4> { @@ -46,3 +28,20 @@ impl BigNumParamsGetter<4> for BLS12_377_Fq_Params { } } +pub global BLS12_377_Fq_PARAMS: BigNumParams<4> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 377, + modulus: [ + 0x0b5d44300000008508c00000000001, 0xd9f300f5138f1ef3622fba09480017, 0x4617c510eac63b05c06ca1493b1a22, 0x01ae3a + ], + double_modulus: [ + 0x0116ba88600000010a11800000000002, 0x01b3e601ea271e3de6c45f741290002d, 0x018c2f8a21d58c760b80d94292763444, 0x035c73 + ], + modulus_u60: U60Repr { limbs: [ + 0x0508c00000000001, 0xb5d44300000008, 0x03622fba09480017, 0x0d9f300f5138f1ef, 0x05c06ca1493b1a22, 0x04617c510eac63b0, 0x01ae3a, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0508c00000000001, 0xb5d44300000008, 0x03622fba09480017, 0x0d9f300f5138f1ef, 0x05c06ca1493b1a22, 0x04617c510eac63b0, 0x01ae3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xd687789c42a591f9fd58c5e4daffcc, 0x0de6776b1a06af2d488d85a6d02d0e, 0xd0cc4060e976c3ca0582ef4f73bbad, 0x261508 + ] +}; diff --git a/src/fields/bls12_377Fr.nr b/src/fields/bls12_377Fr.nr index 6b9789f5..ac6bfd01 100644 --- a/src/fields/bls12_377Fr.nr +++ b/src/fields/bls12_377Fr.nr @@ -16,28 +16,11 @@ //! * G1 curve equation: y^2 = x^3 + 1 //! * G2 curve equation: y^2 = x^3 + B, where //! * B = Fq2(0, 155198655607781456406391640216936120121836107652948796323930557600032281009004493664981332883744016074664192874906) + use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global BLS12_377_Fr_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 253, - modulus: [ - 0xaa76fed00000010a11800000000001, 0x655e9a2ca55660b44d1e5c37b00159, 0x12ab - ], - double_modulus: [ - 0x0154edfda00000021423000000000002, 0x01cabd34594aacc1689a3cb86f6002b2, 0x2555 - ], - modulus_u60: U60Repr { limbs: [ - 0x0a11800000000001, 0x0aa76fed00000010, 0x044d1e5c37b00159, 0x0655e9a2ca55660b, 0x12ab, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0a11800000000001, 0x0aa76fed00000010, 0x044d1e5c37b00159, 0x0655e9a2ca55660b, 0x12ab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x0a180b8d69e258f5204c21151e79ea, 0x491ec40b2c9ee4e51e49faa80548fd, 0x36d9 - ] -}; - pub struct BLS12_377_Fr_Params {} impl BigNumParamsGetter<3> for BLS12_377_Fr_Params { @@ -46,3 +29,20 @@ impl BigNumParamsGetter<3> for BLS12_377_Fr_Params { } } +global BLS12_377_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 253, + modulus: [ + 0xaa76fed00000010a11800000000001, 0x655e9a2ca55660b44d1e5c37b00159, 0x12ab + ], + double_modulus: [ + 0x0154edfda00000021423000000000002, 0x01cabd34594aacc1689a3cb86f6002b2, 0x2555 + ], + modulus_u60: U60Repr { limbs: [ + 0x0a11800000000001, 0x0aa76fed00000010, 0x044d1e5c37b00159, 0x0655e9a2ca55660b, 0x12ab, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0a11800000000001, 0x0aa76fed00000010, 0x044d1e5c37b00159, 0x0655e9a2ca55660b, 0x12ab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xa180b8d69e258f5204c21151e79ea1, 0x91ec40b2c9ee4e51e49faa80548fd0, 0x036d94 + ] +}; diff --git a/src/fields/bls12_381Fq.nr b/src/fields/bls12_381Fq.nr index 93e1ccab..f4c0ef5a 100644 --- a/src/fields/bls12_381Fq.nr +++ b/src/fields/bls12_381Fq.nr @@ -18,24 +18,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global BLS12_381_Fq_PARAMS: BigNumParams<4> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 381, - modulus: [ - 0xabfffeb153ffffb9feffffffffaaab, 0x4b84f38512bf6730d2a0f6b0f6241e, 0xea397fe69a4b1ba7b6434bacd76477, 0x1a0111 - ], - double_modulus: [ - 0x0157fffd62a7ffff73fdffffffff5556, 0x019709e70a257ece61a541ed61ec483c, 0x01d472ffcd3496374f6c869759aec8ed, 0x340222 - ], - modulus_u60: U60Repr { limbs: [ - 0x09feffffffffaaab, 0x0abfffeb153ffffb, 0xd2a0f6b0f6241e, 0x04b84f38512bf673, 0x07b6434bacd76477, 0x0ea397fe69a4b1ba, 0x1a0111, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x09feffffffffaaab, 0x0abfffeb153ffffb, 0xd2a0f6b0f6241e, 0x04b84f38512bf673, 0x07b6434bacd76477, 0x0ea397fe69a4b1ba, 0x1a0111, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x65c59e8163c701ec4f881fd59646e8, 0x09d07fda82a52f7d1dc780a19de74e, 0x4bcf32791738a0406c331e9ae8a46e, 0x2760d7 - ] -}; - pub struct BLS12_381_Fq_Params {} impl BigNumParamsGetter<4> for BLS12_381_Fq_Params { @@ -44,3 +26,20 @@ impl BigNumParamsGetter<4> for BLS12_381_Fq_Params { } } +global BLS12_381_Fq_PARAMS: BigNumParams<4> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 381, + modulus: [ + 0xabfffeb153ffffb9feffffffffaaab, 0x4b84f38512bf6730d2a0f6b0f6241e, 0xea397fe69a4b1ba7b6434bacd76477, 0x1a0111 + ], + double_modulus: [ + 0x0157fffd62a7ffff73fdffffffff5556, 0x019709e70a257ece61a541ed61ec483c, 0x01d472ffcd3496374f6c869759aec8ed, 0x340222 + ], + modulus_u60: U60Repr { limbs: [ + 0x09feffffffffaaab, 0x0abfffeb153ffffb, 0xd2a0f6b0f6241e, 0x04b84f38512bf673, 0x07b6434bacd76477, 0x0ea397fe69a4b1ba, 0x1a0111, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x09feffffffffaaab, 0x0abfffeb153ffffb, 0xd2a0f6b0f6241e, 0x04b84f38512bf673, 0x07b6434bacd76477, 0x0ea397fe69a4b1ba, 0x1a0111, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x5c59e8163c701ec4f881fd59646e8b, 0x9d07fda82a52f7d1dc780a19de74e6, 0xbcf32791738a0406c331e9ae8a46e0, 0x02760d74 + ] +}; diff --git a/src/fields/bls12_381Fr.nr b/src/fields/bls12_381Fr.nr index 6ccf0667..fce8a52b 100644 --- a/src/fields/bls12_381Fr.nr +++ b/src/fields/bls12_381Fr.nr @@ -18,24 +18,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global BLS12_381_Fr_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 255, - modulus: [ - 0xbda402fffe5bfeffffffff00000001, 0xa753299d7d483339d80809a1d80553, 0x73ed - ], - double_modulus: [ - 0x017b4805fffcb7fdfffffffe00000002, 0x014ea6533afa906673b0101343b00aa6, 0xe7da - ], - modulus_u60: U60Repr { limbs: [ - 0x0fffffff00000001, 0x0bda402fffe5bfef, 0x09d80809a1d80553, 0x0a753299d7d48333, 0x73ed, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0fffffff00000001, 0x0bda402fffe5bfef, 0x09d80809a1d80553, 0x0a753299d7d48333, 0x73ed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x410fad2f92eb5c509cde80830358e4, 0x253b7fb78ddf0e2d772dc1f823b4d9, 0x8d54 - ] -}; - pub struct BLS12_381_Fr_Params {} impl BigNumParamsGetter<3> for BLS12_381_Fr_Params { @@ -44,3 +26,20 @@ impl BigNumParamsGetter<3> for BLS12_381_Fr_Params { } } +global BLS12_381_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 255, + modulus: [ + 0xbda402fffe5bfeffffffff00000001, 0xa753299d7d483339d80809a1d80553, 0x73ed + ], + double_modulus: [ + 0x017b4805fffcb7fdfffffffe00000002, 0x014ea6533afa906673b0101343b00aa6, 0xe7da + ], + modulus_u60: U60Repr { limbs: [ + 0x0fffffff00000001, 0x0bda402fffe5bfef, 0x09d80809a1d80553, 0x0a753299d7d48333, 0x73ed, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0fffffff00000001, 0x0bda402fffe5bfef, 0x09d80809a1d80553, 0x0a753299d7d48333, 0x73ed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x10fad2f92eb5c509cde80830358e4c, 0x53b7fb78ddf0e2d772dc1f823b4d94, 0x08d542 + ] +}; diff --git a/src/fields/bn254Fq.nr b/src/fields/bn254Fq.nr index eaacd7f1..fa54b0e2 100644 --- a/src/fields/bn254Fq.nr +++ b/src/fields/bn254Fq.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global BN254_Fq_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 254, - modulus: [ - 0x816a916871ca8d3c208c16d87cfd47, 0x4e72e131a029b85045b68181585d97, 0x3064 - ], - double_modulus: [ - 0x0102d522d0e3951a7841182db0f9fa8e, 0x019ce5c263405370a08b6d0302b0bb2e, 0x60c7 - ], - modulus_u60: U60Repr { limbs: [ - 0x0c208c16d87cfd47, 0x0816a916871ca8d3, 0x45b68181585d97, 0x04e72e131a029b85, 0x3064, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0c208c16d87cfd47, 0x0816a916871ca8d3, 0x45b68181585d97, 0x04e72e131a029b85, 0x3064, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x965e1767cd4c086f3aed8a19bf90e5, 0x7462623a04a7ab074a5868073013ae, 0x54a4 - ] -}; - pub struct BN254_Fq_Params {} impl BigNumParamsGetter<3> for BN254_Fq_Params { @@ -27,3 +9,21 @@ impl BigNumParamsGetter<3> for BN254_Fq_Params { BN254_Fq_PARAMS } } + +global BN254_Fq_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 254, + modulus: [ + 0x816a916871ca8d3c208c16d87cfd47, 0x4e72e131a029b85045b68181585d97, 0x3064 + ], + double_modulus: [ + 0x0102d522d0e3951a7841182db0f9fa8e, 0x019ce5c263405370a08b6d0302b0bb2e, 0x60c7 + ], + modulus_u60: U60Repr { limbs: [ + 0x0c208c16d87cfd47, 0x0816a916871ca8d3, 0x45b68181585d97, 0x04e72e131a029b85, 0x3064, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0c208c16d87cfd47, 0x0816a916871ca8d3, 0x45b68181585d97, 0x04e72e131a029b85, 0x3064, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x65e1767cd4c086f3aed8a19bf90e51, 0x462623a04a7ab074a5868073013ae9, 0x054a47 + ] +}; diff --git a/src/fields/ed25519Fq.nr b/src/fields/ed25519Fq.nr index d8af5af6..254e288e 100644 --- a/src/fields/ed25519Fq.nr +++ b/src/fields/ed25519Fq.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global ED25519_Fq_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 255, - modulus: [ - 0xffffffffffffffffffffffffffffed, 0xffffffffffffffffffffffffffffff, 0x7fff - ], - double_modulus: [ - 0x01ffffffffffffffffffffffffffffda, 0x01fffffffffffffffffffffffffffffe, 0xfffe - ], - modulus_u60: U60Repr { limbs: [ - 0x0fffffffffffffed, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x7fff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0fffffffffffffed, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x7fff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x13, 0x00, 0x8000 - ] -}; - pub struct ED25519_Fq_Params {} impl BigNumParamsGetter<3> for ED25519_Fq_Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<3> for ED25519_Fq_Params { } } +global ED25519_Fq_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 255, + modulus: [ + 0xffffffffffffffffffffffffffffed, 0xffffffffffffffffffffffffffffff, 0x7fff + ], + double_modulus: [ + 0x01ffffffffffffffffffffffffffffda, 0x01fffffffffffffffffffffffffffffe, 0xfffe + ], + modulus_u60: U60Repr { limbs: [ + 0x0fffffffffffffed, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x7fff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0fffffffffffffed, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x7fff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x0130, 0x00, 0x080000 + ] +}; diff --git a/src/fields/ed25519Fr.nr b/src/fields/ed25519Fr.nr index 72be347d..595c95be 100644 --- a/src/fields/ed25519Fr.nr +++ b/src/fields/ed25519Fr.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global ED25519_Fr_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 253, - modulus: [ - 0xdef9dea2f79cd65812631a5cf5d3ed, 0x14, 0x1000 - ], - double_modulus: [ - 0x01bdf3bd45ef39acb024c634b9eba7da, 0x01000000000000000000000000000028, 0x1fff - ], - modulus_u60: U60Repr { limbs: [ - 0x0812631a5cf5d3ed, 0x0def9dea2f79cd65, 0x14, 0x00, 0x1000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0812631a5cf5d3ed, 0x0def9dea2f79cd65, 0x14, 0x00, 0x1000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x84188574218ca69fb673968c28b04c, 0xffffffffffffffffffffffffffffac, 0x3fff - ] -}; - pub struct ED25519_Fr_Params {} impl BigNumParamsGetter<3> for ED25519_Fr_Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<3> for ED25519_Fr_Params { } } +global ED25519_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 253, + modulus: [ + 0xdef9dea2f79cd65812631a5cf5d3ed, 0x14, 0x1000 + ], + double_modulus: [ + 0x01bdf3bd45ef39acb024c634b9eba7da, 0x01000000000000000000000000000028, 0x1fff + ], + modulus_u60: U60Repr { limbs: [ + 0x0812631a5cf5d3ed, 0x0def9dea2f79cd65, 0x14, 0x00, 0x1000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0812631a5cf5d3ed, 0x0def9dea2f79cd65, 0x14, 0x00, 0x1000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x4188574218ca69fb673968c28b04c6, 0xfffffffffffffffffffffffffffac8, 0x03ffff + ] +}; diff --git a/src/fields/mnt4_753Fq.nr b/src/fields/mnt4_753Fq.nr index 14c5d641..076d0bc2 100644 --- a/src/fields/mnt4_753Fq.nr +++ b/src/fields/mnt4_753Fq.nr @@ -1,6 +1,6 @@ //! Blurb sourced from https://github.com/arkworks-rs //! This library implements the base field of the MNT4_753 curve generated in -//! [\[BCTV14\]](https://eprint.iacr.org/2014/595). The name denotes that it is a +//! [[BCTV14]](https://eprint.iacr.org/2014/595). The name denotes that it is a //! Miyaji--Nakabayashi--Takano curve of embedding degree 4, defined over a //! 753-bit (prime) field. The main feature of this curve is that its scalar //! field and base field respectively equal the base field and scalar field of @@ -23,25 +23,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global MNT4_753_Fq_PARAMS: BigNumParams<7> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 753, - modulus: [ - 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 - ], - double_modulus: [ - 0x013aa8a459ba233ebd20c7bc48bd0002, 0x0199d2ece4a948c71020e335884be1c6, 0x01ede4300b3b701e1b4b96a6fc70d0b4, 0x01d141db1b33a249b342b5ef3b622fcd, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 - ], - modulus_u60: U60Repr { limbs: [ - 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x45dcc95da918349f4965a2aee8fd75, 0x282372b75580c27c4d1f1f57a96a11, 0xd58326e3c0552419849e3c7171d852, 0xa300e0ede1965cbf72f0aa9bf03479, 0x67fb932cae2aba9a5d17c1ff73538b, 0xa82727c6eaef38056aaa0aaedb0574, 0x0242f916cf - ] -}; - -pub struct MNT4_753_Fq_Params {} +pub struct MNT4_753_Fq_Params {} impl BigNumParamsGetter<7> for MNT4_753_Fq_Params { fn get_params() -> BigNumParams<7> { @@ -49,3 +31,20 @@ impl BigNumParamsGetter<7> for MNT4_753_Fq_Params { } } +global MNT4_753_Fq_PARAMS: BigNumParams<7> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 753, + modulus: [ + 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 + ], + double_modulus: [ + 0x013aa8a459ba233ebd20c7bc48bd0002, 0x0199d2ece4a948c71020e335884be1c6, 0x01ede4300b3b701e1b4b96a6fc70d0b4, 0x01d141db1b33a249b342b5ef3b622fcd, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 + ], + modulus_u60: U60Repr { limbs: [ + 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x5dcc95da918349f4965a2aee8fd750, 0x82372b75580c27c4d1f1f57a96a114, 0x58326e3c0552419849e3c7171d8522, 0x300e0ede1965cbf72f0aa9bf03479d, 0x7fb932cae2aba9a5d17c1ff73538ba, 0x82727c6eaef38056aaa0aaedb05746, 0x242f916cfa + ] +}; diff --git a/src/fields/mnt4_753Fr.nr b/src/fields/mnt4_753Fr.nr index ba8ae9de..10a3dfc3 100644 --- a/src/fields/mnt4_753Fr.nr +++ b/src/fields/mnt4_753Fr.nr @@ -1,6 +1,6 @@ //! Blurb sourced from https://github.com/arkworks-rs //! This library implements the scalar field of the MNT4_753 curve generated in -//! [\[BCTV14\]](https://eprint.iacr.org/2014/595). The name denotes that it is a +//! [[BCTV14]](https://eprint.iacr.org/2014/595). The name denotes that it is a //! Miyaji--Nakabayashi--Takano curve of embedding degree 4, defined over a //! 753-bit (prime) field. The main feature of this curve is that its scalar //! field and base field respectively equal the base field and scalar field of @@ -23,24 +23,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global MNT4_753_Fr_PARAMS: BigNumParams<7> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 753, - modulus: [ - 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 - ], - double_modulus: [ - 0x0141322e1f42749fb20eedc480000002, 0x01f2ec69327549ad8703787e00af2e9c, 0x015190b353367dd7952852424c6d73be, 0x01d141db1b33a249b342b5ef3b64d8b7, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 - ], - modulus_u60: U60Repr { limbs: [ - 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xa2dae11d15867718ec70f5ff059bba, 0x276d65fe7e00ba391da260f2623ff9, 0x8140a086edaa60c58eb476bdedcb35, 0xa300e0ede1965cbf72f0aa9bee8120, 0x67fb932cae2aba9a5d17c1ff73538b, 0xa82727c6eaef38056aaa0aaedb0574, 0x0242f916cf - ] -}; - pub struct MNT4_753_Fr_Params {} impl BigNumParamsGetter<7> for MNT4_753_Fr_Params { @@ -49,3 +31,20 @@ impl BigNumParamsGetter<7> for MNT4_753_Fr_Params { } } +global MNT4_753_Fr_PARAMS: BigNumParams<7> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 753, + modulus: [ + 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 + ], + double_modulus: [ + 0x0141322e1f42749fb20eedc480000002, 0x01f2ec69327549ad8703787e00af2e9c, 0x015190b353367dd7952852424c6d73be, 0x01d141db1b33a249b342b5ef3b64d8b7, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 + ], + modulus_u60: U60Repr { limbs: [ + 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x2dae11d15867718ec70f5ff059bba2, 0x76d65fe7e00ba391da260f2623ff9a, 0x140a086edaa60c58eb476bdedcb352, 0x300e0ede1965cbf72f0aa9bee81208, 0x7fb932cae2aba9a5d17c1ff73538ba, 0x82727c6eaef38056aaa0aaedb05746, 0x242f916cfa + ] +}; diff --git a/src/fields/mnt6_753Fq.nr b/src/fields/mnt6_753Fq.nr index d9f03a7a..80b9745a 100644 --- a/src/fields/mnt6_753Fq.nr +++ b/src/fields/mnt6_753Fq.nr @@ -1,6 +1,6 @@ //! Blurb sourced from https://github.com/arkworks-rs //! This library implements the base field of the MNT6_753 curve generated in -//! [\[BCTV14\]](https://eprint.iacr.org/2014/595). The name denotes that it is a +//! [[BCTV14]](https://eprint.iacr.org/2014/595). The name denotes that it is a //! Miyaji--Nakabayashi--Takano curve of embedding degree 6, defined over a //! 753-bit (prime) field. The main feature of this curve is that its scalar //! field and base field respectively equal the base field and scalar field of @@ -23,24 +23,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global MNT6_753_Fq_PARAMS: BigNumParams<7> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 753, - modulus: [ - 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 - ], - double_modulus: [ - 0x0141322e1f42749fb20eedc480000002, 0x01f2ec69327549ad8703787e00af2e9c, 0x015190b353367dd7952852424c6d73be, 0x01d141db1b33a249b342b5ef3b64d8b7, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 - ], - modulus_u60: U60Repr { limbs: [ - 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xa2dae11d15867718ec70f5ff059bba, 0x276d65fe7e00ba391da260f2623ff9, 0x8140a086edaa60c58eb476bdedcb35, 0xa300e0ede1965cbf72f0aa9bee8120, 0x67fb932cae2aba9a5d17c1ff73538b, 0xa82727c6eaef38056aaa0aaedb0574, 0x0242f916cf - ] -}; - pub struct MNT6_753_Fq_Params {} impl BigNumParamsGetter<7> for MNT6_753_Fq_Params { @@ -49,3 +31,20 @@ impl BigNumParamsGetter<7> for MNT6_753_Fq_Params { } } +global MNT6_753_Fq_PARAMS: BigNumParams<7> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 753, + modulus: [ + 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 + ], + double_modulus: [ + 0x0141322e1f42749fb20eedc480000002, 0x01f2ec69327549ad8703787e00af2e9c, 0x015190b353367dd7952852424c6d73be, 0x01d141db1b33a249b342b5ef3b64d8b7, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 + ], + modulus_u60: U60Repr { limbs: [ + 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x2dae11d15867718ec70f5ff059bba2, 0x76d65fe7e00ba391da260f2623ff9a, 0x140a086edaa60c58eb476bdedcb352, 0x300e0ede1965cbf72f0aa9bee81208, 0x7fb932cae2aba9a5d17c1ff73538ba, 0x82727c6eaef38056aaa0aaedb05746, 0x242f916cfa + ] +}; diff --git a/src/fields/mnt6_753Fr.nr b/src/fields/mnt6_753Fr.nr index b07cacdc..82ebd40c 100644 --- a/src/fields/mnt6_753Fr.nr +++ b/src/fields/mnt6_753Fr.nr @@ -1,6 +1,6 @@ //! Blurb sourced from https://github.com/arkworks-rs //! This library implements the scalar field of the MNT6_753 curve generated in -//! [\[BCTV14\]](https://eprint.iacr.org/2014/595). The name denotes that it is a +//! [[BCTV14]](https://eprint.iacr.org/2014/595). The name denotes that it is a //! Miyaji--Nakabayashi--Takano curve of embedding degree 6, defined over a //! 753-bit (prime) field. The main feature of this curve is that its scalar //! field and base field respectively equal the base field and scalar field of @@ -23,24 +23,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global MNT6_753_Fr_PARAMS: BigNumParams<7> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 753, - modulus: [ - 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 - ], - double_modulus: [ - 0x013aa8a459ba233ebd20c7bc48bd0002, 0x0199d2ece4a948c71020e335884be1c6, 0x01ede4300b3b701e1b4b96a6fc70d0b4, 0x01d141db1b33a249b342b5ef3b622fcd, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 - ], - modulus_u60: U60Repr { limbs: [ - 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x45dcc95da918349f4965a2aee8fd75, 0x282372b75580c27c4d1f1f57a96a11, 0xd58326e3c0552419849e3c7171d852, 0xa300e0ede1965cbf72f0aa9bf03479, 0x67fb932cae2aba9a5d17c1ff73538b, 0xa82727c6eaef38056aaa0aaedb0574, 0x0242f916cf - ] -}; - pub struct MNT6_753_Fr_Params {} impl BigNumParamsGetter<7> for MNT6_753_Fr_Params { @@ -49,3 +31,20 @@ impl BigNumParamsGetter<7> for MNT6_753_Fr_Params { } } +global MNT6_753_Fr_PARAMS: BigNumParams<7> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 753, + modulus: [ + 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 + ], + double_modulus: [ + 0x013aa8a459ba233ebd20c7bc48bd0002, 0x0199d2ece4a948c71020e335884be1c6, 0x01ede4300b3b701e1b4b96a6fc70d0b4, 0x01d141db1b33a249b342b5ef3b622fcd, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 + ], + modulus_u60: U60Repr { limbs: [ + 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x5dcc95da918349f4965a2aee8fd750, 0x82372b75580c27c4d1f1f57a96a114, 0x58326e3c0552419849e3c7171d8522, 0x300e0ede1965cbf72f0aa9bf03479d, 0x7fb932cae2aba9a5d17c1ff73538ba, 0x82727c6eaef38056aaa0aaedb05746, 0x242f916cfa + ] +}; diff --git a/src/fields/pallasFq.nr b/src/fields/pallasFq.nr index 4265ae55..e305c4fa 100644 --- a/src/fields/pallasFq.nr +++ b/src/fields/pallasFq.nr @@ -1,5 +1,5 @@ //! Blurb sourced from https://github.com/arkworks-rs -//! This library implements the scalar field of the prime-order curve Pallas, generated by +//! This library implements the base field of the prime-order curve Pallas, generated by //! [Daira Hopwood](https://github.com/zcash/pasta). The main feature of this //! curve is that it forms a cycle with Vesta, i.e. its scalar field and base //! field respectively are the base field and scalar field of Vesta. @@ -17,24 +17,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global Pallas_Fq_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 255, - modulus: [ - 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 - ], - double_modulus: [ - 0x018d31f81299f237325a61da00000002, 0x01000000000000000000000000000043, 0x7fff - ], - modulus_u60: U60Repr { limbs: [ - 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xe59c0fdacc1b919b4b3c4bfffffffc, 0xffffffffffffffffffffffffffff76, 0xffff - ] -}; - pub struct Pallas_Fq_Params {} impl BigNumParamsGetter<3> for Pallas_Fq_Params { @@ -43,3 +25,20 @@ impl BigNumParamsGetter<3> for Pallas_Fq_Params { } } +global Pallas_Fq_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 255, + modulus: [ + 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 + ], + double_modulus: [ + 0x018d31f81299f237325a61da00000002, 0x01000000000000000000000000000043, 0x7fff + ], + modulus_u60: U60Repr { limbs: [ + 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x59c0fdacc1b919b4b3c4bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff + ] +}; diff --git a/src/fields/pallasFr.nr b/src/fields/pallasFr.nr index e696d38f..a865f93e 100644 --- a/src/fields/pallasFr.nr +++ b/src/fields/pallasFr.nr @@ -1,5 +1,5 @@ //! Blurb sourced from https://github.com/arkworks-rs -//! This library implements the base field of the prime-order curve Pallas, generated by +//! This library implements the scalar field of the prime-order curve Pallas, generated by //! [Daira Hopwood](https://github.com/zcash/pasta). The main feature of this //! curve is that it forms a cycle with Vesta, i.e. its scalar field and base //! field respectively are the base field and scalar field of Vesta. @@ -17,24 +17,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global Pallas_Fr_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 255, - modulus: [ - 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 - ], - double_modulus: [ - 0x018d31f8132951bb188dd64200000002, 0x01000000000000000000000000000043, 0x7fff - ], - modulus_u60: U60Repr { limbs: [ - 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xe59c0fd9ad5c89cee4537bfffffffc, 0xffffffffffffffffffffffffffff76, 0xffff - ] -}; - pub struct Pallas_Fr_Params {} impl BigNumParamsGetter<3> for Pallas_Fr_Params { @@ -43,3 +25,20 @@ impl BigNumParamsGetter<3> for Pallas_Fr_Params { } } +global Pallas_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 255, + modulus: [ + 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 + ], + double_modulus: [ + 0x018d31f8132951bb188dd64200000002, 0x01000000000000000000000000000043, 0x7fff + ], + modulus_u60: U60Repr { limbs: [ + 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x59c0fd9ad5c89cee4537bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff + ] +}; diff --git a/src/fields/secp256k1Fq.nr b/src/fields/secp256k1Fq.nr index 8615e19e..84274f71 100644 --- a/src/fields/secp256k1Fq.nr +++ b/src/fields/secp256k1Fq.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global Secp256k1_Fq_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 256, - modulus: [ - 0xfffffffffffffffffffffefffffc2f, 0xffffffffffffffffffffffffffffff, 0xffff - ], - double_modulus: [ - 0x01fffffffffffffffffffffdfffff85e, 0x01fffffffffffffffffffffffffffffe, 0x01fffe - ], - modulus_u60: U60Repr { limbs: [ - 0x0ffffffefffffc2f, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0ffffffefffffc2f, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x01000003d1, 0x00, 0x010000 - ] -}; - pub struct Secp256k1_Fq_Params {} impl BigNumParamsGetter<3> for Secp256k1_Fq_Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<3> for Secp256k1_Fq_Params { } } +global Secp256k1_Fq_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 256, + modulus: [ + 0xfffffffffffffffffffffefffffc2f, 0xffffffffffffffffffffffffffffff, 0xffff + ], + double_modulus: [ + 0x01fffffffffffffffffffffdfffff85e, 0x01fffffffffffffffffffffffffffffe, 0x01fffe + ], + modulus_u60: U60Repr { limbs: [ + 0x0ffffffefffffc2f, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0ffffffefffffc2f, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x1000003d10, 0x00, 0x100000 + ] +}; diff --git a/src/fields/secp256k1Fr.nr b/src/fields/secp256k1Fr.nr index 65474658..a8dcac44 100644 --- a/src/fields/secp256k1Fr.nr +++ b/src/fields/secp256k1Fr.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global Secp256k1_Fr_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 256, - modulus: [ - 0xaedce6af48a03bbfd25e8cd0364141, 0xfffffffffffffffffffffffffffeba, 0xffff - ], - double_modulus: [ - 0x015db9cd5e9140777fa4bd19a06c8282, 0x01fffffffffffffffffffffffffffd74, 0x01fffe - ], - modulus_u60: U60Repr { limbs: [ - 0x0fd25e8cd0364141, 0x0aedce6af48a03bb, 0x0ffffffffffffeba, 0x0fffffffffffffff, 0xffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0fd25e8cd0364141, 0x0aedce6af48a03bb, 0x0ffffffffffffeba, 0x0fffffffffffffff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x51231950b75fc4402da1732fc9bec0, 0x0145, 0x010000 - ] -}; - pub struct Secp256k1_Fr_Params {} impl BigNumParamsGetter<3> for Secp256k1_Fr_Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<3> for Secp256k1_Fr_Params { } } +global Secp256k1_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 256, + modulus: [ + 0xaedce6af48a03bbfd25e8cd0364141, 0xfffffffffffffffffffffffffffeba, 0xffff + ], + double_modulus: [ + 0x015db9cd5e9140777fa4bd19a06c8282, 0x01fffffffffffffffffffffffffffd74, 0x01fffe + ], + modulus_u60: U60Repr { limbs: [ + 0x0fd25e8cd0364141, 0x0aedce6af48a03bb, 0x0ffffffffffffeba, 0x0fffffffffffffff, 0xffff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0fd25e8cd0364141, 0x0aedce6af48a03bb, 0x0ffffffffffffeba, 0x0fffffffffffffff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x1231950b75fc4402da1732fc9bec09, 0x1455, 0x100000 + ] +}; diff --git a/src/fields/secp256r1Fq.nr b/src/fields/secp256r1Fq.nr index acad7082..77c6808e 100644 --- a/src/fields/secp256r1Fq.nr +++ b/src/fields/secp256r1Fq.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global Secp256r1_Fq_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 256, - modulus: [ - 0xffffffffffffffffffffffff, 0xffff00000001000000000000000000, 0xffff - ], - double_modulus: [ - 0x01000001fffffffffffffffffffffffe, 0x01fffe00000001ffffffffffffffffff, 0x01fffe - ], - modulus_u60: U60Repr { limbs: [ - 0x0fffffffffffffff, 0x0fffffffff, 0x00, 0x0ffff00000001000, 0xffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0fffffffffffffff, 0x0fffffffff, 0x00, 0x0ffff00000001000, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xfffffeffffffff0000000000000003, 0xfffffffffffffffefffffffeff, 0x010000 - ] -}; - pub struct Secp256r1_Fq_Params {} impl BigNumParamsGetter<3> for Secp256r1_Fq_Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<3> for Secp256r1_Fq_Params { } } +global Secp256r1_Fq_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 256, + modulus: [ + 0xffffffffffffffffffffffff, 0xffff00000001000000000000000000, 0xffff + ], + double_modulus: [ + 0x01000001fffffffffffffffffffffffe, 0x01fffe00000001ffffffffffffffffff, 0x01fffe + ], + modulus_u60: U60Repr { limbs: [ + 0x0fffffffffffffff, 0x0fffffffff, 0x00, 0x0ffff00000001000, 0xffff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0fffffffffffffff, 0x0fffffffff, 0x00, 0x0ffff00000001000, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0xffffeffffffff00000000000000030, 0x0fffffffffffffffefffffffefff, 0x100000 + ] +}; diff --git a/src/fields/secp256r1Fr.nr b/src/fields/secp256r1Fr.nr index 4ed0088b..29d6d92a 100644 --- a/src/fields/secp256r1Fr.nr +++ b/src/fields/secp256r1Fr.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global Secp256r1_Fr_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 256, - modulus: [ - 0xe6faada7179e84f3b9cac2fc632551, 0xffff00000000ffffffffffffffffbc, 0xffff - ], - double_modulus: [ - 0x01cdf55b4e2f3d09e7739585f8c64aa2, 0x01fffe00000001ffffffffffffffff78, 0x01fffe - ], - modulus_u60: U60Repr { limbs: [ - 0x03b9cac2fc632551, 0x0e6faada7179e84f, 0x0fffffffffffffbc, 0x0ffff00000000fff, 0xffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x03b9cac2fc632551, 0x0e6faada7179e84f, 0x0fffffffffffffbc, 0x0ffff00000000fff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x190552df1a6c21012ffd85eedf9bfe, 0xfffffffffffffffeffffffff43, 0x010000 - ] -}; - pub struct Secp256r1_Fr_Params {} impl BigNumParamsGetter<3> for Secp256r1_Fr_Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<3> for Secp256r1_Fr_Params { } } +global Secp256r1_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 256, + modulus: [ + 0xe6faada7179e84f3b9cac2fc632551, 0xffff00000000ffffffffffffffffbc, 0xffff + ], + double_modulus: [ + 0x01cdf55b4e2f3d09e7739585f8c64aa2, 0x01fffe00000001ffffffffffffffff78, 0x01fffe + ], + modulus_u60: U60Repr { limbs: [ + 0x03b9cac2fc632551, 0x0e6faada7179e84f, 0x0fffffffffffffbc, 0x0ffff00000000fff, 0xffff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x03b9cac2fc632551, 0x0e6faada7179e84f, 0x0fffffffffffffbc, 0x0ffff00000000fff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x90552df1a6c21012ffd85eedf9bfe6, 0x0fffffffffffffffeffffffff431, 0x100000 + ] +}; diff --git a/src/fields/secp384r1Fq.nr b/src/fields/secp384r1Fq.nr index 9149f604..3035c0e2 100644 --- a/src/fields/secp384r1Fq.nr +++ b/src/fields/secp384r1Fq.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global Secp384r1_Fq_PARAMS: BigNumParams<4> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 384, - modulus: [ - 0xffffff0000000000000000ffffffff, 0xfffffffffffffffffffffffffffeff, 0xffffffffffffffffffffffffffffff, 0xffffff - ], - double_modulus: [ - 0x01fffffe0000000000000001fffffffe, 0x01fffffffffffffffffffffffffffdfe, 0x01fffffffffffffffffffffffffffffe, 0x01fffffe - ], - modulus_u60: U60Repr { limbs: [ - 0xffffffff, 0x0ffffff000000000, 0x0ffffffffffffeff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0xffffffff, 0x0ffffff000000000, 0x0ffffffffffffeff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xffffffffffffffff00000001, 0x0100, 0x00, 0x01000000 - ] -}; - pub struct Secp384r1_Fq_Params {} impl BigNumParamsGetter<4> for Secp384r1_Fq_Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<4> for Secp384r1_Fq_Params { } } +global Secp384r1_Fq_PARAMS: BigNumParams<4> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 384, + modulus: [ + 0xffffff0000000000000000ffffffff, 0xfffffffffffffffffffffffffffeff, 0xffffffffffffffffffffffffffffff, 0xffffff + ], + double_modulus: [ + 0x01fffffe0000000000000001fffffffe, 0x01fffffffffffffffffffffffffffdfe, 0x01fffffffffffffffffffffffffffffe, 0x01fffffe + ], + modulus_u60: U60Repr { limbs: [ + 0xffffffff, 0x0ffffff000000000, 0x0ffffffffffffeff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0xffffffff, 0x0ffffff000000000, 0x0ffffffffffffeff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x0ffffffffffffffff000000010, 0x1000, 0x00, 0x10000000 + ] +}; diff --git a/src/fields/secp384r1Fr.nr b/src/fields/secp384r1Fr.nr index 75393219..0d819a83 100644 --- a/src/fields/secp384r1Fr.nr +++ b/src/fields/secp384r1Fr.nr @@ -2,24 +2,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global Secp384r1_Fr_PARAMS: BigNumParams<4> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 384, - modulus: [ - 0x1a0db248b0a77aecec196accc52973, 0xffffffffffffc7634d81f4372ddf58, 0xffffffffffffffffffffffffffffff, 0xffffff - ], - double_modulus: [ - 0x01341b6491614ef5d9d832d5998a52e6, 0x01ffffffffffff8ec69b03e86e5bbeaf, 0x01fffffffffffffffffffffffffffffe, 0x01fffffe - ], - modulus_u60: U60Repr { limbs: [ - 0x0cec196accc52973, 0x01a0db248b0a77ae, 0x034d81f4372ddf58, 0x0ffffffffffffc76, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0cec196accc52973, 0x01a0db248b0a77ae, 0x034d81f4372ddf58, 0x0ffffffffffffc76, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xe5f24db74f58851313e695333ad68d, 0x389cb27e0bc8d220a7, 0x00, 0x01000000 - ] -}; - pub struct Secp384r1_Fr_Params {} impl BigNumParamsGetter<4> for Secp384r1_Fr_Params { @@ -28,3 +10,20 @@ impl BigNumParamsGetter<4> for Secp384r1_Fr_Params { } } +global Secp384r1_Fr_PARAMS: BigNumParams<4> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 384, + modulus: [ + 0x1a0db248b0a77aecec196accc52973, 0xffffffffffffc7634d81f4372ddf58, 0xffffffffffffffffffffffffffffff, 0xffffff + ], + double_modulus: [ + 0x01341b6491614ef5d9d832d5998a52e6, 0x01ffffffffffff8ec69b03e86e5bbeaf, 0x01fffffffffffffffffffffffffffffe, 0x01fffffe + ], + modulus_u60: U60Repr { limbs: [ + 0x0cec196accc52973, 0x01a0db248b0a77ae, 0x034d81f4372ddf58, 0x0ffffffffffffc76, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0cec196accc52973, 0x01a0db248b0a77ae, 0x034d81f4372ddf58, 0x0ffffffffffffc76, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x5f24db74f58851313e695333ad68d0, 0x0389cb27e0bc8d220a7e, 0x00, 0x10000000 + ] +}; diff --git a/src/fields/vestaFq.nr b/src/fields/vestaFq.nr index 0fcecf4e..59c0bfc4 100644 --- a/src/fields/vestaFq.nr +++ b/src/fields/vestaFq.nr @@ -18,24 +18,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global Vesta_Fq_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 255, - modulus: [ - 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 - ], - double_modulus: [ - 0x018d31f8132951bb188dd64200000002, 0x01000000000000000000000000000043, 0x7fff - ], - modulus_u60: U60Repr { limbs: [ - 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xe59c0fd9ad5c89cee4537bfffffffc, 0xffffffffffffffffffffffffffff76, 0xffff - ] -}; - pub struct Vesta_Fq_Params {} impl BigNumParamsGetter<3> for Vesta_Fq_Params { @@ -44,3 +26,21 @@ impl BigNumParamsGetter<3> for Vesta_Fq_Params { } } +global Vesta_Fq_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 255, + modulus: [ + 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 + ], + double_modulus: [ + 0x018d31f8132951bb188dd64200000002, 0x01000000000000000000000000000043, 0x7fff + ], + modulus_u60: U60Repr { limbs: [ + 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x59c0fd9ad5c89cee4537bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff + ] +}; + diff --git a/src/fields/vestaFr.nr b/src/fields/vestaFr.nr index c0367491..25c45332 100644 --- a/src/fields/vestaFr.nr +++ b/src/fields/vestaFr.nr @@ -18,24 +18,6 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -global Vesta_Fr_PARAMS: BigNumParams<3> = BigNumParams { - has_multiplicative_inverse: true, - modulus_bits_getter: || 255, - modulus: [ - 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 - ], - double_modulus: [ - 0x018d31f81299f237325a61da00000002, 0x01000000000000000000000000000043, 0x7fff - ], - modulus_u60: U60Repr { limbs: [ - 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xe59c0fdacc1b919b4b3c4bfffffffc, 0xffffffffffffffffffffffffffff76, 0xffff - ] -}; - pub struct Vesta_Fr_Params {} impl BigNumParamsGetter<3> for Vesta_Fr_Params { @@ -44,3 +26,20 @@ impl BigNumParamsGetter<3> for Vesta_Fr_Params { } } +global Vesta_Fr_PARAMS: BigNumParams<3> = BigNumParams { + has_multiplicative_inverse: true, + modulus_bits_getter: || 255, + modulus: [ + 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 + ], + double_modulus: [ + 0x018d31f81299f237325a61da00000002, 0x01000000000000000000000000000043, 0x7fff + ], + modulus_u60: U60Repr { limbs: [ + 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x59c0fdacc1b919b4b3c4bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff + ] +}; diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index 0387dcee..f42931e8 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -3,7 +3,7 @@ use crate::utils::map::map; use crate::params::BigNumParams; use crate::constrained_ops::{ - conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, neg, add, sub, + derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, neg, add, sub, mul, div, udiv_mod, udiv, umod }; use crate::unconstrained_ops::{ @@ -23,6 +23,7 @@ pub struct RuntimeBigNum { pub(crate) trait RuntimeBigNumTrait { fn new(params: BigNumParams) -> Self; fn one(params: BigNumParams) -> Self; + fn derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; fn from_slice(params: BigNumParams, limbs: [Field]) -> Self; fn from_array(params: BigNumParams, limbs: [Field; N]) -> Self; @@ -104,6 +105,13 @@ impl RuntimeBigNumTrait for RuntimeBigNum { result } + fn derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self { + let limbs = unsafe { + derive_from_seed(params, seed) + }; + Self { limbs, params } + } + // UNCONSTRAINED! (Hence `__` prefix). fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self { let limbs = unsafe { @@ -273,11 +281,11 @@ impl RuntimeBigNumTrait for RuntimeBigNum { let (q_limbs, r_limbs) = unsafe { __compute_quadratic_expression( params, - lhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + map(lhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), lhs_flags, - rhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + map(rhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), rhs_flags, - linear_terms.map(|bn| Self::get_limbs(bn)), + map(linear_terms, |bn| Self::get_limbs(bn)), linear_flags ) }; @@ -295,11 +303,11 @@ impl RuntimeBigNumTrait for RuntimeBigNum { ) { evaluate_quadratic_expression( params, - lhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + map(lhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), lhs_flags, - rhs_terms.map(|bns| map(bns, |bn| Self::get_limbs(bn))), + map(rhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), rhs_flags, - linear_terms.map(|bn| Self::get_limbs(bn)), + map(linear_terms, |bn| Self::get_limbs(bn)), linear_flags ) } diff --git a/src/runtime_bignum_test.nr b/src/runtime_bignum_test.nr index 61e318d8..d7503ac8 100644 --- a/src/runtime_bignum_test.nr +++ b/src/runtime_bignum_test.nr @@ -1,107 +1,88 @@ use crate::utils::u60_representation::U60Repr; use crate::runtime_bignum::RuntimeBigNum; -use crate::params::BigNumParams; +use crate::params::{ BigNumParams, BigNumParamsGetter }; + use crate::fields::bn254Fq::BN254_Fq_Params; +use crate::fields::secp256k1Fq::Secp256k1_Fq_Params; +use crate::fields::bls12_381Fq::BLS12_381_Fq_Params; +use crate::fields::bls12_381Fr::BLS12_381_Fr_Params; +use crate::fields::bls12_377Fq::BLS12_377_Fq_Params; +use crate::fields::bls12_377Fr::BLS12_377_Fr_Params; + +global TEST_2048_PARAMS: BigNumParams<18> = BigNumParams { + has_multiplicative_inverse: false, + modulus_bits_getter: || 2048, + modulus: [ + 0xc0a197a5ae0fcdceb052c9732614fe, 0x656ae034423283422243918ab83be3, 0x6bf590da48a7c1070b7d5aabaac678, 0x0cce39f530238b606f24b296e2bda9, 0x01e1fef9bb9c1c3ead98f226f1bfa0, 0xad8c1c816e12e0ed1379055e373abf, 0xcebe80e474f753aa9d1461c435123d, 0xaee5a18ceedef88d115a8b93c167ad, 0x268ba83c4a65c4307427fc495d9e44, 0xdd2777926848667b7df79f342639d4, 0xf455074c96855ca0068668efe7da3d, 0x5ddba6b30bbc168bfb3a1225f27d65, 0x591fec484f36707524133bcd6f4258, 0x59641b756766aeebe66781dd01d062, 0x58bc5eaff4b165e142bf9e2480eebb, 0x667a3964f08e06df772ce64b229a72, 0x9c1fdb18907711bfe3e3c1cf918395, 0xb8 + ], + double_modulus: [ + 0x0181432f4b5c1f9b9d60a592e64c29fc, 0x01cad5c06884650684448723157077c6, 0x01d7eb21b4914f820e16fab557558cef, 0x01199c73ea604716c0de49652dc57b51, 0x0103c3fdf37738387d5b31e44de37f3f, 0x015b183902dc25c1da26f20abc6e757d, 0x019d7d01c8e9eea7553a28c3886a247a, 0x015dcb4319ddbdf11a22b5172782cf5a, 0x014d17507894cb8860e84ff892bb3c88, 0x01ba4eef24d090ccf6fbef3e684c73a7, 0x01e8aa0e992d0ab9400d0cd1dfcfb47a, 0x01bbb74d6617782d17f674244be4faca, 0x01b23fd8909e6ce0ea4826779ade84af, 0x01b2c836eacecd5dd7cccf03ba03a0c3, 0x01b178bd5fe962cbc2857f3c4901dd75, 0x01ccf472c9e11c0dbeee59cc964534e3, 0x01383fb63120ee237fc7c7839f230729, 0x0170 + ], + modulus_u60: U60Repr { limbs: [ + 0x0eb052c9732614fe, 0x0c0a197a5ae0fcdc, 0x022243918ab83be3, 0x0656ae0344232834, 0x070b7d5aabaac678, 0x06bf590da48a7c10, 0x6f24b296e2bda9, 0xcce39f530238b6, 0x0ead98f226f1bfa0, 0x1e1fef9bb9c1c3, 0x0d1379055e373abf, 0x0ad8c1c816e12e0e, 0x0a9d1461c435123d, 0x0cebe80e474f753a, 0x0d115a8b93c167ad, 0x0aee5a18ceedef88, 0x7427fc495d9e44, 0x0268ba83c4a65c43, 0x0b7df79f342639d4, 0x0dd2777926848667, 0x068668efe7da3d, 0x0f455074c96855ca, 0x0bfb3a1225f27d65, 0x05ddba6b30bbc168, 0x0524133bcd6f4258, 0x0591fec484f36707, 0x0be66781dd01d062, 0x059641b756766aee, 0x0142bf9e2480eebb, 0x058bc5eaff4b165e, 0x0f772ce64b229a72, 0x0667a3964f08e06d, 0x0fe3e3c1cf918395, 0x09c1fdb18907711b, 0xb8, 0x00]}, + modulus_u60_x4: U60Repr { limbs: [ + 0x0eb052c9732614fe, 0x0c0a197a5ae0fcdc, 0x022243918ab83be3, 0x0656ae0344232834, 0x070b7d5aabaac678, 0x06bf590da48a7c10, 0x6f24b296e2bda9, 0xcce39f530238b6, 0x0ead98f226f1bfa0, 0x1e1fef9bb9c1c3, 0x0d1379055e373abf, 0x0ad8c1c816e12e0e, 0x0a9d1461c435123d, 0x0cebe80e474f753a, 0x0d115a8b93c167ad, 0x0aee5a18ceedef88, 0x7427fc495d9e44, 0x0268ba83c4a65c43, 0x0b7df79f342639d4, 0x0dd2777926848667, 0x068668efe7da3d, 0x0f455074c96855ca, 0x0bfb3a1225f27d65, 0x05ddba6b30bbc168, 0x0524133bcd6f4258, 0x0591fec484f36707, 0x0be66781dd01d062, 0x059641b756766aee, 0x0142bf9e2480eebb, 0x058bc5eaff4b165e, 0x0f772ce64b229a72, 0x0667a3964f08e06d, 0x0fe3e3c1cf918395, 0x09c1fdb18907711b, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + redc_param: [ + 0x1697def7100cd5cf8d890b4ef2ec3f, 0x765ba8304214dac764d3f4adc31859, 0x8404bd14d927ea230e60d4bebf9406, 0xc4d53a23bacc251ecbfc4b7ba5a0b4, 0x3eaf3499474a6f5b2fff83f1259c87, 0xbff4c737b97281f1a5f2384a8c16d9, 0x1b4cf2f55358476b53237829990555, 0xe7a804e8eacfe3a2a5673bc3885b86, 0xabadeae4282906c817adf70eab4ae1, 0x66f7df257fe2bf27f0809aceed9b0e, 0xd90fb7428901b8bed11f6b81e36bf1, 0x36e6ba885c60b7024c563605df7e07, 0x2b7c58d2fb5d2c8478963ae6d4a44f, 0x6ee761de26635f114ccc3f7d74f855, 0x3fb726a10cf2220897513f05243de3, 0x43a26bbd732496eb4d828591b8056e, 0xf4e42304e60fb3a54fca735499f2cf, 0x162f + ] +}; + +struct Test2048Params {} + +// See https://github.com/noir-lang/noir/issues/6172 +#[test] +fn silence_warning() { + let _ = Test2048Params {}; +} -global BN254_Fq_PARAMS = BN254_Fq_Params::get_params(); - -fn get_2048_BN_params() -> BigNumParams<18> { - let has_multiplicative_inverse = false; - let modulus_bits_getter = || 2048; - let modulus: [Field; 18] = [ - 0x0000000000000000000000000000000000c0a197a5ae0fcdceb052c9732614fe, - 0x0000000000000000000000000000000000656ae034423283422243918ab83be3, - 0x00000000000000000000000000000000006bf590da48a7c1070b7d5aabaac678, - 0x00000000000000000000000000000000000cce39f530238b606f24b296e2bda9, - 0x000000000000000000000000000000000001e1fef9bb9c1c3ead98f226f1bfa0, - 0x0000000000000000000000000000000000ad8c1c816e12e0ed1379055e373abf, - 0x0000000000000000000000000000000000cebe80e474f753aa9d1461c435123d, - 0x0000000000000000000000000000000000aee5a18ceedef88d115a8b93c167ad, - 0x0000000000000000000000000000000000268ba83c4a65c4307427fc495d9e44, - 0x0000000000000000000000000000000000dd2777926848667b7df79f342639d4, - 0x0000000000000000000000000000000000f455074c96855ca0068668efe7da3d, - 0x00000000000000000000000000000000005ddba6b30bbc168bfb3a1225f27d65, - 0x0000000000000000000000000000000000591fec484f36707524133bcd6f4258, - 0x000000000000000000000000000000000059641b756766aeebe66781dd01d062, - 0x000000000000000000000000000000000058bc5eaff4b165e142bf9e2480eebb, - 0x0000000000000000000000000000000000667a3964f08e06df772ce64b229a72, - 0x00000000000000000000000000000000009c1fdb18907711bfe3e3c1cf918395, - 0x00000000000000000000000000000000000000000000000000000000000000b8 - ]; - let redc_param: [Field; 18] = [ - 0x000000000000000000000000000000000091697def7100cd5cf8d890b4ef2ec3, - 0x00000000000000000000000000000000006765ba8304214dac764d3f4adc3185, - 0x000000000000000000000000000000000048404bd14d927ea230e60d4bebf940, - 0x00000000000000000000000000000000007c4d53a23bacc251ecbfc4b7ba5a0b, - 0x000000000000000000000000000000000093eaf3499474a6f5b2fff83f1259c8, - 0x00000000000000000000000000000000005bff4c737b97281f1a5f2384a8c16d, - 0x000000000000000000000000000000000061b4cf2f55358476b5323782999055, - 0x00000000000000000000000000000000001e7a804e8eacfe3a2a5673bc3885b8, - 0x0000000000000000000000000000000000eabadeae4282906c817adf70eab4ae, - 0x0000000000000000000000000000000000166f7df257fe2bf27f0809aceed9b0, - 0x00000000000000000000000000000000007d90fb7428901b8bed11f6b81e36bf, - 0x0000000000000000000000000000000000f36e6ba885c60b7024c563605df7e0, - 0x000000000000000000000000000000000052b7c58d2fb5d2c8478963ae6d4a44, - 0x000000000000000000000000000000000036ee761de26635f114ccc3f7d74f85, - 0x0000000000000000000000000000000000e3fb726a10cf2220897513f05243de, - 0x0000000000000000000000000000000000f43a26bbd732496eb4d828591b8056, - 0x0000000000000000000000000000000000ff4e42304e60fb3a54fca735499f2c, - 0x0000000000000000000000000000000000000000000000000000000000000162 - ]; - BigNumParams::new( - has_multiplicative_inverse, - modulus_bits_getter, - modulus, - redc_param - ) +impl BigNumParamsGetter<18> for Test2048Params { + fn get_params() -> BigNumParams<18> { + TEST_2048_PARAMS + } } -fn test_eq(params: BigNumParams) { - let a = unsafe { - RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) - }; - let b = unsafe { - RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) - }; - let c = unsafe { - RuntimeBigNum::__derive_from_seed(params, [2, 2, 3, 4]) - }; +#[test] +fn test_add() { + let params = BN254_Fq_Params::get_params(); - let modulus = a.modulus(); - let t0: U60Repr = (U60Repr::from(modulus.limbs)); - let t1: U60Repr = (U60Repr::from(b.limbs)); - let b_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; + let a = unsafe{ RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; + let b = unsafe{ RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) }; - assert((a == b) == true); - assert((a == b_plus_modulus) == true); - assert((c == b) == false); - assert((c == a) == false); -} + let one = RuntimeBigNum::one(params); -// 98760 -// 99689 -// 929 gates for a 2048 bit mul -fn test_mul(params: BigNumParams) { - let a = unsafe { - RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) - }; - let b = unsafe { - RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) - }; + a.validate_in_range(); + a.validate_in_field(); + b.validate_in_range(); + b.validate_in_field(); - let c = (a + b) * (a + b); - let d = (a * a) + (b * b) + (a * b) + (a * b); + let mut c = a + b; + c = c + c; + let d = (a + b) * (one + one); assert(c == d); + + let e = one + one; + for i in 1..3 { + assert(e.limbs[i] == 0); + } + assert(e.limbs[0] == 2); } -fn test_add(params: BigNumParams) { - let a = unsafe { - RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) - }; - let b = unsafe { - RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) - }; - let one = RuntimeBigNum::one(params); +/** + * @brief experimenting with macro madness and code generation to make some tests that apply to multiple BigNum parametrisations! + **/ +comptime fn make_test(f: StructDefinition, N: Quoted, typ: Quoted) -> Quoted { + let k = f.name(); + quote{ +impl $k { +#[test] +fn test_add() { + let params = $typ ::get_params(); + + let a = unsafe{ RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; + let b = unsafe{ RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) }; + + let one: RuntimeBigNum<$N> = RuntimeBigNum::one(params); + a.validate_in_range(); a.validate_in_field(); b.validate_in_range(); @@ -113,13 +94,96 @@ fn test_add(params: BigNumParams) { assert(c == d); let e = one + one; - for i in 1..N { + for i in 1..$N { assert(e.limbs[i] == 0); } assert(e.limbs[0] == 2); } -fn test_div(params: BigNumParams) { +#[test] +fn test_sub() { + let params = $typ ::get_params(); + + // 0 - 1 should equal p - 1 + let mut a: RuntimeBigNum<$N> = RuntimeBigNum::new(params); + let mut b: RuntimeBigNum<$N> = RuntimeBigNum::one(params); + let mut expected = RuntimeBigNum { limbs: params.modulus, params }; + expected.limbs[0] -= 1; // p - 1 + + let result = a - b; + assert(result == expected); +} + +#[test] +fn test_sub_modulus_limit() { + let params = $typ ::get_params(); + // if we underflow, maximum result should be ... + // 0 - 1 = o-1 + // 0 - p = 0 + let mut a: RuntimeBigNum<$N> = RuntimeBigNum::new(params); + let mut b = RuntimeBigNum { limbs: params.modulus, params }; + let mut expected: RuntimeBigNum<$N> = RuntimeBigNum::new(params); + + let result = a - b; + assert(result == expected); +} + +#[test(should_fail_with = "call to assert_max_bit_size")] +fn test_sub_modulus_underflow() { + let params = $typ ::get_params(); + + // 0 - (p + 1) is smaller than p and should produce unsatisfiable constraints + let mut a: RuntimeBigNum<$N> = RuntimeBigNum::new(params); + let mut b = RuntimeBigNum { limbs: params.modulus, params }; + b.limbs[0] += 1; + let mut expected: RuntimeBigNum<$N> = RuntimeBigNum::one(params); + + let result = a - b; + + assert(result == expected); +} + +#[test] +fn test_add_modulus_limit() { + let params = $typ ::get_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 + // this is the largest value that will satisfy the range check applied when constructing a bignum + let p: U60Repr<$N, 2> = U60Repr::from(params.modulus); + let one = unsafe{ U60Repr::one() }; + + let a = RuntimeBigNum { limbs: U60Repr::into(p), params }; + + let two_pow_modulus_bits_minus_one: U60Repr<$N, 2> = unsafe{ one.shl(a.modulus_bits()) - one }; + + let b = RuntimeBigNum { limbs: U60Repr::into(two_pow_modulus_bits_minus_one), params }; + + let result = a + b; + assert(result == b); +} + +#[test(should_fail_with = "call to assert_max_bit_size")] +fn test_add_modulus_overflow() { + let params = $typ ::get_params(); + + let p : U60Repr<$N, 2> = U60Repr::from(params.modulus); + let one = unsafe{ U60Repr::one() }; + + let a = RuntimeBigNum { limbs: U60Repr::into(p + one), params }; + + let mut two_pow_modulus_bits_minus_one: U60Repr<$N, 2> = unsafe{ one.shl(a.modulus_bits()) - one }; + + let b = RuntimeBigNum { limbs: U60Repr::into(two_pow_modulus_bits_minus_one), params }; + + let result = a + b; + assert(result == b); +} + +#[test] +fn test_mul() { + let params = $typ ::get_params(); + let a = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; @@ -127,21 +191,63 @@ fn test_div(params: BigNumParams) { RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) }; - let c = a / b; - assert((b * c) == a); + let c = (a + b) * (a + b); + let d = (a * a) + (b * b) + (a * b) + (a * b); + assert(c == d); } -unconstrained fn test_invmod(params: BigNumParams) { - let u = RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]); - for _ in 0..1 { - let v = u.__invmod(); - let result = u.__mul(v); - let expected = RuntimeBigNum::one(params); - assert(result.limbs == expected.limbs); +#[test] +fn test_quadratic_expression() { + let params = $typ ::get_params(); + + for i in 0..32 { + let X1 = unsafe{ RuntimeBigNum::__derive_from_seed(params, [i as u8, 2, 3, 4]) }; + let Y1 = unsafe{ RuntimeBigNum::__derive_from_seed(params, [i as u8, i as u8, 6, 7]) }; + let Z1: RuntimeBigNum<$N> = RuntimeBigNum::one(params); + + let (_, YY_mul_2) = unsafe{ RuntimeBigNum::__compute_quadratic_expression(params, [[Y1]], [[false]], [[Y1, Y1]], [[false, false]], [], []) }; + let mut (_, XX_mul_3) = unsafe{ RuntimeBigNum::__compute_quadratic_expression( + params, + [[X1]], + [[false]], + [[X1, X1, X1]], + [[false, false, false]], + [], + [] + ) }; + let (_, D) = unsafe{ RuntimeBigNum::__compute_quadratic_expression(params, [[X1, X1]], [[false, false]], [[YY_mul_2]], [[false]], [], []) }; + let mut (_, X3) = unsafe{ RuntimeBigNum::__compute_quadratic_expression( + params, + [[XX_mul_3]], + [[false]], + [[XX_mul_3]], + [[false]], + [D, D], + [true, true] + ) }; + let (_, Y3) = unsafe{ RuntimeBigNum::__compute_quadratic_expression( + params, + [[XX_mul_3], [YY_mul_2]], + [[false], [true]], + [[D, X3], [YY_mul_2, YY_mul_2]], + [[false, true], [false, false]], + [], + [] + ) }; + // 3XX * (D - X3) - 8YYYY + + let (_, Z3) = unsafe{ RuntimeBigNum::__compute_quadratic_expression(params, [[Y1]], [[false]], [[Z1, Z1]], [[false, false]], [], []) }; + + X3.validate_in_field(); + Y3.validate_in_field(); + Z3.validate_in_field(); } } -unconstrained fn assert_is_not_equal(params: BigNumParams) { +#[test] +fn assert_is_not_equal() { + let params = $typ ::get_params(); + let a = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; @@ -152,7 +258,10 @@ unconstrained fn assert_is_not_equal(params: BigNumParams) { a.assert_is_not_equal(b); } -unconstrained fn assert_is_not_equal_fail(params: BigNumParams) { +#[test(should_fail_with = "asssert_is_not_equal fail")] +fn assert_is_not_equal_fail() { + let params = $typ ::get_params(); + let a = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; @@ -163,7 +272,10 @@ unconstrained fn assert_is_not_equal_fail(params: BigNumParams) { a.assert_is_not_equal(b); } -fn assert_is_not_equal_overloaded_lhs_fail(params: BigNumParams) { +#[test(should_fail_with = "asssert_is_not_equal fail")] +fn assert_is_not_equal_overloaded_lhs_fail() { + let params = $typ ::get_params(); + let a = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; @@ -173,13 +285,17 @@ fn assert_is_not_equal_overloaded_lhs_fail(params: BigNumParams) let modulus = params.modulus; - let t0: U60Repr = U60Repr::from(a.limbs); - let t1: U60Repr = U60Repr::from(modulus); + let t0: U60Repr<$N, 2> = U60Repr::from(a.limbs); + let t1: U60Repr<$N, 2> = U60Repr::from(modulus); let a_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; + a_plus_modulus.assert_is_not_equal(b); } -fn assert_is_not_equal_overloaded_rhs_fail(params: BigNumParams) { +#[test(should_fail_with = "asssert_is_not_equal fail")] +fn assert_is_not_equal_overloaded_rhs_fail() { + let params = $typ ::get_params(); + let a = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; @@ -189,13 +305,17 @@ fn assert_is_not_equal_overloaded_rhs_fail(params: BigNumParams) let modulus = params.modulus; - let t0: U60Repr = U60Repr::from(b.limbs); - let t1: U60Repr = U60Repr::from(modulus); + let t0: U60Repr<$N, 2> = U60Repr::from(b.limbs); + let t1: U60Repr<$N, 2> = U60Repr::from(modulus); let b_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; + a.assert_is_not_equal(b_plus_modulus); } -fn assert_is_not_equal_overloaded_fail(params: BigNumParams) { +#[test(should_fail_with = "asssert_is_not_equal fail")] +fn assert_is_not_equal_overloaded_fail() { + let params = $typ ::get_params(); + let a = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; @@ -205,228 +325,135 @@ fn assert_is_not_equal_overloaded_fail(params: BigNumParams) { let modulus = params.modulus; - let t0: U60Repr = U60Repr::from(a.limbs); - let t1: U60Repr = U60Repr::from(b.limbs); - let t2: U60Repr = U60Repr::from(modulus); + let t0: U60Repr<$N, 2> = U60Repr::from(a.limbs); + let t1: U60Repr<$N, 2> = U60Repr::from(b.limbs); + let t2: U60Repr<$N, 2> = U60Repr::from(modulus); + let a_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t2), params }; let b_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t1 + t2), params }; + a_plus_modulus.assert_is_not_equal(b_plus_modulus); } #[test] -fn test_eq_BN() { - let params = BN254_Fq_PARAMS; - test_eq(params); -} -#[test] -fn test_add_BN() { - let params = BN254_Fq_PARAMS; +fn test_derive() +{ + let params = $typ ::get_params(); - let mut a = RuntimeBigNum { limbs: params.modulus, params }; - let mut b = a; - let mut expected = a; - - a.limbs[0] -= 1; - b.limbs[0] -= 1; - expected.limbs[0] -= 2; - - let result = a + b; - assert(result == expected); + let a = RuntimeBigNum::derive_from_seed(params, "hello".as_bytes()); + let b = unsafe { + RuntimeBigNum::__derive_from_seed(params, "hello".as_bytes()) + }; + assert(a == b); } #[test] -fn test_sub_test_BN() { - let params = BN254_Fq_PARAMS; +fn test_eq() { + let params = $typ ::get_params(); - // 0 - 1 should equal p - 1 - let mut a = RuntimeBigNum::new(params); - let mut b = RuntimeBigNum::one(params); - let mut expected = RuntimeBigNum { limbs: params.modulus, params }; - expected.limbs[0] -= 1; // p - 1 + let a = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let b = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let c = unsafe { + RuntimeBigNum::__derive_from_seed(params, [2, 2, 3, 4]) + }; - let result = a - b; - assert(result == expected); -} + let modulus = a.modulus(); -#[test] -fn test_sub_modulus_limit() { - let params = BN254_Fq_PARAMS; + let t0: U60Repr<$N, 2> = (U60Repr::from(modulus.limbs)); + let t1: U60Repr<$N, 2> = (U60Repr::from(b.limbs)); - // if we underflow, maximum result should be ... - // 0 - 1 = o-1 - // 0 - p = 0 - let mut a= RuntimeBigNum::new(params); - let mut b= RuntimeBigNum { limbs: params.modulus, params }; - let mut expected= RuntimeBigNum::new(params); + let b_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; - let result = a - b; - assert(result == expected); + assert((a == b) == true); + assert((a == b_plus_modulus) == true); + assert((c == b) == false); + assert((c == a) == false); } -#[test(should_fail_with = "call to assert_max_bit_size")] -fn test_sub_modulus_underflow() { - let params = BN254_Fq_PARAMS; - - // 0 - (p + 1) is smaller than p and should produce unsatisfiable constraints - let mut a = RuntimeBigNum::new(params); - let mut b = RuntimeBigNum { limbs: params.modulus, params }; - b.limbs[0] += 1; - let mut expected = RuntimeBigNum::one(params); - - let result = a - b; - - assert(result == expected); } - -#[test] -fn test_add_modulus_limit() { - let params = BN254_Fq_PARAMS; - - // 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 : U60Repr<3, 2> = U60Repr::from(params.modulus); - let two_pow_254_minus_1: U60Repr<3, 2> = U60Repr::from([0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x3fff]); - let a = RuntimeBigNum { limbs: U60Repr::into(p), params }; - let b = RuntimeBigNum { limbs: U60Repr::into(two_pow_254_minus_1), params }; - let result = a + b; - assert(result == b); } - -#[test(should_fail_with = "call to assert_max_bit_size")] -fn test_add_modulus_overflow() { - let params = BN254_Fq_PARAMS; - - //(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 : U60Repr<3, 2> = U60Repr::from(params.modulus); - let two_pow_254_minus_1: U60Repr<3, 2> = U60Repr::from([0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x3fff]); - let one = U60Repr::from([1, 0, 0]); - let a = RuntimeBigNum { limbs: U60Repr::into(p + one), params }; - let b = RuntimeBigNum { limbs: U60Repr::into(two_pow_254_minus_1), params }; - let result = a + b; - assert(result == b); } -#[test] -fn test_mul_BN() { - let params = BN254_Fq_PARAMS; - test_mul(params); -} +#[make_test(quote{3},quote{BN254_Fq_Params})] +pub struct BNTests{} -#[test] -fn test_add_BN2() { - let params = BN254_Fq_PARAMS; - test_add(params); -} +#[make_test(quote{3},quote{Secp256k1_Fq_Params})] +pub struct Secp256K1FqTests{} -#[test] -fn test_div_BN() { - let params = BN254_Fq_PARAMS; - test_div(params); -} +#[make_test(quote{4},quote{BLS12_381_Fq_Params})] +pub struct BLS12_381FqTests{} -#[test] -unconstrained fn test_invmod_BN() { - let params = BN254_Fq_PARAMS; - test_invmod(params); -} +#[make_test(quote{18},quote{Test2048Params})] +pub struct Test2048Tests{} -#[test] -unconstrained fn test_assert_is_not_equal_BN() { - let params = BN254_Fq_PARAMS; - assert_is_not_equal(params); -} +#[make_test(quote{3},quote{BLS12_381_Fr_Params})] +pub struct BLS12_381_Fr_ParamsTests{} -#[test(should_fail_with = "asssert_is_not_equal fail")] -unconstrained fn test_assert_is_not_equal_fail_BN() { - let params = BN254_Fq_PARAMS; - assert_is_not_equal_fail(params); -} +#[make_test(quote{4},quote{BLS12_377_Fq_Params})] +pub struct BLS12_377_Fq_ParamsTests{} -#[test(should_fail_with = "asssert_is_not_equal fail")] -fn test_assert_is_not_equal_overloaded_lhs_fail_BN() { - let params = BN254_Fq_PARAMS; - assert_is_not_equal_overloaded_lhs_fail(params); -} +#[make_test(quote{3},quote{BLS12_377_Fr_Params})] +pub struct BLS12_377_Fr_ParamsTests{} -#[test(should_fail_with = "asssert_is_not_equal fail")] -fn test_assert_is_not_equal_overloaded_rhs_fail_BN() { - let params = BN254_Fq_PARAMS; - assert_is_not_equal_overloaded_rhs_fail(params); -} +// 98760 +// 99689 +// 929 gates for a 2048 bit mul -#[test(should_fail_with = "asssert_is_not_equal fail")] -fn test_assert_is_not_equal_overloaded_fail_BN() { - let params = BN254_Fq_PARAMS; - assert_is_not_equal_overloaded_fail(params); -} +fn test_div(params: BigNumParams) { + let a = unsafe { + RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) + }; + let b = unsafe { + RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) + }; -#[test] -fn test_eq_2048() { - let params = get_2048_BN_params(); - test_eq(params); + let c = a / b; + assert((b * c) == a); } -#[test] -fn test_mul_2048() { - let params = get_2048_BN_params(); - test_mul(params); +unconstrained fn test_invmod(params: BigNumParams) { + let u = RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]); + for _ in 0..1 { + let v = u.__invmod(); + let result = u.__mul(v); + let expected = RuntimeBigNum::one(params); + assert(result.limbs == expected.limbs); + } } #[test] -fn test_add_2048() { - let params = get_2048_BN_params(); - test_add(params); +fn test_div_BN() { + let params = BN254_Fq_Params::get_params(); + test_div(params); } #[test] -unconstrained fn test_assert_is_not_equal_2048() { - let params = get_2048_BN_params(); - assert_is_not_equal(params); -} - -#[test(should_fail_with = "asssert_is_not_equal fail")] -unconstrained fn test_assert_is_not_equal_fail_2048() { - let params = get_2048_BN_params(); - assert_is_not_equal_fail(params); -} - -#[test(should_fail_with = "asssert_is_not_equal fail")] -fn test_assert_is_not_equal_overloaded_lhs_fail_2048() { - let params = get_2048_BN_params(); - assert_is_not_equal_overloaded_lhs_fail(params); -} - -#[test(should_fail_with = "asssert_is_not_equal fail")] -fn test_assert_is_not_equal_overloaded_rhs_fail_2048() { - let params = get_2048_BN_params(); - assert_is_not_equal_overloaded_rhs_fail(params); -} - -#[test(should_fail_with = "asssert_is_not_equal fail")] -fn test_assert_is_not_equal_overloaded_fail_2048() { - let params = get_2048_BN_params(); - assert_is_not_equal_overloaded_fail(params); +fn test_invmod_BN() { + let params = BN254_Fq_Params::get_params(); + unsafe { test_invmod(params) }; } // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril // #[test] // fn test_div_2048() { -// let params = get_2048_BN_params(); +// let params = get_2048_params(); // test_div(params); // } // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril // #[test] // fn test_invmod_2048() { -// let params = get_2048_BN_params(); +// let params = get_2048_params(); // test_invmod(params); // } #[test] fn test_2048_bit_quadratic_expression() { - let params = get_2048_BN_params(); + let params = TEST_2048_PARAMS; let a: [Field; 18] = [ 0x000000000000000000000000000000000083684820ff40795b8d9f1be2220cba, 0x0000000000000000000000000000000000d4924fbdc522b07b6cd0ef5508fd66, @@ -488,109 +515,12 @@ fn test_2048_bit_quadratic_expression() { 0x0000000000000000000000000000000000000000000000000000000000000058 ]; - let a= RuntimeBigNum { limbs: a, params }; - let b = RuntimeBigNum { limbs: b, params }; - let c = a * b; + let a_bn = RuntimeBigNum { limbs: a, params }; + let b_bn = RuntimeBigNum { limbs: b, params }; + let c = a_bn * b_bn; assert(c.limbs == c_expected); - a.validate_in_range(); - - RuntimeBigNum::evaluate_quadratic_expression(params, [[a]], [[false]], [[b]], [[false]], [c], [true]); -} - -#[test] -fn test_expressions() { - let params = BN254_Fq_PARAMS; - - let x: [Field; 6] = [ - 0x000000000000000000000000000000000083684820ff40795b8d9f1be2220cba, 0x0000000000000000000000000000000000d4924fbdc522b07b6cd0ef5508fd66, 0x0000000000000000000000000000000000d48f6c43c5930f3d70d6db09a48f4a, - 0x0000000000000000000000000000000000e7f72b2c0756704bea85be38352b34, 0x00000000000000000000000000000000000000000000000000000000b05d5ac5, 0 - ]; - - let y= RuntimeBigNum { - limbs: [ - 0x1, - 0x1, - 0x0 - ], params - }; - let z= RuntimeBigNum { - limbs: [ - 0x2, - 0x2, - 0x0 - ], params - }; - let yy = unsafe { - y.__add(y) - }; - - assert(yy.limbs == z.limbs); - - let uu= RuntimeBigNum { - limbs: [ - 0x0000000000000000000000000000000000b4a832748da6ad742a1fd81b787643, - 0x00000000000000000000000000000000009575f594e04080471712c1d7f18e89, - 0x000000000000000000000000000000000000000000000000000000000000063 - ], - params - }; - let vv= RuntimeBigNum { - limbs: [ - 0x0000000000000000000000000000000000b4aec2748da6ad742a1fd81b787643, - 0x00000000000000000000000000000000009575f594e0408047171a01d7f18e89, - 0x0000000000000000000000000000000000000000000000000000000000000062 - ], - params - }; - let w= RuntimeBigNum { - limbs: [ - 0x0000000000000000000000000000000000b4a832748da6ad742a1fd81b787643, - 0x00000000000000000000000000000000009575f594e04080471712c1d7f18e89, - 0x0000000000000000000000000000000000000000000000000000000000001f93 - ], - params - }; - let x= RuntimeBigNum { - limbs: [ - 0x0000000000000000000000000000000000b4aec2748da6ad742a1fd81b787643, - 0x00000000000000000000000000000000009575f594e0408047171a01d7f18e89, - 0x0000000000000000000000000000000000000000000000000000000000000f93 - ], - params - }; - let wx = unsafe { - w.__mul(x) - }; - let uv = unsafe { - uu.__mul(vv) - }; - let y = unsafe { - (uv.__add(wx)).__neg() - }; - let z = unsafe { - uv.__add(wx) - }; + a_bn.validate_in_range(); - RuntimeBigNum::evaluate_quadratic_expression( - params, - [[uu], [w]], - [[false], [false]], - [[vv], [x]], - [[false], [false]], - [z], - [true] - ); - RuntimeBigNum::evaluate_quadratic_expression( - params, - [[uu], [w]], - [[false], [false]], - [[vv], [x]], - [[false], [false]], - [y], - [false] - ); - - let wx_constrained = w * x; - assert(wx_constrained.limbs == wx.limbs); + RuntimeBigNum::evaluate_quadratic_expression(params, [[a_bn]], [[false]], [[b_bn]], [[false]], [c], [true]); } diff --git a/src/unconstrained_helpers.nr b/src/unconstrained_helpers.nr index 0d9dd581..fb9f29db 100644 --- a/src/unconstrained_helpers.nr +++ b/src/unconstrained_helpers.nr @@ -3,6 +3,18 @@ use crate::utils::split_bits; use crate::params::BigNumParams as P; +/** + * In this file: + * + * __validate_in_field_compute_borrow_flags + * __validate_gt_remainder + * __neg_with_flags + * __add_with_flags + * __sub_with_flags + * __barrett_reduction + * __tonelli_shanks_sqrt + */ + unconstrained pub(crate) fn __validate_in_field_compute_borrow_flags(params: P, val: [Field; N]) -> [bool; N] { let mut flags: [bool; N] = [false; N]; let modulus: [Field; N] = params.modulus; @@ -164,6 +176,13 @@ unconstrained pub(crate) fn __sub_with_flags(params: P, lhs: [Fie (result, carry_flags, borrow_flags, underflow) } +/** + * @brief BARRETT_REDUCTION_OVERFLOW_BITS defines how large an input to barrett reduction can be + * @details maximum value = modulus^2 <( x: [Field; 2 * N], redc_param: [Field; N], @@ -177,9 +196,23 @@ unconstrained pub(crate) fn __barrett_reduction( mulout[i + j] += x[i] * redc_param[j]; } } - mulout = split_bits::__normalize_limbs(mulout, 3 * N - 1); + mulout = split_bits::__normalize_limbs(mulout, 3 * N - 2); let mulout_u60: U60Repr = U60Repr::new(mulout); - let mut quotient_u60 = mulout_u60.shr((k + k)); + + // When we apply the barrett reduction, the maximum value of the output will be + // <= p * (1 + x/2^{2k}) + // where p = modulus, + // x = reduction input + // if x > p * p, we need k to be larger than modulus_bits() + // we hardcode k = 4, which means that the maximum value of x is approx. 16 * p * p + // this should be larger than most values put into `evaluate_quadratic_expression` + // TODO: try and detect cases where x might be too large at comptime + // N.B. BARRETT_REDUCTION_OVERFLOW_BITS affects how `redc_param` is generated. + // `redc_param` = 2^{modulus_bits() * 2 + BARRETT_REDUCTION_OVERFLOW_BITS} / modulus + // NOTE: very niche edge case error that we need to be aware of: + // N must be large enough to cover the modulus *plus* BARRETT_REDUCTION_OVERFLOW_BITS + // i.e. a 359-bit prime needs (I think) 4 limbs to represent or we may overflow when calling __barrett_reduction + let mut quotient_u60 = mulout_u60.shr((k + k + BARRETT_REDUCTION_OVERFLOW_BITS)); // N.B. we assume that the shifted quotient cannot exceed 2 times original bit size. // (partial_quotient should be just slightly larger than the modulus, we could probably represent with a size N+1 array) @@ -221,3 +254,154 @@ unconstrained pub(crate) fn __barrett_reduction( (q, r) } + + +// /** +// * @brief compute the log of the size of the primitive root +// * @details find the maximum value k where x^k = 1, where x = primitive root +// * This is needed for our Tonelli-Shanks sqrt algorithm +// **/ +// unconstrained fn primitive_root_log_size(self) -> u32 { +// let mut target: U60Repr = self.modulus_u60 - U60Repr::one(); +// let mut result: u32 = 0; +// for _ in 0..Params::modulus_bits() { +// let lsb_is_one = (target.limbs[0] & 1) == 1; +// if (!lsb_is_one) { +// result += 1; +// target.shr1(); +// } else { +// break; +// } +// } +// result +// } +// /** +// * @brief inner loop fn for `find_multiplive_generator` +// * @details recursive function to get around the lack of a `while` keyword +// **/ +// unconstrained fn recursively_find_multiplicative_generator( +// self, +// target: BigNum, +// p_minus_one_over_two: BigNum +// ) -> (bool, BigNum) { +// let exped = (self.__pow(target, p_minus_one_over_two)); +// let found = exped.__eq(self.__neg(BigNum::one())); +// let mut result: (bool, BigNum) = (found, target); +// if (!found) { +// let _target = unsafe { +// self.__add(target, BigNum::one()) +// }; +// result = self.recursively_find_multiplicative_generator(_target, p_minus_one_over_two); +// } +// result +// } +// /** +// * @brief find multiplicative generator `g` where `g` is the smallest value that is not a quadratic residue +// * i.e. smallest g where g^2 = -1 +// * @note WARNING if multiplicative generator does not exist, this function will enter an infinite loop! +// **/ +// unconstrained fn multiplicative_generator(self) -> BigNum { +// let mut target = BigNum::one(); +// let p_minus_one_over_two: U60Repr = (self.modulus_u60 - U60Repr::one()).shr(1); +// let p_minus_one_over_two: BigNum = BigNum::from_array(U60Repr::into(p_minus_one_over_two)); +// let (_, target) = self.recursively_find_multiplicative_generator(target, p_minus_one_over_two); +// target +// } +// unconstrained fn __tonelli_shanks_sqrt_inner_loop_check(self, t2m: BigNum, i: u32) -> u32 { +// let is_one = t2m.__eq(BigNum::one()); +// let mut result = i; +// if (!is_one) { +// let t2m = self.__mul(t2m, t2m); +// let i = i + 1; +// result = self.__tonelli_shanks_sqrt_inner_loop_check(t2m, i); +// } +// result +// } + +// /** +// * @brief compute a modular square root using the Tonelli-Shanks algorithm +// * @details only use for prime fields! Function may infinite loop if used for non-prime fields +// * @note this is unconstrained fn. To constrain a square root, validate that output^2 = self +// * TODO: create fn that constrains nonexistence of square root (i.e. find x where x^2 = -self) +// **/ +// unconstrained fn __tonelli_shanks_sqrt( +// self, +// input: BigNum +// ) -> std::option::Option> { +// // Tonelli-shanks algorithm begins by finding a field element Q and integer S, +// // such that (p - 1) = Q.2^{s} +// // We can compute the square root of a, by considering a^{(Q + 1) / 2} = R +// // Once we have found such an R, we have +// // R^{2} = a^{Q + 1} = a^{Q}a +// // If a^{Q} = 1, we have found our square root. +// // Otherwise, we have a^{Q} = t, where t is a 2^{s-1}'th root of unity. +// // This is because t^{2^{s-1}} = a^{Q.2^{s-1}}. +// // We know that (p - 1) = Q.w^{s}, therefore t^{2^{s-1}} = a^{(p - 1) / 2} +// // From Euler's criterion, if a is a quadratic residue, a^{(p - 1) / 2} = 1 +// // i.e. t^{2^{s-1}} = 1 +// // To proceed with computing our square root, we want to transform t into a smaller subgroup, +// // specifically, the (s-2)'th roots of unity. +// // We do this by finding some value b,such that +// // (t.b^2)^{2^{s-2}} = 1 and R' = R.b +// // Finding such a b is trivial, because from Euler's criterion, we know that, +// // for any quadratic non-residue z, z^{(p - 1) / 2} = -1 +// // i.e. z^{Q.2^{s-1}} = -1 +// // => z^Q is a 2^{s-1}'th root of -1 +// // => z^{Q^2} is a 2^{s-2}'th root of -1 +// // Since t^{2^{s-1}} = 1, we know that t^{2^{s - 2}} = -1 +// // => t.z^{Q^2} is a 2^{s - 2}'th root of unity. +// // We can iteratively transform t into ever smaller subgroups, until t = 1. +// // At each iteration, we need to find a new value for b, which we can obtain +// // by repeatedly squaring z^{Q} +// let one: U60Repr = unsafe { +// U60Repr::one() +// }; +// let primitive_root_log_size = self.primitive_root_log_size(); +// let mut Q = (self.modulus_u60 - one).shr(primitive_root_log_size - 1); +// let mut Q_minus_one_over_two = (Q - one).shr(2); +// let mut Q_minus_one_over_two = BigNum::from_array(U60Repr::into(Q_minus_one_over_two)); +// let mut z = self.multiplicative_generator(); // the generator is a non-residue +// let mut b = self.__pow(input, Q_minus_one_over_two); +// let mut r = self.__mul(input, b); +// let mut t = self.__mul(r, b); +// let mut check: BigNum = t; +// for _ in 0..primitive_root_log_size - 1 { +// check = self.__mul(check, check); +// } +// let mut found_root = false; +// if (check.__eq(BigNum::one()) == false) {} else { +// let mut t1 = self.__pow(z, Q_minus_one_over_two); +// let mut t2 = self.__mul(t1, z); +// let mut c = self.__mul(t2, t1); +// let mut m: u32 = primitive_root_log_size; +// // tonelli shanks inner 1 +// // (if t2m == 1) then skip +// // else increase i and square t2m and go again +// // algorithm runtime should only be max the number of bits in modulus +// let num_bits: u32 = Params::modulus_bits(); +// for _ in 0..num_bits { +// if (t.__eq(BigNum::one())) { +// found_root = true; +// break; +// } +// let mut t2m = t; +// // while loop time +// let i = self.__tonelli_shanks_sqrt_inner_loop_check(t2m, 0); +// let mut j = m - i - 1; +// b = c; +// for _ in 0..j { // how big +// if (j == 0) { +// break; +// } +// b = self.__mul(b, b); +// //j -= 1; +// } +// c = self.__mul(b, b); +// t = self.__mul(t, c); +// r = self.__mul(r, b); +// m = i; +// } +// } +// let mut result = std::option::Option { _value: r, _is_some: found_root }; +// result +// } diff --git a/src/unconstrained_ops.nr b/src/unconstrained_ops.nr index f2650abf..580d7399 100644 --- a/src/unconstrained_ops.nr +++ b/src/unconstrained_ops.nr @@ -4,6 +4,26 @@ use crate::utils::split_bits; use crate::params::BigNumParams as P; use crate::unconstrained_helpers::__barrett_reduction; +/** + * In this file: + * + * __one + * __derive_from_seed + * __eq + * __is_zero + * __neg + * __add + * __sub + * __mul_with_quotient + * __mul + * __div + * __udiv_mod + * __invmod + * __pow + * __batch_invert + * __batch_invert_slice + */ + unconstrained pub(crate) fn __one() -> [Field; N] { let mut limbs: [Field; N] = [0; N]; limbs[0] = 1; @@ -11,7 +31,21 @@ unconstrained pub(crate) fn __one() -> [Field; N] { } unconstrained pub(crate) fn __derive_from_seed(params: P, seed: [u8; SeedBytes]) -> [Field; N] { - let mut rolling_seed = seed; + let mut rolling_hash_fields: [Field; (SeedBytes / 31) + 1] = [0; (SeedBytes / 31) + 1]; + let mut seed_ptr = 0; + for i in 0..(SeedBytes / 31) + 1 { + let mut packed: Field = 0; + for _ in 0..31 { + if (seed_ptr < SeedBytes) { + packed *= 256; + packed += seed[seed_ptr] as Field; + seed_ptr += 1; + } + } + rolling_hash_fields[i] = packed; + } + let compressed = std::hash::poseidon2::Poseidon2::hash(rolling_hash_fields, (SeedBytes / 31) + 1); + let mut rolling_hash: [Field; 2] = [compressed, 0]; let mut to_reduce: [Field; 2 * N] = [0; 2 * N]; @@ -30,7 +64,8 @@ unconstrained pub(crate) fn __derive_from_seed(p } for i in 0..(N - 1) { - let hash: [u8; 32] = std::hash::sha256(rolling_seed); + let hash = std::hash::poseidon2::Poseidon2::hash(rolling_hash, 2); + let hash : [u8; 30] = hash.to_le_bytes(); let mut lo: Field = 0; let mut hi: Field = 0; for j in 0..15 { @@ -44,11 +79,12 @@ unconstrained pub(crate) fn __derive_from_seed(p } to_reduce[2 * i] = lo; to_reduce[2 * i + 1] = hi; - rolling_seed[0] += 1; + rolling_hash[1] += 1; } { - let hash: [u8; 32] = std::hash::sha256(rolling_seed); + let hash = std::hash::poseidon2::Poseidon2::hash(rolling_hash, 2); + let hash : [u8; 30] = hash.to_le_bytes(); let mut hi: Field = 0; for j in 0..(last_limb_bytes - 1) { hi *= 256; @@ -133,10 +169,11 @@ unconstrained pub(crate) fn __mul_with_quotient(params: P, lhs: [ mul[i + j] += lhs[i] * rhs[j]; } } + let to_reduce = split_bits::__normalize_limbs(mul, 2 * N); let modulus_bits_getter = params.modulus_bits_getter; let modulus_bits = modulus_bits_getter(); let (q, r) = __barrett_reduction( - split_bits::__normalize_limbs(mul, 2 * N), + to_reduce, params.redc_param, modulus_bits, params.modulus, diff --git a/src/utils/map.nr b/src/utils/map.nr index 9d95e2d1..698e5f46 100644 --- a/src/utils/map.nr +++ b/src/utils/map.nr @@ -1,10 +1,9 @@ // Copied from std::array, because I couldn't figure out how to import the `map` method of the weird trait for an array. // And the reason I wanted direct access to it, is because I couldn't figure out how to implement a double map. pub(crate) fn map(arr: [T; N], f: fn[Env](T) -> U) -> [U; N] { - let first_elem = f(arr[0]); - let mut ret = [first_elem; N]; + let mut ret: [U; N] = std::mem::zeroed(); - for i in 1..arr.len() { + for i in 0..arr.len() { ret[i] = f(arr[i]); } From 9e73b245cc3f6d28a738200cd914cd537d8b941f Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Mon, 21 Oct 2024 17:42:06 +0100 Subject: [PATCH 10/29] fix merge mistake --- src/runtime_bignum_test.nr | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/runtime_bignum_test.nr b/src/runtime_bignum_test.nr index b2de3a34..f88c3ded 100644 --- a/src/runtime_bignum_test.nr +++ b/src/runtime_bignum_test.nr @@ -40,11 +40,6 @@ impl BigNumParamsGetter<18> for Test2048Params { TEST_2048_PARAMS } } -impl NotRuntimeBigNumParamsTrait<18> for Test2048Params { - fn modulus_bits() -> u32 { - 2048 - } -} /** * @brief experimenting with macro madness and code generation to make some tests that apply to multiple BigNum parametrisations! From c0dcaf7d56e5e1788d5644edb8b272cbc8792a3a Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Mon, 21 Oct 2024 21:08:52 +0100 Subject: [PATCH 11/29] add sqrt code from zac --- src/bignum.nr | 21 +++- src/runtime_bignum.nr | 21 +++- src/runtime_bignum_test.nr | 28 ++++- src/unconstrained_helpers.nr | 219 +++++++++++------------------------ src/unconstrained_ops.nr | 93 ++++++++++++++- 5 files changed, 224 insertions(+), 158 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index b5a0fdbe..be4d59bd 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -2,12 +2,12 @@ use crate::utils::map::map; use crate::params::BigNumParamsGetter; use crate::constrained_ops::{ - derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, neg, add, sub, - mul, div, udiv_mod, udiv, umod + derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, + neg, add, sub, mul, div, udiv_mod, udiv, umod }; use crate::unconstrained_ops::{ __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, - __batch_invert, __batch_invert_slice + __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt }; use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}; use crate::serialization::{from_be_bytes, to_le_bytes}; @@ -51,6 +51,8 @@ pub(crate) trait BigNumTrait { unconstrained fn __batch_invert(to_invert: [Self; M]) -> [Self; M]; unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; + unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option; + unconstrained fn __compute_quadratic_expression( lhs: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], @@ -216,6 +218,19 @@ impl BigNumTrait for BigNum where Params: BigN __batch_invert_slice(params, x.map(|bn| Self::get_limbs(bn))).map(|limbs| Self { limbs }) } + unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option { + let params = Params::get_params(); + let maybe_limbs = unsafe { + __tonelli_shanks_sqrt(params, self.limbs) + }; + let result: std::option::Option = if maybe_limbs.is_some() { + std::option::Option::some(Self { limbs: maybe_limbs.unwrap_unchecked() }) + } else { + std::option::Option::none() + }; + result + } + unconstrained fn __compute_quadratic_expression( lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index f42931e8..b3d4499e 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -3,12 +3,12 @@ use crate::utils::map::map; use crate::params::BigNumParams; use crate::constrained_ops::{ - derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, neg, add, sub, - mul, div, udiv_mod, udiv, umod + derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, + neg, add, sub, mul, div, udiv_mod, udiv, umod }; use crate::unconstrained_ops::{ __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, - __batch_invert, __batch_invert_slice + __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt }; use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}; use crate::serialization::{from_be_bytes, to_le_bytes}; @@ -54,6 +54,8 @@ pub(crate) trait RuntimeBigNumTrait { fn __batch_invert(x: [Self; M]) -> [Self; M]; unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; + unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option; + fn __compute_quadratic_expression( params: BigNumParams, lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], @@ -268,6 +270,19 @@ impl RuntimeBigNumTrait for RuntimeBigNum { all_limbs.map(|limbs| Self { limbs, params }) } + unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option { + let params = self.params; + let maybe_limbs = unsafe { + __tonelli_shanks_sqrt(params, self.limbs) + }; + let result: std::option::Option = if maybe_limbs.is_some() { + std::option::Option::some(Self { limbs: maybe_limbs.unwrap_unchecked(), params }) + } else { + std::option::Option::none() + }; + result + } + // UNCONSTRAINED! (Hence `__` prefix). fn __compute_quadratic_expression( params: BigNumParams, diff --git a/src/runtime_bignum_test.nr b/src/runtime_bignum_test.nr index f88c3ded..9f3bee0f 100644 --- a/src/runtime_bignum_test.nr +++ b/src/runtime_bignum_test.nr @@ -1,6 +1,6 @@ use crate::utils::u60_representation::U60Repr; use crate::runtime_bignum::RuntimeBigNum; -use crate::params::{ BigNumParams, BigNumParamsGetter }; +use crate::params::{BigNumParams, BigNumParamsGetter}; use crate::fields::bn254Fq::BN254_Fq_Params; use crate::fields::secp256k1Fq::Secp256k1_Fq_Params; @@ -410,7 +410,9 @@ fn test_div_BN() { #[test] fn test_invmod_BN() { let params = BN254_Fq_Params::get_params(); - unsafe { test_invmod(params) }; + unsafe { + test_invmod(params) + }; } // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril @@ -500,3 +502,25 @@ fn test_2048_bit_quadratic_expression() { RuntimeBigNum::evaluate_quadratic_expression(params, [[a_bn]], [[false]], [[b_bn]], [[false]], [c], [true]); } + +#[test] +fn test_sqrt_BN() { + let params = BN254_Fq_Params::get_params(); + + let x = RuntimeBigNum { limbs: [144, 0, 0], params }; + // let y = RuntimeBigNum { limbs: [143, 0, 0], params }; + + let maybe_sqrt_x = unsafe { x.__tonelli_shanks_sqrt() }; + // let maybe_sqrt_y = unsafe { y.__tonelli_shanks_sqrt() }; + + // println(f"maybe_sqrt_x: {maybe_sqrt_x}"); + // println(f"maybe_sqrt_y: {maybe_sqrt_y}"); + + // let sqrt_x = maybe_sqrt_x.unwrap(); + // println(f"sqrt_x: {sqrt_x}"); + + assert(x == x); + + // assert(maybe_sqrt_x.unwrap() == RuntimeBigNum { limbs: [12, 0, 0], params }); + // assert(maybe_sqrt_y.is_none()); +} \ No newline at end of file diff --git a/src/unconstrained_helpers.nr b/src/unconstrained_helpers.nr index fb9f29db..55d7c772 100644 --- a/src/unconstrained_helpers.nr +++ b/src/unconstrained_helpers.nr @@ -2,6 +2,8 @@ use crate::utils::u60_representation::U60Repr; use crate::utils::split_bits; use crate::params::BigNumParams as P; +use crate::unconstrained_ops::{ __one, __eq, __neg, __add, __mul, __pow }; + /** * In this file: @@ -255,153 +257,72 @@ unconstrained pub(crate) fn __barrett_reduction( (q, r) } +/** +* @brief compute the log of the size of the primitive root +* @details find the maximum value k where x^k = 1, where x = primitive root +* This is needed for our Tonelli-Shanks sqrt algorithm +**/ +unconstrained pub(crate) fn __primitive_root_log_size(params: P) -> u32 { + let mut target: U60Repr = params.modulus_u60 - U60Repr::one(); + let mut result: u32 = 0; + let modulus_bits_getter = params.modulus_bits_getter; + let modulus_bits = modulus_bits_getter(); + for _ in 0..modulus_bits { + let lsb_is_one = (target.limbs[0] & 1) == 1; + if (!lsb_is_one) { + result += 1; + target.shr1(); + } else { + break; + } + } + result +} + +/** +* @brief inner loop fn for `find_multiplive_generator` +* @details recursive function to get around the lack of a `while` keyword +**/ +unconstrained fn __recursively_find_multiplicative_generator( + params: P, + target: [Field; N], + p_minus_one_over_two: [Field; N] +) -> (bool, [Field; N]) { + let exped = __pow(params, target, p_minus_one_over_two); + let one: [Field; N] = __one(); + let neg_one = __neg(params, one); + let found = __eq(exped, neg_one); + let mut result: (bool, [Field; N]) = (found, target); + if (!found) { + let _target = unsafe { + __add(params, target, one) + }; + result = __recursively_find_multiplicative_generator(params, _target, p_minus_one_over_two); + } + result +} + +/** +* @brief find multiplicative generator `g` where `g` is the smallest value that is not a quadratic residue +* i.e. smallest g where g^2 = -1 +* @note WARNING if multiplicative generator does not exist, this function will enter an infinite loop! +**/ +unconstrained pub(crate) fn __multiplicative_generator(params: P) -> [Field; N] { + let mut target: [Field; N] = __one(); + let p_minus_one_over_two: U60Repr = (params.modulus_u60 - U60Repr::one()).shr(1); + let p_minus_one_over_two: [Field; N] = U60Repr::into(p_minus_one_over_two); + let (_, target) = __recursively_find_multiplicative_generator(params, target, p_minus_one_over_two); + target +} -// /** -// * @brief compute the log of the size of the primitive root -// * @details find the maximum value k where x^k = 1, where x = primitive root -// * This is needed for our Tonelli-Shanks sqrt algorithm -// **/ -// unconstrained fn primitive_root_log_size(self) -> u32 { -// let mut target: U60Repr = self.modulus_u60 - U60Repr::one(); -// let mut result: u32 = 0; -// for _ in 0..Params::modulus_bits() { -// let lsb_is_one = (target.limbs[0] & 1) == 1; -// if (!lsb_is_one) { -// result += 1; -// target.shr1(); -// } else { -// break; -// } -// } -// result -// } -// /** -// * @brief inner loop fn for `find_multiplive_generator` -// * @details recursive function to get around the lack of a `while` keyword -// **/ -// unconstrained fn recursively_find_multiplicative_generator( -// self, -// target: BigNum, -// p_minus_one_over_two: BigNum -// ) -> (bool, BigNum) { -// let exped = (self.__pow(target, p_minus_one_over_two)); -// let found = exped.__eq(self.__neg(BigNum::one())); -// let mut result: (bool, BigNum) = (found, target); -// if (!found) { -// let _target = unsafe { -// self.__add(target, BigNum::one()) -// }; -// result = self.recursively_find_multiplicative_generator(_target, p_minus_one_over_two); -// } -// result -// } -// /** -// * @brief find multiplicative generator `g` where `g` is the smallest value that is not a quadratic residue -// * i.e. smallest g where g^2 = -1 -// * @note WARNING if multiplicative generator does not exist, this function will enter an infinite loop! -// **/ -// unconstrained fn multiplicative_generator(self) -> BigNum { -// let mut target = BigNum::one(); -// let p_minus_one_over_two: U60Repr = (self.modulus_u60 - U60Repr::one()).shr(1); -// let p_minus_one_over_two: BigNum = BigNum::from_array(U60Repr::into(p_minus_one_over_two)); -// let (_, target) = self.recursively_find_multiplicative_generator(target, p_minus_one_over_two); -// target -// } -// unconstrained fn __tonelli_shanks_sqrt_inner_loop_check(self, t2m: BigNum, i: u32) -> u32 { -// let is_one = t2m.__eq(BigNum::one()); -// let mut result = i; -// if (!is_one) { -// let t2m = self.__mul(t2m, t2m); -// let i = i + 1; -// result = self.__tonelli_shanks_sqrt_inner_loop_check(t2m, i); -// } -// result -// } - -// /** -// * @brief compute a modular square root using the Tonelli-Shanks algorithm -// * @details only use for prime fields! Function may infinite loop if used for non-prime fields -// * @note this is unconstrained fn. To constrain a square root, validate that output^2 = self -// * TODO: create fn that constrains nonexistence of square root (i.e. find x where x^2 = -self) -// **/ -// unconstrained fn __tonelli_shanks_sqrt( -// self, -// input: BigNum -// ) -> std::option::Option> { -// // Tonelli-shanks algorithm begins by finding a field element Q and integer S, -// // such that (p - 1) = Q.2^{s} -// // We can compute the square root of a, by considering a^{(Q + 1) / 2} = R -// // Once we have found such an R, we have -// // R^{2} = a^{Q + 1} = a^{Q}a -// // If a^{Q} = 1, we have found our square root. -// // Otherwise, we have a^{Q} = t, where t is a 2^{s-1}'th root of unity. -// // This is because t^{2^{s-1}} = a^{Q.2^{s-1}}. -// // We know that (p - 1) = Q.w^{s}, therefore t^{2^{s-1}} = a^{(p - 1) / 2} -// // From Euler's criterion, if a is a quadratic residue, a^{(p - 1) / 2} = 1 -// // i.e. t^{2^{s-1}} = 1 -// // To proceed with computing our square root, we want to transform t into a smaller subgroup, -// // specifically, the (s-2)'th roots of unity. -// // We do this by finding some value b,such that -// // (t.b^2)^{2^{s-2}} = 1 and R' = R.b -// // Finding such a b is trivial, because from Euler's criterion, we know that, -// // for any quadratic non-residue z, z^{(p - 1) / 2} = -1 -// // i.e. z^{Q.2^{s-1}} = -1 -// // => z^Q is a 2^{s-1}'th root of -1 -// // => z^{Q^2} is a 2^{s-2}'th root of -1 -// // Since t^{2^{s-1}} = 1, we know that t^{2^{s - 2}} = -1 -// // => t.z^{Q^2} is a 2^{s - 2}'th root of unity. -// // We can iteratively transform t into ever smaller subgroups, until t = 1. -// // At each iteration, we need to find a new value for b, which we can obtain -// // by repeatedly squaring z^{Q} -// let one: U60Repr = unsafe { -// U60Repr::one() -// }; -// let primitive_root_log_size = self.primitive_root_log_size(); -// let mut Q = (self.modulus_u60 - one).shr(primitive_root_log_size - 1); -// let mut Q_minus_one_over_two = (Q - one).shr(2); -// let mut Q_minus_one_over_two = BigNum::from_array(U60Repr::into(Q_minus_one_over_two)); -// let mut z = self.multiplicative_generator(); // the generator is a non-residue -// let mut b = self.__pow(input, Q_minus_one_over_two); -// let mut r = self.__mul(input, b); -// let mut t = self.__mul(r, b); -// let mut check: BigNum = t; -// for _ in 0..primitive_root_log_size - 1 { -// check = self.__mul(check, check); -// } -// let mut found_root = false; -// if (check.__eq(BigNum::one()) == false) {} else { -// let mut t1 = self.__pow(z, Q_minus_one_over_two); -// let mut t2 = self.__mul(t1, z); -// let mut c = self.__mul(t2, t1); -// let mut m: u32 = primitive_root_log_size; -// // tonelli shanks inner 1 -// // (if t2m == 1) then skip -// // else increase i and square t2m and go again -// // algorithm runtime should only be max the number of bits in modulus -// let num_bits: u32 = Params::modulus_bits(); -// for _ in 0..num_bits { -// if (t.__eq(BigNum::one())) { -// found_root = true; -// break; -// } -// let mut t2m = t; -// // while loop time -// let i = self.__tonelli_shanks_sqrt_inner_loop_check(t2m, 0); -// let mut j = m - i - 1; -// b = c; -// for _ in 0..j { // how big -// if (j == 0) { -// break; -// } -// b = self.__mul(b, b); -// //j -= 1; -// } -// c = self.__mul(b, b); -// t = self.__mul(t, c); -// r = self.__mul(r, b); -// m = i; -// } -// } -// let mut result = std::option::Option { _value: r, _is_some: found_root }; -// result -// } +unconstrained pub(crate) fn __tonelli_shanks_sqrt_inner_loop_check(params: P, t2m: [Field; N], i: u32) -> u32 { + let one: [Field; N] = __one(); + let is_one = __eq(t2m, one); + let mut result = i; + if (!is_one) { + let t2m = __mul(params, t2m, t2m); + let i = i + 1; + result = __tonelli_shanks_sqrt_inner_loop_check(params, t2m, i); + } + result +} diff --git a/src/unconstrained_ops.nr b/src/unconstrained_ops.nr index 580d7399..7dafac61 100644 --- a/src/unconstrained_ops.nr +++ b/src/unconstrained_ops.nr @@ -2,7 +2,7 @@ use crate::utils::u60_representation::U60Repr; use crate::utils::split_bits; use crate::params::BigNumParams as P; -use crate::unconstrained_helpers::__barrett_reduction; +use crate::unconstrained_helpers::{__barrett_reduction, __primitive_root_log_size, __multiplicative_generator, __tonelli_shanks_sqrt_inner_loop_check}; /** * In this file: @@ -325,3 +325,94 @@ unconstrained pub(crate) fn __batch_invert_slice(params: P, x: [[ } result } + +/** +* @brief compute a modular square root using the Tonelli-Shanks algorithm +* @details only use for prime fields! Function may infinite loop if used for non-prime fields +* @note this is unconstrained fn. To constrain a square root, validate that output^2 = self +* TODO: create fn that constrains nonexistence of square root (i.e. find x where x^2 = -self) +**/ +unconstrained pub(crate) fn __tonelli_shanks_sqrt( + params: P, + input: [Field; N] +) -> std::option::Option<[Field; N]> { + // Tonelli-shanks algorithm begins by finding a field element Q and integer S, + // such that (p - 1) = Q.2^{s} + // We can compute the square root of a, by considering a^{(Q + 1) / 2} = R + // Once we have found such an R, we have + // R^{2} = a^{Q + 1} = a^{Q}a + // If a^{Q} = 1, we have found our square root. + // Otherwise, we have a^{Q} = t, where t is a 2^{s-1}'th root of unity. + // This is because t^{2^{s-1}} = a^{Q.2^{s-1}}. + // We know that (p - 1) = Q.w^{s}, therefore t^{2^{s-1}} = a^{(p - 1) / 2} + // From Euler's criterion, if a is a quadratic residue, a^{(p - 1) / 2} = 1 + // i.e. t^{2^{s-1}} = 1 + // To proceed with computing our square root, we want to transform t into a smaller subgroup, + // specifically, the (s-2)'th roots of unity. + // We do this by finding some value b,such that + // (t.b^2)^{2^{s-2}} = 1 and R' = R.b + // Finding such a b is trivial, because from Euler's criterion, we know that, + // for any quadratic non-residue z, z^{(p - 1) / 2} = -1 + // i.e. z^{Q.2^{s-1}} = -1 + // => z^Q is a 2^{s-1}'th root of -1 + // => z^{Q^2} is a 2^{s-2}'th root of -1 + // Since t^{2^{s-1}} = 1, we know that t^{2^{s - 2}} = -1 + // => t.z^{Q^2} is a 2^{s - 2}'th root of unity. + // We can iteratively transform t into ever smaller subgroups, until t = 1. + // At each iteration, we need to find a new value for b, which we can obtain + // by repeatedly squaring z^{Q} + let one_u60: U60Repr = unsafe { + U60Repr::one() + }; + let primitive_root_log_size = __primitive_root_log_size(params); + let mut Q = (params.modulus_u60 - one_u60).shr(primitive_root_log_size - 1); + let Q_minus_one_over_two_u60 = (Q - one_u60).shr(2); + let Q_minus_one_over_two: [Field; N] = U60Repr::into(Q_minus_one_over_two_u60); + let mut z = __multiplicative_generator(params); // the generator is a non-residue + let mut b = __pow(params, input, Q_minus_one_over_two); + let mut r = __mul(params, input, b); + let mut t = __mul(params, r, b); + let mut check: [Field; N] = t; + for _ in 0..primitive_root_log_size - 1 { + check = __mul(params, check, check); + } + let mut found_root = false; + let one: [Field; N] = __one::(); + if (__eq(check, one) == false) {} else { + let mut t1 = __pow(params, z, Q_minus_one_over_two); + let mut t2 = __mul(params, t1, z); + let mut c = __mul(params, t2, t1); + let mut m: u32 = primitive_root_log_size; + // tonelli shanks inner 1 + // (if t2m == 1) then skip + // else increase i and square t2m and go again + // algorithm runtime should only be max the number of bits in modulus + let modulus_bits_getter = params.modulus_bits_getter; + let modulus_bits = modulus_bits_getter(); + let num_bits: u32 = modulus_bits; + for _ in 0..num_bits { + if (__eq(t, one)) { + found_root = true; + break; + } + let mut t2m = t; + // while loop time + let i = __tonelli_shanks_sqrt_inner_loop_check(params, t2m, 0); + let mut j = m - i - 1; + b = c; + for _ in 0..j { // how big + if (j == 0) { + break; + } + b = __mul(params, b, b); + //j -= 1; + } + c = __mul(params, b, b); + t = __mul(params, t, c); + r = __mul(params, r, b); + m = i; + } + } + let mut result = std::option::Option { _value: r, _is_some: found_root }; + result +} From 33611026357627f3e11005120e14b3f271c1b8e2 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Mon, 21 Oct 2024 21:54:47 +0100 Subject: [PATCH 12/29] fix sqrt test --- src/bignum.nr | 7 +------ src/runtime_bignum.nr | 11 ++++++----- src/runtime_bignum_test.nr | 17 ++++------------- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index be4d59bd..f3d45d49 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -223,12 +223,7 @@ impl BigNumTrait for BigNum where Params: BigN let maybe_limbs = unsafe { __tonelli_shanks_sqrt(params, self.limbs) }; - let result: std::option::Option = if maybe_limbs.is_some() { - std::option::Option::some(Self { limbs: maybe_limbs.unwrap_unchecked() }) - } else { - std::option::Option::none() - }; - result + maybe_limbs.map(|limbs| Self { limbs }) } unconstrained fn __compute_quadratic_expression( diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index b3d4499e..cf0d283a 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -54,7 +54,7 @@ pub(crate) trait RuntimeBigNumTrait { fn __batch_invert(x: [Self; M]) -> [Self; M]; unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; - unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option; + unconstrained fn __tonelli_shanks_sqrt(self) -> (bool, Self); fn __compute_quadratic_expression( params: BigNumParams, @@ -270,15 +270,16 @@ impl RuntimeBigNumTrait for RuntimeBigNum { all_limbs.map(|limbs| Self { limbs, params }) } - unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option { + // @dev We intentionally don't use std::option::Option, because the Option::none() case doesn't propagate the `params`, so the code breaks. Specifically, the code stops evaluating modulus_bits = self.params.modulus_bits_getter() as constant, which then breaks calls to `validate_in_range()` (e.g. via calls to `==` on `self`), because `validate_in_range` calls `assert_max_bit_size` on a value derived from `modulus_bits`. I'm not sure why it stops evaluating the getter's return value as constant if we return a std::Option, really. + unconstrained fn __tonelli_shanks_sqrt(self) -> (bool, Self) { let params = self.params; let maybe_limbs = unsafe { __tonelli_shanks_sqrt(params, self.limbs) }; - let result: std::option::Option = if maybe_limbs.is_some() { - std::option::Option::some(Self { limbs: maybe_limbs.unwrap_unchecked(), params }) + let result: (bool, Self) = if maybe_limbs.is_some() { + (true, Self { limbs: maybe_limbs.unwrap_unchecked(), params }) } else { - std::option::Option::none() + (false, Self::new(params)) }; result } diff --git a/src/runtime_bignum_test.nr b/src/runtime_bignum_test.nr index 9f3bee0f..2ba36137 100644 --- a/src/runtime_bignum_test.nr +++ b/src/runtime_bignum_test.nr @@ -507,20 +507,11 @@ fn test_2048_bit_quadratic_expression() { fn test_sqrt_BN() { let params = BN254_Fq_Params::get_params(); - let x = RuntimeBigNum { limbs: [144, 0, 0], params }; - // let y = RuntimeBigNum { limbs: [143, 0, 0], params }; + let x = RuntimeBigNum { limbs: [9, 0, 0], params }; - let maybe_sqrt_x = unsafe { x.__tonelli_shanks_sqrt() }; - // let maybe_sqrt_y = unsafe { y.__tonelli_shanks_sqrt() }; + let (_, maybe_sqrt_x) = unsafe { x.__tonelli_shanks_sqrt() }; - // println(f"maybe_sqrt_x: {maybe_sqrt_x}"); - // println(f"maybe_sqrt_y: {maybe_sqrt_y}"); + assert(maybe_sqrt_x * maybe_sqrt_x == x); - // let sqrt_x = maybe_sqrt_x.unwrap(); - // println(f"sqrt_x: {sqrt_x}"); - - assert(x == x); - - // assert(maybe_sqrt_x.unwrap() == RuntimeBigNum { limbs: [12, 0, 0], params }); - // assert(maybe_sqrt_y.is_none()); + assert(x == x); // This was breaking for a while, because a previous version of RuntimeBigNum::__tonelli_shanks_sqrt() was returning an Option. My theory is that this meant Option:none() wasn't propagating the params anymore, which for some reason was causing the params of x to no-longer be evaluated as constant, which is strange. } \ No newline at end of file From d66161caca5591e89423a593b0b589b24694ebee Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Mon, 21 Oct 2024 22:03:48 +0100 Subject: [PATCH 13/29] fmt --- src/runtime_bignum_test.nr | 6 ++++-- src/unconstrained_helpers.nr | 3 +-- src/unconstrained_ops.nr | 16 ++++++++++------ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/runtime_bignum_test.nr b/src/runtime_bignum_test.nr index 2ba36137..2fe95757 100644 --- a/src/runtime_bignum_test.nr +++ b/src/runtime_bignum_test.nr @@ -509,9 +509,11 @@ fn test_sqrt_BN() { let x = RuntimeBigNum { limbs: [9, 0, 0], params }; - let (_, maybe_sqrt_x) = unsafe { x.__tonelli_shanks_sqrt() }; + let (_, maybe_sqrt_x) = unsafe { + x.__tonelli_shanks_sqrt() + }; assert(maybe_sqrt_x * maybe_sqrt_x == x); assert(x == x); // This was breaking for a while, because a previous version of RuntimeBigNum::__tonelli_shanks_sqrt() was returning an Option. My theory is that this meant Option:none() wasn't propagating the params anymore, which for some reason was causing the params of x to no-longer be evaluated as constant, which is strange. -} \ No newline at end of file +} diff --git a/src/unconstrained_helpers.nr b/src/unconstrained_helpers.nr index 55d7c772..4141c305 100644 --- a/src/unconstrained_helpers.nr +++ b/src/unconstrained_helpers.nr @@ -2,8 +2,7 @@ use crate::utils::u60_representation::U60Repr; use crate::utils::split_bits; use crate::params::BigNumParams as P; -use crate::unconstrained_ops::{ __one, __eq, __neg, __add, __mul, __pow }; - +use crate::unconstrained_ops::{__one, __eq, __neg, __add, __mul, __pow}; /** * In this file: diff --git a/src/unconstrained_ops.nr b/src/unconstrained_ops.nr index 7dafac61..3e1547c4 100644 --- a/src/unconstrained_ops.nr +++ b/src/unconstrained_ops.nr @@ -2,7 +2,10 @@ use crate::utils::u60_representation::U60Repr; use crate::utils::split_bits; use crate::params::BigNumParams as P; -use crate::unconstrained_helpers::{__barrett_reduction, __primitive_root_log_size, __multiplicative_generator, __tonelli_shanks_sqrt_inner_loop_check}; +use crate::unconstrained_helpers::{ + __barrett_reduction, __primitive_root_log_size, __multiplicative_generator, + __tonelli_shanks_sqrt_inner_loop_check +}; /** * In this file: @@ -158,7 +161,11 @@ unconstrained pub(crate) fn __add( * @brief given inputs `x, y` compute 2p + x - y (unconstrained) * @description see `__neg` for why we use 2p instead of p **/ -unconstrained pub(crate) fn __sub(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { +unconstrained pub(crate) fn __sub( + params: P, + lhs: [Field; N], + rhs: [Field; N] +) -> [Field; N] { __add(params, lhs, __neg(params, rhs)) } @@ -332,10 +339,7 @@ unconstrained pub(crate) fn __batch_invert_slice(params: P, x: [[ * @note this is unconstrained fn. To constrain a square root, validate that output^2 = self * TODO: create fn that constrains nonexistence of square root (i.e. find x where x^2 = -self) **/ -unconstrained pub(crate) fn __tonelli_shanks_sqrt( - params: P, - input: [Field; N] -) -> std::option::Option<[Field; N]> { +unconstrained pub(crate) fn __tonelli_shanks_sqrt(params: P, input: [Field; N]) -> std::option::Option<[Field; N]> { // Tonelli-shanks algorithm begins by finding a field element Q and integer S, // such that (p - 1) = Q.2^{s} // We can compute the square root of a, by considering a^{(Q + 1) / 2} = R From e5dbed07830affac0d3a78a2cd19b6469934e131 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Mon, 21 Oct 2024 22:06:57 +0100 Subject: [PATCH 14/29] fmt --- src/unconstrained_ops.nr | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/unconstrained_ops.nr b/src/unconstrained_ops.nr index 3e1547c4..85ad548c 100644 --- a/src/unconstrained_ops.nr +++ b/src/unconstrained_ops.nr @@ -161,11 +161,7 @@ unconstrained pub(crate) fn __add( * @brief given inputs `x, y` compute 2p + x - y (unconstrained) * @description see `__neg` for why we use 2p instead of p **/ -unconstrained pub(crate) fn __sub( - params: P, - lhs: [Field; N], - rhs: [Field; N] -) -> [Field; N] { +unconstrained pub(crate) fn __sub(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { __add(params, lhs, __neg(params, rhs)) } From 27309976a69a5376c84ed0781fae49c0e78f9b60 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Tue, 22 Oct 2024 16:41:18 +0100 Subject: [PATCH 15/29] riddle with MOD_BITS --- src/bignum.nr | 81 ++++++----- src/bignum_test.nr | 82 ++++++------ src/constrained_ops.nr | 65 +++++---- src/expressions.nr | 27 ++-- src/fields/U1024.nr | 8 +- src/fields/U2048.nr | 8 +- src/fields/U256.nr | 8 +- src/fields/U384.nr | 8 +- src/fields/U4096.nr | 8 +- src/fields/U512.nr | 8 +- src/fields/U768.nr | 8 +- src/fields/U8192.nr | 8 +- src/fields/bls12_377Fq.nr | 8 +- src/fields/bls12_377Fr.nr | 8 +- src/fields/bls12_381Fq.nr | 8 +- src/fields/bls12_381Fr.nr | 8 +- src/fields/bn254Fq.nr | 8 +- src/fields/ed25519Fq.nr | 8 +- src/fields/ed25519Fr.nr | 8 +- src/fields/mnt4_753Fq.nr | 8 +- src/fields/mnt4_753Fr.nr | 8 +- src/fields/mnt6_753Fq.nr | 8 +- src/fields/mnt6_753Fr.nr | 8 +- src/fields/mod.nr | 2 +- src/fields/pallasFq.nr | 8 +- src/fields/pallasFr.nr | 8 +- src/fields/secp256k1Fq.nr | 8 +- src/fields/secp256k1Fr.nr | 8 +- src/fields/secp256r1Fq.nr | 8 +- src/fields/secp256r1Fr.nr | 8 +- src/fields/secp384r1Fq.nr | 8 +- src/fields/secp384r1Fr.nr | 8 +- src/fields/vestaFq.nr | 8 +- src/fields/vestaFr.nr | 8 +- src/params.nr | 12 +- src/runtime_bignum.nr | 133 +++++++++--------- src/runtime_bignum_test.nr | 153 ++++++++++----------- src/serialization.nr | 18 +-- src/unconstrained_helpers.nr | 146 ++++++++++---------- src/unconstrained_ops.nr | 252 +++++++++++++++++------------------ 40 files changed, 594 insertions(+), 609 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index f3d45d49..09d14ea7 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -7,12 +7,12 @@ use crate::constrained_ops::{ }; use crate::unconstrained_ops::{ __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, - __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt + __batch_invert, __batch_invert_slice //, __tonelli_shanks_sqrt }; use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}; use crate::serialization::{from_be_bytes, to_le_bytes}; -pub struct BigNum { +pub struct BigNum { limbs: [Field; N] } @@ -51,7 +51,7 @@ pub(crate) trait BigNumTrait { unconstrained fn __batch_invert(to_invert: [Self; M]) -> [Self; M]; unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; - unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option; + // unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option; unconstrained fn __compute_quadratic_expression( lhs: [[Self; LHS_N]; NUM_PRODUCTS], @@ -88,7 +88,7 @@ pub(crate) trait BigNumTrait { fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; } -impl BigNumTrait for BigNum where Params: BigNumParamsGetter { +impl BigNumTrait for BigNum where Params: BigNumParamsGetter { fn new() -> Self { Self { limbs: [0; N] } @@ -102,12 +102,12 @@ impl BigNumTrait for BigNum where Params: BigN fn derive_from_seed(seed: [u8; SeedBytes]) -> Self { let params = Params::get_params(); - Self { limbs: derive_from_seed(params, seed) } + 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(params, seed) } + Self { limbs: __derive_from_seed::<_, MOD_BITS, _>(params, seed) } } fn from_slice(limbs: [Field]) -> Self { @@ -120,12 +120,12 @@ impl BigNumTrait for BigNum where Params: BigN fn from_be_bytes(x: [u8; NBytes]) -> Self { let params = Params::get_params(); - Self { limbs: from_be_bytes(params, x) } + Self { limbs: from_be_bytes::<_, MOD_BITS, _>(params, x) } } fn to_le_bytes(self) -> [u8; NBytes] { let params = Params::get_params(); - to_le_bytes(params, self.limbs) + to_le_bytes::<_, MOD_BITS, _>(params, self.limbs) } fn modulus() -> Self { @@ -133,8 +133,7 @@ impl BigNumTrait for BigNum where Params: BigN } fn modulus_bits() -> u32 { - let modulus_bits_getter = Params::get_params().modulus_bits_getter; - modulus_bits_getter() + MOD_BITS } fn num_limbs() -> u32 { @@ -182,12 +181,12 @@ impl BigNumTrait for BigNum where Params: BigN unconstrained fn __mul(self, other: Self) -> Self { let params = Params::get_params(); - Self::from_array(__mul(params, self.limbs, other.limbs)) + Self::from_array(__mul::<_, MOD_BITS>(params, self.limbs, other.limbs)) } unconstrained fn __div(self, divisor: Self) -> Self { let params = Params::get_params(); - Self::from_array(__div(params, self.limbs, divisor.limbs)) + Self::from_array(__div::<_, MOD_BITS>(params, self.limbs, divisor.limbs)) } unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self) { @@ -198,33 +197,33 @@ impl BigNumTrait for BigNum where Params: BigN unconstrained fn __invmod(self) -> Self { let params = Params::get_params(); assert(params.has_multiplicative_inverse); - Self { limbs: __invmod(params, self.limbs) } + Self { limbs: __invmod::<_, MOD_BITS>(params, self.limbs) } } unconstrained fn __pow(self, exponent: Self) -> Self { let params = Params::get_params(); - Self { limbs: __pow(params, self.limbs, exponent.limbs) } + 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(params, x.map(|bn| Self::get_limbs(bn))).map(|limbs| Self {limbs}) + __batch_invert::<_, MOD_BITS, _>(params, x.map(|bn| Self::get_limbs(bn))).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(params, x.map(|bn| Self::get_limbs(bn))).map(|limbs| Self { limbs }) + __batch_invert_slice::<_, MOD_BITS>(params, x.map(|bn| Self::get_limbs(bn))).map(|limbs| Self { limbs }) } - unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option { - let params = Params::get_params(); - let maybe_limbs = unsafe { - __tonelli_shanks_sqrt(params, self.limbs) - }; - maybe_limbs.map(|limbs| Self { limbs }) - } + // unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option { + // let params = Params::get_params(); + // let maybe_limbs = unsafe { + // __tonelli_shanks_sqrt(params, self.limbs) + // }; + // maybe_limbs.map(|limbs| Self { limbs }) + // } unconstrained fn __compute_quadratic_expression( lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], @@ -235,7 +234,7 @@ impl BigNumTrait for BigNum where Params: BigN linear_flags: [bool; ADD_N] ) -> (Self, Self) { let params = Params::get_params(); - let (q_limbs, r_limbs) = __compute_quadratic_expression( + let (q_limbs, r_limbs) = __compute_quadratic_expression::<_, MOD_BITS, _, _, _, _>( params, map(lhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), lhs_flags, @@ -256,7 +255,7 @@ impl BigNumTrait for BigNum where Params: BigN linear_flags: [bool; ADD_N] ) { let params = Params::get_params(); - evaluate_quadratic_expression( + evaluate_quadratic_expression::<_, MOD_BITS, _, _, _, _>( params, map(lhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), lhs_flags, @@ -269,12 +268,12 @@ impl BigNumTrait for BigNum where Params: BigN fn validate_in_field(self: Self) { let params = Params::get_params(); - validate_in_field(params, self.limbs); + validate_in_field::<_, MOD_BITS>(params, self.limbs); } fn validate_in_range(self) { let params = Params::get_params(); - validate_in_range(params, self.limbs); + validate_in_range::<_, MOD_BITS>(params, self.limbs); } fn assert_is_not_equal(self, other: Self) { @@ -284,23 +283,23 @@ impl BigNumTrait for BigNum where Params: BigN fn neg(self) -> Self { let params = Params::get_params(); - Self { limbs: neg(params, self.limbs) } + Self { limbs: neg::<_, MOD_BITS>(params, self.limbs) } } fn udiv_mod(self, divisor: Self) -> (Self, Self) { let params = Params::get_params(); - let (q, r) = udiv_mod(params, self.limbs, divisor.limbs); + 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(params, self.limbs, divisor.limbs) } + Self { limbs: udiv::<_, MOD_BITS>(params, self.limbs, divisor.limbs) } } fn umod(self, divisor: Self) -> Self { let params = Params::get_params(); - Self { limbs: umod(params, self.limbs, divisor.limbs) } + Self { limbs: umod::<_, MOD_BITS>(params, self.limbs, divisor.limbs) } } fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self { @@ -310,47 +309,47 @@ impl BigNumTrait for BigNum where Params: BigN // impl BigNumTrait for BigNum where Params: BigNumParamsGetter {} -impl std::ops::Add for BigNum where Params: BigNumParamsGetter { +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(params, self.limbs, other.limbs) } + Self { limbs: add::<_, MOD_BITS>(params, self.limbs, other.limbs) } } } -impl std::ops::Sub for BigNum where Params: BigNumParamsGetter { +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(params, self.limbs, other.limbs) } + Self { limbs: sub::<_, MOD_BITS>(params, self.limbs, other.limbs) } } } -impl std::ops::Mul for BigNum where Params: BigNumParamsGetter { +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(params, self.limbs, other.limbs) } + Self { limbs: mul::<_, MOD_BITS>(params, self.limbs, other.limbs) } } } -impl std::ops::Div for BigNum where Params: BigNumParamsGetter { +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(params, self.limbs, other.limbs) } + Self { limbs: div::<_, MOD_BITS>(params, self.limbs, other.limbs) } } } -impl std::cmp::Eq for BigNum where Params: BigNumParamsGetter { +impl std::cmp::Eq for BigNum where Params: BigNumParamsGetter { fn eq(self, other: Self) -> bool { let params = Params::get_params(); - eq(params, self.limbs, other.limbs) + eq::<_, MOD_BITS>(params, self.limbs, other.limbs) } } diff --git a/src/bignum_test.nr b/src/bignum_test.nr index 15243613..23931e04 100644 --- a/src/bignum_test.nr +++ b/src/bignum_test.nr @@ -18,9 +18,9 @@ fn silence_warning() { let _ = Test2048Params {}; } -global TEST_2048_PARAMS: BigNumParams<18> = BigNumParams { +global TEST_2048_PARAMS: BigNumParams<18, 2048> = BigNumParams { has_multiplicative_inverse: false, - modulus_bits_getter: || 2048, + // modulus_bits_getter: || 2048, modulus: [ 0xc0a197a5ae0fcdceb052c9732614fe, 0x656ae034423283422243918ab83be3, 0x6bf590da48a7c1070b7d5aabaac678, 0x0cce39f530238b606f24b296e2bda9, 0x01e1fef9bb9c1c3ead98f226f1bfa0, 0xad8c1c816e12e0ed1379055e373abf, 0xcebe80e474f753aa9d1461c435123d, 0xaee5a18ceedef88d115a8b93c167ad, 0x268ba83c4a65c4307427fc495d9e44, 0xdd2777926848667b7df79f342639d4, 0xf455074c96855ca0068668efe7da3d, 0x5ddba6b30bbc168bfb3a1225f27d65, 0x591fec484f36707524133bcd6f4258, 0x59641b756766aeebe66781dd01d062, 0x58bc5eaff4b165e142bf9e2480eebb, 0x667a3964f08e06df772ce64b229a72, 0x9c1fdb18907711bfe3e3c1cf918395, 0xb8 ], @@ -36,26 +36,29 @@ global TEST_2048_PARAMS: BigNumParams<18> = BigNumParams { ] }; -impl BigNumParamsGetter<18> for Test2048Params { - fn get_params() -> BigNumParams<18> { +impl BigNumParamsGetter<18, 2048> for Test2048Params { + fn get_params() -> BigNumParams<18, 2048> { TEST_2048_PARAMS } } -type Fq = BigNum<3, BN254_Fq_Params>; +type Fq = BigNum<3, 254, BN254_Fq_Params>; +type BN256 = BigNum<3, 257, U256Params>; +type BN381 = BigNum<4, 381, BLS12_381_Fq_Params>; +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: BigNum<4, BLS12_381_Fq_Params> = BigNum { + let X1: BN381 = BigNum { limbs: [ 0x55e83ff97a1aeffb3af00adb22c6bb, 0x8c4f9774b905a14e3a3f171bac586c, 0xa73197d7942695638c4fa9ac0fc368, 0x17f1d3 ] }; X1.validate_in_field(); - let mut (_, XX_mul_3): (BigNum<4, BLS12_381_Fq_Params>, BigNum<4, BLS12_381_Fq_Params> ) = unsafe { + let mut (_, XX_mul_3): (BN381, BN381) = unsafe { BigNum::__compute_quadratic_expression( [[X1, X1, X1]], [[false, false, false]], @@ -252,8 +255,8 @@ fn assert_is_not_equal_overloaded_fail() where BN: BigNumTrait = BigNum::new(); - test_eq::<3, BigNum<3, BN254_Fq_Params>>(); + // let stub: Fq = BigNum::new(); + test_eq::<3, Fq>(); } #[test] fn test_add_BN() { @@ -334,130 +337,131 @@ fn test_add_modulus_overflow() { #[test] fn test_mul_BN() { - test_mul::<3, BigNum<3, BN254_Fq_Params>>(); + test_mul::<3, Fq>(); } #[test] fn test_add_BN2() { - test_add::<3, BigNum<3, BN254_Fq_Params>>(); + test_add::<3, Fq>(); } #[test] fn test_div_BN() { - test_div::<3, BigNum<3, BN254_Fq_Params>>(); + test_div::<3, Fq>(); } #[test] fn test_invmod_BN() { - test_invmod::<3, BigNum<3, BN254_Fq_Params>>(); + test_invmod::<3, Fq>(); } #[test] fn test_assert_is_not_equal_BN() { - assert_is_not_equal::<3, BigNum<3, BN254_Fq_Params>>(); + assert_is_not_equal::<3, Fq>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_fail_BN() { - assert_is_not_equal_fail::<3, BigNum<3, BN254_Fq_Params>>(); + assert_is_not_equal_fail::<3, Fq>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_lhs_fail_BN() { - assert_is_not_equal_overloaded_lhs_fail::<3, BigNum<3, BN254_Fq_Params>>(); + assert_is_not_equal_overloaded_lhs_fail::<3, Fq>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_rhs_fail_BN() { - assert_is_not_equal_overloaded_rhs_fail::<3, BigNum<3, BN254_Fq_Params>>(); + assert_is_not_equal_overloaded_rhs_fail::<3, Fq>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_fail_BN() { - assert_is_not_equal_overloaded_fail::<3, BigNum<3, BN254_Fq_Params>>(); + assert_is_not_equal_overloaded_fail::<3, Fq>(); } #[test] fn test_eq_2048() { - test_eq::<18, BigNum<18, Test2048Params>>(); + test_eq::<18, BN2048>(); } #[test] fn test_mul_2048() { - test_mul::<18, BigNum<18, Test2048Params>>(); + test_mul::<18, BN2048>(); } #[test] fn test_add_2048() { - test_add::<18, BigNum<18, Test2048Params>>(); + test_add::<18, BN2048>(); } #[test] fn test_assert_is_not_equal_2048() { - assert_is_not_equal::<18, BigNum<18, Test2048Params>>(); + assert_is_not_equal::<18, BN2048>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_fail_2048() { - assert_is_not_equal_fail::<18, BigNum<18, Test2048Params>>(); + assert_is_not_equal_fail::<18, BN2048>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_lhs_fail_2048() { - assert_is_not_equal_overloaded_lhs_fail::<18, BigNum<18, Test2048Params>>(); + assert_is_not_equal_overloaded_lhs_fail::<18, BN2048>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_rhs_fail_2048() { - assert_is_not_equal_overloaded_rhs_fail::<18, BigNum<18, Test2048Params>>(); + assert_is_not_equal_overloaded_rhs_fail::<18, BN2048>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_fail_2048() { - assert_is_not_equal_overloaded_fail::<18, BigNum<18, Test2048Params>>(); + assert_is_not_equal_overloaded_fail::<18, BN2048>(); } #[test] fn test_eq_U256() { - test_eq::<3, BigNum<3, U256Params>>(); + test_eq::<3, BN256>(); } #[test] fn test_mul_U256() { - test_mul::<3, BigNum<3, U256Params>>(); + test_mul::<3, BN256>(); } #[test] fn test_add_U256() { - test_add::<3, BigNum<3, U256Params>>(); + test_add::<3, BN256>(); } #[test] fn test_assert_is_not_equal_U256() { - assert_is_not_equal::<3, BigNum<3, U256Params>>(); + assert_is_not_equal::<3, BN256>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_fail_U256() { - assert_is_not_equal_fail::<3, BigNum<3, U256Params>>(); + assert_is_not_equal_fail::<3, BN256>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_lhs_fail_U256() { - assert_is_not_equal_overloaded_lhs_fail::<3, BigNum<3, U256Params>>(); + assert_is_not_equal_overloaded_lhs_fail::<3, BN256>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_rhs_fail_U256() { - assert_is_not_equal_overloaded_rhs_fail::<3, BigNum<3, U256Params>>(); + assert_is_not_equal_overloaded_rhs_fail::<3, BN256>(); } #[test(should_fail_with = "asssert_is_not_equal fail")] fn test_assert_is_not_equal_overloaded_fail_U256() { - assert_is_not_equal_overloaded_fail::<3, BigNum<3, U256Params>>(); + assert_is_not_equal_overloaded_fail::<3, BN256>(); } -type U256 = BigNum<3, U256Params>; +type U256 = BN256; + #[test] fn test_udiv_mod_U256() { let a: U256 = unsafe { @@ -477,14 +481,14 @@ fn test_udiv_mod_U256() { // // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril // #[test] // fn test_div_2048() { -// let stub: BigNum<18, Test2048Params> = BigNum::new(); +// 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: BigNum<18, Test2048Params> = BigNum::new(); +// let stub: BN2048 = BigNum::new(); // test_invmod(stub); // } @@ -551,8 +555,8 @@ fn test_2048_bit_quadratic_expression() { 0x0000000000000000000000000000000000000000000000000000000000000058 ]; - let a_bn: BigNum<18, Test2048Params> = BigNum { limbs: a }; - let b_bn: BigNum<18, Test2048Params> = BigNum { limbs: b }; + let a_bn: BN2048 = BigNum { limbs: a }; + let b_bn: BN2048 = BigNum { limbs: b }; let c_bn = unsafe { a_bn.__mul(b_bn) }; diff --git a/src/constrained_ops.nr b/src/constrained_ops.nr index d2580413..98544eb2 100644 --- a/src/constrained_ops.nr +++ b/src/constrained_ops.nr @@ -34,7 +34,7 @@ use crate::expressions::evaluate_quadratic_expression; * We use a hash function that can be modelled as a random oracle * This function *should* produce an output that is a uniformly randomly distributed value modulo BigNum::modulus() **/ -pub(crate) fn derive_from_seed(params: P, seed: [u8; SeedBytes]) -> [Field; N] { +pub(crate) fn derive_from_seed(params: P, seed: [u8; SeedBytes]) -> [Field; N] { let mut rolling_seed: [u8; SeedBytes + 1] = [0; SeedBytes + 1]; for i in 0..SeedBytes { rolling_seed[i] = seed[i]; @@ -77,9 +77,7 @@ pub(crate) fn derive_from_seed(params: P, see } } - let modulus_bits_getter = params.modulus_bits_getter; - let modulus_bits = modulus_bits_getter(); - let num_bits = modulus_bits * 2; + let num_bits = MOD_BITS * 2; let num_bytes = num_bits / 8 + ((num_bits % 8) != 0) as u32; let bits_in_last_byte = num_bits as u8 % 8; @@ -156,7 +154,7 @@ pub(crate) fn conditional_select(lhs: [Field; N], rhs: [Field; N], p * However the probability of an honest Prover being unable to satisfy this check is tiny! * (todo: compute how tiny) **/ -pub(crate) fn assert_is_not_equal(params: P, lhs: [Field; N], rhs: [Field; N]) { +pub(crate) fn assert_is_not_equal(params: P, lhs: [Field; N], rhs: [Field; N]) { let mut l: Field = 0; let mut r: Field = 0; let mut modulus_mod_n: Field = 0; @@ -179,8 +177,8 @@ pub(crate) fn assert_is_not_equal(params: P, lhs: [Field; N], rhs assert(target != 0, "asssert_is_not_equal fail"); } -pub(crate) fn eq(params: P, lhs: [Field; N], rhs: [Field; N]) -> bool { - let diff = sub(params, lhs, rhs); +pub(crate) fn eq(params: P, lhs: [Field; N], rhs: [Field; N]) -> bool { + let diff = sub::<_, MOD_BITS>(params, lhs, rhs); // if self == other, possible values of `diff` will be `p` or `0` // (the subtract operator constrains diff to be < ceil(log(p))) // TODO: can do this more efficiently via witngen in unconstrained functions? @@ -193,7 +191,7 @@ pub(crate) fn eq(params: P, lhs: [Field; N], rhs: [Field; N]) -> is_equal_modulus | is_equal_zero } -pub(crate) fn validate_in_field(params: P, val: [Field; N]) { +pub(crate) fn validate_in_field(params: P, val: [Field; N]) { // N.B. need to combine with validate_in_range if `self` limbs have not been range constrained let mut p_minus_self: [Field; N] = [0; N]; let modulus: [Field; N] = params.modulus; @@ -211,19 +209,17 @@ pub(crate) fn validate_in_field(params: P, val: [Field; N]) { p_minus_self[N - 1] -= borrow_flags[N - 2] as Field; let mut compare = val; compare = p_minus_self; - validate_in_range(params, compare); + validate_in_range::<_, MOD_BITS>(params, compare); } /** * @brief Validate a BigNum instance is correctly range constrained to contain no more than Params::modulus_bits() **/ -pub(crate) fn validate_in_range(params: P, limbs: [Field; N]) { +pub(crate) fn validate_in_range(params: P, limbs: [Field; N]) { for i in 0..(N - 1) { limbs[i].assert_max_bit_size(120); } - let modulus_bits_getter = params.modulus_bits_getter; - let modulus_bits = modulus_bits_getter(); - let final_limb_bits = modulus_bits - ((N - 1) * 120); + let final_limb_bits = MOD_BITS - ((N - 1) * 120); limbs[N - 1].assert_max_bit_size(final_limb_bits as u32); } @@ -240,18 +236,17 @@ pub(crate) fn validate_in_range(params: P, limbs: [Field; N]) { * Note: doesn't this mean that final_limb_bits should be constrained to be 126 bits, not modulus_bits() - ((N - 1) * 120) + 6? * TODO: think about this more! we want the range constraint we apply to be as small as allowable as this is more efficient **/ -pub(crate) fn validate_quotient_in_range(params: P, limbs: [Field; N]) { +pub(crate) fn validate_quotient_in_range(params: P, limbs: [Field; N]) { for i in 0..(N) { limbs[i].assert_max_bit_size(120); } // Note: replace magic number 6 with definition - let modulus_bits_getter = params.modulus_bits_getter; - let final_limb_bits = modulus_bits_getter() - ((N - 1) * 120) + 6; + let final_limb_bits = MOD_BITS - ((N - 1) * 120) + 6; limbs[N - 1].assert_max_bit_size(final_limb_bits as u32); } // validate that lhs - rhs does not underflow i.e. lhs > rhs -pub(crate) fn validate_gt(params: P, lhs: [Field; N], rhs: [Field; N]) { +pub(crate) fn validate_gt(params: P, lhs: [Field; N], rhs: [Field; N]) { // so we do... p - x - r = 0 and there might be borrow flags // a - b = r @@ -260,7 +255,7 @@ pub(crate) fn validate_gt(params: P, lhs: [Field; N], rhs: [Field __validate_gt_remainder(lhs, rhs) }; - validate_in_range(params, result); + validate_in_range::<_, MOD_BITS>(params, result); let borrow_shift = 0x1000000000000000000000000000000; let carry_shift = 0x1000000000000000000000000000000; @@ -280,12 +275,12 @@ pub(crate) fn validate_gt(params: P, lhs: [Field; N], rhs: [Field assert(result_limb == 0); } -pub(crate) fn neg(params: P, val: [Field; N]) -> [Field; N] { +pub(crate) fn neg(params: P, val: [Field; N]) -> [Field; N] { // so we do... p - x - r = 0 and there might be borrow flags let (result, borrow_flags) = unsafe { __neg_with_flags(params, val) }; - validate_in_range(params, result); + validate_in_range::<_, MOD_BITS>(params, result); let modulus = params.modulus; let borrow_shift = 0x1000000000000000000000000000000; let result_limb = modulus[0] - val[0] - result[0] + (borrow_flags[0] as Field * borrow_shift); @@ -300,12 +295,12 @@ pub(crate) fn neg(params: P, val: [Field; N]) -> [Field; N] { result } -pub(crate) fn add(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { +pub(crate) fn add(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { // so we do... p - x - r = 0 and there might be borrow flags let (result, carry_flags, borrow_flags, overflow_modulus) = unsafe { __add_with_flags(params, lhs, rhs) }; - validate_in_range(params, result); + validate_in_range::<_, MOD_BITS>(params, result); let modulus = params.modulus; let borrow_shift = 0x1000000000000000000000000000000; let carry_shift = 0x1000000000000000000000000000000; @@ -329,7 +324,7 @@ pub(crate) fn add(params: P, lhs: [Field; N], rhs: [Field; N]) -> result } -pub(crate) fn sub(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { +pub(crate) fn sub(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { // so we do... p - x - r = 0 and there might be borrow flags // a - b = r @@ -337,7 +332,7 @@ pub(crate) fn sub(params: P, lhs: [Field; N], rhs: [Field; N]) -> let (result, carry_flags, borrow_flags, underflow) = unsafe { __sub_with_flags(params, lhs, rhs) }; - validate_in_range(params, result); + validate_in_range::<_, MOD_BITS>(params, result); let modulus = params.modulus; let borrow_shift = 0x1000000000000000000000000000000; let carry_shift = 0x1000000000000000000000000000000; @@ -365,21 +360,21 @@ pub(crate) fn sub(params: P, lhs: [Field; N], rhs: [Field; N]) -> // 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 -pub(crate) fn mul(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { +pub(crate) fn mul(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { let result = unsafe { - __mul(params, lhs, rhs) + __mul::<_, MOD_BITS>(params, lhs, rhs) }; evaluate_quadratic_expression(params, [[lhs]], [[false]], [[rhs]], [[false]], [result], [true]); result } // Note: this method is expensive! Witness computation is extremely expensive as it requires modular exponentiation -pub(crate) fn div(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { +pub(crate) fn div(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { assert( params.has_multiplicative_inverse, "BigNum has no multiplicative inverse. Use udiv for unsigned integer division" ); let result = unsafe { - __div(params, lhs, rhs) + __div::<_, MOD_BITS>(params, lhs, rhs) }; evaluate_quadratic_expression(params, [[result]], [[false]], [[rhs]], [[false]], [lhs], [true]); result @@ -392,8 +387,8 @@ pub(crate) fn div(params: P, lhs: [Field; N], rhs: [Field; N]) -> * 2. numerator % divisor = remainder * 3. divisor * quotient + remainder = numerator **/ -pub(crate) fn udiv_mod( - params: P, +pub(crate) fn udiv_mod( + params: P, numerator: [Field; N], divisor: [Field; N] ) -> ([Field; N], [Field; N]) { @@ -414,7 +409,7 @@ pub(crate) fn udiv_mod( ); // we need (remainder < divisor) // implies (divisor - remainder > 0) - validate_gt(params, divisor, remainder); + validate_gt::<_, MOD_BITS>(params, divisor, remainder); (quotient, remainder) } @@ -423,8 +418,8 @@ pub(crate) fn udiv_mod( * * i.e. return param is floor(numerator / divisor) **/ -pub(crate) fn udiv(params: P, numerator: [Field; N], divisor: [Field; N]) -> [Field; N] { - udiv_mod(params, numerator, divisor).0 +pub(crate) fn udiv(params: P, numerator: [Field; N], divisor: [Field; N]) -> [Field; N] { + udiv_mod::<_, MOD_BITS>(params, numerator, divisor).0 } /** @@ -432,7 +427,7 @@ pub(crate) fn udiv(params: P, numerator: [Field; N], divisor: [Fi * * i.e. 1. numerator % divisor = return value **/ -pub(crate) fn umod(params: P, numerator: [Field; N], divisor: [Field; N]) -> [Field; N] { - udiv_mod(params, numerator, divisor).1 +pub(crate) fn umod(params: P, numerator: [Field; N], divisor: [Field; N]) -> [Field; N] { + udiv_mod::<_, MOD_BITS>(params, numerator, divisor).1 } diff --git a/src/expressions.nr b/src/expressions.nr index e2821113..9bff9f3e 100644 --- a/src/expressions.nr +++ b/src/expressions.nr @@ -41,12 +41,13 @@ use crate::unconstrained_helpers::__barrett_reduction; **/ unconstrained fn __compute_quadratic_expression_with_borrow_flags< let N: u32, + let MOD_BITS: u32, let LHS_N: u32, let RHS_N: u32, let NUM_PRODUCTS: u32, let ADD_N: u32 >( - params: P, + params: P, lhs_terms: [[[Field; N]; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs_terms: [[[Field; N]; RHS_N]; NUM_PRODUCTS], @@ -69,11 +70,11 @@ unconstrained fn __compute_quadratic_expression_with_borrow_flags< let mut relation_result: [Field; 2 * N] = split_bits::__normalize_limbs(mulout_p, 2 * N); let modulus: [Field; N] = params.modulus; - let modulus_bits_getter = params.modulus_bits_getter; + let modulus_bits = MOD_BITS; let (quotient, remainder) = __barrett_reduction( relation_result, params.redc_param, - modulus_bits_getter(), + modulus_bits, modulus, params.modulus_u60_x4 ); @@ -124,8 +125,8 @@ unconstrained fn __compute_quadratic_expression_with_borrow_flags< // We know that, for a valid bignum element, the limbs in `x` will be <2^{120} // Therefore each of the limbs in `p` (except the most significant) will borrow 2^{120} from the more significant limb. // Finally, to ensure we do not underflow in the most significant limb, we use `2p` instead of `p` -unconstrained fn __add_linear_expression( - params: P, +unconstrained fn __add_linear_expression( + params: P, x: [[Field; N]; M], flags: [bool; M] ) -> ([Field; N]) { @@ -155,12 +156,13 @@ unconstrained fn __add_linear_expression( **/ unconstrained fn __compute_quadratic_expression_product< let N: u32, + let MOD_BITS: u32, let LHS_N: u32, let RHS_N: u32, let NUM_PRODUCTS: u32, let ADD_N: u32 >( - params: P, + params: P, lhs_terms: [[[Field; N]; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs_terms: [[[Field; N]; RHS_N]; NUM_PRODUCTS], @@ -199,12 +201,13 @@ unconstrained fn __compute_quadratic_expression_product< **/ unconstrained pub(crate) fn __compute_quadratic_expression< let N: u32, + let MOD_BITS: u32, let LHS_N: u32, let RHS_N: u32, let NUM_PRODUCTS: u32, let ADD_N: u32 >( - params: P, + params: P, lhs_terms: [[[Field; N]; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs_terms: [[[Field; N]; RHS_N]; NUM_PRODUCTS], @@ -227,8 +230,7 @@ unconstrained pub(crate) fn __compute_quadratic_expression< // size 4 // a[3] * b[3] = a[6] = 7 // TODO: ugly! Will fail if input slice is empty - let modulus_bits_getter = params.modulus_bits_getter; - let k = modulus_bits_getter(); + let k = MOD_BITS; let (quotient, remainder) = __barrett_reduction( relation_result, @@ -282,12 +284,13 @@ unconstrained pub(crate) fn __compute_quadratic_expression< **/ pub(crate) fn evaluate_quadratic_expression< let N: u32, + let MOD_BITS: u32, let LHS_N: u32, let RHS_N: u32, let NUM_PRODUCTS: u32, let ADD_N: u32 >( - params: P, + params: P, lhs_terms: [[[Field; N]; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs_terms: [[[Field; N]; RHS_N]; NUM_PRODUCTS], @@ -297,7 +300,7 @@ pub(crate) fn evaluate_quadratic_expression< ) { // use an unconstrained function to compute the value of the quotient let (quotient, _, borrow_flags): ([Field; N], [Field; N], [Field; 2 * N]) = unsafe { - __compute_quadratic_expression_with_borrow_flags( + __compute_quadratic_expression_with_borrow_flags::<_, MOD_BITS, _, _, _, _>( params, lhs_terms, lhs_flags, @@ -309,7 +312,7 @@ pub(crate) fn evaluate_quadratic_expression< }; // constrain the quotient to be in the range [0, ..., 2^{m} - 1], where `m` is log2(modulus) rounded up. // Additionally, validate quotient limbs are also in the range [0, ..., 2^{120} - 1] - validate_quotient_in_range(params, quotient); + validate_quotient_in_range::<_, MOD_BITS>(params, quotient); // TODO, validate we do not overflow N2 when multiplying and N when adding // (should be a compile-time check...unconstrained function?) diff --git a/src/fields/U1024.nr b/src/fields/U1024.nr index c5aef12d..95d48c08 100644 --- a/src/fields/U1024.nr +++ b/src/fields/U1024.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct U1024Params {} -impl BigNumParamsGetter<9> for U1024Params { - fn get_params() -> BigNumParams<9> { +impl BigNumParamsGetter<9, 1025> for U1024Params { + fn get_params() -> BigNumParams<9, 1025> { U1024_PARAMS } } -global U1024_PARAMS: BigNumParams<9> = BigNumParams { +global U1024_PARAMS: BigNumParams<9, 1025> = BigNumParams { has_multiplicative_inverse: false, - modulus_bits_getter: || 1025, + // modulus_bits_getter: || 1025, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000000000000000 ], diff --git a/src/fields/U2048.nr b/src/fields/U2048.nr index 8902b5de..a8bc6aae 100644 --- a/src/fields/U2048.nr +++ b/src/fields/U2048.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct U2048Params {} -impl BigNumParamsGetter<18> for U2048Params { - fn get_params() -> BigNumParams<18> { +impl BigNumParamsGetter<18, 2049> for U2048Params { + fn get_params() -> BigNumParams<18, 2049> { U2048_PARAMS } } -global U2048_PARAMS: BigNumParams<18> = BigNumParams { +global U2048_PARAMS: BigNumParams<18, 2049> = BigNumParams { has_multiplicative_inverse: false, - modulus_bits_getter: || 2049, + // modulus_bits_getter: || 2049, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100 ], diff --git a/src/fields/U256.nr b/src/fields/U256.nr index 65f71be3..3ebf219a 100644 --- a/src/fields/U256.nr +++ b/src/fields/U256.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct U256Params {} -impl BigNumParamsGetter<3> for U256Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 257> for U256Params { + fn get_params() -> BigNumParams<3, 257> { U256_PARAMS } } -global U256_PARAMS: BigNumParams<3> = BigNumParams { +global U256_PARAMS: BigNumParams<3, 257> = BigNumParams { has_multiplicative_inverse: false, - modulus_bits_getter: || 257, + // modulus_bits_getter: || 257, modulus: [ 0x00, 0x00, 0x010000 ], diff --git a/src/fields/U384.nr b/src/fields/U384.nr index c076695c..fc23929a 100644 --- a/src/fields/U384.nr +++ b/src/fields/U384.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct U384_Params {} -impl BigNumParamsGetter<4> for U384_Params { - fn get_params() -> BigNumParams<4> { +impl BigNumParamsGetter<4, 385> for U384_Params { + fn get_params() -> BigNumParams<4, 385> { U384_PARAMS } } -global U384_PARAMS: BigNumParams<4> = BigNumParams { +global U384_PARAMS: BigNumParams<4, 385> = BigNumParams { has_multiplicative_inverse: false, - modulus_bits_getter: || 385, + // modulus_bits_getter: || 385, modulus: [ 0x00, 0x00, 0x00, 0x01000000 ], diff --git a/src/fields/U4096.nr b/src/fields/U4096.nr index 06335a1d..6fe04000 100644 --- a/src/fields/U4096.nr +++ b/src/fields/U4096.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct U4096Params {} -impl BigNumParamsGetter<35> for U4096Params { - fn get_params() -> BigNumParams<35> { +impl BigNumParamsGetter<35, 4097> for U4096Params { + fn get_params() -> BigNumParams<35, 4097> { U4096_PARAMS } } -global U4096_PARAMS: BigNumParams<35> = BigNumParams { +global U4096_PARAMS: BigNumParams<35, 4097> = BigNumParams { has_multiplicative_inverse: false, - modulus_bits_getter: || 4097, + // modulus_bits_getter: || 4097, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000 ], diff --git a/src/fields/U512.nr b/src/fields/U512.nr index 2b91b00b..28d4d756 100644 --- a/src/fields/U512.nr +++ b/src/fields/U512.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct U512Params {} -impl BigNumParamsGetter<5> for U512Params { - fn get_params() -> BigNumParams<5> { +impl BigNumParamsGetter<5, 513> for U512Params { + fn get_params() -> BigNumParams<5, 513> { U512_PARAMS } } -global U512_PARAMS: BigNumParams<5> = BigNumParams { +global U512_PARAMS: BigNumParams<5, 513> = BigNumParams { has_multiplicative_inverse: false, - modulus_bits_getter: || 513, + // modulus_bits_getter: || 513, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x0100000000 ], diff --git a/src/fields/U768.nr b/src/fields/U768.nr index 8d8eee1e..8c6118f5 100644 --- a/src/fields/U768.nr +++ b/src/fields/U768.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct U768Params {} -impl BigNumParamsGetter<7> for U768Params { - fn get_params() -> BigNumParams<7> { +impl BigNumParamsGetter<7, 769> for U768Params { + fn get_params() -> BigNumParams<7, 769> { U768_PARAMS } } -global U768_PARAMS: BigNumParams<7> = BigNumParams { +global U768_PARAMS: BigNumParams<7, 769> = BigNumParams { has_multiplicative_inverse: false, - modulus_bits_getter: || 769, + // modulus_bits_getter: || 769, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000000000 ], diff --git a/src/fields/U8192.nr b/src/fields/U8192.nr index 91702ec3..92bccf56 100644 --- a/src/fields/U8192.nr +++ b/src/fields/U8192.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct U8192Params {} -impl BigNumParamsGetter<69> for U8192Params { - fn get_params() -> BigNumParams<69> { +impl BigNumParamsGetter<69, 8193> for U8192Params { + fn get_params() -> BigNumParams<69, 8193> { U8192_PARAMS } } -global U8192_PARAMS: BigNumParams<69> = BigNumParams { +global U8192_PARAMS: BigNumParams<69, 8193> = BigNumParams { has_multiplicative_inverse: false, - modulus_bits_getter: || 8193, + // modulus_bits_getter: || 8193, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000 ], diff --git a/src/fields/bls12_377Fq.nr b/src/fields/bls12_377Fq.nr index 4fb833ef..adc8a8ff 100644 --- a/src/fields/bls12_377Fq.nr +++ b/src/fields/bls12_377Fq.nr @@ -22,15 +22,15 @@ use crate::utils::u60_representation::U60Repr; pub struct BLS12_377_Fq_Params {} -impl BigNumParamsGetter<4> for BLS12_377_Fq_Params { - fn get_params() -> BigNumParams<4> { +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> = BigNumParams { +pub global BLS12_377_Fq_PARAMS: BigNumParams<4, 377> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 377, + // modulus_bits_getter: || 377, modulus: [ 0x0b5d44300000008508c00000000001, 0xd9f300f5138f1ef3622fba09480017, 0x4617c510eac63b05c06ca1493b1a22, 0x01ae3a ], diff --git a/src/fields/bls12_377Fr.nr b/src/fields/bls12_377Fr.nr index ac6bfd01..8ed2667b 100644 --- a/src/fields/bls12_377Fr.nr +++ b/src/fields/bls12_377Fr.nr @@ -23,15 +23,15 @@ use crate::utils::u60_representation::U60Repr; pub struct BLS12_377_Fr_Params {} -impl BigNumParamsGetter<3> for BLS12_377_Fr_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 253> for BLS12_377_Fr_Params { + fn get_params() -> BigNumParams<3, 253> { BLS12_377_Fr_PARAMS } } -global BLS12_377_Fr_PARAMS: BigNumParams<3> = BigNumParams { +global BLS12_377_Fr_PARAMS: BigNumParams<3, 253> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 253, + // modulus_bits_getter: || 253, modulus: [ 0xaa76fed00000010a11800000000001, 0x655e9a2ca55660b44d1e5c37b00159, 0x12ab ], diff --git a/src/fields/bls12_381Fq.nr b/src/fields/bls12_381Fq.nr index f4c0ef5a..3180dce8 100644 --- a/src/fields/bls12_381Fq.nr +++ b/src/fields/bls12_381Fq.nr @@ -20,15 +20,15 @@ use crate::utils::u60_representation::U60Repr; pub struct BLS12_381_Fq_Params {} -impl BigNumParamsGetter<4> for BLS12_381_Fq_Params { - fn get_params() -> BigNumParams<4> { +impl BigNumParamsGetter<4, 381> for BLS12_381_Fq_Params { + fn get_params() -> BigNumParams<4, 381> { BLS12_381_Fq_PARAMS } } -global BLS12_381_Fq_PARAMS: BigNumParams<4> = BigNumParams { +global BLS12_381_Fq_PARAMS: BigNumParams<4, 381> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 381, + // modulus_bits_getter: || 381, modulus: [ 0xabfffeb153ffffb9feffffffffaaab, 0x4b84f38512bf6730d2a0f6b0f6241e, 0xea397fe69a4b1ba7b6434bacd76477, 0x1a0111 ], diff --git a/src/fields/bls12_381Fr.nr b/src/fields/bls12_381Fr.nr index 831fab46..9643503d 100644 --- a/src/fields/bls12_381Fr.nr +++ b/src/fields/bls12_381Fr.nr @@ -20,15 +20,15 @@ use crate::utils::u60_representation::U60Repr; pub struct BLS12_381_Fr_Params {} -impl BigNumParamsGetter<3> for BLS12_381_Fr_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 255> for BLS12_381_Fr_Params { + fn get_params() -> BigNumParams<3, 255> { BLS12_381_Fr_PARAMS } } -global BLS12_381_Fr_PARAMS: BigNumParams<3> = BigNumParams { +global BLS12_381_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 255, + // modulus_bits_getter: || 255, modulus: [ 0xbda402fffe5bfeffffffff00000001, 0xa753299d7d483339d80809a1d80553, 0x73ed ], diff --git a/src/fields/bn254Fq.nr b/src/fields/bn254Fq.nr index fa54b0e2..0efc9852 100644 --- a/src/fields/bn254Fq.nr +++ b/src/fields/bn254Fq.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct BN254_Fq_Params {} -impl BigNumParamsGetter<3> for BN254_Fq_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 254> for BN254_Fq_Params { + fn get_params() -> BigNumParams<3, 254> { BN254_Fq_PARAMS } } -global BN254_Fq_PARAMS: BigNumParams<3> = BigNumParams { +global BN254_Fq_PARAMS: BigNumParams<3, 254> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 254, + // modulus_bits_getter: || 254, modulus: [ 0x816a916871ca8d3c208c16d87cfd47, 0x4e72e131a029b85045b68181585d97, 0x3064 ], diff --git a/src/fields/ed25519Fq.nr b/src/fields/ed25519Fq.nr index 254e288e..a5723341 100644 --- a/src/fields/ed25519Fq.nr +++ b/src/fields/ed25519Fq.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct ED25519_Fq_Params {} -impl BigNumParamsGetter<3> for ED25519_Fq_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 255> for ED25519_Fq_Params { + fn get_params() -> BigNumParams<3, 255> { ED25519_Fq_PARAMS } } -global ED25519_Fq_PARAMS: BigNumParams<3> = BigNumParams { +global ED25519_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 255, + // modulus_bits_getter: || 255, modulus: [ 0xffffffffffffffffffffffffffffed, 0xffffffffffffffffffffffffffffff, 0x7fff ], diff --git a/src/fields/ed25519Fr.nr b/src/fields/ed25519Fr.nr index 595c95be..fa4f42e5 100644 --- a/src/fields/ed25519Fr.nr +++ b/src/fields/ed25519Fr.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct ED25519_Fr_Params {} -impl BigNumParamsGetter<3> for ED25519_Fr_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 255> for ED25519_Fr_Params { + fn get_params() -> BigNumParams<3, 255> { ED25519_Fr_PARAMS } } -global ED25519_Fr_PARAMS: BigNumParams<3> = BigNumParams { +global ED25519_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 253, + // modulus_bits_getter: || 253, modulus: [ 0xdef9dea2f79cd65812631a5cf5d3ed, 0x14, 0x1000 ], diff --git a/src/fields/mnt4_753Fq.nr b/src/fields/mnt4_753Fq.nr index 076d0bc2..8f55df3a 100644 --- a/src/fields/mnt4_753Fq.nr +++ b/src/fields/mnt4_753Fq.nr @@ -25,15 +25,15 @@ use crate::utils::u60_representation::U60Repr; pub struct MNT4_753_Fq_Params {} -impl BigNumParamsGetter<7> for MNT4_753_Fq_Params { - fn get_params() -> BigNumParams<7> { +impl BigNumParamsGetter<7, 753> for MNT4_753_Fq_Params { + fn get_params() -> BigNumParams<7, 753> { MNT4_753_Fq_PARAMS } } -global MNT4_753_Fq_PARAMS: BigNumParams<7> = BigNumParams { +global MNT4_753_Fq_PARAMS: BigNumParams<7, 753> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 753, + // modulus_bits_getter: || 753, modulus: [ 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 ], diff --git a/src/fields/mnt4_753Fr.nr b/src/fields/mnt4_753Fr.nr index 10a3dfc3..05d50c05 100644 --- a/src/fields/mnt4_753Fr.nr +++ b/src/fields/mnt4_753Fr.nr @@ -25,15 +25,15 @@ use crate::utils::u60_representation::U60Repr; pub struct MNT4_753_Fr_Params {} -impl BigNumParamsGetter<7> for MNT4_753_Fr_Params { - fn get_params() -> BigNumParams<7> { +impl BigNumParamsGetter<7, 753> for MNT4_753_Fr_Params { + fn get_params() -> BigNumParams<7, 753> { MNT4_753_Fr_PARAMS } } -global MNT4_753_Fr_PARAMS: BigNumParams<7> = BigNumParams { +global MNT4_753_Fr_PARAMS: BigNumParams<7, 753> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 753, + // modulus_bits_getter: || 753, modulus: [ 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 ], diff --git a/src/fields/mnt6_753Fq.nr b/src/fields/mnt6_753Fq.nr index 80b9745a..031d2143 100644 --- a/src/fields/mnt6_753Fq.nr +++ b/src/fields/mnt6_753Fq.nr @@ -25,15 +25,15 @@ use crate::utils::u60_representation::U60Repr; pub struct MNT6_753_Fq_Params {} -impl BigNumParamsGetter<7> for MNT6_753_Fq_Params { - fn get_params() -> BigNumParams<7> { +impl BigNumParamsGetter<7, 753> for MNT6_753_Fq_Params { + fn get_params() -> BigNumParams<7, 753> { MNT6_753_Fq_PARAMS } } -global MNT6_753_Fq_PARAMS: BigNumParams<7> = BigNumParams { +global MNT6_753_Fq_PARAMS: BigNumParams<7, 753> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 753, + // modulus_bits_getter: || 753, modulus: [ 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 ], diff --git a/src/fields/mnt6_753Fr.nr b/src/fields/mnt6_753Fr.nr index 82ebd40c..5d20a489 100644 --- a/src/fields/mnt6_753Fr.nr +++ b/src/fields/mnt6_753Fr.nr @@ -25,15 +25,15 @@ use crate::utils::u60_representation::U60Repr; pub struct MNT6_753_Fr_Params {} -impl BigNumParamsGetter<7> for MNT6_753_Fr_Params { - fn get_params() -> BigNumParams<7> { +impl BigNumParamsGetter<7, 753> for MNT6_753_Fr_Params { + fn get_params() -> BigNumParams<7, 753> { MNT6_753_Fr_PARAMS } } -global MNT6_753_Fr_PARAMS: BigNumParams<7> = BigNumParams { +global MNT6_753_Fr_PARAMS: BigNumParams<7, 753> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 753, + // modulus_bits_getter: || 753, modulus: [ 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 ], diff --git a/src/fields/mod.nr b/src/fields/mod.nr index 14c73f80..ef20e94e 100644 --- a/src/fields/mod.nr +++ b/src/fields/mod.nr @@ -33,5 +33,5 @@ pub mod U8192; // use crate::bignum::BigNum; // use bn254Fq::BN254_Fq_Params; // -// type Fq = BigNum<3, BN254_Fq_Params>; +// type Fq = BigNum<3, 254, BN254_Fq_Params>; diff --git a/src/fields/pallasFq.nr b/src/fields/pallasFq.nr index e305c4fa..9faebe59 100644 --- a/src/fields/pallasFq.nr +++ b/src/fields/pallasFq.nr @@ -19,15 +19,15 @@ use crate::utils::u60_representation::U60Repr; pub struct Pallas_Fq_Params {} -impl BigNumParamsGetter<3> for Pallas_Fq_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 255> for Pallas_Fq_Params { + fn get_params() -> BigNumParams<3, 255> { Pallas_Fq_PARAMS } } -global Pallas_Fq_PARAMS: BigNumParams<3> = BigNumParams { +global Pallas_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 255, + // modulus_bits_getter: || 255, modulus: [ 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 ], diff --git a/src/fields/pallasFr.nr b/src/fields/pallasFr.nr index a865f93e..7f302af6 100644 --- a/src/fields/pallasFr.nr +++ b/src/fields/pallasFr.nr @@ -19,15 +19,15 @@ use crate::utils::u60_representation::U60Repr; pub struct Pallas_Fr_Params {} -impl BigNumParamsGetter<3> for Pallas_Fr_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 255> for Pallas_Fr_Params { + fn get_params() -> BigNumParams<3, 255> { Pallas_Fr_PARAMS } } -global Pallas_Fr_PARAMS: BigNumParams<3> = BigNumParams { +global Pallas_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 255, + // modulus_bits_getter: || 255, modulus: [ 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 ], diff --git a/src/fields/secp256k1Fq.nr b/src/fields/secp256k1Fq.nr index 84274f71..e2a93c09 100644 --- a/src/fields/secp256k1Fq.nr +++ b/src/fields/secp256k1Fq.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct Secp256k1_Fq_Params {} -impl BigNumParamsGetter<3> for Secp256k1_Fq_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 256> for Secp256k1_Fq_Params { + fn get_params() -> BigNumParams<3, 256> { Secp256k1_Fq_PARAMS } } -global Secp256k1_Fq_PARAMS: BigNumParams<3> = BigNumParams { +global Secp256k1_Fq_PARAMS: BigNumParams<3, 256> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 256, + // modulus_bits_getter: || 256, modulus: [ 0xfffffffffffffffffffffefffffc2f, 0xffffffffffffffffffffffffffffff, 0xffff ], diff --git a/src/fields/secp256k1Fr.nr b/src/fields/secp256k1Fr.nr index a8dcac44..224a6769 100644 --- a/src/fields/secp256k1Fr.nr +++ b/src/fields/secp256k1Fr.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct Secp256k1_Fr_Params {} -impl BigNumParamsGetter<3> for Secp256k1_Fr_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 256> for Secp256k1_Fr_Params { + fn get_params() -> BigNumParams<3, 256> { Secp256k1_Fr_PARAMS } } -global Secp256k1_Fr_PARAMS: BigNumParams<3> = BigNumParams { +global Secp256k1_Fr_PARAMS: BigNumParams<3, 256> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 256, + // modulus_bits_getter: || 256, modulus: [ 0xaedce6af48a03bbfd25e8cd0364141, 0xfffffffffffffffffffffffffffeba, 0xffff ], diff --git a/src/fields/secp256r1Fq.nr b/src/fields/secp256r1Fq.nr index 77c6808e..e02de4c4 100644 --- a/src/fields/secp256r1Fq.nr +++ b/src/fields/secp256r1Fq.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct Secp256r1_Fq_Params {} -impl BigNumParamsGetter<3> for Secp256r1_Fq_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 265> for Secp256r1_Fq_Params { + fn get_params() -> BigNumParams<3, 265> { Secp256r1_Fq_PARAMS } } -global Secp256r1_Fq_PARAMS: BigNumParams<3> = BigNumParams { +global Secp256r1_Fq_PARAMS: BigNumParams<3, 265> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 256, + // modulus_bits_getter: || 256, modulus: [ 0xffffffffffffffffffffffff, 0xffff00000001000000000000000000, 0xffff ], diff --git a/src/fields/secp256r1Fr.nr b/src/fields/secp256r1Fr.nr index 29d6d92a..058708b1 100644 --- a/src/fields/secp256r1Fr.nr +++ b/src/fields/secp256r1Fr.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct Secp256r1_Fr_Params {} -impl BigNumParamsGetter<3> for Secp256r1_Fr_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 256> for Secp256r1_Fr_Params { + fn get_params() -> BigNumParams<3, 256> { Secp256r1_Fr_PARAMS } } -global Secp256r1_Fr_PARAMS: BigNumParams<3> = BigNumParams { +global Secp256r1_Fr_PARAMS: BigNumParams<3, 256> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 256, + // modulus_bits_getter: || 256, modulus: [ 0xe6faada7179e84f3b9cac2fc632551, 0xffff00000000ffffffffffffffffbc, 0xffff ], diff --git a/src/fields/secp384r1Fq.nr b/src/fields/secp384r1Fq.nr index 3035c0e2..a0e61e10 100644 --- a/src/fields/secp384r1Fq.nr +++ b/src/fields/secp384r1Fq.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct Secp384r1_Fq_Params {} -impl BigNumParamsGetter<4> for Secp384r1_Fq_Params { - fn get_params() -> BigNumParams<4> { +impl BigNumParamsGetter<4, 384> for Secp384r1_Fq_Params { + fn get_params() -> BigNumParams<4, 384> { Secp384r1_Fq_PARAMS } } -global Secp384r1_Fq_PARAMS: BigNumParams<4> = BigNumParams { +global Secp384r1_Fq_PARAMS: BigNumParams<4, 384> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 384, + // modulus_bits_getter: || 384, modulus: [ 0xffffff0000000000000000ffffffff, 0xfffffffffffffffffffffffffffeff, 0xffffffffffffffffffffffffffffff, 0xffffff ], diff --git a/src/fields/secp384r1Fr.nr b/src/fields/secp384r1Fr.nr index 0d819a83..03488aef 100644 --- a/src/fields/secp384r1Fr.nr +++ b/src/fields/secp384r1Fr.nr @@ -4,15 +4,15 @@ use crate::utils::u60_representation::U60Repr; pub struct Secp384r1_Fr_Params {} -impl BigNumParamsGetter<4> for Secp384r1_Fr_Params { - fn get_params() -> BigNumParams<4> { +impl BigNumParamsGetter<4, 384> for Secp384r1_Fr_Params { + fn get_params() -> BigNumParams<4, 384> { Secp384r1_Fr_PARAMS } } -global Secp384r1_Fr_PARAMS: BigNumParams<4> = BigNumParams { +global Secp384r1_Fr_PARAMS: BigNumParams<4, 384> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 384, + // modulus_bits_getter: || 384, modulus: [ 0x1a0db248b0a77aecec196accc52973, 0xffffffffffffc7634d81f4372ddf58, 0xffffffffffffffffffffffffffffff, 0xffffff ], diff --git a/src/fields/vestaFq.nr b/src/fields/vestaFq.nr index cabcb87a..dcc03778 100644 --- a/src/fields/vestaFq.nr +++ b/src/fields/vestaFq.nr @@ -20,15 +20,15 @@ use crate::utils::u60_representation::U60Repr; pub struct Vesta_Fq_Params {} -impl BigNumParamsGetter<3> for Vesta_Fq_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 255> for Vesta_Fq_Params { + fn get_params() -> BigNumParams<3, 255> { Vesta_Fq_PARAMS } } -global Vesta_Fq_PARAMS: BigNumParams<3> = BigNumParams { +global Vesta_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 255, + // modulus_bits_getter: || 255, modulus: [ 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 ], diff --git a/src/fields/vestaFr.nr b/src/fields/vestaFr.nr index 25c45332..8c253de3 100644 --- a/src/fields/vestaFr.nr +++ b/src/fields/vestaFr.nr @@ -20,15 +20,15 @@ use crate::utils::u60_representation::U60Repr; pub struct Vesta_Fr_Params {} -impl BigNumParamsGetter<3> for Vesta_Fr_Params { - fn get_params() -> BigNumParams<3> { +impl BigNumParamsGetter<3, 255> for Vesta_Fr_Params { + fn get_params() -> BigNumParams<3, 255> { Vesta_Fr_PARAMS } } -global Vesta_Fr_PARAMS: BigNumParams<3> = BigNumParams { +global Vesta_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - modulus_bits_getter: || 255, + // modulus_bits_getter: || 255, modulus: [ 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 ], diff --git a/src/params.nr b/src/params.nr index 61c198b5..57b555ec 100644 --- a/src/params.nr +++ b/src/params.nr @@ -1,11 +1,11 @@ use crate::utils::u60_representation::U60Repr; -pub(crate) struct BigNumParams { +pub(crate) struct BigNumParams { has_multiplicative_inverse: bool, // @brief modulus_bits = log2(modulus) rounded up // This needs to be a comptime const, so that it can be used as an argument to std::field::assert_constant() - modulus_bits_getter: fn () -> u32, + // modulus_bits_getter: fn () -> u32, // @brief modulus: all BigNum operations are evaluated modulo this value modulus: [Field; N], @@ -22,20 +22,18 @@ pub(crate) struct BigNumParams { } // To be implemented by the user for any BigNum they define, or within the predefined BigNums in the `fields/` dir. -pub(crate) trait BigNumParamsGetter { - fn get_params() -> BigNumParams; +pub(crate) trait BigNumParamsGetter { + fn get_params() -> BigNumParams; } -impl BigNumParams { +impl BigNumParams { pub fn new( has_multiplicative_inverse: bool, - modulus_bits_getter: fn() -> u32, modulus: [Field; N], redc_param: [Field; N] ) -> Self { Self { has_multiplicative_inverse, - modulus_bits_getter, modulus, modulus_u60: U60Repr::from(modulus), modulus_u60_x4: U60Repr::from(modulus), diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index cf0d283a..482bb85e 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -8,26 +8,28 @@ use crate::constrained_ops::{ }; use crate::unconstrained_ops::{ __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, - __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt + __batch_invert, __batch_invert_slice //, __tonelli_shanks_sqrt }; use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}; use crate::serialization::{from_be_bytes, to_le_bytes}; -pub struct RuntimeBigNum { +pub struct RuntimeBigNum { limbs: [Field; N], - params: BigNumParams, + params: BigNumParams, } +impl RuntimeBigNum {} + // All functions prefixed `__` are unconstrained! // They're not actually decorated as `unconstrained` because to return the `params` (as part of Self) from an `unconstrained` fn would cause range constraints. Instead, each `__` fn wraps a call to an unconstrained fn, so that the already-range-constrained `params` can be inserted into Self after the unconstrained call. -pub(crate) trait RuntimeBigNumTrait { - fn new(params: BigNumParams) -> Self; - fn one(params: BigNumParams) -> Self; - fn derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; - fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; - fn from_slice(params: BigNumParams, limbs: [Field]) -> Self; - fn from_array(params: BigNumParams, limbs: [Field; N]) -> Self; - fn from_be_bytes(params: BigNumParams, x: [u8; NBytes]) -> Self; +pub(crate) trait RuntimeBigNumTrait { + fn new(params: BigNumParams) -> Self; + fn one(params: BigNumParams) -> Self; + fn derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; + fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; + fn from_slice(params: BigNumParams, limbs: [Field]) -> Self; + fn from_array(params: BigNumParams, limbs: [Field; N]) -> Self; + fn from_be_bytes(params: BigNumParams, x: [u8; NBytes]) -> Self; fn to_le_bytes(self) -> [u8; NBytes]; @@ -54,10 +56,10 @@ pub(crate) trait RuntimeBigNumTrait { fn __batch_invert(x: [Self; M]) -> [Self; M]; unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; - unconstrained fn __tonelli_shanks_sqrt(self) -> (bool, Self); + // unconstrained fn __tonelli_shanks_sqrt(self) -> (bool, Self); fn __compute_quadratic_expression( - params: BigNumParams, + params: BigNumParams, lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], @@ -67,7 +69,7 @@ pub(crate) trait RuntimeBigNumTrait { ) -> (Self, Self); fn evaluate_quadratic_expression( - params: BigNumParams, + params: BigNumParams, lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], @@ -94,48 +96,48 @@ pub(crate) trait RuntimeBigNumTrait { fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; } -impl RuntimeBigNumTrait for RuntimeBigNum { +impl RuntimeBigNumTrait for RuntimeBigNum { - fn new(params: BigNumParams) -> Self { + fn new(params: BigNumParams) -> Self { let limbs: [Field; N] = [0; N]; Self { limbs, params } } - fn one(params: BigNumParams) -> Self { + fn one(params: BigNumParams) -> Self { let mut result = RuntimeBigNum::new(params); result.limbs[0] = 1; result } - fn derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self { + fn derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self { let limbs = unsafe { - derive_from_seed(params, seed) + derive_from_seed::<_, MOD_BITS, _>(params, seed) }; Self { limbs, params } } // UNCONSTRAINED! (Hence `__` prefix). - fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self { + fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self { let limbs = unsafe { - __derive_from_seed(params, seed) + __derive_from_seed::<_, MOD_BITS, _>(params, seed) }; Self { limbs, params } } - fn from_slice(params: BigNumParams, limbs: [Field]) -> Self { + fn from_slice(params: BigNumParams, limbs: [Field]) -> Self { Self { limbs: limbs.as_array(), params } } - fn from_array(params: BigNumParams, limbs: [Field; N]) -> Self { + fn from_array(params: BigNumParams, limbs: [Field; N]) -> Self { Self { limbs, params } } - fn from_be_bytes(params: BigNumParams, x: [u8; NBytes]) -> Self { - Self { limbs: from_be_bytes(params, x), params } + fn from_be_bytes(params: BigNumParams, x: [u8; NBytes]) -> Self { + Self { limbs: from_be_bytes::<_, MOD_BITS, _>(params, x), params } } fn to_le_bytes(self) -> [u8; NBytes] { - to_le_bytes(self.params, self.limbs) + to_le_bytes::<_, MOD_BITS, _>(self.params, self.limbs) } fn modulus(self) -> Self { @@ -144,8 +146,7 @@ impl RuntimeBigNumTrait for RuntimeBigNum { } fn modulus_bits(self) -> u32 { - let getter = self.params.modulus_bits_getter; - getter() + MOD_BITS } fn num_limbs() -> u32 { @@ -207,7 +208,7 @@ impl RuntimeBigNumTrait for RuntimeBigNum { fn __mul(self, other: Self) -> Self { let params = self.params; let limbs = unsafe { - __mul(params, self.limbs, other.limbs) + __mul::<_, MOD_BITS>(params, self.limbs, other.limbs) }; Self { params, limbs } } @@ -216,7 +217,7 @@ impl RuntimeBigNumTrait for RuntimeBigNum { fn __div(self, divisor: Self) -> Self { let params = self.params; let limbs = unsafe { - __div(params, self.limbs, divisor.limbs) + __div::<_, MOD_BITS>(params, self.limbs, divisor.limbs) }; Self { params, limbs } } @@ -235,7 +236,7 @@ impl RuntimeBigNumTrait for RuntimeBigNum { let params = self.params; assert(params.has_multiplicative_inverse); let limbs = unsafe { - __invmod(params, self.limbs) + __invmod::<_, MOD_BITS>(params, self.limbs) }; Self { limbs, params } } @@ -244,7 +245,7 @@ impl RuntimeBigNumTrait for RuntimeBigNum { fn __pow(self, exponent: Self) -> Self { let params = self.params; let limbs = unsafe { - __pow(params, self.limbs, exponent.limbs) + __pow::<_, MOD_BITS>(params, self.limbs, exponent.limbs) }; Self { limbs, params } } @@ -254,7 +255,7 @@ impl RuntimeBigNumTrait for RuntimeBigNum { let params = x[0].params; assert(params.has_multiplicative_inverse); let all_limbs = unsafe { - __batch_invert(params, x.map(|bn| Self::get_limbs(bn))) + __batch_invert::<_, MOD_BITS, _>(params, x.map(|bn| Self::get_limbs(bn))) }; all_limbs.map(|limbs| Self { limbs, params }) } @@ -264,29 +265,29 @@ impl RuntimeBigNumTrait for RuntimeBigNum { let params = x[0].params; assert(params.has_multiplicative_inverse); let all_limbs = unsafe { - let inv_slice = __batch_invert_slice(params, x.map(|bn| Self::get_limbs(bn))); + let inv_slice = __batch_invert_slice::<_, MOD_BITS>(params, x.map(|bn| Self::get_limbs(bn))); inv_slice.as_array() }; all_limbs.map(|limbs| Self { limbs, params }) } // @dev We intentionally don't use std::option::Option, because the Option::none() case doesn't propagate the `params`, so the code breaks. Specifically, the code stops evaluating modulus_bits = self.params.modulus_bits_getter() as constant, which then breaks calls to `validate_in_range()` (e.g. via calls to `==` on `self`), because `validate_in_range` calls `assert_max_bit_size` on a value derived from `modulus_bits`. I'm not sure why it stops evaluating the getter's return value as constant if we return a std::Option, really. - unconstrained fn __tonelli_shanks_sqrt(self) -> (bool, Self) { - let params = self.params; - let maybe_limbs = unsafe { - __tonelli_shanks_sqrt(params, self.limbs) - }; - let result: (bool, Self) = if maybe_limbs.is_some() { - (true, Self { limbs: maybe_limbs.unwrap_unchecked(), params }) - } else { - (false, Self::new(params)) - }; - result - } + // unconstrained fn __tonelli_shanks_sqrt(self) -> (bool, Self) { + // let params = self.params; + // let maybe_limbs = unsafe { + // __tonelli_shanks_sqrt(params, self.limbs) + // }; + // let result: (bool, Self) = if maybe_limbs.is_some() { + // (true, Self { limbs: maybe_limbs.unwrap_unchecked(), params }) + // } else { + // (false, Self::new(params)) + // }; + // result + // } // UNCONSTRAINED! (Hence `__` prefix). fn __compute_quadratic_expression( - params: BigNumParams, + params: BigNumParams, lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], @@ -295,7 +296,7 @@ impl RuntimeBigNumTrait for RuntimeBigNum { linear_flags: [bool; ADD_N] ) -> (Self, Self) { let (q_limbs, r_limbs) = unsafe { - __compute_quadratic_expression( + __compute_quadratic_expression::<_, MOD_BITS, _, _, _, _>( params, map(lhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), lhs_flags, @@ -309,7 +310,7 @@ impl RuntimeBigNumTrait for RuntimeBigNum { } fn evaluate_quadratic_expression( - params: BigNumParams, + params: BigNumParams, lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], @@ -317,7 +318,7 @@ impl RuntimeBigNumTrait for RuntimeBigNum { linear_terms: [Self; ADD_N], linear_flags: [bool; ADD_N] ) { - evaluate_quadratic_expression( + evaluate_quadratic_expression::<_, MOD_BITS, _, _, _, _>( params, map(lhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), lhs_flags, @@ -330,12 +331,12 @@ impl RuntimeBigNumTrait for RuntimeBigNum { fn validate_in_field(self: Self) { let params = self.params; - validate_in_field(params, self.limbs); + validate_in_field::<_, MOD_BITS>(params, self.limbs); } fn validate_in_range(self) { let params = self.params; - validate_in_range(params, self.limbs); + validate_in_range::<_, MOD_BITS>(params, self.limbs); } fn assert_is_not_equal(self, other: Self) { @@ -345,23 +346,23 @@ impl RuntimeBigNumTrait for RuntimeBigNum { fn neg(self) -> Self { let params = self.params; - Self { limbs: neg(params, self.limbs), params } + Self { limbs: neg::<_, MOD_BITS>(params, self.limbs), params } } fn udiv_mod(self, divisor: Self) -> (Self, Self) { let params = self.params; - let (q, r) = udiv_mod(params, self.limbs, divisor.limbs); + let (q, r) = udiv_mod::<_, MOD_BITS>(params, self.limbs, divisor.limbs); (Self { limbs: q, params }, Self { limbs: r, params }) } fn udiv(self, divisor: Self) -> Self { let params = self.params; - Self { limbs: udiv(params, self.limbs, divisor.limbs), params } + Self { limbs: udiv::<_, MOD_BITS>(params, self.limbs, divisor.limbs), params } } fn umod(self, divisor: Self) -> Self { let params = self.params; - Self { limbs: umod(params, self.limbs, divisor.limbs), params } + Self { limbs: umod::<_, MOD_BITS>(params, self.limbs, divisor.limbs), params } } fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self { @@ -370,46 +371,46 @@ impl RuntimeBigNumTrait for RuntimeBigNum { } } -impl std::ops::Add for RuntimeBigNum { +impl std::ops::Add for RuntimeBigNum { // 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 = self.params; - Self { limbs: add(params, self.limbs, other.limbs), params } + Self { limbs: add::<_, MOD_BITS>(params, self.limbs, other.limbs), params } } } -impl std::ops::Sub for RuntimeBigNum { +impl std::ops::Sub for RuntimeBigNum { // 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 = self.params; - Self { limbs: sub(params, self.limbs, other.limbs), params } + Self { limbs: sub::<_, MOD_BITS>(params, self.limbs, other.limbs), params } } } -impl std::ops::Mul for RuntimeBigNum { +impl std::ops::Mul for RuntimeBigNum { // 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 = self.params; - Self { limbs: mul(params, self.limbs, other.limbs), params } + Self { limbs: mul::<_, MOD_BITS>(params, self.limbs, other.limbs), params } } } -impl std::ops::Div for RuntimeBigNum { +impl std::ops::Div for RuntimeBigNum { // Note: this method is expensive! Witness computation is extremely expensive as it requires modular exponentiation fn div(self, divisor: Self) -> Self { let params = self.params; - Self { limbs: div(params, self.limbs, divisor.limbs), params } + Self { limbs: div::<_, MOD_BITS>(params, self.limbs, divisor.limbs), params } } } -impl std::cmp::Eq for RuntimeBigNum { +impl std::cmp::Eq for RuntimeBigNum { fn eq(self, other: Self) -> bool { let params = self.params; - eq(params, self.limbs, other.limbs) + eq::<_, MOD_BITS>(params, self.limbs, other.limbs) } } diff --git a/src/runtime_bignum_test.nr b/src/runtime_bignum_test.nr index 2fe95757..d819de24 100644 --- a/src/runtime_bignum_test.nr +++ b/src/runtime_bignum_test.nr @@ -9,9 +9,9 @@ use crate::fields::bls12_381Fr::BLS12_381_Fr_Params; use crate::fields::bls12_377Fq::BLS12_377_Fq_Params; use crate::fields::bls12_377Fr::BLS12_377_Fr_Params; -global TEST_2048_PARAMS: BigNumParams<18> = BigNumParams { +global TEST_2048_PARAMS: BigNumParams<18, 2048> = BigNumParams { has_multiplicative_inverse: false, - modulus_bits_getter: || 2048, + // modulus_bits_getter: || 2048, modulus: [ 0xc0a197a5ae0fcdceb052c9732614fe, 0x656ae034423283422243918ab83be3, 0x6bf590da48a7c1070b7d5aabaac678, 0x0cce39f530238b606f24b296e2bda9, 0x01e1fef9bb9c1c3ead98f226f1bfa0, 0xad8c1c816e12e0ed1379055e373abf, 0xcebe80e474f753aa9d1461c435123d, 0xaee5a18ceedef88d115a8b93c167ad, 0x268ba83c4a65c4307427fc495d9e44, 0xdd2777926848667b7df79f342639d4, 0xf455074c96855ca0068668efe7da3d, 0x5ddba6b30bbc168bfb3a1225f27d65, 0x591fec484f36707524133bcd6f4258, 0x59641b756766aeebe66781dd01d062, 0x58bc5eaff4b165e142bf9e2480eebb, 0x667a3964f08e06df772ce64b229a72, 0x9c1fdb18907711bfe3e3c1cf918395, 0xb8 ], @@ -35,8 +35,8 @@ fn silence_warning() { let _ = Test2048Params {}; } -impl BigNumParamsGetter<18> for Test2048Params { - fn get_params() -> BigNumParams<18> { +impl BigNumParamsGetter<18, 2048> for Test2048Params { + fn get_params() -> BigNumParams<18, 2048> { TEST_2048_PARAMS } } @@ -44,7 +44,7 @@ impl BigNumParamsGetter<18> for Test2048Params { /** * @brief experimenting with macro madness and code generation to make some tests that apply to multiple BigNum parametrisations! **/ -comptime fn make_test(f: StructDefinition, N: Quoted, typ: Quoted) -> Quoted { +comptime fn make_test(f: StructDefinition, N: Quoted, MOD_BITS: Quoted, typ: Quoted) -> Quoted { let k = f.name(); quote{ impl $k { @@ -52,10 +52,10 @@ impl $k { fn test_add() { let params = $typ ::get_params(); - let a = unsafe{ RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; - let b = unsafe{ RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) }; + let a: RuntimeBigNum<$N, $MOD_BITS> = unsafe{ RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; + let b: RuntimeBigNum<$N, $MOD_BITS> = unsafe{ RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) }; - let one: RuntimeBigNum<$N> = RuntimeBigNum::one(params); + let one: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum::one(params); a.validate_in_range(); a.validate_in_field(); @@ -79,9 +79,10 @@ fn test_sub() { let params = $typ ::get_params(); // 0 - 1 should equal p - 1 - let mut a: RuntimeBigNum<$N> = RuntimeBigNum::new(params); - let mut b: RuntimeBigNum<$N> = RuntimeBigNum::one(params); - let mut expected = RuntimeBigNum { limbs: params.modulus, params }; + let mut a: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum::new(params); + let mut b: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum::one(params); + let mut expected: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: params.modulus, params }; + expected.limbs[0] -= 1; // p - 1 let result = a - b; @@ -95,9 +96,9 @@ fn test_sub_modulus_limit() { // if we underflow, maximum result should be ... // 0 - 1 = o-1 // 0 - p = 0 - let mut a: RuntimeBigNum<$N> = RuntimeBigNum::new(params); - let mut b = RuntimeBigNum { limbs: params.modulus, params }; - let mut expected: RuntimeBigNum<$N> = RuntimeBigNum::new(params); + let mut a: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum::new(params); + let mut b: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: params.modulus, params }; + let mut expected: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum::new(params); let result = a - b; assert(result == expected); @@ -109,10 +110,10 @@ fn test_sub_modulus_underflow() { let params = $typ ::get_params(); // 0 - (p + 1) is smaller than p and should produce unsatisfiable constraints - let mut a: RuntimeBigNum<$N> = RuntimeBigNum::new(params); - let mut b = RuntimeBigNum { limbs: params.modulus, params }; + let mut a: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum::new(params); + let mut b: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: params.modulus, params }; b.limbs[0] += 1; - let mut expected: RuntimeBigNum<$N> = RuntimeBigNum::one(params); + let mut expected: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum::one(params); let result = a - b; @@ -129,11 +130,11 @@ fn test_add_modulus_limit() { let p: U60Repr<$N, 2> = U60Repr::from(params.modulus); let one = unsafe{ U60Repr::one() }; - let a = RuntimeBigNum { limbs: U60Repr::into(p), params }; + let a: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(p), params }; let two_pow_modulus_bits_minus_one: U60Repr<$N, 2> = unsafe{ one.shl(a.modulus_bits()) - one }; - let b = RuntimeBigNum { limbs: U60Repr::into(two_pow_modulus_bits_minus_one), params }; + let b: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(two_pow_modulus_bits_minus_one), params }; let result = a + b; assert(result == b); @@ -146,11 +147,11 @@ fn test_add_modulus_overflow() { let p : U60Repr<$N, 2> = U60Repr::from(params.modulus); let one = unsafe{ U60Repr::one() }; - let a = RuntimeBigNum { limbs: U60Repr::into(p + one), params }; + let a: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(p + one), params }; let mut two_pow_modulus_bits_minus_one: U60Repr<$N, 2> = unsafe{ one.shl(a.modulus_bits()) - one }; - let b = RuntimeBigNum { limbs: U60Repr::into(two_pow_modulus_bits_minus_one), params }; + let b: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(two_pow_modulus_bits_minus_one), params }; let result = a + b; assert(result == b); @@ -160,10 +161,10 @@ fn test_add_modulus_overflow() { fn test_mul() { let params = $typ ::get_params(); - let a = unsafe { + let a: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; - let b = unsafe { + let b: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) }; @@ -177,12 +178,12 @@ fn test_quadratic_expression() { let params = $typ ::get_params(); for i in 0..32 { - let X1 = unsafe{ RuntimeBigNum::__derive_from_seed(params, [i as u8, 2, 3, 4]) }; - let Y1 = unsafe{ RuntimeBigNum::__derive_from_seed(params, [i as u8, i as u8, 6, 7]) }; - let Z1: RuntimeBigNum<$N> = RuntimeBigNum::one(params); + let X1: RuntimeBigNum<$N, $MOD_BITS> = unsafe{ RuntimeBigNum::__derive_from_seed(params, [i as u8, 2, 3, 4]) }; + let Y1: RuntimeBigNum<$N, $MOD_BITS> = unsafe{ RuntimeBigNum::__derive_from_seed(params, [i as u8, i as u8, 6, 7]) }; + let Z1: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum::one(params); - let (_, YY_mul_2) = unsafe{ RuntimeBigNum::__compute_quadratic_expression(params, [[Y1]], [[false]], [[Y1, Y1]], [[false, false]], [], []) }; - let mut (_, XX_mul_3) = unsafe{ RuntimeBigNum::__compute_quadratic_expression( + let (_, YY_mul_2): (RuntimeBigNum<$N, $MOD_BITS>, RuntimeBigNum<$N, $MOD_BITS>) = unsafe{ RuntimeBigNum::__compute_quadratic_expression(params, [[Y1]], [[false]], [[Y1, Y1]], [[false, false]], [], []) }; + let mut (_, XX_mul_3): (RuntimeBigNum<$N, $MOD_BITS>, RuntimeBigNum<$N, $MOD_BITS>) = unsafe{ RuntimeBigNum::__compute_quadratic_expression( params, [[X1]], [[false]], @@ -191,7 +192,7 @@ fn test_quadratic_expression() { [], [] ) }; - let (_, D) = unsafe{ RuntimeBigNum::__compute_quadratic_expression(params, [[X1, X1]], [[false, false]], [[YY_mul_2]], [[false]], [], []) }; + let (_, D): (RuntimeBigNum<$N, $MOD_BITS>, RuntimeBigNum<$N, $MOD_BITS>) = unsafe{ RuntimeBigNum::__compute_quadratic_expression(params, [[X1, X1]], [[false, false]], [[YY_mul_2]], [[false]], [], []) }; let mut (_, X3) = unsafe{ RuntimeBigNum::__compute_quadratic_expression( params, [[XX_mul_3]], @@ -201,7 +202,7 @@ fn test_quadratic_expression() { [D, D], [true, true] ) }; - let (_, Y3) = unsafe{ RuntimeBigNum::__compute_quadratic_expression( + let (_, Y3): (RuntimeBigNum<$N, $MOD_BITS>, RuntimeBigNum<$N, $MOD_BITS>) = unsafe{ RuntimeBigNum::__compute_quadratic_expression( params, [[XX_mul_3], [YY_mul_2]], [[false], [true]], @@ -212,7 +213,7 @@ fn test_quadratic_expression() { ) }; // 3XX * (D - X3) - 8YYYY - let (_, Z3) = unsafe{ RuntimeBigNum::__compute_quadratic_expression(params, [[Y1]], [[false]], [[Z1, Z1]], [[false, false]], [], []) }; + let (_, Z3): (RuntimeBigNum<$N, $MOD_BITS>, RuntimeBigNum<$N, $MOD_BITS>) = unsafe{ RuntimeBigNum::__compute_quadratic_expression(params, [[Y1]], [[false]], [[Z1, Z1]], [[false, false]], [], []) }; X3.validate_in_field(); Y3.validate_in_field(); @@ -224,10 +225,10 @@ fn test_quadratic_expression() { fn assert_is_not_equal() { let params = $typ ::get_params(); - let a = unsafe { + let a: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; - let b = unsafe { + let b: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) }; @@ -238,10 +239,10 @@ fn assert_is_not_equal() { fn assert_is_not_equal_fail() { let params = $typ ::get_params(); - let a = unsafe { + let a: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; - let b = unsafe { + let b: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; @@ -252,10 +253,10 @@ fn assert_is_not_equal_fail() { fn assert_is_not_equal_overloaded_lhs_fail() { let params = $typ ::get_params(); - let a = unsafe { + let a: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; - let b = unsafe { + let b: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; @@ -263,7 +264,7 @@ fn assert_is_not_equal_overloaded_lhs_fail() { let t0: U60Repr<$N, 2> = U60Repr::from(a.limbs); let t1: U60Repr<$N, 2> = U60Repr::from(modulus); - let a_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; + let a_plus_modulus: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; a_plus_modulus.assert_is_not_equal(b); } @@ -272,10 +273,10 @@ fn assert_is_not_equal_overloaded_lhs_fail() { fn assert_is_not_equal_overloaded_rhs_fail() { let params = $typ ::get_params(); - let a = unsafe { + let a: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; - let b = unsafe { + let b: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; @@ -283,7 +284,7 @@ fn assert_is_not_equal_overloaded_rhs_fail() { let t0: U60Repr<$N, 2> = U60Repr::from(b.limbs); let t1: U60Repr<$N, 2> = U60Repr::from(modulus); - let b_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; + let b_plus_modulus: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; a.assert_is_not_equal(b_plus_modulus); } @@ -292,10 +293,10 @@ fn assert_is_not_equal_overloaded_rhs_fail() { fn assert_is_not_equal_overloaded_fail() { let params = $typ ::get_params(); - let a = unsafe { + let a: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; - let b = unsafe { + let b: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; @@ -305,8 +306,8 @@ fn assert_is_not_equal_overloaded_fail() { let t1: U60Repr<$N, 2> = U60Repr::from(b.limbs); let t2: U60Repr<$N, 2> = U60Repr::from(modulus); - let a_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t2), params }; - let b_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t1 + t2), params }; + let a_plus_modulus: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(t0 + t2), params }; + let b_plus_modulus: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(t1 + t2), params }; a_plus_modulus.assert_is_not_equal(b_plus_modulus); } @@ -316,8 +317,8 @@ fn test_derive() { let params = $typ ::get_params(); - let a = RuntimeBigNum::derive_from_seed(params, "hello".as_bytes()); - let b = unsafe { + let a: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum::derive_from_seed(params, "hello".as_bytes()); + let b: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, "hello".as_bytes()) }; assert(a == b); @@ -327,13 +328,13 @@ fn test_derive() fn test_eq() { let params = $typ ::get_params(); - let a = unsafe { + let a: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; - let b = unsafe { + let b: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; - let c = unsafe { + let c: RuntimeBigNum<$N, $MOD_BITS> = unsafe { RuntimeBigNum::__derive_from_seed(params, [2, 2, 3, 4]) }; @@ -342,7 +343,7 @@ fn test_eq() { let t0: U60Repr<$N, 2> = (U60Repr::from(modulus.limbs)); let t1: U60Repr<$N, 2> = (U60Repr::from(b.limbs)); - let b_plus_modulus = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; + let b_plus_modulus: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(t0 + t1), params }; assert((a == b) == true); assert((a == b_plus_modulus) == true); @@ -354,36 +355,36 @@ fn test_eq() { } } -#[make_test(quote{3},quote{BN254_Fq_Params})] +#[make_test(quote{3}, quote{254}, quote{BN254_Fq_Params})] pub struct BNTests{} -#[make_test(quote{3},quote{Secp256k1_Fq_Params})] +#[make_test(quote{3}, quote{256}, quote{Secp256k1_Fq_Params})] pub struct Secp256K1FqTests{} -#[make_test(quote{4},quote{BLS12_381_Fq_Params})] +#[make_test(quote{4}, quote{381} ,quote{BLS12_381_Fq_Params})] pub struct BLS12_381FqTests{} -#[make_test(quote{18},quote{Test2048Params})] +#[make_test(quote{18}, quote{2048}, quote{Test2048Params})] pub struct Test2048Tests{} -#[make_test(quote{3},quote{BLS12_381_Fr_Params})] +#[make_test(quote{3}, quote{255}, quote{BLS12_381_Fr_Params})] pub struct BLS12_381_Fr_ParamsTests{} -#[make_test(quote{4},quote{BLS12_377_Fq_Params})] +#[make_test(quote{4}, quote{377}, quote{BLS12_377_Fq_Params})] pub struct BLS12_377_Fq_ParamsTests{} -#[make_test(quote{3},quote{BLS12_377_Fr_Params})] +#[make_test(quote{3}, quote{253}, quote{BLS12_377_Fr_Params})] pub struct BLS12_377_Fr_ParamsTests{} // 98760 // 99689 // 929 gates for a 2048 bit mul -fn test_div(params: BigNumParams) { - let a = unsafe { +fn test_div(params: BigNumParams) { + let a: RuntimeBigNum = unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; - let b = unsafe { + let b: RuntimeBigNum = unsafe { RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) }; @@ -391,12 +392,12 @@ fn test_div(params: BigNumParams) { assert((b * c) == a); } -unconstrained fn test_invmod(params: BigNumParams) { - let u = RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]); +unconstrained fn test_invmod(params: BigNumParams) { + let u: RuntimeBigNum = RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]); for _ in 0..1 { let v = u.__invmod(); let result = u.__mul(v); - let expected = RuntimeBigNum::one(params); + let expected: RuntimeBigNum = RuntimeBigNum::one(params); assert(result.limbs == expected.limbs); } } @@ -493,8 +494,8 @@ fn test_2048_bit_quadratic_expression() { 0x0000000000000000000000000000000000000000000000000000000000000058 ]; - let a_bn = RuntimeBigNum { limbs: a, params }; - let b_bn = RuntimeBigNum { limbs: b, params }; + let a_bn: RuntimeBigNum<_, 2048> = RuntimeBigNum { limbs: a, params }; + let b_bn: RuntimeBigNum<_, 2048> = RuntimeBigNum { limbs: b, params }; let c = a_bn * b_bn; assert(c.limbs == c_expected); @@ -503,17 +504,17 @@ fn test_2048_bit_quadratic_expression() { RuntimeBigNum::evaluate_quadratic_expression(params, [[a_bn]], [[false]], [[b_bn]], [[false]], [c], [true]); } -#[test] -fn test_sqrt_BN() { - let params = BN254_Fq_Params::get_params(); +// #[test] +// fn test_sqrt_BN() { +// let params = BN254_Fq_Params::get_params(); - let x = RuntimeBigNum { limbs: [9, 0, 0], params }; +// let x = RuntimeBigNum { limbs: [9, 0, 0], params }; - let (_, maybe_sqrt_x) = unsafe { - x.__tonelli_shanks_sqrt() - }; +// let (_, maybe_sqrt_x) = unsafe { +// x.__tonelli_shanks_sqrt() +// }; - assert(maybe_sqrt_x * maybe_sqrt_x == x); +// assert(maybe_sqrt_x * maybe_sqrt_x == x); - assert(x == x); // This was breaking for a while, because a previous version of RuntimeBigNum::__tonelli_shanks_sqrt() was returning an Option. My theory is that this meant Option:none() wasn't propagating the params anymore, which for some reason was causing the params of x to no-longer be evaluated as constant, which is strange. -} +// assert(x == x); // This was breaking for a while, because a previous version of RuntimeBigNum::__tonelli_shanks_sqrt() was returning an Option. My theory is that this meant Option:none() wasn't propagating the params anymore, which for some reason was causing the params of x to no-longer be evaluated as constant, which is strange. +// } diff --git a/src/serialization.nr b/src/serialization.nr index bba1672f..96a852e4 100644 --- a/src/serialization.nr +++ b/src/serialization.nr @@ -3,15 +3,13 @@ use crate::params::BigNumParams as P; /** * @brief construct a BigNum instance out of an array of bytes in BIG ENDIAN format * @description: each 120-bit limb represents 15 bytes, we require that the size of the byte array -* is precisely large enough to cover Params::modulus_bits() +* is precisely large enough to cover MOD_BITS * @param x: input byte array **/ -pub(crate) fn from_be_bytes(params: P, x: [u8; NBytes]) -> [Field; N] { +pub(crate) fn from_be_bytes(params: P, x: [u8; NBytes]) -> [Field; N] { let num_bits = NBytes * 8; - let modulus_bits_getter = params.modulus_bits_getter; - let modulus_bits = modulus_bits_getter(); - assert(num_bits >= modulus_bits); - assert(num_bits - modulus_bits < 8); + assert(num_bits >= MOD_BITS); + assert(num_bits - MOD_BITS < 8); let mut result = [0; N]; let excess_bytes = N * 15 - NBytes; @@ -36,7 +34,7 @@ pub(crate) fn from_be_bytes(params: P, x: [u8; N } // max_bits_in_most_significant_byte should be known at comptime. if not...messy! - let mut max_bits_in_most_significant_byte = 8 - (num_bits - modulus_bits); + let mut max_bits_in_most_significant_byte = 8 - (num_bits - MOD_BITS); let most_significant_byte: Field = x[0] as Field; @@ -44,10 +42,8 @@ pub(crate) fn from_be_bytes(params: P, x: [u8; N result } -pub(crate) fn to_le_bytes(params: P, val: [Field; N]) -> [u8; NBytes] { - let modulus_bits_getter = params.modulus_bits_getter; - let modulus_bits = modulus_bits_getter(); - let nbytes = (modulus_bits / 8) + (modulus_bits % 8 != 0) as u32; +pub(crate) fn to_le_bytes(params: P, val: [Field; N]) -> [u8; NBytes] { + let nbytes = (MOD_BITS / 8) + (MOD_BITS % 8 != 0) as u32; assert(nbytes <= NBytes); let mut result: [u8; NBytes] = [0; NBytes]; diff --git a/src/unconstrained_helpers.nr b/src/unconstrained_helpers.nr index 4141c305..3c46ee1a 100644 --- a/src/unconstrained_helpers.nr +++ b/src/unconstrained_helpers.nr @@ -16,7 +16,7 @@ use crate::unconstrained_ops::{__one, __eq, __neg, __add, __mul, __pow}; * __tonelli_shanks_sqrt */ -unconstrained pub(crate) fn __validate_in_field_compute_borrow_flags(params: P, val: [Field; N]) -> [bool; N] { +unconstrained pub(crate) fn __validate_in_field_compute_borrow_flags(params: P, val: [Field; N]) -> [bool; N] { let mut flags: [bool; N] = [false; N]; let modulus: [Field; N] = params.modulus; flags[0] = modulus[0].lt(val[0]); @@ -26,7 +26,7 @@ unconstrained pub(crate) fn __validate_in_field_compute_borrow_flags flags } -unconstrained pub(crate) fn __validate_gt_remainder(lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [bool; N], [bool; N]) { +unconstrained pub(crate) fn __validate_gt_remainder(lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [bool; N], [bool; N]) { let a_u60 : U60Repr = U60Repr::from(lhs); let mut b_u60 : U60Repr = U60Repr::from(rhs); @@ -67,7 +67,7 @@ unconstrained pub(crate) fn __validate_gt_remainder(lhs: [Field; N], (result, carry_flags, borrow_flags) } -unconstrained pub(crate) fn __neg_with_flags(params: P, val: [Field; N]) -> ([Field; N], [bool; N]) { +unconstrained pub(crate) fn __neg_with_flags(params: P, val: [Field; N]) -> ([Field; N], [bool; N]) { let x_u60 : U60Repr = U60Repr::from(val); let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; @@ -88,7 +88,7 @@ unconstrained pub(crate) fn __neg_with_flags(params: P, val: [Fie (result, borrow_flags) } -unconstrained pub(crate) fn __add_with_flags(params: P, lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [bool; N], [bool; N], bool) { +unconstrained pub(crate) fn __add_with_flags(params: P, lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [bool; N], [bool; N], bool) { let a_u60 : U60Repr = U60Repr::from(lhs); let b_u60 : U60Repr = U60Repr::from(rhs); let add_u60 = a_u60 + b_u60; @@ -134,7 +134,7 @@ unconstrained pub(crate) fn __add_with_flags(params: P, lhs: [Fie (result, carry_flags, borrow_flags, overflow) } -unconstrained pub(crate) fn __sub_with_flags(params: P, lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [bool; N], [bool; N], bool) { +unconstrained pub(crate) fn __sub_with_flags(params: P, lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [bool; N], [bool; N], bool) { let a_u60 : U60Repr = U60Repr::from(lhs); let b_u60 : U60Repr = U60Repr::from(rhs); @@ -256,72 +256,70 @@ unconstrained pub(crate) fn __barrett_reduction( (q, r) } -/** -* @brief compute the log of the size of the primitive root -* @details find the maximum value k where x^k = 1, where x = primitive root -* This is needed for our Tonelli-Shanks sqrt algorithm -**/ -unconstrained pub(crate) fn __primitive_root_log_size(params: P) -> u32 { - let mut target: U60Repr = params.modulus_u60 - U60Repr::one(); - let mut result: u32 = 0; - let modulus_bits_getter = params.modulus_bits_getter; - let modulus_bits = modulus_bits_getter(); - for _ in 0..modulus_bits { - let lsb_is_one = (target.limbs[0] & 1) == 1; - if (!lsb_is_one) { - result += 1; - target.shr1(); - } else { - break; - } - } - result -} - -/** -* @brief inner loop fn for `find_multiplive_generator` -* @details recursive function to get around the lack of a `while` keyword -**/ -unconstrained fn __recursively_find_multiplicative_generator( - params: P, - target: [Field; N], - p_minus_one_over_two: [Field; N] -) -> (bool, [Field; N]) { - let exped = __pow(params, target, p_minus_one_over_two); - let one: [Field; N] = __one(); - let neg_one = __neg(params, one); - let found = __eq(exped, neg_one); - let mut result: (bool, [Field; N]) = (found, target); - if (!found) { - let _target = unsafe { - __add(params, target, one) - }; - result = __recursively_find_multiplicative_generator(params, _target, p_minus_one_over_two); - } - result -} - -/** -* @brief find multiplicative generator `g` where `g` is the smallest value that is not a quadratic residue -* i.e. smallest g where g^2 = -1 -* @note WARNING if multiplicative generator does not exist, this function will enter an infinite loop! -**/ -unconstrained pub(crate) fn __multiplicative_generator(params: P) -> [Field; N] { - let mut target: [Field; N] = __one(); - let p_minus_one_over_two: U60Repr = (params.modulus_u60 - U60Repr::one()).shr(1); - let p_minus_one_over_two: [Field; N] = U60Repr::into(p_minus_one_over_two); - let (_, target) = __recursively_find_multiplicative_generator(params, target, p_minus_one_over_two); - target -} - -unconstrained pub(crate) fn __tonelli_shanks_sqrt_inner_loop_check(params: P, t2m: [Field; N], i: u32) -> u32 { - let one: [Field; N] = __one(); - let is_one = __eq(t2m, one); - let mut result = i; - if (!is_one) { - let t2m = __mul(params, t2m, t2m); - let i = i + 1; - result = __tonelli_shanks_sqrt_inner_loop_check(params, t2m, i); - } - result -} +// /** +// * @brief compute the log of the size of the primitive root +// * @details find the maximum value k where x^k = 1, where x = primitive root +// * This is needed for our Tonelli-Shanks sqrt algorithm +// **/ +// unconstrained pub(crate) fn __primitive_root_log_size(params: P) -> u32 { +// let mut target: U60Repr = params.modulus_u60 - U60Repr::one(); +// let mut result: u32 = 0; +// for _ in 0..MOD_BITS { +// let lsb_is_one = (target.limbs[0] & 1) == 1; +// if (!lsb_is_one) { +// result += 1; +// target.shr1(); +// } else { +// break; +// } +// } +// result +// } + +// /** +// * @brief inner loop fn for `find_multiplive_generator` +// * @details recursive function to get around the lack of a `while` keyword +// **/ +// unconstrained fn __recursively_find_multiplicative_generator( +// params: P, +// target: [Field; N], +// p_minus_one_over_two: [Field; N] +// ) -> (bool, [Field; N]) { +// let exped = __pow(params, target, p_minus_one_over_two); +// let one: [Field; N] = __one(); +// let neg_one = __neg(params, one); +// let found = __eq(exped, neg_one); +// let mut result: (bool, [Field; N]) = (found, target); +// if (!found) { +// let _target = unsafe { +// __add(params, target, one) +// }; +// result = __recursively_find_multiplicative_generator(params, _target, p_minus_one_over_two); +// } +// result +// } + +// /** +// * @brief find multiplicative generator `g` where `g` is the smallest value that is not a quadratic residue +// * i.e. smallest g where g^2 = -1 +// * @note WARNING if multiplicative generator does not exist, this function will enter an infinite loop! +// **/ +// unconstrained pub(crate) fn __multiplicative_generator(params: P) -> [Field; N] { +// let mut target: [Field; N] = __one(); +// let p_minus_one_over_two: U60Repr = (params.modulus_u60 - U60Repr::one()).shr(1); +// let p_minus_one_over_two: [Field; N] = U60Repr::into(p_minus_one_over_two); +// let (_, target) = __recursively_find_multiplicative_generator(params, target, p_minus_one_over_two); +// target +// } + +// unconstrained pub(crate) fn __tonelli_shanks_sqrt_inner_loop_check(params: P, t2m: [Field; N], i: u32) -> u32 { +// let one: [Field; N] = __one(); +// let is_one = __eq(t2m, one); +// let mut result = i; +// if (!is_one) { +// let t2m = __mul::<_, MOD_BITS>(params, t2m, t2m); +// let i = i + 1; +// result = __tonelli_shanks_sqrt_inner_loop_check::<_, MOD_BITS>(params, t2m, i); +// } +// result +// } diff --git a/src/unconstrained_ops.nr b/src/unconstrained_ops.nr index 85ad548c..9aab557c 100644 --- a/src/unconstrained_ops.nr +++ b/src/unconstrained_ops.nr @@ -3,8 +3,7 @@ use crate::utils::split_bits; use crate::params::BigNumParams as P; use crate::unconstrained_helpers::{ - __barrett_reduction, __primitive_root_log_size, __multiplicative_generator, - __tonelli_shanks_sqrt_inner_loop_check + __barrett_reduction //, __primitive_root_log_size, __multiplicative_generator, __tonelli_shanks_sqrt_inner_loop_check }; /** @@ -33,7 +32,7 @@ unconstrained pub(crate) fn __one() -> [Field; N] { limbs } -unconstrained pub(crate) fn __derive_from_seed(params: P, seed: [u8; SeedBytes]) -> [Field; N] { +unconstrained pub(crate) fn __derive_from_seed(params: P, seed: [u8; SeedBytes]) -> [Field; N] { let mut rolling_hash_fields: [Field; (SeedBytes / 31) + 1] = [0; (SeedBytes / 31) + 1]; let mut seed_ptr = 0; for i in 0..(SeedBytes / 31) + 1 { @@ -52,9 +51,7 @@ unconstrained pub(crate) fn __derive_from_seed(p let mut to_reduce: [Field; 2 * N] = [0; 2 * N]; - let modulus_bits_getter = params.modulus_bits_getter; - let modulus_bits = modulus_bits_getter(); - let mut double_modulus_bits = modulus_bits * 2; + let mut double_modulus_bits = MOD_BITS * 2; let mut double_modulus_bytes = (double_modulus_bits) / 8 + (double_modulus_bits % 8 != 0) as u32; let mut last_limb_bytes = double_modulus_bytes % 15; @@ -100,12 +97,11 @@ unconstrained pub(crate) fn __derive_from_seed(p hi += last_bits as Field; to_reduce[2 * N - 2] = hi; } - let modulus_bits_getter = params.modulus_bits_getter; - let modulus_bits = modulus_bits_getter(); + let (_, remainder) = __barrett_reduction( to_reduce, params.redc_param, - modulus_bits, + MOD_BITS, params.modulus, params.modulus_u60_x4 ); @@ -135,14 +131,14 @@ unconstrained pub(crate) fn __is_zero(limbs: [Field; N]) -> bool { * N.B. constrained BigNum operations do not fully constrain outputs to be in the range [0, p-1] * because such a check is expensive and usually unneccesary. */ -unconstrained pub(crate) fn __neg(params: P, limbs: [Field; N]) -> [Field; N] { +unconstrained pub(crate) fn __neg(params: P, limbs: [Field; N]) -> [Field; N] { let f: [Field; N] = limbs; let x_u60 : U60Repr = U60Repr::from(f); U60Repr::into(params.modulus_u60 - x_u60) } -unconstrained pub(crate) fn __add( - params: P, +unconstrained pub(crate) fn __add( + params: P, lhs: [Field; N], rhs: [Field; N] ) -> [Field; N] { @@ -161,11 +157,11 @@ unconstrained pub(crate) fn __add( * @brief given inputs `x, y` compute 2p + x - y (unconstrained) * @description see `__neg` for why we use 2p instead of p **/ -unconstrained pub(crate) fn __sub(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { +unconstrained pub(crate) fn __sub(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { __add(params, lhs, __neg(params, rhs)) } -unconstrained pub(crate) fn __mul_with_quotient(params: P, lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [Field; N]) { +unconstrained pub(crate) fn __mul_with_quotient(params: P, lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [Field; N]) { let mut mul: [Field; 2 * N] = [0; 2 * N]; for i in 0..N { for j in 0..N { @@ -173,12 +169,10 @@ unconstrained pub(crate) fn __mul_with_quotient(params: P, lhs: [ } } let to_reduce = split_bits::__normalize_limbs(mul, 2 * N); - let modulus_bits_getter = params.modulus_bits_getter; - let modulus_bits = modulus_bits_getter(); let (q, r) = __barrett_reduction( to_reduce, params.redc_param, - modulus_bits, + MOD_BITS, params.modulus, params.modulus_u60_x4 ); @@ -186,22 +180,22 @@ unconstrained pub(crate) fn __mul_with_quotient(params: P, lhs: [ (q, r) } -unconstrained pub(crate) fn __mul( - params: P, +unconstrained pub(crate) fn __mul( + params: P, lhs: [Field; N], rhs: [Field; N] ) -> [Field; N] { - let (_, b) = __mul_with_quotient(params, lhs, rhs); + let (_, b) = __mul_with_quotient::<_, MOD_BITS>(params, lhs, rhs); b } -unconstrained pub(crate) fn __div( - params: P, +unconstrained pub(crate) fn __div( + params: P, numerator: [Field; N], divisor: [Field; N] ) -> [Field; N] { - let inv_divisor = __invmod(params, divisor); - __mul(params, numerator, inv_divisor) + let inv_divisor = __invmod::<_, MOD_BITS>(params, divisor); + __mul::<_, MOD_BITS>(params, numerator, inv_divisor) } /** @@ -211,7 +205,7 @@ unconstrained pub(crate) fn __div( * 2. numerator % divisor = remainder * 3. divisor * quotient + remainder = numerator **/ -unconstrained pub(crate) fn __udiv_mod(numerator: [Field; N], divisor: [Field; N]) -> ([Field; N], [Field; N]) { +unconstrained pub(crate) fn __udiv_mod(numerator: [Field; N], divisor: [Field; N]) -> ([Field; N], [Field; N]) { let mut quotient_u60: U60Repr = U60Repr::from([0; N]); let mut remainder_u60: U60Repr = U60Repr::from(numerator); @@ -248,37 +242,35 @@ unconstrained pub(crate) fn __udiv_mod(numerator: [Field; N], diviso (U60Repr::into(quotient_u60), U60Repr::into(remainder_u60)) } -unconstrained pub(crate) fn __invmod(params: P, val: [Field; N]) -> [Field; N] { +unconstrained pub(crate) fn __invmod(params: P, val: [Field; N]) -> [Field; N] { let one: [Field; N] = __one::(); let one_u60: U60Repr = U60Repr::from(one); let exp_u60 = params.modulus_u60.sub(one_u60.add(one_u60)); let exp = U60Repr::into(exp_u60); - __pow(params, val, exp) + __pow::<_, MOD_BITS>(params, val, exp) } -unconstrained pub(crate) fn __pow( - params: P, +unconstrained pub(crate) fn __pow( + params: P, val: [Field; N], exponent: [Field; N] ) -> [Field; N] { let x: U60Repr = U60Repr::from(exponent); - let modulus_bits_getter = params.modulus_bits_getter; - let modulus_bits = modulus_bits_getter(); - let num_bits = modulus_bits + 1; + let num_bits = MOD_BITS + 1; let mut accumulator: [Field; N] = __one::(); for i in 0..num_bits { - accumulator = __mul(params, accumulator, accumulator); + accumulator = __mul::<_, MOD_BITS>(params, accumulator, accumulator); if x.get_bit(num_bits - i - 1) { - accumulator = __mul(params, accumulator, val); + accumulator = __mul::<_, MOD_BITS>(params, accumulator, val); } } accumulator } -unconstrained pub(crate) fn __batch_invert(params: P, x: [[Field; N]; M]) -> [[Field; N]; M] { +unconstrained pub(crate) fn __batch_invert(params: P, x: [[Field; N]; M]) -> [[Field; N]; M] { // TODO: ugly! Will fail if input slice is empty let mut accumulator: [Field; N] = __one::(); let mut result: [[Field; N]; M] = [[0; N]; M]; @@ -286,24 +278,24 @@ unconstrained pub(crate) fn __batch_invert(params: P, for i in 0..x.len() { temporaries = temporaries.push_back(accumulator); if (__is_zero(x[i]) == false) { - accumulator = __mul(params, accumulator, x[i]); + accumulator = __mul::<_, MOD_BITS>(params, accumulator, x[i]); } } - accumulator = __invmod(params, accumulator); + accumulator = __invmod::<_, MOD_BITS>(params, accumulator); let mut T0: [Field; N] = [0; N]; for i in 0..x.len() { let idx = x.len() - 1 - i; if (__is_zero(x[idx]) == false) { - T0 = __mul(params, accumulator, temporaries[idx]); - accumulator = __mul(params, accumulator, x[idx]); + T0 = __mul::<_, MOD_BITS>(params, accumulator, temporaries[idx]); + accumulator = __mul::<_, MOD_BITS>(params, accumulator, x[idx]); result[idx] = T0; } } result } -unconstrained pub(crate) fn __batch_invert_slice(params: P, x: [[Field; N]]) -> [[Field; N]] { +unconstrained pub(crate) fn __batch_invert_slice(params: P, x: [[Field; N]]) -> [[Field; N]] { // TODO: ugly! Will fail if input slice is empty let mut accumulator: [Field; N] = __one::(); let mut result: [[Field; N]] = [[0; N]]; @@ -311,108 +303,106 @@ unconstrained pub(crate) fn __batch_invert_slice(params: P, x: [[ for i in 0..x.len() { temporaries = temporaries.push_back(accumulator); if (__is_zero(x[i]) == false) { - accumulator = __mul(params, accumulator, x[i]); + accumulator = __mul::<_, MOD_BITS>(params, accumulator, x[i]); } result = result.push_back([0; N]); } - accumulator = __invmod(params, accumulator); + accumulator = __invmod::<_, MOD_BITS>(params, accumulator); let mut T0: [Field; N] = [0; N]; for i in 0..x.len() { let idx = x.len() - 1 - i; if (__is_zero(x[idx]) == false) { - T0 = __mul(params, accumulator, temporaries[idx]); - accumulator = __mul(params, accumulator, x[idx]); + T0 = __mul::<_, MOD_BITS>(params, accumulator, temporaries[idx]); + accumulator = __mul::<_, MOD_BITS>(params, accumulator, x[idx]); result[idx] = T0; } } result } -/** -* @brief compute a modular square root using the Tonelli-Shanks algorithm -* @details only use for prime fields! Function may infinite loop if used for non-prime fields -* @note this is unconstrained fn. To constrain a square root, validate that output^2 = self -* TODO: create fn that constrains nonexistence of square root (i.e. find x where x^2 = -self) -**/ -unconstrained pub(crate) fn __tonelli_shanks_sqrt(params: P, input: [Field; N]) -> std::option::Option<[Field; N]> { - // Tonelli-shanks algorithm begins by finding a field element Q and integer S, - // such that (p - 1) = Q.2^{s} - // We can compute the square root of a, by considering a^{(Q + 1) / 2} = R - // Once we have found such an R, we have - // R^{2} = a^{Q + 1} = a^{Q}a - // If a^{Q} = 1, we have found our square root. - // Otherwise, we have a^{Q} = t, where t is a 2^{s-1}'th root of unity. - // This is because t^{2^{s-1}} = a^{Q.2^{s-1}}. - // We know that (p - 1) = Q.w^{s}, therefore t^{2^{s-1}} = a^{(p - 1) / 2} - // From Euler's criterion, if a is a quadratic residue, a^{(p - 1) / 2} = 1 - // i.e. t^{2^{s-1}} = 1 - // To proceed with computing our square root, we want to transform t into a smaller subgroup, - // specifically, the (s-2)'th roots of unity. - // We do this by finding some value b,such that - // (t.b^2)^{2^{s-2}} = 1 and R' = R.b - // Finding such a b is trivial, because from Euler's criterion, we know that, - // for any quadratic non-residue z, z^{(p - 1) / 2} = -1 - // i.e. z^{Q.2^{s-1}} = -1 - // => z^Q is a 2^{s-1}'th root of -1 - // => z^{Q^2} is a 2^{s-2}'th root of -1 - // Since t^{2^{s-1}} = 1, we know that t^{2^{s - 2}} = -1 - // => t.z^{Q^2} is a 2^{s - 2}'th root of unity. - // We can iteratively transform t into ever smaller subgroups, until t = 1. - // At each iteration, we need to find a new value for b, which we can obtain - // by repeatedly squaring z^{Q} - let one_u60: U60Repr = unsafe { - U60Repr::one() - }; - let primitive_root_log_size = __primitive_root_log_size(params); - let mut Q = (params.modulus_u60 - one_u60).shr(primitive_root_log_size - 1); - let Q_minus_one_over_two_u60 = (Q - one_u60).shr(2); - let Q_minus_one_over_two: [Field; N] = U60Repr::into(Q_minus_one_over_two_u60); - let mut z = __multiplicative_generator(params); // the generator is a non-residue - let mut b = __pow(params, input, Q_minus_one_over_two); - let mut r = __mul(params, input, b); - let mut t = __mul(params, r, b); - let mut check: [Field; N] = t; - for _ in 0..primitive_root_log_size - 1 { - check = __mul(params, check, check); - } - let mut found_root = false; - let one: [Field; N] = __one::(); - if (__eq(check, one) == false) {} else { - let mut t1 = __pow(params, z, Q_minus_one_over_two); - let mut t2 = __mul(params, t1, z); - let mut c = __mul(params, t2, t1); - let mut m: u32 = primitive_root_log_size; - // tonelli shanks inner 1 - // (if t2m == 1) then skip - // else increase i and square t2m and go again - // algorithm runtime should only be max the number of bits in modulus - let modulus_bits_getter = params.modulus_bits_getter; - let modulus_bits = modulus_bits_getter(); - let num_bits: u32 = modulus_bits; - for _ in 0..num_bits { - if (__eq(t, one)) { - found_root = true; - break; - } - let mut t2m = t; - // while loop time - let i = __tonelli_shanks_sqrt_inner_loop_check(params, t2m, 0); - let mut j = m - i - 1; - b = c; - for _ in 0..j { // how big - if (j == 0) { - break; - } - b = __mul(params, b, b); - //j -= 1; - } - c = __mul(params, b, b); - t = __mul(params, t, c); - r = __mul(params, r, b); - m = i; - } - } - let mut result = std::option::Option { _value: r, _is_some: found_root }; - result -} +// /** +// * @brief compute a modular square root using the Tonelli-Shanks algorithm +// * @details only use for prime fields! Function may infinite loop if used for non-prime fields +// * @note this is unconstrained fn. To constrain a square root, validate that output^2 = self +// * TODO: create fn that constrains nonexistence of square root (i.e. find x where x^2 = -self) +// **/ +// unconstrained pub(crate) fn __tonelli_shanks_sqrt(params: P, input: [Field; N]) -> std::option::Option<[Field; N]> { +// // Tonelli-shanks algorithm begins by finding a field element Q and integer S, +// // such that (p - 1) = Q.2^{s} +// // We can compute the square root of a, by considering a^{(Q + 1) / 2} = R +// // Once we have found such an R, we have +// // R^{2} = a^{Q + 1} = a^{Q}a +// // If a^{Q} = 1, we have found our square root. +// // Otherwise, we have a^{Q} = t, where t is a 2^{s-1}'th root of unity. +// // This is because t^{2^{s-1}} = a^{Q.2^{s-1}}. +// // We know that (p - 1) = Q.w^{s}, therefore t^{2^{s-1}} = a^{(p - 1) / 2} +// // From Euler's criterion, if a is a quadratic residue, a^{(p - 1) / 2} = 1 +// // i.e. t^{2^{s-1}} = 1 +// // To proceed with computing our square root, we want to transform t into a smaller subgroup, +// // specifically, the (s-2)'th roots of unity. +// // We do this by finding some value b,such that +// // (t.b^2)^{2^{s-2}} = 1 and R' = R.b +// // Finding such a b is trivial, because from Euler's criterion, we know that, +// // for any quadratic non-residue z, z^{(p - 1) / 2} = -1 +// // i.e. z^{Q.2^{s-1}} = -1 +// // => z^Q is a 2^{s-1}'th root of -1 +// // => z^{Q^2} is a 2^{s-2}'th root of -1 +// // Since t^{2^{s-1}} = 1, we know that t^{2^{s - 2}} = -1 +// // => t.z^{Q^2} is a 2^{s - 2}'th root of unity. +// // We can iteratively transform t into ever smaller subgroups, until t = 1. +// // At each iteration, we need to find a new value for b, which we can obtain +// // by repeatedly squaring z^{Q} +// let one_u60: U60Repr = unsafe { +// U60Repr::one() +// }; +// let primitive_root_log_size = __primitive_root_log_size(params); +// let mut Q = (params.modulus_u60 - one_u60).shr(primitive_root_log_size - 1); +// let Q_minus_one_over_two_u60 = (Q - one_u60).shr(2); +// let Q_minus_one_over_two: [Field; N] = U60Repr::into(Q_minus_one_over_two_u60); +// let mut z = __multiplicative_generator(params); // the generator is a non-residue +// let mut b = __pow(params, input, Q_minus_one_over_two); +// let mut r = __mul(params, input, b); +// let mut t = __mul(params, r, b); +// let mut check: [Field; N] = t; +// for _ in 0..primitive_root_log_size - 1 { +// check = __mul(params, check, check); +// } +// let mut found_root = false; +// let one: [Field; N] = __one::(); +// if (__eq(check, one) == false) {} else { +// let mut t1 = __pow(params, z, Q_minus_one_over_two); +// let mut t2 = __mul(params, t1, z); +// let mut c = __mul(params, t2, t1); +// let mut m: u32 = primitive_root_log_size; +// // tonelli shanks inner 1 +// // (if t2m == 1) then skip +// // else increase i and square t2m and go again +// // algorithm runtime should only be max the number of bits in modulus + +// for _ in 0..MOD_BITS { +// if (__eq(t, one)) { +// found_root = true; +// break; +// } +// let mut t2m = t; +// // while loop time +// let i = __tonelli_shanks_sqrt_inner_loop_check(params, t2m, 0); +// let mut j = m - i - 1; +// b = c; +// for _ in 0..j { // how big +// if (j == 0) { +// break; +// } +// b = __mul(params, b, b); +// //j -= 1; +// } +// c = __mul(params, b, b); +// t = __mul(params, t, c); +// r = __mul(params, r, b); +// m = i; +// } +// } +// let mut result = std::option::Option { _value: r, _is_some: found_root }; +// result +// } From b2ce9a4de3125073d14cc872744681d5350dd3dd Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Tue, 22 Oct 2024 17:09:04 +0100 Subject: [PATCH 16/29] tonelli --- src/bignum.nr | 18 ++-- src/runtime_bignum.nr | 28 +++--- src/runtime_bignum_test.nr | 20 ++-- src/unconstrained_helpers.nr | 134 +++++++++++++-------------- src/unconstrained_ops.nr | 172 +++++++++++++++++------------------ 5 files changed, 186 insertions(+), 186 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index 09d14ea7..03b9fcec 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -7,7 +7,7 @@ use crate::constrained_ops::{ }; use crate::unconstrained_ops::{ __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, - __batch_invert, __batch_invert_slice //, __tonelli_shanks_sqrt + __batch_invert, __batch_invert_slice , __tonelli_shanks_sqrt }; use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}; use crate::serialization::{from_be_bytes, to_le_bytes}; @@ -51,7 +51,7 @@ pub(crate) trait BigNumTrait { unconstrained fn __batch_invert(to_invert: [Self; M]) -> [Self; M]; unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; - // unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option; + unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option; unconstrained fn __compute_quadratic_expression( lhs: [[Self; LHS_N]; NUM_PRODUCTS], @@ -217,13 +217,13 @@ impl BigNumTrait for BigNum(params, x.map(|bn| Self::get_limbs(bn))).map(|limbs| Self { limbs }) } - // unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option { - // let params = Params::get_params(); - // let maybe_limbs = unsafe { - // __tonelli_shanks_sqrt(params, self.limbs) - // }; - // maybe_limbs.map(|limbs| Self { limbs }) - // } + unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option { + let params = Params::get_params(); + let maybe_limbs = unsafe { + __tonelli_shanks_sqrt(params, self.limbs) + }; + maybe_limbs.map(|limbs| Self { limbs }) + } unconstrained fn __compute_quadratic_expression( lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index 482bb85e..3021e71f 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -8,7 +8,7 @@ use crate::constrained_ops::{ }; use crate::unconstrained_ops::{ __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, - __batch_invert, __batch_invert_slice //, __tonelli_shanks_sqrt + __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt }; use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}; use crate::serialization::{from_be_bytes, to_le_bytes}; @@ -56,7 +56,7 @@ pub(crate) trait RuntimeBigNumTrait { fn __batch_invert(x: [Self; M]) -> [Self; M]; unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; - // unconstrained fn __tonelli_shanks_sqrt(self) -> (bool, Self); + unconstrained fn __tonelli_shanks_sqrt(self) -> (bool, Self); fn __compute_quadratic_expression( params: BigNumParams, @@ -272,18 +272,18 @@ impl RuntimeBigNumTrait for RuntimeB } // @dev We intentionally don't use std::option::Option, because the Option::none() case doesn't propagate the `params`, so the code breaks. Specifically, the code stops evaluating modulus_bits = self.params.modulus_bits_getter() as constant, which then breaks calls to `validate_in_range()` (e.g. via calls to `==` on `self`), because `validate_in_range` calls `assert_max_bit_size` on a value derived from `modulus_bits`. I'm not sure why it stops evaluating the getter's return value as constant if we return a std::Option, really. - // unconstrained fn __tonelli_shanks_sqrt(self) -> (bool, Self) { - // let params = self.params; - // let maybe_limbs = unsafe { - // __tonelli_shanks_sqrt(params, self.limbs) - // }; - // let result: (bool, Self) = if maybe_limbs.is_some() { - // (true, Self { limbs: maybe_limbs.unwrap_unchecked(), params }) - // } else { - // (false, Self::new(params)) - // }; - // result - // } + unconstrained fn __tonelli_shanks_sqrt(self) -> (bool, Self) { + let params = self.params; + let maybe_limbs = unsafe { + __tonelli_shanks_sqrt(params, self.limbs) + }; + let result: (bool, Self) = if maybe_limbs.is_some() { + (true, Self { limbs: maybe_limbs.unwrap_unchecked(), params }) + } else { + (false, Self::new(params)) + }; + result + } // UNCONSTRAINED! (Hence `__` prefix). fn __compute_quadratic_expression( diff --git a/src/runtime_bignum_test.nr b/src/runtime_bignum_test.nr index d819de24..05652a2c 100644 --- a/src/runtime_bignum_test.nr +++ b/src/runtime_bignum_test.nr @@ -504,17 +504,17 @@ fn test_2048_bit_quadratic_expression() { RuntimeBigNum::evaluate_quadratic_expression(params, [[a_bn]], [[false]], [[b_bn]], [[false]], [c], [true]); } -// #[test] -// fn test_sqrt_BN() { -// let params = BN254_Fq_Params::get_params(); +#[test] +fn test_sqrt_BN() { + let params = BN254_Fq_Params::get_params(); -// let x = RuntimeBigNum { limbs: [9, 0, 0], params }; + let x = RuntimeBigNum { limbs: [9, 0, 0], params }; -// let (_, maybe_sqrt_x) = unsafe { -// x.__tonelli_shanks_sqrt() -// }; + let (_, maybe_sqrt_x) = unsafe { + x.__tonelli_shanks_sqrt() + }; -// assert(maybe_sqrt_x * maybe_sqrt_x == x); + assert(maybe_sqrt_x * maybe_sqrt_x == x); -// assert(x == x); // This was breaking for a while, because a previous version of RuntimeBigNum::__tonelli_shanks_sqrt() was returning an Option. My theory is that this meant Option:none() wasn't propagating the params anymore, which for some reason was causing the params of x to no-longer be evaluated as constant, which is strange. -// } + assert(x == x); // This was breaking for a while, because a previous version of RuntimeBigNum::__tonelli_shanks_sqrt() was returning an Option. My theory is that this meant Option:none() wasn't propagating the params anymore, which for some reason was causing the params of x to no-longer be evaluated as constant, which is strange. +} diff --git a/src/unconstrained_helpers.nr b/src/unconstrained_helpers.nr index 3c46ee1a..7cf4d397 100644 --- a/src/unconstrained_helpers.nr +++ b/src/unconstrained_helpers.nr @@ -256,70 +256,70 @@ unconstrained pub(crate) fn __barrett_reduction( (q, r) } -// /** -// * @brief compute the log of the size of the primitive root -// * @details find the maximum value k where x^k = 1, where x = primitive root -// * This is needed for our Tonelli-Shanks sqrt algorithm -// **/ -// unconstrained pub(crate) fn __primitive_root_log_size(params: P) -> u32 { -// let mut target: U60Repr = params.modulus_u60 - U60Repr::one(); -// let mut result: u32 = 0; -// for _ in 0..MOD_BITS { -// let lsb_is_one = (target.limbs[0] & 1) == 1; -// if (!lsb_is_one) { -// result += 1; -// target.shr1(); -// } else { -// break; -// } -// } -// result -// } - -// /** -// * @brief inner loop fn for `find_multiplive_generator` -// * @details recursive function to get around the lack of a `while` keyword -// **/ -// unconstrained fn __recursively_find_multiplicative_generator( -// params: P, -// target: [Field; N], -// p_minus_one_over_two: [Field; N] -// ) -> (bool, [Field; N]) { -// let exped = __pow(params, target, p_minus_one_over_two); -// let one: [Field; N] = __one(); -// let neg_one = __neg(params, one); -// let found = __eq(exped, neg_one); -// let mut result: (bool, [Field; N]) = (found, target); -// if (!found) { -// let _target = unsafe { -// __add(params, target, one) -// }; -// result = __recursively_find_multiplicative_generator(params, _target, p_minus_one_over_two); -// } -// result -// } - -// /** -// * @brief find multiplicative generator `g` where `g` is the smallest value that is not a quadratic residue -// * i.e. smallest g where g^2 = -1 -// * @note WARNING if multiplicative generator does not exist, this function will enter an infinite loop! -// **/ -// unconstrained pub(crate) fn __multiplicative_generator(params: P) -> [Field; N] { -// let mut target: [Field; N] = __one(); -// let p_minus_one_over_two: U60Repr = (params.modulus_u60 - U60Repr::one()).shr(1); -// let p_minus_one_over_two: [Field; N] = U60Repr::into(p_minus_one_over_two); -// let (_, target) = __recursively_find_multiplicative_generator(params, target, p_minus_one_over_two); -// target -// } - -// unconstrained pub(crate) fn __tonelli_shanks_sqrt_inner_loop_check(params: P, t2m: [Field; N], i: u32) -> u32 { -// let one: [Field; N] = __one(); -// let is_one = __eq(t2m, one); -// let mut result = i; -// if (!is_one) { -// let t2m = __mul::<_, MOD_BITS>(params, t2m, t2m); -// let i = i + 1; -// result = __tonelli_shanks_sqrt_inner_loop_check::<_, MOD_BITS>(params, t2m, i); -// } -// result -// } +/** +* @brief compute the log of the size of the primitive root +* @details find the maximum value k where x^k = 1, where x = primitive root +* This is needed for our Tonelli-Shanks sqrt algorithm +**/ +unconstrained pub(crate) fn __primitive_root_log_size(params: P) -> u32 { + let mut target: U60Repr = params.modulus_u60 - U60Repr::one(); + let mut result: u32 = 0; + for _ in 0..MOD_BITS { + let lsb_is_one = (target.limbs[0] & 1) == 1; + if (!lsb_is_one) { + result += 1; + target.shr1(); + } else { + break; + } + } + result +} + +/** +* @brief inner loop fn for `find_multiplive_generator` +* @details recursive function to get around the lack of a `while` keyword +**/ +unconstrained fn __recursively_find_multiplicative_generator( + params: P, + target: [Field; N], + p_minus_one_over_two: [Field; N] +) -> (bool, [Field; N]) { + let exped = __pow(params, target, p_minus_one_over_two); + let one: [Field; N] = __one(); + let neg_one = __neg(params, one); + let found = __eq(exped, neg_one); + let mut result: (bool, [Field; N]) = (found, target); + if (!found) { + let _target = unsafe { + __add(params, target, one) + }; + result = __recursively_find_multiplicative_generator::<_, MOD_BITS>(params, _target, p_minus_one_over_two); + } + result +} + +/** +* @brief find multiplicative generator `g` where `g` is the smallest value that is not a quadratic residue +* i.e. smallest g where g^2 = -1 +* @note WARNING if multiplicative generator does not exist, this function will enter an infinite loop! +**/ +unconstrained pub(crate) fn __multiplicative_generator(params: P) -> [Field; N] { + let mut target: [Field; N] = __one(); + let p_minus_one_over_two: U60Repr = (params.modulus_u60 - U60Repr::one()).shr(1); + let p_minus_one_over_two: [Field; N] = U60Repr::into(p_minus_one_over_two); + let (_, target) = __recursively_find_multiplicative_generator::<_, MOD_BITS>(params, target, p_minus_one_over_two); + target +} + +unconstrained pub(crate) fn __tonelli_shanks_sqrt_inner_loop_check(params: P, t2m: [Field; N], i: u32) -> u32 { + let one: [Field; N] = __one(); + let is_one = __eq(t2m, one); + let mut result = i; + if (!is_one) { + let t2m = __mul::<_, MOD_BITS>(params, t2m, t2m); + let i = i + 1; + result = __tonelli_shanks_sqrt_inner_loop_check::<_, MOD_BITS>(params, t2m, i); + } + result +} diff --git a/src/unconstrained_ops.nr b/src/unconstrained_ops.nr index 9aab557c..49585051 100644 --- a/src/unconstrained_ops.nr +++ b/src/unconstrained_ops.nr @@ -3,7 +3,7 @@ use crate::utils::split_bits; use crate::params::BigNumParams as P; use crate::unconstrained_helpers::{ - __barrett_reduction //, __primitive_root_log_size, __multiplicative_generator, __tonelli_shanks_sqrt_inner_loop_check + __barrett_reduction , __primitive_root_log_size, __multiplicative_generator, __tonelli_shanks_sqrt_inner_loop_check }; /** @@ -321,88 +321,88 @@ unconstrained pub(crate) fn __batch_invert_slice( result } -// /** -// * @brief compute a modular square root using the Tonelli-Shanks algorithm -// * @details only use for prime fields! Function may infinite loop if used for non-prime fields -// * @note this is unconstrained fn. To constrain a square root, validate that output^2 = self -// * TODO: create fn that constrains nonexistence of square root (i.e. find x where x^2 = -self) -// **/ -// unconstrained pub(crate) fn __tonelli_shanks_sqrt(params: P, input: [Field; N]) -> std::option::Option<[Field; N]> { -// // Tonelli-shanks algorithm begins by finding a field element Q and integer S, -// // such that (p - 1) = Q.2^{s} -// // We can compute the square root of a, by considering a^{(Q + 1) / 2} = R -// // Once we have found such an R, we have -// // R^{2} = a^{Q + 1} = a^{Q}a -// // If a^{Q} = 1, we have found our square root. -// // Otherwise, we have a^{Q} = t, where t is a 2^{s-1}'th root of unity. -// // This is because t^{2^{s-1}} = a^{Q.2^{s-1}}. -// // We know that (p - 1) = Q.w^{s}, therefore t^{2^{s-1}} = a^{(p - 1) / 2} -// // From Euler's criterion, if a is a quadratic residue, a^{(p - 1) / 2} = 1 -// // i.e. t^{2^{s-1}} = 1 -// // To proceed with computing our square root, we want to transform t into a smaller subgroup, -// // specifically, the (s-2)'th roots of unity. -// // We do this by finding some value b,such that -// // (t.b^2)^{2^{s-2}} = 1 and R' = R.b -// // Finding such a b is trivial, because from Euler's criterion, we know that, -// // for any quadratic non-residue z, z^{(p - 1) / 2} = -1 -// // i.e. z^{Q.2^{s-1}} = -1 -// // => z^Q is a 2^{s-1}'th root of -1 -// // => z^{Q^2} is a 2^{s-2}'th root of -1 -// // Since t^{2^{s-1}} = 1, we know that t^{2^{s - 2}} = -1 -// // => t.z^{Q^2} is a 2^{s - 2}'th root of unity. -// // We can iteratively transform t into ever smaller subgroups, until t = 1. -// // At each iteration, we need to find a new value for b, which we can obtain -// // by repeatedly squaring z^{Q} -// let one_u60: U60Repr = unsafe { -// U60Repr::one() -// }; -// let primitive_root_log_size = __primitive_root_log_size(params); -// let mut Q = (params.modulus_u60 - one_u60).shr(primitive_root_log_size - 1); -// let Q_minus_one_over_two_u60 = (Q - one_u60).shr(2); -// let Q_minus_one_over_two: [Field; N] = U60Repr::into(Q_minus_one_over_two_u60); -// let mut z = __multiplicative_generator(params); // the generator is a non-residue -// let mut b = __pow(params, input, Q_minus_one_over_two); -// let mut r = __mul(params, input, b); -// let mut t = __mul(params, r, b); -// let mut check: [Field; N] = t; -// for _ in 0..primitive_root_log_size - 1 { -// check = __mul(params, check, check); -// } -// let mut found_root = false; -// let one: [Field; N] = __one::(); -// if (__eq(check, one) == false) {} else { -// let mut t1 = __pow(params, z, Q_minus_one_over_two); -// let mut t2 = __mul(params, t1, z); -// let mut c = __mul(params, t2, t1); -// let mut m: u32 = primitive_root_log_size; -// // tonelli shanks inner 1 -// // (if t2m == 1) then skip -// // else increase i and square t2m and go again -// // algorithm runtime should only be max the number of bits in modulus - -// for _ in 0..MOD_BITS { -// if (__eq(t, one)) { -// found_root = true; -// break; -// } -// let mut t2m = t; -// // while loop time -// let i = __tonelli_shanks_sqrt_inner_loop_check(params, t2m, 0); -// let mut j = m - i - 1; -// b = c; -// for _ in 0..j { // how big -// if (j == 0) { -// break; -// } -// b = __mul(params, b, b); -// //j -= 1; -// } -// c = __mul(params, b, b); -// t = __mul(params, t, c); -// r = __mul(params, r, b); -// m = i; -// } -// } -// let mut result = std::option::Option { _value: r, _is_some: found_root }; -// result -// } +/** +* @brief compute a modular square root using the Tonelli-Shanks algorithm +* @details only use for prime fields! Function may infinite loop if used for non-prime fields +* @note this is unconstrained fn. To constrain a square root, validate that output^2 = self +* TODO: create fn that constrains nonexistence of square root (i.e. find x where x^2 = -self) +**/ +unconstrained pub(crate) fn __tonelli_shanks_sqrt(params: P, input: [Field; N]) -> std::option::Option<[Field; N]> { + // Tonelli-shanks algorithm begins by finding a field element Q and integer S, + // such that (p - 1) = Q.2^{s} + // We can compute the square root of a, by considering a^{(Q + 1) / 2} = R + // Once we have found such an R, we have + // R^{2} = a^{Q + 1} = a^{Q}a + // If a^{Q} = 1, we have found our square root. + // Otherwise, we have a^{Q} = t, where t is a 2^{s-1}'th root of unity. + // This is because t^{2^{s-1}} = a^{Q.2^{s-1}}. + // We know that (p - 1) = Q.w^{s}, therefore t^{2^{s-1}} = a^{(p - 1) / 2} + // From Euler's criterion, if a is a quadratic residue, a^{(p - 1) / 2} = 1 + // i.e. t^{2^{s-1}} = 1 + // To proceed with computing our square root, we want to transform t into a smaller subgroup, + // specifically, the (s-2)'th roots of unity. + // We do this by finding some value b,such that + // (t.b^2)^{2^{s-2}} = 1 and R' = R.b + // Finding such a b is trivial, because from Euler's criterion, we know that, + // for any quadratic non-residue z, z^{(p - 1) / 2} = -1 + // i.e. z^{Q.2^{s-1}} = -1 + // => z^Q is a 2^{s-1}'th root of -1 + // => z^{Q^2} is a 2^{s-2}'th root of -1 + // Since t^{2^{s-1}} = 1, we know that t^{2^{s - 2}} = -1 + // => t.z^{Q^2} is a 2^{s - 2}'th root of unity. + // We can iteratively transform t into ever smaller subgroups, until t = 1. + // At each iteration, we need to find a new value for b, which we can obtain + // by repeatedly squaring z^{Q} + let one_u60: U60Repr = unsafe { + U60Repr::one() + }; + let primitive_root_log_size = __primitive_root_log_size::<_, MOD_BITS>(params); + let mut Q = (params.modulus_u60 - one_u60).shr(primitive_root_log_size - 1); + let Q_minus_one_over_two_u60 = (Q - one_u60).shr(2); + let Q_minus_one_over_two: [Field; N] = U60Repr::into(Q_minus_one_over_two_u60); + let mut z = __multiplicative_generator::<_, MOD_BITS>(params); // the generator is a non-residue + let mut b = __pow::<_, MOD_BITS>(params, input, Q_minus_one_over_two); + let mut r = __mul::<_, MOD_BITS>(params, input, b); + let mut t = __mul::<_, MOD_BITS>(params, r, b); + let mut check: [Field; N] = t; + for _ in 0..primitive_root_log_size - 1 { + check = __mul::<_, MOD_BITS>(params, check, check); + } + let mut found_root = false; + let one: [Field; N] = __one::(); + if (__eq(check, one) == false) {} else { + let mut t1 = __pow::<_, MOD_BITS>(params, z, Q_minus_one_over_two); + let mut t2 = __mul::<_, MOD_BITS>(params, t1, z); + let mut c = __mul::<_, MOD_BITS>(params, t2, t1); + let mut m: u32 = primitive_root_log_size; + // tonelli shanks inner 1 + // (if t2m == 1) then skip + // else increase i and square t2m and go again + // algorithm runtime should only be max the number of bits in modulus + + for _ in 0..MOD_BITS { + if (__eq(t, one)) { + found_root = true; + break; + } + let mut t2m = t; + // while loop time + let i = __tonelli_shanks_sqrt_inner_loop_check::<_, MOD_BITS>(params, t2m, 0); + let mut j = m - i - 1; + b = c; + for _ in 0..j { // how big + if (j == 0) { + break; + } + b = __mul(params, b, b); + //j -= 1; + } + c = __mul::<_, MOD_BITS>(params, b, b); + t = __mul::<_, MOD_BITS>(params, t, c); + r = __mul::<_, MOD_BITS>(params, r, b); + m = i; + } + } + let mut result = std::option::Option { _value: r, _is_some: found_root }; + result +} From c42a40b7b27e8d610259bf139b9ee7e94f41e5d2 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Tue, 22 Oct 2024 17:17:56 +0100 Subject: [PATCH 17/29] option --- src/runtime_bignum.nr | 13 ++++--------- src/runtime_bignum_test.nr | 8 ++++---- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index 3021e71f..aa83b660 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -56,7 +56,7 @@ pub(crate) trait RuntimeBigNumTrait { fn __batch_invert(x: [Self; M]) -> [Self; M]; unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; - unconstrained fn __tonelli_shanks_sqrt(self) -> (bool, Self); + fn __tonelli_shanks_sqrt(self) -> std::option::Option; fn __compute_quadratic_expression( params: BigNumParams, @@ -271,18 +271,13 @@ impl RuntimeBigNumTrait for RuntimeB all_limbs.map(|limbs| Self { limbs, params }) } - // @dev We intentionally don't use std::option::Option, because the Option::none() case doesn't propagate the `params`, so the code breaks. Specifically, the code stops evaluating modulus_bits = self.params.modulus_bits_getter() as constant, which then breaks calls to `validate_in_range()` (e.g. via calls to `==` on `self`), because `validate_in_range` calls `assert_max_bit_size` on a value derived from `modulus_bits`. I'm not sure why it stops evaluating the getter's return value as constant if we return a std::Option, really. - unconstrained fn __tonelli_shanks_sqrt(self) -> (bool, Self) { + // UNCONSTRAINED! (Hence `__` prefix). + fn __tonelli_shanks_sqrt(self) -> std::option::Option { let params = self.params; let maybe_limbs = unsafe { __tonelli_shanks_sqrt(params, self.limbs) }; - let result: (bool, Self) = if maybe_limbs.is_some() { - (true, Self { limbs: maybe_limbs.unwrap_unchecked(), params }) - } else { - (false, Self::new(params)) - }; - result + maybe_limbs.map(|limbs| Self { limbs, params }) } // UNCONSTRAINED! (Hence `__` prefix). diff --git a/src/runtime_bignum_test.nr b/src/runtime_bignum_test.nr index 05652a2c..aa451a23 100644 --- a/src/runtime_bignum_test.nr +++ b/src/runtime_bignum_test.nr @@ -510,11 +510,11 @@ fn test_sqrt_BN() { let x = RuntimeBigNum { limbs: [9, 0, 0], params }; - let (_, maybe_sqrt_x) = unsafe { - x.__tonelli_shanks_sqrt() - }; + let maybe_sqrt_x = x.__tonelli_shanks_sqrt(); + + let sqrt_x = maybe_sqrt_x.unwrap(); - assert(maybe_sqrt_x * maybe_sqrt_x == x); + assert(sqrt_x * sqrt_x == x); assert(x == x); // This was breaking for a while, because a previous version of RuntimeBigNum::__tonelli_shanks_sqrt() was returning an Option. My theory is that this meant Option:none() wasn't propagating the params anymore, which for some reason was causing the params of x to no-longer be evaluated as constant, which is strange. } From d7558da417456e4f55a0e857eb7cc4ca1672dcb7 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Tue, 22 Oct 2024 17:38:21 +0100 Subject: [PATCH 18/29] tidy --- src/bignum_test.nr | 1 - src/fields/U1024.nr | 1 - src/fields/U2048.nr | 1 - src/fields/U256.nr | 1 - src/fields/U384.nr | 1 - src/fields/U4096.nr | 1 - src/fields/U512.nr | 1 - src/fields/U768.nr | 1 - src/fields/U8192.nr | 1 - src/fields/bls12_377Fq.nr | 1 - src/fields/bls12_377Fr.nr | 1 - src/fields/bls12_381Fq.nr | 1 - src/fields/bls12_381Fr.nr | 1 - src/fields/bn254Fq.nr | 1 - src/fields/ed25519Fq.nr | 1 - src/fields/ed25519Fr.nr | 1 - src/fields/mnt4_753Fq.nr | 2 +- src/fields/mnt4_753Fr.nr | 3 +-- src/fields/mnt6_753Fq.nr | 2 +- src/fields/mnt6_753Fr.nr | 2 +- src/fields/pallasFq.nr | 1 - src/fields/pallasFr.nr | 1 - src/fields/secp256k1Fq.nr | 1 - src/fields/secp256k1Fr.nr | 1 - src/fields/secp256r1Fq.nr | 1 - src/fields/secp256r1Fr.nr | 1 - src/fields/secp384r1Fq.nr | 1 - src/fields/secp384r1Fr.nr | 1 - src/fields/vestaFq.nr | 1 - src/fields/vestaFr.nr | 1 - src/lib.nr | 2 +- src/params.nr | 4 ---- src/runtime_bignum.nr | 10 ++++++++++ src/runtime_bignum_test.nr | 3 --- 34 files changed, 15 insertions(+), 39 deletions(-) diff --git a/src/bignum_test.nr b/src/bignum_test.nr index 23931e04..5002fed2 100644 --- a/src/bignum_test.nr +++ b/src/bignum_test.nr @@ -20,7 +20,6 @@ fn silence_warning() { global TEST_2048_PARAMS: BigNumParams<18, 2048> = BigNumParams { has_multiplicative_inverse: false, - // modulus_bits_getter: || 2048, modulus: [ 0xc0a197a5ae0fcdceb052c9732614fe, 0x656ae034423283422243918ab83be3, 0x6bf590da48a7c1070b7d5aabaac678, 0x0cce39f530238b606f24b296e2bda9, 0x01e1fef9bb9c1c3ead98f226f1bfa0, 0xad8c1c816e12e0ed1379055e373abf, 0xcebe80e474f753aa9d1461c435123d, 0xaee5a18ceedef88d115a8b93c167ad, 0x268ba83c4a65c4307427fc495d9e44, 0xdd2777926848667b7df79f342639d4, 0xf455074c96855ca0068668efe7da3d, 0x5ddba6b30bbc168bfb3a1225f27d65, 0x591fec484f36707524133bcd6f4258, 0x59641b756766aeebe66781dd01d062, 0x58bc5eaff4b165e142bf9e2480eebb, 0x667a3964f08e06df772ce64b229a72, 0x9c1fdb18907711bfe3e3c1cf918395, 0xb8 ], diff --git a/src/fields/U1024.nr b/src/fields/U1024.nr index 95d48c08..a5374f96 100644 --- a/src/fields/U1024.nr +++ b/src/fields/U1024.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<9, 1025> for U1024Params { global U1024_PARAMS: BigNumParams<9, 1025> = BigNumParams { has_multiplicative_inverse: false, - // modulus_bits_getter: || 1025, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000000000000000 ], diff --git a/src/fields/U2048.nr b/src/fields/U2048.nr index a8bc6aae..9bf83b10 100644 --- a/src/fields/U2048.nr +++ b/src/fields/U2048.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<18, 2049> for U2048Params { global U2048_PARAMS: BigNumParams<18, 2049> = BigNumParams { has_multiplicative_inverse: false, - // modulus_bits_getter: || 2049, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100 ], diff --git a/src/fields/U256.nr b/src/fields/U256.nr index 3ebf219a..4922c462 100644 --- a/src/fields/U256.nr +++ b/src/fields/U256.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<3, 257> for U256Params { global U256_PARAMS: BigNumParams<3, 257> = BigNumParams { has_multiplicative_inverse: false, - // modulus_bits_getter: || 257, modulus: [ 0x00, 0x00, 0x010000 ], diff --git a/src/fields/U384.nr b/src/fields/U384.nr index fc23929a..0d58e8c8 100644 --- a/src/fields/U384.nr +++ b/src/fields/U384.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<4, 385> for U384_Params { global U384_PARAMS: BigNumParams<4, 385> = BigNumParams { has_multiplicative_inverse: false, - // modulus_bits_getter: || 385, modulus: [ 0x00, 0x00, 0x00, 0x01000000 ], diff --git a/src/fields/U4096.nr b/src/fields/U4096.nr index 6fe04000..1f80c3ff 100644 --- a/src/fields/U4096.nr +++ b/src/fields/U4096.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<35, 4097> for U4096Params { global U4096_PARAMS: BigNumParams<35, 4097> = BigNumParams { has_multiplicative_inverse: false, - // modulus_bits_getter: || 4097, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000 ], diff --git a/src/fields/U512.nr b/src/fields/U512.nr index 28d4d756..4e3894f8 100644 --- a/src/fields/U512.nr +++ b/src/fields/U512.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<5, 513> for U512Params { global U512_PARAMS: BigNumParams<5, 513> = BigNumParams { has_multiplicative_inverse: false, - // modulus_bits_getter: || 513, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x0100000000 ], diff --git a/src/fields/U768.nr b/src/fields/U768.nr index 8c6118f5..bcd5405e 100644 --- a/src/fields/U768.nr +++ b/src/fields/U768.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<7, 769> for U768Params { global U768_PARAMS: BigNumParams<7, 769> = BigNumParams { has_multiplicative_inverse: false, - // modulus_bits_getter: || 769, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000000000 ], diff --git a/src/fields/U8192.nr b/src/fields/U8192.nr index 92bccf56..f5bca5e1 100644 --- a/src/fields/U8192.nr +++ b/src/fields/U8192.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<69, 8193> for U8192Params { global U8192_PARAMS: BigNumParams<69, 8193> = BigNumParams { has_multiplicative_inverse: false, - // modulus_bits_getter: || 8193, modulus: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000 ], diff --git a/src/fields/bls12_377Fq.nr b/src/fields/bls12_377Fq.nr index adc8a8ff..843af29c 100644 --- a/src/fields/bls12_377Fq.nr +++ b/src/fields/bls12_377Fq.nr @@ -30,7 +30,6 @@ impl BigNumParamsGetter<4, 377> for BLS12_377_Fq_Params { pub global BLS12_377_Fq_PARAMS: BigNumParams<4, 377> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 377, modulus: [ 0x0b5d44300000008508c00000000001, 0xd9f300f5138f1ef3622fba09480017, 0x4617c510eac63b05c06ca1493b1a22, 0x01ae3a ], diff --git a/src/fields/bls12_377Fr.nr b/src/fields/bls12_377Fr.nr index 8ed2667b..cc0404ab 100644 --- a/src/fields/bls12_377Fr.nr +++ b/src/fields/bls12_377Fr.nr @@ -31,7 +31,6 @@ impl BigNumParamsGetter<3, 253> for BLS12_377_Fr_Params { global BLS12_377_Fr_PARAMS: BigNumParams<3, 253> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 253, modulus: [ 0xaa76fed00000010a11800000000001, 0x655e9a2ca55660b44d1e5c37b00159, 0x12ab ], diff --git a/src/fields/bls12_381Fq.nr b/src/fields/bls12_381Fq.nr index 3180dce8..d7d2079c 100644 --- a/src/fields/bls12_381Fq.nr +++ b/src/fields/bls12_381Fq.nr @@ -28,7 +28,6 @@ impl BigNumParamsGetter<4, 381> for BLS12_381_Fq_Params { global BLS12_381_Fq_PARAMS: BigNumParams<4, 381> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 381, modulus: [ 0xabfffeb153ffffb9feffffffffaaab, 0x4b84f38512bf6730d2a0f6b0f6241e, 0xea397fe69a4b1ba7b6434bacd76477, 0x1a0111 ], diff --git a/src/fields/bls12_381Fr.nr b/src/fields/bls12_381Fr.nr index 9643503d..0b359dcd 100644 --- a/src/fields/bls12_381Fr.nr +++ b/src/fields/bls12_381Fr.nr @@ -28,7 +28,6 @@ impl BigNumParamsGetter<3, 255> for BLS12_381_Fr_Params { global BLS12_381_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 255, modulus: [ 0xbda402fffe5bfeffffffff00000001, 0xa753299d7d483339d80809a1d80553, 0x73ed ], diff --git a/src/fields/bn254Fq.nr b/src/fields/bn254Fq.nr index 0efc9852..ba12593c 100644 --- a/src/fields/bn254Fq.nr +++ b/src/fields/bn254Fq.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<3, 254> for BN254_Fq_Params { global BN254_Fq_PARAMS: BigNumParams<3, 254> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 254, modulus: [ 0x816a916871ca8d3c208c16d87cfd47, 0x4e72e131a029b85045b68181585d97, 0x3064 ], diff --git a/src/fields/ed25519Fq.nr b/src/fields/ed25519Fq.nr index a5723341..24a39572 100644 --- a/src/fields/ed25519Fq.nr +++ b/src/fields/ed25519Fq.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<3, 255> for ED25519_Fq_Params { global ED25519_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 255, modulus: [ 0xffffffffffffffffffffffffffffed, 0xffffffffffffffffffffffffffffff, 0x7fff ], diff --git a/src/fields/ed25519Fr.nr b/src/fields/ed25519Fr.nr index fa4f42e5..5dd6070c 100644 --- a/src/fields/ed25519Fr.nr +++ b/src/fields/ed25519Fr.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<3, 255> for ED25519_Fr_Params { global ED25519_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 253, modulus: [ 0xdef9dea2f79cd65812631a5cf5d3ed, 0x14, 0x1000 ], diff --git a/src/fields/mnt4_753Fq.nr b/src/fields/mnt4_753Fq.nr index 8f55df3a..0e1c5273 100644 --- a/src/fields/mnt4_753Fq.nr +++ b/src/fields/mnt4_753Fq.nr @@ -33,7 +33,7 @@ impl BigNumParamsGetter<7, 753> for MNT4_753_Fq_Params { global MNT4_753_Fq_PARAMS: BigNumParams<7, 753> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 753, + modulus: [ 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 ], diff --git a/src/fields/mnt4_753Fr.nr b/src/fields/mnt4_753Fr.nr index 05d50c05..aa010a4d 100644 --- a/src/fields/mnt4_753Fr.nr +++ b/src/fields/mnt4_753Fr.nr @@ -32,8 +32,7 @@ impl BigNumParamsGetter<7, 753> for MNT4_753_Fr_Params { } global MNT4_753_Fr_PARAMS: BigNumParams<7, 753> = BigNumParams { - has_multiplicative_inverse: true, - // modulus_bits_getter: || 753, + has_multiplicative_inverse: true, modulus: [ 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 ], diff --git a/src/fields/mnt6_753Fq.nr b/src/fields/mnt6_753Fq.nr index 031d2143..29e9a0d3 100644 --- a/src/fields/mnt6_753Fq.nr +++ b/src/fields/mnt6_753Fq.nr @@ -33,7 +33,7 @@ impl BigNumParamsGetter<7, 753> for MNT6_753_Fq_Params { global MNT6_753_Fq_PARAMS: BigNumParams<7, 753> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 753, + modulus: [ 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 ], diff --git a/src/fields/mnt6_753Fr.nr b/src/fields/mnt6_753Fr.nr index 5d20a489..d487164f 100644 --- a/src/fields/mnt6_753Fr.nr +++ b/src/fields/mnt6_753Fr.nr @@ -33,7 +33,7 @@ impl BigNumParamsGetter<7, 753> for MNT6_753_Fr_Params { global MNT6_753_Fr_PARAMS: BigNumParams<7, 753> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 753, + modulus: [ 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 ], diff --git a/src/fields/pallasFq.nr b/src/fields/pallasFq.nr index 9faebe59..ae60bcbb 100644 --- a/src/fields/pallasFq.nr +++ b/src/fields/pallasFq.nr @@ -27,7 +27,6 @@ impl BigNumParamsGetter<3, 255> for Pallas_Fq_Params { global Pallas_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 255, modulus: [ 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 ], diff --git a/src/fields/pallasFr.nr b/src/fields/pallasFr.nr index 7f302af6..b7bf1380 100644 --- a/src/fields/pallasFr.nr +++ b/src/fields/pallasFr.nr @@ -27,7 +27,6 @@ impl BigNumParamsGetter<3, 255> for Pallas_Fr_Params { global Pallas_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 255, modulus: [ 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 ], diff --git a/src/fields/secp256k1Fq.nr b/src/fields/secp256k1Fq.nr index e2a93c09..7321a003 100644 --- a/src/fields/secp256k1Fq.nr +++ b/src/fields/secp256k1Fq.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<3, 256> for Secp256k1_Fq_Params { global Secp256k1_Fq_PARAMS: BigNumParams<3, 256> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 256, modulus: [ 0xfffffffffffffffffffffefffffc2f, 0xffffffffffffffffffffffffffffff, 0xffff ], diff --git a/src/fields/secp256k1Fr.nr b/src/fields/secp256k1Fr.nr index 224a6769..2e846558 100644 --- a/src/fields/secp256k1Fr.nr +++ b/src/fields/secp256k1Fr.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<3, 256> for Secp256k1_Fr_Params { global Secp256k1_Fr_PARAMS: BigNumParams<3, 256> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 256, modulus: [ 0xaedce6af48a03bbfd25e8cd0364141, 0xfffffffffffffffffffffffffffeba, 0xffff ], diff --git a/src/fields/secp256r1Fq.nr b/src/fields/secp256r1Fq.nr index e02de4c4..6465cd22 100644 --- a/src/fields/secp256r1Fq.nr +++ b/src/fields/secp256r1Fq.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<3, 265> for Secp256r1_Fq_Params { global Secp256r1_Fq_PARAMS: BigNumParams<3, 265> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 256, modulus: [ 0xffffffffffffffffffffffff, 0xffff00000001000000000000000000, 0xffff ], diff --git a/src/fields/secp256r1Fr.nr b/src/fields/secp256r1Fr.nr index 058708b1..9b8fea4f 100644 --- a/src/fields/secp256r1Fr.nr +++ b/src/fields/secp256r1Fr.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<3, 256> for Secp256r1_Fr_Params { global Secp256r1_Fr_PARAMS: BigNumParams<3, 256> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 256, modulus: [ 0xe6faada7179e84f3b9cac2fc632551, 0xffff00000000ffffffffffffffffbc, 0xffff ], diff --git a/src/fields/secp384r1Fq.nr b/src/fields/secp384r1Fq.nr index a0e61e10..26e288a2 100644 --- a/src/fields/secp384r1Fq.nr +++ b/src/fields/secp384r1Fq.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<4, 384> for Secp384r1_Fq_Params { global Secp384r1_Fq_PARAMS: BigNumParams<4, 384> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 384, modulus: [ 0xffffff0000000000000000ffffffff, 0xfffffffffffffffffffffffffffeff, 0xffffffffffffffffffffffffffffff, 0xffffff ], diff --git a/src/fields/secp384r1Fr.nr b/src/fields/secp384r1Fr.nr index 03488aef..b6585248 100644 --- a/src/fields/secp384r1Fr.nr +++ b/src/fields/secp384r1Fr.nr @@ -12,7 +12,6 @@ impl BigNumParamsGetter<4, 384> for Secp384r1_Fr_Params { global Secp384r1_Fr_PARAMS: BigNumParams<4, 384> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 384, modulus: [ 0x1a0db248b0a77aecec196accc52973, 0xffffffffffffc7634d81f4372ddf58, 0xffffffffffffffffffffffffffffff, 0xffffff ], diff --git a/src/fields/vestaFq.nr b/src/fields/vestaFq.nr index dcc03778..8c2f6d3b 100644 --- a/src/fields/vestaFq.nr +++ b/src/fields/vestaFq.nr @@ -28,7 +28,6 @@ impl BigNumParamsGetter<3, 255> for Vesta_Fq_Params { global Vesta_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 255, modulus: [ 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 ], diff --git a/src/fields/vestaFr.nr b/src/fields/vestaFr.nr index 8c253de3..05b0e9d4 100644 --- a/src/fields/vestaFr.nr +++ b/src/fields/vestaFr.nr @@ -28,7 +28,6 @@ impl BigNumParamsGetter<3, 255> for Vesta_Fr_Params { global Vesta_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { has_multiplicative_inverse: true, - // modulus_bits_getter: || 255, modulus: [ 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 ], diff --git a/src/lib.nr b/src/lib.nr index e55bdbbb..63caa51b 100644 --- a/src/lib.nr +++ b/src/lib.nr @@ -6,7 +6,7 @@ pub mod params; pub mod bignum; pub mod runtime_bignum; -// Functions on structs +// Free functions called by structs pub(crate) mod unconstrained_ops; pub(crate) mod constrained_ops; pub(crate) mod unconstrained_helpers; diff --git a/src/params.nr b/src/params.nr index 57b555ec..fcf8187b 100644 --- a/src/params.nr +++ b/src/params.nr @@ -3,10 +3,6 @@ use crate::utils::u60_representation::U60Repr; pub(crate) struct BigNumParams { has_multiplicative_inverse: bool, - // @brief modulus_bits = log2(modulus) rounded up - // This needs to be a comptime const, so that it can be used as an argument to std::field::assert_constant() - // modulus_bits_getter: fn () -> u32, - // @brief modulus: all BigNum operations are evaluated modulo this value modulus: [Field; N], diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index aa83b660..55b8b638 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -44,20 +44,30 @@ pub(crate) trait RuntimeBigNumTrait { unconstrained fn __eq(self, other: Self) -> bool; unconstrained fn __is_zero(self) -> bool; + // unconstrained fn __neg(self) -> Self; + // unconstrained fn __add(self, other: Self) -> Self; + // unconstrained fn __sub(self, other: Self) -> Self; + // unconstrained fn __mul(self, other: Self) -> Self; + // unconstrained fn __div(self, other: Self) -> Self; + // unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self); + // unconstrained fn __invmod(self) -> Self; + // unconstrained fn __pow(self, exponent: Self) -> Self; + // unconstrained fn __batch_invert(x: [Self; M]) -> [Self; M]; unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; fn __tonelli_shanks_sqrt(self) -> std::option::Option; + // unconstrained fn __compute_quadratic_expression( params: BigNumParams, lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], diff --git a/src/runtime_bignum_test.nr b/src/runtime_bignum_test.nr index aa451a23..4ad252a4 100644 --- a/src/runtime_bignum_test.nr +++ b/src/runtime_bignum_test.nr @@ -11,7 +11,6 @@ use crate::fields::bls12_377Fr::BLS12_377_Fr_Params; global TEST_2048_PARAMS: BigNumParams<18, 2048> = BigNumParams { has_multiplicative_inverse: false, - // modulus_bits_getter: || 2048, modulus: [ 0xc0a197a5ae0fcdceb052c9732614fe, 0x656ae034423283422243918ab83be3, 0x6bf590da48a7c1070b7d5aabaac678, 0x0cce39f530238b606f24b296e2bda9, 0x01e1fef9bb9c1c3ead98f226f1bfa0, 0xad8c1c816e12e0ed1379055e373abf, 0xcebe80e474f753aa9d1461c435123d, 0xaee5a18ceedef88d115a8b93c167ad, 0x268ba83c4a65c4307427fc495d9e44, 0xdd2777926848667b7df79f342639d4, 0xf455074c96855ca0068668efe7da3d, 0x5ddba6b30bbc168bfb3a1225f27d65, 0x591fec484f36707524133bcd6f4258, 0x59641b756766aeebe66781dd01d062, 0x58bc5eaff4b165e142bf9e2480eebb, 0x667a3964f08e06df772ce64b229a72, 0x9c1fdb18907711bfe3e3c1cf918395, 0xb8 ], @@ -515,6 +514,4 @@ fn test_sqrt_BN() { let sqrt_x = maybe_sqrt_x.unwrap(); assert(sqrt_x * sqrt_x == x); - - assert(x == x); // This was breaking for a while, because a previous version of RuntimeBigNum::__tonelli_shanks_sqrt() was returning an Option. My theory is that this meant Option:none() wasn't propagating the params anymore, which for some reason was causing the params of x to no-longer be evaluated as constant, which is strange. } From e7996a8bd8a39c5d0ccbd4b1cf601e212d901a00 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Tue, 22 Oct 2024 17:43:35 +0100 Subject: [PATCH 19/29] warnings --- src/bignum.nr | 3 +-- src/constrained_ops.nr | 14 +++++++------- src/runtime_bignum.nr | 3 +-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index 03b9fcec..645167e2 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -272,8 +272,7 @@ impl BigNumTrait for BigNum(params, self.limbs); + validate_in_range::<_, MOD_BITS>(self.limbs); } fn assert_is_not_equal(self, other: Self) { diff --git a/src/constrained_ops.nr b/src/constrained_ops.nr index 98544eb2..564369f9 100644 --- a/src/constrained_ops.nr +++ b/src/constrained_ops.nr @@ -121,7 +121,7 @@ pub(crate) fn derive_from_seed(bigfield_rhs_limbs); let mut result: [Field; N] = [0; N]; @@ -209,13 +209,13 @@ pub(crate) fn validate_in_field(params: P(params, compare); + validate_in_range::<_, MOD_BITS>(compare); } /** * @brief Validate a BigNum instance is correctly range constrained to contain no more than Params::modulus_bits() **/ -pub(crate) fn validate_in_range(params: P, limbs: [Field; N]) { +pub(crate) fn validate_in_range(limbs: [Field; N]) { for i in 0..(N - 1) { limbs[i].assert_max_bit_size(120); } @@ -255,7 +255,7 @@ pub(crate) fn validate_gt(params: P, __validate_gt_remainder(lhs, rhs) }; - validate_in_range::<_, MOD_BITS>(params, result); + validate_in_range::<_, MOD_BITS>(result); let borrow_shift = 0x1000000000000000000000000000000; let carry_shift = 0x1000000000000000000000000000000; @@ -280,7 +280,7 @@ pub(crate) fn neg(params: P, val: [F let (result, borrow_flags) = unsafe { __neg_with_flags(params, val) }; - validate_in_range::<_, MOD_BITS>(params, result); + validate_in_range::<_, MOD_BITS>(result); let modulus = params.modulus; let borrow_shift = 0x1000000000000000000000000000000; let result_limb = modulus[0] - val[0] - result[0] + (borrow_flags[0] as Field * borrow_shift); @@ -300,7 +300,7 @@ pub(crate) fn add(params: P, lhs: [F let (result, carry_flags, borrow_flags, overflow_modulus) = unsafe { __add_with_flags(params, lhs, rhs) }; - validate_in_range::<_, MOD_BITS>(params, result); + validate_in_range::<_, MOD_BITS>(result); let modulus = params.modulus; let borrow_shift = 0x1000000000000000000000000000000; let carry_shift = 0x1000000000000000000000000000000; @@ -332,7 +332,7 @@ pub(crate) fn sub(params: P, lhs: [F let (result, carry_flags, borrow_flags, underflow) = unsafe { __sub_with_flags(params, lhs, rhs) }; - validate_in_range::<_, MOD_BITS>(params, result); + validate_in_range::<_, MOD_BITS>(result); let modulus = params.modulus; let borrow_shift = 0x1000000000000000000000000000000; let carry_shift = 0x1000000000000000000000000000000; diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index 55b8b638..04ce019a 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -340,8 +340,7 @@ impl RuntimeBigNumTrait for RuntimeB } fn validate_in_range(self) { - let params = self.params; - validate_in_range::<_, MOD_BITS>(params, self.limbs); + validate_in_range::<_, MOD_BITS>(self.limbs); } fn assert_is_not_equal(self, other: Self) { From 43112783cae220d9e96afb87585f3d4f5f9fabb2 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Tue, 22 Oct 2024 17:50:21 +0100 Subject: [PATCH 20/29] warnings --- src/bignum.nr | 6 ++---- src/constrained_ops.nr | 6 +++--- src/expressions.nr | 2 +- src/runtime_bignum.nr | 8 ++++---- src/runtime_bignum_test.nr | 4 ++-- src/serialization.nr | 6 ++---- 6 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index 645167e2..94d237d7 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -119,13 +119,11 @@ impl BigNumTrait for BigNum(x: [u8; NBytes]) -> Self { - let params = Params::get_params(); - Self { limbs: from_be_bytes::<_, MOD_BITS, _>(params, x) } + Self { limbs: from_be_bytes::<_, MOD_BITS, _>(x) } } fn to_le_bytes(self) -> [u8; NBytes] { - let params = Params::get_params(); - to_le_bytes::<_, MOD_BITS, _>(params, self.limbs) + to_le_bytes::<_, MOD_BITS, _>(self.limbs) } fn modulus() -> Self { diff --git a/src/constrained_ops.nr b/src/constrained_ops.nr index 564369f9..22d7b0fd 100644 --- a/src/constrained_ops.nr +++ b/src/constrained_ops.nr @@ -236,7 +236,7 @@ pub(crate) fn validate_in_range(limbs: [Field; N] * Note: doesn't this mean that final_limb_bits should be constrained to be 126 bits, not modulus_bits() - ((N - 1) * 120) + 6? * TODO: think about this more! we want the range constraint we apply to be as small as allowable as this is more efficient **/ -pub(crate) fn validate_quotient_in_range(params: P, limbs: [Field; N]) { +pub(crate) fn validate_quotient_in_range(limbs: [Field; N]) { for i in 0..(N) { limbs[i].assert_max_bit_size(120); } @@ -246,7 +246,7 @@ pub(crate) fn validate_quotient_in_range(params: } // validate that lhs - rhs does not underflow i.e. lhs > rhs -pub(crate) fn validate_gt(params: P, lhs: [Field; N], rhs: [Field; N]) { +pub(crate) fn validate_gt(lhs: [Field; N], rhs: [Field; N]) { // so we do... p - x - r = 0 and there might be borrow flags // a - b = r @@ -409,7 +409,7 @@ pub(crate) fn udiv_mod( ); // we need (remainder < divisor) // implies (divisor - remainder > 0) - validate_gt::<_, MOD_BITS>(params, divisor, remainder); + validate_gt::<_, MOD_BITS>(divisor, remainder); (quotient, remainder) } diff --git a/src/expressions.nr b/src/expressions.nr index 9bff9f3e..bdd01d73 100644 --- a/src/expressions.nr +++ b/src/expressions.nr @@ -312,7 +312,7 @@ pub(crate) fn evaluate_quadratic_expression< }; // constrain the quotient to be in the range [0, ..., 2^{m} - 1], where `m` is log2(modulus) rounded up. // Additionally, validate quotient limbs are also in the range [0, ..., 2^{120} - 1] - validate_quotient_in_range::<_, MOD_BITS>(params, quotient); + validate_quotient_in_range::<_, MOD_BITS>(quotient); // TODO, validate we do not overflow N2 when multiplying and N when adding // (should be a compile-time check...unconstrained function?) diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index 04ce019a..5e9c7dcd 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -34,7 +34,7 @@ pub(crate) trait RuntimeBigNumTrait { fn to_le_bytes(self) -> [u8; NBytes]; fn modulus(self) -> Self; - fn modulus_bits(self) -> u32; + fn modulus_bits() -> u32; fn num_limbs() -> u32; // fn get(self) -> [Field]; fn get_limbs(self) -> [Field; N]; @@ -143,11 +143,11 @@ impl RuntimeBigNumTrait for RuntimeB } fn from_be_bytes(params: BigNumParams, x: [u8; NBytes]) -> Self { - Self { limbs: from_be_bytes::<_, MOD_BITS, _>(params, x), params } + Self { limbs: from_be_bytes::<_, MOD_BITS, _>(x), params } } fn to_le_bytes(self) -> [u8; NBytes] { - to_le_bytes::<_, MOD_BITS, _>(self.params, self.limbs) + to_le_bytes::<_, MOD_BITS, _>(self.limbs) } fn modulus(self) -> Self { @@ -155,7 +155,7 @@ impl RuntimeBigNumTrait for RuntimeB Self { limbs: params.modulus, params } } - fn modulus_bits(self) -> u32 { + fn modulus_bits() -> u32 { MOD_BITS } diff --git a/src/runtime_bignum_test.nr b/src/runtime_bignum_test.nr index 4ad252a4..c772ca4f 100644 --- a/src/runtime_bignum_test.nr +++ b/src/runtime_bignum_test.nr @@ -131,7 +131,7 @@ fn test_add_modulus_limit() { let a: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(p), params }; - let two_pow_modulus_bits_minus_one: U60Repr<$N, 2> = unsafe{ one.shl(a.modulus_bits()) - one }; + let two_pow_modulus_bits_minus_one: U60Repr<$N, 2> = unsafe{ one.shl($MOD_BITS) - one }; let b: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(two_pow_modulus_bits_minus_one), params }; @@ -148,7 +148,7 @@ fn test_add_modulus_overflow() { let a: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(p + one), params }; - let mut two_pow_modulus_bits_minus_one: U60Repr<$N, 2> = unsafe{ one.shl(a.modulus_bits()) - one }; + let mut two_pow_modulus_bits_minus_one: U60Repr<$N, 2> = unsafe{ one.shl($MOD_BITS) - one }; let b: RuntimeBigNum<$N, $MOD_BITS> = RuntimeBigNum { limbs: U60Repr::into(two_pow_modulus_bits_minus_one), params }; diff --git a/src/serialization.nr b/src/serialization.nr index 96a852e4..538bfbdb 100644 --- a/src/serialization.nr +++ b/src/serialization.nr @@ -1,12 +1,10 @@ -use crate::params::BigNumParams as P; - /** * @brief construct a BigNum instance out of an array of bytes in BIG ENDIAN format * @description: each 120-bit limb represents 15 bytes, we require that the size of the byte array * is precisely large enough to cover MOD_BITS * @param x: input byte array **/ -pub(crate) fn from_be_bytes(params: P, x: [u8; NBytes]) -> [Field; N] { +pub(crate) fn from_be_bytes(x: [u8; NBytes]) -> [Field; N] { let num_bits = NBytes * 8; assert(num_bits >= MOD_BITS); assert(num_bits - MOD_BITS < 8); @@ -42,7 +40,7 @@ pub(crate) fn from_be_bytes(para result } -pub(crate) fn to_le_bytes(params: P, val: [Field; N]) -> [u8; NBytes] { +pub(crate) fn to_le_bytes(val: [Field; N]) -> [u8; NBytes] { let nbytes = (MOD_BITS / 8) + (MOD_BITS % 8 != 0) as u32; assert(nbytes <= NBytes); From dd0a7a3be1113e019747057f51077426bb32a252 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Tue, 22 Oct 2024 18:08:57 +0100 Subject: [PATCH 21/29] fmt --- src/bignum.nr | 2 +- src/constrained_ops.nr | 11 +++++++++-- src/params.nr | 6 +----- src/unconstrained_helpers.nr | 12 ++++++++++-- src/unconstrained_ops.nr | 33 +++++++++++---------------------- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index 94d237d7..0c68a6ff 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -7,7 +7,7 @@ use crate::constrained_ops::{ }; use crate::unconstrained_ops::{ __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, - __batch_invert, __batch_invert_slice , __tonelli_shanks_sqrt + __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt }; use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}; use crate::serialization::{from_be_bytes, to_le_bytes}; diff --git a/src/constrained_ops.nr b/src/constrained_ops.nr index 22d7b0fd..215fde49 100644 --- a/src/constrained_ops.nr +++ b/src/constrained_ops.nr @@ -34,7 +34,10 @@ use crate::expressions::evaluate_quadratic_expression; * We use a hash function that can be modelled as a random oracle * This function *should* produce an output that is a uniformly randomly distributed value modulo BigNum::modulus() **/ -pub(crate) fn derive_from_seed(params: P, seed: [u8; SeedBytes]) -> [Field; N] { +pub(crate) fn derive_from_seed( + params: P, + seed: [u8; SeedBytes] +) -> [Field; N] { let mut rolling_seed: [u8; SeedBytes + 1] = [0; SeedBytes + 1]; for i in 0..SeedBytes { rolling_seed[i] = seed[i]; @@ -427,7 +430,11 @@ pub(crate) fn udiv(params: P, numera * * i.e. 1. numerator % divisor = return value **/ -pub(crate) fn umod(params: P, numerator: [Field; N], divisor: [Field; N]) -> [Field; N] { +pub(crate) fn umod( + params: P, + numerator: [Field; N], + divisor: [Field; N] +) -> [Field; N] { udiv_mod::<_, MOD_BITS>(params, numerator, divisor).1 } diff --git a/src/params.nr b/src/params.nr index fcf8187b..60f98696 100644 --- a/src/params.nr +++ b/src/params.nr @@ -23,11 +23,7 @@ pub(crate) trait BigNumParamsGetter { } impl BigNumParams { - pub fn new( - has_multiplicative_inverse: bool, - modulus: [Field; N], - redc_param: [Field; N] - ) -> Self { + pub fn new(has_multiplicative_inverse: bool, modulus: [Field; N], redc_param: [Field; N]) -> Self { Self { has_multiplicative_inverse, modulus, diff --git a/src/unconstrained_helpers.nr b/src/unconstrained_helpers.nr index 7cf4d397..e80689de 100644 --- a/src/unconstrained_helpers.nr +++ b/src/unconstrained_helpers.nr @@ -88,7 +88,11 @@ unconstrained pub(crate) fn __neg_with_flags(para (result, borrow_flags) } -unconstrained pub(crate) fn __add_with_flags(params: P, lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [bool; N], [bool; N], bool) { +unconstrained pub(crate) fn __add_with_flags( + params: P, + lhs: [Field; N], + rhs: [Field; N] +) -> ([Field; N], [bool; N], [bool; N], bool) { let a_u60 : U60Repr = U60Repr::from(lhs); let b_u60 : U60Repr = U60Repr::from(rhs); let add_u60 = a_u60 + b_u60; @@ -134,7 +138,11 @@ unconstrained pub(crate) fn __add_with_flags(para (result, carry_flags, borrow_flags, overflow) } -unconstrained pub(crate) fn __sub_with_flags(params: P, lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [bool; N], [bool; N], bool) { +unconstrained pub(crate) fn __sub_with_flags( + params: P, + lhs: [Field; N], + rhs: [Field; N] +) -> ([Field; N], [bool; N], [bool; N], bool) { let a_u60 : U60Repr = U60Repr::from(lhs); let b_u60 : U60Repr = U60Repr::from(rhs); diff --git a/src/unconstrained_ops.nr b/src/unconstrained_ops.nr index 49585051..a7d7f92f 100644 --- a/src/unconstrained_ops.nr +++ b/src/unconstrained_ops.nr @@ -3,7 +3,8 @@ use crate::utils::split_bits; use crate::params::BigNumParams as P; use crate::unconstrained_helpers::{ - __barrett_reduction , __primitive_root_log_size, __multiplicative_generator, __tonelli_shanks_sqrt_inner_loop_check + __barrett_reduction, __primitive_root_log_size, __multiplicative_generator, + __tonelli_shanks_sqrt_inner_loop_check }; /** @@ -137,11 +138,7 @@ unconstrained pub(crate) fn __neg(params: P( - params: P, - lhs: [Field; N], - rhs: [Field; N] -) -> [Field; N] { +unconstrained pub(crate) fn __add(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { let x_u60 : U60Repr = U60Repr::from(lhs); let y_u60 : U60Repr = U60Repr::from(rhs); @@ -157,7 +154,11 @@ unconstrained pub(crate) fn __add( * @brief given inputs `x, y` compute 2p + x - y (unconstrained) * @description see `__neg` for why we use 2p instead of p **/ -unconstrained pub(crate) fn __sub(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { +unconstrained pub(crate) fn __sub( + params: P, + lhs: [Field; N], + rhs: [Field; N] +) -> [Field; N] { __add(params, lhs, __neg(params, rhs)) } @@ -180,20 +181,12 @@ unconstrained pub(crate) fn __mul_with_quotient(p (q, r) } -unconstrained pub(crate) fn __mul( - params: P, - lhs: [Field; N], - rhs: [Field; N] -) -> [Field; N] { +unconstrained pub(crate) fn __mul(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { let (_, b) = __mul_with_quotient::<_, MOD_BITS>(params, lhs, rhs); b } -unconstrained pub(crate) fn __div( - params: P, - numerator: [Field; N], - divisor: [Field; N] -) -> [Field; N] { +unconstrained pub(crate) fn __div(params: P, numerator: [Field; N], divisor: [Field; N]) -> [Field; N] { let inv_divisor = __invmod::<_, MOD_BITS>(params, divisor); __mul::<_, MOD_BITS>(params, numerator, inv_divisor) } @@ -250,11 +243,7 @@ unconstrained pub(crate) fn __invmod(params: P(params, val, exp) } -unconstrained pub(crate) fn __pow( - params: P, - val: [Field; N], - exponent: [Field; N] -) -> [Field; N] { +unconstrained pub(crate) fn __pow(params: P, val: [Field; N], exponent: [Field; N]) -> [Field; N] { let x: U60Repr = U60Repr::from(exponent); let num_bits = MOD_BITS + 1; From 70c48850764c57024bec8cda4d3875e518f306d2 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Tue, 22 Oct 2024 19:01:22 +0100 Subject: [PATCH 22/29] latest nightly --- src/bignum.nr | 104 ++++++++++++++++---------------- src/bignum_test.nr | 26 ++++---- src/params.nr | 18 +++--- src/runtime_bignum.nr | 94 ++++++++++++++--------------- src/unconstrained_ops.nr | 6 +- src/utils/u60_representation.nr | 22 +++---- 6 files changed, 137 insertions(+), 133 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index 0c68a6ff..3d01a8ea 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -13,47 +13,47 @@ use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expr use crate::serialization::{from_be_bytes, to_le_bytes}; pub struct BigNum { - limbs: [Field; N] + pub limbs: [Field; N] } pub(crate) trait BigNumTrait { // TODO: this crashes the compiler? v0.32 // fn default() -> Self { std::default::Default::default () } - fn new() -> Self; - fn one() -> Self; - fn derive_from_seed(seed: [u8; SeedBytes]) -> Self; - unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self; - fn from_slice(limbs: [Field]) -> Self; - fn from_array(limbs: [Field; N]) -> Self; - fn from_be_bytes(x: [u8; NBytes]) -> Self; - fn to_le_bytes(self) -> [u8; NBytes]; - - fn modulus() -> Self; - fn modulus_bits() -> u32; - fn num_limbs() -> u32; - // fn get(self) -> [Field]; - fn get_limbs(self) -> [Field; N]; - fn get_limb(self, idx: u32) -> Field; - fn set_limb(&mut self, idx: u32, value: Field); - - unconstrained fn __eq(self, other: Self) -> bool; - unconstrained fn __is_zero(self) -> bool; - - unconstrained fn __neg(self) -> Self; - unconstrained fn __add(self, other: Self) -> Self; - unconstrained fn __sub(self, other: Self) -> Self; - unconstrained fn __mul(self, other: Self) -> Self; - unconstrained fn __div(self, other: Self) -> Self; - unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self); - unconstrained fn __invmod(self) -> Self; - unconstrained fn __pow(self, exponent: Self) -> Self; - - unconstrained fn __batch_invert(to_invert: [Self; M]) -> [Self; M]; - unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; - - unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option; - - unconstrained fn __compute_quadratic_expression( + pub fn new() -> Self; + pub fn one() -> Self; + pub fn derive_from_seed(seed: [u8; SeedBytes]) -> Self; + unconstrained pub fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self; + pub fn from_slice(limbs: [Field]) -> Self; + pub fn from_array(limbs: [Field; N]) -> Self; + pub fn from_be_bytes(x: [u8; NBytes]) -> Self; + pub fn to_le_bytes(self) -> [u8; NBytes]; + + pub fn modulus() -> Self; + pub fn modulus_bits() -> u32; + pub fn num_limbs() -> u32; + // pub fn get(self) -> [Field]; + pub fn get_limbs(self) -> [Field; N]; + pub fn get_limb(self, idx: u32) -> Field; + pub fn set_limb(&mut self, idx: u32, value: Field); + + unconstrained pub fn __eq(self, other: Self) -> bool; + unconstrained pub fn __is_zero(self) -> bool; + + unconstrained pub fn __neg(self) -> Self; + unconstrained pub fn __add(self, other: Self) -> Self; + unconstrained pub fn __sub(self, other: Self) -> Self; + unconstrained pub fn __mul(self, other: Self) -> Self; + unconstrained pub fn __div(self, other: Self) -> Self; + unconstrained pub fn __udiv_mod(self, divisor: Self) -> (Self, Self); + unconstrained pub fn __invmod(self) -> Self; + unconstrained pub fn __pow(self, exponent: Self) -> Self; + + unconstrained pub fn __batch_invert(to_invert: [Self; M]) -> [Self; M]; + unconstrained pub fn __batch_invert_slice(to_invert: [Self]) -> [Self]; + + unconstrained pub fn __tonelli_shanks_sqrt(self) -> std::option::Option; + + unconstrained pub fn __compute_quadratic_expression( lhs: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs: [[Self; RHS_N]; NUM_PRODUCTS], @@ -62,7 +62,7 @@ pub(crate) trait BigNumTrait { add_flags: [bool; ADD_N] ) -> (Self, Self); - fn evaluate_quadratic_expression( + pub fn evaluate_quadratic_expression( lhs: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs: [[Self; RHS_N]; NUM_PRODUCTS], @@ -71,21 +71,21 @@ pub(crate) trait BigNumTrait { add_flags: [bool; ADD_N] ); - fn eq(self, other: Self) -> bool { self == other } - fn assert_is_not_equal(self, other: Self); - fn validate_in_range(self); - fn validate_in_field(self); - - fn neg(self) -> Self; - fn add(self, other: Self) -> Self { self + other } - fn sub(self, other: Self) -> Self { self - other } - fn mul(self, other: Self) -> Self { self * other } - fn div(self, other: Self) -> Self { self / other } - fn udiv_mod(self, divisor: Self) -> (Self, Self); - fn udiv(self, divisor: Self) -> Self; - fn umod(self, divisor: Self) -> Self; - - fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; + pub fn eq(self, other: Self) -> bool { self == other } + pub fn assert_is_not_equal(self, other: Self); + pub fn validate_in_range(self); + pub fn validate_in_field(self); + + pub fn neg(self) -> Self; + pub fn add(self, other: Self) -> Self { self + other } + pub fn sub(self, other: Self) -> Self { self - other } + pub fn mul(self, other: Self) -> Self { self * other } + pub fn div(self, other: Self) -> Self { self / other } + pub fn udiv_mod(self, divisor: Self) -> (Self, Self); + pub fn udiv(self, divisor: Self) -> Self; + pub fn umod(self, divisor: Self) -> Self; + + pub fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; } impl BigNumTrait for BigNum where Params: BigNumParamsGetter { diff --git a/src/bignum_test.nr b/src/bignum_test.nr index 5002fed2..cc40e247 100644 --- a/src/bignum_test.nr +++ b/src/bignum_test.nr @@ -267,8 +267,8 @@ fn test_add_BN() { b.limbs[0] -= 1; expected.limbs[0] -= 2; - let result = a.add(b); - assert(result.eq(expected)); + let result = a + b; + assert(result == expected); } #[test] @@ -279,8 +279,8 @@ fn test_sub_test_BN() { let mut expected: Fq = BigNum::modulus(); expected.limbs[0] -= 1; // p - 1 - let result = a.sub(b); - assert(result.eq(expected)); + let result = a - b; + assert(result == expected); } #[test] @@ -292,8 +292,8 @@ fn test_sub_modulus_limit() { let mut b: Fq = BigNum::modulus(); let mut expected = BigNum::new(); - let result = a.sub(b); - assert(result.eq(expected)); + let result = a - b; + assert(result == expected); } #[test(should_fail_with = "call to assert_max_bit_size")] @@ -304,8 +304,8 @@ fn test_sub_modulus_underflow() { b.limbs[0] += 1; let mut expected = BigNum::one(); - let result = a.sub(b); - assert(result.eq(expected)); + let result = a - b; + assert(result == expected); } #[test] @@ -317,8 +317,8 @@ fn test_add_modulus_limit() { let two_pow_254_minus_1: U60Repr<3, 2> = U60Repr::from([0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x3fff]); let a: Fq = BigNum { limbs: U60Repr::into(p) }; let b: Fq = BigNum { limbs: U60Repr::into(two_pow_254_minus_1) }; - let result = a.add(b); - assert(result.eq(b)); + let result = a + b; + assert(result == b); } #[test(should_fail_with = "call to assert_max_bit_size")] @@ -330,8 +330,8 @@ fn test_add_modulus_overflow() { let one = U60Repr::from([1, 0, 0]); let a: Fq = BigNum { limbs: U60Repr::into(p + one) }; let b: Fq = BigNum { limbs: U60Repr::into(two_pow_254_minus_1) }; - let result = a.add(b); - assert(result.eq(b)); + let result = a + b; + assert(result == b); } #[test] @@ -474,7 +474,7 @@ fn test_udiv_mod_U256() { let product = unsafe { q.__mul(b).__add(r) }; - assert(product.eq(a)); + assert(product == a); } // // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril diff --git a/src/params.nr b/src/params.nr index 60f98696..d0a2467a 100644 --- a/src/params.nr +++ b/src/params.nr @@ -1,25 +1,25 @@ use crate::utils::u60_representation::U60Repr; -pub(crate) struct BigNumParams { - has_multiplicative_inverse: bool, +pub struct BigNumParams { + pub has_multiplicative_inverse: bool, // @brief modulus: all BigNum operations are evaluated modulo this value - modulus: [Field; N], + pub modulus: [Field; N], // @brief modulus but represented in a U60Repr form - modulus_u60: U60Repr, - modulus_u60_x4: U60Repr, + pub modulus_u60: U60Repr, + pub modulus_u60_x4: U60Repr, // @brief double_modulus: used when performing negations and subtractions - double_modulus: [Field; N], + pub double_modulus: [Field; N], // @brief redc_param used for __barrett_reduction. See https://en.wikipedia.org/wiki/Barrett_reduction - redc_param: [Field; N], + pub redc_param: [Field; N], } // To be implemented by the user for any BigNum they define, or within the predefined BigNums in the `fields/` dir. -pub(crate) trait BigNumParamsGetter { - fn get_params() -> BigNumParams; +pub trait BigNumParamsGetter { + pub fn get_params() -> BigNumParams; } impl BigNumParams { diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index 5e9c7dcd..9bd84c4a 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -14,8 +14,8 @@ use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expr use crate::serialization::{from_be_bytes, to_le_bytes}; pub struct RuntimeBigNum { - limbs: [Field; N], - params: BigNumParams, + pub limbs: [Field; N], + pub params: BigNumParams, } impl RuntimeBigNum {} @@ -23,52 +23,52 @@ impl RuntimeBigNum {} // All functions prefixed `__` are unconstrained! // They're not actually decorated as `unconstrained` because to return the `params` (as part of Self) from an `unconstrained` fn would cause range constraints. Instead, each `__` fn wraps a call to an unconstrained fn, so that the already-range-constrained `params` can be inserted into Self after the unconstrained call. pub(crate) trait RuntimeBigNumTrait { - fn new(params: BigNumParams) -> Self; - fn one(params: BigNumParams) -> Self; - fn derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; - fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; - fn from_slice(params: BigNumParams, limbs: [Field]) -> Self; - fn from_array(params: BigNumParams, limbs: [Field; N]) -> Self; - fn from_be_bytes(params: BigNumParams, x: [u8; NBytes]) -> Self; - - fn to_le_bytes(self) -> [u8; NBytes]; - - fn modulus(self) -> Self; - fn modulus_bits() -> u32; - fn num_limbs() -> u32; - // fn get(self) -> [Field]; - fn get_limbs(self) -> [Field; N]; - fn get_limb(self, idx: u32) -> Field; - fn set_limb(&mut self, idx: u32, value: Field); + pub fn new(params: BigNumParams) -> Self; + pub fn one(params: BigNumParams) -> Self; + pub fn derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; + pub fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; + pub fn from_slice(params: BigNumParams, limbs: [Field]) -> Self; + pub fn from_array(params: BigNumParams, limbs: [Field; N]) -> Self; + pub fn from_be_bytes(params: BigNumParams, x: [u8; NBytes]) -> Self; + + pub fn to_le_bytes(self) -> [u8; NBytes]; + + pub fn modulus(self) -> Self; + pub fn modulus_bits() -> u32; + pub fn num_limbs() -> u32; + // pub fn get(self) -> [Field]; + pub fn get_limbs(self) -> [Field; N]; + pub fn get_limb(self, idx: u32) -> Field; + pub fn set_limb(&mut self, idx: u32, value: Field); unconstrained fn __eq(self, other: Self) -> bool; unconstrained fn __is_zero(self) -> bool; // unconstrained - fn __neg(self) -> Self; + pub fn __neg(self) -> Self; // unconstrained - fn __add(self, other: Self) -> Self; + pub fn __add(self, other: Self) -> Self; // unconstrained - fn __sub(self, other: Self) -> Self; + pub fn __sub(self, other: Self) -> Self; // unconstrained - fn __mul(self, other: Self) -> Self; + pub fn __mul(self, other: Self) -> Self; // unconstrained - fn __div(self, other: Self) -> Self; + pub fn __div(self, other: Self) -> Self; // unconstrained - fn __udiv_mod(self, divisor: Self) -> (Self, Self); + pub fn __udiv_mod(self, divisor: Self) -> (Self, Self); // unconstrained - fn __invmod(self) -> Self; + pub fn __invmod(self) -> Self; // unconstrained - fn __pow(self, exponent: Self) -> Self; + pub fn __pow(self, exponent: Self) -> Self; // unconstrained - fn __batch_invert(x: [Self; M]) -> [Self; M]; + pub fn __batch_invert(x: [Self; M]) -> [Self; M]; unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; - fn __tonelli_shanks_sqrt(self) -> std::option::Option; + pub fn __tonelli_shanks_sqrt(self) -> std::option::Option; // unconstrained - fn __compute_quadratic_expression( + pub fn __compute_quadratic_expression( params: BigNumParams, lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], @@ -78,7 +78,7 @@ pub(crate) trait RuntimeBigNumTrait { linear_flags: [bool; ADD_N] ) -> (Self, Self); - fn evaluate_quadratic_expression( + pub fn evaluate_quadratic_expression( params: BigNumParams, lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], @@ -88,22 +88,22 @@ pub(crate) trait RuntimeBigNumTrait { linear_flags: [bool; ADD_N] ); - fn eq(lhs: Self, rhs: Self) -> bool { lhs == rhs } - fn assert_is_not_equal(self, other: Self); - fn validate_in_field(self); - fn validate_in_range(self); - // fn validate_gt(self, lhs: Self, rhs: Self); - - fn neg(self) -> Self; - fn add(lhs: Self, rhs: Self) -> Self { lhs + rhs } - fn sub(lhs: Self, rhs: Self) -> Self { lhs - rhs } - fn mul(lhs: Self, rhs: Self) -> Self { lhs * rhs } - fn div(lhs: Self, rhs: Self) -> Self { lhs / rhs } - fn udiv_mod(numerator: Self, divisor: Self) -> (Self, Self); - fn udiv(numerator: Self, divisor: Self) -> Self; - fn umod(numerator: Self, divisor: Self) -> Self; - - fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; + pub fn eq(lhs: Self, rhs: Self) -> bool { lhs == rhs } + pub fn assert_is_not_equal(self, other: Self); + pub fn validate_in_field(self); + pub fn validate_in_range(self); + // pub fn validate_gt(self, lhs: Self, rhs: Self); + + pub fn neg(self) -> Self; + pub fn add(lhs: Self, rhs: Self) -> Self { lhs + rhs } + pub fn sub(lhs: Self, rhs: Self) -> Self { lhs - rhs } + pub fn mul(lhs: Self, rhs: Self) -> Self { lhs * rhs } + pub fn div(lhs: Self, rhs: Self) -> Self { lhs / rhs } + pub fn udiv_mod(numerator: Self, divisor: Self) -> (Self, Self); + pub fn udiv(numerator: Self, divisor: Self) -> Self; + pub fn umod(numerator: Self, divisor: Self) -> Self; + + pub fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; } impl RuntimeBigNumTrait for RuntimeBigNum { diff --git a/src/unconstrained_ops.nr b/src/unconstrained_ops.nr index a7d7f92f..2215da36 100644 --- a/src/unconstrained_ops.nr +++ b/src/unconstrained_ops.nr @@ -392,6 +392,10 @@ unconstrained pub(crate) fn __tonelli_shanks_sqrt m = i; } } - let mut result = std::option::Option { _value: r, _is_some: found_root }; + let result = if found_root { + std::option::Option::some(r) + } else { + std::option::Option::none() + }; result } diff --git a/src/utils/u60_representation.nr b/src/utils/u60_representation.nr index 889fc0fa..c90c3d71 100644 --- a/src/utils/u60_representation.nr +++ b/src/utils/u60_representation.nr @@ -9,7 +9,7 @@ use crate::utils::msb::get_msb64; * as well as when performing bit shifts. */ pub struct U60Repr { - limbs: [u64; N * NumSegments] + pub(crate) limbs: [u64; N * NumSegments] } impl std::ops::Add for U60Repr { @@ -78,7 +78,7 @@ impl std::cmp::Eq for U60Repr impl U60Repr { - unconstrained pub fn new(x: [Field; N * NumFieldSegments]) -> Self { + unconstrained pub(crate) fn new(x: [Field; N * NumFieldSegments]) -> Self { let mut result: Self = U60Repr { limbs: [0; N * NumSegments] }; for i in 0..(N * NumFieldSegments) { let (lo, hi) = split_bits::split_60_bits(x[i]); @@ -88,13 +88,13 @@ impl U60Repr { result } - unconstrained pub fn one() -> Self { + unconstrained pub(crate) fn one() -> Self { let mut result: Self = U60Repr { limbs: [0; N * NumSegments] }; result.limbs[0] = 1; result } - unconstrained fn into_field_array(x: U60Repr) -> [Field; N * NumSegments / 2] { + unconstrained pub(crate) fn into_field_array(x: U60Repr) -> [Field; N * NumSegments / 2] { let mut result: [Field; N * NumSegments / 2] = [0; N * NumSegments / 2]; let two_pow_60: Field = 0x1000000000000000; for i in 0..(N * NumSegments / 2) { @@ -103,7 +103,7 @@ impl U60Repr { result } - unconstrained fn gte(self, b: Self) -> bool { + unconstrained pub(crate) fn gte(self, b: Self) -> bool { let mut result = false; let mut early_exit = false; for i in 0..(N * NumSegments) { @@ -123,7 +123,7 @@ impl U60Repr { result } - fn get_bit(self, bit: u32) -> bool { + pub(crate) fn get_bit(self, bit: u32) -> bool { let segment_index = bit / 60; let uint_index = bit % 60; @@ -133,7 +133,7 @@ impl U60Repr { } // note: shr cannot satisfy `Shr` Trait due to `shift` parameter being u64 and not u8 (shift value might be greater than 255) - fn shr(self, shift: u32) -> Self { + pub(crate) fn shr(self, shift: u32) -> Self { let mut result: Self = U60Repr { limbs: [0; N * NumSegments] }; let num_shifted_limbs = shift / 60; @@ -152,7 +152,7 @@ impl U60Repr { } // note: shr cannot satisfy `Shr` Trait due to `shift` parameter being u64 and not u8 (shift value might be greater than 255) - fn shr1(&mut self) { + pub(crate) fn shr1(&mut self) { let value = self.limbs[NumSegments * N - 1]; self.limbs[NumSegments * N - 1] = value >> 1; @@ -166,7 +166,7 @@ impl U60Repr { } // note: shr cannot satisfy `Shr` Trait due to `shift` parameter being u64 and not u8 (shift value might be greater than 255) - fn shl(self, shift: u32) -> Self { + pub(crate) fn shl(self, shift: u32) -> Self { let mut result: Self = U60Repr { limbs: [0; NumSegments * N] }; let num_shifted_limbs = shift / 60; @@ -197,7 +197,7 @@ impl U60Repr { result } - fn increment(&mut self) { + pub(crate) fn increment(&mut self) { let mut carry: u64 = 0; let mut add: u64 = self.limbs[0] + 1; @@ -213,7 +213,7 @@ impl U60Repr { } } - unconstrained fn get_msb(val: Self) -> u32 { + unconstrained pub(crate) fn get_msb(val: Self) -> u32 { let mut count = 0; for i in 0..N * NumSegments { let v = val.limbs[((N * NumSegments) - 1 - i)]; From 59ceb916d6db7f4350f0c3729397e40ae3009632 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Tue, 22 Oct 2024 19:21:15 +0100 Subject: [PATCH 23/29] fix to work with latest aztec-packages version of nargo --- src/constrained_ops.nr | 10 ++++------ src/expressions.nr | 6 +++--- src/serialization.nr | 5 +---- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/constrained_ops.nr b/src/constrained_ops.nr index 215fde49..933e175d 100644 --- a/src/constrained_ops.nr +++ b/src/constrained_ops.nr @@ -220,10 +220,9 @@ pub(crate) fn validate_in_field(params: P(limbs: [Field; N]) { for i in 0..(N - 1) { - limbs[i].assert_max_bit_size(120); + limbs[i].assert_max_bit_size::<120>(); } - let final_limb_bits = MOD_BITS - ((N - 1) * 120); - limbs[N - 1].assert_max_bit_size(final_limb_bits as u32); + limbs[N - 1].assert_max_bit_size::(); } /** @@ -241,11 +240,10 @@ pub(crate) fn validate_in_range(limbs: [Field; N] **/ pub(crate) fn validate_quotient_in_range(limbs: [Field; N]) { for i in 0..(N) { - limbs[i].assert_max_bit_size(120); + limbs[i].assert_max_bit_size::<120>(); } // Note: replace magic number 6 with definition - let final_limb_bits = MOD_BITS - ((N - 1) * 120) + 6; - limbs[N - 1].assert_max_bit_size(final_limb_bits as u32); + limbs[N - 1].assert_max_bit_size::(); } // validate that lhs - rhs does not underflow i.e. lhs > rhs diff --git a/src/expressions.nr b/src/expressions.nr index bdd01d73..1274f86c 100644 --- a/src/expressions.nr +++ b/src/expressions.nr @@ -394,10 +394,10 @@ pub(crate) fn evaluate_quadratic_expression< // N.B. borrow_flags is `Field` type because making it `bool` would apply boolean constraints to all `N2` array entries. // We only use `N2 - 2` borrow flags so applying 1-bit range checks on the array elements we use is more efficient. // TODO: Once it is possible to perform arithmetic on generics we can use `borrow_flags: [bool;N+N-2]` to avoid this issue - borrow_flags[0].assert_max_bit_size(1); + borrow_flags[0].assert_max_bit_size::<1>(); product_limbs[0] += borrow_flags[0] * borrow_shift; for i in 1..(N + N - 2) { - borrow_flags[i].assert_max_bit_size(1); + borrow_flags[i].assert_max_bit_size::<1>(); product_limbs[i] += (borrow_flags[i] * borrow_shift - borrow_flags[i - 1] * borrow_carry); } @@ -419,7 +419,7 @@ pub(crate) fn evaluate_quadratic_expression< for i in 0..N + N - 2 { product_limbs[i] *= hi_downshift; std::as_witness(product_limbs[i]); - product_limbs[i].assert_max_bit_size(126); // N.B. is this sufficient? going beyond 126 costs us 1 gate per limb + product_limbs[i].assert_max_bit_size::<126>(); // N.B. is this sufficient? going beyond 126 costs us 1 gate per limb product_limbs[i + 1] += product_limbs[i]; } // the most significant limb has no limb to "carry" values into - the entire limb must equal zero diff --git a/src/serialization.nr b/src/serialization.nr index 538bfbdb..dc404c03 100644 --- a/src/serialization.nr +++ b/src/serialization.nr @@ -31,12 +31,9 @@ pub(crate) fn from_be_bytes(x: [ result[N - i - 1] = limb; } - // max_bits_in_most_significant_byte should be known at comptime. if not...messy! - let mut max_bits_in_most_significant_byte = 8 - (num_bits - MOD_BITS); - let most_significant_byte: Field = x[0] as Field; - most_significant_byte.assert_max_bit_size(max_bits_in_most_significant_byte as u32); + most_significant_byte.assert_max_bit_size::<8 - (NBytes * 8 - MOD_BITS)>(); result } From 709f7ffa0e09a431150c3e2121fe46feec5637bc Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Tue, 22 Oct 2024 19:50:59 +0100 Subject: [PATCH 24/29] README --- README.md | 92 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index efc32af1..01d771d8 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ TODO ## Dependencies -- Noir ≥v0.32.0 -- Barretenberg ≥v0.46.1 +- Noir ≥v0.35.0 +- Barretenberg ≥v0.56.1 Refer to [Noir's docs](https://noir-lang.org/docs/getting_started/installation/) and [Barretenberg's docs](https://github.com/AztecProtocol/aztec-packages/blob/master/barretenberg/cpp/src/barretenberg/bb/readme.md#installation) for installation steps. @@ -50,12 +50,13 @@ If your field moduli is _also_ known at compile-time, use the `BigNumTrait` defi Big numbers are instantiated with the BigNum struct: ```rust -struct BigNum { +struct BigNum { limbs: [Field; N] } ``` - `N` is the number of `Field` limbs together holding the value of the big number +- `MOD_BITS` is the bit-length of the modulus of the big number. - `Params` is the parameters associated with the big number; refer to sections below for presets and customizations ### Usage @@ -68,7 +69,7 @@ A simple 1 + 2 = 3 check in 256-bit unsigned integers: use dep::bignum::fields::U256::U256Params; use dep::bignum::BigNum; -type U256 = BigNum<3, U256Params>; +type U256 = BigNum<3, 257, U256Params>; fn main() { let one: U256 = BigNum::from_array([1, 0, 0]); @@ -96,7 +97,7 @@ e.g. use dep::bignum::fields::U256::U256Params; use dep::bignum::BigNum; -type U256 = BigNum<3, U256Params>; +type U256 = BigNum<3, 257, U256Params>; fn foo(x: U256, y: U256) -> U256 { x.udiv(y) @@ -105,70 +106,76 @@ fn foo(x: U256, y: U256) -> U256 { ##### Fields -`BigNum::fields` contains `BigNumInstance` constructors for common fields. +`BigNum::fields` contains `BigNumParams` for common fields. Feature requests and/or pull requests welcome for missing fields you need. TODO: Document existing field presets (e.g. bls, ed25519, secp256k1) -## `runtime_bignum` +## `RuntimeBigNum` -If your field moduli is _not_ known at compile-time (e.g. RSA verification), use the traits and structs defined in `runtime_bignum`: `runtime_bignum::BigNumTrait` and `runtime_bignum::BigNumInstanceTrait` +If your field moduli is _not_ known at compile-time (e.g. RSA verification), use the `RuntimeBigNum` struct defined in `runtime_bignum.nr`: `runtime_bignum::RuntimeBigNum`. -A `runtime_bignum::BigNumInstance` wraps the bignum modulus (as well as a derived parameter used internally to perform Barret reductions). A `BigNumInstance` object is required to evaluate most bignum operations. +```rust +use dep::bignum::fields::bn254Fq::BN254_Fq_Params; -### Types +// Notice how we don't provide the params here, because we're pretending they're +// not known at compile-time, for illustration purposes. +type My_RBN = RuntimeBigNum<3, 254>; -bignum operations are evaluated using two structs and a trait: `ParamsTrait`, `BigNum`, `BigNumInstance` +fn main() { + let params = BN254_Fq_Params::get_params(); // or some other params known at runtime. -`ParamsTrait` defines the compile-time properties of a BigNum instance: the number of modulus bits and the Barret reduction parameter `k` (TODO: these two values should be the same?!) + // Notice how we feed the params in, because we're pretending they're not + // known at compile-time. + let one: My_RBN = RuntimeBigNum::from_array(params, [1, 0, 0]); + let two: My_RBN = RuntimeBigNum::from_array(params, [2, 0, 0]); + let three: My_RBN = RuntimeBigNum::from_array(params, [3, 0, 0]); -`BigNumInstance` is a generator type that is used to create `BigNum` objects and evaluate operations on `BigNum` objects. It wraps BigNum parameters that may not be known at compile time (the `modulus` and a reduction parameter required for Barret reductions (`redc_param`)) + assert((one + two) == three); +} +``` -The `BigNum` struct represents individual big numbers. +### Types -BigNumInstance parameters (`modulus`, `redc_param`) can be provided at runtime via witnesses (e.g. RSA verification). The `redc_param` is only used in unconstrained functions and does not need to be derived from `modulus` in-circuit. +User-facing structs: -### Usage +`BigNum`: big numbers whose parameters are all known at compile-time. -#### Example +`RuntimeBigNum`: big numbers whose parameters are only known at runtime. (Note: the number of bits of the modulus of the bignum must be known at compile-time). -```rust -use crate::bignum::fields::bn254Fq{BNParams, BN254INSTANCE}; -use crate::bignum::runtime_bignum::BigNumInstance; -use crate::bignum::BigNum; -type Fq = BigNum<3, BNParams>; -type FqInst = BigNumInstance<3, BNParams>; +If creating custom bignum params: + +`BigNumParams` is needed, to declare your params. These parameters (`modulus`, `redc_param`) can be provided at runtime via witnesses (e.g. RSA verification). The `redc_param` is only used in unconstrained functions and does not need to be derived from `modulus` in-circuit. + +`BigNumParamsGetter` is a convenient wrapper around params, which is needed if declaring a new type of `BigNum`. -fn example(Fq a, Fq b) -> Fq { - let instance: FqInst = BN254INSTANCE; - instance.mul(a, b) -} -``` #### Methods ##### Arithmetics -Basic expressions can be evaluated using `BigNumInstance::add, BigNumInstance::sub, BigNumInstance::mul`. However, when evaluating relations (up to degree 2) that are more complex than single operations, the function `BigNumInstance::evaluate_quadratic_expression` is more efficient (due to needing only a single modular reduction). +Basic expressions can be evaluated using the `BigNum` and `RuntimeBigNum` operators `+`,`-`,`*`,`/`. However, when evaluating relations (up to degree 2) that are more complex than single operations, the static methods `BigNum::evaluate_quadratic_expression` or `RuntimeBigNum::evaluate_quadratic_expression` are much more efficient (due to needing only a single modular reduction). ##### Unconstrained arithmetics -Unconstrained functions `__mul, __add, __sub, __div, __pow` can be used to compute witnesses that can then be fed into `BigNumInstance::evaluate_quadratic_expression`. +Unconstrained functions `__mul, __add, __sub, __div, __pow` etc. can be used to compute witnesses that can then be fed into `BigNumInstance::evaluate_quadratic_expression`. -> **Note:** `__div`, `__pow` and `div` 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) +> **Note:** `__div`, `__pow` and `div` 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). e.g. if we wanted to compute `(a + b) * c + (d - e) * f = g` by evaluating the above example, `g` can be derived via: ```rust -let bn: BigNumInstance<3, BNParams> = BNInstance(); -let t0 = bn.__mul(bn.__add(a, b), c); -let t1 = bn.__mul(bn.__add(d, bn.__neg(e)), f); +let a: BigNumInstance<3, 254, BN254_Fq_Params> = BigNum::new(); +let t0 = c.__mul(a.__add(b)); +let t1 = f.__mul(d.__sub(e)); let g = bn.__add(t0, t1); ``` -See `bignum_test.nr` for more examples. +then the values can be arranged and fed-into `evaluate_quadratic_expression`. + +See `bignum_test.nr` and `runtime_bignum_test.nr` for more examples. ##### `evaluate_quadratic_expression` @@ -206,9 +213,9 @@ BigNum::evaluate_quadratic_expresson(lhs_terms, lhs_flags, rhs_terms, rhs_flags, ##### TODO: Document other available methods -#### Deriving BigNumInstance parameters: `modulus`, `redc_param` +#### Deriving BigNumParams parameters: `modulus`, `redc_param` -For common fields, BigNumInstance parameters can be pulled from the presets in `BigNum::fields`. +For common fields, BigNumParams parameters can be pulled from the presets in `bignum/fields/`. For other moduli (e.g. those used in RSA verification), both `modulus` and `redc_param` must be computed and formatted according to the following speficiations: @@ -218,17 +225,16 @@ For other moduli (e.g. those used in RSA verification), both `modulus` and `redc `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. -BigNumInstance parameters can be derived from a known modulus using the rust crate `noir-bignum-paramgen` (https://crates.io/crates/noir-bignum-paramgen) +BigNumParams parameters can be derived from a known modulus using the rust crate `noir-bignum-paramgen` (https://crates.io/crates/noir-bignum-paramgen) ## Additional usage examples ```rust -use crate::bignum::fields::bn254Fq::BNParams; -use crate::bignum::fields::BN254Instance; -use crate::bignum::BigNum; -use crate::bignum::runtime_bignum::BigNumInstance; +use dep::bignum::fields::bn254Fq::BN254_Fq_Params; + +use dep::bignum::BigNum; -type Fq = BigNum<3, BNParams>; +type Fq = BigNum<3, 254, BN254_Fq_Params>; fn example_mul(Fq a, Fq b) -> Fq { a * b From 042ffa9290350e00cb78963417a788a24f13856d Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Tue, 22 Oct 2024 20:12:08 +0100 Subject: [PATCH 25/29] tidy filing --- src/bignum.nr | 21 ++++++++++++--------- src/{ => fns}/constrained_ops.nr | 12 +++++++----- src/{ => fns}/expressions.nr | 6 ++++-- src/fns/mod.nr | 6 ++++++ src/{ => fns}/serialization.nr | 0 src/{ => fns}/unconstrained_helpers.nr | 2 +- src/{ => fns}/unconstrained_ops.nr | 2 +- src/lib.nr | 24 ++++++++++++------------ src/runtime_bignum.nr | 21 ++++++++++++--------- src/{ => tests}/bignum_test.nr | 0 src/tests/mod.nr | 2 ++ src/{ => tests}/runtime_bignum_test.nr | 0 12 files changed, 57 insertions(+), 39 deletions(-) rename src/{ => fns}/constrained_ops.nr (98%) rename src/{ => fns}/expressions.nr (99%) create mode 100644 src/fns/mod.nr rename src/{ => fns}/serialization.nr (100%) rename src/{ => fns}/unconstrained_helpers.nr (99%) rename src/{ => fns}/unconstrained_ops.nr (99%) rename src/{ => tests}/bignum_test.nr (100%) create mode 100644 src/tests/mod.nr rename src/{ => tests}/runtime_bignum_test.nr (100%) diff --git a/src/bignum.nr b/src/bignum.nr index 3d01a8ea..87c6a263 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -1,16 +1,19 @@ use crate::utils::map::map; use crate::params::BigNumParamsGetter; -use crate::constrained_ops::{ - derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, - neg, add, sub, mul, div, udiv_mod, udiv, umod -}; -use crate::unconstrained_ops::{ - __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, - __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt + +use crate::fns::{ + constrained_ops::{ + derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, + neg, add, sub, mul, div, udiv_mod, udiv, umod + }, + unconstrained_ops::{ + __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, + __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt + }, + expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, + serialization::{from_be_bytes, to_le_bytes} }; -use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}; -use crate::serialization::{from_be_bytes, to_le_bytes}; pub struct BigNum { pub limbs: [Field; N] diff --git a/src/constrained_ops.nr b/src/fns/constrained_ops.nr similarity index 98% rename from src/constrained_ops.nr rename to src/fns/constrained_ops.nr index 933e175d..f510fb3d 100644 --- a/src/constrained_ops.nr +++ b/src/fns/constrained_ops.nr @@ -1,11 +1,13 @@ use crate::params::BigNumParams as P; -use crate::unconstrained_helpers::{ - __validate_in_field_compute_borrow_flags, __validate_gt_remainder, __neg_with_flags, - __add_with_flags, __sub_with_flags +use crate::fns::{ + unconstrained_helpers::{ + __validate_in_field_compute_borrow_flags, __validate_gt_remainder, __neg_with_flags, + __add_with_flags, __sub_with_flags, + }, + unconstrained_ops::{__mul, __div, __udiv_mod}, + expressions::evaluate_quadratic_expression, }; -use crate::unconstrained_ops::{__mul, __div, __udiv_mod}; -use crate::expressions::evaluate_quadratic_expression; /** * In this file: diff --git a/src/expressions.nr b/src/fns/expressions.nr similarity index 99% rename from src/expressions.nr rename to src/fns/expressions.nr index 1274f86c..0461c0e5 100644 --- a/src/expressions.nr +++ b/src/fns/expressions.nr @@ -1,8 +1,10 @@ use crate::utils::split_bits; use crate::params::BigNumParams as P; -use crate::constrained_ops::validate_quotient_in_range; -use crate::unconstrained_helpers::__barrett_reduction; +use crate::fns::{ + constrained_ops::validate_quotient_in_range, + unconstrained_helpers::__barrett_reduction +}; /** * In this file: diff --git a/src/fns/mod.nr b/src/fns/mod.nr new file mode 100644 index 00000000..256c53db --- /dev/null +++ b/src/fns/mod.nr @@ -0,0 +1,6 @@ +// Free functions called by structs +pub(crate) mod unconstrained_ops; +pub(crate) mod constrained_ops; +pub(crate) mod unconstrained_helpers; +pub(crate) mod expressions; +pub(crate) mod serialization; \ No newline at end of file diff --git a/src/serialization.nr b/src/fns/serialization.nr similarity index 100% rename from src/serialization.nr rename to src/fns/serialization.nr diff --git a/src/unconstrained_helpers.nr b/src/fns/unconstrained_helpers.nr similarity index 99% rename from src/unconstrained_helpers.nr rename to src/fns/unconstrained_helpers.nr index e80689de..ba0404b9 100644 --- a/src/unconstrained_helpers.nr +++ b/src/fns/unconstrained_helpers.nr @@ -2,7 +2,7 @@ use crate::utils::u60_representation::U60Repr; use crate::utils::split_bits; use crate::params::BigNumParams as P; -use crate::unconstrained_ops::{__one, __eq, __neg, __add, __mul, __pow}; +use crate::fns::unconstrained_ops::{__one, __eq, __neg, __add, __mul, __pow}; /** * In this file: diff --git a/src/unconstrained_ops.nr b/src/fns/unconstrained_ops.nr similarity index 99% rename from src/unconstrained_ops.nr rename to src/fns/unconstrained_ops.nr index 2215da36..b9dab098 100644 --- a/src/unconstrained_ops.nr +++ b/src/fns/unconstrained_ops.nr @@ -2,7 +2,7 @@ use crate::utils::u60_representation::U60Repr; use crate::utils::split_bits; use crate::params::BigNumParams as P; -use crate::unconstrained_helpers::{ +use crate::fns::unconstrained_helpers::{ __barrett_reduction, __primitive_root_log_size, __multiplicative_generator, __tonelli_shanks_sqrt_inner_loop_check }; diff --git a/src/lib.nr b/src/lib.nr index 63caa51b..5edb314e 100644 --- a/src/lib.nr +++ b/src/lib.nr @@ -1,18 +1,18 @@ -pub(crate) mod utils; +// BigNum +pub mod bignum; + +// RuntimeBigNum +pub mod runtime_bignum; + +// Pre-defined fields and bignums for people to use: pub mod fields; -// Structs +// Structs enabling people to define their own bignum params pub mod params; -pub mod bignum; -pub mod runtime_bignum; -// Free functions called by structs -pub(crate) mod unconstrained_ops; -pub(crate) mod constrained_ops; -pub(crate) mod unconstrained_helpers; -pub(crate) mod expressions; -pub(crate) mod serialization; +// Free functions and other utils, called by the BigNum and RuntimeBigNum structs +pub(crate) mod fns; +pub(crate) mod utils; // Tests -mod bignum_test; -mod runtime_bignum_test; +mod tests; diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index 9bd84c4a..dce45434 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -2,16 +2,19 @@ use dep::std; use crate::utils::map::map; use crate::params::BigNumParams; -use crate::constrained_ops::{ - derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, - neg, add, sub, mul, div, udiv_mod, udiv, umod -}; -use crate::unconstrained_ops::{ - __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, - __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt + +use crate::fns::{ + constrained_ops::{ + derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, + neg, add, sub, mul, div, udiv_mod, udiv, umod + }, + unconstrained_ops::{ + __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, + __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt + }, + expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, + serialization::{from_be_bytes, to_le_bytes}, }; -use crate::expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}; -use crate::serialization::{from_be_bytes, to_le_bytes}; pub struct RuntimeBigNum { pub limbs: [Field; N], diff --git a/src/bignum_test.nr b/src/tests/bignum_test.nr similarity index 100% rename from src/bignum_test.nr rename to src/tests/bignum_test.nr diff --git a/src/tests/mod.nr b/src/tests/mod.nr new file mode 100644 index 00000000..f972d4ba --- /dev/null +++ b/src/tests/mod.nr @@ -0,0 +1,2 @@ +mod bignum_test; +mod runtime_bignum_test; \ No newline at end of file diff --git a/src/runtime_bignum_test.nr b/src/tests/runtime_bignum_test.nr similarity index 100% rename from src/runtime_bignum_test.nr rename to src/tests/runtime_bignum_test.nr From 13195a0413347375f6d205b80cc24f0e12634a44 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Fri, 25 Oct 2024 11:01:30 +0100 Subject: [PATCH 26/29] version bump --- Nargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nargo.toml b/Nargo.toml index 4eb93691..337a2e09 100644 --- a/Nargo.toml +++ b/Nargo.toml @@ -2,6 +2,6 @@ name = "bignum" type = "lib" authors = [""] -compiler_version = ">=0.35.0" +compiler_version = ">=0.36.0" [dependencies] From 5afa312d42e40a9f38419f36de215c7bc7eabb10 Mon Sep 17 00:00:00 2001 From: Michael Connor Date: Fri, 25 Oct 2024 11:02:43 +0100 Subject: [PATCH 27/29] fmt --- src/bignum.nr | 119 +++-- src/fields/U1024.nr | 39 +- src/fields/U2048.nr | 58 ++- src/fields/U256.nr | 26 +- src/fields/U384.nr | 30 +- src/fields/U4096.nr | 83 +++- src/fields/U512.nr | 51 ++- src/fields/U768.nr | 74 ++- src/fields/U8192.nr | 648 ++++++++++++++++++++++++++- src/fields/bls12_377Fq.nr | 61 ++- src/fields/bls12_377Fr.nr | 46 +- src/fields/bls12_381Fq.nr | 63 ++- src/fields/bls12_381Fr.nr | 46 +- src/fields/bn254Fq.nr | 44 +- src/fields/ed25519Fq.nr | 46 +- src/fields/ed25519Fr.nr | 41 +- src/fields/mnt4_753Fq.nr | 89 +++- src/fields/mnt4_753Fr.nr | 90 +++- src/fields/mnt6_753Fq.nr | 91 +++- src/fields/mnt6_753Fr.nr | 91 +++- src/fields/pallasFq.nr | 41 +- src/fields/pallasFr.nr | 41 +- src/fields/secp256k1Fq.nr | 46 +- src/fields/secp256k1Fr.nr | 46 +- src/fields/secp256r1Fq.nr | 41 +- src/fields/secp256r1Fr.nr | 46 +- src/fields/secp384r1Fq.nr | 58 ++- src/fields/secp384r1Fr.nr | 58 ++- src/fields/vestaFq.nr | 41 +- src/fields/vestaFr.nr | 41 +- src/fns/constrained_ops.nr | 164 ++++--- src/fns/expressions.nr | 75 +--- src/fns/mod.nr | 2 +- src/fns/serialization.nr | 10 +- src/fns/unconstrained_helpers.nr | 103 +++-- src/fns/unconstrained_ops.nr | 105 +++-- src/params.nr | 8 +- src/runtime_bignum.nr | 120 ++--- src/tests/bignum_test.nr | 429 ++++++++++++------ src/tests/mod.nr | 2 +- src/tests/runtime_bignum_test.nr | 227 ++++++++-- src/utils/msb.nr | 20 +- src/utils/split_bits.nr | 44 +- src/utils/u60_representation.nr | 27 +- src/utils/u60_representation_test.nr | 50 +-- 45 files changed, 2753 insertions(+), 928 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index 87c6a263..aaad1c8a 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -4,19 +4,18 @@ use crate::params::BigNumParamsGetter; use crate::fns::{ constrained_ops::{ - derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, - neg, add, sub, mul, div, udiv_mod, udiv, umod + derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, + validate_in_range, neg, add, sub, mul, div, udiv_mod, udiv, umod, }, unconstrained_ops::{ - __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, - __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt - }, - expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, - serialization::{from_be_bytes, to_le_bytes} + __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, + __invmod, __pow, __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt, + }, expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, + serialization::{from_be_bytes, to_le_bytes}, }; pub struct BigNum { - pub limbs: [Field; N] + pub limbs: [Field; N], } pub(crate) trait BigNumTrait { @@ -25,7 +24,7 @@ pub(crate) trait BigNumTrait { pub fn new() -> Self; pub fn one() -> Self; pub fn derive_from_seed(seed: [u8; SeedBytes]) -> Self; - unconstrained pub fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self; + pub unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self; pub fn from_slice(limbs: [Field]) -> Self; pub fn from_array(limbs: [Field; N]) -> Self; pub fn from_be_bytes(x: [u8; NBytes]) -> Self; @@ -39,30 +38,30 @@ pub(crate) trait BigNumTrait { pub fn get_limb(self, idx: u32) -> Field; pub fn set_limb(&mut self, idx: u32, value: Field); - unconstrained pub fn __eq(self, other: Self) -> bool; - unconstrained pub fn __is_zero(self) -> bool; + pub unconstrained fn __eq(self, other: Self) -> bool; + pub unconstrained fn __is_zero(self) -> bool; - unconstrained pub fn __neg(self) -> Self; - unconstrained pub fn __add(self, other: Self) -> Self; - unconstrained pub fn __sub(self, other: Self) -> Self; - unconstrained pub fn __mul(self, other: Self) -> Self; - unconstrained pub fn __div(self, other: Self) -> Self; - unconstrained pub fn __udiv_mod(self, divisor: Self) -> (Self, Self); - unconstrained pub fn __invmod(self) -> Self; - unconstrained pub fn __pow(self, exponent: Self) -> Self; + pub unconstrained fn __neg(self) -> Self; + pub unconstrained fn __add(self, other: Self) -> Self; + pub unconstrained fn __sub(self, other: Self) -> Self; + pub unconstrained fn __mul(self, other: Self) -> Self; + pub unconstrained fn __div(self, other: Self) -> Self; + pub unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self); + pub unconstrained fn __invmod(self) -> Self; + pub unconstrained fn __pow(self, exponent: Self) -> Self; - unconstrained pub fn __batch_invert(to_invert: [Self; M]) -> [Self; M]; - unconstrained pub fn __batch_invert_slice(to_invert: [Self]) -> [Self]; + pub unconstrained fn __batch_invert(to_invert: [Self; M]) -> [Self; M]; + pub unconstrained fn __batch_invert_slice(to_invert: [Self]) -> [Self]; - unconstrained pub fn __tonelli_shanks_sqrt(self) -> std::option::Option; + pub unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option; - unconstrained pub fn __compute_quadratic_expression( + pub unconstrained fn __compute_quadratic_expression( lhs: [[Self; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs: [[Self; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], add: [Self; ADD_N], - add_flags: [bool; ADD_N] + add_flags: [bool; ADD_N], ) -> (Self, Self); pub fn evaluate_quadratic_expression( @@ -71,19 +70,29 @@ pub(crate) trait BigNumTrait { rhs: [[Self; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], add: [Self; ADD_N], - add_flags: [bool; ADD_N] + add_flags: [bool; ADD_N], ); - pub fn eq(self, other: Self) -> bool { self == other } + pub fn eq(self, other: Self) -> bool { + self == other + } pub fn assert_is_not_equal(self, other: Self); pub fn validate_in_range(self); pub fn validate_in_field(self); pub fn neg(self) -> Self; - pub fn add(self, other: Self) -> Self { self + other } - pub fn sub(self, other: Self) -> Self { self - other } - pub fn mul(self, other: Self) -> Self { self * other } - pub fn div(self, other: Self) -> Self { self / other } + pub fn add(self, other: Self) -> Self { + self + other + } + pub fn sub(self, other: Self) -> Self { + self - other + } + pub fn mul(self, other: Self) -> Self { + self * other + } + pub fn div(self, other: Self) -> Self { + self / other + } pub fn udiv_mod(self, divisor: Self) -> (Self, Self); pub fn udiv(self, divisor: Self) -> Self; pub fn umod(self, divisor: Self) -> Self; @@ -91,7 +100,10 @@ pub(crate) trait BigNumTrait { pub fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; } -impl BigNumTrait for BigNum where Params: BigNumParamsGetter { +impl BigNumTrait for BigNum +where + Params: BigNumParamsGetter, +{ fn new() -> Self { Self { limbs: [0; N] } @@ -209,20 +221,22 @@ impl BigNumTrait for BigNum(x: [Self; M]) -> [Self; M] { let params = Params::get_params(); assert(params.has_multiplicative_inverse); - __batch_invert::<_, MOD_BITS, _>(params, x.map(|bn| Self::get_limbs(bn))).map(|limbs| Self {limbs}) + __batch_invert::<_, MOD_BITS, _>(params, x.map(|bn| Self::get_limbs(bn))).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::get_limbs(bn))).map(|limbs| Self { limbs }) + __batch_invert_slice::<_, MOD_BITS>(params, x.map(|bn| Self::get_limbs(bn))).map(|limbs| { + Self { limbs } + }) } unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option { let params = Params::get_params(); - let maybe_limbs = unsafe { - __tonelli_shanks_sqrt(params, self.limbs) - }; + let maybe_limbs = unsafe { __tonelli_shanks_sqrt(params, self.limbs) }; maybe_limbs.map(|limbs| Self { limbs }) } @@ -232,7 +246,7 @@ impl BigNumTrait for BigNum (Self, Self) { let params = Params::get_params(); let (q_limbs, r_limbs) = __compute_quadratic_expression::<_, MOD_BITS, _, _, _, _>( @@ -242,7 +256,7 @@ impl BigNumTrait for BigNum BigNumTrait for BigNum( @@ -263,7 +277,7 @@ impl BigNumTrait for BigNum BigNumTrait for BigNum BigNumTrait for BigNum where Params: BigNumParamsGetter {} -impl std::ops::Add for BigNum where Params: BigNumParamsGetter { +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 { @@ -318,7 +335,10 @@ impl std::ops::Add for BigNum std::ops::Sub for BigNum where Params: BigNumParamsGetter { +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 { @@ -327,7 +347,10 @@ impl std::ops::Sub for BigNum std::ops::Mul for BigNum where Params: BigNumParamsGetter { +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` @@ -338,7 +361,10 @@ impl std::ops::Mul for BigNum std::ops::Div for BigNum where Params: BigNumParamsGetter { +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(); @@ -346,7 +372,10 @@ impl std::ops::Div for BigNum std::cmp::Eq for BigNum where Params: BigNumParamsGetter { +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) diff --git a/src/fields/U1024.nr b/src/fields/U1024.nr index a5374f96..5f8f438a 100644 --- a/src/fields/U1024.nr +++ b/src/fields/U1024.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U1024Params {} +pub struct U1024Params {} impl BigNumParamsGetter<9, 1025> for U1024Params { fn get_params() -> BigNumParams<9, 1025> { @@ -11,18 +11,31 @@ impl BigNumParamsGetter<9, 1025> for U1024Params { } global U1024_PARAMS: BigNumParams<9, 1025> = BigNumParams { - has_multiplicative_inverse: false, - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000000000000000 + has_multiplicative_inverse: false, + modulus: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000000000000000], + double_modulus: [ + 0x01000000000000000000000000000000, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0x01ffffffffffffffff, + ], + modulus_u60: U60Repr { + limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffffffffffff + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x400000000000000000 - ] + }, + redc_param: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x400000000000000000], }; diff --git a/src/fields/U2048.nr b/src/fields/U2048.nr index 9bf83b10..6c689179 100644 --- a/src/fields/U2048.nr +++ b/src/fields/U2048.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U2048Params {} +pub struct U2048Params {} impl BigNumParamsGetter<18, 2049> for U2048Params { fn get_params() -> BigNumParams<18, 2049> { @@ -11,18 +11,50 @@ impl BigNumParamsGetter<18, 2049> for U2048Params { } global U2048_PARAMS: BigNumParams<18, 2049> = BigNumParams { - has_multiplicative_inverse: false, - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100 + has_multiplicative_inverse: false, + modulus: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0100, + ], + double_modulus: [ + 0x01000000000000000000000000000000, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0x01ff, + ], + modulus_u60: U60Repr { + limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100, 0x00, ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ff + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4000 - ] + }, + redc_param: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4000, + ], }; diff --git a/src/fields/U256.nr b/src/fields/U256.nr index 4922c462..e542d4a5 100644 --- a/src/fields/U256.nr +++ b/src/fields/U256.nr @@ -11,18 +11,16 @@ impl BigNumParamsGetter<3, 257> for U256Params { } global U256_PARAMS: BigNumParams<3, 257> = BigNumParams { - has_multiplicative_inverse: false, - modulus: [ - 0x00, 0x00, 0x010000 - ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0x01ffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x400000 - ] + has_multiplicative_inverse: false, + modulus: [0x00, 0x00, 0x010000], + double_modulus: [ + 0x01000000000000000000000000000000, + 0xffffffffffffffffffffffffffffff, + 0x01ffff, + ], + modulus_u60: U60Repr { limbs: [0x00, 0x00, 0x00, 0x00, 0x010000, 0x00] }, + modulus_u60_x4: U60Repr { + limbs: [0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + }, + redc_param: [0x00, 0x00, 0x400000], }; diff --git a/src/fields/U384.nr b/src/fields/U384.nr index 0d58e8c8..572fbe67 100644 --- a/src/fields/U384.nr +++ b/src/fields/U384.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U384_Params {} +pub struct U384_Params {} impl BigNumParamsGetter<4, 385> for U384_Params { fn get_params() -> BigNumParams<4, 385> { @@ -11,18 +11,20 @@ impl BigNumParamsGetter<4, 385> for U384_Params { } global U384_PARAMS: BigNumParams<4, 385> = BigNumParams { - has_multiplicative_inverse: false, - modulus: [ - 0x00, 0x00, 0x00, 0x01000000 + has_multiplicative_inverse: false, + modulus: [0x00, 0x00, 0x00, 0x01000000], + double_modulus: [ + 0x01000000000000000000000000000000, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0x01ffffff, + ], + modulus_u60: U60Repr { limbs: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000, 0x00] }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x40000000 - ] + }, + redc_param: [0x00, 0x00, 0x00, 0x40000000], }; diff --git a/src/fields/U4096.nr b/src/fields/U4096.nr index 1f80c3ff..d63124c7 100644 --- a/src/fields/U4096.nr +++ b/src/fields/U4096.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U4096Params {} +pub struct U4096Params {} impl BigNumParamsGetter<35, 4097> for U4096Params { fn get_params() -> BigNumParams<35, 4097> { @@ -11,18 +11,75 @@ impl BigNumParamsGetter<35, 4097> for U4096Params { } global U4096_PARAMS: BigNumParams<35, 4097> = BigNumParams { - has_multiplicative_inverse: false, - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000 + has_multiplicative_inverse: false, + modulus: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x010000, + ], + double_modulus: [ + 0x01000000000000000000000000000000, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0x01ffff, + ], + modulus_u60: U60Repr { + limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffff + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x010000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x400000 - ] + }, + redc_param: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x400000, + ], }; diff --git a/src/fields/U512.nr b/src/fields/U512.nr index 4e3894f8..50277773 100644 --- a/src/fields/U512.nr +++ b/src/fields/U512.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U512Params {} +pub struct U512Params {} impl BigNumParamsGetter<5, 513> for U512Params { fn get_params() -> BigNumParams<5, 513> { @@ -11,19 +11,42 @@ impl BigNumParamsGetter<5, 513> for U512Params { } global U512_PARAMS: BigNumParams<5, 513> = BigNumParams { - has_multiplicative_inverse: false, - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x0100000000 + has_multiplicative_inverse: false, + modulus: [0x00, 0x00, 0x00, 0x00, 0x0100000000], + double_modulus: [ + 0x01000000000000000000000000000000, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0x01ffffffff, + ], + modulus_u60: U60Repr { + limbs: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00], + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0100000000, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffff - ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x4000000000 - ] + }, + redc_param: [0x00, 0x00, 0x00, 0x00, 0x4000000000], }; diff --git a/src/fields/U768.nr b/src/fields/U768.nr index bcd5405e..c9e0cb44 100644 --- a/src/fields/U768.nr +++ b/src/fields/U768.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U768Params {} +pub struct U768Params {} impl BigNumParamsGetter<7, 769> for U768Params { fn get_params() -> BigNumParams<7, 769> { @@ -11,18 +11,66 @@ impl BigNumParamsGetter<7, 769> for U768Params { } global U768_PARAMS: BigNumParams<7, 769> = BigNumParams { - has_multiplicative_inverse: false, - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000000000 + has_multiplicative_inverse: false, + modulus: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000000000], + double_modulus: [ + 0x01000000000000000000000000000000, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0x01ffffffffffff, + ], + modulus_u60: U60Repr { + limbs: [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01000000000000, + 0x00, ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffffffff + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01000000000000, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000000000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01000000000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40000000000000 - ] + }, + redc_param: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40000000000000], }; diff --git a/src/fields/U8192.nr b/src/fields/U8192.nr index f5bca5e1..a70b3917 100644 --- a/src/fields/U8192.nr +++ b/src/fields/U8192.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct U8192Params {} +pub struct U8192Params {} impl BigNumParamsGetter<69, 8193> for U8192Params { fn get_params() -> BigNumParams<69, 8193> { @@ -11,18 +11,640 @@ impl BigNumParamsGetter<69, 8193> for U8192Params { } global U8192_PARAMS: BigNumParams<69, 8193> = BigNumParams { - has_multiplicative_inverse: false, - modulus: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000 + has_multiplicative_inverse: false, + modulus: [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0100000000, + ], + double_modulus: [ + 0x01000000000000000000000000000000, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0x01ffffffff, + ], + modulus_u60: U60Repr { + limbs: [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0100000000, + 0x00, ], - double_modulus: [ - 0x01000000000000000000000000000000, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x01ffffffff + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0100000000, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0100000000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4000000000 - ] + }, + redc_param: [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x4000000000, + ], }; diff --git a/src/fields/bls12_377Fq.nr b/src/fields/bls12_377Fq.nr index 843af29c..81a6cc98 100644 --- a/src/fields/bls12_377Fq.nr +++ b/src/fields/bls12_377Fq.nr @@ -29,18 +29,55 @@ impl BigNumParamsGetter<4, 377> for BLS12_377_Fq_Params { } pub global BLS12_377_Fq_PARAMS: BigNumParams<4, 377> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0x0b5d44300000008508c00000000001, 0xd9f300f5138f1ef3622fba09480017, 0x4617c510eac63b05c06ca1493b1a22, 0x01ae3a + has_multiplicative_inverse: true, + modulus: [ + 0x0b5d44300000008508c00000000001, + 0xd9f300f5138f1ef3622fba09480017, + 0x4617c510eac63b05c06ca1493b1a22, + 0x01ae3a, + ], + double_modulus: [ + 0x0116ba88600000010a11800000000002, + 0x01b3e601ea271e3de6c45f741290002d, + 0x018c2f8a21d58c760b80d94292763444, + 0x035c73, + ], + modulus_u60: U60Repr { + limbs: [ + 0x0508c00000000001, + 0xb5d44300000008, + 0x03622fba09480017, + 0x0d9f300f5138f1ef, + 0x05c06ca1493b1a22, + 0x04617c510eac63b0, + 0x01ae3a, + 0x00, ], - double_modulus: [ - 0x0116ba88600000010a11800000000002, 0x01b3e601ea271e3de6c45f741290002d, 0x018c2f8a21d58c760b80d94292763444, 0x035c73 + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0508c00000000001, + 0xb5d44300000008, + 0x03622fba09480017, + 0x0d9f300f5138f1ef, + 0x05c06ca1493b1a22, + 0x04617c510eac63b0, + 0x01ae3a, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x0508c00000000001, 0xb5d44300000008, 0x03622fba09480017, 0x0d9f300f5138f1ef, 0x05c06ca1493b1a22, 0x04617c510eac63b0, 0x01ae3a, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0508c00000000001, 0xb5d44300000008, 0x03622fba09480017, 0x0d9f300f5138f1ef, 0x05c06ca1493b1a22, 0x04617c510eac63b0, 0x01ae3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xd687789c42a591f9fd58c5e4daffcc, 0x0de6776b1a06af2d488d85a6d02d0e, 0xd0cc4060e976c3ca0582ef4f73bbad, 0x261508 - ] + }, + redc_param: [ + 0xd687789c42a591f9fd58c5e4daffcc, + 0x0de6776b1a06af2d488d85a6d02d0e, + 0xd0cc4060e976c3ca0582ef4f73bbad, + 0x261508, + ], }; diff --git a/src/fields/bls12_377Fr.nr b/src/fields/bls12_377Fr.nr index cc0404ab..123b8139 100644 --- a/src/fields/bls12_377Fr.nr +++ b/src/fields/bls12_377Fr.nr @@ -21,7 +21,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct BLS12_377_Fr_Params {} +pub struct BLS12_377_Fr_Params {} impl BigNumParamsGetter<3, 253> for BLS12_377_Fr_Params { fn get_params() -> BigNumParams<3, 253> { @@ -30,18 +30,38 @@ impl BigNumParamsGetter<3, 253> for BLS12_377_Fr_Params { } global BLS12_377_Fr_PARAMS: BigNumParams<3, 253> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0xaa76fed00000010a11800000000001, 0x655e9a2ca55660b44d1e5c37b00159, 0x12ab + has_multiplicative_inverse: true, + modulus: [0xaa76fed00000010a11800000000001, 0x655e9a2ca55660b44d1e5c37b00159, 0x12ab], + double_modulus: [ + 0x0154edfda00000021423000000000002, + 0x01cabd34594aacc1689a3cb86f6002b2, + 0x2555, + ], + modulus_u60: U60Repr { + limbs: [ + 0x0a11800000000001, + 0x0aa76fed00000010, + 0x044d1e5c37b00159, + 0x0655e9a2ca55660b, + 0x12ab, + 0x00, ], - double_modulus: [ - 0x0154edfda00000021423000000000002, 0x01cabd34594aacc1689a3cb86f6002b2, 0x2555 + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0a11800000000001, + 0x0aa76fed00000010, + 0x044d1e5c37b00159, + 0x0655e9a2ca55660b, + 0x12ab, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x0a11800000000001, 0x0aa76fed00000010, 0x044d1e5c37b00159, 0x0655e9a2ca55660b, 0x12ab, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0a11800000000001, 0x0aa76fed00000010, 0x044d1e5c37b00159, 0x0655e9a2ca55660b, 0x12ab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xa180b8d69e258f5204c21151e79ea1, 0x91ec40b2c9ee4e51e49faa80548fd0, 0x036d94 - ] + }, + redc_param: [0xa180b8d69e258f5204c21151e79ea1, 0x91ec40b2c9ee4e51e49faa80548fd0, 0x036d94], }; diff --git a/src/fields/bls12_381Fq.nr b/src/fields/bls12_381Fq.nr index d7d2079c..f2ef2e65 100644 --- a/src/fields/bls12_381Fq.nr +++ b/src/fields/bls12_381Fq.nr @@ -18,7 +18,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct BLS12_381_Fq_Params {} +pub struct BLS12_381_Fq_Params {} impl BigNumParamsGetter<4, 381> for BLS12_381_Fq_Params { fn get_params() -> BigNumParams<4, 381> { @@ -27,18 +27,55 @@ impl BigNumParamsGetter<4, 381> for BLS12_381_Fq_Params { } global BLS12_381_Fq_PARAMS: BigNumParams<4, 381> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0xabfffeb153ffffb9feffffffffaaab, 0x4b84f38512bf6730d2a0f6b0f6241e, 0xea397fe69a4b1ba7b6434bacd76477, 0x1a0111 + has_multiplicative_inverse: true, + modulus: [ + 0xabfffeb153ffffb9feffffffffaaab, + 0x4b84f38512bf6730d2a0f6b0f6241e, + 0xea397fe69a4b1ba7b6434bacd76477, + 0x1a0111, + ], + double_modulus: [ + 0x0157fffd62a7ffff73fdffffffff5556, + 0x019709e70a257ece61a541ed61ec483c, + 0x01d472ffcd3496374f6c869759aec8ed, + 0x340222, + ], + modulus_u60: U60Repr { + limbs: [ + 0x09feffffffffaaab, + 0x0abfffeb153ffffb, + 0xd2a0f6b0f6241e, + 0x04b84f38512bf673, + 0x07b6434bacd76477, + 0x0ea397fe69a4b1ba, + 0x1a0111, + 0x00, ], - double_modulus: [ - 0x0157fffd62a7ffff73fdffffffff5556, 0x019709e70a257ece61a541ed61ec483c, 0x01d472ffcd3496374f6c869759aec8ed, 0x340222 + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x09feffffffffaaab, + 0x0abfffeb153ffffb, + 0xd2a0f6b0f6241e, + 0x04b84f38512bf673, + 0x07b6434bacd76477, + 0x0ea397fe69a4b1ba, + 0x1a0111, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x09feffffffffaaab, 0x0abfffeb153ffffb, 0xd2a0f6b0f6241e, 0x04b84f38512bf673, 0x07b6434bacd76477, 0x0ea397fe69a4b1ba, 0x1a0111, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x09feffffffffaaab, 0x0abfffeb153ffffb, 0xd2a0f6b0f6241e, 0x04b84f38512bf673, 0x07b6434bacd76477, 0x0ea397fe69a4b1ba, 0x1a0111, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x5c59e8163c701ec4f881fd59646e8b, 0x9d07fda82a52f7d1dc780a19de74e6, 0xbcf32791738a0406c331e9ae8a46e0, 0x02760d74 - ] + }, + redc_param: [ + 0x5c59e8163c701ec4f881fd59646e8b, + 0x9d07fda82a52f7d1dc780a19de74e6, + 0xbcf32791738a0406c331e9ae8a46e0, + 0x02760d74, + ], }; diff --git a/src/fields/bls12_381Fr.nr b/src/fields/bls12_381Fr.nr index 0b359dcd..2635d62b 100644 --- a/src/fields/bls12_381Fr.nr +++ b/src/fields/bls12_381Fr.nr @@ -18,7 +18,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct BLS12_381_Fr_Params {} +pub struct BLS12_381_Fr_Params {} impl BigNumParamsGetter<3, 255> for BLS12_381_Fr_Params { fn get_params() -> BigNumParams<3, 255> { @@ -27,18 +27,38 @@ impl BigNumParamsGetter<3, 255> for BLS12_381_Fr_Params { } global BLS12_381_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0xbda402fffe5bfeffffffff00000001, 0xa753299d7d483339d80809a1d80553, 0x73ed + has_multiplicative_inverse: true, + modulus: [0xbda402fffe5bfeffffffff00000001, 0xa753299d7d483339d80809a1d80553, 0x73ed], + double_modulus: [ + 0x017b4805fffcb7fdfffffffe00000002, + 0x014ea6533afa906673b0101343b00aa6, + 0xe7da, + ], + modulus_u60: U60Repr { + limbs: [ + 0x0fffffff00000001, + 0x0bda402fffe5bfef, + 0x09d80809a1d80553, + 0x0a753299d7d48333, + 0x73ed, + 0x00, ], - double_modulus: [ - 0x017b4805fffcb7fdfffffffe00000002, 0x014ea6533afa906673b0101343b00aa6, 0xe7da + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0fffffff00000001, + 0x0bda402fffe5bfef, + 0x09d80809a1d80553, + 0x0a753299d7d48333, + 0x73ed, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x0fffffff00000001, 0x0bda402fffe5bfef, 0x09d80809a1d80553, 0x0a753299d7d48333, 0x73ed, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0fffffff00000001, 0x0bda402fffe5bfef, 0x09d80809a1d80553, 0x0a753299d7d48333, 0x73ed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x10fad2f92eb5c509cde80830358e4c, 0x53b7fb78ddf0e2d772dc1f823b4d94, 0x08d542 - ] + }, + redc_param: [0x10fad2f92eb5c509cde80830358e4c, 0x53b7fb78ddf0e2d772dc1f823b4d94, 0x08d542], }; diff --git a/src/fields/bn254Fq.nr b/src/fields/bn254Fq.nr index ba12593c..d1fd56e9 100644 --- a/src/fields/bn254Fq.nr +++ b/src/fields/bn254Fq.nr @@ -11,18 +11,38 @@ impl BigNumParamsGetter<3, 254> for BN254_Fq_Params { } global BN254_Fq_PARAMS: BigNumParams<3, 254> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0x816a916871ca8d3c208c16d87cfd47, 0x4e72e131a029b85045b68181585d97, 0x3064 + has_multiplicative_inverse: true, + modulus: [0x816a916871ca8d3c208c16d87cfd47, 0x4e72e131a029b85045b68181585d97, 0x3064], + double_modulus: [ + 0x0102d522d0e3951a7841182db0f9fa8e, + 0x019ce5c263405370a08b6d0302b0bb2e, + 0x60c7, + ], + modulus_u60: U60Repr { + limbs: [ + 0x0c208c16d87cfd47, + 0x0816a916871ca8d3, + 0x45b68181585d97, + 0x04e72e131a029b85, + 0x3064, + 0x00, ], - double_modulus: [ - 0x0102d522d0e3951a7841182db0f9fa8e, 0x019ce5c263405370a08b6d0302b0bb2e, 0x60c7 + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0c208c16d87cfd47, + 0x0816a916871ca8d3, + 0x45b68181585d97, + 0x04e72e131a029b85, + 0x3064, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x0c208c16d87cfd47, 0x0816a916871ca8d3, 0x45b68181585d97, 0x04e72e131a029b85, 0x3064, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0c208c16d87cfd47, 0x0816a916871ca8d3, 0x45b68181585d97, 0x04e72e131a029b85, 0x3064, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x65e1767cd4c086f3aed8a19bf90e51, 0x462623a04a7ab074a5868073013ae9, 0x054a47 - ] + }, + redc_param: [0x65e1767cd4c086f3aed8a19bf90e51, 0x462623a04a7ab074a5868073013ae9, 0x054a47], }; diff --git a/src/fields/ed25519Fq.nr b/src/fields/ed25519Fq.nr index 24a39572..0a19b9a0 100644 --- a/src/fields/ed25519Fq.nr +++ b/src/fields/ed25519Fq.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct ED25519_Fq_Params {} +pub struct ED25519_Fq_Params {} impl BigNumParamsGetter<3, 255> for ED25519_Fq_Params { fn get_params() -> BigNumParams<3, 255> { @@ -11,18 +11,38 @@ impl BigNumParamsGetter<3, 255> for ED25519_Fq_Params { } global ED25519_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0xffffffffffffffffffffffffffffed, 0xffffffffffffffffffffffffffffff, 0x7fff + has_multiplicative_inverse: true, + modulus: [0xffffffffffffffffffffffffffffed, 0xffffffffffffffffffffffffffffff, 0x7fff], + double_modulus: [ + 0x01ffffffffffffffffffffffffffffda, + 0x01fffffffffffffffffffffffffffffe, + 0xfffe, + ], + modulus_u60: U60Repr { + limbs: [ + 0x0fffffffffffffed, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0x7fff, + 0x00, ], - double_modulus: [ - 0x01ffffffffffffffffffffffffffffda, 0x01fffffffffffffffffffffffffffffe, 0xfffe + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0fffffffffffffed, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0x7fff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x0fffffffffffffed, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x7fff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0fffffffffffffed, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x7fff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x0130, 0x00, 0x080000 - ] + }, + redc_param: [0x0130, 0x00, 0x080000], }; diff --git a/src/fields/ed25519Fr.nr b/src/fields/ed25519Fr.nr index 5dd6070c..cdc2005f 100644 --- a/src/fields/ed25519Fr.nr +++ b/src/fields/ed25519Fr.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct ED25519_Fr_Params {} +pub struct ED25519_Fr_Params {} impl BigNumParamsGetter<3, 255> for ED25519_Fr_Params { fn get_params() -> BigNumParams<3, 255> { @@ -11,18 +11,31 @@ impl BigNumParamsGetter<3, 255> for ED25519_Fr_Params { } global ED25519_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0xdef9dea2f79cd65812631a5cf5d3ed, 0x14, 0x1000 + has_multiplicative_inverse: true, + modulus: [0xdef9dea2f79cd65812631a5cf5d3ed, 0x14, 0x1000], + double_modulus: [ + 0x01bdf3bd45ef39acb024c634b9eba7da, + 0x01000000000000000000000000000028, + 0x1fff, + ], + modulus_u60: U60Repr { + limbs: [0x0812631a5cf5d3ed, 0x0def9dea2f79cd65, 0x14, 0x00, 0x1000, 0x00], + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0812631a5cf5d3ed, + 0x0def9dea2f79cd65, + 0x14, + 0x00, + 0x1000, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - double_modulus: [ - 0x01bdf3bd45ef39acb024c634b9eba7da, 0x01000000000000000000000000000028, 0x1fff - ], - modulus_u60: U60Repr { limbs: [ - 0x0812631a5cf5d3ed, 0x0def9dea2f79cd65, 0x14, 0x00, 0x1000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0812631a5cf5d3ed, 0x0def9dea2f79cd65, 0x14, 0x00, 0x1000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x4188574218ca69fb673968c28b04c6, 0xfffffffffffffffffffffffffffac8, 0x03ffff - ] + }, + redc_param: [0x4188574218ca69fb673968c28b04c6, 0xfffffffffffffffffffffffffffac8, 0x03ffff], }; diff --git a/src/fields/mnt4_753Fq.nr b/src/fields/mnt4_753Fq.nr index 0e1c5273..849a7532 100644 --- a/src/fields/mnt4_753Fq.nr +++ b/src/fields/mnt4_753Fq.nr @@ -32,19 +32,82 @@ impl BigNumParamsGetter<7, 753> for MNT4_753_Fq_Params { } global MNT4_753_Fq_PARAMS: BigNumParams<7, 753> = BigNumParams { - has_multiplicative_inverse: true, - - modulus: [ - 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 + has_multiplicative_inverse: true, + modulus: [ + 0x9d54522cdd119f5e9063de245e8001, + 0xcce9767254a4638810719ac425f0e3, + 0x76f218059db80f0da5cb537e38685a, + 0xe8a0ed8d99d124d9a15af79db117e7, + 0x8fafed5eb7e8f96c97d87307fdb925, + 0xc41110229022eee2cdadb7f997505b, + 0x01c4c62d92, + ], + double_modulus: [ + 0x013aa8a459ba233ebd20c7bc48bd0002, + 0x0199d2ece4a948c71020e335884be1c6, + 0x01ede4300b3b701e1b4b96a6fc70d0b4, + 0x01d141db1b33a249b342b5ef3b622fcd, + 0x011f5fdabd6fd1f2d92fb0e60ffb724a, + 0x01882220452045ddc59b5b6ff32ea0b6, + 0x03898c5b24, + ], + modulus_u60: U60Repr { + limbs: [ + 0x0e9063de245e8001, + 0x09d54522cdd119f5, + 0x0810719ac425f0e3, + 0x0cce9767254a4638, + 0x0da5cb537e38685a, + 0x076f218059db80f0, + 0x09a15af79db117e7, + 0x0e8a0ed8d99d124d, + 0x0c97d87307fdb925, + 0x08fafed5eb7e8f96, + 0x02cdadb7f997505b, + 0x0c41110229022eee, + 0x01c4c62d92, + 0x00, ], - double_modulus: [ - 0x013aa8a459ba233ebd20c7bc48bd0002, 0x0199d2ece4a948c71020e335884be1c6, 0x01ede4300b3b701e1b4b96a6fc70d0b4, 0x01d141db1b33a249b342b5ef3b622fcd, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0e9063de245e8001, + 0x09d54522cdd119f5, + 0x0810719ac425f0e3, + 0x0cce9767254a4638, + 0x0da5cb537e38685a, + 0x076f218059db80f0, + 0x09a15af79db117e7, + 0x0e8a0ed8d99d124d, + 0x0c97d87307fdb925, + 0x08fafed5eb7e8f96, + 0x02cdadb7f997505b, + 0x0c41110229022eee, + 0x01c4c62d92, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x5dcc95da918349f4965a2aee8fd750, 0x82372b75580c27c4d1f1f57a96a114, 0x58326e3c0552419849e3c7171d8522, 0x300e0ede1965cbf72f0aa9bf03479d, 0x7fb932cae2aba9a5d17c1ff73538ba, 0x82727c6eaef38056aaa0aaedb05746, 0x242f916cfa - ] + }, + redc_param: [ + 0x5dcc95da918349f4965a2aee8fd750, + 0x82372b75580c27c4d1f1f57a96a114, + 0x58326e3c0552419849e3c7171d8522, + 0x300e0ede1965cbf72f0aa9bf03479d, + 0x7fb932cae2aba9a5d17c1ff73538ba, + 0x82727c6eaef38056aaa0aaedb05746, + 0x242f916cfa, + ], }; diff --git a/src/fields/mnt4_753Fr.nr b/src/fields/mnt4_753Fr.nr index aa010a4d..21982f9f 100644 --- a/src/fields/mnt4_753Fr.nr +++ b/src/fields/mnt4_753Fr.nr @@ -23,7 +23,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct MNT4_753_Fr_Params {} +pub struct MNT4_753_Fr_Params {} impl BigNumParamsGetter<7, 753> for MNT4_753_Fr_Params { fn get_params() -> BigNumParams<7, 753> { @@ -32,18 +32,82 @@ impl BigNumParamsGetter<7, 753> for MNT4_753_Fr_Params { } global MNT4_753_Fr_PARAMS: BigNumParams<7, 753> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 + has_multiplicative_inverse: true, + modulus: [ + 0xa099170fa13a4fd90776e240000001, + 0xf97634993aa4d6c381bc3f0057974e, + 0x28c859a99b3eebca9429212636b9df, + 0xe8a0ed8d99d124d9a15af79db26c5c, + 0x8fafed5eb7e8f96c97d87307fdb925, + 0xc41110229022eee2cdadb7f997505b, + 0x01c4c62d92, + ], + double_modulus: [ + 0x0141322e1f42749fb20eedc480000002, + 0x01f2ec69327549ad8703787e00af2e9c, + 0x015190b353367dd7952852424c6d73be, + 0x01d141db1b33a249b342b5ef3b64d8b7, + 0x011f5fdabd6fd1f2d92fb0e60ffb724a, + 0x01882220452045ddc59b5b6ff32ea0b6, + 0x03898c5b24, + ], + modulus_u60: U60Repr { + limbs: [ + 0x090776e240000001, + 0x0a099170fa13a4fd, + 0x0381bc3f0057974e, + 0x0f97634993aa4d6c, + 0x0a9429212636b9df, + 0x028c859a99b3eebc, + 0x09a15af79db26c5c, + 0x0e8a0ed8d99d124d, + 0x0c97d87307fdb925, + 0x08fafed5eb7e8f96, + 0x02cdadb7f997505b, + 0x0c41110229022eee, + 0x01c4c62d92, + 0x00, ], - double_modulus: [ - 0x0141322e1f42749fb20eedc480000002, 0x01f2ec69327549ad8703787e00af2e9c, 0x015190b353367dd7952852424c6d73be, 0x01d141db1b33a249b342b5ef3b64d8b7, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x090776e240000001, + 0x0a099170fa13a4fd, + 0x0381bc3f0057974e, + 0x0f97634993aa4d6c, + 0x0a9429212636b9df, + 0x028c859a99b3eebc, + 0x09a15af79db26c5c, + 0x0e8a0ed8d99d124d, + 0x0c97d87307fdb925, + 0x08fafed5eb7e8f96, + 0x02cdadb7f997505b, + 0x0c41110229022eee, + 0x01c4c62d92, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x2dae11d15867718ec70f5ff059bba2, 0x76d65fe7e00ba391da260f2623ff9a, 0x140a086edaa60c58eb476bdedcb352, 0x300e0ede1965cbf72f0aa9bee81208, 0x7fb932cae2aba9a5d17c1ff73538ba, 0x82727c6eaef38056aaa0aaedb05746, 0x242f916cfa - ] + }, + redc_param: [ + 0x2dae11d15867718ec70f5ff059bba2, + 0x76d65fe7e00ba391da260f2623ff9a, + 0x140a086edaa60c58eb476bdedcb352, + 0x300e0ede1965cbf72f0aa9bee81208, + 0x7fb932cae2aba9a5d17c1ff73538ba, + 0x82727c6eaef38056aaa0aaedb05746, + 0x242f916cfa, + ], }; diff --git a/src/fields/mnt6_753Fq.nr b/src/fields/mnt6_753Fq.nr index 29e9a0d3..421a36b4 100644 --- a/src/fields/mnt6_753Fq.nr +++ b/src/fields/mnt6_753Fq.nr @@ -23,7 +23,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct MNT6_753_Fq_Params {} +pub struct MNT6_753_Fq_Params {} impl BigNumParamsGetter<7, 753> for MNT6_753_Fq_Params { fn get_params() -> BigNumParams<7, 753> { @@ -32,19 +32,82 @@ impl BigNumParamsGetter<7, 753> for MNT6_753_Fq_Params { } global MNT6_753_Fq_PARAMS: BigNumParams<7, 753> = BigNumParams { - has_multiplicative_inverse: true, - - modulus: [ - 0xa099170fa13a4fd90776e240000001, 0xf97634993aa4d6c381bc3f0057974e, 0x28c859a99b3eebca9429212636b9df, 0xe8a0ed8d99d124d9a15af79db26c5c, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 + has_multiplicative_inverse: true, + modulus: [ + 0xa099170fa13a4fd90776e240000001, + 0xf97634993aa4d6c381bc3f0057974e, + 0x28c859a99b3eebca9429212636b9df, + 0xe8a0ed8d99d124d9a15af79db26c5c, + 0x8fafed5eb7e8f96c97d87307fdb925, + 0xc41110229022eee2cdadb7f997505b, + 0x01c4c62d92, + ], + double_modulus: [ + 0x0141322e1f42749fb20eedc480000002, + 0x01f2ec69327549ad8703787e00af2e9c, + 0x015190b353367dd7952852424c6d73be, + 0x01d141db1b33a249b342b5ef3b64d8b7, + 0x011f5fdabd6fd1f2d92fb0e60ffb724a, + 0x01882220452045ddc59b5b6ff32ea0b6, + 0x03898c5b24, + ], + modulus_u60: U60Repr { + limbs: [ + 0x090776e240000001, + 0x0a099170fa13a4fd, + 0x0381bc3f0057974e, + 0x0f97634993aa4d6c, + 0x0a9429212636b9df, + 0x028c859a99b3eebc, + 0x09a15af79db26c5c, + 0x0e8a0ed8d99d124d, + 0x0c97d87307fdb925, + 0x08fafed5eb7e8f96, + 0x02cdadb7f997505b, + 0x0c41110229022eee, + 0x01c4c62d92, + 0x00, ], - double_modulus: [ - 0x0141322e1f42749fb20eedc480000002, 0x01f2ec69327549ad8703787e00af2e9c, 0x015190b353367dd7952852424c6d73be, 0x01d141db1b33a249b342b5ef3b64d8b7, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x090776e240000001, + 0x0a099170fa13a4fd, + 0x0381bc3f0057974e, + 0x0f97634993aa4d6c, + 0x0a9429212636b9df, + 0x028c859a99b3eebc, + 0x09a15af79db26c5c, + 0x0e8a0ed8d99d124d, + 0x0c97d87307fdb925, + 0x08fafed5eb7e8f96, + 0x02cdadb7f997505b, + 0x0c41110229022eee, + 0x01c4c62d92, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x090776e240000001, 0x0a099170fa13a4fd, 0x0381bc3f0057974e, 0x0f97634993aa4d6c, 0x0a9429212636b9df, 0x028c859a99b3eebc, 0x09a15af79db26c5c, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x2dae11d15867718ec70f5ff059bba2, 0x76d65fe7e00ba391da260f2623ff9a, 0x140a086edaa60c58eb476bdedcb352, 0x300e0ede1965cbf72f0aa9bee81208, 0x7fb932cae2aba9a5d17c1ff73538ba, 0x82727c6eaef38056aaa0aaedb05746, 0x242f916cfa - ] + }, + redc_param: [ + 0x2dae11d15867718ec70f5ff059bba2, + 0x76d65fe7e00ba391da260f2623ff9a, + 0x140a086edaa60c58eb476bdedcb352, + 0x300e0ede1965cbf72f0aa9bee81208, + 0x7fb932cae2aba9a5d17c1ff73538ba, + 0x82727c6eaef38056aaa0aaedb05746, + 0x242f916cfa, + ], }; diff --git a/src/fields/mnt6_753Fr.nr b/src/fields/mnt6_753Fr.nr index d487164f..24110720 100644 --- a/src/fields/mnt6_753Fr.nr +++ b/src/fields/mnt6_753Fr.nr @@ -23,7 +23,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct MNT6_753_Fr_Params {} +pub struct MNT6_753_Fr_Params {} impl BigNumParamsGetter<7, 753> for MNT6_753_Fr_Params { fn get_params() -> BigNumParams<7, 753> { @@ -32,19 +32,82 @@ impl BigNumParamsGetter<7, 753> for MNT6_753_Fr_Params { } global MNT6_753_Fr_PARAMS: BigNumParams<7, 753> = BigNumParams { - has_multiplicative_inverse: true, - - modulus: [ - 0x9d54522cdd119f5e9063de245e8001, 0xcce9767254a4638810719ac425f0e3, 0x76f218059db80f0da5cb537e38685a, 0xe8a0ed8d99d124d9a15af79db117e7, 0x8fafed5eb7e8f96c97d87307fdb925, 0xc41110229022eee2cdadb7f997505b, 0x01c4c62d92 + has_multiplicative_inverse: true, + modulus: [ + 0x9d54522cdd119f5e9063de245e8001, + 0xcce9767254a4638810719ac425f0e3, + 0x76f218059db80f0da5cb537e38685a, + 0xe8a0ed8d99d124d9a15af79db117e7, + 0x8fafed5eb7e8f96c97d87307fdb925, + 0xc41110229022eee2cdadb7f997505b, + 0x01c4c62d92, + ], + double_modulus: [ + 0x013aa8a459ba233ebd20c7bc48bd0002, + 0x0199d2ece4a948c71020e335884be1c6, + 0x01ede4300b3b701e1b4b96a6fc70d0b4, + 0x01d141db1b33a249b342b5ef3b622fcd, + 0x011f5fdabd6fd1f2d92fb0e60ffb724a, + 0x01882220452045ddc59b5b6ff32ea0b6, + 0x03898c5b24, + ], + modulus_u60: U60Repr { + limbs: [ + 0x0e9063de245e8001, + 0x09d54522cdd119f5, + 0x0810719ac425f0e3, + 0x0cce9767254a4638, + 0x0da5cb537e38685a, + 0x076f218059db80f0, + 0x09a15af79db117e7, + 0x0e8a0ed8d99d124d, + 0x0c97d87307fdb925, + 0x08fafed5eb7e8f96, + 0x02cdadb7f997505b, + 0x0c41110229022eee, + 0x01c4c62d92, + 0x00, ], - double_modulus: [ - 0x013aa8a459ba233ebd20c7bc48bd0002, 0x0199d2ece4a948c71020e335884be1c6, 0x01ede4300b3b701e1b4b96a6fc70d0b4, 0x01d141db1b33a249b342b5ef3b622fcd, 0x011f5fdabd6fd1f2d92fb0e60ffb724a, 0x01882220452045ddc59b5b6ff32ea0b6, 0x03898c5b24 + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0e9063de245e8001, + 0x09d54522cdd119f5, + 0x0810719ac425f0e3, + 0x0cce9767254a4638, + 0x0da5cb537e38685a, + 0x076f218059db80f0, + 0x09a15af79db117e7, + 0x0e8a0ed8d99d124d, + 0x0c97d87307fdb925, + 0x08fafed5eb7e8f96, + 0x02cdadb7f997505b, + 0x0c41110229022eee, + 0x01c4c62d92, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0e9063de245e8001, 0x09d54522cdd119f5, 0x0810719ac425f0e3, 0x0cce9767254a4638, 0x0da5cb537e38685a, 0x076f218059db80f0, 0x09a15af79db117e7, 0x0e8a0ed8d99d124d, 0x0c97d87307fdb925, 0x08fafed5eb7e8f96, 0x02cdadb7f997505b, 0x0c41110229022eee, 0x01c4c62d92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x5dcc95da918349f4965a2aee8fd750, 0x82372b75580c27c4d1f1f57a96a114, 0x58326e3c0552419849e3c7171d8522, 0x300e0ede1965cbf72f0aa9bf03479d, 0x7fb932cae2aba9a5d17c1ff73538ba, 0x82727c6eaef38056aaa0aaedb05746, 0x242f916cfa - ] + }, + redc_param: [ + 0x5dcc95da918349f4965a2aee8fd750, + 0x82372b75580c27c4d1f1f57a96a114, + 0x58326e3c0552419849e3c7171d8522, + 0x300e0ede1965cbf72f0aa9bf03479d, + 0x7fb932cae2aba9a5d17c1ff73538ba, + 0x82727c6eaef38056aaa0aaedb05746, + 0x242f916cfa, + ], }; diff --git a/src/fields/pallasFq.nr b/src/fields/pallasFq.nr index ae60bcbb..a5f6a1a8 100644 --- a/src/fields/pallasFq.nr +++ b/src/fields/pallasFq.nr @@ -17,7 +17,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Pallas_Fq_Params {} +pub struct Pallas_Fq_Params {} impl BigNumParamsGetter<3, 255> for Pallas_Fq_Params { fn get_params() -> BigNumParams<3, 255> { @@ -26,18 +26,31 @@ impl BigNumParamsGetter<3, 255> for Pallas_Fq_Params { } global Pallas_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 + has_multiplicative_inverse: true, + modulus: [0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000], + double_modulus: [ + 0x018d31f81299f237325a61da00000002, + 0x01000000000000000000000000000043, + 0x7fff, + ], + modulus_u60: U60Repr { + limbs: [0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00], + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x092d30ed00000001, + 0x04698fc094cf91b9, + 0x22, + 0x00, + 0x4000, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - double_modulus: [ - 0x018d31f81299f237325a61da00000002, 0x01000000000000000000000000000043, 0x7fff - ], - modulus_u60: U60Repr { limbs: [ - 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x59c0fdacc1b919b4b3c4bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff - ] + }, + redc_param: [0x59c0fdacc1b919b4b3c4bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff], }; diff --git a/src/fields/pallasFr.nr b/src/fields/pallasFr.nr index b7bf1380..502b0da2 100644 --- a/src/fields/pallasFr.nr +++ b/src/fields/pallasFr.nr @@ -17,7 +17,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Pallas_Fr_Params {} +pub struct Pallas_Fr_Params {} impl BigNumParamsGetter<3, 255> for Pallas_Fr_Params { fn get_params() -> BigNumParams<3, 255> { @@ -26,18 +26,31 @@ impl BigNumParamsGetter<3, 255> for Pallas_Fr_Params { } global Pallas_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 + has_multiplicative_inverse: true, + modulus: [0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000], + double_modulus: [ + 0x018d31f8132951bb188dd64200000002, + 0x01000000000000000000000000000043, + 0x7fff, + ], + modulus_u60: U60Repr { + limbs: [0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00], + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0c46eb2100000001, + 0x04698fc0994a8dd8, + 0x22, + 0x00, + 0x4000, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - double_modulus: [ - 0x018d31f8132951bb188dd64200000002, 0x01000000000000000000000000000043, 0x7fff - ], - modulus_u60: U60Repr { limbs: [ - 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x59c0fd9ad5c89cee4537bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff - ] + }, + redc_param: [0x59c0fd9ad5c89cee4537bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff], }; diff --git a/src/fields/secp256k1Fq.nr b/src/fields/secp256k1Fq.nr index 7321a003..463ea901 100644 --- a/src/fields/secp256k1Fq.nr +++ b/src/fields/secp256k1Fq.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Secp256k1_Fq_Params {} +pub struct Secp256k1_Fq_Params {} impl BigNumParamsGetter<3, 256> for Secp256k1_Fq_Params { fn get_params() -> BigNumParams<3, 256> { @@ -11,18 +11,38 @@ impl BigNumParamsGetter<3, 256> for Secp256k1_Fq_Params { } global Secp256k1_Fq_PARAMS: BigNumParams<3, 256> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0xfffffffffffffffffffffefffffc2f, 0xffffffffffffffffffffffffffffff, 0xffff + has_multiplicative_inverse: true, + modulus: [0xfffffffffffffffffffffefffffc2f, 0xffffffffffffffffffffffffffffff, 0xffff], + double_modulus: [ + 0x01fffffffffffffffffffffdfffff85e, + 0x01fffffffffffffffffffffffffffffe, + 0x01fffe, + ], + modulus_u60: U60Repr { + limbs: [ + 0x0ffffffefffffc2f, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0xffff, + 0x00, ], - double_modulus: [ - 0x01fffffffffffffffffffffdfffff85e, 0x01fffffffffffffffffffffffffffffe, 0x01fffe + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0ffffffefffffc2f, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0xffff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x0ffffffefffffc2f, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0ffffffefffffc2f, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x1000003d10, 0x00, 0x100000 - ] + }, + redc_param: [0x1000003d10, 0x00, 0x100000], }; diff --git a/src/fields/secp256k1Fr.nr b/src/fields/secp256k1Fr.nr index 2e846558..9b137928 100644 --- a/src/fields/secp256k1Fr.nr +++ b/src/fields/secp256k1Fr.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Secp256k1_Fr_Params {} +pub struct Secp256k1_Fr_Params {} impl BigNumParamsGetter<3, 256> for Secp256k1_Fr_Params { fn get_params() -> BigNumParams<3, 256> { @@ -11,18 +11,38 @@ impl BigNumParamsGetter<3, 256> for Secp256k1_Fr_Params { } global Secp256k1_Fr_PARAMS: BigNumParams<3, 256> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0xaedce6af48a03bbfd25e8cd0364141, 0xfffffffffffffffffffffffffffeba, 0xffff + has_multiplicative_inverse: true, + modulus: [0xaedce6af48a03bbfd25e8cd0364141, 0xfffffffffffffffffffffffffffeba, 0xffff], + double_modulus: [ + 0x015db9cd5e9140777fa4bd19a06c8282, + 0x01fffffffffffffffffffffffffffd74, + 0x01fffe, + ], + modulus_u60: U60Repr { + limbs: [ + 0x0fd25e8cd0364141, + 0x0aedce6af48a03bb, + 0x0ffffffffffffeba, + 0x0fffffffffffffff, + 0xffff, + 0x00, ], - double_modulus: [ - 0x015db9cd5e9140777fa4bd19a06c8282, 0x01fffffffffffffffffffffffffffd74, 0x01fffe + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0fd25e8cd0364141, + 0x0aedce6af48a03bb, + 0x0ffffffffffffeba, + 0x0fffffffffffffff, + 0xffff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x0fd25e8cd0364141, 0x0aedce6af48a03bb, 0x0ffffffffffffeba, 0x0fffffffffffffff, 0xffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0fd25e8cd0364141, 0x0aedce6af48a03bb, 0x0ffffffffffffeba, 0x0fffffffffffffff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x1231950b75fc4402da1732fc9bec09, 0x1455, 0x100000 - ] + }, + redc_param: [0x1231950b75fc4402da1732fc9bec09, 0x1455, 0x100000], }; diff --git a/src/fields/secp256r1Fq.nr b/src/fields/secp256r1Fq.nr index 6465cd22..4d4ebaee 100644 --- a/src/fields/secp256r1Fq.nr +++ b/src/fields/secp256r1Fq.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Secp256r1_Fq_Params {} +pub struct Secp256r1_Fq_Params {} impl BigNumParamsGetter<3, 265> for Secp256r1_Fq_Params { fn get_params() -> BigNumParams<3, 265> { @@ -11,18 +11,31 @@ impl BigNumParamsGetter<3, 265> for Secp256r1_Fq_Params { } global Secp256r1_Fq_PARAMS: BigNumParams<3, 265> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0xffffffffffffffffffffffff, 0xffff00000001000000000000000000, 0xffff + has_multiplicative_inverse: true, + modulus: [0xffffffffffffffffffffffff, 0xffff00000001000000000000000000, 0xffff], + double_modulus: [ + 0x01000001fffffffffffffffffffffffe, + 0x01fffe00000001ffffffffffffffffff, + 0x01fffe, + ], + modulus_u60: U60Repr { + limbs: [0x0fffffffffffffff, 0x0fffffffff, 0x00, 0x0ffff00000001000, 0xffff, 0x00], + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0fffffffffffffff, + 0x0fffffffff, + 0x00, + 0x0ffff00000001000, + 0xffff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - double_modulus: [ - 0x01000001fffffffffffffffffffffffe, 0x01fffe00000001ffffffffffffffffff, 0x01fffe - ], - modulus_u60: U60Repr { limbs: [ - 0x0fffffffffffffff, 0x0fffffffff, 0x00, 0x0ffff00000001000, 0xffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0fffffffffffffff, 0x0fffffffff, 0x00, 0x0ffff00000001000, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0xffffeffffffff00000000000000030, 0x0fffffffffffffffefffffffefff, 0x100000 - ] + }, + redc_param: [0xffffeffffffff00000000000000030, 0x0fffffffffffffffefffffffefff, 0x100000], }; diff --git a/src/fields/secp256r1Fr.nr b/src/fields/secp256r1Fr.nr index 9b8fea4f..8db71855 100644 --- a/src/fields/secp256r1Fr.nr +++ b/src/fields/secp256r1Fr.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Secp256r1_Fr_Params {} +pub struct Secp256r1_Fr_Params {} impl BigNumParamsGetter<3, 256> for Secp256r1_Fr_Params { fn get_params() -> BigNumParams<3, 256> { @@ -11,18 +11,38 @@ impl BigNumParamsGetter<3, 256> for Secp256r1_Fr_Params { } global Secp256r1_Fr_PARAMS: BigNumParams<3, 256> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0xe6faada7179e84f3b9cac2fc632551, 0xffff00000000ffffffffffffffffbc, 0xffff + has_multiplicative_inverse: true, + modulus: [0xe6faada7179e84f3b9cac2fc632551, 0xffff00000000ffffffffffffffffbc, 0xffff], + double_modulus: [ + 0x01cdf55b4e2f3d09e7739585f8c64aa2, + 0x01fffe00000001ffffffffffffffff78, + 0x01fffe, + ], + modulus_u60: U60Repr { + limbs: [ + 0x03b9cac2fc632551, + 0x0e6faada7179e84f, + 0x0fffffffffffffbc, + 0x0ffff00000000fff, + 0xffff, + 0x00, ], - double_modulus: [ - 0x01cdf55b4e2f3d09e7739585f8c64aa2, 0x01fffe00000001ffffffffffffffff78, 0x01fffe + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x03b9cac2fc632551, + 0x0e6faada7179e84f, + 0x0fffffffffffffbc, + 0x0ffff00000000fff, + 0xffff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x03b9cac2fc632551, 0x0e6faada7179e84f, 0x0fffffffffffffbc, 0x0ffff00000000fff, 0xffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x03b9cac2fc632551, 0x0e6faada7179e84f, 0x0fffffffffffffbc, 0x0ffff00000000fff, 0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x90552df1a6c21012ffd85eedf9bfe6, 0x0fffffffffffffffeffffffff431, 0x100000 - ] + }, + redc_param: [0x90552df1a6c21012ffd85eedf9bfe6, 0x0fffffffffffffffeffffffff431, 0x100000], }; diff --git a/src/fields/secp384r1Fq.nr b/src/fields/secp384r1Fq.nr index 26e288a2..599aeec8 100644 --- a/src/fields/secp384r1Fq.nr +++ b/src/fields/secp384r1Fq.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Secp384r1_Fq_Params {} +pub struct Secp384r1_Fq_Params {} impl BigNumParamsGetter<4, 384> for Secp384r1_Fq_Params { fn get_params() -> BigNumParams<4, 384> { @@ -11,18 +11,50 @@ impl BigNumParamsGetter<4, 384> for Secp384r1_Fq_Params { } global Secp384r1_Fq_PARAMS: BigNumParams<4, 384> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0xffffff0000000000000000ffffffff, 0xfffffffffffffffffffffffffffeff, 0xffffffffffffffffffffffffffffff, 0xffffff + has_multiplicative_inverse: true, + modulus: [ + 0xffffff0000000000000000ffffffff, + 0xfffffffffffffffffffffffffffeff, + 0xffffffffffffffffffffffffffffff, + 0xffffff, + ], + double_modulus: [ + 0x01fffffe0000000000000001fffffffe, + 0x01fffffffffffffffffffffffffffdfe, + 0x01fffffffffffffffffffffffffffffe, + 0x01fffffe, + ], + modulus_u60: U60Repr { + limbs: [ + 0xffffffff, + 0x0ffffff000000000, + 0x0ffffffffffffeff, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0xffffff, + 0x00, ], - double_modulus: [ - 0x01fffffe0000000000000001fffffffe, 0x01fffffffffffffffffffffffffffdfe, 0x01fffffffffffffffffffffffffffffe, 0x01fffffe + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0xffffffff, + 0x0ffffff000000000, + 0x0ffffffffffffeff, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0xffffff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0xffffffff, 0x0ffffff000000000, 0x0ffffffffffffeff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0xffffffff, 0x0ffffff000000000, 0x0ffffffffffffeff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x0ffffffffffffffff000000010, 0x1000, 0x00, 0x10000000 - ] + }, + redc_param: [0x0ffffffffffffffff000000010, 0x1000, 0x00, 0x10000000], }; diff --git a/src/fields/secp384r1Fr.nr b/src/fields/secp384r1Fr.nr index b6585248..6755694e 100644 --- a/src/fields/secp384r1Fr.nr +++ b/src/fields/secp384r1Fr.nr @@ -2,7 +2,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Secp384r1_Fr_Params {} +pub struct Secp384r1_Fr_Params {} impl BigNumParamsGetter<4, 384> for Secp384r1_Fr_Params { fn get_params() -> BigNumParams<4, 384> { @@ -11,18 +11,50 @@ impl BigNumParamsGetter<4, 384> for Secp384r1_Fr_Params { } global Secp384r1_Fr_PARAMS: BigNumParams<4, 384> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0x1a0db248b0a77aecec196accc52973, 0xffffffffffffc7634d81f4372ddf58, 0xffffffffffffffffffffffffffffff, 0xffffff + has_multiplicative_inverse: true, + modulus: [ + 0x1a0db248b0a77aecec196accc52973, + 0xffffffffffffc7634d81f4372ddf58, + 0xffffffffffffffffffffffffffffff, + 0xffffff, + ], + double_modulus: [ + 0x01341b6491614ef5d9d832d5998a52e6, + 0x01ffffffffffff8ec69b03e86e5bbeaf, + 0x01fffffffffffffffffffffffffffffe, + 0x01fffffe, + ], + modulus_u60: U60Repr { + limbs: [ + 0x0cec196accc52973, + 0x01a0db248b0a77ae, + 0x034d81f4372ddf58, + 0x0ffffffffffffc76, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0xffffff, + 0x00, ], - double_modulus: [ - 0x01341b6491614ef5d9d832d5998a52e6, 0x01ffffffffffff8ec69b03e86e5bbeaf, 0x01fffffffffffffffffffffffffffffe, 0x01fffffe + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0cec196accc52973, + 0x01a0db248b0a77ae, + 0x034d81f4372ddf58, + 0x0ffffffffffffc76, + 0x0fffffffffffffff, + 0x0fffffffffffffff, + 0xffffff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - modulus_u60: U60Repr { limbs: [ - 0x0cec196accc52973, 0x01a0db248b0a77ae, 0x034d81f4372ddf58, 0x0ffffffffffffc76, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0cec196accc52973, 0x01a0db248b0a77ae, 0x034d81f4372ddf58, 0x0ffffffffffffc76, 0x0fffffffffffffff, 0x0fffffffffffffff, 0xffffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x5f24db74f58851313e695333ad68d0, 0x0389cb27e0bc8d220a7e, 0x00, 0x10000000 - ] + }, + redc_param: [0x5f24db74f58851313e695333ad68d0, 0x0389cb27e0bc8d220a7e, 0x00, 0x10000000], }; diff --git a/src/fields/vestaFq.nr b/src/fields/vestaFq.nr index 8c2f6d3b..56a309b1 100644 --- a/src/fields/vestaFq.nr +++ b/src/fields/vestaFq.nr @@ -18,7 +18,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Vesta_Fq_Params {} +pub struct Vesta_Fq_Params {} impl BigNumParamsGetter<3, 255> for Vesta_Fq_Params { fn get_params() -> BigNumParams<3, 255> { @@ -27,18 +27,31 @@ impl BigNumParamsGetter<3, 255> for Vesta_Fq_Params { } global Vesta_Fq_PARAMS: BigNumParams<3, 255> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000 + has_multiplicative_inverse: true, + modulus: [0x4698fc0994a8dd8c46eb2100000001, 0x22, 0x4000], + double_modulus: [ + 0x018d31f8132951bb188dd64200000002, + 0x01000000000000000000000000000043, + 0x7fff, + ], + modulus_u60: U60Repr { + limbs: [0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00], + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0c46eb2100000001, + 0x04698fc0994a8dd8, + 0x22, + 0x00, + 0x4000, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - double_modulus: [ - 0x018d31f8132951bb188dd64200000002, 0x01000000000000000000000000000043, 0x7fff - ], - modulus_u60: U60Repr { limbs: [ - 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0c46eb2100000001, 0x04698fc0994a8dd8, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x59c0fd9ad5c89cee4537bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff - ] + }, + redc_param: [0x59c0fd9ad5c89cee4537bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff], }; diff --git a/src/fields/vestaFr.nr b/src/fields/vestaFr.nr index 05b0e9d4..438b2ff3 100644 --- a/src/fields/vestaFr.nr +++ b/src/fields/vestaFr.nr @@ -18,7 +18,7 @@ use crate::params::BigNumParamsGetter; use crate::params::BigNumParams; use crate::utils::u60_representation::U60Repr; -pub struct Vesta_Fr_Params {} +pub struct Vesta_Fr_Params {} impl BigNumParamsGetter<3, 255> for Vesta_Fr_Params { fn get_params() -> BigNumParams<3, 255> { @@ -27,18 +27,31 @@ impl BigNumParamsGetter<3, 255> for Vesta_Fr_Params { } global Vesta_Fr_PARAMS: BigNumParams<3, 255> = BigNumParams { - has_multiplicative_inverse: true, - modulus: [ - 0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000 + has_multiplicative_inverse: true, + modulus: [0x4698fc094cf91b992d30ed00000001, 0x22, 0x4000], + double_modulus: [ + 0x018d31f81299f237325a61da00000002, + 0x01000000000000000000000000000043, + 0x7fff, + ], + modulus_u60: U60Repr { + limbs: [0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00], + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x092d30ed00000001, + 0x04698fc094cf91b9, + 0x22, + 0x00, + 0x4000, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, ], - double_modulus: [ - 0x018d31f81299f237325a61da00000002, 0x01000000000000000000000000000043, 0x7fff - ], - modulus_u60: U60Repr { limbs: [ - 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x092d30ed00000001, 0x04698fc094cf91b9, 0x22, 0x00, 0x4000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, - redc_param: [ - 0x59c0fdacc1b919b4b3c4bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff - ] + }, + redc_param: [0x59c0fdacc1b919b4b3c4bfffffffc4, 0xfffffffffffffffffffffffffff76e, 0x0fffff], }; diff --git a/src/fns/constrained_ops.nr b/src/fns/constrained_ops.nr index f510fb3d..b6c6d211 100644 --- a/src/fns/constrained_ops.nr +++ b/src/fns/constrained_ops.nr @@ -4,9 +4,7 @@ use crate::fns::{ unconstrained_helpers::{ __validate_in_field_compute_borrow_flags, __validate_gt_remainder, __neg_with_flags, __add_with_flags, __sub_with_flags, - }, - unconstrained_ops::{__mul, __div, __udiv_mod}, - expressions::evaluate_quadratic_expression, + }, unconstrained_ops::{__mul, __div, __udiv_mod}, expressions::evaluate_quadratic_expression, }; /** @@ -38,7 +36,7 @@ use crate::fns::{ **/ pub(crate) fn derive_from_seed( params: P, - seed: [u8; SeedBytes] + seed: [u8; SeedBytes], ) -> [Field; N] { let mut rolling_seed: [u8; SeedBytes + 1] = [0; SeedBytes + 1]; for i in 0..SeedBytes { @@ -62,7 +60,8 @@ pub(crate) fn derive_from_seed 0) as u32; + let mut num_remaining_limbs = + (num_remaining_bytes / 15) + (num_remaining_bytes % 15 > 0) as u32; let mut more_than_N_minus_one_limbs = (num_remaining_limbs > (N - 1)) as u32; let mut num_limbs_in_bigfield = more_than_N_minus_one_limbs * (N - 1) + num_remaining_limbs * (1 - more_than_N_minus_one_limbs); @@ -125,7 +124,7 @@ pub(crate) fn derive_from_seed(bigfield_rhs_limbs); let mut result: [Field; N] = [0; N]; @@ -143,7 +142,11 @@ pub(crate) fn derive_from_seed(lhs: [Field; N], rhs: [Field; N], predicate: bool) -> [Field; N] { +pub(crate) fn conditional_select( + lhs: [Field; N], + rhs: [Field; N], + predicate: bool, +) -> [Field; N] { let mut result: [Field; N] = lhs; for i in 0..N { result[i] = (lhs[i] - rhs[i]) * predicate as Field + rhs[i]; @@ -159,7 +162,11 @@ pub(crate) fn conditional_select(lhs: [Field; N], rhs: [Field; N], p * However the probability of an honest Prover being unable to satisfy this check is tiny! * (todo: compute how tiny) **/ -pub(crate) fn assert_is_not_equal(params: P, lhs: [Field; N], rhs: [Field; N]) { +pub(crate) fn assert_is_not_equal( + params: P, + lhs: [Field; N], + rhs: [Field; N], +) { let mut l: Field = 0; let mut r: Field = 0; let mut modulus_mod_n: Field = 0; @@ -170,7 +177,7 @@ pub(crate) fn assert_is_not_equal(params: P(params: P(params: P, lhs: [Field; N], rhs: [Field; N]) -> bool { +pub(crate) fn eq( + params: P, + lhs: [Field; N], + rhs: [Field; N], +) -> bool { let diff = sub::<_, MOD_BITS>(params, lhs, rhs); // if self == other, possible values of `diff` will be `p` or `0` // (the subtract operator constrains diff to be < ceil(log(p))) @@ -196,20 +207,21 @@ pub(crate) fn eq(params: P, lhs: [Fi is_equal_modulus | is_equal_zero } -pub(crate) fn validate_in_field(params: P, val: [Field; N]) { +pub(crate) fn validate_in_field( + params: P, + val: [Field; N], +) { // N.B. need to combine with validate_in_range if `self` limbs have not been range constrained let mut p_minus_self: [Field; N] = [0; N]; let modulus: [Field; N] = params.modulus; for i in 0..N { p_minus_self[i] = modulus[i] - val[i]; } - let borrow_flags = unsafe { - __validate_in_field_compute_borrow_flags(params, val) - }; + let borrow_flags = unsafe { __validate_in_field_compute_borrow_flags(params, val) }; let two_pow_120: Field = 0x1000000000000000000000000000000; p_minus_self[0] += borrow_flags[0] as Field * two_pow_120; for i in 1..N - 1 { - p_minus_self[i] += (borrow_flags[i] as Field * two_pow_120 - borrow_flags[i-1] as Field); + p_minus_self[i] += (borrow_flags[i] as Field * two_pow_120 - borrow_flags[i - 1] as Field); } p_minus_self[N - 1] -= borrow_flags[N - 2] as Field; let mut compare = val; @@ -251,12 +263,9 @@ pub(crate) fn validate_quotient_in_range(limbs: [ // validate that lhs - rhs does not underflow i.e. lhs > rhs pub(crate) fn validate_gt(lhs: [Field; N], rhs: [Field; N]) { // so we do... p - x - r = 0 and there might be borrow flags - // a - b = r // p + a - b - r = 0 - let (result, carry_flags, borrow_flags) = unsafe { - __validate_gt_remainder(lhs, rhs) - }; + let (result, carry_flags, borrow_flags) = unsafe { __validate_gt_remainder(lhs, rhs) }; validate_in_range::<_, MOD_BITS>(result); @@ -264,7 +273,8 @@ pub(crate) fn validate_gt(lhs: [Field; N], rhs: [ let carry_shift = 0x1000000000000000000000000000000; let mut addend: [Field; N] = [0; N]; - let result_limb = lhs[0] - rhs[0] + addend[0] - result[0] - 1 + (borrow_flags[0] as Field * borrow_shift) + let result_limb = lhs[0] - rhs[0] + addend[0] - result[0] - 1 + + (borrow_flags[0] as Field * borrow_shift) - (carry_flags[0] as Field * carry_shift); assert(result_limb == 0); for i in 1..N - 1 { @@ -273,16 +283,19 @@ pub(crate) fn validate_gt(lhs: [Field; N], rhs: [ + ((borrow_flags[i] as Field - carry_flags[i] as Field) * borrow_shift); assert(result_limb == 0); } - let result_limb = lhs[N - 1] - rhs[N - 1] + addend[N - 1] - result[N - 1] - borrow_flags[N - 2] as Field + let result_limb = lhs[N - 1] - rhs[N - 1] + addend[N - 1] + - result[N - 1] + - borrow_flags[N - 2] as Field + carry_flags[N - 2] as Field; assert(result_limb == 0); } -pub(crate) fn neg(params: P, val: [Field; N]) -> [Field; N] { +pub(crate) fn neg( + params: P, + val: [Field; N], +) -> [Field; N] { // so we do... p - x - r = 0 and there might be borrow flags - let (result, borrow_flags) = unsafe { - __neg_with_flags(params, val) - }; + let (result, borrow_flags) = unsafe { __neg_with_flags(params, val) }; validate_in_range::<_, MOD_BITS>(result); let modulus = params.modulus; let borrow_shift = 0x1000000000000000000000000000000; @@ -298,11 +311,14 @@ pub(crate) fn neg(params: P, val: [F result } -pub(crate) fn add(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { +pub(crate) fn add( + params: P, + lhs: [Field; N], + rhs: [Field; N], +) -> [Field; N] { // so we do... p - x - r = 0 and there might be borrow flags - let (result, carry_flags, borrow_flags, overflow_modulus) = unsafe { - __add_with_flags(params, lhs, rhs) - }; + let (result, carry_flags, borrow_flags, overflow_modulus) = + unsafe { __add_with_flags(params, lhs, rhs) }; validate_in_range::<_, MOD_BITS>(result); let modulus = params.modulus; let borrow_shift = 0x1000000000000000000000000000000; @@ -312,7 +328,8 @@ pub(crate) fn add(params: P, lhs: [F if (overflow_modulus) { subtrahend = modulus; } - let result_limb = lhs[0] + rhs[0] - subtrahend[0] - result[0] + (borrow_flags[0] as Field * borrow_shift) + let result_limb = lhs[0] + rhs[0] - subtrahend[0] - result[0] + + (borrow_flags[0] as Field * borrow_shift) - (carry_flags[0] as Field * carry_shift); assert(result_limb == 0); for i in 1..N - 1 { @@ -321,20 +338,25 @@ pub(crate) fn add(params: P, lhs: [F + ((borrow_flags[i] as Field - carry_flags[i] as Field) * borrow_shift); assert(result_limb == 0); } - let result_limb = lhs[N - 1] + rhs[N - 1] - subtrahend[N - 1] - result[N - 1] - borrow_flags[N - 2] as Field + let result_limb = lhs[N - 1] + rhs[N - 1] + - subtrahend[N - 1] + - result[N - 1] + - borrow_flags[N - 2] as Field + carry_flags[N - 2] as Field; assert(result_limb == 0); result } -pub(crate) fn sub(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { +pub(crate) fn sub( + params: P, + lhs: [Field; N], + rhs: [Field; N], +) -> [Field; N] { // so we do... p - x - r = 0 and there might be borrow flags - // a - b = r // p + a - b - r = 0 - let (result, carry_flags, borrow_flags, underflow) = unsafe { - __sub_with_flags(params, lhs, rhs) - }; + let (result, carry_flags, borrow_flags, underflow) = + unsafe { __sub_with_flags(params, lhs, rhs) }; validate_in_range::<_, MOD_BITS>(result); let modulus = params.modulus; let borrow_shift = 0x1000000000000000000000000000000; @@ -344,7 +366,8 @@ pub(crate) fn sub(params: P, lhs: [F if (underflow) { addend = modulus; } - let result_limb = lhs[0] - rhs[0] + addend[0] - result[0] + (borrow_flags[0] as Field * borrow_shift) + let result_limb = lhs[0] - rhs[0] + addend[0] - result[0] + + (borrow_flags[0] as Field * borrow_shift) - (carry_flags[0] as Field * carry_shift); assert(result_limb == 0); for i in 1..N - 1 { @@ -353,7 +376,9 @@ pub(crate) fn sub(params: P, lhs: [F + ((borrow_flags[i] as Field - carry_flags[i] as Field) * borrow_shift); assert(result_limb == 0); } - let result_limb = lhs[N - 1] - rhs[N - 1] + addend[N - 1] - result[N - 1] - borrow_flags[N - 2] as Field + let result_limb = lhs[N - 1] - rhs[N - 1] + addend[N - 1] + - result[N - 1] + - borrow_flags[N - 2] as Field + carry_flags[N - 2] as Field; assert(result_limb == 0); result @@ -363,23 +388,44 @@ pub(crate) fn sub(params: P, lhs: [F // 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 -pub(crate) fn mul(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { - let result = unsafe { - __mul::<_, MOD_BITS>(params, lhs, rhs) - }; - evaluate_quadratic_expression(params, [[lhs]], [[false]], [[rhs]], [[false]], [result], [true]); +pub(crate) fn mul( + params: P, + lhs: [Field; N], + rhs: [Field; N], +) -> [Field; N] { + let result = unsafe { __mul::<_, MOD_BITS>(params, lhs, rhs) }; + evaluate_quadratic_expression( + params, + [[lhs]], + [[false]], + [[rhs]], + [[false]], + [result], + [true], + ); result } // Note: this method is expensive! Witness computation is extremely expensive as it requires modular exponentiation -pub(crate) fn div(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { +pub(crate) fn div( + params: P, + lhs: [Field; N], + rhs: [Field; N], +) -> [Field; N] { assert( - params.has_multiplicative_inverse, "BigNum has no multiplicative inverse. Use udiv for unsigned integer division" + params.has_multiplicative_inverse, + "BigNum has no multiplicative inverse. Use udiv for unsigned integer division", + ); + let result = unsafe { __div::<_, MOD_BITS>(params, lhs, rhs) }; + evaluate_quadratic_expression( + params, + [[result]], + [[false]], + [[rhs]], + [[false]], + [lhs], + [true], ); - let result = unsafe { - __div::<_, MOD_BITS>(params, lhs, rhs) - }; - evaluate_quadratic_expression(params, [[result]], [[false]], [[rhs]], [[false]], [lhs], [true]); result } @@ -393,11 +439,9 @@ pub(crate) fn div(params: P, lhs: [F pub(crate) fn udiv_mod( params: P, numerator: [Field; N], - divisor: [Field; N] + divisor: [Field; N], ) -> ([Field; N], [Field; N]) { - let (quotient, remainder) = unsafe { - __udiv_mod(numerator, divisor) - }; + let (quotient, remainder) = unsafe { __udiv_mod(numerator, divisor) }; // self / divisor = quotient rounded // quotient * divisor + remainder - self = 0 @@ -408,7 +452,7 @@ pub(crate) fn udiv_mod( [[divisor]], [[false]], [numerator, remainder], - [true, false] + [true, false], ); // we need (remainder < divisor) // implies (divisor - remainder > 0) @@ -421,7 +465,11 @@ pub(crate) fn udiv_mod( * * i.e. return param is floor(numerator / divisor) **/ -pub(crate) fn udiv(params: P, numerator: [Field; N], divisor: [Field; N]) -> [Field; N] { +pub(crate) fn udiv( + params: P, + numerator: [Field; N], + divisor: [Field; N], +) -> [Field; N] { udiv_mod::<_, MOD_BITS>(params, numerator, divisor).0 } @@ -433,7 +481,7 @@ pub(crate) fn udiv(params: P, numera pub(crate) fn umod( params: P, numerator: [Field; N], - divisor: [Field; N] + divisor: [Field; N], ) -> [Field; N] { udiv_mod::<_, MOD_BITS>(params, numerator, divisor).1 } diff --git a/src/fns/expressions.nr b/src/fns/expressions.nr index 0461c0e5..38b2abfb 100644 --- a/src/fns/expressions.nr +++ b/src/fns/expressions.nr @@ -2,8 +2,7 @@ use crate::utils::split_bits; use crate::params::BigNumParams as P; use crate::fns::{ - constrained_ops::validate_quotient_in_range, - unconstrained_helpers::__barrett_reduction + constrained_ops::validate_quotient_in_range, unconstrained_helpers::__barrett_reduction, }; /** @@ -41,24 +40,16 @@ use crate::fns::{ * @param linear_terms an array of BigNum * @param linear_flags an array of sign flags **/ -unconstrained fn __compute_quadratic_expression_with_borrow_flags< - let N: u32, - let MOD_BITS: u32, - let LHS_N: u32, - let RHS_N: u32, - let NUM_PRODUCTS: u32, - let ADD_N: u32 ->( +unconstrained fn __compute_quadratic_expression_with_borrow_flags( params: P, lhs_terms: [[[Field; N]; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs_terms: [[[Field; N]; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], linear_terms: [[Field; N]; ADD_N], - linear_flags: [bool; ADD_N] + linear_flags: [bool; ADD_N], ) -> ([Field; N], [Field; N], [Field; 2 * N]) { // TODO, validate we do not overflow N2 when multiplying and N when adding - let mut mulout_p = __compute_quadratic_expression_product( params, lhs_terms, @@ -66,7 +57,7 @@ unconstrained fn __compute_quadratic_expression_with_borrow_flags< rhs_terms, rhs_flags, linear_terms, - linear_flags + linear_flags, ); let mut mulout_n: [Field; 2 * N] = [0; 2 * N]; let mut relation_result: [Field; 2 * N] = split_bits::__normalize_limbs(mulout_p, 2 * N); @@ -78,7 +69,7 @@ unconstrained fn __compute_quadratic_expression_with_borrow_flags< params.redc_param, modulus_bits, modulus, - params.modulus_u60_x4 + params.modulus_u60_x4, ); assert(remainder == [0; N]); @@ -109,11 +100,15 @@ unconstrained fn __compute_quadratic_expression_with_borrow_flags< mulout_p[i] += hi_bits; // determine whether negative limb values are greater than positive limb values - let underflow: Field = mulout_p[i].lt(mulout_n[i] + (borrow_flags[i - 1] * borrow_carry)) as Field; + let underflow: Field = + mulout_p[i].lt(mulout_n[i] + (borrow_flags[i - 1] * borrow_carry)) as Field; borrow_flags[i] = underflow; - hi_bits = (mulout_p[i] - mulout_n[i] + (borrow_flags[i] * borrow_shift) - - (borrow_flags[i - 1] * borrow_carry)) * downshift; + hi_bits = ( + mulout_p[i] - mulout_n[i] + (borrow_flags[i] * borrow_shift) + - (borrow_flags[i - 1] * borrow_carry) + ) + * downshift; } (quotient, remainder, borrow_flags) @@ -130,7 +125,7 @@ unconstrained fn __compute_quadratic_expression_with_borrow_flags< unconstrained fn __add_linear_expression( params: P, x: [[Field; N]; M], - flags: [bool; M] + flags: [bool; M], ) -> ([Field; N]) { // TODO, validate we do not overflow N2 when multiplying and N when adding let mut sum: [Field; N] = [0; N]; @@ -156,21 +151,14 @@ unconstrained fn __add_linear_expression( +unconstrained fn __compute_quadratic_expression_product( params: P, lhs_terms: [[[Field; N]; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs_terms: [[[Field; N]; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], linear_terms: [[Field; N]; ADD_N], - linear_flags: [bool; ADD_N] + linear_flags: [bool; ADD_N], ) -> [Field; 2 * N] { // TODO, validate we do not overflow N2 when multiplying and N when adding let mut lhs: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS]; @@ -201,21 +189,14 @@ unconstrained fn __compute_quadratic_expression_product< * @brief computes the quotient/remainder of a quadratic expression * @details see __compute_quadratic_expression_with_borrow_flags for full description **/ -unconstrained pub(crate) fn __compute_quadratic_expression< - let N: u32, - let MOD_BITS: u32, - let LHS_N: u32, - let RHS_N: u32, - let NUM_PRODUCTS: u32, - let ADD_N: u32 ->( +pub(crate) unconstrained fn __compute_quadratic_expression( params: P, lhs_terms: [[[Field; N]; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs_terms: [[[Field; N]; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], linear_terms: [[Field; N]; ADD_N], - linear_flags: [bool; ADD_N] + linear_flags: [bool; ADD_N], ) -> ([Field; N], [Field; N]) { // TODO, validate we do not overflow N2 when multiplying and N when adding let mulout = __compute_quadratic_expression_product( @@ -225,7 +206,7 @@ unconstrained pub(crate) fn __compute_quadratic_expression< rhs_terms, rhs_flags, linear_terms, - linear_flags + linear_flags, ); let mut relation_result: [Field; 2 * N] = split_bits::__normalize_limbs(mulout, 2 * N); @@ -239,7 +220,7 @@ unconstrained pub(crate) fn __compute_quadratic_expression< params.redc_param, k, params.modulus, - params.modulus_u60_x4 + params.modulus_u60_x4, ); let mut q = quotient; @@ -284,21 +265,14 @@ unconstrained pub(crate) fn __compute_quadratic_expression< * @param linear_terms an array of BigNum * @param linear_flags an array of sign flags **/ -pub(crate) fn evaluate_quadratic_expression< - let N: u32, - let MOD_BITS: u32, - let LHS_N: u32, - let RHS_N: u32, - let NUM_PRODUCTS: u32, - let ADD_N: u32 ->( +pub(crate) fn evaluate_quadratic_expression( params: P, lhs_terms: [[[Field; N]; LHS_N]; NUM_PRODUCTS], lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS], rhs_terms: [[[Field; N]; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], linear_terms: [[Field; N]; ADD_N], - linear_flags: [bool; ADD_N] + linear_flags: [bool; ADD_N], ) { // use an unconstrained function to compute the value of the quotient let (quotient, _, borrow_flags): ([Field; N], [Field; N], [Field; 2 * N]) = unsafe { @@ -309,7 +283,7 @@ pub(crate) fn evaluate_quadratic_expression< rhs_terms, rhs_flags, linear_terms, - linear_flags + linear_flags, ) }; // constrain the quotient to be in the range [0, ..., 2^{m} - 1], where `m` is log2(modulus) rounded up. @@ -317,7 +291,6 @@ pub(crate) fn evaluate_quadratic_expression< validate_quotient_in_range::<_, MOD_BITS>(quotient); // TODO, validate we do not overflow N2 when multiplying and N when adding // (should be a compile-time check...unconstrained function?) - // Compute the linear sums that represent lhs_1, rhs_1, lhs_2, rhs_2, add let mut t0: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS]; let mut t1: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS]; @@ -392,7 +365,6 @@ pub(crate) fn evaluate_quadratic_expression< // (the barretenberg backend can evaluate these in 5.25 gates. 127 bits costs 6.5 gates) let borrow_shift: Field = 0x40000000000000000000000000000000000000000000000000000000000000; // 2^{246} let borrow_carry: Field = 0x40000000000000000000000000000000; // 2^{246 - 120} = 2^{126} - // N.B. borrow_flags is `Field` type because making it `bool` would apply boolean constraints to all `N2` array entries. // We only use `N2 - 2` borrow flags so applying 1-bit range checks on the array elements we use is more efficient. // TODO: Once it is possible to perform arithmetic on generics we can use `borrow_flags: [bool;N+N-2]` to avoid this issue @@ -400,8 +372,7 @@ pub(crate) fn evaluate_quadratic_expression< product_limbs[0] += borrow_flags[0] * borrow_shift; for i in 1..(N + N - 2) { borrow_flags[i].assert_max_bit_size::<1>(); - product_limbs[i] += - (borrow_flags[i] * borrow_shift - borrow_flags[i - 1] * borrow_carry); + product_limbs[i] += (borrow_flags[i] * borrow_shift - borrow_flags[i - 1] * borrow_carry); } product_limbs[N + N - 2] -= borrow_flags[N + N - 3] * borrow_carry; diff --git a/src/fns/mod.nr b/src/fns/mod.nr index 256c53db..dd9f5af0 100644 --- a/src/fns/mod.nr +++ b/src/fns/mod.nr @@ -3,4 +3,4 @@ pub(crate) mod unconstrained_ops; pub(crate) mod constrained_ops; pub(crate) mod unconstrained_helpers; pub(crate) mod expressions; -pub(crate) mod serialization; \ No newline at end of file +pub(crate) mod serialization; diff --git a/src/fns/serialization.nr b/src/fns/serialization.nr index dc404c03..926f4271 100644 --- a/src/fns/serialization.nr +++ b/src/fns/serialization.nr @@ -4,7 +4,9 @@ * is precisely large enough to cover MOD_BITS * @param x: input byte array **/ -pub(crate) fn from_be_bytes(x: [u8; NBytes]) -> [Field; N] { +pub(crate) fn from_be_bytes( + x: [u8; NBytes], +) -> [Field; N] { let num_bits = NBytes * 8; assert(num_bits >= MOD_BITS); assert(num_bits - MOD_BITS < 8); @@ -37,7 +39,9 @@ pub(crate) fn from_be_bytes(x: [ result } -pub(crate) fn to_le_bytes(val: [Field; N]) -> [u8; NBytes] { +pub(crate) fn to_le_bytes( + val: [Field; N], +) -> [u8; NBytes] { let nbytes = (MOD_BITS / 8) + (MOD_BITS % 8 != 0) as u32; assert(nbytes <= NBytes); @@ -51,7 +55,7 @@ pub(crate) fn to_le_bytes(val: [ let last_limb_bytes: [u8; 15] = val[N - 1].to_le_bytes(); let num_last_bytes = (NBytes - (N - 1) * 15); for i in 0..num_last_bytes { - result[(N-1) * 15 + i] = last_limb_bytes[i]; + result[(N - 1) * 15 + i] = last_limb_bytes[i]; } result } diff --git a/src/fns/unconstrained_helpers.nr b/src/fns/unconstrained_helpers.nr index ba0404b9..694971e5 100644 --- a/src/fns/unconstrained_helpers.nr +++ b/src/fns/unconstrained_helpers.nr @@ -16,7 +16,10 @@ use crate::fns::unconstrained_ops::{__one, __eq, __neg, __add, __mul, __pow}; * __tonelli_shanks_sqrt */ -unconstrained pub(crate) fn __validate_in_field_compute_borrow_flags(params: P, val: [Field; N]) -> [bool; N] { +pub(crate) unconstrained fn __validate_in_field_compute_borrow_flags( + params: P, + val: [Field; N], +) -> [bool; N] { let mut flags: [bool; N] = [false; N]; let modulus: [Field; N] = params.modulus; flags[0] = modulus[0].lt(val[0]); @@ -26,15 +29,18 @@ unconstrained pub(crate) fn __validate_in_field_compute_borrow_flags(lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [bool; N], [bool; N]) { - let a_u60 : U60Repr = U60Repr::from(lhs); - let mut b_u60 : U60Repr = U60Repr::from(rhs); +pub(crate) unconstrained fn __validate_gt_remainder( + lhs: [Field; N], + rhs: [Field; N], +) -> ([Field; N], [bool; N], [bool; N]) { + let a_u60: U60Repr = U60Repr::from(lhs); + let mut b_u60: U60Repr = U60Repr::from(rhs); let underflow = b_u60.gte(a_u60); b_u60 += U60Repr::one(); assert(underflow == false, "BigNum::validate_gt check fails"); - let mut addend_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; - let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; + let mut addend_u60: U60Repr = U60Repr { limbs: [0; 2 * N] }; + let mut result_u60: U60Repr = U60Repr { limbs: [0; 2 * N] }; let mut carry: u64 = 0; let mut carry_in: u64 = 0; @@ -58,8 +64,8 @@ unconstrained pub(crate) fn __validate_gt_remainder(params: P, val: [Field; N]) -> ([Field; N], [bool; N]) { - let x_u60 : U60Repr = U60Repr::from(val); - let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; +pub(crate) unconstrained fn __neg_with_flags( + params: P, + val: [Field; N], +) -> ([Field; N], [bool; N]) { + let x_u60: U60Repr = U60Repr::from(val); + let mut result_u60: U60Repr = U60Repr { limbs: [0; 2 * N] }; let mut borrow: u64 = 0; let mut borrow_in: u64 = 0; @@ -88,19 +97,19 @@ unconstrained pub(crate) fn __neg_with_flags(para (result, borrow_flags) } -unconstrained pub(crate) fn __add_with_flags( +pub(crate) unconstrained fn __add_with_flags( params: P, lhs: [Field; N], - rhs: [Field; N] + rhs: [Field; N], ) -> ([Field; N], [bool; N], [bool; N], bool) { - let a_u60 : U60Repr = U60Repr::from(lhs); - let b_u60 : U60Repr = U60Repr::from(rhs); + let a_u60: U60Repr = U60Repr::from(lhs); + let b_u60: U60Repr = U60Repr::from(rhs); let add_u60 = a_u60 + b_u60; let overflow = add_u60.gte(params.modulus_u60); - let mut subtrahend_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; - let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; + let mut subtrahend_u60: U60Repr = U60Repr { limbs: [0; 2 * N] }; + let mut result_u60: U60Repr = U60Repr { limbs: [0; 2 * N] }; if overflow { subtrahend_u60 = params.modulus_u60; @@ -138,18 +147,18 @@ unconstrained pub(crate) fn __add_with_flags( (result, carry_flags, borrow_flags, overflow) } -unconstrained pub(crate) fn __sub_with_flags( +pub(crate) unconstrained fn __sub_with_flags( params: P, lhs: [Field; N], - rhs: [Field; N] + rhs: [Field; N], ) -> ([Field; N], [bool; N], [bool; N], bool) { - let a_u60 : U60Repr = U60Repr::from(lhs); - let b_u60 : U60Repr = U60Repr::from(rhs); + let a_u60: U60Repr = U60Repr::from(lhs); + let b_u60: U60Repr = U60Repr::from(rhs); let underflow = b_u60.gte(a_u60 + U60Repr::one()); - let mut addend_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; - let mut result_u60 : U60Repr = U60Repr { limbs: [0; 2 * N] }; + let mut addend_u60: U60Repr = U60Repr { limbs: [0; 2 * N] }; + let mut result_u60: U60Repr = U60Repr { limbs: [0; 2 * N] }; if underflow { addend_u60 = params.modulus_u60; @@ -177,8 +186,8 @@ unconstrained pub(crate) fn __sub_with_flags( carry = 0; borrow = 0; } - carry_flags[i/2] = carry as bool; - borrow_flags[i/2] = borrow as bool; + carry_flags[i / 2] = carry as bool; + borrow_flags[i / 2] = borrow as bool; } } let result = U60Repr::into(result_u60); @@ -192,14 +201,14 @@ unconstrained pub(crate) fn __sub_with_flags( **/ comptime global BARRETT_REDUCTION_OVERFLOW_BITS: u32 = 4; -unconstrained pub(crate) fn __barrett_reduction( +pub(crate) unconstrained fn __barrett_reduction( x: [Field; 2 * N], redc_param: [Field; N], k: u32, modulus: [Field; N], - modulus_u60: U60Repr + modulus_u60: U60Repr, ) -> ([Field; N], [Field; N]) { - let mut mulout: [Field; 3 * N] = [0; 3 * N]; + let mut mulout: [Field; 3 * N] = [0; 3 * N]; for i in 0..(N + N) { for j in 0..N { mulout[i + j] += x[i] * redc_param[j]; @@ -231,8 +240,8 @@ unconstrained pub(crate) fn __barrett_reduction( partial_quotient[i] = partial_quotient_full[i]; } // quotient_mul_modulus can never exceed input value `x` so can fit into size-2 array - let mut quotient_mul_modulus: [Field; 2 * N] = [0; 2 * N]; - let mut quotient_mul_modulus_normalized: [Field; 2 * N] = [0; 2 * N]; + let mut quotient_mul_modulus: [Field; 2 * N] = [0; 2 * N]; + let mut quotient_mul_modulus_normalized: [Field; 2 * N] = [0; 2 * N]; for j in 0..N { for i in 0..(N + N - j) { quotient_mul_modulus[i + j] += partial_quotient[i] * modulus[j]; @@ -250,7 +259,7 @@ unconstrained pub(crate) fn __barrett_reduction( } let quotient_mul_modulus_u60: U60Repr = U60Repr::new(quotient_mul_modulus_normalized); - let x_u60 : U60Repr = U60Repr::new(x); + let x_u60: U60Repr = U60Repr::new(x); let mut remainder_u60 = x_u60 - quotient_mul_modulus_u60; if (remainder_u60.gte(modulus_u60)) { @@ -269,7 +278,9 @@ unconstrained pub(crate) fn __barrett_reduction( * @details find the maximum value k where x^k = 1, where x = primitive root * This is needed for our Tonelli-Shanks sqrt algorithm **/ -unconstrained pub(crate) fn __primitive_root_log_size(params: P) -> u32 { +pub(crate) unconstrained fn __primitive_root_log_size( + params: P, +) -> u32 { let mut target: U60Repr = params.modulus_u60 - U60Repr::one(); let mut result: u32 = 0; for _ in 0..MOD_BITS { @@ -291,7 +302,7 @@ unconstrained pub(crate) fn __primitive_root_log_size( params: P, target: [Field; N], - p_minus_one_over_two: [Field; N] + p_minus_one_over_two: [Field; N], ) -> (bool, [Field; N]) { let exped = __pow(params, target, p_minus_one_over_two); let one: [Field; N] = __one(); @@ -299,10 +310,12 @@ unconstrained fn __recursively_find_multiplicative_generator(params, _target, p_minus_one_over_two); + let _target = unsafe { __add(params, target, one) }; + result = __recursively_find_multiplicative_generator::<_, MOD_BITS>( + params, + _target, + p_minus_one_over_two, + ); } result } @@ -312,15 +325,25 @@ unconstrained fn __recursively_find_multiplicative_generator(params: P) -> [Field; N] { +pub(crate) unconstrained fn __multiplicative_generator( + params: P, +) -> [Field; N] { let mut target: [Field; N] = __one(); let p_minus_one_over_two: U60Repr = (params.modulus_u60 - U60Repr::one()).shr(1); let p_minus_one_over_two: [Field; N] = U60Repr::into(p_minus_one_over_two); - let (_, target) = __recursively_find_multiplicative_generator::<_, MOD_BITS>(params, target, p_minus_one_over_two); + let (_, target) = __recursively_find_multiplicative_generator::<_, MOD_BITS>( + params, + target, + p_minus_one_over_two, + ); target } -unconstrained pub(crate) fn __tonelli_shanks_sqrt_inner_loop_check(params: P, t2m: [Field; N], i: u32) -> u32 { +pub(crate) unconstrained fn __tonelli_shanks_sqrt_inner_loop_check( + params: P, + t2m: [Field; N], + i: u32, +) -> u32 { let one: [Field; N] = __one(); let is_one = __eq(t2m, one); let mut result = i; diff --git a/src/fns/unconstrained_ops.nr b/src/fns/unconstrained_ops.nr index b9dab098..b72f913b 100644 --- a/src/fns/unconstrained_ops.nr +++ b/src/fns/unconstrained_ops.nr @@ -4,7 +4,7 @@ use crate::utils::split_bits; use crate::params::BigNumParams as P; use crate::fns::unconstrained_helpers::{ __barrett_reduction, __primitive_root_log_size, __multiplicative_generator, - __tonelli_shanks_sqrt_inner_loop_check + __tonelli_shanks_sqrt_inner_loop_check, }; /** @@ -27,13 +27,16 @@ use crate::fns::unconstrained_helpers::{ * __batch_invert_slice */ -unconstrained pub(crate) fn __one() -> [Field; N] { +pub(crate) unconstrained fn __one() -> [Field; N] { let mut limbs: [Field; N] = [0; N]; limbs[0] = 1; limbs } -unconstrained pub(crate) fn __derive_from_seed(params: P, seed: [u8; SeedBytes]) -> [Field; N] { +pub(crate) unconstrained fn __derive_from_seed( + params: P, + seed: [u8; SeedBytes], +) -> [Field; N] { let mut rolling_hash_fields: [Field; (SeedBytes / 31) + 1] = [0; (SeedBytes / 31) + 1]; let mut seed_ptr = 0; for i in 0..(SeedBytes / 31) + 1 { @@ -47,13 +50,15 @@ unconstrained pub(crate) fn __derive_from_seed(lhs: [Field; N], rhs: [Field; N]) -> bool { +pub(crate) unconstrained fn __eq(lhs: [Field; N], rhs: [Field; N]) -> bool { lhs == rhs } -unconstrained pub(crate) fn __is_zero(limbs: [Field; N]) -> bool { +pub(crate) unconstrained fn __is_zero(limbs: [Field; N]) -> bool { let mut result: bool = true; for i in 0..N { result = result & (limbs[i] == 0); @@ -132,15 +137,22 @@ unconstrained pub(crate) fn __is_zero(limbs: [Field; N]) -> bool { * N.B. constrained BigNum operations do not fully constrain outputs to be in the range [0, p-1] * because such a check is expensive and usually unneccesary. */ -unconstrained pub(crate) fn __neg(params: P, limbs: [Field; N]) -> [Field; N] { +pub(crate) unconstrained fn __neg( + params: P, + limbs: [Field; N], +) -> [Field; N] { let f: [Field; N] = limbs; - let x_u60 : U60Repr = U60Repr::from(f); + let x_u60: U60Repr = U60Repr::from(f); U60Repr::into(params.modulus_u60 - x_u60) } -unconstrained pub(crate) fn __add(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { - let x_u60 : U60Repr = U60Repr::from(lhs); - let y_u60 : U60Repr = U60Repr::from(rhs); +pub(crate) unconstrained fn __add( + params: P, + lhs: [Field; N], + rhs: [Field; N], +) -> [Field; N] { + let x_u60: U60Repr = U60Repr::from(lhs); + let y_u60: U60Repr = U60Repr::from(rhs); let mut z_u60 = x_u60 + y_u60; @@ -154,15 +166,19 @@ unconstrained pub(crate) fn __add(params: P( +pub(crate) unconstrained fn __sub( params: P, lhs: [Field; N], - rhs: [Field; N] + rhs: [Field; N], ) -> [Field; N] { __add(params, lhs, __neg(params, rhs)) } -unconstrained pub(crate) fn __mul_with_quotient(params: P, lhs: [Field; N], rhs: [Field; N]) -> ([Field; N], [Field; N]) { +pub(crate) unconstrained fn __mul_with_quotient( + params: P, + lhs: [Field; N], + rhs: [Field; N], +) -> ([Field; N], [Field; N]) { let mut mul: [Field; 2 * N] = [0; 2 * N]; for i in 0..N { for j in 0..N { @@ -175,18 +191,26 @@ unconstrained pub(crate) fn __mul_with_quotient(p params.redc_param, MOD_BITS, params.modulus, - params.modulus_u60_x4 + params.modulus_u60_x4, ); (q, r) } -unconstrained pub(crate) fn __mul(params: P, lhs: [Field; N], rhs: [Field; N]) -> [Field; N] { +pub(crate) unconstrained fn __mul( + params: P, + lhs: [Field; N], + rhs: [Field; N], +) -> [Field; N] { let (_, b) = __mul_with_quotient::<_, MOD_BITS>(params, lhs, rhs); b } -unconstrained pub(crate) fn __div(params: P, numerator: [Field; N], divisor: [Field; N]) -> [Field; N] { +pub(crate) unconstrained fn __div( + params: P, + numerator: [Field; N], + divisor: [Field; N], +) -> [Field; N] { let inv_divisor = __invmod::<_, MOD_BITS>(params, divisor); __mul::<_, MOD_BITS>(params, numerator, inv_divisor) } @@ -198,7 +222,10 @@ unconstrained pub(crate) fn __div(params: P(numerator: [Field; N], divisor: [Field; N]) -> ([Field; N], [Field; N]) { +pub(crate) unconstrained fn __udiv_mod( + numerator: [Field; N], + divisor: [Field; N], +) -> ([Field; N], [Field; N]) { let mut quotient_u60: U60Repr = U60Repr::from([0; N]); let mut remainder_u60: U60Repr = U60Repr::from(numerator); @@ -235,7 +262,10 @@ unconstrained pub(crate) fn __udiv_mod(numerator: (U60Repr::into(quotient_u60), U60Repr::into(remainder_u60)) } -unconstrained pub(crate) fn __invmod(params: P, val: [Field; N]) -> [Field; N] { +pub(crate) unconstrained fn __invmod( + params: P, + val: [Field; N], +) -> [Field; N] { let one: [Field; N] = __one::(); let one_u60: U60Repr = U60Repr::from(one); let exp_u60 = params.modulus_u60.sub(one_u60.add(one_u60)); @@ -243,7 +273,11 @@ unconstrained pub(crate) fn __invmod(params: P(params, val, exp) } -unconstrained pub(crate) fn __pow(params: P, val: [Field; N], exponent: [Field; N]) -> [Field; N] { +pub(crate) unconstrained fn __pow( + params: P, + val: [Field; N], + exponent: [Field; N], +) -> [Field; N] { let x: U60Repr = U60Repr::from(exponent); let num_bits = MOD_BITS + 1; @@ -259,7 +293,10 @@ unconstrained pub(crate) fn __pow(params: P(params: P, x: [[Field; N]; M]) -> [[Field; N]; M] { +pub(crate) unconstrained fn __batch_invert( + params: P, + x: [[Field; N]; M], +) -> [[Field; N]; M] { // TODO: ugly! Will fail if input slice is empty let mut accumulator: [Field; N] = __one::(); let mut result: [[Field; N]; M] = [[0; N]; M]; @@ -284,7 +321,10 @@ unconstrained pub(crate) fn __batch_invert(params: P, x: [[Field; N]]) -> [[Field; N]] { +pub(crate) unconstrained fn __batch_invert_slice( + params: P, + x: [[Field; N]], +) -> [[Field; N]] { // TODO: ugly! Will fail if input slice is empty let mut accumulator: [Field; N] = __one::(); let mut result: [[Field; N]] = [[0; N]]; @@ -316,7 +356,10 @@ unconstrained pub(crate) fn __batch_invert_slice( * @note this is unconstrained fn. To constrain a square root, validate that output^2 = self * TODO: create fn that constrains nonexistence of square root (i.e. find x where x^2 = -self) **/ -unconstrained pub(crate) fn __tonelli_shanks_sqrt(params: P, input: [Field; N]) -> std::option::Option<[Field; N]> { +pub(crate) unconstrained fn __tonelli_shanks_sqrt( + params: P, + input: [Field; N], +) -> std::option::Option<[Field; N]> { // Tonelli-shanks algorithm begins by finding a field element Q and integer S, // such that (p - 1) = Q.2^{s} // We can compute the square root of a, by considering a^{(Q + 1) / 2} = R @@ -342,9 +385,7 @@ unconstrained pub(crate) fn __tonelli_shanks_sqrt // We can iteratively transform t into ever smaller subgroups, until t = 1. // At each iteration, we need to find a new value for b, which we can obtain // by repeatedly squaring z^{Q} - let one_u60: U60Repr = unsafe { - U60Repr::one() - }; + let one_u60: U60Repr = unsafe { U60Repr::one() }; let primitive_root_log_size = __primitive_root_log_size::<_, MOD_BITS>(params); let mut Q = (params.modulus_u60 - one_u60).shr(primitive_root_log_size - 1); let Q_minus_one_over_two_u60 = (Q - one_u60).shr(2); @@ -368,7 +409,6 @@ unconstrained pub(crate) fn __tonelli_shanks_sqrt // (if t2m == 1) then skip // else increase i and square t2m and go again // algorithm runtime should only be max the number of bits in modulus - for _ in 0..MOD_BITS { if (__eq(t, one)) { found_root = true; @@ -379,7 +419,8 @@ unconstrained pub(crate) fn __tonelli_shanks_sqrt let i = __tonelli_shanks_sqrt_inner_loop_check::<_, MOD_BITS>(params, t2m, 0); let mut j = m - i - 1; b = c; - for _ in 0..j { // how big + for _ in 0..j { + // how big if (j == 0) { break; } diff --git a/src/params.nr b/src/params.nr index d0a2467a..01854ab3 100644 --- a/src/params.nr +++ b/src/params.nr @@ -23,14 +23,18 @@ pub trait BigNumParamsGetter { } impl BigNumParams { - pub fn new(has_multiplicative_inverse: bool, modulus: [Field; N], redc_param: [Field; N]) -> Self { + pub fn new( + has_multiplicative_inverse: bool, + modulus: [Field; N], + redc_param: [Field; N], + ) -> Self { Self { has_multiplicative_inverse, modulus, modulus_u60: U60Repr::from(modulus), modulus_u60_x4: U60Repr::from(modulus), double_modulus: get_double_modulus(modulus), - redc_param + redc_param, } } } diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index dce45434..66e091eb 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -5,14 +5,13 @@ use crate::params::BigNumParams; use crate::fns::{ constrained_ops::{ - derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, validate_in_range, - neg, add, sub, mul, div, udiv_mod, udiv, umod + derive_from_seed, conditional_select, assert_is_not_equal, eq, validate_in_field, + validate_in_range, neg, add, sub, mul, div, udiv_mod, udiv, umod, }, unconstrained_ops::{ - __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, __invmod, __pow, - __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt - }, - expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, + __derive_from_seed, __eq, __is_zero, __neg, __add, __sub, __mul, __div, __udiv_mod, + __invmod, __pow, __batch_invert, __batch_invert_slice, __tonelli_shanks_sqrt, + }, expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, serialization::{from_be_bytes, to_le_bytes}, }; @@ -28,11 +27,20 @@ impl RuntimeBigNum {} pub(crate) trait RuntimeBigNumTrait { pub fn new(params: BigNumParams) -> Self; pub fn one(params: BigNumParams) -> Self; - pub fn derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; - pub fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self; + pub fn derive_from_seed( + params: BigNumParams, + seed: [u8; SeedBytes], + ) -> Self; + pub fn __derive_from_seed( + params: BigNumParams, + seed: [u8; SeedBytes], + ) -> Self; pub fn from_slice(params: BigNumParams, limbs: [Field]) -> Self; pub fn from_array(params: BigNumParams, limbs: [Field; N]) -> Self; - pub fn from_be_bytes(params: BigNumParams, x: [u8; NBytes]) -> Self; + pub fn from_be_bytes( + params: BigNumParams, + x: [u8; NBytes], + ) -> Self; pub fn to_le_bytes(self) -> [u8; NBytes]; @@ -78,7 +86,7 @@ pub(crate) trait RuntimeBigNumTrait { rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], linear_terms: [Self; ADD_N], - linear_flags: [bool; ADD_N] + linear_flags: [bool; ADD_N], ) -> (Self, Self); pub fn evaluate_quadratic_expression( @@ -88,20 +96,30 @@ pub(crate) trait RuntimeBigNumTrait { rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], linear_terms: [Self; ADD_N], - linear_flags: [bool; ADD_N] + linear_flags: [bool; ADD_N], ); - pub fn eq(lhs: Self, rhs: Self) -> bool { lhs == rhs } + pub fn eq(lhs: Self, rhs: Self) -> bool { + lhs == rhs + } pub fn assert_is_not_equal(self, other: Self); pub fn validate_in_field(self); pub fn validate_in_range(self); // pub fn validate_gt(self, lhs: Self, rhs: Self); pub fn neg(self) -> Self; - pub fn add(lhs: Self, rhs: Self) -> Self { lhs + rhs } - pub fn sub(lhs: Self, rhs: Self) -> Self { lhs - rhs } - pub fn mul(lhs: Self, rhs: Self) -> Self { lhs * rhs } - pub fn div(lhs: Self, rhs: Self) -> Self { lhs / rhs } + pub fn add(lhs: Self, rhs: Self) -> Self { + lhs + rhs + } + pub fn sub(lhs: Self, rhs: Self) -> Self { + lhs - rhs + } + pub fn mul(lhs: Self, rhs: Self) -> Self { + lhs * rhs + } + pub fn div(lhs: Self, rhs: Self) -> Self { + lhs / rhs + } pub fn udiv_mod(numerator: Self, divisor: Self) -> (Self, Self); pub fn udiv(numerator: Self, divisor: Self) -> Self; pub fn umod(numerator: Self, divisor: Self) -> Self; @@ -122,18 +140,20 @@ impl RuntimeBigNumTrait for RuntimeB result } - fn derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self { - let limbs = unsafe { - derive_from_seed::<_, MOD_BITS, _>(params, seed) - }; + fn derive_from_seed( + params: BigNumParams, + seed: [u8; SeedBytes], + ) -> Self { + let limbs = unsafe { derive_from_seed::<_, MOD_BITS, _>(params, seed) }; Self { limbs, params } } // UNCONSTRAINED! (Hence `__` prefix). - fn __derive_from_seed(params: BigNumParams, seed: [u8; SeedBytes]) -> Self { - let limbs = unsafe { - __derive_from_seed::<_, MOD_BITS, _>(params, seed) - }; + fn __derive_from_seed( + params: BigNumParams, + seed: [u8; SeedBytes], + ) -> Self { + let limbs = unsafe { __derive_from_seed::<_, MOD_BITS, _>(params, seed) }; Self { limbs, params } } @@ -193,54 +213,42 @@ impl RuntimeBigNumTrait for RuntimeB // UNCONSTRAINED! (Hence `__` prefix). fn __neg(self) -> Self { let params = self.params; - let limbs = unsafe { - __neg(params, self.limbs) - }; + let limbs = unsafe { __neg(params, self.limbs) }; Self { params, limbs } } // UNCONSTRAINED! (Hence `__` prefix). fn __add(self, other: Self) -> Self { let params = self.params; - let limbs = unsafe { - __add(params, self.limbs, other.limbs) - }; + let limbs = unsafe { __add(params, self.limbs, other.limbs) }; Self { params, limbs } } // UNCONSTRAINED! (Hence `__` prefix). fn __sub(self, other: Self) -> Self { let params = self.params; - let limbs = unsafe { - __sub(params, self.limbs, other.limbs) - }; + let limbs = unsafe { __sub(params, self.limbs, other.limbs) }; Self { params, limbs } } // UNCONSTRAINED! (Hence `__` prefix). fn __mul(self, other: Self) -> Self { let params = self.params; - let limbs = unsafe { - __mul::<_, MOD_BITS>(params, self.limbs, other.limbs) - }; + let limbs = unsafe { __mul::<_, MOD_BITS>(params, self.limbs, other.limbs) }; Self { params, limbs } } // UNCONSTRAINED! (Hence `__` prefix). fn __div(self, divisor: Self) -> Self { let params = self.params; - let limbs = unsafe { - __div::<_, MOD_BITS>(params, self.limbs, divisor.limbs) - }; + let limbs = unsafe { __div::<_, MOD_BITS>(params, self.limbs, divisor.limbs) }; Self { params, limbs } } // UNCONSTRAINED! (Hence `__` prefix). fn __udiv_mod(self, divisor: Self) -> (Self, Self) { let params = self.params; - let (q, r) = unsafe { - __udiv_mod(self.limbs, divisor.limbs) - }; + let (q, r) = unsafe { __udiv_mod(self.limbs, divisor.limbs) }; (Self { limbs: q, params }, Self { limbs: r, params }) } @@ -248,18 +256,14 @@ impl RuntimeBigNumTrait for RuntimeB fn __invmod(self) -> Self { let params = self.params; assert(params.has_multiplicative_inverse); - let limbs = unsafe { - __invmod::<_, MOD_BITS>(params, self.limbs) - }; + let limbs = unsafe { __invmod::<_, MOD_BITS>(params, self.limbs) }; Self { limbs, params } } // UNCONSTRAINED! (Hence `__` prefix). fn __pow(self, exponent: Self) -> Self { let params = self.params; - let limbs = unsafe { - __pow::<_, MOD_BITS>(params, self.limbs, exponent.limbs) - }; + let limbs = unsafe { __pow::<_, MOD_BITS>(params, self.limbs, exponent.limbs) }; Self { limbs, params } } @@ -267,9 +271,8 @@ impl RuntimeBigNumTrait for RuntimeB fn __batch_invert(x: [Self; M]) -> [Self; M] { let params = x[0].params; assert(params.has_multiplicative_inverse); - let all_limbs = unsafe { - __batch_invert::<_, MOD_BITS, _>(params, x.map(|bn| Self::get_limbs(bn))) - }; + let all_limbs = + unsafe { __batch_invert::<_, MOD_BITS, _>(params, x.map(|bn| Self::get_limbs(bn))) }; all_limbs.map(|limbs| Self { limbs, params }) } @@ -278,7 +281,8 @@ impl RuntimeBigNumTrait for RuntimeB let params = x[0].params; assert(params.has_multiplicative_inverse); let all_limbs = unsafe { - let inv_slice = __batch_invert_slice::<_, MOD_BITS>(params, x.map(|bn| Self::get_limbs(bn))); + let inv_slice = + __batch_invert_slice::<_, MOD_BITS>(params, x.map(|bn| Self::get_limbs(bn))); inv_slice.as_array() }; all_limbs.map(|limbs| Self { limbs, params }) @@ -287,9 +291,7 @@ impl RuntimeBigNumTrait for RuntimeB // UNCONSTRAINED! (Hence `__` prefix). fn __tonelli_shanks_sqrt(self) -> std::option::Option { let params = self.params; - let maybe_limbs = unsafe { - __tonelli_shanks_sqrt(params, self.limbs) - }; + let maybe_limbs = unsafe { __tonelli_shanks_sqrt(params, self.limbs) }; maybe_limbs.map(|limbs| Self { limbs, params }) } @@ -301,7 +303,7 @@ impl RuntimeBigNumTrait for RuntimeB rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], linear_terms: [Self; ADD_N], - linear_flags: [bool; ADD_N] + linear_flags: [bool; ADD_N], ) -> (Self, Self) { let (q_limbs, r_limbs) = unsafe { __compute_quadratic_expression::<_, MOD_BITS, _, _, _, _>( @@ -311,7 +313,7 @@ impl RuntimeBigNumTrait for RuntimeB map(rhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), rhs_flags, map(linear_terms, |bn| Self::get_limbs(bn)), - linear_flags + linear_flags, ) }; (Self { limbs: q_limbs, params }, Self { limbs: r_limbs, params }) @@ -324,7 +326,7 @@ impl RuntimeBigNumTrait for RuntimeB rhs_terms: [[Self; RHS_N]; NUM_PRODUCTS], rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS], linear_terms: [Self; ADD_N], - linear_flags: [bool; ADD_N] + linear_flags: [bool; ADD_N], ) { evaluate_quadratic_expression::<_, MOD_BITS, _, _, _, _>( params, @@ -333,7 +335,7 @@ impl RuntimeBigNumTrait for RuntimeB map(rhs_terms, |bns| map(bns, |bn| Self::get_limbs(bn))), rhs_flags, map(linear_terms, |bn| Self::get_limbs(bn)), - linear_flags + linear_flags, ) } diff --git a/src/tests/bignum_test.nr b/src/tests/bignum_test.nr index cc40e247..9449ddc3 100644 --- a/src/tests/bignum_test.nr +++ b/src/tests/bignum_test.nr @@ -10,29 +10,192 @@ use crate::fields::bn254Fq::BN254_Fq_Params; use crate::fields::U256::U256Params; use crate::fields::bls12_381Fq::BLS12_381_Fq_Params; -struct Test2048Params{} +struct Test2048Params {} // See https://github.com/noir-lang/noir/issues/6172 #[test] fn silence_warning() { - let _ = Test2048Params {}; + let _ = Test2048Params {}; } global TEST_2048_PARAMS: BigNumParams<18, 2048> = BigNumParams { has_multiplicative_inverse: false, modulus: [ - 0xc0a197a5ae0fcdceb052c9732614fe, 0x656ae034423283422243918ab83be3, 0x6bf590da48a7c1070b7d5aabaac678, 0x0cce39f530238b606f24b296e2bda9, 0x01e1fef9bb9c1c3ead98f226f1bfa0, 0xad8c1c816e12e0ed1379055e373abf, 0xcebe80e474f753aa9d1461c435123d, 0xaee5a18ceedef88d115a8b93c167ad, 0x268ba83c4a65c4307427fc495d9e44, 0xdd2777926848667b7df79f342639d4, 0xf455074c96855ca0068668efe7da3d, 0x5ddba6b30bbc168bfb3a1225f27d65, 0x591fec484f36707524133bcd6f4258, 0x59641b756766aeebe66781dd01d062, 0x58bc5eaff4b165e142bf9e2480eebb, 0x667a3964f08e06df772ce64b229a72, 0x9c1fdb18907711bfe3e3c1cf918395, 0xb8 + 0xc0a197a5ae0fcdceb052c9732614fe, + 0x656ae034423283422243918ab83be3, + 0x6bf590da48a7c1070b7d5aabaac678, + 0x0cce39f530238b606f24b296e2bda9, + 0x01e1fef9bb9c1c3ead98f226f1bfa0, + 0xad8c1c816e12e0ed1379055e373abf, + 0xcebe80e474f753aa9d1461c435123d, + 0xaee5a18ceedef88d115a8b93c167ad, + 0x268ba83c4a65c4307427fc495d9e44, + 0xdd2777926848667b7df79f342639d4, + 0xf455074c96855ca0068668efe7da3d, + 0x5ddba6b30bbc168bfb3a1225f27d65, + 0x591fec484f36707524133bcd6f4258, + 0x59641b756766aeebe66781dd01d062, + 0x58bc5eaff4b165e142bf9e2480eebb, + 0x667a3964f08e06df772ce64b229a72, + 0x9c1fdb18907711bfe3e3c1cf918395, + 0xb8, ], double_modulus: [ - 0x0181432f4b5c1f9b9d60a592e64c29fc, 0x01cad5c06884650684448723157077c6, 0x01d7eb21b4914f820e16fab557558cef, 0x01199c73ea604716c0de49652dc57b51, 0x0103c3fdf37738387d5b31e44de37f3f, 0x015b183902dc25c1da26f20abc6e757d, 0x019d7d01c8e9eea7553a28c3886a247a, 0x015dcb4319ddbdf11a22b5172782cf5a, 0x014d17507894cb8860e84ff892bb3c88, 0x01ba4eef24d090ccf6fbef3e684c73a7, 0x01e8aa0e992d0ab9400d0cd1dfcfb47a, 0x01bbb74d6617782d17f674244be4faca, 0x01b23fd8909e6ce0ea4826779ade84af, 0x01b2c836eacecd5dd7cccf03ba03a0c3, 0x01b178bd5fe962cbc2857f3c4901dd75, 0x01ccf472c9e11c0dbeee59cc964534e3, 0x01383fb63120ee237fc7c7839f230729, 0x0170 + 0x0181432f4b5c1f9b9d60a592e64c29fc, + 0x01cad5c06884650684448723157077c6, + 0x01d7eb21b4914f820e16fab557558cef, + 0x01199c73ea604716c0de49652dc57b51, + 0x0103c3fdf37738387d5b31e44de37f3f, + 0x015b183902dc25c1da26f20abc6e757d, + 0x019d7d01c8e9eea7553a28c3886a247a, + 0x015dcb4319ddbdf11a22b5172782cf5a, + 0x014d17507894cb8860e84ff892bb3c88, + 0x01ba4eef24d090ccf6fbef3e684c73a7, + 0x01e8aa0e992d0ab9400d0cd1dfcfb47a, + 0x01bbb74d6617782d17f674244be4faca, + 0x01b23fd8909e6ce0ea4826779ade84af, + 0x01b2c836eacecd5dd7cccf03ba03a0c3, + 0x01b178bd5fe962cbc2857f3c4901dd75, + 0x01ccf472c9e11c0dbeee59cc964534e3, + 0x01383fb63120ee237fc7c7839f230729, + 0x0170, ], - modulus_u60: U60Repr { limbs: [ - 0x0eb052c9732614fe, 0x0c0a197a5ae0fcdc, 0x022243918ab83be3, 0x0656ae0344232834, 0x070b7d5aabaac678, 0x06bf590da48a7c10, 0x6f24b296e2bda9, 0xcce39f530238b6, 0x0ead98f226f1bfa0, 0x1e1fef9bb9c1c3, 0x0d1379055e373abf, 0x0ad8c1c816e12e0e, 0x0a9d1461c435123d, 0x0cebe80e474f753a, 0x0d115a8b93c167ad, 0x0aee5a18ceedef88, 0x7427fc495d9e44, 0x0268ba83c4a65c43, 0x0b7df79f342639d4, 0x0dd2777926848667, 0x068668efe7da3d, 0x0f455074c96855ca, 0x0bfb3a1225f27d65, 0x05ddba6b30bbc168, 0x0524133bcd6f4258, 0x0591fec484f36707, 0x0be66781dd01d062, 0x059641b756766aee, 0x0142bf9e2480eebb, 0x058bc5eaff4b165e, 0x0f772ce64b229a72, 0x0667a3964f08e06d, 0x0fe3e3c1cf918395, 0x09c1fdb18907711b, 0xb8, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0eb052c9732614fe, 0x0c0a197a5ae0fcdc, 0x022243918ab83be3, 0x0656ae0344232834, 0x070b7d5aabaac678, 0x06bf590da48a7c10, 0x6f24b296e2bda9, 0xcce39f530238b6, 0x0ead98f226f1bfa0, 0x1e1fef9bb9c1c3, 0x0d1379055e373abf, 0x0ad8c1c816e12e0e, 0x0a9d1461c435123d, 0x0cebe80e474f753a, 0x0d115a8b93c167ad, 0x0aee5a18ceedef88, 0x7427fc495d9e44, 0x0268ba83c4a65c43, 0x0b7df79f342639d4, 0x0dd2777926848667, 0x068668efe7da3d, 0x0f455074c96855ca, 0x0bfb3a1225f27d65, 0x05ddba6b30bbc168, 0x0524133bcd6f4258, 0x0591fec484f36707, 0x0be66781dd01d062, 0x059641b756766aee, 0x0142bf9e2480eebb, 0x058bc5eaff4b165e, 0x0f772ce64b229a72, 0x0667a3964f08e06d, 0x0fe3e3c1cf918395, 0x09c1fdb18907711b, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + modulus_u60: U60Repr { + limbs: [ + 0x0eb052c9732614fe, + 0x0c0a197a5ae0fcdc, + 0x022243918ab83be3, + 0x0656ae0344232834, + 0x070b7d5aabaac678, + 0x06bf590da48a7c10, + 0x6f24b296e2bda9, + 0xcce39f530238b6, + 0x0ead98f226f1bfa0, + 0x1e1fef9bb9c1c3, + 0x0d1379055e373abf, + 0x0ad8c1c816e12e0e, + 0x0a9d1461c435123d, + 0x0cebe80e474f753a, + 0x0d115a8b93c167ad, + 0x0aee5a18ceedef88, + 0x7427fc495d9e44, + 0x0268ba83c4a65c43, + 0x0b7df79f342639d4, + 0x0dd2777926848667, + 0x068668efe7da3d, + 0x0f455074c96855ca, + 0x0bfb3a1225f27d65, + 0x05ddba6b30bbc168, + 0x0524133bcd6f4258, + 0x0591fec484f36707, + 0x0be66781dd01d062, + 0x059641b756766aee, + 0x0142bf9e2480eebb, + 0x058bc5eaff4b165e, + 0x0f772ce64b229a72, + 0x0667a3964f08e06d, + 0x0fe3e3c1cf918395, + 0x09c1fdb18907711b, + 0xb8, + 0x00, + ], + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0eb052c9732614fe, + 0x0c0a197a5ae0fcdc, + 0x022243918ab83be3, + 0x0656ae0344232834, + 0x070b7d5aabaac678, + 0x06bf590da48a7c10, + 0x6f24b296e2bda9, + 0xcce39f530238b6, + 0x0ead98f226f1bfa0, + 0x1e1fef9bb9c1c3, + 0x0d1379055e373abf, + 0x0ad8c1c816e12e0e, + 0x0a9d1461c435123d, + 0x0cebe80e474f753a, + 0x0d115a8b93c167ad, + 0x0aee5a18ceedef88, + 0x7427fc495d9e44, + 0x0268ba83c4a65c43, + 0x0b7df79f342639d4, + 0x0dd2777926848667, + 0x068668efe7da3d, + 0x0f455074c96855ca, + 0x0bfb3a1225f27d65, + 0x05ddba6b30bbc168, + 0x0524133bcd6f4258, + 0x0591fec484f36707, + 0x0be66781dd01d062, + 0x059641b756766aee, + 0x0142bf9e2480eebb, + 0x058bc5eaff4b165e, + 0x0f772ce64b229a72, + 0x0667a3964f08e06d, + 0x0fe3e3c1cf918395, + 0x09c1fdb18907711b, + 0xb8, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ], + }, redc_param: [ - 0x1697def7100cd5cf8d890b4ef2ec3f, 0x765ba8304214dac764d3f4adc31859, 0x8404bd14d927ea230e60d4bebf9406, 0xc4d53a23bacc251ecbfc4b7ba5a0b4, 0x3eaf3499474a6f5b2fff83f1259c87, 0xbff4c737b97281f1a5f2384a8c16d9, 0x1b4cf2f55358476b53237829990555, 0xe7a804e8eacfe3a2a5673bc3885b86, 0xabadeae4282906c817adf70eab4ae1, 0x66f7df257fe2bf27f0809aceed9b0e, 0xd90fb7428901b8bed11f6b81e36bf1, 0x36e6ba885c60b7024c563605df7e07, 0x2b7c58d2fb5d2c8478963ae6d4a44f, 0x6ee761de26635f114ccc3f7d74f855, 0x3fb726a10cf2220897513f05243de3, 0x43a26bbd732496eb4d828591b8056e, 0xf4e42304e60fb3a54fca735499f2cf, 0x162f - ] + 0x1697def7100cd5cf8d890b4ef2ec3f, + 0x765ba8304214dac764d3f4adc31859, + 0x8404bd14d927ea230e60d4bebf9406, + 0xc4d53a23bacc251ecbfc4b7ba5a0b4, + 0x3eaf3499474a6f5b2fff83f1259c87, + 0xbff4c737b97281f1a5f2384a8c16d9, + 0x1b4cf2f55358476b53237829990555, + 0xe7a804e8eacfe3a2a5673bc3885b86, + 0xabadeae4282906c817adf70eab4ae1, + 0x66f7df257fe2bf27f0809aceed9b0e, + 0xd90fb7428901b8bed11f6b81e36bf1, + 0x36e6ba885c60b7024c563605df7e07, + 0x2b7c58d2fb5d2c8478963ae6d4a44f, + 0x6ee761de26635f114ccc3f7d74f855, + 0x3fb726a10cf2220897513f05243de3, + 0x43a26bbd732496eb4d828591b8056e, + 0xf4e42304e60fb3a54fca735499f2cf, + 0x162f, + ], }; impl BigNumParamsGetter<18, 2048> for Test2048Params { @@ -53,8 +216,11 @@ type BN2048 = BigNum<18, 2048, Test2048Params>; fn test_bls_reduction() { let X1: BN381 = BigNum { limbs: [ - 0x55e83ff97a1aeffb3af00adb22c6bb, 0x8c4f9774b905a14e3a3f171bac586c, 0xa73197d7942695638c4fa9ac0fc368, 0x17f1d3 - ] + 0x55e83ff97a1aeffb3af00adb22c6bb, + 0x8c4f9774b905a14e3a3f171bac586c, + 0xa73197d7942695638c4fa9ac0fc368, + 0x17f1d3, + ], }; X1.validate_in_field(); let mut (_, XX_mul_3): (BN381, BN381) = unsafe { @@ -64,22 +230,19 @@ fn test_bls_reduction() { [[X1]], [[false]], [], - [] + [], ) }; XX_mul_3.validate_in_field(); } -fn test_eq() where BN: BigNumTrait { - let a = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; - let b = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; - let c = unsafe { - BN::__derive_from_seed([2, 2, 3, 4]) - }; +fn test_eq() +where + BN: BigNumTrait, +{ + let a = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; + let b = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; + let c = unsafe { BN::__derive_from_seed([2, 2, 3, 4]) }; let modulus = BN::modulus(); let t0: U60Repr = (U60Repr::from(modulus.get_limbs())); @@ -110,26 +273,24 @@ fn test_eq() where BN: BigNumTrait { // // // 98760 // // // 99689 // // // 929 gates for a 2048 bit mul -fn test_mul() where BN: BigNumTrait + std::ops::Mul + std::ops::Add { - let a: BN = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; - let b: BN = unsafe { - BN::__derive_from_seed([4, 5, 6, 7]) - }; +fn test_mul() +where + BN: BigNumTrait + std::ops::Mul + std::ops::Add, +{ + let a: BN = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; + let b: BN = unsafe { BN::__derive_from_seed([4, 5, 6, 7]) }; let c = (a + b) * (a + b); let d = (a * a) + (b * b) + (a * b) + (a * b); assert(c.eq(d)); } -fn test_add() where BN: BigNumTrait + std::ops::Add + std::ops::Mul + std::cmp::Eq { - let a = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; - let b: BN = unsafe { - BN::__derive_from_seed([4, 5, 6, 7]) - }; +fn test_add() +where + BN: BigNumTrait + std::ops::Add + std::ops::Mul + std::cmp::Eq, +{ + let a = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; + let b: BN = unsafe { BN::__derive_from_seed([4, 5, 6, 7]) }; let one = BN::one(); a.validate_in_range(); a.validate_in_field(); @@ -152,63 +313,56 @@ fn test_add() where BN: BigNumTrait + std::ops::Add + std::op } } -fn test_div() where BN: BigNumTrait + std::ops::Div + std::ops::Mul + std::ops::Add + std::cmp::Eq { - let a = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; - let b = unsafe { - BN::__derive_from_seed([4, 5, 6, 7]) - }; +fn test_div() +where + BN: BigNumTrait + std::ops::Div + std::ops::Mul + std::ops::Add + std::cmp::Eq, +{ + let a = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; + let b = unsafe { BN::__derive_from_seed([4, 5, 6, 7]) }; let c = a / b; assert((b * c) == (a)); } -fn test_invmod() where BN: BigNumTrait + std::cmp::Eq { - let u = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; +fn test_invmod() +where + BN: BigNumTrait + std::cmp::Eq, +{ + let u = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; for _ in 0..1 { - let v = unsafe { - u.__invmod() - }; - let result = unsafe { - u.__mul(v) - }; + let v = unsafe { u.__invmod() }; + let result = unsafe { u.__mul(v) }; let expected = BN::one(); assert(result == expected); } } -fn assert_is_not_equal() where BN: BigNumTrait { - let a = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; - let b = unsafe { - BN::__derive_from_seed([4, 5, 6, 7]) - }; +fn assert_is_not_equal() +where + BN: BigNumTrait, +{ + let a = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; + let b = unsafe { BN::__derive_from_seed([4, 5, 6, 7]) }; a.assert_is_not_equal(b); } -fn assert_is_not_equal_fail() where BN: BigNumTrait { - let a = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; - let b = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; +fn assert_is_not_equal_fail() +where + BN: BigNumTrait, +{ + let a = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; + let b = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; a.assert_is_not_equal(b); } -fn assert_is_not_equal_overloaded_lhs_fail() where BN: BigNumTrait { - let a = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; - let b = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; +fn assert_is_not_equal_overloaded_lhs_fail() +where + BN: BigNumTrait, +{ + let a = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; + let b = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; let modulus = BN::modulus(); @@ -218,13 +372,12 @@ fn assert_is_not_equal_overloaded_lhs_fail() where BN: BigNumTra a_plus_modulus.assert_is_not_equal(b); } -fn assert_is_not_equal_overloaded_rhs_fail() where BN: BigNumTrait { - let a = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; - let b = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; +fn assert_is_not_equal_overloaded_rhs_fail() +where + BN: BigNumTrait, +{ + let a = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; + let b = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; let modulus = BN::modulus(); @@ -234,13 +387,12 @@ fn assert_is_not_equal_overloaded_rhs_fail() where BN: BigNumTra a.assert_is_not_equal(b_plus_modulus); } -fn assert_is_not_equal_overloaded_fail() where BN: BigNumTrait { - let a = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; - let b = unsafe { - BN::__derive_from_seed([1, 2, 3, 4]) - }; +fn assert_is_not_equal_overloaded_fail() +where + BN: BigNumTrait, +{ + let a = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; + let b = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; let modulus = BN::modulus(); @@ -278,7 +430,6 @@ fn test_sub_test_BN() { let mut b: Fq = BigNum::one(); let mut expected: Fq = BigNum::modulus(); expected.limbs[0] -= 1; // p - 1 - let result = a - b; assert(result == expected); } @@ -313,8 +464,12 @@ 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 : U60Repr<3, 2> = U60Repr::from(BN254_Fq_Params::get_params().modulus); - let two_pow_254_minus_1: U60Repr<3, 2> = U60Repr::from([0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x3fff]); + let p: U60Repr<3, 2> = U60Repr::from(BN254_Fq_Params::get_params().modulus); + let two_pow_254_minus_1: U60Repr<3, 2> = U60Repr::from([ + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0x3fff, + ]); let a: Fq = BigNum { limbs: U60Repr::into(p) }; let b: Fq = BigNum { limbs: U60Repr::into(two_pow_254_minus_1) }; let result = a + b; @@ -325,8 +480,12 @@ 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 : U60Repr<3, 2> = U60Repr::from(BN254_Fq_Params::get_params().modulus); - let two_pow_254_minus_1: U60Repr<3, 2> = U60Repr::from([0xffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffff, 0x3fff]); + let p: U60Repr<3, 2> = U60Repr::from(BN254_Fq_Params::get_params().modulus); + let two_pow_254_minus_1: U60Repr<3, 2> = U60Repr::from([ + 0xffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffff, + 0x3fff, + ]); let one = U60Repr::from([1, 0, 0]); let a: Fq = BigNum { limbs: U60Repr::into(p + one) }; let b: Fq = BigNum { limbs: U60Repr::into(two_pow_254_minus_1) }; @@ -463,17 +622,13 @@ type U256 = BN256; #[test] fn test_udiv_mod_U256() { - let a: U256 = unsafe { - BigNum::__derive_from_seed([1, 2, 3, 4]) - }; + let a: U256 = unsafe { BigNum::__derive_from_seed([1, 2, 3, 4]) }; let b: U256 = BigNum::from_array([12, 0, 0]); let (q, r) = a.udiv_mod(b); // let qb = q.__mul(b); - let product = unsafe { - q.__mul(b).__add(r) - }; + let product = unsafe { q.__mul(b).__add(r) }; assert(product == a); } @@ -511,7 +666,7 @@ fn test_2048_bit_quadratic_expression() { 0x00000000000000000000000000000000001400e1f0a38695db66993fe042c48b, 0x0000000000000000000000000000000000e1d829cb4fa8cabb7d0265efbd8527, 0x000000000000000000000000000000000055f1a92a5dd099ef2bcd89ac175b52, - 0x00000000000000000000000000000000000000000000000000000000000000fc + 0x00000000000000000000000000000000000000000000000000000000000000fc, ]; let b: [Field; 18] = [ 0x0000000000000000000000000000000000c5694493e9bcc76e68dfcf73e0fde1, @@ -531,7 +686,7 @@ fn test_2048_bit_quadratic_expression() { 0x00000000000000000000000000000000002a6850cce14a20463913002ddc0fa6, 0x0000000000000000000000000000000000a97e3b06586bfa62325ef7557ab536, 0x0000000000000000000000000000000000b942b0d26e5be2e08cd425107c59f7, - 0x0000000000000000000000000000000000000000000000000000000000000031 + 0x0000000000000000000000000000000000000000000000000000000000000031, ]; let c_expected: [Field; 18] = [ 0x00000000000000000000000000000000004518a874adebbcf963fed876dfcf78, @@ -551,14 +706,12 @@ fn test_2048_bit_quadratic_expression() { 0x00000000000000000000000000000000004432a79276f4375ff3ec2ced8b6cf6, 0x0000000000000000000000000000000000a0922d75e96e3f9e31c0cbbcbd708a, 0x00000000000000000000000000000000004013822c9e9aa5b5b1e9c33e4332b7, - 0x0000000000000000000000000000000000000000000000000000000000000058 + 0x0000000000000000000000000000000000000000000000000000000000000058, ]; let a_bn: BN2048 = BigNum { limbs: a }; let b_bn: BN2048 = BigNum { limbs: b }; - let c_bn = unsafe { - a_bn.__mul(b_bn) - }; + let c_bn = unsafe { a_bn.__mul(b_bn) }; assert(c_bn.limbs == c_expected); a_bn.validate_in_range(); @@ -569,27 +722,17 @@ fn test_2048_bit_quadratic_expression() { #[test] fn test_expressions() { let x: [Field; 6] = [ - 0x000000000000000000000000000000000083684820ff40795b8d9f1be2220cba, 0x0000000000000000000000000000000000d4924fbdc522b07b6cd0ef5508fd66, 0x0000000000000000000000000000000000d48f6c43c5930f3d70d6db09a48f4a, - 0x0000000000000000000000000000000000e7f72b2c0756704bea85be38352b34, 0x00000000000000000000000000000000000000000000000000000000b05d5ac5, 0 + 0x000000000000000000000000000000000083684820ff40795b8d9f1be2220cba, + 0x0000000000000000000000000000000000d4924fbdc522b07b6cd0ef5508fd66, + 0x0000000000000000000000000000000000d48f6c43c5930f3d70d6db09a48f4a, + 0x0000000000000000000000000000000000e7f72b2c0756704bea85be38352b34, + 0x00000000000000000000000000000000000000000000000000000000b05d5ac5, + 0, ]; - let y: Fq = BigNum { - limbs: [ - 0x1, - 0x1, - 0x0 - ] - }; - let z: Fq = BigNum { - limbs: [ - 0x2, - 0x2, - 0x0 - ] - }; - let yy = unsafe { - y.__add(y) - }; + let y: Fq = BigNum { limbs: [0x1, 0x1, 0x0] }; + let z: Fq = BigNum { limbs: [0x2, 0x2, 0x0] }; + let yy = unsafe { y.__add(y) }; assert(yy.limbs == z.limbs); @@ -597,42 +740,34 @@ fn test_expressions() { limbs: [ 0x0000000000000000000000000000000000b4a832748da6ad742a1fd81b787643, 0x00000000000000000000000000000000009575f594e04080471712c1d7f18e89, - 0x000000000000000000000000000000000000000000000000000000000000063 - ] + 0x000000000000000000000000000000000000000000000000000000000000063, + ], }; let vv: Fq = BigNum { limbs: [ 0x0000000000000000000000000000000000b4aec2748da6ad742a1fd81b787643, 0x00000000000000000000000000000000009575f594e0408047171a01d7f18e89, - 0x0000000000000000000000000000000000000000000000000000000000000062 - ] + 0x0000000000000000000000000000000000000000000000000000000000000062, + ], }; let w: Fq = BigNum { limbs: [ 0x0000000000000000000000000000000000b4a832748da6ad742a1fd81b787643, 0x00000000000000000000000000000000009575f594e04080471712c1d7f18e89, - 0x0000000000000000000000000000000000000000000000000000000000001f93 - ] + 0x0000000000000000000000000000000000000000000000000000000000001f93, + ], }; let x: Fq = BigNum { limbs: [ 0x0000000000000000000000000000000000b4aec2748da6ad742a1fd81b787643, 0x00000000000000000000000000000000009575f594e0408047171a01d7f18e89, - 0x0000000000000000000000000000000000000000000000000000000000000f93 - ] - }; - let wx = unsafe { - w.__mul(x) - }; - let uv = unsafe { - uu.__mul(vv) - }; - let y = unsafe { - (uv.__add(wx)).__neg() - }; - let z = unsafe { - uv.__add(wx) + 0x0000000000000000000000000000000000000000000000000000000000000f93, + ], }; + let wx = unsafe { w.__mul(x) }; + let uv = unsafe { uu.__mul(vv) }; + let y = unsafe { (uv.__add(wx)).__neg() }; + let z = unsafe { uv.__add(wx) }; BigNum::evaluate_quadratic_expression( [[uu], [w]], @@ -640,7 +775,7 @@ fn test_expressions() { [[vv], [x]], [[false], [false]], [z], - [true] + [true], ); BigNum::evaluate_quadratic_expression( [[uu], [w]], @@ -648,7 +783,7 @@ fn test_expressions() { [[vv], [x]], [[false], [false]], [y], - [false] + [false], ); let wx_constrained = w * x; diff --git a/src/tests/mod.nr b/src/tests/mod.nr index f972d4ba..fdef940a 100644 --- a/src/tests/mod.nr +++ b/src/tests/mod.nr @@ -1,2 +1,2 @@ mod bignum_test; -mod runtime_bignum_test; \ No newline at end of file +mod runtime_bignum_test; diff --git a/src/tests/runtime_bignum_test.nr b/src/tests/runtime_bignum_test.nr index c772ca4f..a97f4ccd 100644 --- a/src/tests/runtime_bignum_test.nr +++ b/src/tests/runtime_bignum_test.nr @@ -12,18 +12,181 @@ use crate::fields::bls12_377Fr::BLS12_377_Fr_Params; global TEST_2048_PARAMS: BigNumParams<18, 2048> = BigNumParams { has_multiplicative_inverse: false, modulus: [ - 0xc0a197a5ae0fcdceb052c9732614fe, 0x656ae034423283422243918ab83be3, 0x6bf590da48a7c1070b7d5aabaac678, 0x0cce39f530238b606f24b296e2bda9, 0x01e1fef9bb9c1c3ead98f226f1bfa0, 0xad8c1c816e12e0ed1379055e373abf, 0xcebe80e474f753aa9d1461c435123d, 0xaee5a18ceedef88d115a8b93c167ad, 0x268ba83c4a65c4307427fc495d9e44, 0xdd2777926848667b7df79f342639d4, 0xf455074c96855ca0068668efe7da3d, 0x5ddba6b30bbc168bfb3a1225f27d65, 0x591fec484f36707524133bcd6f4258, 0x59641b756766aeebe66781dd01d062, 0x58bc5eaff4b165e142bf9e2480eebb, 0x667a3964f08e06df772ce64b229a72, 0x9c1fdb18907711bfe3e3c1cf918395, 0xb8 + 0xc0a197a5ae0fcdceb052c9732614fe, + 0x656ae034423283422243918ab83be3, + 0x6bf590da48a7c1070b7d5aabaac678, + 0x0cce39f530238b606f24b296e2bda9, + 0x01e1fef9bb9c1c3ead98f226f1bfa0, + 0xad8c1c816e12e0ed1379055e373abf, + 0xcebe80e474f753aa9d1461c435123d, + 0xaee5a18ceedef88d115a8b93c167ad, + 0x268ba83c4a65c4307427fc495d9e44, + 0xdd2777926848667b7df79f342639d4, + 0xf455074c96855ca0068668efe7da3d, + 0x5ddba6b30bbc168bfb3a1225f27d65, + 0x591fec484f36707524133bcd6f4258, + 0x59641b756766aeebe66781dd01d062, + 0x58bc5eaff4b165e142bf9e2480eebb, + 0x667a3964f08e06df772ce64b229a72, + 0x9c1fdb18907711bfe3e3c1cf918395, + 0xb8, ], double_modulus: [ - 0x0181432f4b5c1f9b9d60a592e64c29fc, 0x01cad5c06884650684448723157077c6, 0x01d7eb21b4914f820e16fab557558cef, 0x01199c73ea604716c0de49652dc57b51, 0x0103c3fdf37738387d5b31e44de37f3f, 0x015b183902dc25c1da26f20abc6e757d, 0x019d7d01c8e9eea7553a28c3886a247a, 0x015dcb4319ddbdf11a22b5172782cf5a, 0x014d17507894cb8860e84ff892bb3c88, 0x01ba4eef24d090ccf6fbef3e684c73a7, 0x01e8aa0e992d0ab9400d0cd1dfcfb47a, 0x01bbb74d6617782d17f674244be4faca, 0x01b23fd8909e6ce0ea4826779ade84af, 0x01b2c836eacecd5dd7cccf03ba03a0c3, 0x01b178bd5fe962cbc2857f3c4901dd75, 0x01ccf472c9e11c0dbeee59cc964534e3, 0x01383fb63120ee237fc7c7839f230729, 0x0170 + 0x0181432f4b5c1f9b9d60a592e64c29fc, + 0x01cad5c06884650684448723157077c6, + 0x01d7eb21b4914f820e16fab557558cef, + 0x01199c73ea604716c0de49652dc57b51, + 0x0103c3fdf37738387d5b31e44de37f3f, + 0x015b183902dc25c1da26f20abc6e757d, + 0x019d7d01c8e9eea7553a28c3886a247a, + 0x015dcb4319ddbdf11a22b5172782cf5a, + 0x014d17507894cb8860e84ff892bb3c88, + 0x01ba4eef24d090ccf6fbef3e684c73a7, + 0x01e8aa0e992d0ab9400d0cd1dfcfb47a, + 0x01bbb74d6617782d17f674244be4faca, + 0x01b23fd8909e6ce0ea4826779ade84af, + 0x01b2c836eacecd5dd7cccf03ba03a0c3, + 0x01b178bd5fe962cbc2857f3c4901dd75, + 0x01ccf472c9e11c0dbeee59cc964534e3, + 0x01383fb63120ee237fc7c7839f230729, + 0x0170, ], - modulus_u60: U60Repr { limbs: [ - 0x0eb052c9732614fe, 0x0c0a197a5ae0fcdc, 0x022243918ab83be3, 0x0656ae0344232834, 0x070b7d5aabaac678, 0x06bf590da48a7c10, 0x6f24b296e2bda9, 0xcce39f530238b6, 0x0ead98f226f1bfa0, 0x1e1fef9bb9c1c3, 0x0d1379055e373abf, 0x0ad8c1c816e12e0e, 0x0a9d1461c435123d, 0x0cebe80e474f753a, 0x0d115a8b93c167ad, 0x0aee5a18ceedef88, 0x7427fc495d9e44, 0x0268ba83c4a65c43, 0x0b7df79f342639d4, 0x0dd2777926848667, 0x068668efe7da3d, 0x0f455074c96855ca, 0x0bfb3a1225f27d65, 0x05ddba6b30bbc168, 0x0524133bcd6f4258, 0x0591fec484f36707, 0x0be66781dd01d062, 0x059641b756766aee, 0x0142bf9e2480eebb, 0x058bc5eaff4b165e, 0x0f772ce64b229a72, 0x0667a3964f08e06d, 0x0fe3e3c1cf918395, 0x09c1fdb18907711b, 0xb8, 0x00]}, - modulus_u60_x4: U60Repr { limbs: [ - 0x0eb052c9732614fe, 0x0c0a197a5ae0fcdc, 0x022243918ab83be3, 0x0656ae0344232834, 0x070b7d5aabaac678, 0x06bf590da48a7c10, 0x6f24b296e2bda9, 0xcce39f530238b6, 0x0ead98f226f1bfa0, 0x1e1fef9bb9c1c3, 0x0d1379055e373abf, 0x0ad8c1c816e12e0e, 0x0a9d1461c435123d, 0x0cebe80e474f753a, 0x0d115a8b93c167ad, 0x0aee5a18ceedef88, 0x7427fc495d9e44, 0x0268ba83c4a65c43, 0x0b7df79f342639d4, 0x0dd2777926848667, 0x068668efe7da3d, 0x0f455074c96855ca, 0x0bfb3a1225f27d65, 0x05ddba6b30bbc168, 0x0524133bcd6f4258, 0x0591fec484f36707, 0x0be66781dd01d062, 0x059641b756766aee, 0x0142bf9e2480eebb, 0x058bc5eaff4b165e, 0x0f772ce64b229a72, 0x0667a3964f08e06d, 0x0fe3e3c1cf918395, 0x09c1fdb18907711b, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + modulus_u60: U60Repr { + limbs: [ + 0x0eb052c9732614fe, + 0x0c0a197a5ae0fcdc, + 0x022243918ab83be3, + 0x0656ae0344232834, + 0x070b7d5aabaac678, + 0x06bf590da48a7c10, + 0x6f24b296e2bda9, + 0xcce39f530238b6, + 0x0ead98f226f1bfa0, + 0x1e1fef9bb9c1c3, + 0x0d1379055e373abf, + 0x0ad8c1c816e12e0e, + 0x0a9d1461c435123d, + 0x0cebe80e474f753a, + 0x0d115a8b93c167ad, + 0x0aee5a18ceedef88, + 0x7427fc495d9e44, + 0x0268ba83c4a65c43, + 0x0b7df79f342639d4, + 0x0dd2777926848667, + 0x068668efe7da3d, + 0x0f455074c96855ca, + 0x0bfb3a1225f27d65, + 0x05ddba6b30bbc168, + 0x0524133bcd6f4258, + 0x0591fec484f36707, + 0x0be66781dd01d062, + 0x059641b756766aee, + 0x0142bf9e2480eebb, + 0x058bc5eaff4b165e, + 0x0f772ce64b229a72, + 0x0667a3964f08e06d, + 0x0fe3e3c1cf918395, + 0x09c1fdb18907711b, + 0xb8, + 0x00, + ], + }, + modulus_u60_x4: U60Repr { + limbs: [ + 0x0eb052c9732614fe, + 0x0c0a197a5ae0fcdc, + 0x022243918ab83be3, + 0x0656ae0344232834, + 0x070b7d5aabaac678, + 0x06bf590da48a7c10, + 0x6f24b296e2bda9, + 0xcce39f530238b6, + 0x0ead98f226f1bfa0, + 0x1e1fef9bb9c1c3, + 0x0d1379055e373abf, + 0x0ad8c1c816e12e0e, + 0x0a9d1461c435123d, + 0x0cebe80e474f753a, + 0x0d115a8b93c167ad, + 0x0aee5a18ceedef88, + 0x7427fc495d9e44, + 0x0268ba83c4a65c43, + 0x0b7df79f342639d4, + 0x0dd2777926848667, + 0x068668efe7da3d, + 0x0f455074c96855ca, + 0x0bfb3a1225f27d65, + 0x05ddba6b30bbc168, + 0x0524133bcd6f4258, + 0x0591fec484f36707, + 0x0be66781dd01d062, + 0x059641b756766aee, + 0x0142bf9e2480eebb, + 0x058bc5eaff4b165e, + 0x0f772ce64b229a72, + 0x0667a3964f08e06d, + 0x0fe3e3c1cf918395, + 0x09c1fdb18907711b, + 0xb8, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ], + }, redc_param: [ - 0x1697def7100cd5cf8d890b4ef2ec3f, 0x765ba8304214dac764d3f4adc31859, 0x8404bd14d927ea230e60d4bebf9406, 0xc4d53a23bacc251ecbfc4b7ba5a0b4, 0x3eaf3499474a6f5b2fff83f1259c87, 0xbff4c737b97281f1a5f2384a8c16d9, 0x1b4cf2f55358476b53237829990555, 0xe7a804e8eacfe3a2a5673bc3885b86, 0xabadeae4282906c817adf70eab4ae1, 0x66f7df257fe2bf27f0809aceed9b0e, 0xd90fb7428901b8bed11f6b81e36bf1, 0x36e6ba885c60b7024c563605df7e07, 0x2b7c58d2fb5d2c8478963ae6d4a44f, 0x6ee761de26635f114ccc3f7d74f855, 0x3fb726a10cf2220897513f05243de3, 0x43a26bbd732496eb4d828591b8056e, 0xf4e42304e60fb3a54fca735499f2cf, 0x162f - ] + 0x1697def7100cd5cf8d890b4ef2ec3f, + 0x765ba8304214dac764d3f4adc31859, + 0x8404bd14d927ea230e60d4bebf9406, + 0xc4d53a23bacc251ecbfc4b7ba5a0b4, + 0x3eaf3499474a6f5b2fff83f1259c87, + 0xbff4c737b97281f1a5f2384a8c16d9, + 0x1b4cf2f55358476b53237829990555, + 0xe7a804e8eacfe3a2a5673bc3885b86, + 0xabadeae4282906c817adf70eab4ae1, + 0x66f7df257fe2bf27f0809aceed9b0e, + 0xd90fb7428901b8bed11f6b81e36bf1, + 0x36e6ba885c60b7024c563605df7e07, + 0x2b7c58d2fb5d2c8478963ae6d4a44f, + 0x6ee761de26635f114ccc3f7d74f855, + 0x3fb726a10cf2220897513f05243de3, + 0x43a26bbd732496eb4d828591b8056e, + 0xf4e42304e60fb3a54fca735499f2cf, + 0x162f, + ], }; struct Test2048Params {} @@ -31,7 +194,7 @@ struct Test2048Params {} // See https://github.com/noir-lang/noir/issues/6172 #[test] fn silence_warning() { - let _ = Test2048Params {}; + let _ = Test2048Params {}; } impl BigNumParamsGetter<18, 2048> for Test2048Params { @@ -45,7 +208,7 @@ impl BigNumParamsGetter<18, 2048> for Test2048Params { **/ comptime fn make_test(f: StructDefinition, N: Quoted, MOD_BITS: Quoted, typ: Quoted) -> Quoted { let k = f.name(); - quote{ + quote { impl $k { #[test] fn test_add() { @@ -355,37 +518,35 @@ fn test_eq() { } #[make_test(quote{3}, quote{254}, quote{BN254_Fq_Params})] -pub struct BNTests{} +pub struct BNTests {} #[make_test(quote{3}, quote{256}, quote{Secp256k1_Fq_Params})] -pub struct Secp256K1FqTests{} +pub struct Secp256K1FqTests {} #[make_test(quote{4}, quote{381} ,quote{BLS12_381_Fq_Params})] -pub struct BLS12_381FqTests{} +pub struct BLS12_381FqTests {} #[make_test(quote{18}, quote{2048}, quote{Test2048Params})] -pub struct Test2048Tests{} +pub struct Test2048Tests {} #[make_test(quote{3}, quote{255}, quote{BLS12_381_Fr_Params})] -pub struct BLS12_381_Fr_ParamsTests{} +pub struct BLS12_381_Fr_ParamsTests {} #[make_test(quote{4}, quote{377}, quote{BLS12_377_Fq_Params})] -pub struct BLS12_377_Fq_ParamsTests{} +pub struct BLS12_377_Fq_ParamsTests {} #[make_test(quote{3}, quote{253}, quote{BLS12_377_Fr_Params})] -pub struct BLS12_377_Fr_ParamsTests{} +pub struct BLS12_377_Fr_ParamsTests {} // 98760 // 99689 // 929 gates for a 2048 bit mul fn test_div(params: BigNumParams) { - let a: RuntimeBigNum = unsafe { - RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) - }; - let b: RuntimeBigNum = unsafe { - RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) - }; + let a: RuntimeBigNum = + unsafe { RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]) }; + let b: RuntimeBigNum = + unsafe { RuntimeBigNum::__derive_from_seed(params, [4, 5, 6, 7]) }; let c = a / b; assert((b * c) == a); @@ -410,9 +571,7 @@ fn test_div_BN() { #[test] fn test_invmod_BN() { let params = BN254_Fq_Params::get_params(); - unsafe { - test_invmod(params) - }; + unsafe { test_invmod(params) }; } // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril @@ -450,7 +609,7 @@ fn test_2048_bit_quadratic_expression() { 0x00000000000000000000000000000000001400e1f0a38695db66993fe042c48b, 0x0000000000000000000000000000000000e1d829cb4fa8cabb7d0265efbd8527, 0x000000000000000000000000000000000055f1a92a5dd099ef2bcd89ac175b52, - 0x00000000000000000000000000000000000000000000000000000000000000fc + 0x00000000000000000000000000000000000000000000000000000000000000fc, ]; let b: [Field; 18] = [ 0x0000000000000000000000000000000000c5694493e9bcc76e68dfcf73e0fde1, @@ -470,7 +629,7 @@ fn test_2048_bit_quadratic_expression() { 0x00000000000000000000000000000000002a6850cce14a20463913002ddc0fa6, 0x0000000000000000000000000000000000a97e3b06586bfa62325ef7557ab536, 0x0000000000000000000000000000000000b942b0d26e5be2e08cd425107c59f7, - 0x0000000000000000000000000000000000000000000000000000000000000031 + 0x0000000000000000000000000000000000000000000000000000000000000031, ]; let c_expected: [Field; 18] = [ 0x00000000000000000000000000000000004518a874adebbcf963fed876dfcf78, @@ -490,7 +649,7 @@ fn test_2048_bit_quadratic_expression() { 0x00000000000000000000000000000000004432a79276f4375ff3ec2ced8b6cf6, 0x0000000000000000000000000000000000a0922d75e96e3f9e31c0cbbcbd708a, 0x00000000000000000000000000000000004013822c9e9aa5b5b1e9c33e4332b7, - 0x0000000000000000000000000000000000000000000000000000000000000058 + 0x0000000000000000000000000000000000000000000000000000000000000058, ]; let a_bn: RuntimeBigNum<_, 2048> = RuntimeBigNum { limbs: a, params }; @@ -500,7 +659,15 @@ fn test_2048_bit_quadratic_expression() { a_bn.validate_in_range(); - RuntimeBigNum::evaluate_quadratic_expression(params, [[a_bn]], [[false]], [[b_bn]], [[false]], [c], [true]); + RuntimeBigNum::evaluate_quadratic_expression( + params, + [[a_bn]], + [[false]], + [[b_bn]], + [[false]], + [c], + [true], + ); } #[test] diff --git a/src/utils/msb.nr b/src/utils/msb.nr index 172ca12b..3452eacd 100644 --- a/src/utils/msb.nr +++ b/src/utils/msb.nr @@ -3,18 +3,16 @@ global n1: u32 = 0xffffffff; global MUL_DE_BRUIJN_BIT: [u32; 128] = [ - 0,// change to 1 if you want bitSize(0) = 1 - 48, n1, n1, 31, n1, 15, 51, n1, 63, 5, n1, n1, n1, 19, n1, - 23, 28, n1, n1, n1, 40, 36, 46, n1, 13, n1, n1, n1, 34, n1, 58, - n1, 60, 2, 43, 55, n1, n1, n1, 50, 62, 4, n1, 18, 27, n1, 39, - 45, n1, n1, 33, 57, n1, 1, 54, n1, 49, n1, 17, n1, n1, 32, n1, - 53, n1, 16, n1, n1, 52, n1, n1, n1, 64, 6, 7, 8, n1, 9, n1, - n1, n1, 20, 10, n1, n1, 24, n1, 29, n1, n1, 21, n1, 11, n1, n1, - 41, n1, 25, 37, n1, 47, n1, 30, 14, n1, n1, n1, n1, 22, n1, n1, - 35, 12, n1, n1, n1, 59, 42, n1, n1, 61, 3, 26, 38, 44, n1, 56 - ]; + 0, // change to 1 if you want bitSize(0) = 1 + 48, n1, n1, 31, n1, 15, 51, n1, 63, 5, n1, n1, n1, 19, n1, 23, 28, n1, n1, n1, 40, 36, 46, n1, + 13, n1, n1, n1, 34, n1, 58, n1, 60, 2, 43, 55, n1, n1, n1, 50, 62, 4, n1, 18, 27, n1, 39, 45, + n1, n1, 33, 57, n1, 1, 54, n1, 49, n1, 17, n1, n1, 32, n1, 53, n1, 16, n1, n1, 52, n1, n1, n1, + 64, 6, 7, 8, n1, 9, n1, n1, n1, 20, 10, n1, n1, 24, n1, 29, n1, n1, 21, n1, 11, n1, n1, 41, n1, + 25, 37, n1, 47, n1, 30, 14, n1, n1, n1, n1, 22, n1, n1, 35, 12, n1, n1, n1, 59, 42, n1, n1, 61, + 3, 26, 38, 44, n1, 56, +]; -unconstrained pub fn get_msb64(x: u64) -> u32 { +pub unconstrained fn get_msb64(x: u64) -> u32 { let mut v = x; v |= v >> 1; v |= v >> 2; diff --git a/src/utils/split_bits.nr b/src/utils/split_bits.nr index 3527080e..94d79ea9 100644 --- a/src/utils/split_bits.nr +++ b/src/utils/split_bits.nr @@ -1,13 +1,28 @@ - // Decomposes a single field into two 120 bit fields and a carry -unconstrained pub fn split_120_bits(x: Field) -> (Field, Field) { +pub unconstrained fn split_120_bits(x: Field) -> (Field, Field) { let x_bytes: [u8; 32] = x.to_le_bytes(); let mut low: Field = 0; let mut high: Field = 0; let offsets: [Field; 17] = [ - 1, 0x100, 0x10000, 0x1000000, 0x100000000, 0x10000000000, 0x1000000000000, 0x100000000000000, 0x10000000000000000, 0x1000000000000000000, 0x100000000000000000000, 0x10000000000000000000000, 0x1000000000000000000000000, 0x100000000000000000000000000, 0x10000000000000000000000000000, 0x1000000000000000000000000000000, 0x100000000000000000000000000000000 + 1, + 0x100, + 0x10000, + 0x1000000, + 0x100000000, + 0x10000000000, + 0x1000000000000, + 0x100000000000000, + 0x10000000000000000, + 0x1000000000000000000, + 0x100000000000000000000, + 0x10000000000000000000000, + 0x1000000000000000000000000, + 0x100000000000000000000000000, + 0x10000000000000000000000000000, + 0x1000000000000000000000000000000, + 0x100000000000000000000000000000000, ]; for i in 0..15 { @@ -26,13 +41,22 @@ unconstrained pub fn split_120_bits(x: Field) -> (Field, Field) { * * @description Expects the input limb to be in the range [0, ..., 2^{120 - 1}] **/ -unconstrained pub fn split_60_bits(x: Field) -> (u64, u64) { +pub unconstrained fn split_60_bits(x: Field) -> (u64, u64) { let x_bytes: [u8; 32] = x.to_le_bytes(); let mut low: u64 = 0; let mut high: u64 = 0; - let offsets: [u64; 8] = [1, 0x100, 0x10000, 0x1000000, 0x100000000, 0x10000000000, 0x1000000000000, 0x100000000000000]; + let offsets: [u64; 8] = [ + 1, + 0x100, + 0x10000, + 0x1000000, + 0x100000000, + 0x10000000000, + 0x1000000000000, + 0x100000000000000, + ]; for i in 0..8 { low += (x_bytes[i] as u64) * offsets[i]; high += (x_bytes[i + 8] as u64) * offsets[i]; @@ -44,21 +68,21 @@ unconstrained pub fn split_60_bits(x: Field) -> (u64, u64) { (low, high) } -unconstrained pub(crate) fn __normalize_limbs( +pub(crate) unconstrained fn __normalize_limbs( input: [Field; N], - range: u32 + range: u32, ) -> [Field; N] { let mut normalized: [Field; N] = [0; N]; let mut inp: _ = input; for i in 0..(range - 1) { let (lo, hi) = split_120_bits(inp[i]); - normalized[i]= lo; - inp[i + 1] += hi; + normalized[i] = lo; + inp[i + 1] += hi; } { let (lo, hi) = split_120_bits(inp[range - 1]); - normalized[range - 1]= lo; + normalized[range - 1] = lo; assert(hi == 0); } normalized diff --git a/src/utils/u60_representation.nr b/src/utils/u60_representation.nr index c90c3d71..ea4c9b50 100644 --- a/src/utils/u60_representation.nr +++ b/src/utils/u60_representation.nr @@ -9,7 +9,7 @@ use crate::utils::msb::get_msb64; * as well as when performing bit shifts. */ pub struct U60Repr { - pub(crate) limbs: [u64; N * NumSegments] + pub(crate) limbs: [u64; N * NumSegments], } impl std::ops::Add for U60Repr { @@ -49,9 +49,7 @@ impl std::convert::From<[Field; N]> for U60Rep fn from(input: [Field; N]) -> Self { let mut result: Self = U60Repr { limbs: [0; N * NumSegments] }; for i in 0..(N) { - let (lo, hi) = unsafe { - split_bits::split_60_bits(input[i]) - }; + let (lo, hi) = unsafe { split_bits::split_60_bits(input[i]) }; result.limbs[2 * i] = lo; result.limbs[2 * i + 1] = hi; } @@ -78,7 +76,9 @@ impl std::cmp::Eq for U60Repr impl U60Repr { - unconstrained pub(crate) fn new(x: [Field; N * NumFieldSegments]) -> Self { + pub(crate) unconstrained fn new( + x: [Field; N * NumFieldSegments], + ) -> Self { let mut result: Self = U60Repr { limbs: [0; N * NumSegments] }; for i in 0..(N * NumFieldSegments) { let (lo, hi) = split_bits::split_60_bits(x[i]); @@ -88,22 +88,24 @@ impl U60Repr { result } - unconstrained pub(crate) fn one() -> Self { + pub(crate) unconstrained fn one() -> Self { let mut result: Self = U60Repr { limbs: [0; N * NumSegments] }; result.limbs[0] = 1; result } - unconstrained pub(crate) fn into_field_array(x: U60Repr) -> [Field; N * NumSegments / 2] { + pub(crate) unconstrained fn into_field_array( + x: U60Repr, + ) -> [Field; N * NumSegments / 2] { let mut result: [Field; N * NumSegments / 2] = [0; N * NumSegments / 2]; let two_pow_60: Field = 0x1000000000000000; for i in 0..(N * NumSegments / 2) { - result[i]= x.limbs[2 * i] as Field + (x.limbs[2 * i + 1] as Field * two_pow_60); + result[i] = x.limbs[2 * i] as Field + (x.limbs[2 * i + 1] as Field * two_pow_60); } result } - unconstrained pub(crate) fn gte(self, b: Self) -> bool { + pub(crate) unconstrained fn gte(self, b: Self) -> bool { let mut result = false; let mut early_exit = false; for i in 0..(N * NumSegments) { @@ -111,7 +113,9 @@ impl U60Repr { result = true; early_exit = true; break; - } else if (b.limbs[(N * NumSegments) - 1 - i] != self.limbs[((N * NumSegments) - 1 - i)]) { + } else if ( + b.limbs[(N * NumSegments) - 1 - i] != self.limbs[((N * NumSegments) - 1 - i)] + ) { result = false; early_exit = true; break; @@ -185,7 +189,6 @@ impl U60Repr { result.limbs[num_shifted_limbs] = (value << (limb_shift as u8)) & mask; // shift 84. num shifted = 1 - for i in 1..((N * NumSegments) - num_shifted_limbs) { let value = self.limbs[i]; let upshift = ((value << (limb_shift as u8)) + remainder) & mask; @@ -213,7 +216,7 @@ impl U60Repr { } } - unconstrained pub(crate) fn get_msb(val: Self) -> u32 { + pub(crate) unconstrained fn get_msb(val: Self) -> u32 { let mut count = 0; for i in 0..N * NumSegments { let v = val.limbs[((N * NumSegments) - 1 - i)]; diff --git a/src/utils/u60_representation_test.nr b/src/utils/u60_representation_test.nr index 431da4d4..da1a38ec 100644 --- a/src/utils/u60_representation_test.nr +++ b/src/utils/u60_representation_test.nr @@ -4,12 +4,8 @@ use crate::utils::u60_representation::U60Repr; unconstrained fn test_conversion() { let p = 0xffffffffffffffffffffffffffffff; // 2^120 - 1 let expected: [Field; 3 * 2] = [p, p - 1, p - 2, p - 3, p - 4, p - 5]; - let u60repr: U60Repr<3, 4> = unsafe { - U60Repr::new(expected) - }; - let result = unsafe { - u60repr.into_field_array() - }; + let u60repr: U60Repr<3, 4> = unsafe { U60Repr::new(expected) }; + let result = unsafe { u60repr.into_field_array() }; assert(result == expected); } @@ -23,14 +19,10 @@ fn test_shr() { // 120 bits of 01010101 (repeating) let Y = 0x555555555555555555555555555555; let input: [Field; 6] = [X, X, X, X, X, X]; - let u60repr: U60Repr<3, 6> = unsafe { - U60Repr::new(input) - }; + let u60repr: U60Repr<3, 6> = unsafe { U60Repr::new(input) }; let result = u60repr.shr(121); - let expected: U60Repr<3, 6> = unsafe { - U60Repr::new([Y, Y, Y, Y, Y, 0]) - }; + let expected: U60Repr<3, 6> = unsafe { U60Repr::new([Y, Y, Y, Y, Y, 0]) }; assert(result == expected); let noshift = u60repr.shr(0); @@ -44,14 +36,10 @@ fn test_shl() { // 120 bits of 01010101 (repeating) let Y = 0x555555555555555555555555555555; let input: [Field; 6] = [Y, Y, Y, Y, Y, Y]; - let u60repr: U60Repr<3, 6> = unsafe { - U60Repr::new(input) - }; + let u60repr: U60Repr<3, 6> = unsafe { U60Repr::new(input) }; let result = u60repr.shl(121); - let expected: U60Repr<3, 6> = unsafe { - U60Repr::new([0, X, X, X, X, X, X, 0, 0]) - }; + let expected: U60Repr<3, 6> = unsafe { U60Repr::new([0, X, X, X, X, X, X, 0, 0]) }; assert(result == expected); let noshift = u60repr.shr(0); @@ -63,9 +51,7 @@ fn test_get_bit() { // 0x8000 = b1000000000000000 (16th bit is high) // 256th bit of input should be high let input: [Field; 6] = [0, 0, 0x8000, 0, 0, 0]; - let u60repr: U60Repr<3, 6> = unsafe { - U60Repr::new(input) - }; + let u60repr: U60Repr<3, 6> = unsafe { U60Repr::new(input) }; for i in 0..720 { if i == 255 { assert(u60repr.get_bit(i) == true); @@ -79,36 +65,22 @@ fn test_get_bit() { unconstrained fn test_gte() { let p = 0xffffffffffffffffffffffffffffff; // 2^120 - 1 let input: [Field; 6] = [p, p - 1, p - 2, p - 3, p - 4, p - 5]; - let lhs: U60Repr<3, 6> = unsafe { - U60Repr::new(input) - }; + let lhs: U60Repr<3, 6> = unsafe { U60Repr::new(input) }; { let rhs = lhs; - assert( - unsafe { - lhs.gte(rhs) - } - ); + assert(unsafe { lhs.gte(rhs) }); } { // make rhs smaller by 1 let mut rhs: U60Repr<3, 6> = lhs; rhs.limbs[0] -= 1; - assert( - unsafe { - lhs.gte(rhs) - } - ); + assert(unsafe { lhs.gte(rhs) }); } { // make rhs greater by 1 let mut rhs = lhs; rhs.limbs[0] += 1; - assert( - !unsafe { - lhs.gte(rhs) - } - ); + assert(!unsafe { lhs.gte(rhs) }); } } From 54a2a345ede458c6443d8cd923f6046757964c7d Mon Sep 17 00:00:00 2001 From: sirasistant Date: Fri, 25 Oct 2024 10:49:03 +0000 Subject: [PATCH 28/29] use nargo 0.36 for ci --- .github/workflows/test.yml | 4 ++-- README.md | 4 +--- src/lib.nr | 4 ++++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 90122135..971fc98e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - toolchain: [nightly, 0.35.0] + toolchain: [nightly, 0.36.0] steps: - name: Checkout sources uses: actions/checkout@v4 @@ -38,7 +38,7 @@ jobs: - name: Install Nargo uses: noir-lang/noirup@v0.1.3 with: - toolchain: 0.35.0 + toolchain: 0.36.0 - name: Run formatter run: nargo fmt --check diff --git a/README.md b/README.md index 01d771d8..781e4631 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ TODO ## Dependencies -- Noir ≥v0.35.0 +- Noir ≥v0.36.0 - Barretenberg ≥v0.56.1 Refer to [Noir's docs](https://noir-lang.org/docs/getting_started/installation/) and [Barretenberg's docs](https://github.com/AztecProtocol/aztec-packages/blob/master/barretenberg/cpp/src/barretenberg/bb/readme.md#installation) for installation steps. @@ -144,14 +144,12 @@ User-facing structs: `RuntimeBigNum`: big numbers whose parameters are only known at runtime. (Note: the number of bits of the modulus of the bignum must be known at compile-time). - If creating custom bignum params: `BigNumParams` is needed, to declare your params. These parameters (`modulus`, `redc_param`) can be provided at runtime via witnesses (e.g. RSA verification). The `redc_param` is only used in unconstrained functions and does not need to be derived from `modulus` in-circuit. `BigNumParamsGetter` is a convenient wrapper around params, which is needed if declaring a new type of `BigNum`. - #### Methods ##### Arithmetics diff --git a/src/lib.nr b/src/lib.nr index 5edb314e..60b25d8d 100644 --- a/src/lib.nr +++ b/src/lib.nr @@ -14,5 +14,9 @@ pub mod params; pub(crate) mod fns; pub(crate) mod utils; +// Re-export the main structs so that users don't have to specify the paths +pub use bignum::BigNum; +pub use runtime_bignum::RuntimeBigNum; + // Tests mod tests; From 39ef97d671006506cd9fb8f28198d315b74edc7e Mon Sep 17 00:00:00 2001 From: kashbrti Date: Fri, 25 Oct 2024 11:54:06 +0100 Subject: [PATCH 29/29] Update test.yml --- .github/workflows/test.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 971fc98e..1691bfea 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,3 +42,27 @@ jobs: - name: Run formatter run: nargo fmt --check + + +# This is a job which depends on all test jobs and reports the overall status. + # This allows us to add/remove test jobs without having to update the required workflows. + tests-end: + name: Noir End + runs-on: ubuntu-latest + # We want this job to always run (even if the dependant jobs fail) as we want this job to fail rather than skipping. + if: ${{ always() }} + needs: + - test + - format + + steps: + - name: Report overall success + run: | + if [[ $FAIL == true ]]; then + exit 1 + else + exit 0 + fi + env: + # We treat any cancelled, skipped or failing jobs as a failure for the workflow as a whole. + FAIL: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}