Skip to content

Commit

Permalink
EXP opcode #180
Browse files Browse the repository at this point in the history
  • Loading branch information
ETatuzova committed Jan 8, 2025
1 parent 1fed3a7 commit b9c55b2
Show file tree
Hide file tree
Showing 16 changed files with 598 additions and 33 deletions.
1 change: 1 addition & 0 deletions crypto3.nix
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ in stdenv.mkDerivation {
cd crypto3
# remove || true after all tests are fixed under clang-sanitizers check:
ctest --verbose --output-on-failure -R > test_errors.txt || true
cat test_errors.txt
cd ..
mkdir -p ${placeholder "out"}/test-logs
find .. -type f -name '*_test.xml' -exec cp {} ${placeholder "out"}/test-logs \;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,10 +340,7 @@ namespace nil {
word_type a = stack_pop();
word_type input_b = stack_pop();
int shift = (input_b < 256) ? int(input_b) : 256;
// TODO(ioxid): FIXME: this should be right shift
word_type r = a << shift;
// word_type b = word_type(1) << shift;
stack.push(r);
stack.push(a >> shift);
pc++; gas -= 3;
break;
}
Expand All @@ -352,7 +349,7 @@ namespace nil {
word_type input_b = stack_pop();
word_type a = abs_word(input_a);
int shift = (input_b < 256) ? int(input_b) : 256;
word_type r = a << shift;
word_type r = a >> shift;
word_type result =
is_negative(input_a) ? ((r == 0) ? neg_one : negate_word(r)) : r;
stack.push(result);
Expand Down
421 changes: 421 additions & 0 deletions crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/exp.hpp

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ namespace nil {
zkevm_word_type b = stack.back();
stack.pop_back();
_rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, false, b));
zkevm_word_type result = (a * b);
zkevm_word_type result = wrapping_mul(a, b);
_rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result));
stack.push_back(result);
pc++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ namespace nil {
std::vector<TYPE> d_log(8);
std::vector<TYPE> d_inv(8);
TYPE d_sum;
TYPE r_sum;
TYPE d_sum_inv;
TYPE d_sum_inv_1;
TYPE s;
Expand Down Expand Up @@ -86,6 +87,7 @@ namespace nil {
allocate(A[i], i, 0);
allocate(D[i], i + 16, 0);
allocate(R[i], i, 1);
r_sum += R[i];
}
allocate(d_sum, 32, 0);
allocate(d_sum_inv, 33, 0);
Expand All @@ -102,6 +104,15 @@ namespace nil {
constrain(d_sum * (d_sum_inv * d_sum - 1));
constrain(d_sum_inv * (d_sum_inv * d_sum - 1));
constrain(d_sum_inv_1 * (d_sum_inv_1 * (d_sum - 1) - 1));
constrain((s - 1) * (d_sum - 1) * d_sum); // s == 0 => (d == 0 & d == 1)
// s == 0 && d == 1 => R == A
for( std::size_t i = 0; i < 16; i++){
constrain( (s - 1) * d_sum * (R[i] - A[i]));
}

// (s == 0 && d == 0) => R == 1
constrain((s - 1) * (d_sum - 1) * (R[15] - 1));
constrain((s - 1) * (d_sum - 1) * (r_sum - R[15]));

auto A_128 = chunks16_to_chunks128<TYPE>(A);
auto D_128 = chunks16_to_chunks128<TYPE>(D);
Expand All @@ -110,6 +121,7 @@ namespace nil {
constrain( (1 - (d_sum - 1) * d_sum_inv_1) * (A_128.second - R_128.second) );
constrain( (1 - (d_sum - 1) * d_sum_inv_1) * s );


if constexpr( stage == GenerationStage::CONSTRAINTS ){
constrain(current_state.pc_next() - current_state.pc(1) - 1); // PC transition
// constrain(current_state.gas(1) - current_state.gas_next() - 5); // GAS transition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ namespace nil {
if constexpr( stage == GenerationStage::ASSIGNMENT ){
auto a = w_to_16(current_state.stack_top());
auto b = w_to_16(current_state.stack_top(1));
auto r = w_to_16(current_state.stack_top() * current_state.stack_top(1));
auto r = w_to_16(wrapping_mul(current_state.stack_top(), current_state.stack_top(1)));
std::cout << "\ta = " << std::hex << current_state.stack_top() << std::dec << std::endl;
std::cout << "\tb = " << std::hex << current_state.stack_top(1) << std::dec << std::endl;
std::cout << "\tr = " << std::hex << current_state.stack_top() * current_state.stack_top(1) << std::dec << std::endl;
std::cout << "\tr = " << std::hex << wrapping_mul(current_state.stack_top(), current_state.stack_top(1)) << std::dec << std::endl;
for( std::size_t i = 0; i < 16; i++){
A[i] = a[i];
B[i] = b[i];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ namespace nil {
// field_tag is 0
// value is boolean
// initial_value is 0
// state_root eqauls state_root_prev
// state_root equals state_root_prev
// value column at previous rotation equals value_prev at current rotation
special_constraints[TX_ACCESS_LIST_ACCOUNT_STORAGE_OP].push_back(context_object.relativize(tx_access_list_account_selector * field_type[1], -1));
special_constraints[TX_ACCESS_LIST_ACCOUNT_STORAGE_OP].push_back(context_object.relativize(tx_access_list_account_selector * value_hi[1], -1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ namespace nil {
exponentiation_lo(max_exponentiations)
{
if constexpr (stage == GenerationStage::ASSIGNMENT) {
BOOST_ASSERT(input.size() <= max_exponentiations);
BOOST_ASSERT(input.size() < max_exponentiations);

std::size_t i = 0;
std::cout << "Exp table:" << std::endl;
Expand All @@ -91,22 +91,15 @@ namespace nil {
zkevm_word_type base = input[i].first;
zkevm_word_type exponent = input[i].second;
zkevm_word_type exponentiation = exp_by_squaring(base, exponent);
// We don't prove zero and one exponent by lookup table
if( exponent == 0 || exponent == 1 ) continue;
std::cout <<"\t" << base << " ^ " << exponent << " = " << exponentiation << std::endl;

selector[i] = 1;
base_hi[i] = w_hi<FieldType>(base); base_lo[i] = w_lo<FieldType>(base);
exponent_hi[i] = w_hi<FieldType>(exponent); exponent_lo[i] = w_lo<FieldType>(exponent);
exponentiation_hi[i] = w_hi<FieldType>(exponentiation); exponentiation_lo[i] = w_lo<FieldType>(exponentiation);
}

// if there are unused rows, fill in with valid exp triplets (0^1 = 0)
// while (i < max_exponentiations) {
// selector[i] = 0;
// base_hi[i] = 0; base_lo[i] = 0;
// exponent_hi[i] = 0; exponent_lo[i] = 0;
// exponentiation_hi[i] = 0; exponentiation_lo[i] = 0;
// i++;
// }
}

for (std::size_t i = 0; i < max_exponentiations; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ namespace nil {
std::size_t max_zkevm_rows,
std::size_t max_copy,
std::size_t max_rw,
std::size_t max_keccak_blocks,
std::size_t max_exponentations,
std::size_t max_bytecode
){
std::size_t implemented_opcodes_amount = get_implemented_opcodes_list().size();
Expand All @@ -89,7 +89,7 @@ namespace nil {
witness_amount += CopyTable::get_witness_amount();
witness_amount += 10;
nil::crypto3::zk::snark::plonk_table_description<FieldType> desc(witness_amount, 1, 5, 20);
desc.usable_rows_amount = std::max(max_zkevm_rows, std::max(std::max(max_copy, max_rw), std::max(max_keccak_blocks, max_bytecode)) + 1);
desc.usable_rows_amount = std::max(max_zkevm_rows, std::max(std::max(max_copy, max_rw), std::max(max_exponentations, max_bytecode)) + 1);
return desc;
}

Expand All @@ -99,7 +99,7 @@ namespace nil {
std::size_t max_zkevm_rows,
std::size_t max_copy,
std::size_t max_rw,
std::size_t max_keccak_blocks,
std::size_t max_exponentations,
std::size_t max_bytecode,
std::size_t max_exponentiations = 50 // TODO:remove it later
) :generic_component<FieldType,stage>(context_object), implemented_opcodes(get_implemented_opcodes_list()) {
Expand Down Expand Up @@ -527,7 +527,7 @@ namespace nil {
tmp[3] = context_object.relativize(evm_opcode_constraint, -1);
tmp[4] = context_object.relativize(evm_opcode_constraint * all_states[1].bytecode_hash_hi, -1);
tmp[5] = context_object.relativize(evm_opcode_constraint * all_states[1].bytecode_hash_lo, -1);

// TODO(oclaw): bytecode check is disabled since hash algorithm for circuits is not finalized yet
// https://github.com/NilFoundation/placeholder/issues/205
// context_object.relative_lookup(tmp, "zkevm_bytecode", 1, max_zkevm_rows-1);
Expand Down
1 change: 1 addition & 0 deletions crypto3/libs/blueprint/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ set(ZKEVM_BBF_TESTS_FILES
"zkevm_bbf/rw"
"zkevm_bbf/bytecode"
"zkevm_bbf/copy"
"zkevm_bbf/exp"
"zkevm_bbf/opcodes/pushx"
"zkevm_bbf/opcodes/iszero"
"zkevm_bbf/opcodes/mod_ops"
Expand Down
87 changes: 87 additions & 0 deletions crypto3/libs/blueprint/test/zkevm_bbf/exp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2024 Elena Tatuzova <[email protected]>
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//---------------------------------------------------------------------------//

#define BOOST_TEST_MODULE blueprint_plonk_exp_test

#include <boost/test/unit_test.hpp>

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

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

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

#include <nil/blueprint/blueprint/plonk/circuit.hpp>
#include <nil/blueprint/blueprint/plonk/assignment.hpp>
#include <nil/blueprint/bbf/l1_wrapper.hpp>
#include <nil/blueprint/zkevm_bbf/exp.hpp>

#include "./test_l1_wrapper.hpp"

using namespace nil::crypto3;
using namespace nil::blueprint;

class zkEVMExpTestFixture: public BBFTestFixture {
public:
zkEVMExpTestFixture():BBFTestFixture(){}

template <typename field_type>
void test_zkevm_exp(
const std::vector<std::pair<zkevm_word_type, zkevm_word_type>> &exps,
std::size_t max_exponentiations,
std::size_t max_exp_rows,
bool expected_result = true
){
typename nil::blueprint::bbf::exponentiation<field_type,nil::blueprint::bbf::GenerationStage::ASSIGNMENT>::input_type exp_assignment_input = exps;
typename nil::blueprint::bbf::exponentiation<field_type,nil::blueprint::bbf::GenerationStage::CONSTRAINTS>::input_type exp_constraint_input;

bool result = test_bbf_component<field_type, nil::blueprint::bbf::exponentiation>(
"exp",
{} , // Public input
exp_assignment_input, // Assignment input
exp_constraint_input, // Circuit input
max_exp_rows, // Maximum size of exp circuit
max_exponentiations // Maximum rows in exponentiation dynamic lookup table
);
BOOST_CHECK((!check_satisfiability && !generate_proof) || result == expected_result); // Max_rw, Max_mpt
}
};

BOOST_FIXTURE_TEST_SUITE(zkevm_bbf_exp, zkEVMExpTestFixture)
using field_type = nil::crypto3::algebra::curves::alt_bn128_254::scalar_field_type;
BOOST_AUTO_TEST_CASE(one_exponent){
std::vector<std::pair<zkevm_word_type, zkevm_word_type>> exp_input;
exp_input.push_back({2, 2});
exp_input.push_back({3, 3});
test_zkevm_exp<field_type>(exp_input, 50, 3000);
}
BOOST_AUTO_TEST_SUITE_END()
30 changes: 28 additions & 2 deletions crypto3/libs/blueprint/test/zkevm_bbf/hardhat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@

#include <nil/blueprint/blueprint/plonk/circuit.hpp>
#include <nil/blueprint/blueprint/plonk/assignment.hpp>
#include <nil/blueprint/bbf/l1_wrapper.hpp>

#include <nil/blueprint/zkevm_bbf/zkevm.hpp>
#include <nil/blueprint/zkevm_bbf/rw.hpp>
#include <nil/blueprint/zkevm_bbf/copy.hpp>
#include <nil/blueprint/zkevm_bbf/bytecode.hpp>
#include <nil/blueprint/zkevm_bbf/keccak.hpp>
#include <nil/blueprint/zkevm_bbf/exp.hpp>

#include "./test_l1_wrapper.hpp"

Expand Down Expand Up @@ -85,6 +86,8 @@ class zkEVMHardhatTestFixture: public BBFTestFixture {
std::size_t max_rw = max_sizes.max_rw;
std::size_t max_copy = max_sizes.max_copy;
std::size_t max_zkevm_rows = max_sizes.max_zkevm_rows;
std::size_t max_exponentiations = max_sizes.max_exponentiations;
std::size_t max_exp_rows = max_sizes.max_exp_rows;

typename nil::blueprint::bbf::copy<field_type,nil::blueprint::bbf::GenerationStage::ASSIGNMENT>::input_type copy_assignment_input;
typename nil::blueprint::bbf::copy<field_type,nil::blueprint::bbf::GenerationStage::CONSTRAINTS>::input_type copy_constraint_input;
Expand Down Expand Up @@ -118,17 +121,31 @@ class zkEVMHardhatTestFixture: public BBFTestFixture {
bytecode_assignment_input.keccak_buffers = circuit_inputs.keccaks();
bool result;

typename nil::blueprint::bbf::exponentiation<field_type,nil::blueprint::bbf::GenerationStage::ASSIGNMENT>::input_type exp_assignment_input;
typename nil::blueprint::bbf::exponentiation<field_type,nil::blueprint::bbf::GenerationStage::CONSTRAINTS>::input_type exp_constraint_input;
exp_assignment_input = circuit_inputs.exponentiations();

// Max_rows, max_bytecode, max_rw
result = test_bbf_component<field_type, nil::blueprint::bbf::zkevm>(
"zkevm",
{}, zkevm_assignment_input, zkevm_constraint_input,
max_zkevm_rows,
max_copy,
max_rw,
max_keccak_blocks,
max_exponentiations,
max_bytecode
);
BOOST_ASSERT(result);
// std::cout << std::endl;

// Max_copy, Max_rw, Max_keccak, Max_bytecode
result =test_bbf_component<field_type, nil::blueprint::bbf::exponentiation>(
"exp",
{}, exp_assignment_input, exp_constraint_input,
max_exp_rows,
max_exponentiations
);
BOOST_ASSERT(result);
std::cout << std::endl;

// Max_copy, Max_rw, Max_keccak, Max_bytecode
Expand Down Expand Up @@ -184,6 +201,7 @@ BOOST_AUTO_TEST_CASE(minimal_math) {
max_sizes.max_copy = 500;
max_sizes.max_zkevm_rows = 500;
max_sizes.max_exponentiations = 50;
max_sizes.max_exp_rows = 500;

complex_test<field_type>(bytecodes, pts, max_sizes);
}
Expand All @@ -200,6 +218,7 @@ BOOST_AUTO_TEST_CASE(modular_operations) {
max_sizes.max_copy = 500;
max_sizes.max_zkevm_rows = 500;
max_sizes.max_exponentiations = 50;
max_sizes.max_exp_rows = 500;

complex_test<field_type>(bytecodes, pts, max_sizes);
}
Expand All @@ -215,6 +234,7 @@ BOOST_AUTO_TEST_CASE(exp) {
max_sizes.max_rw = 1000;
max_sizes.max_copy = 500;
max_sizes.max_zkevm_rows = 2000;
max_sizes.max_exp_rows = 500;
max_sizes.max_exponentiations = 50;

complex_test<field_type>(bytecodes, pts, max_sizes);
Expand All @@ -232,6 +252,7 @@ BOOST_AUTO_TEST_CASE(keccak) {
max_sizes.max_copy = 500;
max_sizes.max_zkevm_rows = 500;
max_sizes.max_exponentiations = 50;
max_sizes.max_exp_rows = 500;

complex_test<field_type>(bytecodes, pts, max_sizes);
}
Expand All @@ -248,6 +269,7 @@ BOOST_AUTO_TEST_CASE(mstore8) {
max_sizes.max_copy = 3000;
max_sizes.max_zkevm_rows = 4500;
max_sizes.max_exponentiations = 50;
max_sizes.max_exp_rows = 500;

complex_test<field_type>(bytecodes, pts, max_sizes);
}
Expand All @@ -264,6 +286,7 @@ BOOST_AUTO_TEST_CASE(meminit) {
max_sizes.max_copy = 3000;
max_sizes.max_zkevm_rows = 10000;
max_sizes.max_exponentiations = 50;
max_sizes.max_exp_rows = 500;

complex_test<field_type>(bytecodes, pts, max_sizes);
}
Expand All @@ -280,7 +303,10 @@ BOOST_AUTO_TEST_CASE(calldatacopy) {
max_sizes.max_copy = 3000;
max_sizes.max_zkevm_rows = 4500;
max_sizes.max_exponentiations = 50;
max_sizes.max_exp_rows = 500;

complex_test<field_type>(bytecodes, pts, max_sizes);
}


BOOST_AUTO_TEST_SUITE_END()
Loading

0 comments on commit b9c55b2

Please sign in to comment.