mirror of
https://github.com/logos-co/nomos-pocs.git
synced 2025-01-09 09:02:13 +00:00
move zone_id into {input,output}witness
This commit is contained in:
parent
3646971fd9
commit
720836e7f2
@ -1,9 +1,6 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{cl::partial_tx::PartialTx, zone_layer::notes::ZoneId};
|
||||||
cl::{partial_tx::PartialTx, BalanceWitness, PartialTxWitness},
|
|
||||||
zone_layer::notes::ZoneId,
|
|
||||||
};
|
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
@ -45,27 +42,10 @@ impl Bundle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
pub struct BundleWitness {
|
|
||||||
pub partials: Vec<PartialTxWitness>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BundleWitness {
|
|
||||||
pub fn balance(&self) -> BalanceWitness {
|
|
||||||
BalanceWitness::combine(self.partials.iter().map(|ptx| ptx.balance()), [0u8; 16])
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub fn commit(&self) -> Bundle {
|
|
||||||
// Bundle {
|
|
||||||
// partials: Vec::from_iter(self.partials.iter().map(|ptx| ptx.commit())),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::cl::{
|
use crate::cl::{
|
||||||
balance::UnitBalance,
|
balance::{BalanceWitness, UnitBalance},
|
||||||
input::InputWitness,
|
input::InputWitness,
|
||||||
note::{derive_unit, NoteWitness},
|
note::{derive_unit, NoteWitness},
|
||||||
nullifier::NullifierSecret,
|
nullifier::NullifierSecret,
|
||||||
@ -73,25 +53,35 @@ mod test {
|
|||||||
partial_tx::PartialTxWitness,
|
partial_tx::PartialTxWitness,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bundle_balance() {
|
fn test_bundle_balance() {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
let zone_id = [0; 32];
|
||||||
let (nmo, eth, crv) = (derive_unit("NMO"), derive_unit("ETH"), derive_unit("CRV"));
|
let (nmo, eth, crv) = (derive_unit("NMO"), derive_unit("ETH"), derive_unit("CRV"));
|
||||||
|
|
||||||
let nf_a = NullifierSecret::random(&mut rng);
|
let nf_a = NullifierSecret::random(&mut rng);
|
||||||
let nf_b = NullifierSecret::random(&mut rng);
|
let nf_b = NullifierSecret::random(&mut rng);
|
||||||
let nf_c = NullifierSecret::random(&mut rng);
|
let nf_c = NullifierSecret::random(&mut rng);
|
||||||
|
|
||||||
let nmo_10_utxo = OutputWitness::new(NoteWitness::basic(10, nmo, &mut rng), nf_a.commit());
|
let nmo_10_utxo = OutputWitness::new(
|
||||||
|
NoteWitness::basic(10, nmo, &mut rng),
|
||||||
|
nf_a.commit(),
|
||||||
|
zone_id,
|
||||||
|
);
|
||||||
let nmo_10_in = InputWitness::from_output(nmo_10_utxo, nf_a);
|
let nmo_10_in = InputWitness::from_output(nmo_10_utxo, nf_a);
|
||||||
|
|
||||||
let eth_23_utxo = OutputWitness::new(NoteWitness::basic(23, eth, &mut rng), nf_b.commit());
|
let eth_23_utxo = OutputWitness::new(
|
||||||
|
NoteWitness::basic(23, eth, &mut rng),
|
||||||
|
nf_b.commit(),
|
||||||
|
zone_id,
|
||||||
|
);
|
||||||
let eth_23_in = InputWitness::from_output(eth_23_utxo, nf_b);
|
let eth_23_in = InputWitness::from_output(eth_23_utxo, nf_b);
|
||||||
|
|
||||||
let crv_4840_out =
|
let crv_4840_out = OutputWitness::new(
|
||||||
OutputWitness::new(NoteWitness::basic(4840, crv, &mut rng), nf_c.commit());
|
NoteWitness::basic(4840, crv, &mut rng),
|
||||||
|
nf_c.commit(),
|
||||||
|
zone_id,
|
||||||
|
);
|
||||||
|
|
||||||
let ptx_unbalanced = PartialTxWitness {
|
let ptx_unbalanced = PartialTxWitness {
|
||||||
inputs: vec![nmo_10_in, eth_23_in],
|
inputs: vec![nmo_10_in, eth_23_in],
|
||||||
@ -99,13 +89,9 @@ mod test {
|
|||||||
balance_blinding: BalanceWitness::random_blinding(&mut rng),
|
balance_blinding: BalanceWitness::random_blinding(&mut rng),
|
||||||
};
|
};
|
||||||
|
|
||||||
let bundle_witness = BundleWitness {
|
assert!(!ptx_unbalanced.balance().is_zero());
|
||||||
partials: vec![ptx_unbalanced.clone()],
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(!bundle_witness.balance().is_zero());
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bundle_witness.balance().balances,
|
ptx_unbalanced.balance().balances,
|
||||||
vec![
|
vec![
|
||||||
UnitBalance {
|
UnitBalance {
|
||||||
unit: nmo,
|
unit: nmo,
|
||||||
@ -129,10 +115,12 @@ mod test {
|
|||||||
let nmo_10_out = OutputWitness::new(
|
let nmo_10_out = OutputWitness::new(
|
||||||
NoteWitness::basic(10, nmo, &mut rng),
|
NoteWitness::basic(10, nmo, &mut rng),
|
||||||
NullifierSecret::random(&mut rng).commit(), // transferring to a random owner
|
NullifierSecret::random(&mut rng).commit(), // transferring to a random owner
|
||||||
|
zone_id,
|
||||||
);
|
);
|
||||||
let eth_23_out = OutputWitness::new(
|
let eth_23_out = OutputWitness::new(
|
||||||
NoteWitness::basic(23, eth, &mut rng),
|
NoteWitness::basic(23, eth, &mut rng),
|
||||||
NullifierSecret::random(&mut rng).commit(), // transferring to a random owner
|
NullifierSecret::random(&mut rng).commit(), // transferring to a random owner
|
||||||
|
zone_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
let ptx_solved = PartialTxWitness {
|
let ptx_solved = PartialTxWitness {
|
||||||
@ -141,11 +129,10 @@ mod test {
|
|||||||
balance_blinding: BalanceWitness::random_blinding(&mut rng),
|
balance_blinding: BalanceWitness::random_blinding(&mut rng),
|
||||||
};
|
};
|
||||||
|
|
||||||
let witness = BundleWitness {
|
let bundle_balance =
|
||||||
partials: vec![ptx_unbalanced, ptx_solved],
|
BalanceWitness::combine([ptx_unbalanced.balance(), ptx_solved.balance()], [0; 16]);
|
||||||
};
|
|
||||||
|
|
||||||
assert!(witness.balance().is_zero());
|
assert!(bundle_balance.is_zero());
|
||||||
assert_eq!(witness.balance().balances, vec![]);
|
assert_eq!(bundle_balance.balances, vec![]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,59 +24,65 @@ pub struct Input {
|
|||||||
pub struct InputWitness {
|
pub struct InputWitness {
|
||||||
pub note: NoteWitness,
|
pub note: NoteWitness,
|
||||||
pub nf_sk: NullifierSecret,
|
pub nf_sk: NullifierSecret,
|
||||||
|
pub zone_id: ZoneId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputWitness {
|
impl InputWitness {
|
||||||
pub fn new(note: NoteWitness, nf_sk: NullifierSecret) -> Self {
|
pub fn new(note: NoteWitness, nf_sk: NullifierSecret, zone_id: ZoneId) -> Self {
|
||||||
Self { note, nf_sk }
|
Self {
|
||||||
|
note,
|
||||||
|
nf_sk,
|
||||||
|
zone_id,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_output(output: OutputWitness, nf_sk: NullifierSecret) -> Self {
|
pub fn from_output(output: OutputWitness, nf_sk: NullifierSecret) -> Self {
|
||||||
assert_eq!(nf_sk.commit(), output.nf_pk);
|
assert_eq!(nf_sk.commit(), output.nf_pk);
|
||||||
Self::new(output.note, nf_sk)
|
Self::new(output.note, nf_sk, output.zone_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn public(output: OutputWitness) -> Self {
|
pub fn public(output: OutputWitness) -> Self {
|
||||||
let nf_sk = NullifierSecret::zero();
|
let nf_sk = NullifierSecret::zero();
|
||||||
assert_eq!(nf_sk.commit(), output.nf_pk); // ensure the output was a public UTXO
|
assert_eq!(nf_sk.commit(), output.nf_pk); // ensure the output was a public UTXO
|
||||||
Self::new(output.note, nf_sk)
|
Self::new(output.note, nf_sk, output.zone_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evolved_nonce(&self, tag: &dyn AsRef<[u8]>, domain: &[u8]) -> Nonce {
|
pub fn evolved_nonce(&self, domain: &[u8]) -> Nonce {
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
hasher.update(b"NOMOS_COIN_EVOLVE");
|
hasher.update(b"NOMOS_COIN_EVOLVE");
|
||||||
hasher.update(domain);
|
hasher.update(domain);
|
||||||
hasher.update(self.nf_sk.0);
|
hasher.update(self.nf_sk.0);
|
||||||
hasher.update(self.note.commit(tag, self.nf_sk.commit()).0);
|
hasher.update(self.note.commit(&self.zone_id, self.nf_sk.commit()).0);
|
||||||
|
|
||||||
let nonce_bytes: [u8; 32] = hasher.finalize().into();
|
let nonce_bytes: [u8; 32] = hasher.finalize().into();
|
||||||
Nonce::from_bytes(nonce_bytes)
|
Nonce::from_bytes(nonce_bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evolve_output(&self, tag: &dyn AsRef<[u8]>, domain: &[u8]) -> OutputWitness {
|
pub fn evolve_output(&self, domain: &[u8]) -> OutputWitness {
|
||||||
OutputWitness {
|
OutputWitness {
|
||||||
note: NoteWitness {
|
note: NoteWitness {
|
||||||
nonce: self.evolved_nonce(tag, domain),
|
nonce: self.evolved_nonce(domain),
|
||||||
..self.note
|
..self.note
|
||||||
},
|
},
|
||||||
nf_pk: self.nf_sk.commit(),
|
nf_pk: self.nf_sk.commit(),
|
||||||
|
zone_id: self.zone_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nullifier(&self, tag: &dyn AsRef<[u8]>) -> Nullifier {
|
pub fn nullifier(&self) -> Nullifier {
|
||||||
Nullifier::new(tag, self.nf_sk, self.note_commitment(tag))
|
Nullifier::new(&self.zone_id, self.nf_sk, self.note_commitment())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn commit(&self, zone_id: ZoneId) -> Input {
|
pub fn commit(&self) -> Input {
|
||||||
Input {
|
Input {
|
||||||
nullifier: self.nullifier(&zone_id),
|
nullifier: self.nullifier(),
|
||||||
constraint: self.note.constraint,
|
constraint: self.note.constraint,
|
||||||
zone_id,
|
zone_id: self.zone_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn note_commitment(&self, tag: &dyn AsRef<[u8]>) -> NoteCommitment {
|
pub fn note_commitment(&self) -> NoteCommitment {
|
||||||
self.note.commit(tag, self.nf_sk.commit())
|
self.note.commit(&self.zone_id, self.nf_sk.commit())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,10 +65,11 @@ impl MMR {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn commit(&self) -> [u8; 32] {
|
pub fn commit(&self) -> [u8; 32] {
|
||||||
|
// todo: baggin the peaks
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
for mrr_root in self.roots.iter() {
|
for mmr_root in self.roots.iter() {
|
||||||
hasher.update(mrr_root.root);
|
hasher.update(mmr_root.root);
|
||||||
hasher.update(mrr_root.height.to_le_bytes());
|
hasher.update(mmr_root.height.to_le_bytes());
|
||||||
}
|
}
|
||||||
hasher.finalize().into()
|
hasher.finalize().into()
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ pub mod output;
|
|||||||
pub mod partial_tx;
|
pub mod partial_tx;
|
||||||
|
|
||||||
pub use balance::{Balance, BalanceWitness};
|
pub use balance::{Balance, BalanceWitness};
|
||||||
pub use bundle::{Bundle, BundleWitness};
|
pub use bundle::Bundle;
|
||||||
pub use input::{Input, InputWitness};
|
pub use input::{Input, InputWitness};
|
||||||
pub use note::{Constraint, Nonce, NoteCommitment, NoteWitness};
|
pub use note::{Constraint, Nonce, NoteCommitment, NoteWitness};
|
||||||
pub use nullifier::{Nullifier, NullifierCommitment, NullifierSecret};
|
pub use nullifier::{Nullifier, NullifierCommitment, NullifierSecret};
|
||||||
|
@ -19,26 +19,35 @@ pub struct Output {
|
|||||||
pub struct OutputWitness {
|
pub struct OutputWitness {
|
||||||
pub note: NoteWitness,
|
pub note: NoteWitness,
|
||||||
pub nf_pk: NullifierCommitment,
|
pub nf_pk: NullifierCommitment,
|
||||||
|
pub zone_id: ZoneId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OutputWitness {
|
impl OutputWitness {
|
||||||
pub fn new(note: NoteWitness, nf_pk: NullifierCommitment) -> Self {
|
pub fn new(note: NoteWitness, nf_pk: NullifierCommitment, zone_id: ZoneId) -> Self {
|
||||||
Self { note, nf_pk }
|
Self {
|
||||||
}
|
note,
|
||||||
|
nf_pk,
|
||||||
pub fn public(note: NoteWitness) -> Self {
|
|
||||||
let nf_pk = NullifierSecret::zero().commit();
|
|
||||||
Self { note, nf_pk }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn commit_note(&self, tag: &dyn AsRef<[u8]>) -> NoteCommitment {
|
|
||||||
self.note.commit(tag, self.nf_pk)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn commit(&self, zone_id: ZoneId) -> Output {
|
|
||||||
Output {
|
|
||||||
zone_id,
|
zone_id,
|
||||||
note_comm: self.commit_note(&zone_id),
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn public(note: NoteWitness, zone_id: ZoneId) -> Self {
|
||||||
|
let nf_pk = NullifierSecret::zero().commit();
|
||||||
|
Self {
|
||||||
|
note,
|
||||||
|
nf_pk,
|
||||||
|
zone_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn commit_note(&self) -> NoteCommitment {
|
||||||
|
self.note.commit(&self.zone_id, self.nf_pk)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn commit(&self) -> Output {
|
||||||
|
Output {
|
||||||
|
zone_id: self.zone_id,
|
||||||
|
note_comm: self.commit_note(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
use rand_core::{CryptoRngCore, RngCore};
|
use rand_core::{CryptoRngCore, RngCore};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::cl::{
|
||||||
cl::{
|
balance::{Balance, BalanceWitness},
|
||||||
balance::{Balance, BalanceWitness},
|
input::{Input, InputWitness},
|
||||||
input::{Input, InputWitness},
|
merkle,
|
||||||
merkle,
|
output::{Output, OutputWitness},
|
||||||
output::{Output, OutputWitness},
|
|
||||||
},
|
|
||||||
zone_layer::notes::ZoneId,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const MAX_INPUTS: usize = 8;
|
pub const MAX_INPUTS: usize = 8;
|
||||||
@ -68,33 +65,17 @@ impl PartialTxWitness {
|
|||||||
BalanceWitness::from_ptx(self, self.balance_blinding)
|
BalanceWitness::from_ptx(self, self.balance_blinding)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn commit(&self, input_zones: &[ZoneId], output_zones: &[ZoneId]) -> PartialTx {
|
pub fn commit(&self) -> PartialTx {
|
||||||
assert_eq!(self.inputs.len(), input_zones.len());
|
|
||||||
assert_eq!(self.outputs.len(), output_zones.len());
|
|
||||||
PartialTx {
|
PartialTx {
|
||||||
inputs: self
|
inputs: self.inputs.iter().map(InputWitness::commit).collect(),
|
||||||
.inputs
|
outputs: self.outputs.iter().map(OutputWitness::commit).collect(),
|
||||||
.iter()
|
|
||||||
.zip(input_zones.iter())
|
|
||||||
.map(|(i, z)| i.commit(*z))
|
|
||||||
.collect(),
|
|
||||||
|
|
||||||
outputs: self
|
|
||||||
.outputs
|
|
||||||
.iter()
|
|
||||||
.zip(output_zones.iter())
|
|
||||||
.map(|(o, z)| o.commit(*z))
|
|
||||||
.collect(),
|
|
||||||
balance: self.balance().commit(),
|
balance: self.balance().commit(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_witness(&self, zone_id: ZoneId, idx: usize) -> PartialTxInputWitness {
|
pub fn input_witness(&self, idx: usize) -> PartialTxInputWitness {
|
||||||
let input_bytes = Vec::from_iter(
|
let input_bytes =
|
||||||
self.inputs
|
Vec::from_iter(self.inputs.iter().map(|i| i.commit().to_bytes().to_vec()));
|
||||||
.iter()
|
|
||||||
.map(|i| i.commit(zone_id).to_bytes().to_vec()),
|
|
||||||
);
|
|
||||||
let input_merkle_leaves = merkle::padded_leaves::<MAX_INPUTS>(&input_bytes);
|
let input_merkle_leaves = merkle::padded_leaves::<MAX_INPUTS>(&input_bytes);
|
||||||
|
|
||||||
let path = merkle::path(input_merkle_leaves, idx);
|
let path = merkle::path(input_merkle_leaves, idx);
|
||||||
@ -102,12 +83,9 @@ impl PartialTxWitness {
|
|||||||
PartialTxInputWitness { input, path }
|
PartialTxInputWitness { input, path }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn output_witness(&self, zone_id: ZoneId, idx: usize) -> PartialTxOutputWitness {
|
pub fn output_witness(&self, idx: usize) -> PartialTxOutputWitness {
|
||||||
let output_bytes = Vec::from_iter(
|
let output_bytes =
|
||||||
self.outputs
|
Vec::from_iter(self.outputs.iter().map(|o| o.commit().to_bytes().to_vec()));
|
||||||
.iter()
|
|
||||||
.map(|o| o.commit(zone_id).to_bytes().to_vec()),
|
|
||||||
);
|
|
||||||
let output_merkle_leaves = merkle::padded_leaves::<MAX_OUTPUTS>(&output_bytes);
|
let output_merkle_leaves = merkle::padded_leaves::<MAX_OUTPUTS>(&output_bytes);
|
||||||
|
|
||||||
let path = merkle::path(output_merkle_leaves, idx);
|
let path = merkle::path(output_merkle_leaves, idx);
|
||||||
@ -151,8 +129,8 @@ pub struct PartialTxInputWitness {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PartialTxInputWitness {
|
impl PartialTxInputWitness {
|
||||||
pub fn input_root(&self, zone_id: ZoneId) -> [u8; 32] {
|
pub fn input_root(&self) -> [u8; 32] {
|
||||||
let leaf = merkle::leaf(&self.input.commit(zone_id).to_bytes());
|
let leaf = merkle::leaf(&self.input.commit().to_bytes());
|
||||||
merkle::path_root(leaf, &self.path)
|
merkle::path_root(leaf, &self.path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,8 +143,8 @@ pub struct PartialTxOutputWitness {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PartialTxOutputWitness {
|
impl PartialTxOutputWitness {
|
||||||
pub fn output_root(&self, zone_id: ZoneId) -> [u8; 32] {
|
pub fn output_root(&self) -> [u8; 32] {
|
||||||
let leaf = merkle::leaf(&self.output.commit(zone_id).to_bytes());
|
let leaf = merkle::leaf(&self.output.commit().to_bytes());
|
||||||
merkle::path_root(leaf, &self.path)
|
merkle::path_root(leaf, &self.path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
use cl::cl::{
|
use cl::{
|
||||||
note::derive_unit, BalanceWitness, BundleWitness, InputWitness, NoteWitness,
|
cl::{
|
||||||
NullifierCommitment, NullifierSecret, OutputWitness, PartialTxWitness,
|
note::derive_unit, BalanceWitness, InputWitness, NoteWitness, NullifierCommitment,
|
||||||
|
NullifierSecret, OutputWitness, PartialTxWitness,
|
||||||
|
},
|
||||||
|
zone_layer::notes::ZoneId,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn receive_utxo(note: NoteWitness, nf_pk: NullifierCommitment) -> OutputWitness {
|
fn receive_utxo(note: NoteWitness, nf_pk: NullifierCommitment, zone_id: ZoneId) -> OutputWitness {
|
||||||
OutputWitness::new(note, nf_pk)
|
OutputWitness::new(note, nf_pk, zone_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple_transfer() {
|
fn test_simple_transfer() {
|
||||||
let nmo = derive_unit("NMO");
|
let nmo = derive_unit("NMO");
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
let zone_id = [0; 32];
|
||||||
|
|
||||||
let sender_nf_sk = NullifierSecret::random(&mut rng);
|
let sender_nf_sk = NullifierSecret::random(&mut rng);
|
||||||
let sender_nf_pk = sender_nf_sk.commit();
|
let sender_nf_pk = sender_nf_sk.commit();
|
||||||
@ -18,12 +22,16 @@ fn test_simple_transfer() {
|
|||||||
let recipient_nf_pk = NullifierSecret::random(&mut rng).commit();
|
let recipient_nf_pk = NullifierSecret::random(&mut rng).commit();
|
||||||
|
|
||||||
// Assume the sender has received an unspent output from somewhere
|
// Assume the sender has received an unspent output from somewhere
|
||||||
let utxo = receive_utxo(NoteWitness::basic(10, nmo, &mut rng), sender_nf_pk);
|
let utxo = receive_utxo(NoteWitness::basic(10, nmo, &mut rng), sender_nf_pk, zone_id);
|
||||||
|
|
||||||
// and wants to send 8 NMO to some recipient and return 2 NMO to itself.
|
// and wants to send 8 NMO to some recipient and return 2 NMO to itself.
|
||||||
let recipient_output =
|
let recipient_output = OutputWitness::new(
|
||||||
OutputWitness::new(NoteWitness::basic(8, nmo, &mut rng), recipient_nf_pk);
|
NoteWitness::basic(8, nmo, &mut rng),
|
||||||
let change_output = OutputWitness::new(NoteWitness::basic(2, nmo, &mut rng), sender_nf_pk);
|
recipient_nf_pk,
|
||||||
|
zone_id,
|
||||||
|
);
|
||||||
|
let change_output =
|
||||||
|
OutputWitness::new(NoteWitness::basic(2, nmo, &mut rng), sender_nf_pk, zone_id);
|
||||||
|
|
||||||
let ptx_witness = PartialTxWitness {
|
let ptx_witness = PartialTxWitness {
|
||||||
inputs: vec![InputWitness::from_output(utxo, sender_nf_sk)],
|
inputs: vec![InputWitness::from_output(utxo, sender_nf_sk)],
|
||||||
@ -31,10 +39,5 @@ fn test_simple_transfer() {
|
|||||||
balance_blinding: BalanceWitness::random_blinding(&mut rng),
|
balance_blinding: BalanceWitness::random_blinding(&mut rng),
|
||||||
};
|
};
|
||||||
|
|
||||||
let bundle = BundleWitness {
|
assert!(ptx_witness.balance().is_zero())
|
||||||
partials: vec![ptx_witness],
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(bundle.balance().is_zero())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ pub struct ProvedLedgerTransition {
|
|||||||
// TODO: find a better name
|
// TODO: find a better name
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ProvedBundle {
|
pub struct ProvedBundle {
|
||||||
pub bundle: ProvedBalance,
|
pub balance: ProvedBalance,
|
||||||
pub ptxs: Vec<ProvedPartialTx>,
|
pub ptxs: Vec<ProvedPartialTx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ impl ProvedBundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn proofs(&self) -> Vec<risc0_zkvm::Receipt> {
|
fn proofs(&self) -> Vec<risc0_zkvm::Receipt> {
|
||||||
let mut proofs = vec![self.bundle.risc0_receipt.clone()];
|
let mut proofs = vec![self.balance.risc0_receipt.clone()];
|
||||||
proofs.extend(self.ptxs.iter().map(|p| p.risc0_receipt.clone()));
|
proofs.extend(self.ptxs.iter().map(|p| p.risc0_receipt.clone()));
|
||||||
proofs
|
proofs
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ use ledger_proof_statements::ptx::{PtxPrivate, PtxPublic};
|
|||||||
|
|
||||||
use crate::error::{Error, Result};
|
use crate::error::{Error, Result};
|
||||||
use cl::cl::{merkle, PartialTxWitness};
|
use cl::cl::{merkle, PartialTxWitness};
|
||||||
use cl::zone_layer::notes::ZoneId;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ProvedPartialTx {
|
pub struct ProvedPartialTx {
|
||||||
@ -15,15 +14,11 @@ impl ProvedPartialTx {
|
|||||||
ptx_witness: PartialTxWitness,
|
ptx_witness: PartialTxWitness,
|
||||||
input_cm_paths: Vec<Vec<merkle::PathNode>>,
|
input_cm_paths: Vec<Vec<merkle::PathNode>>,
|
||||||
cm_roots: Vec<[u8; 32]>,
|
cm_roots: Vec<[u8; 32]>,
|
||||||
from: Vec<ZoneId>,
|
|
||||||
to: Vec<ZoneId>,
|
|
||||||
) -> Result<ProvedPartialTx> {
|
) -> Result<ProvedPartialTx> {
|
||||||
let ptx_private = PtxPrivate {
|
let ptx_private = PtxPrivate {
|
||||||
ptx: ptx_witness,
|
ptx: ptx_witness,
|
||||||
input_cm_paths,
|
input_cm_paths,
|
||||||
cm_roots: cm_roots.clone(),
|
cm_roots: cm_roots.clone(),
|
||||||
from,
|
|
||||||
to,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let env = risc0_zkvm::ExecutorEnv::builder()
|
let env = risc0_zkvm::ExecutorEnv::builder()
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
use cl::{
|
use cl::{
|
||||||
cl::{
|
cl::{
|
||||||
balance::Unit, merkle, mmr::MMR, note::derive_unit, BalanceWitness, BundleWitness,
|
balance::Unit, merkle, mmr::MMR, note::derive_unit, BalanceWitness, InputWitness,
|
||||||
InputWitness, NoteWitness, NullifierCommitment, NullifierSecret, OutputWitness,
|
NoteWitness, NullifierCommitment, NullifierSecret, OutputWitness, PartialTxWitness,
|
||||||
PartialTxWitness,
|
|
||||||
},
|
},
|
||||||
zone_layer::{
|
zone_layer::{
|
||||||
ledger::LedgerWitness,
|
ledger::LedgerWitness,
|
||||||
notes::ZoneNote,
|
notes::{ZoneId, ZoneNote},
|
||||||
tx::{UpdateBundle, ZoneUpdate},
|
tx::{UpdateBundle, ZoneUpdate},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -43,8 +42,8 @@ impl User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive_utxo(note: NoteWitness, nf_pk: NullifierCommitment) -> OutputWitness {
|
fn receive_utxo(note: NoteWitness, nf_pk: NullifierCommitment, zone_id: ZoneId) -> OutputWitness {
|
||||||
OutputWitness::new(note, nf_pk)
|
OutputWitness::new(note, nf_pk, zone_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cross_transfer_transition(
|
fn cross_transfer_transition(
|
||||||
@ -52,18 +51,23 @@ fn cross_transfer_transition(
|
|||||||
input_path: Vec<merkle::PathNode>,
|
input_path: Vec<merkle::PathNode>,
|
||||||
to: User,
|
to: User,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
zone_a: [u8; 32],
|
zone_a: ZoneId,
|
||||||
zone_b: [u8; 32],
|
zone_b: ZoneId,
|
||||||
mut ledger_a: LedgerWitness,
|
mut ledger_a: LedgerWitness,
|
||||||
mut ledger_b: LedgerWitness,
|
mut ledger_b: LedgerWitness,
|
||||||
) -> (ProvedLedgerTransition, ProvedLedgerTransition) {
|
) -> (ProvedLedgerTransition, ProvedLedgerTransition) {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
assert!(amount <= input.note.value);
|
assert!(amount <= input.note.value);
|
||||||
let change = input.note.value - amount;
|
let change = input.note.value - amount;
|
||||||
let transfer = OutputWitness::new(NoteWitness::basic(amount, *nmo(), &mut rng), to.pk());
|
let transfer = OutputWitness::new(
|
||||||
|
NoteWitness::basic(amount, *nmo(), &mut rng),
|
||||||
|
to.pk(),
|
||||||
|
zone_b,
|
||||||
|
);
|
||||||
let change = OutputWitness::new(
|
let change = OutputWitness::new(
|
||||||
NoteWitness::basic(change, *nmo(), &mut rng),
|
NoteWitness::basic(change, *nmo(), &mut rng),
|
||||||
input.nf_sk.commit(),
|
input.nf_sk.commit(),
|
||||||
|
zone_a,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Construct the ptx consuming the input and producing the two outputs.
|
// Construct the ptx consuming the input and producing the two outputs.
|
||||||
@ -76,24 +80,22 @@ fn cross_transfer_transition(
|
|||||||
ptx_witness.clone(),
|
ptx_witness.clone(),
|
||||||
vec![input_path],
|
vec![input_path],
|
||||||
vec![ledger_a.commitments.roots[0].root],
|
vec![ledger_a.commitments.roots[0].root],
|
||||||
vec![zone_a],
|
|
||||||
vec![zone_b, zone_a],
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let bundle = ProvedBalance::prove(&BalancePrivate {
|
let balance = ProvedBalance::prove(&BalancePrivate {
|
||||||
balances: vec![ptx_witness.balance()],
|
balances: vec![ptx_witness.balance()],
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let zone_tx = ProvedBundle {
|
let zone_tx = ProvedBundle {
|
||||||
ptxs: vec![proved_ptx.clone()],
|
ptxs: vec![proved_ptx.clone()],
|
||||||
bundle,
|
balance,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Prove the constraints for alices input (she uses the no-op constraint)
|
// Prove the constraints for alices input (she uses the no-op constraint)
|
||||||
let constraint_proof =
|
let constraint_proof =
|
||||||
ConstraintProof::prove_nop(input.nullifier(&zone_a), proved_ptx.public.ptx.root());
|
ConstraintProof::prove_nop(input.nullifier(), proved_ptx.public.ptx.root());
|
||||||
|
|
||||||
let ledger_a_transition = ProvedLedgerTransition::prove(
|
let ledger_a_transition = ProvedLedgerTransition::prove(
|
||||||
ledger_a.clone(),
|
ledger_a.clone(),
|
||||||
@ -106,10 +108,10 @@ fn cross_transfer_transition(
|
|||||||
let ledger_b_transition =
|
let ledger_b_transition =
|
||||||
ProvedLedgerTransition::prove(ledger_b.clone(), zone_b, vec![zone_tx], vec![]).unwrap();
|
ProvedLedgerTransition::prove(ledger_b.clone(), zone_b, vec![zone_tx], vec![]).unwrap();
|
||||||
|
|
||||||
ledger_a.commitments.push(&change.commit_note(&zone_a).0);
|
ledger_a.commitments.push(&change.commit_note().0);
|
||||||
ledger_a.nullifiers.push(input.nullifier(&zone_a));
|
ledger_a.nullifiers.push(input.nullifier());
|
||||||
|
|
||||||
ledger_b.commitments.push(&transfer.commit_note(&zone_b).0);
|
ledger_b.commitments.push(&transfer.commit_note().0);
|
||||||
|
|
||||||
assert_eq!(ledger_a_transition.public.ledger, ledger_a.commit());
|
assert_eq!(ledger_a_transition.public.ledger, ledger_a.commit());
|
||||||
assert_eq!(ledger_b_transition.public.ledger, ledger_b.commit());
|
assert_eq!(ledger_b_transition.public.ledger, ledger_b.commit());
|
||||||
@ -121,6 +123,9 @@ fn cross_transfer_transition(
|
|||||||
fn zone_update_cross() {
|
fn zone_update_cross() {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let zone_a_id = [0; 32];
|
||||||
|
let zone_b_id = [1; 32];
|
||||||
|
|
||||||
// alice is sending 8 NMO to bob.
|
// alice is sending 8 NMO to bob.
|
||||||
|
|
||||||
let alice = User::random(&mut rng);
|
let alice = User::random(&mut rng);
|
||||||
@ -130,15 +135,13 @@ fn zone_update_cross() {
|
|||||||
let utxo = receive_utxo(
|
let utxo = receive_utxo(
|
||||||
NoteWitness::stateless(10, *nmo(), ConstraintProof::nop_constraint(), &mut rng),
|
NoteWitness::stateless(10, *nmo(), ConstraintProof::nop_constraint(), &mut rng),
|
||||||
alice.pk(),
|
alice.pk(),
|
||||||
|
zone_a_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
let alice_input = InputWitness::from_output(utxo, alice.sk());
|
let alice_input = InputWitness::from_output(utxo, alice.sk());
|
||||||
|
|
||||||
let zone_a_id = [0; 32];
|
|
||||||
let zone_b_id = [1; 32];
|
|
||||||
|
|
||||||
let mut mmr = MMR::new();
|
let mut mmr = MMR::new();
|
||||||
let input_cm_path = mmr.push(&utxo.commit_note(&zone_a_id).0).path;
|
let input_cm_path = mmr.push(&utxo.commit_note().0).path;
|
||||||
|
|
||||||
let ledger_a = LedgerWitness {
|
let ledger_a = LedgerWitness {
|
||||||
commitments: mmr,
|
commitments: mmr,
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
use cl::{
|
use cl::cl::{merkle, PartialTx, PartialTxWitness};
|
||||||
cl::{merkle, PartialTx, PartialTxWitness},
|
|
||||||
zone_layer::notes::ZoneId,
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
@ -15,6 +12,4 @@ pub struct PtxPrivate {
|
|||||||
pub ptx: PartialTxWitness,
|
pub ptx: PartialTxWitness,
|
||||||
pub input_cm_paths: Vec<Vec<merkle::PathNode>>,
|
pub input_cm_paths: Vec<Vec<merkle::PathNode>>,
|
||||||
pub cm_roots: Vec<[u8; 32]>,
|
pub cm_roots: Vec<[u8; 32]>,
|
||||||
pub from: Vec<ZoneId>,
|
|
||||||
pub to: Vec<ZoneId>,
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user