diff --git a/Cargo.toml b/Cargo.toml index 0ab62c8..d25ff34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ anyhow = "1.0.86" covenants-gadgets = { git = "https://github.com/Bitcoin-Wildlife-Sanctuary/covenants-gadgets" } clap = { version = "4.5.0", features = ["derive"] } colored = "2.1.0" -bitcoin-circle-stark = {git = "https://github.com/Bitcoin-Wildlife-Sanctuary/bitcoin-circle-stark"} +bitcoin-circle-stark = { git = "https://github.com/Bitcoin-Wildlife-Sanctuary/bitcoin-circle-stark" } [profile.dev] opt-level = 3 diff --git a/src/bin/demo.rs b/src/bin/demo.rs index 1785c93..fe88f58 100644 --- a/src/bin/demo.rs +++ b/src/bin/demo.rs @@ -13,10 +13,12 @@ use fibonacci_example::quotients::compute_quotients_hints; use fibonacci_example::split::{FibonacciSplitInput, FibonacciSplitProgram, FibonacciSplitState}; use fibonacci_example::FIB_LOG_SIZE; use std::io::Write; -use stwo_prover::core::channel::{BWSSha256Channel, Channel}; +use stwo_prover::core::channel::Sha256Channel; use stwo_prover::core::fields::m31::{BaseField, M31}; use stwo_prover::core::fields::IntoSlice; -use stwo_prover::core::vcs::bws_sha256_hash::BWSSha256Hasher; +use stwo_prover::core::pcs::PcsConfig; +use stwo_prover::core::vcs::sha256_hash::Sha256Hasher; +use stwo_prover::core::vcs::sha256_merkle::Sha256MerkleChannel; use stwo_prover::examples::fibonacci::Fibonacci; use stwo_prover::trace_generation::commit_and_prove; @@ -97,20 +99,23 @@ fn main() { println!("================================================"); } else { let fib = Fibonacci::new(FIB_LOG_SIZE, M31::reduce(443693538)); + let config = PcsConfig::default(); let trace = fib.get_trace(); - let channel = - &mut BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[fib - .air - .component - .claim]))); - let proof = commit_and_prove(&fib.air, channel, vec![trace]).unwrap(); - - let channel = - &mut BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[fib - .air - .component - .claim]))); + let channel = &mut Sha256Channel::default(); + channel.update_digest(Sha256Hasher::hash(BaseField::into_slice(&[fib + .air + .component + .claim]))); + let proof = + commit_and_prove::<_, Sha256MerkleChannel>(&fib.air, channel, vec![trace], config) + .unwrap(); + + let channel = &mut Sha256Channel::default(); + channel.update_digest(Sha256Hasher::hash(BaseField::into_slice(&[fib + .air + .component + .claim]))); let (fiat_shamir_output, fiat_shamir_hints) = compute_fiat_shamir_hints(proof.clone(), channel, &fib.air).unwrap(); diff --git a/src/bitcoin_script/fiat_shamir.rs b/src/bitcoin_script/fiat_shamir.rs index cc60779..b6ff870 100644 --- a/src/bitcoin_script/fiat_shamir.rs +++ b/src/bitcoin_script/fiat_shamir.rs @@ -12,7 +12,7 @@ use bitcoin_scriptexec::{profiler_end, profiler_start}; use rust_bitcoin_m31::{ qm31_copy, qm31_dup, qm31_equalverify, qm31_from_bottom, qm31_over, qm31_roll, }; -use stwo_prover::core::channel::BWSSha256Channel; +use stwo_prover::core::channel::Sha256Channel; use stwo_prover::core::fields::m31::M31; use stwo_prover::core::poly::circle::CanonicCoset; use stwo_prover::core::prover::{LOG_BLOWUP_FACTOR, N_QUERIES, PROOF_OF_WORK_BITS}; @@ -52,7 +52,7 @@ impl FibonacciFiatShamirGadget { /// - masked points (3 * 8 = 24) /// - oods point (8) /// - pub fn run(channel: &BWSSha256Channel) -> Script { + pub fn run(channel: &Sha256Channel) -> Script { script! { // push the initial channel { channel.digest } diff --git a/src/bitcoin_script/mod.rs b/src/bitcoin_script/mod.rs index 08f55b6..a6be47a 100644 --- a/src/bitcoin_script/mod.rs +++ b/src/bitcoin_script/mod.rs @@ -4,7 +4,7 @@ use crate::bitcoin_script::prepare::FibonacciPrepareGadget; use crate::bitcoin_script::quotients::FibonacciPerQueryQuotientGadget; use bitcoin_circle_stark::treepp::*; use bitcoin_circle_stark::utils::clean_stack; -use stwo_prover::core::channel::BWSSha256Channel; +use stwo_prover::core::channel::Sha256Channel; use stwo_prover::core::prover::N_QUERIES; mod composition; @@ -25,7 +25,7 @@ pub struct FibonacciVerifierGadget; impl FibonacciVerifierGadget { /// Run the verifier in the Bitcoin script. - pub fn run_verifier(channel: &BWSSha256Channel) -> Script { + pub fn run_verifier(channel: &Sha256Channel) -> Script { script! { // Run the Fiat-Shamir gadget { FibonacciFiatShamirGadget::run(channel) } @@ -81,39 +81,45 @@ mod test { use bitcoin_circle_stark::tests_utils::report::report_bitcoin_script_size; use bitcoin_circle_stark::treepp::*; use bitcoin_scriptexec::execute_script_with_witness_unlimited_stack; - use stwo_prover::core::channel::{BWSSha256Channel, Channel}; + use stwo_prover::core::channel::Sha256Channel; use stwo_prover::core::fields::m31::{BaseField, M31}; use stwo_prover::core::fields::IntoSlice; - use stwo_prover::core::vcs::bws_sha256_hash::BWSSha256Hasher; + use stwo_prover::core::pcs::PcsConfig; + use stwo_prover::core::vcs::sha256_hash::Sha256Hasher; + use stwo_prover::core::vcs::sha256_merkle::Sha256MerkleChannel; use stwo_prover::examples::fibonacci::Fibonacci; use stwo_prover::trace_generation::{commit_and_prove, commit_and_verify}; #[test] fn test_verifier() { let fib = Fibonacci::new(FIB_LOG_SIZE, M31::reduce(443693538)); + let config = PcsConfig::default(); let trace = fib.get_trace(); - let channel = - &mut BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[fib - .air - .component - .claim]))); - let proof = commit_and_prove(&fib.air, channel, vec![trace]).unwrap(); + let channel = &mut Sha256Channel::default(); + channel.update_digest(Sha256Hasher::hash(BaseField::into_slice(&[fib + .air + .component + .claim]))); + let proof = + commit_and_prove::<_, Sha256MerkleChannel>(&fib.air, channel, vec![trace], config) + .unwrap(); { - let channel = - &mut BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[fib - .air - .component - .claim]))); - commit_and_verify(proof.clone(), &fib.air, channel).unwrap(); - } - - let channel = - &mut BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[fib + let channel = &mut Sha256Channel::default(); + channel.update_digest(Sha256Hasher::hash(BaseField::into_slice(&[fib .air .component .claim]))); + commit_and_verify::(proof.clone(), &fib.air, channel, config) + .unwrap(); + } + + let channel = &mut Sha256Channel::default(); + channel.update_digest(Sha256Hasher::hash(BaseField::into_slice(&[fib + .air + .component + .claim]))); let channel_clone = channel.clone(); let hint = verify_with_hints(proof, &fib.air, channel).unwrap(); diff --git a/src/fiat_shamir.rs b/src/fiat_shamir.rs index 1138cb7..4a6f887 100644 --- a/src/fiat_shamir.rs +++ b/src/fiat_shamir.rs @@ -10,24 +10,24 @@ use itertools::Itertools; use stwo_prover::core::air::accumulation::PointEvaluationAccumulator; use stwo_prover::core::air::ComponentProvers; use stwo_prover::core::air::{AirProver, Component}; -use stwo_prover::core::channel::{BWSSha256Channel, Channel}; +use stwo_prover::core::channel::{Channel, Sha256Channel}; use stwo_prover::core::circle::{CirclePoint, Coset}; use stwo_prover::core::fields::m31::M31; use stwo_prover::core::fields::qm31::{SecureField, QM31}; +use stwo_prover::core::fields::secure_column::SECURE_EXTENSION_DEGREE; use stwo_prover::core::fri::{ get_opening_positions, CirclePolyDegreeBound, FriConfig, FriLayerVerifier, FriVerificationError, FOLD_STEP, }; -use stwo_prover::core::pcs::{CommitmentSchemeVerifier, TreeVec}; +use stwo_prover::core::pcs::{CommitmentSchemeVerifier, PcsConfig, TreeVec}; use stwo_prover::core::poly::line::LineDomain; -use stwo_prover::core::proof_of_work::ProofOfWork; use stwo_prover::core::prover::{ StarkProof, VerificationError, LOG_BLOWUP_FACTOR, LOG_LAST_LAYER_DEGREE_BOUND, N_QUERIES, PROOF_OF_WORK_BITS, }; use stwo_prover::core::queries::{Queries, SparseSubCircleDomain}; -use stwo_prover::core::vcs::bws_sha256_hash::BWSSha256Hash; -use stwo_prover::core::vcs::bws_sha256_merkle::BWSSha256MerkleHasher; +use stwo_prover::core::vcs::sha256_hash::{Sha256Hash, Sha256Hasher}; +use stwo_prover::core::vcs::sha256_merkle::{Sha256MerkleChannel, Sha256MerkleHasher}; use stwo_prover::core::{ColumnVec, InteractionElements, LookupValues}; use stwo_prover::examples::fibonacci::air::FibonacciAir; use stwo_prover::trace_generation::AirTraceGenerator; @@ -36,7 +36,7 @@ use stwo_prover::trace_generation::AirTraceGenerator; /// Hints for performing the Fiat-Shamir transform until finalizing the queries. pub struct FiatShamirHints { /// Commitments from the proof. - pub commitments: [BWSSha256Hash; 2], + pub commitments: [Sha256Hash; 2], /// random_coeff comes from adding `proof.commitments[0]` to the channel. pub random_coeff_hint: DrawHints, @@ -60,7 +60,7 @@ pub struct FiatShamirHints { pub circle_poly_alpha_hint: DrawHints, /// fri commit and hints for deriving the folding parameter - pub fri_commitment_and_folding_hints: Vec<(BWSSha256Hash, DrawHints)>, + pub fri_commitment_and_folding_hints: Vec<(Sha256Hash, DrawHints)>, /// last layer poly (assuming only one element) pub last_layer: QM31, @@ -161,18 +161,19 @@ pub struct FiatShamirOutput { pub last_layer: QM31, /// fri commit and hints for deriving the folding parameter - pub fri_commitment_and_folding_hints: Vec<(BWSSha256Hash, DrawHints)>, + pub fri_commitment_and_folding_hints: Vec<(Sha256Hash, DrawHints)>, } /// Generate Fiat Shamir hints along with fri inputs pub fn compute_fiat_shamir_hints( - proof: StarkProof, - channel: &mut BWSSha256Channel, + proof: StarkProof, + channel: &mut Sha256Channel, air: &FibonacciAir, ) -> Result<(FiatShamirOutput, FiatShamirHints), VerificationError> { + let config = PcsConfig::default(); // Read trace commitment. - let mut commitment_scheme: CommitmentSchemeVerifier = - CommitmentSchemeVerifier::new(); + let mut commitment_scheme: CommitmentSchemeVerifier = + CommitmentSchemeVerifier::new(config); let air_prover = air.to_air_prover(); let components = ComponentProvers(air_prover.component_provers()); @@ -212,7 +213,9 @@ pub fn compute_fiat_shamir_hints( let masked_points = trace_sample_points.clone(); // TODO(spapini): Change when we support multiple interactions. - let sampled_points = components.components().mask_points(oods_point); + let mut sampled_points = components.components().mask_points(oods_point); + // Add the composition polynomial mask points. + sampled_points.push(vec![vec![oods_point]; SECURE_EXTENSION_DEGREE]); // this step is just a reorganization of the data assert_eq!(sampled_points.0[0][0][0], masked_points[0][0][0]); @@ -311,7 +314,10 @@ pub fn compute_fiat_shamir_hints( .into_iter() .enumerate() { - channel.mix_digest(proof.commitment); + channel.update_digest(Sha256Hasher::concat_and_hash( + &proof.commitment, + &channel.digest(), + )); let (folding_alpha, folding_alpha_hint) = channel.draw_felt_and_hints(); folding_alphas.push(folding_alpha); @@ -351,13 +357,15 @@ pub fn compute_fiat_shamir_hints( let pow_hint = PoWHint::new( channel.digest, - proof.commitment_scheme_proof.proof_of_work.nonce, + proof.commitment_scheme_proof.proof_of_work, PROOF_OF_WORK_BITS, ); // Verify proof of work. - ProofOfWork::new(PROOF_OF_WORK_BITS) - .verify(channel, &proof.commitment_scheme_proof.proof_of_work)?; + channel.mix_nonce(proof.commitment_scheme_proof.proof_of_work); + if channel.trailing_zeros() < PROOF_OF_WORK_BITS { + return Err(VerificationError::ProofOfWork); + } let column_log_sizes = bounds .iter() diff --git a/src/fold.rs b/src/fold.rs index fb31a63..e22167b 100644 --- a/src/fold.rs +++ b/src/fold.rs @@ -9,7 +9,7 @@ use stwo_prover::core::fft::ibutterfly; use stwo_prover::core::fields::m31::M31; use stwo_prover::core::fields::qm31::SecureField; use stwo_prover::core::fri::FriProof; -use stwo_prover::core::vcs::bws_sha256_merkle::BWSSha256MerkleHasher; +use stwo_prover::core::vcs::sha256_merkle::Sha256MerkleHasher; /// The hints for folding for each query. #[derive(Clone)] @@ -29,7 +29,7 @@ impl Pushable for PerQueryFoldHints { /// Compute the hints for folding. pub fn compute_fold_hints( - fri_proof: &FriProof, + fri_proof: &FriProof, fs_output: &FiatShamirOutput, prepare_output: &PrepareOutput, quotients_output: &QuotientsOutput, diff --git a/src/lib.rs b/src/lib.rs index ae8405f..865e2ad 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,12 +22,12 @@ use crate::quotients::compute_quotients_hints; use bitcoin_circle_stark::treepp::pushable::{Builder, Pushable}; use quotients::PerQueryQuotientHint; use stwo_prover::core::air::Air; -use stwo_prover::core::channel::BWSSha256Channel; +use stwo_prover::core::channel::Sha256Channel; use stwo_prover::core::circle::CirclePoint; use stwo_prover::core::fields::qm31::SecureField; use stwo_prover::core::pcs::TreeVec; use stwo_prover::core::prover::{InvalidOodsSampleStructure, StarkProof, VerificationError}; -use stwo_prover::core::vcs::bws_sha256_merkle::BWSSha256MerkleHasher; +use stwo_prover::core::vcs::sha256_merkle::Sha256MerkleHasher; use stwo_prover::core::ColumnVec; use stwo_prover::examples::fibonacci::air::FibonacciAir; @@ -65,9 +65,9 @@ impl Pushable for VerifierHints { /// A verifier program that generates hints. pub fn verify_with_hints( - proof: StarkProof, + proof: StarkProof, air: &FibonacciAir, - channel: &mut BWSSha256Channel, + channel: &mut Sha256Channel, ) -> Result { let (fiat_shamir_output, fiat_shamir_hints) = compute_fiat_shamir_hints(proof.clone(), channel, air).unwrap(); @@ -130,12 +130,13 @@ fn sampled_values_to_mask( #[cfg(test)] mod test { - use stwo_prover::core::channel::{BWSSha256Channel, Channel}; + use stwo_prover::core::channel::Sha256Channel; use stwo_prover::core::fields::m31::{BaseField, M31}; use stwo_prover::core::fields::IntoSlice; + use stwo_prover::core::pcs::PcsConfig; use stwo_prover::core::prover::StarkProof; - use stwo_prover::core::vcs::bws_sha256_hash::BWSSha256Hasher; - use stwo_prover::core::vcs::bws_sha256_merkle::BWSSha256MerkleHasher; + use stwo_prover::core::vcs::sha256_hash::Sha256Hasher; + use stwo_prover::core::vcs::sha256_merkle::{Sha256MerkleChannel, Sha256MerkleHasher}; use stwo_prover::examples::fibonacci::Fibonacci; use stwo_prover::trace_generation::{commit_and_prove, commit_and_verify}; @@ -143,21 +144,23 @@ mod test { fn test_fib_prove() { const FIB_LOG_SIZE: u32 = 5; let fib = Fibonacci::new(FIB_LOG_SIZE, M31::reduce(443693538)); + let config = PcsConfig::default(); let trace = fib.get_trace(); - let channel = - &mut BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[fib - .air - .component - .claim]))); - let proof: StarkProof = - commit_and_prove(&fib.air, channel, vec![trace]).unwrap(); - - let channel = - &mut BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[fib - .air - .component - .claim]))); - commit_and_verify(proof, &fib.air, channel).unwrap() + let channel = &mut Sha256Channel::default(); + channel.update_digest(Sha256Hasher::hash(BaseField::into_slice(&[fib + .air + .component + .claim]))); + let proof: StarkProof = + commit_and_prove::<_, Sha256MerkleChannel>(&fib.air, channel, vec![trace], config) + .unwrap(); + + let channel = &mut Sha256Channel::default(); + channel.update_digest(Sha256Hasher::hash(BaseField::into_slice(&[fib + .air + .component + .claim]))); + commit_and_verify::(proof, &fib.air, channel, config).unwrap() } } diff --git a/src/prepare.rs b/src/prepare.rs index 688dda4..fed495f 100644 --- a/src/prepare.rs +++ b/src/prepare.rs @@ -6,7 +6,7 @@ use bitcoin_circle_stark::precomputed_merkle_tree::PrecomputedMerkleTree; use bitcoin_circle_stark::treepp::pushable::{Builder, Pushable}; use itertools::Itertools; use std::iter::zip; -use stwo_prover::core::vcs::bws_sha256_merkle::BWSSha256MerkleHasher; +use stwo_prover::core::vcs::sha256_merkle::Sha256MerkleHasher; use stwo_prover::core::{ backend::cpu::quotients::{batch_random_coeffs, denominator_inverses}, constraints::complex_conjugate_line_coeffs_normalized, @@ -53,7 +53,7 @@ pub struct PrepareOutput { /// prepare output for quotients and verifier hints pub fn compute_prepare_hints( fs_output: &FiatShamirOutput, - proof: &StarkProof, + proof: &StarkProof, ) -> Result<(PrepareOutput, PrepareHints), VerificationError> { let column_size: Vec = fs_output .commitment_scheme_column_log_sizes diff --git a/src/split/mod.rs b/src/split/mod.rs index 2f4d8b8..834d313 100644 --- a/src/split/mod.rs +++ b/src/split/mod.rs @@ -16,13 +16,13 @@ use covenants_gadgets::CovenantProgram; use sha2::digest::Update; use sha2::{Digest, Sha256}; use std::collections::BTreeMap; -use stwo_prover::core::channel::{BWSSha256Channel, Channel}; +use stwo_prover::core::channel::Sha256Channel; use stwo_prover::core::fields::{ m31::{BaseField, M31}, IntoSlice, }; use stwo_prover::core::prover::N_QUERIES; -use stwo_prover::core::vcs::bws_sha256_hash::BWSSha256Hasher; +use stwo_prover::core::vcs::sha256_hash::Sha256Hasher; /// The state of the Fibonacci split program. #[derive(Clone, Debug)] @@ -106,9 +106,10 @@ impl CovenantProgram for FibonacciSplitProgram { } fn get_all_scripts() -> BTreeMap { - let channel = BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[ - M31::reduce(443693538), - ]))); + let mut channel = Sha256Channel::default(); + channel.update_digest(Sha256Hasher::hash(BaseField::into_slice(&[M31::reduce( + 443693538, + )]))); let mut map = BTreeMap::new(); map.insert( @@ -338,9 +339,10 @@ impl CovenantProgram for FibonacciSplitProgram { _ => unreachable!(), }; - let channel = BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[ - M31::reduce(443693538), - ]))); + let mut channel = Sha256Channel::default(); + channel.update_digest(Sha256Hasher::hash(BaseField::into_slice(&[M31::reduce( + 443693538, + )]))); let script = script! { { FibonacciFiatShamirGadget::run(&channel) } @@ -432,32 +434,37 @@ mod test { use std::cell::RefCell; use std::ops::AddAssign; use std::rc::Rc; - use stwo_prover::core::channel::{BWSSha256Channel, Channel}; + use stwo_prover::core::channel::Sha256Channel; use stwo_prover::core::fields::m31::{BaseField, M31}; use stwo_prover::core::fields::IntoSlice; - use stwo_prover::core::vcs::bws_sha256_hash::BWSSha256Hasher; + use stwo_prover::core::pcs::PcsConfig; + use stwo_prover::core::vcs::sha256_hash::Sha256Hasher; + use stwo_prover::core::vcs::sha256_merkle::Sha256MerkleChannel; use stwo_prover::examples::fibonacci::Fibonacci; use stwo_prover::trace_generation::commit_and_prove; #[test] fn test_integration() { let mut prng = ChaCha20Rng::seed_from_u64(0); + let config = PcsConfig::default(); let fib = Fibonacci::new(FIB_LOG_SIZE, M31::reduce(443693538)); let trace = fib.get_trace(); - let channel = - &mut BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[fib - .air - .component - .claim]))); - let proof = commit_and_prove(&fib.air, channel, vec![trace]).unwrap(); - - let channel = - &mut BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[fib - .air - .component - .claim]))); + let channel = &mut Sha256Channel::default(); + channel.update_digest(Sha256Hasher::hash(BaseField::into_slice(&[fib + .air + .component + .claim]))); + let proof = + commit_and_prove::<_, Sha256MerkleChannel>(&fib.air, channel, vec![trace], config) + .unwrap(); + + let channel = &mut Sha256Channel::default(); + channel.update_digest(Sha256Hasher::hash(BaseField::into_slice(&[fib + .air + .component + .claim]))); let (fiat_shamir_output, fiat_shamir_hints) = compute_fiat_shamir_hints(proof.clone(), channel, &fib.air).unwrap();