add deposit-merge vk

This commit is contained in:
Giacomo Pasini 2024-08-07 21:48:14 +02:00
parent a320c20d25
commit d7cf1a3eaf
No known key found for this signature in database
GPG Key ID: FC08489D2D895D4B
6 changed files with 106 additions and 1 deletions

View File

@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum Event {
Spend(Spend),
Merge(Merge),
}
impl Event {
@ -10,6 +11,7 @@ impl Event {
// TODO: add variant tag to byte encoding
match self {
Event::Spend(spend) => spend.to_bytes().to_vec(),
Event::Merge(merge) => merge.to_bytes().to_vec(),
}
}
}
@ -34,3 +36,18 @@ impl Spend {
bytes
}
}
/// An event that authorizes spending zone funds to merge with other notes
/// Balancing of the transaction is done in the zone state death constraint
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct Merge {
pub nf: cl::Nullifier,
}
impl Merge {
pub fn to_bytes(&self) -> [u8; 32] {
let mut bytes = [0; 32];
bytes.copy_from_slice(self.nf.as_bytes());
bytes
}
}

View File

@ -19,3 +19,19 @@ pub struct SpendFundsPrivate {
/// Merkle root of balances in the zone
pub balances_root: [u8; 32],
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct MergePrivate {
// The note we're spending
pub funds_note: cl::PartialTxInputWitness,
// The zone note that is authorizing the spend
pub zone_note: cl::PartialTxOutputWitness,
// The event emitted by the zone that authorizes spending this note
pub merge_event: common::events::Merge,
// Path to the zone output events root
pub merge_event_state_path: Vec<cl::merkle::PathNode>,
// Merkle root of txs included in the zone
pub txs_root: [u8; 32],
// Merkle root of balances in the zone
pub balances_root: [u8; 32],
}

View File

@ -7,5 +7,5 @@ edition = "2021"
risc0-build = { version = "1.0" }
[package.metadata.risc0]
methods = ["spend_zone_funds", "zone_state"]
methods = ["spend_zone_funds", "zone_state", "zone_merge"]

View File

@ -0,0 +1,21 @@
[package]
name = "zone-merge"
version = "0.1.0"
edition = "2021"
[workspace]
[dependencies]
risc0-zkvm = { version = "1.0", default-features = false, features = ['std'] }
serde = { version = "1.0", features = ["derive"] }
cl = { path = "../../../cl/cl" }
goas_proof_statements = { path = "../../proof_statements" }
ledger_proof_statements = { path = "../../../cl/ledger_proof_statements" }
sha2 = "0.10"
[patch.crates-io]
# add RISC Zero accelerator support for all downstream usages of the following crates.
sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2-v0.10.8-risczero.0" }
crypto-bigint = { git = "https://github.com/risc0/RustCrypto-crypto-bigint", tag = "v0.5.5-risczero.0" }
curve25519-dalek = { git = "https://github.com/risc0/curve25519-dalek", tag = "curve25519-4.1.2-risczero.0" }

View File

@ -0,0 +1,44 @@
use cl::{merkle, nullifier::Nullifier, PtxRoot};
use goas_proof_statements::zone_funds::MergePrivate;
use ledger_proof_statements::death_constraint::DeathConstraintPublic;
use risc0_zkvm::guest::env;
fn main() {
let MergePrivate {
funds_note,
zone_note,
merge_event,
merge_event_state_path,
txs_root,
balances_root,
} = env::read();
let input_root = funds_note.input_root();
let output_root = zone_note.output_root();
let nf = Nullifier::new(funds_note.input.nf_sk, funds_note.input.nonce);
// check the zone funds note is the one in the spend event
assert_eq!(nf, merge_event.nf);
// ** Assert merge spent event was an output of the correct zone stf **
// The zone state field is a merkle tree over:
// root
// / \
// io state
// / \ / \
// events txs zoneid balances
// We need to check that:
// 1) There is a valid path from the spend event to the events root
// 2) The zone id matches the one in the current funds note state
// 3) The witnesses for merge path, txs and balances allow to calculate the correct root
let zone_id = funds_note.input.note.state; // TODO: is there more state?
let merge_event_leaf = merkle::leaf(&merge_event.to_bytes());
let event_root = merkle::path_root(merge_event_leaf, &merge_event_state_path);
assert_eq!(
merkle::root([event_root, txs_root, zone_id, balances_root]),
zone_note.output.note.state
);
let ptx_root = PtxRoot(merkle::node(input_root, output_root));
env::commit(&DeathConstraintPublic { ptx_root, nf });
}

View File

@ -94,6 +94,13 @@ fn deposit(
.checked_add(amount)
.expect("overflow when depositing");
// authorize the merge of the zone funds
state
.output_events
.push(events::Event::Merge(events::Merge {
nf: Nullifier::new(zone_funds_in.nf_sk, zone_funds_in.nonce),
}));
state
}