lazy_static! {
static ref LEAF_TYPE: &'static [u8] = b"0";
static ref PARENT_TYPE: &'static [u8] = b"1";
static ref ROOT_TYPE: &'static [u8] = b"2";
}
extern crate blake2_rfc as blake2;
extern crate byteorder;
extern crate merkle_tree_stream as merkle_stream;
extern crate rust_sodium as sodium;
pub use self::blake2::blake2b::Blake2bResult;
pub use self::sodium::crypto::sign::ed25519::{PublicKey, SecretKey, Signature};
use self::blake2::blake2b::Blake2b;
use self::byteorder::{BigEndian, WriteBytesExt};
use self::merkle_stream::Node;
use self::sodium::crypto::sign::ed25519::{sign_detached, verify_detached};
pub mod key_pair;
pub fn sign(data: &[u8], secret_key: &SecretKey) -> Signature {
sign_detached(data, secret_key)
}
pub fn verify(
signature: &Signature,
data: &[u8],
public_key: &PublicKey,
) -> bool {
verify_detached(signature, data, public_key)
}
pub fn hash_leaf(data: &Node) -> Blake2bResult {
let mut size = vec![]; size
.write_u64::<BigEndian>(data.len() as u64)
.unwrap();
let mut hasher = Blake2b::new(32);
hasher.update(*LEAF_TYPE);
hasher.update(&size);
hasher.update(data.as_ref().unwrap());
hasher.finalize()
}
pub fn hash_parent(a: &Node, b: &Node) -> Blake2bResult {
assert!(b.position() > a.position());
let mut size = vec![]; size
.write_u64::<BigEndian>((a.len() + b.len()) as u64)
.unwrap();
let mut hasher = Blake2b::new(32);
hasher.update(*PARENT_TYPE);
hasher.update(&size);
hasher.update(a.hash());
hasher.update(b.hash());
hasher.finalize()
}
pub fn hash_roots(roots: &[&Node]) -> Blake2bResult {
let mut hasher = Blake2b::new(32);
hasher.update(*ROOT_TYPE);
for node in roots {
let mut position = Vec::with_capacity(1); position
.write_u64::<BigEndian>((node.position()) as u64)
.unwrap();
let mut len = Vec::with_capacity(1); len
.write_u64::<BigEndian>((node.len()) as u64)
.unwrap();
hasher.update(node.hash());
hasher.update(&position);
hasher.update(&len);
}
hasher.finalize()
}