diff --git a/Cargo.lock b/Cargo.lock index ebd14c31957..3d0e5685239 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4816,11 +4816,10 @@ dependencies = [ [[package]] name = "mithril-stm" -version = "0.11.0" +version = "0.11.1" dependencies = [ "anyhow", "blake2 0.10.6", - "blake2b_simd", "blst", "ciborium", "criterion", diff --git a/mithril-common/Cargo.toml b/mithril-common/Cargo.toml index 2e5b04d3b1a..2f55f725e43 100644 --- a/mithril-common/Cargo.toml +++ b/mithril-common/Cargo.toml @@ -46,7 +46,7 @@ fixed = "1.31.0" hex = { workspace = true } kes-summed-ed25519 = { version = "0.2.1", features = ["serde_enabled", "sk_clone_enabled"] } mithril-merkle-tree = { path = "../internal/mithril-merkle-tree", version = "0.1.4" } -mithril-stm = { path = "../mithril-stm", version = "0.11.0", default-features = false } +mithril-stm = { path = "../mithril-stm", version = "0.11.1", default-features = false } nom = "8.0.0" rand_chacha = { workspace = true } rand_core = { workspace = true } diff --git a/mithril-stm/CHANGELOG.md b/mithril-stm/CHANGELOG.md index 8c7665a7f60..60c20cddf8f 100644 --- a/mithril-stm/CHANGELOG.md +++ b/mithril-stm/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.11.1 (07-20-2026) + +### Changed + +- Updated the transcript hash function for the recursive circuit from `Blake2b512` to the Plutus friendly `Blake2b256` +- Removed `blake2b_simd` dependency to use the `Blake2b256` transcript hash from `midnight-proofs` + ## 0.11.0 (07-16-2026) ### Changed diff --git a/mithril-stm/Cargo.toml b/mithril-stm/Cargo.toml index 0a907c436e5..c286e026459 100644 --- a/mithril-stm/Cargo.toml +++ b/mithril-stm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-stm" -version = "0.11.0" +version = "0.11.1" edition = { workspace = true } authors = { workspace = true } homepage = { workspace = true } @@ -19,7 +19,6 @@ default = ["num-integer-backend"] benchmark-internals = [] # Enable experimental SNARK support future_snark = [ - "dep:blake2b_simd", "dep:ff", "dep:group", "dep:midnight-circuits", @@ -45,7 +44,6 @@ rug-backend = ["rug/default"] [dependencies] anyhow = { workspace = true } blake2 = "0.10.6" -blake2b_simd = { version = "1.0.4", optional = true } # Enforce blst portable feature for runtime detection of Intel ADX instruction set. blst = { version = "0.3.16", features = ["portable"] } ciborium = "0.2.2" @@ -85,7 +83,6 @@ num-traits = { version = "0.2.19", optional = true } rug = { version = "1.30.0", optional = true } [dev-dependencies] -blake2b_simd = "1.0.4" criterion = { version = "0.8.2", features = ["html_reports"] } fs2 = "0.4.3" httpmock = "0.8.3" diff --git a/mithril-stm/src/circuits/halo2_ivc/tests/assets/first_step_cert.bin b/mithril-stm/src/circuits/halo2_ivc/tests/assets/first_step_cert.bin index 2338215b463..aca69b0d696 100644 Binary files a/mithril-stm/src/circuits/halo2_ivc/tests/assets/first_step_cert.bin and b/mithril-stm/src/circuits/halo2_ivc/tests/assets/first_step_cert.bin differ diff --git a/mithril-stm/src/circuits/halo2_ivc/tests/assets/genesis_step_output.bin b/mithril-stm/src/circuits/halo2_ivc/tests/assets/genesis_step_output.bin index 17c9bd77525..6b221c963d2 100644 Binary files a/mithril-stm/src/circuits/halo2_ivc/tests/assets/genesis_step_output.bin and b/mithril-stm/src/circuits/halo2_ivc/tests/assets/genesis_step_output.bin differ diff --git a/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_chain_state.bin b/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_chain_state.bin index cc03d62884a..0850bcec11e 100644 Binary files a/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_chain_state.bin and b/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_chain_state.bin differ diff --git a/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_proof_accumulator_bytes.bin b/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_proof_accumulator_bytes.bin index 34d40349478..9d8e88100c6 100644 Binary files a/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_proof_accumulator_bytes.bin and b/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_proof_accumulator_bytes.bin differ diff --git a/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_step_output.bin b/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_step_output.bin index 30878292f6e..1fd65ae13ed 100644 Binary files a/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_step_output.bin and b/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_step_output.bin differ diff --git a/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_step_output_accumulator_bytes.bin b/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_step_output_accumulator_bytes.bin index a3774bc0adc..51d6901bf48 100644 Binary files a/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_step_output_accumulator_bytes.bin and b/mithril-stm/src/circuits/halo2_ivc/tests/assets/recursive_step_output_accumulator_bytes.bin differ diff --git a/mithril-stm/src/circuits/halo2_ivc/tests/assets/same_epoch_step_output.bin b/mithril-stm/src/circuits/halo2_ivc/tests/assets/same_epoch_step_output.bin index 8e6a9fa20bc..cbd3b6135c5 100644 Binary files a/mithril-stm/src/circuits/halo2_ivc/tests/assets/same_epoch_step_output.bin and b/mithril-stm/src/circuits/halo2_ivc/tests/assets/same_epoch_step_output.bin differ diff --git a/mithril-stm/src/circuits/halo2_ivc/tests/common/generators/proofs.rs b/mithril-stm/src/circuits/halo2_ivc/tests/common/generators/proofs.rs index 0a6b33c2f6d..78bea6941c7 100644 --- a/mithril-stm/src/circuits/halo2_ivc/tests/common/generators/proofs.rs +++ b/mithril-stm/src/circuits/halo2_ivc/tests/common/generators/proofs.rs @@ -6,9 +6,11 @@ use midnight_circuits::hash::poseidon::PoseidonState; use midnight_curves::Bls12; use midnight_proofs::{ plonk::{create_proof, prepare}, - poly::commitment::PolynomialCommitmentScheme, - poly::kzg::{KZGCommitmentScheme, msm::DualMSM, params::ParamsKZG}, - transcript::{CircuitTranscript, Hashable, Sampleable, Transcript, TranscriptHash}, + poly::{ + commitment::PolynomialCommitmentScheme, + kzg::{KZGCommitmentScheme, msm::DualMSM, params::ParamsKZG}, + }, + transcript::{Blake2b256, CircuitTranscript, Hashable, Sampleable, Transcript, TranscriptHash}, }; use rand_core::{CryptoRng, RngCore}; @@ -117,7 +119,7 @@ pub(crate) fn prove_blake2b_ivc( public_inputs: &[NativeField], random_generator: &mut (impl RngCore + CryptoRng), ) -> Vec { - prove_ivc_with_transcript::( + prove_ivc_with_transcript::( commitment_parameters, proving_key, ivc_circuit_data, @@ -163,7 +165,7 @@ pub(crate) fn verify_prepare_blake2b_ivc( proof: &[u8], public_inputs: &[NativeField], ) -> DualMSM { - verify_prepare_ivc_with_transcript::( + verify_prepare_ivc_with_transcript::( verifying_key, proof, public_inputs, diff --git a/mithril-stm/src/circuits/test_utils/file_mutex.rs b/mithril-stm/src/circuits/test_utils/file_mutex.rs index aa66b293d51..0edf1b656fd 100644 --- a/mithril-stm/src/circuits/test_utils/file_mutex.rs +++ b/mithril-stm/src/circuits/test_utils/file_mutex.rs @@ -14,8 +14,8 @@ use std::{ path::{Path, PathBuf}, }; -use blake2b_simd::Params as Blake2bParams; use fs2::FileExt; +use sha2::{Digest, Sha256}; use crate::StmResult; @@ -59,13 +59,14 @@ impl FileMutex { /// guarded artifacts under [`Self::directory`]. The length prefix on each input keeps the /// concatenation unambiguous. pub(crate) fn for_shared_cache(label: &str, fingerprint: &[&[u8]]) -> Self { - let mut hasher = Blake2bParams::new().hash_length(16).to_state(); + let mut hasher = Sha256::new(); hasher.update(CACHE_SCHEMA_VERSION); for input in fingerprint { - hasher.update(&(input.len() as u64).to_le_bytes()); + hasher.update((input.len() as u64).to_le_bytes()); hasher.update(input); } - let directory = shared_cache_root().join(format!("{label}-{}", hasher.finalize().to_hex())); + let directory = + shared_cache_root().join(format!("{label}-{}", hex::encode(hasher.finalize()))); Self::new(directory.join(".lock")) } diff --git a/mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs b/mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs index d700c84ff0b..025f460808f 100644 --- a/mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs +++ b/mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs @@ -17,7 +17,7 @@ use midnight_proofs::{ commitment::PolynomialCommitmentScheme, kzg::{KZGCommitmentScheme, params::ParamsKZG}, }, - transcript::{CircuitTranscript, Hashable, Sampleable, Transcript, TranscriptHash}, + transcript::{Blake2b256, CircuitTranscript, Hashable, Sampleable, Transcript, TranscriptHash}, }; use rand_core::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; @@ -314,7 +314,7 @@ impl IvcProver { protocol_message_preimage: &ProtocolMessagePreimage, genesis_bootstrap: &IvcGenesisBootstrapInput, rolling_state: Option<&IvcRollingState>, - ) -> StmResult<(IvcProof, Option)> { + ) -> StmResult<(IvcProof, Option)> { ensure_advanceable_rolling_state(rolling_state)?; // `rolling_state = None` is the first certificate: bootstrap from genesis internally, @@ -378,7 +378,7 @@ impl IvcProver { None }; - let blake2b_bytes = IvcProof::::prove_with_transcript( + let blake2b_bytes = IvcProof::::prove_with_transcript( &self.ivc_setup.srs, &self.ivc_setup.ivc_proving_key, &circuit_data, @@ -454,6 +454,8 @@ impl IvcProver { #[cfg(test)] mod tests { + use midnight_proofs::transcript::Blake2b256; + use crate::{ circuits::halo2_ivc::{ state::Global, @@ -528,7 +530,7 @@ mod tests { verification_context.combined_fixed_bases, ); - let proof = IvcProof::::new( + let proof = IvcProof::::new( step_output.ivc_proof, step_output.next_state, step_output.next_accumulator, @@ -544,15 +546,15 @@ mod tests { let step_output = load_embedded_next_epoch_step_output_asset() .expect("recursive step output asset should load"); - let proof = IvcProof::::new( + let proof = IvcProof::::new( step_output.ivc_proof, step_output.next_state, step_output.next_accumulator, ); let bytes = proof.to_bytes().expect("serialization should not fail"); - let restored = IvcProof::::from_bytes(&bytes) - .expect("deserialization should not fail"); + let restored = + IvcProof::::from_bytes(&bytes).expect("deserialization should not fail"); assert_eq!( bytes, @@ -565,7 +567,7 @@ mod tests { let step_output = load_embedded_next_epoch_step_output_asset() .expect("recursive step output asset should load"); - let proof = IvcProof::::new( + let proof = IvcProof::::new( step_output.ivc_proof, step_output.next_state, step_output.next_accumulator, @@ -584,7 +586,7 @@ mod tests { let mut wrong_msg = STEP_OUTPUT_MSG; wrong_msg[0] ^= 0xff; - let proof = IvcProof::::new( + let proof = IvcProof::::new( step_output.ivc_proof, step_output.next_state, step_output.next_accumulator, @@ -623,7 +625,7 @@ mod tests { verification_context.combined_fixed_bases, ); - let proof = IvcProof::::new( + let proof = IvcProof::::new( step_output.ivc_proof, step_output.next_state, step_output.next_accumulator, @@ -652,7 +654,7 @@ mod tests { let mid = tampered_bytes.len() / 2; tampered_bytes[mid] ^= 0xff; - let proof = IvcProof::::new( + let proof = IvcProof::::new( IvcProofBytes::new(tampered_bytes), step_output.next_state, step_output.next_accumulator, @@ -676,7 +678,7 @@ mod tests { step_output.next_state.message = MessageHash::ZERO; - let proof = IvcProof::::new( + let proof = IvcProof::::new( step_output.ivc_proof, step_output.next_state, step_output.next_accumulator, @@ -703,7 +705,7 @@ mod tests { let tampered_msg = &[0u8; 32]; step_output.next_state.message = MessageHash::ZERO; - let proof = IvcProof::::new( + let proof = IvcProof::::new( step_output.ivc_proof, step_output.next_state, step_output.next_accumulator, @@ -730,7 +732,7 @@ mod tests { let same_epoch = load_embedded_following_certificate_in_epoch_asset() .expect("same-epoch step output asset should load"); - let proof = IvcProof::::new( + let proof = IvcProof::::new( step_output.ivc_proof, same_epoch.next_state, step_output.next_accumulator, @@ -757,7 +759,7 @@ mod tests { let same_epoch = load_embedded_following_certificate_in_epoch_asset() .expect("same-epoch step output asset should load"); - let proof = IvcProof::::new( + let proof = IvcProof::::new( step_output.ivc_proof, step_output.next_state, same_epoch.next_accumulator, @@ -775,14 +777,14 @@ mod tests { #[test] fn ivc_proof_verify_rejects_poseidon_proof_bytes() { - // Constructing an `IvcProof` with Poseidon-transcript bytes + // Constructing an `IvcProof` with Poseidon-transcript bytes // and verifying it with the Blake2b path must fail: the two transcript formats // are not interchangeable. let (global, verifier_setup) = build_proof_verifier_context(); let chain_state = load_embedded_recursive_chain_state_asset() .expect("recursive chain state asset should load"); - let proof = IvcProof::::new( + let proof = IvcProof::::new( chain_state.ivc_proof, chain_state.state, chain_state.accumulator, @@ -825,7 +827,7 @@ mod tests { wrong_fixed_bases, ); - let proof = IvcProof::::new( + let proof = IvcProof::::new( step_output.ivc_proof, step_output.next_state, step_output.next_accumulator, diff --git a/mithril-stm/src/protocol/aggregate_signature/clerk.rs b/mithril-stm/src/protocol/aggregate_signature/clerk.rs index 810a9e57bb9..f117467f16f 100644 --- a/mithril-stm/src/protocol/aggregate_signature/clerk.rs +++ b/mithril-stm/src/protocol/aggregate_signature/clerk.rs @@ -1,11 +1,13 @@ -use anyhow::Context; use std::marker::PhantomData; #[cfg(feature = "future_snark")] use std::sync::Arc; +use anyhow::Context; #[cfg(feature = "future_snark")] use anyhow::anyhow; #[cfg(feature = "future_snark")] +use midnight_proofs::transcript::Blake2b256; +#[cfg(feature = "future_snark")] use rand_core::OsRng; use crate::{ @@ -261,7 +263,7 @@ fn ivc_prover_input_preparation_and_prove( ivc_prover_setup: Arc, certificate_verifying_key: NonRecursiveCircuitVerifyingKey, ) -> StmResult<( - IvcProof, + IvcProof, Option, AncillaryVerifierData, )> { diff --git a/mithril-stm/src/protocol/aggregate_signature/signature.rs b/mithril-stm/src/protocol/aggregate_signature/signature.rs index 19f5865e66d..06195fc0206 100644 --- a/mithril-stm/src/protocol/aggregate_signature/signature.rs +++ b/mithril-stm/src/protocol/aggregate_signature/signature.rs @@ -1,6 +1,8 @@ use std::{collections::HashMap, fmt::Display, hash::Hash, str::FromStr}; use anyhow::anyhow; +#[cfg(feature = "future_snark")] +use midnight_proofs::transcript::Blake2b256; use serde::{Deserialize, Serialize}; use crate::{ @@ -144,7 +146,7 @@ pub enum AggregateSignature { /// IVC SNARK proof system. #[cfg(feature = "future_snark")] - IvcSnark(Box>), + IvcSnark(Box>), /// Concatenation proof system. // The 'untagged' attribute is required for backward compatibility. @@ -495,7 +497,7 @@ impl AggregateSignature { /// If the aggregate signature is an IVC proof, return it. #[cfg(feature = "future_snark")] - pub fn get_ivc_proof(&self) -> Option<&IvcProof> { + pub fn get_ivc_proof(&self) -> Option<&IvcProof> { match self { AggregateSignature::IvcSnark(proof) => Some(proof), AggregateSignature::Concatenation(_) => None, @@ -510,6 +512,8 @@ mod tests { #[cfg(feature = "future_snark")] mod ivc_proof { + use midnight_proofs::transcript::Blake2b256; + use crate::{Clerk, Parameters, protocol::aggregate_signature::tests::setup_equal_parties}; use crate::{ @@ -550,7 +554,7 @@ mod tests { context.certificate_verifying_key, context.recursive_verifying_key, )); - let proof = IvcProof::::new( + let proof = IvcProof::::new( step_output.ivc_proof, step_output.next_state, step_output.next_accumulator, @@ -583,7 +587,7 @@ mod tests { let clerk = Clerk::new_clerk_from_signer(&ps[0]); let avk = clerk.compute_aggregate_verification_key(); - let proof = IvcProof::::new( + let proof = IvcProof::::new( step_output.ivc_proof, step_output.next_state, step_output.next_accumulator,