Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mithril-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
7 changes: 7 additions & 0 deletions mithril-stm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 1 addition & 4 deletions mithril-stm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 }
Expand All @@ -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",
Expand All @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -117,7 +119,7 @@ pub(crate) fn prove_blake2b_ivc(
public_inputs: &[NativeField],
random_generator: &mut (impl RngCore + CryptoRng),
) -> Vec<u8> {
prove_ivc_with_transcript::<blake2b_simd::State>(
prove_ivc_with_transcript::<Blake2b256>(
commitment_parameters,
proving_key,
ivc_circuit_data,
Expand Down Expand Up @@ -163,7 +165,7 @@ pub(crate) fn verify_prepare_blake2b_ivc(
proof: &[u8],
public_inputs: &[NativeField],
) -> DualMSM<PairingEngine> {
verify_prepare_ivc_with_transcript::<blake2b_simd::State>(
verify_prepare_ivc_with_transcript::<Blake2b256>(
verifying_key,
proof,
public_inputs,
Expand Down
9 changes: 5 additions & 4 deletions mithril-stm/src/circuits/test_utils/file_mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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"))
}

Expand Down
38 changes: 20 additions & 18 deletions mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -314,7 +314,7 @@ impl<R: RngCore + CryptoRng> IvcProver<R> {
protocol_message_preimage: &ProtocolMessagePreimage,
genesis_bootstrap: &IvcGenesisBootstrapInput,
rolling_state: Option<&IvcRollingState>,
) -> StmResult<(IvcProof<blake2b_simd::State>, Option<IvcRollingState>)> {
) -> StmResult<(IvcProof<Blake2b256>, Option<IvcRollingState>)> {
ensure_advanceable_rolling_state(rolling_state)?;

// `rolling_state = None` is the first certificate: bootstrap from genesis internally,
Expand Down Expand Up @@ -378,7 +378,7 @@ impl<R: RngCore + CryptoRng> IvcProver<R> {
None
};

let blake2b_bytes = IvcProof::<blake2b_simd::State>::prove_with_transcript(
let blake2b_bytes = IvcProof::<Blake2b256>::prove_with_transcript(
&self.ivc_setup.srs,
&self.ivc_setup.ivc_proving_key,
&circuit_data,
Expand Down Expand Up @@ -454,6 +454,8 @@ impl<R: RngCore + CryptoRng> IvcProver<R> {
#[cfg(test)]
mod tests {

use midnight_proofs::transcript::Blake2b256;

use crate::{
circuits::halo2_ivc::{
state::Global,
Expand Down Expand Up @@ -528,7 +530,7 @@ mod tests {
verification_context.combined_fixed_bases,
);

let proof = IvcProof::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
step_output.ivc_proof,
step_output.next_state,
step_output.next_accumulator,
Expand All @@ -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::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::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::<blake2b_simd::State>::from_bytes(&bytes)
.expect("deserialization should not fail");
let restored =
IvcProof::<Blake2b256>::from_bytes(&bytes).expect("deserialization should not fail");

assert_eq!(
bytes,
Expand All @@ -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::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
step_output.ivc_proof,
step_output.next_state,
step_output.next_accumulator,
Expand All @@ -584,7 +586,7 @@ mod tests {
let mut wrong_msg = STEP_OUTPUT_MSG;
wrong_msg[0] ^= 0xff;

let proof = IvcProof::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
step_output.ivc_proof,
step_output.next_state,
step_output.next_accumulator,
Expand Down Expand Up @@ -623,7 +625,7 @@ mod tests {
verification_context.combined_fixed_bases,
);

let proof = IvcProof::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
step_output.ivc_proof,
step_output.next_state,
step_output.next_accumulator,
Expand Down Expand Up @@ -652,7 +654,7 @@ mod tests {
let mid = tampered_bytes.len() / 2;
tampered_bytes[mid] ^= 0xff;

let proof = IvcProof::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
IvcProofBytes::new(tampered_bytes),
step_output.next_state,
step_output.next_accumulator,
Expand All @@ -676,7 +678,7 @@ mod tests {

step_output.next_state.message = MessageHash::ZERO;

let proof = IvcProof::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
step_output.ivc_proof,
step_output.next_state,
step_output.next_accumulator,
Expand All @@ -703,7 +705,7 @@ mod tests {
let tampered_msg = &[0u8; 32];
step_output.next_state.message = MessageHash::ZERO;

let proof = IvcProof::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
step_output.ivc_proof,
step_output.next_state,
step_output.next_accumulator,
Expand All @@ -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::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
step_output.ivc_proof,
same_epoch.next_state,
step_output.next_accumulator,
Expand All @@ -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::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
step_output.ivc_proof,
step_output.next_state,
same_epoch.next_accumulator,
Expand All @@ -775,14 +777,14 @@ mod tests {

#[test]
fn ivc_proof_verify_rejects_poseidon_proof_bytes() {
// Constructing an `IvcProof<blake2b_simd::State>` with Poseidon-transcript bytes
// Constructing an `IvcProof<Blake2b256>` 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::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
chain_state.ivc_proof,
chain_state.state,
chain_state.accumulator,
Expand Down Expand Up @@ -825,7 +827,7 @@ mod tests {
wrong_fixed_bases,
);

let proof = IvcProof::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
step_output.ivc_proof,
step_output.next_state,
step_output.next_accumulator,
Expand Down
6 changes: 4 additions & 2 deletions mithril-stm/src/protocol/aggregate_signature/clerk.rs
Original file line number Diff line number Diff line change
@@ -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::{
Expand Down Expand Up @@ -261,7 +263,7 @@ fn ivc_prover_input_preparation_and_prove<D: MembershipDigest>(
ivc_prover_setup: Arc<IvcSnarkProverSetup>,
certificate_verifying_key: NonRecursiveCircuitVerifyingKey,
) -> StmResult<(
IvcProof<blake2b_simd::State>,
IvcProof<Blake2b256>,
Option<AncillaryProverData>,
AncillaryVerifierData,
)> {
Expand Down
12 changes: 8 additions & 4 deletions mithril-stm/src/protocol/aggregate_signature/signature.rs
Original file line number Diff line number Diff line change
@@ -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::{
Expand Down Expand Up @@ -144,7 +146,7 @@ pub enum AggregateSignature<D: MembershipDigest> {

/// IVC SNARK proof system.
#[cfg(feature = "future_snark")]
IvcSnark(Box<IvcProof<blake2b_simd::State>>),
IvcSnark(Box<IvcProof<Blake2b256>>),

/// Concatenation proof system.
// The 'untagged' attribute is required for backward compatibility.
Expand Down Expand Up @@ -495,7 +497,7 @@ impl<D: MembershipDigest> AggregateSignature<D> {

/// If the aggregate signature is an IVC proof, return it.
#[cfg(feature = "future_snark")]
pub fn get_ivc_proof(&self) -> Option<&IvcProof<blake2b_simd::State>> {
pub fn get_ivc_proof(&self) -> Option<&IvcProof<Blake2b256>> {
match self {
AggregateSignature::IvcSnark(proof) => Some(proof),
AggregateSignature::Concatenation(_) => None,
Expand All @@ -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::{
Expand Down Expand Up @@ -550,7 +554,7 @@ mod tests {
context.certificate_verifying_key,
context.recursive_verifying_key,
));
let proof = IvcProof::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
step_output.ivc_proof,
step_output.next_state,
step_output.next_accumulator,
Expand Down Expand Up @@ -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::<blake2b_simd::State>::new(
let proof = IvcProof::<Blake2b256>::new(
step_output.ivc_proof,
step_output.next_state,
step_output.next_accumulator,
Expand Down