diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f7cde6..5ecea87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ### Features - [\#121](https://github.com/arkworks-rs/curves/pull/121) Add the ed25519 curve. +- [\#122](https://github.com/arkworks-rs/curves/pull/122) Add the secp256k1 and secq256k1 curves. - [\#124](https://github.com/arkworks-rs/curves/pull/124) Add the curve25519 curve. ### Improvements diff --git a/Cargo.toml b/Cargo.toml index c00b0a1..d28c365 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,9 @@ members = [ "pallas", "vesta", + "secp256k1", + "secq256k1", + "curve25519", "ed25519", ] @@ -59,3 +62,8 @@ lto = "thin" incremental = true debug-assertions = true debug = true + +[patch.crates-io] +ark-ff = { git = "https://github.com/arkworks-rs/algebra/", branch = "release-0.4" } +ark-poly = { git = "https://github.com/arkworks-rs/algebra/", branch = "release-0.4" } +ark-serialize = { git = "https://github.com/arkworks-rs/algebra/", branch = "release-0.4" } \ No newline at end of file diff --git a/curve-constraint-tests/src/lib.rs b/curve-constraint-tests/src/lib.rs index 2c281de..71af555 100644 --- a/curve-constraint-tests/src/lib.rs +++ b/curve-constraint-tests/src/lib.rs @@ -321,8 +321,10 @@ pub mod curves { *limb = u64::MAX; } - let modulus_last_limb_bits = ::MODULUS_BIT_SIZE % 64; - *max.last_mut().unwrap() >>= 64 - modulus_last_limb_bits; + let modulus_num_bits_mod_64 = ::MODULUS_BIT_SIZE % 64; + if modulus_num_bits_mod_64 != 0 { + *max.last_mut().unwrap() >>= 64 - modulus_num_bits_mod_64; + } let scalars = [ C::ScalarField::rand(&mut rng) .into_bigint() diff --git a/secp256k1/Cargo.toml b/secp256k1/Cargo.toml new file mode 100644 index 0000000..19214b2 --- /dev/null +++ b/secp256k1/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "ark-secp256k1" +version = "0.4.0-alpha.1" +authors = [ "arkworks contributors" ] +description = "The secp256k1 curve" +homepage = "https://arkworks.rs" +repository = "https://github.com/arkworks-rs/curves" +documentation = "https://docs.rs/ark-secp256k1/" +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/secp256k1/LICENSE-APACHE b/secp256k1/LICENSE-APACHE new file mode 120000 index 0000000..965b606 --- /dev/null +++ b/secp256k1/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/secp256k1/LICENSE-MIT b/secp256k1/LICENSE-MIT new file mode 120000 index 0000000..76219eb --- /dev/null +++ b/secp256k1/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/secp256k1/src/constraints/curves.rs b/secp256k1/src/constraints/curves.rs new file mode 100644 index 0000000..390d714 --- /dev/null +++ b/secp256k1/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 secp256k1 curve. +pub type GVar = ProjectiveVar; + +#[test] +fn test() { + ark_curve_constraint_tests::curves::sw_test::().unwrap(); +} diff --git a/secp256k1/src/constraints/fields.rs b/secp256k1/src/constraints/fields.rs new file mode 100644 index 0000000..aa806e3 --- /dev/null +++ b/secp256k1/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/secp256k1/src/constraints/mod.rs b/secp256k1/src/constraints/mod.rs new file mode 100644 index 0000000..b6f4a37 --- /dev/null +++ b/secp256k1/src/constraints/mod.rs @@ -0,0 +1,7 @@ +//! This module implements the R1CS equivalent of `ark_secp256k1`. + +mod curves; +mod fields; + +pub use curves::*; +pub use fields::*; diff --git a/secp256k1/src/curves/mod.rs b/secp256k1/src/curves/mod.rs new file mode 100644 index 0000000..6bf439c --- /dev/null +++ b/secp256k1/src/curves/mod.rs @@ -0,0 +1,52 @@ +use ark_ec::{ + models::CurveConfig, + short_weierstrass::{self as sw, SWCurveConfig}, +}; +use ark_ff::{Field, MontFp, Zero}; + +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 Parameters; + +impl CurveConfig for Parameters { + 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 Parameters { + /// COEFF_A = 0 + const COEFF_A: Fq = Fq::ZERO; + + /// COEFF_B = 7 + const COEFF_B: Fq = MontFp!("7"); + + /// GENERATOR = (G_GENERATOR_X, G_GENERATOR_Y) + const GENERATOR: Affine = Affine::new_unchecked(G_GENERATOR_X, G_GENERATOR_Y); + + #[inline(always)] + fn mul_by_a(_: Self::BaseField) -> Self::BaseField { + Self::BaseField::zero() + } +} + +/// G_GENERATOR_X = 55066263022277343669578718895168534326250603453777594175500187360389116729240 +pub const G_GENERATOR_X: Fq = + MontFp!("55066263022277343669578718895168534326250603453777594175500187360389116729240"); + +/// G_GENERATOR_Y = 32670510020758816978083085130507043184471273380659243275938904335757337482424 +pub const G_GENERATOR_Y: Fq = + MontFp!("32670510020758816978083085130507043184471273380659243275938904335757337482424"); diff --git a/secp256k1/src/curves/tests.rs b/secp256k1/src/curves/tests.rs new file mode 100755 index 0000000..f7bc50c --- /dev/null +++ b/secp256k1/src/curves/tests.rs @@ -0,0 +1,4 @@ +use crate::Projective; +use ark_algebra_test_templates::*; + +test_group!(g1; Projective; sw); diff --git a/secp256k1/src/fields/fq.rs b/secp256k1/src/fields/fq.rs new file mode 100644 index 0000000..eb045f2 --- /dev/null +++ b/secp256k1/src/fields/fq.rs @@ -0,0 +1,7 @@ +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; + +#[derive(MontConfig)] +#[modulus = "115792089237316195423570985008687907853269984665640564039457584007908834671663"] +#[generator = "3"] +pub struct FqConfig; +pub type Fq = Fp256>; diff --git a/secp256k1/src/fields/fr.rs b/secp256k1/src/fields/fr.rs new file mode 100644 index 0000000..cb476cb --- /dev/null +++ b/secp256k1/src/fields/fr.rs @@ -0,0 +1,7 @@ +use ark_ff::fields::{Fp256, MontBackend, MontConfig}; + +#[derive(MontConfig)] +#[modulus = "115792089237316195423570985008687907852837564279074904382605163141518161494337"] +#[generator = "7"] +pub struct FrConfig; +pub type Fr = Fp256>; diff --git a/secp256k1/src/fields/mod.rs b/secp256k1/src/fields/mod.rs new file mode 100644 index 0000000..5156179 --- /dev/null +++ b/secp256k1/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/secp256k1/src/fields/tests.rs b/secp256k1/src/fields/tests.rs new file mode 100644 index 0000000..bd978b4 --- /dev/null +++ b/secp256k1/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/secp256k1/src/lib.rs b/secp256k1/src/lib.rs new file mode 100644 index 0000000..de2254b --- /dev/null +++ b/secp256k1/src/lib.rs @@ -0,0 +1,27 @@ +#![cfg_attr(not(feature = "std"), no_std)] +#![deny( + warnings, + unused, + future_incompatible, + nonstandard_style, + rust_2018_idioms +)] +#![forbid(unsafe_code)] + +//! This library implements the secp256k1 curve. +//! Source: +//! +//! Curve information: +//! * Base field: q = +//! 115792089237316195423570985008687907853269984665640564039457584007908834671663 +//! * Scalar field: r = +//! 115792089237316195423570985008687907852837564279074904382605163141518161494337 +//! * Curve equation: y^2 = x^3 + 7 + +#[cfg(feature = "r1cs")] +pub mod constraints; +mod curves; +mod fields; + +pub use curves::*; +pub use fields::*; diff --git a/secq256k1/Cargo.toml b/secq256k1/Cargo.toml new file mode 100644 index 0000000..911d55d --- /dev/null +++ b/secq256k1/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "ark-secq256k1" +version = "0.4.0-alpha.1" +authors = [ "arkworks contributors" ] +description = "The secq256k1 curve" +homepage = "https://arkworks.rs" +repository = "https://github.com/arkworks-rs/curves" +documentation = "https://docs.rs/ark-secp256k1/" +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 } +ark-secp256k1 = { path = "../secp256k1" } + +[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/secq256k1/LICENSE-APACHE b/secq256k1/LICENSE-APACHE new file mode 120000 index 0000000..965b606 --- /dev/null +++ b/secq256k1/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/secq256k1/LICENSE-MIT b/secq256k1/LICENSE-MIT new file mode 120000 index 0000000..76219eb --- /dev/null +++ b/secq256k1/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/secq256k1/src/constraints/curves.rs b/secq256k1/src/constraints/curves.rs new file mode 100644 index 0000000..561d85c --- /dev/null +++ b/secq256k1/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 secq256k1 curve. +pub type GVar = ProjectiveVar; + +#[test] +fn test() { + ark_curve_constraint_tests::curves::sw_test::().unwrap(); +} diff --git a/secq256k1/src/constraints/fields.rs b/secq256k1/src/constraints/fields.rs new file mode 100644 index 0000000..aa806e3 --- /dev/null +++ b/secq256k1/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/secq256k1/src/constraints/mod.rs b/secq256k1/src/constraints/mod.rs new file mode 100644 index 0000000..5b34bda --- /dev/null +++ b/secq256k1/src/constraints/mod.rs @@ -0,0 +1,7 @@ +//! This module implements the R1CS equivalent of `ark_secq256k1`. + +mod curves; +mod fields; + +pub use curves::*; +pub use fields::*; diff --git a/secq256k1/src/curves/mod.rs b/secq256k1/src/curves/mod.rs new file mode 100644 index 0000000..0796dd3 --- /dev/null +++ b/secq256k1/src/curves/mod.rs @@ -0,0 +1,52 @@ +use ark_ec::{ + models::CurveConfig, + short_weierstrass::{self as sw, SWCurveConfig}, +}; +use ark_ff::{Field, MontFp, Zero}; + +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 Parameters; + +impl CurveConfig for Parameters { + 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 Parameters { + /// COEFF_A = 0 + const COEFF_A: Fq = Fq::ZERO; + + /// COEFF_B = 7 + const COEFF_B: Fq = MontFp!("7"); + + /// GENERATOR = (G_GENERATOR_X, G_GENERATOR_Y) + const GENERATOR: Affine = Affine::new_unchecked(G_GENERATOR_X, G_GENERATOR_Y); + + #[inline(always)] + fn mul_by_a(_: Self::BaseField) -> Self::BaseField { + Self::BaseField::zero() + } +} + +/// G_GENERATOR_X = 53718550993811904772965658690407829053653678808745171666022356150019200052646 +pub const G_GENERATOR_X: Fq = + MontFp!("53718550993811904772965658690407829053653678808745171666022356150019200052646"); + +/// G_GENERATOR_Y = 28941648020349172432234515805717979317553499307621291159490218670604692907903 +pub const G_GENERATOR_Y: Fq = + MontFp!("28941648020349172432234515805717979317553499307621291159490218670604692907903"); diff --git a/secq256k1/src/curves/tests.rs b/secq256k1/src/curves/tests.rs new file mode 100755 index 0000000..f7bc50c --- /dev/null +++ b/secq256k1/src/curves/tests.rs @@ -0,0 +1,4 @@ +use crate::Projective; +use ark_algebra_test_templates::*; + +test_group!(g1; Projective; sw); diff --git a/secq256k1/src/fields/fq.rs b/secq256k1/src/fields/fq.rs new file mode 100644 index 0000000..22fc089 --- /dev/null +++ b/secq256k1/src/fields/fq.rs @@ -0,0 +1,2 @@ +pub use ark_secp256k1::Fr as Fq; +pub use ark_secp256k1::FrConfig as FqConfig; diff --git a/secq256k1/src/fields/fr.rs b/secq256k1/src/fields/fr.rs new file mode 100644 index 0000000..3a597cf --- /dev/null +++ b/secq256k1/src/fields/fr.rs @@ -0,0 +1,2 @@ +pub use ark_secp256k1::Fq as Fr; +pub use ark_secp256k1::FqConfig as FrConfig; diff --git a/secq256k1/src/fields/mod.rs b/secq256k1/src/fields/mod.rs new file mode 100644 index 0000000..c78624a --- /dev/null +++ b/secq256k1/src/fields/mod.rs @@ -0,0 +1,5 @@ +pub mod fq; +pub use self::fq::*; + +pub mod fr; +pub use self::fr::*; diff --git a/secq256k1/src/lib.rs b/secq256k1/src/lib.rs new file mode 100644 index 0000000..29edd5e --- /dev/null +++ b/secq256k1/src/lib.rs @@ -0,0 +1,27 @@ +#![cfg_attr(not(feature = "std"), no_std)] +#![deny( + warnings, + unused, + future_incompatible, + nonstandard_style, + rust_2018_idioms +)] +#![forbid(unsafe_code)] + +//! This library implements the secq256k1 curve. +//! Source: +//! +//! Curve information: +//! * Base field: q = +//! 115792089237316195423570985008687907852837564279074904382605163141518161494337 +//! * Scalar field: r = +//! 115792089237316195423570985008687907853269984665640564039457584007908834671663 +//! * Curve equation: y^2 = x^3 + 7 + +#[cfg(feature = "r1cs")] +pub mod constraints; +mod curves; +mod fields; + +pub use curves::*; +pub use fields::*;