diff --git a/crypto-primitives/Cargo.toml b/crypto-primitives/Cargo.toml index a3c9bc5..5799c15 100644 --- a/crypto-primitives/Cargo.toml +++ b/crypto-primitives/Cargo.toml @@ -26,6 +26,7 @@ ark-serialize = { version = "^0.4.0", default-features = false, features = [ "de 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.4.0", optional = true, default-features = false } ark-snark = { version = "^0.4.0", 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/merkle_tree/constraints.rs b/crypto-primitives/src/merkle_tree/constraints.rs index aa9fbb8..ccad3a9 100644 --- a/crypto-primitives/src/merkle_tree/constraints.rs +++ b/crypto-primitives/src/merkle_tree/constraints.rs @@ -1,5 +1,5 @@ use crate::crh::TwoToOneCRHSchemeGadget; -use crate::merkle_tree::{Config, IdentityDigestConverter}; +use crate::merkle_tree::Config; use crate::{crh::CRHSchemeGadget, merkle_tree::Path}; use ark_ff::PrimeField; use ark_r1cs_std::prelude::*; @@ -9,11 +9,15 @@ use ark_std::fmt::Debug; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; +#[cfg(test)] +use crate::merkle_tree::IdentityDigestConverter; + pub trait DigestVarConverter { type TargetType: Borrow; fn convert(from: From) -> Result; } +#[cfg(test)] impl DigestVarConverter for IdentityDigestConverter { type TargetType = T; diff --git a/crypto-primitives/src/merkle_tree/mod.rs b/crypto-primitives/src/merkle_tree/mod.rs index 5a7e493..14b9671 100644 --- a/crypto-primitives/src/merkle_tree/mod.rs +++ b/crypto-primitives/src/merkle_tree/mod.rs @@ -49,10 +49,12 @@ pub trait DigestConverter { } /// A trivial converter where digest of previous layer's hash is the same as next layer's input. +#[cfg(test)] pub struct IdentityDigestConverter { _prev_layer_digest: T, } +#[cfg(test)] impl DigestConverter for IdentityDigestConverter { type TargetType = T; fn convert(item: T) -> Result { diff --git a/crypto-primitives/src/sponge/merlin/mod.rs b/crypto-primitives/src/sponge/merlin/mod.rs new file mode 100644 index 0000000..47906de --- /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 2356f16..47a2c20 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;