From 1778ee138cb833ea9b7aaf0c0164edd461c4ae40 Mon Sep 17 00:00:00 2001 From: sun Date: Wed, 23 Dec 2020 14:28:20 +0800 Subject: [PATCH 1/2] merge secp256k1 --- zkp-toolkit/curve/Cargo.toml | 4 +- zkp-toolkit/curve/src/lib.rs | 5 ++ zkp-toolkit/curve/src/secp256k1/fq.rs | 65 +++++++++++++++ zkp-toolkit/curve/src/secp256k1/fr.rs | 101 +++++++++++++++++++++++ zkp-toolkit/curve/src/secp256k1/group.rs | 64 ++++++++++++++ zkp-toolkit/curve/src/secp256k1/mod.rs | 20 +++++ zkp-toolkit/curve/src/secp256k1/tests.rs | 76 +++++++++++++++++ zkp-toolkit/curve/src/tests/fields.rs | 2 +- zkp-toolkit/math/src/fields/macros.rs | 42 ++++++---- zkp-toolkit/scheme/Cargo.toml | 2 +- zkp-toolkit/scheme/tests/mini.rs | 4 +- 11 files changed, 365 insertions(+), 20 deletions(-) create mode 100644 zkp-toolkit/curve/src/secp256k1/fq.rs create mode 100644 zkp-toolkit/curve/src/secp256k1/fr.rs create mode 100644 zkp-toolkit/curve/src/secp256k1/group.rs create mode 100644 zkp-toolkit/curve/src/secp256k1/mod.rs create mode 100644 zkp-toolkit/curve/src/secp256k1/tests.rs diff --git a/zkp-toolkit/curve/Cargo.toml b/zkp-toolkit/curve/Cargo.toml index 04a10d7..0e88ce6 100644 --- a/zkp-toolkit/curve/Cargo.toml +++ b/zkp-toolkit/curve/Cargo.toml @@ -22,7 +22,7 @@ rand = { version = "0.7", default-features = false } rand_xorshift = "0.2" [features] -default = [ "std" ] +default = [ "std", "secp256k1" ] full = [ "bls12_377", @@ -38,6 +38,7 @@ full = [ "jubjub", "baby_jubjub", "curve25519", + "secp256k1", ] bls12_377 = [] @@ -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" ] diff --git a/zkp-toolkit/curve/src/lib.rs b/zkp-toolkit/curve/src/lib.rs index 2608001..3230315 100755 --- a/zkp-toolkit/curve/src/lib.rs +++ b/zkp-toolkit/curve/src/lib.rs @@ -138,5 +138,10 @@ pub mod curve25519; pub use curve25519::Curve25519; /////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +#[cfg(feature = "secp256k1")] +pub mod secp256k1; +/////////////////////////////////////////////////////////////////////////////// + #[cfg(test)] pub(crate) mod tests; diff --git a/zkp-toolkit/curve/src/secp256k1/fq.rs b/zkp-toolkit/curve/src/secp256k1/fq.rs new file mode 100644 index 0000000..fafa6dd --- /dev/null +++ b/zkp-toolkit/curve/src/secp256k1/fq.rs @@ -0,0 +1,65 @@ +use math::{ + biginteger::BigInteger320 as BigInteger, + fields::{Fp320, Fp320Parameters, FpParameters}, +}; + +pub type Fq = Fp320; + +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 = 2; + + /// 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]); +} diff --git a/zkp-toolkit/curve/src/secp256k1/fr.rs b/zkp-toolkit/curve/src/secp256k1/fr.rs new file mode 100644 index 0000000..610bd45 --- /dev/null +++ b/zkp-toolkit/curve/src/secp256k1/fr.rs @@ -0,0 +1,101 @@ +use math::{ + biginteger::BigInteger320 as BigInteger, + fields::{Fp320, Fp320Parameters, FpParameters}, +}; + +pub type Fr = Fp320; + +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 = 32; + + /// 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, + ]); +} diff --git a/zkp-toolkit/curve/src/secp256k1/group.rs b/zkp-toolkit/curve/src/secp256k1/group.rs new file mode 100644 index 0000000..674d3ce --- /dev/null +++ b/zkp-toolkit/curve/src/secp256k1/group.rs @@ -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; +pub type Projective = GroupProjective; + +#[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 + ]) +); diff --git a/zkp-toolkit/curve/src/secp256k1/mod.rs b/zkp-toolkit/curve/src/secp256k1/mod.rs new file mode 100644 index 0000000..53897c0 --- /dev/null +++ b/zkp-toolkit/curve/src/secp256k1/mod.rs @@ -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; diff --git a/zkp-toolkit/curve/src/secp256k1/tests.rs b/zkp-toolkit/curve/src/secp256k1/tests.rs new file mode 100644 index 0000000..9d3ccde --- /dev/null +++ b/zkp-toolkit/curve/src/secp256k1/tests.rs @@ -0,0 +1,76 @@ +use math::{ + biginteger::BigInteger256 as BigInteger, + bytes::{FromBytes, ToBytes}, + curves::{AffineCurve, ProjectiveCurve}, + fields::{Field, LegendreSymbol::*, SquareRootField}, + test_rng, One, Zero, +}; + +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::(); +} + +#[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::(); +} + +#[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::(); +} + +#[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::(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()); +} diff --git a/zkp-toolkit/curve/src/tests/fields.rs b/zkp-toolkit/curve/src/tests/fields.rs index be20b9a..7f2c57b 100755 --- a/zkp-toolkit/curve/src/tests/fields.rs +++ b/zkp-toolkit/curve/src/tests/fields.rs @@ -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; diff --git a/zkp-toolkit/math/src/fields/macros.rs b/zkp-toolkit/math/src/fields/macros.rs index d10bac2..400e754 100644 --- a/zkp-toolkit/math/src/fields/macros.rs +++ b/zkp-toolkit/math/src/fields/macros.rs @@ -94,19 +94,25 @@ macro_rules! impl_Fp { *result_byte = *in_byte; } - let mask: u64 = 0xffffffffffffffff >> P::REPR_SHAVE_BITS; - // the flags will be at the same byte with the lowest shaven bits or the one after - let flags_byte_position: usize = 7 - P::REPR_SHAVE_BITS as usize / 8; - let flags_mask: u8 = ((1 << P::REPR_SHAVE_BITS % 8) - 1) << (8 - P::REPR_SHAVE_BITS % 8); - // take the last 8 bytes and pass the mask - let last_bytes = &mut result_bytes[($limbs - 1) * 8..]; - let mut flags: u8 = 0; - for (i, (b, m)) in last_bytes.iter_mut().zip(&mask.to_le_bytes()).enumerate() { - if i == flags_byte_position { - flags = *b & flags_mask + let flags = if P::REPR_SHAVE_BITS == 64 { + result_bytes.last_mut().map(|v| *v = 0); + 0 + } else { + let mask: u64 = 0xffffffffffffffff >> P::REPR_SHAVE_BITS; + // the flags will be at the same byte with the lowest shaven bits or the one after + let flags_byte_position: usize = 7 - P::REPR_SHAVE_BITS as usize / 8; + let flags_mask: u8 = ((1 << P::REPR_SHAVE_BITS % 8) - 1) << (8 - P::REPR_SHAVE_BITS % 8); + // take the last 8 bytes and pass the mask + let last_bytes = &mut result_bytes[($limbs - 1) * 8..]; + let mut flags: u8 = 0; + for (i, (b, m)) in last_bytes.iter_mut().zip(&mask.to_le_bytes()).enumerate() { + if i == flags_byte_position { + flags = *b & flags_mask + } + *b &= m; } - *b &= m; - } + flags + }; Self::read(&mut &result_bytes[..]).ok().map(|f| (f, flags)) } @@ -624,10 +630,14 @@ macro_rules! impl_prime_field_standard_sample { loop { let mut tmp = $field(rng.sample(rand::distributions::Standard), PhantomData); // Mask away the unused bits at the beginning. - tmp.0 - .as_mut() - .last_mut() - .map(|val| *val &= core::u64::MAX >> P::REPR_SHAVE_BITS); + if P::REPR_SHAVE_BITS == 64 { + tmp.0.as_mut().last_mut().map(|val| *val = 0); + } else { + tmp.0 + .as_mut() + .last_mut() + .map(|val| *val &= core::u64::MAX >> P::REPR_SHAVE_BITS); + } if tmp.is_valid() { return tmp; diff --git a/zkp-toolkit/scheme/Cargo.toml b/zkp-toolkit/scheme/Cargo.toml index b48047f..ce7550a 100644 --- a/zkp-toolkit/scheme/Cargo.toml +++ b/zkp-toolkit/scheme/Cargo.toml @@ -39,5 +39,5 @@ digest = { version = "0.8", default-features = false, optional = true } csv = { version = "1" } rand = { version = "0.7" } blake2 = { version = "0.8", default-features = false } -curve = { path = "../curve", default-features = false, features = [ "bls12_381", "bn_256", "sw6", "baby_jubjub", "curve25519" ] } +curve = { path = "../curve", default-features = false, features = [ "bls12_381", "bn_256", "sw6", "baby_jubjub", "curve25519", "secp256k1" ] } postcard = { version = "0.5", default-features = false, features = ["alloc"] } diff --git a/zkp-toolkit/scheme/tests/mini.rs b/zkp-toolkit/scheme/tests/mini.rs index f97e714..670418c 100644 --- a/zkp-toolkit/scheme/tests/mini.rs +++ b/zkp-toolkit/scheme/tests/mini.rs @@ -119,7 +119,9 @@ fn mini_marlin() { #[test] fn mini_bulletproofs() { //use curve::baby_jubjub::{BabyJubJub as G, Fr}; // size: 100%, time: 100%, 100% - use curve::curve25519::{Curve25519 as G, Fr}; // size: 71%, time: 13%, 14% + //use curve::curve25519::{Curve25519 as G, Fr}; // size: 71%, time: 13%, 14% + //use curve::secp256k1::{Fr, Secp256k1 as G}; // size: 71%, time: 13%, 14% + use curve::bn_256::{Bn_256 as G, Fr}; // size: 71%, time: 13%, 14% use scheme::bulletproofs::{create_random_proof, verify_proof}; use std::time::Instant; From 1cf1cfd7b09fddb7d5d7a489b94b0b4a8d9b3d7e Mon Sep 17 00:00:00 2001 From: sun Date: Wed, 23 Dec 2020 14:46:26 +0800 Subject: [PATCH 2/2] fix test --- zkp-toolkit/curve/Cargo.toml | 2 +- zkp-toolkit/curve/src/lib.rs | 2 ++ zkp-toolkit/curve/src/secp256k1/fq.rs | 2 +- zkp-toolkit/curve/src/secp256k1/fr.rs | 2 +- zkp-toolkit/curve/src/secp256k1/tests.rs | 8 +------- 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/zkp-toolkit/curve/Cargo.toml b/zkp-toolkit/curve/Cargo.toml index 0e88ce6..7a694d4 100644 --- a/zkp-toolkit/curve/Cargo.toml +++ b/zkp-toolkit/curve/Cargo.toml @@ -22,7 +22,7 @@ rand = { version = "0.7", default-features = false } rand_xorshift = "0.2" [features] -default = [ "std", "secp256k1" ] +default = [ "std" ] full = [ "bls12_377", diff --git a/zkp-toolkit/curve/src/lib.rs b/zkp-toolkit/curve/src/lib.rs index 3230315..a7186d1 100755 --- a/zkp-toolkit/curve/src/lib.rs +++ b/zkp-toolkit/curve/src/lib.rs @@ -141,6 +141,8 @@ pub use curve25519::Curve25519; /////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "secp256k1")] pub mod secp256k1; +#[cfg(feature = "secp256k1")] +pub use secp256k1::Secp256k1; /////////////////////////////////////////////////////////////////////////////// #[cfg(test)] diff --git a/zkp-toolkit/curve/src/secp256k1/fq.rs b/zkp-toolkit/curve/src/secp256k1/fq.rs index fafa6dd..e601f31 100644 --- a/zkp-toolkit/curve/src/secp256k1/fq.rs +++ b/zkp-toolkit/curve/src/secp256k1/fq.rs @@ -43,7 +43,7 @@ impl FpParameters for FqParameters { const GENERATOR: BigInteger = BigInteger([0u64, 17179873092u64, 0u64, 0u64, 0u64]); /// 2^s ? s=1 - const TWO_ADICITY: u32 = 2; + 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]); diff --git a/zkp-toolkit/curve/src/secp256k1/fr.rs b/zkp-toolkit/curve/src/secp256k1/fr.rs index 610bd45..b5b9e5e 100644 --- a/zkp-toolkit/curve/src/secp256k1/fr.rs +++ b/zkp-toolkit/curve/src/secp256k1/fr.rs @@ -61,7 +61,7 @@ impl FpParameters for FrParameters { ]); /// 2^s ? s=6 - const TWO_ADICITY: u32 = 32; + const TWO_ADICITY: u32 = 6; /// 2^s root of unity computed by GENERATOR^t TODO const ROOT_OF_UNITY: BigInteger = BigInteger([ diff --git a/zkp-toolkit/curve/src/secp256k1/tests.rs b/zkp-toolkit/curve/src/secp256k1/tests.rs index 9d3ccde..e1805e3 100644 --- a/zkp-toolkit/curve/src/secp256k1/tests.rs +++ b/zkp-toolkit/curve/src/secp256k1/tests.rs @@ -1,10 +1,4 @@ -use math::{ - biginteger::BigInteger256 as BigInteger, - bytes::{FromBytes, ToBytes}, - curves::{AffineCurve, ProjectiveCurve}, - fields::{Field, LegendreSymbol::*, SquareRootField}, - test_rng, One, Zero, -}; +use math::{curves::AffineCurve, fields::Field, test_rng}; use crate::tests::fields::{field_test, primefield_test}; use crate::tests::{curves::*, groups::*};