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 #445

Merged
merged 23 commits into from
Aug 28, 2022
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
46 changes: 22 additions & 24 deletions ec/src/models/mnt4/g2.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::ops::Neg;
weikengchen marked this conversation as resolved.
Show resolved Hide resolved

use crate::{
mnt4::MNT4Parameters,
models::mnt4::MNT4,
Expand Down Expand Up @@ -53,32 +55,28 @@ impl<P: MNT4Parameters> From<G2Affine<P>> for G2Prepared<P> {
t: <Fp2<P::Fp2Config>>::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) = MNT4::<P>::doubling_step_for_flipped_miller_loop(&r);
g2p.double_coefficients.push(coeff);
r = r2;

if *bit {
let (r2, coeff) =
let neg_g2 = g2.neg();
for bit in P::ATE_LOOP_COUNT.iter().skip(1) {
let (r2, coeff) = MNT4::<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) =
MNT4::<P>::mixed_addition_step_for_flipped_miller_loop(&g2.x, &g2.y, &r);
g2p.addition_coefficients.push(coeff);
r = r2;
}

tmp >>= 1;
},
-1 => {
(r_temp, add_coeff) = MNT4::<P>::mixed_addition_step_for_flipped_miller_loop(
&neg_g2.x, &neg_g2.y, &r,
);
},
_ => continue,
weikengchen marked this conversation as resolved.
Show resolved Hide resolved
}
g2p.addition_coefficients.push(add_coeff);
r = r_temp;
}

if P::ATE_IS_LOOP_COUNT_NEG {
Expand Down
29 changes: 19 additions & 10 deletions ec/src/models/mnt4/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use ark_ff::{
fp2::{Fp2, Fp2Config},
fp4::{Fp4, Fp4Config},
BitIteratorBE, CyclotomicMultSubgroup, Field, PrimeField,
CyclotomicMultSubgroup, Field, PrimeField,
};
use num_traits::{One, Zero};

Expand All @@ -25,7 +25,7 @@ pub type GT<P> = Fp4<P>;
pub trait MNT4Parameters: 'static {
const TWIST: Fp2<Self::Fp2Config>;
const TWIST_COEFF_A: Fp2<Self::Fp2Config>;
const ATE_LOOP_COUNT: &'static [u64];
const ATE_LOOP_COUNT: &'static [i8];
const ATE_IS_LOOP_COUNT_NEG: bool;
const FINAL_EXPONENT_LAST_CHUNK_1: <Self::Fp as PrimeField>::BigInt;
const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool;
Expand Down Expand Up @@ -110,28 +110,37 @@ impl<P: MNT4Parameters> MNT4<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 (bit, dc) in BitIteratorBE::without_leading_zeros(P::ATE_LOOP_COUNT)
.skip(1)
.zip(&q.double_coefficients)
{
let y_over_twist_neg = -q.y_over_twist;
weikengchen marked this conversation as resolved.
Show resolved Hide resolved
for (bit, dc) in P::ATE_LOOP_COUNT.iter().skip(1).zip(&q.double_coefficients) {
let g_rr_at_p = Fp4::new(
-dc.c_4c - &(dc.c_j * &p.x_twist) + &dc.c_l,
dc.c_h * &p.y_twist,
);

f = f.square() * &g_rr_at_p;

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

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

g_rq_at_p = Fp4::new(
ac.c_rz * &p.y_twist,
-(y_over_twist_neg * &ac.c_rz + &(l1_coeff * &ac.c_l1)),
);
} else {
weikengchen marked this conversation as resolved.
Show resolved Hide resolved
continue;
weikengchen marked this conversation as resolved.
Show resolved Hide resolved
}
f *= &g_rq_at_p;
}

if P::ATE_IS_LOOP_COUNT_NEG {
Expand Down
46 changes: 22 additions & 24 deletions ec/src/models/mnt6/g2.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::ops::Neg;

use crate::{
mnt6::MNT6Parameters,
models::mnt6::MNT6,
Expand Down Expand Up @@ -53,32 +55,28 @@ impl<P: MNT6Parameters> From<G2Affine<P>> for G2Prepared<P> {
t: <Fp3<P::Fp3Config>>::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) = MNT6::<P>::doubling_step_for_flipped_miller_loop(&r);
g2p.double_coefficients.push(coeff);
r = r2;

if *bit {
let (r2, coeff) =
let neg_g2 = g2.neg();
for bit in P::ATE_LOOP_COUNT.iter().skip(1) {
let (r2, coeff) = MNT6::<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) =
MNT6::<P>::mixed_addition_step_for_flipped_miller_loop(&g2.x, &g2.y, &r);
g2p.addition_coefficients.push(coeff);
r = r2;
}

tmp >>= 1;
},
-1 => {
(r_temp, add_coeff) = MNT6::<P>::mixed_addition_step_for_flipped_miller_loop(
&neg_g2.x, &neg_g2.y, &r,
);
},
_ => continue,
weikengchen marked this conversation as resolved.
Show resolved Hide resolved
}
g2p.addition_coefficients.push(add_coeff);
r = r_temp;
}

if P::ATE_IS_LOOP_COUNT_NEG {
Expand Down
27 changes: 18 additions & 9 deletions ec/src/models/mnt6/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use ark_ff::{
fp3::{Fp3, Fp3Config},
fp6_2over3::{Fp6, Fp6Config},
BitIteratorBE, CyclotomicMultSubgroup, Field, PrimeField,
CyclotomicMultSubgroup, Field, PrimeField,
};
use num_traits::{One, Zero};

Expand All @@ -25,7 +25,7 @@ pub type GT<P> = Fp6<P>;
pub trait MNT6Parameters: 'static {
const TWIST: Fp3<Self::Fp3Config>;
const TWIST_COEFF_A: Fp3<Self::Fp3Config>;
const ATE_LOOP_COUNT: &'static [u64];
const ATE_LOOP_COUNT: &'static [i8];
const ATE_IS_LOOP_COUNT_NEG: bool;
const FINAL_EXPONENT_LAST_CHUNK_1: <Self::Fp as PrimeField>::BigInt;
const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool;
Expand Down Expand Up @@ -112,27 +112,36 @@ impl<P: MNT6Parameters> MNT6<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 (bit, dc) in BitIteratorBE::without_leading_zeros(P::ATE_LOOP_COUNT)
.skip(1)
.zip(&q.double_coefficients)
{
let y_over_twist_neg = -q.y_over_twist;
weikengchen marked this conversation as resolved.
Show resolved Hide resolved
for (bit, dc) in P::ATE_LOOP_COUNT.iter().skip(1).zip(&q.double_coefficients) {
let g_rr_at_p = Fp6::new(
dc.c_l - &dc.c_4c - &(dc.c_j * &p.x_twist),
dc.c_h * &p.y_twist,
);

f = f.square() * &g_rr_at_p;

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

let g_rq_at_p = Fp6::new(
g_rq_at_p = Fp6::new(
ac.c_rz * &p.y_twist,
-(q.y_over_twist * &ac.c_rz + &(l1_coeff * &ac.c_l1)),
);
f *= &g_rq_at_p;
} else if *bit == -1 {
let ac = &q.addition_coefficients[add_idx];
add_idx += 1;
g_rq_at_p = Fp6::new(
ac.c_rz * &p.y_twist,
-(y_over_twist_neg * &ac.c_rz + &(l1_coeff * &ac.c_l1)),
);
} else {
continue;
}
weikengchen marked this conversation as resolved.
Show resolved Hide resolved
f *= &g_rq_at_p;
}

if P::ATE_IS_LOOP_COUNT_NEG {
Expand Down