Skip to content

Commit

Permalink
merkle_tree component #16
Browse files Browse the repository at this point in the history
  • Loading branch information
Luannet committed Apr 23, 2022
1 parent 0f8eca4 commit 67b93a5
Show file tree
Hide file tree
Showing 4 changed files with 271 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,4 @@ namespace nil {
} // namespace crypto3
} // namespace nil

#endif // CRYPTO3_ZK_BLUEPRINT_PLONK_SHA256_HPP
#endif // CRYPTO3_ZK_BLUEPRINT_PLONK_DECOMPOSITION_HPP
187 changes: 187 additions & 0 deletions include/nil/crypto3/zk/components/merkle_tree/plonk/merkle_tree.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2021 Mikhail Komarov <nemo@nil.foundation>
// Copyright (c) 2021 Nikita Kaskov <nbering@nil.foundation>
// Copyright (c) 2022 Alisa Cherniaeva <a.cherniaeva@nil.foundation>
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//---------------------------------------------------------------------------//
// @file Declaration of interfaces for auxiliary components for the MERKLE_TREE component.
//---------------------------------------------------------------------------//

#ifndef CRYPTO3_ZK_BLUEPRINT_MERKLE_TREE_HPP
#define CRYPTO3_ZK_BLUEPRINT_MERKLE_TREE_HPP

#include <nil/crypto3/zk/blueprint/plonk.hpp>
#include <nil/crypto3/zk/assignment/plonk.hpp>
#include <nil/crypto3/zk/components/hashes/sha256/plonk/sha256.hpp>

namespace nil {
namespace crypto3 {
namespace zk {
namespace components {

template<typename ArithmetizationType,
typename CurveType,
std::size_t... WireIndexes>
class merkle_tree;

template<typename BlueprintFieldType,
typename ArithmetizationParams,
typename CurveType,
std::size_t W0,
std::size_t W1,
std::size_t W2,
std::size_t W3,
std::size_t W4,
std::size_t W5,
std::size_t W6,
std::size_t W7,
std::size_t W8>
class merkle_tree<snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>,
CurveType,
W0,
W1,
W2,
W3,
W4,
W5,
W6,
W7,
W8> {

typedef snark::plonk_constraint_system<BlueprintFieldType,
ArithmetizationParams> ArithmetizationType;

using var = snark::plonk_variable<BlueprintFieldType>;

using sha256_component = sha256<ArithmetizationType, BlueprintFieldType,
W0, W1, W2, W3, W4, W5, W6, W7, W8>;

public:

constexpr static const std::size_t required_rows_amount = 1023 * sha256_component::required_rows_amount;

struct params_type {
std::array<var, 2048> data;
};

struct allocated_data_type {
allocated_data_type() {
previously_allocated = false;
}

// TODO access modifiers
bool previously_allocated;
std::array<std::size_t, 1> selectors;
};

struct result_type {
std::array<var, 2> output = {var(0, 0, false), var(0, 0, false)};

result_type(const std::size_t &component_start_row) {
std::array<var, 2> output = {var(W0, component_start_row + required_rows_amount - 1, false),
var(W1, component_start_row + required_rows_amount - 1, false)};
}
};

static std::size_t allocate_rows (blueprint<ArithmetizationType> &bp){
return bp.allocate_rows(required_rows_amount);
}

static result_type generate_circuit(
blueprint<ArithmetizationType> &bp,
blueprint_assignment_table<ArithmetizationType> &assignment,
const params_type &params,
allocated_data_type &allocated_data,
const std::size_t &component_start_row) {

generate_gates(bp, assignment, params, allocated_data, component_start_row);
generate_copy_constraints(bp, assignment, params, component_start_row);
return result_type(component_start_row);
}

static result_type generate_assignments(
blueprint_assignment_table<ArithmetizationType>
&assignment,
const params_type &params,
const std::size_t &component_start_row) {
std::size_t row = component_start_row;
std::array<var, 2048> data;
for (std::size_t i = 0; i < 2048; i++) {
data[i] = params.data[i];
}
int k;
for(std::size_t i = 11; i > -1; i-=2) {
k = 0;
for (std::size_t j = 0; j < (1 << i); j +=4) {
std::array<var, 4> sha_blocks = {data[j], data[j + 1], data[j + 2], data[j + 3]};
typename sha256_component::params_type sha_params = {sha_blocks};
auto sha_output = sha256_component::generate_assignments(assignment,
sha_params, row);
data[k] = sha_output.output[0];
data[k + 1] = sha_output.output[0];
}
k +=2;
}
return result_type(component_start_row);
}

private:

static void generate_gates(
blueprint<ArithmetizationType> &bp,
blueprint_assignment_table<ArithmetizationType> &assignment,
const params_type &params,
allocated_data_type &allocated_data,
const std::size_t &component_start_row) {
std::size_t row = component_start_row;
for(std::size_t i = 11; i > -1; i-=2) {
for (std::size_t j = 0; j < (1 << i); j +=4) {
sha256_component::generate_gates(bp, assignment,
allocated_data, row);
}
}

}

static void generate_copy_constraints(
blueprint<ArithmetizationType> &bp,
blueprint_assignment_table<ArithmetizationType> &assignment,
const params_type &params,
const std::size_t &component_start_row) {
std::size_t row = component_start_row;
for(std::size_t i = 11; i > -1; i-=2) {
for (std::size_t j = 0; j < (1 << i); j +=4) {
sha256_component::generate_copy_constraints(bp, assignment,
allocated_data, row);
}
}
}


};

} // namespace components
} // namespace zk
} // namespace crypto3
} // namespace nil

#endif // CRYPTO3_ZK_BLUEPRINT_PLONK_MERKLE_TREE_HPP
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ set(PLONK_TESTS_FILES
"algebra/curves/plonk/endo_scalar"
"hashes/plonk/poseidon"
"hashes/plonk/sha256"
"merkle_tree/plonk/merkle_tree"
"verifiers/kimchi/base_field"
"verifiers/kimchi/scalar_field"
"verifiers/kimchi/basic_verifier"
Expand Down
82 changes: 82 additions & 0 deletions test/merkle_tree/plonk/merkle_tree.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2021-2022 Mikhail Komarov <nemo@nil.foundation>
// Copyright (c) 2021-2022 Nikita Kaskov <nbering@nil.foundation>
// Copyright (c) 2022 Alisa Cherniaeva <a.cherniaeva@nil.foundation>
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//---------------------------------------------------------------------------//

#define BOOST_TEST_MODULE plonk_sha256_test

#include <boost/test/unit_test.hpp>

#include <nil/crypto3/algebra/curves/pallas.hpp>
#include <nil/crypto3/algebra/fields/arithmetic_params/pallas.hpp>
#include <nil/crypto3/algebra/random_element.hpp>

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

#include <nil/crypto3/zk/snark/arithmetization/plonk/params.hpp>

#include <nil/crypto3/zk/blueprint/plonk.hpp>
#include <nil/crypto3/zk/assignment/plonk.hpp>
#include <nil/crypto3/zk/components/merkle_tree/plonk/merkle_tree.hpp>

#include "../../test_plonk_component.hpp"

using namespace nil::crypto3;

BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite)

BOOST_AUTO_TEST_CASE(blueprint_plonk_merkle_tree) {

using curve_type = algebra::curves::pallas;
using BlueprintFieldType = typename curve_type::base_field_type;
constexpr std::size_t WitnessColumns = 9;
constexpr std::size_t PublicInputColumns = 3;
constexpr std::size_t ConstantColumns = 2;
constexpr std::size_t SelectorColumns = 73;
using hash_type = nil::crypto3::hashes::keccak_1600<256>;
constexpr std::size_t Lambda = 1;

using ArithmetizationParams = zk::snark::plonk_arithmetization_params<WitnessColumns,
PublicInputColumns, ConstantColumns, SelectorColumns>;
using ArithmetizationType = zk::snark::plonk_constraint_system<BlueprintFieldType,
ArithmetizationParams>;
using var = zk::snark::plonk_variable<BlueprintFieldType>;

using component_type = zk::components::merkle_tree<ArithmetizationType, curve_type,
0, 1, 2, 3, 4, 5, 6, 7, 8>;

std::array<typename ArithmetizationType::field_type::value_type, 2048> hash_input;
std::array<var, 2048> input_state_var;
for (std::size_t i = 0; i < 2048; i++) {
hash_input[i] = 0;
input_state_var[i] = var(2, i, false, var::column_type::public_input);
}

typename component_type::params_type params = {input_state_var};
test_component<component_type, BlueprintFieldType, ArithmetizationParams, hash_type, Lambda> (params, hash_input);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 67b93a5

Please sign in to comment.