diff --git a/nimue-pow/Cargo.toml b/nimue-pow/Cargo.toml index 550898a..3b227d3 100644 --- a/nimue-pow/Cargo.toml +++ b/nimue-pow/Cargo.toml @@ -14,6 +14,7 @@ blake3 = "1.5.4" keccak = { version = "0.1.4"} bytemuck = "1.17.1" rayon = { version = "1.10.0", optional = true } +rand = "0.8.5" [features] default = ["parallel"] diff --git a/nimue-pow/src/blake3.rs b/nimue-pow/src/blake3.rs index 7c928bf..fa448de 100644 --- a/nimue-pow/src/blake3.rs +++ b/nimue-pow/src/blake3.rs @@ -144,11 +144,12 @@ impl Blake3PoW { #[test] fn test_pow_blake3() { - use crate::{ByteIOPattern, ByteReader, ByteWriter, IOPattern, PoWChallenge, PoWIOPattern}; + use crate::{ByteIOPattern, ByteReader, ByteWriter, PoWChallenge, PoWIOPattern}; + use nimue::{DefaultHash, IOPattern}; const BITS: f64 = 10.0; - let iopattern = IOPattern::new("the proof of work lottery 🎰") + let iopattern = IOPattern::::new("the proof of work lottery 🎰") .add_bytes(1, "something") .challenge_pow("rolling dices"); diff --git a/nimue-pow/src/keccak.rs b/nimue-pow/src/keccak.rs index 29a010f..b5c37d4 100644 --- a/nimue-pow/src/keccak.rs +++ b/nimue-pow/src/keccak.rs @@ -30,11 +30,12 @@ impl PowStrategy for KeccakPoW { #[test] fn test_pow_keccak() { - use crate::{ByteIOPattern, ByteReader, ByteWriter, IOPattern, PoWChallenge, PoWIOPattern}; + use crate::{ByteIOPattern, ByteReader, ByteWriter, PoWChallenge, PoWIOPattern}; + use nimue::{DefaultHash, IOPattern}; const BITS: f64 = 10.0; - let iopattern = IOPattern::new("the proof of work lottery 🎰") + let iopattern = IOPattern::::new("the proof of work lottery 🎰") .add_bytes(1, "something") .challenge_pow("rolling dices"); diff --git a/nimue-pow/src/lib.rs b/nimue-pow/src/lib.rs index df26924..5b0c3a5 100644 --- a/nimue-pow/src/lib.rs +++ b/nimue-pow/src/lib.rs @@ -2,8 +2,8 @@ pub mod blake3; pub mod keccak; use nimue::{ - Arthur, ByteChallenges, ByteIOPattern, ByteReader, ByteWriter, IOPattern, Merlin, ProofError, - ProofResult, + Arthur, ByteChallenges, ByteIOPattern, ByteReader, ByteWriter, DuplexHash, Merlin, ProofError, + ProofResult, Unit, }; /// [`IOPattern`] for proof-of-work challenges. @@ -21,7 +21,10 @@ pub trait PoWIOPattern { fn challenge_pow(self, label: &str) -> Self; } -impl PoWIOPattern for IOPattern { +impl PoWIOPattern for IOPattern +where + IOPattern: ByteIOPattern, +{ fn challenge_pow(self, label: &str) -> Self { // 16 bytes challenge and 16 bytes nonce (that will be written) self.challenge_bytes(32, label).add_bytes(8, "pow-nonce") @@ -33,9 +36,12 @@ pub trait PoWChallenge { fn challenge_pow(&mut self, bits: f64) -> ProofResult<()>; } -impl PoWChallenge for Merlin +impl PoWChallenge for Merlin where - Merlin: ByteWriter, + U: Unit, + H: DuplexHash, + R: rand::CryptoRng + rand::RngCore, + Merlin: ByteWriter + ByteChallenges, { fn challenge_pow(&mut self, bits: f64) -> ProofResult<()> { let challenge = self.challenge_bytes()?; @@ -47,9 +53,11 @@ where } } -impl<'a> PoWChallenge for Arthur<'a> +impl<'a, H, U> PoWChallenge for Arthur<'a, H, U> where - Arthur<'a>: ByteReader, + U: Unit, + H: DuplexHash, + Arthur<'a, H, U>: ByteReader + ByteChallenges, { fn challenge_pow(&mut self, bits: f64) -> ProofResult<()> { let challenge = self.challenge_bytes()?; diff --git a/nimue/src/plugins/ark/common.rs b/nimue/src/plugins/ark/common.rs index 9a48030..9fd4d96 100644 --- a/nimue/src/plugins/ark/common.rs +++ b/nimue/src/plugins/ark/common.rs @@ -78,7 +78,7 @@ where impl FieldChallenges for T where F: Field, - T: ByteChallenges, + T: UnitTranscript, { fn fill_challenge_scalars(&mut self, output: &mut [F]) -> ProofResult<()> { let base_field_size = bytes_uniform_modp(F::BasePrimeField::MODULUS_BIT_SIZE); @@ -96,6 +96,29 @@ where } } +impl FieldChallenges> for Arthur<'_, H, Fp> +where + C: FpConfig, + H: DuplexHash>, +{ + fn fill_challenge_scalars(&mut self, output: &mut [Fp]) -> ProofResult<()> { + self.fill_challenge_units(output) + .map_err(ProofError::InvalidIO) + } +} + +impl FieldChallenges> for Merlin, R> +where + C: FpConfig, + H: DuplexHash>, + R: CryptoRng + RngCore, +{ + fn fill_challenge_scalars(&mut self, output: &mut [Fp]) -> ProofResult<()> { + self.fill_challenge_units(output) + .map_err(ProofError::InvalidIO) + } +} + // Field <-> Field interactions: impl FieldPublic for Merlin, R> @@ -191,7 +214,7 @@ where // Field <-> Bytes interactions: -impl<'a, H, C, const N: usize> BytePublic for Arthur<'a, H, Fp> +impl BytePublic for Arthur<'_, H, Fp> where C: FpConfig, H: DuplexHash>, @@ -222,7 +245,7 @@ impl ByteChallenges for Merlin, R> where C: FpConfig, H: DuplexHash>, - R: CryptoRng + rand::RngCore, + R: CryptoRng + RngCore, { fn fill_challenge_bytes(&mut self, output: &mut [u8]) -> Result<(), IOPatternError> { if output.is_empty() { @@ -244,7 +267,7 @@ where } /// XXX. duplicate code -impl<'a, H, C, const N: usize> ByteChallenges for Arthur<'a, H, Fp> +impl ByteChallenges for Arthur<'_, H, Fp> where C: FpConfig, H: DuplexHash>, diff --git a/nimue/src/plugins/ark/writer.rs b/nimue/src/plugins/ark/writer.rs index 8d3e3eb..1742986 100644 --- a/nimue/src/plugins/ark/writer.rs +++ b/nimue/src/plugins/ark/writer.rs @@ -4,7 +4,10 @@ use ark_serialize::CanonicalSerialize; use rand::{CryptoRng, RngCore}; use super::{FieldPublic, FieldWriter, GroupPublic, GroupWriter}; -use crate::{DuplexHash, Merlin, ProofResult, UnitTranscript}; +use crate::{ + Arthur, BytePublic, ByteReader, ByteWriter, DuplexHash, IOPatternError, Merlin, ProofResult, + Unit, UnitTranscript, +}; impl FieldWriter for Merlin { fn add_scalars(&mut self, input: &[F]) -> ProofResult<()> { @@ -58,3 +61,27 @@ where Ok(()) } } + +impl ByteWriter for Merlin, R> +where + H: DuplexHash>, + C: FpConfig, + R: RngCore + CryptoRng, +{ + fn add_bytes(&mut self, input: &[u8]) -> Result<(), IOPatternError> { + self.public_bytes(input)?; + self.transcript.extend(input); + Ok(()) + } +} + +impl<'a, H, C, const N: usize> ByteReader for Arthur<'a, H, Fp> +where + H: DuplexHash>, + C: FpConfig, +{ + fn fill_next_bytes(&mut self, input: &mut [u8]) -> Result<(), IOPatternError> { + u8::read(&mut self.transcript, input)?; + self.public_bytes(input) + } +}