mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 05:21:08 +00:00
Hashing proc macro utils (#9875)
* hashing macro * fmt * use in easy place, and fix blake sizes * fix * Fixes, docs. Allow ident as input. * fix doc tests * update error in test (nmapkey and key are same type). * hashing crates under sp_core * Doc updates and format. * use all existing hashing functions. * return array of u8 * Update primitives/core/hashing/proc-macro/src/impls.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * ToTokeen for an array of u8 * fix * re * Improve impls * complete doc tests * fmt * fix doctest format * fix ui test (nmap key type alias) Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: Bastian Köcher <info@kchr.de>
This commit is contained in:
Generated
+26
@@ -2051,6 +2051,7 @@ dependencies = [
|
||||
"smallvec 1.7.0",
|
||||
"sp-arithmetic",
|
||||
"sp-core",
|
||||
"sp-core-hashing-proc-macro",
|
||||
"sp-inherents",
|
||||
"sp-io",
|
||||
"sp-runtime",
|
||||
@@ -7919,6 +7920,7 @@ dependencies = [
|
||||
"sc-tracing",
|
||||
"sp-api",
|
||||
"sp-core",
|
||||
"sp-core-hashing-proc-macro",
|
||||
"sp-externalities",
|
||||
"sp-io",
|
||||
"sp-maybe-compressed-blob",
|
||||
@@ -9303,6 +9305,8 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.9.8",
|
||||
"sp-core-hashing",
|
||||
"sp-core-hashing-proc-macro",
|
||||
"sp-debug-derive",
|
||||
"sp-externalities",
|
||||
"sp-runtime-interface",
|
||||
@@ -9319,6 +9323,28 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sp-core-hashing"
|
||||
version = "4.0.0-dev"
|
||||
dependencies = [
|
||||
"blake2-rfc",
|
||||
"byteorder",
|
||||
"sha2 0.9.8",
|
||||
"sp-std",
|
||||
"tiny-keccak",
|
||||
"twox-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sp-core-hashing-proc-macro"
|
||||
version = "4.0.0-dev"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"sp-core-hashing",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sp-database"
|
||||
version = "4.0.0-dev"
|
||||
|
||||
@@ -155,6 +155,8 @@ members = [
|
||||
"primitives/consensus/pow",
|
||||
"primitives/consensus/vrf",
|
||||
"primitives/core",
|
||||
"primitives/core/hashing",
|
||||
"primitives/core/hashing/proc-macro",
|
||||
"primitives/database",
|
||||
"primitives/debug-derive",
|
||||
"primitives/externalities",
|
||||
|
||||
@@ -33,6 +33,7 @@ sc-executor-wasmtime = { version = "0.10.0-dev", path = "wasmtime", optional = t
|
||||
parking_lot = "0.11.1"
|
||||
log = "0.4.8"
|
||||
libsecp256k1 = "0.6"
|
||||
sp-core-hashing-proc-macro = { version = "4.0.0-dev", path = "../../primitives/core/hashing/proc-macro" }
|
||||
|
||||
[dev-dependencies]
|
||||
wat = "1.0"
|
||||
|
||||
@@ -344,7 +344,7 @@ fn decode_version(mut version: &[u8]) -> Result<RuntimeVersion, WasmError> {
|
||||
})?
|
||||
.into();
|
||||
|
||||
let core_api_id = sp_core::hashing::blake2_64(b"Core");
|
||||
let core_api_id = sp_core_hashing_proc_macro::blake2b_64!(b"Core");
|
||||
if v.has_api_with(&core_api_id, |v| v >= 3) {
|
||||
sp_api::RuntimeVersion::decode(&mut version).map_err(|_| {
|
||||
WasmError::Instantiation("failed to decode \"Core_version\" result".into())
|
||||
|
||||
@@ -34,6 +34,7 @@ bitflags = "1.3"
|
||||
impl-trait-for-tuples = "0.2.1"
|
||||
smallvec = "1.7.0"
|
||||
log = { version = "0.4.14", default-features = false }
|
||||
sp-core-hashing-proc-macro = { version = "4.0.0-dev", path = "../../primitives/core/hashing/proc-macro" }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.3.0"
|
||||
|
||||
@@ -42,6 +42,8 @@ pub use scale_info;
|
||||
pub use serde;
|
||||
pub use sp_core::Void;
|
||||
#[doc(hidden)]
|
||||
pub use sp_core_hashing_proc_macro;
|
||||
#[doc(hidden)]
|
||||
pub use sp_io::{self, storage::root as storage_root};
|
||||
#[doc(hidden)]
|
||||
pub use sp_runtime::RuntimeDebug;
|
||||
@@ -427,9 +429,7 @@ macro_rules! parameter_types {
|
||||
/// Returns the key for this parameter type.
|
||||
#[allow(unused)]
|
||||
pub fn key() -> [u8; 16] {
|
||||
$crate::sp_io::hashing::twox_128(
|
||||
concat!(":", stringify!($name), ":").as_bytes()
|
||||
)
|
||||
$crate::sp_core_hashing_proc_macro::twox_128!(b":", $name, b":")
|
||||
}
|
||||
|
||||
/// Set the value of this parameter type in the storage.
|
||||
|
||||
@@ -4,8 +4,8 @@ error[E0277]: the trait bound `Bar: MaxEncodedLen` is not satisfied
|
||||
10 | #[pallet::generate_storage_info]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ the trait `MaxEncodedLen` is not implemented for `Bar`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `KeyGeneratorMaxEncodedLen` for `Key<frame_support::Twox64Concat, Bar>`
|
||||
= note: required because of the requirements on the impl of `StorageInfoTrait` for `frame_support::pallet_prelude::StorageNMap<_GeneratedPrefixForStorageFoo<T>, Key<frame_support::Twox64Concat, Bar>, u32>`
|
||||
= note: required because of the requirements on the impl of `KeyGeneratorMaxEncodedLen` for `NMapKey<frame_support::Twox64Concat, Bar>`
|
||||
= note: required because of the requirements on the impl of `StorageInfoTrait` for `frame_support::pallet_prelude::StorageNMap<_GeneratedPrefixForStorageFoo<T>, NMapKey<frame_support::Twox64Concat, Bar>, u32>`
|
||||
note: required by `storage_info`
|
||||
--> $DIR/storage.rs:71:2
|
||||
|
|
||||
|
||||
@@ -66,6 +66,7 @@ sha2 = { version = "0.9.8", default-features = false, optional = true }
|
||||
hex = { version = "0.4", default-features = false, optional = true }
|
||||
twox-hash = { version = "1.6.1", default-features = false, optional = true }
|
||||
libsecp256k1 = { version = "0.6", default-features = false, features = ["hmac", "static-context"], optional = true }
|
||||
sp-core-hashing = { version = "4.0.0-dev", path = "./hashing", default-features = false, optional = true }
|
||||
merlin = { version = "2.0", default-features = false, optional = true }
|
||||
ss58-registry = "1.0.0"
|
||||
sp-runtime-interface = { version = "4.0.0-dev", default-features = false, path = "../runtime-interface" }
|
||||
@@ -76,6 +77,7 @@ hex-literal = "0.3.3"
|
||||
rand = "0.7.2"
|
||||
criterion = "0.3.3"
|
||||
serde_json = "1.0"
|
||||
sp-core-hashing-proc-macro = { version = "4.0.0-dev", path = "./hashing/proc-macro" }
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
@@ -118,6 +120,7 @@ std = [
|
||||
"regex",
|
||||
"num-traits/std",
|
||||
"tiny-keccak",
|
||||
"sp-core-hashing/std",
|
||||
"sp-debug-derive/std",
|
||||
"sp-externalities",
|
||||
"sp-storage/std",
|
||||
@@ -142,6 +145,7 @@ full_crypto = [
|
||||
"sha2",
|
||||
"twox-hash",
|
||||
"libsecp256k1",
|
||||
"sp-core-hashing",
|
||||
"sp-runtime-interface/disable_target_static_assertions",
|
||||
"merlin",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
[package]
|
||||
name = "sp-core-hashing"
|
||||
version = "4.0.0-dev"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://substrate.dev"
|
||||
repository = "https://github.com/paritytech/substrate/"
|
||||
description = "Primitive core crate hashing implementation."
|
||||
documentation = "https://docs.rs/sp-core-hashing"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[dependencies]
|
||||
sp-std = { version = "4.0.0-dev", default-features = false, path = "../../std" }
|
||||
byteorder = { version = "1.3.2", default-features = false }
|
||||
|
||||
blake2-rfc = { version = "0.2.18", default-features = false }
|
||||
tiny-keccak = { version = "2.0.1", features = ["keccak"] }
|
||||
sha2 = { version = "0.9.2", default-features = false }
|
||||
twox-hash = { version = "1.5.0", default-features = false }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
"blake2-rfc/std",
|
||||
"sha2/std",
|
||||
"sp-std/std",
|
||||
"twox-hash/std",
|
||||
]
|
||||
@@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "sp-core-hashing-proc-macro"
|
||||
version = "4.0.0-dev"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://substrate.dev"
|
||||
repository = "https://github.com/paritytech/substrate/"
|
||||
description = "This crate provides procedural macros for calculating static hash."
|
||||
documentation = "https://docs.rs/sp-core-hashing-proc-macro"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "1.0.77", features = ["full", "parsing"] }
|
||||
quote = "1.0.6"
|
||||
proc-macro2 = "1.0.29"
|
||||
sp-core-hashing = { version = "4.0.0-dev", path = "../", default-features = false }
|
||||
@@ -0,0 +1,124 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use quote::quote;
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
pub(super) struct InputBytes(pub Vec<u8>);
|
||||
|
||||
pub(super) struct MultipleInputBytes(pub Vec<Vec<u8>>);
|
||||
|
||||
impl MultipleInputBytes {
|
||||
pub(super) fn concatenated(mut self) -> Vec<u8> {
|
||||
if self.0.len() == 0 {
|
||||
Vec::new()
|
||||
} else {
|
||||
let mut result = core::mem::take(&mut self.0[0]);
|
||||
for other in self.0[1..].iter_mut() {
|
||||
result.append(other);
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for InputBytes {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
match syn::ExprArray::parse(input) {
|
||||
Ok(array) => {
|
||||
let mut bytes = Vec::<u8>::new();
|
||||
for expr in array.elems.iter() {
|
||||
match expr {
|
||||
syn::Expr::Lit(lit) => match &lit.lit {
|
||||
syn::Lit::Int(b) => bytes.push(b.base10_parse()?),
|
||||
syn::Lit::Byte(b) => bytes.push(b.value()),
|
||||
_ =>
|
||||
return Err(syn::Error::new(
|
||||
input.span(),
|
||||
"Expected array of u8 elements.".to_string(),
|
||||
)),
|
||||
},
|
||||
_ =>
|
||||
return Err(syn::Error::new(
|
||||
input.span(),
|
||||
"Expected array of u8 elements.".to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
return Ok(InputBytes(bytes))
|
||||
},
|
||||
Err(_e) => (),
|
||||
}
|
||||
// use rust names as a vec of their utf8 bytecode.
|
||||
match syn::Ident::parse(input) {
|
||||
Ok(ident) => return Ok(InputBytes(ident.to_string().as_bytes().to_vec())),
|
||||
Err(_e) => (),
|
||||
}
|
||||
Ok(InputBytes(syn::LitByteStr::parse(input)?.value()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for MultipleInputBytes {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let elts =
|
||||
syn::punctuated::Punctuated::<InputBytes, syn::token::Comma>::parse_terminated(input)?;
|
||||
Ok(MultipleInputBytes(elts.into_iter().map(|elt| elt.0).collect()))
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn twox_64(bytes: Vec<u8>) -> TokenStream {
|
||||
bytes_to_array(sp_core_hashing::twox_64(bytes.as_slice()))
|
||||
}
|
||||
|
||||
pub(super) fn twox_128(bytes: Vec<u8>) -> TokenStream {
|
||||
bytes_to_array(sp_core_hashing::twox_128(bytes.as_slice()))
|
||||
}
|
||||
|
||||
pub(super) fn blake2b_512(bytes: Vec<u8>) -> TokenStream {
|
||||
bytes_to_array(sp_core_hashing::blake2_512(bytes.as_slice()))
|
||||
}
|
||||
|
||||
pub(super) fn blake2b_256(bytes: Vec<u8>) -> TokenStream {
|
||||
bytes_to_array(sp_core_hashing::blake2_256(bytes.as_slice()))
|
||||
}
|
||||
|
||||
pub(super) fn blake2b_64(bytes: Vec<u8>) -> TokenStream {
|
||||
bytes_to_array(sp_core_hashing::blake2_64(bytes.as_slice()))
|
||||
}
|
||||
|
||||
pub(super) fn keccak_256(bytes: Vec<u8>) -> TokenStream {
|
||||
bytes_to_array(sp_core_hashing::keccak_256(bytes.as_slice()))
|
||||
}
|
||||
|
||||
pub(super) fn keccak_512(bytes: Vec<u8>) -> TokenStream {
|
||||
bytes_to_array(sp_core_hashing::keccak_512(bytes.as_slice()))
|
||||
}
|
||||
|
||||
pub(super) fn sha2_256(bytes: Vec<u8>) -> TokenStream {
|
||||
bytes_to_array(sp_core_hashing::sha2_256(bytes.as_slice()))
|
||||
}
|
||||
|
||||
fn bytes_to_array(bytes: impl IntoIterator<Item = u8>) -> TokenStream {
|
||||
let bytes = bytes.into_iter();
|
||||
|
||||
quote!(
|
||||
[ #( #bytes ),* ]
|
||||
)
|
||||
.into()
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Macros to calculate constant hash bytes result.
|
||||
//!
|
||||
//! Macros from this crate does apply a specific hash function on input.
|
||||
//! Input can be literal byte array as `b"content"` or array of bytes
|
||||
//! as `[1, 2, 3]`.
|
||||
//! Rust identifier can also be use, in this case we use their utf8 string
|
||||
//! byte representation, for instance if the ident is `MyStruct`, then
|
||||
//! `b"MyStruct"` will be hashed.
|
||||
//! If multiple arguments comma separated are passed, they are concatenated
|
||||
//! then hashed.
|
||||
//!
|
||||
//! Examples:
|
||||
//!
|
||||
//! ```rust
|
||||
//! assert_eq!(
|
||||
//! sp_core_hashing_proc_macro::blake2b_256!(b"test"),
|
||||
//! sp_core_hashing::blake2_256(b"test"),
|
||||
//! );
|
||||
//! assert_eq!(
|
||||
//! sp_core_hashing_proc_macro::blake2b_256!([1u8]),
|
||||
//! sp_core_hashing::blake2_256(&[1u8]),
|
||||
//! );
|
||||
//! assert_eq!(
|
||||
//! sp_core_hashing_proc_macro::blake2b_256!([1, 2, 3]),
|
||||
//! sp_core_hashing::blake2_256(&[1, 2, 3]),
|
||||
//! );
|
||||
//! assert_eq!(
|
||||
//! sp_core_hashing_proc_macro::blake2b_256!(identifier),
|
||||
//! sp_core_hashing::blake2_256(b"identifier"),
|
||||
//! );
|
||||
//! assert_eq!(
|
||||
//! sp_core_hashing_proc_macro::blake2b_256!(identifier, b"/string"),
|
||||
//! sp_core_hashing::blake2_256(b"identifier/string"),
|
||||
//! );
|
||||
//! ```
|
||||
|
||||
mod impls;
|
||||
|
||||
use impls::MultipleInputBytes;
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
/// Process a Blake2 64-bit hash of bytes parameter outputs a `[u8; 8]`.
|
||||
/// Multiple inputs are concatenated before hashing.
|
||||
/// Input can be identifier (name of identifier as bytes is used), byte string or
|
||||
/// array of bytes.
|
||||
#[proc_macro]
|
||||
pub fn blake2b_64(input: TokenStream) -> TokenStream {
|
||||
impls::blake2b_64(syn::parse_macro_input!(input as MultipleInputBytes).concatenated())
|
||||
}
|
||||
|
||||
/// Apply a Blake2 256-bit hash of bytes parameter, outputs a `[u8; 32]`.
|
||||
/// Multiple inputs are concatenated before hashing.
|
||||
/// Input can be identifier (name of identifier as bytes is used), byte string or
|
||||
/// array of bytes.
|
||||
#[proc_macro]
|
||||
pub fn blake2b_256(input: TokenStream) -> TokenStream {
|
||||
impls::blake2b_256(syn::parse_macro_input!(input as MultipleInputBytes).concatenated())
|
||||
}
|
||||
|
||||
/// Apply a Blake2 512-bit hash of bytes parameter, outputs a `[u8; 64]`.
|
||||
/// Multiple inputs are concatenated before hashing.
|
||||
/// Input can be identifier (name of identifier as bytes is used), byte string or
|
||||
/// array of bytes.
|
||||
#[proc_macro]
|
||||
pub fn blake2b_512(input: TokenStream) -> TokenStream {
|
||||
impls::blake2b_512(syn::parse_macro_input!(input as MultipleInputBytes).concatenated())
|
||||
}
|
||||
|
||||
/// Apply a XX 64-bit hash on its bytes parameter, outputs a `[u8; 8]`.
|
||||
/// Multiple inputs are concatenated before hashing.
|
||||
/// Input can be identifier (name of identifier as bytes is used), byte string or
|
||||
/// array of bytes.
|
||||
#[proc_macro]
|
||||
pub fn twox_64(input: TokenStream) -> TokenStream {
|
||||
impls::twox_64(syn::parse_macro_input!(input as MultipleInputBytes).concatenated())
|
||||
}
|
||||
|
||||
/// Apply a XX 128-bit hash on its bytes parameter, outputs a `[u8; 16]`.
|
||||
/// Multiple inputs are concatenated before hashing.
|
||||
/// Input can be identifier (name of identifier as bytes is used), byte string or
|
||||
/// array of bytes.
|
||||
#[proc_macro]
|
||||
pub fn twox_128(input: TokenStream) -> TokenStream {
|
||||
impls::twox_128(syn::parse_macro_input!(input as MultipleInputBytes).concatenated())
|
||||
}
|
||||
|
||||
/// Apply a keccak 256-bit hash on its bytes parameter, outputs a `[u8; 32]`.
|
||||
/// Multiple inputs are concatenated before hashing.
|
||||
/// Input can be identifier (name of identifier as bytes is used), byte string or
|
||||
/// array of bytes.
|
||||
#[proc_macro]
|
||||
pub fn keccak_256(input: TokenStream) -> TokenStream {
|
||||
impls::keccak_256(syn::parse_macro_input!(input as MultipleInputBytes).concatenated())
|
||||
}
|
||||
|
||||
/// Apply a keccak 512-bit hash on its bytes parameter, outputs a `[u8; 64]`.
|
||||
/// Multiple inputs are concatenated before hashing.
|
||||
/// Input can be identifier (name of identifier as bytes is used), byte string or
|
||||
/// array of bytes.
|
||||
#[proc_macro]
|
||||
pub fn keccak_512(input: TokenStream) -> TokenStream {
|
||||
impls::keccak_512(syn::parse_macro_input!(input as MultipleInputBytes).concatenated())
|
||||
}
|
||||
|
||||
/// Apply a sha2 256-bit hash on its bytes parameter, outputs a `[u8; 32]`.
|
||||
/// Multiple inputs are concatenated before hashing.
|
||||
/// Input can be identifier (name of identifier as bytes is used), byte string or
|
||||
/// array of bytes.
|
||||
#[proc_macro]
|
||||
pub fn sha2_256(input: TokenStream) -> TokenStream {
|
||||
impls::sha2_256(syn::parse_macro_input!(input as MultipleInputBytes).concatenated())
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Hashing Functions.
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
use tiny_keccak::{Hasher, Keccak};
|
||||
|
||||
/// 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 = [0; 64];
|
||||
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 = [0; 32];
|
||||
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 = [0; 16];
|
||||
blake2_128_into(data, &mut r);
|
||||
r
|
||||
}
|
||||
|
||||
/// Do a Blake2 64-bit hash and place result in `dest`.
|
||||
pub fn blake2_64_into(data: &[u8], dest: &mut [u8; 8]) {
|
||||
dest.copy_from_slice(blake2_rfc::blake2b::blake2b(8, &[], data).as_bytes());
|
||||
}
|
||||
|
||||
/// Do a Blake2 64-bit hash and return result.
|
||||
pub fn blake2_64(data: &[u8]) -> [u8; 8] {
|
||||
let mut r = [0; 8];
|
||||
blake2_64_into(data, &mut r);
|
||||
r
|
||||
}
|
||||
|
||||
/// Do a XX 64-bit hash and place result in `dest`.
|
||||
pub fn twox_64_into(data: &[u8], dest: &mut [u8; 8]) {
|
||||
use core::hash::Hasher;
|
||||
let mut h0 = twox_hash::XxHash::with_seed(0);
|
||||
h0.write(data);
|
||||
let r0 = h0.finish();
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
LittleEndian::write_u64(&mut dest[0..8], r0);
|
||||
}
|
||||
|
||||
/// Do a XX 64-bit hash and return result.
|
||||
pub fn twox_64(data: &[u8]) -> [u8; 8] {
|
||||
let mut r: [u8; 8] = [0; 8];
|
||||
twox_64_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 core::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] = [0; 16];
|
||||
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 ::core::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] = [0; 32];
|
||||
twox_256_into(data, &mut r);
|
||||
r
|
||||
}
|
||||
|
||||
/// Do a keccak 256-bit hash and return result.
|
||||
pub fn keccak_256(data: &[u8]) -> [u8; 32] {
|
||||
let mut keccak = Keccak::v256();
|
||||
keccak.update(data);
|
||||
let mut output = [0u8; 32];
|
||||
keccak.finalize(&mut output);
|
||||
output
|
||||
}
|
||||
|
||||
/// Do a keccak 512-bit hash and return result.
|
||||
pub fn keccak_512(data: &[u8]) -> [u8; 64] {
|
||||
let mut keccak = Keccak::v512();
|
||||
keccak.update(data);
|
||||
let mut output = [0u8; 64];
|
||||
keccak.finalize(&mut output);
|
||||
output
|
||||
}
|
||||
|
||||
/// Do a sha2 256-bit hash and return result.
|
||||
pub fn sha2_256(data: &[u8]) -> [u8; 32] {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(data);
|
||||
let mut output = [0u8; 32];
|
||||
output.copy_from_slice(&hasher.finalize());
|
||||
output
|
||||
}
|
||||
@@ -22,147 +22,45 @@
|
||||
//! unless you know what you're doing. Using `sp_io` will be more performant, since instead of
|
||||
//! computing the hash in WASM it delegates that computation to the host client.
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
use tiny_keccak::{Hasher, Keccak};
|
||||
pub use sp_core_hashing::*;
|
||||
|
||||
/// 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());
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
/// Do a Blake2 512-bit hash and return result.
|
||||
pub fn blake2_512(data: &[u8]) -> [u8; 64] {
|
||||
let mut r = [0; 64];
|
||||
blake2_512_into(data, &mut r);
|
||||
r
|
||||
}
|
||||
#[test]
|
||||
fn blake2b() {
|
||||
assert_eq!(sp_core_hashing_proc_macro::blake2b_64!(b""), blake2_64(b"")[..]);
|
||||
assert_eq!(sp_core_hashing_proc_macro::blake2b_256!(b"test"), blake2_256(b"test")[..]);
|
||||
assert_eq!(sp_core_hashing_proc_macro::blake2b_512!(b""), blake2_512(b"")[..]);
|
||||
}
|
||||
|
||||
/// 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());
|
||||
}
|
||||
#[test]
|
||||
fn keccak() {
|
||||
assert_eq!(sp_core_hashing_proc_macro::keccak_256!(b"test"), keccak_256(b"test")[..]);
|
||||
assert_eq!(sp_core_hashing_proc_macro::keccak_512!(b"test"), keccak_512(b"test")[..]);
|
||||
}
|
||||
|
||||
/// Do a Blake2 256-bit hash and return result.
|
||||
pub fn blake2_256(data: &[u8]) -> [u8; 32] {
|
||||
let mut r = [0; 32];
|
||||
blake2_256_into(data, &mut r);
|
||||
r
|
||||
}
|
||||
#[test]
|
||||
fn sha2() {
|
||||
assert_eq!(sp_core_hashing_proc_macro::sha2_256!(b"test"), sha2_256(b"test")[..]);
|
||||
}
|
||||
|
||||
/// 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());
|
||||
}
|
||||
#[test]
|
||||
fn twox() {
|
||||
assert_eq!(sp_core_hashing_proc_macro::twox_128!(b"test"), twox_128(b"test")[..]);
|
||||
assert_eq!(sp_core_hashing_proc_macro::twox_64!(b""), twox_64(b"")[..]);
|
||||
}
|
||||
|
||||
/// Do a Blake2 128-bit hash and return result.
|
||||
pub fn blake2_128(data: &[u8]) -> [u8; 16] {
|
||||
let mut r = [0; 16];
|
||||
blake2_128_into(data, &mut r);
|
||||
r
|
||||
}
|
||||
|
||||
/// Do a Blake2 64-bit hash and place result in `dest`.
|
||||
pub fn blake2_64_into(data: &[u8], dest: &mut [u8; 8]) {
|
||||
dest.copy_from_slice(blake2_rfc::blake2b::blake2b(8, &[], data).as_bytes());
|
||||
}
|
||||
|
||||
/// Do a Blake2 64-bit hash and return result.
|
||||
pub fn blake2_64(data: &[u8]) -> [u8; 8] {
|
||||
let mut r = [0; 8];
|
||||
blake2_64_into(data, &mut r);
|
||||
r
|
||||
}
|
||||
|
||||
/// Do a XX 64-bit hash and place result in `dest`.
|
||||
pub fn twox_64_into(data: &[u8], dest: &mut [u8; 8]) {
|
||||
use core::hash::Hasher;
|
||||
let mut h0 = twox_hash::XxHash::with_seed(0);
|
||||
h0.write(data);
|
||||
let r0 = h0.finish();
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
LittleEndian::write_u64(&mut dest[0..8], r0);
|
||||
}
|
||||
|
||||
/// Do a XX 64-bit hash and return result.
|
||||
pub fn twox_64(data: &[u8]) -> [u8; 8] {
|
||||
let mut r: [u8; 8] = [0; 8];
|
||||
twox_64_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 core::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] = [0; 16];
|
||||
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 ::core::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] = [0; 32];
|
||||
twox_256_into(data, &mut r);
|
||||
r
|
||||
}
|
||||
|
||||
/// Do a keccak 256-bit hash and return result.
|
||||
pub fn keccak_256(data: &[u8]) -> [u8; 32] {
|
||||
let mut keccak = Keccak::v256();
|
||||
keccak.update(data);
|
||||
let mut output = [0u8; 32];
|
||||
keccak.finalize(&mut output);
|
||||
output
|
||||
}
|
||||
|
||||
/// Do a keccak 512-bit hash and return result.
|
||||
pub fn keccak_512(data: &[u8]) -> [u8; 64] {
|
||||
let mut keccak = Keccak::v512();
|
||||
keccak.update(data);
|
||||
let mut output = [0u8; 64];
|
||||
keccak.finalize(&mut output);
|
||||
output
|
||||
}
|
||||
|
||||
/// Do a sha2 256-bit hash and return result.
|
||||
pub fn sha2_256(data: &[u8]) -> [u8; 32] {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(data);
|
||||
let mut output = [0u8; 32];
|
||||
output.copy_from_slice(&hasher.finalize());
|
||||
output
|
||||
#[test]
|
||||
fn twox_concats() {
|
||||
assert_eq!(
|
||||
sp_core_hashing_proc_macro::twox_128!(b"test", b"123", b"45", b"", b"67890"),
|
||||
super::twox_128(&b"test1234567890"[..]),
|
||||
);
|
||||
assert_eq!(
|
||||
sp_core_hashing_proc_macro::twox_128!(b"test", test, b"45", b"", b"67890"),
|
||||
super::twox_128(&b"testtest4567890"[..]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user