Migrate to ff revision with trait constants

This commit is contained in:
Jack Grigg 2022-11-19 12:07:08 +00:00
parent 6921efd8fd
commit 1c21a8944c
6 changed files with 56 additions and 60 deletions

View file

@ -74,4 +74,4 @@ uninline-portable = []
serde = ["hex", "serde_crate"] serde = ["hex", "serde_crate"]
[patch.crates-io] [patch.crates-io]
ff = { git = "https://github.com/zkcrypto/ff.git", rev = "9a844a72d30ea9f859cd46dcc2237a1ae3277ddc" } ff = { git = "https://github.com/zkcrypto/ff.git", rev = "c070ffbaea8cb17e57f817a91ed0e364ff679b7c" }

View file

@ -36,7 +36,7 @@ pub trait FieldExt: ff::PrimeField + From<bool> + Ord + Group<Scalar = Self> {
/// Modulus of the field written as a string for display purposes /// Modulus of the field written as a string for display purposes
const MODULUS: &'static str; const MODULUS: &'static str;
/// Inverse of `PrimeField::root_of_unity()` /// Inverse of `PrimeField::ROOT_OF_UNITY`
const ROOT_OF_UNITY_INV: Self; const ROOT_OF_UNITY_INV: Self;
/// Generator of the $t-order$ multiplicative subgroup /// Generator of the $t-order$ multiplicative subgroup
@ -107,10 +107,10 @@ impl<F: FieldExt + SqrtTableHelpers> SqrtTables<F> {
marker: PhantomData, 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) // gi == ROOT_OF_UNITY^(256^i)
let gtab_i: Vec<F> = (0..256) let gtab_i: Vec<F> = (0..256)
.scan(F::one(), |acc, _| { .scan(F::ONE, |acc, _| {
let res = *acc; let res = *acc;
*acc *= *gi; *acc *= *gi;
Some(res) Some(res)
@ -205,7 +205,7 @@ impl<F: FieldExt + SqrtTableHelpers> SqrtTables<F> {
let sqdiv = res.square() * div; let sqdiv = res.square() * div;
let is_square = (sqdiv - num).is_zero(); 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( assert!(bool::from(
num.is_zero() | div.is_zero() | (is_square ^ is_nonsquare) num.is_zero() | div.is_zero() | (is_square ^ is_nonsquare)
)); ));
@ -222,7 +222,7 @@ impl<F: FieldExt + SqrtTableHelpers> SqrtTables<F> {
let sq = res.square(); let sq = res.square();
let is_square = (sq - u).is_zero(); 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))); assert!(bool::from(u.is_zero() | (is_square ^ is_nonsquare)));
(is_square, res) (is_square, res)

View file

@ -897,7 +897,7 @@ macro_rules! impl_projective_curve_ext {
use super::hashtocurve; use super::hashtocurve;
Box::new(move |message| { 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); hashtocurve::hash_to_field($name::CURVE_ID, domain_prefix, message, &mut us);
let q0 = hashtocurve::map_to_curve_simple_swu::<$base, $name, $iso>( let q0 = hashtocurve::map_to_curve_simple_swu::<$base, $name, $iso>(
&us[0], &us[0],
@ -1110,7 +1110,7 @@ impl Ep {
0x4000000000000000, 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([ pub const THETA: Fp = Fp::from_raw([
0xca330bcc09ac318e, 0xca330bcc09ac318e,
0x51f64fc4dc888857, 0x51f64fc4dc888857,
@ -1210,7 +1210,7 @@ impl Eq {
0x4000000000000000, 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([ pub const THETA: Fq = Fq::from_raw([
0x632cae9872df1b5d, 0x632cae9872df1b5d,
0x38578ccadf03ac27, 0x38578ccadf03ac27,

View file

@ -1,7 +1,7 @@
use core::fmt; use core::fmt;
use core::ops::{Add, Mul, Neg, Sub}; use core::ops::{Add, Mul, Neg, Sub};
use ff::PrimeField; use ff::{Field, PrimeField};
use rand::RngCore; use rand::RngCore;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; 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_additive!(Fp, Fp);
impl_binops_multiplicative!(Fp, Fp); impl_binops_multiplicative!(Fp, Fp);
impl<T: ::core::borrow::Borrow<Fp>> ::core::iter::Sum<T> for Fp {
fn sum<I: Iterator<Item = T>>(iter: I) -> Self {
iter.fold(Self::ZERO, |acc, item| acc + item.borrow())
}
}
impl<T: ::core::borrow::Borrow<Fp>> ::core::iter::Product<T> for Fp {
fn product<I: Iterator<Item = T>>(iter: I) -> Self {
iter.fold(Self::ONE, |acc, item| acc * item.borrow())
}
}
/// INV = -(p^{-1} mod 2^64) mod 2^64 /// INV = -(p^{-1} mod 2^64) mod 2^64
const INV: u64 = 0x992d30ecffffffff; const INV: u64 = 0x992d30ecffffffff;
@ -481,6 +493,9 @@ impl Group for Fp {
} }
impl ff::Field for Fp { impl ff::Field for Fp {
const ZERO: Self = Self::zero();
const ONE: Self = Self::one();
fn random(mut rng: impl RngCore) -> Self { fn random(mut rng: impl RngCore) -> Self {
Self::from_u512([ Self::from_u512([
rng.next_u64(), 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 { fn double(&self) -> Self {
self.double() self.double()
} }
@ -575,7 +582,9 @@ impl ff::PrimeField for Fp {
const NUM_BITS: u32 = 255; const NUM_BITS: u32 = 255;
const CAPACITY: u32 = 254; const CAPACITY: u32 = 254;
const MULTIPLICATIVE_GENERATOR: Self = GENERATOR;
const S: u32 = S; const S: u32 = S;
const ROOT_OF_UNITY: Self = ROOT_OF_UNITY;
fn from_repr(repr: Self::Repr) -> CtOption<Self> { fn from_repr(repr: Self::Repr) -> CtOption<Self> {
let mut tmp = Fp([0, 0, 0, 0]); let mut tmp = Fp([0, 0, 0, 0]);
@ -620,14 +629,6 @@ impl ff::PrimeField for Fp {
fn is_odd(&self) -> Choice { fn is_odd(&self) -> Choice {
Choice::from(self.to_repr()[0] & 1) 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")))] #[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] #[test]
fn test_inv() { fn test_inv() {
// Compute -(r^{-1} mod 2^64) mod 2^64 by exponentiating // 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); 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 // (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 num = num * Fp::ROOT_OF_UNITY;
let expected = Fp::TWO_INV * Fp::root_of_unity() * Fp::from(5).invert().unwrap(); let expected = Fp::TWO_INV * Fp::ROOT_OF_UNITY * Fp::from(5).invert().unwrap();
let (is_square, v) = Fp::sqrt_ratio(&num, &div); let (is_square, v) = Fp::sqrt_ratio(&num, &div);
assert!(!bool::from(is_square)); assert!(!bool::from(is_square));
assert!(v == expected || (-v) == expected); assert!(v == expected || (-v) == expected);
@ -892,14 +890,14 @@ fn test_zeta() {
#[test] #[test]
fn test_root_of_unity() { fn test_root_of_unity() {
assert_eq!( 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() Fp::one()
); );
} }
#[test] #[test]
fn test_inv_root_of_unity() { 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] #[test]
@ -912,7 +910,7 @@ fn test_delta() {
assert_eq!(Fp::DELTA, GENERATOR.pow(&[1u64 << Fp::S, 0, 0, 0])); assert_eq!(Fp::DELTA, GENERATOR.pow(&[1u64 << Fp::S, 0, 0, 0]));
assert_eq!( assert_eq!(
Fp::DELTA, Fp::DELTA,
Fp::multiplicative_generator().pow(&[1u64 << Fp::S, 0, 0, 0]) Fp::MULTIPLICATIVE_GENERATOR.pow(&[1u64 << Fp::S, 0, 0, 0])
); );
} }

View file

@ -1,7 +1,7 @@
use core::fmt; use core::fmt;
use core::ops::{Add, Mul, Neg, Sub}; use core::ops::{Add, Mul, Neg, Sub};
use ff::PrimeField; use ff::{Field, PrimeField};
use rand::RngCore; use rand::RngCore;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; 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_additive!(Fq, Fq);
impl_binops_multiplicative!(Fq, Fq); impl_binops_multiplicative!(Fq, Fq);
impl<T: ::core::borrow::Borrow<Fq>> ::core::iter::Sum<T> for Fq {
fn sum<I: Iterator<Item = T>>(iter: I) -> Self {
iter.fold(Self::ZERO, |acc, item| acc + item.borrow())
}
}
impl<T: ::core::borrow::Borrow<Fq>> ::core::iter::Product<T> for Fq {
fn product<I: Iterator<Item = T>>(iter: I) -> Self {
iter.fold(Self::ONE, |acc, item| acc * item.borrow())
}
}
/// INV = -(q^{-1} mod 2^64) mod 2^64 /// INV = -(q^{-1} mod 2^64) mod 2^64
const INV: u64 = 0x8c46eb20ffffffff; const INV: u64 = 0x8c46eb20ffffffff;
@ -481,6 +493,9 @@ impl Group for Fq {
} }
impl ff::Field for Fq { impl ff::Field for Fq {
const ZERO: Self = Self::zero();
const ONE: Self = Self::one();
fn random(mut rng: impl RngCore) -> Self { fn random(mut rng: impl RngCore) -> Self {
Self::from_u512([ Self::from_u512([
rng.next_u64(), 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 { fn double(&self) -> Self {
self.double() self.double()
} }
@ -575,7 +582,9 @@ impl ff::PrimeField for Fq {
const NUM_BITS: u32 = 255; const NUM_BITS: u32 = 255;
const CAPACITY: u32 = 254; const CAPACITY: u32 = 254;
const MULTIPLICATIVE_GENERATOR: Self = GENERATOR;
const S: u32 = S; const S: u32 = S;
const ROOT_OF_UNITY: Self = ROOT_OF_UNITY;
fn from_repr(repr: Self::Repr) -> CtOption<Self> { fn from_repr(repr: Self::Repr) -> CtOption<Self> {
let mut tmp = Fq([0, 0, 0, 0]); let mut tmp = Fq([0, 0, 0, 0]);
@ -620,14 +629,6 @@ impl ff::PrimeField for Fq {
fn is_odd(&self) -> Choice { fn is_odd(&self) -> Choice {
Choice::from(self.to_repr()[0] & 1) 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")))] #[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] #[test]
fn test_inv() { fn test_inv() {
// Compute -(r^{-1} mod 2^64) mod 2^64 by exponentiating // 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); 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 // (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 num = num * Fq::ROOT_OF_UNITY;
let expected = Fq::TWO_INV * Fq::root_of_unity() * Fq::from(5).invert().unwrap(); let expected = Fq::TWO_INV * Fq::ROOT_OF_UNITY * Fq::from(5).invert().unwrap();
let (is_square, v) = Fq::sqrt_ratio(&num, &div); let (is_square, v) = Fq::sqrt_ratio(&num, &div);
assert!(!bool::from(is_square)); assert!(!bool::from(is_square));
assert!(v == expected || (-v) == expected); assert!(v == expected || (-v) == expected);
@ -890,14 +888,14 @@ fn test_zeta() {
#[test] #[test]
fn test_root_of_unity() { fn test_root_of_unity() {
assert_eq!( 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() Fq::one()
); );
} }
#[test] #[test]
fn test_inv_root_of_unity() { 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] #[test]
@ -910,7 +908,7 @@ fn test_delta() {
assert_eq!(Fq::DELTA, GENERATOR.pow(&[1u64 << Fq::S, 0, 0, 0])); assert_eq!(Fq::DELTA, GENERATOR.pow(&[1u64 << Fq::S, 0, 0, 0]));
assert_eq!( assert_eq!(
Fq::DELTA, Fq::DELTA,
Fq::multiplicative_generator().pow(&[1u64 << Fq::S, 0, 0, 0]) Fq::MULTIPLICATIVE_GENERATOR.pow(&[1u64 << Fq::S, 0, 0, 0])
); );
} }

View file

@ -136,7 +136,7 @@ pub fn map_to_curve_simple_swu<F: FieldExt, C: CurveExt<Base = F>, I: CurveExt<B
let b = I::b(); let b = I::b();
let z_u2 = z * u.square(); let z_u2 = z * u.square();
let ta = z_u2.square() + z_u2; let ta = z_u2.square() + z_u2;
let num_x1 = b * (ta + F::one()); let num_x1 = b * (ta + F::ONE);
let div = a * F::conditional_select(&-ta, &z, ta.is_zero()); let div = a * F::conditional_select(&-ta, &z, ta.is_zero());
let num2_x1 = num_x1.square(); let num2_x1 = num_x1.square();
let div2 = div.square(); let div2 = div.square();