Skip to content

Commit

Permalink
add poseidon merkle tree test #584
Browse files Browse the repository at this point in the history
  • Loading branch information
CblPOK-git committed Mar 26, 2024
1 parent 7679c02 commit f382f35
Show file tree
Hide file tree
Showing 3 changed files with 2,188 additions and 1 deletion.
3 changes: 2 additions & 1 deletion tests/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ add_zkllvm_unit_test("algebra/fields/pallas_arithmetics/loop")
add_zkllvm_unit_test("algebra/fields/pallas_arithmetics/mul")
add_zkllvm_unit_test("algebra/fields/pallas_arithmetics/sub")

# add_zkllvm_unit_test("algebra/fields/private_input/private_input_add")
add_zkllvm_unit_test("algebra/fields/private_input/private_input_add")
add_zkllvm_unit_test("algebra/fields/conversion/itogf_pallas")

# int tests
Expand Down Expand Up @@ -252,6 +252,7 @@ add_zkllvm_unit_test("libc/memset/memset")
# hashes
add_zkllvm_unit_test("hashes/sha256/sha2_256")
add_zkllvm_unit_test("hashes/poseidon/poseidon")
add_zkllvm_unit_test("hashes/merkle_tree/poseidon/0x800_inputs/test")

# recursive prover tests
add_zkllvm_unit_test("algebra/recursive_prover/fri_lin_inter/fri_lin_inter")
Expand Down
136 changes: 136 additions & 0 deletions tests/cpp/hashes/merkle_tree/poseidon/0x800_inputs/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#ifndef __ZKLLVM__
#include "../../../../read_boost_json.hpp"
#include <cstdint>
#include <fstream>
#endif

#include <nil/crypto3/hash/algorithm/hash.hpp>
#include <nil/crypto3/hash/poseidon.hpp>

using namespace nil::crypto3;
using namespace nil::crypto3::algebra::curves;

typename pallas::base_field_type::value_type calculate_hash(
typename pallas::base_field_type::value_type a,
typename pallas::base_field_type::value_type b
) {
#ifdef __ZKLLVM__
return hash<hashes::poseidon> (a, b);
#else
using poseidon_policy = nil::crypto3::hashes::detail::mina_poseidon_policy<typename pallas::base_field_type>;
using permutation_type = nil::crypto3::hashes::detail::poseidon_permutation<poseidon_policy>;
using state_type = typename permutation_type::state_type;

state_type state;
state[0] = 0;
state[1] = a;
state[2] = b;
permutation_type::permute(state);
return state[2];
#endif
}


[[circuit]] typename pallas::base_field_type::value_type merkle_tree_poseidon (
std::array<typename pallas::base_field_type::value_type, 0x800> input) {

std::array<typename pallas::base_field_type::value_type, 0x400> layer_400_leaves;
std::size_t layer_400_size = 0x400;
std::array<typename pallas::base_field_type::value_type, 0x200> layer_200_leaves;
std::size_t layer_200_size = 0x200;
std::array<typename pallas::base_field_type::value_type, 0x100> layer_100_leaves;
std::size_t layer_100_size = 0x100;
std::array<typename pallas::base_field_type::value_type, 0x080> layer_080_leaves;
std::size_t layer_080_size = 0x080;
std::array<typename pallas::base_field_type::value_type, 0x040> layer_040_leaves;
std::size_t layer_040_size = 0x040;
std::array<typename pallas::base_field_type::value_type, 0x020> layer_020_leaves;
std::size_t layer_020_size = 0x020;
std::array<typename pallas::base_field_type::value_type, 0x010> layer_010_leaves;
std::size_t layer_010_size = 0x010;
std::array<typename pallas::base_field_type::value_type, 0x008> layer_008_leaves;
std::size_t layer_008_size = 0x008;
std::array<typename pallas::base_field_type::value_type, 0x004> layer_004_leaves;
std::size_t layer_004_size = 0x004;
std::array<typename pallas::base_field_type::value_type, 0x002> layer_002_leaves;
std::size_t layer_002_size = 0x002;
typename pallas::base_field_type::value_type root;


for (std::size_t leaf_index = 0; leaf_index < layer_400_size; leaf_index++) {
layer_400_leaves[leaf_index] =
calculate_hash(input[2 * leaf_index], input[2 * leaf_index + 1]);
}

for (std::size_t leaf_index = 0; leaf_index < layer_200_size; leaf_index++) {
layer_200_leaves[leaf_index] =
calculate_hash(layer_400_leaves[2 * leaf_index], layer_400_leaves[2 * leaf_index + 1]);
}

for (std::size_t leaf_index = 0; leaf_index < layer_100_size; leaf_index++) {
layer_100_leaves[leaf_index] =
calculate_hash(layer_200_leaves[2 * leaf_index], layer_200_leaves[2 * leaf_index + 1]);
}

for (std::size_t leaf_index = 0; leaf_index < layer_080_size; leaf_index++) {
layer_080_leaves[leaf_index] =
calculate_hash(layer_100_leaves[2 * leaf_index], layer_100_leaves[2 * leaf_index + 1]);
}

for (std::size_t leaf_index = 0; leaf_index < layer_040_size; leaf_index++) {
layer_040_leaves[leaf_index] =
calculate_hash(layer_080_leaves[2 * leaf_index], layer_080_leaves[2 * leaf_index + 1]);
}

for (std::size_t leaf_index = 0; leaf_index < layer_020_size; leaf_index++) {
layer_020_leaves[leaf_index] =
calculate_hash(layer_040_leaves[2 * leaf_index], layer_040_leaves[2 * leaf_index + 1]);
}

for (std::size_t leaf_index = 0; leaf_index < layer_010_size; leaf_index++) {
layer_010_leaves[leaf_index] =
calculate_hash(layer_020_leaves[2 * leaf_index], layer_020_leaves[2 * leaf_index + 1]);
}

for (std::size_t leaf_index = 0; leaf_index < layer_008_size; leaf_index++) {
layer_008_leaves[leaf_index] =
calculate_hash(layer_010_leaves[2 * leaf_index], layer_010_leaves[2 * leaf_index + 1]);
}

for (std::size_t leaf_index = 0; leaf_index < layer_004_size; leaf_index++) {
layer_004_leaves[leaf_index] =
calculate_hash(layer_008_leaves[2 * leaf_index], layer_008_leaves[2 * leaf_index + 1]);
}

for (std::size_t leaf_index = 0; leaf_index < layer_002_size; leaf_index++) {
layer_002_leaves[leaf_index] =
calculate_hash(layer_004_leaves[2 * leaf_index], layer_004_leaves[2 * leaf_index + 1]);
}

typename pallas::base_field_type::value_type real_root = calculate_hash(layer_002_leaves[0], layer_002_leaves[1]);
#ifndef __ZKLLVM__
std::cout << real_root.data << std::endl;
#endif
return real_root;
}


#ifndef __ZKLLVM__

int main (int argc, char *argv[]){
if (argc != 2) {
std::cerr << "one command line argument must be provided\n";
std::abort();
}

boost::json::value input_json = read_boost_json(std::string(argv[1]));

using BlueprintFieldType = typename pallas::base_field_type;

std::array<typename BlueprintFieldType::value_type, 0x800> inp = read_array_field <BlueprintFieldType, 0x800>(input_json, 0);

merkle_tree_poseidon(inp);

return 0;
}
#endif
Loading

0 comments on commit f382f35

Please sign in to comment.