hashing with blake2

This commit is contained in:
NikVolf 2019-09-03 17:47:21 +03:00
parent d8c04e8143
commit b03b4cf958
4 changed files with 40 additions and 5 deletions

View File

@ -11,4 +11,5 @@ quickcheck = "0.8"
[dependencies]
derive_more = "0.15"
bigint = "4"
byteorder = "1"
byteorder = "1"
blake2-rfc = { git = "https://github.com/gtank/blake2-rfc.git", rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9" }

View File

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

View File

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

View File

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