diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 7d5f50ddc4..72a5687799 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -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)" = "" "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" diff --git a/substrate/executor/Cargo.toml b/substrate/executor/Cargo.toml index 2d124f60ac..0401bd4c77 100644 --- a/substrate/executor/Cargo.toml +++ b/substrate/executor/Cargo.toml @@ -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] diff --git a/substrate/executor/src/lib.rs b/substrate/executor/src/lib.rs index 3c54d25efb..f1da582538 100644 --- a/substrate/executor/src/lib.rs +++ b/substrate/executor/src/lib.rs @@ -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] diff --git a/substrate/executor/src/wasm_executor.rs b/substrate/executor/src/wasm_executor.rs index 07056b1df7..c0c638fa3d 100644 --- a/substrate/executor/src/wasm_executor.rs +++ b/substrate/executor/src/wasm_executor.rs @@ -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()); diff --git a/substrate/native-runtime/support/Cargo.toml b/substrate/native-runtime/support/Cargo.toml index f576037bd2..1c24c014e6 100644 --- a/substrate/native-runtime/support/Cargo.toml +++ b/substrate/native-runtime/support/Cargo.toml @@ -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" } diff --git a/substrate/native-runtime/support/src/lib.rs b/substrate/native-runtime/support/src/lib.rs index aaa323f98d..caa7f3b272 100644 --- a/substrate/native-runtime/support/src/lib.rs +++ b/substrate/native-runtime/support/src/lib.rs @@ -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 { diff --git a/substrate/primitives/Cargo.toml b/substrate/primitives/Cargo.toml index 045afba827..77eccdea88 100644 --- a/substrate/primitives/Cargo.toml +++ b/substrate/primitives/Cargo.toml @@ -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" } diff --git a/substrate/primitives/src/ed25519.rs b/substrate/primitives/src/ed25519.rs index 2630f858d2..e9ac7e473c 100644 --- a/substrate/primitives/src/ed25519.rs +++ b/substrate/primitives/src/ed25519.rs @@ -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 { + 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() { diff --git a/substrate/primitives/src/hash.rs b/substrate/primitives/src/hash.rs index cef573f6f2..0b56d5757f 100644 --- a/substrate/primitives/src/hash.rs +++ b/substrate/primitives/src/hash.rs @@ -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 { diff --git a/substrate/primitives/src/lib.rs b/substrate/primitives/src/lib.rs index fc26658200..cb7606add2 100644 --- a/substrate/primitives/src/lib.rs +++ b/substrate/primitives/src/lib.rs @@ -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 } diff --git a/substrate/state_machine/Cargo.toml b/substrate/state_machine/Cargo.toml index a0d25c821c..458bae8e1e 100644 --- a/substrate/state_machine/Cargo.toml +++ b/substrate/state_machine/Cargo.toml @@ -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" diff --git a/substrate/state_machine/src/lib.rs b/substrate/state_machine/src/lib.rs index 91622c9bc4..cee96a36ad 100644 --- a/substrate/state_machine/src/lib.rs +++ b/substrate/state_machine/src/lib.rs @@ -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; diff --git a/substrate/wasm-runtime/polkadot/src/runtime/session.rs b/substrate/wasm-runtime/polkadot/src/runtime/session.rs index ee88937ead..412809d6b8 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/session.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/session.rs @@ -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]]); diff --git a/substrate/wasm-runtime/polkadot/src/runtime/staking.rs b/substrate/wasm-runtime/polkadot/src/runtime/staking.rs index 127b7041ad..f3bae42060 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/staking.rs @@ -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, || { diff --git a/substrate/wasm-runtime/polkadot/src/runtime/system.rs b/substrate/wasm-runtime/polkadot/src/runtime/system.rs index 0b3b8a590b..0bf300d2b3 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/system.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/system.rs @@ -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 { diff --git a/substrate/wasm-runtime/polkadot/src/runtime/timestamp.rs b/substrate/wasm-runtime/polkadot/src/runtime/timestamp.rs index 2232843b07..10708a5a3c 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/timestamp.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/timestamp.rs @@ -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, || { diff --git a/substrate/wasm-runtime/polkadot/src/support/primitives.rs b/substrate/wasm-runtime/polkadot/src/support/primitives.rs index ecac3fbbd4..fb983bf84e 100644 --- a/substrate/wasm-runtime/polkadot/src/support/primitives.rs +++ b/substrate/wasm-runtime/polkadot/src/support/primitives.rs @@ -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 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()) } } diff --git a/substrate/wasm-runtime/polkadot/src/support/storable.rs b/substrate/wasm-runtime/polkadot/src/support/storable.rs index 7d45587338..177475b2d7 100644 --- a/substrate/wasm-runtime/polkadot/src/support/storable.rs +++ b/substrate/wasm-runtime/polkadot/src/support/storable.rs @@ -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 Storable for T { fn lookup(key: &[u8]) -> Option { - 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) } } diff --git a/substrate/wasm-runtime/support/src/lib.rs b/substrate/wasm-runtime/support/src/lib.rs index 57606a3f1b..bc987ff396 100644 --- a/substrate/wasm-runtime/support/src/lib.rs +++ b/substrate/wasm-runtime/support/src/lib.rs @@ -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 } } diff --git a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index 658efc3738..dbc3273e1b 100644 Binary files a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm and b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm differ diff --git a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm index 1d1c937b70..d04664b607 100644 Binary files a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm and b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm differ diff --git a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 69e547cd11..5c717847a5 100644 Binary files a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm and b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm differ diff --git a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm index cbf1c77bdc..64fb6a48bf 100644 Binary files a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm and b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm differ diff --git a/substrate/wasm-runtime/test/src/lib.rs b/substrate/wasm-runtime/test/src/lib.rs index f6eb4c024e..1cf1934976 100644 --- a/substrate/wasm-runtime/test/src/lib.rs +++ b/substrate/wasm-runtime/test/src/lib.rs @@ -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) -> Vec { - keccak256(&input).to_vec() +fn test_blake2_256(input: Vec) -> Vec { + blake2_256(&input).to_vec() +} + +fn test_twox_256(input: Vec) -> Vec { + twox_256(&input).to_vec() +} + +fn test_twox_128(input: Vec) -> Vec { + twox_128(&input).to_vec() } fn test_ed25519_verify(input: Vec) -> Vec { @@ -35,5 +43,4 @@ fn test_data_in(input: Vec) -> Vec { 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);