From 693c2f88e17c5ba9af4c111e71bef74f106a4c4c Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 19 Jan 2018 21:28:19 +0100 Subject: [PATCH] Repotting and docs. --- substrate/primitives/src/ed25519.rs | 54 ++-------------- substrate/primitives/src/hashing.rs | 88 +++++++++++++++++++++++++ substrate/primitives/src/hexdisplay.rs | 38 +++++++++++ substrate/primitives/src/lib.rs | 89 +------------------------- 4 files changed, 136 insertions(+), 133 deletions(-) create mode 100644 substrate/primitives/src/hashing.rs create mode 100644 substrate/primitives/src/hexdisplay.rs diff --git a/substrate/primitives/src/ed25519.rs b/substrate/primitives/src/ed25519.rs index e9ac7e473c..cdbbc194c7 100644 --- a/substrate/primitives/src/ed25519.rs +++ b/substrate/primitives/src/ed25519.rs @@ -4,6 +4,7 @@ use untrusted; use ring::{rand, signature}; use rustc_hex::FromHex; +/// Verify a message without type checking the parameters' types for the right size. pub fn verify(sig: &[u8], message: &[u8], public: &[u8]) -> bool { let public_key = untrusted::Input::from(public); let msg = untrusted::Input::from(message); @@ -27,9 +28,12 @@ pub struct Pair(signature::Ed25519KeyPair); pub struct Signature ([u8; 64]); impl Signature { + /// A new signature from the given 64-byte `data`. pub fn from(data: [u8; 64]) -> Self { Signature(data) } + + /// A new signature from the given slice that should be 64 bytes long. pub fn from_slice(data: &[u8]) -> Self { let mut r = [0u8; 64]; r.copy_from_slice(data); @@ -50,9 +54,12 @@ impl AsRef<[u8]> for Signature { } impl Public { + /// A new instance from the given 32-byte `data`. pub fn from(data: [u8; 32]) -> Self { Public(data) } + + /// A new instance from the given slice that should be 32 bytes long. pub fn from_slice(data: &[u8]) -> Self { let mut r = [0u8; 32]; r.copy_from_slice(data); @@ -166,53 +173,9 @@ 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::*; - use super::hexdisplay::HexDisplay; #[test] fn test_vector_should_work() { @@ -238,7 +201,6 @@ mod test { fn seeded_pair_should_work() { let pair = Pair::from_seed(b"12345678901234567890123456789012"); let public = pair.public(); - println!("{}", HexDisplay::from(&public.0)); assert_eq!(public, "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".into()); let message = b"Something important"; let signature = pair.sign(&message[..]); @@ -252,8 +214,6 @@ mod test { assert_eq!(public, "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".into()); let message = FromHex::from_hex("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000").unwrap(); let signature = pair.sign(&message[..]); - println!("pub: {}", HexDisplay::from(&public.0)); - println!("sig: {}", HexDisplay::from(&signature.0)); assert!(signature.verify(&message[..], &public)); } } diff --git a/substrate/primitives/src/hashing.rs b/substrate/primitives/src/hashing.rs new file mode 100644 index 0000000000..b21e06391e --- /dev/null +++ b/substrate/primitives/src/hashing.rs @@ -0,0 +1,88 @@ +use blake2_rfc; +use twox_hash; + +/// 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/primitives/src/hexdisplay.rs b/substrate/primitives/src/hexdisplay.rs new file mode 100644 index 0000000000..708d5e0528 --- /dev/null +++ b/substrate/primitives/src/hexdisplay.rs @@ -0,0 +1,38 @@ +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]); diff --git a/substrate/primitives/src/lib.rs b/substrate/primitives/src/lib.rs index cb7606add2..c774ec7f42 100644 --- a/substrate/primitives/src/lib.rs +++ b/substrate/primitives/src/lib.rs @@ -51,6 +51,8 @@ pub mod parachain; pub mod uint; pub mod validator; pub mod ed25519; +pub mod hexdisplay; +pub mod hashing; /// Alias to 160-bit hash when used in the context of an account address. pub type Address = hash::H160; @@ -59,94 +61,9 @@ pub type Signature = hash::H512; pub use self::hash::{H160, H256}; pub use self::uint::{U256, U512}; +pub use hashing::{blake2_256, twox_128, twox_256}; /// A hash function. pub fn hash(data: &[u8]) -> hash::H256 { 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 -}