From c46cda920f15129921b4327dae3051cb4df1d9ee Mon Sep 17 00:00:00 2001 From: Deirdre Connolly Date: Tue, 28 Jul 2020 03:52:04 -0400 Subject: [PATCH] Add primitive merkle_crh_sapling function --- zebra-chain/src/commitments/sapling.rs | 8 ----- .../src/treestate/note_commitment_tree.rs | 35 ++++++++++++++++++- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/zebra-chain/src/commitments/sapling.rs b/zebra-chain/src/commitments/sapling.rs index a1d3f1dc..323d6715 100644 --- a/zebra-chain/src/commitments/sapling.rs +++ b/zebra-chain/src/commitments/sapling.rs @@ -82,14 +82,6 @@ pub fn pedersen_hash_to_point(domain: [u8; 8], M: &BitVec) -> jubjub:: result } -/// Pedersen Hash Function -/// -/// https://zips.z.cash/protocol/protocol.pdf#concretepedersenhash -#[allow(non_snake_case)] -pub fn pedersen_hash(domain: [u8; 8], M: &BitVec) -> jubjub::Fq { - jubjub::AffinePoint::from(pedersen_hash_to_point(domain, M)).get_u() -} - /// Mixing Pedersen Hash Function /// /// Used to compute ρ from a note commitment and its position in the diff --git a/zebra-chain/src/treestate/note_commitment_tree.rs b/zebra-chain/src/treestate/note_commitment_tree.rs index b2698df0..54d9838a 100644 --- a/zebra-chain/src/treestate/note_commitment_tree.rs +++ b/zebra-chain/src/treestate/note_commitment_tree.rs @@ -9,14 +9,47 @@ //! append-only. //! //! A root of a note commitment tree is associated with each treestate. + #![allow(clippy::unit_arg)] +#![allow(dead_code)] use std::{fmt, io}; +use bitvec::prelude::*; #[cfg(test)] use proptest_derive::Arbitrary; -use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize}; +use crate::{ + commitments::sapling::pedersen_hash_to_point, + serialization::{SerializationError, ZcashDeserialize, ZcashSerialize}, +}; + +/// Pedersen Hash Function +/// +/// https://zips.z.cash/protocol/protocol.pdf#concretepedersenhash +#[allow(non_snake_case)] +fn pedersen_hash(domain: [u8; 8], M: &BitVec) -> jubjub::Fq { + jubjub::AffinePoint::from(pedersen_hash_to_point(domain, M)).get_u() +} + +/// MerkleCRH^Sapling Hash Function +/// +/// MerkleCRH^Sapling(layer, left,right) := PedersenHash(“Zcash_PH”, l || left ||right) +/// where l = I2LEBSP_6(MerkleDepth^Sapling − 1 − layer) +/// +/// https://zips.z.cash/protocol/protocol.pdf#merklecrh +// TODO: refine layer as a wrapper type around a bitvec/bitslice? +// TODO: refine output type as *NodeHash, combine with RootHash +fn merkle_crh_sapling(layer: u8, left: [u8; 32], right: [u8; 32]) -> jubjub::Fq { + let mut s: BitVec = BitVec::new(); + + // Prefix: l = I2LEBSP_6(MerkleDepth^Sapling − 1 − layer) + s.append(&mut bitvec![31 - layer; 1]); + s.append(&mut BitVec::::from_slice(&left[..])); + s.append(&mut BitVec::::from_slice(&right[..])); + + pedersen_hash(*b"Zcash_PH", &s) +} /// The index of a note’s commitment at the leafmost layer of its Note /// Commitment Tree.