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
18 changes: 17 additions & 1 deletion crates/core/executor/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ pub struct ZKMContext<'a> {

/// The maximum number of cpu cycles to use for execution.
pub max_cycles: Option<u64>,

/// Skip deferred proof verification.
pub skip_deferred_proof_verification: bool,
}

/// A builder for [`ZKMContext`].
Expand All @@ -30,6 +33,7 @@ pub struct ZKMContextBuilder<'a> {
hook_registry_entries: Vec<(u32, BoxedHook<'a>)>,
subproof_verifier: Option<&'a dyn SubproofVerifier>,
max_cycles: Option<u64>,
skip_deferred_proof_verification: bool,
}

impl<'a> ZKMContext<'a> {
Expand Down Expand Up @@ -68,7 +72,13 @@ impl<'a> ZKMContextBuilder<'a> {
});
let subproof_verifier = take(&mut self.subproof_verifier);
let cycle_limit = take(&mut self.max_cycles);
ZKMContext { hook_registry, subproof_verifier, max_cycles: cycle_limit }
let skip_deferred_proof_verification = take(&mut self.skip_deferred_proof_verification);
ZKMContext {
hook_registry,
subproof_verifier,
max_cycles: cycle_limit,
skip_deferred_proof_verification,
}
}

/// Add a runtime [Hook](super::Hook) into the context.
Expand Down Expand Up @@ -107,6 +117,12 @@ impl<'a> ZKMContextBuilder<'a> {
self.max_cycles = Some(max_cycles);
self
}

/// Set the skip deferred proof verification flag.
pub fn set_skip_deferred_proof_verification(&mut self, skip: bool) -> &mut Self {
self.skip_deferred_proof_verification = skip;
self
}
}

#[cfg(test)]
Expand Down
21 changes: 21 additions & 0 deletions crates/core/executor/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ pub const DEFAULT_PC_INC: u32 = 4;
/// A valid pc should be divisible by 4, so we use 1 to indicate that the pc is not used.
pub const UNUSED_PC: u32 = 1;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
/// Whether to verify deferred proofs during execution.
pub enum DeferredProofVerification {
/// Verify deferred proofs during execution.
Enabled,
/// Skip verification of deferred proofs.
Disabled,
}

/// An executor for the MIPS zkVM.
///
/// The executor is responsible for executing a user program and tracing important events which
Expand Down Expand Up @@ -100,6 +109,10 @@ pub struct Executor<'a> {
/// The maximum number of cpu cycles to use for execution.
pub max_cycles: Option<u64>,

/// Skip deferred proof verification. This check is informational only, not related to circuit
/// correctness.
pub deferred_proof_verification: DeferredProofVerification,

/// The state of the execution.
pub state: ExecutionState,

Expand Down Expand Up @@ -327,6 +340,11 @@ impl<'a> Executor<'a> {
hook_registry,
opts,
max_cycles: context.max_cycles,
deferred_proof_verification: if context.skip_deferred_proof_verification {
DeferredProofVerification::Disabled
} else {
DeferredProofVerification::Enabled
},
memory_checkpoint: Memory::default(),
uninitialized_memory_checkpoint: Memory::default(),
local_memory_access: HashMap::new(),
Expand Down Expand Up @@ -363,6 +381,9 @@ impl<'a> Executor<'a> {
pub fn recover(program: Program, state: ExecutionState, opts: ZKMCoreOpts) -> Self {
let mut runtime = Self::new(program, opts);
runtime.state = state;
// Disable deferred proof verification since we're recovering from a checkpoint, and the
// checkpoint creator already had a chance to check the proofs.
runtime.deferred_proof_verification = DeferredProofVerification::Disabled;
runtime
}

Expand Down
8 changes: 6 additions & 2 deletions crates/core/executor/src/syscalls/verify.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::program::MAX_MEMORY;

use crate::ExecutionError;
use crate::{DeferredProofVerification, ExecutionError};

use super::{Syscall, SyscallCode, SyscallContext};

Expand All @@ -17,6 +17,10 @@ impl Syscall for VerifySyscall {
) -> Result<Option<u32>, ExecutionError> {
let rt = &mut ctx.rt;

if rt.deferred_proof_verification == DeferredProofVerification::Disabled {
return Ok(None);
}

// vkey_ptr is a pointer to [u32; 8] which contains the verification key.
// pv_digest_ptr is a pointer to [u32; 8] which contains the public values digest.

Expand All @@ -36,13 +40,13 @@ impl Syscall for VerifySyscall {
if proof_index >= rt.state.proof_stream.len() {
panic!("Not enough proofs were written to the runtime.");
}
let (proof, proof_vk) = &rt.state.proof_stream[proof_index];
rt.state.proof_stream_ptr += 1;

let vkey_bytes: [u32; 8] = vkey.try_into().unwrap();
let pv_digest_bytes: [u32; 8] = pv_digest.try_into().unwrap();

if let Some(verifier) = rt.subproof_verifier {
let (proof, proof_vk) = &rt.state.proof_stream[proof_index];
if let Err(e) =
verifier.verify_deferred_proof(proof, proof_vk, vkey_bytes, pv_digest_bytes)
{
Expand Down
12 changes: 12 additions & 0 deletions crates/sdk/src/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ impl<'a> Execute<'a> {
self.context_builder.max_cycles(max_cycles);
self
}

/// Skip deferred proof verification.
pub fn set_skip_deferred_proof_verification(mut self, value: bool) -> Self {
self.context_builder.set_skip_deferred_proof_verification(value);
self
}
}

/// Builder to prepare and configure proving execution of a program on an input.
Expand Down Expand Up @@ -221,4 +227,10 @@ impl<'a> Prove<'a> {
self.timeout = Some(timeout);
self
}

/// Set the skip deferred proof verification flag.
pub fn set_skip_deferred_proof_verification(mut self, value: bool) -> Self {
self.context_builder.set_skip_deferred_proof_verification(value);
self
}
}