From 69a9c3513bfe94ebd03efaa0ac49d63ea4afbc3a Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Tue, 10 Jan 2023 13:59:32 +0100 Subject: [PATCH] More NIST curves (#142) Co-authored-by: Pratyush Mishra --- Cargo.toml | 4 ++- secp256r1/Cargo.toml | 30 +++++++++++++++++ secp256r1/LICENSE-APACHE | 1 + secp256r1/LICENSE-MIT | 1 + secp256r1/src/constraints/curves.rs | 10 ++++++ secp256r1/src/constraints/fields.rs | 11 +++++++ secp256r1/src/constraints/mod.rs | 7 ++++ secp256r1/src/curves/mod.rs | 50 +++++++++++++++++++++++++++++ secp256r1/src/curves/tests.rs | 4 +++ secp256r1/src/fields/fq.rs | 7 ++++ secp256r1/src/fields/fr.rs | 7 ++++ secp256r1/src/fields/mod.rs | 8 +++++ secp256r1/src/fields/tests.rs | 5 +++ secp256r1/src/lib.rs | 29 +++++++++++++++++ secp384r1/Cargo.toml | 30 +++++++++++++++++ secp384r1/LICENSE-APACHE | 1 + secp384r1/LICENSE-MIT | 1 + secp384r1/src/constraints/curves.rs | 10 ++++++ secp384r1/src/constraints/fields.rs | 11 +++++++ secp384r1/src/constraints/mod.rs | 7 ++++ secp384r1/src/curves/mod.rs | 50 +++++++++++++++++++++++++++++ secp384r1/src/curves/tests.rs | 4 +++ secp384r1/src/fields/fq.rs | 7 ++++ secp384r1/src/fields/fr.rs | 7 ++++ secp384r1/src/fields/mod.rs | 8 +++++ secp384r1/src/fields/tests.rs | 5 +++ secp384r1/src/lib.rs | 29 +++++++++++++++++ 27 files changed, 343 insertions(+), 1 deletion(-) create mode 100644 secp256r1/Cargo.toml create mode 120000 secp256r1/LICENSE-APACHE create mode 120000 secp256r1/LICENSE-MIT create mode 100644 secp256r1/src/constraints/curves.rs create mode 100644 secp256r1/src/constraints/fields.rs create mode 100644 secp256r1/src/constraints/mod.rs create mode 100644 secp256r1/src/curves/mod.rs create mode 100755 secp256r1/src/curves/tests.rs create mode 100644 secp256r1/src/fields/fq.rs create mode 100644 secp256r1/src/fields/fr.rs create mode 100644 secp256r1/src/fields/mod.rs create mode 100644 secp256r1/src/fields/tests.rs create mode 100644 secp256r1/src/lib.rs create mode 100644 secp384r1/Cargo.toml create mode 120000 secp384r1/LICENSE-APACHE create mode 120000 secp384r1/LICENSE-MIT create mode 100644 secp384r1/src/constraints/curves.rs create mode 100644 secp384r1/src/constraints/fields.rs create mode 100644 secp384r1/src/constraints/mod.rs create mode 100644 secp384r1/src/curves/mod.rs create mode 100755 secp384r1/src/curves/tests.rs create mode 100644 secp384r1/src/fields/fq.rs create mode 100644 secp384r1/src/fields/fr.rs create mode 100644 secp384r1/src/fields/mod.rs create mode 100644 secp384r1/src/fields/tests.rs create mode 100644 secp384r1/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index a0fccb8..1844ec6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,8 @@ members = [ "vesta", "secp256k1", + "secp256r1", + "secp384r1", "secq256k1", "curve25519", @@ -69,4 +71,4 @@ ark-ec = { git = "https://github.com/arkworks-rs/algebra/" } ark-poly = { git = "https://github.com/arkworks-rs/algebra/" } ark-serialize = { git = "https://github.com/arkworks-rs/algebra/" } ark-algebra-test-templates = { git = "https://github.com/arkworks-rs/algebra/" } -ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std/" } \ No newline at end of file +ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std/" } diff --git a/secp256r1/Cargo.toml b/secp256r1/Cargo.toml new file mode 100644 index 0000000..71be0c4 --- /dev/null +++ b/secp256r1/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "ark-secp256r1" +version = "0.4.0-alpha" +authors = [ "arkworks contributors" ] +description = "The secp256r1 curve" +homepage = "https://arkworks.rs" +repository = "https://github.com/arkworks-rs/curves" +documentation = "https://docs.rs/ark-secp256r1/" +keywords = ["cryptography", "finite-fields", "elliptic-curves" ] +categories = ["cryptography"] +include = ["Cargo.toml", "src", "LICENSE-APACHE", "LICENSE-MIT"] +license = "MIT/Apache-2.0" +edition = "2021" + +[dependencies] +ark-ff = { version = "0.4.0-alpha", default-features = false } +ark-ec = { version = "0.4.0-alpha", default-features = false } +ark-r1cs-std = { version = "0.4.0-alpha", default-features = false, optional = true } +ark-std = { version = "0.4.0-alpha", default-features = false } + +[dev-dependencies] +ark-relations = { version = "0.4.0-alpha", default-features = false } +ark-serialize = { version = "0.4.0-alpha", default-features = false } +ark-algebra-test-templates = { version = "0.4.0-alpha", 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" ] diff --git a/secp256r1/LICENSE-APACHE b/secp256r1/LICENSE-APACHE new file mode 120000 index 0000000..965b606 --- /dev/null +++ b/secp256r1/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/secp256r1/LICENSE-MIT b/secp256r1/LICENSE-MIT new file mode 120000 index 0000000..76219eb --- /dev/null +++ b/secp256r1/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/secp256r1/src/constraints/curves.rs b/secp256r1/src/constraints/curves.rs new file mode 100644 index 0000000..faff0cb --- /dev/null +++ b/secp256r1/src/constraints/curves.rs @@ -0,0 +1,10 @@ +use crate::{constraints::FqVar, *}; +use ark_r1cs_std::groups::curves::short_weierstrass::ProjectiveVar; + +/// A group element in the secp256r1 curve. +pub type GVar = ProjectiveVar; + +#[test] +fn test() { + ark_curve_constraint_tests::curves::sw_test::().unwrap(); +} diff --git a/secp256r1/src/constraints/fields.rs b/secp256r1/src/constraints/fields.rs new file mode 100644 index 0000000..aa806e3 --- /dev/null +++ b/secp256r1/src/constraints/fields.rs @@ -0,0 +1,11 @@ +use ark_r1cs_std::fields::fp::FpVar; + +use crate::fq::Fq; + +/// A variable that is the R1CS equivalent of `crate::Fq`. +pub type FqVar = FpVar; + +#[test] +fn test() { + ark_curve_constraint_tests::fields::field_test::<_, _, FqVar>().unwrap(); +} diff --git a/secp256r1/src/constraints/mod.rs b/secp256r1/src/constraints/mod.rs new file mode 100644 index 0000000..9bbb38a --- /dev/null +++ b/secp256r1/src/constraints/mod.rs @@ -0,0 +1,7 @@ +//! This module implements the R1CS equivalent of `ark_secp256r1`. + +mod curves; +mod fields; + +pub use curves::*; +pub use fields::*; diff --git a/secp256r1/src/curves/mod.rs b/secp256r1/src/curves/mod.rs new file mode 100644 index 0000000..140c28e --- /dev/null +++ b/secp256r1/src/curves/mod.rs @@ -0,0 +1,50 @@ +use ark_ec::{ + models::CurveConfig, + short_weierstrass::{self as sw, SWCurveConfig}, +}; +use ark_ff::{Field, MontFp}; + +use crate::{fq::Fq, fr::Fr}; + +#[cfg(test)] +mod tests; + +pub type Affine = sw::Affine; +pub type Projective = sw::Projective; + +#[derive(Copy, Clone, Default, PartialEq, Eq)] +pub struct Config; + +impl CurveConfig for Config { + type BaseField = Fq; + type ScalarField = Fr; + + /// COFACTOR = 1 + const COFACTOR: &'static [u64] = &[0x1]; + + /// COFACTOR_INV = COFACTOR^{-1} mod r = 1 + #[rustfmt::skip] + const COFACTOR_INV: Fr = Fr::ONE; +} + +impl SWCurveConfig for Config { + /// COEFF_A = -3 + const COEFF_A: Fq = MontFp!("-3"); + + /// COEFF_B = 41058363725152142129326129780047268409114441015993725554835256314039467401291 + const COEFF_B: Fq = + MontFp!("41058363725152142129326129780047268409114441015993725554835256314039467401291"); + + /// GENERATOR = (G_GENERATOR_X, G_GENERATOR_Y) + const GENERATOR: Affine = Affine::new_unchecked(G_GENERATOR_X, G_GENERATOR_Y); +} + +/// G_GENERATOR_X = +/// 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 +pub const G_GENERATOR_X: Fq = + MontFp!("48439561293906451759052585252797914202762949526041747995844080717082404635286"); + +/// G_GENERATOR_Y = +/// 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5 +pub const G_GENERATOR_Y: Fq = + MontFp!("36134250956749795798585127919587881956611106672985015071877198253568414405109"); diff --git a/secp256r1/src/curves/tests.rs b/secp256r1/src/curves/tests.rs new file mode 100755 index 0000000..f7bc50c --- /dev/null +++ b/secp256r1/src/curves/tests.rs @@ -0,0 +1,4 @@ +use crate::Projective; +use ark_algebra_test_templates::*; + +test_group!(g1; Projective; sw); diff --git a/secp256r1/src/fields/fq.rs b/secp256r1/src/fields/fq.rs new file mode 100644 index 0000000..c03197a --- /dev/null +++ b/secp256r1/src/fields/fq.rs @@ -0,0 +1,7 @@ +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; + +#[derive(MontConfig)] +#[modulus = "115792089210356248762697446949407573530086143415290314195533631308867097853951"] +#[generator = "2"] +pub struct FqConfig; +pub type Fq = Fp256>; diff --git a/secp256r1/src/fields/fr.rs b/secp256r1/src/fields/fr.rs new file mode 100644 index 0000000..7992bbc --- /dev/null +++ b/secp256r1/src/fields/fr.rs @@ -0,0 +1,7 @@ +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; + +#[derive(MontConfig)] +#[modulus = "115792089210356248762697446949407573529996955224135760342422259061068512044369"] +#[generator = "11"] +pub struct FrConfig; +pub type Fr = Fp256>; diff --git a/secp256r1/src/fields/mod.rs b/secp256r1/src/fields/mod.rs new file mode 100644 index 0000000..5156179 --- /dev/null +++ b/secp256r1/src/fields/mod.rs @@ -0,0 +1,8 @@ +pub mod fq; +pub use self::fq::*; + +pub mod fr; +pub use self::fr::*; + +#[cfg(test)] +mod tests; diff --git a/secp256r1/src/fields/tests.rs b/secp256r1/src/fields/tests.rs new file mode 100644 index 0000000..bd978b4 --- /dev/null +++ b/secp256r1/src/fields/tests.rs @@ -0,0 +1,5 @@ +use crate::{Fq, Fr}; +use ark_algebra_test_templates::*; + +test_field!(fr; Fr; mont_prime_field); +test_field!(fq; Fq; mont_prime_field); diff --git a/secp256r1/src/lib.rs b/secp256r1/src/lib.rs new file mode 100644 index 0000000..ab90d4e --- /dev/null +++ b/secp256r1/src/lib.rs @@ -0,0 +1,29 @@ +#![cfg_attr(not(feature = "std"), no_std)] +#![deny( + warnings, + unused, + future_incompatible, + nonstandard_style, + rust_2018_idioms +)] +#![forbid(unsafe_code)] + +//! This library implements the secp256r1 curve. +//! Source: +//! +//! Curve information: +//! * Base field: q = +//! 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff +//! * Scalar field: r = +//! 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 +//! * a = -3 +//! * b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b +//! * Curve equation: y^2 = x^3 + ax + b + +#[cfg(feature = "r1cs")] +pub mod constraints; +mod curves; +mod fields; + +pub use curves::*; +pub use fields::*; diff --git a/secp384r1/Cargo.toml b/secp384r1/Cargo.toml new file mode 100644 index 0000000..6b86f23 --- /dev/null +++ b/secp384r1/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "ark-secp384r1" +version = "0.4.0-alpha" +authors = [ "arkworks contributors" ] +description = "The secp384r1 curve" +homepage = "https://arkworks.rs" +repository = "https://github.com/arkworks-rs/curves" +documentation = "https://docs.rs/ark-secp384r1/" +keywords = ["cryptography", "finite-fields", "elliptic-curves" ] +categories = ["cryptography"] +include = ["Cargo.toml", "src", "LICENSE-APACHE", "LICENSE-MIT"] +license = "MIT/Apache-2.0" +edition = "2021" + +[dependencies] +ark-ff = { version = "0.4.0-alpha", default-features = false } +ark-ec = { version = "0.4.0-alpha", default-features = false } +ark-r1cs-std = { version = "0.4.0-alpha", default-features = false, optional = true } +ark-std = { version = "0.4.0-alpha", default-features = false } + +[dev-dependencies] +ark-relations = { version = "0.4.0-alpha", default-features = false } +ark-serialize = { version = "0.4.0-alpha", default-features = false } +ark-algebra-test-templates = { version = "0.4.0-alpha", 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" ] diff --git a/secp384r1/LICENSE-APACHE b/secp384r1/LICENSE-APACHE new file mode 120000 index 0000000..965b606 --- /dev/null +++ b/secp384r1/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/secp384r1/LICENSE-MIT b/secp384r1/LICENSE-MIT new file mode 120000 index 0000000..76219eb --- /dev/null +++ b/secp384r1/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/secp384r1/src/constraints/curves.rs b/secp384r1/src/constraints/curves.rs new file mode 100644 index 0000000..74f1993 --- /dev/null +++ b/secp384r1/src/constraints/curves.rs @@ -0,0 +1,10 @@ +use crate::{constraints::FqVar, *}; +use ark_r1cs_std::groups::curves::short_weierstrass::ProjectiveVar; + +/// A group element in the secp384r1 curve. +pub type GVar = ProjectiveVar; + +#[test] +fn test() { + ark_curve_constraint_tests::curves::sw_test::().unwrap(); +} diff --git a/secp384r1/src/constraints/fields.rs b/secp384r1/src/constraints/fields.rs new file mode 100644 index 0000000..aa806e3 --- /dev/null +++ b/secp384r1/src/constraints/fields.rs @@ -0,0 +1,11 @@ +use ark_r1cs_std::fields::fp::FpVar; + +use crate::fq::Fq; + +/// A variable that is the R1CS equivalent of `crate::Fq`. +pub type FqVar = FpVar; + +#[test] +fn test() { + ark_curve_constraint_tests::fields::field_test::<_, _, FqVar>().unwrap(); +} diff --git a/secp384r1/src/constraints/mod.rs b/secp384r1/src/constraints/mod.rs new file mode 100644 index 0000000..8554fb7 --- /dev/null +++ b/secp384r1/src/constraints/mod.rs @@ -0,0 +1,7 @@ +//! This module implements the R1CS equivalent of `ark_secp384r1`. + +mod curves; +mod fields; + +pub use curves::*; +pub use fields::*; diff --git a/secp384r1/src/curves/mod.rs b/secp384r1/src/curves/mod.rs new file mode 100644 index 0000000..04f2724 --- /dev/null +++ b/secp384r1/src/curves/mod.rs @@ -0,0 +1,50 @@ +use ark_ec::{ + models::CurveConfig, + short_weierstrass::{self as sw, SWCurveConfig}, +}; +use ark_ff::{Field, MontFp}; + +use crate::{fq::Fq, fr::Fr}; + +#[cfg(test)] +mod tests; + +pub type Affine = sw::Affine; +pub type Projective = sw::Projective; + +#[derive(Copy, Clone, Default, PartialEq, Eq)] +pub struct Config; + +impl CurveConfig for Config { + type BaseField = Fq; + type ScalarField = Fr; + + /// COFACTOR = 1 + const COFACTOR: &'static [u64] = &[0x1]; + + /// COFACTOR_INV = COFACTOR^{-1} mod r = 1 + #[rustfmt::skip] + const COFACTOR_INV: Fr = Fr::ONE; +} + +impl SWCurveConfig for Config { + /// COEFF_A = -3 + const COEFF_A: Fq = MontFp!("-3"); + + /// COEFF_B = 27580193559959705877849011840389048093056905856361568521428707301988689241309860865136260764883745107765439761230575 + const COEFF_B: Fq = + MontFp!("27580193559959705877849011840389048093056905856361568521428707301988689241309860865136260764883745107765439761230575"); + + /// GENERATOR = (G_GENERATOR_X, G_GENERATOR_Y) + const GENERATOR: Affine = Affine::new_unchecked(G_GENERATOR_X, G_GENERATOR_Y); +} + +/// G_GENERATOR_X = +/// 26247035095799689268623156744566981891852923491109213387815615900925518854738050089022388053975719786650872476732087 +pub const G_GENERATOR_X: Fq = + MontFp!("26247035095799689268623156744566981891852923491109213387815615900925518854738050089022388053975719786650872476732087"); + +/// G_GENERATOR_Y = +/// 8325710961489029985546751289520108179287853048861315594709205902480503199884419224438643760392947333078086511627871 +pub const G_GENERATOR_Y: Fq = + MontFp!("8325710961489029985546751289520108179287853048861315594709205902480503199884419224438643760392947333078086511627871"); diff --git a/secp384r1/src/curves/tests.rs b/secp384r1/src/curves/tests.rs new file mode 100755 index 0000000..f7bc50c --- /dev/null +++ b/secp384r1/src/curves/tests.rs @@ -0,0 +1,4 @@ +use crate::Projective; +use ark_algebra_test_templates::*; + +test_group!(g1; Projective; sw); diff --git a/secp384r1/src/fields/fq.rs b/secp384r1/src/fields/fq.rs new file mode 100644 index 0000000..569acba --- /dev/null +++ b/secp384r1/src/fields/fq.rs @@ -0,0 +1,7 @@ +use ark_ff::fields::{Fp384, MontBackend, MontConfig}; + +#[derive(MontConfig)] +#[modulus = "39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319"] +#[generator = "2"] +pub struct FqConfig; +pub type Fq = Fp384>; diff --git a/secp384r1/src/fields/fr.rs b/secp384r1/src/fields/fr.rs new file mode 100644 index 0000000..06d66f7 --- /dev/null +++ b/secp384r1/src/fields/fr.rs @@ -0,0 +1,7 @@ +use ark_ff::fields::{Fp384, MontBackend, MontConfig}; + +#[derive(MontConfig)] +#[modulus = "39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643"] +#[generator = "2"] +pub struct FrConfig; +pub type Fr = Fp384>; diff --git a/secp384r1/src/fields/mod.rs b/secp384r1/src/fields/mod.rs new file mode 100644 index 0000000..5156179 --- /dev/null +++ b/secp384r1/src/fields/mod.rs @@ -0,0 +1,8 @@ +pub mod fq; +pub use self::fq::*; + +pub mod fr; +pub use self::fr::*; + +#[cfg(test)] +mod tests; diff --git a/secp384r1/src/fields/tests.rs b/secp384r1/src/fields/tests.rs new file mode 100644 index 0000000..bd978b4 --- /dev/null +++ b/secp384r1/src/fields/tests.rs @@ -0,0 +1,5 @@ +use crate::{Fq, Fr}; +use ark_algebra_test_templates::*; + +test_field!(fr; Fr; mont_prime_field); +test_field!(fq; Fq; mont_prime_field); diff --git a/secp384r1/src/lib.rs b/secp384r1/src/lib.rs new file mode 100644 index 0000000..2df8975 --- /dev/null +++ b/secp384r1/src/lib.rs @@ -0,0 +1,29 @@ +#![cfg_attr(not(feature = "std"), no_std)] +#![deny( + warnings, + unused, + future_incompatible, + nonstandard_style, + rust_2018_idioms +)] +#![forbid(unsafe_code)] + +//! This library implements the secp384r1 curve. +//! Source: +//! +//! Curve information: +//! * Base field: q = +//! 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff +//! * Scalar field: r = +//! 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973 +//! * a = -3 +//! * b = 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef +//! * Curve equation: y^2 = x^3 + ax + b + +#[cfg(feature = "r1cs")] +pub mod constraints; +mod curves; +mod fields; + +pub use curves::*; +pub use fields::*;