diff --git a/.travis.yml b/.travis.yml index a7736231..9ddae8a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: rust rust: - - 1.32.0 + - 1.36.0 cache: cargo diff --git a/Cargo.lock b/Cargo.lock index 26def55a..03b2a4dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,14 @@ dependencies = [ "stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "arrayref" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arrayvec" -version = "0.4.7" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -70,12 +75,22 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "blake2-rfc" -version = "0.2.18" -source = "git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9#7a5b5fc99ae483a0043db7547fb79a6fa44b88a9" +name = "blake2b_simd" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "blake2s_simd" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -292,7 +307,8 @@ name = "librustzcash" version = "0.1.0" dependencies = [ "bellman 0.1.0", - "blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)", + "blake2b_simd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2s_simd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.4.0", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -435,7 +451,8 @@ name = "sapling-crypto" version = "0.0.1" dependencies = [ "bellman 0.1.0", - "blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)", + "blake2b_simd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2s_simd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.4.0", @@ -529,7 +546,7 @@ name = "zcash_primitives" version = "0.0.0" dependencies = [ "aes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)", + "blake2b_simd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "crypto_api_chachapoly 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.4.0", @@ -547,7 +564,7 @@ name = "zcash_proofs" version = "0.0.0" dependencies = [ "bellman 0.1.0", - "blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)", + "blake2b_simd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.4.0", "pairing 0.14.2", @@ -560,11 +577,13 @@ dependencies = [ "checksum aes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6fb1737cdc8da3db76e90ca817a194249a38fcb500c2e6ecec39b29448aa873" "checksum aes-soft 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67cc03b0a090a05cb01e96998a01905d7ceedce1bc23b756c0bb7faa0682ccb1" "checksum aesni 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6810b7fb9f2bb4f76f05ac1c170b8dde285b6308955dc3afd89710268c958d9e" -"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" +"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" +"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" "checksum bech32 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58946044516aa9dc922182e0d6e9d124a31aafe6b421614654eb27cf90cec09c" "checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" -"checksum blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)" = "" +"checksum blake2b_simd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d909f9ef55928e57e7de9638828bc9407233b5cb0904066a7edebbaa9946db2f" +"checksum blake2s_simd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fa20660ff9f1e6d0a05444b5ebbbae13e4c018d4c66cc78c7e421e3396358a52" "checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d" "checksum block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "370424437b9459f3dfd68428ed9376ddfe03d8b70ede29cc533b3557df186ab4" "checksum block-padding 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc4358306e344bf9775d0197fd00d2603e5afb0771bb353538630f022068ea3" diff --git a/librustzcash/Cargo.toml b/librustzcash/Cargo.toml index 3edc928e..e75a71c0 100644 --- a/librustzcash/Cargo.toml +++ b/librustzcash/Cargo.toml @@ -15,6 +15,8 @@ crate-type = ["staticlib"] [dependencies] bellman = { path = "../bellman" } +blake2b_simd = "0.5" +blake2s_simd = "0.5" ff = { path = "../ff" } libc = "0.2" pairing = { path = "../pairing" } @@ -24,7 +26,3 @@ rand = "0.4" sapling-crypto = { path = "../sapling-crypto" } zcash_primitives = { path = "../zcash_primitives" } zcash_proofs = { path = "../zcash_proofs" } - -[dependencies.blake2-rfc] -git = "https://github.com/gtank/blake2-rfc" -rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9" diff --git a/librustzcash/src/equihash.rs b/librustzcash/src/equihash.rs index da2693bc..d251bc19 100644 --- a/librustzcash/src/equihash.rs +++ b/librustzcash/src/equihash.rs @@ -1,4 +1,4 @@ -use blake2_rfc::blake2b::{Blake2b, Blake2bResult}; +use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams, State as Blake2bState}; use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt}; use std::io::Cursor; use std::mem::size_of; @@ -33,7 +33,7 @@ impl Params { } impl Node { - fn new(p: &Params, state: &Blake2b, i: u32) -> Self { + fn new(p: &Params, state: &Blake2bState, i: u32) -> Self { let hash = generate_hash(state, i / p.indices_per_hash_output()); let start = ((i % p.indices_per_hash_output()) * p.n / 8) as usize; let end = start + (p.n as usize) / 8; @@ -99,15 +99,18 @@ impl Node { } } -fn initialise_state(n: u32, k: u32, digest_len: u8) -> Blake2b { +fn initialise_state(n: u32, k: u32, digest_len: u8) -> Blake2bState { let mut personalization: Vec = Vec::from("ZcashPoW"); personalization.write_u32::(n).unwrap(); personalization.write_u32::(k).unwrap(); - Blake2b::with_params(digest_len as usize, &[], &[], &personalization) + Blake2bParams::new() + .hash_length(digest_len as usize) + .personal(&personalization) + .to_state() } -fn generate_hash(base_state: &Blake2b, i: u32) -> Blake2bResult { +fn generate_hash(base_state: &Blake2bState, i: u32) -> Blake2bHash { let mut lei = [0u8; 4]; (&mut lei[..]).write_u32::(i).unwrap(); @@ -249,7 +252,7 @@ pub fn is_valid_solution_iterative( return rows[0].is_zero(hash_len); } -fn tree_validator(p: &Params, state: &Blake2b, indices: &[u32]) -> Option { +fn tree_validator(p: &Params, state: &Blake2bState, indices: &[u32]) -> Option { if indices.len() > 1 { let end = indices.len(); let mid = end / 2; diff --git a/librustzcash/src/rustzcash.rs b/librustzcash/src/rustzcash.rs index 96bb718a..cfb26e10 100644 --- a/librustzcash/src/rustzcash.rs +++ b/librustzcash/src/rustzcash.rs @@ -1,5 +1,6 @@ extern crate bellman; -extern crate blake2_rfc; +extern crate blake2b_simd; +extern crate blake2s_simd; extern crate byteorder; extern crate ff; extern crate libc; @@ -32,7 +33,7 @@ use bellman::groth16::{ create_random_proof, verify_proof, Parameters, PreparedVerifyingKey, Proof, }; -use blake2_rfc::blake2s::Blake2s; +use blake2s_simd::Params as Blake2sParams; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; @@ -319,7 +320,10 @@ pub extern "system" fn librustzcash_crh_ivk( let ak = unsafe { &*ak }; let nk = unsafe { &*nk }; - let mut h = Blake2s::with_params(32, &[], &[], CRH_IVK_PERSONALIZATION); + let mut h = Blake2sParams::new() + .hash_length(32) + .personal(CRH_IVK_PERSONALIZATION) + .to_state(); h.update(ak); h.update(nk); let mut h = h.finalize().as_ref().to_vec(); diff --git a/sapling-crypto/Cargo.toml b/sapling-crypto/Cargo.toml index d9852191..7d437745 100644 --- a/sapling-crypto/Cargo.toml +++ b/sapling-crypto/Cargo.toml @@ -14,15 +14,13 @@ features = ["expose-arith"] [dependencies] bellman = { path = "../bellman" } +blake2b_simd = "0.5" +blake2s_simd = "0.5" ff = { path = "../ff" } rand = "0.4" digest = "0.7" byteorder = "1" -[dependencies.blake2-rfc] -git = "https://github.com/gtank/blake2-rfc" -rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9" - [dev-dependencies] hex-literal = "0.1" rust-crypto = "0.2" diff --git a/sapling-crypto/src/circuit/blake2s.rs b/sapling-crypto/src/circuit/blake2s.rs index 93af8069..46bbe676 100644 --- a/sapling-crypto/src/circuit/blake2s.rs +++ b/sapling-crypto/src/circuit/blake2s.rs @@ -320,13 +320,13 @@ pub fn blake2s>( #[cfg(test)] mod test { + use blake2s_simd::Params as Blake2sParams; use rand::{XorShiftRng, SeedableRng, Rng}; use pairing::bls12_381::{Bls12}; use ::circuit::boolean::{Boolean, AllocatedBit}; use ::circuit::test::TestConstraintSystem; use super::blake2s; use bellman::{ConstraintSystem}; - use blake2_rfc::blake2s::Blake2s; #[test] fn test_blank_hash() { @@ -392,7 +392,7 @@ mod test { for input_len in (0..32).chain((32..256).filter(|a| a % 8 == 0)) { - let mut h = Blake2s::with_params(32, &[], &[], b"12345678"); + let mut h = Blake2sParams::new().hash_length(32).personal(b"12345678").to_state(); let data: Vec = (0..input_len).map(|_| rng.gen()).collect(); diff --git a/sapling-crypto/src/circuit/test/mod.rs b/sapling-crypto/src/circuit/test/mod.rs index 18a77ba4..79d128a5 100644 --- a/sapling-crypto/src/circuit/test/mod.rs +++ b/sapling-crypto/src/circuit/test/mod.rs @@ -16,7 +16,7 @@ use byteorder::{BigEndian, ByteOrder}; use std::cmp::Ordering; use std::collections::BTreeMap; -use blake2_rfc::blake2s::Blake2s; +use blake2s_simd::{Params as Blake2sParams, State as Blake2sState}; #[derive(Debug)] enum NamedObject { @@ -96,7 +96,7 @@ fn proc_lc( fn hash_lc( terms: &[(Variable, E::Fr)], - h: &mut Blake2s + h: &mut Blake2sState ) { let map = proc_lc::(terms); @@ -226,7 +226,7 @@ impl TestConstraintSystem { } pub fn hash(&self) -> String { - let mut h = Blake2s::new(32); + let mut h = Blake2sParams::new().hash_length(32).to_state(); { let mut buf = [0u8; 24]; diff --git a/sapling-crypto/src/group_hash.rs b/sapling-crypto/src/group_hash.rs index 43e87e8f..7369e047 100644 --- a/sapling-crypto/src/group_hash.rs +++ b/sapling-crypto/src/group_hash.rs @@ -8,7 +8,7 @@ use ff::{ PrimeField }; -use blake2_rfc::blake2s::Blake2s; +use blake2s_simd::Params; use constants; /// Produces a random point in the Jubjub curve. @@ -25,13 +25,15 @@ pub fn group_hash( // Check to see that scalar field is 255 bits assert!(E::Fr::NUM_BITS == 255); - let mut h = Blake2s::with_params(32, &[], &[], personalization); - h.update(constants::GH_FIRST_BLOCK); - h.update(tag); - let h = h.finalize().as_ref().to_vec(); - assert!(h.len() == 32); + let h = Params::new() + .hash_length(32) + .personal(personalization) + .to_state() + .update(constants::GH_FIRST_BLOCK) + .update(tag) + .finalize(); - match edwards::Point::::read(&h[..], params) { + match edwards::Point::::read(h.as_ref(), params) { Ok(p) => { let p = p.mul_by_cofactor(params); diff --git a/sapling-crypto/src/lib.rs b/sapling-crypto/src/lib.rs index ae375736..0535d9a2 100644 --- a/sapling-crypto/src/lib.rs +++ b/sapling-crypto/src/lib.rs @@ -1,6 +1,7 @@ extern crate pairing; extern crate bellman; -extern crate blake2_rfc; +extern crate blake2b_simd; +extern crate blake2s_simd; extern crate digest; extern crate ff; extern crate rand; diff --git a/sapling-crypto/src/primitives/mod.rs b/sapling-crypto/src/primitives/mod.rs index fea332c9..4026392c 100644 --- a/sapling-crypto/src/primitives/mod.rs +++ b/sapling-crypto/src/primitives/mod.rs @@ -22,7 +22,7 @@ use jubjub::{ FixedGenerators }; -use blake2_rfc::blake2s::Blake2s; +use blake2s_simd::Params as Blake2sParams; #[derive(Clone)] pub struct ValueCommitment { @@ -87,9 +87,12 @@ impl ViewingKey { self.ak.write(&mut preimage[0..32]).unwrap(); self.nk.write(&mut preimage[32..64]).unwrap(); - let mut h = Blake2s::with_params(32, &[], &[], constants::CRH_IVK_PERSONALIZATION); - h.update(&preimage); - let mut h = h.finalize().as_ref().to_vec(); + let mut h = [0; 32]; + h.copy_from_slice(Blake2sParams::new() + .hash_length(32) + .personal(constants::CRH_IVK_PERSONALIZATION) + .hash(&preimage) + .as_bytes()); // Drop the most significant five bits, so it can be interpreted as a scalar. h[31] &= 0b0000_0111; @@ -255,10 +258,12 @@ impl Note { let mut nf_preimage = [0u8; 64]; viewing_key.nk.write(&mut nf_preimage[0..32]).unwrap(); rho.write(&mut nf_preimage[32..64]).unwrap(); - let mut h = Blake2s::with_params(32, &[], &[], constants::PRF_NF_PERSONALIZATION); - h.update(&nf_preimage); - - h.finalize().as_ref().to_vec() + Blake2sParams::new() + .hash_length(32) + .personal(constants::PRF_NF_PERSONALIZATION) + .hash(&nf_preimage) + .as_bytes() + .to_vec() } /// Computes the note commitment diff --git a/sapling-crypto/src/util.rs b/sapling-crypto/src/util.rs index e67e6608..1e759ba7 100644 --- a/sapling-crypto/src/util.rs +++ b/sapling-crypto/src/util.rs @@ -1,9 +1,9 @@ -use blake2_rfc::blake2b::Blake2b; +use blake2b_simd::Params; use jubjub::{JubjubEngine, ToUniform}; pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> E::Fs { - let mut hasher = Blake2b::with_params(64, &[], &[], persona); + let mut hasher = Params::new().hash_length(64).personal(persona).to_state(); hasher.update(a); hasher.update(b); let ret = hasher.finalize(); diff --git a/zcash_primitives/Cargo.toml b/zcash_primitives/Cargo.toml index 06a117b3..771f3511 100644 --- a/zcash_primitives/Cargo.toml +++ b/zcash_primitives/Cargo.toml @@ -7,6 +7,7 @@ authors = [ [dependencies] aes = "0.2" +blake2b_simd = "0.5" byteorder = "1" crypto_api_chachapoly = "0.1" ff = { path = "../ff" } @@ -17,7 +18,3 @@ pairing = { path = "../pairing" } rand = "0.4" sapling-crypto = { path = "../sapling-crypto" } sha2 = "0.8" - -[dependencies.blake2-rfc] -git = "https://github.com/gtank/blake2-rfc" -rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9" diff --git a/zcash_primitives/src/keys.rs b/zcash_primitives/src/keys.rs index e6066e3e..fca31ed2 100644 --- a/zcash_primitives/src/keys.rs +++ b/zcash_primitives/src/keys.rs @@ -2,7 +2,7 @@ //! //! Implements section 4.2.2 of the Zcash Protocol Specification. -use blake2_rfc::blake2b::{Blake2b, Blake2bResult}; +use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams}; use ff::{PrimeField, PrimeFieldRepr}; use sapling_crypto::{ jubjub::{edwards, FixedGenerators, JubjubEngine, JubjubParams, ToUniform, Unknown}, @@ -13,12 +13,15 @@ use std::io::{self, Read, Write}; pub const PRF_EXPAND_PERSONALIZATION: &'static [u8; 16] = b"Zcash_ExpandSeed"; /// PRF^expand(sk, t) := BLAKE2b-512("Zcash_ExpandSeed", sk || t) -pub fn prf_expand(sk: &[u8], t: &[u8]) -> Blake2bResult { - prf_expand_vec(sk, &[t]) +pub fn prf_expand(sk: &[u8], t: &[u8]) -> Blake2bHash { + prf_expand_vec(sk, &vec![t]) } -pub fn prf_expand_vec(sk: &[u8], ts: &[&[u8]]) -> Blake2bResult { - let mut h = Blake2b::with_params(64, &[], &[], PRF_EXPAND_PERSONALIZATION); +pub fn prf_expand_vec(sk: &[u8], ts: &[&[u8]]) -> Blake2bHash { + let mut h = Blake2bParams::new() + .hash_length(64) + .personal(PRF_EXPAND_PERSONALIZATION) + .to_state(); h.update(sk); for t in ts { h.update(t); diff --git a/zcash_primitives/src/lib.rs b/zcash_primitives/src/lib.rs index 07d2385c..70bd8fad 100644 --- a/zcash_primitives/src/lib.rs +++ b/zcash_primitives/src/lib.rs @@ -2,7 +2,7 @@ extern crate lazy_static; extern crate aes; -extern crate blake2_rfc; +extern crate blake2b_simd; extern crate byteorder; extern crate crypto_api_chachapoly; extern crate ff; diff --git a/zcash_primitives/src/note_encryption.rs b/zcash_primitives/src/note_encryption.rs index 3d1c55be..610b746f 100644 --- a/zcash_primitives/src/note_encryption.rs +++ b/zcash_primitives/src/note_encryption.rs @@ -1,6 +1,6 @@ //! Implementation of in-band secret distribution for Zcash transactions. -use blake2_rfc::blake2b::{Blake2b, Blake2bResult}; +use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams}; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use crypto_api_chachapoly::{ChaCha20Ietf, ChachaPolyIetf}; use ff::{PrimeField, PrimeFieldRepr}; @@ -168,14 +168,15 @@ where fn kdf_sapling( dhsecret: edwards::Point, epk: &edwards::Point, -) -> Blake2bResult { +) -> Blake2bHash { let mut input = [0u8; 64]; dhsecret.write(&mut input[0..32]).unwrap(); epk.write(&mut input[32..64]).unwrap(); - let mut h = Blake2b::with_params(32, &[], &[], KDF_SAPLING_PERSONALIZATION); - h.update(&input); - h.finalize() + Blake2bParams::new() + .hash_length(32) + .personal(KDF_SAPLING_PERSONALIZATION) + .hash(&input) } /// Sapling PRF^ock. @@ -186,16 +187,17 @@ fn prf_ock( cv: &edwards::Point, cmu: &Fr, epk: &edwards::Point, -) -> Blake2bResult { +) -> Blake2bHash { let mut ock_input = [0u8; 128]; ock_input[0..32].copy_from_slice(&ovk.0); cv.write(&mut ock_input[32..64]).unwrap(); cmu.into_repr().write_le(&mut ock_input[64..96]).unwrap(); epk.write(&mut ock_input[96..128]).unwrap(); - let mut h = Blake2b::with_params(32, &[], &[], PRF_OCK_PERSONALIZATION); - h.update(&ock_input); - h.finalize() + Blake2bParams::new() + .hash_length(32) + .personal(PRF_OCK_PERSONALIZATION) + .hash(&ock_input) } /// An API for encrypting Sapling notes. diff --git a/zcash_primitives/src/transaction/sighash.rs b/zcash_primitives/src/transaction/sighash.rs index 85302ee0..774e7b47 100644 --- a/zcash_primitives/src/transaction/sighash.rs +++ b/zcash_primitives/src/transaction/sighash.rs @@ -1,4 +1,4 @@ -use blake2_rfc::blake2b::Blake2b; +use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams}; use byteorder::{LittleEndian, WriteBytesExt}; use ff::{PrimeField, PrimeFieldRepr}; @@ -39,7 +39,7 @@ macro_rules! update_i64 { macro_rules! update_hash { ($h:expr, $cond:expr, $value:expr) => { if $cond { - $h.update(&$value); + $h.update(&$value.as_ref()); } else { $h.update(&[0; 32]); } @@ -67,47 +67,51 @@ impl SigHashVersion { } } -fn prevout_hash(tx: &TransactionData) -> Vec { +fn prevout_hash(tx: &TransactionData) -> Blake2bHash { let mut data = Vec::with_capacity(tx.vin.len() * 36); for t_in in &tx.vin { t_in.prevout.write(&mut data).unwrap(); } - let mut h = Blake2b::with_params(32, &[], &[], ZCASH_PREVOUTS_HASH_PERSONALIZATION); - h.update(&data); - h.finalize().as_ref().to_vec() + Blake2bParams::new() + .hash_length(32) + .personal(ZCASH_PREVOUTS_HASH_PERSONALIZATION) + .hash(&data) } -fn sequence_hash(tx: &TransactionData) -> Vec { +fn sequence_hash(tx: &TransactionData) -> Blake2bHash { let mut data = Vec::with_capacity(tx.vin.len() * 4); for t_in in &tx.vin { (&mut data) .write_u32::(t_in.sequence) .unwrap(); } - let mut h = Blake2b::with_params(32, &[], &[], ZCASH_SEQUENCE_HASH_PERSONALIZATION); - h.update(&data); - h.finalize().as_ref().to_vec() + Blake2bParams::new() + .hash_length(32) + .personal(ZCASH_SEQUENCE_HASH_PERSONALIZATION) + .hash(&data) } -fn outputs_hash(tx: &TransactionData) -> Vec { +fn outputs_hash(tx: &TransactionData) -> Blake2bHash { let mut data = Vec::with_capacity(tx.vout.len() * (4 + 1)); for t_out in &tx.vout { t_out.write(&mut data).unwrap(); } - let mut h = Blake2b::with_params(32, &[], &[], ZCASH_OUTPUTS_HASH_PERSONALIZATION); - h.update(&data); - h.finalize().as_ref().to_vec() + Blake2bParams::new() + .hash_length(32) + .personal(ZCASH_OUTPUTS_HASH_PERSONALIZATION) + .hash(&data) } -fn single_output_hash(tx_out: &TxOut) -> Vec { +fn single_output_hash(tx_out: &TxOut) -> Blake2bHash { let mut data = vec![]; tx_out.write(&mut data).unwrap(); - let mut h = Blake2b::with_params(32, &[], &[], ZCASH_OUTPUTS_HASH_PERSONALIZATION); - h.update(&data); - h.finalize().as_ref().to_vec() + Blake2bParams::new() + .hash_length(32) + .personal(ZCASH_OUTPUTS_HASH_PERSONALIZATION) + .hash(&data) } -fn joinsplits_hash(tx: &TransactionData) -> Vec { +fn joinsplits_hash(tx: &TransactionData) -> Blake2bHash { let mut data = Vec::with_capacity( tx.joinsplits.len() * if tx.version < SAPLING_TX_VERSION { @@ -120,12 +124,13 @@ fn joinsplits_hash(tx: &TransactionData) -> Vec { js.write(&mut data).unwrap(); } data.extend_from_slice(&tx.joinsplit_pubkey.unwrap()); - let mut h = Blake2b::with_params(32, &[], &[], ZCASH_JOINSPLITS_HASH_PERSONALIZATION); - h.update(&data); - h.finalize().as_ref().to_vec() + Blake2bParams::new() + .hash_length(32) + .personal(ZCASH_JOINSPLITS_HASH_PERSONALIZATION) + .hash(&data) } -fn shielded_spends_hash(tx: &TransactionData) -> Vec { +fn shielded_spends_hash(tx: &TransactionData) -> Blake2bHash { let mut data = Vec::with_capacity(tx.shielded_spends.len() * 384); for s_spend in &tx.shielded_spends { s_spend.cv.write(&mut data).unwrap(); @@ -134,19 +139,21 @@ fn shielded_spends_hash(tx: &TransactionData) -> Vec { s_spend.rk.write(&mut data).unwrap(); data.extend_from_slice(&s_spend.zkproof); } - let mut h = Blake2b::with_params(32, &[], &[], ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION); - h.update(&data); - h.finalize().as_ref().to_vec() + Blake2bParams::new() + .hash_length(32) + .personal(ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION) + .hash(&data) } -fn shielded_outputs_hash(tx: &TransactionData) -> Vec { +fn shielded_outputs_hash(tx: &TransactionData) -> Blake2bHash { let mut data = Vec::with_capacity(tx.shielded_outputs.len() * 948); for s_out in &tx.shielded_outputs { s_out.write(&mut data).unwrap(); } - let mut h = Blake2b::with_params(32, &[], &[], ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION); - h.update(&data); - h.finalize().as_ref().to_vec() + Blake2bParams::new() + .hash_length(32) + .personal(ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION) + .hash(&data) } pub fn signature_hash_data( @@ -158,26 +165,16 @@ pub fn signature_hash_data( let sigversion = SigHashVersion::from_tx(tx); match sigversion { SigHashVersion::Overwinter | SigHashVersion::Sapling => { - let hash_outputs = if (hash_type & SIGHASH_MASK) != SIGHASH_SINGLE - && (hash_type & SIGHASH_MASK) != SIGHASH_NONE - { - outputs_hash(tx) - } else if (hash_type & SIGHASH_MASK) == SIGHASH_SINGLE - && transparent_input.is_some() - && transparent_input.as_ref().unwrap().0 < tx.vout.len() - { - single_output_hash(&tx.vout[transparent_input.as_ref().unwrap().0]) - } else { - vec![0; 32] - }; - let mut personal = [0; 16]; (&mut personal[..12]).copy_from_slice(ZCASH_SIGHASH_PERSONALIZATION_PREFIX); (&mut personal[12..]) .write_u32::(consensus_branch_id) .unwrap(); - let mut h = Blake2b::with_params(32, &[], &[], &personal); + let mut h = Blake2bParams::new() + .hash_length(32) + .personal(&personal) + .to_state(); let mut tmp = [0; 8]; update_u32!(h, tx.header(), tmp); @@ -190,7 +187,20 @@ pub fn signature_hash_data( && (hash_type & SIGHASH_MASK) != SIGHASH_NONE, sequence_hash(tx) ); - h.update(&hash_outputs); + if (hash_type & SIGHASH_MASK) != SIGHASH_SINGLE + && (hash_type & SIGHASH_MASK) != SIGHASH_NONE + { + h.update(outputs_hash(tx).as_ref()); + } else if (hash_type & SIGHASH_MASK) == SIGHASH_SINGLE + && transparent_input.is_some() + && transparent_input.as_ref().unwrap().0 < tx.vout.len() + { + h.update( + single_output_hash(&tx.vout[transparent_input.as_ref().unwrap().0]).as_ref(), + ); + } else { + h.update(&[0; 32]); + }; update_hash!(h, !tx.joinsplits.is_empty(), joinsplits_hash(tx)); if sigversion == SigHashVersion::Sapling { update_hash!(h, !tx.shielded_spends.is_empty(), shielded_spends_hash(tx)); diff --git a/zcash_primitives/src/zip32.rs b/zcash_primitives/src/zip32.rs index db5adcda..a34ae183 100644 --- a/zcash_primitives/src/zip32.rs +++ b/zcash_primitives/src/zip32.rs @@ -1,5 +1,5 @@ use aes::Aes256; -use blake2_rfc::blake2b::Blake2b; +use blake2b_simd::Params as Blake2bParams; use byteorder::{ByteOrder, LittleEndian, ReadBytesExt, WriteBytesExt}; use ff::Field; use fpe::ff1::{BinaryNumeralString, FF1}; @@ -33,7 +33,10 @@ struct FVKFingerprint([u8; 32]); impl From<&FullViewingKey> for FVKFingerprint { fn from(fvk: &FullViewingKey) -> Self { - let mut h = Blake2b::with_params(32, &[], &[], ZIP32_SAPLING_FVFP_PERSONALIZATION); + let mut h = Blake2bParams::new() + .hash_length(32) + .personal(ZIP32_SAPLING_FVFP_PERSONALIZATION) + .to_state(); h.update(&fvk.to_bytes()); let mut fvfp = [0u8; 32]; fvfp.copy_from_slice(h.finalize().as_bytes()); @@ -225,9 +228,10 @@ impl std::fmt::Debug for ExtendedFullViewingKey { impl ExtendedSpendingKey { pub fn master(seed: &[u8]) -> Self { - let mut h = Blake2b::with_params(64, &[], &[], ZIP32_SAPLING_MASTER_PERSONALIZATION); - h.update(seed); - let i = h.finalize(); + let i = Blake2bParams::new() + .hash_length(64) + .personal(ZIP32_SAPLING_MASTER_PERSONALIZATION) + .hash(seed); let sk_m = &i.as_bytes()[..32]; let mut c_m = [0u8; 32]; diff --git a/zcash_proofs/Cargo.toml b/zcash_proofs/Cargo.toml index 85a72109..34bd520a 100644 --- a/zcash_proofs/Cargo.toml +++ b/zcash_proofs/Cargo.toml @@ -7,13 +7,10 @@ authors = [ [dependencies] bellman = { path = "../bellman" } +blake2b_simd = "0.5" byteorder = "1" ff = { path = "../ff" } pairing = { path = "../pairing" } rand = "0.4" sapling-crypto = { path = "../sapling-crypto" } zcash_primitives = { path = "../zcash_primitives" } - -[dependencies.blake2-rfc] -git = "https://github.com/gtank/blake2-rfc" -rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9" diff --git a/zcash_proofs/src/hashreader.rs b/zcash_proofs/src/hashreader.rs index a422d520..dbe686ff 100644 --- a/zcash_proofs/src/hashreader.rs +++ b/zcash_proofs/src/hashreader.rs @@ -1,10 +1,10 @@ -use blake2_rfc::blake2b::Blake2b; +use blake2b_simd::State; use std::io::{self, Read}; /// Abstraction over a reader which hashes the data being read. pub struct HashReader { reader: R, - hasher: Blake2b, + hasher: State, } impl HashReader { @@ -12,7 +12,7 @@ impl HashReader { pub fn new(reader: R) -> Self { HashReader { reader: reader, - hasher: Blake2b::new(64), + hasher: State::new(), } } diff --git a/zcash_proofs/src/lib.rs b/zcash_proofs/src/lib.rs index 97dd5012..25434f40 100644 --- a/zcash_proofs/src/lib.rs +++ b/zcash_proofs/src/lib.rs @@ -1,5 +1,5 @@ extern crate bellman; -extern crate blake2_rfc; +extern crate blake2b_simd; extern crate byteorder; extern crate ff; extern crate pairing;