From 0f70482cbfaa48ceac7f26a516f117eb09b6bd35 Mon Sep 17 00:00:00 2001 From: Vasiliy Olekhov <145333445+vo-nil@users.noreply.github.com> Date: Wed, 8 Nov 2023 12:23:58 +0300 Subject: [PATCH] 46 check values in etha point (#48) * contract returs status #45 * EVM verifier interface update #45 NilFoundation/evm-placeholder-verification#81 * remove utils.sol if no helper functions generated #45 NilFoundation/evm-placeholder-verification#81 * Added check values for eta points #46 --- .../blueprint/transpiler/evm_verifier_gen.hpp | 93 ++++++++++++++++--- .../templates/commitment_scheme.hpp | 5 +- .../transpiler/templates/external_gate.hpp | 2 +- .../transpiler/templates/modular_verifier.hpp | 10 +- 4 files changed, 92 insertions(+), 18 deletions(-) diff --git a/include/nil/blueprint/transpiler/evm_verifier_gen.hpp b/include/nil/blueprint/transpiler/evm_verifier_gen.hpp index b9011d5..f8f01c8 100644 --- a/include/nil/blueprint/transpiler/evm_verifier_gen.hpp +++ b/include/nil/blueprint/transpiler/evm_verifier_gen.hpp @@ -318,6 +318,7 @@ namespace nil { } _permutation_offset = _variable_values_offset; + _public_input_offset = _variable_values_offset; for( std::size_t i = 0; i < PlaceholderParams::arithmetization_params::witness_columns + PlaceholderParams::arithmetization_params::public_input_columns; i++){ if(i == PlaceholderParams::arithmetization_params::witness_columns){ _public_input_offset = _permutation_offset; @@ -602,6 +603,8 @@ namespace nil { boost::replace_all(result, "$GATE_LIB_ID$", to_string(gate_modules_count)); boost::replace_all(result, "$CONSTRAINT_SERIES_CODE$", code); boost::replace_all(result, "$MODULUS$", to_string(PlaceholderParams::field_type::modulus)); + boost::replace_all(result, "$UTILS_LIBRARY_IMPORT$", _term_powers.size() >0? "import \"./utils.sol\";" : ""); + std::ofstream out; out.open(_folder_name + "/gate_" + to_string(gate_modules_count) + ".sol"); @@ -613,19 +616,21 @@ namespace nil { } } - std::stringstream power_functions; - for(std::size_t power: _term_powers) { - power_functions << generate_power_function(power); - } + if (_term_powers.size() > 0) { + std::stringstream power_functions; + for(std::size_t power: _term_powers) { + power_functions << generate_power_function(power); + } - std::string utils_library(utils_library_template); - boost::replace_all(utils_library, "$MODULUS$", to_string(PlaceholderParams::field_type::modulus)); - boost::replace_all(utils_library, "$POWER_FUNCTIONS$", power_functions.str()); - boost::replace_all(utils_library, "$TEST_NAME$", _test_name); - std::ofstream utils; - utils.open(_folder_name + "/utils.sol"); - utils << utils_library; - utils.close(); + std::string utils_library(utils_library_template); + boost::replace_all(utils_library, "$MODULUS$", to_string(PlaceholderParams::field_type::modulus)); + boost::replace_all(utils_library, "$POWER_FUNCTIONS$", power_functions.str()); + boost::replace_all(utils_library, "$TEST_NAME$", _test_name); + std::ofstream utils; + utils.open(_folder_name + "/utils.sol"); + utils << utils_library; + utils.close(); + } for ( i = 0; i < gate_modules_count; ++i ) { std::string gate_eval_string = gate_call_template; @@ -775,6 +780,69 @@ namespace nil { return lookup_str.str(); } + std::string eta_point_verification_code() { + std::stringstream result; + auto fixed_poly_values = _common_data.commitment_scheme_data; + + std::size_t poly_points = 2; + + if (fixed_poly_values.size() == 0) + return ""; + + result << "\t\t{" << std::endl; + result << "\t\t\tuint256 poly_at_eta;" << std::endl; + + result << "\t\t\t/* 1 - 2*permutation_size */" << std::endl; + std::size_t i = 0, j = 0; + std::size_t point_offset = 8; + + while (j < 2*_permutation_size) { + result << "\t\t\tpoly_at_eta = basic_marshalling.get_uint256_be(blob, " << point_offset+(poly_points-1)*32 << ");" << "// " << i << std::endl; + result << "\t\t\tif(poly_at_eta != " << std::showbase<< std::hex << fixed_poly_values[0][i] << ") return false;" << std::endl; + point_offset += 32*poly_points; + ++i; + ++j; + } + + result << "\t\t\t/* 2 - special selectors */" << std::endl; + poly_points = 3; + j = 0; + while (j < 2) { + result << "\t\t\tpoly_at_eta = basic_marshalling.get_uint256_be(blob, " << point_offset+(poly_points-1)*32 << ");" << "// " << i << std::endl; + result << "\t\t\tif(poly_at_eta != " << std::showbase<< std::hex << fixed_poly_values[0][i] << ") return false;" << std::endl; + point_offset += 32*poly_points; + ++i; + ++j; + } + + std::size_t column_rotation_offset = PlaceholderParams::witness_columns + PlaceholderParams::public_input_columns; + result << "\t\t\t/* 3 - constant columns */" << std::endl; + j = 0; + while (j < PlaceholderParams::arithmetization_params::constant_columns) { + poly_points = _common_data.columns_rotations[column_rotation_offset + j].size()+1; + result << "\t\t\tpoly_at_eta = basic_marshalling.get_uint256_be(blob, " << point_offset+(poly_points-1)*32 << ");" << "// " << i << std::endl; + result << "\t\t\tif(poly_at_eta != " << std::showbase<< std::hex << fixed_poly_values[0][i] << ") return false;" << std::endl; + point_offset += 32*poly_points; + ++i; + ++j; + } + + result << "\t\t\t/* 4 - selector columns */" << std::endl; + column_rotation_offset = PlaceholderParams::witness_columns + PlaceholderParams::public_input_columns + PlaceholderParams::constant_columns; + j = 0; + while (j < PlaceholderParams::arithmetization_params::selector_columns) { + poly_points = _common_data.columns_rotations[column_rotation_offset + j].size()+1; + result << "\t\t\tpoly_at_eta = basic_marshalling.get_uint256_be(blob, " << point_offset+(poly_points-1)*32 << ");" << "// " << i << std::endl; + result << "\t\t\tif(poly_at_eta != " << std::showbase<< std::hex << fixed_poly_values[0][i] << ") return false;" << std::endl; + point_offset += 32*(poly_points); + ++i; + ++j; + } + + result << "\t\t}" << std::endl; + return result.str(); + } + void print(){ std::filesystem::create_directory(_folder_name); std::cout << "Generating verifier " << _test_name << std::endl; @@ -811,6 +879,7 @@ namespace nil { reps["$LOOKUP_INCLUDES$"] = _lookup_includes; reps["$LOOKUP_ARGUMENT_COMPUTATION$"] = lookup_argument; reps["$COMMITMENT_CODE$"] = commitment_code; + reps["$ETA_VALUES_VERIFICATION$"] = eta_point_verification_code(); commitment_scheme_replaces(reps, _common_data, _lpc_scheme, _permutation_size, _use_lookups); diff --git a/include/nil/blueprint/transpiler/templates/commitment_scheme.hpp b/include/nil/blueprint/transpiler/templates/commitment_scheme.hpp index 5d8fd54..4901886 100644 --- a/include/nil/blueprint/transpiler/templates/commitment_scheme.hpp +++ b/include/nil/blueprint/transpiler/templates/commitment_scheme.hpp @@ -422,6 +422,9 @@ library modular_commitment_scheme_$TEST_NAME$ { types.transcript_data memory tr_state; tr_state.current_challenge = transcript_state; commitment_state memory state; + + $ETA_VALUES_VERIFICATION$ + { uint256 offset; @@ -591,4 +594,4 @@ library modular_commitment_scheme_$TEST_NAME$ { } } -#endif //__MODULAR_CONTRACT_TEMPLATE_HPP__ \ No newline at end of file +#endif //__MODULAR_CONTRACT_TEMPLATE_HPP__ diff --git a/include/nil/blueprint/transpiler/templates/external_gate.hpp b/include/nil/blueprint/transpiler/templates/external_gate.hpp index 3bb3ed0..356dca8 100644 --- a/include/nil/blueprint/transpiler/templates/external_gate.hpp +++ b/include/nil/blueprint/transpiler/templates/external_gate.hpp @@ -41,7 +41,7 @@ namespace nil { pragma solidity >=0.8.4; import "../../../contracts/basic_marshalling.sol"; -import "./utils.sol"; +$UTILS_LIBRARY_IMPORT$ library gate_$TEST_NAME$_$GATE_LIB_ID${ uint256 constant modulus = $MODULUS$; diff --git a/include/nil/blueprint/transpiler/templates/modular_verifier.hpp b/include/nil/blueprint/transpiler/templates/modular_verifier.hpp index ef16102..089b685 100644 --- a/include/nil/blueprint/transpiler/templates/modular_verifier.hpp +++ b/include/nil/blueprint/transpiler/templates/modular_verifier.hpp @@ -9,12 +9,12 @@ namespace nil { { uint256 lookup_offset = table_offset + quotient_offset + uint256(uint8(blob[z_offset + basic_marshalling.get_length(blob, z_offset - 0x8) *0x20 + 0xf])) * 0x20; uint256[4] memory lookup_argument; + uint256 lookup_commitment = basic_marshalling.get_uint256_be(blob, 0x81); ILookupArgument lookup_contract = ILookupArgument(_lookup_argument_address); (lookup_argument, tr_state.current_challenge) = lookup_contract.verify( -// (lookup_argument, tr_state.current_challenge) = modular_lookup_argument_$TEST_NAME$.verify( blob[special_selectors_offset: table_offset + quotient_offset], blob[lookup_offset:lookup_offset + sorted_columns * 0x60], - basic_marshalling.get_uint256_be(blob, 0x81), + lookup_commitment, state.l0, tr_state.current_challenge ); @@ -151,7 +151,7 @@ contract modular_verifier_$TEST_NAME$ is IModularVerifier{ function verify( bytes calldata blob, uint256[] calldata public_input - ) public view{ + ) public view returns (bool result) { verifier_state memory state; state.b = true; state.gas = gasleft(); @@ -191,6 +191,7 @@ contract modular_verifier_$TEST_NAME$ is IModularVerifier{ state.F[2] = permutation_argument[2]; } + //4. Lookup library call $LOOKUP_LIBRARY_CALL$ //5. Push permutation batch to transcript @@ -266,10 +267,11 @@ contract modular_verifier_$TEST_NAME$ is IModularVerifier{ } console.log("Gas for verification:", state.gas-gasleft()); + result = state.b; } } )"; } } -#endif //__MODULAR_CONTRACT_TEMPLATE_HPP__ \ No newline at end of file +#endif //__MODULAR_CONTRACT_TEMPLATE_HPP__