Remove the Keccak C library and use the pure Rust impl (#8657)
* Add license and readme * Use pure rust implementation * Bump version to 0.1.1 * Don't use C, prefer the pure Rust implementation * Add test for `write_keccak` * Bump version * Add benchmarks * Add benchmarks * Add keccak_256, keccak_512, keccak_256_unchecked and keccak_512_unchecked – mostly for compatibility with ethash * Remove failed git merge attempt from external git repo Cargo.lock updates * whitespace * Mark unsafe function unsafe * Unsafe calls in unsafe block * Document unsafety invariants * Revert unintended changes to Cargo.lock
This commit is contained in:
parent
6552256981
commit
9e719f088f
53
Cargo.lock
generated
53
Cargo.lock
generated
@ -251,7 +251,7 @@ dependencies = [
|
||||
"ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethjson 0.1.0",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"rlp 0.2.1",
|
||||
"rlp_derive 0.1.0",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -487,7 +487,7 @@ version = "1.12.0"
|
||||
dependencies = [
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -541,7 +541,7 @@ dependencies = [
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"journaldb 0.1.0",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
@ -633,7 +633,7 @@ dependencies = [
|
||||
"hashdb 0.1.1",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -685,7 +685,7 @@ dependencies = [
|
||||
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"linked-hash-map 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-reactor 0.1.0",
|
||||
@ -730,7 +730,7 @@ dependencies = [
|
||||
"ethkey 0.3.0",
|
||||
"igd 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -769,7 +769,7 @@ dependencies = [
|
||||
"ethkey 0.3.0",
|
||||
"fetch 0.1.0",
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"patricia-trie 0.1.0",
|
||||
@ -803,7 +803,7 @@ dependencies = [
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -851,7 +851,7 @@ dependencies = [
|
||||
"jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"jsonrpc-tcp-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -875,7 +875,7 @@ dependencies = [
|
||||
"ethkey 0.3.0",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -900,7 +900,7 @@ dependencies = [
|
||||
"ethkey 0.3.0",
|
||||
"evm 0.1.0",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"rlp 0.2.1",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unexpected 0.1.0",
|
||||
@ -1021,7 +1021,7 @@ dependencies = [
|
||||
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memory-cache 0.1.0",
|
||||
@ -1345,7 +1345,7 @@ dependencies = [
|
||||
"ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashdb 0.1.1",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1454,9 +1454,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "keccak-hash"
|
||||
version = "0.1.0"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"cc 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1648,7 +1647,7 @@ dependencies = [
|
||||
"ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashdb 0.1.1",
|
||||
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"plain_hasher 0.1.0",
|
||||
"rlp 0.2.1",
|
||||
]
|
||||
@ -1987,7 +1986,7 @@ dependencies = [
|
||||
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"journaldb 0.1.0",
|
||||
"jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2051,7 +2050,7 @@ dependencies = [
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"linked-hash-map 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2115,7 +2114,7 @@ dependencies = [
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2208,7 +2207,7 @@ dependencies = [
|
||||
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
@ -2244,7 +2243,7 @@ dependencies = [
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-rpc 1.12.0",
|
||||
@ -2332,7 +2331,7 @@ dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-sync 1.12.0",
|
||||
"ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2440,7 +2439,7 @@ dependencies = [
|
||||
"ethcore-logger 1.12.0",
|
||||
"ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashdb 0.1.1",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memorydb 0.1.1",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2736,7 +2735,7 @@ dependencies = [
|
||||
"ethabi-contract 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3472,7 +3471,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"rlp 0.2.1",
|
||||
]
|
||||
|
||||
@ -3482,7 +3481,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"rlp 0.2.1",
|
||||
"trie-standardmap 0.1.0",
|
||||
]
|
||||
@ -3630,7 +3629,7 @@ dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethereum-types 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethjson 0.1.0",
|
||||
"keccak-hash 0.1.0",
|
||||
"keccak-hash 0.1.2",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"patricia-trie 0.1.0",
|
||||
"rlp 0.2.1",
|
||||
|
@ -21,32 +21,36 @@ pub type H256 = [u8; 32];
|
||||
pub mod keccak_512 {
|
||||
use super::hash;
|
||||
|
||||
pub use self::hash::keccak_512 as unchecked;
|
||||
pub use self::hash::keccak_512_unchecked as unchecked;
|
||||
|
||||
pub fn write(input: &[u8], output: &mut [u8]) {
|
||||
unsafe { hash::keccak_512(output.as_mut_ptr(), output.len(), input.as_ptr(), input.len()) };
|
||||
hash::keccak_512(input, output);
|
||||
}
|
||||
|
||||
pub fn inplace(input: &mut [u8]) {
|
||||
// This is safe since `sha3_*` uses an internal buffer and copies the result to the output. This
|
||||
// This is safe since `keccak_*` uses an internal buffer and copies the result to the output. This
|
||||
// means that we can reuse the input buffer for both input and output.
|
||||
unsafe { hash::keccak_512(input.as_mut_ptr(), input.len(), input.as_ptr(), input.len()) };
|
||||
unsafe {
|
||||
hash::keccak_512_unchecked(input.as_mut_ptr(), input.len(), input.as_ptr(), input.len());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod keccak_256 {
|
||||
use super::hash;
|
||||
|
||||
pub use self::hash::keccak_256 as unchecked;
|
||||
pub use self::hash::keccak_256_unchecked as unchecked;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn write(input: &[u8], output: &mut [u8]) {
|
||||
unsafe { hash::keccak_256(output.as_mut_ptr(), output.len(), input.as_ptr(), input.len()) };
|
||||
hash::keccak_256(input, output);
|
||||
}
|
||||
|
||||
pub fn inplace(input: &mut [u8]) {
|
||||
// This is safe since `sha3_*` uses an internal buffer and copies the result to the output. This
|
||||
// This is safe since `keccak_*` uses an internal buffer and copies the result to the output. This
|
||||
// means that we can reuse the input buffer for both input and output.
|
||||
unsafe { hash::keccak_256(input.as_mut_ptr(), input.len(), input.as_ptr(), input.len()) };
|
||||
unsafe {
|
||||
hash::keccak_256_unchecked(input.as_mut_ptr(), input.len(), input.as_ptr(), input.len());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,15 @@
|
||||
[package]
|
||||
description = "Rust bindings for tinykeccak C library"
|
||||
homepage = "http://parity.io"
|
||||
homepage = "https://github.com/paritytech/keccak-hash"
|
||||
readme = "README.md"
|
||||
license = "GPL-3.0"
|
||||
name = "keccak-hash"
|
||||
version = "0.1.0"
|
||||
version = "0.1.2"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
ethereum-types = "0.3"
|
||||
tiny-keccak = "1.3"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
tiny-keccak = "1.4.1"
|
||||
|
||||
[dev-dependencies]
|
||||
tempdir = "0.3"
|
||||
|
36
util/hash/benches/keccak_256.rs
Normal file
36
util/hash/benches/keccak_256.rs
Normal file
@ -0,0 +1,36 @@
|
||||
#![feature(test)]
|
||||
|
||||
extern crate test;
|
||||
extern crate ethereum_types;
|
||||
extern crate keccak_hash;
|
||||
|
||||
use keccak_hash::{keccak, write_keccak};
|
||||
use test::Bencher;
|
||||
|
||||
#[bench]
|
||||
fn bench_keccak_256_with_empty_input(b: &mut Bencher) {
|
||||
let empty = [0u8;0];
|
||||
b.bytes = empty.len() as u64;
|
||||
b.iter(|| {
|
||||
let _out = keccak(empty);
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_keccak_256_with_typical_input(b: &mut Bencher) {
|
||||
let data: Vec<u8> = From::from("some medum length string with important information");
|
||||
b.bytes = data.len() as u64;
|
||||
b.iter(|| {
|
||||
let _out = keccak(&data);
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_keccak_256_with_large_input(b: &mut Bencher) {
|
||||
// 4096 chars
|
||||
let data: Vec<u8> = From::from("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");
|
||||
b.bytes = data.len() as u64;
|
||||
b.iter(|| {
|
||||
let _out = keccak(&data);
|
||||
})
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// build.rs
|
||||
|
||||
// Bring in a dependency on an externally maintained `cc` package which manages
|
||||
// invoking the C compiler.
|
||||
extern crate cc;
|
||||
|
||||
fn main() {
|
||||
cc::Build::new().file("src/tinykeccak.c").compile("libtinykeccak.a");
|
||||
}
|
||||
|
@ -18,7 +18,9 @@ extern crate ethereum_types;
|
||||
extern crate tiny_keccak;
|
||||
|
||||
use std::io;
|
||||
use std::slice;
|
||||
use tiny_keccak::Keccak;
|
||||
|
||||
pub use ethereum_types::H256;
|
||||
|
||||
/// Get the KECCAK (i.e. Keccak) hash of the empty bytes string.
|
||||
@ -30,12 +32,6 @@ pub const KECCAK_NULL_RLP: H256 = H256( [0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x5
|
||||
/// The KECCAK of the RLP encoding of empty list.
|
||||
pub const KECCAK_EMPTY_LIST_RLP: H256 = H256( [0x1d, 0xcc, 0x4d, 0xe8, 0xde, 0xc7, 0x5d, 0x7a, 0xab, 0x85, 0xb5, 0x67, 0xb6, 0xcc, 0xd4, 0x1a, 0xd3, 0x12, 0x45, 0x1b, 0x94, 0x8a, 0x74, 0x13, 0xf0, 0xa1, 0x42, 0xfd, 0x40, 0xd4, 0x93, 0x47] );
|
||||
|
||||
extern {
|
||||
/// Hashes input. Returns -1 if either out or input does not exist. Otherwise returns 0.
|
||||
pub fn keccak_256(out: *mut u8, outlen: usize, input: *const u8, inputlen: usize) -> i32;
|
||||
/// Hashes input. Returns -1 if either out or input does not exist. Otherwise returns 0.
|
||||
pub fn keccak_512(out: *mut u8, outlen: usize, input: *const u8, inputlen: usize) -> i32;
|
||||
}
|
||||
|
||||
pub fn keccak<T: AsRef<[u8]>>(s: T) -> H256 {
|
||||
let mut result = [0u8; 32];
|
||||
@ -43,15 +39,30 @@ pub fn keccak<T: AsRef<[u8]>>(s: T) -> H256 {
|
||||
H256(result)
|
||||
}
|
||||
|
||||
pub fn write_keccak<T: AsRef<[u8]>>(s: T, dest: &mut [u8]) {
|
||||
let input = s.as_ref();
|
||||
unsafe {
|
||||
// we can safely ignore keccak_256 output, cause we know that both input
|
||||
// and dest are properly allocated
|
||||
keccak_256(dest.as_mut_ptr(), dest.len(), input.as_ptr(), input.len());
|
||||
}
|
||||
pub unsafe fn keccak_256_unchecked(out: *mut u8, outlen: usize, input: *const u8, inputlen: usize) {
|
||||
// This is safe since `keccak_*` uses an internal buffer and copies the result to the output. This
|
||||
// means that we can reuse the input buffer for both input and output.
|
||||
Keccak::keccak256(
|
||||
slice::from_raw_parts(input, inputlen),
|
||||
slice::from_raw_parts_mut(out, outlen)
|
||||
);
|
||||
}
|
||||
|
||||
pub unsafe fn keccak_512_unchecked(out: *mut u8, outlen: usize, input: *const u8, inputlen: usize) {
|
||||
// This is safe since `keccak_*` uses an internal buffer and copies the result to the output. This
|
||||
// means that we can reuse the input buffer for both input and output.
|
||||
Keccak::keccak512(
|
||||
slice::from_raw_parts(input, inputlen),
|
||||
slice::from_raw_parts_mut(out, outlen)
|
||||
);
|
||||
}
|
||||
|
||||
pub fn keccak_256(input: &[u8], mut output: &mut [u8]) { Keccak::keccak256(input, &mut output); }
|
||||
|
||||
pub fn keccak_512(input: &[u8], mut output: &mut [u8]) { Keccak::keccak512(input, &mut output); }
|
||||
|
||||
pub fn write_keccak<T: AsRef<[u8]>>(s: T, dest: &mut [u8]) { Keccak::keccak256(s.as_ref(), dest); }
|
||||
|
||||
pub fn keccak_pipe(r: &mut io::BufRead, w: &mut io::Write) -> Result<H256, io::Error> {
|
||||
let mut output = [0u8; 32];
|
||||
let mut input = [0u8; 1024];
|
||||
@ -82,17 +93,33 @@ mod tests {
|
||||
use std::fs;
|
||||
use std::io::{Write, BufReader};
|
||||
use self::tempdir::TempDir;
|
||||
use super::{keccak, keccak_buffer, KECCAK_EMPTY};
|
||||
use super::{keccak, write_keccak, keccak_buffer, KECCAK_EMPTY};
|
||||
|
||||
#[test]
|
||||
fn keccak_empty() {
|
||||
assert_eq!(keccak([0u8; 0]), KECCAK_EMPTY);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn keccak_as() {
|
||||
assert_eq!(keccak([0x41u8; 32]), From::from("59cad5948673622c1d64e2322488bf01619f7ff45789741b15a9f782ce9290a8"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_keccak_with_content() {
|
||||
let data: Vec<u8> = From::from("hello world");
|
||||
let expected = vec![
|
||||
0x47, 0x17, 0x32, 0x85, 0xa8, 0xd7, 0x34, 0x1e,
|
||||
0x5e, 0x97, 0x2f, 0xc6, 0x77, 0x28, 0x63, 0x84,
|
||||
0xf8, 0x02, 0xf8, 0xef, 0x42, 0xa5, 0xec, 0x5f,
|
||||
0x03, 0xbb, 0xfa, 0x25, 0x4c, 0xb0, 0x1f, 0xad
|
||||
];
|
||||
let mut dest = [0u8;32];
|
||||
write_keccak(data, &mut dest);
|
||||
|
||||
assert_eq!(dest, expected.as_ref());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_keccak_a_file() {
|
||||
// given
|
||||
|
@ -1,177 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/** libkeccak-tiny
|
||||
*
|
||||
* A single-file implementation of SHA-3 and SHAKE.
|
||||
*
|
||||
* Implementor: David Leon Gil
|
||||
* License: CC0, attribution kindly requested. Blame taken too,
|
||||
* but not liability.
|
||||
*/
|
||||
|
||||
#define decshake(bits) \
|
||||
int shake##bits(uint8_t*, size_t, const uint8_t*, size_t);
|
||||
|
||||
#define deckeccak(bits) \
|
||||
int keccak_##bits(uint8_t*, size_t, const uint8_t*, size_t);
|
||||
|
||||
decshake(128)
|
||||
decshake(256)
|
||||
deckeccak(224)
|
||||
deckeccak(256)
|
||||
deckeccak(384)
|
||||
deckeccak(512)
|
||||
|
||||
/******** The Keccak-f[1600] permutation ********/
|
||||
|
||||
/*** Constants. ***/
|
||||
static const uint8_t rho[24] = \
|
||||
{ 1, 3, 6, 10, 15, 21,
|
||||
28, 36, 45, 55, 2, 14,
|
||||
27, 41, 56, 8, 25, 43,
|
||||
62, 18, 39, 61, 20, 44};
|
||||
static const uint8_t pi[24] = \
|
||||
{10, 7, 11, 17, 18, 3,
|
||||
5, 16, 8, 21, 24, 4,
|
||||
15, 23, 19, 13, 12, 2,
|
||||
20, 14, 22, 9, 6, 1};
|
||||
static const uint64_t RC[24] = \
|
||||
{1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,
|
||||
0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,
|
||||
0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL,
|
||||
0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,
|
||||
0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL,
|
||||
0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL};
|
||||
|
||||
/*** Helper macros to unroll the permutation. ***/
|
||||
#define rol(x, s) (((x) << s) | ((x) >> (64 - s)))
|
||||
#define REPEAT6(e) e e e e e e
|
||||
#define REPEAT24(e) REPEAT6(e e e e)
|
||||
#define REPEAT5(e) e e e e e
|
||||
#define FOR5(v, s, e) \
|
||||
v = 0; \
|
||||
REPEAT5(e; v += s;)
|
||||
|
||||
/*** Keccak-f[1600] ***/
|
||||
static inline void keccakf(void* state) {
|
||||
uint64_t* a = (uint64_t*)state;
|
||||
uint64_t b[5] = {0};
|
||||
uint64_t t = 0;
|
||||
uint8_t x, y;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 24; i++) {
|
||||
// Theta
|
||||
FOR5(x, 1,
|
||||
b[x] = 0;
|
||||
FOR5(y, 5,
|
||||
b[x] ^= a[x + y]; ))
|
||||
FOR5(x, 1,
|
||||
FOR5(y, 5,
|
||||
a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); ))
|
||||
// Rho and pi
|
||||
t = a[1];
|
||||
x = 0;
|
||||
REPEAT24(b[0] = a[pi[x]];
|
||||
a[pi[x]] = rol(t, rho[x]);
|
||||
t = b[0];
|
||||
x++; )
|
||||
// Chi
|
||||
FOR5(y,
|
||||
5,
|
||||
FOR5(x, 1,
|
||||
b[x] = a[y + x];)
|
||||
FOR5(x, 1,
|
||||
a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); ))
|
||||
// Iota
|
||||
a[0] ^= RC[i];
|
||||
}
|
||||
}
|
||||
|
||||
/******** The FIPS202-defined functions. ********/
|
||||
|
||||
/*** Some helper macros. ***/
|
||||
|
||||
#define _(S) do { S } while (0)
|
||||
#define FOR(i, ST, L, S) \
|
||||
_({size_t i; for (i = 0; i < L; i += ST) { S; }})
|
||||
#define mkapply_ds(NAME, S) \
|
||||
static inline void NAME(uint8_t* dst, \
|
||||
const uint8_t* src, \
|
||||
size_t len) { \
|
||||
FOR(i, 1, len, S); \
|
||||
}
|
||||
#define mkapply_sd(NAME, S) \
|
||||
static inline void NAME(const uint8_t* src, \
|
||||
uint8_t* dst, \
|
||||
size_t len) { \
|
||||
FOR(i, 1, len, S); \
|
||||
}
|
||||
|
||||
mkapply_ds(xorin, dst[i] ^= src[i]) // xorin
|
||||
mkapply_sd(setout, dst[i] = src[i]) // setout
|
||||
|
||||
#define P keccakf
|
||||
#define Plen 200
|
||||
|
||||
// Fold P*F over the full blocks of an input.
|
||||
#define foldP(I, L, F) \
|
||||
while (L >= rate) { \
|
||||
F(a, I, rate); \
|
||||
P(a); \
|
||||
I += rate; \
|
||||
L -= rate; \
|
||||
}
|
||||
|
||||
/** The sponge-based hash construction. **/
|
||||
static inline int hash(uint8_t* out, size_t outlen,
|
||||
const uint8_t* in, size_t inlen,
|
||||
size_t rate, uint8_t delim) {
|
||||
if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
|
||||
return -1;
|
||||
}
|
||||
uint8_t a[Plen] = {0};
|
||||
// Absorb input.
|
||||
foldP(in, inlen, xorin);
|
||||
// Xor in the DS and pad frame.
|
||||
a[inlen] ^= delim;
|
||||
a[rate - 1] ^= 0x80;
|
||||
// Xor in the last block.
|
||||
xorin(a, in, inlen);
|
||||
// Apply P
|
||||
P(a);
|
||||
// Squeeze output.
|
||||
foldP(out, outlen, setout);
|
||||
setout(a, out, outlen);
|
||||
memset(a, 0, 200);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** Helper macros to define SHA3 and SHAKE instances. ***/
|
||||
#define defshake(bits) \
|
||||
int shake##bits(uint8_t* out, size_t outlen, \
|
||||
const uint8_t* in, size_t inlen) { \
|
||||
return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x1f); \
|
||||
}
|
||||
#define defkeccak(bits) \
|
||||
int keccak_##bits(uint8_t* out, size_t outlen, \
|
||||
const uint8_t* in, size_t inlen) { \
|
||||
if (outlen > (bits/8)) { \
|
||||
return -1; \
|
||||
} \
|
||||
return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \
|
||||
}
|
||||
|
||||
/*** FIPS202 SHAKE VOFs ***/
|
||||
defshake(128)
|
||||
defshake(256)
|
||||
|
||||
/*** FIPS202 SHA3 FOFs ***/
|
||||
defkeccak(224)
|
||||
defkeccak(256)
|
||||
defkeccak(384)
|
||||
defkeccak(512)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user