From fd79de5408997899f9d183f92f01baf49a9a406f Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 27 Mar 2020 23:19:58 +1300 Subject: [PATCH] ff: Add PrimeField: From constraint --- bellman/src/groth16/tests/dummy_engine.rs | 6 ++++++ ff/ff_derive/src/lib.rs | 9 +++++++++ ff/src/lib.rs | 6 +++--- pairing/src/bls12_381/fq.rs | 13 ++++--------- pairing/src/bls12_381/fq2.rs | 2 +- pairing/src/bls12_381/fr.rs | 7 ++----- pairing/src/bls12_381/tests/mod.rs | 18 +++++++++--------- pairing/src/tests/field.rs | 2 +- zcash_primitives/src/jubjub/fs.rs | 16 +++++++++++----- zcash_primitives/src/primitives.rs | 4 ++-- zcash_proofs/src/sapling/mod.rs | 4 ++-- 11 files changed, 50 insertions(+), 37 deletions(-) diff --git a/bellman/src/groth16/tests/dummy_engine.rs b/bellman/src/groth16/tests/dummy_engine.rs index 4693aaa1a..2ef9798c8 100644 --- a/bellman/src/groth16/tests/dummy_engine.rs +++ b/bellman/src/groth16/tests/dummy_engine.rs @@ -34,6 +34,12 @@ impl fmt::Display for Fr { } } +impl From for Fr { + fn from(v: u64) -> Fr { + Fr(Wrapping((v % MODULUS_R.0 as u64) as u32)) + } +} + impl ConditionallySelectable for Fr { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { Fr(Wrapping(u32::conditional_select( diff --git a/ff/ff_derive/src/lib.rs b/ff/ff_derive/src/lib.rs index 121c296dc..9a8a74462 100644 --- a/ff/ff_derive/src/lib.rs +++ b/ff/ff_derive/src/lib.rs @@ -853,6 +853,15 @@ fn prime_field_impl( } } + impl From for #name { + #[inline(always)] + fn from(val: u64) -> #name { + let mut raw = [0u64; #limbs]; + raw[0] = val; + #name(#repr(raw)) * #name(R2) + } + } + impl From<#name> for #repr { fn from(e: #name) -> #repr { e.into_repr() diff --git a/ff/src/lib.rs b/ff/src/lib.rs index e3cb8b474..8bb8ffabc 100644 --- a/ff/src/lib.rs +++ b/ff/src/lib.rs @@ -256,7 +256,7 @@ impl fmt::Display for PrimeFieldDecodingError { } /// This represents an element of a prime field. -pub trait PrimeField: Field { +pub trait PrimeField: Field + From { /// The prime field can be converted back and forth into this biginteger /// representation. type Repr: PrimeFieldRepr + From; @@ -274,7 +274,7 @@ pub trait PrimeField: Field { let mut res = Self::zero(); - let ten = Self::from_repr(Self::Repr::from(10)).unwrap(); + let ten = Self::from(10); let mut first_digit = true; @@ -290,7 +290,7 @@ pub trait PrimeField: Field { } res.mul_assign(&ten); - res.add_assign(&Self::from_repr(Self::Repr::from(u64::from(c))).unwrap()); + res.add_assign(&Self::from(u64::from(c))); } None => { return None; diff --git a/pairing/src/bls12_381/fq.rs b/pairing/src/bls12_381/fq.rs index 2f7b15d16..5a8f17307 100644 --- a/pairing/src/bls12_381/fq.rs +++ b/pairing/src/bls12_381/fq.rs @@ -456,7 +456,7 @@ pub struct Fq(FqRepr); #[test] fn test_b_coeff() { - assert_eq!(Fq::from_repr(FqRepr::from(4)).unwrap(), B_COEFF); + assert_eq!(Fq::from(4), B_COEFF); } #[test] @@ -1586,7 +1586,7 @@ fn test_fq_is_valid() { assert!(!a.is_valid()); a.0.sub_noborrow(&FqRepr::from(1)); assert!(a.is_valid()); - assert!(Fq(FqRepr::from(0)).is_valid()); + assert!(Fq::from(0).is_valid()); assert!(Fq(FqRepr([ 0xdf4671abd14dab3e, 0xe2dc0c9f534fbd33, @@ -2193,10 +2193,7 @@ fn test_fq_root_of_unity() { use ff::SqrtField; assert_eq!(Fq::S, 1); - assert_eq!( - Fq::multiplicative_generator(), - Fq::from_repr(FqRepr::from(2)).unwrap() - ); + assert_eq!(Fq::multiplicative_generator(), Fq::from(2)); assert_eq!( Fq::multiplicative_generator().pow_vartime([ 0xdcff7fffffffd555u64, @@ -2225,9 +2222,7 @@ fn test_fq_ordering() { // FqRepr's ordering is well-tested, but we still need to make sure the Fq // elements aren't being compared in Montgomery form. for i in 0..100 { - assert!( - Fq::from_repr(FqRepr::from(i + 1)).unwrap() > Fq::from_repr(FqRepr::from(i)).unwrap() - ); + assert!(Fq::from(i + 1) > Fq::from(i)); } } diff --git a/pairing/src/bls12_381/fq2.rs b/pairing/src/bls12_381/fq2.rs index e0955f08f..6e6230736 100644 --- a/pairing/src/bls12_381/fq2.rs +++ b/pairing/src/bls12_381/fq2.rs @@ -364,7 +364,7 @@ fn test_fq2_squaring() { a.square(), Fq2 { c0: Fq::zero(), - c1: Fq::from_repr(FqRepr::from(2)).unwrap(), + c1: Fq::from(2), } ); // 2u diff --git a/pairing/src/bls12_381/fr.rs b/pairing/src/bls12_381/fr.rs index f520d303e..028287d20 100644 --- a/pairing/src/bls12_381/fr.rs +++ b/pairing/src/bls12_381/fr.rs @@ -368,7 +368,7 @@ fn test_fr_is_valid() { assert!(!a.is_valid()); a.0.sub_noborrow(&FrRepr::from(1)); assert!(a.is_valid()); - assert!(Fr(FrRepr::from(0)).is_valid()); + assert!(Fr::from(0).is_valid()); assert!(Fr(FrRepr([ 0xffffffff00000000, 0x53bda402fffe5bfe, @@ -961,10 +961,7 @@ fn test_fr_root_of_unity() { use ff::SqrtField; assert_eq!(Fr::S, 32); - assert_eq!( - Fr::multiplicative_generator(), - Fr::from_repr(FrRepr::from(7)).unwrap() - ); + assert_eq!(Fr::multiplicative_generator(), Fr::from(7)); assert_eq!( Fr::multiplicative_generator().pow_vartime([ 0xfffe5bfeffffffffu64, diff --git a/pairing/src/bls12_381/tests/mod.rs b/pairing/src/bls12_381/tests/mod.rs index 9c5b2c93f..f79961cdb 100644 --- a/pairing/src/bls12_381/tests/mod.rs +++ b/pairing/src/bls12_381/tests/mod.rs @@ -191,7 +191,7 @@ fn test_g1_uncompressed_invalid_vectors() { loop { let mut x3b = x.square(); x3b.mul_assign(&x); - x3b.add_assign(&Fq::from_repr(FqRepr::from(4)).unwrap()); // TODO: perhaps expose coeff_b through API? + x3b.add_assign(&Fq::from(4)); // TODO: perhaps expose coeff_b through API? let y = x3b.sqrt(); if y.is_some().into() { @@ -331,8 +331,8 @@ fn test_g2_uncompressed_invalid_vectors() { let mut x3b = x.square(); x3b.mul_assign(&x); x3b.add_assign(&Fq2 { - c0: Fq::from_repr(FqRepr::from(4)).unwrap(), - c1: Fq::from_repr(FqRepr::from(4)).unwrap(), + c0: Fq::from(4), + c1: Fq::from(4), }); // TODO: perhaps expose coeff_b through API? let y = x3b.sqrt(); @@ -428,7 +428,7 @@ fn test_g1_compressed_invalid_vectors() { loop { let mut x3b = x.square(); x3b.mul_assign(&x); - x3b.add_assign(&Fq::from_repr(FqRepr::from(4)).unwrap()); // TODO: perhaps expose coeff_b through API? + x3b.add_assign(&Fq::from(4)); // TODO: perhaps expose coeff_b through API? if x3b.sqrt().is_some().into() { x.add_assign(&Fq::one()); @@ -452,7 +452,7 @@ fn test_g1_compressed_invalid_vectors() { loop { let mut x3b = x.square(); x3b.mul_assign(&x); - x3b.add_assign(&Fq::from_repr(FqRepr::from(4)).unwrap()); // TODO: perhaps expose coeff_b through API? + x3b.add_assign(&Fq::from(4)); // TODO: perhaps expose coeff_b through API? if x3b.sqrt().is_some().into() { // We know this is on the curve, but it's likely not going to be in the correct subgroup. @@ -558,8 +558,8 @@ fn test_g2_compressed_invalid_vectors() { let mut x3b = x.square(); x3b.mul_assign(&x); x3b.add_assign(&Fq2 { - c0: Fq::from_repr(FqRepr::from(4)).unwrap(), - c1: Fq::from_repr(FqRepr::from(4)).unwrap(), + c0: Fq::from(4), + c1: Fq::from(4), }); // TODO: perhaps expose coeff_b through API? if x3b.sqrt().is_some().into() { @@ -589,8 +589,8 @@ fn test_g2_compressed_invalid_vectors() { let mut x3b = x.square(); x3b.mul_assign(&x); x3b.add_assign(&Fq2 { - c0: Fq::from_repr(FqRepr::from(4)).unwrap(), - c1: Fq::from_repr(FqRepr::from(4)).unwrap(), + c0: Fq::from(4), + c1: Fq::from(4), }); // TODO: perhaps expose coeff_b through API? if x3b.sqrt().is_some().into() { diff --git a/pairing/src/tests/field.rs b/pairing/src/tests/field.rs index a1f72b84b..64242322e 100644 --- a/pairing/src/tests/field.rs +++ b/pairing/src/tests/field.rs @@ -119,7 +119,7 @@ pub fn from_str_tests() { let n = rng.next_u64(); let a = F::from_str(&format!("{}", n)).unwrap(); - let b = F::from_repr(n.into()).unwrap(); + let b = F::from(n); assert_eq!(a, b); } diff --git a/zcash_primitives/src/jubjub/fs.rs b/zcash_primitives/src/jubjub/fs.rs index 6e902cbd3..466d4c5ea 100644 --- a/zcash_primitives/src/jubjub/fs.rs +++ b/zcash_primitives/src/jubjub/fs.rs @@ -278,6 +278,15 @@ impl ::std::fmt::Display for Fs { } } +impl From for Fs { + #[inline(always)] + fn from(val: u64) -> Fs { + let mut raw = [0u64; 4]; + raw[0] = val; + Fs(FsRepr(raw)) * Fs(R2) + } +} + impl From for FsRepr { fn from(e: Fs) -> FsRepr { e.into_repr() @@ -514,7 +523,7 @@ impl Field for Fs { #[inline] fn zero() -> Self { - Fs(FsRepr::from(0)) + Fs::from(0) } #[inline] @@ -1683,10 +1692,7 @@ fn test_fs_num_bits() { #[test] fn test_fs_root_of_unity() { assert_eq!(Fs::S, 1); - assert_eq!( - Fs::multiplicative_generator(), - Fs::from_repr(FsRepr::from(6)).unwrap() - ); + assert_eq!(Fs::multiplicative_generator(), Fs::from(6)); assert_eq!( Fs::multiplicative_generator().pow_vartime([ 0x684b872f6b7b965bu64, diff --git a/zcash_primitives/src/primitives.rs b/zcash_primitives/src/primitives.rs index af4fa3ad0..6e01a1052 100644 --- a/zcash_primitives/src/primitives.rs +++ b/zcash_primitives/src/primitives.rs @@ -24,7 +24,7 @@ impl ValueCommitment { pub fn cm(&self, params: &E::Params) -> edwards::Point { params .generator(FixedGenerators::ValueCommitmentValue) - .mul(self.value, params) + .mul(E::Fs::from(self.value), params) .add( ¶ms .generator(FixedGenerators::ValueCommitmentRandomness) @@ -291,7 +291,7 @@ impl Note { let rho = self.cm_full_point(params).add( ¶ms .generator(FixedGenerators::NullifierPosition) - .mul(position, params), + .mul(E::Fs::from(position), params), params, ); diff --git a/zcash_proofs/src/sapling/mod.rs b/zcash_proofs/src/sapling/mod.rs index 60ffd9bde..cd3757874 100644 --- a/zcash_proofs/src/sapling/mod.rs +++ b/zcash_proofs/src/sapling/mod.rs @@ -2,7 +2,7 @@ use pairing::bls12_381::Bls12; use zcash_primitives::jubjub::{ - edwards, fs::FsRepr, FixedGenerators, JubjubBls12, JubjubParams, Unknown, + edwards, fs::Fs, FixedGenerators, JubjubBls12, JubjubParams, Unknown, }; use zcash_primitives::transaction::components::Amount; @@ -30,7 +30,7 @@ fn compute_value_balance( // Compute it in the exponent let mut value_balance = params .generator(FixedGenerators::ValueCommitmentValue) - .mul(FsRepr::from(abs), params); + .mul(Fs::from(abs), params); // Negate if necessary if is_negative {