From 9dac74822471f5fadd732370fb4ab7b0ca5c719b Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 12 Dec 2019 22:59:18 +0000 Subject: [PATCH] Make Field::double take &self and return Self --- bellman/src/gadgets/multipack.rs | 4 +-- bellman/src/gadgets/num.rs | 4 +-- bellman/src/gadgets/uint32.rs | 4 +-- bellman/src/groth16/tests/dummy_engine.rs | 6 ++--- ff/ff_derive/src/lib.rs | 10 +++++--- ff/src/lib.rs | 3 ++- pairing/src/bls12_381/ec.rs | 26 ++++++++----------- pairing/src/bls12_381/fq.rs | 7 ++--- pairing/src/bls12_381/fq12.rs | 8 +++--- pairing/src/bls12_381/fq2.rs | 13 +++++----- pairing/src/bls12_381/fq6.rs | 16 ++++++------ pairing/src/bls12_381/fr.rs | 7 ++--- pairing/src/bls12_381/mod.rs | 31 ++++++++--------------- pairing/src/tests/field.rs | 8 ++---- zcash_primitives/src/jubjub/edwards.rs | 2 +- zcash_primitives/src/jubjub/fs.rs | 19 +++++++------- zcash_primitives/src/jubjub/mod.rs | 3 +-- zcash_primitives/src/jubjub/montgomery.rs | 7 +++-- zcash_primitives/src/jubjub/tests.rs | 5 +--- zcash_primitives/src/pedersen_hash.rs | 6 ++--- zcash_proofs/src/circuit/ecc.rs | 5 ++-- zcash_proofs/src/circuit/sapling.rs | 2 +- zcash_proofs/src/circuit/sprout/mod.rs | 2 +- 23 files changed, 87 insertions(+), 111 deletions(-) diff --git a/bellman/src/gadgets/multipack.rs b/bellman/src/gadgets/multipack.rs index 445a360bf..8ee6a1546 100644 --- a/bellman/src/gadgets/multipack.rs +++ b/bellman/src/gadgets/multipack.rs @@ -20,7 +20,7 @@ where for bit in bits { num = num.add_bool_with_coeff(CS::one(), bit, coeff); - coeff.double(); + coeff = coeff.double(); } let input = cs.alloc_input(|| format!("input {}", i), || Ok(*num.get_value().get()?))?; @@ -63,7 +63,7 @@ pub fn compute_multipacking(bits: &[bool]) -> Vec { cur.add_assign(&coeff); } - coeff.double(); + coeff = coeff.double(); } result.push(cur); diff --git a/bellman/src/gadgets/num.rs b/bellman/src/gadgets/num.rs index bce55ced1..08a175bf5 100644 --- a/bellman/src/gadgets/num.rs +++ b/bellman/src/gadgets/num.rs @@ -177,7 +177,7 @@ impl AllocatedNum { for bit in result.iter().rev() { lc = lc + (coeff, bit.get_variable()); - coeff.double(); + coeff = coeff.double(); } lc = lc - self.variable; @@ -203,7 +203,7 @@ impl AllocatedNum { for bit in bits.iter() { lc = lc + (coeff, bit.get_variable()); - coeff.double(); + coeff = coeff.double(); } lc = lc - self.variable; diff --git a/bellman/src/gadgets/uint32.rs b/bellman/src/gadgets/uint32.rs index 8bf4558df..16bb65135 100644 --- a/bellman/src/gadgets/uint32.rs +++ b/bellman/src/gadgets/uint32.rs @@ -330,7 +330,7 @@ impl UInt32 { all_constants &= bit.is_constant(); - coeff.double(); + coeff = coeff.double(); } } @@ -368,7 +368,7 @@ impl UInt32 { max_value >>= 1; i += 1; - coeff.double(); + coeff = coeff.double(); } // Enforce equality between the sum and result diff --git a/bellman/src/groth16/tests/dummy_engine.rs b/bellman/src/groth16/tests/dummy_engine.rs index 46641b347..224f84ee5 100644 --- a/bellman/src/groth16/tests/dummy_engine.rs +++ b/bellman/src/groth16/tests/dummy_engine.rs @@ -144,8 +144,8 @@ impl Field for Fr { self.0 = (self.0 * self.0) % MODULUS_R; } - fn double(&mut self) { - self.0 = (self.0 << 1) % MODULUS_R; + fn double(&self) -> Self { + Fr((self.0 << 1) % MODULUS_R) } fn inverse(&self) -> Option { @@ -406,7 +406,7 @@ impl CurveProjective for Fr { } fn double(&mut self) { - ::double(self); + self.0 = ::double(self).0; } fn add_assign(&mut self, other: &Self) { diff --git a/ff/ff_derive/src/lib.rs b/ff/ff_derive/src/lib.rs index 0e804c786..88146b343 100644 --- a/ff/ff_derive/src/lib.rs +++ b/ff/ff_derive/src/lib.rs @@ -1040,12 +1040,16 @@ fn prime_field_impl( } #[inline] - fn double(&mut self) { + fn double(&self) -> Self { + let mut ret = *self; + // This cannot exceed the backing capacity. - self.0.mul2(); + ret.0.mul2(); // However, it may need to be reduced. - self.reduce(); + ret.reduce(); + + ret } fn inverse(&self) -> Option { diff --git a/ff/src/lib.rs b/ff/src/lib.rs index c605f6433..fd8d45db9 100644 --- a/ff/src/lib.rs +++ b/ff/src/lib.rs @@ -54,7 +54,8 @@ pub trait Field: fn square(&mut self); /// Doubles this element. - fn double(&mut self); + #[must_use] + fn double(&self) -> Self; /// Computes the multiplicative inverse of this element, if nonzero. fn inverse(&self) -> Option; diff --git a/pairing/src/bls12_381/ec.rs b/pairing/src/bls12_381/ec.rs index c1da107c5..6f4559207 100644 --- a/pairing/src/bls12_381/ec.rs +++ b/pairing/src/bls12_381/ec.rs @@ -322,11 +322,10 @@ macro_rules! curve_impl { d.square(); d.sub_assign(&a); d.sub_assign(&c); - d.double(); + d = d.double(); // E = 3*A - let mut e = a; - e.double(); + let mut e = a.double(); e.add_assign(&a); // F = E^2 @@ -335,7 +334,7 @@ macro_rules! curve_impl { // Z3 = 2*Y1*Z1 self.z.mul_assign(&self.y); - self.z.double(); + self.z = self.z.double(); // X3 = F-2*D self.x = f; @@ -346,9 +345,7 @@ macro_rules! curve_impl { self.y = d; self.y.sub_assign(&self.x); self.y.mul_assign(&e); - c.double(); - c.double(); - c.double(); + c = c.double().double().double(); self.y.sub_assign(&c); } @@ -401,8 +398,7 @@ macro_rules! curve_impl { h.sub_assign(&u1); // I = (2*H)^2 - let mut i = h; - i.double(); + let mut i = h.double(); i.square(); // J = H*I @@ -412,7 +408,7 @@ macro_rules! curve_impl { // r = 2*(S2-S1) let mut r = s2; r.sub_assign(&s1); - r.double(); + r = r.double(); // V = U1*I let mut v = u1; @@ -430,7 +426,7 @@ macro_rules! curve_impl { self.y.sub_assign(&self.x); self.y.mul_assign(&r); s1.mul_assign(&j); // S1 = S1 * J * 2 - s1.double(); + s1 = s1.double(); self.y.sub_assign(&s1); // Z3 = ((Z1+Z2)^2 - Z1Z1 - Z2Z2)*H @@ -484,9 +480,7 @@ macro_rules! curve_impl { hh.square(); // I = 4*HH - let mut i = hh; - i.double(); - i.double(); + let i = hh.double().double(); // J = H*I let mut j = h; @@ -495,7 +489,7 @@ macro_rules! curve_impl { // r = 2*(S2-Y1) let mut r = s2; r.sub_assign(&self.y); - r.double(); + r = r.double(); // V = X1*I let mut v = self.x; @@ -510,7 +504,7 @@ macro_rules! curve_impl { // Y3 = r*(V-X3)-2*Y1*J j.mul_assign(&self.y); // J = 2*Y1*J - j.double(); + j = j.double(); self.y = v; self.y.sub_assign(&self.x); self.y.mul_assign(&r); diff --git a/pairing/src/bls12_381/fq.rs b/pairing/src/bls12_381/fq.rs index f17a2783b..77c85ea46 100644 --- a/pairing/src/bls12_381/fq.rs +++ b/pairing/src/bls12_381/fq.rs @@ -2001,11 +2001,8 @@ fn test_fq_double() { for _ in 0..1000 { // Ensure doubling a is equivalent to adding a to itself. - let mut a = Fq::random(&mut rng); - let mut b = a; - b.add_assign(&a); - a.double(); - assert_eq!(a, b); + let a = Fq::random(&mut rng); + assert_eq!(a.double(), a + a); } } diff --git a/pairing/src/bls12_381/fq12.rs b/pairing/src/bls12_381/fq12.rs index 6bc66a45e..d07272516 100644 --- a/pairing/src/bls12_381/fq12.rs +++ b/pairing/src/bls12_381/fq12.rs @@ -183,9 +183,11 @@ impl Field for Fq12 { self.c0.is_zero() && self.c1.is_zero() } - fn double(&mut self) { - self.c0.double(); - self.c1.double(); + fn double(&self) -> Self { + Fq12 { + c0: self.c0.double(), + c1: self.c1.double(), + } } fn frobenius_map(&mut self, power: usize) { diff --git a/pairing/src/bls12_381/fq2.rs b/pairing/src/bls12_381/fq2.rs index e60c374d8..137c1baf0 100644 --- a/pairing/src/bls12_381/fq2.rs +++ b/pairing/src/bls12_381/fq2.rs @@ -213,9 +213,11 @@ impl Field for Fq2 { self.c0 = c0; } - fn double(&mut self) { - self.c0.double(); - self.c1.double(); + fn double(&self) -> Self { + Fq2 { + c0: self.c0.double(), + c1: self.c1.double(), + } } fn inverse(&self) -> Option { @@ -741,7 +743,7 @@ fn test_fq2_doubling() { use super::fq::FqRepr; use ff::PrimeField; - let mut a = Fq2 { + let a = Fq2 { c0: Fq::from_repr(FqRepr([ 0x2d0078036923ffc7, 0x11e59ea221a3b6d2, @@ -761,9 +763,8 @@ fn test_fq2_doubling() { ])) .unwrap(), }; - a.double(); assert_eq!( - a, + a.double(), Fq2 { c0: Fq::from_repr(FqRepr([ 0x5a00f006d247ff8e, diff --git a/pairing/src/bls12_381/fq6.rs b/pairing/src/bls12_381/fq6.rs index a50e283d3..8e5b394c3 100644 --- a/pairing/src/bls12_381/fq6.rs +++ b/pairing/src/bls12_381/fq6.rs @@ -286,10 +286,12 @@ impl Field for Fq6 { self.c0.is_zero() && self.c1.is_zero() && self.c2.is_zero() } - fn double(&mut self) { - self.c0.double(); - self.c1.double(); - self.c2.double(); + fn double(&self) -> Self { + Fq6 { + c0: self.c0.double(), + c1: self.c1.double(), + c2: self.c2.double(), + } } fn frobenius_map(&mut self, power: usize) { @@ -306,16 +308,14 @@ impl Field for Fq6 { s0.square(); let mut ab = self.c0; ab.mul_assign(&self.c1); - let mut s1 = ab; - s1.double(); + let s1 = ab.double(); let mut s2 = self.c0; s2.sub_assign(&self.c1); s2.add_assign(&self.c2); s2.square(); let mut bc = self.c1; bc.mul_assign(&self.c2); - let mut s3 = bc; - s3.double(); + let s3 = bc.double(); let mut s4 = self.c2; s4.square(); diff --git a/pairing/src/bls12_381/fr.rs b/pairing/src/bls12_381/fr.rs index d72557e6f..21832dec2 100644 --- a/pairing/src/bls12_381/fr.rs +++ b/pairing/src/bls12_381/fr.rs @@ -760,11 +760,8 @@ fn test_fr_double() { for _ in 0..1000 { // Ensure doubling a is equivalent to adding a to itself. - let mut a = Fr::random(&mut rng); - let mut b = a; - b.add_assign(&a); - a.double(); - assert_eq!(a, b); + let a = Fr::random(&mut rng); + assert_eq!(a.double(), a + a); } } diff --git a/pairing/src/bls12_381/mod.rs b/pairing/src/bls12_381/mod.rs index 32e23e1a5..0a3813d96 100644 --- a/pairing/src/bls12_381/mod.rs +++ b/pairing/src/bls12_381/mod.rs @@ -199,10 +199,9 @@ impl G2Prepared { tmp3.square(); tmp3.sub_assign(&tmp0); tmp3.sub_assign(&tmp2); - tmp3.double(); + tmp3 = tmp3.double(); - let mut tmp4 = tmp0; - tmp4.double(); + let mut tmp4 = tmp0.double(); tmp4.add_assign(&tmp0); let mut tmp6 = r.x; @@ -227,29 +226,25 @@ impl G2Prepared { r.y.sub_assign(&r.x); r.y.mul_assign(&tmp4); - tmp2.double(); - tmp2.double(); - tmp2.double(); + tmp2 = tmp2.double().double().double(); r.y.sub_assign(&tmp2); tmp3 = tmp4; tmp3.mul_assign(&zsquared); - tmp3.double(); - tmp3 = tmp3.neg(); + tmp3 = tmp3.double().neg(); tmp6.square(); tmp6.sub_assign(&tmp0); tmp6.sub_assign(&tmp5); - tmp1.double(); - tmp1.double(); + tmp1 = tmp1.double().double(); tmp6.sub_assign(&tmp1); tmp0 = r.z; tmp0.mul_assign(&zsquared); - tmp0.double(); + tmp0 = tmp0.double(); (tmp0, tmp3, tmp6) } @@ -278,9 +273,7 @@ impl G2Prepared { let mut t3 = t2; t3.square(); - let mut t4 = t3; - t4.double(); - t4.double(); + let t4 = t3.double().double(); let mut t5 = t4; t5.mul_assign(&t2); @@ -315,7 +308,7 @@ impl G2Prepared { t0 = r.y; t0.mul_assign(&t5); - t0.double(); + t0 = t0.double(); r.y = t8; r.y.sub_assign(&t0); @@ -328,16 +321,14 @@ impl G2Prepared { t10.sub_assign(&ztsquared); - t9.double(); + t9 = t9.double(); t9.sub_assign(&t10); - t10 = r.z; - t10.double(); + t10 = r.z.double(); t6 = t6.neg(); - t1 = t6; - t1.double(); + t1 = t6.double(); (t10, t1, t9) } diff --git a/pairing/src/tests/field.rs b/pairing/src/tests/field.rs index 89b203887..304e142b7 100644 --- a/pairing/src/tests/field.rs +++ b/pairing/src/tests/field.rs @@ -211,12 +211,8 @@ fn random_negation_tests(rng: &mut R) { fn random_doubling_tests(rng: &mut R) { for _ in 0..10000 { - let mut a = F::random(rng); - let mut b = a; - a.add_assign(&b); - b.double(); - - assert_eq!(a, b); + let a = F::random(rng); + assert_eq!(a + a, a.double()); } } diff --git a/zcash_primitives/src/jubjub/edwards.rs b/zcash_primitives/src/jubjub/edwards.rs index 8c7df4c71..45975cbc8 100644 --- a/zcash_primitives/src/jubjub/edwards.rs +++ b/zcash_primitives/src/jubjub/edwards.rs @@ -345,7 +345,7 @@ impl Point { // C = 2*Z1^2 let mut c = self.z; c.square(); - c.double(); + c = c.double(); // D = a*A // = -A diff --git a/zcash_primitives/src/jubjub/fs.rs b/zcash_primitives/src/jubjub/fs.rs index 53d0ee355..aa1859022 100644 --- a/zcash_primitives/src/jubjub/fs.rs +++ b/zcash_primitives/src/jubjub/fs.rs @@ -502,12 +502,16 @@ impl Field for Fs { } #[inline] - fn double(&mut self) { + fn double(&self) -> Self { + let mut ret = *self; + // This cannot exceed the backing capacity. - self.0.mul2(); + ret.0.mul2(); // However, it may need to be reduced. - self.reduce(); + ret.reduce(); + + ret } fn inverse(&self) -> Option { @@ -680,7 +684,7 @@ impl Fs { fn mul_bits>(&self, bits: BitIterator) -> Self { let mut res = Self::zero(); for bit in bits { - res.double(); + res = res.double(); if bit { res.add_assign(self) @@ -1466,11 +1470,8 @@ fn test_fs_double() { for _ in 0..1000 { // Ensure doubling a is equivalent to adding a to itself. - let mut a = Fs::random(&mut rng); - let mut b = a; - b.add_assign(&a); - a.double(); - assert_eq!(a, b); + let a = Fs::random(&mut rng); + assert_eq!(a.double(), a + a); } } diff --git a/zcash_primitives/src/jubjub/mod.rs b/zcash_primitives/src/jubjub/mod.rs index 9428600be..06a3810bf 100644 --- a/zcash_primitives/src/jubjub/mod.rs +++ b/zcash_primitives/src/jubjub/mod.rs @@ -195,8 +195,7 @@ impl JubjubParams for JubjubBls12 { impl JubjubBls12 { pub fn new() -> Self { let montgomery_a = Fr::from_str("40962").unwrap(); - let mut montgomery_2a = montgomery_a; - montgomery_2a.double(); + let montgomery_2a = montgomery_a.double(); let mut tmp_params = JubjubBls12 { // d = -(10240/10241) diff --git a/zcash_primitives/src/jubjub/montgomery.rs b/zcash_primitives/src/jubjub/montgomery.rs index 18acc0d50..5bb052f6e 100644 --- a/zcash_primitives/src/jubjub/montgomery.rs +++ b/zcash_primitives/src/jubjub/montgomery.rs @@ -216,19 +216,18 @@ impl Point { { let mut tmp = *params.montgomery_a(); tmp.mul_assign(&self.x); - tmp.double(); + tmp = tmp.double(); delta.add_assign(&tmp); } { let mut tmp = self.x; tmp.square(); delta.add_assign(&tmp); - tmp.double(); + tmp = tmp.double(); delta.add_assign(&tmp); } { - let mut tmp = self.y; - tmp.double(); + let tmp = self.y.double(); delta.mul_assign(&tmp.inverse().expect("y is nonzero so this must be nonzero")); } diff --git a/zcash_primitives/src/jubjub/tests.rs b/zcash_primitives/src/jubjub/tests.rs index d1527378f..2469d58a8 100644 --- a/zcash_primitives/src/jubjub/tests.rs +++ b/zcash_primitives/src/jubjub/tests.rs @@ -314,10 +314,7 @@ fn test_jubjub_params(params: &E::Params) { { // Check that 2A is consistent with A - let mut tmp = *params.montgomery_a(); - tmp.double(); - - assert_eq!(&tmp, params.montgomery_2a()); + assert_eq!(¶ms.montgomery_a().double(), params.montgomery_2a()); } { diff --git a/zcash_primitives/src/pedersen_hash.rs b/zcash_primitives/src/pedersen_hash.rs index d12b6a407..ea182a5ac 100644 --- a/zcash_primitives/src/pedersen_hash.rs +++ b/zcash_primitives/src/pedersen_hash.rs @@ -58,7 +58,7 @@ where if a { tmp.add_assign(&cur); } - cur.double(); // 2^1 * cur + cur = cur.double(); // 2^1 * cur if b { tmp.add_assign(&cur); } @@ -75,9 +75,7 @@ where if chunks_remaining == 0 { break; } else { - cur.double(); // 2^2 * cur - cur.double(); // 2^3 * cur - cur.double(); // 2^4 * cur + cur = cur.double().double().double(); // 2^4 * cur } } diff --git a/zcash_proofs/src/circuit/ecc.rs b/zcash_proofs/src/circuit/ecc.rs index 7072f0147..9889a5081 100644 --- a/zcash_proofs/src/circuit/ecc.rs +++ b/zcash_proofs/src/circuit/ecc.rs @@ -340,7 +340,7 @@ impl EdwardsPoint { // Compute x3 = (2.A) / (1 + C) let x3 = AllocatedNum::alloc(cs.namespace(|| "x3"), || { let mut t0 = *a.get_value().get()?; - t0.double(); + t0 = t0.double(); let mut t1 = E::Fr::one(); t1.add_assign(c.get_value().get()?); @@ -366,8 +366,7 @@ impl EdwardsPoint { // Compute y3 = (U - 2.A) / (1 - C) let y3 = AllocatedNum::alloc(cs.namespace(|| "y3"), || { let mut t0 = *a.get_value().get()?; - t0.double(); - t0 = t0.neg(); + t0 = t0.double().neg(); t0.add_assign(t.get_value().get()?); let mut t1 = E::Fr::one(); diff --git a/zcash_proofs/src/circuit/sapling.rs b/zcash_proofs/src/circuit/sapling.rs index ddb0f1c11..9782a4f96 100644 --- a/zcash_proofs/src/circuit/sapling.rs +++ b/zcash_proofs/src/circuit/sapling.rs @@ -245,7 +245,7 @@ impl<'a, E: JubjubEngine> Circuit for Spend<'a, E> { let mut coeff = E::Fr::one(); for bit in &value_bits { value_num = value_num.add_bool_with_coeff(CS::one(), bit, coeff); - coeff.double(); + coeff = coeff.double(); } // Place the value in the note diff --git a/zcash_proofs/src/circuit/sprout/mod.rs b/zcash_proofs/src/circuit/sprout/mod.rs index 187704779..6afe67793 100644 --- a/zcash_proofs/src/circuit/sprout/mod.rs +++ b/zcash_proofs/src/circuit/sprout/mod.rs @@ -268,7 +268,7 @@ impl NoteValue { let mut coeff = E::Fr::one(); for b in &self.bits { tmp = tmp + (coeff, b.get_variable()); - coeff.double(); + coeff = coeff.double(); } tmp