diff --git a/crypto3/libs/blueprint/include/nil/blueprint/blueprint/plonk/assignment.hpp b/crypto3/libs/blueprint/include/nil/blueprint/blueprint/plonk/assignment.hpp index df9e40e295..572cafe8cb 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/blueprint/plonk/assignment.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/blueprint/plonk/assignment.hpp @@ -152,9 +152,9 @@ namespace nil { using ranges = std::vector>; public: - static constexpr const std::size_t private_storage_index = std::numeric_limits::max(); - static constexpr const std::size_t batch_private_storage_index = std::numeric_limits::max() - 1; - static constexpr const std::size_t batch_constant_storage_index = std::numeric_limits::max() - 2; + static constexpr const std::size_t private_storage_index = std::numeric_limits::max()-2; + static constexpr const std::size_t batch_private_storage_index = std::numeric_limits::max() - 3; + static constexpr const std::size_t batch_constant_storage_index = std::numeric_limits::max() - 4; assignment(std::size_t witness_amount, std::size_t public_input_amount, std::size_t constant_amount, std::size_t selector_amount) diff --git a/crypto3/libs/blueprint/test/verifiers/placeholder/verifier.cpp b/crypto3/libs/blueprint/test/verifiers/placeholder/verifier.cpp index 535e95cc23..29eec06638 100644 --- a/crypto3/libs/blueprint/test/verifiers/placeholder/verifier.cpp +++ b/crypto3/libs/blueprint/test/verifiers/placeholder/verifier.cpp @@ -416,6 +416,7 @@ void test_multiple_arithmetizations(std::string folder_name){ BOOST_AUTO_TEST_SUITE(blueprint_pallas_test_suite) BOOST_AUTO_TEST_CASE(basic_test) { +// test_multiple_arithmetizations("../libs/blueprint/test/verifiers/placeholder/data/merkle_tree_poseidon"); test_multiple_arithmetizations("../test/verifiers/placeholder/data/merkle_tree_poseidon"); } diff --git a/crypto3/libs/marshalling/core/include/nil/marshalling/status_type.hpp b/crypto3/libs/marshalling/core/include/nil/marshalling/status_type.hpp index b8158d6458..2229a888fb 100644 --- a/crypto3/libs/marshalling/core/include/nil/marshalling/status_type.hpp +++ b/crypto3/libs/marshalling/core/include/nil/marshalling/status_type.hpp @@ -97,6 +97,7 @@ namespace nil { case status_type::error_status_amount: return "unreachable"; } + return "unreachable"; } }; } // namespace marshalling diff --git a/crypto3/libs/marshalling/zk/test/detail/circuits.hpp b/crypto3/libs/marshalling/zk/test/detail/circuits.hpp index e9d8a76213..9622e53fa1 100644 --- a/crypto3/libs/marshalling/zk/test/detail/circuits.hpp +++ b/crypto3/libs/marshalling/zk/test/detail/circuits.hpp @@ -54,7 +54,7 @@ namespace nil { namespace crypto3 { namespace zk { namespace snark { - template + template class circuit_description { typedef zk::snark::detail::placeholder_policy policy_type; @@ -63,7 +63,7 @@ namespace nil { public: std::size_t table_rows; - std::size_t usable_rows = usable_rows_amount; + std::size_t usable_rows; typename policy_type::variable_assignment_type table; @@ -96,14 +96,12 @@ namespace nil { const std::size_t rows_amount_1 = 13; template - circuit_description, rows_amount_1> circuit_test_1( + circuit_description> circuit_test_1( typename nil::crypto3::random::algebraic_engine alg_rnd = nil::crypto3::random::algebraic_engine(), boost::random::mt11213b rnd = boost::random::mt11213b() ) { using assignment_type = typename FieldType::value_type; - constexpr static const std::size_t usable_rows = rows_amount_1; - constexpr static const std::size_t witness_columns = witness_columns_1; constexpr static const std::size_t public_columns = public_columns_1; constexpr static const std::size_t constant_columns = constant_columns_1; @@ -112,7 +110,8 @@ namespace nil { witness_columns + public_columns + constant_columns; typedef placeholder_circuit_params circuit_params; - circuit_description test_circuit; + circuit_description test_circuit; + test_circuit.usable_rows = rows_amount_1; std::vector> table(table_columns); std::vector q_add(test_circuit.usable_rows); @@ -139,9 +138,9 @@ namespace nil { q_add[i] = one; q_mul[i] = FieldType::value_type::zero(); - plonk_variable x(1u, i, false, + plonk_variable x(1, i, false, plonk_variable::column_type::witness); - plonk_variable y(2, i - 1u, false, + plonk_variable y(2, i - 1, false, plonk_variable::column_type::witness); //test_circuit.copy_constraints.push_back(plonk_copy_constraint(x, y)); } @@ -155,9 +154,9 @@ namespace nil { q_add[i] = FieldType::value_type::zero(); q_mul[i] = one; - plonk_variable x(1u, i, false, + plonk_variable x(1, i, false, plonk_variable::column_type::witness); - plonk_variable y(0u, 0u, false, + plonk_variable y(0, 0, false, plonk_variable::column_type::public_input); test_circuit.copy_constraints.push_back(plonk_copy_constraint(x, y)); } @@ -184,9 +183,9 @@ namespace nil { test_circuit.table_rows = zk_padding>(test_circuit.table, alg_rnd); - plonk_variable w0(0u, 0u, true, plonk_variable::column_type::witness); - plonk_variable w1(1u, 0u, true, plonk_variable::column_type::witness); - plonk_variable w2(2, 0u, true, plonk_variable::column_type::witness); + plonk_variable w0(0, 0, true, plonk_variable::column_type::witness); + plonk_variable w1(1, 0, true, plonk_variable::column_type::witness); + plonk_variable w2(2, 0, true, plonk_variable::column_type::witness); plonk_constraint add_constraint; add_constraint += w0; @@ -194,7 +193,7 @@ namespace nil { add_constraint -= w2; std::vector> add_gate_costraints {add_constraint}; - plonk_gate> add_gate(0u, add_gate_costraints); + plonk_gate> add_gate(0, add_gate_costraints); test_circuit.gates.push_back(add_gate); plonk_constraint mul_constraint; @@ -204,7 +203,7 @@ namespace nil { mul_constraint -= w2; std::vector> mul_gate_costraints {mul_constraint}; - plonk_gate> mul_gate(1u, mul_gate_costraints); + plonk_gate> mul_gate(1, mul_gate_costraints); test_circuit.gates.push_back(mul_gate); return test_circuit; @@ -220,7 +219,7 @@ namespace nil { // k-1 | MUL | x | y | z | 0 | 0 | 1 | // // ADD: x + y = z, copy(prev(z), y) - // MUL: x * y + prev(x) = z, copy(p1u, y) + // MUL: x * y + prev(x) = z, copy(p1, y) //---------------------------------------------------------------------------// constexpr static const std::size_t witness_columns_t = 3; constexpr static const std::size_t public_columns_t = 1; @@ -229,7 +228,7 @@ namespace nil { constexpr static const std::size_t usable_rows_t = 5; template - circuit_description, usable_rows_t> + circuit_description> circuit_test_t( typename FieldType::value_type pi0 = 0u, typename nil::crypto3::random::algebraic_engine alg_rnd = nil::crypto3::random::algebraic_engine(), @@ -237,7 +236,6 @@ namespace nil { ) { using assignment_type = typename FieldType::value_type; - constexpr static const std::size_t usable_rows = usable_rows_t; constexpr static const std::size_t witness_columns = witness_columns_t; constexpr static const std::size_t public_columns = public_columns_t; constexpr static const std::size_t constant_columns = constant_columns_t; @@ -247,8 +245,9 @@ namespace nil { typedef placeholder_circuit_params circuit_params; - circuit_description test_circuit; + circuit_description test_circuit; test_circuit.public_input_sizes = {3}; + test_circuit.usable_rows = usable_rows_t; std::vector> table(table_columns); @@ -276,9 +275,9 @@ namespace nil { q_add[i] = one; q_mul[i] = FieldType::value_type::zero(); - plonk_variable x(1u, i, false, + plonk_variable x(1, i, false, plonk_variable::column_type::witness); - plonk_variable y(2, i - 1u, false, + plonk_variable y(2, i - 1, false, plonk_variable::column_type::witness); test_circuit.copy_constraints.push_back(plonk_copy_constraint(x, y)); } @@ -292,9 +291,9 @@ namespace nil { q_add[i] = FieldType::value_type::zero(); q_mul[i] = one; - plonk_variable x(1u, i, false, + plonk_variable x(1, i, false, plonk_variable::column_type::witness); - plonk_variable y(0u, 0u, false, + plonk_variable y(0, 0, false, plonk_variable::column_type::public_input); test_circuit.copy_constraints.push_back(plonk_copy_constraint(x, y)); } @@ -322,13 +321,13 @@ namespace nil { public_input_assignment, constant_assignment, selectors_assignment)); test_circuit.table_rows = zk_padding>(test_circuit.table, alg_rnd); - plonk_variable w0(0u, 0u, true, + plonk_variable w0(0, 0, true, plonk_variable::column_type::witness); - plonk_variable w1(1u, 0u, true, + plonk_variable w1(1, 0, true, plonk_variable::column_type::witness); - plonk_variable w2(2, 0u, true, + plonk_variable w2(2, 0, true, plonk_variable::column_type::witness); - plonk_variable w0_prev(0u, -1u, true, + plonk_variable w0_prev(0, -1, true, plonk_variable::column_type::witness); plonk_constraint add_constraint; @@ -337,7 +336,7 @@ namespace nil { add_constraint -= w2; std::vector> add_gate_costraints {add_constraint}; - plonk_gate> add_gate(0u, add_gate_costraints); + plonk_gate> add_gate(0, add_gate_costraints); test_circuit.gates.push_back(add_gate); plonk_constraint mul_constraint; @@ -348,7 +347,7 @@ namespace nil { mul_constraint += w0_prev; std::vector> mul_gate_costraints {mul_constraint}; - plonk_gate> mul_gate(1u, mul_gate_costraints); + plonk_gate> mul_gate(1, mul_gate_costraints); //test_circuit.gates.push_back(mul_gate); return test_circuit; @@ -362,7 +361,7 @@ namespace nil { constexpr static const std::size_t usable_rows_3 = 4; template - circuit_description, usable_rows_3> circuit_test_3( + circuit_description> circuit_test_3( typename nil::crypto3::random::algebraic_engine alg_rnd = nil::crypto3::random::algebraic_engine(), boost::random::mt11213b rnd = boost::random::mt11213b() ) { @@ -374,11 +373,11 @@ namespace nil { constexpr static const std::size_t selector_columns = selector_columns_3; constexpr static const std::size_t table_columns = witness_columns + public_columns + constant_columns; - constexpr static const std::size_t usable_rows = usable_rows_3; typedef placeholder_circuit_params circuit_params; - circuit_description test_circuit; + circuit_description test_circuit; + test_circuit.usable_rows = usable_rows_3; std::vector> table(table_columns); for (std::size_t j = 0; j < table_columns; j++) { @@ -390,9 +389,9 @@ namespace nil { table[1] = {0u, 0u, 0u, 0u}; table[2] = {0u, 0u, 0u, 0u}; - table[3] = {0u, 1u, 0u, 1u}; //Lookup values - table[4] = {0u, 0u, 1u, 0u}; //Lookup values - table[5] = {0u, 1u, 0u, 0u}; //Lookup values + table[3] = {0u, 1u, 0u, 1u}; //Lookup values + table[4] = {0u, 0u, 1u, 0u}; //Lookup values + table[5] = {0u, 1u, 0u, 0u}; //Lookup values std::vector> private_assignment(witness_columns); for (std::size_t i = 0; i < witness_columns; i++) { @@ -420,13 +419,13 @@ namespace nil { public_input_assignment, constant_assignment, selectors_assignment)); test_circuit.table_rows = zk_padding(test_circuit.table, alg_rnd); - plonk_variable w0(0u, 0u, true, plonk_variable::column_type::witness); - plonk_variable w1(1u, 0u, true, plonk_variable::column_type::witness); - plonk_variable w2(2, 0u, true, plonk_variable::column_type::witness); + plonk_variable w0(0, 0, true, plonk_variable::column_type::witness); + plonk_variable w1(1, 0, true, plonk_variable::column_type::witness); + plonk_variable w2(2, 0, true, plonk_variable::column_type::witness); - plonk_variable c0(0u, 0u, true, plonk_variable::column_type::constant); - plonk_variable c1(1u, 0u, true, plonk_variable::column_type::constant); - plonk_variable c2(2, 0u, true, plonk_variable::column_type::constant); + plonk_variable c0(0, 0, true, plonk_variable::column_type::constant); + plonk_variable c1(1, 0, true, plonk_variable::column_type::constant); + plonk_variable c2(2, 0, true, plonk_variable::column_type::constant); plonk_lookup_constraint lookup_constraint; @@ -436,7 +435,7 @@ namespace nil { lookup_constraint.table_id = 1; std::vector> lookup_constraints = {lookup_constraint}; - plonk_lookup_gate> lookup_gate(0u, lookup_constraints); + plonk_lookup_gate> lookup_gate(0, lookup_constraints); test_circuit.lookup_gates.push_back(lookup_gate); // Add constructor for lookup table @@ -467,7 +466,7 @@ namespace nil { constexpr static const std::size_t selector_columns_4 = 3; template - circuit_description, 5> circuit_test_4( + circuit_description> circuit_test_4( typename nil::crypto3::random::algebraic_engine alg_rnd = nil::crypto3::random::algebraic_engine(), boost::random::mt11213b rnd = boost::random::mt11213b() ) { @@ -484,8 +483,9 @@ namespace nil { typedef placeholder_circuit_params circuit_params; - circuit_description test_circuit; + circuit_description test_circuit; test_circuit.table_rows = 1 << rows_log; + test_circuit.usable_rows = 5; std::vector> table(table_columns); for (std::size_t j = 0; j < table_columns; j++) { @@ -493,12 +493,9 @@ namespace nil { } // lookup inputs - table[0] = {unsigned(rnd() % 2), unsigned(rnd() % 2), unsigned(rnd() % 2), - unsigned(rnd() % 2), unsigned(rnd() % 2), 0u, 0u, 0u}; - table[1] = {unsigned(rnd() % 2), unsigned(rnd() % 2), unsigned(rnd() % 2), - unsigned(rnd() % 2), unsigned(rnd() % 2), 0u, 0u, 0u};; - table[2] = {table[0][0] * table[1][0], table[0][1] * table[1][1], - table[0][2] * table[1][2], table[0][3] * table[1][3], table[0][4] * table[1][4], 0u, 0u, 0u}; + table[0] = {rnd() % 2, rnd() % 2, rnd(), rnd() % 2, rnd() % 2, 0u, 0u, 0u}; + table[1] = {rnd() % 2, rnd() % 2, rnd(), rnd() % 2, rnd() % 2, 0u, 0u, 0u};; + table[2] = {table[0][0] * table[1][0], table[0][1] * table[1][1], table[0][2] * table[1][2], table[0][3] * table[1][3], table[0][4] * table[1][4], 0u, 0u, 0u}; //lookup values @@ -529,13 +526,13 @@ namespace nil { public_input_assignment, constant_assignment, selectors_assignment)); - plonk_variable w0(0u, 0u, true, plonk_variable::column_type::witness); - plonk_variable w1(1u, 0u, true, plonk_variable::column_type::witness); - plonk_variable w2(2, 0u, true, plonk_variable::column_type::witness); + plonk_variable w0(0, 0, true, plonk_variable::column_type::witness); + plonk_variable w1(1, 0, true, plonk_variable::column_type::witness); + plonk_variable w2(2, 0, true, plonk_variable::column_type::witness); - plonk_variable c0(0u, 0u, true, plonk_variable::column_type::constant); - plonk_variable c1(1u, 0u, true, plonk_variable::column_type::constant); - plonk_variable c2(2, 0u, true, plonk_variable::column_type::constant); + plonk_variable c0(0, 0, true, plonk_variable::column_type::constant); + plonk_variable c1(1, 0, true, plonk_variable::column_type::constant); + plonk_variable c2(2, 0, true, plonk_variable::column_type::constant); plonk_constraint mul_constraint; typename plonk_constraint::term_type w0_term(w0); @@ -544,7 +541,7 @@ namespace nil { mul_constraint -= w2; std::vector> mul_gate_costraints {mul_constraint}; - plonk_gate> mul_gate(1u, mul_gate_costraints); + plonk_gate> mul_gate(1, mul_gate_costraints); test_circuit.gates.push_back(mul_gate); plonk_lookup_constraint lookup_constraint; @@ -582,14 +579,13 @@ namespace nil { constexpr static const std::size_t usable_rows_5 = 30; template - circuit_description, usable_rows_5> + circuit_description> circuit_test_5( typename nil::crypto3::random::algebraic_engine alg_rnd = nil::crypto3::random::algebraic_engine(), boost::random::mt11213b rnd = boost::random::mt11213b() ) { using assignment_type = typename FieldType::value_type; - constexpr static const std::size_t usable_rows = usable_rows_5; constexpr static const std::size_t witness_columns = witness_columns_5; constexpr static const std::size_t public_input_columns = public_columns_5; constexpr static const std::size_t constant_columns = constant_columns_5; @@ -597,8 +593,9 @@ namespace nil { typedef placeholder_circuit_params circuit_params; - circuit_description test_circuit; + circuit_description test_circuit; test_circuit.public_input_sizes = {witness_columns}; + test_circuit.usable_rows = usable_rows_5; std::vector> private_assignment(witness_columns); std::vector> public_input_assignment(public_input_columns); @@ -609,10 +606,13 @@ namespace nil { selectors_assignment[0].resize(test_circuit.usable_rows); for(std::size_t i = 0; i < witness_columns; i++) { private_assignment[i].resize(test_circuit.usable_rows); - private_assignment[i][0] = private_assignment[i][2] = public_input_assignment[0][i] = typename FieldType::value_type(rnd() % witness_columns); + private_assignment[i][0] = private_assignment[i][2] = public_input_assignment[0][i] = + typename FieldType::value_type(rnd() % witness_columns); private_assignment[i][1] = 1u; - plonk_variable pi(0u, i, false, plonk_variable::column_type::public_input); - plonk_variable wi(i, 0u, false, plonk_variable::column_type::witness); + plonk_variable pi( + 0, i, false, plonk_variable::column_type::public_input); + plonk_variable wi( + i, 0, false, plonk_variable::column_type::witness); test_circuit.copy_constraints.push_back(plonk_copy_constraint({pi, wi})); } selectors_assignment[0][1] = 1u; @@ -625,13 +625,13 @@ namespace nil { std::vector> mul_gate_constraints; for( std::size_t i = 0; i < witness_columns; i++){ - plonk_variable w0(i, -1u, true, plonk_variable::column_type::witness); - plonk_variable w1(i, 0u, true, plonk_variable::column_type::witness); - plonk_variable w2(i, 1u, true, plonk_variable::column_type::witness); + plonk_variable w0(i, -1, true, plonk_variable::column_type::witness); + plonk_variable w1(i, 0, true, plonk_variable::column_type::witness); + plonk_variable w2(i, 1, true, plonk_variable::column_type::witness); mul_gate_constraints.push_back(w0 - w1 * w2); } - plonk_gate> mul_gate(0u, mul_gate_constraints); + plonk_gate> mul_gate(0, mul_gate_constraints); test_circuit.gates.push_back(mul_gate); return test_circuit; @@ -655,7 +655,7 @@ namespace nil { constexpr static const std::size_t selector_columns_fib = 1; template - circuit_description, usable_rows> + circuit_description > circuit_test_fib( typename nil::crypto3::random::algebraic_engine alg_rnd = nil::crypto3::random::algebraic_engine() ) { @@ -670,7 +670,8 @@ namespace nil { typedef placeholder_circuit_params circuit_params; - circuit_description test_circuit; + circuit_description test_circuit; + test_circuit.usable_rows = usable_rows; std::vector> table(table_columns); std::vector q_add(test_circuit.usable_rows); @@ -693,14 +694,6 @@ namespace nil { table[2][0] = zero; table[2][1] = one; - plonk_variable x0(0u, 0u, false, plonk_variable::column_type::witness); - plonk_variable x1(0u, 1u, false, plonk_variable::column_type::witness); - plonk_variable p0(1u, 0u, false, plonk_variable::column_type::public_input); - plonk_variable p1(1u, 1u, false, plonk_variable::column_type::public_input); - -// test_circuit.copy_constraints.push_back(plonk_copy_constraint(x0u, p0)); -// test_circuit.copy_constraints.push_back(plonk_copy_constraint(x1u, p1)); - for (std::size_t i = 2; i < test_circuit.usable_rows - 1; i++) { table[0][i] = table[0][i-2] + table[0][i-1]; table[1][i] = zero; @@ -726,9 +719,9 @@ namespace nil { public_input_assignment, constant_assignment, selectors_assignment)); test_circuit.table_rows = zk_padding>(test_circuit.table, alg_rnd); - plonk_variable w0(0u, -1u, true, plonk_variable::column_type::witness); - plonk_variable w1(0u, 0u, true, plonk_variable::column_type::witness); - plonk_variable w2(0u, 1u, true, plonk_variable::column_type::witness); + plonk_variable w0(0, -1, true, plonk_variable::column_type::witness); + plonk_variable w1(0, 0, true, plonk_variable::column_type::witness); + plonk_variable w2(0, 1, true, plonk_variable::column_type::witness); typename plonk_constraint::term_type w0_term(w0); typename plonk_constraint::term_type w1_term(w1); @@ -740,7 +733,7 @@ namespace nil { fib_constraint -= w2_term; std::vector> fib_costraints {fib_constraint}; - plonk_gate> fib_gate(0u, fib_costraints); + plonk_gate> fib_gate(0, fib_costraints); test_circuit.gates.push_back(fib_gate); return test_circuit; @@ -772,7 +765,7 @@ namespace nil { constexpr static const std::size_t usable_rows_6 = 6; template - circuit_description, usable_rows_6> circuit_test_6( + circuit_description> circuit_test_6( typename nil::crypto3::random::algebraic_engine alg_rnd = nil::crypto3::random::algebraic_engine(), boost::random::mt11213b rnd = boost::random::mt11213b() ) { @@ -787,7 +780,8 @@ namespace nil { typedef placeholder_circuit_params circuit_params; - circuit_description test_circuit; + circuit_description test_circuit; + test_circuit.usable_rows = usable_rows_6; std::vector> table(table_columns); for (std::size_t j = 0; j < table_columns; j++) { @@ -795,10 +789,8 @@ namespace nil { } // lookup inputs - table[0] = {unsigned(rnd() % 5 + 2), unsigned(rnd() % 5 + 2), unsigned(rnd() % 5 + 2), - unsigned(rnd() % 5 + 2), unsigned(rnd() % 5 + 2), unsigned(rnd() % 5 + 2)}; - table[1] = {7u, table[0][0] + table[0][1], table[0][1] + table[0][2], table[0][2] + table[0][3], - table[0][3] + table[0][4], table[0][4] + table[0][5]}; + table[0] = {rnd() % 5 + 2, rnd() % 5 + 2, rnd() % 5 + 2, rnd() % 5 + 2, rnd() % 5 + 2, rnd() % 5 + 2}; + table[1] = {7u, table[0][0] + table[0][1], table[0][1] + table[0][2], table[0][2] + table[0][3], table[0][3] + table[0][4], table[0][4] + table[0][5]}; // selectors // Reserved zero row for unselected lookup input rows @@ -833,9 +825,9 @@ namespace nil { public_input_assignment, constant_assignment, selectors_assignment)); test_circuit.table_rows = zk_padding(test_circuit.table, alg_rnd); - plonk_variable w0 (0, 0, true, plonk_variable::column_type::witness); + plonk_variable w0( 0, 0, true, plonk_variable::column_type::witness); plonk_variable w0_1(0,-1, true, plonk_variable::column_type::witness); - plonk_variable w1 (1, 0, true, plonk_variable::column_type::witness); + plonk_variable w1( 1, 0, true, plonk_variable::column_type::witness); plonk_variable c0(0, 0, true, plonk_variable::column_type::constant); plonk_variable c1(1, 0, true, plonk_variable::column_type::constant); @@ -850,7 +842,7 @@ namespace nil { lookup_constraint2.table_id = 2; std::vector> lookup_constraints = {lookup_constraint1, lookup_constraint2}; - plonk_lookup_gate> lookup_gate(1u, lookup_constraints); + plonk_lookup_gate> lookup_gate(1, lookup_constraints); test_circuit.lookup_gates.push_back(lookup_gate); @@ -866,11 +858,11 @@ namespace nil { test_circuit.lookup_gates.push_back(lookup_gate2); // Add constructor for lookup table - plonk_lookup_table table1(1u, 0u); // 2 -- selector_id, 3 -- number of columns; + plonk_lookup_table table1(1, 0); // 2 -- selector_id, 3 -- number of columns; table1.append_option({c0}); test_circuit.lookup_tables.push_back(table1); - plonk_lookup_table table2(1u, 0u); // 2 -- selector_id, 3 -- number of columns; + plonk_lookup_table table2(1, 0); // 2 -- selector_id, 3 -- number of columns; table2.append_option({c0}); table2.append_option({c1}); table2.append_option({c2}); @@ -880,8 +872,8 @@ namespace nil { } // Big columns rotations check: - // Table 1: LT1 options: {L1u, L2, L3, L4, L5, L6, L7} - // Table 2: LT2 options: {L1u, L2} || { L3, L4 } + // Table 1: LT1 options: {L1, L2, L3, L4, L5, L6, L7} + // Table 2: LT2 options: {L1, L2} || { L3, L4 } // Table 3: LT2 options: {L5} || {L6} || {L7} // Lookup gate1: // w1{-3}, w1{-2}, w1{-1}, w1, w1{+1}, w1{+2},w1{+3}, \in Table 1 selector s2 @@ -914,7 +906,7 @@ namespace nil { constexpr static const std::size_t usable_rows_7 = 14; template - circuit_description, usable_rows_7> circuit_test_7( + circuit_description> circuit_test_7( typename nil::crypto3::random::algebraic_engine alg_rnd = nil::crypto3::random::algebraic_engine(), boost::random::mt11213b rnd = boost::random::mt11213b() ) { @@ -929,7 +921,8 @@ namespace nil { typedef placeholder_circuit_params circuit_params; - circuit_description test_circuit; + circuit_description test_circuit; + test_circuit.usable_rows = usable_rows_7; std::vector> table(table_columns); for (std::size_t j = 0; j < table_columns; j++) { @@ -984,17 +977,15 @@ namespace nil { public_input_assignment, constant_assignment, selectors_assignment)); test_circuit.table_rows = zk_padding(test_circuit.table, alg_rnd); - plonk_variable w0(0, 0, true, - plonk_variable::column_type::witness); - plonk_variable w0__7(0, -7, true, - plonk_variable::column_type::witness); + plonk_variable w0( 0, 0, true, plonk_variable::column_type::witness); + plonk_variable w0__7(0,-7, true, plonk_variable::column_type::witness); plonk_constraint add_constraint; add_constraint += w0; add_constraint -= w0__7; std::vector> add_gate_costraints {add_constraint}; - plonk_gate> add_gate(0u, add_gate_costraints); + plonk_gate> add_gate(0, add_gate_costraints); test_circuit.gates.push_back(add_gate); plonk_variable w0__3( 0,-3, true, plonk_variable::column_type::witness); @@ -1018,10 +1009,10 @@ namespace nil { lookup_constraint1.table_id = 1; std::vector> lookup_constraints = {lookup_constraint1}; - plonk_lookup_gate> lookup_gate(1u, lookup_constraints); + plonk_lookup_gate> lookup_gate(1, lookup_constraints); test_circuit.lookup_gates.push_back(lookup_gate); - plonk_variable w1(1, 0, true, plonk_variable::column_type::witness); + plonk_variable w1( 1, 0, true, plonk_variable::column_type::witness); plonk_lookup_constraint lookup_constraint2; lookup_constraint2.lookup_input = {w0, w1}; lookup_constraint2.table_id = 2; @@ -1030,7 +1021,7 @@ namespace nil { plonk_lookup_gate> lookup_gate2(2, lookup_constraints2); test_circuit.lookup_gates.push_back(lookup_gate2); - plonk_variable w1__1( 1u, -1u, true, plonk_variable::column_type::witness); + plonk_variable w1__1( 1, -1, true, plonk_variable::column_type::witness); plonk_lookup_constraint lookup_constraint3; typename plonk_constraint::term_type w1__1_term(w1__1); typename plonk_constraint::term_type w1_term(w1); @@ -1058,6 +1049,127 @@ namespace nil { return test_circuit; } + + // Selector -1 test: + // Table 1: options: {C1, C2} + // Lookup gate1: + // PI + W1, \in Table 1 selector -1 + // Gate1 + // W1 - PI * 2 = 0, selector -1 + // ------------------------- + // | PI | W1 | C1 | C2 | + // ------------------------- + // | a | 2*a | 0 | 42 | + // | a | 2*a | 3 | 45 | + // | a | 2*a | 6 | 48 | + // | a | 2*a | 9 | 51 | + // | a | 2*a | 12 | 54 | + // | a | 2*a | 15 | 57 | + // | a | 2*a | 18 | 60 | + // | a | 2*a | 21 | | + // | a | 2*a | 24 | | + // | a | 2*a | 27 | | + // | a | 2*a | 30 | | + // | a | 2*a | 33 | | + // | a | 2*a | 36 | | + // | a | 2*a | 39 | | + // ------------------------- + constexpr static const std::size_t witness_columns_8= 1; + constexpr static const std::size_t public_columns_8 = 1; + constexpr static const std::size_t constant_columns_8 = 2; + constexpr static const std::size_t selector_columns_8 = 0; + constexpr static const std::size_t usable_rows_8 = 14; + + template + circuit_description> circuit_test_8( + typename nil::crypto3::random::algebraic_engine alg_rnd = nil::crypto3::random::algebraic_engine(), + boost::random::mt11213b rnd = boost::random::mt11213b() + ) { + using assignment_type = typename FieldType::value_type; + using var = nil::crypto3::zk::snark::plonk_variable; + + constexpr static const std::size_t witness_columns = 1; + constexpr static const std::size_t public_columns = 1; + constexpr static const std::size_t constant_columns = 2; + constexpr static const std::size_t selector_columns = 0; + constexpr static const std::size_t table_columns = + witness_columns + public_columns + constant_columns + selector_columns; + constexpr static const std::size_t usable_rows = 14; + constexpr static const std::size_t max_input_value = 2; //(usable_rows - 1) * 2; + + typedef placeholder_circuit_params circuit_params; + + circuit_description test_circuit; + test_circuit.usable_rows = usable_rows; + + std::vector> table(table_columns); + for (std::size_t j = 0; j < table_columns; j++) { + table[j].resize(test_circuit.usable_rows); + } + for (std::size_t j = 0; j < usable_rows; j++) { + table[1][j] = rnd() % max_input_value; // Public input + table[0][j] = table[1][j] * 2; // Witness + table[2][j] = j == 0? 0: 3 * (j - 1); // Static lookup table 1 + table[3][j] = j == 0? 0: 3 * (j - 1 + usable_rows - 1 ); // Static lookup table 2 + } + + std::vector> private_assignment(witness_columns); + for (std::size_t i = 0; i < witness_columns; i++) { + private_assignment[i] = table[i]; + } + + std::vector> public_input_assignment(public_columns); + for (std::size_t i = 0; i < public_columns; i++) { + public_input_assignment[i] = table[i + witness_columns]; + } + + std::vector> constant_assignment(constant_columns); + for (std::size_t i = 0; i < constant_columns; i++) { + constant_assignment[i] = table[i + witness_columns + public_columns]; + } + + std::vector> selector_assignment(selector_columns); + for (std::size_t i = 0; i < selector_columns; i++) { + selector_assignment[i] = table[i + witness_columns + public_columns + constant_columns]; + } + + test_circuit.table = plonk_assignment_table( + plonk_private_assignment_table(private_assignment), + plonk_public_assignment_table( + public_input_assignment, + constant_assignment, + selector_assignment + ) + ); + test_circuit.table_rows = zk_padding(test_circuit.table, alg_rnd); + + std::vector> constraints; + var pi(0,0,true,var::column_type::public_input); + var w(0,0,true,var::column_type::witness); + var c0(0,0,true,var::column_type::constant); + var c1(0,0,true,var::column_type::constant); + constraints.push_back(2 * pi - w); + plonk_gate> add_gate( + PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, constraints + ); + test_circuit.gates.push_back(add_gate); + + plonk_lookup_table lookup_table( + 1, PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED + ); // switched on everywhere except the first row. + lookup_table.append_option({c0}); + lookup_table.append_option({c1}); + test_circuit.lookup_tables.push_back(lookup_table); + + std::vector> lookup_constraints; + lookup_constraints.push_back({1, {pi + w}}); + plonk_lookup_gate> lookup_gate( + PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, lookup_constraints + ); + test_circuit.lookup_gates.push_back(lookup_gate); + + return test_circuit; + } } // namespace snark } // namespace zk } // namespace crypto3 diff --git a/crypto3/libs/marshalling/zk/test/placeholder_common_data.cpp b/crypto3/libs/marshalling/zk/test/placeholder_common_data.cpp index a3f623b21e..1a58733730 100644 --- a/crypto3/libs/marshalling/zk/test/placeholder_common_data.cpp +++ b/crypto3/libs/marshalling/zk/test/placeholder_common_data.cpp @@ -782,10 +782,7 @@ struct placeholder_kzg_test_fixture_v2 : public test_tools::random_test_initiali using policy_type = zk::snark::detail::placeholder_policy; - using circuit_type = - circuit_description, - UsableRowsAmount>; + using circuit_type = circuit_description>; placeholder_kzg_test_fixture_v2() : desc(WitnessColumns, PublicInputColumns, ConstantColumns, SelectorColumns) diff --git a/crypto3/libs/marshalling/zk/test/placeholder_proof.cpp b/crypto3/libs/marshalling/zk/test/placeholder_proof.cpp index 26577de3b4..ea5d1eb344 100644 --- a/crypto3/libs/marshalling/zk/test/placeholder_proof.cpp +++ b/crypto3/libs/marshalling/zk/test/placeholder_proof.cpp @@ -1293,8 +1293,7 @@ struct placeholder_kzg_test_fixture_v2 : public test_tools::random_test_initiali using circuit_type = circuit_description, - usable_rows_amount>; + placeholder_circuit_params>; placeholder_kzg_test_fixture_v2() : desc(WitnessColumns, PublicInputColumns, ConstantColumns, SelectorColumns) diff --git a/crypto3/libs/marshalling/zk/test/plonk_constraint_system.cpp b/crypto3/libs/marshalling/zk/test/plonk_constraint_system.cpp index 30a4a26d4d..c317feb02e 100644 --- a/crypto3/libs/marshalling/zk/test/plonk_constraint_system.cpp +++ b/crypto3/libs/marshalling/zk/test/plonk_constraint_system.cpp @@ -533,3 +533,69 @@ BOOST_FIXTURE_TEST_CASE(constraint_system_marshalling_test, test_tools::random_t test_constraint_system(constraint_system); } BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(placeholder_circuit8) + using Endianness = nil::marshalling::option::big_endian; + using TTypeBase = nil::marshalling::field_type; + using curve_type = algebra::curves::pallas; + using field_type = typename curve_type::base_field_type; + + constexpr static const std::size_t table_rows_log = 4; + constexpr static const std::size_t table_rows = 1 << table_rows_log; + constexpr static const std::size_t usable_rows = 14; + + struct placeholder_test_params { + using merkle_hash_type = hashes::keccak_1600<512>; + using transcript_hash_type = hashes::keccak_1600<512>; + + constexpr static const std::size_t witness_columns = witness_columns_8; + constexpr static const std::size_t public_input_columns = public_columns_8; + constexpr static const std::size_t constant_columns = constant_columns_8; + constexpr static const std::size_t selector_columns = selector_columns_8; + + constexpr static const std::size_t lambda = 40; + constexpr static const std::size_t m = 2; + }; + + using circuit_params = placeholder_circuit_params; + using transcript_type = typename transcript::fiat_shamir_heuristic_sequential; + using lpc_params_type = commitments::list_polynomial_commitment_params< + typename placeholder_test_params::merkle_hash_type, + typename placeholder_test_params::transcript_hash_type, + placeholder_test_params::m + >; + + using lpc_type = commitments::list_polynomial_commitment; + using lpc_scheme_type = typename commitments::lpc_commitment_scheme; + using lpc_placeholder_params_type = nil::crypto3::zk::snark::placeholder_params; + using policy_type = zk::snark::detail::placeholder_policy; + +BOOST_FIXTURE_TEST_CASE(constraint_system_marshalling_test, test_tools::random_test_initializer) { + auto circuit = circuit_test_8( + alg_random_engines.template get_alg_engine(), + generic_random_engine + ); + plonk_table_description desc( + placeholder_test_params::witness_columns, + placeholder_test_params::public_input_columns, + placeholder_test_params::constant_columns, + placeholder_test_params::selector_columns + ); + + desc.rows_amount = circuit.table_rows; + desc.usable_rows_amount = circuit.usable_rows; + + typename policy_type::constraint_system_type constraint_system( + circuit.gates, + circuit.copy_constraints, + circuit.lookup_gates, + circuit.lookup_tables + ); + typename policy_type::variable_assignment_type assignments = circuit.table; + + if(has_argv("--print")) + test_constraint_system(constraint_system, "circuit7"); + else + test_constraint_system(constraint_system); +} +BOOST_AUTO_TEST_SUITE_END() diff --git a/crypto3/libs/transpiler/include/nil/blueprint/transpiler/lpc_evm_verifier_gen.hpp b/crypto3/libs/transpiler/include/nil/blueprint/transpiler/lpc_evm_verifier_gen.hpp index d1531756ba..7f92f29ad7 100644 --- a/crypto3/libs/transpiler/include/nil/blueprint/transpiler/lpc_evm_verifier_gen.hpp +++ b/crypto3/libs/transpiler/include/nil/blueprint/transpiler/lpc_evm_verifier_gen.hpp @@ -709,10 +709,6 @@ namespace nil { "\t\t\tstate.l_shifted = addmod( state.l_shifted, mulmod(state.shifted_selector_value, mulmod( state.theta_acc, basic_marshalling.get_uint256_be(blob, " << _var_indices.at(shifted_var) * 0x20 << "), modulus), modulus), modulus);" << std::endl; lookup_str << "\t\t\tstate.theta_acc = mulmod(state.theta_acc, state.theta, modulus);" << std::endl; } - lookup_str << - "\t\t\tl = mulmod( l, state.mask, modulus);" << std::endl; - lookup_str << - "\t\t\tstate.l_shifted = mulmod( state.l_shifted, state.shifted_mask, modulus);" << std::endl; lookup_str << "\t\t\tstate.g = mulmod(state.g, addmod( state.factor, addmod(l, mulmod(state.beta, state.l_shifted, modulus), modulus), modulus), modulus);" << std::endl; j++; } diff --git a/crypto3/libs/transpiler/include/nil/blueprint/transpiler/templates/modular_verifier.hpp b/crypto3/libs/transpiler/include/nil/blueprint/transpiler/templates/modular_verifier.hpp index 3a92bc19b9..daec621a60 100644 --- a/crypto3/libs/transpiler/include/nil/blueprint/transpiler/templates/modular_verifier.hpp +++ b/crypto3/libs/transpiler/include/nil/blueprint/transpiler/templates/modular_verifier.hpp @@ -205,19 +205,6 @@ contract modular_verifier_$TEST_NAME$ is IModularVerifier{ uint256 theta = transcript.get_field_challenge(tr_state, modulus); state.F[7] = modular_gate_argument.verify(blob[table_offset:table_end_offset], theta); - state.F[7] = mulmod( - state.F[7], - addmod( - 1, - modulus - addmod( - basic_marshalling.get_uint256_be(blob, special_selectors_offset), - basic_marshalling.get_uint256_be(blob, special_selectors_offset + 0x40), - modulus - ), - modulus - ), - modulus - ); // console.log("F[0] = ", state.F[0]); // console.log("F[1] = ", state.F[1]); // console.log("F[2] = ", state.F[2]); diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint_system.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint_system.hpp index 6300afef3d..f39937a6fd 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint_system.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint_system.hpp @@ -50,8 +50,9 @@ namespace nil { namespace crypto3 { namespace zk { namespace snark { - /************************* PLONK constraint system ****************************/ + constexpr static std::size_t const PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED = std::numeric_limits::max(); + constexpr static std::size_t const PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED = std::numeric_limits::max() - 1; // Useful for lookup tables template struct plonk_constraint_system { diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/padding.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/padding.hpp index 461d4fb8b7..5305bf9472 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/padding.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/padding.hpp @@ -102,15 +102,15 @@ namespace nil { } for (std::uint32_t pi_index = 0; pi_index < table._public_table.public_inputs_amount(); pi_index++) { - table._public_table._public_inputs[pi_index].resize(usable_rows_amount, FieldType::value_type::zero()); + table._public_table._public_inputs[pi_index].resize(padded_rows_amount, FieldType::value_type::zero()); } for (std::uint32_t c_index = 0; c_index < table._public_table.constants_amount(); c_index++) { - table._public_table._constants[c_index].resize(usable_rows_amount, FieldType::value_type::zero()); + table._public_table._constants[c_index].resize(padded_rows_amount, FieldType::value_type::zero()); } for (std::uint32_t s_index = 0; s_index < table._public_table.selectors_amount(); s_index++) { - table._public_table._selectors[s_index].resize(usable_rows_amount, FieldType::value_type::zero()); + table._public_table._selectors[s_index].resize(padded_rows_amount, FieldType::value_type::zero()); } @@ -120,25 +120,6 @@ namespace nil { table._private_table._witnesses[w_index][i] = alg_rnd(); } } - - for (std::uint32_t pi_index = 0; pi_index < table._public_table.public_inputs_amount(); pi_index++) { - table._public_table._public_inputs[pi_index].resize(padded_rows_amount, FieldType::value_type::zero()); - } - - for (std::uint32_t c_index = 0; c_index < table._public_table.constants_amount(); c_index++) { - table._public_table._constants[c_index].resize(padded_rows_amount); - for(std::size_t i = usable_rows_amount; i < padded_rows_amount; i++) { - table._public_table._constants[c_index][i] = alg_rnd(); - } - } - - for (std::uint32_t s_index = 0; s_index < table._public_table.selectors_amount(); s_index++) { - table._public_table._selectors[s_index].resize(padded_rows_amount); - for(std::size_t i = usable_rows_amount; i < padded_rows_amount; i++) { - table._public_table._selectors[s_index][i] = alg_rnd(); - } - } - return padded_rows_amount; } } // namespace snark diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/gates_argument.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/gates_argument.hpp index 0823a1b6dd..1f63bbfb7b 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/gates_argument.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/gates_argument.hpp @@ -80,7 +80,10 @@ namespace nil { const plonk_polynomial_dfs_table &assignments, std::shared_ptr> domain, std::size_t extended_domain_size, - std::unordered_map& variable_values_out) { + std::unordered_map& variable_values_out, + const polynomial_dfs_type &mask_polynomial, + const polynomial_dfs_type &lagrange_0 + ) { std::unordered_map variable_counts; @@ -94,26 +97,33 @@ namespace nil { visitor.visit(expr); for (const auto& [var, count]: variable_counts) { - // We may have variable values in required sizes in some cases. if (variable_values_out.find(var) != variable_values_out.end()) continue; - polynomial_dfs_type assignment = assignments.get_variable_value(var, domain); - if (count > 1) { - assignment.resize(extended_domain_size, domain, extended_domain); + // We may have variable values in required sizes in some cases. + if( var.index == PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED && var.type == polynomial_dfs_variable_type::column_type::selector ) { + variable_values_out[var] = mask_polynomial; + } else if (var.index == PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED && var.type == polynomial_dfs_variable_type::column_type::selector){ + variable_values_out[var] = mask_polynomial - lagrange_0; + } else { + polynomial_dfs_type assignment = assignments.get_variable_value(var, domain); + if (count > 1) { + assignment.resize(extended_domain_size, domain, extended_domain); + } + variable_values_out[var] = assignment; } - variable_values_out[var] = assignment; } } - static inline std::array - prove_eval( - const typename policy_type::constraint_system_type &constraint_system, - const plonk_polynomial_dfs_table - &column_polynomials, - std::shared_ptr> original_domain, - std::uint32_t max_gates_degree, - const polynomial_dfs_type &mask_polynomial, - transcript_type& transcript) { + static inline std::array prove_eval( + const typename policy_type::constraint_system_type &constraint_system, + const plonk_polynomial_dfs_table + &column_polynomials, + std::shared_ptr> original_domain, + std::uint32_t max_gates_degree, + const polynomial_dfs_type &mask_polynomial, + const polynomial_dfs_type &lagrange_0, + transcript_type& transcript + ) { PROFILE_SCOPE("gate_argument_time"); // max_gates_degree that comes from the outside does not take into account multiplication @@ -168,8 +178,8 @@ namespace nil { } } - auto selector = polynomial_dfs_variable_type( - gate.selector_index, 0, false, polynomial_dfs_variable_type::column_type::selector); + polynomial_dfs_variable_type selector = polynomial_dfs_variable_type( + gate.selector_index, 0, false, polynomial_dfs_variable_type::column_type::selector); for (size_t i = 0; i < extended_domain_sizes.size(); ++i) { gate_results[i] *= selector; @@ -184,8 +194,11 @@ namespace nil { if (i != 0 && extended_domain_sizes[i] != extended_domain_sizes[i-1]) { variable_values.clear(); } - build_variable_value_map(expressions[i], column_polynomials, original_domain, - extended_domain_sizes[i], variable_values); + build_variable_value_map( + expressions[i], column_polynomials, original_domain, + extended_domain_sizes[i], variable_values, + mask_polynomial, lagrange_0 + ); math::cached_expression_evaluator evaluator( expressions[i], [&assignments=variable_values, domain_size=extended_domain_sizes[i]] @@ -197,7 +210,6 @@ namespace nil { F[0] += evaluator.evaluate(); } - F[0] *= mask_polynomial; return F; } @@ -230,7 +242,6 @@ namespace nil { F[0] += gate_result; } - F[0] *= mask_value; return F; } }; diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp index 9cfc0830c3..03d9ffe36d 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp @@ -162,15 +162,17 @@ namespace nil { 0, basic_domain->m, FieldType::value_type::zero()); polynomial_dfs_type mask_assignment = one_polynomial - preprocessed_data.q_last - preprocessed_data.q_blind; + polynomial_dfs_type lagrange0 = preprocessed_data.common_data.lagrange_0; std::unique_ptr> lookup_value_ptr = - prepare_lookup_value(mask_assignment); + prepare_lookup_value(mask_assignment, lagrange0); auto& lookup_value = *lookup_value_ptr; std::unique_ptr> lookup_input_ptr = - prepare_lookup_input(); + prepare_lookup_input(mask_assignment, lagrange0); auto& lookup_input = *lookup_input_ptr; + // 3. Lookup_input and lookup_value are ready // Now sort them! // Reduce value and input: @@ -427,7 +429,9 @@ namespace nil { } std::unique_ptr> prepare_lookup_value( - const polynomial_dfs_type& mask_assignment) { + const polynomial_dfs_type &mask_assignment, + const polynomial_dfs_type &lagrange0 + ) { PROFILE_SCOPE("Lookup argument preparing lookup value"); typename FieldType::value_type theta_acc; @@ -436,7 +440,14 @@ namespace nil { auto lookup_value_ptr = std::make_unique>(); for (std::size_t t_id = 0; t_id < lookup_tables.size(); t_id++) { const plonk_lookup_table &l_table = lookup_tables[t_id]; - const polynomial_dfs_type &lookup_tag = plonk_columns.selector(l_table.tag_index); + polynomial_dfs_type lookup_tag; + if( l_table.tag_index == PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED ){ + lookup_tag = mask_assignment; + } else if( l_table.tag_index == PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED ){ + lookup_tag = mask_assignment - lagrange0; + } else { + lookup_tag = plonk_columns.selector(l_table.tag_index); + } for (std::size_t o_id = 0; o_id < l_table.lookup_options.size(); o_id++) { polynomial_dfs_type v = (typename FieldType::value_type(t_id + 1)) * lookup_tag; theta_acc = theta; @@ -446,14 +457,16 @@ namespace nil { v += theta_acc * lookup_tag * c; theta_acc *= theta; } - v *= mask_assignment; lookup_value_ptr->push_back(v); } } return std::move(lookup_value_ptr); } - std::unique_ptr> prepare_lookup_input() { + std::unique_ptr> prepare_lookup_input( + const polynomial_dfs_type &mask_assignment, + const polynomial_dfs_type &lagrange0 + ) { PROFILE_SCOPE("Lookup argument preparing lookup input"); auto value_type_to_polynomial_dfs = []( @@ -470,7 +483,13 @@ namespace nil { auto lookup_input_ptr = std::make_unique>(); for (const auto &gate : lookup_gates) { math::expression expr; - polynomial_dfs_type lookup_selector = plonk_columns.selector(gate.tag_index); + polynomial_dfs_type lookup_selector; + if( gate.tag_index == PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED ){ + lookup_selector = mask_assignment; + } else if( gate.tag_index == PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED ){ + lookup_selector = mask_assignment - lagrange0; + } else + lookup_selector = plonk_columns.selector(gate.tag_index); for (const auto &constraint : gate.constraints) { polynomial_dfs_type l = lookup_selector * (typename FieldType::value_type(constraint.table_id)); theta_acc = theta; @@ -589,10 +608,7 @@ namespace nil { std::unordered_map sorting_map; for (std::size_t i = 0; i < reduced_value.size(); i++) { for (std::size_t j = 0; j < usable_rows_amount; j++) { - if(sorting_map.find(reduced_value[i][j]) != sorting_map.end()) - sorting_map[reduced_value[i][j]]++; - else - sorting_map[reduced_value[i][j]] = 1; + sorting_map[reduced_value[i][j]] = 1; } } @@ -611,8 +627,6 @@ namespace nil { ); std::size_t i1 = 0; std::size_t j1 = 0; - typename FieldType::value_type prev = FieldType::value_type::zero(); - auto append_to_sorted = [usable_rows_amount, &sorted, &i1, &j1] ( const typename FieldType::value_type& value) { sorted[i1][j1] = value; @@ -624,24 +638,12 @@ namespace nil { for (std::size_t i = 0; i < reduced_value.size(); i++) { for (std::size_t j = 0; j < usable_rows_amount; j++) { - if (reduced_value[i][j] != prev) { - if (prev == FieldType::value_type::zero()) { - BOOST_ASSERT(j1 < usable_rows_amount); - append_to_sorted(prev); - } else { - for (std::size_t k = 0; k < sorting_map[prev]; k++) { - BOOST_ASSERT(j1 < usable_rows_amount); - append_to_sorted(prev); - } - } - prev = reduced_value[i][j]; + typename FieldType::value_type val = reduced_value[i][j]; + for (std::size_t k = 0; k < sorting_map[val]; k++) { + BOOST_ASSERT(j1 < usable_rows_amount); + append_to_sorted(val); } - } - } - if (prev != FieldType::value_type::zero()) { - for (std::size_t k = 0; k < sorting_map[prev]; k++) { - //BOOST_ASSERT(j1 < usable_rows_amount); - append_to_sorted(prev); + sorting_map[val] = 1; } } @@ -719,8 +721,8 @@ namespace nil { const auto &table = lookup_tables[t_id]; auto key = std::tuple(table.tag_index, 0, plonk_variable::column_type::selector); auto shifted_key = std::tuple(table.tag_index, 1, plonk_variable::column_type::selector); - auto selector_value = evaluations[key]; - auto shifted_selector_value = evaluations[shifted_key]; + typename FieldType::value_type selector_value = evaluations[key];; + typename FieldType::value_type shifted_selector_value = evaluations[shifted_key];; for( std::size_t o_id = 0; o_id < table.lookup_options.size(); o_id++){ typename FieldType::value_type v = selector_value * (t_id + 1); typename FieldType::value_type shifted_v = shifted_selector_value * (t_id + 1); @@ -734,8 +736,6 @@ namespace nil { shifted_v += theta_acc * evaluations[shifted_key1]* shifted_selector_value; theta_acc *= theta; } - v *= mask_value; - shifted_v *= shifted_mask_value; lookup_value.push_back(v); shifted_lookup_value.push_back(shifted_v); } @@ -746,7 +746,7 @@ namespace nil { for( std::size_t g_id = 0; g_id < lookup_gates.size(); g_id++ ){ const auto &gate = lookup_gates[g_id]; auto key = std::tuple(gate.tag_index, 0, plonk_variable::column_type::selector); - auto selector_value = evaluations[key]; + typename FieldType::value_type selector_value= evaluations[key]; for( std::size_t c_id = 0; c_id < gate.constraints.size(); c_id++){ const auto &constraint = gate.constraints[c_id]; typename FieldType::value_type l = selector_value * constraint.table_id; diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp index 5668a581cc..1155a15274 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp @@ -188,6 +188,7 @@ namespace nil { preprocessed_public_data.common_data.basic_domain, preprocessed_public_data.common_data.max_gates_degree, mask_polynomial, + preprocessed_public_data.common_data.lagrange_0, transcript )[0]; diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp index ed3ee9b5da..afbd73465c 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp @@ -330,6 +330,43 @@ namespace nil { ++j; } } + typename FieldType::value_type mask_value = FieldType::value_type::one() - + proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, common_data.permuted_columns.size() * 2, 0) - + proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, common_data.permuted_columns.size() * 2 + 1, 0); + typename FieldType::value_type shifted_mask_value = FieldType::value_type::one() - + proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, common_data.permuted_columns.size() * 2, 1) - + proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, common_data.permuted_columns.size() * 2 + 1, 1); + + // All rows selector + { + auto key = std::make_tuple( + PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 0, + plonk_variable::column_type::selector + ); + columns_at_y[key] = mask_value; + } + { + auto key = std::make_tuple( + PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 1, + plonk_variable::column_type::selector + ); + columns_at_y[key] = shifted_mask_value; + } + // All rows selector + { + auto key = std::make_tuple( + PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, 0, + plonk_variable::column_type::selector + ); + columns_at_y[key] = mask_value - common_data.lagrange_0.evaluate(proof.eval_proof.challenge); + } + { + auto key = std::make_tuple( + PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, 1, + plonk_variable::column_type::selector + ); + columns_at_y[key] = shifted_mask_value - common_data.lagrange_0.evaluate(proof.eval_proof.challenge * common_data.basic_domain->get_domain_element(1)); + } // 6. lookup argument bool is_lookup_enabled = (constraint_system.lookup_gates().size() > 0); @@ -365,9 +402,7 @@ namespace nil { std::array gate_argument = placeholder_gates_argument::verify_eval( constraint_system.gates(), columns_at_y, proof.eval_proof.challenge, - FieldType::value_type::one() - - proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, common_data.permuted_columns.size() * 2, 0) - - proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, common_data.permuted_columns.size() * 2 + 1, 0), + mask_value, transcript ); diff --git a/crypto3/libs/zk/test/systems/plonk/placeholder/circuits.hpp b/crypto3/libs/zk/test/systems/plonk/placeholder/circuits.hpp index 199befe012..b851d0aca0 100644 --- a/crypto3/libs/zk/test/systems/plonk/placeholder/circuits.hpp +++ b/crypto3/libs/zk/test/systems/plonk/placeholder/circuits.hpp @@ -606,7 +606,7 @@ namespace nil { selectors_assignment[0].resize(test_circuit.usable_rows); for(std::size_t i = 0; i < witness_columns; i++) { private_assignment[i].resize(test_circuit.usable_rows); - private_assignment[i][0] = private_assignment[i][2] = public_input_assignment[0][i] = + private_assignment[i][0] = private_assignment[i][2] = public_input_assignment[0][i] = typename FieldType::value_type(rnd() % witness_columns); private_assignment[i][1] = 1u; plonk_variable pi( @@ -1049,6 +1049,121 @@ namespace nil { return test_circuit; } + + // Selector -1 test: + // Table 1: options: {C1, C2} + // Lookup gate1: + // PI + W1, \in Table 1 selector -1 + // Gate1 + // W1 - PI * 2 = 0, selector -1 + // ------------------------- + // | PI | W1 | C1 | C2 | + // ------------------------- + // | a | 2*a | 0 | 42 | + // | a | 2*a | 3 | 45 | + // | a | 2*a | 6 | 48 | + // | a | 2*a | 9 | 51 | + // | a | 2*a | 12 | 54 | + // | a | 2*a | 15 | 57 | + // | a | 2*a | 18 | 60 | + // | a | 2*a | 21 | | + // | a | 2*a | 24 | | + // | a | 2*a | 27 | | + // | a | 2*a | 30 | | + // | a | 2*a | 33 | | + // | a | 2*a | 36 | | + // | a | 2*a | 39 | | + // ------------------------- + template + circuit_description> circuit_test_8( + typename nil::crypto3::random::algebraic_engine alg_rnd = nil::crypto3::random::algebraic_engine(), + boost::random::mt11213b rnd = boost::random::mt11213b() + ) { + using assignment_type = typename FieldType::value_type; + using var = nil::crypto3::zk::snark::plonk_variable; + + constexpr static const std::size_t witness_columns = 1; + constexpr static const std::size_t public_columns = 1; + constexpr static const std::size_t constant_columns = 2; + constexpr static const std::size_t selector_columns = 0; + constexpr static const std::size_t table_columns = + witness_columns + public_columns + constant_columns + selector_columns; + constexpr static const std::size_t usable_rows = 14; + constexpr static const std::size_t max_input_value = 2; //(usable_rows - 1) * 2; + + typedef placeholder_circuit_params circuit_params; + + circuit_description test_circuit; + test_circuit.usable_rows = usable_rows; + + std::vector> table(table_columns); + for (std::size_t j = 0; j < table_columns; j++) { + table[j].resize(test_circuit.usable_rows); + } + for (std::size_t j = 0; j < usable_rows; j++) { + table[1][j] = rnd() % max_input_value; // Public input + table[0][j] = table[1][j] * 2; // Witness + table[2][j] = j == 0? 0: 3 * (j - 1); // Static lookup table 1 + table[3][j] = j == 0? 0: 3 * (j - 1 + usable_rows - 1 ); // Static lookup table 2 + } + + std::vector> private_assignment(witness_columns); + for (std::size_t i = 0; i < witness_columns; i++) { + private_assignment[i] = table[i]; + } + + std::vector> public_input_assignment(public_columns); + for (std::size_t i = 0; i < public_columns; i++) { + public_input_assignment[i] = table[i + witness_columns]; + } + + std::vector> constant_assignment(constant_columns); + for (std::size_t i = 0; i < constant_columns; i++) { + constant_assignment[i] = table[i + witness_columns + public_columns]; + } + + std::vector> selector_assignment(selector_columns); + for (std::size_t i = 0; i < selector_columns; i++) { + selector_assignment[i] = table[i + witness_columns + public_columns + constant_columns]; + } + + test_circuit.table = plonk_assignment_table( + plonk_private_assignment_table(private_assignment), + plonk_public_assignment_table( + public_input_assignment, + constant_assignment, + selector_assignment + ) + ); + test_circuit.table_rows = zk_padding(test_circuit.table, alg_rnd); + + std::vector> constraints; + var pi(0,0,true,var::column_type::public_input); + var w(0,0,true,var::column_type::witness); + var c0(0,0,true,var::column_type::constant); + var c1(0,0,true,var::column_type::constant); + constraints.push_back(2 * pi - w); + plonk_gate> add_gate( + PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, constraints + ); + test_circuit.gates.push_back(add_gate); + + plonk_lookup_table lookup_table( + 1, PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED + ); // switched on everywhere except the first row. + lookup_table.append_option({c0}); + lookup_table.append_option({c1}); + test_circuit.lookup_tables.push_back(lookup_table); + + std::vector> lookup_constraints; + lookup_constraints.push_back({1, {pi + w}}); + plonk_lookup_gate> lookup_gate( + PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, lookup_constraints + ); + test_circuit.lookup_gates.push_back(lookup_gate); + + return test_circuit; + } } // namespace snark } // namespace zk } // namespace crypto3 diff --git a/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_circuits.cpp b/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_circuits.cpp index 0e0c02f817..483e7db324 100644 --- a/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_circuits.cpp +++ b/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_circuits.cpp @@ -129,6 +129,17 @@ BOOST_AUTO_TEST_SUITE(placeholder_circuits) BOOST_CHECK(test_runner.run_test()); } + BOOST_AUTO_TEST_CASE(circuit8) + { + test_tools::random_test_initializer random_test_initializer; + auto circuit = circuit_test_8( + random_test_initializer.alg_random_engines.template get_alg_engine(), + random_test_initializer.generic_random_engine + ); + test_runner_type test_runner(circuit); + BOOST_CHECK(test_runner.run_test()); + } + BOOST_AUTO_TEST_CASE(circuit_fib) { test_tools::random_test_initializer random_test_initializer; diff --git a/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_gate_argument.cpp b/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_gate_argument.cpp index 6448147d94..0fd6e3b3d4 100644 --- a/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_gate_argument.cpp +++ b/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_gate_argument.cpp @@ -147,7 +147,11 @@ BOOST_AUTO_TEST_SUITE(placeholder_gate_argument) std::array, 1> prover_res = placeholder_gates_argument::prove_eval( constraint_system, polynomial_table, preprocessed_public_data.common_data.basic_domain, - preprocessed_public_data.common_data.max_gates_degree, mask_polynomial, prover_transcript); + preprocessed_public_data.common_data.max_gates_degree, + mask_polynomial, + preprocessed_public_data.common_data.lagrange_0, + prover_transcript + ); // Challenge phase typename field_type::value_type y = algebra::random_element(); @@ -203,6 +207,18 @@ BOOST_AUTO_TEST_SUITE(placeholder_gate_argument) auto mask_value = field_type::value_type::one() - preprocessed_public_data.q_last.evaluate(y) - preprocessed_public_data.q_blind.evaluate(y); + + // All rows selector + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 0, plonk_variable::column_type::selector); + columns_at_y[key] = mask_value; + } + // All rows selector except the first row + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, 0, plonk_variable::column_type::selector); + columns_at_y[key] = mask_value - preprocessed_public_data.common_data.lagrange_0.evaluate(y); + } + std::array verifier_res = placeholder_gates_argument::verify_eval( constraint_system.gates(), columns_at_y, y, mask_value, verifier_transcript); diff --git a/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_lookup_argument.cpp b/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_lookup_argument.cpp index 6a37bbe055..2c5e2fa01f 100644 --- a/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_lookup_argument.cpp +++ b/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_lookup_argument.cpp @@ -210,6 +210,25 @@ BOOST_AUTO_TEST_SUITE(placeholder_circuit3_lookup_test) special_selector_values_shifted[0] = preprocessed_public_data.q_last.evaluate(y * omega); special_selector_values_shifted[1] = preprocessed_public_data.q_blind.evaluate(y * omega); + // All rows selector + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 0, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y) -preprocessed_public_data.q_blind.evaluate(y) ; + } + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 1, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y * omega) -preprocessed_public_data.q_blind.evaluate(y * omega) ; + } + // All rows selector + { + auto key = std::make_tuple( -2, 0, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y) -preprocessed_public_data.q_blind.evaluate(y) - preprocessed_public_data.common_data.lagrange_0.evaluate(y); + } + { + auto key = std::make_tuple( -2, 1, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y * omega) -preprocessed_public_data.q_blind.evaluate(y * omega) - preprocessed_public_data.common_data.lagrange_0.evaluate(y * omega); + } + placeholder_lookup_argument_verifier lookup_verifier; std::array verifier_res = lookup_verifier.verify_eval( preprocessed_public_data.common_data, @@ -391,6 +410,25 @@ BOOST_AUTO_TEST_SUITE(placeholder_circuit4_lookup_test) special_selector_values_shifted[0] = preprocessed_public_data.q_last.evaluate(y * omega); special_selector_values_shifted[1] = preprocessed_public_data.q_blind.evaluate(y * omega); + // All rows selector + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 0, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y) -preprocessed_public_data.q_blind.evaluate(y) ; + } + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 1, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y * omega) -preprocessed_public_data.q_blind.evaluate(y * omega) ; + } + // All rows selector + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, 0, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y) -preprocessed_public_data.q_blind.evaluate(y) - preprocessed_public_data.common_data.lagrange_0.evaluate(y); + } + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, 1, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y * omega) -preprocessed_public_data.q_blind.evaluate(y * omega) - preprocessed_public_data.common_data.lagrange_0.evaluate(y * omega); + } + placeholder_lookup_argument_verifier verifier; std::array verifier_res = verifier.verify_eval( preprocessed_public_data.common_data, diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint_system.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint_system.hpp index 6300afef3d..a05a927fdf 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint_system.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint_system.hpp @@ -52,6 +52,8 @@ namespace nil { namespace snark { /************************* PLONK constraint system ****************************/ + constexpr static std::size_t const PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED = std::numeric_limits::max(); + constexpr static std::size_t const PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED = std::numeric_limits::max() - 1; // Useful for lookup tables template struct plonk_constraint_system { diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/padding.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/padding.hpp index 461d4fb8b7..fdda9cfe4a 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/padding.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/padding.hpp @@ -102,15 +102,15 @@ namespace nil { } for (std::uint32_t pi_index = 0; pi_index < table._public_table.public_inputs_amount(); pi_index++) { - table._public_table._public_inputs[pi_index].resize(usable_rows_amount, FieldType::value_type::zero()); + table._public_table._public_inputs[pi_index].resize(padded_rows_amount, FieldType::value_type::zero()); } for (std::uint32_t c_index = 0; c_index < table._public_table.constants_amount(); c_index++) { - table._public_table._constants[c_index].resize(usable_rows_amount, FieldType::value_type::zero()); + table._public_table._constants[c_index].resize(padded_rows_amount, FieldType::value_type::zero()); } for (std::uint32_t s_index = 0; s_index < table._public_table.selectors_amount(); s_index++) { - table._public_table._selectors[s_index].resize(usable_rows_amount, FieldType::value_type::zero()); + table._public_table._selectors[s_index].resize(padded_rows_amount, FieldType::value_type::zero()); } @@ -121,24 +121,6 @@ namespace nil { } } - for (std::uint32_t pi_index = 0; pi_index < table._public_table.public_inputs_amount(); pi_index++) { - table._public_table._public_inputs[pi_index].resize(padded_rows_amount, FieldType::value_type::zero()); - } - - for (std::uint32_t c_index = 0; c_index < table._public_table.constants_amount(); c_index++) { - table._public_table._constants[c_index].resize(padded_rows_amount); - for(std::size_t i = usable_rows_amount; i < padded_rows_amount; i++) { - table._public_table._constants[c_index][i] = alg_rnd(); - } - } - - for (std::uint32_t s_index = 0; s_index < table._public_table.selectors_amount(); s_index++) { - table._public_table._selectors[s_index].resize(padded_rows_amount); - for(std::size_t i = usable_rows_amount; i < padded_rows_amount; i++) { - table._public_table._selectors[s_index][i] = alg_rnd(); - } - } - return padded_rows_amount; } } // namespace snark diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/gates_argument.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/gates_argument.hpp index 09bbc12b08..0caeb35316 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/gates_argument.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/gates_argument.hpp @@ -83,10 +83,12 @@ namespace nil { const plonk_polynomial_dfs_table &assignments, std::shared_ptr> domain, std::size_t extended_domain_size, - std::unordered_map& variable_values_out) { + std::unordered_map& variable_values_out, + const polynomial_dfs_type &mask_polynomial, + const polynomial_dfs_type &lagrange_0 + ) { std::unordered_map variable_counts; - std::vector variables; math::expression_for_each_variable_visitor visitor( @@ -108,7 +110,7 @@ namespace nil { math::make_evaluation_domain(extended_domain_size); parallel_for(0, variables.size(), - [&variables, &variable_values_out, &assignments, &domain, &extended_domain, extended_domain_size](std::size_t i) { + [&variables, &variable_values_out, &assignments, &domain, &extended_domain, extended_domain_size, &mask_polynomial, &lagrange_0](std::size_t i) { const variable_type& var = variables[i]; // Convert the variable to polynomial_dfs variable type. @@ -116,7 +118,13 @@ namespace nil { static_cast( static_cast(var.type))); - polynomial_dfs_type assignment = assignments.get_variable_value(var_dfs, domain); + polynomial_dfs_type assignment; + if( var.index == PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED && var.type == variable_type::column_type::selector){ + assignment = mask_polynomial; + } else if( var.index == PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED && var.type == variable_type::column_type::selector) { + assignment = mask_polynomial - lagrange_0; + } else + assignment = assignments.get_variable_value(var_dfs, domain); // In parallel version we always resize the assignment poly, it's better for parallelization. // if (count > 1) { @@ -125,15 +133,16 @@ namespace nil { }, ThreadPool::PoolLevel::HIGH); } - static inline std::array - prove_eval( - const typename policy_type::constraint_system_type &constraint_system, - const plonk_polynomial_dfs_table - &column_polynomials, - std::shared_ptr> original_domain, - std::uint32_t max_gates_degree, - const polynomial_dfs_type &mask_polynomial, - transcript_type& transcript) { + static inline std::array prove_eval( + const typename policy_type::constraint_system_type &constraint_system, + const plonk_polynomial_dfs_table + &column_polynomials, + std::shared_ptr> original_domain, + std::uint32_t max_gates_degree, + const polynomial_dfs_type &mask_polynomial, + const polynomial_dfs_type &lagrange_0, + transcript_type& transcript + ) { PROFILE_SCOPE("gate_argument_time"); // max_gates_degree that comes from the outside does not take into account multiplication @@ -186,8 +195,7 @@ namespace nil { } } } - auto selector = variable_type( - gate.selector_index, 0, false, variable_type::column_type::selector); + variable_type selector(gate.selector_index, 0, false, variable_type::column_type::selector); for (size_t i = 0; i < extended_domain_sizes.size(); ++i) { gate_results[i] *= selector; expressions[i] += gate_results[i]; @@ -199,9 +207,12 @@ namespace nil { F[0] = polynomial_dfs_type::zero(); for (std::size_t i = 0; i < extended_domain_sizes.size(); ++i) { std::unordered_map variable_values; - - build_variable_value_map(expressions[i], column_polynomials, original_domain, - extended_domain_sizes[i], variable_values); + + build_variable_value_map( + expressions[i], column_polynomials, original_domain, + extended_domain_sizes[i], variable_values, + mask_polynomial, lagrange_0 + ); polynomial_dfs_type result(extended_domain_sizes[i] - 1, extended_domain_sizes[i]); wait_for_all(parallel_run_in_chunks( @@ -212,7 +223,7 @@ namespace nil { // Don't use cache here. In practice it's slower to maintain the cache // than to re-compute the subexpression value when value type is field element. math::expression_evaluator evaluator( - expressions[i], + expressions[i], [&assignments=variable_values, j] (const variable_type &var) -> const typename FieldType::value_type& { return assignments[var][j]; @@ -220,10 +231,9 @@ namespace nil { result[j] = evaluator.evaluate(); } }, ThreadPool::PoolLevel::HIGH)); - + F[0] += result; }; - F[0] *= mask_polynomial; return F; } @@ -256,7 +266,6 @@ namespace nil { F[0] += gate_result; } - F[0] *= mask_value; return F; } }; diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp index d1ef6ffb41..e32205d1bf 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp @@ -164,15 +164,15 @@ namespace nil { 0, basic_domain->m, FieldType::value_type::one()); polynomial_dfs_type zero_polynomial( 0, basic_domain->m, FieldType::value_type::zero()); - polynomial_dfs_type mask_assignment = - one_polynomial - preprocessed_data.q_last - preprocessed_data.q_blind; + polynomial_dfs_type mask_assignment = one_polynomial - preprocessed_data.q_last - preprocessed_data.q_blind; + polynomial_dfs_type lagrange0 = preprocessed_data.common_data.lagrange_0; std::unique_ptr> lookup_value_ptr = - prepare_lookup_value(mask_assignment); + prepare_lookup_value(mask_assignment, lagrange0); auto& lookup_value = *lookup_value_ptr; std::unique_ptr> lookup_input_ptr = - prepare_lookup_input(); + prepare_lookup_input(mask_assignment, lagrange0); auto& lookup_input = *lookup_input_ptr; // 3. Lookup_input and lookup_value are ready @@ -280,10 +280,10 @@ namespace nil { polynomial_dfs_type current_poly = V_L; polynomial_dfs_type previous_poly = V_L; - // We need to store all the values of current_poly. Suddenly this increases the RAM usage, but + // We need to store all the values of current_poly. Suddenly this increases the RAM usage, but // there's no other way to parallelize this loop. std::vector all_polys(1, V_L); - + for (std::size_t i = 0; i < lookup_alphas.size(); ++i) { parallel_for(0, preprocessed_data.common_data.desc.usable_rows_amount, @@ -310,7 +310,7 @@ namespace nil { } }, ThreadPool::PoolLevel::HIGH)); - + std::size_t last = lookup_alphas.size(); F_dfs_2_parts.back() = previous_poly * gs[last] - V_L_shifted * hs[last]; F_dfs[2] += polynomial_sum(std::move(F_dfs_2_parts)); @@ -373,11 +373,11 @@ namespace nil { parallel_for(lookup_part_start_indices[current_part], lookup_part_start_indices[current_part + 1], [&g_multipliers, &one, &beta, &part1, &gamma, &lookup_input, &lookup_value, &lookup_part_start_indices, ¤t_part, this](std::size_t i) { if (i < lookup_input.size()) { - g_multipliers[i - lookup_part_start_indices[current_part]] = + g_multipliers[i - lookup_part_start_indices[current_part]] = (one + beta) * (gamma + lookup_input[i]); } else { auto lookup_shifted = math::polynomial_shift(lookup_value[i - lookup_input.size()], 1, this->basic_domain->m); - g_multipliers[i - lookup_part_start_indices[current_part]] = + g_multipliers[i - lookup_part_start_indices[current_part]] = part1 + lookup_value[i - lookup_input.size()] + beta * lookup_shifted; } }, ThreadPool::PoolLevel::HIGH); @@ -414,7 +414,7 @@ namespace nil { parallel_for(lookup_part_start_indices[current_part], lookup_part_start_indices[current_part + 1], [&sorted, &h_multipliers, &one, &beta, &gamma, &lookup_part_start_indices, ¤t_part, this](std::size_t i) { auto sorted_shifted = math::polynomial_shift(sorted[i], 1, this->basic_domain->m); - h_multipliers[i - lookup_part_start_indices[current_part]] = + h_multipliers[i - lookup_part_start_indices[current_part]] = (one + beta) * gamma + sorted[i] + beta * sorted_shifted; }, ThreadPool::PoolLevel::HIGH); @@ -468,14 +468,22 @@ namespace nil { } std::unique_ptr> prepare_lookup_value( - const polynomial_dfs_type& mask_assignment) { + const polynomial_dfs_type &mask_assignment, + const polynomial_dfs_type &lagrange0 + ) { PROFILE_SCOPE("Lookup argument preparing lookup value"); // Prepare lookup value auto lookup_value_ptr = std::make_unique>(); for (std::size_t t_id = 0; t_id < lookup_tables.size(); t_id++) { const plonk_lookup_table &l_table = lookup_tables[t_id]; - const polynomial_dfs_type &lookup_tag = plonk_columns.selector(l_table.tag_index); + polynomial_dfs_type lookup_tag; + if(l_table.tag_index == PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED ) + lookup_tag = mask_assignment; + else if( l_table.tag_index == PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED ) + lookup_tag = mask_assignment - lagrange0; + else + lookup_tag = plonk_columns.selector(l_table.tag_index); // Increase the size to fit the next table values. std::size_t lookup_values_used = lookup_value_ptr->size(); @@ -489,14 +497,16 @@ namespace nil { v += theta_acc * lookup_tag * plonk_columns.constant(l_table.lookup_options[o_id][i].index); theta_acc *= this->theta; } - v *= mask_assignment; (*lookup_value_ptr)[lookup_values_used + o_id] = v; }, ThreadPool::PoolLevel::HIGH); } return std::move(lookup_value_ptr); } - std::unique_ptr> prepare_lookup_input() { + std::unique_ptr> prepare_lookup_input( + const polynomial_dfs_type &mask_assignment, + const polynomial_dfs_type &lagrange0 + ) { PROFILE_SCOPE("Lookup argument preparing lookup input"); using polynomial_dfs_variable_type = plonk_variable; @@ -504,7 +514,14 @@ namespace nil { // Prepare lookup input auto lookup_input_ptr = std::make_unique>(); for (const auto &gate : lookup_gates) { - polynomial_dfs_type lookup_selector = plonk_columns.selector(gate.tag_index); + polynomial_dfs_type lookup_selector; + if( gate.tag_index == PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED ){ + lookup_selector = mask_assignment; + } else if( gate.tag_index == PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED ){ + lookup_selector = mask_assignment - lagrange0; + } else { + lookup_selector = plonk_columns.selector(gate.tag_index); + } // Increase the size to fit the next table values. std::size_t lookup_inputs_used = lookup_input_ptr->size(); @@ -528,7 +545,7 @@ namespace nil { // For each variable with a rotation pre-compute its value. std::unordered_map rotated_variable_values; - + math::expression_for_each_variable_visitor visitor( [&rotated_variable_values, &assignments=plonk_columns, &domain=basic_domain] (const polynomial_dfs_variable_type& var) { @@ -538,7 +555,7 @@ namespace nil { }); visitor.visit(expr); - math::cached_expression_evaluator evaluator(expr, + math::cached_expression_evaluator evaluator(expr, [&domain=basic_domain, &assignments=plonk_columns, &rotated_variable_values] (const polynomial_dfs_variable_type &var) -> const polynomial_dfs_type& { if (var.rotation == 0) { @@ -638,10 +655,7 @@ namespace nil { std::unordered_map sorting_map; for (std::size_t i = 0; i < reduced_value.size(); i++) { for (std::size_t j = 0; j < usable_rows_amount; j++) { - if(sorting_map.find(reduced_value[i][j]) != sorting_map.end()) - sorting_map[reduced_value[i][j]]++; - else - sorting_map[reduced_value[i][j]] = 1; + sorting_map[reduced_value[i][j]] = 1; } } @@ -660,7 +674,6 @@ namespace nil { ); std::size_t i1 = 0; std::size_t j1 = 0; - typename FieldType::value_type prev = FieldType::value_type::zero(); auto append_to_sorted = [usable_rows_amount, &sorted, &i1, &j1] ( const typename FieldType::value_type& value) { @@ -673,24 +686,12 @@ namespace nil { for (std::size_t i = 0; i < reduced_value.size(); i++) { for (std::size_t j = 0; j < usable_rows_amount; j++) { - if (reduced_value[i][j] != prev) { - if (prev == FieldType::value_type::zero()) { - BOOST_ASSERT(j1 < usable_rows_amount); - append_to_sorted(prev); - } else { - for (std::size_t k = 0; k < sorting_map[prev]; k++) { - BOOST_ASSERT(j1 < usable_rows_amount); - append_to_sorted(prev); - } - } - prev = reduced_value[i][j]; + typename FieldType::value_type val = reduced_value[i][j]; + for (std::size_t k = 0; k < sorting_map[val]; k++) { + BOOST_ASSERT(j1 < usable_rows_amount); + append_to_sorted(val); } - } - } - if (prev != FieldType::value_type::zero()) { - for (std::size_t k = 0; k < sorting_map[prev]; k++) { - //BOOST_ASSERT(j1 < usable_rows_amount); - append_to_sorted(prev); + sorting_map[val] = 1; } } @@ -783,8 +784,6 @@ namespace nil { shifted_v += theta_acc * evaluations[shifted_key1]* shifted_selector_value; theta_acc *= theta; } - v *= mask_value; - shifted_v *= shifted_mask_value; lookup_value.push_back(v); shifted_lookup_value.push_back(shifted_v); } diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp index 2365a28463..0b4aa654c6 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp @@ -190,6 +190,7 @@ namespace nil { preprocessed_public_data.common_data.basic_domain, preprocessed_public_data.common_data.max_gates_degree, mask_polynomial, + preprocessed_public_data.common_data.lagrange_0, transcript )[0]; diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp index 5ddf292269..2ced8f970f 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp @@ -331,6 +331,38 @@ namespace nil { } } + typename FieldType::value_type mask_value = FieldType::value_type::one() - + proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, common_data.permuted_columns.size() * 2, 0) - + proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, common_data.permuted_columns.size() * 2 + 1, 0); + typename FieldType::value_type shifted_mask_value = FieldType::value_type::one() - + proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, common_data.permuted_columns.size() * 2, 1) - + proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, common_data.permuted_columns.size() * 2 + 1, 1); + + // All rows selector + { + auto key = std::make_tuple( + PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 0, + plonk_variable::column_type::selector + ); + columns_at_y[key] = mask_value; + } + { + auto key = std::make_tuple( + PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 1, + plonk_variable::column_type::selector + ); + columns_at_y[key] = shifted_mask_value; + } + // All rows selector + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, 0, plonk_variable::column_type::selector); + columns_at_y[key] = mask_value - common_data.lagrange_0.evaluate(proof.eval_proof.challenge); + } + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, 1, plonk_variable::column_type::selector); + columns_at_y[key] = shifted_mask_value - common_data.lagrange_0.evaluate(proof.eval_proof.challenge * common_data.basic_domain->get_domain_element(1)); + } + // 6. lookup argument bool is_lookup_enabled = (constraint_system.lookup_gates().size() > 0); std::array lookup_argument; @@ -365,10 +397,7 @@ namespace nil { std::array gate_argument = placeholder_gates_argument::verify_eval( constraint_system.gates(), columns_at_y, proof.eval_proof.challenge, - FieldType::value_type::one() - - proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, common_data.permuted_columns.size() * 2, 0) - - proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, common_data.permuted_columns.size() * 2 + 1, 0), - transcript + mask_value, transcript ); std::array alphas = diff --git a/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/circuits.hpp b/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/circuits.hpp index 199befe012..4732679f87 100644 --- a/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/circuits.hpp +++ b/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/circuits.hpp @@ -606,7 +606,7 @@ namespace nil { selectors_assignment[0].resize(test_circuit.usable_rows); for(std::size_t i = 0; i < witness_columns; i++) { private_assignment[i].resize(test_circuit.usable_rows); - private_assignment[i][0] = private_assignment[i][2] = public_input_assignment[0][i] = + private_assignment[i][0] = private_assignment[i][2] = public_input_assignment[0][i] = typename FieldType::value_type(rnd() % witness_columns); private_assignment[i][1] = 1u; plonk_variable pi( @@ -1049,6 +1049,116 @@ namespace nil { return test_circuit; } + + + // Selector -1 test: + // Table 1: options: {C1, C2} + // Lookup gate1: + // PI + W1, \in Table 1 selector -1 + // Gate1 + // W1 - PI * 2 = 0, selector -1 + // ------------------------- + // | PI | W1 | C1 | C2 | + // ------------------------- + // | a | 2*a | 0 | 42 | + // | a | 2*a | 3 | 45 | + // | a | 2*a | 6 | 48 | + // | a | 2*a | 9 | 51 | + // | a | 2*a | 12 | 54 | + // | a | 2*a | 15 | 57 | + // | a | 2*a | 18 | 60 | + // | a | 2*a | 21 | | + // | a | 2*a | 24 | | + // | a | 2*a | 27 | | + // | a | 2*a | 30 | | + // | a | 2*a | 33 | | + // | a | 2*a | 36 | | + // | a | 2*a | 39 | | + // ------------------------- + template + circuit_description> circuit_test_8( + typename nil::crypto3::random::algebraic_engine alg_rnd = nil::crypto3::random::algebraic_engine(), + boost::random::mt11213b rnd = boost::random::mt11213b() + ) { + using assignment_type = typename FieldType::value_type; + using var = nil::crypto3::zk::snark::plonk_variable; + + constexpr static const std::size_t witness_columns = 1; + constexpr static const std::size_t public_columns = 1; + constexpr static const std::size_t constant_columns = 2; + constexpr static const std::size_t selector_columns = 0; + constexpr static const std::size_t table_columns = + witness_columns + public_columns + constant_columns + selector_columns; + constexpr static const std::size_t usable_rows = 14; + constexpr static const std::size_t max_input_value = 2; //(usable_rows - 1) * 2; + + typedef placeholder_circuit_params circuit_params; + + circuit_description test_circuit; + test_circuit.usable_rows = usable_rows; + + std::vector> table(table_columns); + for (std::size_t j = 0; j < table_columns; j++) { + table[j].resize(test_circuit.usable_rows); + } + for (std::size_t j = 0; j < usable_rows; j++) { + table[1][j] = rnd() % max_input_value; // Public input + table[0][j] = table[1][j] * 2; // Witness + table[2][j] = j == 0? 0: 3 * (j - 1); // Static lookup table 1 + table[3][j] = j == 0? 0: 3 * (j - 1 + usable_rows - 1 ); // Static lookup table 2 + } + + std::vector> private_assignment(witness_columns); + for (std::size_t i = 0; i < witness_columns; i++) { + private_assignment[i] = table[i]; + } + + std::vector> public_input_assignment(public_columns); + for (std::size_t i = 0; i < public_columns; i++) { + public_input_assignment[i] = table[i + witness_columns]; + } + + std::vector> constant_assignment(constant_columns); + for (std::size_t i = 0; i < constant_columns; i++) { + constant_assignment[i] = table[i + witness_columns + public_columns]; + } + + std::vector> selector_assignment(selector_columns); + for (std::size_t i = 0; i < selector_columns; i++) { + selector_assignment[i] = table[i + witness_columns + public_columns + constant_columns]; + } + + test_circuit.table = plonk_assignment_table( + plonk_private_assignment_table(private_assignment), + plonk_public_assignment_table( + public_input_assignment, + constant_assignment, + selector_assignment + ) + ); + test_circuit.table_rows = zk_padding(test_circuit.table, alg_rnd); + + std::vector> constraints; + var pi(0,0,true,var::column_type::public_input); + var w(0,0,true,var::column_type::witness); + var c0(0,0,true,var::column_type::constant); + var c1(0,0,true,var::column_type::constant); + constraints.push_back(2 * pi - w); + plonk_gate> add_gate(PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, constraints); + test_circuit.gates.push_back(add_gate); + + plonk_lookup_table lookup_table(1, PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED); // switched on everywhere except the first row. + lookup_table.append_option({c0}); + lookup_table.append_option({c1}); + test_circuit.lookup_tables.push_back(lookup_table); + + std::vector> lookup_constraints; + lookup_constraints.push_back({1, {pi + w}}); + plonk_lookup_gate> lookup_gate(PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, lookup_constraints); + test_circuit.lookup_gates.push_back(lookup_gate); + + return test_circuit; + } } // namespace snark } // namespace zk } // namespace crypto3 diff --git a/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/placeholder_circuits.cpp b/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/placeholder_circuits.cpp index 0e0c02f817..d132738c13 100644 --- a/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/placeholder_circuits.cpp +++ b/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/placeholder_circuits.cpp @@ -139,5 +139,14 @@ BOOST_AUTO_TEST_SUITE(placeholder_circuits) BOOST_CHECK(test_runner.run_test()); } - + BOOST_AUTO_TEST_CASE(circuit8) + { + test_tools::random_test_initializer random_test_initializer; + auto circuit = circuit_test_8( + random_test_initializer.alg_random_engines.template get_alg_engine(), + random_test_initializer.generic_random_engine + ); + test_runner_type test_runner(circuit); + BOOST_CHECK(test_runner.run_test()); + } BOOST_AUTO_TEST_SUITE_END() diff --git a/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/placeholder_gate_argument.cpp b/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/placeholder_gate_argument.cpp index 6448147d94..b036a827ea 100644 --- a/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/placeholder_gate_argument.cpp +++ b/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/placeholder_gate_argument.cpp @@ -147,7 +147,10 @@ BOOST_AUTO_TEST_SUITE(placeholder_gate_argument) std::array, 1> prover_res = placeholder_gates_argument::prove_eval( constraint_system, polynomial_table, preprocessed_public_data.common_data.basic_domain, - preprocessed_public_data.common_data.max_gates_degree, mask_polynomial, prover_transcript); + preprocessed_public_data.common_data.max_gates_degree, + mask_polynomial, preprocessed_public_data.common_data.lagrange_0, + prover_transcript + ); // Challenge phase typename field_type::value_type y = algebra::random_element(); @@ -203,6 +206,17 @@ BOOST_AUTO_TEST_SUITE(placeholder_gate_argument) auto mask_value = field_type::value_type::one() - preprocessed_public_data.q_last.evaluate(y) - preprocessed_public_data.q_blind.evaluate(y); + + // All rows selector + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 0, plonk_variable::column_type::selector); + columns_at_y[key] = mask_value; + } + // All rows selector except the first row + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, 0, plonk_variable::column_type::selector); + columns_at_y[key] = mask_value - preprocessed_public_data.common_data.lagrange_0.evaluate(y); + } std::array verifier_res = placeholder_gates_argument::verify_eval( constraint_system.gates(), columns_at_y, y, mask_value, verifier_transcript); diff --git a/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/placeholder_lookup_argument.cpp b/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/placeholder_lookup_argument.cpp index 6a37bbe055..7f029351a1 100644 --- a/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/placeholder_lookup_argument.cpp +++ b/parallel-crypto3/libs/parallel-zk/test/systems/plonk/placeholder/placeholder_lookup_argument.cpp @@ -210,6 +210,25 @@ BOOST_AUTO_TEST_SUITE(placeholder_circuit3_lookup_test) special_selector_values_shifted[0] = preprocessed_public_data.q_last.evaluate(y * omega); special_selector_values_shifted[1] = preprocessed_public_data.q_blind.evaluate(y * omega); + // All rows selector + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 0, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y) -preprocessed_public_data.q_blind.evaluate(y) ; + } + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 1, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y * omega) -preprocessed_public_data.q_blind.evaluate(y * omega) ; + } + // All rows selector + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, 0, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y) -preprocessed_public_data.q_blind.evaluate(y) - preprocessed_public_data.common_data.lagrange_0.evaluate(y); + } + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, 1, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y * omega) -preprocessed_public_data.q_blind.evaluate(y * omega) - preprocessed_public_data.common_data.lagrange_0.evaluate(y * omega); + } + placeholder_lookup_argument_verifier lookup_verifier; std::array verifier_res = lookup_verifier.verify_eval( preprocessed_public_data.common_data, @@ -391,6 +410,25 @@ BOOST_AUTO_TEST_SUITE(placeholder_circuit4_lookup_test) special_selector_values_shifted[0] = preprocessed_public_data.q_last.evaluate(y * omega); special_selector_values_shifted[1] = preprocessed_public_data.q_blind.evaluate(y * omega); + // All rows selector + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 0, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y) -preprocessed_public_data.q_blind.evaluate(y) ; + } + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_USABLE_ROWS_SELECTED, 1, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y * omega) -preprocessed_public_data.q_blind.evaluate(y * omega) ; + } + // All rows selector + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, 0, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y) -preprocessed_public_data.q_blind.evaluate(y) - preprocessed_public_data.common_data.lagrange_0.evaluate(y); + } + { + auto key = std::make_tuple( PLONK_SPECIAL_SELECTOR_ALL_NON_FIRST_USABLE_ROWS_SELECTED, 1, plonk_variable::column_type::selector); + columns_at_y[key] = 1 - preprocessed_public_data.q_last.evaluate(y * omega) -preprocessed_public_data.q_blind.evaluate(y * omega) - preprocessed_public_data.common_data.lagrange_0.evaluate(y * omega); + } + placeholder_lookup_argument_verifier verifier; std::array verifier_res = verifier.verify_eval( preprocessed_public_data.common_data, diff --git a/zkevm-framework/libs/preset/include/zkevm_framework/preset/bytecode.hpp b/zkevm-framework/libs/preset/include/zkevm_framework/preset/bytecode.hpp index f1cf022b33..7a3a78c743 100644 --- a/zkevm-framework/libs/preset/include/zkevm_framework/preset/bytecode.hpp +++ b/zkevm-framework/libs/preset/include/zkevm_framework/preset/bytecode.hpp @@ -62,14 +62,6 @@ std::optional initialize_bytecode_circuit( nil::blueprint::components::generate_circuit(component_instance, bytecode_circuit, bytecode_table, input, 0); - std::size_t cur_selector_id = 0; - for (const auto& gate : bytecode_circuit.gates()) { - cur_selector_id = std::max(cur_selector_id, gate.selector_index); - } - for (const auto& lookup_gate : bytecode_circuit.lookup_gates()) { - cur_selector_id = std::max(cur_selector_id, lookup_gate.tag_index); - } - cur_selector_id++; nil::crypto3::zk::snark::pack_lookup_tables_horizontal( bytecode_circuit.get_reserved_indices(), bytecode_circuit.get_reserved_tables(), bytecode_circuit.get_reserved_dynamic_tables(), bytecode_circuit, bytecode_table, diff --git a/zkevm-framework/libs/preset/include/zkevm_framework/preset/sha256.hpp b/zkevm-framework/libs/preset/include/zkevm_framework/preset/sha256.hpp index b52a8e1e7d..43d540fa98 100644 --- a/zkevm-framework/libs/preset/include/zkevm_framework/preset/sha256.hpp +++ b/zkevm-framework/libs/preset/include/zkevm_framework/preset/sha256.hpp @@ -70,14 +70,6 @@ std::optional initialize_sha256_circuit( nil::blueprint::components::generate_circuit(component_instance, sha256_circuit, sha256_table, input, 0); - std::size_t cur_selector_id = 0; - for (const auto& gate : sha256_circuit.gates()) { - cur_selector_id = std::max(cur_selector_id, gate.selector_index); - } - for (const auto& lookup_gate : sha256_circuit.lookup_gates()) { - cur_selector_id = std::max(cur_selector_id, lookup_gate.tag_index); - } - cur_selector_id++; nil::crypto3::zk::snark::pack_lookup_tables_horizontal( sha256_circuit.get_reserved_indices(), sha256_circuit.get_reserved_tables(), sha256_circuit.get_reserved_dynamic_tables(), sha256_circuit, sha256_table,