From c6542eb717e73baaeda156dafe0ab187089a995f Mon Sep 17 00:00:00 2001 From: Al-Kindi-0 <82364884+Al-Kindi-0@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:24:23 +0100 Subject: [PATCH] feat: improve integration of PRNG for zk --- crypto/src/merkle/mod.rs | 45 +++--- crypto/src/merkle/tests.rs | 43 +++++- examples/src/fibonacci/fib2/mod.rs | 2 +- examples/src/fibonacci/fib2/prover.rs | 17 +-- examples/src/fibonacci/fib8/mod.rs | 2 +- examples/src/fibonacci/fib8/prover.rs | 17 +-- examples/src/fibonacci/fib_small/mod.rs | 2 +- examples/src/fibonacci/fib_small/prover.rs | 17 +-- examples/src/fibonacci/mulfib2/mod.rs | 2 +- examples/src/fibonacci/mulfib2/prover.rs | 17 +-- examples/src/fibonacci/mulfib8/mod.rs | 2 +- examples/src/fibonacci/mulfib8/prover.rs | 17 +-- examples/src/lamport/aggregate/mod.rs | 2 +- examples/src/lamport/aggregate/prover.rs | 17 +-- examples/src/lamport/threshold/mod.rs | 2 +- examples/src/lamport/threshold/prover.rs | 17 +-- examples/src/merkle/mod.rs | 2 +- examples/src/merkle/prover.rs | 17 +-- examples/src/merkle/tests.rs | 2 +- examples/src/rescue/mod.rs | 2 +- examples/src/rescue/prover.rs | 17 +-- examples/src/rescue/tests.rs | 2 +- examples/src/rescue_raps/mod.rs | 2 +- examples/src/rescue_raps/prover.rs | 17 +-- examples/src/rescue_raps/tests.rs | 2 +- examples/src/vdf/exempt/mod.rs | 2 +- examples/src/vdf/exempt/prover.rs | 17 +-- examples/src/vdf/exempt/tests.rs | 2 +- examples/src/vdf/regular/mod.rs | 2 +- examples/src/vdf/regular/prover.rs | 17 +-- examples/src/vdf/regular/tests.rs | 2 +- fri/benches/prover.rs | 16 +- fri/src/prover/channel.rs | 47 +++--- fri/src/prover/mod.rs | 35 ++--- fri/src/prover/tests.rs | 8 +- prover/benches/lagrange_kernel.rs | 20 +-- prover/src/channel.rs | 83 +++++----- prover/src/constraints/composition_poly.rs | 15 +- prover/src/lib.rs | 161 +++++++++++++++----- prover/src/matrix/col_matrix.rs | 7 +- prover/src/trace/trace_lde/default/mod.rs | 6 +- prover/src/trace/trace_lde/default/tests.rs | 11 +- prover/src/trace/trace_lde/mod.rs | 2 +- verifier/src/channel.rs | 5 +- winterfell/Cargo.toml | 2 - winterfell/src/lib.rs | 18 ++- winterfell/src/tests.rs | 15 +- 47 files changed, 407 insertions(+), 370 deletions(-) diff --git a/crypto/src/merkle/mod.rs b/crypto/src/merkle/mod.rs index 6024d86ca..a125e05ff 100644 --- a/crypto/src/merkle/mod.rs +++ b/crypto/src/merkle/mod.rs @@ -7,11 +7,11 @@ use alloc::{ collections::{BTreeMap, BTreeSet}, vec::Vec, }; -use core::slice; +use core::{marker::PhantomData, slice}; use rand::{ distributions::{Distribution, Standard}, - thread_rng, Rng, RngCore, SeedableRng, + Rng, RngCore, SeedableRng, }; use crate::{ @@ -481,20 +481,21 @@ impl VectorCommitment for MerkleTree { // SALTED MERKLE TREE // ================================================================================================ -pub struct SaltedMerkleTree { +pub struct SaltedMerkleTree { leaves: Vec, tree: MerkleTree, salts: Vec, + _prng: PhantomData

, } -impl SaltedMerkleTree +impl SaltedMerkleTree where Standard: Distribution<::Digest>, { // CONSTRUCTORS // -------------------------------------------------------------------------------------------- - pub fn new(leaves: Vec, prng: &mut R) -> Result { + pub fn new(leaves: Vec, prng: &mut P) -> Result { if leaves.len() < 2 { return Err(MerkleTreeError::TooFewLeaves(2, leaves.len())); } @@ -513,7 +514,7 @@ where let tree = MerkleTree::new(salted_leaves)?; - Ok(Self { tree, leaves, salts }) + Ok(Self { tree, leaves, salts, _prng: PhantomData }) } /// Returns the root of the tree. @@ -521,15 +522,19 @@ where self.tree.root() } + /// Returns the depth of the tree. pub fn depth(&self) -> usize { self.tree.depth() } + /// Returns a Merkle proof to a leaf at the specified `index`. pub fn prove(&self, index: usize) -> Result, MerkleTreeError> { let (_, proof) = self.tree.prove(index)?; Ok((self.leaves[index], (self.salts[index], proof))) } + /// Computes Merkle proofs for the provided indexes, compresses the proofs into a single batch + /// and returns the batch proof alongside the leaves at the provided indexes. pub fn prove_batch( &self, indexes: &[usize], @@ -540,6 +545,7 @@ where Ok((leaves_at_indices, (salts_at_indices, proof))) } + /// Checks whether the `proof` for the given `leaf` at the specified `index` is valid. pub fn verify( root: H::Digest, index: usize, @@ -552,15 +558,6 @@ where } /// Checks whether the batch proof contains Merkle paths for the of the specified `indexes`. - /// - /// # Errors - /// Returns an error if: - /// * No indexes were provided (i.e., `indexes` is an empty slice). - /// * Number of provided indexes is greater than 255. - /// * Any of the specified `indexes` is greater than or equal to the number of leaves in the - /// tree from which the batch proof was generated. - /// * List of indexes contains duplicates. - /// * Any of the paths in the batch proof does not resolve to the specified `root`. pub fn verify_batch( root: &H::Digest, indexes: &[usize], @@ -586,7 +583,7 @@ impl Distribution> for Standard { } } -impl VectorCommitment for SaltedMerkleTree +impl VectorCommitment for SaltedMerkleTree where Standard: Distribution<::Digest>, { @@ -599,16 +596,16 @@ where type Error = MerkleTreeError; fn new(items: Vec) -> Result { - let mut _prng = thread_rng(); - let seed = [0_u8; 32]; - let mut prng = rand_chacha::ChaCha20Rng::from_seed(seed); + // TODO: make random + let seed = P::Seed::default(); + let mut prng = P::from_seed(seed); SaltedMerkleTree::new(items, &mut prng) } fn with_options(items: Vec, _options: Self::Options) -> Result { - let mut _prng = thread_rng(); - let seed = [0_u8; 32]; - let mut prng = rand_chacha::ChaCha20Rng::from_seed(seed); + // TODO: make random + let seed = P::Seed::default(); + let mut prng = P::from_seed(seed); Self::new(items, &mut prng) } @@ -645,7 +642,7 @@ where item: H::Digest, proof: &Self::Proof, ) -> Result<(), Self::Error> { - SaltedMerkleTree::::verify(commitment, index, item, proof.0, &proof.1) + SaltedMerkleTree::::verify(commitment, index, item, proof.0, &proof.1) } fn verify_many( @@ -654,6 +651,6 @@ where items: &[H::Digest], proof: &Self::MultiProof, ) -> Result<(), Self::Error> { - SaltedMerkleTree::::verify_batch(&commitment, indexes, items, &proof.0, &proof.1) + SaltedMerkleTree::::verify_batch(&commitment, indexes, items, &proof.0, &proof.1) } } diff --git a/crypto/src/merkle/tests.rs b/crypto/src/merkle/tests.rs index dac785294..c6e60aa9d 100644 --- a/crypto/src/merkle/tests.rs +++ b/crypto/src/merkle/tests.rs @@ -5,6 +5,7 @@ use math::fields::f128::BaseElement; use proptest::prelude::*; +use rand_chacha::ChaCha20Rng; use super::*; @@ -258,22 +259,50 @@ fn from_proofs() { fn verify_salted() { // depth 4 let leaves = Digest256::bytes_as_digests(&LEAVES4).to_vec(); - let mut prng = thread_rng(); - let tree: SaltedMerkleTree = SaltedMerkleTree::new(leaves, &mut prng).unwrap(); + let mut prng = ChaCha20Rng::from_entropy(); + let tree: SaltedMerkleTree = SaltedMerkleTree::new(leaves, &mut prng).unwrap(); let (leaf, (salt, proof)) = tree.prove(1).unwrap(); - assert!(SaltedMerkleTree::::verify(*tree.root(), 1, leaf, salt, &proof).is_ok()); + assert!(SaltedMerkleTree::::verify( + *tree.root(), + 1, + leaf, + salt, + &proof + ) + .is_ok()); let (leaf, (salt, proof)) = tree.prove(2).unwrap(); - assert!(SaltedMerkleTree::::verify(*tree.root(), 2, leaf, salt, &proof).is_ok()); + assert!(SaltedMerkleTree::::verify( + *tree.root(), + 2, + leaf, + salt, + &proof + ) + .is_ok()); // depth 5 let leaf = Digest256::bytes_as_digests(&LEAVES8).to_vec(); - let tree: SaltedMerkleTree = SaltedMerkleTree::new(leaf, &mut prng).unwrap(); + let tree: SaltedMerkleTree = SaltedMerkleTree::new(leaf, &mut prng).unwrap(); let (leaf, (salt, proof)) = tree.prove(1).unwrap(); - assert!(SaltedMerkleTree::::verify(*tree.root(), 1, leaf, salt, &proof).is_ok()); + assert!(SaltedMerkleTree::::verify( + *tree.root(), + 1, + leaf, + salt, + &proof + ) + .is_ok()); let (leaf, (salt, proof)) = tree.prove(6).unwrap(); - assert!(SaltedMerkleTree::::verify(*tree.root(), 6, leaf, salt, &proof).is_ok()); + assert!(SaltedMerkleTree::::verify( + *tree.root(), + 6, + leaf, + salt, + &proof + ) + .is_ok()); } proptest! { diff --git a/examples/src/fibonacci/fib2/mod.rs b/examples/src/fibonacci/fib2/mod.rs index ddc6cf77e..7b06615ee 100644 --- a/examples/src/fibonacci/fib2/mod.rs +++ b/examples/src/fibonacci/fib2/mod.rs @@ -108,7 +108,7 @@ where }); // generate the proof - prover.prove(trace).unwrap() + prover.prove(trace, None).unwrap() } fn verify(&self, proof: Proof) -> Result<(), VerifierError> { diff --git a/examples/src/fibonacci/fib2/prover.rs b/examples/src/fibonacci/fib2/prover.rs index 42a3ff270..5a9241d75 100644 --- a/examples/src/fibonacci/fib2/prover.rs +++ b/examples/src/fibonacci/fib2/prover.rs @@ -4,11 +4,10 @@ // LICENSE file in the root directory of this source tree. use air::ZkParameters; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use winterfell::{ crypto::MerkleTree, matrix::ColMatrix, AuxRandElements, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, DefaultTraceLde, PartitionOptions, StarkDomain, Trace, TraceInfo, - TracePolyTable, TraceTable, + DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, PartitionOptions, StarkDomain, Trace, + TraceInfo, TracePolyTable, TraceTable, }; use super::{ @@ -64,6 +63,7 @@ where DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, Self::Air, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, trace: &Self::Trace) -> BaseElement { let last_step = trace.length() - 1; @@ -81,16 +81,9 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E: FieldElement>( diff --git a/examples/src/fibonacci/fib8/mod.rs b/examples/src/fibonacci/fib8/mod.rs index 322079c21..ac0cdd234 100644 --- a/examples/src/fibonacci/fib8/mod.rs +++ b/examples/src/fibonacci/fib8/mod.rs @@ -108,7 +108,7 @@ where }); // generate the proof - prover.prove(trace).unwrap() + prover.prove(trace, None).unwrap() } fn verify(&self, proof: Proof) -> Result<(), VerifierError> { diff --git a/examples/src/fibonacci/fib8/prover.rs b/examples/src/fibonacci/fib8/prover.rs index 01f56103b..9a4db53af 100644 --- a/examples/src/fibonacci/fib8/prover.rs +++ b/examples/src/fibonacci/fib8/prover.rs @@ -4,11 +4,10 @@ // LICENSE file in the root directory of this source tree. use air::ZkParameters; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use winterfell::{ crypto::MerkleTree, matrix::ColMatrix, AuxRandElements, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, DefaultTraceLde, PartitionOptions, StarkDomain, Trace, TraceInfo, - TracePolyTable, TraceTable, + DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, PartitionOptions, StarkDomain, Trace, + TraceInfo, TracePolyTable, TraceTable, }; use super::{ @@ -79,6 +78,7 @@ where DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, Self::Air, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, trace: &Self::Trace) -> BaseElement { let last_step = trace.length() - 1; @@ -96,16 +96,9 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E: FieldElement>( diff --git a/examples/src/fibonacci/fib_small/mod.rs b/examples/src/fibonacci/fib_small/mod.rs index 672605ac4..e8ca2b5e1 100644 --- a/examples/src/fibonacci/fib_small/mod.rs +++ b/examples/src/fibonacci/fib_small/mod.rs @@ -119,7 +119,7 @@ where }); // generate the proof - prover.prove(trace).unwrap() + prover.prove(trace, None).unwrap() } fn verify(&self, proof: Proof) -> Result<(), VerifierError> { diff --git a/examples/src/fibonacci/fib_small/prover.rs b/examples/src/fibonacci/fib_small/prover.rs index be69faee8..cf5d49964 100644 --- a/examples/src/fibonacci/fib_small/prover.rs +++ b/examples/src/fibonacci/fib_small/prover.rs @@ -3,11 +3,10 @@ // This source code is licensed under the MIT license found in the // LICENSE file in the root directory of this source tree. use air::ZkParameters; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use winterfell::{ crypto::MerkleTree, matrix::ColMatrix, AuxRandElements, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, DefaultTraceLde, PartitionOptions, StarkDomain, Trace, TraceInfo, - TracePolyTable, TraceTable, + DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, PartitionOptions, StarkDomain, Trace, + TraceInfo, TracePolyTable, TraceTable, }; use super::{ @@ -69,6 +68,7 @@ where DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, Self::Air, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, trace: &Self::Trace) -> BaseElement { let last_step = trace.length() - 1; @@ -86,16 +86,9 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E: FieldElement>( diff --git a/examples/src/fibonacci/mulfib2/mod.rs b/examples/src/fibonacci/mulfib2/mod.rs index d7b3e11d8..0f7943372 100644 --- a/examples/src/fibonacci/mulfib2/mod.rs +++ b/examples/src/fibonacci/mulfib2/mod.rs @@ -108,7 +108,7 @@ where }); // generate the proof - prover.prove(trace).unwrap() + prover.prove(trace, None).unwrap() } fn verify(&self, proof: Proof) -> Result<(), VerifierError> { diff --git a/examples/src/fibonacci/mulfib2/prover.rs b/examples/src/fibonacci/mulfib2/prover.rs index 15907a100..f867fceaa 100644 --- a/examples/src/fibonacci/mulfib2/prover.rs +++ b/examples/src/fibonacci/mulfib2/prover.rs @@ -4,11 +4,10 @@ // LICENSE file in the root directory of this source tree. use air::ZkParameters; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use winterfell::{ crypto::MerkleTree, matrix::ColMatrix, AuxRandElements, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, DefaultTraceLde, PartitionOptions, StarkDomain, Trace, TraceInfo, - TracePolyTable, TraceTable, + DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, PartitionOptions, StarkDomain, Trace, + TraceInfo, TracePolyTable, TraceTable, }; use super::{ @@ -60,6 +59,7 @@ where DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, Self::Air, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, trace: &Self::Trace) -> BaseElement { let last_step = trace.length() - 1; @@ -77,16 +77,9 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E: FieldElement>( diff --git a/examples/src/fibonacci/mulfib8/mod.rs b/examples/src/fibonacci/mulfib8/mod.rs index 43bd27be0..6e0d10f4a 100644 --- a/examples/src/fibonacci/mulfib8/mod.rs +++ b/examples/src/fibonacci/mulfib8/mod.rs @@ -109,7 +109,7 @@ where }); // generate the proof - prover.prove(trace).unwrap() + prover.prove(trace, None).unwrap() } fn verify(&self, proof: Proof) -> Result<(), VerifierError> { diff --git a/examples/src/fibonacci/mulfib8/prover.rs b/examples/src/fibonacci/mulfib8/prover.rs index 197a350c1..8574af60c 100644 --- a/examples/src/fibonacci/mulfib8/prover.rs +++ b/examples/src/fibonacci/mulfib8/prover.rs @@ -4,11 +4,10 @@ // LICENSE file in the root directory of this source tree. use air::ZkParameters; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use winterfell::{ crypto::MerkleTree, matrix::ColMatrix, AuxRandElements, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, DefaultTraceLde, PartitionOptions, StarkDomain, Trace, TraceInfo, - TracePolyTable, TraceTable, + DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, PartitionOptions, StarkDomain, Trace, + TraceInfo, TracePolyTable, TraceTable, }; use super::{ @@ -72,6 +71,7 @@ where DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, Self::Air, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, trace: &Self::Trace) -> BaseElement { let last_step = trace.length() - 1; @@ -89,16 +89,9 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E: FieldElement>( diff --git a/examples/src/lamport/aggregate/mod.rs b/examples/src/lamport/aggregate/mod.rs index 6dd2a8d02..0de22e2ad 100644 --- a/examples/src/lamport/aggregate/mod.rs +++ b/examples/src/lamport/aggregate/mod.rs @@ -134,7 +134,7 @@ where }); // generate the proof - prover.prove(trace).unwrap() + prover.prove(trace, None).unwrap() } fn verify(&self, proof: Proof) -> Result<(), VerifierError> { diff --git a/examples/src/lamport/aggregate/prover.rs b/examples/src/lamport/aggregate/prover.rs index 61af1b91b..0c881bbab 100644 --- a/examples/src/lamport/aggregate/prover.rs +++ b/examples/src/lamport/aggregate/prover.rs @@ -4,13 +4,12 @@ // LICENSE file in the root directory of this source tree. use air::ZkParameters; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; #[cfg(feature = "concurrent")] use winterfell::iterators::*; use winterfell::{ crypto::MerkleTree, matrix::ColMatrix, AuxRandElements, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, DefaultTraceLde, PartitionOptions, StarkDomain, TraceInfo, - TracePolyTable, TraceTable, + DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, PartitionOptions, StarkDomain, + TraceInfo, TracePolyTable, TraceTable, }; use super::{ @@ -109,6 +108,7 @@ where DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, Self::Air, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, _trace: &Self::Trace) -> PublicInputs { self.pub_inputs.clone() @@ -125,16 +125,9 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E: FieldElement>( diff --git a/examples/src/lamport/threshold/mod.rs b/examples/src/lamport/threshold/mod.rs index c64fa7755..5120c50cb 100644 --- a/examples/src/lamport/threshold/mod.rs +++ b/examples/src/lamport/threshold/mod.rs @@ -140,7 +140,7 @@ where }); // generate the proof - prover.prove(trace).unwrap() + prover.prove(trace, None).unwrap() } fn verify(&self, proof: Proof) -> Result<(), VerifierError> { diff --git a/examples/src/lamport/threshold/prover.rs b/examples/src/lamport/threshold/prover.rs index f5cad228c..b47a77139 100644 --- a/examples/src/lamport/threshold/prover.rs +++ b/examples/src/lamport/threshold/prover.rs @@ -6,13 +6,12 @@ use std::collections::HashMap; use air::ZkParameters; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; #[cfg(feature = "concurrent")] use winterfell::iterators::*; use winterfell::{ crypto::MerkleTree, matrix::ColMatrix, AuxRandElements, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, DefaultTraceLde, PartitionOptions, StarkDomain, TraceInfo, - TracePolyTable, TraceTable, + DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, PartitionOptions, StarkDomain, + TraceInfo, TracePolyTable, TraceTable, }; use super::{ @@ -151,6 +150,7 @@ where DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, Self::Air, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, _trace: &Self::Trace) -> PublicInputs { self.pub_inputs.clone() @@ -167,16 +167,9 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E: FieldElement>( diff --git a/examples/src/merkle/mod.rs b/examples/src/merkle/mod.rs index 6b8771218..37c0fc2f5 100644 --- a/examples/src/merkle/mod.rs +++ b/examples/src/merkle/mod.rs @@ -130,7 +130,7 @@ where }); // generate the proof - prover.prove(trace).unwrap() + prover.prove(trace, None).unwrap() } fn verify(&self, proof: Proof) -> Result<(), VerifierError> { diff --git a/examples/src/merkle/prover.rs b/examples/src/merkle/prover.rs index 57a21625b..1cd5ca6e1 100644 --- a/examples/src/merkle/prover.rs +++ b/examples/src/merkle/prover.rs @@ -4,11 +4,10 @@ // LICENSE file in the root directory of this source tree. use air::ZkParameters; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use winterfell::{ crypto::MerkleTree, matrix::ColMatrix, AuxRandElements, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, DefaultTraceLde, PartitionOptions, StarkDomain, Trace, TraceInfo, - TracePolyTable, TraceTable, + DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, PartitionOptions, StarkDomain, Trace, + TraceInfo, TracePolyTable, TraceTable, }; use super::{ @@ -113,6 +112,7 @@ where DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, Self::Air, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, trace: &Self::Trace) -> PublicInputs { let last_step = trace.length() - 1; @@ -132,16 +132,9 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E: FieldElement>( diff --git a/examples/src/merkle/tests.rs b/examples/src/merkle/tests.rs index cd180a63a..c75f5120d 100644 --- a/examples/src/merkle/tests.rs +++ b/examples/src/merkle/tests.rs @@ -31,5 +31,5 @@ fn build_options(use_extension_field: bool) -> ProofOptions { } else { FieldExtension::None }; - ProofOptions::new(28, 8, 0, extension, 4, 31, true) + ProofOptions::new(28, 8, 0, extension, 4, 31, false) } diff --git a/examples/src/rescue/mod.rs b/examples/src/rescue/mod.rs index 5534625d5..c4b747d09 100644 --- a/examples/src/rescue/mod.rs +++ b/examples/src/rescue/mod.rs @@ -113,7 +113,7 @@ where }); // generate the proof - prover.prove(trace).unwrap() + prover.prove(trace, None).unwrap() } fn verify(&self, proof: Proof) -> Result<(), VerifierError> { diff --git a/examples/src/rescue/prover.rs b/examples/src/rescue/prover.rs index a2797d9ed..c64be386e 100644 --- a/examples/src/rescue/prover.rs +++ b/examples/src/rescue/prover.rs @@ -4,11 +4,10 @@ // LICENSE file in the root directory of this source tree. use air::ZkParameters; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use winterfell::{ crypto::MerkleTree, matrix::ColMatrix, AuxRandElements, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, DefaultTraceLde, PartitionOptions, StarkDomain, Trace, TraceInfo, - TracePolyTable, TraceTable, + DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, PartitionOptions, StarkDomain, Trace, + TraceInfo, TracePolyTable, TraceTable, }; use super::{ @@ -79,6 +78,7 @@ where DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, Self::Air, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, trace: &Self::Trace) -> PublicInputs { let last_step = trace.length() - 1; @@ -99,16 +99,9 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E: FieldElement>( diff --git a/examples/src/rescue/tests.rs b/examples/src/rescue/tests.rs index 9ab273500..b3dd81a68 100644 --- a/examples/src/rescue/tests.rs +++ b/examples/src/rescue/tests.rs @@ -31,5 +31,5 @@ fn build_options(use_extension_field: bool) -> ProofOptions { } else { FieldExtension::None }; - ProofOptions::new(28, 8, 0, extension, 4, 31, true) + ProofOptions::new(28, 8, 0, extension, 4, 31, false) } diff --git a/examples/src/rescue_raps/mod.rs b/examples/src/rescue_raps/mod.rs index 533298097..57f26884d 100644 --- a/examples/src/rescue_raps/mod.rs +++ b/examples/src/rescue_raps/mod.rs @@ -126,7 +126,7 @@ where }); // generate the proof - prover.prove(trace).unwrap() + prover.prove(trace, None).unwrap() } fn verify(&self, proof: Proof) -> Result<(), VerifierError> { diff --git a/examples/src/rescue_raps/prover.rs b/examples/src/rescue_raps/prover.rs index 7050626e9..e6fc22262 100644 --- a/examples/src/rescue_raps/prover.rs +++ b/examples/src/rescue_raps/prover.rs @@ -5,11 +5,10 @@ use air::ZkParameters; use core_utils::uninit_vector; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use winterfell::{ crypto::MerkleTree, matrix::ColMatrix, AuxRandElements, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, DefaultTraceLde, PartitionOptions, StarkDomain, Trace, TraceInfo, - TracePolyTable, + DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, PartitionOptions, StarkDomain, Trace, + TraceInfo, TracePolyTable, }; use super::{ @@ -109,6 +108,7 @@ where DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, Self::Air, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, trace: &Self::Trace) -> PublicInputs { let last_step = trace.length() - 1; @@ -131,16 +131,9 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E: FieldElement>( diff --git a/examples/src/rescue_raps/tests.rs b/examples/src/rescue_raps/tests.rs index 3f3419fae..155b4ee8f 100644 --- a/examples/src/rescue_raps/tests.rs +++ b/examples/src/rescue_raps/tests.rs @@ -33,5 +33,5 @@ fn build_options(use_extension_field: bool) -> ProofOptions { } else { FieldExtension::None }; - ProofOptions::new(28, 8, 0, extension, 4, 31, true) + ProofOptions::new(28, 8, 0, extension, 4, 31, false) } diff --git a/examples/src/vdf/exempt/mod.rs b/examples/src/vdf/exempt/mod.rs index cc1dd53e9..58ece8133 100644 --- a/examples/src/vdf/exempt/mod.rs +++ b/examples/src/vdf/exempt/mod.rs @@ -104,7 +104,7 @@ where }); // generate the proof - prover.prove(trace).unwrap() + prover.prove(trace, None).unwrap() } fn verify(&self, proof: Proof) -> Result<(), VerifierError> { diff --git a/examples/src/vdf/exempt/prover.rs b/examples/src/vdf/exempt/prover.rs index ed41c3799..3c72e6919 100644 --- a/examples/src/vdf/exempt/prover.rs +++ b/examples/src/vdf/exempt/prover.rs @@ -4,11 +4,10 @@ // LICENSE file in the root directory of this source tree. use air::ZkParameters; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use winterfell::{ crypto::MerkleTree, matrix::ColMatrix, AuxRandElements, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, DefaultTraceLde, PartitionOptions, StarkDomain, Trace, TraceInfo, - TracePolyTable, TraceTable, + DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, PartitionOptions, StarkDomain, Trace, + TraceInfo, TracePolyTable, TraceTable, }; use super::{ @@ -60,6 +59,7 @@ where DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, Self::Air, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, trace: &Self::Trace) -> VdfInputs { // the result is read from the second to last step because the last last step contains @@ -82,16 +82,9 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E: FieldElement>( diff --git a/examples/src/vdf/exempt/tests.rs b/examples/src/vdf/exempt/tests.rs index c9c46d6e2..b7eec7f6a 100644 --- a/examples/src/vdf/exempt/tests.rs +++ b/examples/src/vdf/exempt/tests.rs @@ -31,5 +31,5 @@ fn build_options(use_extension_field: bool) -> ProofOptions { } else { FieldExtension::None }; - ProofOptions::new(85, 4, 0, extension, 4, 31, true) + ProofOptions::new(85, 4, 0, extension, 4, 31, false) } diff --git a/examples/src/vdf/regular/mod.rs b/examples/src/vdf/regular/mod.rs index 3cdcaba3d..4b7ba4468 100644 --- a/examples/src/vdf/regular/mod.rs +++ b/examples/src/vdf/regular/mod.rs @@ -101,7 +101,7 @@ where }); // generate the proof - prover.prove(trace).unwrap() + prover.prove(trace, None).unwrap() } fn verify(&self, proof: Proof) -> Result<(), VerifierError> { diff --git a/examples/src/vdf/regular/prover.rs b/examples/src/vdf/regular/prover.rs index 41dbac4f2..7d6c3def3 100644 --- a/examples/src/vdf/regular/prover.rs +++ b/examples/src/vdf/regular/prover.rs @@ -4,11 +4,10 @@ // LICENSE file in the root directory of this source tree. use air::ZkParameters; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use winterfell::{ crypto::MerkleTree, matrix::ColMatrix, AuxRandElements, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, DefaultTraceLde, PartitionOptions, StarkDomain, Trace, TraceInfo, - TracePolyTable, TraceTable, + DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, PartitionOptions, StarkDomain, Trace, + TraceInfo, TracePolyTable, TraceTable, }; use super::{ @@ -57,6 +56,7 @@ where DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, Self::Air, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, trace: &Self::Trace) -> VdfInputs { let last_step = trace.length() - 1; @@ -77,16 +77,9 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E: FieldElement>( diff --git a/examples/src/vdf/regular/tests.rs b/examples/src/vdf/regular/tests.rs index 93ed54e54..f4b409b85 100644 --- a/examples/src/vdf/regular/tests.rs +++ b/examples/src/vdf/regular/tests.rs @@ -31,5 +31,5 @@ fn build_options(use_extension_field: bool) -> ProofOptions { } else { FieldExtension::None }; - ProofOptions::new(2, 4, 0, extension, 2, 255, true) + ProofOptions::new(2, 4, 0, extension, 2, 255, false) } diff --git a/fri/benches/prover.rs b/fri/benches/prover.rs index 07b3b4ef5..2f8e72b57 100644 --- a/fri/benches/prover.rs +++ b/fri/benches/prover.rs @@ -8,6 +8,7 @@ use std::time::Duration; use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; use crypto::{hashers::Blake3_256, DefaultRandomCoin, MerkleTree}; use math::{fft, fields::f128::BaseElement, FieldElement}; +use rand_chacha::ChaCha20Rng; use rand_utils::rand_vector; use winter_fri::{DefaultProverChannel, FriOptions, FriProver}; @@ -23,7 +24,6 @@ pub fn build_layers(c: &mut Criterion) { for &domain_size in &BATCH_SIZES { let evaluations = build_evaluations(domain_size); - let mut prng = ::from_entropy(); fri_group.bench_with_input( BenchmarkId::new("build_layers", domain_size), @@ -34,13 +34,15 @@ pub fn build_layers(c: &mut Criterion) { b.iter_batched( || e.clone(), |evaluations| { - let mut channel = DefaultProverChannel::< - BaseElement, - Blake3_256, - DefaultRandomCoin>, - >::new(domain_size, 32, false); + let mut channel = + DefaultProverChannel::< + BaseElement, + Blake3_256, + ChaCha20Rng, + DefaultRandomCoin>, + >::new(domain_size, 32, false, None); - prover.build_layers(&mut channel, evaluations, &mut prng); + prover.build_layers(&mut channel, evaluations); prover.reset(); }, BatchSize::LargeInput, diff --git a/fri/src/prover/channel.rs b/fri/src/prover/channel.rs index 38a4771b4..5ee144f40 100644 --- a/fri/src/prover/channel.rs +++ b/fri/src/prover/channel.rs @@ -8,6 +8,7 @@ use core::marker::PhantomData; use crypto::{Digest, ElementHasher, Hasher, RandomCoin}; use math::FieldElement; +use rand::{RngCore, SeedableRng}; // PROVER CHANNEL TRAIT // ================================================================================================ @@ -34,13 +35,10 @@ pub trait ProverChannel { /// the hash of each row to get one entry of the vector being committed to. Thus, the number /// of elements grouped into a single leaf is equal to the `folding_factor` used for FRI layer /// construction. - fn commit_fri_layer

( + fn commit_fri_layer( &mut self, layer_root: ::Digest, - prng: &mut P, - ) -> Option<::Digest> - where - P: rand::RngCore; + ) -> Option<::Digest>; /// Returns a random α drawn uniformly at random from the entire field. /// @@ -59,10 +57,11 @@ pub trait ProverChannel { /// /// Though this implementation is intended primarily for testing purposes, it can be used in /// production use cases as well. -pub struct DefaultProverChannel +pub struct DefaultProverChannel where E: FieldElement, H: ElementHasher, + P: RngCore, R: RandomCoin, { public_coin: R, @@ -71,13 +70,15 @@ where num_queries: usize, is_zk: bool, salts: Vec>, + prng: Option

, _field_element: PhantomData, } -impl DefaultProverChannel +impl DefaultProverChannel where E: FieldElement, H: ElementHasher, + P: RngCore + SeedableRng, R: RandomCoin, { /// Returns a new prover channel instantiated from the specified parameters. @@ -86,13 +87,24 @@ where /// Panics if: /// * `domain_size` is smaller than 8 or is not a power of two. /// * `num_queries` is zero. - pub fn new(domain_size: usize, num_queries: usize, is_zk: bool) -> Self { + pub fn new( + domain_size: usize, + num_queries: usize, + is_zk: bool, + seed: Option<

::Seed>, + ) -> Self { assert!(domain_size >= 8, "domain size must be at least 8, but was {domain_size}"); assert!( domain_size.is_power_of_two(), "domain size must be a power of two, but was {domain_size}" ); assert!(num_queries > 0, "number of queries must be greater than zero"); + + let prng = if is_zk { + Some(P::from_seed(seed.expect("must provide the seed when zk is enabled"))) + } else { + None + }; DefaultProverChannel { public_coin: RandomCoin::new(&[]), commitments: Vec::new(), @@ -100,6 +112,7 @@ where num_queries, is_zk, salts: vec![], + prng, _field_element: PhantomData, } } @@ -126,29 +139,29 @@ where } } -impl ProverChannel for DefaultProverChannel +impl ProverChannel for DefaultProverChannel where E: FieldElement, H: ElementHasher, + P: RngCore, R: RandomCoin, { type Hasher = H; - fn commit_fri_layer( + fn commit_fri_layer( &mut self, layer_root: H::Digest, - prng: &mut P, ) -> Option<::Digest> { self.commitments.push(layer_root); - // sample a salt for Fiat-Shamir is zero-knowledge is enabled + // sample a salt for Fiat-Shamir if zero-knowledge is enabled let salt = if self.is_zk { let mut buffer = [0_u8; 32]; - prng.fill_bytes(&mut buffer); - - let salt = Digest::from_random_bytes(&buffer); - - Some(salt) + self.prng + .as_mut() + .expect("should have a PRNG when zk is enabled") + .fill_bytes(&mut buffer); + Some(Digest::from_random_bytes(&buffer)) } else { None }; diff --git a/fri/src/prover/mod.rs b/fri/src/prover/mod.rs index 3accc5998..cf32f0efd 100644 --- a/fri/src/prover/mod.rs +++ b/fri/src/prover/mod.rs @@ -179,12 +179,7 @@ where /// /// # Panics /// Panics if the prover state is dirty (the vector of layers is not empty). - pub fn build_layers( - &mut self, - channel: &mut C, - mut evaluations: Vec, - prng: &mut R, - ) { + pub fn build_layers(&mut self, channel: &mut C, mut evaluations: Vec) { assert!( self.layers.is_empty(), "a prior proof generation request has not been completed yet" @@ -194,25 +189,20 @@ where // has small enough degree for _ in 0..self.options.num_fri_layers(evaluations.len()) { match self.folding_factor() { - 2 => self.build_layer::(channel, &mut evaluations, prng), - 4 => self.build_layer::(channel, &mut evaluations, prng), - 8 => self.build_layer::(channel, &mut evaluations, prng), - 16 => self.build_layer::(channel, &mut evaluations, prng), + 2 => self.build_layer::<2>(channel, &mut evaluations), + 4 => self.build_layer::<4>(channel, &mut evaluations), + 8 => self.build_layer::<8>(channel, &mut evaluations), + 16 => self.build_layer::<16>(channel, &mut evaluations), _ => unimplemented!("folding factor {} is not supported", self.folding_factor()), } } - self.set_remainder(channel, &mut evaluations, prng); + self.set_remainder(channel, &mut evaluations); } /// Builds a single FRI layer by first committing to the `evaluations`, then drawing a random /// alpha from the channel and use it to perform degree-respecting projection. - fn build_layer( - &mut self, - channel: &mut C, - evaluations: &mut Vec, - prng: &mut R, - ) { + fn build_layer(&mut self, channel: &mut C, evaluations: &mut Vec) { // commit to the evaluations at the current layer; we do this by first transposing the // evaluations into a matrix of N columns, then hashing each row into a digest, and finally // commiting to vector of these digests; we do this so that we could de-commit to N values @@ -221,7 +211,7 @@ where let evaluation_vector_commitment = build_layer_commitment::<_, _, V, N>(&transposed_evaluations) .expect("failed to construct FRI layer commitment"); - let salt = channel.commit_fri_layer(evaluation_vector_commitment.commitment(), prng); + let salt = channel.commit_fri_layer(evaluation_vector_commitment.commitment()); self.salts.push(salt); // draw a pseudo-random coefficient from the channel, and use it in degree-respecting @@ -236,18 +226,13 @@ where } /// Creates remainder polynomial in coefficient form from a vector of `evaluations` over a domain. - fn set_remainder( - &mut self, - channel: &mut C, - evaluations: &mut [E], - prng: &mut R, - ) { + fn set_remainder(&mut self, channel: &mut C, evaluations: &mut [E]) { let inv_twiddles = fft::get_inv_twiddles(evaluations.len()); fft::interpolate_poly_with_offset(evaluations, &inv_twiddles, self.options.domain_offset()); let remainder_poly_size = evaluations.len() / self.options.blowup_factor(); let remainder_poly = evaluations[..remainder_poly_size].to_vec(); let commitment = ::hash_elements(&remainder_poly); - let salt = channel.commit_fri_layer(commitment, prng); + let salt = channel.commit_fri_layer(commitment); self.salts.push(salt); self.remainder_poly = FriRemainder(remainder_poly); } diff --git a/fri/src/prover/tests.rs b/fri/src/prover/tests.rs index 7387076cd..82df57b9c 100644 --- a/fri/src/prover/tests.rs +++ b/fri/src/prover/tests.rs @@ -7,7 +7,6 @@ use alloc::vec::Vec; use crypto::{hashers::Blake3_256, DefaultRandomCoin, Hasher, MerkleTree, RandomCoin}; use math::{fft, fields::f128::BaseElement, FieldElement}; -use rand::SeedableRng; use rand_chacha::ChaCha20Rng; use utils::{Deserializable, Serializable, SliceReader}; @@ -46,8 +45,8 @@ fn fri_folding_4() { pub fn build_prover_channel( trace_length: usize, options: &FriOptions, -) -> DefaultProverChannel> { - DefaultProverChannel::new(trace_length * options.blowup_factor(), 32, false) +) -> DefaultProverChannel> { + DefaultProverChannel::new(trace_length * options.blowup_factor(), 32, false, None) } pub fn build_evaluations(trace_length: usize, lde_blowup: usize) -> Vec { @@ -107,8 +106,7 @@ fn fri_prove_verify( // instantiate the prover and generate the proof let mut prover = FriProver::<_, _, _, MerkleTree>::new(options.clone()); - let mut prng = ChaCha20Rng::from_entropy(); - prover.build_layers(&mut channel, evaluations.clone(), &mut prng); + prover.build_layers(&mut channel, evaluations.clone()); let positions = channel.draw_query_positions(0); let proof = prover.build_proof(&positions); diff --git a/prover/benches/lagrange_kernel.rs b/prover/benches/lagrange_kernel.rs index 82d3c00f0..a30e15446 100644 --- a/prover/benches/lagrange_kernel.rs +++ b/prover/benches/lagrange_kernel.rs @@ -13,11 +13,9 @@ use air::{ use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; use crypto::{hashers::Blake3_256, DefaultRandomCoin, MerkleTree, RandomCoin}; use math::{fields::f64::BaseElement, ExtensionOf, FieldElement}; -use rand::SeedableRng; -use rand_chacha::ChaCha20Rng; use winter_prover::{ - matrix::ColMatrix, DefaultConstraintEvaluator, DefaultTraceLde, Prover, ProverGkrProof, - StarkDomain, Trace, TracePolyTable, + matrix::ColMatrix, DefaultConstraintEvaluator, DefaultTraceLde, MockPrng, Prover, + ProverGkrProof, StarkDomain, Trace, TracePolyTable, }; const TRACE_LENS: [usize; 2] = [2_usize.pow(16), 2_usize.pow(20)]; @@ -34,7 +32,7 @@ fn prove_with_lagrange_kernel(c: &mut Criterion) { let prover = LagrangeProver::new(AUX_TRACE_WIDTH); b.iter_batched( || trace.clone(), - |trace| prover.prove(trace).unwrap(), + |trace| prover.prove(trace, None).unwrap(), BatchSize::SmallInput, ) }); @@ -191,6 +189,7 @@ impl Prover for LagrangeProver { DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, LagrangeKernelAir, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, _trace: &Self::Trace) -> <::Air as Air>::PublicInputs { } @@ -206,19 +205,12 @@ impl Prover for LagrangeProver { domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + _prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) where E: math::FieldElement, { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, _prng) } fn new_evaluator<'a, E>( diff --git a/prover/src/channel.rs b/prover/src/channel.rs index 97d90aab7..a4d2bdc09 100644 --- a/prover/src/channel.rs +++ b/prover/src/channel.rs @@ -13,7 +13,7 @@ use air::{ use crypto::{Digest, ElementHasher, Hasher, RandomCoin, VectorCommitment}; use fri::FriProof; use math::{FieldElement, ToElements}; -use rand::RngCore; +use rand::{RngCore, SeedableRng}; #[cfg(feature = "concurrent")] use utils::iterators::*; use utils::Serializable; @@ -21,11 +21,12 @@ use utils::Serializable; // TYPES AND INTERFACES // ================================================================================================ -pub struct ProverChannel<'a, A, E, H, R, V> +pub struct ProverChannel<'a, A, E, H, P, R, V> where A: Air, E: FieldElement, H: ElementHasher, + P: RngCore, R: RandomCoin, V: VectorCommitment, { @@ -36,6 +37,7 @@ where ood_frame: OodFrame, pow_nonce: u64, salts: Vec>, + prng: Option

, _field_element: PhantomData, _vector_commitment: PhantomData, } @@ -43,18 +45,24 @@ where // PROVER CHANNEL IMPLEMENTATION // ================================================================================================ -impl<'a, A, E, H, R, V> ProverChannel<'a, A, E, H, R, V> +impl<'a, A, E, H, P, R, V> ProverChannel<'a, A, E, H, P, R, V> where A: Air, E: FieldElement, H: ElementHasher, + P: RngCore + SeedableRng, R: RandomCoin, V: VectorCommitment, { // CONSTRUCTOR // -------------------------------------------------------------------------------------------- /// Creates a new prover channel for the specified `air` and public inputs. - pub fn new(air: &'a A, mut pub_inputs_elements: Vec, zk_blowup: usize) -> Self { + pub fn new( + air: &'a A, + mut pub_inputs_elements: Vec, + zk_blowup: usize, + seed: Option<

::Seed>, + ) -> Self { let context = Context::new::( air.trace_info().clone(), air.options().clone(), @@ -67,6 +75,12 @@ where let mut coin_seed_elements = context.to_elements(); coin_seed_elements.append(&mut pub_inputs_elements); + let prng = if air.options().is_zk() { + Some(P::from_seed(seed.expect("must provide the seed when zk is enabled"))) + } else { + None + }; + ProverChannel { air, public_coin: RandomCoin::new(&coin_seed_elements), @@ -75,6 +89,7 @@ where ood_frame: OodFrame::default(), pow_nonce: 0, salts: vec![], + prng, _field_element: PhantomData, _vector_commitment: PhantomData, } @@ -84,16 +99,16 @@ where // -------------------------------------------------------------------------------------------- /// Commits the prover the extended execution trace. - pub fn commit_trace

(&mut self, trace_root: H::Digest, prng: &mut P) - where - P: RngCore, - { + pub fn commit_trace(&mut self, trace_root: H::Digest) { self.commitments.add::(&trace_root); - // sample a salt for Fiat-Shamir is zero-knowledge is enabled + // sample a salt for Fiat-Shamir if zero-knowledge is enabled let salt = if self.air.is_zk() { let mut buffer = [0_u8; 32]; - prng.fill_bytes(&mut buffer); + self.prng + .as_mut() + .expect("should have a PRNG when zk is enabled") + .fill_bytes(&mut buffer); Some(Digest::from_random_bytes(&buffer)) } else { None @@ -103,16 +118,16 @@ where } /// Commits the prover to the evaluations of the constraint composition polynomial. - pub fn commit_constraints

(&mut self, constraint_root: H::Digest, prng: &mut P) - where - P: RngCore, - { + pub fn commit_constraints(&mut self, constraint_root: H::Digest) { self.commitments.add::(&constraint_root); - // sample a salt for Fiat-Shamir is zero-knowledge is enabled + // sample a salt for Fiat-Shamir if zero-knowledge is enabled let salt = if self.air.is_zk() { let mut buffer = [0_u8; 32]; - prng.fill_bytes(&mut buffer); + self.prng + .as_mut() + .expect("should have a PRNG when zk is enabled") + .fill_bytes(&mut buffer); Some(Digest::from_random_bytes(&buffer)) } else { None @@ -123,16 +138,16 @@ where /// Saves the evaluations of trace polynomials over the out-of-domain evaluation frame. This /// also reseeds the public coin with the hashes of the evaluation frame states. - pub fn send_ood_trace_states

(&mut self, trace_ood_frame: &TraceOodFrame, prng: &mut P) - where - P: RngCore, - { + pub fn send_ood_trace_states(&mut self, trace_ood_frame: &TraceOodFrame) { let trace_states_hash = self.ood_frame.set_trace_states::(trace_ood_frame); // sample a salt for Fiat-Shamir if zero-knowledge is enabled let salt = if self.air.is_zk() { let mut buffer = [0_u8; 32]; - prng.fill_bytes(&mut buffer); + self.prng + .as_mut() + .expect("should have a PRNG when zk is enabled") + .fill_bytes(&mut buffer); Some(Digest::from_random_bytes(&buffer)) } else { None @@ -143,16 +158,16 @@ where /// Saves the evaluations of constraint composition polynomial columns at the out-of-domain /// point. This also reseeds the public coin wit the hash of the evaluations. - pub fn send_ood_constraint_evaluations

(&mut self, evaluations: &[E], prng: &mut P) - where - P: RngCore, - { + pub fn send_ood_constraint_evaluations(&mut self, evaluations: &[E]) { self.ood_frame.set_constraint_evaluations(evaluations); // sample a salt for Fiat-Shamir is zero-knowledge is enabled let salt = if self.air.is_zk() { let mut buffer = [0_u8; 32]; - prng.fill_bytes(&mut buffer); + self.prng + .as_mut() + .expect("should have a PRNG when zk is enabled") + .fill_bytes(&mut buffer); Some(Digest::from_random_bytes(&buffer)) } else { None @@ -264,31 +279,31 @@ where // FRI PROVER CHANNEL IMPLEMENTATION // ================================================================================================ -impl fri::ProverChannel for ProverChannel<'_, A, E, H, R, V> +impl fri::ProverChannel for ProverChannel<'_, A, E, H, P, R, V> where A: Air, E: FieldElement, H: ElementHasher, + P: RngCore, R: RandomCoin, V: VectorCommitment, { type Hasher = H; /// Commits the prover to a FRI layer. - fn commit_fri_layer

( - &mut self, - layer_root: H::Digest, - prng: &mut P, - ) -> Option<::Digest> + fn commit_fri_layer(&mut self, layer_root: H::Digest) -> Option<::Digest> where P: RngCore, { self.commitments.add::(&layer_root); - // sample a salt for Fiat-Shamir is zero-knowledge is enabled + // sample a salt for Fiat-Shamir if zero-knowledge is enabled let salt = if self.air.is_zk() { let mut buffer = [0_u8; 32]; - prng.fill_bytes(&mut buffer); + self.prng + .as_mut() + .expect("should have a PRNG when zk is enabled") + .fill_bytes(&mut buffer); Some(Digest::from_random_bytes(&buffer)) } else { None diff --git a/prover/src/constraints/composition_poly.rs b/prover/src/constraints/composition_poly.rs index a418a04c9..2de032981 100644 --- a/prover/src/constraints/composition_poly.rs +++ b/prover/src/constraints/composition_poly.rs @@ -65,7 +65,7 @@ impl CompositionPoly { domain: &StarkDomain, num_cols: usize, zk_parameters: Option, - prng: &mut R, + prng: &mut Option, ) -> Self { assert!( domain.trace_length() < composition_trace.num_rows(), @@ -95,7 +95,10 @@ impl CompositionPoly { let mut zk_col = vec![E::ZERO; extended_len]; for a in zk_col.iter_mut() { - let bytes = prng.gen::<[u8; 32]>(); + let bytes = prng + .as_mut() + .expect("should contain a PRNG when zk is enabled") + .gen::<[u8; 32]>(); *a = E::from_random_bytes(&bytes[..E::VALUE_SIZE]) .expect("failed to generate randomness"); } @@ -150,7 +153,7 @@ impl CompositionPoly { fn complement_to( polys: Vec>, l: usize, - prng: &mut R, + prng: &mut Option, ) -> Vec> { let mut result = vec![]; @@ -162,7 +165,10 @@ fn complement_to( let diff = l - poly.len(); for eval in current_poly.iter_mut().take(diff) { - let bytes = prng.gen::<[u8; 32]>(); + let bytes = prng + .as_mut() + .expect("should contain a PRNG when zk is enabled") + .gen::<[u8; 32]>(); *eval = E::from_random_bytes(&bytes[..E::VALUE_SIZE]) .expect("failed to generate randomness"); } @@ -180,6 +186,7 @@ fn complement_to( result.push(res) } + // TODO: is this always guaranteed to not panic? let poly = polys.last().unwrap(); let mut res = vec![E::ZERO; l]; for (i, entry) in poly.iter().enumerate() { diff --git a/prover/src/lib.rs b/prover/src/lib.rs index ae282908c..a29e43aa1 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -58,8 +58,7 @@ use math::{ fields::{CubeExtension, QuadExtension}, ExtensibleField, FieldElement, StarkField, ToElements, }; -use rand::{RngCore, SeedableRng}; -use rand_chacha::ChaCha20Rng; +use rand::{Error, RngCore, SeedableRng}; use tracing::{event, info_span, instrument, Level}; pub use utils::{ iterators, ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable, @@ -157,6 +156,9 @@ pub trait Prover { where E: FieldElement; + /// PRNG used when zero-knowledge (zk) is enabled. + type ZkPrng: RngCore + SeedableRng; + // REQUIRED METHODS // -------------------------------------------------------------------------------------------- @@ -186,6 +188,7 @@ pub trait Prover { domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) where E: FieldElement; @@ -242,7 +245,11 @@ pub trait Prover { /// Public inputs must match the value returned from /// [Self::get_pub_inputs()](Prover::get_pub_inputs) for the provided trace. #[maybe_async] - fn prove(&self, trace: Self::Trace) -> Result + fn prove( + &self, + trace: Self::Trace, + seed: Option<::Seed>, + ) -> Result where ::PublicInputs: Send, ::GkrProof: Send, @@ -251,18 +258,20 @@ pub trait Prover { // of static dispatch for selecting two generic parameter: extension field and hash // function. match self.options().field_extension() { - FieldExtension::None => maybe_await!(self.generate_proof::(trace)), + FieldExtension::None => { + maybe_await!(self.generate_proof::(trace, seed)) + }, FieldExtension::Quadratic => { if !>::is_supported() { return Err(ProverError::UnsupportedFieldExtension(2)); } - maybe_await!(self.generate_proof::>(trace)) + maybe_await!(self.generate_proof::>(trace, seed)) }, FieldExtension::Cubic => { if !>::is_supported() { return Err(ProverError::UnsupportedFieldExtension(3)); } - maybe_await!(self.generate_proof::>(trace)) + maybe_await!(self.generate_proof::>(trace, seed)) }, } } @@ -275,7 +284,11 @@ pub trait Prover { /// TODO: make this function un-callable externally? #[doc(hidden)] #[maybe_async] - fn generate_proof(&self, trace: Self::Trace) -> Result + fn generate_proof( + &self, + trace: Self::Trace, + seed: Option<::Seed>, + ) -> Result where E: FieldElement, ::PublicInputs: Send, @@ -292,19 +305,26 @@ pub trait Prover { // execution of the computation for the provided public inputs. let air = Self::Air::new(trace.info().clone(), pub_inputs, self.options().clone()); + // get the zk parameter, which are None unless zk is enabled + let zk_parameters = air.context().zk_parameters(); + + // create a PRNG to be used when zk is enabled, and also generates a seed to be used in + // generating salting values for Fiat-Shamir by `ProverChannel` + let (mut prng, seed) = generate_prng_and_new_seed(seed); + // create a channel which is used to simulate interaction between the prover and the // verifier; the channel will be used to commit to values and to draw randomness that // should come from the verifier. - let mut channel = - ProverChannel::::new( - &air, - pub_inputs_elements, - air.context().zk_blowup_factor(), - ); - let mut _prng = ChaCha20Rng::from_entropy(); - let seed = [0_u8; 32]; - let mut prng = ChaCha20Rng::from_seed(seed); - let zk_parameters = air.context().zk_parameters(); + let mut channel = ProverChannel::< + Self::Air, + E, + Self::HashFn, + Self::ZkPrng, + Self::RandomCoin, + Self::VC, + >::new( + &air, pub_inputs_elements, air.context().zk_blowup_factor(), seed + ); // 1 ----- Commit to the execution trace -------------------------------------------------- @@ -321,8 +341,8 @@ pub trait Prover { &trace, &domain, zk_parameters, + &mut channel, &mut prng, - &mut channel )); // build the auxiliary trace segment, and append the resulting segments to trace commitment @@ -359,7 +379,7 @@ pub trait Prover { // commit to the LDE of the extended auxiliary trace segment by writing its // commitment into the channel - channel.commit_trace(aux_segment_commitment, &mut prng); + channel.commit_trace(aux_segment_commitment); drop(span); aux_segment_polys @@ -432,10 +452,10 @@ pub trait Prover { // z * g^2, z * g^4, ..., z * g^(2^(v-1)), where v = log(trace_len). let ood_trace_states = trace_polys.get_ood_frame(z, air.context().trace_info().length()); - channel.send_ood_trace_states(&ood_trace_states, &mut prng); + channel.send_ood_trace_states(&ood_trace_states); let ood_evaluations = composition_poly.evaluate_at(z, air.is_zk()); - channel.send_ood_constraint_evaluations(&ood_evaluations, &mut prng); + channel.send_ood_constraint_evaluations(&ood_evaluations); // draw random coefficients to use during DEEP polynomial composition, and use them to // initialize the DEEP composition polynomial @@ -480,7 +500,7 @@ pub trait Prover { let num_layers = fri_options.num_fri_layers(lde_domain_size); let mut fri_prover = FriProver::<_, _, _, Self::VC>::new(fri_options); info_span!("compute_fri_layers", num_layers) - .in_scope(|| fri_prover.build_layers(&mut channel, deep_evaluations, &mut prng)); + .in_scope(|| fri_prover.build_layers(&mut channel, deep_evaluations)); // 7 ----- determine query positions ------------------------------------------------------ let query_positions = { @@ -542,17 +562,16 @@ pub trait Prover { /// The commitment is computed by building a vector containing the hashes of each row in /// the evaluation matrix, and then building vector commitment of the resulting vector. #[maybe_async] - fn build_constraint_commitment( + fn build_constraint_commitment( &self, composition_poly_trace: CompositionPolyTrace, num_constraint_composition_columns: usize, domain: &StarkDomain, zk_parameters: Option, - prng: &mut R, + prng: &mut Option, ) -> (ConstraintCommitment, CompositionPoly) where E: FieldElement, - R: RngCore, { // first, build constraint composition polynomial from its trace as follows: // - interpolate the trace into a polynomial in coefficient form @@ -597,7 +616,8 @@ pub trait Prover { let commitment = composed_evaluations.commit_to_rows::( self.options() .partition_options() - .partition_size::(num_constraint_composition_columns) + zk_parameters.is_some() as usize, + .partition_size::(num_constraint_composition_columns) + + zk_parameters.is_some() as usize, ); ConstraintCommitment::new(composed_evaluations, commitment) }); @@ -607,18 +627,26 @@ pub trait Prover { #[doc(hidden)] #[instrument(skip_all)] + #[allow(clippy::type_complexity)] #[maybe_async] - fn commit_to_main_trace_segment( + fn commit_to_main_trace_segment( &self, trace: &Self::Trace, domain: &StarkDomain, zk_parameters: Option, - prng: &mut R, - channel: &mut ProverChannel<'_, Self::Air, E, Self::HashFn, Self::RandomCoin, Self::VC>, + channel: &mut ProverChannel< + '_, + Self::Air, + E, + Self::HashFn, + Self::ZkPrng, + Self::RandomCoin, + Self::VC, + >, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) where E: FieldElement, - R: RngCore, { // extend the main execution trace and commit to the extended trace let (trace_lde, trace_polys) = maybe_await!(self.new_trace_lde( @@ -626,7 +654,8 @@ pub trait Prover { trace.main_segment(), domain, self.options().partition_options(), - zk_parameters + zk_parameters, + prng, )); // get the commitment to the main trace segment LDE @@ -634,31 +663,39 @@ pub trait Prover { // commit to the LDE of the main trace by writing the the commitment string into // the channel - channel.commit_trace(main_trace_commitment, prng); + channel.commit_trace(main_trace_commitment); (trace_lde, trace_polys) } #[doc(hidden)] #[instrument(skip_all)] + #[allow(clippy::type_complexity)] #[maybe_async] - fn commit_to_constraint_evaluations( + fn commit_to_constraint_evaluations( &self, air: &Self::Air, composition_poly_trace: CompositionPolyTrace, domain: &StarkDomain, - channel: &mut ProverChannel<'_, Self::Air, E, Self::HashFn, Self::RandomCoin, Self::VC>, + channel: &mut ProverChannel< + '_, + Self::Air, + E, + Self::HashFn, + Self::ZkPrng, + Self::RandomCoin, + Self::VC, + >, zk_parameters: Option, - prng: &mut R, + prng: &mut Option, ) -> (ConstraintCommitment, CompositionPoly) where E: FieldElement, - R: RngCore, { // first, build a commitment to the evaluations of the constraint composition polynomial // columns let (constraint_commitment, composition_poly) = maybe_await!(self - .build_constraint_commitment::( + .build_constraint_commitment::( composition_poly_trace, air.context().num_constraint_composition_columns(), domain, @@ -668,8 +705,56 @@ pub trait Prover { // then, commit to the evaluations of constraints by writing the commitment string of // the constraint commitment into the channel - channel.commit_constraints(constraint_commitment.commitment(), prng); + channel.commit_constraints(constraint_commitment.commitment()); (constraint_commitment, composition_poly) } } + +// MOCK PRNG FOR ZERO-KNOWLEDGE +// ================================================================================================= + +/// A mock PRNG used when zero-knowledge is not enabled. +pub struct MockPrng; +impl SeedableRng for MockPrng { + type Seed = [u8; 8]; + + fn from_seed(_seed: Self::Seed) -> Self { + Self + } +} + +impl RngCore for MockPrng { + fn next_u32(&mut self) -> u32 { + 0 + } + + fn next_u64(&mut self) -> u64 { + 0 + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + dest.iter_mut().for_each(|d| *d = 0); + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + dest.iter_mut().for_each(|d| *d = 0); + Ok(()) + } +} + +/// A helper funcation that generates a PRNG from a seed when zero-knowledge is enabled. +fn generate_prng_and_new_seed( + seed: Option<

::Seed>, +) -> (Option

, Option<

::Seed>) { + match seed { + Some(seed) => { + let mut prng = P::from_seed(seed); + let mut seed =

::Seed::default(); + prng.fill_bytes(seed.as_mut()); + + (Some(prng), Some(seed)) + }, + None => (None, None), + } +} diff --git a/prover/src/matrix/col_matrix.rs b/prover/src/matrix/col_matrix.rs index 62a953878..2ec304d30 100644 --- a/prover/src/matrix/col_matrix.rs +++ b/prover/src/matrix/col_matrix.rs @@ -314,7 +314,7 @@ impl ColMatrix { /// 2. \hat{w}(x) is the randomized witness polynomial. /// 3. r(x) is the randomizer polynomial and has degree `(zk_blowup - 1) * n`. /// 4. Z_H(x) = (x^n - 1). - pub(crate) fn randomize(&self, zk_blowup: usize, prng: &mut R) -> Self { + pub(crate) fn randomize(&self, zk_blowup: usize, prng: &mut Option) -> Self { let cur_len = self.num_rows(); let extended_len = zk_blowup * cur_len; let pad_len = extended_len - cur_len; @@ -324,7 +324,10 @@ impl ColMatrix { .map(|col| { let mut added = vec![E::ZERO; pad_len]; for a in added.iter_mut() { - let bytes = prng.gen::<[u8; 32]>(); + let bytes = prng + .as_mut() + .expect("should have a PRNG when zk is enabled") + .gen::<[u8; 32]>(); *a = E::from_random_bytes(&bytes[..E::VALUE_SIZE]) .expect("failed to generate randomness"); } diff --git a/prover/src/trace/trace_lde/default/mod.rs b/prover/src/trace/trace_lde/default/mod.rs index 2f596aed7..6b93a92c5 100644 --- a/prover/src/trace/trace_lde/default/mod.rs +++ b/prover/src/trace/trace_lde/default/mod.rs @@ -69,7 +69,7 @@ where domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, - prng: &mut R, + prng: &mut Option, ) -> (Self, TracePolyTable) { // extend the main execution trace and build a commitment to the extended trace let (main_segment_lde, main_segment_vector_com, main_segment_polys) = @@ -153,7 +153,7 @@ where aux_trace: &ColMatrix, domain: &StarkDomain, zk_parameters: Option, - prng: &mut R, + prng: &mut Option, ) -> (ColMatrix, H::Digest) { // extend the auxiliary trace segment and build a commitment to the extended trace let (aux_segment_lde, aux_segment_oracles, aux_segment_polys) = @@ -287,7 +287,7 @@ fn build_trace_commitment( domain: &StarkDomain, partition_size: usize, zk_parameters: Option, - prng: &mut R, + prng: &mut Option, ) -> (RowMatrix, V, ColMatrix) where E: FieldElement, diff --git a/prover/src/trace/trace_lde/default/tests.rs b/prover/src/trace/trace_lde/default/tests.rs index f716fa0ab..88d1c4234 100644 --- a/prover/src/trace/trace_lde/default/tests.rs +++ b/prover/src/trace/trace_lde/default/tests.rs @@ -16,7 +16,7 @@ use rand_chacha::ChaCha20Rng; use crate::{ tests::{build_fib_trace, MockAir}, - DefaultTraceLde, StarkDomain, Trace, TraceLde, + DefaultTraceLde, MockPrng, StarkDomain, Trace, TraceLde, }; type Blake3 = Blake3_256; @@ -29,7 +29,7 @@ fn extend_trace_table() { let trace = build_fib_trace(trace_length * 2); let domain = StarkDomain::new(&air); let partition_option = PartitionOptions::default(); - let mut prng = ChaCha20Rng::from_entropy(); + let prng = ChaCha20Rng::from_entropy(); // build the trace polynomials, extended trace, and commitment using the default TraceLde impl let (trace_lde, trace_polys) = DefaultTraceLde::>::new( @@ -38,7 +38,7 @@ fn extend_trace_table() { &domain, partition_option, None, - &mut prng, + &mut Some(prng), ); // check the width and length of the extended trace @@ -84,16 +84,15 @@ fn commit_trace_table() { let trace = build_fib_trace(trace_length * 2); let domain = StarkDomain::new(&air); let partition_option = PartitionOptions::default(); - let mut prng = ChaCha20Rng::from_entropy(); // build the trace polynomials, extended trace, and commitment using the default TraceLde impl - let (trace_lde, _) = DefaultTraceLde::>::new( + let (trace_lde, _) = DefaultTraceLde::>::new::( trace.info(), trace.main_segment(), &domain, partition_option, None, - &mut prng, + &mut None, ); // build commitment, using a Merkle tree, to the trace rows diff --git a/prover/src/trace/trace_lde/mod.rs b/prover/src/trace/trace_lde/mod.rs index 6abcf8b96..721f7733a 100644 --- a/prover/src/trace/trace_lde/mod.rs +++ b/prover/src/trace/trace_lde/mod.rs @@ -51,7 +51,7 @@ pub trait TraceLde: Sync { aux_trace: &ColMatrix, domain: &StarkDomain, zk_parameters: Option, - prng: &mut R, + prng: &mut Option, ) -> (ColMatrix, ::Digest); /// Reads current and next rows from the main trace segment into the specified frame. diff --git a/verifier/src/channel.rs b/verifier/src/channel.rs index 2175b8b88..50f810fe4 100644 --- a/verifier/src/channel.rs +++ b/verifier/src/channel.rs @@ -133,8 +133,9 @@ where .partition_size::(air.context().trace_info().main_trace_width()); let partition_size_aux = partition_options.partition_size::(air.context().trace_info().aux_segment_width()); - let partition_size_constraint = partition_options - .partition_size::(air.context().num_constraint_composition_columns() + air.is_zk() as usize); + let partition_size_constraint = partition_options.partition_size::( + air.context().num_constraint_composition_columns() + air.is_zk() as usize, + ); // --- parse Fiat-Shamir salts ----------------------------------------------- let salts: Vec> = Vec::read_from_bytes(&salts) .map_err(|err| VerifierError::ProofDeserializationError(err.to_string()))?; diff --git a/winterfell/Cargo.toml b/winterfell/Cargo.toml index 1d3aaa04f..cdeeb59ec 100644 --- a/winterfell/Cargo.toml +++ b/winterfell/Cargo.toml @@ -26,8 +26,6 @@ air = { version = "0.10", path = "../air", package = "winter-air", default-featu prover = { version = "0.10", path = "../prover", package = "winter-prover", default-features = false } verifier = { version = "0.10", path = "../verifier", package = "winter-verifier", default-features = false } -rand_chacha = { version = "0.3", default-features = false } - # Allow math in docs [package.metadata.docs.rs] rustdoc-args = ["--html-in-header", ".cargo/katex-header.html"] diff --git a/winterfell/src/lib.rs b/winterfell/src/lib.rs index 50b235aaf..736c14883 100644 --- a/winterfell/src/lib.rs +++ b/winterfell/src/lib.rs @@ -267,7 +267,7 @@ //! //! # use winterfell::{ //! # Air, AirContext, Assertion, AuxRandElements, ByteWriter, DefaultConstraintEvaluator, -//! # EvaluationFrame, PartitionOptions, TraceInfo, TransitionConstraintDegree, +//! # EvaluationFrame, PartitionOptions, TraceInfo, TransitionConstraintDegree, MockPrng, //! # }; //! # //! # pub struct PublicInputs { @@ -353,6 +353,7 @@ //! type TraceLde> = DefaultTraceLde; //! type ConstraintEvaluator<'a, E: FieldElement> = //! DefaultConstraintEvaluator<'a, Self::Air, E>; +//! type ZkPrng = MockPrng; //! //! // Our public inputs consist of the first and last value in the execution trace. //! fn get_pub_inputs(&self, trace: &Self::Trace) -> PublicInputs { @@ -374,8 +375,9 @@ //! domain: &StarkDomain, //! partition_option: PartitionOptions, //! is_zk: Option, +//! prng: &mut Option, //! ) -> (Self::TraceLde, TracePolyTable) { -//! DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, is_zk) +//! DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, is_zk, prng) //! } //! //! fn new_evaluator<'a, E: FieldElement>( @@ -405,7 +407,7 @@ //! # DefaultTraceLde, EvaluationFrame, TraceInfo, //! # TransitionConstraintDegree, TraceTable, FieldExtension, PartitionOptions, Prover, //! # ProofOptions, StarkDomain, Proof, Trace, TracePolyTable, -//! # ZkParameters +//! # ZkParameters, MockPrng, //! # }; //! # //! # pub fn build_do_work_trace(start: BaseElement, n: usize) -> TraceTable { @@ -500,6 +502,7 @@ //! # type TraceLde> = DefaultTraceLde; //! # type ConstraintEvaluator<'a, E: FieldElement> = //! # DefaultConstraintEvaluator<'a, Self::Air, E>; +//! # type ZkPrng = MockPrng; //! # //! # fn get_pub_inputs(&self, trace: &Self::Trace) -> PublicInputs { //! # let last_step = trace.length() - 1; @@ -520,8 +523,9 @@ //! # domain: &StarkDomain, //! # partition_option: PartitionOptions, //! # is_zk: Option, +//! # prng: &mut Option, //! # ) -> (Self::TraceLde, TracePolyTable) { -//! # DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, is_zk) +//! # DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, is_zk, prng) //! # } //! # //! # fn new_evaluator<'a, E: FieldElement>( @@ -557,7 +561,7 @@ //! //! // Instantiate the prover and generate the proof. //! let prover = WorkProver::new(options); -//! let proof = prover.prove(trace).unwrap(); +//! let proof = prover.prove(trace, None).unwrap(); //! //! // The verifier will accept proofs with parameters which guarantee 95 bits or more of //! // conjectured security @@ -607,8 +611,8 @@ pub use prover::{ BoundaryConstraint, BoundaryConstraintGroup, CompositionPolyTrace, ConstraintCompositionCoefficients, ConstraintDivisor, ConstraintEvaluator, DeepCompositionCoefficients, DefaultConstraintEvaluator, DefaultTraceLde, EvaluationFrame, - FieldExtension, Proof, ProofOptions, Prover, ProverError, ProverGkrProof, StarkDomain, Trace, - TraceInfo, TraceLde, TracePolyTable, TraceTable, TraceTableFragment, + FieldExtension, MockPrng, Proof, ProofOptions, Prover, ProverError, ProverGkrProof, + StarkDomain, Trace, TraceInfo, TraceLde, TracePolyTable, TraceTable, TraceTableFragment, TransitionConstraintDegree, }; pub use verifier::{verify, AcceptableOptions, ByteWriter, VerifierError}; diff --git a/winterfell/src/tests.rs b/winterfell/src/tests.rs index 0bcb25566..541d6d8ed 100644 --- a/winterfell/src/tests.rs +++ b/winterfell/src/tests.rs @@ -12,7 +12,6 @@ use prover::{ math::{fields::f64::BaseElement, ExtensionOf, FieldElement}, matrix::ColMatrix, }; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; use super::*; @@ -24,7 +23,7 @@ fn test_complex_lagrange_kernel_air() { let prover = LagrangeComplexProver::new(AUX_TRACE_WIDTH); - let proof = prover.prove(trace).unwrap(); + let proof = prover.prove(trace, None).unwrap(); verify::< LagrangeKernelComplexAir, @@ -222,6 +221,7 @@ impl Prover for LagrangeComplexProver { DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = DefaultConstraintEvaluator<'a, LagrangeKernelComplexAir, E>; + type ZkPrng = MockPrng; fn get_pub_inputs(&self, _trace: &Self::Trace) -> <::Air as Air>::PublicInputs { } @@ -237,19 +237,12 @@ impl Prover for LagrangeComplexProver { domain: &StarkDomain, partition_option: PartitionOptions, zk_parameters: Option, + prng: &mut Option, ) -> (Self::TraceLde, TracePolyTable) where E: math::FieldElement, { - let mut prng = ChaCha20Rng::from_entropy(); - DefaultTraceLde::new( - trace_info, - main_trace, - domain, - partition_option, - zk_parameters, - &mut prng, - ) + DefaultTraceLde::new(trace_info, main_trace, domain, partition_option, zk_parameters, prng) } fn new_evaluator<'a, E>(