Introduce better hashing.

- Blake2 for secure hashing
- XX for fast hashing
This commit is contained in:
Gav
2018-01-19 14:17:56 +01:00
parent 748ee54870
commit c29313c618
24 changed files with 307 additions and 98 deletions
@@ -65,7 +65,7 @@ fn rotate_session() {
#[cfg(test)]
mod tests {
use runtime_support::with_externalities;
use runtime_support::{with_externalities, twox_128};
use keyedvec::KeyedVec;
use joiner::Joiner;
use testing::{one, two, TestExternalities};
@@ -76,15 +76,15 @@ mod tests {
#[test]
fn session_change_should_work() {
let mut t = TestExternalities { storage: map![
b"ses\0bps".to_vec() => vec![].join(&2u64),
twox_128(b"ses\0bps").to_vec() => vec![].join(&2u64),
// the validators (10, 20, ...)
b"ses\0key\0len".to_vec() => vec![].join(&2u32),
0u32.to_keyed_vec(b"ses\0key\0") => vec![10; 32],
1u32.to_keyed_vec(b"ses\0key\0") => vec![20; 32],
twox_128(b"ses\0key\0len").to_vec() => vec![].join(&2u32),
twox_128(&0u32.to_keyed_vec(b"ses\0key\0")).to_vec() => vec![10; 32],
twox_128(&1u32.to_keyed_vec(b"ses\0key\0")).to_vec() => vec![20; 32],
// initial session keys (11, 21, ...)
b"con\0aut\0len".to_vec() => vec![].join(&2u32),
0u32.to_keyed_vec(b"con\0aut\0") => vec![11; 32],
1u32.to_keyed_vec(b"con\0aut\0") => vec![21; 32]
twox_128(b"con\0aut\0len").to_vec() => vec![].join(&2u32),
twox_128(&0u32.to_keyed_vec(b"con\0aut\0")).to_vec() => vec![11; 32],
twox_128(&1u32.to_keyed_vec(b"con\0aut\0")).to_vec() => vec![21; 32]
], };
with_externalities(&mut t, || {
assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]);
@@ -102,7 +102,7 @@ pub fn check_new_era() {
#[cfg(test)]
mod tests {
use runtime_support::with_externalities;
use runtime_support::{with_externalities, twox_128};
use keyedvec::KeyedVec;
use joiner::Joiner;
use testing::{one, two, TestExternalities};
@@ -113,8 +113,8 @@ mod tests {
#[test]
fn staking_eras_work() {
let mut t = TestExternalities { storage: map![
b"ses\0bps".to_vec() => vec![].join(&1u64),
b"sta\0spe".to_vec() => vec![].join(&2u64)
twox_128(b"ses\0bps").to_vec() => vec![].join(&1u64),
twox_128(b"sta\0spe").to_vec() => vec![].join(&2u64)
], };
with_externalities(&mut t, || {
assert_eq!(staking::era_length(), 2u64);
@@ -180,7 +180,7 @@ mod tests {
let two = two();
let mut t = TestExternalities { storage: map![
one.to_keyed_vec(b"sta\0bal\0") => vec![].join(&42u64)
twox_128(&one.to_keyed_vec(b"sta\0bal\0")).to_vec() => vec![].join(&42u64)
], };
with_externalities(&mut t, || {
@@ -195,7 +195,7 @@ mod tests {
let two = two();
let mut t = TestExternalities { storage: map![
one.to_keyed_vec(b"sta\0bal\0") => vec![].join(&111u64)
twox_128(&one.to_keyed_vec(b"sta\0bal\0")).to_vec() => vec![].join(&111u64)
], };
with_externalities(&mut t, || {
@@ -45,7 +45,7 @@ pub fn execute_block(mut block: Block) {
// store the header hash in storage.
let header_hash_key = header.number.to_keyed_vec(b"sys\0old\0");
header.keccak256().store(&header_hash_key);
header.blake2_256().store(&header_hash_key);
// execute transactions
block.transactions.iter().for_each(execute_transaction);
@@ -97,7 +97,7 @@ mod tests {
use function::Function;
use keyedvec::KeyedVec;
use slicable::Slicable;
use runtime_support::with_externalities;
use runtime_support::{with_externalities, twox_128};
use primitives::{UncheckedTransaction, Transaction};
use statichex::StaticHexInto;
use runtime::{system, staking};
@@ -109,7 +109,7 @@ mod tests {
let two = two();
let mut t = TestExternalities { storage: map![
one.to_keyed_vec(b"sta\0bal\0") => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
twox_128(&one.to_keyed_vec(b"sta\0bal\0")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
], };
let tx = UncheckedTransaction {
@@ -13,14 +13,14 @@ pub fn set(now: Timestamp) {
mod tests {
use joiner::Joiner;
use keyedvec::KeyedVec;
use runtime_support::with_externalities;
use runtime_support::{with_externalities, twox_128};
use runtime::timestamp;
use testing::TestExternalities;
#[test]
fn timestamp_works() {
let mut t = TestExternalities { storage: map![
b"tim\0val".to_vec() => vec![].join(&42u64)
twox_128(b"tim\0val").to_vec() => vec![].join(&42u64)
], };
with_externalities(&mut t, || {
@@ -3,7 +3,7 @@ use streamreader::StreamReader;
use joiner::Joiner;
use slicable::{Slicable, NonTrivialSlicable};
use function::Function;
use runtime_support::{size_of, keccak256, ed25519_verify};
use runtime_support::{size_of, blake2_256, twox_128, twox_256, ed25519_verify};
#[cfg(test)]
use std::fmt;
@@ -109,12 +109,20 @@ impl Slicable for Transaction {
}
pub trait Hashable: Sized {
fn keccak256(&self) -> [u8; 32];
fn blake2_256(&self) -> [u8; 32];
fn twox_128(&self) -> [u8; 16];
fn twox_256(&self) -> [u8; 32];
}
impl<T: Slicable> Hashable for T {
fn keccak256(&self) -> [u8; 32] {
keccak256(&self.to_vec())
fn blake2_256(&self) -> [u8; 32] {
blake2_256(&self.to_vec())
}
fn twox_128(&self) -> [u8; 16] {
twox_128(&self.to_vec())
}
fn twox_256(&self) -> [u8; 32] {
twox_256(&self.to_vec())
}
}
@@ -1,7 +1,7 @@
use slicable::Slicable;
use endiansensitive::EndianSensitive;
use keyedvec::KeyedVec;
use runtime_support;
use runtime_support::{self, twox_128, Vec};
pub trait Storable {
fn lookup_default(key: &[u8]) -> Self where Self: Sized + Default { Self::lookup(key).unwrap_or_else(Default::default) }
@@ -9,20 +9,20 @@ pub trait Storable {
fn store(&self, key: &[u8]);
}
pub fn kill(key: &[u8]) { runtime_support::set_storage(key, b""); }
pub fn kill(key: &[u8]) { runtime_support::set_storage(&twox_128(key)[..], b""); }
impl<T: Default + Sized + EndianSensitive> Storable for T {
fn lookup(key: &[u8]) -> Option<Self> {
Slicable::set_as_slice(|out| runtime_support::read_storage(key, out) == out.len())
Slicable::set_as_slice(|out| runtime_support::read_storage(&twox_128(key)[..], out) == out.len())
}
fn store(&self, key: &[u8]) {
self.as_slice_then(|slice| runtime_support::set_storage(key, slice));
self.as_slice_then(|slice| runtime_support::set_storage(&twox_128(key)[..], slice));
}
}
impl Storable for [u8] {
fn store(&self, key: &[u8]) {
runtime_support::set_storage(key, self)
runtime_support::set_storage(&twox_128(key)[..], self)
}
}
+26 -4
View File
@@ -29,7 +29,9 @@ extern "C" {
fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8;
fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32) -> u32;
fn ext_chain_id() -> u64;
fn ext_keccak256(data: *const u8, len: u32, out: *mut u8);
fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8);
fn ext_twox_128(data: *const u8, len: u32, out: *mut u8);
fn ext_twox_256(data: *const u8, len: u32, out: *mut u8);
fn ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32;
}
@@ -80,12 +82,32 @@ pub fn chain_id() -> u64 {
}
}
/// Conduct a keccak256 hash.
pub fn keccak256(data: &[u8]) -> [u8; 32] {
/// Conduct a 256-bit Blake2 hash.
pub fn blake2_256(data: &[u8]) -> [u8; 32] {
unsafe {
let mut result: [u8; 32] = uninitialized();
// guaranteed to write into result.
ext_keccak256(&data[0], data.len() as u32, &mut result[0]);
ext_blake2_256(&data[0], data.len() as u32, &mut result[0]);
result
}
}
/// Conduct four XX hashes to give a 256-bit result.
pub fn twox_256(data: &[u8]) -> [u8; 32] {
unsafe {
let mut result: [u8; 32] = uninitialized();
// guaranteed to write into result.
ext_twox_256(&data[0], data.len() as u32, &mut result[0]);
result
}
}
/// Conduct two XX hashes to give a 256-bit result.
pub fn twox_128(data: &[u8]) -> [u8; 16] {
unsafe {
let mut result: [u8; 16] = uninitialized();
// guaranteed to write into result.
ext_twox_128(&data[0], data.len() as u32, &mut result[0]);
result
}
}
+12 -5
View File
@@ -8,10 +8,18 @@ use alloc::vec::Vec;
#[macro_use]
extern crate runtime_support;
use runtime_support::{set_storage, storage, print, keccak256, ed25519_verify};
use runtime_support::{set_storage, storage, print, blake2_256, twox_128, twox_256, ed25519_verify};
fn test_keccak256(input: Vec<u8>) -> Vec<u8> {
keccak256(&input).to_vec()
fn test_blake2_256(input: Vec<u8>) -> Vec<u8> {
blake2_256(&input).to_vec()
}
fn test_twox_256(input: Vec<u8>) -> Vec<u8> {
twox_256(&input).to_vec()
}
fn test_twox_128(input: Vec<u8>) -> Vec<u8> {
twox_128(&input).to_vec()
}
fn test_ed25519_verify(input: Vec<u8>) -> Vec<u8> {
@@ -35,5 +43,4 @@ fn test_data_in(input: Vec<u8>) -> Vec<u8> {
b"all ok!".to_vec()
}
impl_stubs!(test_data_in, test_keccak256, test_ed25519_verify);
impl_stubs!(test_data_in, test_blake2_256, test_twox_256, test_twox_128, test_ed25519_verify);