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