diff --git a/src/groth16/prover.rs b/src/groth16/prover.rs index 3c5b90f..c31b4db 100644 --- a/src/groth16/prover.rs +++ b/src/groth16/prover.rs @@ -314,34 +314,34 @@ where } let mut g_a = vk.delta_g1.mul(r); - g_a.add_assign_mixed(&vk.alpha_g1); + AddAssign::<&E::G1Affine>::add_assign(&mut g_a, &vk.alpha_g1); let mut g_b = vk.delta_g2.mul(s); - g_b.add_assign_mixed(&vk.beta_g2); + AddAssign::<&E::G2Affine>::add_assign(&mut g_b, &vk.beta_g2); let mut g_c; { let mut rs = r; rs.mul_assign(&s); g_c = vk.delta_g1.mul(rs); - g_c.add_assign(&vk.alpha_g1.mul(s)); - g_c.add_assign(&vk.beta_g1.mul(r)); + AddAssign::<&E::G1>::add_assign(&mut g_c, &vk.alpha_g1.mul(s)); + AddAssign::<&E::G1>::add_assign(&mut g_c, &vk.beta_g1.mul(r)); } let mut a_answer = a_inputs.wait()?; - a_answer.add_assign(&a_aux.wait()?); - g_a.add_assign(&a_answer); + AddAssign::<&E::G1>::add_assign(&mut a_answer, &a_aux.wait()?); + AddAssign::<&E::G1>::add_assign(&mut g_a, &a_answer); a_answer.mul_assign(s); - g_c.add_assign(&a_answer); + AddAssign::<&E::G1>::add_assign(&mut g_c, &a_answer); - let mut b1_answer = b_g1_inputs.wait()?; - b1_answer.add_assign(&b_g1_aux.wait()?); + let mut b1_answer: E::G1 = b_g1_inputs.wait()?; + AddAssign::<&E::G1>::add_assign(&mut b1_answer, &b_g1_aux.wait()?); let mut b2_answer = b_g2_inputs.wait()?; - b2_answer.add_assign(&b_g2_aux.wait()?); + AddAssign::<&E::G2>::add_assign(&mut b2_answer, &b_g2_aux.wait()?); - g_b.add_assign(&b2_answer); + AddAssign::<&E::G2>::add_assign(&mut g_b, &b2_answer); b1_answer.mul_assign(r); - g_c.add_assign(&b1_answer); - g_c.add_assign(&h.wait()?); - g_c.add_assign(&l.wait()?); + AddAssign::<&E::G1>::add_assign(&mut g_c, &b1_answer); + AddAssign::<&E::G1>::add_assign(&mut g_c, &h.wait()?); + AddAssign::<&E::G1>::add_assign(&mut g_c, &l.wait()?); Ok(Proof { a: g_a.into_affine(), diff --git a/src/groth16/tests/dummy_engine.rs b/src/groth16/tests/dummy_engine.rs index 4b87d9a..6c011c3 100644 --- a/src/groth16/tests/dummy_engine.rs +++ b/src/groth16/tests/dummy_engine.rs @@ -413,10 +413,6 @@ impl CurveProjective for Fr { self.0 = ::double(self).0; } - fn add_assign_mixed(&mut self, other: &Self) { - AddAssign::add_assign(self, other); - } - fn mul_assign::Repr>>(&mut self, other: S) { let tmp = Fr::from_repr(other.into()).unwrap(); diff --git a/src/groth16/verifier.rs b/src/groth16/verifier.rs index 8ee8a74..5983667 100644 --- a/src/groth16/verifier.rs +++ b/src/groth16/verifier.rs @@ -31,7 +31,7 @@ pub fn verify_proof<'a, E: Engine>( let mut acc = pvk.ic[0].into_projective(); for (i, b) in public_inputs.iter().zip(pvk.ic.iter().skip(1)) { - acc.add_assign(&b.mul(i.into_repr())); + AddAssign::<&E::G1>::add_assign(&mut acc, &b.mul(i.into_repr())); } // The original verification equation is: diff --git a/src/multiexp.rs b/src/multiexp.rs index 3f1ed0b..0bc61ba 100644 --- a/src/multiexp.rs +++ b/src/multiexp.rs @@ -19,16 +19,24 @@ pub trait SourceBuilder: Send + Sync + 'static + Clone { /// A source of bases, like an iterator. pub trait Source { - /// Parses the element from the source. Fails if the point is at infinity. - fn add_assign_mixed( - &mut self, - to: &mut ::Projective, - ) -> Result<(), SynthesisError>; + fn next(&mut self) -> Result<&G, SynthesisError>; /// Skips `amt` elements from the source, avoiding deserialization. fn skip(&mut self, amt: usize) -> Result<(), SynthesisError>; } +pub trait AddAssignFromSource: CurveProjective { + /// Parses the element from the source. Fails if the point is at infinity. + fn add_assign_from_source::Affine>>( + &mut self, + source: &mut S, + ) -> Result<(), SynthesisError> { + AddAssign::<&::Affine>::add_assign(self, source.next()?); + Ok(()) + } +} +impl AddAssignFromSource for G where G: CurveProjective {} + impl SourceBuilder for (Arc>, usize) { type Source = (Arc>, usize); @@ -38,10 +46,7 @@ impl SourceBuilder for (Arc>, usize) { } impl Source for (Arc>, usize) { - fn add_assign_mixed( - &mut self, - to: &mut ::Projective, - ) -> Result<(), SynthesisError> { + fn next(&mut self) -> Result<&G, SynthesisError> { if self.0.len() <= self.1 { return Err(io::Error::new( io::ErrorKind::UnexpectedEof, @@ -54,11 +59,10 @@ impl Source for (Arc>, usize) { return Err(SynthesisError::UnexpectedIdentity); } - to.add_assign_mixed(&self.0[self.1]); - + let ret = &self.0[self.1]; self.1 += 1; - Ok(()) + Ok(ret) } fn skip(&mut self, amt: usize) -> Result<(), SynthesisError> { @@ -154,12 +158,12 @@ fn multiexp_inner( mut skip: u32, c: u32, handle_trivial: bool, -) -> Box::Projective, Error = SynthesisError>> +) -> Box> where for<'a> &'a Q: QueryDensity, D: Send + Sync + 'static + Clone + AsRef, - G: CurveAffine, - S: SourceBuilder, + G: CurveProjective, + S: SourceBuilder<::Affine>, { // Perform this region of the multiexp let this = { @@ -169,13 +173,13 @@ where pool.compute(move || { // Accumulate the result - let mut acc = G::Projective::zero(); + let mut acc = G::zero(); // Build a source for the bases let mut bases = bases.new(); // Create space for the buckets - let mut buckets = vec![::Projective::zero(); (1 << c) - 1]; + let mut buckets = vec![G::zero(); (1 << c) - 1]; let zero = ::Fr::zero().into_repr(); let one = ::Fr::one().into_repr(); @@ -187,7 +191,7 @@ where bases.skip(1)?; } else if exp == one { if handle_trivial { - bases.add_assign_mixed(&mut acc)?; + acc.add_assign_from_source(&mut bases)?; } else { bases.skip(1)?; } @@ -197,7 +201,8 @@ where let exp = exp.as_ref()[0] % (1 << c); if exp != 0 { - bases.add_assign_mixed(&mut buckets[(exp - 1) as usize])?; + (&mut buckets[(exp - 1) as usize]) + .add_assign_from_source(&mut bases)?; } else { bases.skip(1)?; } @@ -209,7 +214,7 @@ where // e.g. 3a + 2b + 1c = a + // (a) + b + // ((a) + b) + c - let mut running_sum = G::Projective::zero(); + let mut running_sum = G::zero(); for exp in buckets.into_iter().rev() { running_sum.add_assign(&exp); acc.add_assign(&running_sum); @@ -237,7 +242,7 @@ where c, false, )) - .map(move |(this, mut higher)| { + .map(move |(this, mut higher): (_, G)| { for _ in 0..c { higher.double(); } @@ -257,12 +262,12 @@ pub fn multiexp( bases: S, density_map: D, exponents: Arc::Fr as PrimeField>::Repr>>, -) -> Box::Projective, Error = SynthesisError>> +) -> Box> where for<'a> &'a Q: QueryDensity, D: Send + Sync + 'static + Clone + AsRef, - G: CurveAffine, - S: SourceBuilder, + G: CurveProjective, + S: SourceBuilder<::Affine>, { let c = if exponents.len() < 32 { 3u32 @@ -283,16 +288,16 @@ where #[cfg(feature = "pairing")] #[test] fn test_with_bls12() { - fn naive_multiexp( - bases: Arc>, + fn naive_multiexp( + bases: Arc::Affine>>, exponents: Arc::Repr>>, - ) -> G::Projective { + ) -> G { assert_eq!(bases.len(), exponents.len()); - let mut acc = G::Projective::zero(); + let mut acc = G::zero(); for (base, exp) in bases.iter().zip(exponents.iter()) { - acc.add_assign(&base.mul(*exp)); + AddAssign::<&G>::add_assign(&mut acc, &base.mul(*exp)); } acc @@ -315,7 +320,7 @@ fn test_with_bls12() { .collect::>(), ); - let naive = naive_multiexp(g.clone(), v.clone()); + let naive: ::G1 = naive_multiexp(g.clone(), v.clone()); let pool = Worker::new();