group: Add mixed-addition scalar multiplication bounds to CurveAffine
Replaces the explicit CurveAffine::mul trait method.
This commit is contained in:
parent
0941dddc13
commit
b0a3713d7e
|
@ -463,12 +463,12 @@ where
|
|||
let g2 = g2.into_affine();
|
||||
|
||||
let vk = VerifyingKey::<E> {
|
||||
alpha_g1: g1.mul(alpha).into_affine(),
|
||||
beta_g1: g1.mul(beta).into_affine(),
|
||||
beta_g2: g2.mul(beta).into_affine(),
|
||||
gamma_g2: g2.mul(gamma).into_affine(),
|
||||
delta_g1: g1.mul(delta).into_affine(),
|
||||
delta_g2: g2.mul(delta).into_affine(),
|
||||
alpha_g1: (g1 * &alpha).into_affine(),
|
||||
beta_g1: (g1 * &beta).into_affine(),
|
||||
beta_g2: (g2 * &beta).into_affine(),
|
||||
gamma_g2: (g2 * &gamma).into_affine(),
|
||||
delta_g1: (g1 * &delta).into_affine(),
|
||||
delta_g2: (g2 * &delta).into_affine(),
|
||||
ic,
|
||||
};
|
||||
|
||||
|
|
|
@ -301,18 +301,18 @@ where
|
|||
return Err(SynthesisError::UnexpectedIdentity);
|
||||
}
|
||||
|
||||
let mut g_a = vk.delta_g1.mul(r);
|
||||
let mut g_a = vk.delta_g1 * &r;
|
||||
AddAssign::<&E::G1Affine>::add_assign(&mut g_a, &vk.alpha_g1);
|
||||
let mut g_b = vk.delta_g2.mul(s);
|
||||
let mut g_b = vk.delta_g2 * &s;
|
||||
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);
|
||||
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));
|
||||
g_c = vk.delta_g1 * &rs;
|
||||
AddAssign::<&E::G1>::add_assign(&mut g_c, &(vk.alpha_g1 * &s));
|
||||
AddAssign::<&E::G1>::add_assign(&mut g_c, &(vk.beta_g1 * &r));
|
||||
}
|
||||
let mut a_answer = a_inputs.wait()?;
|
||||
AddAssign::<&E::G1>::add_assign(&mut a_answer, &a_aux.wait()?);
|
||||
|
|
|
@ -475,15 +475,6 @@ impl CurveAffine for Fr {
|
|||
Choice::from(if <Fr as Field>::is_zero(self) { 1 } else { 0 })
|
||||
}
|
||||
|
||||
fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, other: S) -> Self::Projective {
|
||||
let mut res = *self;
|
||||
let tmp = Fr::from_repr(other.into()).unwrap();
|
||||
|
||||
MulAssign::mul_assign(&mut res, &tmp);
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn into_projective(&self) -> Self::Projective {
|
||||
*self
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use ff::PrimeField;
|
||||
use group::{CurveAffine, CurveProjective};
|
||||
use pairing::{Engine, PairingCurveAffine};
|
||||
use std::ops::{AddAssign, Neg};
|
||||
|
@ -31,7 +30,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)) {
|
||||
AddAssign::<&E::G1>::add_assign(&mut acc, &b.mul(i.to_repr()));
|
||||
AddAssign::<&E::G1>::add_assign(&mut acc, &(*b * i));
|
||||
}
|
||||
|
||||
// The original verification equation is:
|
||||
|
|
|
@ -308,7 +308,7 @@ fn test_with_bls12() {
|
|||
let mut acc = G::identity();
|
||||
|
||||
for (base, exp) in bases.iter().zip(exponents.iter()) {
|
||||
AddAssign::<&G>::add_assign(&mut acc, &base.mul(exp.to_repr()));
|
||||
AddAssign::<&G>::add_assign(&mut acc, &(*base * *exp));
|
||||
}
|
||||
|
||||
acc
|
||||
|
|
|
@ -99,7 +99,9 @@ pub trait CurveProjective:
|
|||
+ GroupOpsOwned<<Self as CurveProjective>::Affine>
|
||||
{
|
||||
type Base: Field;
|
||||
type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar>;
|
||||
type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar>
|
||||
+ Mul<Self::Scalar, Output = Self>
|
||||
+ for<'r> Mul<Self::Scalar, Output = Self>;
|
||||
|
||||
/// Converts a batch of projective elements into affine elements. This function will
|
||||
/// panic if `p.len() != q.len()`.
|
||||
|
@ -131,6 +133,8 @@ pub trait CurveAffine:
|
|||
+ Eq
|
||||
+ 'static
|
||||
+ Neg<Output = Self>
|
||||
+ Mul<<Self as CurveAffine>::Scalar, Output = <Self as CurveAffine>::Projective>
|
||||
+ for<'r> Mul<<Self as CurveAffine>::Scalar, Output = <Self as CurveAffine>::Projective>
|
||||
{
|
||||
type Scalar: PrimeField;
|
||||
type Base: Field;
|
||||
|
@ -148,9 +152,6 @@ pub trait CurveAffine:
|
|||
/// additive identity.
|
||||
fn is_identity(&self) -> Choice;
|
||||
|
||||
/// Performs scalar multiplication of this element with mixed addition.
|
||||
fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, other: S) -> Self::Projective;
|
||||
|
||||
/// Converts this element into its affine representation.
|
||||
fn into_projective(&self) -> Self::Projective;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ff::{Field, PrimeField};
|
||||
use rand::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::Neg;
|
||||
use std::ops::{Mul, Neg};
|
||||
|
||||
use crate::{CurveAffine, CurveProjective, EncodedPoint};
|
||||
|
||||
|
@ -273,8 +273,8 @@ fn random_multiplication_tests<G: CurveProjective>() {
|
|||
tmp2.add_assign(&b);
|
||||
|
||||
// Affine multiplication
|
||||
let mut tmp3 = a_affine.mul(s);
|
||||
tmp3.add_assign(&b_affine.mul(s));
|
||||
let mut tmp3 = Mul::<G::Scalar>::mul(a_affine, s);
|
||||
tmp3.add_assign(Mul::<G::Scalar>::mul(b_affine, s));
|
||||
|
||||
assert_eq!(tmp1, tmp2);
|
||||
assert_eq!(tmp1, tmp3);
|
||||
|
|
|
@ -141,7 +141,8 @@ macro_rules! curve_impl {
|
|||
}
|
||||
|
||||
fn is_in_correct_subgroup_assuming_on_curve(&self) -> bool {
|
||||
self.mul($scalarfield::char()).is_identity().into()
|
||||
let bits = BitIterator::<u8, _>::new($scalarfield::char());
|
||||
self.mul_bits_u8(bits).is_identity().into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,6 +159,24 @@ macro_rules! curve_impl {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Mul<$scalarfield> for $affine {
|
||||
type Output = $projective;
|
||||
|
||||
fn mul(self, by: $scalarfield) -> $projective {
|
||||
let bits = BitIterator::<u8, <$scalarfield as PrimeField>::Repr>::new(by.into());
|
||||
self.mul_bits_u8(bits)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> ::std::ops::Mul<&'r $scalarfield> for $affine {
|
||||
type Output = $projective;
|
||||
|
||||
fn mul(self, by: &'r $scalarfield) -> $projective {
|
||||
let bits = BitIterator::<u8, <$scalarfield as PrimeField>::Repr>::new(by.into());
|
||||
self.mul_bits_u8(bits)
|
||||
}
|
||||
}
|
||||
|
||||
impl CurveAffine for $affine {
|
||||
type Scalar = $scalarfield;
|
||||
type Base = $basefield;
|
||||
|
@ -181,11 +200,6 @@ macro_rules! curve_impl {
|
|||
Choice::from(if self.infinity { 1 } else { 0 })
|
||||
}
|
||||
|
||||
fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, by: S) -> $projective {
|
||||
let bits = BitIterator::<u8, _>::new(by.into());
|
||||
self.mul_bits_u8(bits)
|
||||
}
|
||||
|
||||
fn into_projective(&self) -> $projective {
|
||||
(*self).into()
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ pub mod tests;
|
|||
|
||||
pub mod bls12_381;
|
||||
|
||||
use core::ops::Mul;
|
||||
use ff::{Field, PrimeField, ScalarEngine};
|
||||
use group::{CurveAffine, CurveProjective, GroupOps, GroupOpsOwned, ScalarMul, ScalarMulOwned};
|
||||
use subtle::CtOption;
|
||||
|
@ -43,7 +44,9 @@ pub trait Engine: ScalarEngine {
|
|||
Projective = Self::G1,
|
||||
Pair = Self::G2Affine,
|
||||
PairingResult = Self::Fqk,
|
||||
> + From<Self::G1>;
|
||||
> + From<Self::G1>
|
||||
+ Mul<Self::Fr, Output = Self::G1>
|
||||
+ for<'a> Mul<&'a Self::Fr, Output = Self::G1>;
|
||||
|
||||
/// The projective representation of an element in G2.
|
||||
type G2: CurveProjective<Base = Self::Fqe, Scalar = Self::Fr, Affine = Self::G2Affine>
|
||||
|
@ -60,7 +63,9 @@ pub trait Engine: ScalarEngine {
|
|||
Projective = Self::G2,
|
||||
Pair = Self::G1Affine,
|
||||
PairingResult = Self::Fqk,
|
||||
> + From<Self::G2>;
|
||||
> + From<Self::G2>
|
||||
+ Mul<Self::Fr, Output = Self::G2>
|
||||
+ for<'a> Mul<&'a Self::Fr, Output = Self::G2>;
|
||||
|
||||
/// The base field that hosts G1.
|
||||
type Fq: PrimeField;
|
||||
|
|
Loading…
Reference in New Issue