From d9e6469811655e7272d4a5cf23f888b8776e4acc Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 18 Oct 2018 00:48:28 +0200 Subject: Simplify sha3. --- libdevcore/SHA3.cpp | 93 +++++++++++------------------------------------------ libdevcore/SHA3.h | 8 +---- 2 files changed, 19 insertions(+), 82 deletions(-) (limited to 'libdevcore') diff --git a/libdevcore/SHA3.cpp b/libdevcore/SHA3.cpp index e41a5e3b..6933f255 100644 --- a/libdevcore/SHA3.cpp +++ b/libdevcore/SHA3.cpp @@ -31,7 +31,7 @@ using namespace dev; namespace dev { -namespace keccak +namespace { /** libkeccak-tiny @@ -43,26 +43,6 @@ namespace keccak * but not liability. */ -#define decshake(bits) \ - int shake##bits(uint8_t*, size_t, const uint8_t*, size_t); - -#define decsha3(bits) \ - int sha3_##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) -decsha3(224) -decsha3(256) -decsha3(384) -decsha3(512) -deckeccak(224) -deckeccak(256) -deckeccak(384) -deckeccak(512) - /******** The Keccak-f[1600] permutation ********/ /*** Constants. ***/ @@ -164,13 +144,15 @@ mkapply_sd(setout, dst[i] = src[i]) // setout } /** 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; - } +inline void hash( + uint8_t* out, + size_t outlen, + const uint8_t* in, + size_t inlen, + size_t rate, + uint8_t delim +) +{ uint8_t a[Plen] = {0}; // Absorb input. foldP(in, inlen, xorin); @@ -185,58 +167,19 @@ static inline int hash(uint8_t* out, size_t outlen, 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 defsha3(bits) \ - int sha3_##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), 0x06); \ - } -#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 ***/ -defsha3(224) -defsha3(256) -defsha3(384) -defsha3(512) - -/*** KECCAK FOFs ***/ -defkeccak(224) -defkeccak(256) -defkeccak(384) -defkeccak(512) - } -bool keccak256(bytesConstRef _input, bytesRef o_output) +h256 keccak256(bytesConstRef _input) { - // FIXME: What with unaligned memory? - if (o_output.size() != 32) - return false; - keccak::keccak256(o_output.data(), 32, _input.data(), _input.size()); -// keccak::keccak(ret.data(), 32, (uint64_t const*)_input.data(), _input.size()); - return true; + h256 output; + // Parameters used: + // The 0x01 is the specific padding for keccak (sha3 uses 0x06) and + // the way the round size (or window or whatever it was) is calculated. + // 200 - (256 / 4) is the "rate" + hash(output.data(), output.size, _input.data(), _input.size(), 200 - (256 / 4), 0x01); + return output; } } diff --git a/libdevcore/SHA3.h b/libdevcore/SHA3.h index d1e2cc98..0d5f69bb 100644 --- a/libdevcore/SHA3.h +++ b/libdevcore/SHA3.h @@ -30,14 +30,8 @@ namespace dev { -// Keccak-256 convenience routines. - -/// Calculate Keccak-256 hash of the given input and load it into the given output. -/// @returns false if o_output.size() != 32. -bool keccak256(bytesConstRef _input, bytesRef o_output); - /// Calculate Keccak-256 hash of the given input, returning as a 256-bit hash. -inline h256 keccak256(bytesConstRef _input) { h256 ret; keccak256(_input, ret.ref()); return ret; } +h256 keccak256(bytesConstRef _input); /// Calculate Keccak-256 hash of the given input, returning as a 256-bit hash. inline h256 keccak256(bytes const& _input) { return keccak256(bytesConstRef(&_input)); } -- cgit From e78b95d9d4ecb6d8d56ca0f04a6f9b4f7d974fbb Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 18 Oct 2018 13:35:20 +0200 Subject: Renamed SHA3.{h,cpp} files. --- libdevcore/CommonData.cpp | 2 +- libdevcore/Keccak256.cpp | 186 ++++++++++++++++++++++++++++++++++++++++++++++ libdevcore/Keccak256.h | 45 +++++++++++ libdevcore/SHA3.cpp | 185 --------------------------------------------- libdevcore/SHA3.h | 45 ----------- libdevcore/SwarmHash.cpp | 2 +- 6 files changed, 233 insertions(+), 232 deletions(-) create mode 100644 libdevcore/Keccak256.cpp create mode 100644 libdevcore/Keccak256.h delete mode 100644 libdevcore/SHA3.cpp delete mode 100644 libdevcore/SHA3.h (limited to 'libdevcore') diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index 6d7c74d7..cb79fa98 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include diff --git a/libdevcore/Keccak256.cpp b/libdevcore/Keccak256.cpp new file mode 100644 index 00000000..7933fc7e --- /dev/null +++ b/libdevcore/Keccak256.cpp @@ -0,0 +1,186 @@ +/* + This file is part of solidity. + + solidity 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. + + solidity 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 solidity. If not, see . +*/ +/** @file SHA3.cpp + * @author Gav Wood + * @date 2014 + */ + +#include + +#include +#include +#include +#include + +using namespace std; +using namespace dev; + +namespace dev +{ + +namespace +{ + +/** 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. + */ + +/******** 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}; + + for (int i = 0; i < 24; i++) + { + uint8_t x, y; + // 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 + uint64_t 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) \ + _(for (size_t 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. **/ +inline void hash( + uint8_t* out, + size_t outlen, + const uint8_t* in, + size_t inlen, + size_t rate, + uint8_t delim +) +{ + 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); +} + +} + +h256 keccak256(bytesConstRef _input) +{ + h256 output; + // Parameters used: + // The 0x01 is the specific padding for keccak (sha3 uses 0x06) and + // the way the round size (or window or whatever it was) is calculated. + // 200 - (256 / 4) is the "rate" + hash(output.data(), output.size, _input.data(), _input.size(), 200 - (256 / 4), 0x01); + return output; +} + +} diff --git a/libdevcore/Keccak256.h b/libdevcore/Keccak256.h new file mode 100644 index 00000000..0d5f69bb --- /dev/null +++ b/libdevcore/Keccak256.h @@ -0,0 +1,45 @@ +/* + This file is part of solidity. + + solidity 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. + + solidity 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 solidity. If not, see . +*/ +/** @file SHA3.h + * @author Gav Wood + * @date 2014 + * + * The FixedHash fixed-size "hash" container type. + */ + +#pragma once + +#include + +#include + +namespace dev +{ + +/// Calculate Keccak-256 hash of the given input, returning as a 256-bit hash. +h256 keccak256(bytesConstRef _input); + +/// Calculate Keccak-256 hash of the given input, returning as a 256-bit hash. +inline h256 keccak256(bytes const& _input) { return keccak256(bytesConstRef(&_input)); } + +/// Calculate Keccak-256 hash of the given input (presented as a binary-filled string), returning as a 256-bit hash. +inline h256 keccak256(std::string const& _input) { return keccak256(bytesConstRef(_input)); } + +/// Calculate Keccak-256 hash of the given input (presented as a FixedHash), returns a 256-bit hash. +template inline h256 keccak256(FixedHash const& _input) { return keccak256(_input.ref()); } + +} diff --git a/libdevcore/SHA3.cpp b/libdevcore/SHA3.cpp deleted file mode 100644 index 6933f255..00000000 --- a/libdevcore/SHA3.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* - This file is part of solidity. - - solidity 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. - - solidity 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 solidity. If not, see . -*/ -/** @file SHA3.cpp - * @author Gav Wood - * @date 2014 - */ - -#include "SHA3.h" -#include -#include -#include -#include - -using namespace std; -using namespace dev; - -namespace dev -{ - -namespace -{ - -/** 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. - */ - -/******** 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}; - - for (int i = 0; i < 24; i++) - { - uint8_t x, y; - // 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 - uint64_t 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) \ - _(for (size_t 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. **/ -inline void hash( - uint8_t* out, - size_t outlen, - const uint8_t* in, - size_t inlen, - size_t rate, - uint8_t delim -) -{ - 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); -} - -} - -h256 keccak256(bytesConstRef _input) -{ - h256 output; - // Parameters used: - // The 0x01 is the specific padding for keccak (sha3 uses 0x06) and - // the way the round size (or window or whatever it was) is calculated. - // 200 - (256 / 4) is the "rate" - hash(output.data(), output.size, _input.data(), _input.size(), 200 - (256 / 4), 0x01); - return output; -} - -} diff --git a/libdevcore/SHA3.h b/libdevcore/SHA3.h deleted file mode 100644 index 0d5f69bb..00000000 --- a/libdevcore/SHA3.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - This file is part of solidity. - - solidity 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. - - solidity 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 solidity. If not, see . -*/ -/** @file SHA3.h - * @author Gav Wood - * @date 2014 - * - * The FixedHash fixed-size "hash" container type. - */ - -#pragma once - -#include - -#include - -namespace dev -{ - -/// Calculate Keccak-256 hash of the given input, returning as a 256-bit hash. -h256 keccak256(bytesConstRef _input); - -/// Calculate Keccak-256 hash of the given input, returning as a 256-bit hash. -inline h256 keccak256(bytes const& _input) { return keccak256(bytesConstRef(&_input)); } - -/// Calculate Keccak-256 hash of the given input (presented as a binary-filled string), returning as a 256-bit hash. -inline h256 keccak256(std::string const& _input) { return keccak256(bytesConstRef(_input)); } - -/// Calculate Keccak-256 hash of the given input (presented as a FixedHash), returns a 256-bit hash. -template inline h256 keccak256(FixedHash const& _input) { return keccak256(_input.ref()); } - -} diff --git a/libdevcore/SwarmHash.cpp b/libdevcore/SwarmHash.cpp index 1c718200..3b8d2f3e 100644 --- a/libdevcore/SwarmHash.cpp +++ b/libdevcore/SwarmHash.cpp @@ -19,7 +19,7 @@ #include -#include +#include using namespace std; using namespace dev; -- cgit