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