diff --git a/crypto-primitives/Cargo.toml b/crypto-primitives/Cargo.toml index ad74dcda..affa780d 100644 --- a/crypto-primitives/Cargo.toml +++ b/crypto-primitives/Cargo.toml @@ -26,6 +26,7 @@ ark-serialize = { version = "0.5.0-alpha", default-features = false, features = blake2 = { version = "0.10", default-features = false } sha2 = { version = "0.10", default-features = false } digest = { version = "0.10", default-features = false } +merlin = { version = "3.0.0", default-features = false, optional = true } ark-r1cs-std = { version = "0.5.0-alpha", optional = true, default-features = false } ark-snark = { version = "0.5.0-alpha", default-features = false } @@ -42,8 +43,8 @@ print-trace = [ "ark-std/print-trace" ] parallel = [ "std", "rayon", "ark-ec/parallel", "ark-std/parallel", "ark-ff/parallel" ] r1cs = [ "ark-r1cs-std", "tracing" ] crh = [ "sponge" ] -sponge = [] -commitment = ["crh"] +sponge = [ "merlin" ] +commitment = [ "crh" ] merkle_tree = ["crh", "hashbrown"] encryption = [] prf = [] diff --git a/crypto-primitives/src/commitment/blake2s/constraints.rs b/crypto-primitives/src/commitment/blake2s/constraints.rs index 07f28ca8..3989d974 100644 --- a/crypto-primitives/src/commitment/blake2s/constraints.rs +++ b/crypto-primitives/src/commitment/blake2s/constraints.rs @@ -1,13 +1,11 @@ -use ark_relations::r1cs::{Namespace, SynthesisError}; - use crate::{ commitment::{blake2s, CommitmentGadget}, prf::blake2s::constraints::{evaluate_blake2s, OutputVar}, }; use ark_ff::{Field, PrimeField}; use ark_r1cs_std::prelude::*; - -use core::borrow::Borrow; +use ark_relations::r1cs::{Namespace, SynthesisError}; +use ark_std::borrow::Borrow; #[derive(Clone)] pub struct ParametersVar; diff --git a/crypto-primitives/src/commitment/blake2s/mod.rs b/crypto-primitives/src/commitment/blake2s/mod.rs index cab562ed..724f3771 100644 --- a/crypto-primitives/src/commitment/blake2s/mod.rs +++ b/crypto-primitives/src/commitment/blake2s/mod.rs @@ -1,5 +1,4 @@ -use super::CommitmentScheme; -use crate::Error; +use crate::{commitment::CommitmentScheme, Error}; use ark_std::rand::Rng; use blake2::Blake2s256 as b2s; use digest::Digest; diff --git a/crypto-primitives/src/commitment/constraints.rs b/crypto-primitives/src/commitment/constraints.rs index 5124e5a5..e7a533ee 100644 --- a/crypto-primitives/src/commitment/constraints.rs +++ b/crypto-primitives/src/commitment/constraints.rs @@ -2,7 +2,7 @@ use crate::commitment::CommitmentScheme; use ark_ff::Field; use ark_r1cs_std::prelude::*; use ark_relations::r1cs::SynthesisError; -use core::fmt::Debug; +use ark_std::fmt::Debug; pub trait CommitmentGadget { type OutputVar: EqGadget diff --git a/crypto-primitives/src/commitment/injective_map/constraints.rs b/crypto-primitives/src/commitment/injective_map/constraints.rs index bc9dc628..13a9d67f 100644 --- a/crypto-primitives/src/commitment/injective_map/constraints.rs +++ b/crypto-primitives/src/commitment/injective_map/constraints.rs @@ -5,7 +5,6 @@ use crate::commitment::{ Window, }, }; - pub use crate::crh::injective_map::constraints::InjectiveMapGadget; use ark_ec::CurveGroup; use ark_ff::{Field, PrimeField}; @@ -14,7 +13,6 @@ use ark_r1cs_std::{ uint8::UInt8, }; use ark_relations::r1cs::SynthesisError; - use ark_std::marker::PhantomData; type ConstraintF = <::BaseField as Field>::BasePrimeField; diff --git a/crypto-primitives/src/commitment/injective_map/mod.rs b/crypto-primitives/src/commitment/injective_map/mod.rs index 700edf7b..ca32904c 100644 --- a/crypto-primitives/src/commitment/injective_map/mod.rs +++ b/crypto-primitives/src/commitment/injective_map/mod.rs @@ -1,10 +1,10 @@ -use crate::Error; -use ark_std::marker::PhantomData; - -use super::{pedersen, CommitmentScheme}; pub use crate::crh::injective_map::InjectiveMap; +use crate::{ + commitment::{pedersen, CommitmentScheme}, + Error, +}; use ark_ec::CurveGroup; -use ark_std::rand::Rng; +use ark_std::{marker::PhantomData, rand::Rng}; #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/crypto-primitives/src/commitment/mod.rs b/crypto-primitives/src/commitment/mod.rs index 30edabeb..c94db15b 100644 --- a/crypto-primitives/src/commitment/mod.rs +++ b/crypto-primitives/src/commitment/mod.rs @@ -1,7 +1,7 @@ +use crate::Error; use ark_ff::UniformRand; use ark_serialize::CanonicalSerialize; -use ark_std::rand::Rng; -use ark_std::{fmt::Debug, hash::Hash}; +use ark_std::{fmt::Debug, hash::Hash, rand::Rng}; pub mod blake2s; pub mod injective_map; @@ -12,8 +12,6 @@ pub mod constraints; #[cfg(feature = "r1cs")] pub use constraints::*; -use crate::Error; - pub trait CommitmentScheme { type Output: CanonicalSerialize + Clone + Default + Eq + Hash + Debug; type Parameters: Clone; diff --git a/crypto-primitives/src/commitment/pedersen/constraints.rs b/crypto-primitives/src/commitment/pedersen/constraints.rs index 8386815d..8dec380a 100644 --- a/crypto-primitives/src/commitment/pedersen/constraints.rs +++ b/crypto-primitives/src/commitment/pedersen/constraints.rs @@ -7,11 +7,10 @@ use ark_ff::{ fields::{Field, PrimeField}, Zero, }; +use ark_r1cs_std::prelude::*; use ark_relations::r1cs::{Namespace, SynthesisError}; use ark_serialize::CanonicalSerialize; - -use ark_r1cs_std::prelude::*; -use core::{borrow::Borrow, iter, marker::PhantomData}; +use ark_std::{borrow::Borrow, iter, marker::PhantomData}; type ConstraintF = <::BaseField as Field>::BasePrimeField; diff --git a/crypto-primitives/src/commitment/pedersen/mod.rs b/crypto-primitives/src/commitment/pedersen/mod.rs index e1aa0d4b..96345322 100644 --- a/crypto-primitives/src/commitment/pedersen/mod.rs +++ b/crypto-primitives/src/commitment/pedersen/mod.rs @@ -1,17 +1,15 @@ -use crate::{crh::CRHScheme, Error}; +use super::CommitmentScheme; +pub use crate::crh::pedersen::Window; +use crate::{ + crh::{pedersen, CRHScheme}, + Error, +}; use ark_ec::CurveGroup; use ark_ff::{BitIteratorLE, Field, PrimeField, ToConstraintField}; use ark_serialize::CanonicalSerialize; -use ark_std::marker::PhantomData; -use ark_std::rand::Rng; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; -use ark_std::UniformRand; - -use super::CommitmentScheme; - -use crate::crh::pedersen; -pub use crate::crh::pedersen::Window; +use ark_std::{marker::PhantomData, rand::Rng, UniformRand}; #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/crypto-primitives/src/crh/bowe_hopwood/constraints.rs b/crypto-primitives/src/crh/bowe_hopwood/constraints.rs index a9bf49de..fd0c433b 100644 --- a/crypto-primitives/src/crh/bowe_hopwood/constraints.rs +++ b/crypto-primitives/src/crh/bowe_hopwood/constraints.rs @@ -1,19 +1,18 @@ -use ark_ec::twisted_edwards::{Projective as TEProjective, TECurveConfig}; -use ark_ec::CurveConfig; -use core::{borrow::Borrow, iter, marker::PhantomData}; - use crate::crh::{ - bowe_hopwood::{Parameters, CHUNK_SIZE}, + bowe_hopwood::{Parameters, TwoToOneCRH, CHUNK_SIZE, CRH}, pedersen::{self, Window}, CRHSchemeGadget, TwoToOneCRHSchemeGadget, }; +use ark_ec::{ + twisted_edwards::{Projective as TEProjective, TECurveConfig}, + CurveConfig, +}; use ark_ff::Field; use ark_r1cs_std::{groups::curves::twisted_edwards::AffineVar, prelude::*}; use ark_relations::r1cs::{Namespace, SynthesisError}; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; - -use crate::crh::bowe_hopwood::{TwoToOneCRH, CRH}; +use ark_std::{borrow::Borrow, iter, marker::PhantomData}; type ConstraintF

= <

::BaseField as Field>::BasePrimeField; diff --git a/crypto-primitives/src/crh/bowe_hopwood/mod.rs b/crypto-primitives/src/crh/bowe_hopwood/mod.rs index d284c3ef..89a4ca27 100644 --- a/crypto-primitives/src/crh/bowe_hopwood/mod.rs +++ b/crypto-primitives/src/crh/bowe_hopwood/mod.rs @@ -2,28 +2,28 @@ //! specific Twisted Edwards (TE) curves. See [Section 5.4.17 of the Zcash protocol specification](https://raw.githubusercontent.com/zcash/zips/master/protocol/protocol.pdf#concretepedersenhash) for a formal description of this hash function, specialized for the Jubjub curve. //! The implementation in this repository is generic across choice of TE curves. -use crate::Error; -use ark_std::rand::Rng; -use ark_std::{ - fmt::{Debug, Formatter, Result as FmtResult}, - marker::PhantomData, +use crate::{ + crh::{pedersen, CRHScheme, TwoToOneCRHScheme}, + Error, }; -#[cfg(feature = "parallel")] -use rayon::prelude::*; - -use super::pedersen; -use crate::crh::{CRHScheme, TwoToOneCRHScheme}; use ark_ec::{ twisted_edwards::Projective as TEProjective, twisted_edwards::TECurveConfig, AdditiveGroup, CurveGroup, }; use ark_ff::fields::PrimeField; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::borrow::Borrow; -use ark_std::cfg_chunks; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; -use ark_std::UniformRand; +use ark_std::{ + borrow::Borrow, + cfg_chunks, + fmt::{Debug, Formatter, Result as FmtResult}, + marker::PhantomData, + rand::Rng, + UniformRand, +}; +#[cfg(feature = "parallel")] +use rayon::prelude::*; #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/crypto-primitives/src/crh/constraints.rs b/crypto-primitives/src/crh/constraints.rs index 81c0aebd..28ea34b4 100644 --- a/crypto-primitives/src/crh/constraints.rs +++ b/crypto-primitives/src/crh/constraints.rs @@ -1,10 +1,8 @@ -use ark_ff::Field; -use core::fmt::Debug; - use crate::crh::{CRHScheme, TwoToOneCRHScheme}; -use ark_relations::r1cs::SynthesisError; - +use ark_ff::Field; use ark_r1cs_std::prelude::*; +use ark_relations::r1cs::SynthesisError; +use ark_std::fmt::Debug; pub trait CRHSchemeGadget: Sized { type InputVar: ?Sized; diff --git a/crypto-primitives/src/crh/injective_map/constraints.rs b/crypto-primitives/src/crh/injective_map/constraints.rs index 1a60c842..5d034c99 100644 --- a/crypto-primitives/src/crh/injective_map/constraints.rs +++ b/crypto-primitives/src/crh/injective_map/constraints.rs @@ -1,13 +1,11 @@ use crate::crh::{ constraints, - injective_map::{InjectiveMap, PedersenCRHCompressor, TECompressor}, + injective_map::{ + InjectiveMap, PedersenCRHCompressor, PedersenTwoToOneCRHCompressor, TECompressor, + }, pedersen::{constraints as ped_constraints, Window}, - TwoToOneCRHSchemeGadget, + CRHSchemeGadget, TwoToOneCRHSchemeGadget, }; -use ark_std::{fmt::Debug, marker::PhantomData}; - -use crate::crh::injective_map::PedersenTwoToOneCRHCompressor; -use crate::crh::CRHSchemeGadget; use ark_ec::{ twisted_edwards::{Projective as TEProjective, TECurveConfig}, CurveConfig, CurveGroup, @@ -17,6 +15,7 @@ use ark_r1cs_std::{ fields::fp::FpVar, groups::curves::twisted_edwards::AffineVar as TEVar, prelude::*, }; use ark_relations::r1cs::SynthesisError; +use ark_std::{fmt::Debug, marker::PhantomData}; type ConstraintF = <::BaseField as Field>::BasePrimeField; diff --git a/crypto-primitives/src/crh/injective_map/mod.rs b/crypto-primitives/src/crh/injective_map/mod.rs index 289a9006..f84ea1f8 100644 --- a/crypto-primitives/src/crh/injective_map/mod.rs +++ b/crypto-primitives/src/crh/injective_map/mod.rs @@ -1,16 +1,15 @@ -use crate::Error; -use ark_std::rand::Rng; -#[cfg(not(feature = "std"))] -use ark_std::vec::Vec; -use ark_std::{fmt::Debug, hash::Hash, marker::PhantomData}; - -use super::{pedersen, CRHScheme, TwoToOneCRHScheme}; +use crate::{ + crh::{pedersen, CRHScheme, TwoToOneCRHScheme}, + Error, +}; use ark_ec::{ twisted_edwards::{Affine as TEAffine, Projective as TEProjective, TECurveConfig}, CurveConfig, CurveGroup, }; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::borrow::Borrow; +#[cfg(not(feature = "std"))] +use ark_std::vec::Vec; +use ark_std::{borrow::Borrow, fmt::Debug, hash::Hash, marker::PhantomData, rand::Rng}; #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/crypto-primitives/src/crh/mod.rs b/crypto-primitives/src/crh/mod.rs index 08cb4a6e..e0e214b7 100644 --- a/crypto-primitives/src/crh/mod.rs +++ b/crypto-primitives/src/crh/mod.rs @@ -1,20 +1,15 @@ #![allow(clippy::upper_case_acronyms)] +use crate::Error; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_std::{borrow::Borrow, fmt::Debug, hash::Hash, rand::Rng}; -use ark_std::hash::Hash; -use ark_std::rand::Rng; pub mod bowe_hopwood; +#[cfg(feature = "r1cs")] +pub mod constraints; pub mod injective_map; pub mod pedersen; pub mod poseidon; pub mod sha256; - -use crate::Error; - -#[cfg(feature = "r1cs")] -pub mod constraints; - -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::borrow::Borrow; #[cfg(feature = "r1cs")] pub use constraints::*; @@ -22,13 +17,7 @@ pub use constraints::*; /// variable length CRH may also implement this trait in future. pub trait CRHScheme { type Input: ?Sized + Send; - type Output: Clone - + Eq - + core::fmt::Debug - + Hash - + Default - + CanonicalSerialize - + CanonicalDeserialize; + type Output: Clone + Eq + Debug + Hash + Default + CanonicalSerialize + CanonicalDeserialize; type Parameters: Clone + CanonicalSerialize + CanonicalDeserialize + Sync; fn setup(r: &mut R) -> Result; @@ -43,13 +32,7 @@ pub trait TwoToOneCRHScheme { /// Raw Input type of TwoToOneCRH type Input: ?Sized; /// Raw Output type of TwoToOneCRH - type Output: Clone - + Eq - + core::fmt::Debug - + Hash - + Default - + CanonicalSerialize - + CanonicalDeserialize; + type Output: Clone + Eq + Debug + Hash + Default + CanonicalSerialize + CanonicalDeserialize; type Parameters: Clone + CanonicalSerialize + CanonicalDeserialize + Sync; fn setup(r: &mut R) -> Result; diff --git a/crypto-primitives/src/crh/pedersen/constraints.rs b/crypto-primitives/src/crh/pedersen/constraints.rs index 0d1e72ff..ce7aa49f 100644 --- a/crypto-primitives/src/crh/pedersen/constraints.rs +++ b/crypto-primitives/src/crh/pedersen/constraints.rs @@ -1,6 +1,6 @@ use crate::crh::{ - pedersen::{Parameters, Window}, - CRHSchemeGadget as CRHGadgetTrait, + pedersen::{Parameters, TwoToOneCRH, Window, CRH}, + CRHSchemeGadget as CRHGadgetTrait, CRHSchemeGadget, TwoToOneCRHSchemeGadget, }; use ark_ec::CurveGroup; use ark_ff::Field; @@ -8,10 +8,7 @@ use ark_r1cs_std::prelude::*; use ark_relations::r1cs::{Namespace, SynthesisError}; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; - -use crate::crh::pedersen::{TwoToOneCRH, CRH}; -use crate::crh::{CRHSchemeGadget, TwoToOneCRHSchemeGadget}; -use core::{borrow::Borrow, iter, marker::PhantomData}; +use ark_std::{borrow::Borrow, iter, marker::PhantomData}; #[derive(Derivative)] #[derivative(Clone(bound = "C: CurveGroup, GG: CurveVar>"))] diff --git a/crypto-primitives/src/crh/pedersen/mod.rs b/crypto-primitives/src/crh/pedersen/mod.rs index 29d696d4..6fb1650f 100644 --- a/crypto-primitives/src/crh/pedersen/mod.rs +++ b/crypto-primitives/src/crh/pedersen/mod.rs @@ -1,20 +1,21 @@ -use crate::Error; -use ark_std::rand::Rng; -use ark_std::{ - fmt::{Debug, Formatter, Result as FmtResult}, - marker::PhantomData, +use crate::{ + crh::{CRHScheme, TwoToOneCRHScheme}, + Error, }; -#[cfg(feature = "parallel")] -use rayon::prelude::*; - -use crate::crh::{CRHScheme, TwoToOneCRHScheme}; use ark_ec::CurveGroup; use ark_ff::{Field, ToConstraintField}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::borrow::Borrow; -use ark_std::cfg_chunks; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; +use ark_std::{ + borrow::Borrow, + cfg_chunks, + fmt::{Debug, Formatter, Result as FmtResult}, + marker::PhantomData, + rand::Rng, +}; +#[cfg(feature = "parallel")] +use rayon::prelude::*; #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/crypto-primitives/src/crh/poseidon/constraints.rs b/crypto-primitives/src/crh/poseidon/constraints.rs index 059a6934..ef7219ed 100644 --- a/crypto-primitives/src/crh/poseidon/constraints.rs +++ b/crypto-primitives/src/crh/poseidon/constraints.rs @@ -1,22 +1,25 @@ -use crate::crh::poseidon::{TwoToOneCRH, CRH}; -use crate::crh::CRHScheme; -use crate::crh::{ - CRHSchemeGadget as CRHGadgetTrait, TwoToOneCRHSchemeGadget as TwoToOneCRHGadgetTrait, +use crate::{ + crh::{ + poseidon::{TwoToOneCRH, CRH}, + CRHScheme, CRHSchemeGadget as CRHGadgetTrait, + TwoToOneCRHSchemeGadget as TwoToOneCRHGadgetTrait, + }, + sponge::{ + constraints::CryptographicSpongeVar, + poseidon::{constraints::PoseidonSpongeVar, PoseidonConfig}, + Absorb, + }, }; -use crate::sponge::constraints::CryptographicSpongeVar; -use crate::sponge::poseidon::constraints::PoseidonSpongeVar; -use crate::sponge::poseidon::PoseidonConfig; - -use crate::sponge::Absorb; use ark_ff::PrimeField; -use ark_r1cs_std::alloc::{AllocVar, AllocationMode}; -use ark_r1cs_std::fields::fp::FpVar; -use ark_r1cs_std::R1CSVar; +use ark_r1cs_std::{ + alloc::{AllocVar, AllocationMode}, + fields::fp::FpVar, + R1CSVar, +}; use ark_relations::r1cs::{Namespace, SynthesisError}; -use ark_std::borrow::Borrow; -use ark_std::marker::PhantomData; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; +use ark_std::{borrow::Borrow, marker::PhantomData}; #[derive(Clone)] pub struct CRHParametersVar { diff --git a/crypto-primitives/src/crh/poseidon/mod.rs b/crypto-primitives/src/crh/poseidon/mod.rs index 6c465012..4b24e8cd 100644 --- a/crypto-primitives/src/crh/poseidon/mod.rs +++ b/crypto-primitives/src/crh/poseidon/mod.rs @@ -1,11 +1,13 @@ -use crate::crh::TwoToOneCRHScheme; -use crate::sponge::poseidon::{PoseidonConfig, PoseidonSponge}; -use crate::sponge::{Absorb, CryptographicSponge}; -use crate::{crh::CRHScheme, Error}; +use crate::{ + crh::{CRHScheme, TwoToOneCRHScheme}, + sponge::{ + poseidon::{PoseidonConfig, PoseidonSponge}, + Absorb, CryptographicSponge, + }, + Error, +}; use ark_ff::PrimeField; -use ark_std::borrow::Borrow; -use ark_std::marker::PhantomData; -use ark_std::rand::Rng; +use ark_std::{borrow::Borrow, marker::PhantomData, rand::Rng}; #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/crypto-primitives/src/crh/sha256/constraints.rs b/crypto-primitives/src/crh/sha256/constraints.rs index c68c97fd..6bee0060 100644 --- a/crypto-primitives/src/crh/sha256/constraints.rs +++ b/crypto-primitives/src/crh/sha256/constraints.rs @@ -4,9 +4,6 @@ // Thank you! use crate::crh::{sha256::Sha256, CRHSchemeGadget, TwoToOneCRHSchemeGadget}; - -use core::{borrow::Borrow, iter, marker::PhantomData}; - use ark_ff::PrimeField; use ark_r1cs_std::{ alloc::{AllocVar, AllocationMode}, @@ -21,6 +18,7 @@ use ark_r1cs_std::{ use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; +use ark_std::{borrow::Borrow, iter, marker::PhantomData}; const STATE_LEN: usize = 8; diff --git a/crypto-primitives/src/crh/sha256/mod.rs b/crypto-primitives/src/crh/sha256/mod.rs index 16738d88..d07b36ab 100644 --- a/crypto-primitives/src/crh/sha256/mod.rs +++ b/crypto-primitives/src/crh/sha256/mod.rs @@ -1,9 +1,11 @@ -use crate::crh::{CRHScheme, TwoToOneCRHScheme}; -use crate::Error; - -use ark_std::rand::Rng; +use crate::{ + crh::{CRHScheme, TwoToOneCRHScheme}, + Error, +}; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; +use ark_std::{borrow::Borrow, rand::Rng}; +use sha2::digest::Digest; // Re-export the RustCrypto Sha256 type and its associated traits pub use sha2::{digest, Sha256}; @@ -12,10 +14,6 @@ pub use sha2::{digest, Sha256}; pub mod constraints; // Implement the CRH traits for SHA-256 - -use core::borrow::Borrow; -use sha2::digest::Digest; - impl CRHScheme for Sha256 { type Input = [u8]; // This is always 32 bytes. It has to be a Vec to impl CanonicalSerialize diff --git a/crypto-primitives/src/encryption/constraints.rs b/crypto-primitives/src/encryption/constraints.rs index de2a8f91..503f733a 100644 --- a/crypto-primitives/src/encryption/constraints.rs +++ b/crypto-primitives/src/encryption/constraints.rs @@ -1,10 +1,8 @@ use crate::encryption::AsymmetricEncryptionScheme; - +use ark_ff::fields::Field; use ark_r1cs_std::prelude::*; use ark_relations::r1cs::SynthesisError; -use core::fmt::Debug; - -use ark_ff::fields::Field; +use ark_std::fmt::Debug; pub trait AsymmetricEncryptionGadget { type OutputVar: AllocVar diff --git a/crypto-primitives/src/encryption/elgamal/constraints.rs b/crypto-primitives/src/encryption/elgamal/constraints.rs index c5c3c21b..aa7b2a7f 100644 --- a/crypto-primitives/src/encryption/elgamal/constraints.rs +++ b/crypto-primitives/src/encryption/elgamal/constraints.rs @@ -1,15 +1,14 @@ -use ark_r1cs_std::prelude::*; -use ark_relations::r1cs::{Namespace, SynthesisError}; - -use crate::encryption::elgamal::{ - Ciphertext, ElGamal, Parameters, Plaintext, PublicKey, Randomness, +use crate::encryption::{ + elgamal::{Ciphertext, ElGamal, Parameters, Plaintext, PublicKey, Randomness}, + AsymmetricEncryptionGadget, }; -use crate::encryption::AsymmetricEncryptionGadget; use ark_ec::CurveGroup; use ark_ff::{ fields::{Field, PrimeField}, Zero, }; +use ark_r1cs_std::prelude::*; +use ark_relations::r1cs::{Namespace, SynthesisError}; use ark_serialize::CanonicalSerialize; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; diff --git a/crypto-primitives/src/encryption/elgamal/mod.rs b/crypto-primitives/src/encryption/elgamal/mod.rs index 2ffc9563..107710c7 100644 --- a/crypto-primitives/src/encryption/elgamal/mod.rs +++ b/crypto-primitives/src/encryption/elgamal/mod.rs @@ -1,13 +1,10 @@ -#[cfg(feature = "r1cs")] -pub mod constraints; - -use crate::encryption::AsymmetricEncryptionScheme; -use crate::Error; +use crate::{encryption::AsymmetricEncryptionScheme, Error}; use ark_ec::{AdditiveGroup, CurveGroup}; use ark_ff::{fields::PrimeField, UniformRand}; -use ark_std::marker::PhantomData; -use ark_std::ops::Mul; -use ark_std::rand::Rng; +use ark_std::{marker::PhantomData, ops::Mul, rand::Rng}; + +#[cfg(feature = "r1cs")] +pub mod constraints; pub struct ElGamal { _group: PhantomData, diff --git a/crypto-primitives/src/encryption/mod.rs b/crypto-primitives/src/encryption/mod.rs index d1213a76..5c721eb0 100644 --- a/crypto-primitives/src/encryption/mod.rs +++ b/crypto-primitives/src/encryption/mod.rs @@ -1,13 +1,12 @@ +use crate::Error; +use ark_std::rand::Rng; + #[cfg(feature = "r1cs")] pub mod constraints; +pub mod elgamal; #[cfg(feature = "r1cs")] pub use constraints::*; -pub mod elgamal; - -use crate::Error; -use ark_std::rand::Rng; - pub trait AsymmetricEncryptionScheme { type Parameters; type PublicKey; diff --git a/crypto-primitives/src/lib.rs b/crypto-primitives/src/lib.rs index 31ae920b..62d559b7 100644 --- a/crypto-primitives/src/lib.rs +++ b/crypto-primitives/src/lib.rs @@ -51,8 +51,8 @@ pub enum Error { SerializationError(ark_serialize::SerializationError), } -impl core::fmt::Display for Error { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { +impl ark_std::fmt::Display for Error { + fn fmt(&self, f: &mut ark_std::fmt::Formatter<'_>) -> ark_std::fmt::Result { match self { Self::IncorrectInputLength(len) => write!(f, "incorrect input length: {len}"), Self::NotPrimeOrder => write!(f, "element is not prime order"), diff --git a/crypto-primitives/src/merkle_tree/constraints.rs b/crypto-primitives/src/merkle_tree/constraints.rs index aa9fbb87..83ae4f5b 100644 --- a/crypto-primitives/src/merkle_tree/constraints.rs +++ b/crypto-primitives/src/merkle_tree/constraints.rs @@ -1,13 +1,13 @@ -use crate::crh::TwoToOneCRHSchemeGadget; -use crate::merkle_tree::{Config, IdentityDigestConverter}; -use crate::{crh::CRHSchemeGadget, merkle_tree::Path}; +use crate::{ + crh::{CRHSchemeGadget, TwoToOneCRHSchemeGadget}, + merkle_tree::{Config, IdentityDigestConverter, Path}, +}; use ark_ff::PrimeField; use ark_r1cs_std::prelude::*; use ark_relations::r1cs::{Namespace, SynthesisError}; -use ark_std::borrow::Borrow; -use ark_std::fmt::Debug; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; +use ark_std::{borrow::Borrow, fmt::Debug}; pub trait DigestVarConverter { type TargetType: Borrow; diff --git a/crypto-primitives/src/merkle_tree/mod.rs b/crypto-primitives/src/merkle_tree/mod.rs index 5a7e4934..1a400452 100644 --- a/crypto-primitives/src/merkle_tree/mod.rs +++ b/crypto-primitives/src/merkle_tree/mod.rs @@ -1,27 +1,29 @@ #![allow(clippy::needless_range_loop)] -use core::hash::BuildHasherDefault; - /// Defines a trait to chain two types of CRHs. -use crate::crh::TwoToOneCRHScheme; -use crate::sponge::Absorb; -use crate::{crh::CRHScheme, Error}; +use crate::{ + crh::{CRHScheme, TwoToOneCRHScheme}, + sponge::Absorb, + Error, +}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::borrow::Borrow; -use ark_std::collections::BTreeSet; -use ark_std::hash::Hash; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; +use ark_std::{ + borrow::Borrow, + collections::BTreeSet, + fmt::Debug, + hash::{BuildHasherDefault, Hash}, +}; use hashbrown::HashMap; - -#[cfg(test)] -mod tests; +#[cfg(feature = "parallel")] +use rayon::prelude::*; #[cfg(feature = "r1cs")] pub mod constraints; -#[cfg(feature = "parallel")] -use rayon::prelude::*; +#[cfg(test)] +mod tests; #[cfg(all( target_has_atomic = "8", @@ -83,7 +85,7 @@ pub trait Config { // leaf layer type LeafDigest: Clone + Eq - + core::fmt::Debug + + Debug + Hash + Default + CanonicalSerialize @@ -99,7 +101,7 @@ pub trait Config { // inner layer type InnerDigest: Clone + Eq - + core::fmt::Debug + + Debug + Hash + Default + CanonicalSerialize @@ -222,13 +224,13 @@ impl Path

{ /// [I]J L M /// ``` /// Suppose we want to prove I and J, then: -/// `leaf_indexes` is: [2,3] (indexes in Merkle Tree leaves vector) -/// `leaf_siblings_hashes`: [J,I] -/// `auth_paths_prefix_lenghts`: [0,2] -/// `auth_paths_suffixes`: [ [C,D], []] +/// `leaf_indexes` is: `[2,3]` (indexes in Merkle Tree leaves vector) +/// `leaf_siblings_hashes`: `[J,I]` +/// `auth_paths_prefix_lenghts`: `[0,2]` +/// `auth_paths_suffixes`: `[ [C,D], []]` /// We can reconstruct the paths incrementally: /// First, we reconstruct the first path. The prefix length is 0, hence we do not have any prefix encoding. -/// The path is thus [C,D]. +/// The path is thus `[C,D]`. /// Once the first path is verified, we can reconstruct the second path. /// The prefix length of 2 means that the path prefix will be `previous_path[:2] -> [C,D]`. /// Since the Merkle Tree branch is the same, the authentication path is the same (which means in this case that there is no suffix). @@ -584,7 +586,9 @@ impl MerkleTree

{ /// instead of /// `num_leaves*(num_leaves.log2()-1)` /// When verifying the proof, leaves hashes should be supplied in order, that is: + /// ```ignore /// let ordered_leaves: Vec<_> = self.leaf_indexes.into_iter().map(|i| leaves[i]).collect(); + /// ``` pub fn generate_multi_proof( &self, indexes: impl IntoIterator, diff --git a/crypto-primitives/src/merkle_tree/tests/constraints.rs b/crypto-primitives/src/merkle_tree/tests/constraints.rs index 134e5092..ab55dc83 100644 --- a/crypto-primitives/src/merkle_tree/tests/constraints.rs +++ b/crypto-primitives/src/merkle_tree/tests/constraints.rs @@ -1,9 +1,11 @@ mod byte_mt_tests { - use crate::crh::{pedersen, TwoToOneCRHScheme, TwoToOneCRHSchemeGadget}; - - use crate::crh::{CRHScheme, CRHSchemeGadget}; - use crate::merkle_tree::constraints::{BytesVarDigestConverter, ConfigGadget}; - use crate::merkle_tree::{constraints::PathVar, ByteDigestConverter, Config, MerkleTree}; + use crate::crh::{ + pedersen, CRHScheme, CRHSchemeGadget, TwoToOneCRHScheme, TwoToOneCRHSchemeGadget, + }; + use crate::merkle_tree::{ + constraints::{BytesVarDigestConverter, ConfigGadget, PathVar}, + ByteDigestConverter, Config, MerkleTree, + }; use ark_ed_on_bls12_381::{constraints::EdwardsVar, EdwardsProjective as JubJub, Fq}; use ark_r1cs_std::prelude::*; use ark_relations::r1cs::ConstraintSystem; @@ -234,13 +236,14 @@ mod byte_mt_tests { mod field_mt_tests { use crate::crh::{poseidon, CRHSchemeGadget, TwoToOneCRHSchemeGadget}; - use crate::merkle_tree::constraints::ConfigGadget; - use crate::merkle_tree::tests::test_utils::poseidon_parameters; - use crate::merkle_tree::{constraints::PathVar, Config, IdentityDigestConverter, MerkleTree}; - use ark_r1cs_std::fields::fp::FpVar; - use ark_r1cs_std::uint32::UInt32; - use ark_r1cs_std::R1CSVar; - use ark_r1cs_std::{alloc::AllocVar, convert::ToBitsGadget}; + use crate::merkle_tree::{ + constraints::{ConfigGadget, PathVar}, + tests::test_utils::poseidon_parameters, + Config, IdentityDigestConverter, MerkleTree, + }; + use ark_r1cs_std::{ + alloc::AllocVar, convert::ToBitsGadget, fields::fp::FpVar, uint32::UInt32, R1CSVar, + }; use ark_relations::r1cs::ConstraintSystem; use ark_std::{test_rng, One, UniformRand}; diff --git a/crypto-primitives/src/merkle_tree/tests/mod.rs b/crypto-primitives/src/merkle_tree/tests/mod.rs index a2815f57..4f18d6eb 100644 --- a/crypto-primitives/src/merkle_tree/tests/mod.rs +++ b/crypto-primitives/src/merkle_tree/tests/mod.rs @@ -7,8 +7,7 @@ mod bytes_mt_tests { use crate::{crh::*, merkle_tree::*}; use ark_ed_on_bls12_381::EdwardsProjective as JubJub; use ark_ff::BigInteger256; - use ark_std::{test_rng, UniformRand}; - use std::iter::zip; + use ark_std::{iter::zip, test_rng, UniformRand}; #[derive(Clone)] pub(super) struct Window4x256; @@ -184,9 +183,12 @@ mod bytes_mt_tests { } mod field_mt_tests { - use crate::crh::poseidon; - use crate::merkle_tree::tests::test_utils::poseidon_parameters; - use crate::merkle_tree::{Config, IdentityDigestConverter, MerkleTree}; + use crate::{ + crh::poseidon, + merkle_tree::{ + tests::test_utils::poseidon_parameters, Config, IdentityDigestConverter, MerkleTree, + }, + }; use ark_std::{test_rng, One, UniformRand}; type F = ark_ed_on_bls12_381::Fr; diff --git a/crypto-primitives/src/merkle_tree/tests/test_utils.rs b/crypto-primitives/src/merkle_tree/tests/test_utils.rs index ef0795c6..9da40354 100644 --- a/crypto-primitives/src/merkle_tree/tests/test_utils.rs +++ b/crypto-primitives/src/merkle_tree/tests/test_utils.rs @@ -1,6 +1,5 @@ use crate::sponge::poseidon::PoseidonConfig; -use ark_std::str::FromStr; -use ark_std::{One, Zero}; +use ark_std::{str::FromStr, One, Zero}; type F = ark_ed_on_bls12_381::Fr; diff --git a/crypto-primitives/src/prf/blake2s/constraints.rs b/crypto-primitives/src/prf/blake2s/constraints.rs index cd9ea242..c0c180b9 100644 --- a/crypto-primitives/src/prf/blake2s/constraints.rs +++ b/crypto-primitives/src/prf/blake2s/constraints.rs @@ -1,13 +1,11 @@ -use ark_ff::PrimeField; -use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; - use crate::prf::PRFGadget; +use ark_ff::PrimeField; use ark_r1cs_std::prelude::*; +use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; +use ark_std::borrow::Borrow; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; -use core::borrow::Borrow; - // 2.1. Parameters // The following table summarizes various parameters and their ranges: // | BLAKE2b | BLAKE2s | diff --git a/crypto-primitives/src/prf/blake2s/mod.rs b/crypto-primitives/src/prf/blake2s/mod.rs index 7dd10c9b..5addc754 100644 --- a/crypto-primitives/src/prf/blake2s/mod.rs +++ b/crypto-primitives/src/prf/blake2s/mod.rs @@ -1,11 +1,9 @@ +use crate::{prf::PRF, Error}; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; use blake2::{Blake2s256 as B2s, Blake2sMac}; use digest::Digest; -use super::PRF; -use crate::Error; - #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/crypto-primitives/src/prf/constraints.rs b/crypto-primitives/src/prf/constraints.rs index 19fb0da6..2e64729d 100644 --- a/crypto-primitives/src/prf/constraints.rs +++ b/crypto-primitives/src/prf/constraints.rs @@ -1,10 +1,8 @@ -use ark_ff::Field; -use core::fmt::Debug; - use crate::prf::PRF; -use ark_relations::r1cs::{Namespace, SynthesisError}; - +use ark_ff::Field; use ark_r1cs_std::prelude::*; +use ark_relations::r1cs::{Namespace, SynthesisError}; +use ark_std::fmt::Debug; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; diff --git a/crypto-primitives/src/prf/mod.rs b/crypto-primitives/src/prf/mod.rs index fa3da3a4..5aef9297 100644 --- a/crypto-primitives/src/prf/mod.rs +++ b/crypto-primitives/src/prf/mod.rs @@ -1,8 +1,7 @@ #![allow(clippy::upper_case_acronyms)] -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use core::{fmt::Debug, hash::Hash}; - use crate::Error; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_std::{fmt::Debug, hash::Hash}; #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/crypto-primitives/src/signature/constraints.rs b/crypto-primitives/src/signature/constraints.rs index a669c0ad..860a8efb 100644 --- a/crypto-primitives/src/signature/constraints.rs +++ b/crypto-primitives/src/signature/constraints.rs @@ -1,9 +1,8 @@ +use crate::signature::SignatureScheme; use ark_ff::Field; use ark_r1cs_std::prelude::*; use ark_relations::r1cs::SynthesisError; -use crate::signature::SignatureScheme; - pub trait SigVerifyGadget { type ParametersVar: AllocVar + Clone; diff --git a/crypto-primitives/src/signature/mod.rs b/crypto-primitives/src/signature/mod.rs index 1f7cf219..577c6d73 100644 --- a/crypto-primitives/src/signature/mod.rs +++ b/crypto-primitives/src/signature/mod.rs @@ -1,7 +1,6 @@ use crate::Error; use ark_serialize::CanonicalSerialize; -use ark_std::hash::Hash; -use ark_std::rand::Rng; +use ark_std::{hash::Hash, rand::Rng}; #[cfg(feature = "r1cs")] pub mod constraints; diff --git a/crypto-primitives/src/signature/schnorr/constraints.rs b/crypto-primitives/src/signature/schnorr/constraints.rs index 9198465f..f87089c3 100644 --- a/crypto-primitives/src/signature/schnorr/constraints.rs +++ b/crypto-primitives/src/signature/schnorr/constraints.rs @@ -1,15 +1,14 @@ +use crate::signature::{ + schnorr::{Parameters, PublicKey, Schnorr}, + SigRandomizePkGadget, +}; use ark_ec::CurveGroup; use ark_ff::Field; use ark_r1cs_std::prelude::*; use ark_relations::r1cs::{Namespace, SynthesisError}; - -use crate::signature::SigRandomizePkGadget; - #[cfg(not(feature = "std"))] use ark_std::vec::Vec; use ark_std::{borrow::Borrow, marker::PhantomData}; - -use crate::signature::schnorr::{Parameters, PublicKey, Schnorr}; use digest::Digest; type ConstraintF = <::BaseField as Field>::BasePrimeField; diff --git a/crypto-primitives/src/signature/schnorr/mod.rs b/crypto-primitives/src/signature/schnorr/mod.rs index bd7692f6..c27513f3 100644 --- a/crypto-primitives/src/signature/schnorr/mod.rs +++ b/crypto-primitives/src/signature/schnorr/mod.rs @@ -5,11 +5,9 @@ use ark_ff::{ AdditiveGroup, One, ToConstraintField, UniformRand, Zero, }; use ark_serialize::CanonicalSerialize; -use ark_std::ops::Mul; -use ark_std::rand::Rng; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; -use ark_std::{hash::Hash, marker::PhantomData}; +use ark_std::{hash::Hash, marker::PhantomData, ops::Mul, rand::Rng}; use digest::Digest; #[cfg(feature = "r1cs")] diff --git a/crypto-primitives/src/snark/constraints.rs b/crypto-primitives/src/snark/constraints.rs index 92e16b92..ae4a39f0 100644 --- a/crypto-primitives/src/snark/constraints.rs +++ b/crypto-primitives/src/snark/constraints.rs @@ -1,17 +1,19 @@ use ark_ff::{BigInteger, PrimeField}; -use ark_r1cs_std::fields::{ - emulated_fp::{ - params::{get_params, OptimizationType}, - AllocatedEmulatedFpVar, EmulatedFpVar, +use ark_r1cs_std::{ + fields::{ + emulated_fp::{ + params::{get_params, OptimizationType}, + AllocatedEmulatedFpVar, EmulatedFpVar, + }, + fp::{AllocatedFp, FpVar}, }, - fp::{AllocatedFp, FpVar}, + prelude::*, }; -use ark_r1cs_std::prelude::*; -use ark_relations::r1cs::OptimizationGoal; use ark_relations::{ lc, ns, r1cs::{ - ConstraintSynthesizer, ConstraintSystemRef, LinearCombination, Namespace, SynthesisError, + ConstraintSynthesizer, ConstraintSystemRef, LinearCombination, Namespace, OptimizationGoal, + SynthesisError, }, }; use ark_snark::{CircuitSpecificSetupSNARK, UniversalSetupSNARK, SNARK}; @@ -30,9 +32,9 @@ pub trait SNARKGadget> { /// Information about the R1CS constraints required to check proofs relative /// a given verification key. In the context of a LPCP-based pairing-based SNARK - /// like that of [[Groth16]](https://eprint.iacr.org/2016/260), + /// like that of [Groth16](https://eprint.iacr.org/2016/260), /// this is independent of the R1CS matrices, - /// whereas for more "complex" SNARKs like [[Marlin]](https://eprint.iacr.org/2019/1047), + /// whereas for more "complex" SNARKs like [Marlin](https://eprint.iacr.org/2019/1047), /// this can encode information about the highest degree of polynomials /// required to verify proofs. type VerifierSize: PartialOrd + Clone + fmt::Debug; diff --git a/crypto-primitives/src/sponge/absorb.rs b/crypto-primitives/src/sponge/absorb.rs index 60d83e85..b00a61a1 100644 --- a/crypto-primitives/src/sponge/absorb.rs +++ b/crypto-primitives/src/sponge/absorb.rs @@ -1,17 +1,16 @@ -use ark_ec::short_weierstrass::Affine as SWAffine; -use ark_ec::twisted_edwards::Affine as TEAffine; +pub use ark_crypto_primitives_macros::*; use ark_ec::{ - short_weierstrass::SWCurveConfig as SWModelParameters, - twisted_edwards::TECurveConfig as TEModelParameters, + short_weierstrass::{Affine as SWAffine, SWCurveConfig as SWModelParameters}, + twisted_edwards::{Affine as TEAffine, TECurveConfig as TEModelParameters}, +}; +use ark_ff::{ + models::{Fp, FpConfig}, + BigInteger, Field, PrimeField, ToConstraintField, }; -use ark_ff::models::{Fp, FpConfig}; -use ark_ff::{BigInteger, Field, PrimeField, ToConstraintField}; use ark_serialize::CanonicalSerialize; #[cfg(not(feature = "std"))] use ark_std::{string::String, vec::Vec}; -pub use ark_crypto_primitives_macros::*; - /// An interface for objects that can be absorbed by a `CryptographicSponge`. pub trait Absorb { /// Converts the object into a list of bytes that can be absorbed by a `CryptographicSponge`. diff --git a/crypto-primitives/src/sponge/constraints/absorb.rs b/crypto-primitives/src/sponge/constraints/absorb.rs index bb3abb4f..5235f164 100644 --- a/crypto-primitives/src/sponge/constraints/absorb.rs +++ b/crypto-primitives/src/sponge/constraints/absorb.rs @@ -3,15 +3,16 @@ use ark_ec::{ twisted_edwards::TECurveConfig as TEModelParameters, CurveConfig as ModelParameters, }; use ark_ff::{Field, PrimeField}; -use ark_r1cs_std::boolean::Boolean; -use ark_r1cs_std::convert::{ToBytesGadget, ToConstraintFieldGadget}; -use ark_r1cs_std::fields::fp::FpVar; -use ark_r1cs_std::fields::{FieldOpsBounds, FieldVar}; -use ark_r1cs_std::groups::curves::short_weierstrass::{ - AffineVar as SWAffineVar, ProjectiveVar as SWProjectiveVar, +use ark_r1cs_std::{ + boolean::Boolean, + convert::{ToBytesGadget, ToConstraintFieldGadget}, + fields::{fp::FpVar, FieldOpsBounds, FieldVar}, + groups::curves::{ + short_weierstrass::{AffineVar as SWAffineVar, ProjectiveVar as SWProjectiveVar}, + twisted_edwards::AffineVar as TEAffineVar, + }, + uint8::UInt8, }; -use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar as TEAffineVar; -use ark_r1cs_std::uint8::UInt8; use ark_relations::r1cs::SynthesisError; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; @@ -213,9 +214,9 @@ impl> AbsorbGadget for &A { } } -/// Individually absorbs each element in a comma-separated list of [`Absorbable`]s into a sponge. +/// Individually absorbs each element in a comma-separated list of [`AbsorbGadget`]s into a sponge. /// Format is `absorb!(s, a_0, a_1, ..., a_n)`, where `s` is a mutable reference to a sponge -/// and each `a_i` implements `AbsorbableVar`. +/// and each `a_i` implements [`AbsorbGadget`]. #[macro_export] macro_rules! absorb_gadget { ($sponge:expr, $($absorbable:expr),+ ) => { @@ -225,7 +226,7 @@ macro_rules! absorb_gadget { }; } -/// Quickly convert a list of different [`Absorbable`]s into sponge field elements. +/// Quickly convert a list of different [`AbsorbGadget`]s into sponge field elements. #[macro_export] macro_rules! collect_sponge_field_elements_gadget { ($head:expr $(, $tail:expr)* ) => { diff --git a/crypto-primitives/src/sponge/constraints/mod.rs b/crypto-primitives/src/sponge/constraints/mod.rs index aa872fe5..51acebb1 100644 --- a/crypto-primitives/src/sponge/constraints/mod.rs +++ b/crypto-primitives/src/sponge/constraints/mod.rs @@ -1,14 +1,22 @@ use crate::sponge::{Absorb, CryptographicSponge, FieldElementSize}; use ark_ff::PrimeField; -use ark_r1cs_std::alloc::AllocVar; -use ark_r1cs_std::boolean::Boolean; -use ark_r1cs_std::fields::emulated_fp::params::{get_params, OptimizationType}; -use ark_r1cs_std::fields::emulated_fp::{AllocatedEmulatedFpVar, EmulatedFpVar}; -use ark_r1cs_std::fields::fp::{AllocatedFp, FpVar}; -use ark_r1cs_std::uint8::UInt8; -use ark_r1cs_std::R1CSVar; -use ark_relations::lc; -use ark_relations::r1cs::{ConstraintSystemRef, LinearCombination, SynthesisError}; +use ark_r1cs_std::{ + alloc::AllocVar, + boolean::Boolean, + fields::{ + emulated_fp::{ + params::{get_params, OptimizationType}, + AllocatedEmulatedFpVar, EmulatedFpVar, + }, + fp::{AllocatedFp, FpVar}, + }, + uint8::UInt8, + R1CSVar, +}; +use ark_relations::{ + lc, + r1cs::{ConstraintSystemRef, LinearCombination, SynthesisError}, +}; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; diff --git a/crypto-primitives/src/sponge/merlin/mod.rs b/crypto-primitives/src/sponge/merlin/mod.rs new file mode 100644 index 00000000..47906dee --- /dev/null +++ b/crypto-primitives/src/sponge/merlin/mod.rs @@ -0,0 +1,33 @@ +use crate::sponge::{Absorb, CryptographicSponge}; +#[cfg(not(feature = "std"))] +use ark_std::vec::Vec; +pub use merlin::Transcript; + +impl CryptographicSponge for Transcript { + type Config = &'static [u8]; + + fn new(params: &Self::Config) -> Self { + Transcript::new(*params) + } + + fn absorb(&mut self, input: &impl Absorb) { + self.append_message(b"", &input.to_sponge_bytes_as_vec()); + } + + fn squeeze_bytes(&mut self, num_bytes: usize) -> Vec { + let mut dest = vec![0; num_bytes]; + self.challenge_bytes(b"", &mut dest); + dest + } + + fn squeeze_bits(&mut self, num_bits: usize) -> Vec { + let num_bytes = (num_bits + 7) / 8; + let mut tmp = vec![0; num_bytes]; + self.challenge_bytes(b"", &mut tmp); + let dest = tmp + .iter() + .flat_map(|byte| (0..8u32).rev().map(move |i| (byte >> i) & 1 == 1)) + .collect::>(); + dest[..num_bits].to_vec() + } +} diff --git a/crypto-primitives/src/sponge/mod.rs b/crypto-primitives/src/sponge/mod.rs index 2356f169..47a2c202 100644 --- a/crypto-primitives/src/sponge/mod.rs +++ b/crypto-primitives/src/sponge/mod.rs @@ -17,6 +17,11 @@ pub use absorb::*; /// [cos]: https://eprint.iacr.org/2019/1076 pub mod poseidon; +/// The sponge for [Merlin][merlin] +/// +/// [merlin]: https://merlin.cool/ +pub mod merlin; + #[cfg(test)] mod test; diff --git a/crypto-primitives/src/sponge/poseidon/constraints.rs b/crypto-primitives/src/sponge/poseidon/constraints.rs index fc0409ac..60aa800b 100644 --- a/crypto-primitives/src/sponge/poseidon/constraints.rs +++ b/crypto-primitives/src/sponge/poseidon/constraints.rs @@ -1,11 +1,10 @@ -use crate::sponge::constraints::AbsorbGadget; -use crate::sponge::constraints::{CryptographicSpongeVar, SpongeWithGadget}; -use crate::sponge::poseidon::{PoseidonConfig, PoseidonSponge}; -use crate::sponge::DuplexSpongeMode; - +use crate::sponge::{ + constraints::{AbsorbGadget, CryptographicSpongeVar, SpongeWithGadget}, + poseidon::{PoseidonConfig, PoseidonSponge}, + DuplexSpongeMode, +}; use ark_ff::PrimeField; -use ark_r1cs_std::fields::fp::FpVar; -use ark_r1cs_std::prelude::*; +use ark_r1cs_std::{fields::fp::FpVar, prelude::*}; use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError}; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; @@ -169,12 +168,13 @@ impl PoseidonSpongeVar { ..(self.parameters.capacity + num_elements_squeezed + rate_start_index)], ); + // Repeat with updated output slices and rate start index + remaining_output = &mut remaining_output[num_elements_squeezed..]; + // Unless we are done with squeezing in this call, permute. - if remaining_output.len() != self.parameters.rate { + if !remaining_output.is_empty() { self.permute()?; } - // Repeat with updated output slices and rate start index - remaining_output = &mut remaining_output[num_elements_squeezed..]; rate_start_index = 0; } } @@ -223,7 +223,6 @@ impl CryptographicSpongeVar> for PoseidonSpo DuplexSpongeMode::Squeezing { next_squeeze_index: _, } => { - self.permute()?; self.absorb_internal(0, input.as_slice())?; } }; diff --git a/crypto-primitives/src/sponge/poseidon/mod.rs b/crypto-primitives/src/sponge/poseidon/mod.rs index eee18b93..471c1622 100644 --- a/crypto-primitives/src/sponge/poseidon/mod.rs +++ b/crypto-primitives/src/sponge/poseidon/mod.rs @@ -174,12 +174,13 @@ impl PoseidonSponge { ..(self.parameters.capacity + num_elements_squeezed + rate_start_index)], ); + // Repeat with updated output slices + output_remaining = &mut output_remaining[num_elements_squeezed..]; // Unless we are done with squeezing in this call, permute. - if output_remaining.len() != self.parameters.rate { + if !output_remaining.is_empty() { self.permute(); } - // Repeat with updated output slices - output_remaining = &mut output_remaining[num_elements_squeezed..]; + rate_start_index = 0; } } @@ -250,7 +251,6 @@ impl CryptographicSponge for PoseidonSponge { DuplexSpongeMode::Squeezing { next_squeeze_index: _, } => { - self.permute(); self.absorb_internal(0, elems.as_slice()); } }; diff --git a/crypto-primitives/src/sponge/poseidon/tests.rs b/crypto-primitives/src/sponge/poseidon/tests.rs index cc44fd73..337caf7f 100644 --- a/crypto-primitives/src/sponge/poseidon/tests.rs +++ b/crypto-primitives/src/sponge/poseidon/tests.rs @@ -1,10 +1,244 @@ -use crate::sponge::poseidon::{PoseidonConfig, PoseidonSponge}; -use crate::sponge::test::Fr; -use crate::sponge::{Absorb, AbsorbWithLength, CryptographicSponge, FieldBasedCryptographicSponge}; -use crate::{absorb, collect_sponge_bytes, collect_sponge_field_elements}; +use crate::{ + absorb, collect_sponge_bytes, collect_sponge_field_elements, + sponge::{ + poseidon::{PoseidonConfig, PoseidonDefaultConfigField, PoseidonSponge}, + test::Fr, + Absorb, AbsorbWithLength, CryptographicSponge, FieldBasedCryptographicSponge, + }, +}; use ark_ff::{One, PrimeField, UniformRand}; use ark_std::test_rng; +#[test] +// Remove once this PR matures +fn demo_bug() { + let sponge_params = Fr::get_default_poseidon_parameters(2, false).unwrap(); + + let rng = &mut test_rng(); + let input = (0..3).map(|_| Fr::rand(rng)).collect::>(); + + // works good + let e0 = { + let mut sponge = PoseidonSponge::::new(&sponge_params); + sponge.absorb(&input); + sponge.squeeze_native_field_elements(3) + }; + + // works good + let e1 = { + let mut sponge = PoseidonSponge::::new(&sponge_params); + sponge.absorb(&input); + let e0 = sponge.squeeze_native_field_elements(1); + let e1 = sponge.squeeze_native_field_elements(1); + let e2 = sponge.squeeze_native_field_elements(1); + e0.iter() + .chain(e1.iter()) + .chain(e2.iter()) + .cloned() + .collect::>() + }; + + // also works good + let e2 = { + let mut sponge = PoseidonSponge::::new(&sponge_params); + sponge.absorb(&input); + + let e0 = sponge.squeeze_native_field_elements(2); + let e1 = sponge.squeeze_native_field_elements(1); + e0.iter().chain(e1.iter()).cloned().collect::>() + }; + + // skips a permutation if sponge + // * in squeezing mode + // * number of elements are equal to rate + let e3 = { + let mut sponge = PoseidonSponge::::new(&sponge_params); + sponge.absorb(&input); + let e0 = sponge.squeeze_native_field_elements(1); + let e1 = sponge.squeeze_native_field_elements(2); + e0.iter().chain(e1.iter()).cloned().collect::>() + }; + + assert_eq!(e0, e1); + assert_eq!(e0, e2); + assert_eq!(e0, e3); // this will fail +} + +// Remove once this PR matures +fn run_cross_test(cfg: &PoseidonConfig) { + #[derive(Debug, PartialEq, Eq)] + enum SpongeMode { + Absorbing, + Squeezing, + } + + #[derive(Clone, Debug)] + struct Reference { + cfg: PoseidonConfig, + state: Vec, + absorbing: Vec, + squeeze_count: Option, + } + + // workaround to permute a state + fn permute(cfg: &PoseidonConfig, state: &mut [F]) { + let mut sponge = PoseidonSponge::new(&cfg); + sponge.state.copy_from_slice(state); + sponge.permute(); + state.copy_from_slice(&sponge.state) + } + + impl Reference { + fn new(cfg: &PoseidonConfig) -> Self { + let t = cfg.rate + cfg.capacity; + let state = vec![F::zero(); t]; + Self { + cfg: cfg.clone(), + state, + absorbing: Vec::new(), + squeeze_count: None, + } + } + + fn mode(&self) -> SpongeMode { + match self.squeeze_count { + Some(_) => { + assert!(self.absorbing.is_empty()); + SpongeMode::Squeezing + } + None => SpongeMode::Absorbing, + } + } + + fn absorb(&mut self, input: &[F]) { + if !input.is_empty() { + match self.mode() { + SpongeMode::Absorbing => self.absorbing.extend_from_slice(input), + SpongeMode::Squeezing => { + // Append inputs to the absorbing line + self.absorbing.extend_from_slice(input); + // Change mode to absorbing + self.squeeze_count = None; + } + } + } + } + + fn _absorb(&mut self) { + let rate = self.cfg.rate; + self.absorbing.chunks(rate).for_each(|chunk| { + self.state + .iter_mut() + .skip(self.cfg.capacity) + .zip(chunk.iter()) + .for_each(|(s, c)| *s += *c); + permute(&self.cfg, &mut self.state); + }); + + // This case can only happen in the begining when the absorbing line is empty + // and user wants to squeeze elements. Notice that after moving to squueze mode + // if user calls absorb again with empty input it will be ignored + self.absorbing + .is_empty() + .then(|| permute(&self.cfg, &mut self.state)); + + // flush the absorbing line + self.absorbing.clear(); + + // Change to the squeezing mode + assert_eq!(self.mode(), SpongeMode::Absorbing); + self.squeeze_count = Some(0); + } + + pub fn squeeze(&mut self, n: usize) -> Vec { + match self.mode() { + SpongeMode::Absorbing => self._absorb(), + SpongeMode::Squeezing => { + assert!(self.absorbing.is_empty()); + assert!(self.squeeze_count.is_some()); + + // ??? + // **This seems nonsense to me** + // If, + // * number of squeeze is zero AND + // * in squeezing mode AND + // * output index is is at `rate` + // it applies a useless permutation. + // This is also not appied in SAFE sponge + + if n == 0 { + let squeeze_count = self.squeeze_count.unwrap(); + let out_index = self.squeeze_count.unwrap() % self.cfg.rate; + (out_index == 0 && squeeze_count != 0).then(|| { + permute(&self.cfg, &mut self.state); + self.squeeze_count = Some(0); + }); + } + } + } + + let rate = self.cfg.rate; + let mut output = Vec::new(); + for _ in 0..n { + let squeeze_count = self.squeeze_count.unwrap(); + let out_index = squeeze_count % rate; + + // proceed with a permutation if + // * the rate is full + // * and it is not the first output + (out_index == 0 && squeeze_count != 0).then(|| permute(&self.cfg, &mut self.state)); + + // skip the capacity elements + let out_index = out_index + self.cfg.capacity; + output.push(self.state[out_index]); + self.squeeze_count.as_mut().map(|c| *c += 1); + } + + output + } + } + + let mut sponge = PoseidonSponge::new(cfg); + let mut sponge_ref = Reference::new(cfg); + let mut rng = test_rng(); + + for _ in 0..1000 { + let test = (0..100) + .map(|_| { + use crate::ark_std::rand::Rng; + let do_absorb = rng.gen_bool(0.5); + let do_squeeze = rng.gen_bool(0.5); + + ( + (do_absorb, rng.gen_range(0..=cfg.rate * 2 + 1)), + (do_squeeze, rng.gen_range(0..=cfg.rate * 2 + 1)), + ) + }) + .collect::>(); + + // fuzz fuzz + for (_i, ((do_absorb, n_absorb), (do_squeeze, n_squeeze))) in test.into_iter().enumerate() { + do_absorb.then(|| { + let inputs = (0..n_absorb).map(|_| F::rand(&mut rng)).collect::>(); + sponge_ref.absorb(&inputs); + sponge.absorb(&inputs); + }); + do_squeeze.then(|| { + let out0 = sponge_ref.squeeze(n_squeeze); + let out1 = sponge.squeeze_field_elements(n_squeeze); + assert_eq!(out0, out1); + }); + } + } +} + +#[test] +// Remove once this PR matures +fn test_cross() { + let cfg = Fr::get_default_poseidon_parameters(2, false).unwrap(); + run_cross_test::(&cfg); +} + fn assert_different_encodings(a: &A, b: &A) { let bytes1 = a.to_sponge_bytes_as_vec(); let bytes2 = b.to_sponge_bytes_as_vec(); diff --git a/crypto-primitives/src/sponge/poseidon/traits.rs b/crypto-primitives/src/sponge/poseidon/traits.rs index c1c446e7..bfe10fed 100644 --- a/crypto-primitives/src/sponge/poseidon/traits.rs +++ b/crypto-primitives/src/sponge/poseidon/traits.rs @@ -1,5 +1,4 @@ -use crate::sponge::poseidon::grain_lfsr::PoseidonGrainLFSR; -use crate::sponge::poseidon::PoseidonConfig; +use crate::sponge::poseidon::{grain_lfsr::PoseidonGrainLFSR, PoseidonConfig}; use ark_ff::{fields::models::*, PrimeField}; #[cfg(not(feature = "std"))] use ark_std::vec::Vec;