Skip to content
Closed
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
1 change: 1 addition & 0 deletions Cargo.lock

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

11 changes: 11 additions & 0 deletions crates/core/executor/src/minimal.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#![allow(clippy::items_after_statements)]
use std::sync::Arc;

use sp1_primitives::consts::PV_DIGEST_NUM_WORDS;

use crate::{Program, SupervisorMode, UserMode};
pub use arch::*;
pub use postprocess::chunked_memory_init_events;
Expand Down Expand Up @@ -148,6 +150,15 @@ impl MinimalExecutorEnum {
}
}

/// Calls `public_value_digest` on the active `MinimalExecutor`.
#[must_use]
pub fn public_value_digest(&self) -> &[u32; PV_DIGEST_NUM_WORDS] {
match self {
Self::Supervisor(e) => e.public_value_digest(),
Self::User(e) => e.public_value_digest(),
}
}

/// Calls `into_public_values_stream` to respective `MinimalExecutor`.
#[must_use]
pub fn into_public_values_stream(self) -> Vec<u8> {
Expand Down
16 changes: 15 additions & 1 deletion crates/core/executor/src/minimal/arch/portable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use sp1_jit::{
};
use sp1_primitives::consts::{
LOG_PAGE_SIZE, PROT_EXEC, PROT_FAILURE_EXEC, PROT_FAILURE_READ, PROT_FAILURE_WRITE, PROT_READ,
PROT_WRITE,
PROT_WRITE, PV_DIGEST_NUM_WORDS,
};

use std::{
Expand Down Expand Up @@ -63,6 +63,7 @@ pub struct MinimalExecutor<M: ExecutionMode> {
exit_code: u32,
max_trace_size: Option<u64>,
public_values_stream: Vec<u8>,
public_value_digest: [u32; PV_DIGEST_NUM_WORDS],
hints: Vec<(u64, Vec<u8>)>,
maybe_unconstrained: Option<UnconstrainedCtx>,
debug_sender: Option<mpsc::SyncSender<Option<debug::State>>>,
Expand Down Expand Up @@ -254,6 +255,12 @@ impl<M: ExecutionMode> SyscallContext for MinimalExecutor<M> {
&mut self.public_values_stream
}

fn commit_public_value_digest_word(&mut self, word_idx: usize, word: u32) {
if let Some(slot) = self.public_value_digest.get_mut(word_idx) {
*slot = word;
}
}

fn enter_unconstrained(&mut self) -> io::Result<()> {
assert!(
self.maybe_unconstrained.is_none(),
Expand Down Expand Up @@ -439,6 +446,7 @@ impl<M: ExecutionMode> MinimalExecutor<M> {
traces: None,
max_trace_size,
public_values_stream: Vec::new(),
public_value_digest: [0; PV_DIGEST_NUM_WORDS],
hints: Vec::new(),
maybe_unconstrained: None,
debug_sender: None,
Expand Down Expand Up @@ -580,6 +588,12 @@ impl<M: ExecutionMode> MinimalExecutor<M> {
&self.public_values_stream
}

/// Get the public-value digest committed by the guest.
#[must_use]
pub fn public_value_digest(&self) -> &[u32; PV_DIGEST_NUM_WORDS] {
&self.public_value_digest
}

/// Consume self, and return the public values stream.
#[must_use]
pub fn into_public_values_stream(self) -> Vec<u8> {
Expand Down
7 changes: 7 additions & 0 deletions crates/core/executor/src/minimal/arch/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use sp1_jit::{
debug, memory::AnonymousMemory, trace_capacity, DebugBackend, JitFunction, JitMemory, MemValue,
RiscOperand, RiscRegister, RiscvTranspiler, TraceChunkHeader, TraceChunkRaw, TranspilerBackend,
};
use sp1_primitives::consts::PV_DIGEST_NUM_WORDS;
use std::marker::PhantomData;
use std::{
collections::VecDeque,
Expand Down Expand Up @@ -226,6 +227,12 @@ impl<M: ExecutionMode> MinimalExecutor<M> {
&self.compiled.public_values_stream
}

/// Get the public-value digest committed by the guest.
#[must_use]
pub fn public_value_digest(&self) -> &[u32; PV_DIGEST_NUM_WORDS] {
&self.compiled.public_value_digest
}

/// Consume self, and return the public values stream.
#[must_use]
pub fn into_public_values_stream(self) -> Vec<u8> {
Expand Down
11 changes: 8 additions & 3 deletions crates/core/executor/src/minimal/ecall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,13 @@ pub fn ecall_handler(ctx: &mut impl SyscallContext, code: SyscallCode) -> Result
ctx.set_exit_code(arg1 as u32);
Ok(None)
}
SyscallCode::COMMIT => {
// COMMIT passes the public-value digest word index in arg1 and the word in arg2.
if let (Ok(word_idx), Ok(digest_word)) = (usize::try_from(arg1), u32::try_from(arg2)) {
ctx.commit_public_value_digest_word(word_idx, digest_word);
}
Ok(None)
}
SyscallCode::MPROTECT => mprotect_syscall(ctx, arg1, arg2),
SyscallCode::HINT_MPROTECT_FLUSH => mprotect_flush_syscall(ctx, arg1, arg2),
SyscallCode::SIG_RETURN => sig_return_syscall(ctx, arg1, arg2),
Expand All @@ -178,9 +185,7 @@ pub fn ecall_handler(ctx: &mut impl SyscallContext, code: SyscallCode) -> Result
SyscallCode::DELETE_PROFILER_SYMBOLS => {
Ok(delete_profile_symbols_syscall(ctx, arg1, arg2))
}
SyscallCode::VERIFY_SP1_PROOF
| SyscallCode::COMMIT
| SyscallCode::COMMIT_DEFERRED_PROOFS => Ok(None),
SyscallCode::VERIFY_SP1_PROOF | SyscallCode::COMMIT_DEFERRED_PROOFS => Ok(None),
}
.map(|opt: Option<u64>| opt.unwrap_or(code as u64))
}
18 changes: 17 additions & 1 deletion crates/core/jit/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{debug, ElfInfo, Interrupt, MemValue, PageProtValue, RiscRegister, TraceChunkHeader};
use memmap2::{MmapMut, MmapOptions};
use sp1_primitives::consts::{PROT_READ, PROT_WRITE};
use sp1_primitives::consts::{PROT_READ, PROT_WRITE, PV_DIGEST_NUM_WORDS};
use std::{collections::VecDeque, io, os::fd::RawFd, ptr::NonNull, sync::mpsc};

pub trait SyscallContext {
Expand Down Expand Up @@ -64,6 +64,8 @@ pub trait SyscallContext {
fn input_buffer(&mut self) -> &mut VecDeque<Vec<u8>>;
/// Get the public values stream.
fn public_values_stream(&mut self) -> &mut Vec<u8>;
/// Commit one word of the public-value digest.
fn commit_public_value_digest_word(&mut self, word_idx: usize, word: u32);
/// Enter the unconstrained context.
fn enter_unconstrained(&mut self) -> io::Result<()>;
/// Exit the unconstrained context.
Expand Down Expand Up @@ -250,6 +252,12 @@ impl SyscallContext for JitContext {
unsafe { self.public_values_stream() }
}

fn commit_public_value_digest_word(&mut self, word_idx: usize, word: u32) {
if let Some(slot) = unsafe { self.public_value_digest() }.get_mut(word_idx) {
*slot = word;
}
}

fn enter_unconstrained(&mut self) -> io::Result<()> {
self.enter_unconstrained()
}
Expand Down Expand Up @@ -361,6 +369,8 @@ pub struct JitContext {
pub(crate) input_buffer: NonNull<VecDeque<Vec<u8>>>,
/// A stream of public values from the program (global to entire program).
pub(crate) public_values_stream: NonNull<Vec<u8>>,
/// The public-value digest words committed by the program.
pub(crate) public_value_digest: NonNull<[u32; PV_DIGEST_NUM_WORDS]>,
/// The hints read by the program, with their corresponding start address.
pub(crate) hints: NonNull<Vec<(u64, Vec<u8>)>>,
/// The memory file descriptor, this is used to create the COW memory at runtime.
Expand Down Expand Up @@ -481,6 +491,12 @@ impl JitContext {
self.public_values_stream.as_mut()
}

/// # Safety
/// - The public-value digest pointer must be non null and valid to write to.
pub const unsafe fn public_value_digest(&mut self) -> &mut [u32; PV_DIGEST_NUM_WORDS] {
self.public_value_digest.as_mut()
}

/// Obtain a view of the registers.
pub const fn registers(&self) -> &[u64; 32] {
&self.registers
Expand Down
6 changes: 6 additions & 0 deletions crates/core/jit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod shm;

use dynasmrt::ExecutableBuffer;
use hashbrown::HashMap;
use sp1_primitives::consts::PV_DIGEST_NUM_WORDS;
use std::{
collections::VecDeque,
io,
Expand Down Expand Up @@ -209,6 +210,8 @@ pub struct JitFunction<M> {

/// A stream of public values from the program (global to entire program).
pub public_values_stream: Vec<u8>,
/// The public-value digest words committed by the program.
pub public_value_digest: [u32; PV_DIGEST_NUM_WORDS],

/// Memory structure,
pub memory: M,
Expand Down Expand Up @@ -256,6 +259,7 @@ impl<M: JitMemory> JitFunction<M> {
input_buffer: VecDeque::new(),
hints: Vec::new(),
public_values_stream: Vec::new(),
public_value_digest: [0; PV_DIGEST_NUM_WORDS],
debug_sender: None,
exit_code: 0,
})
Expand Down Expand Up @@ -340,6 +344,7 @@ impl<M: JitMemory> JitFunction<M> {
hints: NonNull::new_unchecked(&mut self.hints),
maybe_unconstrained: None,
public_values_stream: NonNull::new_unchecked(&mut self.public_values_stream),
public_value_digest: NonNull::new_unchecked(&mut self.public_value_digest),
memory_fd: self.memory.as_raw_fd(),
registers: self.registers,
pc: self.pc,
Expand Down Expand Up @@ -400,6 +405,7 @@ impl<M: JitResetableMemory> JitFunction<M> {
self.input_buffer = VecDeque::new();
self.hints = Vec::new();
self.public_values_stream = Vec::new();
self.public_value_digest = [0; PV_DIGEST_NUM_WORDS];
self.memory.reset();

self.insert_memory_image();
Expand Down
1 change: 1 addition & 0 deletions crates/core/runner-binary/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ categories.workspace = true
[dependencies]
sp1-core-executor = { workspace = true }
sp1-jit = { workspace = true }
sp1-primitives = { workspace = true }

bincode = { workspace = true }
crash-handler = { workspace = true }
Expand Down
2 changes: 2 additions & 0 deletions crates/core/runner-binary/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use serde::{Deserialize, Serialize};
use sp1_core_executor::Program;
use sp1_primitives::consts::PV_DIGEST_NUM_WORDS;
use std::{collections::VecDeque, sync::Arc};

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand All @@ -17,6 +18,7 @@ pub struct Input {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Output {
pub public_values_stream: Vec<u8>,
pub public_value_digest: [u32; PV_DIGEST_NUM_WORDS],
pub hints: Vec<(u64, Vec<u8>)>,
pub global_clk: u64,
pub clk: u64,
Expand Down
1 change: 1 addition & 0 deletions crates/core/runner-binary/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ fn main() {

let output = Output {
public_values_stream: compiled.public_values_stream,
public_value_digest: compiled.public_value_digest,
hints: compiled.hints,
global_clk: compiled.global_clk,
clk: compiled.clk,
Expand Down
8 changes: 7 additions & 1 deletion crates/core/runner/src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use sp1_jit::{
shm::{ShmTraceRing, TraceResult},
trace_capacity, MemValue, MinimalTrace, TraceChunkRaw,
};
use sp1_primitives::consts::MAX_JIT_LOG_ADDR;
use sp1_primitives::consts::{MAX_JIT_LOG_ADDR, PV_DIGEST_NUM_WORDS};
use std::{
collections::VecDeque,
io::{BufRead, BufReader, BufWriter, Write},
Expand Down Expand Up @@ -325,6 +325,12 @@ impl MinimalExecutorRunner {
&self.output().public_values_stream
}

/// Get the public-value digest committed by the guest.
#[must_use]
pub fn public_value_digest(&self) -> &[u32; PV_DIGEST_NUM_WORDS] {
&self.output().public_value_digest
}

/// Consume self, and return the public values stream.
#[must_use]
pub fn into_public_values_stream(self) -> Vec<u8> {
Expand Down
8 changes: 8 additions & 0 deletions crates/core/runner/src/portable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use sp1_core_executor::{
ExecutionError, MinimalExecutorEnum, Program, UnsafeMemory, DEFAULT_MEMORY_LIMIT,
};
use sp1_jit::{MemValue, TraceChunkRaw};
use sp1_primitives::consts::PV_DIGEST_NUM_WORDS;
use std::sync::Arc;

/// Minimal trace portable executor that caps memory entries
Expand Down Expand Up @@ -154,6 +155,13 @@ impl MinimalExecutorRunner {
self.inner.public_values_stream()
}

/// Get the public-value digest committed by the guest.
#[must_use]
#[inline]
pub fn public_value_digest(&self) -> &[u32; PV_DIGEST_NUM_WORDS] {
self.inner.public_value_digest()
}

/// Consume self, and return the public values stream.
#[must_use]
#[inline]
Expand Down
4 changes: 1 addition & 3 deletions crates/hypercube/src/air/public_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use itertools::Itertools;
use serde::{Deserialize, Serialize};
use slop_algebra::{AbstractField, PrimeField32};
use sp1_primitives::consts::split_page_idx;
pub use sp1_primitives::consts::PV_DIGEST_NUM_WORDS;

use crate::{septic_curve::SepticCurve, septic_digest::SepticDigest, PROOF_MAX_NUM_PVS};

Expand All @@ -18,9 +19,6 @@ use crate::addr_to_limbs;
/// The number of non padded elements in the SP1 proofs public values vec.
pub const SP1_PROOF_NUM_PV_ELTS: usize = size_of::<PublicValues<[u8; 4], [u8; 3], [u8; 4], u8>>();

/// The number of 32 bit words in the SP1 proof's committed value digest.
pub const PV_DIGEST_NUM_WORDS: usize = 8;

/// The number of field elements in the poseidon2 digest.
pub const POSEIDON_NUM_WORDS: usize = 8;

Expand Down
3 changes: 3 additions & 0 deletions crates/primitives/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub const WORD_BYTE_SIZE: usize = 2 * WORD_SIZE;
/// The size of an instruction in bytes.
pub const INSTRUCTION_WORD_SIZE: usize = 4;

/// The number of 32-bit words in the SP1 proof's committed value digest.
pub const PV_DIGEST_NUM_WORDS: usize = 8;

/// The number of bytes necessary to represent a 128-bit integer.
pub const LONG_WORD_BYTE_SIZE: usize = 2 * WORD_BYTE_SIZE;

Expand Down
Loading
Loading