mirror of
https://github.com/logos-blockchain/lssa-zkvm-testing.git
synced 2026-01-02 13:23:08 +00:00
refactor
This commit is contained in:
parent
8482a1b182
commit
763495a17f
@ -2,7 +2,10 @@ pub mod account;
|
||||
pub mod types;
|
||||
pub mod visibility;
|
||||
|
||||
use crate::types::{AuthenticationPath, Commitment, Key, Nullifier};
|
||||
use crate::{
|
||||
account::Account,
|
||||
types::{AuthenticationPath, Commitment, Key, Nullifier},
|
||||
};
|
||||
use risc0_zkvm::sha::{Impl, Sha256};
|
||||
|
||||
pub fn hash(bytes: &[u32]) -> [u32; 8] {
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::account::Account;
|
||||
|
||||
/// For this POC we consider 32-bit commitments
|
||||
pub type Commitment = u32;
|
||||
pub type Nullifier = [u32; 8];
|
||||
@ -6,3 +10,12 @@ pub type Nonce = [u32; 8];
|
||||
pub type Key = [u32; 8];
|
||||
pub type AuthenticationPath = [[u32; 8]; 32];
|
||||
pub type ProgramId = [u32; 8];
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct PrivacyExecutionOutput {
|
||||
pub public_accounts_pre: Vec<Account>,
|
||||
pub public_accounts_post: Vec<Account>,
|
||||
pub private_output_commitments: Vec<Commitment>,
|
||||
pub nullifiers: Vec<Nullifier>,
|
||||
pub commitment_tree_root: [u32; 8],
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use core::{
|
||||
account::Account,
|
||||
types::{Commitment, Nullifier},
|
||||
types::{Commitment, Nullifier, PrivacyExecutionOutput},
|
||||
};
|
||||
|
||||
use risc0_zkvm::Receipt;
|
||||
@ -11,27 +11,22 @@ impl MockedSequencer {
|
||||
/// Processes a privacy execution request.
|
||||
/// Verifies the proof of the privacy execution and updates the state of the chain.
|
||||
pub fn process_privacy_execution(&mut self, receipt: Receipt) -> Result<(), ()> {
|
||||
// Parse the output of the proof.
|
||||
// This is the output of the "outer" program
|
||||
let output: (Vec<Account>, Vec<Nullifier>, Vec<Commitment>, [u32; 8]) = receipt.journal.decode().unwrap();
|
||||
let (public_inputs_outputs, nullifiers, commitments, commitment_tree_root) = output;
|
||||
// Parse the output of the "outer" program
|
||||
let output: PrivacyExecutionOutput = receipt.journal.decode().unwrap();
|
||||
|
||||
// Reject in case the root used in the privacy execution is not the current root.
|
||||
if commitment_tree_root != self.get_commitment_tree_root() {
|
||||
if output.commitment_tree_root != self.get_commitment_tree_root() {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
// Reject in case the number of accounts in the public_inputs_outputs is not even.
|
||||
// This is because it is expected to contain the pre and post-states of public the accounts
|
||||
// of the inner execution.
|
||||
if public_inputs_outputs.len() % 2 != 0 {
|
||||
// Reject in case the number of accounts pre states is different from the post states
|
||||
if output.public_accounts_pre.len() != output.public_accounts_post.len() {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
// Reject if the states of the public input accounts used in the inner execution do not
|
||||
// coincide with the on-chain state.
|
||||
let num_input_public = public_inputs_outputs.len() >> 1;
|
||||
for account in public_inputs_outputs.iter().take(num_input_public) {
|
||||
for account in output.public_accounts_pre.iter() {
|
||||
let current_account = self.get_account(&account.address).ok_or(())?;
|
||||
if ¤t_account != account {
|
||||
return Err(());
|
||||
@ -39,7 +34,8 @@ impl MockedSequencer {
|
||||
}
|
||||
|
||||
// Reject if the nullifiers of this privacy execution have already been published.
|
||||
if nullifiers
|
||||
if output
|
||||
.nullifiers
|
||||
.iter()
|
||||
.any(|nullifier| self.nullifier_set.contains(nullifier))
|
||||
{
|
||||
@ -47,7 +43,8 @@ impl MockedSequencer {
|
||||
}
|
||||
|
||||
// Reject if the commitments have already been seen.
|
||||
if commitments
|
||||
if output
|
||||
.private_output_commitments
|
||||
.iter()
|
||||
.any(|commitment| self.commitment_tree.values().contains(commitment))
|
||||
{
|
||||
@ -61,30 +58,21 @@ impl MockedSequencer {
|
||||
// - The given nullifiers correctly correspond to commitments that currently belong to
|
||||
// the commitment tree.
|
||||
// - The given commitments are correctly computed from valid accounts.
|
||||
nssa::verify_privacy_execution(
|
||||
receipt,
|
||||
&public_inputs_outputs,
|
||||
&nullifiers,
|
||||
&commitments,
|
||||
&commitment_tree_root,
|
||||
)?;
|
||||
nssa::verify_privacy_execution(receipt)?;
|
||||
|
||||
// At this point the privacy execution is considered valid.
|
||||
//
|
||||
// Update the state of the public accounts with the post-state of this privacy execution
|
||||
public_inputs_outputs
|
||||
.iter()
|
||||
.cloned()
|
||||
.skip(num_input_public)
|
||||
.for_each(|account_post_state| {
|
||||
self.accounts.insert(account_post_state.address, account_post_state);
|
||||
});
|
||||
|
||||
output.public_accounts_post.into_iter().for_each(|account_post_state| {
|
||||
self.accounts.insert(account_post_state.address, account_post_state);
|
||||
});
|
||||
|
||||
// Add all nullifiers to the nullifier set.
|
||||
self.nullifier_set.extend(nullifiers);
|
||||
self.nullifier_set.extend(output.nullifiers);
|
||||
|
||||
// Add commitments to the commitment tree.
|
||||
for commitment in commitments.iter() {
|
||||
for commitment in output.private_output_commitments.iter() {
|
||||
self.commitment_tree.add_value(*commitment);
|
||||
}
|
||||
|
||||
|
||||
@ -61,8 +61,7 @@ fn main() {
|
||||
.unwrap();
|
||||
|
||||
// Verify the proof
|
||||
let output: (Vec<Account>, Vec<Nullifier>, Vec<Commitment>, [u32; 8]) = receipt.journal.decode().unwrap();
|
||||
assert!(nssa::verify_privacy_execution(receipt, &output.0, &output.1, &output.2, &output.3).is_ok());
|
||||
assert!(nssa::verify_privacy_execution(receipt).is_ok());
|
||||
println!("OK!");
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use core::{
|
||||
account::Account,
|
||||
compute_nullifier, hash, is_in_tree,
|
||||
types::{Nonce, ProgramId},
|
||||
types::{Nonce, PrivacyExecutionOutput, ProgramId},
|
||||
visibility::AccountVisibility,
|
||||
};
|
||||
use risc0_zkvm::{guest::env, serde::to_vec};
|
||||
@ -110,24 +110,29 @@ fn main() {
|
||||
let private_output_commitments: Vec<_> = private_outputs.iter().map(|account| account.commitment()).collect();
|
||||
|
||||
// Get the list of public accounts pre and post states
|
||||
let mut public_inputs_outputs = Vec::new();
|
||||
for (account, visibility) in inputs
|
||||
.iter()
|
||||
.chain(outputs.iter())
|
||||
let mut public_accounts_pre = Vec::new();
|
||||
let mut public_accounts_post = Vec::new();
|
||||
for ((account_pre, account_post), visibility) in inputs
|
||||
.into_iter()
|
||||
.zip(outputs.into_iter())
|
||||
.zip(account_visibilities.iter().chain(account_visibilities.iter()))
|
||||
{
|
||||
match visibility {
|
||||
AccountVisibility::Public => {
|
||||
public_inputs_outputs.push(account);
|
||||
public_accounts_pre.push(account_pre);
|
||||
public_accounts_post.push(account_post);
|
||||
}
|
||||
AccountVisibility::Private(_) => continue,
|
||||
}
|
||||
}
|
||||
|
||||
env::commit(&(
|
||||
public_inputs_outputs,
|
||||
nullifiers,
|
||||
let output = PrivacyExecutionOutput {
|
||||
public_accounts_pre,
|
||||
public_accounts_post,
|
||||
private_output_commitments,
|
||||
nullifiers,
|
||||
commitment_tree_root,
|
||||
));
|
||||
};
|
||||
|
||||
env::commit(&output);
|
||||
}
|
||||
|
||||
@ -129,23 +129,6 @@ pub fn execute_offchain<P: Program>(
|
||||
}
|
||||
|
||||
/// Verifies a proof of the outer program for the given parameters.
|
||||
pub fn verify_privacy_execution(
|
||||
receipt: Receipt,
|
||||
public_accounts_inputs_outputs: &[Account],
|
||||
nullifiers: &[Nullifier],
|
||||
private_output_commitments: &[Commitment],
|
||||
commitment_tree_root: &[u32; 8],
|
||||
) -> Result<(), ()> {
|
||||
let output: (Vec<Account>, Vec<Nullifier>, Vec<Commitment>, [u32; 8]) = receipt.journal.decode().unwrap();
|
||||
let expected_output = (
|
||||
public_accounts_inputs_outputs.to_vec(),
|
||||
nullifiers.to_vec(),
|
||||
private_output_commitments.to_vec(),
|
||||
commitment_tree_root.to_owned(),
|
||||
);
|
||||
if output != expected_output {
|
||||
Err(())
|
||||
} else {
|
||||
receipt.verify(OUTER_ID).map_err(|_| ())
|
||||
}
|
||||
pub fn verify_privacy_execution(receipt: Receipt) -> Result<(), ()> {
|
||||
receipt.verify(OUTER_ID).map_err(|_| ())
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user