Skip to content

Commit

Permalink
Resolved review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
HristoStaykov committed Mar 6, 2024
1 parent 6b78c43 commit 375a9cf
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ std::ostream& operator<<(std::ostream& dest, __uint128_t value) {
std::ostream::sentry s(dest);
if (s) {
char buffer[128];
char* d = std::end(buffer);
char* start = std::end(buffer);
do {
--d;
*d = "0123456789"[value % 10];
value /= 10;
--start;
*start = value % 10 + '0'; // store the rightmost digit
value /= 10; // pop the rightmost digit
} while (value != 0);
int len = std::end(buffer) - d;
if (dest.rdbuf()->sputn(d, len) != len) {
int len = std::end(buffer) - start;
if (dest.rdbuf()->sputn(start, len) != len) {
dest.setstate(std::ios_base::badbit);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
#include "../../circuits_impl/verify_attestation_data_imp.h"

template<>
nlohmann::json serialize<CheckpointVariable>(const CheckpointVariable& checkpoint) {
nlohmann::json serialize(const CheckpointVariable& checkpoint) {
nlohmann::json result;
result["struct"].push_back(pack_int_json(checkpoint.epoch));
result["struct"].push_back(bytes32_to_hash_type(checkpoint.root));
return result;
}

template<>
nlohmann::json serialize<AttestationData>(const AttestationData& attestationData) {
nlohmann::json serialize(const AttestationData& attestationData) {
nlohmann::json result;
result["struct"].push_back(pack_int_json(attestationData.slot));
result["struct"].push_back(pack_int_json(attestationData.index));
Expand All @@ -26,15 +26,8 @@ nlohmann::json serialize<AttestationData>(const AttestationData& attestationData
return result;
}

AttestationData deserializeAttestationData(const nlohmann::json& j) {
AttestationData ad;
// ad.slot = bytes_to_int<decltype(ad.slot)>(bytes);
// ad.index = bytes_to_int<decltype(ad.index)>(bytes);
return ad;
}

template<>
nlohmann::json serialize<Validator>(const Validator& validator) {
nlohmann::json serialize(const Validator& validator) {
nlohmann::json result;
result["struct"].push_back(pack_int_json((int)validator.trusted));
result["struct"].push_back(pack_int_json(validator.validator_index));
Expand All @@ -51,7 +44,7 @@ nlohmann::json serialize<Validator>(const Validator& validator) {
}

template<>
nlohmann::json serialize<Fork>(const Fork& fork) {
nlohmann::json serialize(const Fork& fork) {
nlohmann::json result;
result["struct"].push_back(byte_array_to_json(fork.previous_version));
result["struct"].push_back(byte_array_to_json(fork.current_version));
Expand All @@ -60,7 +53,7 @@ nlohmann::json serialize<Fork>(const Fork& fork) {
}

template<>
nlohmann::json serialize<Attestation>(const Attestation& attestation) {
nlohmann::json serialize(const Attestation& attestation) {
nlohmann::json result;
result["struct"].push_back(serialize(attestation.data));
result["struct"].push_back(byte_array_to_json(attestation.signature));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ int main(int argc, char* argv[]) {
std::cerr << "Needed argument for JSON output.\n";
return -1;
}
std::cout << "processing /finalizer-data/merged_234400.json\n";
std::cout << "processing /finalizer-data/merged_234400.json" << std::endl;
path my_path("/finalizer-data/merged_234400.json");
std::ifstream f(my_path);
auto data = json::parse(f);
Expand All @@ -50,7 +50,6 @@ int main(int argc, char* argv[]) {
<< ", "
<< "{\"field\": 105}"
<< "]";
fout.flush();

std::cout << "DONE\n";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ struct JustificationBitsVariable {

static_vector<bool, 4, true> bits;

constexpr JustificationBitsVariable(std::initializer_list<bool> init) {
constexpr JustificationBitsVariable(const std::initializer_list<bool> init) {
assert_true(init.size() == bits.capacity());
size_t i = 0;
for (const auto &v : init) {
assert_true(i < bits.size());
bits[i++] = v;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,13 @@ namespace circuit_byte_utils {
return ret;
}

template<typename T, size_t SIZE = sizeof(T), bool LittleEndian = true>
enum class Endian { Little, Big };

template<typename T, size_t SIZE = sizeof(T), Endian E = circuit_byte_utils::Endian::Little>
static_vector<Byte, SIZE> int_to_bytes(const T& paramInt) {
static_assert(std::is_integral_v<typename std::remove_reference_t<T>>, "T must be integral");
static_vector<Byte, SIZE> bytes;
if constexpr (LittleEndian) {
if constexpr (E == circuit_byte_utils::Endian::Little) {
for (int i = 0; i < sizeof(T); ++i) {
bytes[i] = (paramInt >> (i * 8));
}
Expand Down Expand Up @@ -218,15 +220,16 @@ namespace circuit_byte_utils {
return hashed;
}

Bytes32 parent_hash(const Bytes32& child1, const Bytes32& child2) {
Bytes32 sha256_pair(const Bytes32& child1, const Bytes32& child2) {
return sha256(child1, child2);
}

sha256_t parent_hash(sha256_t child1, sha256_t child2) {
sha256_t sha256_pair(sha256_t child1, sha256_t child2) {
#ifdef __ZKLLVM__
return hash<hashes::sha2<256>>(child1, child2);
#else
assert_true(false && "Using sha256_t in executable. Use Bytes32 instead.");
return {};
#endif
}

Expand Down
46 changes: 16 additions & 30 deletions vendor/zkllvm-metacraft-circuits/src/circuit_utils/ssz_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ using namespace circuit_byte_utils;

namespace ssz_utils {

template<size_t MERKLE_DEPTH, bool F>
template<size_t MERKLE_DEPTH, bool FULL>
HashType ssz_restore_merkle_root(const HashType& leaf,
const static_vector<HashType, MERKLE_DEPTH, F>& branch,
uint64_t gindex,
const uint64_t depth = MERKLE_DEPTH) {
const static_vector<HashType, MERKLE_DEPTH, FULL>& branch,
uint64_t gindex) {
auto hash = leaf;

for (size_t i = 0; i < depth; i++) {
for (size_t i = 0; i < MERKLE_DEPTH; i++) {
HashType left;
HashType right;

Expand All @@ -28,53 +27,40 @@ namespace ssz_utils {

gindex /= 2;

hash = parent_hash(left, right);
hash = sha256_pair(left, right);
}

return hash;
}

template<size_t MERKLE_DEPTH, bool F>
template<size_t MERKLE_DEPTH, bool FULL>
void ssz_verify_proof(const HashType& root,
const HashType& leaf,
const static_vector<HashType, MERKLE_DEPTH, F>& branch,
const uint64_t gindex,
const uint64_t depth = MERKLE_DEPTH) {
auto expected_root = ssz_restore_merkle_root(leaf, branch, gindex, depth);
const static_vector<HashType, MERKLE_DEPTH, FULL>& branch,
const uint64_t gindex) {
auto expected_root = ssz_restore_merkle_root(leaf, branch, gindex);
assert_true(sha256_equals(root, expected_root));
}

HashType hash_tree_root(uint64_t val) {
#ifdef __ZKLLVM__
// TODO: pack bytes into base_field_element here.
HashType empty_hash_ = {0};
return empty_hash_;
#else
auto bytes = int_to_bytes<uint64_t, 32, true>(val);
return bytes;
#endif
auto bytes = int_to_bytes<uint64_t, 32>(val);
return bytes_to_hash_type(bytes);
}

HashType hash_tree_root(const CheckpointVariable& checkpoint) {
auto epoch_leaf = hash_tree_root(checkpoint.epoch);
return parent_hash(epoch_leaf, checkpoint.root);
return sha256_pair(epoch_leaf, checkpoint.root);
}

HashType hash_tree_root(const JustificationBitsVariable& checkpoint) {
#ifdef __ZKLLVM__
// TODO: pack bytes into base_field_element here.
HashType empty_hash_ = {0};
return empty_hash_;
#else
Bytes32 ret_val {};

Bytes32 bytes {};
for (auto i = 0; i < 4; i++) {
if (checkpoint.bits[i]) {
ret_val[0] = set_nth_bit(ret_val[0], i);
bytes[0] = set_nth_bit(bytes[0], i);
}
}

return ret_val;
#endif
return bytes_to_hash_type(bytes);
}

} // namespace ssz_utils
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "../circuits_impl/verify_attestation_data_imp.h"

[[circuit]] base_field_type
verify_attestation_data(HashType block_root, Attestation attestation, base_field_type sigma) {
[[circuit]] base_field_type verify_attestation_data(HashType block_root, Attestation attestation,
base_field_type sigma) {
auto result = verify_attestation_data_imp(block_root, attestation, sigma);
return result.token;
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static_vector<HashType> compute_zero_hashes(int length = 64) {
#endif

for (int i = 1; i < length; i++) {
xs.push_back(parent_hash(xs[i - 1], xs[i - 1]));
xs.push_back(sha256_pair(xs[i - 1], xs[i - 1]));
}
return xs;
}
Expand All @@ -124,18 +124,18 @@ Proof fill_zero_hashes(const Proof& xs, size_t length = 0) {
#else
auto empty_hash = get_empty_byte_array<32>();
#endif
Proof ws = xs;
Proof witnesses = xs;
int additions_count = length - xs.size();

for (int i = 0; i < ws.size(); i++) {
if (sha256_equals(ws[i], empty_hash)) {
ws[i] = zero_hashes[i];
for (int i = 0; i < witnesses.size(); i++) {
if (sha256_equals(witnesses[i], empty_hash)) {
witnesses[i] = zero_hashes[i];
}
}
for (int i = additions_count; i > 0; i--) {
ws.push_back(zero_hashes[xs.size() + additions_count - i]);
witnesses.push_back(zero_hashes[xs.size() + additions_count - i]);
}
return ws;
return witnesses;
}

HashType hash_validator(Bytes64 pubkey,
Expand All @@ -146,17 +146,16 @@ HashType hash_validator(Bytes64 pubkey,
uint64_t exit_epoch_,
uint64_t withdrawable_epoch_) {
// Convert parameters.
auto effective_balance = bytes_to_hash_type((int_to_bytes<uint64_t, 32, true>(effective_balance_)));
auto slashed = bytes_to_hash_type((int_to_bytes<uint64_t, 32, true>(0)));
auto activation_eligibility_epoch =
bytes_to_hash_type((int_to_bytes<uint64_t, 32, true>(activation_eligibility_epoch_)));
auto activation_epoch = bytes_to_hash_type((int_to_bytes<uint64_t, 32, true>(activation_epoch_)));
auto exit_epoch = bytes_to_hash_type((int_to_bytes<uint64_t, 32, true>(exit_epoch_)));
auto withdrawable_epoch = bytes_to_hash_type((int_to_bytes<uint64_t, 32, true>(withdrawable_epoch_)));
auto effective_balance = bytes_to_hash_type((int_to_bytes<uint64_t, 32>(effective_balance_)));
auto slashed = bytes_to_hash_type((int_to_bytes<uint64_t, 32>(0)));
auto activation_eligibility_epoch = bytes_to_hash_type((int_to_bytes<uint64_t, 32>(activation_eligibility_epoch_)));
auto activation_epoch = bytes_to_hash_type((int_to_bytes<uint64_t, 32>(activation_epoch_)));
auto exit_epoch = bytes_to_hash_type((int_to_bytes<uint64_t, 32>(exit_epoch_)));
auto withdrawable_epoch = bytes_to_hash_type((int_to_bytes<uint64_t, 32>(withdrawable_epoch_)));
auto withdrawal_credentials = bytes_to_hash_type((withdrawal_credentials_));

#ifdef __ZKLLVM__
auto hash = [](const HashType& lhs, const HashType& rhs) { return parent_hash(lhs, rhs); };
auto hash = [](const HashType& lhs, const HashType& rhs) { return sha256_pair(lhs, rhs); };
auto pubkey_hash = hash(bytes_to_hash_type(take<32>(pubkey)), bytes_to_hash_type(take<32>(pubkey, 32)));
#else
auto hash = [](const HashType& lhs, const HashType& rhs) { return sha256(lhs, rhs); };
Expand All @@ -175,13 +174,12 @@ VoteToken
verify_attestation_data_imp(const HashType& block_root, const Attestation& attestation, base_field_type sigma) {
assert_true(sigma != 0);

ssz_verify_proof(block_root, attestation.state_root, fill_zero_hashes(Proof(attestation.state_root_proof)), 11, 3);
ssz_verify_proof(block_root, attestation.state_root, fill_zero_hashes(Proof(attestation.state_root_proof)), 11);

ssz_verify_proof(attestation.state_root,
attestation.validators_root,
fill_zero_hashes(Proof(attestation.validators_root_proof)),
43,
5);
43);

// We aggregate all validator pubkeys to verify the `signature`
// field at the end.
Expand Down Expand Up @@ -213,8 +211,7 @@ VoteToken
ssz_verify_proof(attestation.validators_root,
leaf,
fill_zero_hashes(Proof(v.validator_list_proof)),
0x020000000000ul + v.validator_index,
41);
0x020000000000ul + v.validator_index);

// TODO: Needed?
// assert spec.is_active_validator(
Expand Down Expand Up @@ -261,9 +258,9 @@ uint64_t process_votes(const PubKey* trustedKeys,
const size_t pubkeysCount,
const int64_t sigma,
base_field_type& reconstructed_token) {
const PubKey* prev = nullptr;
uint64_t votes_count = 0;
for (size_t i = 0; i < pubkeysCount; i++) {
const PubKey* prev = &trustedKeys[0];
uint64_t votes_count = (pubkeysCount != 0) ? 1 : 0;
for (size_t i = 1; i < pubkeysCount; i++) {
const auto& pubkey = trustedKeys[i];
base_field_type element;
memcpy(&element, &pubkey, sizeof(element));
Expand All @@ -287,5 +284,6 @@ void prove_finality(const VoteToken& token,

uint64_t votes_count = process_votes(trustedKeys, pubkeysCount, sigma, reconstructed_token);

assert_true(votes_count * 5 > active_validators_count * 4);
assert_true(reconstructed_token == token.token);
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,7 @@ void basic_tests() {
ssz_verify_proof(byte_utils::hexToBytes<32>("b45a79b3d4ed0bce770893498237fafc26885ca1a23a1e77933de33c02802db5"),
byte_utils::hexToBytes<32>("64df3a60d06291506b1e0de11ce4bac1e1cd0e2e3f639d786128c9b79475a78c"),
fill_zero_hashes(proof),
0x020000000000ul + 818904,
41);
0x020000000000ul + 818904);
std::cout << "Done\n";

std::array<unsigned char, 32> key;
Expand All @@ -149,7 +148,7 @@ void basic_tests() {

using namespace byte_utils;
uint64_t val = 1234512345;
Bytes32 bytesVal = int_to_bytes<uint64_t, 32, true>(val);
Bytes32 bytesVal = int_to_bytes<uint64_t, 32>(val);

assert_true(hexToBytes<32>(bytesToHex(bytesVal)) == bytesVal);
assert_true((bytes_to_int<uint64_t, 32>(bytesVal)) == val);
Expand Down
2 changes: 1 addition & 1 deletion vendor/zkllvm-metacraft-circuits/src/utils/byte_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ namespace byte_utils {
JustificationBitsVariable hexToBitsVariable(std::string hex) {
JustificationBitsVariable retval {};
auto bits = hexToBytes<1>(hex);
for (uint64_t i = 0; i < (uint64_t)retval.bits.size(); ++i) {
for (size_t i = 0; i < retval.bits.size(); ++i) {
retval.bits[i] = (bits[0] % 2);
bits[0] /= 2;
}
Expand Down

0 comments on commit 375a9cf

Please sign in to comment.