mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-01-30 23:42:13 +00:00
Migrate to blake2b_simd and blake2s_simd crates
The primary reason for migrating is that these crates provide APIs for setting the personalisation string. This enables us to depend solely on published crates, and thus publish our own crates. The SIMD implementations are ported from libsodium. Closes #67.
This commit is contained in:
parent
91c6b0b3f0
commit
999dcbfcab
43
Cargo.lock
generated
43
Cargo.lock
generated
@ -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",
|
||||
@ -559,11 +576,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"
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
@ -33,7 +34,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};
|
||||
|
||||
@ -336,7 +337,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();
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
|
@ -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];
|
||||
|
@ -7,12 +7,9 @@ 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" }
|
||||
|
||||
[dependencies.blake2-rfc]
|
||||
git = "https://github.com/gtank/blake2-rfc"
|
||||
rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9"
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
extern crate bellman;
|
||||
extern crate blake2_rfc;
|
||||
extern crate blake2b_simd;
|
||||
extern crate byteorder;
|
||||
extern crate ff;
|
||||
extern crate pairing;
|
||||
|
Loading…
Reference in New Issue
Block a user