From b03b4cf958d2c87f0cc95752697a50cc6c0eca52 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Tue, 3 Sep 2019 17:47:21 +0300 Subject: [PATCH] hashing with blake2 --- Cargo.toml | 3 ++- src/lib.rs | 1 + src/node_data.rs | 39 +++++++++++++++++++++++++++++++++++---- src/tree.rs | 2 ++ 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 355bd09..b2d0d81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,5 @@ quickcheck = "0.8" [dependencies] derive_more = "0.15" bigint = "4" -byteorder = "1" \ No newline at end of file +byteorder = "1" +blake2-rfc = { git = "https://github.com/gtank/blake2-rfc.git", rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9" } diff --git a/src/lib.rs b/src/lib.rs index dbc5b91..5ba7e16 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,7 @@ extern crate derive_more; extern crate bigint; extern crate byteorder; +extern crate blake2_rfc as blake2; mod tree; mod node_data; diff --git a/src/node_data.rs b/src/node_data.rs index ba7877f..10bb5b3 100644 --- a/src/node_data.rs +++ b/src/node_data.rs @@ -1,11 +1,12 @@ -use byteorder::{LittleEndian, WriteBytesExt}; - +use byteorder::{LittleEndian, WriteBytesExt, ByteOrder}; use bigint::U256; +use blake2::blake2b::Blake2b; /// Node metadata. #[repr(C)] #[derive(Debug)] pub struct NodeData { + pub consensus_branch_id: u32, pub subtree_commitment: [u8; 32], pub start_time: u32, pub end_time: u32, @@ -19,13 +20,44 @@ pub struct NodeData { pub shielded_tx: u64, } +pub fn blake2b_personal(personalization: &[u8], input: &[u8]) -> [u8; 32] { + let mut hasher = Blake2b::with_params(32, &[], &[], personalization); + hasher.update(input); + let mut result = [0u8; 32]; + result.copy_from_slice(hasher.finalize().as_bytes()); + result +} + +pub fn personalization(branch_id: u32) -> [u8; 16] { + let mut result = [0u8; 16]; + result[..12].copy_from_slice(b"ZcashHistory"); + LittleEndian::write_u32(&mut result[12..], branch_id); + result +} + impl NodeData { pub const MAX_SERIALIZED_SIZE: usize = 32 + 4 + 4 + 4 + 4 + 32 + 32 + 32 + 9 + 9 + 9; // =171; pub fn combine(left: &NodeData, right: &NodeData) -> NodeData { + assert_eq!(left.consensus_branch_id, right.consensus_branch_id); + + let mut hash_buf = [0u8; Self::MAX_SERIALIZED_SIZE * 2]; + let size = { + let mut cursor = ::std::io::Cursor::new(&mut hash_buf[..]); + left.write(&mut cursor).expect("Writing to memory buf with enough length cannot fail; qed"); + right.write(&mut cursor).expect("Writing to memory buf with enough length cannot fail; qed"); + cursor.position() as usize + }; + + let hash = blake2b_personal( + &personalization(left.consensus_branch_id), + &hash_buf[..size] + ); + NodeData { // TODO: hash children - subtree_commitment: [0u8; 32], + consensus_branch_id: left.consensus_branch_id, + subtree_commitment: hash, start_time: left.start_time, end_time: right.end_time, start_target: left.start_target, @@ -33,7 +65,6 @@ impl NodeData { start_sapling_root: left.start_sapling_root, end_sapling_root: right.end_sapling_root, - // TODO: sum work? subtree_total_work: left.subtree_total_work + right.subtree_total_work, start_height: left.start_height, end_height: right.end_height, diff --git a/src/tree.rs b/src/tree.rs index e2b1c5b..efb59e3 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -285,6 +285,7 @@ mod tests { fn leaf(height: u32) -> NodeData { NodeData { + consensus_branch_id: 1, subtree_commitment: [0u8; 32], start_time: 0, end_time: 0, @@ -301,6 +302,7 @@ mod tests { fn node(start_height: u64, end_height: u64) -> NodeData { NodeData { + consensus_branch_id: 1, subtree_commitment: [0u8; 32], start_time: 0, end_time: 0,