From d18269ebcaa8c7c2283847f0836d0bd47732de35 Mon Sep 17 00:00:00 2001 From: Weiliang Li Date: Wed, 18 Mar 2020 20:13:39 +0900 Subject: [PATCH] upgrade pairing (#93) * [wip] upgrade pairing * fix non mock * fix mock * derive Clone for SecretKey * fix bench and derive Clone for poly * sort Cargo.toml * fix Rng * Update mod.rs * Update lib.rs * update * update dep * update dep * bump dep * bump dep * fix test --- .travis.yml | 2 +- Cargo.toml | 31 ++++++++------- benches/bench.rs | 20 +++++----- src/cmp_pairing.rs | 2 +- src/into_fr.rs | 2 +- src/lib.rs | 97 ++++++++++++++++++++++++---------------------- src/mock/mod.rs | 70 +++++++++++++++------------------ src/mock/ms8.rs | 19 ++++----- src/poly.rs | 35 +++++------------ src/secret.rs | 5 +-- src/serde_impl.rs | 23 +++++------ src/util.rs | 9 +++++ 12 files changed, 153 insertions(+), 162 deletions(-) create mode 100644 src/util.rs diff --git a/.travis.yml b/.travis.yml index 069c0fc..24050e9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: rust rust: - - 1.39.0 + - 1.42.0 cache: cargo: true timeout: 1200 diff --git a/Cargo.toml b/Cargo.toml index a3281fa..b6e9748 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,24 +19,27 @@ description = "Pairing threshold cryptography" edition = "2018" [dependencies] -byteorder = "1.3.2" -failure = "0.1.6" +byteorder = "1.3.4" +failure = "0.1.7" +ff = "0.6.0" +group = "0.6.0" hex_fmt = "0.3.0" log = "0.4.8" -pairing = { version = "0.14.2", features = ["u128-support"] } -rand = "0.6.5" -rand04_compat = "0.1.1" -rand_chacha = "0.1.1" -serde = { version = "1.0.102", features = ["derive"] } -tiny-keccak = "1.5.0" -codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false, features = ["derive"], optional = true } -bincode = { version = "1.2", optional = true } -zeroize = "1.0" +pairing = "0.16.0" +rand = "0.7.3" +rand_chacha = "0.2.2" +serde = { version = "1.0.104", features = ["derive"] } +tiny-keccak = { version = "2.0.1", features = ["sha3"] } +zeroize = "1.1.0" + +# optional +bincode = { version = "1.2.1", optional = true } +codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"], optional = true } [dev-dependencies] -bincode = "1.2" -criterion = "0.3.0" -rand_xorshift = "0.1.1" +bincode = "1.2.1" +criterion = "0.3.1" +rand_xorshift = "0.2.0" [[bench]] name = "bench" diff --git a/benches/bench.rs b/benches/bench.rs index b576589..66646e8 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -1,4 +1,5 @@ use criterion::{criterion_group, criterion_main, Criterion}; +use ff::Field; use threshold_crypto::poly::Poly; use threshold_crypto::Fr; @@ -9,7 +10,6 @@ const RNG_SEED: [u8; 16] = *b"0123456789abcdef"; mod poly_benches { use super::*; use rand::SeedableRng; - use rand04_compat::RngExt; use rand_xorshift::XorShiftRng; /// Benchmarks multiplication of two polynomials. @@ -69,9 +69,14 @@ mod poly_benches { c.bench_function_over_inputs( "Polynomial interpolation", move |b, &°| { - let mut gen_tuple = |i: usize| (i, rng.gen04::()); - let rand_samples = move || (0..=deg).map(&mut gen_tuple).collect::>(); - b.iter_with_setup(rand_samples, Poly::interpolate) + b.iter_with_setup( + || { + (0..=deg) + .map(|i| (i, Fr::random(&mut rng))) + .collect::>() + }, + Poly::interpolate, + ) }, &TEST_DEGREES, ); @@ -100,11 +105,8 @@ mod public_key_set_benches { move |b, &&threshold| { let sk_set = SecretKeySet::random(threshold, &mut rng); let pk_set = sk_set.public_keys(); - let mut sig_parts: Vec = (0..=threshold).collect(); - let pieces: &mut [usize] = &mut sig_parts; - let sigs: BTreeMap<_, _> = pieces - .iter() - .map(|&i| { + let sigs: BTreeMap<_, _> = (0..=threshold) + .map(|i| { let sig = sk_set.secret_key_share(i).sign(msg); (i, sig) }) diff --git a/src/cmp_pairing.rs b/src/cmp_pairing.rs index 44aeff8..e383fee 100644 --- a/src/cmp_pairing.rs +++ b/src/cmp_pairing.rs @@ -1,6 +1,6 @@ use std::cmp::Ordering; -use pairing::{CurveAffine, CurveProjective}; +use group::{CurveAffine, CurveProjective}; /// Compares two curve elements and returns their `Ordering`. pub fn cmp_projective(x: &G, y: &G) -> Ordering { diff --git a/src/into_fr.rs b/src/into_fr.rs index 39f8e03..cda8419 100644 --- a/src/into_fr.rs +++ b/src/into_fr.rs @@ -1,5 +1,5 @@ use super::Fr; -use pairing::{Field, PrimeField}; +use ff::{Field, PrimeField}; /// A conversion into an element of the field `Fr`. pub trait IntoFr: Copy { diff --git a/src/lib.rs b/src/lib.rs index 236baae..8823a74 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,20 +25,21 @@ pub mod error; pub mod poly; pub mod serde_impl; +use std::borrow::Borrow; use std::cmp::Ordering; use std::fmt; use std::hash::{Hash, Hasher}; -use std::ptr::copy_nonoverlapping; +use std::vec::Vec; +use ff::Field; +use group::{CurveAffine, CurveProjective, EncodedPoint}; use hex_fmt::HexFmt; use log::debug; -use pairing::{CurveAffine, CurveProjective, EncodedPoint, Engine, Field}; +use pairing::Engine; use rand::distributions::{Distribution, Standard}; -use rand::{rngs::OsRng, Rng, SeedableRng}; -use rand04_compat::RngExt; +use rand::{rngs::OsRng, Rng, RngCore, SeedableRng}; use rand_chacha::ChaChaRng; use serde::{Deserialize, Serialize}; -use tiny_keccak::sha3_256; use zeroize::Zeroize; use crate::cmp_pairing::cmp_projective; @@ -48,6 +49,9 @@ use crate::secret::clear_fr; pub use crate::into_fr::IntoFr; +mod util; +use util::sha3_256; + #[cfg(feature = "use-insecure-test-only-mock-crypto")] mod mock; @@ -68,8 +72,6 @@ pub const PK_SIZE: usize = 48; #[cfg(not(feature = "use-insecure-test-only-mock-crypto"))] pub const SIG_SIZE: usize = 96; -const ERR_OS_RNG: &str = "could not initialize the OS random number generator"; - /// A public key. #[derive(Deserialize, Serialize, Copy, Clone, PartialEq, Eq)] pub struct PublicKey(#[serde(with = "serde_impl::projective")] G1); @@ -117,12 +119,12 @@ impl PublicKey { /// Uses the `OsRng` by default. To pass in a custom random number generator, use /// `encrypt_with_rng()`. pub fn encrypt>(&self, msg: M) -> Ciphertext { - self.encrypt_with_rng(&mut OsRng::new().expect(ERR_OS_RNG), msg) + self.encrypt_with_rng(&mut OsRng, msg) } /// Encrypts the message. - pub fn encrypt_with_rng>(&self, rng: &mut R, msg: M) -> Ciphertext { - let r: Fr = rng.gen04(); + pub fn encrypt_with_rng>(&self, rng: &mut R, msg: M) -> Ciphertext { + let r: Fr = Fr::random(rng); let u = G1Affine::one().mul(r); let v: Vec = { let g = self.0.into_affine().mul(r); @@ -211,7 +213,7 @@ impl Ord for Signature { impl Distribution for Standard { fn sample(&self, rng: &mut R) -> Signature { - Signature(rng.gen04()) + Signature(G2::random(rng)) } } @@ -294,12 +296,12 @@ impl SignatureShare { /// `SecretKey` implements `Deserialize` but not `Serialize` to avoid accidental /// serialization in insecure contexts. To enable both use the `::serde_impl::SerdeSecret` /// wrapper which implements both `Deserialize` and `Serialize`. -#[derive(PartialEq, Eq)] -pub struct SecretKey(Box); +#[derive(PartialEq, Eq, Clone)] +pub struct SecretKey(Fr); impl Zeroize for SecretKey { fn zeroize(&mut self) { - clear_fr(&mut *self.0) + clear_fr(&mut self.0) } } @@ -320,18 +322,10 @@ impl Default for SecretKey { impl Distribution for Standard { /// Creates a new random instance of `SecretKey`. If you do not need to specify your own RNG, /// you should use the [`SecretKey::random()`](struct.SecretKey.html#method.random) constructor, - /// which uses [`rand::thread_rng()`](https://docs.rs/rand/0.6.1/rand/fn.thread_rng.html) + /// which uses [`rand::thread_rng()`](https://docs.rs/rand/0.7.2/rand/fn.thread_rng.html) /// internally as its RNG. fn sample(&self, rng: &mut R) -> SecretKey { - SecretKey(Box::new(rng.gen04())) - } -} - -/// Creates a new `SecretKey` by cloning another `SecretKey`'s prime field element. -impl Clone for SecretKey { - fn clone(&self) -> Self { - let mut fr = *self.0; - SecretKey::from_mut(&mut fr) + SecretKey(Fr::random(rng)) } } @@ -351,13 +345,9 @@ impl SecretKey { /// *WARNING* this constructor will overwrite the referenced `Fr` element with zeros after it /// has been copied onto the heap. pub fn from_mut(fr: &mut Fr) -> Self { - let fr_ptr = fr as *mut Fr; - let mut boxed_fr = Box::new(Fr::zero()); - unsafe { - copy_nonoverlapping(fr_ptr, &mut *boxed_fr as *mut Fr, 1); - } + let sk = SecretKey(*fr); clear_fr(fr); - SecretKey(boxed_fr) + sk } /// Creates a new random instance of `SecretKey`. If you want to use/define your own random @@ -365,7 +355,7 @@ impl SecretKey { /// [`SecretKey::sample()`](struct.SecretKey.html#impl-Distribution). If you do not /// need to specify your own RNG, you should use the /// [`SecretKey::random()`](struct.SecretKey.html#method.random) constructor, which uses - /// [`rand::thread_rng()`](https://docs.rs/rand/0.6.1/rand/fn.thread_rng.html) internally as its + /// [`rand::thread_rng()`](https://docs.rs/rand/0.7.2/rand/fn.thread_rng.html) internally as its /// RNG. pub fn random() -> Self { rand::random() @@ -373,12 +363,12 @@ impl SecretKey { /// Returns the matching public key. pub fn public_key(&self) -> PublicKey { - PublicKey(G1Affine::one().mul(*self.0)) + PublicKey(G1Affine::one().mul(self.0)) } /// Signs the given element of `G2`. pub fn sign_g2>(&self, hash: H) -> Signature { - Signature(hash.into().mul(*self.0)) + Signature(hash.into().mul(self.0)) } /// Signs the given message. @@ -394,7 +384,7 @@ impl SecretKey { return None; } let Ciphertext(ref u, ref v, _) = *ct; - let g = u.into_affine().mul(*self.0); + let g = u.into_affine().mul(self.0); Some(xor_with_hash(g, v)) } @@ -466,7 +456,7 @@ impl SecretKeyShare { /// Returns a decryption share, without validating the ciphertext. pub fn decrypt_share_no_verify(&self, ct: &Ciphertext) -> DecryptionShare { - DecryptionShare(ct.0.into_affine().mul(*(self.0).0)) + DecryptionShare(ct.0.into_affine().mul((self.0).0)) } /// Generates a non-redacted debug string. This method differs from @@ -526,7 +516,7 @@ pub struct DecryptionShare(#[serde(with = "serde_impl::projective")] G1); impl Distribution for Standard { fn sample(&self, rng: &mut R) -> DecryptionShare { - DecryptionShare(rng.gen04()) + DecryptionShare(G1::random(rng)) } } @@ -697,7 +687,7 @@ impl SecretKeySet { /// Returns a hash of the given message in `G2`. pub fn hash_g2>(msg: M) -> G2 { let digest = sha3_256(msg.as_ref()); - ChaChaRng::from_seed(digest).gen04() + G2::random(&mut ChaChaRng::from_seed(digest)) } /// Returns a hash of the group element and message, in the second group. @@ -716,13 +706,11 @@ fn hash_g1_g2>(g1: G1, msg: M) -> G2 { /// Returns the bitwise xor of `bytes` with a sequence of pseudorandom bytes determined by `g1`. fn xor_with_hash(g1: G1, bytes: &[u8]) -> Vec { let digest = sha3_256(g1.into_affine().into_compressed().as_ref()); - let mut rng = ChaChaRng::from_seed(digest); + let rng = ChaChaRng::from_seed(digest); let xor = |(a, b): (u8, &u8)| a ^ b; rng.sample_iter(&Standard).zip(bytes).map(xor).collect() } -use std::borrow::Borrow; - /// Given a list of `t + 1` samples `(i - 1, f(i) * g)` for a polynomial `f` of degree `t`, and a /// group generator `g`, returns `f(0) * g`. fn interpolate(t: usize, items: I) -> Result @@ -798,7 +786,6 @@ mod tests { use std::collections::BTreeMap; use rand::{self, distributions::Standard, random, Rng}; - use rand04_compat::rand04::random as random04; #[test] fn test_interpolate() { @@ -951,7 +938,7 @@ mod tests { /// Some basic sanity checks for the `hash_g2` function. #[test] fn test_hash_g2() { - let mut rng = rand::thread_rng(); + let rng = rand::thread_rng(); let msg: Vec = rng.sample_iter(&Standard).take(1000).collect(); let msg_end0: Vec = msg.iter().chain(b"end0").cloned().collect(); let msg_end1: Vec = msg.iter().chain(b"end1").cloned().collect(); @@ -968,8 +955,8 @@ mod tests { let msg: Vec = rng.sample_iter(&Standard).take(1000).collect(); let msg_end0: Vec = msg.iter().chain(b"end0").cloned().collect(); let msg_end1: Vec = msg.iter().chain(b"end1").cloned().collect(); - let g0 = random04(); - let g1 = random04(); + let g0 = G1::random(&mut rng); + let g1 = G1::random(&mut rng); assert_eq!(hash_g1_g2(g0, &msg), hash_g1_g2(g0, &msg)); assert_ne!(hash_g1_g2(g0, &msg), hash_g1_g2(g0, &msg_end0)); @@ -980,8 +967,9 @@ mod tests { /// Some basic sanity checks for the `hash_bytes` function. #[test] fn test_xor_with_hash() { - let g0 = random04(); - let g1 = random04(); + let mut rng = rand::thread_rng(); + let g0 = G1::random(&mut rng); + let g1 = G1::random(&mut rng); let xwh = xor_with_hash; assert_eq!(xwh(g0, &[0; 5]), xwh(g0, &[0; 5])); assert_ne!(xwh(g0, &[0; 5]), xwh(g1, &[0; 5])); @@ -1071,4 +1059,21 @@ mod tests { sk.zeroize(); assert_eq!(zero_sk, sk); } + + #[test] + fn test_rng_seed() { + let sk1 = SecretKey::random(); + let sk2 = SecretKey::random(); + + assert_ne!(sk1, sk2); + let mut seed = [0u8; 32]; + rand::thread_rng().fill_bytes(&mut seed); + + let mut rng = ChaChaRng::from_seed(seed); + let sk3: SecretKey = rng.sample(Standard); + + let mut rng = ChaChaRng::from_seed(seed); + let sk4: SecretKey = rng.sample(Standard); + assert_eq!(sk3, sk4); + } } diff --git a/src/mock/mod.rs b/src/mock/mod.rs index d73e0c4..d2f56ed 100644 --- a/src/mock/mod.rs +++ b/src/mock/mod.rs @@ -14,10 +14,10 @@ pub mod ms8; use std::{fmt, mem, slice}; -use pairing::{EncodedPoint, Field, GroupDecodingError, PrimeField}; -use rand04_compat::rand04 as rand; - -use super::{CurveAffine, CurveProjective, Engine}; +use ff::{Field, PrimeField, ScalarEngine}; +use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError}; +use pairing::{Engine, PairingCurveAffine}; +use rand::RngCore; pub use self::ms8::Mersenne8; @@ -52,17 +52,17 @@ impl fmt::Display for Ms8Projective { } } -impl rand::Rand for Ms8Affine { - #[inline] - fn rand(rng: &mut R) -> Self { - Ms8Affine(rng.gen()) - } -} +impl PairingCurveAffine for Ms8Affine { + type Prepared = Ms8Affine; + type Pair = Ms8Affine; + type PairingResult = Mersenne8; -impl rand::Rand for Ms8Projective { - #[inline] - fn rand(rng: &mut R) -> Self { - Ms8Projective(rng.gen()) + fn prepare(&self) -> Self::Prepared { + *self + } + + fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult { + self.0 * other.0 } } @@ -78,6 +78,10 @@ impl From for Ms8Projective { } } +impl ScalarEngine for Mocktography { + type Fr = Mersenne8; +} + impl Engine for Mocktography { type G1 = Ms8Projective; type G1Affine = Ms8Affine; @@ -87,15 +91,20 @@ impl Engine for Mocktography { type Fqe = Mersenne8; type Fqk = Mersenne8; - // In newer versions of pairing, this must be moved to `ScalarEngine`: - type Fr = Mersenne8; + fn pairing(p: G1, q: G2) -> Self::Fqk + where + G1: Into, + G2: Into, + { + p.into().0 * q.into().0 + } fn miller_loop<'a, I>(_i: I) -> Self::Fqk where I: IntoIterator< Item = &'a ( - &'a ::Prepared, - &'a ::Prepared, + &'a ::Prepared, + &'a ::Prepared, ), >, { @@ -107,14 +116,6 @@ impl Engine for Mocktography { // Unused? unimplemented!() } - - fn pairing(p: G1, q: G2) -> Self::Fqk - where - G1: Into, - G2: Into, - { - p.into().0 * q.into().0 - } } impl AsRef<[u64]> for Mersenne8 { @@ -164,11 +165,8 @@ impl CurveAffine for Ms8Affine { type Scalar = Mersenne8; type Base = Mersenne8; type Projective = Ms8Projective; - type Prepared = Ms8Affine; type Uncompressed = Ms8Affine; type Compressed = Ms8Affine; - type Pair = Ms8Affine; - type PairingResult = Mersenne8; fn zero() -> Self { Ms8Affine(Mersenne8::zero()) @@ -193,16 +191,6 @@ impl CurveAffine for Ms8Affine { Ms8Projective(self.0 * s) } - fn prepare(&self) -> Self::Prepared { - *self - } - - fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult { - // This is the actual implementation of e: G_1 x G_2 -> G_T. - // We have chosen e(P, Q) = PQ. - self.0 * other.0 - } - fn into_projective(&self) -> Self::Projective { Ms8Projective(self.0) } @@ -214,6 +202,10 @@ impl CurveProjective for Ms8Projective { type Base = Mersenne8; type Affine = Ms8Affine; + fn random(rng: &mut R) -> Self { + Self(Mersenne8::random(rng)) + } + fn zero() -> Self { Ms8Projective(Mersenne8::zero()) } diff --git a/src/mock/ms8.rs b/src/mock/ms8.rs index 12d2865..da54197 100644 --- a/src/mock/ms8.rs +++ b/src/mock/ms8.rs @@ -11,10 +11,8 @@ use std::io::{self, Read, Write}; use std::{fmt, mem, ops}; use byteorder::{BigEndian, ByteOrder}; -use pairing::{ - Field, LegendreSymbol, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, SqrtField, -}; -use rand04_compat::rand04 as rand; +use ff::{Field, LegendreSymbol, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, SqrtField}; +use rand::RngCore; /// Modular exponentiation /// @@ -192,14 +190,11 @@ impl fmt::Display for Mersenne8 { } } -impl rand::Rand for Mersenne8 { - #[inline] - fn rand(rng: &mut R) -> Self { - Mersenne8::from(::rand(rng)) - } -} - impl Field for Mersenne8 { + fn random(rng: &mut R) -> Self { + Mersenne8::from(rng.next_u32()) + } + #[inline] fn zero() -> Self { Mersenne8(0) @@ -437,7 +432,7 @@ mod tests { #![allow(clippy::cognitive_complexity)] use super::{ext_euclid, modular_pow, Mersenne8}; - use pairing::Field; + use ff::Field; #[test] fn ext_euclid_simple() { diff --git a/src/poly.rs b/src/poly.rs index 7af6d28..38614ed 100644 --- a/src/poly.rs +++ b/src/poly.rs @@ -20,11 +20,12 @@ use std::borrow::Borrow; use std::cmp::Ordering; use std::fmt::{self, Debug, Formatter}; use std::hash::{Hash, Hasher}; +use std::iter::repeat_with; use std::{cmp, iter, ops}; -use pairing::{CurveAffine, CurveProjective, Field}; +use ff::Field; +use group::{CurveAffine, CurveProjective}; use rand::Rng; -use rand04_compat::RngExt; use serde::{Deserialize, Serialize}; use zeroize::Zeroize; @@ -35,7 +36,7 @@ use crate::secret::clear_fr; use crate::{Fr, G1Affine, G1}; /// A univariate polynomial in the prime field. -#[derive(Serialize, Deserialize, PartialEq, Eq)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Clone)] pub struct Poly { /// The coefficients of a polynomial. #[serde(with = "super::serde_impl::field_vec")] @@ -56,13 +57,6 @@ impl Drop for Poly { } } -/// Creates a new `Poly` with the same coefficients as another polynomial. -impl Clone for Poly { - fn clone(&self) -> Self { - Poly::from(self.coeff.clone()) - } -} - /// A debug statement where the `coeff` vector of prime field elements has been redacted. impl Debug for Poly { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -299,7 +293,7 @@ impl Poly { if degree == usize::max_value() { return Err(Error::DegreeTooHigh); } - let coeff: Vec = rng.gen_iter04().take(degree + 1).collect(); + let coeff: Vec = repeat_with(|| Fr::random(rng)).take(degree + 1).collect(); Ok(Poly::from(coeff)) } @@ -525,6 +519,7 @@ impl Commitment { /// /// This can be used for Verifiable Secret Sharing and Distributed Key Generation. See the module /// documentation for details. +#[derive(Clone)] pub struct BivarPoly { /// The polynomial's degree in each of the two variables. degree: usize, @@ -548,15 +543,6 @@ impl Drop for BivarPoly { } } -impl Clone for BivarPoly { - fn clone(&self) -> Self { - BivarPoly { - degree: self.degree, - coeff: self.coeff.clone(), - } - } -} - /// A debug statement where the `coeff` vector has been redacted. impl Debug for BivarPoly { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -589,7 +575,7 @@ impl BivarPoly { .ok_or(Error::DegreeTooHigh)?; let poly = BivarPoly { degree, - coeff: rng.gen_iter04().take(len).collect(), + coeff: repeat_with(|| Fr::random(rng)).take(len).collect(), }; Ok(poly) } @@ -772,9 +758,8 @@ mod tests { use super::{coeff_pos, BivarPoly, IntoFr, Poly}; use super::{Fr, G1Affine, G1}; - use pairing::{CurveAffine, CurveProjective, Field}; - use rand; - use rand04_compat::RngExt; + use ff::Field; + use group::{CurveAffine, CurveProjective}; use zeroize::Zeroize; #[test] @@ -826,7 +811,7 @@ mod tests { assert_ne!(random_commitment, zero_commitment); let mut rng = rand::thread_rng(); - let (x, y): (Fr, Fr) = (rng.gen04(), rng.gen04()); + let (x, y): (Fr, Fr) = (Fr::random(&mut rng), Fr::random(&mut rng)); assert_eq!(zero_commitment.evaluate(x, y), G1::zero()); } diff --git a/src/secret.rs b/src/secret.rs index 4902f37..9e6570c 100644 --- a/src/secret.rs +++ b/src/secret.rs @@ -15,15 +15,14 @@ pub(crate) fn clear_fr(fr: &mut Fr) { #[cfg(test)] mod tests { use super::*; - use pairing::Field; + use ff::Field; use rand::thread_rng; - use rand04_compat::RngExt; #[test] fn test_clear() { let mut rng = thread_rng(); - let mut fr: Fr = rng.gen04(); + let mut fr: Fr = Fr::random(&mut rng); assert_ne!(fr, Fr::zero()); clear_fr(&mut fr); diff --git a/src/serde_impl.rs b/src/serde_impl.rs index 2022591..6273b41 100644 --- a/src/serde_impl.rs +++ b/src/serde_impl.rs @@ -85,12 +85,12 @@ impl<'de> Deserialize<'de> for crate::SecretKey { D: Deserializer<'de>, { use crate::{Fr, FrRepr}; - use pairing::PrimeField; + use ff::PrimeField; use serde::de; let mut fr = match Fr::from_repr(FrRepr(Deserialize::deserialize(deserializer)?)) { Ok(x) => x, - Err(pairing::PrimeFieldDecodingError::NotInField(_)) => { + Err(ff::PrimeFieldDecodingError::NotInField(_)) => { return Err(de::Error::invalid_value( de::Unexpected::Other(&"Number outside of prime field."), &"Valid prime field element.", @@ -104,7 +104,7 @@ impl<'de> Deserialize<'de> for crate::SecretKey { impl SerializeSecret for crate::SecretKey { fn serialize_secret(&self, serializer: S) -> Result { - use pairing::PrimeField; + use ff::PrimeField; Serialize::serialize(&self.0.into_repr().0, serializer) } @@ -165,7 +165,7 @@ pub(crate) mod projective { use std::fmt; use std::marker::PhantomData; - use pairing::{CurveAffine, CurveProjective, EncodedPoint}; + use group::{CurveAffine, CurveProjective, EncodedPoint}; use serde::de::{Error as DeserializeError, SeqAccess, Visitor}; use serde::{ser::SerializeTuple, Deserializer, Serializer}; @@ -224,7 +224,7 @@ pub(crate) mod projective_vec { use std::iter::FromIterator; use std::marker::PhantomData; - use pairing::CurveProjective; + use group::CurveProjective; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use super::projective; @@ -275,7 +275,7 @@ pub(crate) mod projective_vec { pub(crate) mod field_vec { use std::borrow::Borrow; - use pairing::PrimeField; + use ff::PrimeField; use serde::de::Error as DeserializeError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -319,9 +319,10 @@ pub(crate) mod field_vec { #[cfg(test)] mod tests { - use bincode; - use rand; - use rand04_compat::RngExt; + use std::iter::repeat_with; + + use ff::Field; + use group::CurveProjective; use serde::{Deserialize, Serialize}; use crate::poly::BivarPoly; @@ -345,8 +346,8 @@ mod tests { fn vecs() { let mut rng = rand::thread_rng(); let vecs = Vecs { - curve_points: rng.gen_iter04().take(10).collect(), - field_elements: rng.gen_iter04().take(10).collect(), + curve_points: repeat_with(|| G1::random(&mut rng)).take(10).collect(), + field_elements: repeat_with(|| Fr::random(&mut rng)).take(10).collect(), }; let ser_vecs = bincode::serialize(&vecs).expect("serialize vecs"); let de_vecs = bincode::deserialize(&ser_vecs).expect("deserialize vecs"); diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..70acc4c --- /dev/null +++ b/src/util.rs @@ -0,0 +1,9 @@ +use tiny_keccak::{Hasher, Sha3}; + +pub(crate) fn sha3_256(data: &[u8]) -> [u8; 32] { + let mut sha3 = Sha3::v256(); + sha3.update(data); + let mut output = [0u8; 32]; + sha3.finalize(&mut output); + output +}