Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Curve: Secp256k1 #52

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
2 changes: 2 additions & 0 deletions zkp-toolkit/curve/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ full = [
"jubjub",
"baby_jubjub",
"curve25519",
"secp256k1",
]

bls12_377 = []
Expand All @@ -53,6 +54,7 @@ mnt6_753 = []
jubjub = ["bls12_381"]
baby_jubjub = ["bn_256"]
curve25519 = ["curve25519-dalek", "rand", "subtle", "zeroize", "sha2"]
secp256k1 = []

std = [ "math/std" ]
parallel = [ "std", "math/parallel" ]
7 changes: 7 additions & 0 deletions zkp-toolkit/curve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,12 @@ pub mod curve25519;
pub use curve25519::Curve25519;
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "secp256k1")]
pub mod secp256k1;
#[cfg(feature = "secp256k1")]
pub use secp256k1::Secp256k1;
///////////////////////////////////////////////////////////////////////////////

#[cfg(test)]
pub(crate) mod tests;
65 changes: 65 additions & 0 deletions zkp-toolkit/curve/src/secp256k1/fq.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use math::{
biginteger::BigInteger320 as BigInteger,
fields::{Fp320, Fp320Parameters, FpParameters},
};

pub type Fq = Fp320<FqParameters>;

pub struct FqParameters;

impl Fp320Parameters for FqParameters {}

impl FpParameters for FqParameters {
type BigInt = BigInteger;

/// Constant representing the modulus
/// p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
/// 115792089237316195423570985008687907853269984665640564039457584007908834671663
const MODULUS: BigInteger = BigInteger([
18446744069414583343u64,
18446744073709551615u64,
18446744073709551615u64,
18446744073709551615u64,
0u64,
]);

/// 256
const MODULUS_BITS: u32 = 256;

const CAPACITY: u32 = Self::MODULUS_BITS - 1;

const REPR_SHAVE_BITS: u32 = 64;

/// R = 2^256 mod q
const R: BigInteger = BigInteger([0u64, 4294968273u64, 0u64, 0u64, 0u64]);

/// R^2 = 2^512 mod q
const R2: BigInteger = BigInteger([0u64, 0u64, 8392367050913u64, 1u64, 0u64]);

/// INV = -(q^{-1} mod 2^64) mod 2^64
const INV: u64 = 15580212934572586289u64;

/// GENERATOR = 4
const GENERATOR: BigInteger = BigInteger([0u64, 17179873092u64, 0u64, 0u64, 0u64]);

/// 2^s ? s=1
const TWO_ADICITY: u32 = 1;

/// 2^s root of unity computed by GENERATOR^t TODO
const ROOT_OF_UNITY: BigInteger = BigInteger([0u64, 4294968273u64, 0u64, 0u64, 0u64]);

/// (Self::MODULUS - 1) / 2
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
18446744071562067479u64,
18446744073709551615u64,
18446744073709551615u64,
9223372036854775807u64,
0u64,
]);

/// t for 2^s * t = MODULUS - 1
const T: BigInteger = BigInteger([0, 0, 0, 0, 0]);

/// (t - 1) / 2
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([0, 0, 0, 0, 0]);
}
101 changes: 101 additions & 0 deletions zkp-toolkit/curve/src/secp256k1/fr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use math::{
biginteger::BigInteger320 as BigInteger,
fields::{Fp320, Fp320Parameters, FpParameters},
};

pub type Fr = Fp320<FrParameters>;

pub struct FrParameters;

impl Fp320Parameters for FrParameters {}

impl FpParameters for FrParameters {
type BigInt = BigInteger;

/// Constant representing the modulus
/// r = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
/// 115792089237316195423570985008687907852837564279074904382605163141518161494337
const MODULUS: BigInteger = BigInteger([
13822214165235122497u64,
13451932020343611451u64,
18446744073709551614u64,
18446744073709551615u64,
0u64,
]);

/// 256
const MODULUS_BITS: u32 = 256;

const CAPACITY: u32 = Self::MODULUS_BITS - 1;

const REPR_SHAVE_BITS: u32 = 64;

/// R = 2^256 mod q
const R: BigInteger = BigInteger([
0u64,
4624529908474429119u64,
4994812053365940164u64,
1u64,
0u64,
]);

/// R^2 = 2^512 mod q
const R2: BigInteger = BigInteger([
2161815027462274937u64,
647662477280039658u64,
2865435121925625427u64,
4330881270917637700u64,
0u64,
]);

/// INV = -(q^{-1} mod 2^64) mod 2^64
const INV: u64 = 5408259542528602431u64;

/// GENERATOR = 4
const GENERATOR: BigInteger = BigInteger([
0u64,
51375560188164860u64,
1532504139754209041u64,
5u64,
0u64,
]);

/// 2^s ? s=6
const TWO_ADICITY: u32 = 6;

/// 2^s root of unity computed by GENERATOR^t TODO
const ROOT_OF_UNITY: BigInteger = BigInteger([
0u64,
4624529908474429119u64,
4994812053365940164u64,
1u64,
0u64,
]);

/// (Self::MODULUS - 1) / 2
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
16134479119472337056u64,
6725966010171805725u64,
18446744073709551615u64,
9223372036854775807u64,
0u64,
]);

/// t for 2^s * t = MODULUS - 1
const T: BigInteger = BigInteger([
17221564289282791685u64,
18080469759223997056u64,
18446744073709551615u64,
288230376151711743u64,
0u64,
]);

/// (t - 1) / 2
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
15996384504856031752u64,
17714195444738442497u64,
18446744073709551615u64,
576460752303423487u64,
0u64,
]);
}
64 changes: 64 additions & 0 deletions zkp-toolkit/curve/src/secp256k1/group.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::{
biginteger::BigInteger320 as BigInteger,
curves::{
models::{ModelParameters, SWModelParameters},
short_weierstrass_jacobian::{GroupAffine, GroupProjective},
},
field_new,
};

use super::fq::Fq;
use super::fr::Fr;

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

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

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

impl SWModelParameters for Parameters {
/// COEFF_A = 0
const COEFF_A: Fq = field_new!(Fq, BigInteger([0, 0, 0, 0, 0]));

/// COEFF_B = 7
const COEFF_B: Fq = field_new!(Fq, BigInteger([0, 30064777911, 0, 0, 0]));

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

/// COFACTOR^(-1) mod r =
const COFACTOR_INV: Fr = field_new!(Fr, BigInteger([0, 4294968273, 0, 0, 0]));

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

/// G1_GENERATOR_X = 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
pub const G1_GENERATOR_X: Fq = field_new!(
Fq,
BigInteger([
13963525493596086728,
15507633334770469156,
2530505477788034779,
10925531211367256732,
0
])
);

/// G1_GENERATOR_Y = 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8
pub const G1_GENERATOR_Y: Fq = field_new!(
Fq,
BigInteger([
14272066994263577270,
12780836220428825624,
10231155108014310989,
8121878653926228278,
0
])
);
20 changes: 20 additions & 0 deletions zkp-toolkit/curve/src/secp256k1/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
mod fq;
mod fr;
mod group;

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

#[derive(Serialize, Deserialize, Clone)]
pub struct Secp256k1;

impl math::Curve for Secp256k1 {
type Fq = Fq;
type Fr = Fr;
type Affine = Affine;
type Projective = Projective;
}

#[cfg(test)]
mod tests;
70 changes: 70 additions & 0 deletions zkp-toolkit/curve/src/secp256k1/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use math::{curves::AffineCurve, fields::Field, test_rng};

use crate::tests::fields::{field_test, primefield_test};
use crate::tests::{curves::*, groups::*};

use super::*;

use core::str::FromStr;
use rand::Rng;

#[test]
fn test_fr() {
let mut rng = test_rng();
let a: Fr = rng.gen();
let b: Fr = rng.gen();
field_test(a, b);
primefield_test::<Fr>();
}

#[test]
fn test_fq() {
let mut rng = test_rng();
let a: Fq = rng.gen();
let b: Fq = rng.gen();
field_test(a, b);
primefield_test::<Fq>();
}

#[test]
fn precompute() {
let b = Fq::from(2u64);
println!("coeff_b: {:?}", b);

let g_x = Fq::from_str(
"55066263022277343669578718895168534326250603453777594175500187360389116729240",
)
.unwrap();
println!("g_x: {:?}", g_x);

let g_y = Fq::from_str(
"32670510020758816978083085130507043184471273380659243275938904335757337482424",
)
.unwrap();
println!("g_y: {:?}", g_y);

let inv = Fq::from(1u64);
println!("{:?}", inv.inverse());
}

#[test]
fn test_projective_curve() {
curve_tests::<Projective>();
}

#[test]
fn test_projective_group() {
let mut rng = test_rng();
let a = rng.gen();
let b = rng.gen();
for _i in 0..100 {
group_test::<Projective>(a, b);
}
}

#[test]
fn test_generator() {
let generator = Affine::prime_subgroup_generator();
assert!(generator.is_on_curve());
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
}
2 changes: 1 addition & 1 deletion zkp-toolkit/curve/src/tests/fields.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#![allow(unused)]
use crate::{
curves::flags::{Flags, SWFlags},
fields::{Field, LegendreSymbol, PrimeField, SquareRootField},
io::Cursor,
curves::flags::{Flags, SWFlags},
};
use rand::{Rng, SeedableRng};
use rand_xorshift::XorShiftRng;
Expand Down
Loading