98 lines
2.5 KiB
Rust

use blake2::{Blake2s256, Digest};
use group::GroupEncoding;
use jubjub::{ExtendedPoint, Scalar};
use crate::nullifier::{NullifierCommitment, NullifierNonce};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NoteCommitment([u8; 32]);
impl NoteCommitment {
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Note {
pub value: u64,
pub unit: String,
}
impl Note {
pub fn new(value: u64, unit: impl Into<String>) -> Self {
Self {
value,
unit: unit.into(),
}
}
pub fn unit_point(&self) -> ExtendedPoint {
crate::balance::unit_point(&self.unit)
}
pub fn balance(&self, blinding: Scalar) -> ExtendedPoint {
crate::balance::balance(self.value, &self.unit, blinding)
}
pub fn commit(&self, nf_pk: NullifierCommitment, nonce: NullifierNonce) -> NoteCommitment {
let mut hasher = Blake2s256::new();
hasher.update(b"NOMOS_CL_NOTE_COMMIT");
hasher.update(self.value.to_le_bytes());
hasher.update(self.unit_point().to_bytes());
hasher.update(nf_pk.as_bytes());
hasher.update(nonce.as_bytes());
let commit_bytes: [u8; 32] = hasher.finalize().into();
NoteCommitment(commit_bytes)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_balance_zero_unitless() {
// Zero is the same across all units
let r = Scalar::from(32);
assert_eq!(
Note::new(0, "NMO").balance(r),
Note::new(0, "ETH").balance(r)
);
}
#[test]
fn test_balance_blinding() {
// balances are blinded
let r1 = Scalar::from(12);
let r2 = Scalar::from(8);
let a = Note::new(10, "NMO");
assert_ne!(a.balance(r1), a.balance(r2));
assert_eq!(a.balance(r1), a.balance(r1));
}
#[test]
fn test_balance_units() {
// Unit's differentiate between values.
let nmo = Note::new(10, "NMO");
let eth = Note::new(10, "ETH");
let r = Scalar::from(1337);
assert_ne!(nmo.balance(r), eth.balance(r));
}
#[test]
fn test_balance_homomorphism() {
let r = Scalar::from(32);
let ten = Note::new(10, "NMO");
let eight = Note::new(8, "NMO");
let two = Note::new(2, "NMO");
assert_eq!(ten.balance(r) - eight.balance(r), two.balance(0.into()));
assert_eq!(
ten.balance(54.into()) - ten.balance(48.into()),
Note::new(0, "NMO").balance(6.into())
);
}
}