diff --git a/emmarin/cl/cl/src/cl/merkle.rs b/emmarin/cl/cl/src/cl/merkle.rs index bb10e3c..8aecb78 100644 --- a/emmarin/cl/cl/src/cl/merkle.rs +++ b/emmarin/cl/cl/src/cl/merkle.rs @@ -43,6 +43,8 @@ pub fn root(elements: [[u8; 32]; N]) -> [u8; 32] { nodes[0] } +pub type Path = Vec; + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum PathNode { Left([u8; 32]), @@ -66,7 +68,7 @@ pub fn path_root(leaf: [u8; 32], path: &[PathNode]) -> [u8; 32] { computed_hash } -pub fn path(leaves: [[u8; 32]; N], idx: usize) -> Vec { +pub fn path(leaves: [[u8; 32]; N], idx: usize) -> Path { assert!(N.is_power_of_two()); assert!(idx < N); diff --git a/emmarin/cl/cl/src/cl/mod.rs b/emmarin/cl/cl/src/cl/mod.rs index c2c25f6..714e83a 100644 --- a/emmarin/cl/cl/src/cl/mod.rs +++ b/emmarin/cl/cl/src/cl/mod.rs @@ -9,6 +9,7 @@ pub mod note; pub mod nullifier; pub mod output; pub mod partial_tx; +pub mod sparse_merkle; pub use balance::{Balance, BalanceWitness}; pub use bundle::Bundle; diff --git a/emmarin/cl/cl/src/zone_layer/ledger.rs b/emmarin/cl/cl/src/zone_layer/ledger.rs index 1273115..240304b 100644 --- a/emmarin/cl/cl/src/zone_layer/ledger.rs +++ b/emmarin/cl/cl/src/zone_layer/ledger.rs @@ -3,12 +3,10 @@ use std::collections::BTreeSet; use crate::cl::{ merkle, mmr::{MMRProof, MMR}, - NoteCommitment, Nullifier, + sparse_merkle, NoteCommitment, Nullifier, }; use serde::{Deserialize, Serialize}; -use super::sparse_merkle_tree; - #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] pub struct Ledger { cm_root: [u8; 32], @@ -31,16 +29,13 @@ impl LedgerWitness { pub fn assert_nf_update(&mut self, nf: Nullifier, path: &[merkle::PathNode]) { // verify that the path corresponds to the nullifier - assert_eq!(sparse_merkle_tree::path_key(path), nf.0); + assert_eq!(sparse_merkle::path_key(path), nf.0); // verify that the nullifier was not already present - assert_eq!( - merkle::path_root(sparse_merkle_tree::ABSENT, path), - self.nf_root - ); + assert_eq!(merkle::path_root(sparse_merkle::ABSENT, path), self.nf_root); // update the nullifer root with the nullifier inserted into the tree - self.nf_root = merkle::path_root(sparse_merkle_tree::PRESENT, path); + self.nf_root = merkle::path_root(sparse_merkle::PRESENT, path); } } @@ -58,7 +53,7 @@ impl LedgerState { } pub fn nf_root(&self) -> [u8; 32] { - sparse_merkle_tree::sparse_root(&self.nullifiers) + sparse_merkle::sparse_root(&self.nullifiers) } pub fn add_commitment(&mut self, cm: NoteCommitment) -> MMRProof { @@ -66,7 +61,7 @@ impl LedgerState { } pub fn add_nullifier(&mut self, nf: Nullifier) -> Vec { - let path = sparse_merkle_tree::sparse_path(nf.0, &self.nullifiers); + let path = sparse_merkle::sparse_path(nf.0, &self.nullifiers); assert!(!self.nullifiers.contains(&nf.0)); self.nullifiers.insert(nf.0); diff --git a/emmarin/cl/cl/src/zone_layer/mod.rs b/emmarin/cl/cl/src/zone_layer/mod.rs index 06da01c..20710b3 100644 --- a/emmarin/cl/cl/src/zone_layer/mod.rs +++ b/emmarin/cl/cl/src/zone_layer/mod.rs @@ -1,4 +1,3 @@ pub mod ledger; pub mod notes; -pub mod sparse_merkle_tree; pub mod tx; diff --git a/emmarin/cl/ledger_proof_statements/src/ledger.rs b/emmarin/cl/ledger_proof_statements/src/ledger.rs index a7feda6..0355703 100644 --- a/emmarin/cl/ledger_proof_statements/src/ledger.rs +++ b/emmarin/cl/ledger_proof_statements/src/ledger.rs @@ -1,4 +1,5 @@ use crate::ptx::PtxPublic; +use cl::cl::merkle; use cl::cl::{bundle::BundleId, Output}; use cl::zone_layer::{ ledger::{Ledger, LedgerWitness}, @@ -19,7 +20,18 @@ pub struct LedgerProofPublic { pub struct LedgerProofPrivate { pub ledger: LedgerWitness, pub id: ZoneId, - pub bundles: Vec>, + pub bundles: Vec, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct LedgerBundleWitness { + pub partials: Vec, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct LedgerPtxWitness { + pub ptx: PtxPublic, + pub nf_proofs: Vec, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] diff --git a/emmarin/cl/ledger_proof_statements/src/ptx.rs b/emmarin/cl/ledger_proof_statements/src/ptx.rs index 93d555c..6f2b189 100644 --- a/emmarin/cl/ledger_proof_statements/src/ptx.rs +++ b/emmarin/cl/ledger_proof_statements/src/ptx.rs @@ -1,15 +1,19 @@ -use cl::cl::{merkle, PartialTx, PartialTxWitness}; +use cl::cl::{ + merkle, + mmr::{MMRProof, MMR}, + PartialTx, PartialTxWitness, +}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct PtxPublic { pub ptx: PartialTx, - pub cm_roots: Vec<[u8; 32]>, + pub cm_mmr: MMR, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct PtxPrivate { pub ptx: PartialTxWitness, - pub input_cm_paths: Vec>, - pub cm_roots: Vec<[u8; 32]>, + pub input_cm_paths: Vec, + pub cm_mmr: MMR, } diff --git a/emmarin/cl/ledger_validity_proof/ledger/src/main.rs b/emmarin/cl/ledger_validity_proof/ledger/src/main.rs index 5849b15..9f9ab02 100644 --- a/emmarin/cl/ledger_validity_proof/ledger/src/main.rs +++ b/emmarin/cl/ledger_validity_proof/ledger/src/main.rs @@ -30,8 +30,9 @@ fn main() { for bundle in bundles { let balance_public = BalancePublic { - balances: bundle.iter().map(|ptx| ptx.ptx.balance).collect::>(), + balances: bundle.partials.iter().map(|bundle_ptx| bundle_ptx.ptx.ptx.balance).collect::>(), }; + // verify bundle is balanced env::verify( nomos_cl_risc0_proofs::BALANCE_ID, @@ -68,41 +69,42 @@ fn main() { fn process_ptx( mut ledger: LedgerWitness, - ptx: &PtxPublic, + ptx_witness: &LedgerPtxWitness, zone_id: ZoneId, roots: &[[u8; 32]], ) -> (LedgerWitness, Vec) { // always verify the ptx to ensure outputs were derived with the correct zone id env::verify(nomos_cl_risc0_proofs::PTX_ID, &serde::to_vec(&ptx).unwrap()).unwrap(); - let cm_roots = &ptx.cm_roots; - let ptx = &ptx.ptx; + PtxWitness { ref ptx, ref nf_proofs } = ptx_witness; - let mut outputs = vec![]; + assert_eq!(ptx.cm_mmr, roots); // we force commitment proofs w.r.t. latest MMR + assert_eq!(ptx.ptx.inputs.len(), nf_proofs.len()); - for (input, input_cm_root) in ptx.inputs.iter().zip(cm_roots) { - if input.zone_id == zone_id { - assert!(roots.contains(input_cm_root)); - assert!(!ledger.nullifiers.contains(&input.nullifier)); - ledger.nullifiers.push(input.nullifier); - - env::verify( - input.constraint.0, - &serde::to_vec(&ConstraintPublic { - ptx_root: ptx.root(), - nf: input.nullifier, - }) - .unwrap(), - ) - .unwrap(); + for (input, nf_proof) in ptx.ptx.inputs.iter().zip(nf_proofs) { + if input.zone_id != zone_id { + continue; } + + ledger.assert_nf_update(input.nullifier, nf_proof); + + env::verify( + input.constraint.0, + &serde::to_vec(&ConstraintPublic { + ptx_root: ptx.root(), + nf: input.nullifier, + }).unwrap(), + ).unwrap(); } + let mut outputs = vec![]; for output in &ptx.outputs { - if output.zone_id == zone_id { - ledger.commitments.push(&output.note_comm.0); - outputs.push(*output); + if output.zone_id != zone_id { + continue; } + + ledger.commitments.push(&output.note_comm.0); + outputs.push(*output); } (ledger, outputs)