goas: unlink input and output balance commitments

This commit is contained in:
David Rusu 2024-07-17 21:54:53 +04:00
parent b20121e293
commit e57566d674
6 changed files with 225 additions and 247 deletions

View File

@ -2,6 +2,9 @@ use curve25519_dalek::{ristretto::RistrettoPoint, traits::VartimeMultiscalarMul,
use lazy_static::lazy_static;
use rand_core::CryptoRngCore;
use serde::{Deserialize, Serialize};
use crate::NoteWitness;
lazy_static! {
// Precompute of ``
static ref PEDERSON_COMMITMENT_BLINDING_POINT: RistrettoPoint = crate::crypto::hash_to_curve(b"NOMOS_CL_PEDERSON_COMMITMENT_BLINDING");
@ -11,40 +14,28 @@ lazy_static! {
pub struct Balance(pub RistrettoPoint);
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
pub struct BalanceWitness {
pub value: u64,
pub unit: RistrettoPoint,
pub blinding: Scalar,
}
pub struct BalanceWitness(pub Scalar);
impl Balance {
pub fn to_bytes(&self) -> [u8; 32] {
self.0.compress().to_bytes().into()
self.0.compress().to_bytes()
}
}
impl BalanceWitness {
pub fn new(value: u64, unit: impl Into<String>, blinding: Scalar) -> Self {
Self {
value,
unit: unit_point(&unit.into()),
blinding,
}
pub fn new(blinding: Scalar) -> Self {
Self(blinding)
}
pub fn random(value: u64, unit: impl Into<String>, mut rng: impl CryptoRngCore) -> Self {
Self::new(value, unit, Scalar::random(&mut rng))
pub fn random(mut rng: impl CryptoRngCore) -> Self {
Self::new(Scalar::random(&mut rng))
}
pub fn commit(&self) -> Balance {
Balance(balance(self.value, self.unit, self.blinding))
pub fn commit(&self, note: &NoteWitness) -> Balance {
Balance(balance(note.value, note.unit, self.0))
}
}
pub fn unit_point(unit: &str) -> RistrettoPoint {
crate::crypto::hash_to_curve(unit.as_bytes())
}
pub fn balance(value: u64, unit: RistrettoPoint, blinding: Scalar) -> RistrettoPoint {
let value_scalar = Scalar::from(value);
// can vartime leak the number of cycles through the stark proof?
@ -54,97 +45,6 @@ pub fn balance(value: u64, unit: RistrettoPoint, blinding: Scalar) -> RistrettoP
)
}
// mod serde_scalar {
// use super::Scalar;
// use serde::de::{self, Visitor};
// use serde::{Deserializer, Serializer};
// use std::fmt;
// // Serialize a SubgroupPoint by converting it to bytes.
// pub fn serialize<S>(scalar: &Scalar, serializer: S) -> Result<S::Ok, S::Error>
// where
// S: Serializer,
// {
// let bytes = scalar.to_bytes();
// serializer.serialize_bytes(&bytes)
// }
// // Deserialize a SubgroupPoint by converting it from bytes.
// pub fn deserialize<'de, D>(deserializer: D) -> Result<Scalar, D::Error>
// where
// D: Deserializer<'de>,
// {
// struct BytesVisitor;
// impl<'de> Visitor<'de> for BytesVisitor {
// type Value = Scalar;
// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
// formatter.write_str("a valid Scalar in byte representation")
// }
// fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
// where
// E: de::Error,
// {
// let mut bytes = <jubjub::SubgroupPoint as group::GroupEncoding>::Repr::default();
// assert_eq!(bytes.len(), v.len());
// bytes.copy_from_slice(v);
// Ok(Scalar::from_bytes(&bytes).unwrap())
// }
// }
// deserializer.deserialize_bytes(BytesVisitor)
// }
// }
// mod serde_point {
// use super::SubgroupPoint;
// use group::GroupEncoding;
// use serde::de::{self, Visitor};
// use serde::{Deserializer, Serializer};
// use std::fmt;
// // Serialize a SubgroupPoint by converting it to bytes.
// pub fn serialize<S>(point: &SubgroupPoint, serializer: S) -> Result<S::Ok, S::Error>
// where
// S: Serializer,
// {
// let bytes = point.to_bytes();
// serializer.serialize_bytes(&bytes)
// }
// // Deserialize a SubgroupPoint by converting it from bytes.
// pub fn deserialize<'de, D>(deserializer: D) -> Result<SubgroupPoint, D::Error>
// where
// D: Deserializer<'de>,
// {
// struct BytesVisitor;
// impl<'de> Visitor<'de> for BytesVisitor {
// type Value = SubgroupPoint;
// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
// formatter.write_str("a valid SubgroupPoint in byte representation")
// }
// fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
// where
// E: de::Error,
// {
// let mut bytes = <jubjub::SubgroupPoint as group::GroupEncoding>::Repr::default();
// assert_eq!(bytes.len(), v.len());
// bytes.copy_from_slice(v);
// Ok(SubgroupPoint::from_bytes(&bytes).unwrap())
// }
// }
// deserializer.deserialize_bytes(BytesVisitor)
// }
// }
#[cfg(test)]
mod test {
@ -165,52 +65,67 @@ mod test {
fn test_balance_zero_unitless() {
// Zero is the same across all units
let mut rng = rand::thread_rng();
let r = Scalar::random(&mut rng);
let b = BalanceWitness::random(&mut rng);
assert_eq!(
BalanceWitness::new(0, "NMO", r).commit(),
BalanceWitness::new(0, "ETH", r).commit(),
b.commit(&NoteWitness::basic(0, "NMO")),
b.commit(&NoteWitness::basic(0, "ETH")),
);
}
#[test]
fn test_balance_blinding() {
// balances are blinded
let r1 = Scalar::from(12u32);
let r2 = Scalar::from(8u32);
let a_w = BalanceWitness::new(10, "NMO", r1);
let b_w = BalanceWitness::new(10, "NMO", r2);
let a = a_w.commit();
let b = b_w.commit();
let r_a = Scalar::from(12u32);
let r_b = Scalar::from(8u32);
let bal_a = BalanceWitness::new(r_a);
let bal_b = BalanceWitness::new(r_b);
let note = NoteWitness::basic(10, "NMO");
let a = bal_a.commit(&note);
let b = bal_b.commit(&note);
assert_ne!(a, b);
assert_eq!(a.0 - b.0, BalanceWitness::new(0, "NMO", r1 - r2).commit().0);
let diff_note = NoteWitness::basic(0, "NMO");
assert_eq!(
a.0 - b.0,
BalanceWitness::new(r_a - r_b).commit(&diff_note).0
);
}
#[test]
fn test_balance_units() {
// Unit's differentiate between values.
let r = Scalar::from(1337u32);
let nmo = BalanceWitness::new(10, "NMO", r);
let eth = BalanceWitness::new(10, "ETH", r);
assert_ne!(nmo.commit(), eth.commit());
let b = BalanceWitness::new(Scalar::from(1337u32));
let nmo = NoteWitness::basic(10, "NMO");
let eth = NoteWitness::basic(10, "ETH");
assert_ne!(b.commit(&nmo), b.commit(&eth));
}
#[test]
fn test_balance_homomorphism() {
let mut rng = rand::thread_rng();
let r1 = Scalar::random(&mut rng);
let r2 = Scalar::random(&mut rng);
let ten = BalanceWitness::new(10, "NMO", 0u32.into());
let eight = BalanceWitness::new(8, "NMO", 0u32.into());
let two = BalanceWitness::new(2, "NMO", 0u32.into());
let b1 = BalanceWitness::random(&mut rng);
let b2 = BalanceWitness::random(&mut rng);
let b_zero = BalanceWitness::new(Scalar::ZERO);
let ten = NoteWitness::basic(10, "NMO");
let eight = NoteWitness::basic(8, "NMO");
let two = NoteWitness::basic(2, "NMO");
let zero = NoteWitness::basic(0, "NMO");
// Values of same unit are homomorphic
assert_eq!(ten.commit().0 - eight.commit().0, two.commit().0);
assert_eq!(
(b1.commit(&ten).0 - b1.commit(&eight).0).compress(),
b_zero.commit(&two).0.compress()
);
// Blinding factors are also homomorphic.
assert_eq!(
BalanceWitness::new(10, "NMO", r1).commit().0
- BalanceWitness::new(10, "NMO", r2).commit().0,
BalanceWitness::new(0, "NMO", r1 - r2).commit().0
b1.commit(&ten).0 - b2.commit(&ten).0,
BalanceWitness::new(b1.0 - b2.0).commit(&zero).0
);
}
}

View File

@ -1,8 +1,8 @@
use serde::{Deserialize, Serialize};
use curve25519_dalek::{constants::RISTRETTO_BASEPOINT_POINT, ristretto::RistrettoPoint, Scalar};
use curve25519_dalek::{constants::RISTRETTO_BASEPOINT_POINT, ristretto::RistrettoPoint};
use crate::partial_tx::PartialTx;
use crate::{partial_tx::PartialTx, BalanceWitness};
/// The transaction bundle is a collection of partial transactions.
/// The goal in bundling transactions is to produce a set of partial transactions
@ -15,7 +15,7 @@ pub struct Bundle {
#[derive(Debug, Clone)]
pub struct BundleWitness {
pub balance_blinding: Scalar,
pub balance: BalanceWitness,
}
impl Bundle {
@ -23,9 +23,8 @@ impl Bundle {
self.partials.iter().map(|ptx| ptx.balance()).sum()
}
pub fn is_balanced(&self, balance_blinding_witness: Scalar) -> bool {
self.balance()
== crate::balance::balance(0, RISTRETTO_BASEPOINT_POINT, balance_blinding_witness)
pub fn is_balanced(&self, witness: BalanceWitness) -> bool {
self.balance() == crate::balance::balance(0, RISTRETTO_BASEPOINT_POINT, witness.0)
}
}
@ -42,15 +41,20 @@ mod test {
fn test_bundle_balance() {
let mut rng = rand::thread_rng();
let nmo_10_in =
InputWitness::random(NoteWitness::new(10, "NMO", [0u8; 32], &mut rng), &mut rng);
let eth_23_in =
InputWitness::random(NoteWitness::new(23, "ETH", [0u8; 32], &mut rng), &mut rng);
let crv_4840_out = OutputWitness::random(
NoteWitness::new(4840, "CRV", [0u8; 32], &mut rng),
NullifierSecret::random(&mut rng).commit(), // transferring to a random owner
&mut rng,
);
let nf_a = NullifierSecret::random(&mut rng);
let nf_b = NullifierSecret::random(&mut rng);
let nf_c = NullifierSecret::random(&mut rng);
let nmo_10_utxo =
OutputWitness::random(NoteWitness::basic(10, "NMO"), nf_a.commit(), &mut rng);
let nmo_10_in = InputWitness::random(nmo_10_utxo, nf_a, &mut rng);
let eth_23_utxo =
OutputWitness::random(NoteWitness::basic(23, "ETH"), nf_b.commit(), &mut rng);
let eth_23_in = InputWitness::random(eth_23_utxo, nf_b, &mut rng);
let crv_4840_out =
OutputWitness::random(NoteWitness::basic(4840, "CRV"), nf_c.commit(), &mut rng);
let ptx_unbalanced = PartialTxWitness {
inputs: vec![nmo_10_in.clone(), eth_23_in.clone()],
@ -58,42 +62,31 @@ mod test {
};
let bundle_witness = BundleWitness {
balance_blinding: crv_4840_out.note.balance.blinding
- nmo_10_in.note.balance.blinding
- eth_23_in.note.balance.blinding,
balance: BalanceWitness::new(
crv_4840_out.balance.0 - nmo_10_in.balance.0 - eth_23_in.balance.0,
),
};
let mut bundle = Bundle {
partials: vec![PartialTx::from_witness(ptx_unbalanced)],
};
assert!(!bundle.is_balanced(bundle_witness.balance_blinding));
assert!(!bundle.is_balanced(bundle_witness.balance));
assert_eq!(
bundle.balance(),
crate::balance::balance(
4840,
hash_to_curve(b"CRV"),
crv_4840_out.note.balance.blinding
) - (crate::balance::balance(
10,
hash_to_curve(b"NMO"),
nmo_10_in.note.balance.blinding
) + crate::balance::balance(
23,
hash_to_curve(b"ETH"),
eth_23_in.note.balance.blinding
))
crate::balance::balance(4840, hash_to_curve(b"CRV"), crv_4840_out.balance.0)
- (crate::balance::balance(10, hash_to_curve(b"NMO"), nmo_10_in.balance.0)
+ crate::balance::balance(23, hash_to_curve(b"ETH"), eth_23_in.balance.0))
);
let crv_4840_in =
InputWitness::random(NoteWitness::new(4840, "CRV", [0u8; 32], &mut rng), &mut rng);
let crv_4840_in = InputWitness::random(crv_4840_out, nf_c, &mut rng);
let nmo_10_out = OutputWitness::random(
NoteWitness::new(10, "NMO", [0u8; 32], &mut rng),
NoteWitness::basic(10, "NMO"),
NullifierSecret::random(&mut rng).commit(), // transferring to a random owner
&mut rng,
);
let eth_23_out = OutputWitness::random(
NoteWitness::new(23, "ETH", [0u8; 32], &mut rng),
NoteWitness::basic(23, "ETH"),
NullifierSecret::random(&mut rng).commit(), // transferring to a random owner
&mut rng,
);
@ -106,11 +99,12 @@ mod test {
}));
let witness = BundleWitness {
balance_blinding: -nmo_10_in.note.balance.blinding - eth_23_in.note.balance.blinding
+ crv_4840_out.note.balance.blinding
- crv_4840_in.note.balance.blinding
+ nmo_10_out.note.balance.blinding
+ eth_23_out.note.balance.blinding,
balance: BalanceWitness::new(
-nmo_10_in.balance.0 - eth_23_in.balance.0 + crv_4840_out.balance.0
- crv_4840_in.balance.0
+ nmo_10_out.balance.0
+ eth_23_out.balance.0,
),
};
assert_eq!(
@ -118,10 +112,10 @@ mod test {
crate::balance::balance(
0,
curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT,
witness.balance_blinding
witness.balance.0
)
);
assert!(bundle.is_balanced(witness.balance_blinding));
assert!(bundle.is_balanced(witness.balance));
}
}

View File

@ -6,8 +6,9 @@ use crate::{
balance::Balance,
note::{DeathCommitment, NoteWitness},
nullifier::{Nullifier, NullifierNonce, NullifierSecret},
BalanceWitness,
};
use rand_core::RngCore;
use rand_core::CryptoRngCore;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
@ -20,30 +21,44 @@ pub struct Input {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct InputWitness {
pub note: NoteWitness,
pub utxo_balance: BalanceWitness,
pub balance: BalanceWitness,
pub nf_sk: NullifierSecret,
pub nonce: NullifierNonce,
}
impl InputWitness {
pub fn random(note: NoteWitness, mut rng: impl RngCore) -> Self {
pub fn random(
output: crate::OutputWitness,
nf_sk: NullifierSecret,
mut rng: impl CryptoRngCore,
) -> Self {
assert_eq!(nf_sk.commit(), output.nf_pk);
Self {
note,
nf_sk: NullifierSecret::random(&mut rng),
nonce: NullifierNonce::random(&mut rng),
note: output.note,
utxo_balance: output.balance,
balance: BalanceWitness::random(&mut rng),
nf_sk,
nonce: output.nonce,
}
}
pub fn nullifier(&self) -> Nullifier {
Nullifier::new(self.nf_sk, self.nonce)
}
pub fn commit(&self) -> Input {
Input {
nullifier: Nullifier::new(self.nf_sk, self.nonce),
balance: self.note.balance(),
nullifier: self.nullifier(),
balance: self.balance.commit(&self.note),
death_cm: self.note.death_commitment(),
}
}
pub fn to_output_witness(&self) -> crate::OutputWitness {
pub fn to_output(&self) -> crate::OutputWitness {
crate::OutputWitness {
note: self.note.clone(),
note: self.note,
balance: self.utxo_balance,
nf_pk: self.nf_sk.commit(),
nonce: self.nonce,
}

View File

@ -1,11 +1,8 @@
use rand_core::CryptoRngCore;
use curve25519_dalek::RistrettoPoint;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use crate::{
balance::{Balance, BalanceWitness},
nullifier::{NullifierCommitment, NullifierNonce},
};
use crate::nullifier::{NullifierCommitment, NullifierNonce};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct DeathCommitment(pub [u8; 32]);
@ -19,6 +16,10 @@ pub fn death_commitment(death_constraint: &[u8]) -> DeathCommitment {
DeathCommitment(death_cm)
}
pub fn unit_point(unit: &str) -> RistrettoPoint {
crate::crypto::hash_to_curve(unit.as_bytes())
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct NoteCommitment([u8; 32]);
@ -32,32 +33,38 @@ impl NoteCommitment {
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
pub struct NoteWitness {
pub balance: BalanceWitness,
pub value: u64,
pub unit: RistrettoPoint,
pub death_constraint: [u8; 32], // death constraint verification key
pub state: [u8; 32],
}
impl NoteWitness {
pub fn new(
value: u64,
unit: impl Into<String>,
state: [u8; 32],
rng: impl CryptoRngCore,
) -> Self {
pub fn new(value: u64, unit: impl Into<String>, state: [u8; 32]) -> Self {
Self {
balance: BalanceWitness::random(value, unit, rng),
value,
unit: unit_point(&unit.into()),
death_constraint: [0u8; 32],
state,
}
}
pub fn basic(value: u64, unit: impl Into<String>) -> Self {
Self {
value,
unit: unit_point(&unit.into()),
death_constraint: [0u8; 32],
state: [0u8; 32],
}
}
pub fn commit(&self, nf_pk: NullifierCommitment, nonce: NullifierNonce) -> NoteCommitment {
let mut hasher = Sha256::new();
hasher.update(b"NOMOS_CL_NOTE_COMMIT");
// COMMIT TO BALANCE
hasher.update(self.balance.value.to_le_bytes());
hasher.update(self.balance.unit.compress().to_bytes());
hasher.update(self.value.to_le_bytes());
hasher.update(self.unit.compress().to_bytes());
// Important! we don't commit to the balance blinding factor as that may make the notes linkable.
// COMMIT TO STATE
@ -74,10 +81,6 @@ impl NoteWitness {
NoteCommitment(commit_bytes)
}
pub fn balance(&self) -> Balance {
self.balance.commit()
}
pub fn death_commitment(&self) -> DeathCommitment {
death_commitment(&self.death_constraint)
}
@ -90,18 +93,57 @@ mod test {
use super::*;
#[test]
fn test_note_commitments_dont_commit_to_balance_blinding() {
fn test_note_commit_permutations() {
let mut rng = rand::thread_rng();
let n1 = NoteWitness::new(12, "NMO", [0u8; 32], &mut rng);
let n2 = NoteWitness::new(12, "NMO", [0u8; 32], &mut rng);
let nf_pk = NullifierSecret::random(&mut rng).commit();
let nonce = NullifierNonce::random(&mut rng);
let nf_nonce = NullifierNonce::random(&mut rng);
// Balance blinding factors are different.
assert_ne!(n1.balance.blinding, n2.balance.blinding);
let reference_note = NoteWitness::new(32, "NMO", [0u8; 32]);
// But their commitments are the same.
assert_eq!(n1.commit(nf_pk, nonce), n2.commit(nf_pk, nonce));
// different notes under same nullifier produce different commitments
let mutation_tests = [
NoteWitness {
value: 12,
..reference_note
},
NoteWitness {
unit: unit_point("ETH"),
..reference_note
},
NoteWitness {
death_constraint: [1u8; 32],
..reference_note
},
NoteWitness {
state: [1u8; 32],
..reference_note
},
];
for n in mutation_tests {
assert_ne!(
n.commit(nf_pk, nf_nonce),
reference_note.commit(nf_pk, nf_nonce)
);
}
// commitment to same note with different nullifiers produce different commitments
let other_nf_pk = NullifierSecret::random(&mut rng).commit();
let other_nf_nonce = NullifierNonce::random(&mut rng);
assert_ne!(
reference_note.commit(nf_pk, nf_nonce),
reference_note.commit(other_nf_pk, nf_nonce)
);
assert_ne!(
reference_note.commit(nf_pk, nf_nonce),
reference_note.commit(nf_pk, other_nf_nonce)
);
assert_ne!(
reference_note.commit(nf_pk, nf_nonce),
reference_note.commit(other_nf_pk, other_nf_nonce)
);
}
}

View File

@ -1,4 +1,4 @@
use rand_core::RngCore;
use rand_core::CryptoRngCore;
use serde::{Deserialize, Serialize};
use crate::{
@ -6,6 +6,7 @@ use crate::{
error::Error,
note::{NoteCommitment, NoteWitness},
nullifier::{NullifierCommitment, NullifierNonce},
BalanceWitness,
};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
@ -14,17 +15,23 @@ pub struct Output {
pub balance: Balance,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct OutputWitness {
pub note: NoteWitness,
pub balance: BalanceWitness,
pub nf_pk: NullifierCommitment,
pub nonce: NullifierNonce,
}
impl OutputWitness {
pub fn random(note: NoteWitness, owner: NullifierCommitment, mut rng: impl RngCore) -> Self {
pub fn random(
note: NoteWitness,
owner: NullifierCommitment,
mut rng: impl CryptoRngCore,
) -> Self {
Self {
note,
balance: BalanceWitness::random(&mut rng),
nf_pk: owner,
nonce: NullifierNonce::random(&mut rng),
}
@ -34,10 +41,14 @@ impl OutputWitness {
self.note.commit(self.nf_pk, self.nonce)
}
pub fn commit_balance(&self) -> Balance {
self.balance.commit(&self.note)
}
pub fn commit(&self) -> Output {
Output {
note_comm: self.commit_note(),
balance: self.note.balance(),
balance: self.commit_balance(),
}
}
}
@ -61,8 +72,7 @@ impl Output {
// - balance == v * hash_to_curve(Unit) + blinding * H
let witness = &proof.0;
self.note_comm == witness.note.commit(witness.nf_pk, witness.nonce)
&& self.balance == witness.note.balance()
self.note_comm == witness.commit_note() && self.balance == witness.commit_balance()
}
pub fn to_bytes(&self) -> [u8; 64] {
@ -82,11 +92,12 @@ mod test {
fn test_output_proof() {
let mut rng = rand::thread_rng();
let note = NoteWitness::new(10, "NMO", [0u8; 32], &mut rng);
let nf_pk = NullifierSecret::random(&mut rng).commit();
let nonce = NullifierNonce::random(&mut rng);
let witness = OutputWitness { note, nf_pk, nonce };
let witness = OutputWitness {
note: NoteWitness::basic(10, "NMO"),
balance: BalanceWitness::random(&mut rng),
nf_pk: NullifierSecret::random(&mut rng).commit(),
nonce: NullifierNonce::random(&mut rng),
};
let output = witness.commit();
let proof = output.prove(&witness).unwrap();
@ -95,11 +106,15 @@ mod test {
let wrong_witnesses = [
OutputWitness {
note: NoteWitness::new(11, "NMO", [0u8; 32], &mut rng),
note: NoteWitness::basic(11, "NMO"),
..witness.clone()
},
OutputWitness {
note: NoteWitness::new(10, "ETH", [0u8; 32], &mut rng),
note: NoteWitness::basic(10, "ETH"),
..witness.clone()
},
OutputWitness {
balance: BalanceWitness::random(&mut rng),
..witness.clone()
},
OutputWitness {

View File

@ -1,6 +1,5 @@
use rand_core::RngCore;
// use risc0_groth16::ProofJson;
use curve25519_dalek::ristretto::RistrettoPoint;
use rand_core::RngCore;
use serde::{Deserialize, Serialize};
use crate::input::{Input, InputWitness};
@ -115,15 +114,20 @@ mod test {
fn test_partial_tx_balance() {
let mut rng = rand::thread_rng();
let nmo_10 =
InputWitness::random(NoteWitness::new(10, "NMO", [0u8; 32], &mut rng), &mut rng);
let eth_23 =
InputWitness::random(NoteWitness::new(23, "ETH", [0u8; 32], &mut rng), &mut rng);
let crv_4840 = OutputWitness::random(
NoteWitness::new(4840, "CRV", [0u8; 32], &mut rng),
NullifierSecret::random(&mut rng).commit(), // transferring to a random owner
&mut rng,
);
let nf_a = NullifierSecret::random(&mut rng);
let nf_b = NullifierSecret::random(&mut rng);
let nf_c = NullifierSecret::random(&mut rng);
let nmo_10_utxo =
OutputWitness::random(NoteWitness::basic(10, "NMO"), nf_a.commit(), &mut rng);
let nmo_10 = InputWitness::random(nmo_10_utxo, nf_a, &mut rng);
let eth_23_utxo =
OutputWitness::random(NoteWitness::basic(23, "ETH"), nf_b.commit(), &mut rng);
let eth_23 = InputWitness::random(eth_23_utxo, nf_b, &mut rng);
let crv_4840 =
OutputWitness::random(NoteWitness::basic(4840, "CRV"), nf_c.commit(), &mut rng);
let ptx_witness = PartialTxWitness {
inputs: vec![nmo_10.clone(), eth_23.clone()],
@ -134,16 +138,9 @@ mod test {
assert_eq!(
ptx.balance(),
crate::balance::balance(4840, hash_to_curve(b"CRV"), crv_4840.note.balance.blinding)
- (crate::balance::balance(
10,
hash_to_curve(b"NMO"),
nmo_10.note.balance.blinding
) + crate::balance::balance(
23,
hash_to_curve(b"ETH"),
eth_23.note.balance.blinding
))
crate::balance::balance(4840, hash_to_curve(b"CRV"), crv_4840.balance.0)
- (crate::balance::balance(10, hash_to_curve(b"NMO"), nmo_10.balance.0)
+ crate::balance::balance(23, hash_to_curve(b"ETH"), eth_23.balance.0))
);
}
}