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
+37 -4
View File
@@ -20,6 +20,14 @@ dependencies = [
"odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "arrayvec"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "assert_matches"
version = "1.1.0"
@@ -90,6 +98,15 @@ name = "bitflags"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blake2-rfc"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.7 (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 = "byteorder"
version = "1.1.0"
@@ -138,6 +155,11 @@ dependencies = [
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "constant_time_eq"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crunchy"
version = "0.1.6"
@@ -710,13 +732,14 @@ dependencies = [
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "polkadot-primitives"
version = "0.1.0"
dependencies = [
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"fixed-hash 0.1.0 (git+https://github.com/paritytech/primitives.git)",
"polkadot-serializer 0.1.0",
@@ -725,7 +748,7 @@ dependencies = [
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"uint 0.1.0 (git+https://github.com/paritytech/primitives.git)",
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -767,7 +790,6 @@ version = "0.1.0"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"polkadot-primitives 0.1.0",
@@ -898,7 +920,6 @@ dependencies = [
"parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"polkadot-primitives 0.1.0",
"polkadot-state-machine 0.1.0",
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1151,6 +1172,14 @@ dependencies = [
"rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "twox-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "uint"
version = "0.1.0"
@@ -1235,6 +1264,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
"checksum arrayvec 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e003cbf6e0e1c43a0fc8df2ea8ea24174514d35cbcf60c35ca6112e0139f65e2"
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
"checksum assert_matches 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e772942dccdf11b368c31e044e4fca9189f80a773d2f0808379de65894cbf57"
"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860"
"checksum backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99f2ce94e22b8e664d95c57fff45b98a966c2252b60691d0b7aeeccd88d70983"
@@ -1243,12 +1273,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5442186ef6560f30f1ee4b9c1e4c87a35a6879d3644550cc248ec2b955eb5fcd"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
"checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6"
"checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b8c532887f1a292d17de05ae858a8fe50a301e196f9ef0ddb7ccd0d1d00f180"
"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
@@ -1351,6 +1383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389"
"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162"
"checksum triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9291c7f0fae44858b5e087dd462afb382354120003778f1695b44aab98c7abd7"
"checksum twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "475352206e7a290c5fccc27624a163e8d0d115f7bb60ca18a64fc9ce056d7435"
"checksum uint 0.1.0 (git+https://github.com/paritytech/primitives.git)" = "<none>"
"checksum unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e01da42520092d0cd2d6ac3ae69eb21a22ad43ff195676b86f8c37f487d6b80"
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
-1
View File
@@ -12,7 +12,6 @@ serde = "1.0"
serde_derive = "1.0"
parity-wasm = "0.15.0"
byteorder = "1.1"
tiny-keccak = "1.3"
rustc-hex = "1.0.0"
[dev-dependencies]
-1
View File
@@ -33,7 +33,6 @@ extern crate polkadot_state_machine as state_machine;
extern crate serde;
extern crate parity_wasm;
extern crate byteorder;
extern crate tiny_keccak;
extern crate rustc_hex;
#[macro_use]
+56 -10
View File
@@ -26,8 +26,7 @@ use state_machine::{Externalities, CodeExecutor};
use error::{Error, ErrorKind, Result};
use wasm_utils::{MemoryInstance, UserDefinedElements,
AddModuleWithoutFullDependentInstance};
use tiny_keccak;
use primitives::ed25519;
use primitives::{ed25519, blake2_256, twox_128, twox_256};
struct Heap {
end: u32,
@@ -141,10 +140,28 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
ext_chain_id() -> u64 => {
this.ext.chain_id()
},
ext_keccak256(data: *const u8, len: u32, out: *mut u8) => {
ext_twox_128(data: *const u8, len: u32, out: *mut u8) => {
let result =
if let Ok(value) = this.memory.get(data, len as usize) {
tiny_keccak::keccak256(&value)
twox_128(&value)
} else {
[0; 16]
};
let _ = this.memory.set(out, &result);
},
ext_twox_256(data: *const u8, len: u32, out: *mut u8) => {
let result =
if let Ok(value) = this.memory.get(data, len as usize) {
twox_256(&value)
} else {
[0; 32]
};
let _ = this.memory.set(out, &result);
},
ext_blake2_256(data: *const u8, len: u32, out: *mut u8) => {
let result =
if let Ok(value) = this.memory.get(data, len as usize) {
blake2_256(&value)
} else {
[0; 32]
};
@@ -223,6 +240,7 @@ mod tests {
use super::*;
use rustc_hex::FromHex;
use primitives::ed25519::hexdisplay::HexDisplay;
#[derive(Debug, Default)]
struct TestExternalities {
@@ -261,16 +279,44 @@ mod tests {
}
#[test]
fn keccak256_should_work() {
fn blake2_256_should_work() {
let mut ext = TestExternalities::default();
let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
assert_eq!(
WasmExecutor.call(&mut ext, &test_code[..], "test_keccak256", &CallData(b"".to_vec())).unwrap(),
FromHex::from_hex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap()
WasmExecutor.call(&mut ext, &test_code[..], "test_blake2_256", &CallData(b"".to_vec())).unwrap(),
FromHex::from_hex("0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8").unwrap()
);
assert_eq!(
WasmExecutor.call(&mut ext, &test_code[..], "test_keccak256", &CallData(b"Hello world!".to_vec())).unwrap(),
FromHex::from_hex("ecd0e108a98e192af1d2c25055f4e3bed784b5c877204e73219a5203251feaab").unwrap()
WasmExecutor.call(&mut ext, &test_code[..], "test_blake2_256", &CallData(b"Hello world!".to_vec())).unwrap(),
FromHex::from_hex("3fbc092db9350757e2ab4f7ee9792bfcd2f5220ada5a4bc684487f60c6034369").unwrap()
);
}
#[test]
fn twox_256_should_work() {
let mut ext = TestExternalities::default();
let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
assert_eq!(
WasmExecutor.call(&mut ext, &test_code[..], "test_twox_256", &CallData(b"".to_vec())).unwrap(),
FromHex::from_hex("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a").unwrap()
);
assert_eq!(
WasmExecutor.call(&mut ext, &test_code[..], "test_twox_256", &CallData(b"Hello world!".to_vec())).unwrap(),
FromHex::from_hex("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74").unwrap()
);
}
#[test]
fn twox_128_should_work() {
let mut ext = TestExternalities::default();
let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
assert_eq!(
WasmExecutor.call(&mut ext, &test_code[..], "test_twox_128", &CallData(b"".to_vec())).unwrap(),
FromHex::from_hex("99e9d85137db46ef4bbea33613baafd5").unwrap()
);
assert_eq!(
WasmExecutor.call(&mut ext, &test_code[..], "test_twox_128", &CallData(b"Hello world!".to_vec())).unwrap(),
FromHex::from_hex("b27dfd7f223f177f2a13647b533599af").unwrap()
);
}
@@ -278,7 +324,7 @@ mod tests {
fn ed25519_verify_should_work() {
let mut ext = TestExternalities::default();
let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
let key = ed25519::Pair::from_seed(&tiny_keccak::keccak256(b"test"));
let key = ed25519::Pair::from_seed(&blake2_256(b"test"));
let sig = key.sign(b"all ok!");
let mut calldata = vec![];
calldata.extend_from_slice(key.public().as_ref());
@@ -11,5 +11,4 @@ lazy_static = "1.0.0"
parking_lot = "0.5"
polkadot-state-machine = { path = "../../state_machine" , version = "0.1" }
environmental = { path = "../../environmental", version = "0.1.0" }
tiny-keccak = "1.3"
polkadot-primitives = { path = "../../primitives", version = "0.1.0" }
+1 -2
View File
@@ -1,7 +1,6 @@
#[macro_use]
extern crate environmental;
extern crate polkadot_state_machine;
extern crate tiny_keccak;
extern crate polkadot_primitives as primitives;
use std::fmt;
@@ -76,7 +75,7 @@ pub fn chain_id() -> u64 {
}
/// Conduct a Keccak-256 hash of the given data.
pub use tiny_keccak::keccak256;
pub use primitives::{blake2_256, twox_128, twox_256};
/// Verify a ed25519 signature.
pub fn ed25519_verify(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> bool {
+3 -1
View File
@@ -9,10 +9,12 @@ fixed-hash = { git = "https://github.com/paritytech/primitives.git" }
rustc-hex = "1.0"
serde = "1.0"
serde_derive = "1.0"
tiny-keccak = "1.3"
uint = { git = "https://github.com/paritytech/primitives.git" }
ring = "0.12"
untrusted = "0.5"
twox-hash = "1.1.0"
byteorder = "1.1"
blake2-rfc = "0.2.18"
[dev-dependencies]
polkadot-serializer = { path = "../serializer", version = "0.1" }
+44 -35
View File
@@ -166,44 +166,53 @@ impl PartialEq for Signature {
}
}
pub mod hexdisplay {
pub struct HexDisplay<'a>(&'a [u8]);
impl<'a> HexDisplay<'a> {
pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) }
}
impl<'a> ::std::fmt::Display for HexDisplay<'a> {
fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
for byte in self.0 {
try!( fmtr.write_fmt(format_args!("{:02x}", byte)));
}
Ok(())
}
}
pub trait AsBytesRef {
fn as_bytes_ref(&self) -> &[u8];
}
impl AsBytesRef for [u8] {
fn as_bytes_ref(&self) -> &[u8] { &self }
}
impl AsBytesRef for Vec<u8> {
fn as_bytes_ref(&self) -> &[u8] { &self }
}
macro_rules! impl_non_endians {
( $( $t:ty ),* ) => { $(
impl AsBytesRef for $t {
fn as_bytes_ref(&self) -> &[u8] { &self[..] }
}
)* }
}
impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8],
[u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40],
[u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]);
}
#[cfg(test)]
mod test {
use super::*;
pub struct HexDisplay<'a>(&'a [u8]);
impl<'a> HexDisplay<'a> {
pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) }
}
impl<'a> ::std::fmt::Display for HexDisplay<'a> {
fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
for byte in self.0 {
try!( fmtr.write_fmt(format_args!("{:02x}", byte)));
}
Ok(())
}
}
pub trait AsBytesRef {
fn as_bytes_ref(&self) -> &[u8];
}
impl AsBytesRef for [u8] {
fn as_bytes_ref(&self) -> &[u8] { &self }
}
macro_rules! impl_non_endians {
( $( $t:ty ),* ) => { $(
impl AsBytesRef for $t {
fn as_bytes_ref(&self) -> &[u8] { &self[..] }
}
)* }
}
impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8],
[u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40],
[u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]);
use super::hexdisplay::HexDisplay;
#[test]
fn test_vector_should_work() {
+2 -2
View File
@@ -41,8 +41,8 @@ impl_hash!(H160, 20);
impl_serde!(H160, 20);
impl_hash!(H256, 32);
impl_serde!(H256, 32);
impl_hash!(H520, 65);
impl_serde!(H520, 65);
impl_hash!(H512, 64);
impl_serde!(H512, 64);
#[cfg(test)]
mod tests {
+91 -3
View File
@@ -20,9 +20,11 @@
extern crate rustc_hex;
extern crate serde;
extern crate tiny_keccak;
extern crate ring;
extern crate untrusted;
extern crate twox_hash;
extern crate byteorder;
extern crate blake2_rfc;
#[macro_use]
extern crate crunchy;
@@ -53,12 +55,98 @@ pub mod ed25519;
/// Alias to 160-bit hash when used in the context of an account address.
pub type Address = hash::H160;
/// Alias to 520-bit hash when used in the context of a signature.
pub type Signature = hash::H520;
pub type Signature = hash::H512;
pub use self::hash::{H160, H256};
pub use self::uint::{U256, U512};
/// A hash function.
pub fn hash(data: &[u8]) -> hash::H256 {
tiny_keccak::keccak256(data).into()
blake2_256(data).into()
}
/// Do a Blake2 512-bit hash and place result in `dest`.
pub fn blake2_512_into(data: &[u8], dest: &mut[u8; 64]) {
dest.copy_from_slice(blake2_rfc::blake2b::blake2b(64, &[], data).as_bytes());
}
/// Do a Blake2 512-bit hash and return result.
pub fn blake2_512(data: &[u8]) -> [u8; 64] {
let mut r: [u8; 64] = unsafe { std::mem::uninitialized() };
blake2_512_into(data, &mut r);
r
}
/// Do a Blake2 256-bit hash and place result in `dest`.
pub fn blake2_256_into(data: &[u8], dest: &mut[u8; 32]) {
dest.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes());
}
/// Do a Blake2 256-bit hash and return result.
pub fn blake2_256(data: &[u8]) -> [u8; 32] {
let mut r: [u8; 32] = unsafe { std::mem::uninitialized() };
blake2_256_into(data, &mut r);
r
}
/// Do a Blake2 128-bit hash and place result in `dest`.
pub fn blake2_128_into(data: &[u8], dest: &mut[u8; 16]) {
dest.copy_from_slice(blake2_rfc::blake2b::blake2b(16, &[], data).as_bytes());
}
/// Do a Blake2 128-bit hash and return result.
pub fn blake2_128(data: &[u8]) -> [u8; 16] {
let mut r: [u8; 16] = unsafe { std::mem::uninitialized() };
blake2_128_into(data, &mut r);
r
}
/// Do a XX 128-bit hash and place result in `dest`.
pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) {
use ::std::hash::Hasher;
let mut h0 = twox_hash::XxHash::with_seed(0);
let mut h1 = twox_hash::XxHash::with_seed(1);
h0.write(data);
h1.write(data);
let r0 = h0.finish();
let r1 = h1.finish();
use byteorder::{ByteOrder, LittleEndian};
LittleEndian::write_u64(&mut dest[0..8], r0);
LittleEndian::write_u64(&mut dest[8..16], r1);
}
/// Do a XX 128-bit hash and return result.
pub fn twox_128(data: &[u8]) -> [u8; 16] {
let mut r: [u8; 16] = unsafe { std::mem::uninitialized() };
twox_128_into(data, &mut r);
r
}
/// Do a XX 256-bit hash and place result in `dest`.
pub fn twox_256_into(data: &[u8], dest: &mut [u8; 32]) {
use ::std::hash::Hasher;
use byteorder::{ByteOrder, LittleEndian};
let mut h0 = twox_hash::XxHash::with_seed(0);
let mut h1 = twox_hash::XxHash::with_seed(1);
let mut h2 = twox_hash::XxHash::with_seed(2);
let mut h3 = twox_hash::XxHash::with_seed(3);
h0.write(data);
h1.write(data);
h2.write(data);
h3.write(data);
let r0 = h0.finish();
let r1 = h1.finish();
let r2 = h2.finish();
let r3 = h3.finish();
LittleEndian::write_u64(&mut dest[0..8], r0);
LittleEndian::write_u64(&mut dest[8..16], r1);
LittleEndian::write_u64(&mut dest[16..24], r2);
LittleEndian::write_u64(&mut dest[24..32], r3);
}
/// Do a XX 256-bit hash and return result.
pub fn twox_256(data: &[u8]) -> [u8; 32] {
let mut r: [u8; 32] = unsafe { std::mem::uninitialized() };
twox_256_into(data, &mut r);
r
}
-1
View File
@@ -7,7 +7,6 @@ description = "Polkadot State Machine"
[dependencies]
polkadot-primitives = { path = "../primitives", version = "0.1.0" }
hashdb = "0.1.1"
keccak-hash = "0.1.0"
patricia-trie = "0.1.0"
memorydb = "0.1.1"
triehash = "0.1"
-1
View File
@@ -22,7 +22,6 @@ extern crate polkadot_primitives as primitives;
extern crate hashdb;
extern crate memorydb;
extern crate keccak_hash;
extern crate patricia_trie;
extern crate triehash;
@@ -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);