diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs index 7ab1225..611243e 100644 --- a/zkvm/src/lib.rs +++ b/zkvm/src/lib.rs @@ -418,10 +418,16 @@ pub fn verify(receipt: Receipt, image_id: impl Into) -> anyhow::Result<( Ok(receipt.verify(image_id)?) } + + #[cfg(test)] mod tests { + use std::primitive; + use super::*; - use test_methods::BIG_CALCULATION_ELF; + use risc0_zkvm::serde::from_slice; + use risc0_zkvm::DeserializeOwned; + use test_methods::{BIG_CALCULATION_ELF, VAR_PUB_INPUTS_ID}; use test_methods::{MULTIPLICATION_ELF, MULTIPLICATION_ID}; use test_methods::{SUMMATION_ELF, SUMMATION_ID}; @@ -514,4 +520,51 @@ mod tests { res } + + #[derive(Serialize)] + struct TestInput { + value: T, + is_public: bool, + } + + impl TestInput { + fn new_public(value: T) -> Self { + Self {value, is_public: true} + } + fn new_private(value: T) -> Self { + Self {value, is_public: false} + } + fn value(&self) -> T { + self.value + } + } + + #[test] + fn test_private_inputs_defined_at_proving_time() { + // Arrange + let public_inputs: Vec> = [1, 2, 3, 4, 5, 6, 7, 8, 100].into_iter().map(TestInput::new_public).collect(); + let private_inputs: Vec> = [9, 10, 11, 150].into_iter().map(TestInput::new_private).collect(); + let public_values_sum: u64 = public_inputs.iter().map(|x| x.value()).sum(); + let private_values_sum: u64 = private_inputs.iter().map(|x| x.value()).sum(); + let expected_sum = private_values_sum + public_values_sum; + let expected_public_values: Vec = public_inputs.iter().map(|x| x.value()).collect(); + + // Act + let mut builder = ExecutorEnv::builder(); + let num_inputs: u64 = (private_inputs.len() + public_inputs.len()) as u64; + builder.write(&num_inputs).unwrap(); + public_inputs.iter().for_each(|x| {builder.write(x).unwrap();}); + private_inputs.iter().for_each(|x| {builder.write(x).unwrap();}); + let prover = default_prover(); + let env = builder.build().unwrap(); + let receipt = prover + .prove(env, test_methods::VAR_PUB_INPUTS_ELF) + .map_err(ExecutionFailureKind::prove_error).unwrap().receipt; + let journal = receipt.journal; + let result: (Vec, u64) = journal.decode().unwrap(); + + // Assert + assert_eq!(result.0, expected_public_values); + assert_eq!(result.1, expected_sum); + } } diff --git a/zkvm/test_methods/guest/Cargo.lock b/zkvm/test_methods/guest/Cargo.lock index 0ee4887..51ee031 100644 --- a/zkvm/test_methods/guest/Cargo.lock +++ b/zkvm/test_methods/guest/Cargo.lock @@ -261,18 +261,18 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" +checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" dependencies = [ "proc-macro2", "quote", @@ -498,9 +498,9 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "libc" -version = "0.2.162" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libm" @@ -825,18 +825,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.214" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -915,21 +915,28 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "toml_datetime", + "toml_write", "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "tracing" version = "0.1.40" @@ -1004,9 +1011,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "winnow" -version = "0.6.20" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" dependencies = [ "memchr", ] diff --git a/zkvm/test_methods/guest/src/bin/var_pub_inputs.rs b/zkvm/test_methods/guest/src/bin/var_pub_inputs.rs new file mode 100644 index 0000000..da77daf --- /dev/null +++ b/zkvm/test_methods/guest/src/bin/var_pub_inputs.rs @@ -0,0 +1,39 @@ +// A POC of how a guest program could handle variable number inputs defined as public or private at proving time + + +use risc0_zkvm::guest::env; + +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +pub struct Input { + value: T, + is_public: bool, +} + +fn read_inputs() -> (Vec, Vec) +where + T: Serialize + for<'a> Deserialize<'a>, +{ + let num_inputs: u64 = env::read(); + + let mut pub_inputs = Vec::new(); + let mut priv_inputs = Vec::new(); + for _ in 0..num_inputs { + let input: Input = env::read(); + if input.is_public { + pub_inputs.push(input.value); + } else { + priv_inputs.push(input.value); + } + } + (priv_inputs, pub_inputs) +} + +fn main() { + let (priv_inputs, pub_inputs) = read_inputs::(); + + let sum = priv_inputs.iter().sum::() + pub_inputs.iter().sum::(); + + env::commit(&(pub_inputs, sum)); +} diff --git a/zkvm/test_methods/src/lib.rs b/zkvm/test_methods/src/lib.rs index 1bdb308..cd788e8 100644 --- a/zkvm/test_methods/src/lib.rs +++ b/zkvm/test_methods/src/lib.rs @@ -1 +1 @@ -include!(concat!(env!("OUT_DIR"), "/methods.rs")); +include!(concat!(env!("OUT_DIR"), "/methods.rs")); \ No newline at end of file