Skip to content

Commit

Permalink
Receipt now supports borsh serialization (risc0#2184)
Browse files Browse the repository at this point in the history
This supersedes risc0#2150

---------

Co-authored-by: Erce Can Bektüre <[email protected]>
Co-authored-by: Erce Can Bektüre <[email protected]>
  • Loading branch information
3 people authored Aug 5, 2024
1 parent 1e6ca46 commit fff6533
Show file tree
Hide file tree
Showing 15 changed files with 166 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ jobs:
run: cargo test -F $FEATURE -F prove --workspace --timings --no-run --exclude doc-test
- name: test workspace
run: cargo test -F $FEATURE -F prove --workspace --timings --exclude doc-test
- name: test borsh
run: cargo test -F $FEATURE -F prove -F borsh -p risc0-zkvm --lib -- borsh
- uses: actions/upload-artifact@v4
with:
name: cargo-timings-${{ matrix.os }}-${{ matrix.device }}
Expand Down
80 changes: 80 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions risc0/binfmt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }

[dependencies]
anyhow = { version = "1.0", default-features = false }
borsh = { version = "1.5.0", default-features = false, features = [
"derive",
], optional = true }
elf = { version = "0.7", default-features = false }
risc0-zkp = { workspace = true }
risc0-zkvm-platform = { workspace = true }
Expand All @@ -28,6 +31,7 @@ rustdoc-args = ["--cfg", "docsrs"]
all-features = true

[features]
borsh = ["dep:borsh", "risc0-zkp/borsh"]
default = ["std"]
std = [
"anyhow/std",
Expand Down
3 changes: 3 additions & 0 deletions risc0/binfmt/src/exit_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

use core::fmt;

#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};
use serde::{Deserialize, Serialize};

/// Exit condition indicated by the zkVM at the end of the guest execution.
Expand All @@ -25,6 +27,7 @@ use serde::{Deserialize, Serialize};
/// additional information (e.g. 0 to indicate success or 1 to indicate an
/// error).
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
pub enum ExitCode {
/// This indicates normal termination of a program with an interior exit
/// code returned from the guest program. A halted program cannot be
Expand Down
3 changes: 3 additions & 0 deletions risc0/binfmt/src/sys_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ extern crate alloc;
use alloc::{collections::VecDeque, vec::Vec};
use core::fmt;

#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};
use risc0_zkp::core::{digest::Digest, hash::sha::Sha256};
use serde::{Deserialize, Serialize};

Expand All @@ -25,6 +27,7 @@ use crate::{tagged_struct, Digestible};
/// Represents the public state of a segment, needed for continuations and
/// receipt verification.
#[derive(Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
pub struct SystemState {
/// The program counter.
pub pc: u32,
Expand Down
4 changes: 4 additions & 0 deletions risc0/zkp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ harness = false
[dependencies]
anyhow = { version = "1.0", default-features = false }
blake2 = { version = "0.10.6", default-features = false }
borsh = { version = "1.5.0", default-features = false, features = [
"derive",
], optional = true }
bytemuck = { version = "1.12", features = ["derive"] }
cfg-if = "1.0"
cust = { version = "0.3", optional = true }
Expand Down Expand Up @@ -54,6 +57,7 @@ rustdoc-args = ["--cfg", "docsrs"]
features = ["prove", "std"]

[features]
borsh = ["dep:borsh"]
circuit_debug = []
cuda = ["dep:cust", "prove", "risc0-sys/cuda"]
default = []
Expand Down
3 changes: 3 additions & 0 deletions risc0/zkp/src/core/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use alloc::{format, vec::Vec};
use core::fmt::{Debug, Display, Formatter};

#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};
use bytemuck::{Pod, PodCastError, Zeroable};
use hex::{FromHex, FromHexError};
use serde::{Deserialize, Serialize};
Expand All @@ -42,6 +44,7 @@ pub const DIGEST_BYTES: usize = DIGEST_WORDS * WORD_SIZE;
#[derive(
Copy, Clone, Eq, Ord, PartialOrd, PartialEq, Hash, Pod, Zeroable, Serialize, Deserialize,
)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[repr(transparent)]
pub struct Digest([u32; DIGEST_WORDS]);

Expand Down
4 changes: 4 additions & 0 deletions risc0/zkvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ required-features = ["prove"]

[dependencies]
anyhow = { version = "1.0", default-features = false }
borsh = { version = "1.5.0", default-features = false, features = [
"derive",
], optional = true }
bytemuck = { version = "1.13", features = ["extern_crate_alloc"] }
cfg-if = "1.0"
getrandom = { version = "0.2", features = ["custom"] }
Expand Down Expand Up @@ -106,6 +109,7 @@ rustdoc-args = ["--cfg", "docsrs"]
features = ["client", "prove", "getrandom", "std"]

[features]
borsh = ["dep:borsh", "risc0-binfmt/borsh", "risc0-zkp/borsh"]
client = [
"dep:bincode",
"dep:bonsai-sdk",
Expand Down
26 changes: 26 additions & 0 deletions risc0/zkvm/src/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ use alloc::{collections::BTreeMap, string::String, vec, vec::Vec};
use core::fmt::Debug;

use anyhow::Result;
#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};
use risc0_core::field::baby_bear::BabyBear;
use risc0_zkp::{
core::{
Expand Down Expand Up @@ -111,6 +113,7 @@ pub use self::{
/// You can use [Journal::decode] to deserialize the journal as typed and
/// structured data, or access the [Journal::bytes] directly.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(test, derive(PartialEq))]
pub struct Receipt {
/// The polymorphic [InnerReceipt].
Expand Down Expand Up @@ -263,6 +266,7 @@ impl Receipt {
/// zkVM execution. Along with an image ID, it constitutes the statement proven by a given
/// [Receipt]
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
pub struct Journal {
/// The raw bytes of the journal.
pub bytes: Vec<u8>,
Expand Down Expand Up @@ -296,6 +300,7 @@ impl AsRef<[u8]> for Journal {
/// verification logic for a specific proof system and circuit. All inner receipt types are
/// zero-knowledge proofs of execution for a RISC-V zkVM.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(test, derive(PartialEq))]
#[non_exhaustive]
pub enum InnerReceipt {
Expand Down Expand Up @@ -386,6 +391,7 @@ impl InnerReceipt {
/// information about development-only mode see our [dev-mode
/// documentation](https://dev.risczero.com/api/generating-proofs/dev-mode).
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(test, derive(PartialEq))]
#[non_exhaustive]
pub struct FakeReceipt<Claim>
Expand Down Expand Up @@ -436,6 +442,7 @@ where
/// for security-relevant decisions, such as choosing whether or not to accept a receipt based on
/// it's stated version.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[non_exhaustive]
pub struct ReceiptMetadata {
/// Information which can be used to decide whether a given verifier is compatible with this
Expand Down Expand Up @@ -557,6 +564,7 @@ impl From<ReceiptClaim> for AssumptionReceipt {
/// Instead of proving only RISC-V execution with [ReceiptClaim], this type can prove any claim
/// implemented by one of its inner types.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(test, derive(PartialEq))]
#[non_exhaustive]
pub enum InnerAssumptionReceipt {
Expand Down Expand Up @@ -790,4 +798,22 @@ mod tests {
}
);
}

#[test]
#[cfg(feature = "borsh")]
fn borsh_serde() {
use crate::ReceiptClaim;
use risc0_zkvm_methods::MULTI_TEST_ID;

let claim = ReceiptClaim::ok(MULTI_TEST_ID, vec![]);
let receipt = Receipt::new(
InnerReceipt::Fake(FakeReceipt {
claim: MaybePruned::Value(claim),
}),
vec![],
);
let encoded = borsh::to_vec(&receipt).unwrap();
let decoded: Receipt = borsh::from_slice(&encoded).unwrap();
assert_eq!(receipt, decoded);
}
}
3 changes: 3 additions & 0 deletions risc0/zkvm/src/receipt/composite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use alloc::{vec, vec::Vec};
use core::fmt::Debug;

use anyhow::Result;
#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};
use risc0_binfmt::{tagged_struct, Digestible, ExitCode};
use risc0_circuit_recursion::CircuitImpl;
use risc0_zkp::{
Expand All @@ -38,6 +40,7 @@ use crate::{
/// continuations, and zero or more [InnerAssumptionReceipt](crate::InnerAssumptionReceipt) structs
/// proving any assumptions.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(test, derive(PartialEq))]
#[non_exhaustive]
pub struct CompositeReceipt {
Expand Down
3 changes: 3 additions & 0 deletions risc0/zkvm/src/receipt/groth16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use alloc::vec::Vec;
use core::fmt::Debug;

use anyhow::Result;
#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};
use risc0_binfmt::{tagged_struct, Digestible};
use risc0_circuit_recursion::control_id::{ALLOWED_CONTROL_ROOT, BN254_IDENTITY_CONTROL_ID};
use risc0_groth16::{fr_from_hex_string, split_digest, Seal, Verifier, VerifyingKey};
Expand All @@ -32,6 +34,7 @@ use crate::{

/// A receipt composed of a Groth16 over the BN_254 curve
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(test, derive(PartialEq))]
#[non_exhaustive]
pub struct Groth16Receipt<Claim>
Expand Down
3 changes: 3 additions & 0 deletions risc0/zkvm/src/receipt/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub const ALLOWED_CODE_MERKLE_DEPTH: usize = 8;
use alloc::vec::Vec;

use anyhow::{ensure, Result};
#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};
use risc0_core::field::baby_bear::BabyBear;
use risc0_zkp::core::{digest::Digest, hash::HashFn};
use serde::{Deserialize, Serialize};
Expand All @@ -49,6 +51,7 @@ pub struct MerkleGroup {
/// in the committed set.
#[non_exhaustive]
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
pub struct MerkleProof {
/// Index of the leaf for which inclusion is being proven.
pub index: u32,
Expand Down
Loading

0 comments on commit fff6533

Please sign in to comment.