From 526d1842d8f7a2cf517ef298b031c9f3788c5800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20G=C3=B3rny?= Date: Thu, 28 Jul 2022 13:31:09 +0200 Subject: [PATCH 01/19] Use BitIteratoreBE instead of a double loop improves code readability --- ec/src/models/mnt6/g2.rs | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/ec/src/models/mnt6/g2.rs b/ec/src/models/mnt6/g2.rs index 34fea52ed..b5a9a3014 100644 --- a/ec/src/models/mnt6/g2.rs +++ b/ec/src/models/mnt6/g2.rs @@ -4,7 +4,7 @@ use crate::{ short_weierstrass::{Affine, Projective}, AffineCurve, }; -use ark_ff::fields::{Field, Fp3}; +use ark_ff::{fields::{Field, Fp3}, BitIteratorBE}; use ark_std::vec::Vec; use num_traits::One; @@ -53,32 +53,18 @@ impl From> for G2Prepared

{ t: >::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 BitIteratorBE::without_leading_zeros(P::ATE_LOOP_COUNT).skip(1) { + let (r2, coeff) = MNT6::

::doubling_step_for_flipped_miller_loop(&r); + g2p.double_coefficients.push(coeff); + r = r2; - for bit in v.iter().rev() { - let (r2, coeff) = MNT6::

::doubling_step_for_flipped_miller_loop(&r); - g2p.double_coefficients.push(coeff); + if bit { + let (r2, coeff) = + MNT6::

::mixed_addition_step_for_flipped_miller_loop(&g2.x, &g2.y, &r); + g2p.addition_coefficients.push(coeff); r = r2; - - if *bit { - let (r2, coeff) = - MNT6::

::mixed_addition_step_for_flipped_miller_loop(&g2.x, &g2.y, &r); - g2p.addition_coefficients.push(coeff); - r = r2; - } - - tmp >>= 1; } + } if P::ATE_IS_LOOP_COUNT_NEG { From 2f295cdaf6b5333e73ea609ccc0f238fb6fb8b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20G=C3=B3rny?= Date: Thu, 28 Jul 2022 13:06:21 +0200 Subject: [PATCH 02/19] Add a 2-NAF loop count --- ec/src/models/mnt6/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index 55a16ba69..1faf56e4c 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -26,6 +26,7 @@ pub trait MNT6Parameters: 'static { const TWIST: Fp3; const TWIST_COEFF_A: Fp3; const ATE_LOOP_COUNT: &'static [u64]; + const ATE_LOOP_COUNT_2: &'static [i8]; const ATE_IS_LOOP_COUNT_NEG: bool; const FINAL_EXPONENT_LAST_CHUNK_1: ::BigInt; const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool; From 24460b75193531b8b1c8b7860574ae242bf2b538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20G=C3=B3rny?= Date: Fri, 29 Jul 2022 15:14:41 +0200 Subject: [PATCH 03/19] Replace loop over bits with loop over 2-NAF --- ec/src/models/mnt6/g2.rs | 29 +++++++++++++++++++++-------- ec/src/models/mnt6/mod.rs | 7 ++++--- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/ec/src/models/mnt6/g2.rs b/ec/src/models/mnt6/g2.rs index b5a9a3014..108ee4667 100644 --- a/ec/src/models/mnt6/g2.rs +++ b/ec/src/models/mnt6/g2.rs @@ -1,10 +1,12 @@ +use core::ops::Neg; + use crate::{ mnt6::MNT6Parameters, models::mnt6::MNT6, short_weierstrass::{Affine, Projective}, AffineCurve, }; -use ark_ff::{fields::{Field, Fp3}, BitIteratorBE}; +use ark_ff::fields::{Field, Fp3}; use ark_std::vec::Vec; use num_traits::One; @@ -53,18 +55,29 @@ impl From> for G2Prepared

{ t: >::one(), }; - for bit in BitIteratorBE::without_leading_zeros(P::ATE_LOOP_COUNT).skip(1) { + let neg_g2 = g2.neg(); + for bit in P::ATE_LOOP_COUNT_2.iter().skip(1) { + // print!("{}", bit); let (r2, coeff) = MNT6::

::doubling_step_for_flipped_miller_loop(&r); g2p.double_coefficients.push(coeff); r = r2; - if bit { - let (r2, coeff) = - MNT6::

::mixed_addition_step_for_flipped_miller_loop(&g2.x, &g2.y, &r); - g2p.addition_coefficients.push(coeff); - r = r2; + let add_coeff; + let r_temp; + match bit { + 1 => { + (r_temp, add_coeff) = + MNT6::

::mixed_addition_step_for_flipped_miller_loop(&g2.x, &g2.y, &r); + }, + -1 => { + (r_temp, add_coeff) = MNT6::

::mixed_addition_step_for_flipped_miller_loop( + &neg_g2.x, &neg_g2.y, &r, + ); + }, + _ => continue, } - + g2p.addition_coefficients.push(add_coeff); + r = r_temp; } if P::ATE_IS_LOOP_COUNT_NEG { diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index 1faf56e4c..c5115f6f6 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -5,7 +5,7 @@ use crate::{ use ark_ff::{ fp3::{Fp3, Fp3Config}, fp6_2over3::{Fp6, Fp6Config}, - BitIteratorBE, Field, PrimeField, + Field, PrimeField, }; use num_traits::{One, Zero}; @@ -113,7 +113,8 @@ impl MNT6

{ // 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) + for ((ind, bit), dc) in P::ATE_LOOP_COUNT_2 + .iter().enumerate() .skip(1) .zip(&q.double_coefficients) { @@ -124,7 +125,7 @@ impl MNT6

{ f = f.square() * &g_rr_at_p; - if bit { + if *bit != 0 { let ac = &q.addition_coefficients[add_idx]; add_idx += 1; From 4b8ddb9fa1268228af5b7c4827924c4ff788d6dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20G=C3=B3rny?= Date: Fri, 29 Jul 2022 15:35:20 +0200 Subject: [PATCH 04/19] for T=-1, should compute L_{R, -Q} --- ec/src/models/mnt6/mod.rs | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index c5115f6f6..2f11488ff 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -114,7 +114,8 @@ impl MNT6

{ // code below gets executed for all bits (EXCEPT the MSB itself) of // mnt6_param_p (skipping leading zeros) in MSB to LSB order for ((ind, bit), dc) in P::ATE_LOOP_COUNT_2 - .iter().enumerate() + .iter() + .enumerate() .skip(1) .zip(&q.double_coefficients) { @@ -125,15 +126,26 @@ impl MNT6

{ f = f.square() * &g_rr_at_p; - if *bit != 0 { - let ac = &q.addition_coefficients[add_idx]; - add_idx += 1; - - let 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; + match *bit { + 1 => { + let ac = &q.addition_coefficients[add_idx]; + add_idx += 1; + let 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; + }, + -1 => { + let ac = &q.addition_coefficients[add_idx]; + add_idx += 1; + let 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; + }, + _ => continue, } } From 2db6f3fd72d014449f9a3df3b9c8c685dae94515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20G=C3=B3rny?= Date: Fri, 29 Jul 2022 15:54:56 +0200 Subject: [PATCH 05/19] no need to enumerate --- ec/src/models/mnt6/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index 2f11488ff..48d2232ec 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -113,9 +113,8 @@ impl MNT6

{ // code below gets executed for all bits (EXCEPT the MSB itself) of // mnt6_param_p (skipping leading zeros) in MSB to LSB order - for ((ind, bit), dc) in P::ATE_LOOP_COUNT_2 + for (bit, dc) in P::ATE_LOOP_COUNT_2 .iter() - .enumerate() .skip(1) .zip(&q.double_coefficients) { From a018a5c2a4ee0710ccd5af597886aa7a298687a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20G=C3=B3rny?= Date: Fri, 29 Jul 2022 15:56:45 +0200 Subject: [PATCH 06/19] simplify the match statement to an if refactor the line computation to leverage an intermediate var y_over_twist, which we negate or not depending on value of "bit" --- ec/src/models/mnt6/mod.rs | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index 48d2232ec..b314a2443 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -125,26 +125,21 @@ impl MNT6

{ f = f.square() * &g_rr_at_p; - match *bit { - 1 => { - let ac = &q.addition_coefficients[add_idx]; - add_idx += 1; - let 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; - }, - -1 => { - let ac = &q.addition_coefficients[add_idx]; - add_idx += 1; - let 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; - }, - _ => continue, + if bit.abs() == 1 { + let ac = &q.addition_coefficients[add_idx]; + add_idx += 1; + + // Compute l_{R,Q}(P) if bit == 1, and l_{R,-Q}(P) if bit == -1 + let y_over_twist = if *bit == 1 { + q.y_over_twist + } else { + -q.y_over_twist + }; + let g_rq_at_p = Fp6::new( + ac.c_rz * &p.y_twist, + -(y_over_twist * &ac.c_rz + &(l1_coeff * &ac.c_l1)), + ); + f *= &g_rq_at_p; } } From 8649c55d445ba0e2e7543edd1a05fa7cdf9adf8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20G=C3=B3rny?= Date: Fri, 29 Jul 2022 16:18:22 +0200 Subject: [PATCH 07/19] deprecate ATE_LOOP_COUNT replaced by its 2NAF in prev. commit --- ec/src/models/mnt6/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index b314a2443..9422f1d18 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -25,7 +25,6 @@ pub type GT

= Fp6

; pub trait MNT6Parameters: 'static { const TWIST: Fp3; const TWIST_COEFF_A: Fp3; - const ATE_LOOP_COUNT: &'static [u64]; const ATE_LOOP_COUNT_2: &'static [i8]; const ATE_IS_LOOP_COUNT_NEG: bool; const FINAL_EXPONENT_LAST_CHUNK_1: ::BigInt; From ab3a20d7de66952d3adf0bac1fa2d87568bfd305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20G=C3=B3rny?= Date: Fri, 29 Jul 2022 16:20:03 +0200 Subject: [PATCH 08/19] Use 2NAF for optimising additions in mnt4 pairing --- ec/src/models/mnt4/g2.rs | 47 +++++++++++++++++++-------------------- ec/src/models/mnt4/mod.rs | 15 +++++++++---- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/ec/src/models/mnt4/g2.rs b/ec/src/models/mnt4/g2.rs index 031175c5e..78d6d822b 100644 --- a/ec/src/models/mnt4/g2.rs +++ b/ec/src/models/mnt4/g2.rs @@ -1,3 +1,5 @@ +use core::ops::Neg; + use crate::{ mnt4::MNT4Parameters, models::mnt4::MNT4, @@ -53,32 +55,29 @@ impl From> for G2Prepared

{ t: >::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::

::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_2.iter().skip(1) { + // print!("{}", bit); + let (r2, coeff) = MNT4::

::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::

::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::

::mixed_addition_step_for_flipped_miller_loop( + &neg_g2.x, &neg_g2.y, &r, + ); + }, + _ => continue, } + g2p.addition_coefficients.push(add_coeff); + r = r_temp; } if P::ATE_IS_LOOP_COUNT_NEG { diff --git a/ec/src/models/mnt4/mod.rs b/ec/src/models/mnt4/mod.rs index f8b096ad5..61fd66228 100644 --- a/ec/src/models/mnt4/mod.rs +++ b/ec/src/models/mnt4/mod.rs @@ -25,7 +25,7 @@ pub type GT

= Fp4

; pub trait MNT4Parameters: 'static { const TWIST: Fp2; const TWIST_COEFF_A: Fp2; - const ATE_LOOP_COUNT: &'static [u64]; + const ATE_LOOP_COUNT_2: &'static [u64]; const ATE_IS_LOOP_COUNT_NEG: bool; const FINAL_EXPONENT_LAST_CHUNK_1: ::BigInt; const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool; @@ -111,7 +111,8 @@ impl MNT4

{ // 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) + for (bit, dc) in P::ATE_LOOP_COUNT_2 + .iter() .skip(1) .zip(&q.double_coefficients) { @@ -122,13 +123,19 @@ impl MNT4

{ f = f.square() * &g_rr_at_p; - if bit { + if bit.abs() == 1 { let ac = &q.addition_coefficients[add_idx]; add_idx += 1; + // Compute l_{R,Q}(P) if bit == 1, and l_{R,-Q}(P) if bit == -1 + let y_over_twist = if *bit == 1 { + q.y_over_twist + } else { + -q.y_over_twist + }; let g_rq_at_p = Fp4::new( ac.c_rz * &p.y_twist, - -(q.y_over_twist * &ac.c_rz + &(l1_coeff * &ac.c_l1)), + -(y_over_twist * &ac.c_rz + &(l1_coeff * &ac.c_l1)), ); f *= &g_rq_at_p; } From 04f9027f20271052cd9fa7015fd4eb6796ae2c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20G=C3=B3rny?= Date: Fri, 29 Jul 2022 17:37:42 +0200 Subject: [PATCH 09/19] clean up --- ec/src/models/mnt4/g2.rs | 1 - ec/src/models/mnt4/mod.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ec/src/models/mnt4/g2.rs b/ec/src/models/mnt4/g2.rs index 78d6d822b..02a270db2 100644 --- a/ec/src/models/mnt4/g2.rs +++ b/ec/src/models/mnt4/g2.rs @@ -57,7 +57,6 @@ impl From> for G2Prepared

{ let neg_g2 = g2.neg(); for bit in P::ATE_LOOP_COUNT_2.iter().skip(1) { - // print!("{}", bit); let (r2, coeff) = MNT4::

::doubling_step_for_flipped_miller_loop(&r); g2p.double_coefficients.push(coeff); r = r2; diff --git a/ec/src/models/mnt4/mod.rs b/ec/src/models/mnt4/mod.rs index 61fd66228..4609f2c10 100644 --- a/ec/src/models/mnt4/mod.rs +++ b/ec/src/models/mnt4/mod.rs @@ -5,7 +5,7 @@ use crate::{ use ark_ff::{ fp2::{Fp2, Fp2Config}, fp4::{Fp4, Fp4Config}, - BitIteratorBE, Field, PrimeField, + Field, PrimeField, }; use num_traits::{One, Zero}; From 807cb323739f98696c916f416ac7359f6b0e9c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20G=C3=B3rny?= Date: Fri, 29 Jul 2022 17:38:35 +0200 Subject: [PATCH 10/19] ATE_LOOP_COUNT_2 should be i8's not u64's --- ec/src/models/mnt4/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ec/src/models/mnt4/mod.rs b/ec/src/models/mnt4/mod.rs index 4609f2c10..9efeddf83 100644 --- a/ec/src/models/mnt4/mod.rs +++ b/ec/src/models/mnt4/mod.rs @@ -25,7 +25,7 @@ pub type GT

= Fp4

; pub trait MNT4Parameters: 'static { const TWIST: Fp2; const TWIST_COEFF_A: Fp2; - const ATE_LOOP_COUNT_2: &'static [u64]; + const ATE_LOOP_COUNT_2: &'static [i8]; const ATE_IS_LOOP_COUNT_NEG: bool; const FINAL_EXPONENT_LAST_CHUNK_1: ::BigInt; const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool; From 876f53feb653b82d2526d79f88f9ded0f1e05625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20G=C3=B3rny?= Date: Fri, 29 Jul 2022 19:22:15 +0200 Subject: [PATCH 11/19] only compute `y_over_twist_neg` once --- ec/src/models/mnt4/mod.rs | 28 +++++++++++++++++----------- ec/src/models/mnt6/mod.rs | 26 ++++++++++++++++---------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/ec/src/models/mnt4/mod.rs b/ec/src/models/mnt4/mod.rs index 9efeddf83..1d6e29ffd 100644 --- a/ec/src/models/mnt4/mod.rs +++ b/ec/src/models/mnt4/mod.rs @@ -110,7 +110,7 @@ impl MNT4

{ // code below gets executed for all bits (EXCEPT the MSB itself) of // mnt6_param_p (skipping leading zeros) in MSB to LSB order - + let y_over_twist_neg = -q.y_over_twist; for (bit, dc) in P::ATE_LOOP_COUNT_2 .iter() .skip(1) @@ -123,22 +123,28 @@ impl MNT4

{ f = f.square() * &g_rr_at_p; - if bit.abs() == 1 { + // 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; + + g_rq_at_p = Fp4::new( + ac.c_rz * &p.y_twist, + -(q.y_over_twist * &ac.c_rz + &(l1_coeff * &ac.c_l1)), + ); + } else if *bit == -1 { let ac = &q.addition_coefficients[add_idx]; add_idx += 1; - // Compute l_{R,Q}(P) if bit == 1, and l_{R,-Q}(P) if bit == -1 - let y_over_twist = if *bit == 1 { - q.y_over_twist - } else { - -q.y_over_twist - }; - let g_rq_at_p = Fp4::new( + g_rq_at_p = Fp4::new( ac.c_rz * &p.y_twist, - -(y_over_twist * &ac.c_rz + &(l1_coeff * &ac.c_l1)), + -(y_over_twist_neg * &ac.c_rz + &(l1_coeff * &ac.c_l1)), ); - f *= &g_rq_at_p; + } else { + continue; } + f *= &g_rq_at_p; } if P::ATE_IS_LOOP_COUNT_NEG { diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index 9422f1d18..d0cf7280e 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -112,6 +112,7 @@ impl MNT6

{ // code below gets executed for all bits (EXCEPT the MSB itself) of // mnt6_param_p (skipping leading zeros) in MSB to LSB order + let y_over_twist_neg = -q.y_over_twist; for (bit, dc) in P::ATE_LOOP_COUNT_2 .iter() .skip(1) @@ -124,22 +125,27 @@ impl MNT6

{ f = f.square() * &g_rr_at_p; - if bit.abs() == 1 { + // 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; - // Compute l_{R,Q}(P) if bit == 1, and l_{R,-Q}(P) if bit == -1 - let y_over_twist = if *bit == 1 { - q.y_over_twist - } else { - -q.y_over_twist - }; - let g_rq_at_p = Fp6::new( + g_rq_at_p = Fp6::new( ac.c_rz * &p.y_twist, - -(y_over_twist * &ac.c_rz + &(l1_coeff * &ac.c_l1)), + -(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; } + f *= &g_rq_at_p; } if P::ATE_IS_LOOP_COUNT_NEG { From 50907d2504778933561360649835749b46571a50 Mon Sep 17 00:00:00 2001 From: Marcin Date: Fri, 29 Jul 2022 20:16:08 +0200 Subject: [PATCH 12/19] Update ec/src/models/mnt6/g2.rs --- ec/src/models/mnt6/g2.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/ec/src/models/mnt6/g2.rs b/ec/src/models/mnt6/g2.rs index 108ee4667..d78d544df 100644 --- a/ec/src/models/mnt6/g2.rs +++ b/ec/src/models/mnt6/g2.rs @@ -57,7 +57,6 @@ impl From> for G2Prepared

{ let neg_g2 = g2.neg(); for bit in P::ATE_LOOP_COUNT_2.iter().skip(1) { - // print!("{}", bit); let (r2, coeff) = MNT6::

::doubling_step_for_flipped_miller_loop(&r); g2p.double_coefficients.push(coeff); r = r2; From f56cce383781980f4cf8480383c22dc421698282 Mon Sep 17 00:00:00 2001 From: Marcin Date: Fri, 19 Aug 2022 19:04:26 +0200 Subject: [PATCH 13/19] rename back to ATE_LOOP_COUNT_2 --- ec/src/models/mnt4/g2.rs | 2 +- ec/src/models/mnt4/mod.rs | 4 ++-- ec/src/models/mnt6/g2.rs | 2 +- ec/src/models/mnt6/mod.rs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ec/src/models/mnt4/g2.rs b/ec/src/models/mnt4/g2.rs index 02a270db2..6afaf8947 100644 --- a/ec/src/models/mnt4/g2.rs +++ b/ec/src/models/mnt4/g2.rs @@ -56,7 +56,7 @@ impl From> for G2Prepared

{ }; let neg_g2 = g2.neg(); - for bit in P::ATE_LOOP_COUNT_2.iter().skip(1) { + for bit in P::ATE_LOOP_COUNT.iter().skip(1) { let (r2, coeff) = MNT4::

::doubling_step_for_flipped_miller_loop(&r); g2p.double_coefficients.push(coeff); r = r2; diff --git a/ec/src/models/mnt4/mod.rs b/ec/src/models/mnt4/mod.rs index 213ef820a..7ceb6c627 100644 --- a/ec/src/models/mnt4/mod.rs +++ b/ec/src/models/mnt4/mod.rs @@ -25,7 +25,7 @@ pub type GT

= Fp4

; pub trait MNT4Parameters: 'static { const TWIST: Fp2; const TWIST_COEFF_A: Fp2; - const ATE_LOOP_COUNT_2: &'static [i8]; + const ATE_LOOP_COUNT: &'static [i8]; const ATE_IS_LOOP_COUNT_NEG: bool; const FINAL_EXPONENT_LAST_CHUNK_1: ::BigInt; const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool; @@ -111,7 +111,7 @@ impl MNT4

{ // code below gets executed for all bits (EXCEPT the MSB itself) of // mnt6_param_p (skipping leading zeros) in MSB to LSB order let y_over_twist_neg = -q.y_over_twist; - for (bit, dc) in P::ATE_LOOP_COUNT_2 + for (bit, dc) in P::ATE_LOOP_COUNT .iter() .skip(1) .zip(&q.double_coefficients) diff --git a/ec/src/models/mnt6/g2.rs b/ec/src/models/mnt6/g2.rs index d78d544df..9834dc682 100644 --- a/ec/src/models/mnt6/g2.rs +++ b/ec/src/models/mnt6/g2.rs @@ -56,7 +56,7 @@ impl From> for G2Prepared

{ }; let neg_g2 = g2.neg(); - for bit in P::ATE_LOOP_COUNT_2.iter().skip(1) { + for bit in P::ATE_LOOP_COUNT.iter().skip(1) { let (r2, coeff) = MNT6::

::doubling_step_for_flipped_miller_loop(&r); g2p.double_coefficients.push(coeff); r = r2; diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index a428e86ff..0d0e347d3 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -25,7 +25,7 @@ pub type GT

= Fp6

; pub trait MNT6Parameters: 'static { const TWIST: Fp3; const TWIST_COEFF_A: Fp3; - const ATE_LOOP_COUNT_2: &'static [i8]; + const ATE_LOOP_COUNT: &'static [i8]; const ATE_IS_LOOP_COUNT_NEG: bool; const FINAL_EXPONENT_LAST_CHUNK_1: ::BigInt; const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool; @@ -113,7 +113,7 @@ impl MNT6

{ // code below gets executed for all bits (EXCEPT the MSB itself) of // mnt6_param_p (skipping leading zeros) in MSB to LSB order let y_over_twist_neg = -q.y_over_twist; - for (bit, dc) in P::ATE_LOOP_COUNT_2 + for (bit, dc) in P::ATE_LOOP_COUNT .iter() .skip(1) .zip(&q.double_coefficients) From e8b4d5072ad6083e9a5014d96d271f081738f371 Mon Sep 17 00:00:00 2001 From: Marcin Date: Fri, 19 Aug 2022 19:05:46 +0200 Subject: [PATCH 14/19] format and remove unused imports --- ec/src/models/mnt4/mod.rs | 8 ++------ ec/src/models/mnt6/mod.rs | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/ec/src/models/mnt4/mod.rs b/ec/src/models/mnt4/mod.rs index 7ceb6c627..de658d376 100644 --- a/ec/src/models/mnt4/mod.rs +++ b/ec/src/models/mnt4/mod.rs @@ -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}; @@ -111,11 +111,7 @@ impl MNT4

{ // code below gets executed for all bits (EXCEPT the MSB itself) of // mnt6_param_p (skipping leading zeros) in MSB to LSB order let y_over_twist_neg = -q.y_over_twist; - for (bit, dc) in P::ATE_LOOP_COUNT - .iter() - .skip(1) - .zip(&q.double_coefficients) - { + 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, diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index 0d0e347d3..1cc1636e7 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -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}; @@ -113,11 +113,7 @@ impl MNT6

{ // code below gets executed for all bits (EXCEPT the MSB itself) of // mnt6_param_p (skipping leading zeros) in MSB to LSB order let y_over_twist_neg = -q.y_over_twist; - for (bit, dc) in P::ATE_LOOP_COUNT - .iter() - .skip(1) - .zip(&q.double_coefficients) - { + 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, From e098ec63341e48c238ea3f83589370503ad7d2e6 Mon Sep 17 00:00:00 2001 From: Weikeng Chen Date: Sat, 27 Aug 2022 11:25:50 -0700 Subject: [PATCH 15/19] Apply suggestions from code review --- ec/src/models/mnt4/g2.rs | 5 +++-- ec/src/models/mnt4/mod.rs | 5 ++++- ec/src/models/mnt6/g2.rs | 3 ++- ec/src/models/mnt6/mod.rs | 5 ++++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ec/src/models/mnt4/g2.rs b/ec/src/models/mnt4/g2.rs index 6afaf8947..ff9ac672d 100644 --- a/ec/src/models/mnt4/g2.rs +++ b/ec/src/models/mnt4/g2.rs @@ -1,4 +1,4 @@ -use core::ops::Neg; +use ark_std::ops::Neg; use crate::{ mnt4::MNT4Parameters, @@ -73,7 +73,8 @@ impl From> for G2Prepared

{ &neg_g2.x, &neg_g2.y, &r, ); }, - _ => continue, + 0 => continue, + _ => unimplemented!() } g2p.addition_coefficients.push(add_coeff); r = r_temp; diff --git a/ec/src/models/mnt4/mod.rs b/ec/src/models/mnt4/mod.rs index de658d376..861b270d2 100644 --- a/ec/src/models/mnt4/mod.rs +++ b/ec/src/models/mnt4/mod.rs @@ -111,6 +111,7 @@ impl MNT4

{ // code below gets executed for all bits (EXCEPT the MSB itself) of // mnt6_param_p (skipping leading zeros) in MSB to LSB order let y_over_twist_neg = -q.y_over_twist; + assert_eq!(P::ATE_LOOP_COUNT.len() - 1, q.double_coefficients.len()); 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, @@ -137,8 +138,10 @@ impl MNT4

{ ac.c_rz * &p.y_twist, -(y_over_twist_neg * &ac.c_rz + &(l1_coeff * &ac.c_l1)), ); - } else { + } else if *bit == 0 { continue; + } else { + unimplemented!(); } f *= &g_rq_at_p; } diff --git a/ec/src/models/mnt6/g2.rs b/ec/src/models/mnt6/g2.rs index 9834dc682..d3942d81e 100644 --- a/ec/src/models/mnt6/g2.rs +++ b/ec/src/models/mnt6/g2.rs @@ -73,7 +73,8 @@ impl From> for G2Prepared

{ &neg_g2.x, &neg_g2.y, &r, ); }, - _ => continue, + 0 => continue, + _ => unimplemented!() } g2p.addition_coefficients.push(add_coeff); r = r_temp; diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index 1cc1636e7..924970591 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -113,6 +113,7 @@ impl MNT6

{ // code below gets executed for all bits (EXCEPT the MSB itself) of // mnt6_param_p (skipping leading zeros) in MSB to LSB order let y_over_twist_neg = -q.y_over_twist; + assert_eq!(P::ATE_LOOP_COUNT.len() - 1, q.double_coefficients.len()); 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), @@ -138,8 +139,10 @@ impl MNT6

{ ac.c_rz * &p.y_twist, -(y_over_twist_neg * &ac.c_rz + &(l1_coeff * &ac.c_l1)), ); - } else { + } else if *bit == 0 { continue; + } else { + unimplemented!(); } f *= &g_rq_at_p; } From 16167fe4818126d7bb432aa6d00f9d31134637a7 Mon Sep 17 00:00:00 2001 From: onewayfunc Date: Sat, 27 Aug 2022 11:28:05 -0700 Subject: [PATCH 16/19] fmt --- ec/src/models/mnt4/g2.rs | 2 +- ec/src/models/mnt6/g2.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ec/src/models/mnt4/g2.rs b/ec/src/models/mnt4/g2.rs index ff9ac672d..5384875a3 100644 --- a/ec/src/models/mnt4/g2.rs +++ b/ec/src/models/mnt4/g2.rs @@ -74,7 +74,7 @@ impl From> for G2Prepared

{ ); }, 0 => continue, - _ => unimplemented!() + _ => unimplemented!(), } g2p.addition_coefficients.push(add_coeff); r = r_temp; diff --git a/ec/src/models/mnt6/g2.rs b/ec/src/models/mnt6/g2.rs index d3942d81e..d671ff218 100644 --- a/ec/src/models/mnt6/g2.rs +++ b/ec/src/models/mnt6/g2.rs @@ -74,7 +74,7 @@ impl From> for G2Prepared

{ ); }, 0 => continue, - _ => unimplemented!() + _ => unimplemented!(), } g2p.addition_coefficients.push(add_coeff); r = r_temp; From b16ca6f080e25b24e167c751eec056e3e98efa31 Mon Sep 17 00:00:00 2001 From: onewayfunc Date: Sat, 27 Aug 2022 11:41:12 -0700 Subject: [PATCH 17/19] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 201ff90c3..a450741b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,7 @@ - Bound `AffineCurve` by - `Mul` - `for<'a> Mul<&'a ScalarField, Output = ProjectiveCurve>` +- [\#445](https://github.com/arkworks-rs/algebra/pull/445) (`ark-ec`) Change the `ATE_LOOP_COUNT` in MNT4/6 curves to use 2-NAF. - [\#446](https://github.com/arkworks-rs/algebra/pull/446) (`ark-ff`) Add `CyclotomicMultSubgroup` trait and impl for extension fields ### Features @@ -84,6 +85,7 @@ - [\#339](https://github.com/arkworks-rs/algebra/pull/339) (`ark-ff`) Remove duplicated code from `test_field` module and replace its usage with `ark-test-curves` crate. - [\#352](https://github.com/arkworks-rs/algebra/pull/352) (`ark-ff`) Update `QuadExtField::sqrt` for better performance. - [\#357](https://github.com/arkworks-rs/algebra/pull/357) (`ark-poly`) Speedup division by vanishing polynomials for dense polynomials. +- [\#445](https://github.com/arkworks-rs/algebra/pull/445) (`ark-ec`) Use 2-NAF for ate pairing in MNT4/6 curves. ### Bugfixes From 99ccfe8566a47a8b1954c3063e2c0d4520e0f4c9 Mon Sep 17 00:00:00 2001 From: Weikeng Chen Date: Sat, 27 Aug 2022 12:48:06 -0700 Subject: [PATCH 18/19] Apply suggestions from code review --- ec/src/models/mnt4/g2.rs | 2 +- ec/src/models/mnt4/mod.rs | 2 +- ec/src/models/mnt6/g2.rs | 2 +- ec/src/models/mnt6/mod.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ec/src/models/mnt4/g2.rs b/ec/src/models/mnt4/g2.rs index 5384875a3..4a1779d2c 100644 --- a/ec/src/models/mnt4/g2.rs +++ b/ec/src/models/mnt4/g2.rs @@ -74,7 +74,7 @@ impl From> for G2Prepared

{ ); }, 0 => continue, - _ => unimplemented!(), + _ => unreachable!(), } g2p.addition_coefficients.push(add_coeff); r = r_temp; diff --git a/ec/src/models/mnt4/mod.rs b/ec/src/models/mnt4/mod.rs index 861b270d2..88b3301b4 100644 --- a/ec/src/models/mnt4/mod.rs +++ b/ec/src/models/mnt4/mod.rs @@ -141,7 +141,7 @@ impl MNT4

{ } else if *bit == 0 { continue; } else { - unimplemented!(); + unreachable!(); } f *= &g_rq_at_p; } diff --git a/ec/src/models/mnt6/g2.rs b/ec/src/models/mnt6/g2.rs index d671ff218..3ab957fae 100644 --- a/ec/src/models/mnt6/g2.rs +++ b/ec/src/models/mnt6/g2.rs @@ -74,7 +74,7 @@ impl From> for G2Prepared

{ ); }, 0 => continue, - _ => unimplemented!(), + _ => unreachable!(), } g2p.addition_coefficients.push(add_coeff); r = r_temp; diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index 924970591..e74f8be5b 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -142,7 +142,7 @@ impl MNT6

{ } else if *bit == 0 { continue; } else { - unimplemented!(); + unreachable!(); } f *= &g_rq_at_p; } From e79322bfc80fbcd96acab7cb0d15bc4c14885c2f Mon Sep 17 00:00:00 2001 From: Pratyush Mishra Date: Sun, 28 Aug 2022 12:53:42 -0700 Subject: [PATCH 19/19] Small cleanup and formatting --- ec/src/models/mnt4/g2.rs | 47 +++++++++++++------------------- ec/src/models/mnt4/mod.rs | 17 ++++++------ ec/src/models/mnt6/g2.rs | 56 +++++++++++++++------------------------ ec/src/models/mnt6/mod.rs | 17 ++++++------ 4 files changed, 57 insertions(+), 80 deletions(-) diff --git a/ec/src/models/mnt4/g2.rs b/ec/src/models/mnt4/g2.rs index 4a1779d2c..17898cbec 100644 --- a/ec/src/models/mnt4/g2.rs +++ b/ec/src/models/mnt4/g2.rs @@ -36,47 +36,38 @@ impl Default for G2Prepared

{ } impl From> for G2Prepared

{ - fn from(g2: G2Affine

) -> Self { + fn from(g: G2Affine

) -> Self { let twist_inv = P::TWIST.inverse().unwrap(); - let mut g2p = G2Prepared { - x: g2.x, - y: g2.y, - x_over_twist: g2.x * &twist_inv, - y_over_twist: g2.y * &twist_inv, + let mut g_prep = G2Prepared { + x: g.x, + y: g.y, + x_over_twist: g.x * &twist_inv, + y_over_twist: g.y * &twist_inv, double_coefficients: vec![], addition_coefficients: vec![], }; let mut r = G2ProjectiveExtended { - x: g2.x, - y: g2.y, + x: g.x, + y: g.y, z: >::one(), t: >::one(), }; - let neg_g2 = g2.neg(); + let neg_g = g.neg(); for bit in P::ATE_LOOP_COUNT.iter().skip(1) { - let (r2, coeff) = MNT4::

::doubling_step_for_flipped_miller_loop(&r); - g2p.double_coefficients.push(coeff); + let (r2, coeff) = MNT4::

::doubling_for_flipped_miller_loop(&r); + g_prep.double_coefficients.push(coeff); r = r2; - let add_coeff; - let r_temp; - match bit { - 1 => { - (r_temp, add_coeff) = - MNT4::

::mixed_addition_step_for_flipped_miller_loop(&g2.x, &g2.y, &r); - }, - -1 => { - (r_temp, add_coeff) = MNT4::

::mixed_addition_step_for_flipped_miller_loop( - &neg_g2.x, &neg_g2.y, &r, - ); - }, + let (r_temp, add_coeff) = match bit { + 1 => MNT4::

::mixed_addition_for_flipped_miller_loop(&g.x, &g.y, &r), + -1 => MNT4::

::mixed_addition_for_flipped_miller_loop(&neg_g.x, &neg_g.y, &r), 0 => continue, _ => unreachable!(), - } - g2p.addition_coefficients.push(add_coeff); + }; + g_prep.addition_coefficients.push(add_coeff); r = r_temp; } @@ -88,15 +79,15 @@ impl From> for G2Prepared

{ let minus_r_affine_x = r.x * &rz2_inv; let minus_r_affine_y = -r.y * &rz3_inv; - let add_result = MNT4::

::mixed_addition_step_for_flipped_miller_loop( + let add_result = MNT4::

::mixed_addition_for_flipped_miller_loop( &minus_r_affine_x, &minus_r_affine_y, &r, ); - g2p.addition_coefficients.push(add_result.1); + g_prep.addition_coefficients.push(add_result.1); } - g2p + g_prep } } diff --git a/ec/src/models/mnt4/mod.rs b/ec/src/models/mnt4/mod.rs index 88b3301b4..296f9f265 100644 --- a/ec/src/models/mnt4/mod.rs +++ b/ec/src/models/mnt4/mod.rs @@ -46,7 +46,7 @@ pub trait MNT4Parameters: 'static { pub struct MNT4(PhantomData P>); impl MNT4

{ - fn doubling_step_for_flipped_miller_loop( + fn doubling_for_flipped_miller_loop( r: &G2ProjectiveExtended

, ) -> (G2ProjectiveExtended

, AteDoubleCoefficients

) { let a = r.t.square(); @@ -75,7 +75,7 @@ impl MNT4

{ (r2, coeff) } - fn mixed_addition_step_for_flipped_miller_loop( + fn mixed_addition_for_flipped_miller_loop( x: &Fp2, y: &Fp2, r: &G2ProjectiveExtended

, @@ -121,28 +121,27 @@ impl MNT4

{ f = f.square() * &g_rr_at_p; // 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 g_rq_at_p = if *bit == 1 { let ac = &q.addition_coefficients[add_idx]; add_idx += 1; - g_rq_at_p = Fp4::new( + Fp4::new( ac.c_rz * &p.y_twist, -(q.y_over_twist * &ac.c_rz + &(l1_coeff * &ac.c_l1)), - ); + ) } else if *bit == -1 { let ac = &q.addition_coefficients[add_idx]; add_idx += 1; - g_rq_at_p = Fp4::new( + Fp4::new( ac.c_rz * &p.y_twist, -(y_over_twist_neg * &ac.c_rz + &(l1_coeff * &ac.c_l1)), - ); + ) } else if *bit == 0 { continue; } else { unreachable!(); - } + }; f *= &g_rq_at_p; } diff --git a/ec/src/models/mnt6/g2.rs b/ec/src/models/mnt6/g2.rs index 3ab957fae..d4bc50eac 100644 --- a/ec/src/models/mnt6/g2.rs +++ b/ec/src/models/mnt6/g2.rs @@ -36,47 +36,38 @@ impl Default for G2Prepared

{ } impl From> for G2Prepared

{ - fn from(g2: G2Affine

) -> Self { + fn from(g: G2Affine

) -> Self { let twist_inv = P::TWIST.inverse().unwrap(); - let mut g2p = G2Prepared { - x: g2.x, - y: g2.y, - x_over_twist: g2.x * &twist_inv, - y_over_twist: g2.y * &twist_inv, + let mut g_prep = G2Prepared { + x: g.x, + y: g.y, + x_over_twist: g.x * &twist_inv, + y_over_twist: g.y * &twist_inv, double_coefficients: vec![], addition_coefficients: vec![], }; let mut r = G2ProjectiveExtended { - x: g2.x, - y: g2.y, + x: g.x, + y: g.y, z: >::one(), t: >::one(), }; - let neg_g2 = g2.neg(); + let neg_g = g.neg(); for bit in P::ATE_LOOP_COUNT.iter().skip(1) { - let (r2, coeff) = MNT6::

::doubling_step_for_flipped_miller_loop(&r); - g2p.double_coefficients.push(coeff); + let (r2, coeff) = MNT6::

::doubling_for_flipped_miller_loop(&r); + g_prep.double_coefficients.push(coeff); r = r2; - let add_coeff; - let r_temp; - match bit { - 1 => { - (r_temp, add_coeff) = - MNT6::

::mixed_addition_step_for_flipped_miller_loop(&g2.x, &g2.y, &r); - }, - -1 => { - (r_temp, add_coeff) = MNT6::

::mixed_addition_step_for_flipped_miller_loop( - &neg_g2.x, &neg_g2.y, &r, - ); - }, + let (r_temp, add_coeff) = match bit { + 1 => MNT6::

::mixed_addition_for_flipper_miller_loop(&g.x, &g.y, &r), + -1 => MNT6::

::mixed_addition_for_flipper_miller_loop(&neg_g.x, &neg_g.y, &r), 0 => continue, _ => unreachable!(), - } - g2p.addition_coefficients.push(add_coeff); + }; + g_prep.addition_coefficients.push(add_coeff); r = r_temp; } @@ -85,18 +76,15 @@ impl From> for G2Prepared

{ let rz2_inv = rz_inv.square(); let rz3_inv = rz_inv * &rz2_inv; - let minus_r_affine_x = r.x * &rz2_inv; - let minus_r_affine_y = -r.y * &rz3_inv; + let minus_r_x = r.x * &rz2_inv; + let minus_r_y = -r.y * &rz3_inv; - let add_result = MNT6::

::mixed_addition_step_for_flipped_miller_loop( - &minus_r_affine_x, - &minus_r_affine_y, - &r, - ); - g2p.addition_coefficients.push(add_result.1); + let add_result = + MNT6::

::mixed_addition_for_flipper_miller_loop(&minus_r_x, &minus_r_y, &r); + g_prep.addition_coefficients.push(add_result.1); } - g2p + g_prep } } diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index e74f8be5b..a79cd0ee3 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -46,7 +46,7 @@ pub trait MNT6Parameters: 'static { pub struct MNT6(PhantomData P>); impl MNT6

{ - fn doubling_step_for_flipped_miller_loop( + fn doubling_for_flipped_miller_loop( r: &G2ProjectiveExtended

, ) -> (G2ProjectiveExtended

, AteDoubleCoefficients

) { let a = r.t.square(); @@ -76,7 +76,7 @@ impl MNT6

{ (r2, coeff) } - fn mixed_addition_step_for_flipped_miller_loop( + fn mixed_addition_for_flipper_miller_loop( x: &Fp3, y: &Fp3, r: &G2ProjectiveExtended

, @@ -123,27 +123,26 @@ impl MNT6

{ f = f.square() * &g_rr_at_p; // 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 g_rq_at_p = if *bit == 1 { let ac = &q.addition_coefficients[add_idx]; add_idx += 1; - g_rq_at_p = Fp6::new( + Fp6::new( ac.c_rz * &p.y_twist, -(q.y_over_twist * &ac.c_rz + &(l1_coeff * &ac.c_l1)), - ); + ) } else if *bit == -1 { let ac = &q.addition_coefficients[add_idx]; add_idx += 1; - g_rq_at_p = Fp6::new( + Fp6::new( ac.c_rz * &p.y_twist, -(y_over_twist_neg * &ac.c_rz + &(l1_coeff * &ac.c_l1)), - ); + ) } else if *bit == 0 { continue; } else { unreachable!(); - } + }; f *= &g_rq_at_p; }