From 8b78a55c711317ff9e60ab35dee3d66b1ede94dd Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Mon, 6 Jul 2020 13:16:21 -0700 Subject: [PATCH] Start work implementing sprout note commitment function --- zebra-chain/src/notes.rs | 6 ++++++ zebra-chain/src/notes/sprout.rs | 38 ++++++++++++++++++++++++--------- zebra-chain/src/types/amount.rs | 4 ++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/zebra-chain/src/notes.rs b/zebra-chain/src/notes.rs index 8f6cbf2ef..cdff16645 100644 --- a/zebra-chain/src/notes.rs +++ b/zebra-chain/src/notes.rs @@ -6,3 +6,9 @@ pub mod sprout; /// The randomness used in the Pedersen Hash for note commitment. #[derive(Copy, Clone, Debug, PartialEq)] pub struct NoteCommitmentRandomness(pub [u8; 32]); + +impl AsRef<[u8]> for NoteCommitmentRandomness { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} diff --git a/zebra-chain/src/notes/sprout.rs b/zebra-chain/src/notes/sprout.rs index 7ebb99279..dff9a1d3e 100644 --- a/zebra-chain/src/notes/sprout.rs +++ b/zebra-chain/src/notes/sprout.rs @@ -1,33 +1,48 @@ //! #![allow(dead_code)] +use super::{memo::Memo, *}; +use crate::serde_helpers; +use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize}; +use crate::types::amount::{Amount, NonNegative}; use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha256}; use std::{ fmt, io::{self}, }; -#[cfg(test)] -use proptest::{collection::vec, prelude::*}; - -use crate::serde_helpers; -use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize}; - -use super::{memo::Memo, *}; - /// pub struct Note { // TODO: refine type as a SHA-256d output derived from a spending key. paying_key: [u8; 32], - value: u64, + value: Amount, // TODO: refine type as the input to the PRF that results in a nullifier. nullifier_seed: [u8; 32], note_commitment_randomness: NoteCommitmentRandomness, } +impl Note { + pub fn note_commitment(&self) -> NoteCommitment { + let leading_byte: u8 = 0xB0; + let mut hasher = Sha256::default(); + hasher.input([leading_byte]); + hasher.input(self.paying_key); + hasher.input(self.value.to_bytes()); + hasher.input(self.nullifier_seed); + hasher.input(self.note_commitment_randomness); + let hash = hasher.result().into(); + NoteCommitment { hash } + } +} + +pub struct NoteCommitment { + hash: [u8; 32], +} + /// The decrypted form of encrypted Sprout notes on the blockchain. pub struct NotePlaintext { - value: u64, + value: Amount, // TODO: refine type rho: [u8; 32], // TODO: refine as jub-jub appropriate in the base field. @@ -82,6 +97,9 @@ impl ZcashDeserialize for EncryptedCiphertext { } } +#[cfg(test)] +use proptest::{collection::vec, prelude::*}; + #[cfg(test)] impl Arbitrary for EncryptedCiphertext { type Parameters = (); diff --git a/zebra-chain/src/types/amount.rs b/zebra-chain/src/types/amount.rs index 84565b88b..9831ddc76 100644 --- a/zebra-chain/src/types/amount.rs +++ b/zebra-chain/src/types/amount.rs @@ -21,6 +21,10 @@ impl Amount { { self.0.try_into() } + + pub fn to_bytes(&self) -> [u8; 8] { + self.0.to_le_bytes() + } } impl std::ops::Add> for Amount