Skip to content

Commit

Permalink
Merge pull request #79 from NilFoundation/78-support-marshalling-of-p…
Browse files Browse the repository at this point in the history
…roofs-when-poseidon-hash-function-is-used-in-the-merkle-tree

[SyncWith: crypto3-zk-marshalling#78] Now Merkle Tree with Poseidon can be marshalled.
  • Loading branch information
martun authored Jan 11, 2024
2 parents 4041696 + 742e576 commit c4943b2
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 18 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,4 @@ jobs:
marshalling_r1cs_gg_ppzksnark_primary_input_test
marshalling_r1cs_gg_ppzksnark_proof_test
marshalling_r1cs_gg_ppzksnark_verification_key_test
# Test should be fixed
# marshalling_merkle_proof_test
marshalling_merkle_proof_test
34 changes: 34 additions & 0 deletions include/nil/crypto3/marshalling/containers/types/merkle_proof.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include <type_traits>
#include <iterator>

#include <nil/crypto3/algebra/type_traits.hpp>
#include <nil/crypto3/marshalling/algebra/types/field_element.hpp>
#include <nil/marshalling/types/bundle.hpp>
#include <nil/marshalling/types/array_list.hpp>
#include <nil/marshalling/types/integral.hpp>
Expand Down Expand Up @@ -64,6 +66,15 @@ namespace nil {
nil::marshalling::types::integral<TTypeBase, std::uint64_t>>>;
};

// For Poseidon, Merkle node will contain a Group Element, not a vector of bytes.
template<typename TTypeBase, typename GroupElementType>
struct merkle_node_value<
TTypeBase,
GroupElementType,
typename std::enable_if<nil::crypto3::algebra::is_field_element<GroupElementType>::value>::type> {
using type = field_element<TTypeBase, GroupElementType>;
};

template<typename TTypeBase, typename MerkleProof>
struct merkle_node_value<
TTypeBase,
Expand Down Expand Up @@ -156,6 +167,20 @@ namespace nil {
return filled_node_value;
}

template<
typename GroupElementType,
typename Endianness,
typename std::enable_if<nil::crypto3::algebra::is_field_element<GroupElementType>::value, bool>::type = true>
typename merkle_node_value<nil::marshalling::field_type<Endianness>, GroupElementType>::type
fill_merkle_node_value(const GroupElementType &node_value) {

using TTypeBase = nil::marshalling::field_type<Endianness>;

typename merkle_node_value<nil::marshalling::field_type<Endianness>, GroupElementType>::type filled_node_value =
field_element<TTypeBase, GroupElementType>(node_value);
return filled_node_value;
}

template<typename MerkleProof,
typename Endianness,
typename std::enable_if<
Expand Down Expand Up @@ -186,6 +211,15 @@ namespace nil {
return node_value;
}

template<
typename GroupElementType,
typename Endianness,
typename std::enable_if<nil::crypto3::algebra::is_field_element<GroupElementType>::value, bool>::type = true>
GroupElementType make_merkle_node_value(const typename merkle_node_value<
nil::marshalling::field_type<Endianness>, GroupElementType>::type &filled_node_value) {
return filled_node_value.value();
}

template<typename MerkleProof,
typename Endianness,
typename std::enable_if<
Expand Down
2 changes: 2 additions & 0 deletions include/nil/crypto3/marshalling/zk/types/commitments/lpc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
#include <nil/crypto3/marshalling/containers/types/merkle_proof.hpp>
#include <nil/crypto3/marshalling/zk/types/commitments/fri.hpp>
#include <nil/crypto3/marshalling/zk/types/commitments/eval_storage.hpp>
#include <nil/crypto3/marshalling/containers/types/merkle_proof.hpp>


namespace nil {
namespace crypto3 {
Expand Down
45 changes: 30 additions & 15 deletions test/merkle_proof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

#include <nil/crypto3/hash/sha2.hpp>
#include <nil/crypto3/hash/keccak.hpp>
#include <nil/crypto3/hash/poseidon.hpp>

#include <nil/crypto3/marshalling/containers/types/merkle_proof.hpp>

Expand Down Expand Up @@ -118,7 +119,6 @@ void test_merkle_proof(std::size_t tree_depth) {
auto write_iter = cv.begin();
nil::marshalling::status_type status = filled_merkle_proof.write(write_iter, cv.size());

std::cout << "Proof size: " << cv.size() << std::endl;
print_merkle_proof(cv.cbegin(), cv.cend(), data[proof_idx].cbegin(), data[proof_idx].cend(), true);

merkle_proof_marshalling_type test_val_read;
Expand All @@ -130,27 +130,42 @@ void test_merkle_proof(std::size_t tree_depth) {

BOOST_AUTO_TEST_SUITE(marshalling_merkle_proof_test_suite)

BOOST_AUTO_TEST_CASE(marshalling_merkle_proof_arity_2_test) {
using curve_type = nil::crypto3::algebra::curves::pallas;
using field_type = typename curve_type::base_field_type;

using HashTypes = boost::mpl::list<
nil::crypto3::hashes::sha2<256>,
nil::crypto3::hashes::keccak_1600<512>,
nil::crypto3::hashes::poseidon<nil::crypto3::hashes::detail::mina_poseidon_policy<field_type>>
>;


BOOST_AUTO_TEST_CASE_TEMPLATE(marshalling_merkle_proof_arity_2_test, HashType, HashTypes) {
std::srand(std::time(0));
test_merkle_proof<nil::marshalling::option::big_endian, nil::crypto3::hashes::sha2<256>, 2>(5);
test_merkle_proof<nil::marshalling::option::big_endian, nil::crypto3::hashes::keccak_1600<256>, 2>(10);
test_merkle_proof<nil::marshalling::option::big_endian, nil::crypto3::hashes::keccak_1600<256>, 2, 300>(15);
test_merkle_proof<nil::marshalling::option::big_endian, HashType, 2>(5);
test_merkle_proof<nil::marshalling::option::big_endian, HashType, 2>(10);
test_merkle_proof<nil::marshalling::option::big_endian, HashType, 2, 300>(15);
}

// TODO: fix test case for arity 3
BOOST_AUTO_TEST_CASE(marshalling_merkle_proof_arity_3_test) {
test_merkle_proof<nil::marshalling::option::big_endian, nil::crypto3::hashes::sha2<256>, 3>(5);
test_merkle_proof<nil::marshalling::option::big_endian, nil::crypto3::hashes::keccak_1600<256>, 3>(5);
// Poseidon hash function supports only Arity 2.
using BlockHashTypes = boost::mpl::list<
nil::crypto3::hashes::sha2<256>,
nil::crypto3::hashes::keccak_1600<512>
>;

BOOST_AUTO_TEST_CASE_TEMPLATE(marshalling_merkle_proof_arity_3_test, HashType, BlockHashTypes) {
test_merkle_proof<nil::marshalling::option::big_endian, HashType, 3>(5);
test_merkle_proof<nil::marshalling::option::big_endian, HashType, 3>(10);
}

BOOST_AUTO_TEST_CASE(marshalling_merkle_proof_arity_4_test) {
test_merkle_proof<nil::marshalling::option::big_endian, nil::crypto3::hashes::sha2<256>, 4>(5);
test_merkle_proof<nil::marshalling::option::big_endian, nil::crypto3::hashes::keccak_1600<256>, 4>(5);
BOOST_AUTO_TEST_CASE_TEMPLATE(marshalling_merkle_proof_arity_4_test, HashType, BlockHashTypes) {
test_merkle_proof<nil::marshalling::option::big_endian, HashType, 4>(5);
test_merkle_proof<nil::marshalling::option::big_endian, HashType, 4>(10);
}

BOOST_AUTO_TEST_CASE(marshalling_merkle_proof_arity_5_test) {
test_merkle_proof<nil::marshalling::option::big_endian, nil::crypto3::hashes::sha2<256>, 5>(5);
test_merkle_proof<nil::marshalling::option::big_endian, nil::crypto3::hashes::keccak_1600<256>, 5>(5);
BOOST_AUTO_TEST_CASE_TEMPLATE(marshalling_merkle_proof_arity_5_test, HashType, BlockHashTypes) {
test_merkle_proof<nil::marshalling::option::big_endian, HashType, 5>(5);
test_merkle_proof<nil::marshalling::option::big_endian, HashType, 5>(10);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit c4943b2

Please sign in to comment.