diff --git a/curves/src/bls12_377/fr.rs b/curves/src/bls12_377/fr.rs index 15ac8188f2..a2f2fd0c11 100644 --- a/curves/src/bls12_377/fr.rs +++ b/curves/src/bls12_377/fr.rs @@ -28,7 +28,6 @@ use snarkvm_utilities::biginteger::BigInteger256 as BigInteger; /// o = q - 1 /// F = GF(q) /// g = F.multiplicative_generator() -/// g = F.multiplicative_generator() /// assert g.multiplicative_order() == o /// g2 = g ** (o/2**s) /// assert g2.multiplicative_order() == 2**s @@ -49,12 +48,21 @@ impl FftParameters for FrParameters { #[rustfmt::skip] const TWO_ADICITY: u32 = 47; + /// TODO (howardwu): CRITICAL - Fix this after a migration plan has been determined. + /// - 0x3c3d3ca739381fb2, + /// - 0x9a14cda3ec99772b, + /// - 0xd7aacc7c59724826, + /// - 0xd1ba211c5cc349c, + /// + 12646347781564978760u64, + /// + 6783048705277173164u64, + /// + 268534165941069093u64, + /// + 1121515446318641358u64, #[rustfmt::skip] const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([ - 12646347781564978760u64, - 6783048705277173164u64, - 268534165941069093u64, - 1121515446318641358u64, + 0x3c3d3ca739381fb2, + 0x9a14cda3ec99772b, + 0xd7aacc7c59724826, + 0xd1ba211c5cc349c, ]); } @@ -65,7 +73,6 @@ impl FieldParameters for FrParameters { /// Encoded in Montgomery form, so the value is /// (22 * R) % q = 5642976643016801619665363617888466827793962762719196659561577942948671127251 #[rustfmt::skip] - #[rustfmt::skip] const GENERATOR: BigInteger = BigInteger([ 2984901390528151251u64, 10561528701063790279u64, diff --git a/curves/src/bls12_377/tests.rs b/curves/src/bls12_377/tests.rs index 81e8d56aab..ebb7bc696b 100644 --- a/curves/src/bls12_377/tests.rs +++ b/curves/src/bls12_377/tests.rs @@ -397,9 +397,12 @@ fn test_fq_root_of_unity() { 0xe9185f1443ab18ec, 0x6b8 ]), - Fq::root_of_unity() + Fq::two_adic_root_of_unity() + ); + assert_eq!( + Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]), + Fq::one() ); - assert_eq!(Fq::root_of_unity().pow([1 << FqParameters::TWO_ADICITY]), Fq::one()); assert!(Fq::multiplicative_generator().sqrt().is_none()); } diff --git a/curves/src/edwards_bls12/fr.rs b/curves/src/edwards_bls12/fr.rs index 7aca1523d4..d881608ce0 100644 --- a/curves/src/edwards_bls12/fr.rs +++ b/curves/src/edwards_bls12/fr.rs @@ -83,7 +83,17 @@ impl FieldParameters for FrParameters { #[rustfmt::skip] const REPR_SHAVE_BITS: u32 = 5; #[rustfmt::skip] - const T: BigInteger = BigInteger([0x0, 0x0, 0x0, 0x0]); + const T: BigInteger = BigInteger([ + 6678124996694371583, + 2975139753996731775, + 14706092969812227584, + 168160046336021674 + ]); #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([0x0, 0x0, 0x0, 0x0]); + const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([ + 12562434535201961599, + 1487569876998365887, + 7353046484906113792, + 84080023168010837 + ]); } diff --git a/curves/src/edwards_sw6/fr.rs b/curves/src/edwards_sw6/fr.rs index 3638245e32..0d429093b0 100644 --- a/curves/src/edwards_sw6/fr.rs +++ b/curves/src/edwards_sw6/fr.rs @@ -95,7 +95,21 @@ impl FieldParameters for FrParameters { #[rustfmt::skip] const REPR_SHAVE_BITS: u32 = 10; #[rustfmt::skip] - const T: BigInteger = BigInteger([0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); + const T: BigInteger = BigInteger([ + 5782852926996632741, + 10160572951715783904, + 8680081325396045328, + 15623293663189641372, + 6210983053257673289, + 3784322272077959 + ]); #[rustfmt::skip] - const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); + const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([ + 2891426463498316370, + 5080286475857891952, + 4340040662698022664, + 17035018868449596494, + 12328863563483612452, + 1892161136038979 + ]); } diff --git a/fields/src/fp3.rs b/fields/src/fp3.rs index 91745eae1d..6ae530e218 100644 --- a/fields/src/fp3.rs +++ b/fields/src/fp3.rs @@ -102,7 +102,7 @@ impl Fp3

{ // Returns the value of QNR^T. #[inline] - pub fn qnr_to_t() -> Self { + pub fn two_adic_root_of_unity() -> Self { Self::new( P::QUADRATIC_NONRESIDUE_TO_T.0, P::QUADRATIC_NONRESIDUE_TO_T.1, diff --git a/fields/src/fp_256.rs b/fields/src/fp_256.rs index bea140568d..e06bd33e4a 100644 --- a/fields/src/fp_256.rs +++ b/fields/src/fp_256.rs @@ -329,11 +329,6 @@ impl PrimeField for Fp256

{ let r = *self; r.0 } - - #[inline] - fn root_of_unity() -> Self { - Fp256::

(P::TWO_ADIC_ROOT_OF_UNITY, PhantomData) - } } impl FftField for Fp256

{ diff --git a/fields/src/fp_320.rs b/fields/src/fp_320.rs index 8ee8a29930..635fa1321f 100644 --- a/fields/src/fp_320.rs +++ b/fields/src/fp_320.rs @@ -365,11 +365,6 @@ impl PrimeField for Fp320

{ let r = *self; r.0 } - - #[inline] - fn root_of_unity() -> Self { - Fp320::

(P::TWO_ADIC_ROOT_OF_UNITY, PhantomData) - } } impl FftField for Fp320

{ diff --git a/fields/src/fp_384.rs b/fields/src/fp_384.rs index bb2b2f870b..143f9017af 100644 --- a/fields/src/fp_384.rs +++ b/fields/src/fp_384.rs @@ -395,11 +395,6 @@ impl PrimeField for Fp384

{ fn into_repr_raw(&self) -> BigInteger { self.0 } - - #[inline] - fn root_of_unity() -> Self { - Fp384::

(P::TWO_ADIC_ROOT_OF_UNITY, PhantomData) - } } impl FftField for Fp384

{ diff --git a/fields/src/fp_768.rs b/fields/src/fp_768.rs index 27fbd51b25..cd054a088d 100644 --- a/fields/src/fp_768.rs +++ b/fields/src/fp_768.rs @@ -709,11 +709,6 @@ impl PrimeField for Fp768

{ r.0 } - #[inline] - fn root_of_unity() -> Self { - Fp768::

(P::TWO_ADIC_ROOT_OF_UNITY, PhantomData) - } - #[inline] fn size_in_bits() -> usize { P::MODULUS_BITS as usize diff --git a/fields/src/fp_832.rs b/fields/src/fp_832.rs index 858d9ef917..c5a31e1851 100644 --- a/fields/src/fp_832.rs +++ b/fields/src/fp_832.rs @@ -678,11 +678,6 @@ impl PrimeField for Fp832

{ r.0 } - #[inline] - fn root_of_unity() -> Self { - Fp832::

(P::TWO_ADIC_ROOT_OF_UNITY, PhantomData) - } - #[inline] fn size_in_bits() -> usize { P::MODULUS_BITS as usize diff --git a/fields/src/macros.rs b/fields/src/macros.rs index bc8045cba9..47456dc747 100644 --- a/fields/src/macros.rs +++ b/fields/src/macros.rs @@ -108,7 +108,7 @@ macro_rules! sqrt_impl { Zero => Some(*$self), QuadraticNonResidue => None, QuadraticResidue => { - let mut z = $Self::qnr_to_t(); + let mut z = $Self::two_adic_root_of_unity(); let mut w = $self.pow($P::T_MINUS_ONE_DIV_TWO); let mut x = w * $self; let mut b = x * w; diff --git a/fields/src/tests_field.rs b/fields/src/tests_field.rs index a37f39280b..a4ed8e9de5 100644 --- a/fields/src/tests_field.rs +++ b/fields/src/tests_field.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with the snarkVM library. If not, see . -use crate::{Field, LegendreSymbol, PrimeField, SquareRootField}; +use crate::{traits::FftParameters, FftField, Field, LegendreSymbol, PrimeField, SquareRootField}; use snarkvm_utilities::{ io::Cursor, serialize::{CanonicalDeserialize, CanonicalSerialize, Flags, SWFlags}, @@ -334,10 +334,46 @@ pub fn field_test(a: F, b: F) { random_field_tests::(); } +pub fn fft_field_test() { + let modulus_minus_one_div_two = F::from_repr(F::modulus_minus_one_div_two()).unwrap(); + assert!(!modulus_minus_one_div_two.is_zero()); + + // modulus - 1 == 2^s * t + // => t == (modulus - 1) / 2^s + // => t == [(modulus - 1) / 2] * [1 / 2^(s-1)] + let two_adicity = F::FftParameters::TWO_ADICITY; + assert!(two_adicity > 0); + let two_s_minus_one = F::from(2_u32).pow(&[(two_adicity - 1) as u64]); + let trace = modulus_minus_one_div_two * two_s_minus_one.inverse().unwrap(); + assert_eq!(trace, F::from_repr(F::trace()).unwrap()); + + // (trace - 1) / 2 == trace_minus_one_div_two + let trace_minus_one_div_two = F::from_repr(F::trace_minus_one_div_two()).unwrap(); + assert!(!trace_minus_one_div_two.is_zero()); + assert_eq!((trace - F::one()) / F::one().double(), trace_minus_one_div_two); + + // multiplicative_generator^trace == root of unity + let generator = F::multiplicative_generator(); + assert!(!generator.is_zero()); + let two_adic_root_of_unity = F::two_adic_root_of_unity(); + assert!(!two_adic_root_of_unity.is_zero()); + assert_eq!(two_adic_root_of_unity.pow([1 << two_adicity]), F::one()); + // TODO (howardwu): CRITICAL - Reenable this after BLS12-377 Fr root_of_unity has been fixed. + // assert_eq!(generator.pow(trace.into_repr().as_ref()), two_adic_root_of_unity); +} + pub fn primefield_test() { let one = F::one(); assert_eq!(F::from_repr(one.into_repr()).unwrap(), one); assert_eq!(F::from_str("1").ok().unwrap(), one); + assert_eq!(F::from_str(&one.to_string()).ok().unwrap(), one); + + let two = F::one().double(); + assert_eq!(F::from_repr(two.into_repr()).unwrap(), two); + assert_eq!(F::from_str("2").ok().unwrap(), two); + assert_eq!(F::from_str(&two.to_string()).ok().unwrap(), two); + + fft_field_test::(); } pub fn sqrt_field_test(elem: F) { diff --git a/fields/src/traits/prime_field.rs b/fields/src/traits/prime_field.rs index afb2f918cd..c174de9ac4 100644 --- a/fields/src/traits/prime_field.rs +++ b/fields/src/traits/prime_field.rs @@ -37,14 +37,6 @@ pub trait PrimeField: FftField::Parameters> /// Returns the underlying raw representation of the prime field element. fn into_repr_raw(&self) -> Self::BigInteger; - /// Returns the 2^s root of unity. - fn root_of_unity() -> Self; - - /// Return the a QNR^T - fn qnr_to_t() -> Self { - Self::root_of_unity() - } - /// Returns the field size in bits. fn size_in_bits() -> usize { Self::Parameters::MODULUS_BITS as usize @@ -52,20 +44,12 @@ pub trait PrimeField: FftField::Parameters> /// Returns the trace. fn trace() -> Self::BigInteger { - // TODO (howardwu): This function has been disabled as - // `snarkvm_curves::edwards_bls12::Fr` and `snarkvm_curves::edwards_sw6::Fr` - // do NOT implement `FieldParameters::T` or `FieldParameters::T_MINUS_ONE_DIV_TWO`. - unimplemented!() - // Self::Parameters::T + Self::Parameters::T } /// Returns the trace minus one divided by two. fn trace_minus_one_div_two() -> Self::BigInteger { - // TODO (howardwu): This function has been disabled as - // `snarkvm_curves::edwards_bls12::Fr` and `snarkvm_curves::edwards_sw6::Fr` - // do NOT implement `FieldParameters::T` or `FieldParameters::T_MINUS_ONE_DIV_TWO`. - unimplemented!() - // Self::Parameters::T_MINUS_ONE_DIV_TWO + Self::Parameters::T_MINUS_ONE_DIV_TWO } /// Returns the modulus minus one divided by two. diff --git a/posw/tests/mod.rs b/posw/tests/mod.rs index aba90dc6ec..c4ff98aa0e 100644 --- a/posw/tests/mod.rs +++ b/posw/tests/mod.rs @@ -20,6 +20,8 @@ use snarkvm_dpc::block::PedersenMerkleRootHash; use snarkvm_posw::{txids_to_roots, Marlin, PoswMarlin}; use snarkvm_utilities::bytes::FromBytes; +use rand::SeedableRng; + #[test] fn test_posw_load_and_mine() { // Load the PoSW Marlin parameters. @@ -75,3 +77,228 @@ fn test_posw_verify_testnet1() { let posw = PoswMarlin::load().unwrap(); assert!(posw.verify(nonce, &proof, &pedersen_merkle_root).is_ok()); } + +#[test] +fn test_posw_setup_vs_load_weak_sanity_check() { + let generated_posw = { + // Load the PoSW Marlin parameters. + let rng = &mut rand_xorshift::XorShiftRng::seed_from_u64(1234567); + // Run the universal setup. + let universal_srs = snarkvm_marlin::MarlinTestnet1::universal_setup(10000, 10000, 100000, rng).unwrap(); + // Run the circuit setup. + PoswMarlin::index(universal_srs).unwrap() + }; + let loaded_posw = PoswMarlin::load().unwrap(); + + let generated_proving_key = generated_posw.pk.unwrap().proving_key; + let loaded_proving_key = loaded_posw.pk.unwrap().proving_key; + + let a = generated_proving_key.committer_key.max_degree; + let b = loaded_proving_key.committer_key.max_degree; + assert_eq!(a, b); + + let a = generated_proving_key.circuit_commitment_randomness.len(); + let b = loaded_proving_key.circuit_commitment_randomness.len(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.max_degree(); + let b = loaded_proving_key.circuit.max_degree(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.index_info.num_variables; + let b = loaded_proving_key.circuit.index_info.num_variables; + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.index_info.num_constraints; + let b = loaded_proving_key.circuit.index_info.num_constraints; + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.index_info.num_non_zero; + let b = loaded_proving_key.circuit.index_info.num_non_zero; + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.index_info.max_degree(); + let b = loaded_proving_key.circuit.index_info.max_degree(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + macro_rules! check_term_sizes { + ($term: ident) => { + let a = generated_proving_key.circuit.$term.len(); + let b = loaded_proving_key.circuit.$term.len(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + // TODO (howardwu): CRITICAL - Confirm expected circuit behavior and reenable inner checks. + // for i in 0..generated_proving_key.circuit.$term.len() { + // let a = generated_proving_key.circuit.$term[i].len(); + // let b = loaded_proving_key.circuit.$term[i].len(); + // println!("{:?} == {:?}? {}", a, b, a == b); + // assert_eq!(a, b); + // } + }; + } + + check_term_sizes!(a); + check_term_sizes!(b); + check_term_sizes!(c); + + macro_rules! check_arithmetization_sizes { + ($term: ident) => { + let a = generated_proving_key.circuit.$term.row.degree_bound(); + let b = loaded_proving_key.circuit.$term.row.degree_bound(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.$term.row.hiding_bound(); + let b = loaded_proving_key.circuit.$term.row.hiding_bound(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.$term.row.polynomial().degree(); + let b = loaded_proving_key.circuit.$term.row.polynomial().degree(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.$term.col.degree_bound(); + let b = loaded_proving_key.circuit.$term.col.degree_bound(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.$term.col.hiding_bound(); + let b = loaded_proving_key.circuit.$term.col.hiding_bound(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.$term.col.polynomial().degree(); + let b = loaded_proving_key.circuit.$term.col.polynomial().degree(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.$term.val.degree_bound(); + let b = loaded_proving_key.circuit.$term.val.degree_bound(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.$term.val.hiding_bound(); + let b = loaded_proving_key.circuit.$term.val.hiding_bound(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.$term.val.polynomial().degree(); + let b = loaded_proving_key.circuit.$term.val.polynomial().degree(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.$term.row_col.degree_bound(); + let b = loaded_proving_key.circuit.$term.row_col.degree_bound(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.$term.row_col.hiding_bound(); + let b = loaded_proving_key.circuit.$term.row_col.hiding_bound(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key.circuit.$term.row_col.polynomial().degree(); + let b = loaded_proving_key.circuit.$term.row_col.polynomial().degree(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key + .circuit + .$term + .evals_on_K + .row + .evaluations + .len(); + let b = loaded_proving_key.circuit.$term.evals_on_K.row.evaluations.len(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key + .circuit + .$term + .evals_on_K + .col + .evaluations + .len(); + let b = loaded_proving_key.circuit.$term.evals_on_K.col.evaluations.len(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key + .circuit + .$term + .evals_on_K + .val + .evaluations + .len(); + let b = loaded_proving_key.circuit.$term.evals_on_K.val.evaluations.len(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key + .circuit + .$term + .evals_on_B + .row + .evaluations + .len(); + let b = loaded_proving_key.circuit.$term.evals_on_B.row.evaluations.len(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key + .circuit + .$term + .evals_on_B + .col + .evaluations + .len(); + let b = loaded_proving_key.circuit.$term.evals_on_B.col.evaluations.len(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key + .circuit + .$term + .evals_on_B + .val + .evaluations + .len(); + let b = loaded_proving_key.circuit.$term.evals_on_B.val.evaluations.len(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + + let a = generated_proving_key + .circuit + .$term + .row_col_evals_on_B + .evaluations + .len(); + let b = loaded_proving_key + .circuit + .$term + .row_col_evals_on_B + .evaluations + .len(); + println!("{:?} == {:?}? {}", a, b, a == b); + assert_eq!(a, b); + }; + } + + println!("------ Checking circuit A arithmetization sizes ------"); + check_arithmetization_sizes!(a_star_arith); + + println!("------ Checking circuit B arithmetization sizes ------"); + check_arithmetization_sizes!(b_star_arith); + + println!("------ Checking circuit C arithmetization sizes ------"); + check_arithmetization_sizes!(c_star_arith); +}