mirror of
https://github.com/logos-blockchain/logos-blockchain-specs.git
synced 2026-01-06 15:13:14 +00:00
98 lines
2.5 KiB
Rust
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())
|
|
);
|
|
}
|
|
}
|