sp1-lib 6.3.1

SP1 zkVM library functions
Documentation
//! Syscalls for the SP1 zkVM.
//!
//! Documentation for these syscalls can be found in the zkVM entrypoint
//! `sp1_zkvm::syscalls` module.

pub mod bls12381;
pub mod bn254;

#[cfg(feature = "ecdsa")]
pub mod ecdsa;

pub mod ed25519;
pub mod io;
pub mod mprotect;
pub mod poseidon2;
pub mod secp256k1;
pub mod secp256r1;
pub mod unconstrained;
pub mod utils;

#[cfg(feature = "verify")]
pub mod verify;

/// Halts the zkVM with exit code 3, signalling that a prover-supplied hint
/// failed verification.
///
/// This exists to disambiguate hint-validation failures from regular Rust
/// panics (which use exit code 1). Patches should call this on any hint check
/// that would otherwise panic, so a malicious prover cannot forge a "panicked"
/// proof by feeding wrong hints.
///
/// Prefer the [`invalid_hint!`] macro when you have a diagnostic message
/// to attach.
#[inline(never)]
pub fn halt_invalid_hint() -> ! {
    unsafe { syscall_halt(3) }
}

/// Internal helper used by [`invalid_hint!`] — write a formatted diagnostic
/// to stderr (FD 2), then halt with exit code 3.
///
/// Kept out-of-line so the macro expansion stays small at every call site.
#[doc(hidden)]
#[cold]
#[inline(never)]
pub fn __invalid_hint_fmt(args: std::fmt::Arguments<'_>) -> ! {
    let msg = std::format!("invalid prover hint: {}\n", args);
    unsafe {
        syscall_write(2, msg.as_ptr(), msg.len());
    }
    halt_invalid_hint()
}

/// Halts the zkVM with exit code 3 (invalid prover hint), optionally writing
/// a formatted diagnostic to stderr first.
///
/// Format-arg syntax matches [`panic!`], but exit code 3 disambiguates
/// hint-validation failures from regular panics (exit code 1) — a malicious
/// prover cannot forge a panicked-program proof by feeding wrong hints.
/// Patches should reach for this on any hint check that would otherwise panic.
///
/// ```ignore
/// sp1_lib::invalid_hint!();                                    // no message
/// sp1_lib::invalid_hint!("Fp inverse hint mismatch");
/// sp1_lib::invalid_hint!("expected {} bytes, got {}", expected, got);
/// ```
#[macro_export]
macro_rules! invalid_hint {
    () => {{
        $crate::halt_invalid_hint()
    }};
    ($($arg:tt)*) => {{
        $crate::__invalid_hint_fmt(::core::format_args!($($arg)*))
    }};
}

extern "C" {
    /// Halts the program with the given exit code.
    pub fn syscall_halt(exit_code: u8) -> !;

    /// Writes the bytes in the given buffer to the given file descriptor.
    pub fn syscall_write(fd: u32, write_buf: *const u8, nbytes: usize);

    /// Reads the bytes from the given file descriptor into the given buffer.
    pub fn syscall_read(fd: u32, read_buf: *mut u8, nbytes: usize);

    /// Executes the SHA-256 extend operation on the given word array.
    pub fn syscall_sha256_extend(w: *mut [u64; 64]);

    /// Executes the SHA-256 compress operation on the given word array and a given state.
    pub fn syscall_sha256_compress(w: *mut [u64; 64], state: *mut [u64; 8]);

    /// Executes an Ed25519 curve addition on the given points.
    pub fn syscall_ed_add(p: *mut [u64; 8], q: *const [u64; 8]);

    /// Executes an Ed25519 curve decompression on the given point.
    pub fn syscall_ed_decompress(point: &mut [u64; 8]);

    /// Executes an Sepc256k1 curve addition on the given points.
    pub fn syscall_secp256k1_add(p: *mut [u64; 8], q: *const [u64; 8]);

    /// Executes an Secp256k1 curve doubling on the given point.
    pub fn syscall_secp256k1_double(p: *mut [u64; 8]);

    /// Executes an Secp256k1 curve decompression on the given point.
    pub fn syscall_secp256k1_decompress(point: &mut [u64; 8], is_odd: bool);

    /// Executes an Secp256r1 curve addition on the given points.
    pub fn syscall_secp256r1_add(p: *mut [u64; 8], q: *const [u64; 8]);

    /// Executes an Secp256r1 curve doubling on the given point.
    pub fn syscall_secp256r1_double(p: *mut [u64; 8]);

    /// Executes an Secp256r1 curve decompression on the given point.
    pub fn syscall_secp256r1_decompress(point: &mut [u64; 8], is_odd: bool);

    /// Executes a Bn254 curve addition on the given points.
    pub fn syscall_bn254_add(p: *mut [u64; 8], q: *const [u64; 8]);

    /// Executes a Bn254 curve doubling on the given point.
    pub fn syscall_bn254_double(p: *mut [u64; 8]);

    /// Executes a BLS12-381 curve addition on the given points.
    pub fn syscall_bls12381_add(p: *mut [u64; 12], q: *const [u64; 12]);

    /// Executes a BLS12-381 curve doubling on the given point.
    pub fn syscall_bls12381_double(p: *mut [u64; 12]);

    /// Executes the Keccak-256 permutation on the given state.
    pub fn syscall_keccak_permute(state: *mut [u64; 25]);

    /// Executes an uint256 multiplication on the given inputs.
    pub fn syscall_uint256_mulmod(x: *mut [u64; 4], y: *const [u64; 4]);

    /// Executes a 256-bit by 2048-bit multiplication on the given inputs.
    pub fn syscall_u256x2048_mul(
        x: *const [u64; 4],
        y: *const [u64; 32],
        lo: *mut [u64; 32],
        hi: *mut [u64; 4],
    );

    /// Executes Uint256 addition operation with carry.
    pub fn syscall_uint256_add_with_carry(
        a: *const [u64; 4],
        b: *const [u64; 4],
        c: *const [u64; 4],
        d: *mut [u64; 4],
        e: *mut [u64; 4],
    );

    /// Executes Uint256 multiplication operation with carry.
    pub fn syscall_uint256_mul_with_carry(
        a: *const [u64; 4],
        b: *const [u64; 4],
        c: *const [u64; 4],
        d: *mut [u64; 4],
        e: *mut [u64; 4],
    );

    /// Enters unconstrained mode.
    pub fn syscall_enter_unconstrained() -> bool;

    /// Exits unconstrained mode.
    pub fn syscall_exit_unconstrained();

    /// Defers the verification of a valid SP1 zkVM proof.
    pub fn syscall_verify_sp1_proof(vk_digest: &[u64; 4], pv_digest: &[u64; 4]);

    /// Returns the length of the next element in the hint stream.
    pub fn syscall_hint_len() -> usize;

    /// Reads the next element in the hint stream into the given buffer.
    pub fn syscall_hint_read(ptr: *mut u8, len: usize);

    /// Allocates a buffer aligned to the given alignment.
    pub fn sys_alloc_aligned(bytes: usize, align: usize) -> *mut u8;

    /// Decompresses a BLS12-381 point.
    pub fn syscall_bls12381_decompress(point: &mut [u64; 12], is_odd: bool);

    /// Computes a big integer operation with a modulus.
    pub fn sys_bigint(
        result: *mut [u64; 4],
        op: u64,
        x: *const [u64; 4],
        y: *const [u64; 4],
        modulus: *const [u64; 4],
    );

    /// Executes a BLS12-381 field addition on the given inputs.
    pub fn syscall_bls12381_fp_addmod(p: *mut u64, q: *const u64);

    /// Executes a BLS12-381 field subtraction on the given inputs.
    pub fn syscall_bls12381_fp_submod(p: *mut u64, q: *const u64);

    /// Executes a BLS12-381 field multiplication on the given inputs.
    pub fn syscall_bls12381_fp_mulmod(p: *mut u64, q: *const u64);

    /// Executes a BLS12-381 Fp2 addition on the given inputs.
    pub fn syscall_bls12381_fp2_addmod(p: *mut u64, q: *const u64);

    /// Executes a BLS12-381 Fp2 subtraction on the given inputs.
    pub fn syscall_bls12381_fp2_submod(p: *mut u64, q: *const u64);

    /// Executes a BLS12-381 Fp2 multiplication on the given inputs.
    pub fn syscall_bls12381_fp2_mulmod(p: *mut u64, q: *const u64);

    /// Executes a BN254 field addition on the given inputs.
    pub fn syscall_bn254_fp_addmod(p: *mut u64, q: *const u64);

    /// Executes a BN254 field subtraction on the given inputs.
    pub fn syscall_bn254_fp_submod(p: *mut u64, q: *const u64);

    /// Executes a BN254 field multiplication on the given inputs.
    pub fn syscall_bn254_fp_mulmod(p: *mut u64, q: *const u64);

    /// Executes a BN254 Fp2 addition on the given inputs.
    pub fn syscall_bn254_fp2_addmod(p: *mut u64, q: *const u64);

    /// Executes a BN254 Fp2 subtraction on the given inputs.
    pub fn syscall_bn254_fp2_submod(p: *mut u64, q: *const u64);

    /// Executes a BN254 Fp2 multiplication on the given inputs.
    pub fn syscall_bn254_fp2_mulmod(p: *mut u64, q: *const u64);

    /// Executes the mprotect syscall.
    pub fn syscall_mprotect(addr: *const u8, prot: u8);

    /// Flushes all pending mprotect changes.
    pub fn syscall_mprotect_flush();

    /// Reads a buffer from the input stream.
    pub fn read_vec_raw() -> ReadVecResult;

    /// Executes the Poseidon2 permutation on the given state buffer in-place.
    pub fn syscall_poseidon2(inout: &mut crate::poseidon2::Poseidon2State);
}

#[repr(C)]
pub struct ReadVecResult {
    pub ptr: *mut u8,
    pub len: usize,
    pub capacity: usize,
}