Skip to content

Commit 40585ea

Browse files
committed
Merge remote-tracking branch 'upstream/master' into vec-allocator
* upstream/master: Add a note on `add_assign_mixed` to CHANGELOG (arkworks-rs#600) Fix linting on nightly Rust (arkworks-rs#598) Build docs correctly on docs.rs (arkworks-rs#590) Set correct minimum supported Rust version (arkworks-rs#592) Add back pairing benchmarks. (arkworks-rs#586) Create test-templates/README (arkworks-rs#585) Create README.md for `bench-templates` (arkworks-rs#583) Update `master` branch to 0.4.0 (arkworks-rs#582) Unify model configs (arkworks-rs#580) Correctly evaluate over domain when `self` is zero polynomial (arkworks-rs#575) Improve `impl From<u128> for Fp` (arkworks-rs#573) should just check the top bit, not two bits (arkworks-rs#560)
2 parents c36601e + d411de4 commit 40585ea

File tree

25 files changed

+279
-193
lines changed

25 files changed

+279
-193
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
- [\#446](https://github.com/arkworks-rs/algebra/pull/446) (`ark-ff`) Add `CyclotomicMultSubgroup` trait and implement it for extension fields
7272
- [\#447](https://github.com/arkworks-rs/algebra/pull/447) (`ark-ec`, `ark-algebra-test-templates`) Rename and refactor group infrastructure, and test infrastructure for fields, groups, and pairings:
7373
- Create new `Group` trait and move some functionality from `ProjectiveCurve` to it.
74+
- Refactor `add_assign_mixed``add_assign` that's polymorphic over its RHS.
7475
- Rename `ProjectiveCurve` to `CurveGroup: Group`.
7576
- Rename some associated types:
7677
- `AffineCurve``Affine`

bench-templates/Cargo.toml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ark-algebra-bench-templates"
3-
version = "0.4.0-alpha.6"
3+
version = "0.4.0"
44
authors = [ "arkworks contributors" ]
55
description = "A benchmark library for finite fields and elliptic curves"
66
homepage = "https://arkworks.rs"
@@ -11,15 +11,16 @@ categories = ["cryptography"]
1111
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
1212
license = "MIT/Apache-2.0"
1313
edition = "2021"
14+
rust-version = "1.63"
1415

1516
################################# Dependencies ################################
1617

1718
[dependencies]
1819
criterion = { version = "0.4.0", features = [ "html_reports" ] }
19-
ark-std = { version = "0.4.0-alpha", default-features = false }
20-
ark-ec = { version = "0.4.0-alpha", path = "../ec", default-features = false }
21-
ark-ff = { version = "0.4.0-alpha", path = "../ff", default-features = false }
22-
ark-serialize = { version = "0.4.0-alpha", path = "../serialize", default-features = false }
20+
ark-std = { version = "0.4.0", default-features = false }
21+
ark-ec = { version = "0.4.0", path = "../ec", default-features = false }
22+
ark-ff = { version = "0.4.0", path = "../ff", default-features = false }
23+
ark-serialize = { version = "0.4.0", path = "../serialize", default-features = false }
2324
paste = { version = "1.0" }
2425

2526
[features]

bench-templates/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# bench-templates
2+
3+
**Warning!!!** This package does not implement any benchmarks, but exports templates and macros for benchmarking.
4+
In order to benchmark arkworks, please run `cargo bench` inside [ark-curves](https://github.com/arkworks-rs/curves).

bench-templates/src/macros/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ macro_rules! bench {
3434
[<$Fr:lower>]::benches,
3535
[<$Fq:lower>]::benches,
3636
[<$FqExt:lower>]::benches,
37-
[<$FqTarget:lower>]::benches
37+
[<$FqTarget:lower>]::benches,
38+
pairing::benches
3839
);
3940
}
4041
};

ec/Cargo.toml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ark-ec"
3-
version = "0.4.0-alpha.6"
3+
version = "0.4.0"
44
authors = [ "arkworks contributors" ]
55
description = "A library for elliptic curves and pairings"
66
homepage = "https://arkworks.rs"
@@ -11,13 +11,13 @@ categories = ["cryptography"]
1111
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
1212
license = "MIT/Apache-2.0"
1313
edition = "2021"
14-
rust-version = "1.57"
14+
rust-version = "1.63"
1515

1616
[dependencies]
17-
ark-std = { version = "0.4.0-alpha", default-features = false }
18-
ark-serialize = { version = "0.4.0-alpha", path = "../serialize", default-features = false }
19-
ark-ff = { version = "0.4.0-alpha", path = "../ff", default-features = false }
20-
ark-poly = { version = "0.4.0-alpha", path = "../poly", default-features = false }
17+
ark-std = { version = "0.4.0", default-features = false }
18+
ark-serialize = { version = "0.4.0", path = "../serialize", default-features = false }
19+
ark-ff = { version = "0.4.0", path = "../ff", default-features = false }
20+
ark-poly = { version = "0.4.0", path = "../poly", default-features = false }
2121
derivative = { version = "2", features = ["use_core"] }
2222
num-traits = { version = "0.2", default-features = false }
2323
rayon = { version = "1", optional = true }
@@ -26,7 +26,7 @@ hashbrown = "0.13.1"
2626
itertools = { version = "0.10", default-features = false }
2727

2828
[dev-dependencies]
29-
ark-test-curves = { version = "0.4.0-alpha", path = "../test-curves", default-features = false, features = ["bls12_381_curve"] }
29+
ark-test-curves = { version = "0.4.0", path = "../test-curves", default-features = false, features = ["bls12_381_curve"] }
3030
sha2 = { version = "0.10", default-features = false }
3131
libtest-mimic = "0.6.0"
3232
serde = "1.0.110"
@@ -38,3 +38,6 @@ hex = "0.4"
3838
default = []
3939
std = [ "ark-std/std", "ark-ff/std", "ark-serialize/std" ]
4040
parallel = [ "std", "rayon", "ark-std/parallel" ]
41+
42+
[package.metadata.docs.rs]
43+
rustdoc-args = ["--html-in-header", "./doc/katex-header.html"]

ec/doc/katex-header.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../doc/katex-header.html

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/mnt4/mod.rs

Lines changed: 31 additions & 17 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)]
@@ -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)