Skip to content
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Pending

- [\#926](https://github.com/arkworks-rs/algebra/pull/926) Add the circom compatible Baby Jubjub curve
- (`ark-starkcurve`) Add 252 bit [Stark curve](https://docs.starknet.io/architecture/cryptography/#the_stark_curve).
- [\#971](https://github.com/arkworks-rs/algebra/pull/971) (`ark-ff`) Make serial_batch_inversion_and_mul public.
- Consolidated logic into `bitreverse_permutation_in_place` and made it public.
Expand Down
1 change: 1 addition & 0 deletions curves/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
members = [
"curve-constraint-tests",

"baby_jubjub",
"bls12_377",
"ed_on_bls12_377",

Expand Down
6 changes: 6 additions & 0 deletions curves/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,14 @@ This repository contains implementations of some popular elliptic curves. The cu

* [`ark-bn254`](bn254): Implements the BN254 pairing-friendly curve
* [`ark-ed-on-bn254`](ed_on_bn254): Implements a Twisted Edwards curve atop the scalar field of BN254
* [`ark-babyjubjub`](baby_jubjub): Implements Baby Jubjub, the [ERC-2494](https://eips.ethereum.org/EIPS/eip-2494)-standardized Twisted Edwards curve atop the scalar field of BN254
* [`ark-grumpkin`](grumpkin): Implements the Grumpkin curve. A curve that forms a cycle with bn254.

`ark-ed-on-bn254` and `ark-babyjubjub` are two representations of the *same* Twisted Edwards curve over the scalar field of BN254, related by an isomorphism (a rescaling of the `x` coordinate). They differ in their curve parameters and generator, and are therefore **not** interchangeable at the byte/coordinate level:

* `ark-ed-on-bn254` uses the arkworks-canonical normalized form with `a = 1` (and `d = 168696/168700 mod q`), which is slightly more efficient for in-arkworks arithmetic, together with an arkworks-specific generator.
* `ark-babyjubjub` uses the exact ERC-2494 parameters (`A = 168700`, `D = 168696`) and the standard base point defined in that spec. Prefer this crate when you need coordinates, serialized points, or test vectors that are compatible with the wider Baby Jubjub ecosystem (e.g. circomlib / iden3).

### MNT-298 cycle of curves and related curves

* [`ark-mnt4-298`](mnt4_298): Implements the MNT4-298 pairing-friendly curve. This curve forms a pairing-friendly cycle with MNT6-298
Expand Down
32 changes: 32 additions & 0 deletions curves/baby_jubjub/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "ark-babyjubjub"
version.workspace = true
authors.workspace = true
description = "The Baby Jubjub Twisted Edwards curve"
homepage.workspace = true
repository.workspace = true
documentation = "https://docs.rs/ark-babyjubjub/"
keywords.workspace = true
categories.workspace = true
include.workspace = true
license.workspace = true
edition.workspace = true

[dependencies]
ark-ff = { workspace = true }
ark-ec = { workspace = true }
ark-std = { workspace = true }
ark-r1cs-std = { workspace = true, optional = true }
ark-bn254 = { workspace = true, features = [ "scalar_field" ] }

[dev-dependencies]
ark-relations = { workspace = true }
ark-serialize = { workspace = true }
ark-algebra-test-templates = { workspace = true }
ark-curve-constraint-tests = { path = "../curve-constraint-tests" }

[features]
default = []
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std", "ark-bn254/std" ]
r1cs = ["ark-r1cs-std"]
asm = [ "ark-ff/asm" ]
1 change: 1 addition & 0 deletions curves/baby_jubjub/LICENSE-APACHE
1 change: 1 addition & 0 deletions curves/baby_jubjub/LICENSE-MIT
11 changes: 11 additions & 0 deletions curves/baby_jubjub/src/constraints/curves.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar;

use crate::{constraints::FqVar, *};

/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
pub type EdwardsVar = AffineVar<EdwardsConfig, FqVar>;

#[test]
fn test() {
ark_curve_constraint_tests::curves::te_test::<EdwardsConfig, EdwardsVar>().unwrap();
}
9 changes: 9 additions & 0 deletions curves/baby_jubjub/src/constraints/fields.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use ark_r1cs_std::fields::fp::FpVar;

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

#[test]
fn test() {
ark_curve_constraint_tests::fields::field_test::<_, _, FqVar>().unwrap();
}
8 changes: 8 additions & 0 deletions curves/baby_jubjub/src/constraints/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//! This module implements the R1CS equivalent of `ark_babyjubjub`.
//! It requires a curve that embeds Baby Jubjub curve.

mod curves;
mod fields;

pub use curves::*;
pub use fields::*;
77 changes: 77 additions & 0 deletions curves/baby_jubjub/src/curves/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use ark_ec::{
models::CurveConfig,
twisted_edwards::{Affine, MontCurveConfig, Projective, TECurveConfig},
};
use ark_ff::{Field, MontFp};

use crate::{Fq, Fr};

#[cfg(test)]
mod tests;

pub type EdwardsAffine = Affine<EdwardsConfig>;
pub type EdwardsProjective = Projective<EdwardsConfig>;

/// `Baby-JubJub` is a twisted Edwards curve. These curves have equations of the
/// form: ax² + y² = 1 + dx²y².
/// over some base finite field Fq.
///
/// Baby-JubJub's curve equation: Ax^2 + y^2 = 1 + Dx^2y^2, where
/// * A = 168700
/// * D = 168696
///
/// q = 21888242871839275222246405745257275088548364400416034343698204186575808495617
#[derive(Clone, Default, PartialEq, Eq)]
pub struct EdwardsConfig;

impl CurveConfig for EdwardsConfig {
type BaseField = Fq;
type ScalarField = Fr;

/// COFACTOR = 8
const COFACTOR: &'static [u64] = &[8];

/// COFACTOR^(-1) mod r =
/// 2394026564107420727433200628387514462817212225638746351800188703329891451411
const COFACTOR_INV: Fr =
MontFp!("2394026564107420727433200628387514462817212225638746351800188703329891451411");
}

impl TECurveConfig for EdwardsConfig {
/// COEFF_A = 168700
const COEFF_A: Fq = MontFp!("168700");

/// COEFF_D = 168696
const COEFF_D: Fq = MontFp!("168696");

/// Standard base points from <https://eips.ethereum.org/EIPS/eip-2494>.
/// Note: A base point B is used instead of a generator G satisfying B = 8 * G.
/// The Montgomery form is
/// x = 7,
/// y = 4258727773875940690362607550498304598101071202821725296872974770776423442226
/// The twisted Edwards form is
/// x = 995203441582195749578291179787384436505546430278305826713579947235728471134
/// y = 5472060717959818805561601436314318772137091100104008585924551046643952123905
const GENERATOR: EdwardsAffine = EdwardsAffine::new_unchecked(GENERATOR_X, GENERATOR_Y);

type MontCurveConfig = EdwardsConfig;
}

impl MontCurveConfig for EdwardsConfig {
/// COEFF_A = 168698
const COEFF_A: Fq = MontFp!("168698");
/// COEFF_B = 1
const COEFF_B: Fq = Fq::ONE;

type TECurveConfig = EdwardsConfig;
}

/// GENERATOR_X =
/// 5299619240641551281634865583518297030282874472190772894086521144482721001553
pub const GENERATOR_X: Fq =
MontFp!("5299619240641551281634865583518297030282874472190772894086521144482721001553");

/// GENERATOR_Y =
/// 16950150798460657717958625567821834550301663161624707787222815936182638968203
pub const GENERATOR_Y: Fq =
MontFp!("16950150798460657717958625567821834550301663161624707787222815936182638968203");
92 changes: 92 additions & 0 deletions curves/baby_jubjub/src/curves/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
use crate::*;
use ark_algebra_test_templates::*;

test_group!(te; EdwardsProjective; te);

/// Worked test vectors taken directly from ERC-2494 (EIP-2494), the Baby Jubjub
/// specification: <https://eips.ethereum.org/EIPS/eip-2494>.
///
/// These "literature tests" pin the implementation to the concrete numeric
/// examples given in the standard, complementing the generic, property-based
/// tests generated by `test_group!` above.
mod eip2494 {
use crate::{EdwardsAffine, EdwardsConfig, Fr};
use ark_ec::{twisted_edwards::TECurveConfig, AffineRepr};
use ark_ff::{MontFp, PrimeField};

/// The neutral element of the group is `O = (0, 1)`.
fn identity() -> EdwardsAffine {
EdwardsAffine::new_unchecked(MontFp!("0"), MontFp!("1"))
}

/// EIP-2494 "Addition of points" worked example.
#[test]
fn test_point_addition() {
let p1 = EdwardsAffine::new_unchecked(
MontFp!(
"17777552123799933955779906779655732241715742912184938656739573121738514868268"
),
MontFp!("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
);
let p2 = EdwardsAffine::new_unchecked(
MontFp!(
"16540640123574156134436876038791482806971768689494387082833631921987005038935"
),
MontFp!(
"20819045374670962167435360035096875258406992893633759881276124905556507972311"
),
);
let expected = EdwardsAffine::new_unchecked(
MontFp!("7916061937171219682591368294088513039687205273691143098332585753343424131937"),
MontFp!(
"14035240266687799601661095864649209771790948434046947201833777492504781204499"
),
);
assert_eq!(p1 + p2, expected.into_group());
}

/// EIP-2494 "Doubling a point" worked example.
#[test]
fn test_point_doubling() {
let p1 = EdwardsAffine::new_unchecked(
MontFp!(
"17777552123799933955779906779655732241715742912184938656739573121738514868268"
),
MontFp!("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
);
let expected = EdwardsAffine::new_unchecked(
MontFp!("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
MontFp!("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
);
assert_eq!(p1 + p1, expected.into_group());
}

/// EIP-2494 membership examples: `O = (0, 1)` is on the curve, `(1, 0)` is not.
#[test]
fn test_on_curve() {
assert!(identity().is_on_curve());
let off_curve = EdwardsAffine::new_unchecked(MontFp!("1"), MontFp!("0"));
assert!(!off_curve.is_on_curve());
}

/// EIP-2494 defines the base point `B = 8 * G`, where `G` is the generator of
/// the full curve group. Arkworks uses this prime-order base point `B` as its
/// `GENERATOR`, so multiplying `G` by the cofactor 8 must recover it.
#[test]
fn test_base_point_is_eight_times_generator() {
let g = EdwardsAffine::new_unchecked(
MontFp!("995203441582195749578291179787384436505546430278305826713579947235728471134"),
MontFp!("5472060717959818805561601436314318772137091100104008585924551046643952123905"),
);
assert_eq!(g.mul_bigint([8u64]), EdwardsConfig::GENERATOR.into_group());
}

/// EIP-2494: the base point `B` has prime order `l` (the scalar field
/// modulus), so `l * B` yields the neutral element `O`.
#[test]
fn test_base_point_order() {
let b = EdwardsConfig::GENERATOR;
assert!(b.is_in_correct_subgroup_assuming_on_curve());
assert_eq!(b.mul_bigint(Fr::MODULUS), identity().into_group());
}
}
8 changes: 8 additions & 0 deletions curves/baby_jubjub/src/fields/fq.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use ark_ff::fields::{Fp256, MontBackend, MontConfig};

#[derive(MontConfig)]
#[modulus = "21888242871839275222246405745257275088548364400416034343698204186575808495617"]
#[generator = "5"]

pub struct FqConfig;
pub type Fq = Fp256<MontBackend<FqConfig, 4>>;
8 changes: 8 additions & 0 deletions curves/baby_jubjub/src/fields/fr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use ark_ff::fields::{Fp256, MontBackend, MontConfig};

#[derive(MontConfig)]
#[modulus = "2736030358979909402780800718157159386076813972158567259200215660948447373041"]
#[generator = "31"]

pub struct FrConfig;
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;
8 changes: 8 additions & 0 deletions curves/baby_jubjub/src/fields/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pub mod fq;
pub mod fr;

pub use fq::*;
pub use fr::*;

#[cfg(test)]
mod tests;
Loading
Loading