diff --git a/Cargo.toml b/Cargo.toml index ffe59a6..3b45c0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ digest = "0.8.1" sha3 = "0.8.2" rayon = "1.3.0" rand_core = { version = "0.5", default-features = false } +rand_chacha = "0.3" itertools = "0.9.0" subtle = "2.4" pasta_curves = "0.3.0" diff --git a/src/bellperson/shape_cs.rs b/src/bellperson/shape_cs.rs index 6e9468f..cb5c6f7 100644 --- a/src/bellperson/shape_cs.rs +++ b/src/bellperson/shape_cs.rs @@ -5,7 +5,7 @@ use std::{ collections::{BTreeMap, HashMap}, }; -use crate::traits::{Group, PrimeField as PF}; +use crate::traits::Group; use ff::{Field, PrimeField}; use bellperson::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; @@ -142,7 +142,7 @@ where s.push_str(&format!("INPUT {}\n", &input)) } - let negone = -::one(); + let negone = -::one(); let powers_of_two = (0..G::Scalar::NUM_BITS) .map(|i| G::Scalar::from(2u64).pow_vartime(&[u64::from(i)])) @@ -159,7 +159,7 @@ where } is_first = false; - if coeff != ::one() && coeff != negone { + if coeff != ::one() && coeff != negone { for (i, x) in powers_of_two.iter().enumerate() { if x == &coeff { s.push_str(&format!("2^{} . ", i)); diff --git a/src/bellperson/solver.rs b/src/bellperson/solver.rs index 39aca5e..a6fb1cd 100644 --- a/src/bellperson/solver.rs +++ b/src/bellperson/solver.rs @@ -1,7 +1,7 @@ //! Support for generating R1CS witness using bellperson. -use crate::traits::{Group, PrimeField as PF}; -use ff::PrimeField; +use crate::traits::Group; +use ff::{Field, PrimeField}; use bellperson::{ multiexp::DensityTracker, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable, diff --git a/src/circuit.rs b/src/circuit.rs index 705795b..296f8da 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -21,7 +21,7 @@ use super::{ }, poseidon::{NovaPoseidonConstants, PoseidonROGadget}, r1cs::RelaxedR1CSInstance, - traits::{Group, PrimeField, StepCircuit}, + traits::{Group, StepCircuit}, }; use bellperson::{ gadgets::{boolean::Boolean, num::AllocatedNum, Assignment}, @@ -31,7 +31,7 @@ use bellperson_nonnative::{ mp::bignat::BigNat, util::{convert::f_to_nat, num::Num}, }; -use ff::PrimeFieldBits; +use ff::{Field, PrimeField, PrimeFieldBits}; #[derive(Debug, Clone)] pub struct NIFSVerifierCircuitParams { @@ -137,7 +137,7 @@ where impl Circuit<::Base> for NIFSVerifierCircuit where G: Group, - ::Base: ff::PrimeField + PrimeField + PrimeFieldBits, + ::Base: PrimeField + PrimeFieldBits, ::Scalar: PrimeFieldBits, SC: StepCircuit, { @@ -421,7 +421,7 @@ where // Allocate the order of the non-native field as a constant let m_bn = alloc_bignat_constant( cs.namespace(|| "alloc m"), - &G::Scalar::get_order(), + &G::get_order(), self.params.limb_width, self.params.n_limbs, )?; @@ -781,12 +781,12 @@ mod tests { let inputs: NIFSVerifierCircuitInputs = NIFSVerifierCircuitInputs::new( default_hash, RelaxedR1CSInstance::default(&gens2, &shape2), - <::Base as PrimeField>::zero(), // TODO: provide real inputs - <::Base as PrimeField>::zero(), // TODO: provide real inputs - <::Base as PrimeField>::zero(), // TODO: provide real inputs - <::Scalar as PrimeField>::zero(), // TODO: provide real inputs - <::Base as PrimeField>::zero(), // TODO: provide real inputs - T, // TODO: provide real inputs + <::Base as Field>::zero(), // TODO: provide real inputs + <::Base as Field>::zero(), // TODO: provide real inputs + <::Base as Field>::zero(), // TODO: provide real inputs + <::Scalar as Field>::zero(), // TODO: provide real inputs + <::Base as Field>::zero(), // TODO: provide real inputs + T, // TODO: provide real inputs w, ); diff --git a/src/lib.rs b/src/lib.rs index d556d0a..e855b53 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -139,7 +139,7 @@ impl FinalSNARK { #[cfg(test)] mod tests { use super::*; - use crate::traits::PrimeField; + use ff::Field; use rand::rngs::OsRng; type S = pasta_curves::pallas::Scalar; diff --git a/src/pasta.rs b/src/pasta.rs index aaa7089..b6dd70f 100644 --- a/src/pasta.rs +++ b/src/pasta.rs @@ -1,13 +1,15 @@ //! This module implements the Nova traits for pallas::Point, pallas::Scalar, vesta::Point, vesta::Scalar. -use crate::traits::{ChallengeTrait, CompressedGroup, Group, PrimeField}; +use crate::traits::{ChallengeTrait, CompressedGroup, Group}; +use ff::Field; use merlin::Transcript; use pasta_curves::{ self, - arithmetic::{CurveAffine, CurveExt, FieldExt, Group as Grp}, + arithmetic::{CurveAffine, CurveExt, Group as Grp}, group::{Curve, GroupEncoding}, - pallas, vesta, Ep, Eq, Fp, Fq, + pallas, vesta, Ep, Eq, }; -use rand::{CryptoRng, RngCore}; +use rand::SeedableRng; +use rand_chacha::ChaCha20Rng; use rug::Integer; use std::{borrow::Borrow, ops::Mul}; @@ -74,28 +76,6 @@ impl Group for pallas::Point { (Self::Base::zero(), Self::Base::zero(), true) } } -} - -impl PrimeField for pallas::Scalar { - fn zero() -> Self { - Fq::zero() - } - fn one() -> Self { - Fq::one() - } - fn from_bytes_mod_order_wide(bytes: &[u8]) -> Option { - if bytes.len() != 64 { - None - } else { - let mut arr = [0; 64]; - arr.copy_from_slice(&bytes[0..64]); - Some(Fq::from_bytes_wide(&arr)) - } - } - - fn random(rng: &mut (impl RngCore + CryptoRng)) -> Self { - ::random(rng) - } fn get_order() -> Integer { Integer::from_str_radix( @@ -108,9 +88,10 @@ impl PrimeField for pallas::Scalar { impl ChallengeTrait for pallas::Scalar { fn challenge(label: &'static [u8], transcript: &mut Transcript) -> Self { - let mut buf = [0u8; 64]; - transcript.challenge_bytes(label, &mut buf); - pallas::Scalar::from_bytes_mod_order_wide(&buf).unwrap() + let mut key: ::Seed = Default::default(); + transcript.challenge_bytes(label, &mut key); + let mut rng = ChaCha20Rng::from_seed(key); + pallas::Scalar::random(&mut rng) } } @@ -188,28 +169,6 @@ impl Group for vesta::Point { (Self::Base::zero(), Self::Base::zero(), true) } } -} - -impl PrimeField for vesta::Scalar { - fn zero() -> Self { - Fp::zero() - } - fn one() -> Self { - Fp::one() - } - fn from_bytes_mod_order_wide(bytes: &[u8]) -> Option { - if bytes.len() != 64 { - None - } else { - let mut arr = [0; 64]; - arr.copy_from_slice(&bytes[0..64]); - Some(Fp::from_bytes_wide(&arr)) - } - } - - fn random(rng: &mut (impl RngCore + CryptoRng)) -> Self { - ::random(rng) - } fn get_order() -> Integer { Integer::from_str_radix( @@ -222,9 +181,10 @@ impl PrimeField for vesta::Scalar { impl ChallengeTrait for vesta::Scalar { fn challenge(label: &'static [u8], transcript: &mut Transcript) -> Self { - let mut buf = [0u8; 64]; - transcript.challenge_bytes(label, &mut buf); - vesta::Scalar::from_bytes_mod_order_wide(&buf).unwrap() + let mut key: ::Seed = Default::default(); + transcript.challenge_bytes(label, &mut key); + let mut rng = ChaCha20Rng::from_seed(key); + vesta::Scalar::random(&mut rng) } } diff --git a/src/poseidon.rs b/src/poseidon.rs index 57e8b18..b916c6c 100644 --- a/src/poseidon.rs +++ b/src/poseidon.rs @@ -189,9 +189,8 @@ mod tests { use super::*; type S = pasta_curves::pallas::Scalar; type G = pasta_curves::pallas::Point; - use crate::{ - bellperson::solver::SatisfyingAssignment, gadgets::utils::le_bits_to_num, traits::PrimeField, - }; + use crate::{bellperson::solver::SatisfyingAssignment, gadgets::utils::le_bits_to_num}; + use ff::Field; use rand::rngs::OsRng; #[test] diff --git a/src/r1cs.rs b/src/r1cs.rs index a2f3081..d3d9e7d 100644 --- a/src/r1cs.rs +++ b/src/r1cs.rs @@ -3,8 +3,9 @@ use super::{ commitments::{CommitGens, CommitTrait, Commitment, CompressedCommitment}, errors::NovaError, - traits::{Group, PrimeField}, + traits::Group, }; +use ff::Field; use itertools::concat; use rayon::prelude::*; diff --git a/src/traits.rs b/src/traits.rs index b4f89fb..dfb0dd4 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -3,52 +3,12 @@ use bellperson::{gadgets::num::AllocatedNum, ConstraintSystem, SynthesisError}; use core::{ borrow::Borrow, fmt::Debug, - ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, + ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}, }; +use ff::PrimeField; use merlin::Transcript; -use rand::{CryptoRng, RngCore}; use rug::Integer; -/// Represents an element of a prime field -pub trait PrimeField: - Sized - + Eq - + Copy - + Clone - + Default - + Send - + Sync - + Debug - + Add - + Sub - + Mul - + Neg - + for<'a> Add<&'a Self, Output = Self> - + for<'a> Mul<&'a Self, Output = Self> - + for<'a> Sub<&'a Self, Output = Self> - + AddAssign - + MulAssign - + SubAssign - + for<'a> AddAssign<&'a Self> - + for<'a> MulAssign<&'a Self> - + for<'a> SubAssign<&'a Self> -{ - /// returns the additive identity of the field - fn zero() -> Self; - - /// returns the multiplicative identity of the field - fn one() -> Self; - - /// converts the supplied bytes into an element of the field - fn from_bytes_mod_order_wide(bytes: &[u8]) -> Option; - - /// returns an uniformly random element from the finite field - fn random(rng: &mut (impl RngCore + CryptoRng)) -> Self; - - /// Get prime field order as a rug::Integer - fn get_order() -> Integer; -} - /// Represents an element of a group pub trait Group: Clone @@ -88,6 +48,9 @@ pub trait Group: /// Returns the affine coordinates (x, y, infinty) for the point fn to_coordinates(&self) -> (Self::Base, Self::Base, bool); + + /// Returns the order of the group as a big integer + fn get_order() -> Integer; } /// Represents a compressed version of a group element @@ -134,7 +97,7 @@ pub trait ScalarMulOwned: for<'r> ScalarMul<&'r Rhs, Output> impl ScalarMulOwned for T where T: for<'r> ScalarMul<&'r Rhs, Output> {} /// A helper trait for a step of the incremental computation (i.e., circuit for F) -pub trait StepCircuit { +pub trait StepCircuit { /// Sythesize the circuit for a computation step and return variable /// that corresponds to the output of the step z_{i+1} fn synthesize>(