Skip to content

Commit c29a9aa

Browse files
committed
Merge branch 'master' into releases
2 parents 667ec3e + 24496c9 commit c29a9aa

File tree

30 files changed

+258
-190
lines changed

30 files changed

+258
-190
lines changed

.github/release-pr-template.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ This is a release PR for version **<%= version.actual %>**<%
99
You will still need to manually publish the cargo crate:
1010

1111
```
12-
$ make VERSION=<latest version> release
12+
$ make VERSION=<%= version.actual %> release
1313
```

ec/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ pub trait AffineRepr:
264264
/// `Self::ScalarField`.
265265
#[must_use]
266266
fn mul_by_cofactor_inv(&self) -> Self {
267-
self.mul_bigint(&Self::Config::COFACTOR_INV.into_bigint())
267+
self.mul_bigint(Self::Config::COFACTOR_INV.into_bigint())
268268
.into()
269269
}
270270
}

ec/src/models/bn/mod.rs

Lines changed: 83 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub enum TwistType {
2323
D,
2424
}
2525

26-
pub trait BnConfig: 'static {
26+
pub trait BnConfig: 'static + Sized {
2727
/// The absolute value of the BN curve parameter `X`
2828
/// (as in `q = 36 X^4 + 36 X^3 + 24 X^2 + 6 X + 1`).
2929
const X: &'static [u64];
@@ -46,65 +46,11 @@ pub trait BnConfig: 'static {
4646
BaseField = Fp2<Self::Fp2Config>,
4747
ScalarField = <Self::G1Config as CurveConfig>::ScalarField,
4848
>;
49-
}
50-
51-
pub mod g1;
52-
pub mod g2;
53-
54-
pub use self::{
55-
g1::{G1Affine, G1Prepared, G1Projective},
56-
g2::{G2Affine, G2Prepared, G2Projective},
57-
};
58-
59-
#[derive(Derivative)]
60-
#[derivative(Copy, Clone, PartialEq, Eq, Debug, Hash)]
61-
pub struct Bn<P: BnConfig>(PhantomData<fn() -> P>);
62-
63-
impl<P: BnConfig> Bn<P> {
64-
/// Evaluates the line function at point p.
65-
fn ell(f: &mut Fp12<P::Fp12Config>, coeffs: &g2::EllCoeff<P>, p: &G1Affine<P>) {
66-
let mut c0 = coeffs.0;
67-
let mut c1 = coeffs.1;
68-
let mut c2 = coeffs.2;
69-
70-
match P::TWIST_TYPE {
71-
TwistType::M => {
72-
c2.mul_assign_by_fp(&p.y);
73-
c1.mul_assign_by_fp(&p.x);
74-
f.mul_by_014(&c0, &c1, &c2);
75-
},
76-
TwistType::D => {
77-
c0.mul_assign_by_fp(&p.y);
78-
c1.mul_assign_by_fp(&p.x);
79-
f.mul_by_034(&c0, &c1, &c2);
80-
},
81-
}
82-
}
83-
84-
fn exp_by_neg_x(mut f: Fp12<P::Fp12Config>) -> Fp12<P::Fp12Config> {
85-
f = f.cyclotomic_exp(&P::X);
86-
if !P::X_IS_NEGATIVE {
87-
f.cyclotomic_inverse_in_place();
88-
}
89-
f
90-
}
91-
}
92-
93-
impl<P: BnConfig> Pairing for Bn<P> {
94-
type BaseField = <P::G1Config as CurveConfig>::BaseField;
95-
type ScalarField = <P::G1Config as CurveConfig>::ScalarField;
96-
type G1 = G1Projective<P>;
97-
type G1Affine = G1Affine<P>;
98-
type G1Prepared = G1Prepared<P>;
99-
type G2 = G2Projective<P>;
100-
type G2Affine = G2Affine<P>;
101-
type G2Prepared = G2Prepared<P>;
102-
type TargetField = Fp12<P::Fp12Config>;
10349

10450
fn multi_miller_loop(
105-
a: impl IntoIterator<Item = impl Into<Self::G1Prepared>>,
106-
b: impl IntoIterator<Item = impl Into<Self::G2Prepared>>,
107-
) -> MillerLoopOutput<Self> {
51+
a: impl IntoIterator<Item = impl Into<G1Prepared<Self>>>,
52+
b: impl IntoIterator<Item = impl Into<G2Prepared<Self>>>,
53+
) -> MillerLoopOutput<Bn<Self>> {
10854
let mut pairs = a
10955
.into_iter()
11056
.zip_eq(b)
@@ -119,44 +65,44 @@ impl<P: BnConfig> Pairing for Bn<P> {
11965

12066
let mut f = cfg_chunks_mut!(pairs, 4)
12167
.map(|pairs| {
122-
let mut f = Self::TargetField::one();
123-
for i in (1..P::ATE_LOOP_COUNT.len()).rev() {
124-
if i != P::ATE_LOOP_COUNT.len() - 1 {
68+
let mut f = <Bn<Self> as Pairing>::TargetField::one();
69+
for i in (1..Self::ATE_LOOP_COUNT.len()).rev() {
70+
if i != Self::ATE_LOOP_COUNT.len() - 1 {
12571
f.square_in_place();
12672
}
12773

12874
for (p, coeffs) in pairs.iter_mut() {
129-
Self::ell(&mut f, &coeffs.next().unwrap(), &p.0);
75+
Bn::<Self>::ell(&mut f, &coeffs.next().unwrap(), &p.0);
13076
}
13177

132-
let bit = P::ATE_LOOP_COUNT[i - 1];
78+
let bit = Self::ATE_LOOP_COUNT[i - 1];
13379
if bit == 1 || bit == -1 {
13480
for (p, coeffs) in pairs.iter_mut() {
135-
Self::ell(&mut f, &coeffs.next().unwrap(), &p.0);
81+
Bn::<Self>::ell(&mut f, &coeffs.next().unwrap(), &p.0);
13682
}
13783
}
13884
}
13985
f
14086
})
141-
.product::<Self::TargetField>();
87+
.product::<<Bn<Self> as Pairing>::TargetField>();
14288

143-
if P::X_IS_NEGATIVE {
89+
if Self::X_IS_NEGATIVE {
14490
f.cyclotomic_inverse_in_place();
14591
}
14692

14793
for (p, coeffs) in &mut pairs {
148-
Self::ell(&mut f, &coeffs.next().unwrap(), &p.0);
94+
Bn::<Self>::ell(&mut f, &coeffs.next().unwrap(), &p.0);
14995
}
15096

15197
for (p, coeffs) in &mut pairs {
152-
Self::ell(&mut f, &coeffs.next().unwrap(), &p.0);
98+
Bn::<Self>::ell(&mut f, &coeffs.next().unwrap(), &p.0);
15399
}
154100

155101
MillerLoopOutput(f)
156102
}
157103

158104
#[allow(clippy::let_and_return)]
159-
fn final_exponentiation(f: MillerLoopOutput<Self>) -> Option<PairingOutput<Self>> {
105+
fn final_exponentiation(f: MillerLoopOutput<Bn<Self>>) -> Option<PairingOutput<Bn<Self>>> {
160106
// Easy part: result = elt^((q^6-1)*(q^2+1)).
161107
// Follows, e.g., Beuchat et al page 9, by computing result as follows:
162108
// elt^((q^6-1)*(q^2+1)) = (conj(elt) * elt^(-1))^(q^2+1)
@@ -191,13 +137,13 @@ impl<P: BnConfig> Pairing for Bn<P> {
191137
//
192138
// result = elt^( 2z * ( 6z^2 + 3z + 1 ) * (q^4 - q^2 + 1)/r ).
193139

194-
let y0 = Self::exp_by_neg_x(r);
140+
let y0 = Bn::<Self>::exp_by_neg_x(r);
195141
let y1 = y0.cyclotomic_square();
196142
let y2 = y1.cyclotomic_square();
197143
let mut y3 = y2 * &y1;
198-
let y4 = Self::exp_by_neg_x(y3);
144+
let y4 = Bn::<Self>::exp_by_neg_x(y3);
199145
let y5 = y4.cyclotomic_square();
200-
let mut y6 = Self::exp_by_neg_x(y5);
146+
let mut y6 = Bn::<Self>::exp_by_neg_x(y5);
201147
y3.cyclotomic_inverse_in_place();
202148
y6.cyclotomic_inverse_in_place();
203149
let y7 = y6 * &y4;
@@ -219,3 +165,68 @@ impl<P: BnConfig> Pairing for Bn<P> {
219165
})
220166
}
221167
}
168+
169+
pub mod g1;
170+
pub mod g2;
171+
172+
pub use self::{
173+
g1::{G1Affine, G1Prepared, G1Projective},
174+
g2::{G2Affine, G2Prepared, G2Projective},
175+
};
176+
177+
#[derive(Derivative)]
178+
#[derivative(Copy, Clone, PartialEq, Eq, Debug, Hash)]
179+
pub struct Bn<P: BnConfig>(PhantomData<fn() -> P>);
180+
181+
impl<P: BnConfig> Bn<P> {
182+
/// Evaluates the line function at point p.
183+
fn ell(f: &mut Fp12<P::Fp12Config>, coeffs: &g2::EllCoeff<P>, p: &G1Affine<P>) {
184+
let mut c0 = coeffs.0;
185+
let mut c1 = coeffs.1;
186+
let mut c2 = coeffs.2;
187+
188+
match P::TWIST_TYPE {
189+
TwistType::M => {
190+
c2.mul_assign_by_fp(&p.y);
191+
c1.mul_assign_by_fp(&p.x);
192+
f.mul_by_014(&c0, &c1, &c2);
193+
},
194+
TwistType::D => {
195+
c0.mul_assign_by_fp(&p.y);
196+
c1.mul_assign_by_fp(&p.x);
197+
f.mul_by_034(&c0, &c1, &c2);
198+
},
199+
}
200+
}
201+
202+
fn exp_by_neg_x(mut f: Fp12<P::Fp12Config>) -> Fp12<P::Fp12Config> {
203+
f = f.cyclotomic_exp(P::X);
204+
if !P::X_IS_NEGATIVE {
205+
f.cyclotomic_inverse_in_place();
206+
}
207+
f
208+
}
209+
}
210+
211+
impl<P: BnConfig> Pairing for Bn<P> {
212+
type BaseField = <P::G1Config as CurveConfig>::BaseField;
213+
type ScalarField = <P::G1Config as CurveConfig>::ScalarField;
214+
type G1 = G1Projective<P>;
215+
type G1Affine = G1Affine<P>;
216+
type G1Prepared = G1Prepared<P>;
217+
type G2 = G2Projective<P>;
218+
type G2Affine = G2Affine<P>;
219+
type G2Prepared = G2Prepared<P>;
220+
type TargetField = Fp12<P::Fp12Config>;
221+
222+
fn multi_miller_loop(
223+
a: impl IntoIterator<Item = impl Into<Self::G1Prepared>>,
224+
b: impl IntoIterator<Item = impl Into<Self::G2Prepared>>,
225+
) -> MillerLoopOutput<Self> {
226+
P::multi_miller_loop(a, b)
227+
}
228+
229+
fn final_exponentiation(f: MillerLoopOutput<Self>) -> Option<PairingOutput<Self>> {
230+
P::final_exponentiation(f)
231+
}
232+
}

ec/src/models/bw6/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ impl<P: BW6Config> BW6<P> {
160160
}
161161

162162
fn exp_by_x(mut f: Fp6<P::Fp6Config>) -> Fp6<P::Fp6Config> {
163-
f = f.cyclotomic_exp(&P::X);
163+
f = f.cyclotomic_exp(P::X);
164164
if P::X_IS_NEGATIVE {
165165
f.cyclotomic_inverse_in_place();
166166
}

ec/src/models/mnt4/mod.rs

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub use self::{
2626

2727
pub type GT<P> = Fp4<P>;
2828

29-
pub trait MNT4Config: 'static {
29+
pub trait MNT4Config: 'static + Sized {
3030
const TWIST: Fp2<Self::Fp2Config>;
3131
const TWIST_COEFF_A: Fp2<Self::Fp2Config>;
3232
const ATE_LOOP_COUNT: &'static [i8];
@@ -43,6 +43,34 @@ pub trait MNT4Config: 'static {
4343
BaseField = Fp2<Self::Fp2Config>,
4444
ScalarField = <Self::G1Config as CurveConfig>::ScalarField,
4545
>;
46+
fn multi_miller_loop(
47+
a: impl IntoIterator<Item = impl Into<G1Prepared<Self>>>,
48+
b: impl IntoIterator<Item = impl Into<G2Prepared<Self>>>,
49+
) -> MillerLoopOutput<MNT4<Self>> {
50+
let pairs = a
51+
.into_iter()
52+
.zip_eq(b)
53+
.map(|(a, b)| (a.into(), b.into()))
54+
.collect::<Vec<_>>();
55+
let result = cfg_into_iter!(pairs)
56+
.map(|(a, b)| MNT4::<Self>::ate_miller_loop(&a, &b))
57+
.product();
58+
MillerLoopOutput(result)
59+
}
60+
61+
fn final_exponentiation(f: MillerLoopOutput<MNT4<Self>>) -> Option<PairingOutput<MNT4<Self>>> {
62+
let value = f.0;
63+
let value_inv = value.inverse().unwrap();
64+
let value_to_first_chunk =
65+
MNT4::<Self>::final_exponentiation_first_chunk(&value, &value_inv);
66+
let value_inv_to_first_chunk =
67+
MNT4::<Self>::final_exponentiation_first_chunk(&value_inv, &value);
68+
let result = MNT4::<Self>::final_exponentiation_last_chunk(
69+
&value_to_first_chunk,
70+
&value_inv_to_first_chunk,
71+
);
72+
Some(PairingOutput(result))
73+
}
4674
}
4775

4876
#[derive(Derivative)]
@@ -185,11 +213,11 @@ impl<P: MNT4Config> MNT4<P> {
185213
let mut elt_q = *elt;
186214
elt_q.frobenius_map_in_place(1);
187215

188-
let w1_part = elt_q.cyclotomic_exp(&P::FINAL_EXPONENT_LAST_CHUNK_1);
216+
let w1_part = elt_q.cyclotomic_exp(P::FINAL_EXPONENT_LAST_CHUNK_1);
189217
let w0_part = if P::FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG {
190-
elt_inv_clone.cyclotomic_exp(&P::FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0)
218+
elt_inv_clone.cyclotomic_exp(P::FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0)
191219
} else {
192-
elt_clone.cyclotomic_exp(&P::FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0)
220+
elt_clone.cyclotomic_exp(P::FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0)
193221
};
194222

195223
w1_part * &w0_part
@@ -211,24 +239,10 @@ impl<P: MNT4Config> Pairing for MNT4<P> {
211239
a: impl IntoIterator<Item = impl Into<Self::G1Prepared>>,
212240
b: impl IntoIterator<Item = impl Into<Self::G2Prepared>>,
213241
) -> MillerLoopOutput<Self> {
214-
let pairs = a
215-
.into_iter()
216-
.zip_eq(b)
217-
.map(|(a, b)| (a.into(), b.into()))
218-
.collect::<Vec<_>>();
219-
let result = cfg_into_iter!(pairs)
220-
.map(|(a, b)| Self::ate_miller_loop(&a, &b))
221-
.product();
222-
MillerLoopOutput(result)
242+
P::multi_miller_loop(a, b)
223243
}
224244

225245
fn final_exponentiation(f: MillerLoopOutput<Self>) -> Option<PairingOutput<Self>> {
226-
let value = f.0;
227-
let value_inv = value.inverse().unwrap();
228-
let value_to_first_chunk = Self::final_exponentiation_first_chunk(&value, &value_inv);
229-
let value_inv_to_first_chunk = Self::final_exponentiation_first_chunk(&value_inv, &value);
230-
let result =
231-
Self::final_exponentiation_last_chunk(&value_to_first_chunk, &value_inv_to_first_chunk);
232-
Some(PairingOutput(result))
246+
P::final_exponentiation(f)
233247
}
234248
}

0 commit comments

Comments
 (0)