diff --git a/CHANGELOG.md b/CHANGELOG.md index 573cfc2..2b9cb06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## v0.4.0 +* security fix: derive challenges for zero-knowledge proof unambiguously + ## v0.3.0 * Update `generic-ec` dep to v0.3 [#48] diff --git a/Cargo.lock b/Cargo.lock index cd361b2..5d8cfaa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -344,9 +344,9 @@ dependencies = [ [[package]] name = "generic-ec" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c35601473af37794b53e8c7dc4a540a659d8de54c957990e88715b4037597d1" +checksum = "10cc122ac7a2ebc45550f766cd23a9040f6d15db440230b0888e5645e8eb2cb4" dependencies = [ "curve25519-dalek", "generic-ec-core", @@ -357,6 +357,7 @@ dependencies = [ "serde", "serde_with 2.0.1", "subtle", + "udigest", "zeroize", ] @@ -517,7 +518,7 @@ dependencies = [ [[package]] name = "paillier-zk" -version = "0.3.0" +version = "0.4.0" dependencies = [ "anyhow", "digest", @@ -525,6 +526,7 @@ dependencies = [ "generic-ec", "rand_core", "rand_dev", + "rand_hash", "rug", "serde", "serde_json", @@ -532,6 +534,7 @@ dependencies = [ "sha2", "subtle", "thiserror", + "udigest", "zeroize", ] @@ -613,6 +616,17 @@ dependencies = [ "rand_core", ] +[[package]] +name = "rand_hash" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "257d7a1ad5533c1faca40f34d4a1ead75b414f16611c0ec210b7fd23e440475f" +dependencies = [ + "digest", + "rand_core", + "udigest", +] + [[package]] name = "rug" version = "1.21.0" @@ -830,6 +844,27 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +[[package]] +name = "udigest" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a435a16abb7029ba807a45242367b087dd767e87e2e5ebc5f0e4189ea114a23" +dependencies = [ + "digest", + "udigest-derive", +] + +[[package]] +name = "udigest-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6296c12e792dbc59565a58920d8d1842997ad5a72ddf2a51f70d70bd7af2ba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "unicode-ident" version = "1.0.5" diff --git a/Cargo.toml b/Cargo.toml index d7477c1..ee2b240 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "paillier-zk" -version = "0.3.0" +version = "0.4.0" edition = "2021" license = "MIT OR Apache-2.0" description = "ZK-proofs for Paillier encryption scheme" @@ -11,7 +11,7 @@ keywords = ["paillier", "zk-proofs", "zero-knowledge"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -generic-ec = "0.3" +generic-ec = { version = "0.4", features = ["udigest"] } rand_core = { version = "0.6", default-features = false } digest = "0.10" fast-paillier = "0.1" @@ -22,9 +22,12 @@ thiserror = "1" serde = { version = "1", features = ["derive"], optional = true } serde_with = { version = "3", default-features = false, features = ["macros"], optional = true } +udigest = { version = "0.2", default-features = false, features = ["inline-struct", "derive"] } +rand_hash = "0.1" + [dev-dependencies] -generic-ec = { version = "0.3", features = ["all-curves"] } -rand_dev = { version = "0.1.0", default-features = false } +generic-ec = { version = "0.4", features = ["udigest", "all-curves"] } +rand_dev = { version = "0.1", default-features = false } sha2 = { version = "0.10", default-features = false } subtle = { version = "2.4", default-features = false } @@ -46,3 +49,4 @@ required-features = ["serde"] [package.metadata.docs.rs] all-features = true + diff --git a/src/common.rs b/src/common.rs index 21af485..08de152 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,4 +1,3 @@ -pub mod rng; pub mod sqrt; use std::sync::Arc; @@ -64,6 +63,17 @@ impl Aux { .into()), } } + + /// Returns a stripped version of `Aux` that contains only public data which can be digested + /// via [`udigest::Digestable`] + pub fn digest_public_data(&self) -> impl udigest::Digestable { + let order = rug::integer::Order::Msf; + udigest::inline_struct!("paillier_zk.aux" { + s: udigest::Bytes(self.s.to_digits::(order)), + t: udigest::Bytes(self.t.to_digits::(order)), + rsa_modulo: udigest::Bytes(self.rsa_modulo.to_digits::(order)), + }) + } } /// Error indicating that proof is invalid @@ -257,6 +267,27 @@ pub fn fail_if_ne(err: E, lhs: T, rhs: T) -> Result<(), E> { } } +/// Digests an integer +/// +/// To be used within `#[udigest(with = "...")]` attribute +pub fn digest_integer( + value: &Integer, + encoder: udigest::encoding::EncodeValue, +) { + let digits = value.to_digits::(rug::integer::Order::Msf); + encoder.encode_leaf_value(digits) +} + +/// Digests any encryption key +/// +/// To be used within `#[udigest(with = "...")]` attribute +pub fn digest_encryption_key( + value: &&dyn fast_paillier::AnyEncryptionKey, + encoder: udigest::encoding::EncodeValue, +) { + digest_integer::(value.n(), encoder) +} + /// A common logic shared across tests and doctests #[cfg(test)] pub mod test { diff --git a/src/common/rng.rs b/src/common/rng.rs deleted file mode 100644 index 2ef0d31..0000000 --- a/src/common/rng.rs +++ /dev/null @@ -1,90 +0,0 @@ -use digest::Digest; - -/// Pseudo-random generateur that obtains values by hashing the provided values -/// salted with an internal counter. The counter is prepended to conserve -/// entropy. -/// -/// Useful when you want to deterministically but securely generate elliptic -/// curve points and scalars from some data -/// -/// Having u64 counter means that the period of the sequence is 2^64 times -/// `Digest::OutputSize` bytes -pub struct HashRng { - hasher: F, - counter: u64, - buffer: digest::Output, - offset: usize, -} - -impl HashRng { - /// Create RNG from a function that will update and finalize a digest. Use it like this: - /// ```ignore - /// HashRng::new(|d| d.chain_update("my_values").finalize()) - /// ``` - pub fn new(hasher: F) -> Self - where - F: Fn(D) -> digest::Output, - { - let d: D = D::new().chain_update(0u64.to_le_bytes()); - let buffer: digest::Output = hasher(d); - HashRng { - hasher, - counter: 1, - offset: 0, - buffer, - } - } -} - -impl rand_core::RngCore for HashRng -where - D: Digest, - F: Fn(D) -> digest::Output, -{ - fn next_u32(&mut self) -> u32 { - const SIZE: usize = std::mem::size_of::(); - // NOTE: careful with SIZE usage, otherwise it panics - if self.offset + SIZE > self.buffer.len() { - self.buffer = (self.hasher)(D::new().chain_update(self.counter.to_le_bytes())); - self.counter = self.counter.wrapping_add(1); - self.offset = 0; - } - let bytes = &self.buffer[self.offset..self.offset + SIZE]; - self.offset += SIZE; - #[allow(clippy::expect_used)] - let bytes: [u8; SIZE] = bytes.try_into().expect("Size mismatch"); - u32::from_le_bytes(bytes) - } - - fn next_u64(&mut self) -> u64 { - rand_core::impls::next_u64_via_u32(self) - } - - fn fill_bytes(&mut self, dest: &mut [u8]) { - rand_core::impls::fill_bytes_via_next(self, dest) - } - - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { - self.fill_bytes(dest); - Ok(()) - } -} - -#[cfg(test)] -mod test { - use rand_core::RngCore; - use sha2::Digest; - - #[test] - fn generate_bytes() { - let hasher = |d: sha2::Sha256| d.chain_update("foobar").finalize(); - let mut rng = super::HashRng::new(hasher); - - // Check that it doesn't panic for any window size - for _ in 0..100 { - let size = (rng.next_u32() as usize) % 256 + 1; - let mut buffer = vec![0; size]; - rng.fill_bytes(&mut buffer); - } - } -} diff --git a/src/group_element_vs_paillier_encryption_in_range.rs b/src/group_element_vs_paillier_encryption_in_range.rs index fbea4a7..ccdd04c 100644 --- a/src/group_element_vs_paillier_encryption_in_range.rs +++ b/src/group_element_vs_paillier_encryption_in_range.rs @@ -34,8 +34,7 @@ //! //! # fn main() -> Result<(), Box> { //! // Prover and verifier have a shared protocol state -//! let shared_state_prover = sha2::Sha256::default(); -//! let shared_state_verifier = sha2::Sha256::default(); +//! let shared_state = "some shared state"; //! let mut rng = rand_core::OsRng; //! # let mut rng = rand_dev::DevRng::new(); //! @@ -69,8 +68,8 @@ //! b: &Point::::generator().into(), //! }; //! let (commitment, proof) = -//! p::non_interactive::prove( -//! shared_state_prover, +//! p::non_interactive::prove::( +//! &shared_state, //! &aux, //! data, //! p::PrivateData { x: &x, nonce: &nonce }, @@ -87,8 +86,8 @@ //! //! # let recv = || (data, commitment, proof); //! let (data, commitment, proof) = recv(); -//! p::non_interactive::verify( -//! shared_state_verifier, +//! p::non_interactive::verify::( +//! &shared_state, //! &aux, //! data, //! &commitment, @@ -111,7 +110,7 @@ pub use crate::common::Aux; /// Security parameters for proof. Choosing the values is a tradeoff between /// speed and chance of rejecting a valid proof or accepting an invalid proof -#[derive(Debug, Clone)] +#[derive(Debug, Clone, udigest::Digestable)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct SecurityParams { /// l in paper, bit size of +-plaintext @@ -119,15 +118,19 @@ pub struct SecurityParams { /// Epsilon in paper, slackness parameter pub epsilon: usize, /// q in paper. Security parameter for challenge + #[udigest(with = crate::common::digest_integer)] pub q: Integer, } /// Public data that both parties know -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, udigest::Digestable)] +#[udigest(bound = "")] pub struct Data<'a, C: Curve> { /// N0 in paper, public key that C was encrypted on + #[udigest(with = crate::common::digest_encryption_key)] pub key0: &'a dyn AnyEncryptionKey, /// C in paper, logarithm of X encrypted on N0 + #[udigest(with = crate::common::digest_integer)] pub c: &'a Ciphertext, /// A basepoint, generator in group pub b: &'a Point, @@ -145,12 +148,16 @@ pub struct PrivateData<'a> { } /// Prover's first message, obtained by [`interactive::commit`] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, udigest::Digestable)] +#[udigest(bound = "")] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(bound = ""))] pub struct Commitment { + #[udigest(with = crate::common::digest_integer)] pub s: Integer, + #[udigest(with = crate::common::digest_integer)] pub a: Ciphertext, pub y: Point, + #[udigest(with = crate::common::digest_integer)] pub d: Integer, } @@ -302,7 +309,7 @@ pub mod interactive { /// The non-interactive version of proof. Completed in one round, for example /// see the documentation of parent module. pub mod non_interactive { - use digest::{typenum::U32, Digest}; + use digest::Digest; use generic_ec::Curve; use rand_core::RngCore; @@ -314,70 +321,52 @@ pub mod non_interactive { /// deriving determenistic challenge. /// /// Obtained from the above interactive proof via Fiat-Shamir heuristic. - pub fn prove( - shared_state: D, + pub fn prove( + shared_state: &impl udigest::Digestable, aux: &Aux, data: Data, pdata: PrivateData, security: &SecurityParams, - rng: &mut R, - ) -> Result<(Commitment, Proof), Error> - where - D: Digest, - { + rng: &mut impl RngCore, + ) -> Result<(Commitment, Proof), Error> { let (comm, pcomm) = super::interactive::commit(aux, data, pdata, security, rng)?; - let challenge = challenge(shared_state, aux, data, &comm, security); + let challenge = challenge::(shared_state, aux, data, &comm, security); let proof = super::interactive::prove(data, pdata, &pcomm, &challenge)?; Ok((comm, proof)) } /// Verify the proof, deriving challenge independently from same data - pub fn verify( - shared_state: D, + pub fn verify( + shared_state: &impl udigest::Digestable, aux: &Aux, data: Data, commitment: &Commitment, security: &SecurityParams, proof: &Proof, - ) -> Result<(), InvalidProof> - where - D: Digest, - { - let challenge = challenge(shared_state, aux, data, commitment, security); + ) -> Result<(), InvalidProof> { + let challenge = challenge::(shared_state, aux, data, commitment, security); super::interactive::verify(aux, data, commitment, security, &challenge, proof) } /// Internal function for deriving challenge from protocol values /// deterministically pub fn challenge( - shared_state: D, + shared_state: &impl udigest::Digestable, aux: &Aux, data: Data, commitment: &Commitment, security: &SecurityParams, ) -> Challenge { - let shared_state = shared_state.finalize(); - let hash = |d: D| { - let order = rug::integer::Order::Msf; - d.chain_update(&shared_state) - .chain_update(C::CURVE_NAME) - .chain_update(aux.s.to_digits::(order)) - .chain_update(aux.t.to_digits::(order)) - .chain_update(aux.rsa_modulo.to_digits::(order)) - .chain_update((security.l as u64).to_le_bytes()) - .chain_update((security.epsilon as u64).to_le_bytes()) - .chain_update(data.key0.n().to_digits::(order)) - .chain_update(data.c.to_digits::(order)) - .chain_update(data.x.to_bytes(true)) - .chain_update(data.b.to_bytes(true)) - .chain_update(commitment.s.to_digits::(order)) - .chain_update(commitment.a.to_digits::(order)) - .chain_update(commitment.y.to_bytes(true)) - .chain_update(commitment.d.to_digits::(order)) - .finalize() - }; - - let mut rng = crate::common::rng::HashRng::new(hash); + let tag = "paillier-zk.group_element_vs_paillier_encryption_in_range.ni-challenge"; + let aux = aux.digest_public_data(); + let seed = udigest::inline_struct!(tag { + shared_state, + aux, + security, + data, + commitment, + }); + let mut rng = rand_hash::HashRng::::from_seed(seed); super::interactive::challenge(security, &mut rng) } } @@ -386,11 +375,12 @@ pub mod non_interactive { mod test { use generic_ec::{Curve, Point, Scalar}; use rug::{Complete, Integer}; + use sha2::Digest; use crate::common::test::random_key; use crate::common::{IntegerExt, InvalidProofReason}; - fn run( + fn run( mut rng: R, security: super::SecurityParams, plaintext: Integer, @@ -415,10 +405,10 @@ mod test { let aux = crate::common::test::aux(&mut rng); - let shared_state = sha2::Sha256::default(); + let shared_state = "shared state"; - let (commitment, proof) = super::non_interactive::prove( - shared_state.clone(), + let (commitment, proof) = super::non_interactive::prove::( + &shared_state, &aux, data, pdata, @@ -427,10 +417,17 @@ mod test { ) .unwrap(); - super::non_interactive::verify(shared_state, &aux, data, &commitment, &security, &proof) + super::non_interactive::verify::( + &shared_state, + &aux, + data, + &commitment, + &security, + &proof, + ) } - fn passing_test() { + fn passing_test() { let mut rng = rand_dev::DevRng::new(); let security = super::SecurityParams { l: 1024, @@ -438,10 +435,10 @@ mod test { q: (Integer::ONE << 128_u32).complete(), }; let plaintext = Integer::from_rng_pm(&(Integer::ONE << security.l).complete(), &mut rng); - run::<_, C>(rng, security, plaintext).expect("proof failed"); + run::<_, C, D>(rng, security, plaintext).expect("proof failed"); } - fn failing_test() { + fn failing_test() { let rng = rand_dev::DevRng::new(); let security = super::SecurityParams { l: 1024, @@ -449,7 +446,7 @@ mod test { q: (Integer::ONE << 128_u32).complete(), }; let plaintext = (Integer::ONE << (security.l + security.epsilon + 1)).complete(); - let r = run::<_, C>(rng, security, plaintext).expect_err("proof should not pass"); + let r = run::<_, C, D>(rng, security, plaintext).expect_err("proof should not pass"); match r.reason() { InvalidProofReason::RangeCheck(_) => (), e => panic!("proof should not fail with: {e:?}"), @@ -458,19 +455,19 @@ mod test { #[test] fn passing_p256() { - passing_test::() + passing_test::() } #[test] fn failing_p256() { - failing_test::() + failing_test::() } #[test] fn passing_million() { - passing_test::() + passing_test::() } #[test] fn failing_million() { - failing_test::() + failing_test::() } } diff --git a/src/lib.rs b/src/lib.rs index 66791ef..95ddc7b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ compile_error!("doctest require that `__internal_doctest` feature is turned on") pub mod _doctest; use common::InvalidProofReason; -pub use common::{rng, BadExponent, IntegerExt, InvalidProof, PaillierError}; +pub use common::{BadExponent, IntegerExt, InvalidProof, PaillierError}; pub use {fast_paillier, rug, rug::Integer}; /// Library general error type diff --git a/src/no_small_factor.rs b/src/no_small_factor.rs index d65e21a..96bc452 100644 --- a/src/no_small_factor.rs +++ b/src/no_small_factor.rs @@ -21,8 +21,7 @@ //! # } //! //! # fn main() -> Result<(), Box> { -//! let shared_state_prover = sha2::Sha256::default(); -//! let shared_state_verifier = sha2::Sha256::default(); +//! let shared_state = "some shared state"; //! let mut rng = rand_core::OsRng; //! # let mut rng = rand_dev::DevRng::new(); //! @@ -49,13 +48,13 @@ //! //! // 2. Prover computes a non-interactive proof that both factors are large enough //! -//! let proof = p::prove( -//! shared_state_prover, +//! let proof = p::prove::( +//! &shared_state, //! &aux, //! data, //! p::PrivateData { p: &p, q: &q }, //! &security, -//! rng, +//! &mut rng, //! )?; //! //! // 4. Prover sends this data to verifier @@ -72,7 +71,7 @@ //! n: &n, //! n_root: &n_root, //! }; -//! p::verify(shared_state_verifier, &aux, data, &security, &proof)?; +//! p::verify::(&shared_state, &aux, data, &security, &proof)?; //! # Ok(()) } //! ``` //! @@ -87,7 +86,7 @@ pub use crate::common::{Aux, InvalidProof}; /// Security parameters for proof. Choosing the values is a tradeoff between /// speed and chance of rejecting a valid proof or accepting an invalid proof -#[derive(Debug, Clone)] +#[derive(Debug, Clone, udigest::Digestable)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct SecurityParams { /// l in paper, security parameter for bit size of plaintext: it needs to @@ -96,15 +95,18 @@ pub struct SecurityParams { /// Epsilon in paper, slackness parameter pub epsilon: usize, /// q in paper. Security parameter for challenge + #[udigest(with = crate::common::digest_integer)] pub q: Integer, } /// Public data that both parties know -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, udigest::Digestable)] pub struct Data<'a> { /// N0 - rsa modulus + #[udigest(with = crate::common::digest_integer)] pub n: &'a Integer, /// A number close to square root of n + #[udigest(with = crate::common::digest_integer)] pub n_root: &'a Integer, } @@ -130,14 +132,20 @@ pub struct PrivateCommitment { } /// Prover's first message, obtained by [`interactive::commit`] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, udigest::Digestable)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Commitment { + #[udigest(with = crate::common::digest_integer)] pub p: Integer, + #[udigest(with = crate::common::digest_integer)] pub q: Integer, + #[udigest(with = crate::common::digest_integer)] pub a: Integer, + #[udigest(with = crate::common::digest_integer)] pub b: Integer, + #[udigest(with = crate::common::digest_integer)] pub t: Integer, + #[udigest(with = crate::common::digest_integer)] pub sigma: Integer, } @@ -292,8 +300,7 @@ pub mod interactive { /// Non-interactive version of the proof pub mod non_interactive { - use digest::{typenum::U32, Digest}; - use rand_core::RngCore; + use digest::Digest; pub use crate::{Error, InvalidProof}; @@ -311,67 +318,49 @@ pub mod non_interactive { /// deriving determenistic challenge. /// /// Obtained from the above interactive proof via Fiat-Shamir heuristic. - pub fn prove( - shared_state: D, + pub fn prove( + shared_state: &impl udigest::Digestable, aux: &Aux, data: Data, pdata: PrivateData, security: &SecurityParams, - rng: R, - ) -> Result - where - D: Digest, - { + rng: &mut impl rand_core::RngCore, + ) -> Result { let (commitment, pcomm) = super::interactive::commit(aux, data, pdata, security, rng)?; - let challenge = challenge(shared_state, aux, data, &commitment, security); + let challenge = challenge::(shared_state, aux, data, &commitment, security); let proof = super::interactive::prove(pdata, &commitment, &pcomm, &challenge)?; Ok(Proof { commitment, proof }) } /// Deterministically compute challenge based on prior known values in protocol - pub fn challenge( - shared_state: D, + pub fn challenge( + shared_state: &impl udigest::Digestable, aux: &Aux, data: Data, commitment: &super::Commitment, security: &SecurityParams, - ) -> Challenge - where - D: Digest, - { - let shared_state = shared_state.finalize(); - let hash = |d: D| { - let order = rug::integer::Order::Msf; - d.chain_update(&shared_state) - .chain_update(aux.s.to_digits::(order)) - .chain_update(aux.t.to_digits::(order)) - .chain_update(aux.rsa_modulo.to_digits::(order)) - .chain_update(data.n.to_digits::(order)) - .chain_update(data.n_root.to_digits::(order)) - .chain_update(commitment.p.to_digits::(order)) - .chain_update(commitment.q.to_digits::(order)) - .chain_update(commitment.a.to_digits::(order)) - .chain_update(commitment.b.to_digits::(order)) - .chain_update(commitment.t.to_digits::(order)) - .chain_update(commitment.sigma.to_digits::(order)) - .finalize() - }; - let mut rng = crate::common::rng::HashRng::new(hash); + ) -> Challenge { + let tag = "paillier_zk.no_small_factor.ni_challenge"; + let seed = udigest::inline_struct!(tag { + shared_state, + security, + aux: aux.digest_public_data(), + data, + commitment, + }); + let mut rng = rand_hash::HashRng::::from_seed(&seed); super::interactive::challenge(security, &mut rng) } /// Verify the proof, deriving challenge independently from same data - pub fn verify( - shared_state: D, + pub fn verify( + shared_state: &impl udigest::Digestable, aux: &Aux, data: Data, security: &SecurityParams, proof: &Proof, - ) -> Result<(), InvalidProof> - where - D: Digest, - { - let challenge = challenge(shared_state, aux, data, &proof.commitment, security); + ) -> Result<(), InvalidProof> { + let challenge = challenge::(shared_state, aux, data, &proof.commitment, security); super::interactive::verify( aux, data, @@ -395,6 +384,8 @@ mod test { #[test] fn passing() { + type D = sha2::Sha256; + let mut rng = rand_dev::DevRng::new(); let p = generate_blum_prime(&mut rng, 256); let q = generate_blum_prime(&mut rng, 256); @@ -410,17 +401,17 @@ mod test { q: (Integer::ONE << 128_u32).complete(), }; let aux = crate::common::test::aux(&mut rng); - let shared_state = sha2::Sha256::default(); - let proof = super::non_interactive::prove( - shared_state.clone(), + let shared_state = "shared state"; + let proof = super::non_interactive::prove::( + &shared_state, &aux, data, super::PrivateData { p: &p, q: &q }, &security, - rng, + &mut rng, ) .unwrap(); - let r = super::non_interactive::verify(shared_state, &aux, data, &security, &proof); + let r = super::non_interactive::verify::(&shared_state, &aux, data, &security, &proof); match r { Ok(()) => (), Err(e) => panic!("Proof should not fail with {e:?}"), @@ -429,6 +420,8 @@ mod test { #[test] fn failing() { + type D = sha2::Sha256; + let mut rng = rand_dev::DevRng::new(); let p = generate_blum_prime(&mut rng, 128); let q = generate_blum_prime(&mut rng, 384); @@ -444,17 +437,17 @@ mod test { q: (Integer::ONE << 128_u32).complete(), }; let aux = crate::common::test::aux(&mut rng); - let shared_state = sha2::Sha256::default(); - let proof = super::non_interactive::prove( - shared_state.clone(), + let shared_state = "shared state"; + let proof = super::non_interactive::prove::( + &shared_state, &aux, data, super::PrivateData { p: &p, q: &q }, &security, - rng, + &mut rng, ) .unwrap(); - let r = super::non_interactive::verify(shared_state, &aux, data, &security, &proof) + let r = super::non_interactive::verify::(&shared_state, &aux, data, &security, &proof) .expect_err("proof should not pass"); match r.reason() { InvalidProofReason::RangeCheck(2) => (), diff --git a/src/paillier_affine_operation_in_range.rs b/src/paillier_affine_operation_in_range.rs index 4db2fb0..bd40af6 100644 --- a/src/paillier_affine_operation_in_range.rs +++ b/src/paillier_affine_operation_in_range.rs @@ -43,8 +43,7 @@ //! //! # fn main() -> Result<(), Box> { //! // Prover and verifier have a shared protocol state -//! let shared_state_prover = sha2::Sha256::default(); -//! let shared_state_verifier = sha2::Sha256::default(); +//! let shared_state = "some shared state"; //! //! let mut rng = rand_core::OsRng; //! # let mut rng = rand_dev::DevRng::new(); @@ -122,8 +121,8 @@ //! nonce_y: &nonce_y, //! }; //! let (commitment, proof) = -//! p::non_interactive::prove( -//! shared_state_prover, +//! p::non_interactive::prove::( +//! &shared_state, //! &aux, //! data, //! pdata, @@ -141,8 +140,8 @@ //! //! # let recv = || (data, commitment, proof); //! let (data, commitment, proof) = recv(); -//! let r = p::non_interactive::verify( -//! shared_state_verifier, +//! let r = p::non_interactive::verify::( +//! &shared_state, //! &aux, //! data, //! &commitment, @@ -166,7 +165,7 @@ pub use crate::common::{Aux, InvalidProof}; /// Security parameters for proof. Choosing the values is a tradeoff between /// speed and chance of rejecting a valid proof or accepting an invalid proof -#[derive(Debug, Clone)] +#[derive(Debug, Clone, udigest::Digestable)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct SecurityParams { /// l in paper, bit size of +-x @@ -176,21 +175,28 @@ pub struct SecurityParams { /// Epsilon in paper, slackness parameter pub epsilon: usize, /// q in paper. Security parameter for challenge + #[udigest(with = crate::common::digest_integer)] pub q: Integer, } /// Public data that both parties know -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, udigest::Digestable)] +#[udigest(bound = "")] pub struct Data<'a, C: Curve> { /// N0 in paper, public key that C was encrypted on + #[udigest(with = crate::common::digest_encryption_key)] pub key0: &'a dyn AnyEncryptionKey, /// N1 in paper, public key that y -> Y was encrypted on + #[udigest(with = crate::common::digest_encryption_key)] pub key1: &'a dyn AnyEncryptionKey, /// C or C0 in paper, some data encrypted on N0 + #[udigest(with = crate::common::digest_integer)] pub c: &'a Ciphertext, /// D or C in paper, result of affine transformation of C0 with x and y + #[udigest(with = crate::common::digest_integer)] pub d: &'a Integer, /// Y in paper, y encrypted on N1 + #[udigest(with = crate::common::digest_integer)] pub y: &'a Ciphertext, /// X in paper, obtained as g^x pub x: &'a Point, @@ -211,15 +217,22 @@ pub struct PrivateData<'a> { // As described in cggmp21 at page 35 /// Prover's first message, obtained by [`interactive::commit`] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, udigest::Digestable)] +#[udigest(bound = "")] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(bound = ""))] pub struct Commitment { + #[udigest(with = crate::common::digest_integer)] pub a: Integer, pub b_x: Point, + #[udigest(with = crate::common::digest_integer)] pub b_y: Integer, + #[udigest(with = crate::common::digest_integer)] pub e: Integer, + #[udigest(with = crate::common::digest_integer)] pub s: Integer, + #[udigest(with = crate::common::digest_integer)] pub f: Integer, + #[udigest(with = crate::common::digest_integer)] pub t: Integer, } @@ -434,9 +447,8 @@ pub mod interactive { /// The non-interactive version of proof. Completed in one round, for example /// see the documentation of parent module. pub mod non_interactive { - use digest::{typenum::U32, Digest}; + use digest::Digest; use generic_ec::Curve; - use rand_core::RngCore; use crate::{Error, InvalidProof}; @@ -446,76 +458,51 @@ pub mod non_interactive { /// deriving determenistic challenge. /// /// Obtained from the above interactive proof via Fiat-Shamir heuristic. - pub fn prove( - shared_state: D, + pub fn prove( + shared_state: &impl udigest::Digestable, aux: &Aux, data: Data, pdata: PrivateData, security: &SecurityParams, - rng: R, - ) -> Result<(Commitment, Proof), Error> - where - D: Digest, - { + rng: &mut impl rand_core::RngCore, + ) -> Result<(Commitment, Proof), Error> { let (comm, pcomm) = super::interactive::commit(aux, data, pdata, security, rng)?; - let challenge = challenge(shared_state, aux, data, &comm, security); + let challenge = challenge::(shared_state, aux, data, &comm, security); let proof = super::interactive::prove(data, pdata, &pcomm, &challenge)?; Ok((comm, proof)) } /// Verify the proof, deriving challenge independently from same data - pub fn verify( - shared_state: D, + pub fn verify( + shared_state: &impl udigest::Digestable, aux: &Aux, data: Data, commitment: &Commitment, security: &SecurityParams, proof: &Proof, - ) -> Result<(), InvalidProof> - where - D: Digest, - { - let challenge = challenge(shared_state, aux, data, commitment, security); + ) -> Result<(), InvalidProof> { + let challenge = challenge::(shared_state, aux, data, commitment, security); super::interactive::verify(aux, data, commitment, security, &challenge, proof) } /// Deterministically compute challenge based on prior known values in protocol - pub fn challenge( - shared_state: D, + pub fn challenge( + shared_state: &impl udigest::Digestable, aux: &Aux, data: Data, commitment: &Commitment, security: &SecurityParams, - ) -> Challenge - where - D: Digest, - { - let shared_state = shared_state.finalize(); - let hash = |d: D| { - let order = rug::integer::Order::Msf; - d.chain_update(&shared_state) - .chain_update(aux.s.to_digits::(order)) - .chain_update(aux.t.to_digits::(order)) - .chain_update(aux.rsa_modulo.to_digits::(order)) - .chain_update((security.l_x as u64).to_le_bytes()) - .chain_update((security.l_y as u64).to_le_bytes()) - .chain_update((security.epsilon as u64).to_le_bytes()) - .chain_update(data.key0.n().to_digits::(order)) - .chain_update(data.key1.n().to_digits::(order)) - .chain_update(data.c.to_digits::(order)) - .chain_update(data.d.to_digits::(order)) - .chain_update(data.y.to_digits::(order)) - .chain_update(data.x.to_bytes(true)) - .chain_update(commitment.a.to_digits::(order)) - .chain_update(commitment.b_x.to_bytes(true)) - .chain_update(commitment.b_y.to_digits::(order)) - .chain_update(commitment.e.to_digits::(order)) - .chain_update(commitment.s.to_digits::(order)) - .chain_update(commitment.f.to_digits::(order)) - .chain_update(commitment.t.to_digits::(order)) - .finalize() - }; - let mut rng = crate::common::rng::HashRng::new(hash); + ) -> Challenge { + let tag = "paillier_zk.paillier_affine_operation_in_range.ni_challenge"; + let aux = aux.digest_public_data(); + let seed = udigest::inline_struct!(tag { + shared_state, + aux, + security, + data, + commitment, + }); + let mut rng = rand_hash::HashRng::::from_seed(seed); super::interactive::challenge(security, &mut rng) } } @@ -524,11 +511,12 @@ pub mod non_interactive { mod test { use generic_ec::{Curve, Point}; use rug::{Complete, Integer}; + use sha2::Digest; use crate::common::test::random_key; use crate::common::{IntegerExt, InvalidProofReason}; - fn run( + fn run( rng: &mut R, security: super::SecurityParams, x: Integer, @@ -567,15 +555,22 @@ mod test { let aux = crate::common::test::aux(rng); - let shared_state = sha2::Sha256::default(); + let shared_state = "shared state"; let (commitment, proof) = - super::non_interactive::prove(shared_state.clone(), &aux, data, pdata, &security, rng) + super::non_interactive::prove::(&shared_state, &aux, data, pdata, &security, rng) .unwrap(); - super::non_interactive::verify(shared_state, &aux, data, &commitment, &security, &proof) + super::non_interactive::verify::( + &shared_state, + &aux, + data, + &commitment, + &security, + &proof, + ) } - fn passing_test() { + fn passing_test() { let mut rng = rand_dev::DevRng::new(); let security = super::SecurityParams { l_x: 1024, @@ -585,10 +580,10 @@ mod test { }; let x = Integer::from_rng_pm(&(Integer::ONE << security.l_x).complete(), &mut rng); let y = Integer::from_rng_pm(&(Integer::ONE << security.l_y).complete(), &mut rng); - run::<_, C>(&mut rng, security, x, y).expect("proof failed"); + run::<_, C, D>(&mut rng, security, x, y).expect("proof failed"); } - fn failing_on_additive() { + fn failing_on_additive() { let mut rng = rand_dev::DevRng::new(); let security = super::SecurityParams { l_x: 1024, @@ -598,14 +593,14 @@ mod test { }; let x = Integer::from_rng_pm(&(Integer::ONE << security.l_x).complete(), &mut rng); let y = (Integer::ONE << (security.l_y + security.epsilon)).complete() + 1; - let r = run::<_, C>(&mut rng, security, x, y).expect_err("proof should not pass"); + let r = run::<_, C, D>(&mut rng, security, x, y).expect_err("proof should not pass"); match r.reason() { InvalidProofReason::RangeCheck(7) => (), e => panic!("proof should not fail with: {e:?}"), } } - fn failing_on_multiplicative() { + fn failing_on_multiplicative() { let mut rng = rand_dev::DevRng::new(); let security = super::SecurityParams { l_x: 1024, @@ -615,7 +610,7 @@ mod test { }; let x = (Integer::ONE << (security.l_x + security.epsilon)).complete() + 1; let y = Integer::from_rng_pm(&(Integer::ONE << security.l_y).complete(), &mut rng); - let r = run::<_, C>(&mut rng, security, x, y).expect_err("proof should not pass"); + let r = run::<_, C, D>(&mut rng, security, x, y).expect_err("proof should not pass"); match r.reason() { InvalidProofReason::RangeCheck(6) => (), e => panic!("proof should not fail with: {e:?}"), @@ -624,27 +619,27 @@ mod test { #[test] fn passing_p256() { - passing_test::() + passing_test::() } #[test] fn failing_p256_add() { - failing_on_additive::() + failing_on_additive::() } #[test] fn failing_p256_mul() { - failing_on_multiplicative::() + failing_on_multiplicative::() } #[test] fn passing_million() { - passing_test::() + passing_test::() } #[test] fn failing_million_add() { - failing_on_additive::() + failing_on_additive::() } #[test] fn failing_million_mul() { - failing_on_multiplicative::() + failing_on_multiplicative::() } } diff --git a/src/paillier_blum_modulus.rs b/src/paillier_blum_modulus.rs index b933ea2..2977dde 100644 --- a/src/paillier_blum_modulus.rs +++ b/src/paillier_blum_modulus.rs @@ -23,15 +23,14 @@ //! // Security parameter //! const SECURITY: usize = 33; //! // Verifier and prover share the same state -//! let prover_shared_state = sha2::Sha256::default(); -//! let verifier_shared_state = sha2::Sha256::default(); +//! let shared_state = "some shared state"; //! //! let data = p::Data { n }; //! let pdata = p::PrivateData { p, q }; //! //! let (commitment, proof) = -//! p::non_interactive::prove::<{SECURITY}, _, _>( -//! prover_shared_state, +//! p::non_interactive::prove::<{SECURITY}, sha2::Sha256>( +//! &shared_state, //! &data, //! &pdata, //! &mut rng, @@ -47,8 +46,8 @@ //! # let recv = || (data, commitment, proof); //! let (data, commitment, proof) = recv(); //! -//! p::non_interactive::verify::<{SECURITY}, _>( -//! verifier_shared_state, +//! p::non_interactive::verify::<{SECURITY}, sha2::Sha256>( +//! &shared_state, //! &data, //! &commitment, //! &proof, @@ -63,9 +62,10 @@ use rug::Integer; use serde::{Deserialize, Serialize}; /// Public data that both parties know: the Paillier-Blum modulus -#[derive(Debug, Clone)] +#[derive(Debug, Clone, udigest::Digestable)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Data { + #[udigest(with = crate::common::digest_integer)] pub n: Integer, } @@ -77,9 +77,10 @@ pub struct PrivateData { } /// Prover's first message, obtained by [`interactive::commit`] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, udigest::Digestable)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Commitment { + #[udigest(with = crate::common::digest_integer)] pub w: Integer, } @@ -226,8 +227,7 @@ pub mod interactive { /// The non-interactive version of proof. Completed in one round, for example /// see the documentation of parent module. pub mod non_interactive { - use digest::{typenum::U32, Digest}; - use rand_core::RngCore; + use digest::Digest; use crate::{Error, InvalidProof}; @@ -237,57 +237,47 @@ pub mod non_interactive { /// deriving determenistic challenge. /// /// Obtained from the above interactive proof via Fiat-Shamir heuristic. - pub fn prove( - shared_state: D, + pub fn prove( + shared_state: &impl udigest::Digestable, data: &Data, pdata: &PrivateData, - rng: &mut R, - ) -> Result<(Commitment, Proof), Error> - where - D: Digest + Clone, - { + rng: &mut impl rand_core::RngCore, + ) -> Result<(Commitment, Proof), Error> { let commitment = super::interactive::commit(data, rng); - let challenge = challenge(shared_state, data, &commitment); + let challenge = challenge::(shared_state, data, &commitment); let proof = super::interactive::prove(data, pdata, &commitment, &challenge)?; Ok((commitment, proof)) } /// Verify the proof, deriving challenge independently from same data - pub fn verify( - shared_state: D, + pub fn verify( + shared_state: &impl udigest::Digestable, data: &Data, commitment: &Commitment, proof: &Proof, - ) -> Result<(), InvalidProof> - where - D: Digest + Clone, - { - let challenge = challenge(shared_state, data, commitment); + ) -> Result<(), InvalidProof> { + let challenge = challenge::(shared_state, data, commitment); super::interactive::verify(data, commitment, &challenge, proof) } /// Deterministically compute challenge based on prior known values in protocol - pub fn challenge( - shared_state: D, - Data { ref n }: &Data, + pub fn challenge( + shared_state: &impl udigest::Digestable, + data: &Data, commitment: &Commitment, - ) -> Challenge - where - D: Digest, - { - let shared_state = shared_state.finalize(); - let hash = |d: D| { - let order = rug::integer::Order::Msf; - d.chain_update(&shared_state) - .chain_update(n.to_digits::(order)) - .chain_update(commitment.w.to_digits::(order)) - .finalize() - }; - let mut rng = crate::common::rng::HashRng::new(hash); + ) -> Challenge { + let tag = "paillier_zk.blum_modulus.ni_challenge"; + let seed = udigest::inline_struct!(tag { + shared_state, + data, + commitment, + }); + let mut rng = rand_hash::HashRng::::from_seed(seed); // since we can't use Default and Integer isn't copy, we initialize // like this let ys = [(); M].map(|()| { - n.random_below_ref(&mut fast_paillier::utils::external_rand(&mut rng)) + data.n + .random_below_ref(&mut fast_paillier::utils::external_rand(&mut rng)) .into() }); Challenge { ys } @@ -300,6 +290,8 @@ mod test { use crate::common::test::{generate_blum_prime, generate_prime}; + type D = sha2::Sha256; + #[test] fn passing() { let mut rng = rand_dev::DevRng::new(); @@ -308,15 +300,10 @@ mod test { let n = (&p * &q).complete(); let data = super::Data { n }; let pdata = super::PrivateData { p, q }; - let shared_state = sha2::Sha256::default(); - let (commitment, proof) = super::non_interactive::prove::<65, _, _>( - shared_state.clone(), - &data, - &pdata, - &mut rng, - ) - .unwrap(); - let r = super::non_interactive::verify(shared_state, &data, &commitment, &proof); + let shared_state = "shared state"; + let (commitment, proof) = + super::non_interactive::prove::<65, D>(&shared_state, &data, &pdata, &mut rng).unwrap(); + let r = super::non_interactive::verify::<65, D>(&shared_state, &data, &commitment, &proof); match r { Ok(()) => (), Err(e) => panic!("{e:?}"), @@ -337,15 +324,10 @@ mod test { let n = (&p * &q).complete(); let data = super::Data { n }; let pdata = super::PrivateData { p, q }; - let shared_state = sha2::Sha256::default(); - let (commitment, proof) = super::non_interactive::prove::<65, _, _>( - shared_state.clone(), - &data, - &pdata, - &mut rng, - ) - .unwrap(); - let r = super::non_interactive::verify(shared_state, &data, &commitment, &proof); + let shared_state = "shared state"; + let (commitment, proof) = + super::non_interactive::prove::<65, D>(&shared_state, &data, &pdata, &mut rng).unwrap(); + let r = super::non_interactive::verify::<65, D>(&shared_state, &data, &commitment, &proof); if r.is_ok() { panic!("proof should not pass"); } diff --git a/src/paillier_encryption_in_range.rs b/src/paillier_encryption_in_range.rs index 9a0e84c..0667310 100644 --- a/src/paillier_encryption_in_range.rs +++ b/src/paillier_encryption_in_range.rs @@ -24,8 +24,7 @@ //! # } //! # fn main() -> Result<(), Box> { //! -//! let shared_state_prover = sha2::Sha256::default(); -//! let shared_state_verifier = sha2::Sha256::default(); +//! let shared_state = "some shared state"; //! //! let mut rng = rand_core::OsRng; //! # let mut rng = rand_dev::DevRng::new(); @@ -53,8 +52,8 @@ //! // 3. Prover computes a non-interactive proof that plaintext is at most 1024 bits: //! //! let data = p::Data { key, ciphertext: &ciphertext }; -//! let (commitment, proof) = p::non_interactive::prove( -//! shared_state_prover, +//! let (commitment, proof) = p::non_interactive::prove::( +//! &shared_state, //! &aux, //! data, //! p::PrivateData { @@ -74,8 +73,8 @@ //! //! # let recv = || (data, commitment, proof); //! let (data, commitment, proof) = recv(); -//! p::non_interactive::verify( -//! shared_state_verifier, +//! p::non_interactive::verify::( +//! &shared_state, //! &aux, //! data, //! &commitment, @@ -111,11 +110,13 @@ pub struct SecurityParams { } /// Public data that both parties know -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, udigest::Digestable)] pub struct Data<'a> { /// N0 in paper, public key that k -> K was encrypted on + #[udigest(with = crate::common::digest_encryption_key)] pub key: &'a dyn AnyEncryptionKey, /// K in paper + #[udigest(with = crate::common::digest_integer)] pub ciphertext: &'a Ciphertext, } @@ -130,11 +131,14 @@ pub struct PrivateData<'a> { // As described in cggmp21 at page 33 /// Prover's first message, obtained by [`interactive::commit`] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, udigest::Digestable)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Commitment { + #[udigest(with = crate::common::digest_integer)] pub s: Integer, + #[udigest(with = crate::common::digest_integer)] pub a: Integer, + #[udigest(with = crate::common::digest_integer)] pub c: Integer, } @@ -293,8 +297,7 @@ pub mod interactive { /// The non-interactive version of proof. Completed in one round, for example /// see the documentation of parent module. pub mod non_interactive { - use digest::{typenum::U32, Digest}; - use rand_core::RngCore; + use digest::Digest; use crate::{Error, InvalidProof}; @@ -304,65 +307,49 @@ pub mod non_interactive { /// deriving determenistic challenge. /// /// Obtained from the above interactive proof via Fiat-Shamir heuristic. - pub fn prove( - shared_state: D, + pub fn prove( + shared_state: &impl udigest::Digestable, aux: &Aux, data: Data, pdata: PrivateData, security: &SecurityParams, - rng: &mut R, - ) -> Result<(Commitment, Proof), Error> - where - D: Digest, - { + rng: &mut impl rand_core::RngCore, + ) -> Result<(Commitment, Proof), Error> { let (comm, pcomm) = super::interactive::commit(aux, data, pdata, security, rng)?; - let challenge = challenge(shared_state, aux, data, &comm, security); + let challenge = challenge::(shared_state, aux, data, &comm, security); let proof = super::interactive::prove(data, pdata, &pcomm, &challenge)?; Ok((comm, proof)) } /// Deterministically compute challenge based on prior known values in protocol - pub fn challenge( - shared_state: D, + pub fn challenge( + shared_state: &impl udigest::Digestable, aux: &Aux, data: Data, commitment: &Commitment, security: &SecurityParams, - ) -> Challenge - where - D: Digest, - { - let order = rug::integer::Order::Msf; - let shared_state = shared_state.finalize(); - let hash = |d: D| { - d.chain_update(&shared_state) - .chain_update(aux.s.to_digits(order)) - .chain_update(aux.t.to_digits(order)) - .chain_update(aux.rsa_modulo.to_digits(order)) - .chain_update(data.key.n().to_digits(order)) - .chain_update(data.ciphertext.to_digits(order)) - .chain_update(commitment.s.to_digits(order)) - .chain_update(commitment.a.to_digits(order)) - .chain_update(commitment.c.to_digits(order)) - .finalize() - }; - let mut rng = crate::common::rng::HashRng::new(hash); + ) -> Challenge { + let tag = "paillier_zk.encryption_in_range.ni_challenge"; + let seed = udigest::inline_struct!(tag { + shared_state, + aux: aux.digest_public_data(), + data, + commitment, + }); + let mut rng = rand_hash::HashRng::::from_seed(seed); super::interactive::challenge(security, &mut rng) } /// Verify the proof, deriving challenge independently from same data - pub fn verify( - shared_state: D, + pub fn verify( + shared_state: &impl udigest::Digestable, aux: &Aux, data: Data, commitment: &Commitment, security: &SecurityParams, proof: &Proof, - ) -> Result<(), InvalidProof> - where - D: Digest, - { - let challenge = challenge(shared_state, aux, data, commitment, security); + ) -> Result<(), InvalidProof> { + let challenge = challenge::(shared_state, aux, data, commitment, security); super::interactive::verify(aux, data, commitment, security, &challenge, proof) } } @@ -370,11 +357,12 @@ pub mod non_interactive { #[cfg(test)] mod test { use rug::{Complete, Integer}; + use sha2::Digest; use crate::common::{IntegerExt, InvalidProofReason}; - fn run_with( - mut rng: &mut R, + fn run_with( + mut rng: &mut impl rand_core::CryptoRngCore, security: super::SecurityParams, plaintext: Integer, ) -> Result<(), crate::common::InvalidProof> { @@ -391,11 +379,18 @@ mod test { nonce: &nonce, }; - let shared_state = sha2::Sha256::default(); + let shared_state = "shared state"; let (commitment, proof) = - super::non_interactive::prove(shared_state.clone(), &aux, data, pdata, &security, rng) + super::non_interactive::prove::(&shared_state, &aux, data, pdata, &security, rng) .unwrap(); - super::non_interactive::verify(shared_state, &aux, data, &commitment, &security, &proof) + super::non_interactive::verify::( + &shared_state, + &aux, + data, + &commitment, + &security, + &proof, + ) } #[test] @@ -407,7 +402,7 @@ mod test { q: (Integer::ONE << 128_u32).complete() - 1, }; let plaintext = Integer::from_rng_pm(&(Integer::ONE << security.l).complete(), &mut rng); - let r = run_with(&mut rng, security, plaintext); + let r = run_with::(&mut rng, security, plaintext); match r { Ok(()) => (), Err(e) => panic!("{e:?}"), @@ -422,7 +417,7 @@ mod test { q: (Integer::ONE << 128_u32).complete() - 1, }; let plaintext = (Integer::ONE << (security.l + security.epsilon)).complete() + 1; - let r = run_with(&mut rng, security, plaintext); + let r = run_with::(&mut rng, security, plaintext); match r.map_err(|e| e.reason()) { Ok(()) => panic!("proof should not pass"), Err(InvalidProofReason::RangeCheck(_)) => (),