Merge pull request #83 from str4d/blake2_simd

Migrate to blake2b_simd and blake2s_simd crates
This commit is contained in:
str4d
2019-07-18 17:41:59 +01:00
committed by GitHub
21 changed files with 173 additions and 130 deletions

View File

@@ -1,6 +1,6 @@
language: rust
rust:
- 1.32.0
- 1.36.0
cache: cargo

43
Cargo.lock generated
View File

@@ -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)" = "<none>"
"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"

View File

@@ -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"

View File

@@ -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<u8> = Vec::from("ZcashPoW");
personalization.write_u32::<LittleEndian>(n).unwrap();
personalization.write_u32::<LittleEndian>(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::<LittleEndian>(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<Node> {
fn tree_validator(p: &Params, state: &Blake2bState, indices: &[u32]) -> Option<Node> {
if indices.len() > 1 {
let end = indices.len();
let mid = end / 2;

View File

@@ -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();

View File

@@ -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"

View File

@@ -320,13 +320,13 @@ pub fn blake2s<E: Engine, CS: ConstraintSystem<E>>(
#[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<u8> = (0..input_len).map(|_| rng.gen()).collect();

View File

@@ -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<E: Engine>(
fn hash_lc<E: Engine>(
terms: &[(Variable, E::Fr)],
h: &mut Blake2s
h: &mut Blake2sState
)
{
let map = proc_lc::<E>(terms);
@@ -226,7 +226,7 @@ impl<E: Engine> TestConstraintSystem<E> {
}
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];

View File

@@ -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<E: JubjubEngine>(
// 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::<E, _>::read(&h[..], params) {
match edwards::Point::<E, _>::read(h.as_ref(), params) {
Ok(p) => {
let p = p.mul_by_cofactor(params);

View File

@@ -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;

View File

@@ -22,7 +22,7 @@ use jubjub::{
FixedGenerators
};
use blake2_rfc::blake2s::Blake2s;
use blake2s_simd::Params as Blake2sParams;
#[derive(Clone)]
pub struct ValueCommitment<E: JubjubEngine> {
@@ -87,9 +87,12 @@ impl<E: JubjubEngine> ViewingKey<E> {
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<E: JubjubEngine> Note<E> {
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

View File

@@ -1,9 +1,9 @@
use blake2_rfc::blake2b::Blake2b;
use blake2b_simd::Params;
use jubjub::{JubjubEngine, ToUniform};
pub fn hash_to_scalar<E: JubjubEngine>(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();

View File

@@ -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"

View File

@@ -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);

View File

@@ -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;

View File

@@ -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<Bls12, PrimeOrder>,
epk: &edwards::Point<Bls12, PrimeOrder>,
) -> 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<Bls12, Unknown>,
cmu: &Fr,
epk: &edwards::Point<Bls12, PrimeOrder>,
) -> 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.

View File

@@ -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<u8> {
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<u8> {
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::<LittleEndian>(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<u8> {
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<u8> {
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<u8> {
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<u8> {
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<u8> {
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<u8> {
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<u8> {
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::<LittleEndian>(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));

View File

@@ -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<E: JubjubEngine> From<&FullViewingKey<E>> for FVKFingerprint {
fn from(fvk: &FullViewingKey<E>) -> 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];

View File

@@ -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"

View File

@@ -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<R: Read> {
reader: R,
hasher: Blake2b,
hasher: State,
}
impl<R: Read> HashReader<R> {
@@ -12,7 +12,7 @@ impl<R: Read> HashReader<R> {
pub fn new(reader: R) -> Self {
HashReader {
reader: reader,
hasher: Blake2b::new(64),
hasher: State::new(),
}
}

View File

@@ -1,5 +1,5 @@
extern crate bellman;
extern crate blake2_rfc;
extern crate blake2b_simd;
extern crate byteorder;
extern crate ff;
extern crate pairing;