Skip to content
Open
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Changelog
## v0.30.0 (Unreleased)

#### Changes

- [BREAKING] `verify`, `Verifier::verify`, and `Verifier::verify_partial` now borrow the proof and the claim instead of consuming them.
- [BREAKING] Renamed the `AdviceMutation::ExtendMap` field `other` to `map` and the `AdviceMutation::ExtendMerkleStore` field `infos` to `inner_nodes`.

## v0.29.0 (2026-08-04)

#### Changes
Expand Down
2 changes: 1 addition & 1 deletion benches/blake3-bench/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ pub fn prove_and_verify_once(fixture: &Blake3Fixture) {
stack_outputs,
);
Verifier::new()
.verify(proof, claim)
.verify(&proof, &claim)
.expect("failed to verify Blake3 benchmark proof");
}

Expand Down
19 changes: 6 additions & 13 deletions benches/synthetic-bench/benches/synthetic_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,6 @@ fn bench_one_scenario(
if axes.contains("verify") {
// Reuse a proof from the `prove` axis when it ran for this scenario. This keeps prove time
// out of the verify measurement without forcing an extra proof in all-axes runs.
let program_info = ProgramInfo::from(program.clone());
let (stack_outputs, proof) = cached_proof.borrow().clone().unwrap_or_else(|| {
let mut host = DefaultHost::default();
prove_sync(
Expand All @@ -365,19 +364,13 @@ fn bench_one_scenario(
)
.expect("prove for verify setup")
});
let claim = ExecutionClaim::from_program_info(
ProgramInfo::from(program.clone()),
StackInputs::default(),
stack_outputs,
);
group.bench_function("verify", |b| {
b.iter_batched(
|| (program_info.clone(), StackInputs::default(), stack_outputs, proof.clone()),
|(program_info, stack_inputs, stack_outputs, proof)| {
let claim = ExecutionClaim::from_program_info(
program_info,
stack_inputs,
stack_outputs,
);
black_box(Verifier::new().verify(proof, claim).expect("verify"));
},
BatchSize::SmallInput,
);
b.iter(|| black_box(Verifier::new().verify(&proof, &claim).expect("verify")));
});
}

Expand Down
2 changes: 1 addition & 1 deletion crates/precompiles/benches/precompiles_bench/support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,6 @@ pub fn verify_once(
stack_outputs,
);
Verifier::new()
.verify(proof, claim)
.verify(&proof, &claim)
.expect("failed to verify precompile benchmark proof");
}
4 changes: 2 additions & 2 deletions crates/test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,11 +696,11 @@ impl Test {
StackOutputs::new(&elements).expect("stack outputs should fit the VM stack");
let claim =
ExecutionClaim::from_program_info(program_info, stack_inputs, stack_outputs);
assert!(verify(proof, claim).is_err());
assert!(verify(&proof, &claim).is_err());
} else {
let claim =
ExecutionClaim::from_program_info(program_info, stack_inputs, stack_outputs);
let result = verify(proof, claim);
let result = verify(&proof, &claim);
assert!(result.is_ok(), "error: {result:?}");
}
}
Expand Down
6 changes: 3 additions & 3 deletions miden-vm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ assert_eq!(8, outputs.first().unwrap().as_canonical_u64());

To verify program execution, use `Verifier::new().verify(...)`. The verifier takes the following parameters:

- `proof: ExecutionProof` - the proof generated during program execution.
- `claim: ExecutionClaim` - the claimed program information, stack inputs, and stack outputs.
- `proof: &ExecutionProof` - the proof generated during program execution.
- `claim: &ExecutionClaim` - the claimed program information, stack inputs, and stack outputs.

Stack inputs are expected to be ordered as if they would be pushed onto the stack one by one. Thus, their expected order on the stack will be the reverse of the order in which they are provided, and the last value in the `stack_inputs` is expected to be the value at the top of the stack.

Expand Down Expand Up @@ -172,7 +172,7 @@ let claim = ExecutionClaim::from_program_info(
);

// Verify the execution claim.
match Verifier::new().verify(proof, claim) {
match Verifier::new().verify(&proof, &claim) {
Ok(_) => println!("Execution verified!"),
Err(err) => eprintln!("Verification failed: {err}"),
}
Expand Down
2 changes: 1 addition & 1 deletion miden-vm/src/cli/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl VerifyCmd {
let stack_outputs = outputs_data.stack_outputs().map_err(Report::msg)?;
let claim =
miden_vm::ExecutionClaim::from_program_info(program_info, stack_inputs, stack_outputs);
miden_vm::verify(proof, claim)
miden_vm::verify(&proof, &claim)
.into_diagnostic()
.wrap_err("Program failed verification!")?;

Expand Down
2 changes: 1 addition & 1 deletion miden-vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ pub mod internal;
///
/// Wire-backed deferred proofs are partial/delegable proof material and are rejected here; use
/// [`Verifier::verify_partial`] to verify and hydrate wire-backed partial proofs.
pub fn verify(proof: ExecutionProof, claim: ExecutionClaim) -> Result<u32, VerificationError> {
pub fn verify(proof: &ExecutionProof, claim: &ExecutionClaim) -> Result<u32, VerificationError> {
miden_verifier::verify(proof, claim)
}
20 changes: 10 additions & 10 deletions miden-vm/tests/integration/prove_verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn assert_prove_verify(

println!("Verifying proof...");
let claim = ExecutionClaim::from_program_info(program.into(), stack_inputs, stack_outputs);
let security_level = verify(proof, claim).expect("Verification failed");
let security_level = verify(&proof, &claim).expect("Verification failed");

println!("Verification successful! Security level: {security_level}");
}
Expand Down Expand Up @@ -338,7 +338,7 @@ mod fast_parallel {
// Verify the proof
let claim =
ExecutionClaim::from_program_info(program.into(), stack_inputs, fast_stack_outputs);
verify(proof, claim).expect("Verification failed");
verify(&proof, &claim).expect("Verification failed");
}

#[test]
Expand Down Expand Up @@ -368,7 +368,7 @@ mod fast_parallel {
.expect("prove_from_trace_sync failed");

let claim = ExecutionClaim::from_program_info(program.into(), stack_inputs, stack_outputs);
verify(proof, claim).expect("Verification failed");
verify(&proof, &claim).expect("Verification failed");
}

#[test]
Expand Down Expand Up @@ -401,7 +401,7 @@ mod fast_parallel {
assert_eq!(proof.deferred_proof().as_wire(), Some(&expected_wire));
let claim = ExecutionClaim::from_program_info(program.into(), stack_inputs, stack_outputs);
let (_, pending) = miden_verifier::Verifier::new()
.verify_partial(proof, claim)
.verify_partial(&proof, &claim)
.expect("partial verification failed");
assert_ne!(pending.root(), miden_core::deferred::TRUE_DIGEST);
let _state = pending.into_state();
Expand Down Expand Up @@ -463,18 +463,18 @@ fn prove_partial_fixture() -> (ExecutionClaim, ExecutionProof) {
fn test_partial_obligation_flow() {
// the default prover emits final deferred material: `verify` accepts it directly
let (claim, proof) = prove_fixture();
verify(proof, claim).expect("final verification should pass");
verify(&proof, &claim).expect("final verification should pass");

// a partial (wire-backed) package is refused by final verification...
let (claim, partial) = prove_partial_fixture();
assert!(matches!(
verify(partial.clone(), claim.clone()),
verify(&partial, &claim),
Err(VerificationError::UnsupportedDeferredProof)
));

// ...and verified by the partial path, which returns the linear obligation
let (_, pending) = Verifier::new()
.verify_partial(partial, claim)
.verify_partial(&partial, &claim)
.expect("partial verification should pass");
assert_eq!(pending.root(), miden_core::deferred::TRUE_DIGEST);
let _state = pending.into_state();
Expand Down Expand Up @@ -509,7 +509,7 @@ fn test_deferred_stark_proof_requires_exact_encoding_and_bound_root() {
.expect("Proving failed");
let claim = ExecutionClaim::from_program_info(program.into(), stack_inputs, stack_outputs);

verify(proof.clone(), claim.clone()).expect("untampered deferred proof should verify");
verify(&proof, &claim).expect("untampered deferred proof should verify");

// The proof encoding is exact: an otherwise-valid proof with a trailing byte is rejected.
let stark = proof.miden_proof();
Expand All @@ -519,12 +519,12 @@ fn test_deferred_stark_proof_requires_exact_encoding_and_bound_root() {
StarkProof::new(proof_bytes, stark.hash_fn()),
proof.deferred_proof().clone(),
);
verify(trailing, claim.clone()).expect_err("trailing proof bytes must be rejected");
verify(&trailing, &claim).expect_err("trailing proof bytes must be rejected");

// The deferred root is statement-bound: replacing it with TRUE must fail.
let tampered = ExecutionProof::new(
StarkProof::new(stark.bytes().to_vec(), stark.hash_fn()),
DeferredProof::empty(),
);
assert!(verify(tampered, claim).is_err());
assert!(verify(&tampered, &claim).is_err());
}
8 changes: 4 additions & 4 deletions processor/src/host/advice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,11 @@ impl AdviceProvider {
AdviceMutation::ExtendStack { stack } => {
self.extend_advice_stack(stack)?;
},
AdviceMutation::ExtendMap { other } => {
self.extend_map(&other)?;
AdviceMutation::ExtendMap { map } => {
self.extend_map(&map)?;
},
AdviceMutation::ExtendMerkleStore { infos } => {
self.extend_merkle_store(infos)?;
AdviceMutation::ExtendMerkleStore { inner_nodes } => {
self.extend_merkle_store(inner_nodes)?;
},
}
Ok(())
Expand Down
12 changes: 6 additions & 6 deletions processor/src/host/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,21 @@ pub use mast_forest_store::{LoadedMastForest, MastForestStore, MemMastForestStor
#[derive(Debug, PartialEq, Eq)]
pub enum AdviceMutation {
ExtendStack { stack: AdviceStack },
ExtendMap { other: AdviceMap },
ExtendMerkleStore { infos: Vec<InnerNodeInfo> },
ExtendMap { map: AdviceMap },
ExtendMerkleStore { inner_nodes: Vec<InnerNodeInfo> },
}

impl AdviceMutation {
pub fn extend_advice_stack(stack: AdviceStack) -> Self {
Self::ExtendStack { stack }
}

pub fn extend_map(other: AdviceMap) -> Self {
Self::ExtendMap { other }
pub fn extend_map(map: AdviceMap) -> Self {
Self::ExtendMap { map }
}

pub fn extend_merkle_store(infos: impl IntoIterator<Item = InnerNodeInfo>) -> Self {
Self::ExtendMerkleStore { infos: Vec::from_iter(infos) }
pub fn extend_merkle_store(inner_nodes: impl IntoIterator<Item = InnerNodeInfo>) -> Self {
Self::ExtendMerkleStore { inner_nodes: Vec::from_iter(inner_nodes) }
}
}
// HOST TRAIT
Expand Down
2 changes: 1 addition & 1 deletion verifier/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ While [Miden](../miden-vm) crate also contains verifier functionality, if a proj

## Usage

Use `verify(proof, claim)` to verify a final `ExecutionProof`. The `ExecutionClaim` contains the
Use `verify(&proof, &claim)` to verify a final `ExecutionProof`. The `ExecutionClaim` contains the
program information and public stack inputs and outputs. The function returns the proof's security
level, or a `VerificationError` if verification fails.

Expand Down
12 changes: 6 additions & 6 deletions verifier/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ impl Verifier {
/// public root.
pub fn verify(
&self,
proof: ExecutionProof,
claim: ExecutionClaim,
proof: &ExecutionProof,
claim: &ExecutionClaim,
) -> Result<u32, VerificationError> {
let miden_security_level = proof.security_level();
let (final_deferred_root, precompile_security_level) =
Expand Down Expand Up @@ -122,8 +122,8 @@ impl Verifier {
/// deferred root.
pub fn verify_partial(
&self,
proof: ExecutionProof,
claim: ExecutionClaim,
proof: &ExecutionProof,
claim: &ExecutionClaim,
) -> Result<(u32, Unsettled), VerificationError> {
let security_level = proof.security_level();
let deferred_state =
Expand Down Expand Up @@ -167,7 +167,7 @@ impl Unsettled {
/// - The provided proof does not prove a correct execution of the claim.
/// - The proof carries wire-backed deferred proof material, which is a partial/delegable form.
/// - The proof's STARK-backed deferred proof, if present, does not verify against its public root.
pub fn verify(proof: ExecutionProof, claim: ExecutionClaim) -> Result<u32, VerificationError> {
pub fn verify(proof: &ExecutionProof, claim: &ExecutionClaim) -> Result<u32, VerificationError> {
Verifier::default().verify(proof, claim)
}

Expand Down Expand Up @@ -212,7 +212,7 @@ fn stark_security_level(_proof: &StarkProof) -> u32 {
}

fn verify_stark(
claim: ExecutionClaim,
claim: &ExecutionClaim,
final_deferred_root: Word,
stark_proof: &StarkProof,
) -> Result<(), VerificationError> {
Expand Down
Loading