From 785f22ca5a49f595d4f82416899fe957ae002ffb Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 3 Oct 2018 13:18:39 +0100 Subject: [PATCH] Move Sapling commitment tree hash into zcash_primitives --- librustzcash/src/rustzcash.rs | 32 +++++++--------------------- zcash_primitives/src/sapling.rs | 37 ++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/librustzcash/src/rustzcash.rs b/librustzcash/src/rustzcash.rs index fb72827..20af7ed 100644 --- a/librustzcash/src/rustzcash.rs +++ b/librustzcash/src/rustzcash.rs @@ -11,7 +11,7 @@ extern crate zcash_proofs; extern crate lazy_static; -use ff::{BitIterator, PrimeField, PrimeFieldRepr}; +use ff::{PrimeField, PrimeFieldRepr}; use pairing::bls12_381::{Bls12, Fr, FrRepr}; use sapling_crypto::{ @@ -22,7 +22,6 @@ use sapling_crypto::{ fs::{Fs, FsRepr}, FixedGenerators, JubjubEngine, JubjubParams, PrimeOrder, ToUniform, Unknown, }, - pedersen_hash::{pedersen_hash, Personalization}, redjubjub::{self, Signature}, }; @@ -57,7 +56,11 @@ use std::ffi::OsString; use std::os::windows::ffi::OsStringExt; use sapling_crypto::primitives::{ProofGenerationKey, ViewingKey}; -use zcash_primitives::{note_encryption::sapling_ka_agree, sapling::spend_sig, zip32, JUBJUB}; +use zcash_primitives::{ + note_encryption::sapling_ka_agree, + sapling::{merkle_hash, spend_sig}, + zip32, JUBJUB, +}; use zcash_proofs::{ load_parameters, sapling::{CommitmentTreeWitness, SaplingProvingContext, SaplingVerificationContext}, @@ -254,28 +257,7 @@ pub extern "system" fn librustzcash_merkle_hash( // size of the representation let b_repr = read_le(unsafe { &(&*b)[..] }); - let mut lhs = [false; 256]; - let mut rhs = [false; 256]; - - for (a, b) in lhs.iter_mut().rev().zip(BitIterator::new(a_repr)) { - *a = b; - } - - for (a, b) in rhs.iter_mut().rev().zip(BitIterator::new(b_repr)) { - *a = b; - } - - let tmp = pedersen_hash::( - Personalization::MerkleTree(depth), - lhs.iter() - .map(|&x| x) - .take(Fr::NUM_BITS as usize) - .chain(rhs.iter().map(|&x| x).take(Fr::NUM_BITS as usize)), - &JUBJUB, - ) - .into_xy() - .0 - .into_repr(); + let tmp = merkle_hash(depth, &a_repr, &b_repr); // Should be okay, caller is responsible for ensuring the pointer // is a valid pointer to 32 bytes that can be mutated. diff --git a/zcash_primitives/src/sapling.rs b/zcash_primitives/src/sapling.rs index b59dc2b..62f5118 100644 --- a/zcash_primitives/src/sapling.rs +++ b/zcash_primitives/src/sapling.rs @@ -1,10 +1,45 @@ -use pairing::bls12_381::Bls12; +use ff::{BitIterator, PrimeField}; +use pairing::bls12_381::{Bls12, Fr, FrRepr}; use rand::OsRng; use sapling_crypto::{ jubjub::{fs::Fs, FixedGenerators, JubjubBls12}, + pedersen_hash::{pedersen_hash, Personalization}, redjubjub::{PrivateKey, PublicKey, Signature}, }; +use JUBJUB; + +/// Compute a parent node in the Sapling commitment tree given its two children. +pub fn merkle_hash(depth: usize, lhs: &FrRepr, rhs: &FrRepr) -> FrRepr { + let lhs = { + let mut tmp = [false; 256]; + for (a, b) in tmp.iter_mut().rev().zip(BitIterator::new(lhs)) { + *a = b; + } + tmp + }; + + let rhs = { + let mut tmp = [false; 256]; + for (a, b) in tmp.iter_mut().rev().zip(BitIterator::new(rhs)) { + *a = b; + } + tmp + }; + + pedersen_hash::( + Personalization::MerkleTree(depth), + lhs.iter() + .map(|&x| x) + .take(Fr::NUM_BITS as usize) + .chain(rhs.iter().map(|&x| x).take(Fr::NUM_BITS as usize)), + &JUBJUB, + ) + .into_xy() + .0 + .into_repr() +} + /// Create the spendAuthSig for a Sapling SpendDescription. pub fn spend_sig( ask: PrivateKey,