From 3e35bd567cb796ca4f758ec0f0beed41410947b5 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Fri, 3 Nov 2023 15:33:53 -0300 Subject: [PATCH] refactor: replace crypto++ with tiny sha3 to compute Keccak hash --- .dockerignore | 2 - .gitignore | 2 - Dockerfile | 2 +- README.md | 6 +- src/Makefile | 43 ++++++------ src/complete-merkle-tree.cpp | 2 + src/cryptopp-keccak-256-hasher.h | 64 ------------------ ...k-256-hasher.cpp => keccak-256-hasher.cpp} | 20 +++++- src/keccak-256-hasher.h | 42 +++++++++++- src/merkle-tree-hash.cpp | 4 +- src/test-merkle-tree-hash.cpp | 4 +- src/test-utils.h | 22 +------ src/uarch-solidity-compat.h | 2 + src/xkcp-keccak-256-hasher.h | 65 ------------------- third-party/tiny_sha3/sha3.c | 54 +++++++++------ third-party/tiny_sha3/sha3.h | 16 ++--- tools/template/control.template | 2 +- 17 files changed, 131 insertions(+), 221 deletions(-) delete mode 100644 src/cryptopp-keccak-256-hasher.h rename src/{xkcp-keccak-256-hasher.cpp => keccak-256-hasher.cpp} (65%) delete mode 100644 src/xkcp-keccak-256-hasher.h diff --git a/.dockerignore b/.dockerignore index 6ebdb8ebd..33554a04f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -12,9 +12,7 @@ **/Dockerfile* build -third-party/cryptopp-CRYPTOPP_7_0_0 third-party/downloads -third-party/grpc src/cartesi-machine-client src/cartesi-machine-server src/cartesi-machine-hash diff --git a/.gitignore b/.gitignore index d773cf5e5..ef0fa359c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,7 @@ *.deb build -third-party/cryptopp-CRYPTOPP_7_0_0 third-party/downloads -third-party/grpc third-party/mongoose-* src/remote-cartesi-machine src/jsonrpc-remote-cartesi-machine diff --git a/Dockerfile b/Dockerfile index 362b849c9..6b1bb3b77 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN apt-get update && \ libboost1.81-dev libssl-dev \ ca-certificates automake libtool patchelf pkg-config lua5.4 liblua5.4-dev \ libgrpc++-dev libprotobuf-dev protobuf-compiler-grpc \ - luarocks libcrypto++-dev && \ + luarocks && \ update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-15 120 && \ update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-15 120 && \ rm -rf /var/lib/apt/lists/* diff --git a/README.md b/README.md index b74a42ab0..d51abe540 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ apt-get install build-essential wget git clang-tidy-15 clang-format-15 \ libboost1.81-dev libssl-dev \ ca-certificates automake libtool patchelf pkg-config lua5.4 liblua5.4-dev \ libgrpc++-dev libprotobuf-dev protobuf-compiler-grpc \ - luarocks libcrypto++-dev + luarocks sudo luarocks install --lua-version=5.4 lpeg sudo luarocks install --lua-version=5.4 dkjson @@ -47,7 +47,7 @@ sudo luarocks install --lua-version=5.4 luaposix ##### MacPorts ``` -sudo port install clang-15 automake boost libtool wget pkgconfig grpc openssl lua libcryptopp lua-luarocks +sudo port install clang-15 automake boost libtool wget pkgconfig grpc openssl lua lua-luarocks sudo luarocks install --lua-version=5.4 lpeg sudo luarocks install --lua-version=5.4 dkjson @@ -58,7 +58,7 @@ sudo luarocks install --lua-version=5.4 luaposix ##### Homebrew ``` -brew install llvm@15 automake boost wget cryptopp pkg-config grpc openssl lua@5.4 luarocks +brew install llvm@15 automake boost wget pkg-config grpc openssl lua@5.4 luarocks luarocks --lua-dir=$(brew --prefix)/opt/lua@5.4 install lpeg luarocks --lua-dir=$(brew --prefix)/opt/lua@5.4 install dkjson luarocks --lua-dir=$(brew --prefix)/opt/lua@5.4 install luasocket diff --git a/src/Makefile b/src/Makefile index 01f8db928..939f90567 100644 --- a/src/Makefile +++ b/src/Makefile @@ -64,8 +64,6 @@ ifneq (,$(shell which brew)) BREW_PREFIX := $(shell brew --prefix) BOOST_LIB_DIR_Darwin=-L$(BREW_PREFIX)/lib BOOST_INC_Darwin=-I$(BREW_PREFIX)/include -CRYPTOPP_LIB_Darwin:=-L$(BREW_PREFIX)/lib -lcryptopp -CRYPTOPP_INC_Darwin:=-I$(BREW_PREFIX)/include GRPC_INC_Darwin:=$(shell pkg-config --cflags-only-I grpc++) GRPC_LIB_Darwin:=$(shell pkg-config --libs grpc++) PROTOBUF_INC_Darwin:=$(shell pkg-config --cflags-only-I protobuf) @@ -74,8 +72,6 @@ else ifneq (,$(shell which port)) # Macports installation PORT_PREFIX := /opt/local BOOST_LIB_DIR_Darwin=-L$(PORT_PREFIX)/libexec/boost/1.81/lib BOOST_INC_Darwin=-I$(PORT_PREFIX)/libexec/boost/1.81/include -CRYPTOPP_LIB_Darwin:=-L$(PORT_PREFIX)/lib -lcryptopp -CRYPTOPP_INC_Darwin:=-I$(PORT_PREFIX)/include GRPC_INC_Darwin:=-I$(PORT_PREFIX)/include GRPC_LIB_Darwin=-L$(PORT_PREFIX)/lib -lgrpc++ -lgrpc -lgpr -lprotobuf -lpthread -labsl_synchronization PROTOBUF_INC_Darwin:=-I$(PORT_PREFIX)/include @@ -106,8 +102,6 @@ INCS_Linux= FS_LIB_Linux=-lstdc++fs PTHREAD_LIB_Linux:=-lpthread BOOST_INC_Linux:= -CRYPTOPP_LIB_Linux:=-lcryptopp -CRYPTOPP_INC_Linux:= GRPC_INC_Linux:=$(shell pkg-config --cflags-only-I grpc++) GRPC_LIB_Linux:=$(shell pkg-config --libs grpc++) PROTOBUF_INC_Linux:=$(shell pkg-config --cflags-only-I protobuf) @@ -129,8 +123,6 @@ CXX=$(CXX_$(UNAME)) SOLDFLAGS:=$(SOLDFLAGS_$(UNAME)) $(GCLDFLAGS) PTHREAD_LIB:=$(PTHREAD_LIB_$(UNAME)) BOOST_INC:=$(BOOST_INC_$(UNAME)) -CRYPTOPP_LIB=$(CRYPTOPP_LIB_$(UNAME)) -CRYPTOPP_INC=$(CRYPTOPP_INC_$(UNAME)) GRPC_INC:=$(GRPC_INC_$(UNAME)) GRPC_LIB:=$(GRPC_LIB_$(UNAME)) PROTOBUF_INC:=$(PROTOBUF_INC_$(UNAME)) @@ -146,15 +138,15 @@ LIBCARTESI_GRPC_LDFLAGS=$(LIBCARTESI_GRPC_LDFLAGS_$(UNAME)) LIBCARTESI_GRPC_TESTS_LDFLAGS=$(LIBCARTESI_GRPC_TESTS_LDFLAGS_$(UNAME)) LIBCARTESI_GRPC_LIB=-L. -lcartesi_grpc-$(EMULATOR_VERSION_MAJOR).$(EMULATOR_VERSION_MINOR) -LIBCARTESI_LIBS:=$(CRYPTOPP_LIB) -LIBCARTESI_GRPC_LIBS:=$(CRYPTOPP_LIB) $(GRPC_LIB) $(PROTOBUF_LIB) -LUACARTESI_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB) -LUACARTESI_GRPC_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB) $(LIBCARTESI_GRPC_LIB) -LUACARTESI_JSONRPC_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB) -REMOTE_CARTESI_MACHINE_LIBS:=$(CRYPTOPP_LIB) $(GRPC_LIB) $(PROTOBUF_LIB) -JSONRPC_REMOTE_CARTESI_MACHINE_LIBS:=$(CRYPTOPP_LIB) -TEST_MACHINE_C_API_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB) $(LIBCARTESI_GRPC_LIB) $(PTHREAD_LIB) -HASH_LIBS:=$(CRYPTOPP_LIB) +LIBCARTESI_LIBS:= +LIBCARTESI_GRPC_LIBS:=$(GRPC_LIB) $(PROTOBUF_LIB) +LUACARTESI_LIBS:=$(LIBCARTESI_LIB) +LUACARTESI_GRPC_LIBS:=$(LIBCARTESI_LIB) $(LIBCARTESI_GRPC_LIB) +LUACARTESI_JSONRPC_LIBS:=$(LIBCARTESI_LIB) +REMOTE_CARTESI_MACHINE_LIBS:=$(GRPC_LIB) $(PROTOBUF_LIB) +JSONRPC_REMOTE_CARTESI_MACHINE_LIBS:= +TEST_MACHINE_C_API_LIBS:=$(LIBCARTESI_LIB) $(LIBCARTESI_GRPC_LIB) $(PTHREAD_LIB) +HASH_LIBS:= #DEFS+= -DMT_ALL_DIRTY @@ -164,9 +156,10 @@ WARNS=-W -Wall -pedantic INCS= \ -I../lib/machine-emulator-defines \ -I../third-party/llvm-flang-uint128 \ + -I../third-party/tiny_sha3 \ -I../third-party/downloads \ -I../third-party/mongoose-7.12 \ - $(LUA_INC) $(CRYPTOPP_INC) $(BOOST_INC) $(PROTOBUF_INC) $(GRPC_INC) $(INCS_$(UNAME)) + $(LUA_INC) $(BOOST_INC) $(PROTOBUF_INC) $(GRPC_INC) $(INCS_$(UNAME)) ifeq ($(dump),yes) #DEFS+=-DDUMP_ILLEGAL_INSN_EXCEPTIONS @@ -248,11 +241,9 @@ PGO_WORKLOAD=\ dhrystone 500000; \ whetstone 2500 -# We ignore xkcp-keccak-256-hasher.cpp because it is missing a header file. -# The file is not being compiled but we want to keep it for reference. # We ignore test-machine-c-api.cpp cause it takes too long. -LINTER_IGNORE_SOURCES=xkcp-keccak-256-hasher.cpp test-machine-c-api.cpp -LINTER_IGNORE_HEADERS=%.pb.h xkcp-keccak-256-hasher.h +LINTER_IGNORE_SOURCES=test-machine-c-api.cpp +LINTER_IGNORE_HEADERS=%.pb.h LINTER_SOURCES=$(filter-out $(LINTER_IGNORE_SOURCES),$(strip $(wildcard *.cpp) $(wildcard *.c))) LINTER_HEADERS=$(filter-out $(LINTER_IGNORE_HEADERS),$(strip $(wildcard *.hpp) $(wildcard *.h))) @@ -317,6 +308,7 @@ LIBCARTESI_OBJS:= \ shadow-pmas-factory.o \ shadow-tlb.o \ shadow-tlb-factory.o \ + keccak-256-hasher.o \ machine-merkle-tree.o \ pristine-merkle-tree.o \ pma.o \ @@ -332,6 +324,7 @@ LIBCARTESI_OBJS:= \ uarch-interpret.o LUACARTESI_OBJS:= \ + keccak-256-hasher.o \ clua-cartesi.o \ clua-i-virtual-machine.o \ clua-machine.o \ @@ -349,6 +342,7 @@ GRPC_GEN_OBJS:= \ cartesi-machine-checkin.grpc.pb.o LIBCARTESI_GRPC_OBJS:= \ + keccak-256-hasher.o \ machine-merkle-tree.o \ pristine-merkle-tree.o \ $(GRPC_GEN_OBJS) \ @@ -525,11 +519,13 @@ hash: merkle-tree-hash tests/test-merkle-tree-hash c-api: $(LIBCARTESI) $(LIBCARTESI_GRPC) tests/test-machine-c-api MERKLE_TREE_HASH_OBJS:= \ + keccak-256-hasher.o \ back-merkle-tree.o \ pristine-merkle-tree.o \ merkle-tree-hash.o TEST_MERKLE_TREE_HASH_OBJS:= \ + keccak-256-hasher.o \ back-merkle-tree.o \ pristine-merkle-tree.o \ complete-merkle-tree.o \ @@ -538,6 +534,7 @@ TEST_MERKLE_TREE_HASH_OBJS:= \ TEST_MACHINE_C_API_OBJS:= \ test-machine-c-api.o \ + keccak-256-hasher.o \ back-merkle-tree.o \ pristine-merkle-tree.o @@ -568,6 +565,7 @@ REMOTE_CARTESI_MACHINE_OBJS:= \ shadow-pmas-factory.o \ shadow-tlb.o \ shadow-tlb-factory.o \ + keccak-256-hasher.o \ machine-merkle-tree.o \ pristine-merkle-tree.o \ pma.o \ @@ -600,6 +598,7 @@ JSONRPC_REMOTE_CARTESI_MACHINE_OBJS:= \ shadow-pmas-factory.o \ shadow-tlb.o \ shadow-tlb-factory.o \ + keccak-256-hasher.o \ machine-merkle-tree.o \ pristine-merkle-tree.o \ pma.o \ diff --git a/src/complete-merkle-tree.cpp b/src/complete-merkle-tree.cpp index 592f9aee7..100cd9739 100644 --- a/src/complete-merkle-tree.cpp +++ b/src/complete-merkle-tree.cpp @@ -15,6 +15,8 @@ // #include "complete-merkle-tree.h" +#include +#include /// \file /// \brief Complete Merkle tree implementation. diff --git a/src/cryptopp-keccak-256-hasher.h b/src/cryptopp-keccak-256-hasher.h deleted file mode 100644 index ec9e81b8e..000000000 --- a/src/cryptopp-keccak-256-hasher.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright Cartesi and individual authors (see AUTHORS) -// SPDX-License-Identifier: LGPL-3.0-or-later -// -// This program is free software: you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License as published by the Free -// Software Foundation, either version 3 of the License, or (at your option) any -// later version. -// -// This program 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 Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License along -// with this program (see COPYING). If not, see . -// - -#ifndef CRYPTOPP_KECCAK_256_HASHER_H -#define CRYPTOPP_KECCAK_256_HASHER_H - -#include "i-hasher.h" -#include -#include - -namespace cartesi { - -class cryptopp_keccak_256_hasher final : - public i_hasher> { - - CryptoPP::Keccak_256 kc{}; - - friend i_hasher>; - - void do_begin(void) { - return kc.Restart(); - } - - void do_add_data(const unsigned char *data, size_t length) { - return kc.Update(data, length); - } - - void do_end(hash_type &hash) { - return kc.Final(hash.data()); - } - -public: - /// \brief Default constructor - cryptopp_keccak_256_hasher(void) = default; - - /// \brief Default destructor - ~cryptopp_keccak_256_hasher(void) = default; - - /// \brief No copy constructor - cryptopp_keccak_256_hasher(const cryptopp_keccak_256_hasher &) = delete; - /// \brief No move constructor - cryptopp_keccak_256_hasher(cryptopp_keccak_256_hasher &&) = delete; - /// \brief No copy assignment - cryptopp_keccak_256_hasher &operator=(const cryptopp_keccak_256_hasher &) = delete; - /// \brief No move assignment - cryptopp_keccak_256_hasher &operator=(cryptopp_keccak_256_hasher &&) = delete; -}; - -} // namespace cartesi - -#endif diff --git a/src/xkcp-keccak-256-hasher.cpp b/src/keccak-256-hasher.cpp similarity index 65% rename from src/xkcp-keccak-256-hasher.cpp rename to src/keccak-256-hasher.cpp index 8146c0d6c..2f5197950 100644 --- a/src/xkcp-keccak-256-hasher.cpp +++ b/src/keccak-256-hasher.cpp @@ -14,4 +14,22 @@ // with this program (see COPYING). If not, see . // -#include "xkcp-keccak-256-hasher.h" +#include "keccak-256-hasher.h" + +#include // NOLINT(bugprone-suspicious-include) + +namespace cartesi { + +void keccak_256_hasher::do_begin(void) { + sha3_init(&m_ctx, 32, 0x01); +} + +void keccak_256_hasher::do_add_data(const unsigned char *data, size_t length) { + sha3_update(&m_ctx, data, length); +} + +void keccak_256_hasher::do_end(hash_type &hash) { + sha3_final(hash.data(), &m_ctx); +} + +} // namespace cartesi diff --git a/src/keccak-256-hasher.h b/src/keccak-256-hasher.h index b1dac7e87..739a8a0e2 100644 --- a/src/keccak-256-hasher.h +++ b/src/keccak-256-hasher.h @@ -17,12 +17,48 @@ #ifndef KECCAK_256_HASHER_H #define KECCAK_256_HASHER_H -#include "cryptopp-keccak-256-hasher.h" +#include + +#include "i-hasher.h" +#include "sha3.h" namespace cartesi { -/// \brief Class used to compute Keccak 256 hashes -using keccak_256_hasher = cryptopp_keccak_256_hasher; +struct keccak_instance final { + union { + uint8_t b[200]; + uint64_t q[25]; + } st; + int pt; +}; + +class keccak_256_hasher final : public i_hasher> { + sha3_ctx_t m_ctx{}; + + friend i_hasher>; + + void do_begin(void); + + void do_add_data(const unsigned char *data, size_t length); + + void do_end(hash_type &hash); + +public: + /// \brief Default constructor + keccak_256_hasher(void) = default; + + /// \brief Default destructor + ~keccak_256_hasher(void) = default; + + /// \brief No copy constructor + keccak_256_hasher(const keccak_256_hasher &) = delete; + /// \brief No move constructor + keccak_256_hasher(keccak_256_hasher &&) = delete; + /// \brief No copy assignment + keccak_256_hasher &operator=(const keccak_256_hasher &) = delete; + /// \brief No move assignment + keccak_256_hasher &operator=(keccak_256_hasher &&) = delete; +}; } // namespace cartesi diff --git a/src/merkle-tree-hash.cpp b/src/merkle-tree-hash.cpp index da9efd2a5..4905011f4 100644 --- a/src/merkle-tree-hash.cpp +++ b/src/merkle-tree-hash.cpp @@ -26,11 +26,11 @@ #include #include "back-merkle-tree.h" -#include "cryptopp-keccak-256-hasher.h" +#include "keccak-256-hasher.h" #include "unique-c-ptr.h" using namespace cartesi; -using hasher_type = cryptopp_keccak_256_hasher; +using hasher_type = keccak_256_hasher; using hash_type = hasher_type::hash_type; /// \brief Checks if string matches prefix and captures remaninder diff --git a/src/test-merkle-tree-hash.cpp b/src/test-merkle-tree-hash.cpp index cdfcfc5a0..9a90e78e1 100644 --- a/src/test-merkle-tree-hash.cpp +++ b/src/test-merkle-tree-hash.cpp @@ -26,14 +26,14 @@ #include "back-merkle-tree.h" #include "complete-merkle-tree.h" -#include "cryptopp-keccak-256-hasher.h" #include "full-merkle-tree.h" +#include "keccak-256-hasher.h" #include "merkle-tree-proof.h" #include "pristine-merkle-tree.h" #include "unique-c-ptr.h" using namespace cartesi; -using hasher_type = cryptopp_keccak_256_hasher; +using hasher_type = keccak_256_hasher; using hash_type = hasher_type::hash_type; /// \brief Checks if string matches prefix and captures remaninder diff --git a/src/test-utils.h b/src/test-utils.h index 5c244ec23..ee871ed1c 100644 --- a/src/test-utils.h +++ b/src/test-utils.h @@ -43,6 +43,7 @@ static hash_type merkle_hash(cartesi::keccak_256_hasher &h, const std::string_vi auto right = merkle_hash(h, std::string_view{data.data() + half_size, half_size}, log2_size); get_concat_hash(h, left, right, result); } else { + h.begin(); h.add_data(reinterpret_cast(data.data()), data.size()); h.end(result); } @@ -65,23 +66,6 @@ static hash_type merkle_hash(const std::string_view &data, int log2_size) { return detail::merkle_hash(h, data, log2_size); } -// static std::string load_file(const std::string &path) { -// std::ifstream ifs(path, std::ios::binary); -// return std::string{std::istreambuf_iterator{ifs}, {}}; -//} - -static std::string load_file(const std::string &path) { - std::streampos size; - std::ifstream file(path, std::ios::binary); - file.seekg(0, std::ios::end); - size = file.tellg(); - file.seekg(0, std::ios::beg); - std::string data; - data.resize(size); - file.read(data.data(), data.size()); - return data; -} - static hash_type calculate_proof_root_hash(const cm_merkle_tree_proof *proof) { hash_type hash; memcpy(hash.data(), proof->target_hash, sizeof(cm_hash)); @@ -102,10 +86,6 @@ static hash_type calculate_proof_root_hash(const cm_merkle_tree_proof *proof) { return hash; } -static int ceil_log2(uint64_t x) { - return static_cast(std::ceil(std::log2(static_cast(x)))); -} - static hash_type calculate_emulator_hash(cm_machine *machine) { cartesi::back_merkle_tree tree(64, 12, 3); std::string page; diff --git a/src/uarch-solidity-compat.h b/src/uarch-solidity-compat.h index 1d67e29be..a3404af8e 100644 --- a/src/uarch-solidity-compat.h +++ b/src/uarch-solidity-compat.h @@ -165,6 +165,8 @@ static inline uint64 int8ToUint64(int8 v) { template void require(T1 condition, T2 message) { + (void) condition; + (void) message; assert((condition) && (message)); } diff --git a/src/xkcp-keccak-256-hasher.h b/src/xkcp-keccak-256-hasher.h deleted file mode 100644 index 5c1c644ef..000000000 --- a/src/xkcp-keccak-256-hasher.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright Cartesi and individual authors (see AUTHORS) -// SPDX-License-Identifier: LGPL-3.0-or-later -// -// This program is free software: you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License as published by the Free -// Software Foundation, either version 3 of the License, or (at your option) any -// later version. -// -// This program 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 Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License along -// with this program (see COPYING). If not, see . -// - -#ifndef XKCP_KECCAK_256_HASHER_H -#define XKCP_KECCAK_256_HASHER_H - -#include - -extern "C" { -#include -} - -#include "i-hasher.h" - -namespace cartesi { - -class xkcp_keccak_256_hasher final : public i_hasher> { - - KeccakWidth1600_SpongeInstance m_state; - - /// \brief No copy constructor - xkcp_keccak_256_hasher(const xkcp_keccak_256_hasher &) = delete; - /// \brief No move constructor - xkcp_keccak_256_hasher(xkcp_keccak_256_hasher &&) = delete; - /// \brief No copy assignment - xkcp_keccak_256_hasher &operator=(const xkcp_keccak_256_hasher &) = delete; - /// \brief No move assignment - xkcp_keccak_256_hasher &operator=(xkcp_keccak_256_hasher &&) = delete; - - friend i_hasher>; - - void do_begin(void) { - KeccakWidth1600_SpongeInitialize(&m_state, 1088, 512); - } - - void do_add_data(const unsigned char *data, size_t length) { - KeccakWidth1600_SpongeAbsorb(&m_state, data, length); - } - - void do_end(hash_type &hash) { - KeccakWidth1600_SpongeAbsorbLastFewBits(&m_state, 1); - KeccakWidth1600_SpongeSqueeze(&m_state, hash.data(), hash.size()); - } - -public: - /// \brief Default constructor - xkcp_keccak_256_hasher(void) = default; -}; - -} // namespace cartesi - -#endif diff --git a/third-party/tiny_sha3/sha3.c b/third-party/tiny_sha3/sha3.c index 931ae0208..7277efa14 100644 --- a/third-party/tiny_sha3/sha3.c +++ b/third-party/tiny_sha3/sha3.c @@ -6,6 +6,27 @@ #include "sha3.h" +// Helper macros for stringification +#define TO_STRING_HELPER(X) #X +#define TO_STRING(X) TO_STRING_HELPER(X) + +// Define loop unrolling depending on the compiler +#if defined(__clang__) +#define UNROLL_LOOP(n) _Pragma(TO_STRING(unroll(n))) +#elif defined(__GNUC__) && !defined(__clang__) +#define UNROLL_LOOP(n) _Pragma(TO_STRING(GCC unroll(n))) +#else +#define UNROLL_LOOP(n) +#endif + +#ifndef KECCAKF_ROUNDS +#define KECCAKF_ROUNDS 24 +#endif + +#ifndef ROTL64 +#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) +#endif + // update the state with given number of rounds void sha3_keccakf(uint64_t st[25]) @@ -35,15 +56,9 @@ void sha3_keccakf(uint64_t st[25]) uint64_t t, bc[5]; #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ - uint8_t *v; - // endianess conversion. this is redundant on little-endian targets for (i = 0; i < 25; i++) { - v = (uint8_t *) &st[i]; - st[i] = ((uint64_t) v[0]) | (((uint64_t) v[1]) << 8) | - (((uint64_t) v[2]) << 16) | (((uint64_t) v[3]) << 24) | - (((uint64_t) v[4]) << 32) | (((uint64_t) v[5]) << 40) | - (((uint64_t) v[6]) << 48) | (((uint64_t) v[7]) << 56); + st[i] = __builtin_bswap64(st[i]); } #endif @@ -51,17 +66,21 @@ void sha3_keccakf(uint64_t st[25]) for (r = 0; r < KECCAKF_ROUNDS; r++) { // Theta + UNROLL_LOOP(5) for (i = 0; i < 5; i++) bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; + UNROLL_LOOP(5) for (i = 0; i < 5; i++) { t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); + UNROLL_LOOP(25) for (j = 0; j < 25; j += 5) st[j + i] ^= t; } // Rho Pi t = st[1]; + UNROLL_LOOP(24) for (i = 0; i < 24; i++) { j = keccakf_piln[i]; bc[0] = st[j]; @@ -70,9 +89,12 @@ void sha3_keccakf(uint64_t st[25]) } // Chi + UNROLL_LOOP(25) for (j = 0; j < 25; j += 5) { + UNROLL_LOOP(5) for (i = 0; i < 5; i++) bc[i] = st[j + i]; + UNROLL_LOOP(5) for (i = 0; i < 5; i++) st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; } @@ -84,23 +106,14 @@ void sha3_keccakf(uint64_t st[25]) #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ // endianess conversion. this is redundant on little-endian targets for (i = 0; i < 25; i++) { - v = (uint8_t *) &st[i]; - t = st[i]; - v[0] = t & 0xFF; - v[1] = (t >> 8) & 0xFF; - v[2] = (t >> 16) & 0xFF; - v[3] = (t >> 24) & 0xFF; - v[4] = (t >> 32) & 0xFF; - v[5] = (t >> 40) & 0xFF; - v[6] = (t >> 48) & 0xFF; - v[7] = (t >> 56) & 0xFF; + st[i] = __builtin_bswap64(st[i]); } #endif } // Initialize the context for SHA3 -int sha3_init(sha3_ctx_t *c, int mdlen) +int sha3_init(sha3_ctx_t *c, int mdlen, int dsuffix) { int i; @@ -109,6 +122,7 @@ int sha3_init(sha3_ctx_t *c, int mdlen) c->mdlen = mdlen; c->rsiz = 200 - 2 * mdlen; c->pt = 0; + c->dsuffix = dsuffix; return 1; } @@ -139,7 +153,7 @@ int sha3_final(void *md, sha3_ctx_t *c) { int i; - c->st.b[c->pt] ^= 0x06; + c->st.b[c->pt] ^= c->dsuffix; c->st.b[c->rsiz - 1] ^= 0x80; sha3_keccakf(c->st.q); @@ -156,7 +170,7 @@ void *sha3(const void *in, size_t inlen, void *md, int mdlen) { sha3_ctx_t sha3; - sha3_init(&sha3, mdlen); + sha3_init(&sha3, mdlen, 0x06); sha3_update(&sha3, in, inlen); sha3_final(md, &sha3); diff --git a/third-party/tiny_sha3/sha3.h b/third-party/tiny_sha3/sha3.h index ba24f4347..d130afdf0 100644 --- a/third-party/tiny_sha3/sha3.h +++ b/third-party/tiny_sha3/sha3.h @@ -7,28 +7,20 @@ #include #include -#ifndef KECCAKF_ROUNDS -#define KECCAKF_ROUNDS 24 -#endif - -#ifndef ROTL64 -#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) -#endif - // state context typedef struct { union { // state: uint8_t b[200]; // 8-bit bytes uint64_t q[25]; // 64-bit words } st; - int pt, rsiz, mdlen; // these don't overflow + int pt, rsiz, mdlen, dsuffix; // these don't overflow } sha3_ctx_t; // Compression function. void sha3_keccakf(uint64_t st[25]); // OpenSSL - like interfece -int sha3_init(sha3_ctx_t *c, int mdlen); // mdlen = hash output in bytes +int sha3_init(sha3_ctx_t *c, int mdlen, int dsuffix); // mdlen = hash output in bytes int sha3_update(sha3_ctx_t *c, const void *data, size_t len); int sha3_final(void *md, sha3_ctx_t *c); // digest goes to md @@ -36,8 +28,8 @@ int sha3_final(void *md, sha3_ctx_t *c); // digest goes to md void *sha3(const void *in, size_t inlen, void *md, int mdlen); // SHAKE128 and SHAKE256 extensible-output functions -#define shake128_init(c) sha3_init(c, 16) -#define shake256_init(c) sha3_init(c, 32) +#define shake128_init(c) sha3_init(c, 16, 0x06) +#define shake256_init(c) sha3_init(c, 32, 0x06) #define shake_update sha3_update void shake_xof(sha3_ctx_t *c); diff --git a/tools/template/control.template b/tools/template/control.template index 2d257462e..90d061d88 100644 --- a/tools/template/control.template +++ b/tools/template/control.template @@ -5,7 +5,7 @@ Homepage: https://docs.cartesi.io/machine/host/cmdline/ Architecture: ARG_ARCH Maintainer: Machine Reference Unit Provides: machine-emulator -Depends: lua5.4, libcrypto++8, libprotobuf32, libgrpc++1.51 +Depends: lua5.4, libprotobuf32, libgrpc++1.51 Section: devel Priority: optional Multi-Arch: foreign