all working now
This commit is contained in:
parent
f8a62fe7c9
commit
fdab50a0e4
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(¬e_cm.0, &cm_mmr_proof));
|
assert!(mmr.verify_proof(¬e_cm.0, &mmr_proof));
|
||||||
|
cm_mmr.push(mmr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for output in ptx.outputs.iter() {
|
for output in ptx.outputs.iter() {
|
||||||
|
|
Loading…
Reference in New Issue