Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use 2-NAF for representing ATE_LOOP_COUNT in MNT Miller loop #96

Merged
merged 9 commits into from
Sep 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ jobs:
echo "ark-ff = { git = 'https://github.com/arkworks-rs/algebra' }"
echo "ark-poly = { git = 'https://github.com/arkworks-rs/algebra' }"
echo "ark-serialize = { git = 'https://github.com/arkworks-rs/algebra' }"
echo "ark-algebra-bench-templates = { git = 'https://github.com/arkworks-rs/algebra' }"
echo "ark-algebra-test-templates = { git = 'https://github.com/arkworks-rs/algebra' }"
echo "ark-r1cs-std = { path = 'r1cs-std' }"
} >> Cargo.toml
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ ark-std = { git = "https://github.com/arkworks-rs/std" }
ark-ec = { git = "https://github.com/arkworks-rs/algebra" }
ark-ff = { git = "https://github.com/arkworks-rs/algebra" }
ark-poly = { git = "https://github.com/arkworks-rs/algebra" }
ark-algebra-bench-templates = { git = "https://github.com/arkworks-rs/algebra" }
ark-test-curves = { git = "https://github.com/arkworks-rs/algebra" }
ark-bls12-381 = { git = "https://github.com/arkworks-rs/curves" }
ark-bls12-377 = { git = "https://github.com/arkworks-rs/curves" }
Expand Down
2 changes: 1 addition & 1 deletion src/groups/curves/short_weierstrass/bls12/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl<P: Bls12Parameters> G1PreparedVar<P> {
let y = self.0.y.value()?;
let infinity = self.0.infinity.value()?;
let g = infinity
.then_some(GroupAffine::zero())
.then_some(GroupAffine::identity())
.unwrap_or(GroupAffine::new(x, y))
.into();
Ok(g)
Expand Down
51 changes: 25 additions & 26 deletions src/groups/curves/short_weierstrass/mnt4/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,33 +291,32 @@ impl<P: MNT4Parameters> G2PreparedVar<P> {
t: Fp2G::<P>::one(),
};

for (idx, value) in P::ATE_LOOP_COUNT.iter().rev().enumerate() {
let mut tmp = *value;
let skip_extraneous_bits = 64 - value.leading_zeros();
let mut v = Vec::with_capacity(16);
for i in 0..64 {
if idx == 0 && (i == 0 || i >= skip_extraneous_bits) {
continue;
}
v.push(tmp & 1 == 1);
tmp >>= 1;
}

for bit in v.iter().rev() {
let (r2, coeff) = PairingVar::<P>::doubling_step_for_flipped_miller_loop(&r)?;
g2p.double_coefficients.push(coeff);
r = r2;

if *bit {
let (r2, coeff) = PairingVar::<P>::mixed_addition_step_for_flipped_miller_loop(
&q.x, &q.y, &r,
)?;
g2p.addition_coefficients.push(coeff);
r = r2;
}

tmp >>= 1;
for bit in P::ATE_LOOP_COUNT.iter().skip(1) {
let (r2, coeff) = PairingVar::<P>::doubling_step_for_flipped_miller_loop(&r)?;
g2p.double_coefficients.push(coeff);
r = r2;

let add_coeff;
let r_temp;
match bit {
1 => {
(r_temp, add_coeff) =
PairingVar::<P>::mixed_addition_step_for_flipped_miller_loop(
&q.x, &q.y, &r,
)?;
},
-1 => {
(r_temp, add_coeff) =
PairingVar::<P>::mixed_addition_step_for_flipped_miller_loop(
&q.x,
&q.y.negate()?,
&r,
)?;
},
_ => continue,
}
g2p.addition_coefficients.push(add_coeff);
r = r_temp;
}

if P::ATE_IS_LOOP_COUNT_NEG {
Expand Down
51 changes: 25 additions & 26 deletions src/groups/curves/short_weierstrass/mnt6/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,33 +291,32 @@ impl<P: MNT6Parameters> G2PreparedVar<P> {
t: Fp3G::<P>::one(),
};

for (idx, value) in P::ATE_LOOP_COUNT.iter().rev().enumerate() {
let mut tmp = *value;
let skip_extraneous_bits = 64 - value.leading_zeros();
let mut v = Vec::with_capacity(16);
for i in 0..64 {
if idx == 0 && (i == 0 || i >= skip_extraneous_bits) {
continue;
}
v.push(tmp & 1 == 1);
tmp >>= 1;
}

for bit in v.iter().rev() {
let (r2, coeff) = PairingVar::<P>::doubling_step_for_flipped_miller_loop(&r)?;
g2p.double_coefficients.push(coeff);
r = r2;

if *bit {
let (r2, coeff) = PairingVar::<P>::mixed_addition_step_for_flipped_miller_loop(
&q.x, &q.y, &r,
)?;
g2p.addition_coefficients.push(coeff);
r = r2;
}

tmp >>= 1;
for bit in P::ATE_LOOP_COUNT.iter().skip(1) {
let (r2, coeff) = PairingVar::<P>::doubling_step_for_flipped_miller_loop(&r)?;
g2p.double_coefficients.push(coeff);
r = r2;

let add_coeff;
let r_temp;
match bit {
1 => {
(r_temp, add_coeff) =
PairingVar::<P>::mixed_addition_step_for_flipped_miller_loop(
&q.x, &q.y, &r,
)?;
},
-1 => {
(r_temp, add_coeff) =
PairingVar::<P>::mixed_addition_step_for_flipped_miller_loop(
&q.x,
&q.y.negate()?,
&r,
)?;
},
_ => continue,
}
g2p.addition_coefficients.push(add_coeff);
r = r_temp;
}

if P::ATE_IS_LOOP_COUNT_NEG {
Expand Down
14 changes: 9 additions & 5 deletions src/groups/curves/short_weierstrass/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use ark_ec::{
short_weierstrass::{
Affine as SWAffine, Projective as SWProjective, SWCurveConfig as SWModelParameters,
},
AffineCurve, ProjectiveCurve,
AffineRepr, CurveGroup,
};
use ark_ff::{BigInteger, BitIteratorBE, Field, One, PrimeField, Zero};
use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError};
Expand Down Expand Up @@ -94,7 +94,7 @@ where
/// constraint system.
pub fn value(&self) -> Result<SWAffine<P>, SynthesisError> {
Ok(match self.infinity.value()? {
true => SWAffine::zero(),
true => SWAffine::identity(),
false => SWAffine::new(self.x.value()?, self.y.value()?),
})
}
Expand Down Expand Up @@ -137,7 +137,7 @@ where
let result = if let Some(z_inv) = z.inverse() {
SWAffine::new(x * &z_inv, y * &z_inv)
} else {
SWAffine::zero()
SWAffine::identity()
};
Ok(result.into())
}
Expand Down Expand Up @@ -209,7 +209,7 @@ where
let (x, y, z) = match f() {
Ok(ge) => {
let ge = ge.into_affine();
if ge.is_zero() {
if ge.is_identity() {
(
Ok(P::BaseField::zero()),
Ok(P::BaseField::one()),
Expand Down Expand Up @@ -782,7 +782,11 @@ where
f: impl FnOnce() -> Result<T, SynthesisError>,
mode: AllocationMode,
) -> Result<Self, SynthesisError> {
Self::new_variable(cs, || f().map(|b| b.borrow().into_projective()), mode)
Self::new_variable(
cs,
|| f().map(|b| SWProjective::from((*b.borrow()).clone())),
mode,
)
}
}

Expand Down
13 changes: 8 additions & 5 deletions src/groups/curves/short_weierstrass/non_zero_affine.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use super::*;
use ark_ec::Group;
use ark_std::ops::Add;

/// An affine representation of a prime order curve point that is guaranteed
/// to *not* be the point at infinity.
Expand Down Expand Up @@ -43,8 +45,7 @@ where
#[tracing::instrument(target = "r1cs", skip(self, other))]
pub fn add_unchecked(&self, other: &Self) -> Result<Self, SynthesisError> {
if [self, other].is_constant() {
let result =
(self.value()?.into_projective() + other.value()?.into_projective()).into_affine();
let result = self.value()?.add(other.value()?).into_affine();
Ok(Self::new(F::constant(result.x), F::constant(result.y)))
} else {
let (x1, y1) = (&self.x, &self.y);
Expand All @@ -70,9 +71,11 @@ where
#[tracing::instrument(target = "r1cs", skip(self))]
pub fn double(&self) -> Result<Self, SynthesisError> {
if [self].is_constant() {
let result = self.value()?.into_projective().double().into_affine();
let result = SWProjective::<P>::from(self.value()?)
.double()
.into_affine();
// Panic if the result is zero.
assert!(!result.is_zero());
assert!(!result.is_identity());
Ok(Self::new(F::constant(result.x), F::constant(result.y)))
} else {
let (x1, y1) = (&self.x, &self.y);
Expand Down Expand Up @@ -236,7 +239,7 @@ mod test_non_zero_affine {
},
R1CSVar,
};
use ark_ec::{models::short_weierstrass::SWCurveConfig, ProjectiveCurve};
use ark_ec::{models::short_weierstrass::SWCurveConfig, CurveGroup};
use ark_relations::r1cs::ConstraintSystem;
use ark_std::{vec::Vec, One};
use ark_test_curves::bls12_381::{g1::Parameters as G1Parameters, Fq};
Expand Down
13 changes: 8 additions & 5 deletions src/groups/curves/twisted_edwards/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ use ark_ec::{
Affine as TEAffine, MontCurveConfig as MontgomeryModelParameter,
Projective as TEProjective, TECurveConfig as TEModelParameters,
},
AffineCurve, ProjectiveCurve,
AffineRepr, CurveGroup, Group,
};
use ark_ff::{BigInteger, BitIteratorBE, Field, One, PrimeField, Zero};

use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError};

use crate::{prelude::*, ToConstraintFieldGadget, Vec};
Expand Down Expand Up @@ -85,7 +84,7 @@ mod montgomery_affine_impl {
p: &TEAffine<P>,
) -> Result<(P::BaseField, P::BaseField), SynthesisError> {
let montgomery_point: GroupAffine<P> = if p.y == P::BaseField::one() {
GroupAffine::zero()
GroupAffine::identity()
} else if p.x == P::BaseField::zero() {
GroupAffine::new(P::BaseField::zero(), P::BaseField::zero())
} else {
Expand Down Expand Up @@ -543,7 +542,7 @@ where
if bits.len() == 2 {
let mut table = [multiples[0], multiples[1], multiples[0] + multiples[1]];

TEProjective::batch_normalization(&mut table);
TEProjective::normalize_batch(&mut table);
let x_s = [zero.x, table[0].x, table[1].x, table[2].x];
let y_s = [zero.y, table[0].y, table[1].y, table[2].y];

Expand Down Expand Up @@ -675,7 +674,11 @@ where
f: impl FnOnce() -> Result<Point, SynthesisError>,
mode: AllocationMode,
) -> Result<Self, SynthesisError> {
Self::new_variable(cs, || f().map(|b| b.borrow().into_projective()), mode)
Self::new_variable(
cs,
|| f().map(|b| TEProjective::<P>::from((*b.borrow()).clone())),
mode,
)
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/groups/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::prelude::*;
use ark_ec::ProjectiveCurve;
use ark_ff::Field;
use ark_relations::r1cs::{Namespace, SynthesisError};
use core::ops::{Add, AddAssign, Sub, SubAssign};

use ark_ec::CurveGroup;
use core::{borrow::Borrow, fmt::Debug};

/// This module contains implementations of arithmetic for various curve models.
Expand All @@ -25,7 +25,7 @@ pub trait GroupOpsBounds<'a, F, T: 'a>:

/// A variable that represents a curve point for
/// the curve `C`.
pub trait CurveVar<C: ProjectiveCurve, ConstraintF: Field>:
pub trait CurveVar<C: CurveGroup, ConstraintF: Field>:
'static
+ Sized
+ Clone
Expand Down
26 changes: 18 additions & 8 deletions src/pairing/mnt4/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use crate::{
},
};
use ark_ec::mnt4::{MNT4Parameters, MNT4};
use ark_ff::BitIteratorBE;

use core::marker::PhantomData;

Expand Down Expand Up @@ -105,10 +104,8 @@ impl<P: MNT4Parameters> PairingVar<P> {

// code below gets executed for all bits (EXCEPT the MSB itself) of
// mnt6_param_p (skipping leading zeros) in MSB to LSB order
for (dbl_idx, bit) in BitIteratorBE::without_leading_zeros(P::ATE_LOOP_COUNT)
.skip(1)
.enumerate()
{
let y_over_twist_neg = &q.y_over_twist.negate()?;
for (dbl_idx, bit) in P::ATE_LOOP_COUNT.iter().skip(1).enumerate() {
let dc = &q.double_coefficients[dbl_idx];

let g_rr_at_p = Fp4G::<P>::new(
Expand All @@ -118,16 +115,29 @@ impl<P: MNT4Parameters> PairingVar<P> {

f = f.square()? * &g_rr_at_p;

if bit {
let g_rq_at_p;
// Compute l_{R,Q}(P) if bit == 1, and l_{R,-Q}(P) if bit == -1
if *bit == 1 {
let ac = &q.addition_coefficients[add_idx];
add_idx += 1;

let g_rq_at_p = Fp4G::<P>::new(
g_rq_at_p = Fp4G::<P>::new(
&ac.c_rz * &p.y_twist,
(&q.y_over_twist * &ac.c_rz + &l1_coeff * &ac.c_l1).negate()?,
);
f *= &g_rq_at_p;
} else if *bit == -1 {
let ac = &q.addition_coefficients[add_idx];
add_idx += 1;

g_rq_at_p = Fp4G::<P>::new(
&ac.c_rz * &p.y_twist,
(y_over_twist_neg * &ac.c_rz + &l1_coeff * &ac.c_l1).negate()?,
);
} else {
continue;
}

f *= &g_rq_at_p;
}

if P::ATE_IS_LOOP_COUNT_NEG {
Expand Down
Loading