all working now

This commit is contained in:
David Rusu 2024-12-06 23:47:54 +04:00
parent f8a62fe7c9
commit fdab50a0e4
8 changed files with 46 additions and 50 deletions

View File

@ -18,6 +18,13 @@ pub struct MMRProof {
pub path: Vec<merkle::PathNode>, pub path: Vec<merkle::PathNode>,
} }
impl MMRProof {
pub fn root(&self, elem: &[u8]) -> [u8; 32] {
let leaf = merkle::leaf(elem);
merkle::path_root(leaf, &self.path)
}
}
impl MMR { impl MMR {
pub fn new() -> Self { pub fn new() -> Self {
Self::default() Self::default()
@ -52,8 +59,7 @@ impl MMR {
pub fn verify_proof(&self, elem: &[u8], proof: &MMRProof) -> bool { pub fn verify_proof(&self, elem: &[u8], proof: &MMRProof) -> bool {
let path_len = proof.path.len(); let path_len = proof.path.len();
let leaf = merkle::leaf(elem); let root = proof.root(elem);
let root = merkle::path_root(leaf, &proof.path);
for mmr_root in self.roots.iter() { for mmr_root in self.roots.iter() {
if mmr_root.height == (path_len + 1) as u8 { if mmr_root.height == (path_len + 1) as u8 {

View File

@ -39,10 +39,10 @@ impl LedgerWitness {
} }
} }
#[derive(Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct LedgerState { pub struct LedgerState {
commitments: MMR, pub commitments: MMR,
nullifiers: BTreeSet<[u8; 32]>, pub nullifiers: BTreeSet<[u8; 32]>,
} }
impl LedgerState { impl LedgerState {
@ -53,10 +53,6 @@ impl LedgerState {
} }
} }
pub fn cm_mmr(&self) -> MMR {
self.commitments.clone()
}
pub fn nf_root(&self) -> [u8; 32] { pub fn nf_root(&self) -> [u8; 32] {
sparse_merkle::sparse_root(&self.nullifiers) sparse_merkle::sparse_root(&self.nullifiers)
} }

View File

@ -15,13 +15,11 @@ pub struct ProvedPartialTx {
impl ProvedPartialTx { impl ProvedPartialTx {
pub fn prove( pub fn prove(
ptx_witness: PartialTxWitness, ptx_witness: PartialTxWitness,
input_cm_paths: Vec<MMRProof>, input_cm_proofs: Vec<(MMR, MMRProof)>,
cm_mmr: MMR,
) -> Result<ProvedPartialTx> { ) -> Result<ProvedPartialTx> {
let ptx_private = PtxPrivate { let ptx_private = PtxPrivate {
ptx: ptx_witness, ptx: ptx_witness,
input_cm_paths, input_cm_proofs,
cm_mmr: cm_mmr.clone(),
}; };
let env = risc0_zkvm::ExecutorEnv::builder() let env = risc0_zkvm::ExecutorEnv::builder()

View File

@ -27,7 +27,6 @@ impl ProvedUpdateBundle {
} }
} }
println!("{:?} | {:?}", expected_zones, actual_zones);
for (bundle, expected) in expected_zones.iter() { for (bundle, expected) in expected_zones.iter() {
if let Some(actual) = actual_zones.get(bundle) { if let Some(actual) = actual_zones.get(bundle) {
if actual != expected { if actual != expected {

View File

@ -1,7 +1,10 @@
use cl::{ use cl::{
cl::{ cl::{
balance::Unit, mmr::MMRProof, note::derive_unit, BalanceWitness, InputWitness, NoteWitness, balance::Unit,
NullifierCommitment, NullifierSecret, OutputWitness, PartialTxWitness, mmr::{MMRProof, MMR},
note::derive_unit,
BalanceWitness, InputWitness, NoteWitness, NullifierCommitment, NullifierSecret,
OutputWitness, PartialTxWitness,
}, },
zone_layer::{ zone_layer::{
ledger::LedgerState, ledger::LedgerState,
@ -48,7 +51,7 @@ fn receive_utxo(note: NoteWitness, nf_pk: NullifierCommitment, zone_id: ZoneId)
fn cross_transfer_transition( fn cross_transfer_transition(
input: InputWitness, input: InputWitness,
input_path: MMRProof, input_proof: (MMR, MMRProof),
to: User, to: User,
amount: u64, amount: u64,
zone_a: ZoneId, zone_a: ZoneId,
@ -74,8 +77,7 @@ fn cross_transfer_transition(
outputs: vec![transfer, change], outputs: vec![transfer, change],
balance_blinding: BalanceWitness::random_blinding(&mut rng), balance_blinding: BalanceWitness::random_blinding(&mut rng),
}; };
let proved_ptx = let proved_ptx = ProvedPartialTx::prove(ptx_witness.clone(), vec![input_proof]).unwrap();
ProvedPartialTx::prove(ptx_witness.clone(), vec![input_path], ledger_a.cm_mmr()).unwrap();
let balance = ProvedBalance::prove(&BalancePrivate { let balance = ProvedBalance::prove(&BalancePrivate {
balances: vec![ptx_witness.balance()], balances: vec![ptx_witness.balance()],
@ -141,7 +143,8 @@ fn zone_update_cross() {
let alice_input = InputWitness::from_output(utxo, alice.sk()); let alice_input = InputWitness::from_output(utxo, alice.sk());
let mut ledger_a = LedgerState::default(); let mut ledger_a = LedgerState::default();
let input_cm_path = ledger_a.add_commitment(utxo.commit_note()); let alice_cm_path = ledger_a.add_commitment(utxo.commit_note());
let alice_cm_proof = (ledger_a.commitments.clone(), alice_cm_path);
let ledger_b = LedgerState::default(); let ledger_b = LedgerState::default();
@ -160,7 +163,7 @@ fn zone_update_cross() {
let (ledger_a_transition, ledger_b_transition) = cross_transfer_transition( let (ledger_a_transition, ledger_b_transition) = cross_transfer_transition(
alice_input, alice_input,
input_cm_path, alice_cm_proof,
bob, bob,
8, 8,
zone_a_id, zone_a_id,

View File

@ -7,12 +7,11 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PtxPublic { pub struct PtxPublic {
pub ptx: PartialTx, pub ptx: PartialTx,
pub cm_mmr: MMR, pub cm_mmr: Vec<MMR>,
} }
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PtxPrivate { pub struct PtxPrivate {
pub ptx: PartialTxWitness, pub ptx: PartialTxWitness,
pub input_cm_proofs: Vec<MMRProof>, pub input_cm_proofs: Vec<(MMR, MMRProof)>,
pub cm_mmr: MMR,
} }

View File

@ -5,8 +5,7 @@ use cl::{
use ledger_proof_statements::{ use ledger_proof_statements::{
balance::BalancePublic, balance::BalancePublic,
constraint::ConstraintPublic, constraint::ConstraintPublic,
ledger::{CrossZoneBundle, LedgerProofPrivate, LedgerProofPublic}, ledger::{CrossZoneBundle, LedgerProofPrivate, LedgerProofPublic, LedgerPtxWitness},
ptx::PtxPublic,
}; };
use risc0_zkvm::{guest::env, serde}; use risc0_zkvm::{guest::env, serde};
@ -21,13 +20,6 @@ fn main() {
let mut cross_bundles = vec![]; let mut cross_bundles = vec![];
let mut outputs = vec![]; let mut outputs = vec![];
let roots = ledger
.commitments
.roots
.iter()
.map(|r| r.root)
.collect::<Vec<_>>();
for bundle in bundles { for bundle in bundles {
let balance_public = BalancePublic { let balance_public = BalancePublic {
balances: bundle.partials.iter().map(|bundle_ptx| bundle_ptx.ptx.ptx.balance).collect::<Vec<_>>(), balances: bundle.partials.iter().map(|bundle_ptx| bundle_ptx.ptx.ptx.balance).collect::<Vec<_>>(),
@ -40,14 +32,13 @@ fn main() {
) )
.unwrap(); .unwrap();
for ptx in &bundle { for ptx in &bundle.partials {
let (new_ledger, ptx_outputs) = process_ptx(ledger, ptx, id, &roots); let ptx_outputs = process_ptx(&mut ledger, ptx, id);
ledger = new_ledger;
outputs.extend(ptx_outputs); outputs.extend(ptx_outputs);
} }
let bundle = Bundle { let bundle = Bundle {
partials: bundle.into_iter().map(|ptx| ptx.ptx).collect(), partials: bundle.partials.into_iter().map(|ptx_witness| ptx_witness.ptx.ptx).collect(),
}; };
let zones = bundle.zones(); let zones = bundle.zones();
if zones.len() > 1 { if zones.len() > 1 {
@ -68,37 +59,40 @@ fn main() {
} }
fn process_ptx( fn process_ptx(
mut ledger: LedgerWitness, ledger: &mut LedgerWitness,
ptx_witness: &LedgerPtxWitness, ptx_witness: &LedgerPtxWitness,
zone_id: ZoneId, zone_id: ZoneId,
roots: &[[u8; 32]], ) -> Vec<Output> {
) -> (LedgerWitness, Vec<Output>) { let ptx = &ptx_witness.ptx;
let nf_proofs = &ptx_witness.nf_proofs;
// always verify the ptx to ensure outputs were derived with the correct zone id // 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(); env::verify(nomos_cl_risc0_proofs::PTX_ID, &serde::to_vec(&ptx).unwrap()).unwrap();
PtxWitness { ref ptx, ref nf_proofs } = ptx_witness;
assert_eq!(ptx.cm_mmr, roots); // we force commitment proofs w.r.t. latest MMR
assert_eq!(ptx.ptx.inputs.len(), nf_proofs.len()); assert_eq!(ptx.ptx.inputs.len(), nf_proofs.len());
assert_eq!(ptx.ptx.inputs.len(), ptx.cm_mmr.len());
for (input, nf_proof) in ptx.ptx.inputs.iter().zip(nf_proofs) { for ((input, nf_proof), cm_mmr) in ptx.ptx.inputs.iter().zip(nf_proofs).zip(ptx.cm_mmr.iter()) {
if input.zone_id != zone_id { if input.zone_id != zone_id {
continue; continue;
} }
assert_eq!(cm_mmr, &ledger.commitments); // we force commitment proofs w.r.t. latest MMR
ledger.assert_nf_update(input.nullifier, nf_proof); ledger.assert_nf_update(input.nullifier, nf_proof);
env::verify( env::verify(
input.constraint.0, input.constraint.0,
&serde::to_vec(&ConstraintPublic { &serde::to_vec(&ConstraintPublic {
ptx_root: ptx.root(), ptx_root: ptx.ptx.root(),
nf: input.nullifier, nf: input.nullifier,
}).unwrap(), }).unwrap(),
).unwrap(); ).unwrap();
} }
let mut outputs = vec![]; let mut outputs = vec![];
for output in &ptx.outputs { for output in &ptx.ptx.outputs {
if output.zone_id != zone_id { if output.zone_id != zone_id {
continue; continue;
} }
@ -107,5 +101,5 @@ fn process_ptx(
outputs.push(*output); outputs.push(*output);
} }
(ledger, outputs) outputs
} }

View File

@ -6,13 +6,14 @@ fn main() {
let PtxPrivate { let PtxPrivate {
ptx, ptx,
input_cm_proofs, input_cm_proofs,
cm_mmr,
} = env::read(); } = env::read();
assert_eq!(ptx.inputs.len(), input_cm_proofs.len()); assert_eq!(ptx.inputs.len(), input_cm_proofs.len());
for (input, cm_mmr_proof) in ptx.inputs.iter().zip(input_cm_proofs) { let mut cm_mmr = Vec::new();
for (input, (mmr, mmr_proof)) in ptx.inputs.iter().zip(input_cm_proofs) {
let note_cm = input.note_commitment(); let note_cm = input.note_commitment();
assert!(cm_mmr.verify_proof(&note_cm.0, &cm_mmr_proof)); assert!(mmr.verify_proof(&note_cm.0, &mmr_proof));
cm_mmr.push(mmr);
} }
for output in ptx.outputs.iter() { for output in ptx.outputs.iter() {