mirror of
https://github.com/logos-blockchain/lssa-zkvm-testing.git
synced 2026-01-02 05:13:09 +00:00
wip
This commit is contained in:
parent
e204db5cd9
commit
c74fa88380
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,2 +1,5 @@
|
||||
target
|
||||
Cargo.lock
|
||||
Cargo.lock
|
||||
risc0-selective-privacy-poc/target
|
||||
risc0-selective-privacy-poc/Cargo.lock
|
||||
risc0-selective-privacy-poc/methods/guest/Cargo.lock
|
||||
17
risc0-selective-privacy-poc/Cargo.toml
Normal file
17
risc0-selective-privacy-poc/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "tuki"
|
||||
version = "0.12.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
risc0-zkvm = "2.2"
|
||||
toy-example-core = {path = "core"}
|
||||
transfer-methods = {path = "transfer_methods"}
|
||||
outer-methods = {path = "outer_methods"}
|
||||
serde = "1.0"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
|
||||
[features]
|
||||
cuda = ["risc0-zkvm/cuda"]
|
||||
default = []
|
||||
prove = ["risc0-zkvm/prove"]
|
||||
8
risc0-selective-privacy-poc/core/Cargo.toml
Normal file
8
risc0-selective-privacy-poc/core/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "toy-example-core"
|
||||
version = "0.12.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
risc0-zkvm = "2.0.2"
|
||||
serde = { version = "1.0", default-features = false }
|
||||
44
risc0-selective-privacy-poc/core/src/lib.rs
Normal file
44
risc0-selective-privacy-poc/core/src/lib.rs
Normal file
@ -0,0 +1,44 @@
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
use risc0_zkvm::{sha::{Impl, Sha256}, serde::to_vec};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Account {
|
||||
pub address: [u32; 8],
|
||||
pub balance: u128,
|
||||
pub nonce: [u32; 8]
|
||||
}
|
||||
|
||||
impl Account {
|
||||
/// Creates a new account with address = hash(private_key) and balance = 0
|
||||
pub fn new(private_key: [u32; 8], nonce: [u32; 8]) -> Self {
|
||||
let address = hash(&private_key);
|
||||
Self { address, balance: 0, nonce }
|
||||
}
|
||||
|
||||
/// Returns Hash(Account)
|
||||
pub fn commitment(&self) -> [u32; 8] {
|
||||
hash(&to_vec(&self).unwrap())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub fn hash(bytes: &[u32]) -> [u32; 8] {
|
||||
Impl::hash_words(&bytes).as_words().try_into().unwrap()
|
||||
}
|
||||
|
||||
pub fn is_in_commitment_tree(_commitment: [u32; 8], _tree_root: [u32; 8]) -> bool {
|
||||
// Dummy implementation
|
||||
true
|
||||
}
|
||||
|
||||
/// Returns Hash(Commitment || private_key)
|
||||
pub fn compute_nullifier(commitment: [u32; 8], private_key: [u32; 8]) -> [u32; 8] {
|
||||
let mut bytes_to_hash = [0; 16];
|
||||
bytes_to_hash[..8].copy_from_slice(&commitment);
|
||||
bytes_to_hash[8..].copy_from_slice(&private_key);
|
||||
hash(&bytes_to_hash)
|
||||
}
|
||||
|
||||
10
risc0-selective-privacy-poc/outer_methods/Cargo.toml
Normal file
10
risc0-selective-privacy-poc/outer_methods/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "outer-methods"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[build-dependencies]
|
||||
risc0-build = { version = "2.2" }
|
||||
|
||||
[package.metadata.risc0]
|
||||
methods = ["guest"]
|
||||
3
risc0-selective-privacy-poc/outer_methods/build.rs
Normal file
3
risc0-selective-privacy-poc/outer_methods/build.rs
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
risc0_build::embed_methods();
|
||||
}
|
||||
11
risc0-selective-privacy-poc/outer_methods/guest/Cargo.toml
Normal file
11
risc0-selective-privacy-poc/outer_methods/guest/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "toy_example"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
risc0-zkvm = { version = "2.2.0", default-features = false, features = ['std'] }
|
||||
toy-example-core = {path = "../../core" }
|
||||
transfer-methods = {path = "../../transfer_methods"}
|
||||
@ -0,0 +1,42 @@
|
||||
use risc0_zkvm::{guest::env, sha::{Impl, Sha256}, serde::to_vec};
|
||||
use toy_example_core::{Account, hash, compute_nullifier, is_in_commitment_tree};
|
||||
use transfer_methods::TRANSFER_ID;
|
||||
|
||||
fn main() {
|
||||
// Read inputs
|
||||
let sender_private_key: [u32; 8] = env::read();
|
||||
let sender: Account = env::read();
|
||||
let receiver: Account = env::read();
|
||||
let balance_to_move: u128 = env::read();
|
||||
let sender_post: Account = env::read();
|
||||
let receiver_post: Account = env::read();
|
||||
let commitment_tree_root: [u32; 8] = env::read();
|
||||
|
||||
// Assert receiver account is fresh
|
||||
assert_eq!(receiver.balance, 0);
|
||||
|
||||
// Prove ownership of sender account by proving
|
||||
// knowledge of the pre-image of its address
|
||||
assert_eq!(hash(&sender_private_key), sender.address);
|
||||
|
||||
// Compute sender account commitment and prove it belongs to commitments tree
|
||||
let sender_commitment = sender.commitment();
|
||||
assert!(is_in_commitment_tree(sender_commitment, commitment_tree_root));
|
||||
|
||||
// Compute nullifier of sender account
|
||||
let sender_nullifier = compute_nullifier(sender_commitment, sender_private_key);
|
||||
|
||||
// Compute receiver commitment
|
||||
let receiver_commitment = receiver_post.commitment();
|
||||
|
||||
// Verify pre states and post states of accounts are consistent
|
||||
// with the execution of the TRANSFER_ELF program
|
||||
env::verify(TRANSFER_ID, &to_vec(&(sender.clone(), receiver.clone(), sender_post.clone(), receiver_post.clone())).unwrap()).unwrap();
|
||||
|
||||
// Assert TRANSFER_ELF program didn't modify address fields
|
||||
assert_eq!(sender.address, sender_post.address);
|
||||
assert_eq!(receiver.address, receiver_post.address);
|
||||
|
||||
// Output nullifier
|
||||
env::commit(&(sender_nullifier, receiver_commitment));
|
||||
}
|
||||
1
risc0-selective-privacy-poc/outer_methods/src/lib.rs
Normal file
1
risc0-selective-privacy-poc/outer_methods/src/lib.rs
Normal file
@ -0,0 +1 @@
|
||||
include!(concat!(env!("OUT_DIR"), "/methods.rs"));
|
||||
4
risc0-selective-privacy-poc/rust-toolchain.toml
Normal file
4
risc0-selective-privacy-poc/rust-toolchain.toml
Normal file
@ -0,0 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "stable"
|
||||
components = ["rustfmt", "rust-src"]
|
||||
profile = "minimal"
|
||||
119
risc0-selective-privacy-poc/src/lib.rs
Normal file
119
risc0-selective-privacy-poc/src/lib.rs
Normal file
@ -0,0 +1,119 @@
|
||||
use std::u128;
|
||||
|
||||
// These constants represent the RISC-V ELF and the image ID generated by risc0-build.
|
||||
// The ELF is used for proving and the ID is used for verification.
|
||||
use transfer_methods::{
|
||||
TRANSFER_ELF, TRANSFER_ID
|
||||
};
|
||||
use outer_methods::{
|
||||
OUTER_ELF, OUTER_ID
|
||||
};
|
||||
use risc0_zkvm::{default_executor, default_prover, ExecutorEnv, Receipt};
|
||||
use toy_example_core::Account;
|
||||
|
||||
fn prove_inner(sender: Account, receiver: Account, balance_to_move: u128) -> (Receipt, Account, Account) {
|
||||
let mut env_builder = ExecutorEnv::builder();
|
||||
env_builder.write(&sender).unwrap();
|
||||
env_builder.write(&receiver).unwrap();
|
||||
env_builder.write(&balance_to_move).unwrap();
|
||||
let env = env_builder.build().unwrap();
|
||||
|
||||
let prover = default_prover();
|
||||
let prove_info = prover
|
||||
.prove(env, TRANSFER_ELF)
|
||||
.unwrap();
|
||||
|
||||
let receipt = prove_info.receipt;
|
||||
|
||||
let output: [Account; 4] = receipt.journal.decode().unwrap();
|
||||
let [_, _, sender_post, receiver_post] = output;
|
||||
|
||||
println!("sender_before: {:?}, sender_after: {:?}", sender, sender_post);
|
||||
println!("receiver_before: {:?}, receiver_after: {:?}", receiver, receiver_post);
|
||||
|
||||
// Sanity check
|
||||
receipt
|
||||
.verify(TRANSFER_ID)
|
||||
.unwrap();
|
||||
|
||||
(receipt, sender_post, receiver_post)
|
||||
}
|
||||
|
||||
pub fn run_private_execution_of_transfer_program() {
|
||||
let commitment_tree_root = [0xdd, 0xee, 0xaa, 0xdd, 0xbb, 0xee, 0xee, 0xff];
|
||||
let sender_private_key = [0; 8];
|
||||
let mut sender = Account::new(sender_private_key, [1; 8]);
|
||||
sender.balance = 150;
|
||||
|
||||
let receiver_private_key = [99; 8];
|
||||
let receiver = Account::new(receiver_private_key, [1; 8]);
|
||||
let balance_to_move: u128 = 3;
|
||||
|
||||
// Prove inner
|
||||
let (inner_receipt, sender_post, receiver_post) = prove_inner(sender.clone(), receiver.clone(), balance_to_move);
|
||||
|
||||
// Prover outer
|
||||
let mut env_builder = ExecutorEnv::builder();
|
||||
env_builder.add_assumption(inner_receipt);
|
||||
env_builder.write(&sender_private_key).unwrap();
|
||||
env_builder.write(&sender).unwrap();
|
||||
env_builder.write(&receiver) .unwrap();
|
||||
env_builder.write(&balance_to_move).unwrap();
|
||||
env_builder.write(&sender_post).unwrap();
|
||||
env_builder.write(&receiver_post).unwrap();
|
||||
env_builder.write(&commitment_tree_root).unwrap();
|
||||
let env = env_builder.build().unwrap();
|
||||
|
||||
let prover = default_prover();
|
||||
let prove_info = prover
|
||||
.prove(env, OUTER_ELF)
|
||||
.unwrap();
|
||||
|
||||
let receipt = prove_info.receipt;
|
||||
|
||||
receipt.verify(OUTER_ID).unwrap();
|
||||
|
||||
let (nullifier, commitment): ([u32; 8], [u32; 8]) = receipt.journal.decode().unwrap();
|
||||
println!("nullifier: {:?}", nullifier);
|
||||
println!("commitment: {:?}", commitment);
|
||||
}
|
||||
|
||||
pub fn run_public_execution_of_transfer_program() {
|
||||
let sender_private_key = [0; 8];
|
||||
let mut sender = Account::new(sender_private_key, [1; 8]);
|
||||
sender.balance = 150;
|
||||
|
||||
let receiver_private_key = [99; 8];
|
||||
let mut receiver = Account::new(receiver_private_key, [1; 8]);
|
||||
receiver.balance = 900;
|
||||
|
||||
let balance_to_move: u128 = 3;
|
||||
|
||||
let mut env_builder = ExecutorEnv::builder();
|
||||
env_builder.write(&sender).unwrap();
|
||||
env_builder.write(&receiver).unwrap();
|
||||
env_builder.write(&balance_to_move).unwrap();
|
||||
let env = env_builder.build().unwrap();
|
||||
|
||||
let executor = default_executor();
|
||||
let result: [Account; 4] = executor.execute(env, TRANSFER_ELF).unwrap().journal.decode().unwrap();
|
||||
let [_, _, sender_post, receiver_post] = result;
|
||||
|
||||
println!("sender_before: {:?}, sender_after: {:?}", sender, sender_post);
|
||||
println!("receiver_before: {:?}, receiver_after: {:?}", receiver, receiver_post);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_private() {
|
||||
run_private_execution_of_transfer_program();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_public() {
|
||||
run_public_execution_of_transfer_program();
|
||||
}
|
||||
}
|
||||
10
risc0-selective-privacy-poc/transfer_methods/Cargo.toml
Normal file
10
risc0-selective-privacy-poc/transfer_methods/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "transfer-methods"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[build-dependencies]
|
||||
risc0-build = { version = "2.2" }
|
||||
|
||||
[package.metadata.risc0]
|
||||
methods = ["guest"]
|
||||
3
risc0-selective-privacy-poc/transfer_methods/build.rs
Normal file
3
risc0-selective-privacy-poc/transfer_methods/build.rs
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
risc0_build::embed_methods();
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "toy_example"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
risc0-zkvm = { version = "2.2.0", default-features = false, features = ['std'] }
|
||||
toy-example-core = {path = "../../core" }
|
||||
@ -0,0 +1,18 @@
|
||||
use risc0_zkvm::{guest::env, sha::{Impl, Sha256}, serde::to_vec};
|
||||
use toy_example_core::Account;
|
||||
|
||||
fn main() {
|
||||
let sender: Account = env::read();
|
||||
let receiver: Account = env::read();
|
||||
let balance_to_move: u128 = env::read();
|
||||
|
||||
assert!(sender.balance >= balance_to_move);
|
||||
|
||||
let mut sender_post = sender.clone();
|
||||
let mut receiver_post = receiver.clone();
|
||||
|
||||
sender_post.balance -= balance_to_move;
|
||||
receiver_post.balance += balance_to_move;
|
||||
|
||||
env::commit(&(sender, receiver, sender_post, receiver_post));
|
||||
}
|
||||
1
risc0-selective-privacy-poc/transfer_methods/src/lib.rs
Normal file
1
risc0-selective-privacy-poc/transfer_methods/src/lib.rs
Normal file
@ -0,0 +1 @@
|
||||
include!(concat!(env!("OUT_DIR"), "/methods.rs"));
|
||||
Loading…
x
Reference in New Issue
Block a user