Skip to content
This repository has been archived by the owner on Dec 18, 2023. It is now read-only.

Support for the Pluto-Eris half-pairing cycle #54

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
`ark-mnt6-753`.
- [\#7](https://github.com/arkworks-rs/curves/pull/7) Add benchmarks for Edwards curves.
- [\#19](https://github.com/arkworks-rs/curves/pull/19) Change field constants to be provided as normal strings, instead of in Montgomery form.
- [\#53](https://github.com/arkworks-rs/curves/pull/53) Add benchmarks for Pallas and Vesta curves.
- [\#54](https://github.com/arkworks-rs/curves/pull/54) Add support for the Pluto-Eris half-pairing cycle.

### Improvements
- [\#42](https://github.com/arkworks-rs/curves/pull/42) Remove the dependency of `rand_xorshift`.
Expand All @@ -30,4 +32,4 @@

## v0.1.0

Initial Release
Initial Release
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ members = [

"pallas",
"vesta",

"pluto",
"eris",
]

[profile.release]
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,9 @@ This repository contains implementations of some popular elliptic curves. The cu
* [`ark-ed-on-mnt4-753`](ed_on_mnt4_753): Implements a Twisted Edwards curve atop the scalar field of MNT4-753

### [Pasta](https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/) cycle of curves
* [`ark-pallas`](pallas): Implements Pallas, a prime-order curve that forms an amicable pair with Vesta
* [`ark-vesta`](vesta): Implements Vesta, a prime-order curve that forms an amicable pair with Pallas
* [`ark-pallas`](pallas): Implements Pallas, a 255-bit prime-order curve that forms an amicable pair with Vesta
* [`ark-vesta`](vesta): Implements Vesta, a 255-bit prime-order curve that forms an amicable pair with Pallas

### [Pluto-Eris](https://github.com/daira/pluto-eris/) half-pairing cycle of curves
* [`ark-pluto`](pluto): Implements Pluto, a 446-bit prime-order pairing-friendly curve that forms an amicable pair with Eris
* [`ark-eris`](eris): Implements Eris, a 446-bit prime-order curve that forms an amicable pair with Pluto
27 changes: 26 additions & 1 deletion curve-benches/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ authors = [
"Matthew Green",
"Ian Miers",
"Pratyush Mishra",
"Howard Wu"
"Howard Wu",
"Daira Hopwood"
]
description = "A benchmark library for finite fields and elliptic curves"
homepage = "https://arkworks.rs"
Expand Down Expand Up @@ -42,6 +43,10 @@ ark-bls12-381 = { path = "../bls12_381" }
ark-ed-on-bls12-381 = { path = "../ed_on_bls12_381" }
ark-bw6-761 = { path = "../bw6_761" }
ark-cp6-782 = { path = "../cp6_782" }
ark-pallas = { path = "../pallas" }
ark-vesta = { path = "../vesta" }
ark-pluto = { path = "../pluto" }
ark-eris = { path = "../eris" }

[features]
asm = [ "ark-ff/asm"]
Expand Down Expand Up @@ -100,3 +105,23 @@ harness = false
name = "mnt6_753"
path = "benches/mnt6_753.rs"
harness = false

[[bench]]
name = "pallas"
path = "benches/pallas.rs"
harness = false

[[bench]]
name = "vesta"
path = "benches/vesta.rs"
harness = false

[[bench]]
name = "pluto"
path = "benches/pluto.rs"
harness = false

[[bench]]
name = "eris"
path = "benches/eris.rs"
harness = false
19 changes: 19 additions & 0 deletions curve-benches/benches/eris.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use ark_curve_benches::*;
use ark_std::ops::{AddAssign, MulAssign, SubAssign};

use ark_ec::ProjectiveCurve;
use ark_eris::{fq::Fq, fr::Fr, Affine as GAffine, Projective as G};
use ark_ff::{
biginteger::{BigInteger448 as FrRepr, BigInteger448 as FqRepr},
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
};

mod g {
use super::*;
ec_bench!(G, GAffine);
}

f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);

bencher::benchmark_main!(fq, fr, g::group_ops);
19 changes: 19 additions & 0 deletions curve-benches/benches/pallas.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use ark_curve_benches::*;
use ark_std::ops::{AddAssign, MulAssign, SubAssign};

use ark_ec::ProjectiveCurve;
use ark_ff::{
biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr},
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
};
use ark_pallas::{fq::Fq, fr::Fr, Affine as GAffine, Projective as G};

mod g {
use super::*;
ec_bench!(G, GAffine);
}

f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);

bencher::benchmark_main!(fq, fr, g::group_ops);
19 changes: 19 additions & 0 deletions curve-benches/benches/pluto.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use ark_curve_benches::*;
use ark_std::ops::{AddAssign, MulAssign, SubAssign};

use ark_ec::ProjectiveCurve;
use ark_ff::{
biginteger::{BigInteger448 as FrRepr, BigInteger448 as FqRepr},
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
};
use ark_pluto::{fq::Fq, fr::Fr, Affine as GAffine, Projective as G};

mod g {
use super::*;
ec_bench!(G, GAffine);
}

f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);

bencher::benchmark_main!(fq, fr, g::group_ops);
19 changes: 19 additions & 0 deletions curve-benches/benches/vesta.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use ark_curve_benches::*;
use ark_std::ops::{AddAssign, MulAssign, SubAssign};

use ark_ec::ProjectiveCurve;
use ark_ff::{
biginteger::{BigInteger256 as FrRepr, BigInteger256 as FqRepr},
BigInteger, Field, PrimeField, SquareRootField, UniformRand,
};
use ark_vesta::{fq::Fq, fr::Fr, Affine as GAffine, Projective as G};

mod g {
use super::*;
ec_bench!(G, GAffine);
}

f_bench!(Fq, Fq, FqRepr, FqRepr, fq);
f_bench!(Fr, Fr, FrRepr, FrRepr, fr);

bencher::benchmark_main!(fq, fr, g::group_ops);
31 changes: 31 additions & 0 deletions eris/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "ark-eris"
version = "0.2.0"
authors = [ "Daira Hopwood", "arkworks contributors" ]
description = "The Eris prime-order elliptic curve"
homepage = "https://arkworks.rs"
repository = "https://github.com/arkworks-rs/curves"
documentation = "https://docs.rs/ark-eris/"
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
categories = ["cryptography"]
include = ["Cargo.toml", "src"]
license = "MIT/Apache-2.0"
edition = "2018"

[dependencies]
ark-ff = { version = "^0.2.0", default-features = false }
ark-ec = { version = "^0.2.0", default-features = false }
ark-r1cs-std = { version = "^0.2.0", default-features = false, optional = true }
ark-std = { version = "^0.2.0", default-features = false }
ark-pluto = { version = "^0.2.0", path = "../pluto", default-features = false, features = [ "scalar_field", "base_field" ] }

[dev-dependencies]
ark-relations = { version = "^0.2.0", default-features = false }
ark-serialize = { version = "^0.2.0", default-features = false }
ark-algebra-test-templates = { version = "^0.2.0", default-features = false }
ark-curve-constraint-tests = { path = "../curve-constraint-tests", default-features = false }

[features]
default = []
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
r1cs = [ "ark-r1cs-std" ]
12 changes: 12 additions & 0 deletions eris/src/constraints/curves.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::*;
use ark_r1cs_std::groups::curves::short_weierstrass::ProjectiveVar;

use crate::constraints::FBaseVar;

/// A group element in the Eris prime-order group.
pub type GVar = ProjectiveVar<ErisParameters, FBaseVar>;

#[test]
fn test() {
ark_curve_constraint_tests::curves::sw_test::<ErisParameters, GVar>().unwrap();
}
10 changes: 10 additions & 0 deletions eris/src/constraints/fields.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use crate::fq::Fq;
use ark_r1cs_std::fields::fp::FpVar;

/// A variable that is the R1CS equivalent of `crate::Fq`.
pub type FBaseVar = FpVar<Fq>;

#[test]
fn test() {
ark_curve_constraint_tests::fields::field_test::<_, _, FBaseVar>().unwrap();
}
107 changes: 107 additions & 0 deletions eris/src/constraints/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//! This module implements the R1CS equivalent of `ark_eris`.
//!
//! It implements field variables for `crate::Fq`,
//! and group variables for `crate::GroupProjective`.
//!
//! The field underlying these constraints is `crate::Fq`.
//!
//! # Examples
//!
//! One can perform standard algebraic operations on `FBaseVar`:
//!
//! ```
//! # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> {
//! use ark_std::UniformRand;
//! use ark_relations::r1cs::*;
//! use ark_r1cs_std::prelude::*;
//! use ark_eris::{*, constraints::*};
//!
//! let cs = ConstraintSystem::<Fq>::new_ref();
//! // This rng is just for test purposes; do not use it
//! // in real applications.
//! let mut rng = ark_std::test_rng();
//!
//! // Generate some random `Fq` elements.
//! let a_native = Fq::rand(&mut rng);
//! let b_native = Fq::rand(&mut rng);
//!
//! // Allocate `a_native` and `b_native` as witness variables in `cs`.
//! let a = FBaseVar::new_witness(ark_relations::ns!(cs, "generate_a"), || Ok(a_native))?;
//! let b = FBaseVar::new_witness(ark_relations::ns!(cs, "generate_b"), || Ok(b_native))?;
//!
//! // Allocate `a_native` and `b_native` as constants in `cs`. This does not add any
//! // constraints or variables.
//! let a_const = FBaseVar::new_constant(ark_relations::ns!(cs, "a_as_constant"), a_native)?;
//! let b_const = FBaseVar::new_constant(ark_relations::ns!(cs, "b_as_constant"), b_native)?;
//!
//! let one = FBaseVar::one();
//! let zero = FBaseVar::zero();
//!
//! // Sanity check one + one = two
//! let two = &one + &one + &zero;
//! two.enforce_equal(&one.double()?)?;
//!
//! assert!(cs.is_satisfied()?);
//!
//! // Check that the value of &a + &b is correct.
//! assert_eq!((&a + &b).value()?, a_native + &b_native);
//!
//! // Check that the value of &a * &b is correct.
//! assert_eq!((&a * &b).value()?, a_native * &b_native);
//!
//! // Check that operations on variables and constants are equivalent.
//! (&a + &b).enforce_equal(&(&a_const + &b_const))?;
//! assert!(cs.is_satisfied()?);
//! # Ok(())
//! # }
//! ```
//!
//! One can also perform standard algebraic operations on `GVar`:
//!
//! ```
//! # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> {
//! # use ark_std::UniformRand;
//! # use ark_relations::r1cs::*;
//! # use ark_r1cs_std::prelude::*;
//! # use ark_eris::{*, constraints::*};
//!
//! # let cs = ConstraintSystem::<Fq>::new_ref();
//! # let mut rng = ark_std::test_rng();
//!
//! // Generate some random `Projective` elements.
//! let a_native = Projective::rand(&mut rng);
//! let b_native = Projective::rand(&mut rng);
//!
//! // Allocate `a_native` and `b_native` as witness variables in `cs`.
//! let a = GVar::new_witness(ark_relations::ns!(cs, "a"), || Ok(a_native))?;
//! let b = GVar::new_witness(ark_relations::ns!(cs, "b"), || Ok(b_native))?;
//!
//! // Allocate `a_native` and `b_native` as constants in `cs`. This does not add any
//! // constraints or variables.
//! let a_const = GVar::new_constant(ark_relations::ns!(cs, "a_as_constant"), a_native)?;
//! let b_const = GVar::new_constant(ark_relations::ns!(cs, "b_as_constant"), b_native)?;
//!
//! // This returns the identity.
//! let zero = GVar::zero();
//!
//! // Sanity check one + one = two
//! let two_a = &a + &a + &zero;
//! two_a.enforce_equal(&a.double()?)?;
//!
//! assert!(cs.is_satisfied()?);
//!
//! // Check that the value of &a + &b is correct.
//! assert_eq!((&a + &b).value()?, a_native + &b_native);
//!
//! // Check that operations on variables and constants are equivalent.
//! (&a + &b).enforce_equal(&(&a_const + &b_const))?;
//! assert!(cs.is_satisfied()?);
//! # Ok(())
//! # }
//! ```

mod curves;
mod fields;

pub use curves::*;
pub use fields::*;
51 changes: 51 additions & 0 deletions eris/src/curves/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use crate::{fq::Fq, fr::Fr};
use ark_ec::{
models::{ModelParameters, SWModelParameters},
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
};
use ark_ff::{field_new, Zero};

#[cfg(test)]
mod tests;

#[derive(Copy, Clone, Default, PartialEq, Eq)]
pub struct ErisParameters;

impl ModelParameters for ErisParameters {
type BaseField = Fq;
type ScalarField = Fr;
}

pub type Affine = GroupAffine<ErisParameters>;
pub type Projective = GroupProjective<ErisParameters>;

impl SWModelParameters for ErisParameters {
/// COEFF_A = 0
const COEFF_A: Fq = field_new!(Fq, "0");

/// COEFF_B = 57
const COEFF_B: Fq = field_new!(Fq, "57");

/// COFACTOR = 1
const COFACTOR: &'static [u64] = &[0x1];

/// COFACTOR_INV = 1
const COFACTOR_INV: Fr = field_new!(Fr, "1");

/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) =
(G_GENERATOR_X, G_GENERATOR_Y);

#[inline(always)]
fn mul_by_a(_: &Self::BaseField) -> Self::BaseField {
Self::BaseField::zero()
}
}

/// G_GENERATOR_X = -2
/// Encoded in Montgomery form, so the value here is -R mod p.
pub const G_GENERATOR_X: Fq = field_new!(Fq, "-2");

/// G_GENERATOR_Y = 7
/// Encoded in Montgomery form, so the value here is 2R mod p.
pub const G_GENERATOR_Y: Fq = field_new!(Fq, "7");
Loading