Skip to content

Commit

Permalink
Refactor curve and pairing traits (#447)
Browse files Browse the repository at this point in the history
Co-authored-by: Weikeng Chen <[email protected]>
Co-authored-by: Marcin Gorny <[email protected]>
Co-authored-by: Dev Ojha <[email protected]>
  • Loading branch information
4 people authored Aug 31, 2022
1 parent 77fb6ab commit fc7dc3e
Show file tree
Hide file tree
Showing 76 changed files with 4,682 additions and 5,012 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,40 @@ jobs:
--all-features"
if: matrix.rust == 'nightly'

test_assembly:
name: Test assembly
runs-on: ubuntu-latest
env:
RUSTFLAGS: -Dwarnings
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Install Rust nightly
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true

- uses: actions/cache@v2
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

- name: Test assembly on nightly
env:
RUSTFLAGS: -C target-cpu=native
uses: actions-rs/cargo@v1
with:
command: test
args: "--workspace \
--package ark-test-curves \
--all-features"

check_no_std:
name: Check no_std
runs-on: ubuntu-latest
Expand Down
16 changes: 8 additions & 8 deletions bench-templates/src/macros/ec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ macro_rules! ec_bench {
let mut count = 0;
b.iter(|| {
let mut tmp = v[count].0;
n_fold!(tmp, v, add_assign_mixed, count);
n_fold!(tmp, v, add_assign, count);
count = (count + 1) % SAMPLES;
tmp
});
}

fn deser(b: &mut $crate::bencher::Bencher) {
use ark_ec::ProjectiveCurve;
use ark_ec::CurveGroup;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
const SAMPLES: usize = 1000;

Expand All @@ -128,7 +128,7 @@ macro_rules! ec_bench {
}

fn ser(b: &mut $crate::bencher::Bencher) {
use ark_ec::ProjectiveCurve;
use ark_ec::CurveGroup;
use ark_serialize::CanonicalSerialize;
const SAMPLES: usize = 1000;

Expand All @@ -137,7 +137,7 @@ macro_rules! ec_bench {
let mut v: Vec<_> = (0..SAMPLES)
.map(|_| <$projective>::rand(&mut rng))
.collect();
let v = <$projective>::batch_normalization_into_affine(v.as_mut_slice());
let v = <$projective>::normalize_batch(v.as_mut_slice());
let mut bytes = Vec::with_capacity(1000);

let mut count = 0;
Expand All @@ -150,7 +150,7 @@ macro_rules! ec_bench {
}

fn deser_unchecked(b: &mut $crate::bencher::Bencher) {
use ark_ec::ProjectiveCurve;
use ark_ec::CurveGroup;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
const SAMPLES: usize = 1000;

Expand Down Expand Up @@ -184,7 +184,7 @@ macro_rules! ec_bench {
let mut v: Vec<_> = (0..SAMPLES)
.map(|_| <$projective>::rand(&mut rng))
.collect();
let v = <$projective>::batch_normalization_into_affine(v.as_mut_slice());
let v = <$projective>::normalize_batch(v.as_mut_slice());
let mut bytes = Vec::with_capacity(1000);

let mut count = 0;
Expand All @@ -197,7 +197,7 @@ macro_rules! ec_bench {
}

fn deser_uncompressed(b: &mut $crate::bencher::Bencher) {
use ark_ec::ProjectiveCurve;
use ark_ec::CurveGroup;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
const SAMPLES: usize = 1000;

Expand All @@ -223,7 +223,7 @@ macro_rules! ec_bench {
}

fn msm_131072(b: &mut $crate::bencher::Bencher) {
use ark_ec::msm::VariableBaseMSM;
use ark_ec::scalar_mul::variable_base::VariableBaseMSM;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
const SAMPLES: usize = 131072;

Expand Down
30 changes: 30 additions & 0 deletions bench-templates/src/macros/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ macro_rules! f_bench {
repr_add_nocarry,
repr_sub_noborrow,
repr_num_bits,
repr_from_bits_le,
repr_from_bits_be,
repr_mul2,
repr_div2,
into_repr,
Expand Down Expand Up @@ -451,5 +453,33 @@ macro_rules! prime_field {
let _ = $f::from(v[count]);
});
}

fn repr_from_bits_be(b: &mut $crate::bencher::Bencher) {
const SAMPLES: usize = 1000;
let mut rng = ark_std::test_rng();
let v = (0..SAMPLES)
.map(|_| ark_ff::BitIteratorBE::new($f_repr::rand(&mut rng)).collect::<Vec<_>>())
.collect::<Vec<_>>();
let mut count = 0;
b.iter(|| {
let mut tmp = $f_repr::from_bits_be(&v[count]);
count = (count + 1) % SAMPLES;
tmp;
});
}

fn repr_from_bits_le(b: &mut $crate::bencher::Bencher) {
const SAMPLES: usize = 1000;
let mut rng = ark_std::test_rng();
let v = (0..SAMPLES)
.map(|_| ark_ff::BitIteratorLE::new($f_repr::rand(&mut rng)).collect::<Vec<_>>())
.collect::<Vec<_>>();
let mut count = 0;
b.iter(|| {
let mut tmp = $f_repr::from_bits_le(&v[count]);
count = (count + 1) % SAMPLES;
tmp;
});
}
};
}
37 changes: 21 additions & 16 deletions bench-templates/src/macros/pairing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,71 @@
macro_rules! pairing_bench {
($curve:ident, $pairing_field:ident) => {
fn miller_loop(b: &mut $crate::bencher::Bencher) {
use ark_ec::pairing::Pairing;
const SAMPLES: usize = 1000;

let mut rng = ark_std::test_rng();

let g1s = (0..SAMPLES).map(|_| G1::rand(&mut rng)).collect::<Vec<_>>();
let g2s = (0..SAMPLES).map(|_| G2::rand(&mut rng)).collect::<Vec<_>>();
let g1s = G1::batch_normalization_into_affine(&g1s);
let g2s = G2::batch_normalization_into_affine(&g2s);
let prepared = g1s
let g1s = G1::normalize_batch(&g1s);
let g2s = G2::normalize_batch(&g2s);
let (prepared_1, prepared_2): (
Vec<<$curve as Pairing>::G1Prepared>,
Vec<<$curve as Pairing>::G2Prepared>,
) = g1s
.into_iter()
.zip(g2s)
.map(|(g1, g2)| (g1.into(), g2.into()))
.collect::<Vec<(
<$curve as PairingEngine>::G1Prepared,
<$curve as PairingEngine>::G2Prepared,
)>>();
.unzip();
let mut count = 0;
b.iter(|| {
let tmp =
$curve::miller_loop(&[(prepared[count].0.clone(), prepared[count].1.clone())]);
let tmp = $curve::multi_miller_loop(
[prepared_1[count].clone()],
[prepared_2[count].clone()],
);
count = (count + 1) % SAMPLES;
tmp
});
}

fn final_exponentiation(b: &mut $crate::bencher::Bencher) {
use ark_ec::pairing::Pairing;
const SAMPLES: usize = 1000;

let mut rng = ark_std::test_rng();

let v: Vec<_> = (0..SAMPLES)
.map(|_| {
(
G1Affine::from(G1::rand(&mut rng)).into(),
G2Affine::from(G2::rand(&mut rng)).into(),
G1Prepared::from(G1::rand(&mut rng)),
G2Prepared::from(G2::rand(&mut rng)),
)
})
.map(|(p, q)| $curve::miller_loop(&[(p, q)]))
.map(|(p, q)| $curve::multi_miller_loop([p], [q]))
.collect();

let mut count = 0;
b.iter(|| {
let tmp = $curve::final_exponentiation(&v[count]);
let tmp = $curve::final_exponentiation(v[count]);
count = (count + 1) % SAMPLES;
tmp
});
}

fn full_pairing(b: &mut $crate::bencher::Bencher) {
use ark_ec::pairing::Pairing;
const SAMPLES: usize = 1000;

let mut rng = ark_std::test_rng();

let v: Vec<(G1, G2)> = (0..SAMPLES)
let (v1, v2): (Vec<G1>, Vec<G2>) = (0..SAMPLES)
.map(|_| (G1::rand(&mut rng), G2::rand(&mut rng)))
.collect();
.unzip();

let mut count = 0;
b.iter(|| {
let tmp = $curve::pairing(v[count].0, v[count].1);
let tmp = $curve::pairing(v1[count], v2[count]);
count = (count + 1) % SAMPLES;
tmp
});
Expand Down
1 change: 1 addition & 0 deletions ec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ num-traits = { version = "0.2", default-features = false }
rayon = { version = "1", optional = true }
zeroize = { version = "1", default-features = false, features = ["zeroize_derive"] }
hashbrown = "0.12.1"
itertools = { version = "0.10", default-features = false }

[dev-dependencies]
ark-test-curves = { version = "^0.3.0", path = "../test-curves", default-features = false, features = ["bls12_381_curve"] }
Expand Down
10 changes: 5 additions & 5 deletions ec/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ Implementations of particular curves using these curve models can be found in [`

The available elliptic curve traits are:

* [`AffineCurve`](https://github.com/arkworks-rs/algebra/blob/master/ec/src/lib.rs#L223) - Interface for elliptic curve points in the 'canonical form' for serialization.
* [`ProjectiveCurve`](https://github.com/arkworks-rs/algebra/blob/master/ec/src/lib.rs#L118) - Interface for elliptic curve points in a representation that is more efficient for most computation.
* [`PairingEngine`](https://github.com/arkworks-rs/algebra/blob/master/ec/src/lib.rs#L41) - Pairing friendly elliptic curves (Contains the pairing function, and acts as a wrapper type on G1, G2, GT, and the relevant fields).
* [`AffineRepr`](https://github.com/arkworks-rs/algebra/blob/master/ec/src/lib.rs#L223) - Interface for elliptic curve points in the 'canonical form' for serialization.
* [`CurveGroup`](https://github.com/arkworks-rs/algebra/blob/master/ec/src/lib.rs#L118) - Interface for elliptic curve points in a representation that is more efficient for most computation.
* [`Pairing`](https://github.com/arkworks-rs/algebra/blob/master/ec/src/lib.rs#L41) - Pairing friendly elliptic curves (Contains the pairing function, and acts as a wrapper type on G1, G2, GT, and the relevant fields).
* [`CurveCycle`](https://github.com/arkworks-rs/algebra/blob/master/ec/src/lib.rs#L319) - Trait representing a cycle of elliptic curves.
* [`PairingFriendlyCycle`](https://github.com/arkworks-rs/algebra/blob/master/ec/src/lib.rs#L331) - Trait representing a cycle of pairing friendly elliptic curves.

The elliptic curve models implemented are:

* [*Short Weierstrass*](https://github.com/arkworks-rs/algebra/blob/master/ec/src/models/short_weierstrass.rs) curves. The `AffineCurve` in this case is in typical Short Weierstrass point representation, and the `ProjectiveCurve` is using points in [Jacobian Coordinates](https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates).
* [*Twisted Edwards*](https://github.com/arkworks-rs/algebra/blob/master/ec/src/models/twisted_edwards.rs) curves. The `AffineCurve` in this case is in standard Twisted Edwards curve representation, whereas the `ProjectiveCurve` uses points in [Extended Twisted Edwards Coordinates](https://eprint.iacr.org/2008/522.pdf).
* [*Short Weierstrass*](https://github.com/arkworks-rs/algebra/blob/master/ec/src/models/short_weierstrass.rs) curves. The `AffineRepr` in this case is in typical Short Weierstrass point representation, and the `CurveGroup` is using points in [Jacobian Coordinates](https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates).
* [*Twisted Edwards*](https://github.com/arkworks-rs/algebra/blob/master/ec/src/models/twisted_edwards.rs) curves. The `AffineRepr` in this case is in standard Twisted Edwards curve representation, whereas the `CurveGroup` uses points in [Extended Twisted Edwards Coordinates](https://eprint.iacr.org/2008/522.pdf).
13 changes: 7 additions & 6 deletions ec/src/hashing/curve_maps/swu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use core::marker::PhantomData;

use crate::{
hashing::{map_to_curve_hasher::MapToCurve, HashToCurveError},
models::short_weierstrass::Affine,
models::short_weierstrass::{Affine, Projective},
};

/// Trait defining the necessary parameters for the SWU hash-to-curve method
Expand Down Expand Up @@ -36,7 +36,7 @@ pub fn parity<F: Field>(element: &F) -> bool {
.map_or(false, |x| x.into_bigint().is_odd())
}

impl<P: SWUParams> MapToCurve<Affine<P>> for SWUMap<P> {
impl<P: SWUParams> MapToCurve<Projective<P>> for SWUMap<P> {
/// Constructs a new map if `P` represents a valid map.
fn new() -> Result<Self, HashToCurveError> {
// Verifying that ZETA is a non-square
Expand Down Expand Up @@ -155,9 +155,10 @@ impl<P: SWUParams> MapToCurve<Affine<P>> for SWUMap<P> {

#[cfg(test)]
mod test {
use crate::hashing::map_to_curve_hasher::MapToCurveBasedHasher;
use crate::hashing::HashToCurve;
use crate::CurveConfig;
use crate::{
hashing::{map_to_curve_hasher::MapToCurveBasedHasher, HashToCurve},
CurveConfig,
};
use ark_ff::field_hashers::DefaultFieldHasher;
use ark_std::vec::Vec;

Expand Down Expand Up @@ -240,7 +241,7 @@ mod test {
#[test]
fn hash_arbitary_string_to_curve_swu() {
let test_swu_to_curve_hasher = MapToCurveBasedHasher::<
Affine<TestSWUMapToCurveParams>,
Projective<TestSWUMapToCurveParams>,
DefaultFieldHasher<Sha256, 128>,
SWUMap<TestSWUMapToCurveParams>,
>::new(&[1])
Expand Down
Loading

0 comments on commit fc7dc3e

Please sign in to comment.