Skip to content

Commit

Permalink
feat!: replace keccak with sha256
Browse files Browse the repository at this point in the history
  • Loading branch information
mpernambuco committed Jan 9, 2025
1 parent 0b141d8 commit feca811
Show file tree
Hide file tree
Showing 21 changed files with 597 additions and 47 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added a "--jobs" option to "uarch-riscv-tests.lua" test
- add-created-files.diff should now be applied with `-p1`
- Improved send_cmio_response bounds checking
- keccak hash algorithm replaced by sha-256

### Fixed
- Fixed --skip-root-hash-store not skipping root hash computation when using the cli
Expand Down
14 changes: 12 additions & 2 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ WARNS=-Wall -Wextra -Wpedantic
INCS+= \
-I../third-party/llvm-flang-uint128 \
-I../third-party/tiny_sha3 \
-I../third-party/SHA256 \
-I../third-party/nlohmann-json \
-I../third-party/downloads \
$(BOOST_INC)
Expand Down Expand Up @@ -212,6 +213,9 @@ endif
# The SHA3 is third party library we always want to compile with O3
SHA3_CFLAGS=-O3

# The SHA256 is third party library we always want to compile with O3
SHA256_CFLAGS=-O3

# Optimization flags for the interpreter
ifneq (,$(filter yes,$(relwithdebinfo) $(release)))
ifneq (,$(filter gcc,$(CC)))
Expand Down Expand Up @@ -375,7 +379,8 @@ LIBCARTESI_OBJS:= \
uarch-pristine-state-hash.o \
uarch-pristine-hash.o \
send-cmio-response.o \
replay-step-state-access-interop.o
replay-step-state-access-interop.o \
sha256.o

CARTESI_CLUA_OBJS:= \
clua.o \
Expand All @@ -394,7 +399,8 @@ LIBCARTESI_MERKLE_TREE_OBJS:= \
back-merkle-tree.o \
pristine-merkle-tree.o \
complete-merkle-tree.o \
full-merkle-tree.o
full-merkle-tree.o \
sha256.o

MERKLE_TREE_HASH_OBJS:= \
merkle-tree-hash.o
Expand Down Expand Up @@ -554,6 +560,10 @@ jsonrpc-discover.cpp: jsonrpc-discover.json
sha3.o: ../third-party/tiny_sha3/sha3.c
$(CC) $(CFLAGS) $(SHA3_CFLAGS) -c -o $@ $<

sha256.o: ../third-party/SHA256/sha256.c
$(CC) $(CFLAGS) $(SHA256_CFLAGS) -c -o $@ $<


uarch-pristine-ram.o: $(UARCH_PRISTINE_RAM_C)
$(CC) $(CFLAGS) -c -o $@ $<

Expand Down
4 changes: 2 additions & 2 deletions src/back-merkle-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include <cstdint>
#include <vector>

#include "keccak-256-hasher.h"
#include "machine-hasher.h"
#include "merkle-tree-proof.h"
#include "pristine-merkle-tree.h"

Expand All @@ -40,7 +40,7 @@ namespace cartesi {
class back_merkle_tree {
public:
/// \brief Hasher class.
using hasher_type = keccak_256_hasher;
using hasher_type = machine_hasher_type;

/// \brief Storage for a hash.
using hash_type = hasher_type::hash_type;
Expand Down
6 changes: 3 additions & 3 deletions src/cartesi/proof.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function _M.roll_hash_up_tree(proof, target_hash)
else
first, second = hash, proof.sibling_hashes[i]
end
hash = cartesi.keccak(first, second)
hash = cartesi.hash(first, second)
end
return hash
end
Expand All @@ -26,7 +26,7 @@ end
function _M.word_slice_assert(root_hash, proof, word)
assert(proof.log2_target_size == 3, "not a word proof")
assert(root_hash == proof.root_hash, "proof root_hash mismatch")
assert(cartesi.keccak(word) == proof.target_hash, "proof target_hash mismatch")
assert(cartesi.hash(word) == proof.target_hash, "proof target_hash mismatch")
assert(_M.roll_hash_up_tree(proof, proof.target_hash) == root_hash, "node not in tree")
end

Expand All @@ -37,7 +37,7 @@ end

function _M.word_splice_assert(root_hash, proof, old_word, new_word, new_root_hash)
_M.word_slice_assert(root_hash, proof, old_word)
assert(_M.roll_hash_up_tree(proof, cartesi.keccak(new_word)) == new_root_hash, "new root hash mismatch")
assert(_M.roll_hash_up_tree(proof, cartesi.hash(new_word)) == new_root_hash, "new root hash mismatch")
end

return _M
43 changes: 42 additions & 1 deletion src/clua-cartesi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,46 @@ static int cartesi_mod_keccak(lua_State *L) {
return 1;
}

/// \brief This is the cartesi.keccak() function implementation.
/// \param L Lua state.
static int cartesi_mod_sha256(lua_State *L) {
using namespace cartesi;
sha_256_hasher h;
sha_256_hasher::hash_type hash;
if (lua_gettop(L) > 2) {
luaL_argerror(L, 3, "too many arguments");
}
if (lua_gettop(L) < 1) {
luaL_argerror(L, 1, "too few arguments");
}
if (lua_isinteger(L, 1) != 0) {
if (lua_gettop(L) > 1) {
luaL_argerror(L, 2, "too many arguments");
}
uint64_t word = luaL_checkinteger(L, 1);
h.begin();
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
h.add_data(reinterpret_cast<const unsigned char *>(&word), sizeof(word));
h.end(hash);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
lua_pushlstring(L, reinterpret_cast<const char *>(hash.data()), hash.size());
return 1;
}
h.begin();
size_t len1 = 0;
const char *hash1 = luaL_checklstring(L, 1, &len1);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
h.add_data(reinterpret_cast<const unsigned char *>(hash1), len1);
size_t len2 = 0;
const char *hash2 = luaL_optlstring(L, 2, "", &len2);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
h.add_data(reinterpret_cast<const unsigned char *>(hash2), len2);
h.end(hash);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
lua_pushlstring(L, reinterpret_cast<const char *>(hash.data()), hash.size());
return 1;
}

static int cartesi_mod_tobase64(lua_State *L) try {
size_t size = 0;
const char *data = luaL_checklstring(L, 1, &size);
Expand Down Expand Up @@ -147,7 +187,8 @@ static int cartesi_mod_new(lua_State *L) try {

/// \brief Contents of the cartesi module table.
static const auto cartesi_mod = clua_make_luaL_Reg_array({
{"keccak", cartesi_mod_keccak},
{"hash", cartesi_mod_sha256},
{"keccak", cartesi_mod_keccak}, // <--- remove this. Use lua keccak256 for the test-cmio.lua
{"tobase64", cartesi_mod_tobase64},
{"frombase64", cartesi_mod_frombase64},
{"tojson", cartesi_mod_tojson},
Expand Down
4 changes: 2 additions & 2 deletions src/complete-merkle-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <type_traits>
#include <vector>

#include "keccak-256-hasher.h"
#include "machine-hasher.h"
#include "merkle-tree-proof.h"
#include "meta.h"
#include "pristine-merkle-tree.h"
Expand All @@ -39,7 +39,7 @@ namespace cartesi {
class complete_merkle_tree {
public:
/// \brief Hasher class.
using hasher_type = keccak_256_hasher;
using hasher_type = machine_hasher_type;

/// \brief Storage for a hash.
using hash_type = hasher_type::hash_type;
Expand Down
4 changes: 2 additions & 2 deletions src/full-merkle-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include <cstdint>
#include <vector>

#include "keccak-256-hasher.h"
#include "machine-hasher.h"
#include "merkle-tree-proof.h"
#include "pristine-merkle-tree.h"

Expand All @@ -34,7 +34,7 @@ namespace cartesi {
class full_merkle_tree {
public:
/// \brief Hasher class.
using hasher_type = keccak_256_hasher;
using hasher_type = machine_hasher_type;

/// \brief Storage for a hash.
using hash_type = hasher_type::hash_type;
Expand Down
28 changes: 28 additions & 0 deletions src/machine-hasher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// 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 <https://www.gnu.org/licenses/>.
//

#ifndef MACHINE_HASHER_H
#define MACHINE_HASHER_H

#include "sha-256-hasher.h"

namespace cartesi {

using machine_hasher_type = sha_256_hasher;

}

#endif
7 changes: 4 additions & 3 deletions src/machine-merkle-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include <unordered_map>
#include <utility>

#include "keccak-256-hasher.h"
#include "machine-hasher.h"
#include "merkle-tree-proof.h"
#include "pristine-merkle-tree.h"

Expand All @@ -51,7 +51,8 @@ namespace cartesi {
/// original data whenever needed and never stored.
/// Pages are divided into *words* that cover LOG2_WORD_SIZE
/// bits of address space.
/// Tree leaves contain Keccak-256 hashes of individual words.
/// Tree leaves contain hashes of individual words.
// The hashing algorithm is provided hasher_type, defined in machine-hasher.h.
///
/// Tree contents are updated page-by-page using calls to
/// machine_merkle_tree#begin_update, machine_merkle_tree#update_page, ...,
Expand Down Expand Up @@ -112,7 +113,7 @@ class machine_merkle_tree final {
}

/// \brief Hasher class.
using hasher_type = keccak_256_hasher;
using hasher_type = machine_hasher_type;

/// \brief Storage for a hash.
using hash_type = hasher_type::hash_type;
Expand Down
6 changes: 3 additions & 3 deletions src/merkle-tree-hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@

#include "back-merkle-tree.h"
#include "i-hasher.h"
#include "keccak-256-hasher.h"
#include "machine-hasher.h"
#include "unique-c-ptr.h"

using namespace cartesi;
using hasher_type = keccak_256_hasher;
using hasher_type = machine_hasher_type;
using hash_type = hasher_type::hash_type;

/// \brief Checks if string matches prefix and captures remaninder
Expand Down Expand Up @@ -175,7 +175,7 @@ the hash of the data in the range.
The Merkle tree root hash is simply the node hash corresponding to the
entire 2^log2_root_size range.
The hash function used is Keccak-256.
The hash function used is machine_hasher_type, defined in machine-hasher.h.
Options:
Expand Down
4 changes: 2 additions & 2 deletions src/pristine-merkle-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include <cstdint>
#include <vector>

#include "keccak-256-hasher.h"
#include "machine-hasher.h"

/// \file
/// \brief Pristine Merkle tree interface.
Expand All @@ -31,7 +31,7 @@ namespace cartesi {
class pristine_merkle_tree {
public:
/// \brief Hasher class.
using hasher_type = keccak_256_hasher;
using hasher_type = machine_hasher_type;

/// \brief Storage for a hash.
using hash_type = hasher_type::hash_type;
Expand Down
66 changes: 66 additions & 0 deletions src/sha-256-hasher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// 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 <https://www.gnu.org/licenses/>.
//

#ifndef SHA256_HASHER_H
#define SHA256_HASHER_H

#include <type_traits>

#include "i-hasher.h"

extern "C" {
#include "sha256.h"
}

namespace cartesi {

class sha_256_hasher final : public i_hasher<sha_256_hasher, std::integral_constant<int, 32>> {
sha256_context m_ctx{};

friend i_hasher<sha_256_hasher, std::integral_constant<int, 32>>;

void do_begin(void) {
sha256_init(&m_ctx);
}

void do_add_data(const unsigned char *data, size_t length) {
sha256_hash(&m_ctx, data, length);
}

void do_end(hash_type &hash) {
sha256_done(&m_ctx, hash.data());
}

public:
/// \brief Default constructor
sha_256_hasher(void) = default;

/// \brief Default destructor
~sha_256_hasher(void) = default;

/// \brief No copy constructor
sha_256_hasher(const sha_256_hasher &) = delete;
/// \brief No move constructor
sha_256_hasher(sha_256_hasher &&) = delete;
/// \brief No copy assignment
sha_256_hasher &operator=(const sha_256_hasher &) = delete;
/// \brief No move assignment
sha_256_hasher &operator=(sha_256_hasher &&) = delete;
};

} // namespace cartesi

#endif
Loading

0 comments on commit feca811

Please sign in to comment.