From 57687cf70fee8c797211900226dbe406d0cc57fb Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sat, 24 Feb 2018 22:53:00 -0700 Subject: [PATCH] Creation of the Note primitive. --- src/lib.rs | 1 + src/pedersen_hash.rs | 2 +- src/primitives/mod.rs | 65 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/primitives/mod.rs diff --git a/src/lib.rs b/src/lib.rs index 48af45c..4a08bf9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,3 +14,4 @@ pub mod jubjub; pub mod circuit; pub mod group_hash; pub mod pedersen_hash; +pub mod primitives; diff --git a/src/pedersen_hash.rs b/src/pedersen_hash.rs index 12e5c7d..1eb75f6 100644 --- a/src/pedersen_hash.rs +++ b/src/pedersen_hash.rs @@ -1,7 +1,7 @@ use jubjub::*; use pairing::*; -use circuit::pedersen_hash::Personalization; +pub use circuit::pedersen_hash::Personalization; pub fn pedersen_hash( personalization: Personalization, diff --git a/src/primitives/mod.rs b/src/primitives/mod.rs new file mode 100644 index 0000000..7a99092 --- /dev/null +++ b/src/primitives/mod.rs @@ -0,0 +1,65 @@ +use pedersen_hash::{ + pedersen_hash, + Personalization +}; + +use byteorder::{ + BigEndian, + ByteOrder +}; + +use jubjub::{ + JubjubEngine, + JubjubParams, + edwards, + PrimeOrder, + FixedGenerators +}; + +pub struct Note { + /// The value of the note + pub value: u64, + /// The diversified base of the address, GH(d) + pub g_d: edwards::Point, + /// The public key of the address, g_d^ivk + pub pk_d: edwards::Point, + /// The commitment randomness + pub r: E::Fs +} + +impl Note { + /// Computes the note commitment + pub fn cm(&self, params: &E::Params) -> E::Fr + { + // Calculate the note contents, as bytes + let mut note_contents = vec![]; + + // Write the value in big endian + BigEndian::write_u64(&mut note_contents, self.value); + + // Write g_d + self.g_d.write(&mut note_contents).unwrap(); + + // Write pk_d + self.pk_d.write(&mut note_contents).unwrap(); + + // Compute the Pedersen hash of the note contents + let hash_of_contents = pedersen_hash( + Personalization::NoteCommitment, + note_contents.into_iter() + .flat_map(|byte| { + (0..8).rev().map(move |i| ((byte >> i) & 1) == 1) + }), + params + ); + + // Compute final commitment + let cm = params.generator(FixedGenerators::NoteCommitmentRandomness) + .mul(self.r, params) + .add(&hash_of_contents, params); + + // The commitment is in the prime order subgroup, so mapping the + // commitment to the x-coordinate is an injective encoding. + cm.into_xy().0 + } +}