From 1c21a8944cc34ce0bff9c1002d269342e750862b Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 19 Nov 2022 12:07:08 +0000 Subject: [PATCH] Migrate to `ff` revision with trait constants --- Cargo.toml | 2 +- src/arithmetic/fields.rs | 10 ++++----- src/curves.rs | 6 ++--- src/fields/fp.rs | 48 +++++++++++++++++++--------------------- src/fields/fq.rs | 48 +++++++++++++++++++--------------------- src/hashtocurve.rs | 2 +- 6 files changed, 56 insertions(+), 60 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 23f20ab..9cfc9da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,4 +74,4 @@ uninline-portable = [] serde = ["hex", "serde_crate"] [patch.crates-io] -ff = { git = "https://github.com/zkcrypto/ff.git", rev = "9a844a72d30ea9f859cd46dcc2237a1ae3277ddc" } +ff = { git = "https://github.com/zkcrypto/ff.git", rev = "c070ffbaea8cb17e57f817a91ed0e364ff679b7c" } diff --git a/src/arithmetic/fields.rs b/src/arithmetic/fields.rs index db16715..6d638c9 100644 --- a/src/arithmetic/fields.rs +++ b/src/arithmetic/fields.rs @@ -36,7 +36,7 @@ pub trait FieldExt: ff::PrimeField + From + Ord + Group { /// Modulus of the field written as a string for display purposes const MODULUS: &'static str; - /// Inverse of `PrimeField::root_of_unity()` + /// Inverse of `PrimeField::ROOT_OF_UNITY` const ROOT_OF_UNITY_INV: Self; /// Generator of the $t-order$ multiplicative subgroup @@ -107,10 +107,10 @@ impl SqrtTables { marker: PhantomData, }; - let mut gtab = (0..4).scan(F::root_of_unity(), |gi, _| { + let mut gtab = (0..4).scan(F::ROOT_OF_UNITY, |gi, _| { // gi == ROOT_OF_UNITY^(256^i) let gtab_i: Vec = (0..256) - .scan(F::one(), |acc, _| { + .scan(F::ONE, |acc, _| { let res = *acc; *acc *= *gi; Some(res) @@ -205,7 +205,7 @@ impl SqrtTables { let sqdiv = res.square() * div; let is_square = (sqdiv - num).is_zero(); - let is_nonsquare = (sqdiv - F::root_of_unity() * num).is_zero(); + let is_nonsquare = (sqdiv - F::ROOT_OF_UNITY * num).is_zero(); assert!(bool::from( num.is_zero() | div.is_zero() | (is_square ^ is_nonsquare) )); @@ -222,7 +222,7 @@ impl SqrtTables { let sq = res.square(); let is_square = (sq - u).is_zero(); - let is_nonsquare = (sq - F::root_of_unity() * u).is_zero(); + let is_nonsquare = (sq - F::ROOT_OF_UNITY * u).is_zero(); assert!(bool::from(u.is_zero() | (is_square ^ is_nonsquare))); (is_square, res) diff --git a/src/curves.rs b/src/curves.rs index 2fda775..52712f3 100644 --- a/src/curves.rs +++ b/src/curves.rs @@ -897,7 +897,7 @@ macro_rules! impl_projective_curve_ext { use super::hashtocurve; Box::new(move |message| { - let mut us = [Field::zero(); 2]; + let mut us = [Field::ZERO; 2]; hashtocurve::hash_to_field($name::CURVE_ID, domain_prefix, message, &mut us); let q0 = hashtocurve::map_to_curve_simple_swu::<$base, $name, $iso>( &us[0], @@ -1110,7 +1110,7 @@ impl Ep { 0x4000000000000000, ]); - /// `(F::root_of_unity().invert().unwrap() * z).sqrt().unwrap()` + /// `(F::ROOT_OF_UNITY.invert().unwrap() * z).sqrt().unwrap()` pub const THETA: Fp = Fp::from_raw([ 0xca330bcc09ac318e, 0x51f64fc4dc888857, @@ -1210,7 +1210,7 @@ impl Eq { 0x4000000000000000, ]); - /// `(F::root_of_unity().invert().unwrap() * z).sqrt().unwrap()` + /// `(F::ROOT_OF_UNITY.invert().unwrap() * z).sqrt().unwrap()` pub const THETA: Fq = Fq::from_raw([ 0x632cae9872df1b5d, 0x38578ccadf03ac27, diff --git a/src/fields/fp.rs b/src/fields/fp.rs index c315111..f781cff 100644 --- a/src/fields/fp.rs +++ b/src/fields/fp.rs @@ -1,7 +1,7 @@ use core::fmt; use core::ops::{Add, Mul, Neg, Sub}; -use ff::PrimeField; +use ff::{Field, PrimeField}; use rand::RngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -173,6 +173,18 @@ impl<'a, 'b> Mul<&'b Fp> for &'a Fp { impl_binops_additive!(Fp, Fp); impl_binops_multiplicative!(Fp, Fp); +impl> ::core::iter::Sum for Fp { + fn sum>(iter: I) -> Self { + iter.fold(Self::ZERO, |acc, item| acc + item.borrow()) + } +} + +impl> ::core::iter::Product for Fp { + fn product>(iter: I) -> Self { + iter.fold(Self::ONE, |acc, item| acc * item.borrow()) + } +} + /// INV = -(p^{-1} mod 2^64) mod 2^64 const INV: u64 = 0x992d30ecffffffff; @@ -481,6 +493,9 @@ impl Group for Fp { } impl ff::Field for Fp { + const ZERO: Self = Self::zero(); + const ONE: Self = Self::one(); + fn random(mut rng: impl RngCore) -> Self { Self::from_u512([ rng.next_u64(), @@ -494,14 +509,6 @@ impl ff::Field for Fp { ]) } - fn zero() -> Self { - Self::zero() - } - - fn one() -> Self { - Self::one() - } - fn double(&self) -> Self { self.double() } @@ -575,7 +582,9 @@ impl ff::PrimeField for Fp { const NUM_BITS: u32 = 255; const CAPACITY: u32 = 254; + const MULTIPLICATIVE_GENERATOR: Self = GENERATOR; const S: u32 = S; + const ROOT_OF_UNITY: Self = ROOT_OF_UNITY; fn from_repr(repr: Self::Repr) -> CtOption { let mut tmp = Fp([0, 0, 0, 0]); @@ -620,14 +629,6 @@ impl ff::PrimeField for Fp { fn is_odd(&self) -> Choice { Choice::from(self.to_repr()[0] & 1) } - - fn multiplicative_generator() -> Self { - GENERATOR - } - - fn root_of_unity() -> Self { - ROOT_OF_UNITY - } } #[cfg(all(feature = "bits", not(target_pointer_width = "64")))] @@ -796,9 +797,6 @@ impl ec_gpu::GpuField for Fp { } } -#[cfg(test)] -use ff::Field; - #[test] fn test_inv() { // Compute -(r^{-1} mod 2^64) mod 2^64 by exponentiating @@ -844,8 +842,8 @@ fn test_sqrt_ratio_and_alt() { assert!(v_alt == v); // (false, sqrt(ROOT_OF_UNITY * num/div)), if num and div are nonzero and num/div is a nonsquare in the field - let num = num * Fp::root_of_unity(); - let expected = Fp::TWO_INV * Fp::root_of_unity() * Fp::from(5).invert().unwrap(); + let num = num * Fp::ROOT_OF_UNITY; + let expected = Fp::TWO_INV * Fp::ROOT_OF_UNITY * Fp::from(5).invert().unwrap(); let (is_square, v) = Fp::sqrt_ratio(&num, &div); assert!(!bool::from(is_square)); assert!(v == expected || (-v) == expected); @@ -892,14 +890,14 @@ fn test_zeta() { #[test] fn test_root_of_unity() { assert_eq!( - Fp::root_of_unity().pow_vartime(&[1 << Fp::S, 0, 0, 0]), + Fp::ROOT_OF_UNITY.pow_vartime(&[1 << Fp::S, 0, 0, 0]), Fp::one() ); } #[test] fn test_inv_root_of_unity() { - assert_eq!(Fp::ROOT_OF_UNITY_INV, Fp::root_of_unity().invert().unwrap()); + assert_eq!(Fp::ROOT_OF_UNITY_INV, Fp::ROOT_OF_UNITY.invert().unwrap()); } #[test] @@ -912,7 +910,7 @@ fn test_delta() { assert_eq!(Fp::DELTA, GENERATOR.pow(&[1u64 << Fp::S, 0, 0, 0])); assert_eq!( Fp::DELTA, - Fp::multiplicative_generator().pow(&[1u64 << Fp::S, 0, 0, 0]) + Fp::MULTIPLICATIVE_GENERATOR.pow(&[1u64 << Fp::S, 0, 0, 0]) ); } diff --git a/src/fields/fq.rs b/src/fields/fq.rs index 3d3d8c7..2046530 100644 --- a/src/fields/fq.rs +++ b/src/fields/fq.rs @@ -1,7 +1,7 @@ use core::fmt; use core::ops::{Add, Mul, Neg, Sub}; -use ff::PrimeField; +use ff::{Field, PrimeField}; use rand::RngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -173,6 +173,18 @@ impl<'a, 'b> Mul<&'b Fq> for &'a Fq { impl_binops_additive!(Fq, Fq); impl_binops_multiplicative!(Fq, Fq); +impl> ::core::iter::Sum for Fq { + fn sum>(iter: I) -> Self { + iter.fold(Self::ZERO, |acc, item| acc + item.borrow()) + } +} + +impl> ::core::iter::Product for Fq { + fn product>(iter: I) -> Self { + iter.fold(Self::ONE, |acc, item| acc * item.borrow()) + } +} + /// INV = -(q^{-1} mod 2^64) mod 2^64 const INV: u64 = 0x8c46eb20ffffffff; @@ -481,6 +493,9 @@ impl Group for Fq { } impl ff::Field for Fq { + const ZERO: Self = Self::zero(); + const ONE: Self = Self::one(); + fn random(mut rng: impl RngCore) -> Self { Self::from_u512([ rng.next_u64(), @@ -494,14 +509,6 @@ impl ff::Field for Fq { ]) } - fn zero() -> Self { - Self::zero() - } - - fn one() -> Self { - Self::one() - } - fn double(&self) -> Self { self.double() } @@ -575,7 +582,9 @@ impl ff::PrimeField for Fq { const NUM_BITS: u32 = 255; const CAPACITY: u32 = 254; + const MULTIPLICATIVE_GENERATOR: Self = GENERATOR; const S: u32 = S; + const ROOT_OF_UNITY: Self = ROOT_OF_UNITY; fn from_repr(repr: Self::Repr) -> CtOption { let mut tmp = Fq([0, 0, 0, 0]); @@ -620,14 +629,6 @@ impl ff::PrimeField for Fq { fn is_odd(&self) -> Choice { Choice::from(self.to_repr()[0] & 1) } - - fn multiplicative_generator() -> Self { - GENERATOR - } - - fn root_of_unity() -> Self { - ROOT_OF_UNITY - } } #[cfg(all(feature = "bits", not(target_pointer_width = "64")))] @@ -795,9 +796,6 @@ impl ec_gpu::GpuField for Fq { } } -#[cfg(test)] -use ff::Field; - #[test] fn test_inv() { // Compute -(r^{-1} mod 2^64) mod 2^64 by exponentiating @@ -843,8 +841,8 @@ fn test_sqrt_ratio_and_alt() { assert!(v_alt == v); // (false, sqrt(ROOT_OF_UNITY * num/div)), if num and div are nonzero and num/div is a nonsquare in the field - let num = num * Fq::root_of_unity(); - let expected = Fq::TWO_INV * Fq::root_of_unity() * Fq::from(5).invert().unwrap(); + let num = num * Fq::ROOT_OF_UNITY; + let expected = Fq::TWO_INV * Fq::ROOT_OF_UNITY * Fq::from(5).invert().unwrap(); let (is_square, v) = Fq::sqrt_ratio(&num, &div); assert!(!bool::from(is_square)); assert!(v == expected || (-v) == expected); @@ -890,14 +888,14 @@ fn test_zeta() { #[test] fn test_root_of_unity() { assert_eq!( - Fq::root_of_unity().pow_vartime(&[1 << Fq::S, 0, 0, 0]), + Fq::ROOT_OF_UNITY.pow_vartime(&[1 << Fq::S, 0, 0, 0]), Fq::one() ); } #[test] fn test_inv_root_of_unity() { - assert_eq!(Fq::ROOT_OF_UNITY_INV, Fq::root_of_unity().invert().unwrap()); + assert_eq!(Fq::ROOT_OF_UNITY_INV, Fq::ROOT_OF_UNITY.invert().unwrap()); } #[test] @@ -910,7 +908,7 @@ fn test_delta() { assert_eq!(Fq::DELTA, GENERATOR.pow(&[1u64 << Fq::S, 0, 0, 0])); assert_eq!( Fq::DELTA, - Fq::multiplicative_generator().pow(&[1u64 << Fq::S, 0, 0, 0]) + Fq::MULTIPLICATIVE_GENERATOR.pow(&[1u64 << Fq::S, 0, 0, 0]) ); } diff --git a/src/hashtocurve.rs b/src/hashtocurve.rs index 3661265..c5b9a45 100644 --- a/src/hashtocurve.rs +++ b/src/hashtocurve.rs @@ -136,7 +136,7 @@ pub fn map_to_curve_simple_swu, I: CurveExt