Add the secp256k1 and secq256k1 curves (#122) Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu> Co-authored-by: onewayfunc <onewayfunc@gmail.com>
Weikeng Chen w.k@berkeley.edu
Fri, 09 Dec 2022 10:41:40 -0800
28 files changed,
336 insertions(+),
2 deletions(-)
jump to
M
CHANGELOG.md
→
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
M
Cargo.toml
→
Cargo.toml
@@ -30,6 +30,9 @@
"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" }
M
curve-constraint-tests/src/lib.rs
→
curve-constraint-tests/src/lib.rs
@@ -321,8 +321,10 @@ for limb in &mut max {
*limb = u64::MAX; } - let modulus_last_limb_bits = <C::ScalarField as PrimeField>::MODULUS_BIT_SIZE % 64; - *max.last_mut().unwrap() >>= 64 - modulus_last_limb_bits; + let modulus_num_bits_mod_64 = <C::ScalarField as PrimeField>::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()
A
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" ]
A
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<Parameters, FqVar>; + +#[test] +fn test() { + ark_curve_constraint_tests::curves::sw_test::<Parameters, GVar>().unwrap(); +}
A
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<Fq>; + +#[test] +fn test() { + ark_curve_constraint_tests::fields::field_test::<_, _, FqVar>().unwrap(); +}
A
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::*;
A
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<Parameters>; +pub type Projective = sw::Projective<Parameters>; + +#[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");
A
secp256k1/src/curves/tests.rs
@@ -0,0 +1,4 @@
+use crate::Projective; +use ark_algebra_test_templates::*; + +test_group!(g1; Projective; sw);
A
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<MontBackend<FqConfig, 4>>;
A
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<MontBackend<FrConfig, 4>>;
A
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;
A
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);
A
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: <https://en.bitcoin.it/wiki/Secp256k1> +//! +//! 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::*;
A
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" ]
A
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<Parameters, FqVar>; + +#[test] +fn test() { + ark_curve_constraint_tests::curves::sw_test::<Parameters, GVar>().unwrap(); +}
A
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<Fq>; + +#[test] +fn test() { + ark_curve_constraint_tests::fields::field_test::<_, _, FqVar>().unwrap(); +}
A
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::*;
A
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<Parameters>; +pub type Projective = sw::Projective<Parameters>; + +#[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");
A
secq256k1/src/curves/tests.rs
@@ -0,0 +1,4 @@
+use crate::Projective; +use ark_algebra_test_templates::*; + +test_group!(g1; Projective; sw);
A
secq256k1/src/fields/fq.rs
@@ -0,0 +1,2 @@
+pub use ark_secp256k1::Fr as Fq; +pub use ark_secp256k1::FrConfig as FqConfig;
A
secq256k1/src/fields/fr.rs
@@ -0,0 +1,2 @@
+pub use ark_secp256k1::Fq as Fr; +pub use ark_secp256k1::FqConfig as FrConfig;
A
secq256k1/src/fields/mod.rs
@@ -0,0 +1,5 @@
+pub mod fq; +pub use self::fq::*; + +pub mod fr; +pub use self::fr::*;
A
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: <https://moderncrypto.org/mail-archive/curves/2018/000992.html> +//! +//! 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::*;