diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml new file mode 100644 index 0000000000..48de973659 --- /dev/null +++ b/.github/workflows/run_tests.yml @@ -0,0 +1,104 @@ +name: Run tests + +on: + # Triggers the workflow on pull request events but only for the master branch + pull_request: + branches: [ master ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +env: + SUITE_REPO: "NilFoundation/crypto3" + LIB_NAME: "blueprint" + CACHE_NAME: "checkout-job-cache" + +jobs: + checkout: + runs-on: [self-hosted, tests-runner] + steps: + - name: Cleanup # TODO - move to scripts on runner + run: | + rm -rf ./* || true + rm -rf ./.??* || true + + - name: Checkout suite + uses: actions/checkout@v3 + with: + repository: ${{ env.SUITE_REPO }} + submodules: recursive + + - name: Checkout source code + uses: actions/checkout@v3 + with: + path: ./libs/${{ env.LIB_NAME }} + submodules: recursive + + - name: Cmake and build + env: + CMAKE_ARGS: " + -DCMAKE_BUILD_TYPE=Debug + -DBUILD_SHARED_LIBS=FALSE + -DBUILD_TESTS=TRUE + " + run: | + mkdir build + cd build + cmake ${{ env.CMAKE_ARGS }} .. + + - name: Archive build results + run: | + touch ${{ env.CACHE_NAME }}.tar.gz + tar -czf ${{ env.CACHE_NAME }}.tar.gz --exclude=${{ env.CACHE_NAME }}.tar.gz . + + - name: Cache archived job output + uses: actions/upload-artifact@v3 + with: + name: ${{ env.CACHE_NAME }} + path: ${{ env.CACHE_NAME }}.tar.gz + retention-days: 1 + + + run_tests: + runs-on: [self-hosted] + needs: [checkout] + strategy: + fail-fast: false + matrix: + target: [ + blueprint_hashes_plonk_sha256_process_test, + blueprint_hashes_plonk_sha512_process_test, + blueprint_non_native_plonk_non_native_demo_test, + blueprint_non_native_plonk_non_native_range_test, + blueprint_non_native_plonk_fixed_base_mul_test, + blueprint_non_native_plonk_complete_addition_test, + blueprint_non_native_plonk_var_base_mul_per_bit_test, + blueprint_non_native_plonk_variable_base_multiplication_test, + ] # Tests to execute + steps: + - name: Cleanup # TODO - move to scripts on runner + run: | + rm -rf ./* || true + rm -rf ./.??* || true + + - name: Upload checkout job cache + uses: actions/download-artifact@v3 + with: + name: ${{ env.CACHE_NAME }} + + - name: Extract artifacts + run: | + tar -xf ${{ env.CACHE_NAME }}.tar.gz + rm ${{ env.CACHE_NAME }}.tar.gz + + - name: Build + working-directory: ./build + run: cmake --build . -t ${{ matrix.target }} + + - name: Run test + working-directory: ./build + run: | + cd libs/${{ env.LIB_NAME }}/test + COLOR='\033[0;33m' + echo -e "${COLOR}${{ matrix.target }}" + ./${{ matrix.target }} diff --git a/.github/workflows/set_version.yml b/.github/workflows/set_version.yml new file mode 100644 index 0000000000..0a969d606c --- /dev/null +++ b/.github/workflows/set_version.yml @@ -0,0 +1,30 @@ +name: Set version + +on: + # Triggers the workflow on push to master branch + push: + branches: [ master ] + +jobs: + set_version: + name: Set and tag version + runs-on: [ubuntu-latest] + env: + VERSION_FILE_NAME: VERSION + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set version + id: set_version + run: | + version=$(cat ${{ env.VERSION_FILE_NAME }} | tr -d '\r').$GITHUB_RUN_NUMBER + echo "VERSION=$version" >> $GITHUB_ENV + + - name: Tag new version + run: git tag v${{ env.VERSION }} + + - name: Push tags + uses: ad-m/github-push-action@master + with: + tags: true diff --git a/README.md b/README.md index 12313c7534..e498a3dde7 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Circuit definition library for =nil; Foundation's cryptography suite. +[![Run tests](https://github.com/NilFoundation/crypto3-blueprint/actions/workflows/run_tests.yml/badge.svg)](https://github.com/NilFoundation/crypto3-blueprint/actions/workflows/run_tests.yml) + ## Building This library uses Boost CMake build modules (https://github.com/BoostCMake/cmake_modules.git). diff --git a/VERSION b/VERSION new file mode 100644 index 0000000000..403a970e31 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.0 diff --git a/cmake/TargetArchitecture.cmake b/cmake/TargetArchitecture.cmake index afaaa7274f..1ce39aa812 100644 --- a/cmake/TargetArchitecture.cmake +++ b/cmake/TargetArchitecture.cmake @@ -101,6 +101,8 @@ function(target_architecture OUTPUT_ARCHITECTURE) set(osx_arch_i386 TRUE) elseif("${osx_arch}" STREQUAL "x86_64") set(osx_arch_x86_64 TRUE) + elseif("${osx_arch}" STREQUAL "arm64") + set(osx_arch_arm64 TRUE) elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support) set(osx_arch_ppc64 TRUE) else() @@ -124,6 +126,10 @@ function(target_architecture OUTPUT_ARCHITECTURE) if(osx_arch_ppc64) list(APPEND ARCH ppc64) endif() + + if(osx_arch_arm64) + list(APPEND ARCH arm64) + endif() else() file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}") diff --git a/include/nil/crypto3/zk/components/hashes/sha256/plonk/sha512.hpp b/include/nil/crypto3/zk/components/hashes/sha256/plonk/sha512.hpp index 9487d0fd1b..1e37dea3ad 100644 --- a/include/nil/crypto3/zk/components/hashes/sha256/plonk/sha512.hpp +++ b/include/nil/crypto3/zk/components/hashes/sha256/plonk/sha512.hpp @@ -33,7 +33,7 @@ #include #include #include -#include +//#include namespace nil { namespace crypto3 { @@ -54,90 +54,164 @@ namespace nil { using var = snark::plonk_variable; - using sha512_process_component = - sha512_process; - using decomposition_component = - decomposition; + using sha512_process_component = + sha512_process; + // using decomposition_component = + // decomposition; - public: + public: +// constexpr static const std::size_t rows_RAM_and_input_words = 16; +// constexpr static const std::size_t rows_amount = - sha512_process_component::rows_amount * 2 + decomposition_component::rows_amount * 2 + 1; + 2 + 3 + sha512_process_component::rows_amount * 2 + 2; - struct params_type { - std::array block_data; + struct var_ec_point { + std::array x; + std::array y; }; - struct allocated_data_type { - allocated_data_type() { - previously_allocated = false; - } - - // TODO access modifiers - bool previously_allocated; + struct params_type { + var_ec_point R; + var_ec_point A; + std::array M; }; struct result_type { - std::array output = {var(0, 0, false), var(0, 0, false)}; + std::array output_state; - result_type(std::size_t component_start_row) { - std::array output = {var(W0, component_start_row + rows_amount - 1, false), - var(W1, component_start_row + rows_amount - 1, false)}; + result_type(const std::size_t &start_row_index) { + output_state = {var(W0, start_row_index + rows_amount - 3, false), + var(W1, start_row_index + rows_amount - 3, false), + var(W2, start_row_index + rows_amount - 3, false), + var(W3, start_row_index + rows_amount - 3, false), + var(W0, start_row_index + rows_amount - 1, false), + var(W1, start_row_index + rows_amount - 1, false), + var(W2, start_row_index + rows_amount - 1, false), + var(W3, start_row_index + rows_amount - 1, false)}; } }; - - static std::size_t allocate_rows(blueprint &bp) { - return bp.allocate_rows(rows_amount); - } - static result_type generate_circuit(blueprint &bp, - blueprint_assignment_table &assignment, - const params_type ¶ms, - allocated_data_type &allocated_data, - std::size_t component_start_row) { + blueprint_public_assignment_table &assignment, + const params_type & params, + const std::size_t start_row_index) { + + generate_gates(bp, assignment, start_row_index); + generate_copy_constraints(bp, assignment, params, start_row_index); + return result_type(start_row_index); - generate_gates(bp, assignment, params, allocated_data, component_start_row); - generate_copy_constraints(bp, assignment, params, component_start_row); - return result_type(component_start_row); } static result_type generate_assignments(blueprint_assignment_table &assignment, const params_type ¶ms, std::size_t component_start_row) { std::size_t row = component_start_row; - std::array input_params_1 = {params.block_data[0], params.block_data[1]}; - typename decomposition_component::params_type decomposition_params = {input_params_1}; - auto sha_block_part_1 = - decomposition_component::generate_assignments(assignment, decomposition_params, row); - row += decomposition_component::rows_amount; - std::array input_params_2 = {params.block_data[2], params.block_data[3]}; - decomposition_params = {input_params_2}; - auto sha_block_part_2 = - decomposition_component::generate_assignments(assignment, decomposition_params, row); - row += decomposition_component::rows_amount; - std::vector input_words(16); - for (int i = 0; i < 8; i++) { - input_words[i] = sha_block_part_1.output_state[i]; - input_words[8 + i] = sha_block_part_2.output_state[i]; + + std::array RAM = { + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.R.x[0]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.R.x[1]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.R.x[2]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.R.x[3]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.R.y[0]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.R.y[1]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.R.y[2]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.R.y[3]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.A.x[0]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.A.x[1]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.A.x[2]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.A.x[3]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.A.y[0]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.A.y[1]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.A.y[2]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.A.y[3]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.M[0]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.M[1]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.M[2]).data), + typename ArithmetizationType::field_type::integral_type(assignment.var_value(params.M[3]).data) + }; + + for (std::size_t i = 0; i < 4; i++) { + assignment.witness(i)[row] = RAM[i]; + assignment.witness(i+4)[row] = RAM[i+4]; + assignment.witness(i)[row+1] = RAM[i+8]; + assignment.witness(i+4)[row+1] = RAM[i+12]; + assignment.witness(i)[row+2] = RAM[i+16]; + } + + std::array input_words_values; + typename ArithmetizationType::field_type::integral_type integral_one = 1; + typename ArithmetizationType::field_type::integral_type mask = ((integral_one<<64) - 1); + input_words_values[0] = (RAM[0]) & mask; + input_words_values[1] = ((RAM[0] >> 64) + (RAM[1] << 2)) & mask; + input_words_values[2] = ((RAM[1] >> 62) + (RAM[2] << 4)) & mask; + input_words_values[3] = ((RAM[2] >> 60) + (RAM[3] << 6) + (RAM[4] << 63)) & mask; + input_words_values[4] = ((RAM[4] >> 1)) & mask; + input_words_values[5] = ((RAM[4] >> 65) + (RAM[5] << 1)) & mask; + input_words_values[6] = ((RAM[5] >> 63) + (RAM[6] << 3)) & mask; + input_words_values[7] = ((RAM[6] >> 61) + (RAM[7] << 5) + (RAM[8] << 62)) & mask; + input_words_values[8] = ((RAM[8] >> 2)) & mask; + input_words_values[9] = ((RAM[9])) & mask; + input_words_values[10] = ((RAM[9] >> 64) + (RAM[10] << 2)) & mask; + input_words_values[11] = ((RAM[10] >> 62) + (RAM[11] << 4) + (RAM[12] << 61)) & mask; + input_words_values[12] = ((RAM[12] >> 3) + (RAM[13] << 63)) & mask; + input_words_values[13] = ((RAM[13] >> 1)) & mask; + input_words_values[14] = ((RAM[13] >> 65) + (RAM[14] << 1)) & mask; + input_words_values[15] = ((RAM[14] >> 63) + (RAM[15] << 3) + (RAM[16] << 60)) & mask; + + row = row + 3; + std::array input_words_vars; + + for (std::size_t i = 0; i < 8; i++) { + assignment.witness(i)[row] = input_words_values[i]; + assignment.witness(i)[row+1] = input_words_values[i+8]; + input_words_vars[i] = var(i, row, false); + input_words_vars[i+8] = var(i, row+1, false); } + + row = row + 2; + std::array constants = { - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179}; for (int i = 0; i < 8; i++) { - assignment.constant(0)[component_start_row + i] = constants[i]; + assignment.constant(0)[component_start_row + i] = constants[i]; } - std::array constants_var = {var(0, row, false, var::column_type::constant), - var(0, row + 1, false, var::column_type::constant), - var(0, row + 2, false, var::column_type::constant), - var(0, row + 3, false, var::column_type::constant), - var(0, row + 4, false, var::column_type::constant), - var(0, row + 5, false, var::column_type::constant), - var(0, row + 6, false, var::column_type::constant), - var(0, row + 7, false, var::column_type::constant)}; - typename sha512_process_component::params_type sha_params = {constants_var, input_words}; - auto sha_output = sha512_process_component::generate_assignments(assignment, sha_params, row); + + std::array constants_var = {var(0, component_start_row, false, var::column_type::constant), + var(0, component_start_row + 1, false, var::column_type::constant), + var(0, component_start_row + 2, false, var::column_type::constant), + var(0, component_start_row + 3, false, var::column_type::constant), + var(0, component_start_row + 4, false, var::column_type::constant), + var(0, component_start_row + 5, false, var::column_type::constant), + var(0, component_start_row + 6, false, var::column_type::constant), + var(0, component_start_row + 7, false, var::column_type::constant)}; + typename sha512_process_component::params_type sha_params = {constants_var, input_words_vars}; + auto sha_output = sha512_process_component::generate_assignments(assignment, sha_params, row).output_state; row += sha512_process_component::rows_amount; - std::array input_words2 = { + input_words_values[0] = ((RAM[16] >> 4) + (RAM[17] << 62)) & mask; + input_words_values[1] = ((RAM[17] >> 2)) & mask; + input_words_values[2] = ((RAM[18])) & mask; + input_words_values[3] = ((RAM[18] >> 64) + (RAM[19] << 2) + (integral_one << 60)) << 3; + + + for (std::size_t i = 4; i < 15; ++i) { + input_words_values[i] = 0; + } + input_words_values[15] = 1024 + 252; + + for (std::size_t i = 0; i < 8; i++) { + assignment.witness(i)[row] = input_words_values[i]; + assignment.witness(i)[row+1] = input_words_values[i+8]; + input_words_vars[i] = var(i, row, false); + input_words_vars[i+8] = var(i, row+1, false); + } + + row = row + 2; + sha_params = {sha_output, input_words_vars}; + + + +/* std::array input_words2 = { 1 << 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 << 9}; for (int i = 0; i < 16; i++) { assignment.constant(0)[component_start_row + 8 + i] = input_words2[i]; @@ -159,33 +233,25 @@ namespace nil { var(0, row + 22, false, var::column_type::constant), var(0, row + 23, false, var::column_type::constant)}; typename sha512_process_component::params_type sha_params2 = {sha_output.output_state, - input_words2_var}; - sha512_process_component::generate_assignments(assignment, sha_params2, row); + input_words2_var}; */ + + sha512_process_component::generate_assignments(assignment, sha_params, row); return result_type(component_start_row); } private: static void generate_gates(blueprint &bp, - blueprint_assignment_table &assignment, - const params_type ¶ms, - allocated_data_type &allocated_data, + blueprint_public_assignment_table &assignment, std::size_t component_start_row) { std::size_t row = component_start_row; - decomposition_component::generate_gates(bp, assignment, allocated_data, row); - decomposition_component::generate_gates(bp, assignment, allocated_data, row); - sha512_process_component::generate_gates(bp, assignment, allocated_data, row); - sha512_process_component::generate_gates(bp, assignment, allocated_data, row); + } static void generate_copy_constraints(blueprint &bp, - blueprint_assignment_table &assignment, + blueprint_public_assignment_table &assignment, const params_type ¶ms, - std::size_t component_start_row) { + const std::size_t &component_start_row) { std::size_t j = component_start_row; - decomposition_component::generate_copy_constraints(bp, assignment, j); - decomposition_component::generate_copy_constraints(bp, assignment, j); - sha512_process_component::generate_copy_constraints(bp, assignment, j); - sha512_process_component::generate_copy_constraints(bp, assignment, j); } }; diff --git a/include/nil/crypto3/zk/components/hashes/sha256/plonk/sha512_process.hpp b/include/nil/crypto3/zk/components/hashes/sha256/plonk/sha512_process.hpp index b24727692c..28646f85e1 100644 --- a/include/nil/crypto3/zk/components/hashes/sha256/plonk/sha512_process.hpp +++ b/include/nil/crypto3/zk/components/hashes/sha256/plonk/sha512_process.hpp @@ -250,7 +250,7 @@ namespace nil { assignment.witness(W6)[i + 2] = sigma0_chunks[0][4]; assignment.witness(W7)[i + 2] = message_scheduling_words[(i - row) / 6 + 9]; assignment.witness(W8)[i + 2] = message_scheduling_words[(i - row) / 6]; - + typename CurveType::base_field_type::integral_type integral_b = typename CurveType::base_field_type::integral_type( message_scheduling_words[(i - row) / 6 + 14].data); @@ -310,7 +310,7 @@ namespace nil { typename CurveType::base_field_type::integral_type(typename CurveType::base_field_type::value_type(2).pow(64).data); assignment.witness(W5)[i + 3] = message_scheduling_words[(i - row) / 6 + 16]; assignment.witness(W6)[i + 3] = (sum - message_scheduling_words[(i - row) / 6 + 16]) / - typename CurveType::base_field_type::integral_type(typename CurveType::base_field_type::value_type(2).pow(64).data); + typename CurveType::base_field_type::integral_type(typename CurveType::base_field_type::value_type(2).pow(64).data); } row = row + 384; for (std::size_t i = row; i < row + 720; i = i + 9) { @@ -364,9 +364,9 @@ namespace nil { assignment.witness(W4)[i + 2] = Sigma1_chunks[0][4]; typename CurveType::base_field_type::integral_type Sigma1 = Sigma1_chunks[0][0] + Sigma1_chunks[0][1] * (1 << (sigma_sizes[0])) + - Sigma1_chunks[0][2] * (1 << (sigma_sizes[0] + sigma_sizes[1])) + - Sigma1_chunks[0][3] * (1 << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2])) + - Sigma1_chunks[0][4] * (1 << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2] + sigma_sizes[3])); + Sigma1_chunks[0][2] * (one << (sigma_sizes[0] + sigma_sizes[1])) + + Sigma1_chunks[0][3] * (one << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2])) + + Sigma1_chunks[0][4] * (one << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2] + sigma_sizes[3])); sparse_values[4] = typename CurveType::base_field_type::integral_type((e_chunks[1][0] + @@ -460,9 +460,9 @@ namespace nil { typename CurveType::base_field_type::integral_type Sigma0 = Sigma0_chunks[0][0] + Sigma0_chunks[0][1] * (1 << sigma_sizes[0]) + - Sigma0_chunks[0][2] * (1 << (sigma_sizes[0] + sigma_sizes[1])) + - Sigma0_chunks[0][3] * (1 << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2])) + - Sigma0_chunks[0][4] * (1 << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2] + sigma_sizes[3])); + Sigma0_chunks[0][2] * (one << (sigma_sizes[0] + sigma_sizes[1])) + + Sigma0_chunks[0][3] * (one << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2])) + + Sigma0_chunks[0][4] * (one << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2] + sigma_sizes[3])); sparse_values[0] = typename CurveType::base_field_type::integral_type((a_chunks[1][0] + a_chunks[1][1] * base4_value.pow(a_sizes[0]) + a_chunks[1][2] * base4_value.pow(a_sizes[0] + a_sizes[1]) + @@ -695,9 +695,9 @@ namespace nil { var(W1, +1) - (var(W8, 0) + var(W0, +1) + var(W0, -1) + var(W1, -1) * (1 << (sigma_sizes[0])) + - var(W2, -1) * (1 << (sigma_sizes[0] + sigma_sizes[1])) + - var(W3, -1) * (1 << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2])) + - var(W4, -1) * (1 << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2] + sigma_sizes[3])) + + var(W2, -1) * (one << (sigma_sizes[0] + sigma_sizes[1])) + + var(W3, -1) * (one << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2])) + + var(W4, -1) * (one << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2] + sigma_sizes[3])) + var(W2, 0) + var(W3, 0) * (1 << 16) + var(W4, 0) * (one << 32) + var(W5, 0) * (one << 48) + var(W0, 0, true, var::column_type::constant))); @@ -713,9 +713,9 @@ namespace nil { var(W7, 0) + m*var(W8, 0)- (var(W1, -1) + var(W0, +1) + var(W1, +1) * (1 << sigma_sizes[0]) + - var(W2, +1) * (1 << (sigma_sizes[0] + sigma_sizes[1])) + - var(W3, +1) * (1 << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2])) + - var(W4, +1) * (1 << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2] + sigma_sizes[3])) + + var(W2, +1) * (one << (sigma_sizes[0] + sigma_sizes[1])) + + var(W3, +1) * (one << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2])) + + var(W4, +1) * (one << (sigma_sizes[0] + sigma_sizes[1] + sigma_sizes[2] + sigma_sizes[3])) + var(W2, 0) + var(W3, 0) * (1 << 16) + var(W4, 0) * (one << 32) + var(W5, 0) * (one << 48))); auto constraint_5 = bp.add_constraint((var(W8, 0) - 6) * (var(W8, 0) - 5) * @@ -870,6 +870,51 @@ namespace nil { blueprint_public_assignment_table &assignment, const params_type ¶ms, const std::size_t &start_row_index) { + + std::size_t row = start_row_index + 2; + + for (std::size_t i = 1; i <= 15; ++i) { + bp.add_copy_constraint({var(W0, row + (i - 1)*6 + 0, false), params.input_words[i]}); + } + for (std::size_t i = 9; i <= 15; ++i) { + bp.add_copy_constraint({var(W7, row + (i - 9)*6 + 2, false), params.input_words[i]}); + } + for (std::size_t i = 0; i <= 15; ++i) { + bp.add_copy_constraint({var(W8, row + (i - 0)*6 + 2, false), params.input_words[i]}); + } + for (std::size_t i = 14; i <= 15; ++i) { + bp.add_copy_constraint({var(W0, row + (i - 14)*6 + 5, false), params.input_words[i]}); + } + + row = row + 384; + + bp.add_copy_constraint({var(W6, row + 2, false), var(W5, start_row_index + 1)}); + bp.add_copy_constraint({var(W6, row + 3, false), var(W6, start_row_index + 1)}); + bp.add_copy_constraint({var(W6, row + 6, false), var(W1, start_row_index + 1)}); + bp.add_copy_constraint({var(W6, row + 5, false), var(W2, start_row_index + 1)}); + + for (std::size_t i = row; i < row + 720 - 9; i = i + 9){ + bp.add_copy_constraint ({var(W6, (i + 2) + 9, false), var(W5, (i + 2), false)}); + bp.add_copy_constraint ({var(W6, (i + 3) + 9, false), var(W6, (i + 2), false)}); + bp.add_copy_constraint ({var(W6, (i + 5) + 9, false), var(W6, (i + 6), false)}); + bp.add_copy_constraint ({var(W6, (i + 6) + 9, false), var(W5, (i + 6), false)}); + } + + bp.add_copy_constraint({var(W0, row + 8, false), params.input_state[0]}); + bp.add_copy_constraint({var(W7, row + 3, false), params.input_state[3]}); + bp.add_copy_constraint({var(W0, row + 0, false), params.input_state[4]}); + bp.add_copy_constraint({var(W8, row + 3, false), params.input_state[7]}); + + row = row + 720; + + bp.add_copy_constraint({var(W0, row, false), params.input_state[0]}); + bp.add_copy_constraint({var(W1, row, false), params.input_state[1]}); + bp.add_copy_constraint({var(W2, row, false), params.input_state[2]}); + bp.add_copy_constraint({var(W3, row, false), params.input_state[3]}); + bp.add_copy_constraint({var(W0, row + 2, false), params.input_state[4]}); + bp.add_copy_constraint({var(W1, row + 2, false), params.input_state[5]}); + bp.add_copy_constraint({var(W2, row + 2, false), params.input_state[6]}); + bp.add_copy_constraint({var(W3, row + 2, false), params.input_state[7]}); } static void generate_assignments_constant(blueprint &bp, diff --git a/include/nil/crypto3/zk/components/non_native/algebra/fields/plonk/ed25519.hpp b/include/nil/crypto3/zk/components/non_native/algebra/fields/plonk/ed25519.hpp index 428f276226..2b9464683d 100644 --- a/include/nil/crypto3/zk/components/non_native/algebra/fields/plonk/ed25519.hpp +++ b/include/nil/crypto3/zk/components/non_native/algebra/fields/plonk/ed25519.hpp @@ -36,7 +36,8 @@ #include #include #include -//#include +#include +#include namespace nil { namespace crypto3 { @@ -92,19 +93,21 @@ namespace nil { W0, W1, W2, W3, W4, W5, W6, W7, W8>; using scalar_non_native_range_component = scalar_non_native_range; - //using sha512_component = sha512; + using non_addition_component = non_native_field_element_addition; + using sha512_component = sha512; using var = snark::plonk_variable; constexpr static const std::size_t selector_seed = 0xfcc2; public: - constexpr static const std::size_t rows_amount = scalar_non_native_range_component::rows_amount + constexpr static const std::size_t rows_amount = /*262144;*/scalar_non_native_range_component::rows_amount + variable_base_mult_component::rows_amount + fixed_base_mult_component::rows_amount + addition_component::rows_amount + reduction_component::rows_amount - + 2 * check_ec_point_component::rows_amount; + + 2 * check_ec_point_component::rows_amount + sha512_component::rows_amount; constexpr static const std::size_t gates_amount = 0; @@ -119,7 +122,7 @@ namespace nil { }; signature e; var_ec_point public_key; - var M; + std::array M; }; //TODO: check if points R and public_key lie on the curve @@ -133,11 +136,15 @@ namespace nil { const params_type ¶ms, std::size_t component_start_row) { std::size_t row = component_start_row; - + //generate_lookup_table(assignment, params, component_start_row); + /*std::size_t n = (1 << 18); + for(std::size_t i = 0; i < n; i++) { + assignment.constant(1)[i] = i; + }*/ var s = params.e.s; auto R = params.e.R; auto pk = params.public_key; - var M = params.M; + std::array M = params.M; /* here we check if s lies in range */ scalar_non_native_range_component::generate_assignments(assignment, {s}, row); @@ -148,28 +155,14 @@ namespace nil { row += check_ec_point_component::rows_amount; /* here we get k = SHA(R||A||M) */ - /* 66*15 + 34 = 1024 bits */ - // auto padded = ...; - // row += ...; - // auto k_vec = sha512_component::generate_assignments(assignment, {padded}, row).output; - // row += sha512_component::rows_amount; - std::array constants = { - 1, 1, 1, 1, - 1, 1, 1, 1}; - for (int i = 0; i < 8; i++) { - assignment.constant(0)[row + i] = constants[i]; - } - std::array k_vec = {var(0, row, false, var::column_type::constant), - var(0, row + 1, false, var::column_type::constant), - var(0, row + 2, false, var::column_type::constant), - var(0, row + 3, false, var::column_type::constant), - var(0, row + 4, false, var::column_type::constant), - var(0, row + 5, false, var::column_type::constant), - var(0, row + 6, false, var::column_type::constant), - var(0, row + 7, false, var::column_type::constant)}; + auto k_vec = sha512_component::generate_assignments(assignment, {{{R.x[0], R.x[1], R.x[2], R.x[3]}, + {R.y[0], R.y[1], R.y[2], R.y[3]}}, {{pk.x[0], pk.x[1], pk.x[2], pk.x[3]}, + {pk.y[0], pk.y[1], pk.y[2], pk.y[3]}}, M}, row).output_state; + row += sha512_component::rows_amount; var k = reduction_component::generate_assignments(assignment, {k_vec}, row).output; row += reduction_component::rows_amount; /* here we check sB == R + kA */ + auto S = fixed_base_mult_component::generate_assignments(assignment, {s}, row).output; row += fixed_base_mult_component::rows_amount; auto A = variable_base_mult_component::generate_assignments(assignment, {{pk.x, pk.y}, k}, row).output; @@ -177,7 +170,6 @@ namespace nil { typename addition_component::params_type add_params = {{A.x, A.y}, {R.x, R.y}}; auto res = addition_component::generate_assignments(assignment, add_params, row).output; row += addition_component::rows_amount; - return result_type(component_start_row); } @@ -190,7 +182,7 @@ namespace nil { var s = params.e.s; auto R = params.e.R; auto pk = params.public_key; - var M = params.M; + std::array M = params.M; /* here we check if s lies in range */ scalar_non_native_range_component::generate_circuit(bp, assignment, {s}, row); @@ -201,21 +193,12 @@ namespace nil { row += check_ec_point_component::rows_amount; /* here we get k = SHA(R||A||M) */ - // auto padded = ...; - // row += ...; - // auto k_vec = sha512_component::generate_circuit(bp, assignment, {padded}, row).output; - // row += sha512_component::rows_amount; - std::array k_vec = {var(0, row, false, var::column_type::constant), - var(0, row + 1, false, var::column_type::constant), - var(0, row + 2, false, var::column_type::constant), - var(0, row + 3, false, var::column_type::constant), - var(0, row + 4, false, var::column_type::constant), - var(0, row + 5, false, var::column_type::constant), - var(0, row + 6, false, var::column_type::constant), - var(0, row + 7, false, var::column_type::constant)}; + auto k_vec = sha512_component::generate_circuit(bp, assignment, {{{R.x[0], R.x[1], R.x[2], R.x[3]}, + {R.y[0], R.y[1], R.y[2], R.y[3]}}, {{pk.x[0], pk.x[1], pk.x[2], pk.x[3]}, + {pk.y[0], pk.y[1], pk.y[2], pk.y[3]}}, M}, row).output_state; + row += sha512_component::rows_amount; var k = reduction_component::generate_circuit(bp, assignment, {k_vec}, row).output; row += reduction_component::rows_amount; - /* here we check sB == R + kA */ auto S = fixed_base_mult_component::generate_circuit(bp, assignment, {s}, row).output; row += fixed_base_mult_component::rows_amount; @@ -224,7 +207,7 @@ namespace nil { typename addition_component::params_type add_params = {{A.x, A.y}, {R.x, R.y}}; auto res = addition_component::generate_circuit(bp, assignment, add_params, row).output; row += addition_component::rows_amount; - + generate_copy_constraints(bp, assignment, params, start_row_index); return result_type(start_row_index); } @@ -243,9 +226,10 @@ namespace nil { const params_type ¶ms, std::size_t component_start_row) { std::size_t row = component_start_row; - row += 5 * non_native_range_component::rows_amount + reduction_component::rows_amount; - auto S = (typename fixed_base_mult_component::result_type(row)).output; - row += fixed_base_mult_component::rows_amount + variable_base_mult_component::rows_amount; + row += scalar_non_native_range_component::rows_amount + 2 * check_ec_point_component::rows_amount + + reduction_component::rows_amount + sha512_component::rows_amount + fixed_base_mult_component::rows_amount; + auto S = (typename fixed_base_mult_component::result_type(row - 1 - addition_component::rows_amount)).output; + row += variable_base_mult_component::rows_amount; auto res = (typename addition_component::result_type(row)).output; bp.add_copy_constraint({{S.x[0]}, {res.x[0]}}); bp.add_copy_constraint({{S.x[1]}, {res.x[1]}}); @@ -253,9 +237,20 @@ namespace nil { bp.add_copy_constraint({{S.x[3]}, {res.x[3]}}); bp.add_copy_constraint({{S.y[0]}, {res.y[0]}}); bp.add_copy_constraint({{S.y[1]}, {res.y[1]}}); - bp.add_copy_constraint({{S.y[2]}, {res.y[2]}}); + bp.add_copy_constraint({{S.y[2]}, {res.y[2]}}); bp.add_copy_constraint({{S.y[3]}, {res.y[3]}}); } + + static void generate_lookup_table(blueprint_assignment_table &assignment, + const params_type ¶ms, + std::size_t component_start_row) { + + std::size_t row = component_start_row; + std::size_t n = (1 << 16); + for(std::size_t i = 0; i < 2; i++) { + assignment.constant(1)[i] = 0; + } + } }; } // namespace components diff --git a/include/nil/crypto3/zk/components/non_native/algebra/fields/plonk/reduction.hpp b/include/nil/crypto3/zk/components/non_native/algebra/fields/plonk/reduction.hpp index f362ec9bb9..e5776b0734 100644 --- a/include/nil/crypto3/zk/components/non_native/algebra/fields/plonk/reduction.hpp +++ b/include/nil/crypto3/zk/components/non_native/algebra/fields/plonk/reduction.hpp @@ -32,6 +32,7 @@ #include #include +#include #include namespace nil { @@ -84,7 +85,7 @@ namespace nil { var output; result_type(std::size_t component_start_row) { - var(W4, component_start_row + rows_amount - 3, false); + output = var(W4, component_start_row + rows_amount - 3, false); } }; @@ -152,39 +153,52 @@ namespace nil { assignment.witness(0)[row + 2] = (q >> 47) & ((1 << (20)) - 1); assignment.witness(4)[row + 1] = r; - assignment.witness(3)[row + 1] = (r) & ((1 << (13)) - 1); - assignment.witness(2)[row + 1] = (r >> 13) & ((1 << (20)) - 1); - assignment.witness(1)[row + 1] = (r >> 33) & ((1 << (20)) - 1); - assignment.witness(0)[row + 1] = (r >> 53) & ((1 << (20)) - 1); - assignment.witness(8)[row] = (r >> 73) & ((1 << (20)) - 1); - assignment.witness(7)[row] = (r >> 93) & ((1 << (20)) - 1); - assignment.witness(6)[row] = (r >> 113) & ((1 << (20)) - 1); - assignment.witness(5)[row] = (r >> 133) & ((1 << (20)) - 1); - assignment.witness(4)[row] = (r >> 153) & ((1 << (20)) - 1); - assignment.witness(3)[row] = (r >> 173) & ((1 << (20)) - 1); - assignment.witness(2)[row] = (r >> 193) & ((1 << (20)) - 1); - assignment.witness(1)[row] = (r >> 213) & ((1 << (20)) - 1); - assignment.witness(0)[row] = (r >> 233); - - auto s_r = assignment.witness(0)[row]; + assignment.witness(3)[row + 1] = typename ArithmetizationType::field_type::value_type((r) & ((1 << (13)) - 1)); + assignment.witness(2)[row + 1] = typename ArithmetizationType::field_type::value_type((r >> 13) & ((1 << (20)) - 1)); + assignment.witness(1)[row + 1] = typename ArithmetizationType::field_type::value_type((r >> 33) & ((1 << (20)) - 1)); + assignment.witness(0)[row + 1] = typename ArithmetizationType::field_type::value_type((r >> 53) & ((1 << (20)) - 1)); + assignment.witness(8)[row] = typename ArithmetizationType::field_type::value_type((r >> 73) & ((1 << (20)) - 1)); + assignment.witness(7)[row] = typename ArithmetizationType::field_type::value_type((r >> 93) & ((1 << (20)) - 1)); + assignment.witness(6)[row] = typename ArithmetizationType::field_type::value_type((r >> 113) & ((1 << (20)) - 1)); + assignment.witness(5)[row] = typename ArithmetizationType::field_type::value_type((r >> 133) & ((1 << (20)) - 1)); + assignment.witness(4)[row] = typename ArithmetizationType::field_type::value_type((r >> 153) & ((1 << (20)) - 1)); + assignment.witness(3)[row] = typename ArithmetizationType::field_type::value_type((r >> 173) & ((1 << (20)) - 1)); + assignment.witness(2)[row] = typename ArithmetizationType::field_type::value_type((r >> 193) & ((1 << (20)) - 1)); + assignment.witness(1)[row] = typename ArithmetizationType::field_type::value_type((r >> 213) & ((1 << (20)) - 1)); + assignment.witness(0)[row] = typename ArithmetizationType::field_type::value_type((r >> 233)); + + typename ArithmetizationType::field_type::value_type s_r = assignment.witness(0)[row]; for (size_t i = 1; i < 9; i++) { s_r += assignment.witness(i)[row]; } s_r += assignment.witness(0)[row + 1] + assignment.witness(1)[row + 1] + - assignment.witness(2)[row + 1] + assignment.witness(3)[row + 1]; + assignment.witness(2)[row + 1]; s_r -= 12 * ((1 << (20)) - 1); - - assignment.witness(5)[row + 1] = 1 / s_r; - assignment.witness(6)[row + 1] = 1; - - auto v = (data[0] + data[1] * 0x10000000000000000_cppui512 + - q * (0x165812631a5cf5d3ed_cppui512) - (r & 0x1ffffffffffffffffff_cppui512)); + algebra::curves::ed25519::scalar_field_type::extended_integral_type one = 1; + assignment.witness(5)[row + 1] = s_r.inversed(); + + //if ((r) & ((1 << (13)) - 1) (L - (one << 252))) { \\TO-DO + assignment.witness(6)[row + 1] = 1; + //} else { + //} + + auto c = data[0] + data[1] * ((one << 64)) + data[3] * (((one << 192)%L) & ((one << 73) - 1)) + + data[4] * (((one << 256)%L) & ((one << 73) - 1)) + + data[5] * (((one << 320)%L) & ((one << 73) - 1)) + + data[6] * (((one << 384)%L) & ((one << 73) - 1)) + + data[7] * (((one << 448)%L) & ((one << 73) - 1)) + + q * ((one << 73) - (L % (one << 73))); + auto d = (r) & ((1 << (13)) - 1) + + ((r >> 13) & ((1 << (20)) - 1))* (one << 13) + + ((r >> 33) & ((1 << (20)) - 1)) * (one << 33) + + ((r >> 53) & ((1 << (20)) - 1)) * (one << 53); + auto v = (c - d) >> 69; assignment.witness(8)[row + 3] = v; - assignment.witness(4)[row + 2] = v >> 41; - assignment.witness(5)[row + 2] = (v >> 21) & ((1 << (20)) - 1); - assignment.witness(6)[row + 2] = (v >> 1) & ((1 << (20)) - 1); - assignment.witness(7)[row + 2] = v & 1; + assignment.witness(4)[row + 2] = v >> 56; + assignment.witness(5)[row + 2] = (v >> 34) & ((1 << (22)) - 1); + assignment.witness(6)[row + 2] = (v >> 12) & ((1 << (22)) - 1); + assignment.witness(7)[row + 2] = v & 4095; return result_type(start_row_index); } @@ -211,8 +225,7 @@ namespace nil { var(W2, 0) * 0x80_cppui512 + var(W3, 0)) * L); auto s_r = var(W0, -1) + var(W1, -1) + var(W2, -1) + var(W3, -1) + var(W4, -1) + var(W5, -1) + - var(W6, -1) + var(W7, -1) + var(W8, -1) + var(W0, 0) + var(W1, 0) + var(W2, 0) + - var(W3, 0) - 12 * ((1 << (20)) - 1); + var(W6, -1) + var(W7, -1) + var(W8, -1) + var(W0, 0) + var(W1, 0) + var(W2, 0) - 12 * ((1 << (20)) - 1); auto constraint_2 = bp.add_constraint( var(W4, 0) - @@ -231,24 +244,29 @@ namespace nil { auto constraint_4 = bp.add_constraint((s_r)*var(W5, 0) + (1 - (s_r)*var(W5, 0)) * var(W6, 0) - 1); - + algebra::curves::ed25519::scalar_field_type::extended_integral_type one = 1; + std::array m = + {((one << 192)%L), ((one << 256)%L), ((one << 320)%L), ((one << 384)%L), ((one << 448)%L)}; auto constraint_5 = bp.add_constraint( - var(W0, +1) + var(W1, +1) * 0x10000000000000000_cppui512 + + var(W0, +1) + var(W1, +1) * (one << 64) + + var(W3, + 1) * ( m[0] & ((one << 73) - 1)) + + var(W4, + 1) * ( m[1] & ((one << 73) - 1)) + + var(W5, + 1) * ( m[2]& ((one << 73) - 1)) + + var(W6, + 1) * ( m[3]& ((one << 73) - 1)) + + var(W7, + 1) * ( m[4]& ((one << 73) - 1)) + (var(W0, 0) * 0x800000000000_cppui512 + var(W1, 0) * 0x8000000_cppui512 + - var(W2, 0) * 0x80_cppui512 + var(W3, 0)) * (0x165812631a5cf5d3ed_cppui512) - - (var(W3, -1) + var(W2, -1) * 0x2000_cppui512 + var(W1, -1) * 0x200000000_cppui512 + - var(W0, -1) * 0x20000000000000_cppui512) - - var(W8, +1)); + var(W2, 0) * 0x80_cppui512 + var(W3, 0)) * ((one << 73) - (L % (one << 73))) - + (var(W3, -1) + var(W2, -1) * (one << 13) + var(W1, -1) * (one << 33) + + var(W0, -1) * (one << 53)) - + var(W8, +1) * (one << 69)); - auto constraint_6 = bp.add_constraint(var(W8, +1) - (var(W4, 0) * 0x20000000000_cppui255 + - var(W5, 0) * 0x200000_cppui255 + - var(W6, 0) * 2 + var(W7, 0))); + auto constraint_6 = bp.add_constraint(var(W8, +1) - (var(W4, 0) * (one << 56) + + var(W5, 0) * (one << 34) + + var(W6, 0) * (one << 12) + var(W7, 0))); - auto constraint_7 = bp.add_constraint((var(W6, 0) - 1) * var(W6, 0)); bp.add_gate(selector_index, - {constraint_2, constraint_3, constraint_4, - constraint_7}); + {constraint_2, constraint_3, constraint_4}); bp.add_gate(selector_index + 1, {constraint_1, constraint_5, constraint_6}); diff --git a/include/nil/crypto3/zk/components/non_native/algebra/fields/plonk/signatures_verification.hpp b/include/nil/crypto3/zk/components/non_native/algebra/fields/plonk/signatures_verification.hpp new file mode 100644 index 0000000000..53dd38f2f0 --- /dev/null +++ b/include/nil/crypto3/zk/components/non_native/algebra/fields/plonk/signatures_verification.hpp @@ -0,0 +1,154 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2022 Alisa Cherniaeva +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// +// @file Declaration of interfaces for auxiliary components for the EDDSA25519 component. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ZK_BLUEPRINT_SIGNATURES_VERIFICATION_HPP +#define CRYPTO3_ZK_BLUEPRINT_SIGNATURES_VERIFICATION_HPP + +#include +#include +#include + +namespace nil { + namespace crypto3 { + namespace zk { + namespace components { + + template + class signatures_verification; + + template + class signatures_verification, + CurveType, + Ed25519Type, + k, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8> { + + typedef snark::plonk_constraint_system ArithmetizationType; + + using ed25519_component = eddsa25519; + + using var = snark::plonk_variable; + using var_ec_point = typename ed25519_component::params_type::var_ec_point; + using signature = typename ed25519_component::params_type::signature; + constexpr static const std::size_t selector_seed = 0xfcc7; + + public: + constexpr static const std::size_t rows_amount = ed25519_component::rows_amount*k; + + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + std::array signatures; + std::array public_keys; + std::array M; + }; + + struct result_type { + result_type(std::size_t component_start_row) { + } + }; + + static result_type generate_assignments(blueprint_assignment_table &assignment, + const params_type ¶ms, + std::size_t component_start_row) { + std::size_t row = component_start_row; + for (std::size_t i = 0; i < k; i++){ + ed25519_component::generate_assignments(assignment, {params.signatures[i], params.public_keys[i], params.M}, row); + row += ed25519_component::rows_amount; + } + return result_type(component_start_row); + } + + static result_type generate_circuit(blueprint &bp, + blueprint_public_assignment_table &assignment, + const params_type ¶ms, + const std::size_t component_start_row){ + std::size_t row = component_start_row; + for (std::size_t i = 0; i < k; i++){ + ed25519_component::generate_circuit(bp, assignment, {params.signatures[i], params.public_keys[i], params.M}, row); + row += ed25519_component::rows_amount; + } + return result_type(component_start_row); + } + + private: + + static void generate_gates( + blueprint &bp, + blueprint_public_assignment_table &public_assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + + } + + static void generate_copy_constraints(blueprint &bp, + blueprint_public_assignment_table &public_assignment, + const params_type ¶ms, + std::size_t component_start_row) { + } + + static void generate_lookup_table(blueprint_assignment_table &assignment, + const params_type ¶ms, + std::size_t component_start_row) { + + std::size_t row = component_start_row; + std::size_t n = (1 << 16); + for(std::size_t i = 0; i < 2; i++) { + assignment.constant(1)[i] = 0; + } + } + }; + + } // namespace components + } // namespace zk + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_ZK_BLUEPRINT_VARIABLE_BASE_MULTIPLICATION_EDWARD25519_HPP \ No newline at end of file diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/batch_scalar/prepare_scalars.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/batch_scalar/prepare_scalars.hpp index 737d28cc31..8580f5a808 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/batch_scalar/prepare_scalars.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/batch_scalar/prepare_scalars.hpp @@ -41,7 +41,7 @@ namespace nil { namespace components { // shift scalars for scalar multiplication input - // f(X) = X -> X - 2^255 when the scalar field is larger than the base field and + // f(X) = X -> X - 2^255 when the scalar field is larger than the base field and // TODO: "larger scalar field is depricated case" // f(X) = X -> (X - 2^255 - 1) / 2 otherwise // Input: [x_0, ..., x_InputSize] // Output: [f(x_0), ..., f(x_InputSize)] diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/binding.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/binding.hpp index 847d844635..377a1c7d56 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/binding.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/binding.hpp @@ -34,7 +34,6 @@ #include #include -#include #include namespace nil { @@ -54,11 +53,8 @@ namespace nil { std::size_t BatchSize> struct fr_data { private: - using verifier_index_type = kimchi_verifier_index_scalar; - - constexpr static const std::size_t f_comm_msm_size = 1 - + 10 // generic_scalars_component::output_size - + verifier_index_type::constraints_amount; + constexpr static const std::size_t f_comm_msm_size = + kimchi_constants::f_comm_msm_size; public: std::array scalars; @@ -85,36 +81,6 @@ namespace nil { var fq_digest; // TODO overflow check std::array challenges; var c; - - - static fq_sponge_output - allocate_fq_output(blueprint_public_assignment_table &assignment, - typename BlueprintFieldType::value_type joint_combiner, - typename BlueprintFieldType::value_type beta, - typename BlueprintFieldType::value_type gamma, - typename BlueprintFieldType::value_type alpha, - typename BlueprintFieldType::value_type zeta, - typename BlueprintFieldType::value_type fq_digest, - std::array challenges, - typename BlueprintFieldType::value_type c) { - - std::array chals; - for (std::size_t i = 0; i < commitment_parms_type::eval_rounds; i++) { - chals[i] = assignment.allocate_public_input(challenges[i]); - } - - return fq_sponge_output { - assignment.allocate_public_input(joint_combiner), - assignment.allocate_public_input(beta), - assignment.allocate_public_input(gamma), - assignment.allocate_public_input(alpha), - assignment.allocate_public_input(zeta), - assignment.allocate_public_input(fq_digest), - chals, - assignment.allocate_public_input(c) - }; - } }; }; } // namespace components diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/index_terms_bases.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/index_terms_bases.hpp new file mode 100644 index 0000000000..169d0bafbd --- /dev/null +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/index_terms_bases.hpp @@ -0,0 +1,385 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2022 Ilia Shirobokov +// +// 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. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_INDEX_TERMS_BASES_HPP +#define CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_INDEX_TERMS_BASES_HPP + +#include + +#include + +#include +#include + +#include +#include + +#include +#include + +namespace nil { + namespace crypto3 { + namespace zk { + namespace components { + + // constraints scalars (exluding generic constraint) + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L568-L673 + // Input: constraint + // Output: constraint-related scalar x for linearization + template + class index_terms_bases; + + template + class index_terms_bases< + snark::plonk_constraint_system, + KimchiParamsType, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef snark::plonk_constraint_system + ArithmetizationType; + + using var = snark::plonk_variable; + + using evaluations_type = typename zk::components::kimchi_proof_evaluations< + BlueprintFieldType, KimchiParamsType>; + + constexpr static const std::size_t selector_seed = 0x0f27; + + using index_terms_list = zk::components::index_terms_scalars_list; + + + constexpr static std::size_t rows() { + std::size_t n = 0; + if (KimchiParamsType::circuit_params::poseidon_gate) { + n += index_terms_list::coefficient_0::rows_amount; + n += index_terms_list::coefficient_1::rows_amount; + n += index_terms_list::coefficient_2::rows_amount; + n += index_terms_list::coefficient_3::rows_amount; + n += index_terms_list::coefficient_4::rows_amount; + n += index_terms_list::coefficient_5::rows_amount; + n += index_terms_list::coefficient_6::rows_amount; + n += index_terms_list::coefficient_7::rows_amount; + n += index_terms_list::coefficient_8::rows_amount; + n += index_terms_list::coefficient_9::rows_amount; + n += index_terms_list::coefficient_10::rows_amount; + n += index_terms_list::coefficient_11::rows_amount; + n += index_terms_list::coefficient_12::rows_amount; + n += index_terms_list::coefficient_13::rows_amount; + n += index_terms_list::coefficient_14::rows_amount; + } + + if (KimchiParamsType::circuit_params::ec_arithmetic_gates) { + n += index_terms_list::var_base_mul::rows_amount; + n += index_terms_list::complete_add::rows_amount; + n += index_terms_list::endo_mul::rows_amount; + n += index_terms_list::endo_mul_scalar::rows_amount; + } + + return n; + } + + public: + constexpr static const std::size_t rows_amount = rows(); + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + var alpha; + var beta; + var gamma; + var joint_combiner; + + std::array + evaluations; + }; + + struct result_type { + std::array output; + + result_type(std::size_t start_row_index) { + } + + result_type() { + } + }; + + static result_type generate_circuit(blueprint &bp, + blueprint_public_assignment_table &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + generate_copy_constraints(bp, assignment, params, start_row_index); + + std::array output; + + std::size_t output_idx = 0; + + if (KimchiParamsType::circuit_params::poseidon_gate) { + output[output_idx++] = index_terms_list::coefficient_0::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[0], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_0::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_1::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[1], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_1::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_2::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[2], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_2::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_3::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[3], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_3::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_4::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[4], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_4::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_5::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[5], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_5::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_6::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[6], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_6::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_7::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[7], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_7::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_8::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[8], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_8::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_9::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[9], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_9::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_10::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[10], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_10::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_11::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[11], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_11::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_12::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[12], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_12::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_13::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[13], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_13::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_14::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[14], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_14::rows_amount; + } + + if (KimchiParamsType::circuit_params::ec_arithmetic_gates) { + output[output_idx++] = index_terms_list::var_base_mul::generate_circuit(bp, assignment, {index_terms_list::var_base_mul_str, + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::var_base_mul::rows_amount; + + output[output_idx++] = index_terms_list::complete_add::generate_circuit(bp, assignment, {index_terms_list::complete_add_str, + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::complete_add::rows_amount; + + output[output_idx++] = index_terms_list::endo_mul::generate_circuit(bp, assignment, {index_terms_list::endo_mul_str, + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::endo_mul::rows_amount; + + output[output_idx++] = index_terms_list::endo_mul_scalar::generate_circuit(bp, assignment, {index_terms_list::endo_mul_scalar_str, + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::endo_mul_scalar::rows_amount; + } + + assert(output_idx == KimchiParamsType::index_term_size()); + assert(row == start_row_index + rows_amount); + + result_type res; + res.output = output; + + return res; + } + + static result_type generate_assignments(blueprint_assignment_table &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + std::array output; + + std::size_t output_idx = 0; + + if (KimchiParamsType::circuit_params::poseidon_gate) { + output[output_idx++] = index_terms_list::coefficient_0::generate_assignments(assignment, {index_terms_list::coefficient_str[0], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_0::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_1::generate_assignments(assignment, {index_terms_list::coefficient_str[1], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_1::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_2::generate_assignments(assignment, {index_terms_list::coefficient_str[2], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_2::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_3::generate_assignments(assignment, {index_terms_list::coefficient_str[3], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_3::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_4::generate_assignments(assignment, {index_terms_list::coefficient_str[4], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_4::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_5::generate_assignments(assignment, {index_terms_list::coefficient_str[5], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_5::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_6::generate_assignments(assignment, {index_terms_list::coefficient_str[6], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_6::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_7::generate_assignments(assignment, {index_terms_list::coefficient_str[7], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_7::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_8::generate_assignments(assignment, {index_terms_list::coefficient_str[8], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_8::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_9::generate_assignments(assignment, {index_terms_list::coefficient_str[9], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_9::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_10::generate_assignments(assignment, {index_terms_list::coefficient_str[10], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_10::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_11::generate_assignments(assignment, {index_terms_list::coefficient_str[11], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_11::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_12::generate_assignments(assignment, {index_terms_list::coefficient_str[12], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_12::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_13::generate_assignments(assignment, {index_terms_list::coefficient_str[13], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_13::rows_amount; + + output[output_idx++] = index_terms_list::coefficient_14::generate_assignments(assignment, {index_terms_list::coefficient_str[14], + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::coefficient_14::rows_amount; + } + + if (KimchiParamsType::circuit_params::ec_arithmetic_gates) { + output[output_idx++] = index_terms_list::var_base_mul::generate_assignments(assignment, {index_terms_list::var_base_mul_str, + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::var_base_mul::rows_amount; + + output[output_idx++] = index_terms_list::complete_add::generate_assignments(assignment, {index_terms_list::complete_add_str, + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::complete_add::rows_amount; + + output[output_idx++] = index_terms_list::endo_mul::generate_assignments(assignment, {index_terms_list::endo_mul_str, + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::endo_mul::rows_amount; + + output[output_idx++] = index_terms_list::endo_mul_scalar::generate_assignments(assignment, {index_terms_list::endo_mul_scalar_str, + params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + row += index_terms_list::endo_mul_scalar::rows_amount; + } + + assert(output_idx == KimchiParamsType::index_term_size()); + assert(row == start_row_index + rows_amount); + + result_type res; + res.output = output; + + return res; + } + + private: + static void generate_gates(blueprint &bp, + blueprint_public_assignment_table &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + + } + + static void generate_copy_constraints(blueprint &bp, + blueprint_public_assignment_table &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + + static void generate_assignments_constants(blueprint &bp, + blueprint_public_assignment_table &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + }; + } // namespace components + } // namespace zk + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_INDEX_TERMS_BASES_HPP \ No newline at end of file diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/index_terms_scalars.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/index_terms_scalars.hpp index 2c3c08606c..6492ccd61a 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/index_terms_scalars.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/index_terms_scalars.hpp @@ -140,6 +140,8 @@ namespace nil { constexpr static const std::size_t gates_amount = 0; struct params_type { + var eval_point; // zeta + var alpha; var beta; var gamma; @@ -147,6 +149,9 @@ namespace nil { std::array evaluations; + + var group_gen; + std::size_t domain_size; }; struct result_type { @@ -174,81 +179,81 @@ namespace nil { if (KimchiParamsType::circuit_params::poseidon_gate) { output[output_idx++] = index_terms_list::coefficient_0::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[0], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_0::rows_amount; output[output_idx++] = index_terms_list::coefficient_1::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[1], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_1::rows_amount; output[output_idx++] = index_terms_list::coefficient_2::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[2], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_2::rows_amount; output[output_idx++] = index_terms_list::coefficient_3::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[3], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_3::rows_amount; output[output_idx++] = index_terms_list::coefficient_4::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[4], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_4::rows_amount; output[output_idx++] = index_terms_list::coefficient_5::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[5], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_5::rows_amount; output[output_idx++] = index_terms_list::coefficient_6::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[6], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_6::rows_amount; output[output_idx++] = index_terms_list::coefficient_7::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[7], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_7::rows_amount; output[output_idx++] = index_terms_list::coefficient_8::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[8], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_8::rows_amount; output[output_idx++] = index_terms_list::coefficient_9::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[9], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_9::rows_amount; output[output_idx++] = index_terms_list::coefficient_10::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[10], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_10::rows_amount; output[output_idx++] = index_terms_list::coefficient_11::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[11], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_11::rows_amount; output[output_idx++] = index_terms_list::coefficient_12::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[12], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_12::rows_amount; output[output_idx++] = index_terms_list::coefficient_13::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[13], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_13::rows_amount; output[output_idx++] = index_terms_list::coefficient_14::generate_circuit(bp, assignment, {index_terms_list::coefficient_str[14], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_14::rows_amount; } if (KimchiParamsType::circuit_params::ec_arithmetic_gates) { output[output_idx++] = index_terms_list::var_base_mul::generate_circuit(bp, assignment, {index_terms_list::var_base_mul_str, - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::var_base_mul::rows_amount; output[output_idx++] = index_terms_list::complete_add::generate_circuit(bp, assignment, {index_terms_list::complete_add_str, - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::complete_add::rows_amount; output[output_idx++] = index_terms_list::endo_mul::generate_circuit(bp, assignment, {index_terms_list::endo_mul_str, - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::endo_mul::rows_amount; output[output_idx++] = index_terms_list::endo_mul_scalar::generate_circuit(bp, assignment, {index_terms_list::endo_mul_scalar_str, - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::endo_mul_scalar::rows_amount; } @@ -273,81 +278,81 @@ namespace nil { if (KimchiParamsType::circuit_params::poseidon_gate) { output[output_idx++] = index_terms_list::coefficient_0::generate_assignments(assignment, {index_terms_list::coefficient_str[0], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_0::rows_amount; output[output_idx++] = index_terms_list::coefficient_1::generate_assignments(assignment, {index_terms_list::coefficient_str[1], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_1::rows_amount; output[output_idx++] = index_terms_list::coefficient_2::generate_assignments(assignment, {index_terms_list::coefficient_str[2], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_2::rows_amount; output[output_idx++] = index_terms_list::coefficient_3::generate_assignments(assignment, {index_terms_list::coefficient_str[3], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_3::rows_amount; output[output_idx++] = index_terms_list::coefficient_4::generate_assignments(assignment, {index_terms_list::coefficient_str[4], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_4::rows_amount; output[output_idx++] = index_terms_list::coefficient_5::generate_assignments(assignment, {index_terms_list::coefficient_str[5], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_5::rows_amount; output[output_idx++] = index_terms_list::coefficient_6::generate_assignments(assignment, {index_terms_list::coefficient_str[6], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_6::rows_amount; output[output_idx++] = index_terms_list::coefficient_7::generate_assignments(assignment, {index_terms_list::coefficient_str[7], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_7::rows_amount; output[output_idx++] = index_terms_list::coefficient_8::generate_assignments(assignment, {index_terms_list::coefficient_str[8], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_8::rows_amount; output[output_idx++] = index_terms_list::coefficient_9::generate_assignments(assignment, {index_terms_list::coefficient_str[9], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_9::rows_amount; output[output_idx++] = index_terms_list::coefficient_10::generate_assignments(assignment, {index_terms_list::coefficient_str[10], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_10::rows_amount; output[output_idx++] = index_terms_list::coefficient_11::generate_assignments(assignment, {index_terms_list::coefficient_str[11], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_11::rows_amount; output[output_idx++] = index_terms_list::coefficient_12::generate_assignments(assignment, {index_terms_list::coefficient_str[12], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_12::rows_amount; output[output_idx++] = index_terms_list::coefficient_13::generate_assignments(assignment, {index_terms_list::coefficient_str[13], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_13::rows_amount; output[output_idx++] = index_terms_list::coefficient_14::generate_assignments(assignment, {index_terms_list::coefficient_str[14], - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::coefficient_14::rows_amount; } if (KimchiParamsType::circuit_params::ec_arithmetic_gates) { output[output_idx++] = index_terms_list::var_base_mul::generate_assignments(assignment, {index_terms_list::var_base_mul_str, - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::var_base_mul::rows_amount; output[output_idx++] = index_terms_list::complete_add::generate_assignments(assignment, {index_terms_list::complete_add_str, - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::complete_add::rows_amount; output[output_idx++] = index_terms_list::endo_mul::generate_assignments(assignment, {index_terms_list::endo_mul_str, - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::endo_mul::rows_amount; output[output_idx++] = index_terms_list::endo_mul_scalar::generate_assignments(assignment, {index_terms_list::endo_mul_scalar_str, - params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations}, row).output; + params.eval_point, params.alpha, params.beta, params.gamma, params.joint_combiner, params.evaluations, params.group_gen, params.domain_size}, row).output; row += index_terms_list::endo_mul_scalar::rows_amount; } diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/perm_scalars.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/perm_scalars.hpp index c2539d692d..d03aa32265 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/perm_scalars.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/perm_scalars.hpp @@ -208,27 +208,6 @@ namespace nil { auto const_res = mul_const_component::generate_assignments(assignment, {res.output, -1}, row); return result_type(start_row_index); } - - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { - - } - - static void generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - } - - static void generate_assignments_constants(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - } }; } // namespace components } // namespace zk diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/rpn_expression.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/rpn_expression.hpp index 6d97b5164f..1c82f820dc 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/rpn_expression.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/rpn_expression.hpp @@ -42,6 +42,9 @@ #include #include +#include +#include + #include @@ -79,13 +82,20 @@ namespace nil { KimchiParamsType::scalar_challenge_size, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14>; - using poseidon_component = zk::components::poseidon; + using poseidon_component = zk::components::poseidon; using exponentiation_component = zk::components::exponentiation; + using vanishes_on_last_4_rows_component = zk::components::vanishes_on_last_4_rows< + ArithmetizationType, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, + W11, W12, W13, W14>; + + using unnormalized_lagrange_basis_component = zk::components::unnormalized_lagrange_basis; + using evaluations_type = typename zk::components::kimchi_proof_evaluations; @@ -133,20 +143,19 @@ namespace nil { case KimchiParamsType::witness_columns + 3: return evals.generic_selector; case KimchiParamsType::witness_columns + 4: - // TODO: lookups - return evals.z; + return evals.lookup.aggreg; case KimchiParamsType::witness_columns + 5: - // TODO: lookups - return evals.z; + return evals.lookup.table; case KimchiParamsType::witness_columns + 6: - // TODO: lookups - return evals.z; - case KimchiParamsType::witness_columns + 7: - // TODO: lookups - return evals.z; + return evals.lookup.runtime; default: - throw std::runtime_error("Unknown column type"); + break; } + + assert(var_column <= KimchiParamsType::witness_columns + + 6 + KimchiParamsType::circuit_params::lookup_columns); + + return evals.lookup.sorted[var_column - KimchiParamsType::witness_columns - 7]; } enum token_type { @@ -173,6 +182,7 @@ namespace nil { token_type type; std::pair value; + int int_data; }; static std::vector @@ -261,7 +271,7 @@ namespace nil { std::size_t col_end_pos = token_str.find(")", col_start_pos); std::string col_str = token_str.substr(col_start_pos, col_end_pos - col_start_pos); - col = KimchiParamsType::witness_columns + 6 + std::stoi(col_str); + col = KimchiParamsType::witness_columns + 7 + std::stoi(col_str); } } @@ -286,6 +296,12 @@ namespace nil { token.type = token_type::vanishes_on_last_4_rows; } else if (token_str.find("UnnormalizedLagrangeBasis") != std::string::npos) { token.type = token_type::unnormalized_lagrange_basis; + + std::size_t exp_start_pos = token_str.find("UnnormalizedLagrangeBasis"); + exp_start_pos = token_str.find("(", exp_start_pos); + std::size_t exp_end_pos = token_str.find(")", exp_start_pos); + std::string exp_str = token_str.substr(exp_start_pos, exp_end_pos - exp_start_pos); + token.int_data = std::stoi(exp_str); } else if (token_str.find("Store") != std::string::npos) { token.type = token_type::store; } else if (token_str.find("Load") != std::string::npos) { @@ -312,12 +328,17 @@ namespace nil { struct params_type { std::string_view expression; + var eval_point; // zeta + var alpha; var beta; var gamma; var joint_combiner; std::array evaluations; + + var group_gen; + std::size_t domain_size; }; struct result_type { @@ -445,12 +466,24 @@ namespace nil { stack.push_back(res); break; } - case token_type::vanishes_on_last_4_rows: - // TODO: lookups + case token_type::vanishes_on_last_4_rows: { + constant_row += 2; // exponentiation component uses 2 constant rows + constant_row++; // vanishes_on_last_4_rows_component saves domain_size into constant + var res = vanishes_on_last_4_rows_component::generate_circuit( + bp, assignment, {params.group_gen, params.domain_size, params.eval_point}, row).output; + row += vanishes_on_last_4_rows_component::rows_amount; + stack.push_back(res); break; - case token_type::unnormalized_lagrange_basis: - // TODO: lookups + } + case token_type::unnormalized_lagrange_basis: { + constant_row += 2; // exponentiation component uses 2 constant rows + constant_row += 3; // unnormalized_lagrange_basis uses 3 constant rows + var res = unnormalized_lagrange_basis_component::generate_circuit( + bp, assignment, {params.group_gen, params.domain_size, params.eval_point, t.int_data}, row).output; + row += unnormalized_lagrange_basis_component::rows_amount; + stack.push_back(res); break; + } case token_type::store: { var x = stack.back(); cache.emplace_back(x); @@ -576,12 +609,24 @@ namespace nil { stack.push_back(res); break; } - case token_type::vanishes_on_last_4_rows: - // TODO: lookups + case token_type::vanishes_on_last_4_rows: { + constant_row += 2; // exponentiation component uses 2 constant rows + constant_row++; // vanishes_on_last_4_rows_component saves domain_size into constant + var res = vanishes_on_last_4_rows_component::generate_assignments( + assignment, {params.group_gen, params.domain_size, params.eval_point}, row).output; + row += vanishes_on_last_4_rows_component::rows_amount; + stack.push_back(res); break; - case token_type::unnormalized_lagrange_basis: - // TODO: lookups + } + case token_type::unnormalized_lagrange_basis: { + constant_row += 2; // exponentiation component uses 2 constant rows + constant_row += 3; // unnormalized_lagrange_basis uses 3 constant rows + var res = unnormalized_lagrange_basis_component::generate_assignments( + assignment, {params.group_gen, params.domain_size, params.eval_point, t.int_data}, row).output; + row += unnormalized_lagrange_basis_component::rows_amount; + stack.push_back(res); break; + } case token_type::store: { var x = stack.back(); cache.emplace_back(x); @@ -636,9 +681,6 @@ namespace nil { row++; break; } - case token_type::unnormalized_lagrange_basis: - // TODO: lookups - break; default: break; } diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/rpn_string_literal.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/rpn_string_literal.hpp index 638872d2ce..2e7d50e4c7 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/rpn_string_literal.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/rpn_string_literal.hpp @@ -42,100 +42,126 @@ #include #include #include -using namespace nil::crypto3; - -constexpr const std::size_t count_delimiters(const char *expression) { - size_t i = 0; - size_t cnt = 0; - for (; expression[i] != '\0'; i++) { - if (expression[i] == ';') { - cnt++; - } - } - return cnt; -} - -constexpr const std::size_t str_len(const char *expression) { - size_t size = 0; - for (; expression[size] != '\0'; size++) { - } - return size; -} - -constexpr std::size_t find_str(const char *expression, const char *str, std::size_t n, std::size_t start_pos, - std::size_t end_pos) { - size_t j = 0; - size_t i = start_pos; - for (; i < end_pos; i++) { - for (j = 0; j < n && expression[i + j] == str[j]; j++) - ; - if (j == n) { - return i; - } - } - return std::string::npos; -} - -template -constexpr size_t rpn_component_rows(const char *expression) { - using mul_component = zk::components::multiplication; - using add_component = zk::components::addition; - using sub_component = zk::components::subtraction; - - using exponentiation_component = zk::components::exponentiation; - - const std::size_t literal_string_size = str_len(expression); - - const size_t mds_size = 3; - std::array str_start = {}; - - std::array str_end = {}; - str_start[0] = 0; - str_end[tokens_array_size - 1] = literal_string_size; - size_t i = 0; - const char *alpha_c = "Alpha"; - const char *beta_c = "Beta"; - const char *gamma_c = "Gamma"; - const char *joint_combiner_c = "JointCombiner"; - const char *endo_coefficient_c = "EndoCoefficient"; - const char *mds_c = "Mds"; - const char *literal_c = "Literal"; - const char *cell_c = "Cell"; - const char *dup_c = "Dup"; - const char *pow_c = "Pow"; - const char *add_c = "Add"; - const char *mul_c = "Mul"; - const char *sub_c = "Sub"; - const char *vanishes_on_last_4_rows_c = "VanishesOnLast4Rows"; - const char *unnormalized_lagrange_basis_c = "UnnormalizedLagrangeBasis"; - const char *store_c = "Store"; - const char *load_c = "Load"; - const char *del = ";"; - for (i = 0; i < tokens_array_size - 1; i++) { - size_t pos = find_str(expression, del, 1, str_start[i], literal_string_size); - str_end[i] = pos; - str_start[i + 1] = pos + 1; - } - size_t rows = 0; - size_t constant_rows = 1 + mds_size * mds_size; - for (i = 0; i < tokens_array_size; i++) { - if (find_str(expression, literal_c, 7, str_start[i], str_end[i]) != std::string::npos) { - constant_rows++; - } else if (find_str(expression, pow_c, 3, str_start[i], str_end[i]) != std::string::npos) { - constant_rows += 2; // exponentiation component uses 2 constant rows - rows += exponentiation_component::rows_amount; - constant_rows++; - } else if (find_str(expression, add_c, 3, str_start[i], str_end[i]) != std::string::npos) { - rows += add_component::rows_amount; - } else if (find_str(expression, mul_c, 3, str_start[i], str_end[i]) != std::string::npos) { - rows += mul_component::rows_amount; - } else if (find_str(expression, sub_c, 3, str_start[i], str_end[i]) != std::string::npos) { - rows += sub_component::rows_amount; - } - } - - size_t res = std::max(rows, constant_rows); - return res; -} \ No newline at end of file +#include +#include + +namespace nil { + namespace crypto3 { + namespace zk { + namespace components { + + constexpr const std::size_t count_delimiters(const char *expression) { + size_t i = 0; + size_t cnt = 0; + for (; expression[i] != '\0'; i++) { + if (expression[i] == ';') { + cnt++; + } + } + return cnt; + } + + constexpr const std::size_t str_len(const char *expression) { + size_t size = 0; + for (; expression[size] != '\0'; size++) { + } + return size; + } + + constexpr std::size_t find_str(const char *expression, const char *str, std::size_t n, std::size_t start_pos, + std::size_t end_pos) { + size_t j = 0; + size_t i = start_pos; + for (; i < end_pos; i++) { + for (j = 0; j < n && expression[i + j] == str[j]; j++) + ; + if (j == n) { + return i; + } + } + return std::string::npos; + } + + template + constexpr size_t rpn_component_rows(const char *expression) { + using mul_component = zk::components::multiplication; + using add_component = zk::components::addition; + using sub_component = zk::components::subtraction; + + using exponentiation_component = zk::components::exponentiation; + + using vanishes_on_last_4_rows_component = zk::components::vanishes_on_last_4_rows< + ArithmetizationType, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14>; + + using unnormalized_lagrange_basis_component = zk::components::unnormalized_lagrange_basis; + + const std::size_t literal_string_size = str_len(expression); + + const size_t mds_size = 3; + std::array str_start = {}; + + std::array str_end = {}; + str_start[0] = 0; + str_end[tokens_array_size - 1] = literal_string_size; + size_t i = 0; + const char *alpha_c = "Alpha"; + const char *beta_c = "Beta"; + const char *gamma_c = "Gamma"; + const char *joint_combiner_c = "JointCombiner"; + const char *endo_coefficient_c = "EndoCoefficient"; + const char *mds_c = "Mds"; + const char *literal_c = "Literal"; + const char *cell_c = "Cell"; + const char *dup_c = "Dup"; + const char *pow_c = "Pow"; + const char *add_c = "Add"; + const char *mul_c = "Mul"; + const char *sub_c = "Sub"; + const char *vanishes_on_last_4_rows_c = "VanishesOnLast4Rows"; + const char *unnormalized_lagrange_basis_c = "UnnormalizedLagrangeBasis"; + const char *store_c = "Store"; + const char *load_c = "Load"; + const char *del = ";"; + for (i = 0; i < tokens_array_size - 1; i++) { + size_t pos = find_str(expression, del, 1, str_start[i], literal_string_size); + str_end[i] = pos; + str_start[i + 1] = pos + 1; + } + size_t rows = 0; + size_t constant_rows = 1 + mds_size * mds_size; + for (i = 0; i < tokens_array_size; i++) { + if (find_str(expression, literal_c, 7, str_start[i], str_end[i]) != std::string::npos) { + constant_rows++; + } else if (find_str(expression, pow_c, 3, str_start[i], str_end[i]) != std::string::npos) { + constant_rows += 2; // exponentiation component uses 2 constant rows + rows += exponentiation_component::rows_amount; + constant_rows++; + } else if (find_str(expression, add_c, 3, str_start[i], str_end[i]) != std::string::npos) { + rows += add_component::rows_amount; + } else if (find_str(expression, mul_c, 3, str_start[i], str_end[i]) != std::string::npos) { + rows += mul_component::rows_amount; + } else if (find_str(expression, sub_c, 3, str_start[i], str_end[i]) != std::string::npos) { + rows += sub_component::rows_amount; + } else if (find_str(expression, vanishes_on_last_4_rows_c, 3, str_start[i], str_end[i]) != std::string::npos) { + constant_rows += 2; // exponentiation component uses 2 constant rows + constant_rows++; // vanishes_on_last_4_rows_component saves domain_size into constant + rows += vanishes_on_last_4_rows_component::rows_amount; + } + else if (find_str(expression, unnormalized_lagrange_basis_c, 3, str_start[i], str_end[i]) != std::string::npos) { + constant_rows += 2; // exponentiation component uses 2 constant rows + constant_rows += 3; // unnormalized_lagrange_basis_component uses 3 constant rows + rows += unnormalized_lagrange_basis_component::rows_amount; + } + } + + size_t res = std::max(rows, constant_rows); + return res; + } + } // namespace components + } // namespace zk + } // namespace crypto3 +} // namespace nil \ No newline at end of file diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/unnormalized_lagrange_basis.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/unnormalized_lagrange_basis.hpp new file mode 100644 index 0000000000..e8e21836e5 --- /dev/null +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/unnormalized_lagrange_basis.hpp @@ -0,0 +1,216 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2022 Ilia Shirobokov +// +// 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. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_CONSTRAINTS_UNNORMALIZED_LAGRANGE_BASIS_HPP +#define CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_CONSTRAINTS_UNNORMALIZED_LAGRANGE_BASIS_HPP + +#include + +#include + +#include +#include + +#include +#include +#include + +namespace nil { + namespace crypto3 { + namespace zk { + namespace components { + + // Compute the ith unnormalized lagrange basis + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/expr.rs#L150 + // Input: group generator (w), + // i, + // domain_size, + // evaluation point (x) + // Output: (x^domain_size - 1) / (x - w^i) + template + class unnormalized_lagrange_basis; + + template + class unnormalized_lagrange_basis< + snark::plonk_constraint_system, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef snark::plonk_constraint_system + ArithmetizationType; + + using var = snark::plonk_variable; + + using sub_component = zk::components::subtraction; + using exp_component = zk::components::exponentiation; + using div_component = zk::components::division; + + constexpr static const std::size_t selector_seed = 0x0f25; + + constexpr static const std::size_t zk_rows = 3; + + public: + constexpr static const std::size_t rows_amount = 3 + 2 * exp_component::rows_amount + + 2 * sub_component::rows_amount + div_component::rows_amount; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + var group_gen; + std::size_t domain_size; + var x; + int i; + }; + + struct result_type { + var output; + + result_type(std::size_t start_row_index) { + std::size_t row = start_row_index + rows_amount - div_component::rows_amount; + output = typename div_component::result_type(row).output; + } + }; + + static result_type generate_circuit(blueprint &bp, + blueprint_public_assignment_table &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + generate_assignments_constants(bp, assignment, params, start_row_index); + + var domain_size(0, start_row_index, false, var::column_type::constant); + var basis_element(0, start_row_index + 1, false, var::column_type::constant); + var one(0, start_row_index + 2, false, var::column_type::constant); + + std::size_t row = start_row_index; + row += 3; // skip row for constants in exp_component + + var denominator = exp_component::generate_circuit(bp, assignment, + {params.group_gen, basis_element}, row).output; + row += exp_component::rows_amount; + + denominator = zk::components::generate_circuit(bp, assignment, + {params.x, denominator}, row).output; + row += sub_component::rows_amount; + + var numerator = exp_component::generate_circuit(bp, assignment, + {params.x, domain_size}, row).output; + row += exp_component::rows_amount; + numerator = zk::components::generate_circuit(bp, assignment, + {numerator, one}, row).output; + row += sub_component::rows_amount; + + var res = zk::components::generate_circuit(bp, assignment, + {numerator, denominator}, row).output; + row += div_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + return result_type(start_row_index); + } + + static result_type generate_assignments(blueprint_assignment_table &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + var domain_size(0, start_row_index, false, var::column_type::constant); + var basis_element(0, start_row_index + 1, false, var::column_type::constant); + var one(0, start_row_index + 2, false, var::column_type::constant); + + std::size_t row = start_row_index; + row += 3; // skip row for constants in exp_component + + var denominator = exp_component::generate_assignments(assignment, + {params.group_gen, basis_element}, row).output; + row += exp_component::rows_amount; + + denominator = sub_component::generate_assignments(assignment, + {params.x, denominator}, row).output; + row += sub_component::rows_amount; + + var numerator = exp_component::generate_assignments(assignment, + {params.x, domain_size}, row).output; + row += exp_component::rows_amount; + numerator = sub_component::generate_assignments(assignment, + {numerator, one}, row).output; + row += sub_component::rows_amount; + + var res = div_component::generate_assignments(assignment, + {numerator, denominator}, row).output; + row += div_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + return result_type(start_row_index); + } + + private: + static void generate_assignments_constants(blueprint &bp, + blueprint_public_assignment_table &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + assignment.constant(0)[row] = params.domain_size; + row++; + assignment.constant(0)[row] = params.i >= 0 ? params.i : params.domain_size - std::size_t(-params.i); + row++; + assignment.constant(0)[row] = 1; + } + }; + } // namespace components + } // namespace zk + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_CONSTRAINTS_UNNORMALIZED_LAGRANGE_BASIS_HPP diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/vanishes_on_last_4_rows.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/vanishes_on_last_4_rows.hpp new file mode 100644 index 0000000000..a1dd265e41 --- /dev/null +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/constraints/vanishes_on_last_4_rows.hpp @@ -0,0 +1,222 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2022 Ilia Shirobokov +// Copyright (c) 2022 Polina Chernyshova +// +// 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. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_CONSTRAINTS_VANISHES_ON_LAST_4_ROWS_HPP +#define CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_CONSTRAINTS_VANISHES_ON_LAST_4_ROWS_HPP + +#include + +#include + +#include +#include + +#include +#include +#include + +namespace nil { + namespace crypto3 { + namespace zk { + namespace components { + + // (x - w^{n - 4}) (x - w^{n - 3}) * (x - w^{n - 2}) * (x - w^{n - 1}) + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/polynomials/permutation.rs#L64 + // Input: group generator (w), + // domain size (n), + // evaluation point (x) + // Output: (x - w^{n - 4}) (x - w^{n - 3}) * (x - w^{n - 2}) * (x - w^{n - 1}) + template + class vanishes_on_last_4_rows; + + template + class vanishes_on_last_4_rows< + snark::plonk_constraint_system, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef snark::plonk_constraint_system + ArithmetizationType; + + using var = snark::plonk_variable; + + using mul_component = zk::components::multiplication; + using exp_component = zk::components::exponentiation; + using sub_component = zk::components::subtraction; + + constexpr static const std::size_t selector_seed = 0x0f25; + + constexpr static const std::size_t zk_rows = 3; + + public: + constexpr static const std::size_t rows_amount = 1 + exp_component::rows_amount + + 6 * mul_component::rows_amount + 4 * sub_component::rows_amount; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + var group_gen; + std::size_t domain_size; + var x; + }; + + struct result_type { + var output; + + result_type(std::size_t start_row_index) { + std::size_t row = start_row_index; + } + }; + + static result_type generate_circuit(blueprint &bp, + blueprint_public_assignment_table &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + generate_assignments_constants(bp, assignment, params, start_row_index); + + var domain_size = var(0, start_row_index, false, var::column_type::constant); + + std::size_t row = start_row_index; + row++; // skip row for constants in exp_component + + result_type result(row); + + var w1 = exp_component::generate_circuit(bp, assignment, {params.group_gen, domain_size}, row).output; + row += exp_component::rows_amount; + var w2 = zk::components::generate_circuit(bp, assignment, {w1, params.group_gen}, row).output; + row += mul_component::rows_amount; + var w3 = zk::components::generate_circuit(bp, assignment, {w2, params.group_gen}, row).output; + row += mul_component::rows_amount; + var w4 = zk::components::generate_circuit(bp, assignment, {w3, params.group_gen}, row).output; + row += mul_component::rows_amount; + + var a1 = zk::components::generate_circuit(bp, assignment, {params.x, w1}, row).output; + row += sub_component::rows_amount; + var a2 = zk::components::generate_circuit(bp, assignment, {params.x, w2}, row).output; + row += sub_component::rows_amount; + var a3 = zk::components::generate_circuit(bp, assignment, {params.x, w3}, row).output; + row += sub_component::rows_amount; + var a4 = zk::components::generate_circuit(bp, assignment, {params.x, w4}, row).output; + row += sub_component::rows_amount; + + var ans1 = zk::components::generate_circuit(bp, assignment, {a1, a2}, row).output; + row += mul_component::rows_amount; + var ans2 = zk::components::generate_circuit(bp, assignment, {ans1, a3}, row).output; + row += mul_component::rows_amount; + result.output = zk::components::generate_circuit(bp, assignment, {ans2, a4}, row).output; + row += mul_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + return result; + } + + static result_type generate_assignments(blueprint_assignment_table &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + var domain_size = var(0, start_row_index, false, var::column_type::constant); + + std::size_t row = start_row_index; + row++; // skip row for constants in exp_component + + result_type result(row); + + var w1 = exp_component::generate_assignments(assignment, {params.group_gen, domain_size}, row).output; + row += exp_component::rows_amount; + var w2 = mul_component::generate_assignments(assignment, {w1, params.group_gen}, row).output; + row += mul_component::rows_amount; + var w3 = mul_component::generate_assignments(assignment, {w2, params.group_gen}, row).output; + row += mul_component::rows_amount; + var w4 = mul_component::generate_assignments(assignment, {w3, params.group_gen}, row).output; + row += mul_component::rows_amount; + + var a1 = sub_component::generate_assignments(assignment, {params.x, w1}, row).output; + row += sub_component::rows_amount; + var a2 = sub_component::generate_assignments(assignment, {params.x, w2}, row).output; + row += sub_component::rows_amount; + var a3 = sub_component::generate_assignments(assignment, {params.x, w3}, row).output; + row += sub_component::rows_amount; + var a4 = sub_component::generate_assignments(assignment, {params.x, w4}, row).output; + row += sub_component::rows_amount; + + var ans1 = mul_component::generate_assignments(assignment, {a1, a2}, row).output; + row += mul_component::rows_amount; + var ans2 = mul_component::generate_assignments(assignment, {ans1, a3}, row).output; + row += mul_component::rows_amount; + result.output = mul_component::generate_assignments(assignment, {ans2, a4}, row).output; + row += mul_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + return result; + } + + private: + static void generate_assignments_constants(blueprint &bp, + blueprint_public_assignment_table &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + assignment.constant(0)[row] = params.domain_size - zk_rows - 1; + } + }; + } // namespace components + } // namespace zk + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_CONSTRAINTS_VANISHES_ON_LAST_4_ROWS_HPP diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/inner_constants.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/inner_constants.hpp index b8655e0b71..00e930c97c 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/inner_constants.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/inner_constants.hpp @@ -40,6 +40,10 @@ namespace nil { namespace components { template struct kimchi_inner_constants { + private: + constexpr static const std::size_t constraints_amount = 2; + + public: using commitment_params_type = typename KimchiParamsType::commitment_params_type; constexpr static std::size_t ft_generic_size = 2 * 5; @@ -78,6 +82,10 @@ namespace nil { + 1) // opening.delta * batch_size; } + + constexpr static std::size_t f_comm_msm_size = 1 + + 10 // generic_scalars_component::output_size + + constraints_amount; }; } // namespace components } // namespace zk diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/oracles_scalar/b_poly_coefficients.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/oracles_scalar/b_poly_coefficients.hpp index 97da415eac..192bf05345 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/oracles_scalar/b_poly_coefficients.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/oracles_scalar/b_poly_coefficients.hpp @@ -134,7 +134,6 @@ namespace nil { row += mul_component::rows_amount; } - generate_copy_constraints(bp, assignment, params, start_row_index); result_type res; res.output = output; return res; @@ -166,20 +165,6 @@ namespace nil { res.output = output; return res; } - - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { - - } - - static void generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - } }; } // namespace components } // namespace zk diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/oracles_scalar/combine_proof_evals.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/oracles_scalar/combine_proof_evals.hpp index 839098e50c..d994eaba58 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/oracles_scalar/combine_proof_evals.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/oracles_scalar/combine_proof_evals.hpp @@ -99,11 +99,27 @@ namespace nil { constexpr static const std::size_t selector_seed = 0x0f23; + constexpr static const std::size_t lookup_rows() { + std::size_t rows = 0; + if (KimchiParamsType::circuit_params::lookup_columns > 0) { + rows += KimchiParamsType::circuit_params::lookup_columns * mul_component::rows_amount; + + rows += 2 * mul_component::rows_amount; + + if (KimchiParamsType::circuit_params::lookup_runtime) { + rows += mul_component::rows_amount; + } + } + + return rows; + } + public: constexpr static const std::size_t rows_amount = KimchiParamsType::witness_columns * mul_component::rows_amount // w + mul_component::rows_amount // z + (KimchiParamsType::permut_size - 1) * mul_component::rows_amount // s + + lookup_rows() + mul_component::rows_amount // generic + mul_component::rows_amount; // poseidon constexpr static const std::size_t gates_amount = 0; @@ -133,8 +149,22 @@ namespace nil { row += mul_component::rows_amount; } // lookup - if (KimchiParamsType::use_lookup) { - // TODO + if (KimchiParamsType::circuit_params::lookup_columns > 0) { + for (std::size_t i = 0; i < KimchiParamsType::circuit_params::lookup_columns; i++) { + output.lookup.sorted[i] = typename mul_component::result_type(row).output; + row += mul_component::rows_amount; + } + + output.lookup.aggreg = typename mul_component::result_type(row).output; + row += mul_component::rows_amount; + + output.lookup.table = typename mul_component::result_type(row).output; + row += mul_component::rows_amount; + + if (KimchiParamsType::circuit_params::lookup_runtime) { + output.lookup.runtime = typename mul_component::result_type(row).output; + row += mul_component::rows_amount; + } } // generic_selector output.generic_selector = typename mul_component::result_type(row).output; @@ -169,8 +199,26 @@ namespace nil { row += mul_component::rows_amount; } // lookup - if (KimchiParamsType::use_lookup) { - // TODO + if (KimchiParamsType::circuit_params::lookup_columns > 0) { + for (std::size_t i = 0; i < KimchiParamsType::circuit_params::lookup_columns; i++) { + zk::components::generate_circuit(bp,assignment, + {params.evals.lookup.sorted[i], params.x}, row); + row += mul_component::rows_amount; + } + + zk::components::generate_circuit(bp,assignment, + {params.evals.lookup.aggreg, params.x}, row); + row += mul_component::rows_amount; + + zk::components::generate_circuit(bp,assignment, + {params.evals.lookup.table, params.x}, row); + row += mul_component::rows_amount; + + if (KimchiParamsType::circuit_params::lookup_runtime) { + zk::components::generate_circuit(bp,assignment, + {params.evals.lookup.runtime, params.x}, row); + row += mul_component::rows_amount; + } } // generic_selector zk::components::generate_circuit(bp, assignment, @@ -181,7 +229,8 @@ namespace nil { {params.evals.poseidon_selector, params.x}, row); row += mul_component::rows_amount; - generate_copy_constraints(bp, assignment, params, start_row_index); + assert(row == start_row_index + rows_amount); + return result_type(start_row_index); } @@ -208,8 +257,26 @@ namespace nil { row += mul_component::rows_amount; } // lookup - if (KimchiParamsType::use_lookup) { - // TODO + if (KimchiParamsType::circuit_params::lookup_columns > 0) { + for (std::size_t i = 0; i < KimchiParamsType::circuit_params::lookup_columns; i++) { + mul_component::generate_assignments(assignment, + {params.evals.lookup.sorted[i], params.x}, row); + row += mul_component::rows_amount; + } + + mul_component::generate_assignments(assignment, + {params.evals.lookup.aggreg, params.x}, row); + row += mul_component::rows_amount; + + mul_component::generate_assignments(assignment, + {params.evals.lookup.table, params.x}, row); + row += mul_component::rows_amount; + + if (KimchiParamsType::circuit_params::lookup_runtime) { + mul_component::generate_assignments(assignment, + {params.evals.lookup.runtime, params.x}, row); + row += mul_component::rows_amount; + } } // generic_selector mul_component::generate_assignments(assignment, @@ -220,21 +287,9 @@ namespace nil { {params.evals.poseidon_selector, params.x}, row); row += mul_component::rows_amount; - return result_type(start_row_index); - } + assert(row == start_row_index + rows_amount); - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { - - } - - static void generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + return result_type(start_row_index); } }; } // namespace components diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/oracles_scalar/ft_eval.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/oracles_scalar/ft_eval.hpp index f38c4ee3dd..3d16b57c63 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/oracles_scalar/ft_eval.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/oracles_scalar/ft_eval.hpp @@ -374,8 +374,9 @@ namespace nil { // evaluate constant term expression var pt = constant_term_component::generate_circuit(bp, assignment, - {index_terms_list::constant_term_str, params.alpha_powers[1], params.beta, params.gamma, params.joint_combiner, - params.combined_evals}, row).output; + {index_terms_list::constant_term_str, params.zeta, + params.alpha_powers[1], params.beta, params.gamma, params.joint_combiner, + params.combined_evals, params.verifier_index.omega, params.verifier_index.domain_size}, row).output; row += constant_term_component::rows_amount; ft_eval0 = zk::components::generate_circuit(bp, @@ -569,8 +570,9 @@ namespace nil { // evaluate constant term expression var pt = constant_term_component::generate_assignments(assignment, - {index_terms_list::constant_term_str, params.alpha_powers[1], params.beta, params.gamma, params.joint_combiner, - params.combined_evals}, row).output; + {index_terms_list::constant_term_str, params.zeta, + params.alpha_powers[1], params.beta, params.gamma, params.joint_combiner, + params.combined_evals, params.verifier_index.omega, params.verifier_index.domain_size}, row).output; row += constant_term_component::rows_amount; ft_eval0 = sub_component::generate_assignments( diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/proof.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/proof.hpp index 3a72003f08..ac0a25e52c 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/proof.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/proof.hpp @@ -119,12 +119,16 @@ namespace nil { zk::components::kimchi_commitment_type; + using witness_comm_type = typename + zk::components::kimchi_commitment_type; + using opening_proof_type = typename zk::components::kimchi_opening_proof_base; struct commitments { - std::array witness_comm; commitment_type lookup_runtime_comm; commitment_type table_comm; diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/zkpm_evaluate.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/zkpm_evaluate.hpp index fff005373f..ff4df0d225 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/zkpm_evaluate.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/detail/zkpm_evaluate.hpp @@ -103,7 +103,7 @@ namespace nil { constexpr static const std::size_t zk_rows = 3; public: - constexpr static const std::size_t rows_amount = exp_component::rows_amount + constexpr static const std::size_t rows_amount = 1 + exp_component::rows_amount + 4 * mul_component::rows_amount + 3 * sub_component::rows_amount; constexpr static const std::size_t gates_amount = 0; @@ -131,6 +131,7 @@ namespace nil { var domain_size = var(0, start_row_index, false, var::column_type::constant); std::size_t row = start_row_index; + row++; // skip row for constants in exp_component result_type result(row); @@ -163,6 +164,7 @@ namespace nil { var domain_size = var(0, start_row_index, false, var::column_type::constant); std::size_t row = start_row_index; + row++; // skip row for constants in exp_component result_type result(row); diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/prepare_batch_scalar.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/prepare_batch_scalar.hpp index 5d053efd05..67fdbd3b14 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/prepare_batch_scalar.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/prepare_batch_scalar.hpp @@ -111,6 +111,8 @@ namespace nil { using batch_proof = batch_evaluation_proof_scalar; + using kimchi_constants = zk::components::kimchi_inner_constants; + using verifier_index_type = kimchi_verifier_index_scalar; using argument_type = typename verifier_index_type::argument_type; @@ -138,9 +140,8 @@ namespace nil { constexpr static const std::size_t rows_amount = rows(); constexpr static const std::size_t gates_amount = 0; - constexpr static const std::size_t f_comm_msm_size = 1 - + generic_scalars_component::output_size - + verifier_index_type::constraints_amount; + constexpr static const std::size_t f_comm_msm_size = + kimchi_constants::f_comm_msm_size; struct params_type { verifier_index_type &verifier_index; @@ -213,10 +214,13 @@ namespace nil { auto index_scalars = index_terms_scalars_component::generate_circuit( bp, assignment, { + oracles_output.oracles.zeta, oracles_output.oracles.alpha, params.fq_output.beta, params.fq_output.gamma, params.fq_output.joint_combiner, - oracles_output.combined_evals}, row + oracles_output.combined_evals, + params.verifier_index.omega, + params.verifier_index.domain_size}, row ).output; row += index_terms_scalars_component::rows_amount; @@ -297,10 +301,13 @@ namespace nil { auto index_scalars = index_terms_scalars_component::generate_assignments( assignment, { + oracles_output.oracles.zeta, oracles_output.oracles.alpha, params.fq_output.beta, params.fq_output.gamma, params.fq_output.joint_combiner, - oracles_output.combined_evals}, row + oracles_output.combined_evals, + params.verifier_index.omega, + params.verifier_index.domain_size}, row ).output; row += index_terms_scalars_component::rows_amount; for(std::size_t i = 0; i < index_scalars.size(); i++) { diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/proof_system/circuit_description.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/proof_system/circuit_description.hpp index dffce6a52d..c5f755825b 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/proof_system/circuit_description.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/proof_system/circuit_description.hpp @@ -43,6 +43,9 @@ namespace nil { static const std::size_t poseidon_gates_count = 15; static const std::size_t ec_arithmetic_gates_count = 4; + + static const std::size_t lookup_columns = 0; + static const bool lookup_runtime = false; }; } // namespace components } // namespace zk diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/proof_system/kimchi_commitment_params.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/proof_system/kimchi_commitment_params.hpp index c55a7428b3..867100b0f7 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/proof_system/kimchi_commitment_params.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/proof_system/kimchi_commitment_params.hpp @@ -46,7 +46,10 @@ namespace nil { constexpr static std::size_t split_poly_eval_size = max_poly_size == (1 << eval_rounds) ? 1 : 2; constexpr static std::size_t srs_len = SrsLen; - constexpr static std::size_t shifted_commitment_split = 1; // TODO + // TODO we can set commitments size values from template but for now it looks like we can just fix it + constexpr static std::size_t shifted_commitment_split = 1; + constexpr static std::size_t max_comm_size = 1; + constexpr static std::size_t w_comm_size = 1; }; } // namespace components } // namespace zk diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/types/evaluation_proof.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/types/evaluation_proof.hpp index 30a03dcdeb..e4f16d9c4f 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/types/evaluation_proof.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/types/evaluation_proof.hpp @@ -39,16 +39,16 @@ namespace nil { template struct kimchi_lookup_evaluations { - /// sorted lookup table polynomial - // pub sorted: Vec, - // /// lookup aggregation polynomial - // pub aggreg: Field, - // // TODO: May be possible to optimize this away? - // /// lookup table polynomial - // pub table: Field, + using var = snark::plonk_variable; + + std::array sorted; + + var aggreg; + var table; + + var runtime; - // /// Optionally, a runtime table polynomial. - // pub runtime: Option, kimchi_lookup_evaluations() { } }; diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/verifier_base_field.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/verifier_base_field.hpp index 9fc2014057..8484f5fbc9 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/verifier_base_field.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/verifier_base_field.hpp @@ -145,6 +145,10 @@ namespace nil { zk::components::kimchi_commitment_type; + using w_comm_type = typename + zk::components::kimchi_commitment_type; + using batch_verify_component = zk::components::batch_verify_base_field static void parse_commitments( - std::array, + std::array, f_comm_base_size> &unshifted_commitments, const std::array comms, std::size_t &comm_idx) { for(std::size_t j = 0; j < CommSize; j ++) { for(std::size_t k = 0; k < comms[j].parts.size(); k++) { - unshifted_commitments[comm_idx][k] = comms[j].parts[k]; + unshifted_commitments[comm_idx].push_back(comms[j].parts[k]); } comm_idx++; } } - static std::array, - f_comm_base_size> prepare_f_comm_unshifted(const params_type ¶ms) { + static std::array, + f_comm_base_size> prepare_f_comm(const params_type ¶ms) { - std::array, + std::array, f_comm_base_size> unshifted_commitments; std::size_t comm_idx = 0; @@ -300,10 +304,9 @@ namespace nil { //get digest from transcript - // ft_comm - std::array, f_comm_base_size> - unshifted_commitments = prepare_f_comm_unshifted(params); + // f_comm + std::array, f_comm_base_size> + unshifted_commitments = prepare_f_comm(params); //to-do: U = zero() typename CurveType::template g1_type::value_type U = @@ -312,13 +315,15 @@ namespace nil { assignment.witness(W1)[row] = U.Y; std::size_t urow = row; std::array shifted_commitment_type_unshifted; - for(std::size_t j = 0; j < KimchiCommitmentParamsType::shifted_commitment_split; j ++) { + KimchiCommitmentParamsType::max_comm_size> shifted_commitment_type_unshifted; + for(std::size_t j = 0; j < KimchiCommitmentParamsType::max_comm_size; j ++) { std::array part_unshifted_commitments; std::array part_scalars; for (std::size_t k = 0; k < f_comm_base_size; k++) { - part_unshifted_commitments[k] = unshifted_commitments[j][k]; - part_scalars[k] = params.proofs[i].scalars[k]; + if (j < unshifted_commitments[k].size()) { + part_unshifted_commitments[k] = unshifted_commitments[k][j]; + part_scalars[k] = params.proofs[i].scalars[k]; + } } auto res = msm_component::generate_assignments(assignment, {part_scalars, part_unshifted_commitments}, row); shifted_commitment_type_unshifted[j] = {res.sum.X, res.sum.Y}; @@ -473,24 +478,25 @@ namespace nil { // auto zeta = transcript.squeeze(). to_field(); //get digest from transcript - std::array, f_comm_base_size> - unshifted_commitments = prepare_f_comm_unshifted(params); + std::array, f_comm_base_size> + unshifted_commitments = prepare_f_comm(params); //to-do: U = zero() std::size_t urow = row; std::array shifted_commitment_type_unshifted; - for(std::size_t j = 0; j < KimchiCommitmentParamsType::shifted_commitment_split; j ++) { + KimchiCommitmentParamsType::max_comm_size> shifted_commitment_type_unshifted; + for(std::size_t j = 0; j < KimchiCommitmentParamsType::max_comm_size; j ++) { std::array part_unshifted_commitments; std::array part_scalars; for (std::size_t k = 0; k < f_comm_base_size; k++) { - part_unshifted_commitments[k] = unshifted_commitments[j][k]; - part_scalars[k] = params.proofs[i].scalars[k]; + if (j < unshifted_commitments[k].size()) { + part_unshifted_commitments[k] = unshifted_commitments[k][j]; + part_scalars[k] = params.proofs[i].scalars[k]; + } } auto res = msm_component::generate_circuit(bp, assignment, {part_scalars, part_unshifted_commitments}, row); shifted_commitment_type_unshifted[j] = {res.sum.X, res.sum.Y}; - row+= msm_component::rows_amount; + row += msm_component::rows_amount; } var_ec_point chunked_shifted_commitment_type_unshifted = {var(0, urow, false), var(1, urow, false)}; row++; @@ -611,4 +617,4 @@ namespace nil { } // namespace crypto3 } // namespace nil -#endif // CRYPTO3_ZK_BLUEPRINT_VARIABLE_BASE_MULTIPLICATION_EDWARD25519_HPP +#endif // CRYPTO3_ZK_BLUEPRINT_BASE_FIELD_HPP diff --git a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/verifier_index.hpp b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/verifier_index.hpp index 8c8356d0da..1323ef112a 100644 --- a/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/verifier_index.hpp +++ b/include/nil/crypto3/zk/components/systems/snark/plonk/kimchi/verifier_index.hpp @@ -53,8 +53,6 @@ namespace nil { Generic, }; - constexpr static const std::size_t constraints_amount = 2; - // nil::crypto3::math::evaluation_domain domain; std::size_t max_quot_size; std::size_t domain_size; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8ebe473680..99a17c7a3b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -63,6 +63,7 @@ set(NON_NATIVE_TESTS_FILES "non_native/plonk/non_native_demo" "non_native/plonk/reduction" "non_native/plonk/ed25519" + "non_native/plonk/signatures_verification" "non_native/plonk/ec_point" ) @@ -79,6 +80,7 @@ set(PLONK_TESTS_FILES "algebra/curves/plonk/multi_scalar_multiplication" "hashes/plonk/poseidon" "hashes/plonk/sha256" + "hashes/plonk/sha512" "hashes/plonk/sha256_process" "hashes/plonk/sha512_process" "hashes/plonk/decomposition" @@ -99,8 +101,10 @@ set(PLONK_TESTS_FILES "verifiers/kimchi/detail/prev_chal_evals" "verifiers/kimchi/detail/ft_eval" "verifiers/kimchi/detail/combine_proof_evals" - "verifiers/kimchi/detail/index_terms_scalars" - "verifiers/kimchi/detail/rpn_expression" + "verifiers/kimchi/detail//constraints/index_terms_scalars" + "verifiers/kimchi/detail/constraints/rpn_expression" + "verifiers/kimchi/detail/constraints/vanishes_on_last_4_rows" + "verifiers/kimchi/detail/constraints/unnormalized_lagrange_basis" "verifiers/kimchi/detail/oracles_cip" "sponge/sponge" "sponge/oracles" diff --git a/test/detail/prepare_scalars.cpp b/test/detail/prepare_scalars.cpp index 422770011f..242108ce01 100644 --- a/test/detail/prepare_scalars.cpp +++ b/test/detail/prepare_scalars.cpp @@ -48,10 +48,10 @@ using namespace nil::crypto3; BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) -BOOST_AUTO_TEST_CASE(blueprint_plonk_prepare_scalars) { +BOOST_AUTO_TEST_CASE(blueprint_plonk_prepare_scalars_vesta) { auto start = std::chrono::high_resolution_clock::now(); - using curve_type = algebra::curves::pallas; + using curve_type = algebra::curves::vesta; using BlueprintFieldType = typename curve_type::scalar_field_type; constexpr std::size_t WitnessColumns = 15; constexpr std::size_t PublicInputColumns = 1; diff --git a/test/hashes/plonk/sha512.cpp b/test/hashes/plonk/sha512.cpp new file mode 100644 index 0000000000..191da628ef --- /dev/null +++ b/test/hashes/plonk/sha512.cpp @@ -0,0 +1,109 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2021-2022 Mikhail Komarov +// Copyright (c) 2021-2022 Nikita Kaskov +// Copyright (c) 2022 Alisa Cherniaeva +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#define BOOST_TEST_MODULE plonk_sha512_test + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include "../../test_plonk_component.hpp" + +#include + +using namespace nil::crypto3; + +BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) + +BOOST_AUTO_TEST_CASE(blueprint_plonk_sha512) { + auto start = std::chrono::high_resolution_clock::now(); + + using curve_type = algebra::curves::pallas; + using BlueprintFieldType = typename curve_type::base_field_type; + using FieldType = typename curve_type::base_field_type; + + constexpr std::size_t WitnessColumns = 9; + constexpr std::size_t PublicInputColumns = 5; + constexpr std::size_t ConstantColumns = 2; + constexpr std::size_t SelectorColumns = 10; + using hash_type = nil::crypto3::hashes::keccak_1600<256>; + constexpr std::size_t Lambda = 1; + + using ArithmetizationParams = + zk::snark::plonk_arithmetization_params; + using ArithmetizationType = zk::snark::plonk_constraint_system; + using AssignmentType = zk::blueprint_assignment_table; + using var = zk::snark::plonk_variable; + + using component_type = zk::components::sha512; + + std::array public_input = {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0}; + + std::array input_state_var = { // + var(0, 0, false, var::column_type::public_input), var(0, 1, false, var::column_type::public_input), + var(0, 2, false, var::column_type::public_input), var(0, 3, false, var::column_type::public_input), + var(0, 4, false, var::column_type::public_input), var(0, 5, false, var::column_type::public_input), + var(0, 6, false, var::column_type::public_input), var(0, 7, false, var::column_type::public_input), + var(0, 8, false, var::column_type::public_input), var(0, 9, false, var::column_type::public_input), + var(0, 10, false, var::column_type::public_input), var(0, 11, false, var::column_type::public_input), + var(0, 12, false, var::column_type::public_input), var(0, 13, false, var::column_type::public_input), + var(0, 14, false, var::column_type::public_input), var(0, 15, false, var::column_type::public_input), + var(0, 16, false, var::column_type::public_input), var(0, 17, false, var::column_type::public_input), + var(0, 18, false, var::column_type::public_input), var(0, 19, false, var::column_type::public_input)}; + + + + + typename component_type::params_type params = { + { {input_state_var[0],input_state_var[1],input_state_var[2],input_state_var[3]}, {input_state_var[4],input_state_var[5],input_state_var[6],input_state_var[7]}}, + { {input_state_var[8],input_state_var[9],input_state_var[10],input_state_var[11]}, {input_state_var[12],input_state_var[13],input_state_var[14],input_state_var[15]}}, + {input_state_var[16],input_state_var[17],input_state_var[18],input_state_var[19]} + }; + + auto result_check = [](AssignmentType &assignment, component_type::result_type &real_res) {}; + test_component(params, public_input, + result_check); + + auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); + std::cout << "Time_execution: " << duration.count() << "ms" << std::endl; +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/hashes/plonk/sha512_process.cpp b/test/hashes/plonk/sha512_process.cpp index d106cc7259..1bb694a3fe 100644 --- a/test/hashes/plonk/sha512_process.cpp +++ b/test/hashes/plonk/sha512_process.cpp @@ -109,18 +109,18 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_sha512_process) { message_schedule_array[i] = typename BlueprintFieldType::integral_type(public_input[8 + i].data); } for(std::size_t i = 16; i < 80; i ++){ - typename BlueprintFieldType::integral_type s0 = ((message_schedule_array[i - 15] >> 7)|((message_schedule_array[i - 15] << (64 - 7)) + typename BlueprintFieldType::integral_type s0 = ((message_schedule_array[i - 15] >> 1)|((message_schedule_array[i - 15] << (64 - 1)) & typename BlueprintFieldType::integral_type((typename BlueprintFieldType::value_type(2).pow(64) - 1).data))) ^ - ((message_schedule_array[i - 15] >> 18)|((message_schedule_array[i - 15] << (64 - 18)) + ((message_schedule_array[i - 15] >> 8)|((message_schedule_array[i - 15] << (64 - 8)) & typename BlueprintFieldType::integral_type((typename BlueprintFieldType::value_type(2).pow(64) - 1).data))) - ^ (message_schedule_array[i - 15] >> 3); - typename BlueprintFieldType::integral_type s1 = ((message_schedule_array[i - 2] >> 17)|((message_schedule_array[i - 2] << (64 - 17)) + ^ (message_schedule_array[i - 15] >> 7); + typename BlueprintFieldType::integral_type s1 = ((message_schedule_array[i - 2] >> 19)|((message_schedule_array[i - 2] << (64 - 19)) & typename BlueprintFieldType::integral_type((typename BlueprintFieldType::value_type(2).pow(64) - 1).data))) ^ - ((message_schedule_array[i - 2] >> 19)|((message_schedule_array[i - 2] << (64 - 19)) + ((message_schedule_array[i - 2] >> 61)|((message_schedule_array[i - 2] << (64 - 61)) & typename BlueprintFieldType::integral_type((typename BlueprintFieldType::value_type(2).pow(64) - 1).data))) - ^ (message_schedule_array[i - 2] >> 10); + ^ (message_schedule_array[i - 2] >> 6); message_schedule_array[i] = (message_schedule_array[i - 16] + s0 + s1 + message_schedule_array[i - 7])% - typename curve_type::base_field_type::integral_type(typename curve_type::base_field_type::value_type(2).pow(64).data); + typename curve_type::base_field_type::integral_type(typename curve_type::base_field_type::value_type(2).pow(64).data); } typename ArithmetizationType::field_type::integral_type a = typename ArithmetizationType::field_type::integral_type(public_input[0].data); typename ArithmetizationType::field_type::integral_type b = typename ArithmetizationType::field_type::integral_type(public_input[1].data); @@ -131,43 +131,22 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_sha512_process) { typename ArithmetizationType::field_type::integral_type g = typename ArithmetizationType::field_type::integral_type(public_input[6].data); typename ArithmetizationType::field_type::integral_type h = typename ArithmetizationType::field_type::integral_type(public_input[7].data); for(std::size_t i = 0; i < 80; i ++){ - typename BlueprintFieldType::integral_type S0 = ((a >> 2)|((a << (64 - 2)) + typename BlueprintFieldType::integral_type S0 = ((a >> 28)|((a << (64 - 28)) & typename BlueprintFieldType::integral_type((typename BlueprintFieldType::value_type(2).pow(64) - 1).data))) ^ - ((a >> 13)|((a << (64 - 13)) + ((a >> 34)|((a << (64 - 34)) & typename BlueprintFieldType::integral_type((typename BlueprintFieldType::value_type(2).pow(64) - 1).data))) - ^ ((a >> 22)|((a << (64 - 22)) + ^ ((a >> 39)|((a << (64 - 39)) & typename BlueprintFieldType::integral_type((typename BlueprintFieldType::value_type(2).pow(64) - 1).data))); - typename BlueprintFieldType::integral_type S1 = ((e >> 6)|((e << (64 - 6)) + + typename BlueprintFieldType::integral_type S1 = ((e >> 14)|((e << (64 - 14)) & typename BlueprintFieldType::integral_type((typename BlueprintFieldType::value_type(2).pow(64) - 1).data))) ^ - ((e >> 11)|((e << (64 - 11)) + ((e >> 18)|((e << (64 - 18)) & typename BlueprintFieldType::integral_type((typename BlueprintFieldType::value_type(2).pow(64) - 1).data))) - ^ ((e >> 25)|((e << (64 - 25)) + ^ ((e >> 41)|((e << (64 - 41)) & typename BlueprintFieldType::integral_type((typename BlueprintFieldType::value_type(2).pow(64) - 1).data))); + typename BlueprintFieldType::integral_type maj = (a & b) ^ (a & c) ^ (b & c); typename BlueprintFieldType::integral_type ch = (e & f) ^ ((~e)& g); - - /*std::vector e_bits(32); - for (std::size_t j = 0; j < 32; j++) { - e_bits[32 - j - 1] = multiprecision::bit_test(e, j); - } - std::vector f_bits(32); - for (std::size_t j = 0; j < 32; j++) { - f_bits[32 - j - 1] = multiprecision::bit_test(f, j); - } - std::vector g_bits(32); - for (std::size_t j = 0; j < 32; j++) { - g_bits[32 - j - 1] = multiprecision::bit_test(g, j); - } - std::vector sizes = {32}; - std::size_t base = 7; - std::array, 2> e_s = - component_type::split_and_sparse(e_bits, sizes, base); - - std::array, 2> f_s = - component_type::split_and_sparse(f_bits, sizes, base); - - std::array, 2> g_s = - component_type::split_and_sparse(g_bits, sizes, base);*/ typename BlueprintFieldType::integral_type tmp1 = h + S1 + ch + round_constant[i] + message_schedule_array[i]; typename BlueprintFieldType::integral_type tmp2 = S0 + maj; h = g; diff --git a/test/non_native/plonk/reduction.cpp b/test/non_native/plonk/reduction.cpp index be980173c6..9dcc9b346c 100644 --- a/test/non_native/plonk/reduction.cpp +++ b/test/non_native/plonk/reduction.cpp @@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(blueprint_variable_base_decomposition_edward25519) { constexpr std::size_t WitnessColumns = 9; constexpr std::size_t PublicInputColumns = 1; constexpr std::size_t ConstantColumns = 0; - constexpr std::size_t SelectorColumns = 2; + constexpr std::size_t SelectorColumns = 3; using hash_type = nil::crypto3::hashes::keccak_1600<256>; constexpr std::size_t Lambda = 40; @@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(blueprint_variable_base_decomposition_edward25519) { using AssignmentType = zk::blueprint_assignment_table; using component_type = zk::components::reduction; - std::vector public_input = {1,0,0,0,0,0,0,0}; + std::vector public_input = {0,0,0,0,0,0,0,1}; std::array input_state_var = {var(0, 0, false, var::column_type::public_input), var(0, 1, false, var::column_type::public_input), var(0, 2, false, var::column_type::public_input), @@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(blueprint_variable_base_decomposition_edward25519) { typename component_type::params_type params = {input_state_var}; auto result_check = [](AssignmentType &assignment, component_type::result_type &real_res) { - // std::cout<( diff --git a/test/non_native/plonk/signatures_verification.cpp b/test/non_native/plonk/signatures_verification.cpp new file mode 100644 index 0000000000..b52b8df35c --- /dev/null +++ b/test/non_native/plonk/signatures_verification.cpp @@ -0,0 +1,354 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2022 Alisa Cherniaeva +// +// 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_signatures_verification_test + +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "../../test_plonk_component.hpp" + +using namespace nil::crypto3; + +BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) + +template +typename ed25519_type::scalar_field_type::value_type sha512(typename ed25519_type::template g1_type::value_type R, + typename ed25519_type::template g1_type::value_type pk, std::array M) { + std::array + round_constant = { + 0x428a2f98d728ae22_cppui64, 0x7137449123ef65cd_cppui64, 0xb5c0fbcfec4d3b2f_cppui64, 0xe9b5dba58189dbbc_cppui64, + 0x3956c25bf348b538_cppui64, 0x59f111f1b605d019_cppui64, 0x923f82a4af194f9b_cppui64, 0xab1c5ed5da6d8118_cppui64, + 0xd807aa98a3030242_cppui64, 0x12835b0145706fbe_cppui64, 0x243185be4ee4b28c_cppui64, 0x550c7dc3d5ffb4e2_cppui64, + 0x72be5d74f27b896f_cppui64, 0x80deb1fe3b1696b1_cppui64, 0x9bdc06a725c71235_cppui64, 0xc19bf174cf692694_cppui64, + 0xe49b69c19ef14ad2_cppui64, 0xefbe4786384f25e3_cppui64, 0x0fc19dc68b8cd5b5_cppui64, 0x240ca1cc77ac9c65_cppui64, + 0x2de92c6f592b0275_cppui64, 0x4a7484aa6ea6e483_cppui64, 0x5cb0a9dcbd41fbd4_cppui64, 0x76f988da831153b5_cppui64, + 0x983e5152ee66dfab_cppui64, 0xa831c66d2db43210_cppui64, 0xb00327c898fb213f_cppui64, 0xbf597fc7beef0ee4_cppui64, + 0xc6e00bf33da88fc2_cppui64, 0xd5a79147930aa725_cppui64, 0x06ca6351e003826f_cppui64, 0x142929670a0e6e70_cppui64, + 0x27b70a8546d22ffc_cppui64, 0x2e1b21385c26c926_cppui64, 0x4d2c6dfc5ac42aed_cppui64, 0x53380d139d95b3df_cppui64, + 0x650a73548baf63de_cppui64, 0x766a0abb3c77b2a8_cppui64, 0x81c2c92e47edaee6_cppui64, 0x92722c851482353b_cppui64, + 0xa2bfe8a14cf10364_cppui64, 0xa81a664bbc423001_cppui64, 0xc24b8b70d0f89791_cppui64, 0xc76c51a30654be30_cppui64, + 0xd192e819d6ef5218_cppui64, 0xd69906245565a910_cppui64, 0xf40e35855771202a_cppui64, 0x106aa07032bbd1b8_cppui64, + 0x19a4c116b8d2d0c8_cppui64, 0x1e376c085141ab53_cppui64, 0x2748774cdf8eeb99_cppui64, 0x34b0bcb5e19b48a8_cppui64, + 0x391c0cb3c5c95a63_cppui64, 0x4ed8aa4ae3418acb_cppui64, 0x5b9cca4f7763e373_cppui64, 0x682e6ff3d6b2b8a3_cppui64, + 0x748f82ee5defb2fc_cppui64, 0x78a5636f43172f60_cppui64, 0x84c87814a1f0ab72_cppui64, 0x8cc702081a6439ec_cppui64, + 0x90befffa23631e28_cppui64, 0xa4506cebde82bde9_cppui64, 0xbef9a3f7b2c67915_cppui64, 0xc67178f2e372532b_cppui64, + 0xca273eceea26619c_cppui64, 0xd186b8c721c0c207_cppui64, 0xeada7dd6cde0eb1e_cppui64, 0xf57d4f7fee6ed178_cppui64, + 0x06f067aa72176fba_cppui64, 0x0a637dc5a2c898a6_cppui64, 0x113f9804bef90dae_cppui64, 0x1b710b35131c471b_cppui64, + 0x28db77f523047d84_cppui64, 0x32caab7b40c72493_cppui64, 0x3c9ebe0a15c9bebc_cppui64, 0x431d67c49c100d4c_cppui64, + 0x4cc5d4becb3e42b6_cppui64, 0x597f299cfc657e2a_cppui64, 0x5fcb6fab3ad6faec_cppui64, 0x6c44198c4a475817_cppui64}; + + std::array message_schedule_array; + std::array public_input = {0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179}; + typename ed25519_type::base_field_type::integral_type one = 1; + typename ed25519_type::base_field_type::integral_type mask = (one << 64) - 1; + typename ed25519_type::base_field_type::integral_type Rx = typename ed25519_type::base_field_type::integral_type(R.X.data); + typename ed25519_type::base_field_type::integral_type Ry = typename ed25519_type::base_field_type::integral_type(R.Y.data); + typename ed25519_type::base_field_type::integral_type pkx = typename ed25519_type::base_field_type::integral_type(pk.X.data); + typename ed25519_type::base_field_type::integral_type pky = typename ed25519_type::base_field_type::integral_type(pk.Y.data); + message_schedule_array[0] = Rx & mask; + message_schedule_array[1] = (Rx >> 64) & mask; + message_schedule_array[2] = (Rx >> 128) & mask; + message_schedule_array[3] = ((Rx >> 192) & mask) + (Ry & 1) * (one << 63); + message_schedule_array[4] = (Ry >> 1) & mask; + message_schedule_array[5] = (Ry >> 65) & mask; + message_schedule_array[6] = (Ry >> 129) & mask; + message_schedule_array[7] = ((Ry >> 193) & mask) + (pkx & 3) * (one << 62); + message_schedule_array[8] = (pkx >> 2) & mask; + message_schedule_array[9] = (pkx >> 66) & mask; + message_schedule_array[10] = (pkx >> 130) & mask; + message_schedule_array[11] = ((pkx >> 194) & mask) + (pky & 7) * (one << 61); + message_schedule_array[12] = (pky >> 3) & mask; + message_schedule_array[13] = (pky >> 67) & mask; + message_schedule_array[14] = (pky >> 131) & mask; + message_schedule_array[15] = ((pky >> 195) & mask) + (M[0] & 15) * (one << 60); + for(std::size_t i = 16; i < 80; i ++){ + typename ed25519_type::base_field_type::integral_type s0 = ((message_schedule_array[i - 15] >> 1)|((message_schedule_array[i - 15] << (64 - 1)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) ^ + ((message_schedule_array[i - 15] >> 8)|((message_schedule_array[i - 15] << (64 - 8)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) + ^ (message_schedule_array[i - 15] >> 7); + typename ed25519_type::base_field_type::integral_type s1 = ((message_schedule_array[i - 2] >> 19)|((message_schedule_array[i - 2] << (64 - 19)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) ^ + ((message_schedule_array[i - 2] >> 61)|((message_schedule_array[i - 2] << (64 - 61)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) + ^ (message_schedule_array[i - 2] >> 6); + message_schedule_array[i] = (message_schedule_array[i - 16] + s0 + s1 + message_schedule_array[i - 7])% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data); + } + typename ed25519_type::base_field_type::integral_type a = typename ed25519_type::base_field_type::integral_type(public_input[0]); + typename ed25519_type::base_field_type::integral_type b = typename ed25519_type::base_field_type::integral_type(public_input[1]); + typename ed25519_type::base_field_type::integral_type c = typename ed25519_type::base_field_type::integral_type(public_input[2]); + typename ed25519_type::base_field_type::integral_type d = typename ed25519_type::base_field_type::integral_type(public_input[3]); + typename ed25519_type::base_field_type::integral_type e = typename ed25519_type::base_field_type::integral_type(public_input[4]); + typename ed25519_type::base_field_type::integral_type f = typename ed25519_type::base_field_type::integral_type(public_input[5]); + typename ed25519_type::base_field_type::integral_type g = typename ed25519_type::base_field_type::integral_type(public_input[6]); + typename ed25519_type::base_field_type::integral_type h = typename ed25519_type::base_field_type::integral_type(public_input[7]); + for(std::size_t i = 0; i < 80; i ++){ + typename ed25519_type::base_field_type::integral_type S0 = ((a >> 28)|((a << (64 - 28)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) ^ + ((a >> 34)|((a << (64 - 34)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) + ^ ((a >> 39)|((a << (64 - 39)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))); + + typename ed25519_type::base_field_type::integral_type S1 = ((e >> 14)|((e << (64 - 14)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) ^ + ((e >> 18)|((e << (64 - 18)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) + ^ ((e >> 41)|((e << (64 - 41)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))); + + typename ed25519_type::base_field_type::integral_type maj = (a & b) ^ (a & c) ^ (b & c); + typename ed25519_type::base_field_type::integral_type ch = (e & f) ^ ((~e)& g); + typename ed25519_type::base_field_type::integral_type tmp1 = h + S1 + ch + round_constant[i] + message_schedule_array[i]; + typename ed25519_type::base_field_type::integral_type tmp2 = S0 + maj; + h = g; + g = f; + f = e; + e = (d + tmp1)% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data); + d = c; + c = b; + b = a; + a = (tmp1 + tmp2)% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data); + } + std::array output_state = {(a + typename ed25519_type::base_field_type::integral_type(public_input[0]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (b + typename ed25519_type::base_field_type::integral_type(public_input[1]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (c + typename ed25519_type::base_field_type::integral_type(public_input[2]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (d + typename ed25519_type::base_field_type::integral_type(public_input[3]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (e + typename ed25519_type::base_field_type::integral_type(public_input[4]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (f + typename ed25519_type::base_field_type::integral_type(public_input[5]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (g + typename ed25519_type::base_field_type::integral_type(public_input[6]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (h + typename ed25519_type::base_field_type::integral_type(public_input[7]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data)}; + typename ed25519_type::base_field_type::integral_type bits_amount = 255*4+256; + message_schedule_array[0] = ((M[0] >> 4) & mask) + (M[1] & 3) * (one << 62); + message_schedule_array[1] = (M[1] >> 2) & mask; + message_schedule_array[2] = M[2] & mask; + message_schedule_array[3] = ((M[2] >> 64) + (M[3]) * (one << 2) + 1 * (one << 60)) << 3; + message_schedule_array[4] = 0; + message_schedule_array[5] = 0; + message_schedule_array[6] = 0; + message_schedule_array[7] = 0; + message_schedule_array[8] = 0; + message_schedule_array[9] = 0; + message_schedule_array[10] = 0; + message_schedule_array[11] = 0; + message_schedule_array[12] = 0; + message_schedule_array[13] = 0; + message_schedule_array[14] = 0; + message_schedule_array[15] = bits_amount; + for(std::size_t i = 16; i < 80; i ++){ + typename ed25519_type::base_field_type::integral_type s0 = ((message_schedule_array[i - 15] >> 1)|((message_schedule_array[i - 15] << (64 - 1)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) ^ + ((message_schedule_array[i - 15] >> 8)|((message_schedule_array[i - 15] << (64 - 8)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) + ^ (message_schedule_array[i - 15] >> 7); + typename ed25519_type::base_field_type::integral_type s1 = ((message_schedule_array[i - 2] >> 19)|((message_schedule_array[i - 2] << (64 - 19)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) ^ + ((message_schedule_array[i - 2] >> 61)|((message_schedule_array[i - 2] << (64 - 61)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) + ^ (message_schedule_array[i - 2] >> 6); + message_schedule_array[i] = (message_schedule_array[i - 16] + s0 + s1 + message_schedule_array[i - 7])% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data); + } + a = typename ed25519_type::base_field_type::integral_type(output_state[0]); + b = typename ed25519_type::base_field_type::integral_type(output_state[1]); + c = typename ed25519_type::base_field_type::integral_type(output_state[2]); + d = typename ed25519_type::base_field_type::integral_type(output_state[3]); + e = typename ed25519_type::base_field_type::integral_type(output_state[4]); + f = typename ed25519_type::base_field_type::integral_type(output_state[5]); + g = typename ed25519_type::base_field_type::integral_type(output_state[6]); + h = typename ed25519_type::base_field_type::integral_type(output_state[7]); + for(std::size_t i = 0; i < 80; i ++){ + typename ed25519_type::base_field_type::integral_type S0 = ((a >> 28)|((a << (64 - 28)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) ^ + ((a >> 34)|((a << (64 - 34)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) + ^ ((a >> 39)|((a << (64 - 39)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))); + + typename ed25519_type::base_field_type::integral_type S1 = ((e >> 14)|((e << (64 - 14)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) ^ + ((e >> 18)|((e << (64 - 18)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))) + ^ ((e >> 41)|((e << (64 - 41)) + & typename ed25519_type::base_field_type::integral_type((typename ed25519_type::base_field_type::value_type(2).pow(64) - 1).data))); + + typename ed25519_type::base_field_type::integral_type maj = (a & b) ^ (a & c) ^ (b & c); + typename ed25519_type::base_field_type::integral_type ch = (e & f) ^ ((~e)& g); + typename ed25519_type::base_field_type::integral_type tmp1 = h + S1 + ch + round_constant[i] + message_schedule_array[i]; + typename ed25519_type::base_field_type::integral_type tmp2 = S0 + maj; + h = g; + g = f; + f = e; + e = (d + tmp1)% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data); + d = c; + c = b; + b = a; + a = (tmp1 + tmp2)% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data); + } + std::array result_state1 = {(a + typename ed25519_type::base_field_type::integral_type(output_state[0]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (b + typename ed25519_type::base_field_type::integral_type(output_state[1]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (c + typename ed25519_type::base_field_type::integral_type(output_state[2]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (d + typename ed25519_type::base_field_type::integral_type(output_state[3]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (e + typename ed25519_type::base_field_type::integral_type(output_state[4]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (f + typename ed25519_type::base_field_type::integral_type(output_state[5]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (g + typename ed25519_type::base_field_type::integral_type(output_state[6]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data), + (h + typename ed25519_type::base_field_type::integral_type(output_state[7]))% + typename ed25519_type::base_field_type::integral_type(typename ed25519_type::base_field_type::value_type(2).pow(64).data)}; + typename ed25519_type::scalar_field_type::value_type two = 2; + typename ed25519_type::scalar_field_type::value_type res = result_state1[0] + result_state1[1] * two.pow(64) + result_state1[2] * two.pow(128) + + result_state1[3] * two.pow(192) + result_state1[4] * two.pow(256) + result_state1[5] * two.pow(320) + result_state1[6] * two.pow(384) + + result_state1[7] * two.pow(448); + + return res; + } + +BOOST_AUTO_TEST_CASE(blueprint_signatures_verification) { + auto start = std::chrono::high_resolution_clock::now(); + + using curve_type = algebra::curves::pallas; + using ed25519_type = algebra::curves::ed25519; + using BlueprintFieldType = typename curve_type::base_field_type; + constexpr std::size_t WitnessColumns = 9; + constexpr std::size_t PublicInputColumns = 1; + constexpr std::size_t ConstantColumns = 1; + constexpr std::size_t SelectorColumns = 21; + using ArithmetizationParams = + zk::snark::plonk_arithmetization_params; + using ArithmetizationType = zk::snark::plonk_constraint_system; + using AssignmentType = zk::blueprint_assignment_table; + using hash_type = nil::crypto3::hashes::keccak_1600<256>; + constexpr std::size_t Lambda = 1; + + using var = zk::snark::plonk_variable; + constexpr const std::size_t k = 1; + using component_type = zk::components::signatures_verification; + using ed25519_component = zk::components::eddsa25519; + using var_ec_point = typename ed25519_component::params_type::var_ec_point; + using signature = typename ed25519_component::params_type::signature; + + ed25519_type::template g1_type::value_type B = + ed25519_type::template g1_type::value_type::one(); + auto M = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001_cppui256; + + std::vector public_input; + typename ed25519_type::base_field_type::integral_type base = 1; + typename ed25519_type::base_field_type::integral_type mask = (base << 66) - 1; + std::array Signatures; + std::array Public_keys; + std::array::value_type, k> Signatures_point; + std::array Signatures_scalar; + std::array::value_type, k> Public_keys_values; + for(std::size_t i = 0; i < k; i++) { + ed25519_type::scalar_field_type::value_type r = algebra::random_element(); + ed25519_type::scalar_field_type::value_type c = algebra::random_element(); + ed25519_type::template g1_type::value_type R = r*B; + Signatures_point[i] = R; + ed25519_type::template g1_type::value_type P = c*B; + Public_keys_values[i] = P; + auto sha_output = sha512(R, P, {ed25519_type::base_field_type::integral_type(M & mask), ed25519_type::base_field_type::integral_type((M >> 66) & mask) + , ed25519_type::base_field_type::integral_type((M >> 132) & mask), ed25519_type::base_field_type::integral_type((M >> 198) & mask)}); + ed25519_type::scalar_field_type::value_type s = r + sha_output*c; + Signatures_scalar[i] = s; + ed25519_type::base_field_type::integral_type Rx = ed25519_type::base_field_type::integral_type(R.X.data); + ed25519_type::base_field_type::integral_type Ry = ed25519_type::base_field_type::integral_type(R.Y.data); + ed25519_type::base_field_type::integral_type Px = ed25519_type::base_field_type::integral_type(P.X.data); + ed25519_type::base_field_type::integral_type Py = ed25519_type::base_field_type::integral_type(P.Y.data); + public_input.insert(public_input.end(), {Rx & mask, (Rx >> 66) & mask, (Rx >> 132) & mask, (Rx >> 198) & mask, + Ry & mask, (Ry >> 66) & mask, (Ry >> 132) & mask, (Ry >> 198) & mask, typename BlueprintFieldType::integral_type(s.data), + Px & mask, (Px >> 66) & mask, (Px >> 132) & mask, (Px >> 198) & mask, + Py & mask, (Py >> 66) & mask, (Py >> 132) & mask, (Py >> 198) & mask}); + std::array e_R_x = {var(0, i*17 + 0, false, var::column_type::public_input), var(0, i*17 + 1, false, var::column_type::public_input), + var(0, i*17 + 2, false, var::column_type::public_input), var(0, i*17 + 3, false, var::column_type::public_input)}; + std::array e_R_y = {var(0, i*17 + 4, false, var::column_type::public_input), var(0, i*17 + 5, false, var::column_type::public_input), + var(0, i*17 + 6, false, var::column_type::public_input), var(0, i*17 + 7, false, var::column_type::public_input)}; + var_ec_point R_i = {e_R_x, e_R_y}; + var e_s = var(0, i*17 + 8, false, var::column_type::public_input); + Signatures[i] = {R_i, e_s}; + std::array pk_x = {var(0, i*17 + 9, false, var::column_type::public_input), var(0, i*17 + 10, false, var::column_type::public_input), + var(0, i*17 + 11, false, var::column_type::public_input), var(0, i*17 + 12, false, var::column_type::public_input)}; + std::array pk_y = {var(0, i*17 + 13, false, var::column_type::public_input), var(0, i*17 + 14, false, var::column_type::public_input), + var(0, i*17 + 15, false, var::column_type::public_input), var(0, i*17 + 16, false, var::column_type::public_input)}; + Public_keys[i] = {pk_x, pk_y}; + } + public_input.insert(public_input.end(), {ed25519_type::base_field_type::integral_type(M & mask), ed25519_type::base_field_type::integral_type((M >> 66) & mask) + , ed25519_type::base_field_type::integral_type((M >> 132) & mask), ed25519_type::base_field_type::integral_type((M >> 198) & mask)}); + + std::array M_var = {var(0, k*17, false, var::column_type::public_input), var(0, k*17 + 1, false, var::column_type::public_input), + var(0, k*17 + 2, false, var::column_type::public_input), var(0, k*17 + 3, false, var::column_type::public_input)}; + + + typename component_type::params_type params = {Signatures, Public_keys, M_var}; + + auto result_check = [](AssignmentType &assignment, + component_type::result_type &real_res) { + }; + + test_component(params, public_input, result_check); + + auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); + std::cout << "Time_execution: " << duration.count() << "ms" << std::endl; +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/verifiers/kimchi/detail/index_terms_scalars.cpp b/test/verifiers/kimchi/detail/constraints/index_terms_scalars.cpp similarity index 92% rename from test/verifiers/kimchi/detail/index_terms_scalars.cpp rename to test/verifiers/kimchi/detail/constraints/index_terms_scalars.cpp index ead0a39b13..a50dc3955e 100644 --- a/test/verifiers/kimchi/detail/index_terms_scalars.cpp +++ b/test/verifiers/kimchi/detail/constraints/index_terms_scalars.cpp @@ -103,6 +103,9 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_index_terms_scalar_test_suite 0x0000000000000000000000000000000005321CB83A4BCD5C63F489B5BF95A8DC_cppui256; typename BlueprintFieldType::value_type zeta_val = 0x0000000000000000000000000000000062F9AE3696EA8F0A85043221DE133E32_cppui256; + typename BlueprintFieldType::value_type omega_val = + 0x0CB8102D0128EBB25343154773101EAF1A9DAEF679667EB4BD1E06B973E985E4_cppui256; + std::size_t domain_size = 512; std::vector public_input; @@ -118,14 +121,20 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_index_terms_scalar_test_suite public_input.push_back(joint_combiner_val); var joint_combiner = var(0, public_input.size() - 1, false, var::column_type::public_input); + public_input.push_back(zeta_val); + var zeta = var(0, public_input.size() - 1, false, var::column_type::public_input); + + public_input.push_back(omega_val); + var omega = var(0, public_input.size() - 1, false, var::column_type::public_input); + using evaluations_type = typename zk::components::kimchi_proof_evaluations< BlueprintFieldType, kimchi_params>; std::array evals; evals[0].w[3] = gamma; typename component_type::params_type params = { - alpha, beta, gamma, joint_combiner, - evals}; + zeta, alpha, beta, gamma, joint_combiner, + evals, omega, domain_size}; auto result_check = [&gamma_val, &beta_val](AssignmentType &assignment, component_type::result_type &real_res) { //assert((gamma_val + beta_val) == assignment.var_value(real_res.output)); diff --git a/test/verifiers/kimchi/detail/rpn_expression.cpp b/test/verifiers/kimchi/detail/constraints/rpn_expression.cpp similarity index 86% rename from test/verifiers/kimchi/detail/rpn_expression.cpp rename to test/verifiers/kimchi/detail/constraints/rpn_expression.cpp index c0ce49c8ff..0ea21ddb08 100644 --- a/test/verifiers/kimchi/detail/rpn_expression.cpp +++ b/test/verifiers/kimchi/detail/constraints/rpn_expression.cpp @@ -89,8 +89,8 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_dup public_input_size, prev_chal_size>; constexpr const char *s = "Alpha;Beta;Cell(Variable { col: Witness(3), row: Curr });Dup;\0"; - const std::size_t array_size = count_delimiters(s); - const std::size_t N = rpn_component_rows(s); + const std::size_t array_size = zk::components::count_delimiters(s); + const std::size_t N = zk::components::rpn_component_rows(s); using component_type = zk::components::rpn_expression; @@ -104,6 +104,9 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_dup 0x0000000000000000000000000000000005321CB83A4BCD5C63F489B5BF95A8DC_cppui256; typename BlueprintFieldType::value_type zeta_val = 0x0000000000000000000000000000000062F9AE3696EA8F0A85043221DE133E32_cppui256; + typename BlueprintFieldType::value_type omega_val = + 0x0CB8102D0128EBB25343154773101EAF1A9DAEF679667EB4BD1E06B973E985E4_cppui256; + std::size_t domain_size = 512; std::vector public_input; @@ -119,11 +122,17 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_dup public_input.push_back(joint_combiner_val); var joint_combiner = var(0, public_input.size() - 1, false, var::column_type::public_input); + public_input.push_back(zeta_val); + var zeta = var(0, public_input.size() - 1, false, var::column_type::public_input); + + public_input.push_back(omega_val); + var omega = var(0, public_input.size() - 1, false, var::column_type::public_input); + using evaluations_type = typename zk::components::kimchi_proof_evaluations; std::array evals; evals[0].w[3] = gamma; - typename component_type::params_type params = {s, alpha, beta, gamma, joint_combiner, evals}; + typename component_type::params_type params = {s, zeta, alpha, beta, gamma, joint_combiner, evals, omega, domain_size}; auto result_check = [&gamma_val, &beta_val](AssignmentType &assignment, component_type::result_type &real_res) { assert(gamma_val == assignment.var_value(real_res.output)); @@ -169,8 +178,8 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_sub public_input_size, prev_chal_size>; constexpr const char *s = "Alpha;Beta;Cell(Variable { col: Witness(3), row: Curr });Sub;\0"; - const std::size_t array_size = count_delimiters(s); - const std::size_t N = rpn_component_rows(s); + const std::size_t array_size = zk::components::count_delimiters(s); + const std::size_t N = zk::components::rpn_component_rows(s); using component_type = zk::components::rpn_expression; @@ -184,6 +193,9 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_sub 0x0000000000000000000000000000000005321CB83A4BCD5C63F489B5BF95A8DC_cppui256; typename BlueprintFieldType::value_type zeta_val = 0x0000000000000000000000000000000062F9AE3696EA8F0A85043221DE133E32_cppui256; + typename BlueprintFieldType::value_type omega_val = + 0x0CB8102D0128EBB25343154773101EAF1A9DAEF679667EB4BD1E06B973E985E4_cppui256; + std::size_t domain_size = 512; std::vector public_input; @@ -199,11 +211,17 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_sub public_input.push_back(joint_combiner_val); var joint_combiner = var(0, public_input.size() - 1, false, var::column_type::public_input); + public_input.push_back(zeta_val); + var zeta = var(0, public_input.size() - 1, false, var::column_type::public_input); + + public_input.push_back(omega_val); + var omega = var(0, public_input.size() - 1, false, var::column_type::public_input); + using evaluations_type = typename zk::components::kimchi_proof_evaluations; std::array evals; evals[0].w[3] = gamma; - typename component_type::params_type params = {s, alpha, beta, gamma, joint_combiner, evals}; + typename component_type::params_type params = {s, zeta, alpha, beta, gamma, joint_combiner, evals, omega, domain_size}; auto result_check = [&gamma_val, &beta_val](AssignmentType &assignment, component_type::result_type &real_res) { assert((gamma_val - beta_val) == assignment.var_value(real_res.output)); @@ -249,8 +267,8 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_add public_input_size, prev_chal_size>; constexpr const char *s = "Alpha;Beta;Cell(Variable { col: Witness(3), row: Curr });Add;\0"; - const std::size_t array_size = count_delimiters(s); - const std::size_t N = rpn_component_rows(s); + const std::size_t array_size = zk::components::count_delimiters(s); + const std::size_t N = zk::components::rpn_component_rows(s); using component_type = zk::components::rpn_expression; @@ -264,6 +282,9 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_add 0x0000000000000000000000000000000005321CB83A4BCD5C63F489B5BF95A8DC_cppui256; typename BlueprintFieldType::value_type zeta_val = 0x0000000000000000000000000000000062F9AE3696EA8F0A85043221DE133E32_cppui256; + typename BlueprintFieldType::value_type omega_val = + 0x0CB8102D0128EBB25343154773101EAF1A9DAEF679667EB4BD1E06B973E985E4_cppui256; + std::size_t domain_size = 512; std::vector public_input; @@ -279,11 +300,17 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_add public_input.push_back(joint_combiner_val); var joint_combiner = var(0, public_input.size() - 1, false, var::column_type::public_input); + public_input.push_back(zeta_val); + var zeta = var(0, public_input.size() - 1, false, var::column_type::public_input); + + public_input.push_back(omega_val); + var omega = var(0, public_input.size() - 1, false, var::column_type::public_input); + using evaluations_type = typename zk::components::kimchi_proof_evaluations; std::array evals; evals[0].w[3] = gamma; - typename component_type::params_type params = {s, alpha, beta, gamma, joint_combiner, evals}; + typename component_type::params_type params = {s, zeta, alpha, beta, gamma, joint_combiner, evals, omega, domain_size}; auto result_check = [&gamma_val, &beta_val](AssignmentType &assignment, component_type::result_type &real_res) { assert((gamma_val + beta_val) == assignment.var_value(real_res.output)); @@ -328,8 +355,8 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_mul public_input_size, prev_chal_size>; constexpr const char *s = "Alpha;Beta;Cell(Variable { col: Witness(3), row: Curr });Mul;\0"; - const std::size_t array_size = count_delimiters(s); - const std::size_t N = rpn_component_rows(s); + const std::size_t array_size = zk::components::count_delimiters(s); + const std::size_t N = zk::components::rpn_component_rows(s); using component_type = zk::components::rpn_expression; @@ -343,6 +370,9 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_mul 0x0000000000000000000000000000000005321CB83A4BCD5C63F489B5BF95A8DC_cppui256; typename BlueprintFieldType::value_type zeta_val = 0x0000000000000000000000000000000062F9AE3696EA8F0A85043221DE133E32_cppui256; + typename BlueprintFieldType::value_type omega_val = + 0x0CB8102D0128EBB25343154773101EAF1A9DAEF679667EB4BD1E06B973E985E4_cppui256; + std::size_t domain_size = 512; std::vector public_input; @@ -358,11 +388,17 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_mul public_input.push_back(joint_combiner_val); var joint_combiner = var(0, public_input.size() - 1, false, var::column_type::public_input); + public_input.push_back(zeta_val); + var zeta = var(0, public_input.size() - 1, false, var::column_type::public_input); + + public_input.push_back(omega_val); + var omega = var(0, public_input.size() - 1, false, var::column_type::public_input); + using evaluations_type = typename zk::components::kimchi_proof_evaluations; std::array evals; evals[0].w[3] = gamma; - typename component_type::params_type params = {s, alpha, beta, gamma, joint_combiner, evals}; + typename component_type::params_type params = {s, zeta, alpha, beta, gamma, joint_combiner, evals, omega, domain_size}; auto result_check = [&gamma_val, &beta_val](AssignmentType &assignment, component_type::result_type &real_res) { assert((gamma_val * beta_val) == assignment.var_value(real_res.output)); @@ -408,8 +444,8 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_pow public_input_size, prev_chal_size>; constexpr const char *s = "Alpha;Beta;Cell(Variable { col: Witness(3), row: Curr });Pow(2);\0"; - const std::size_t array_size = count_delimiters(s); - const std::size_t N = rpn_component_rows(s); + const std::size_t array_size = zk::components::count_delimiters(s); + const std::size_t N = zk::components::rpn_component_rows(s); using component_type = zk::components::rpn_expression; @@ -423,6 +459,9 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_pow 0x0000000000000000000000000000000005321CB83A4BCD5C63F489B5BF95A8DC_cppui256; typename BlueprintFieldType::value_type zeta_val = 0x0000000000000000000000000000000062F9AE3696EA8F0A85043221DE133E32_cppui256; + typename BlueprintFieldType::value_type omega_val = + 0x0CB8102D0128EBB25343154773101EAF1A9DAEF679667EB4BD1E06B973E985E4_cppui256; + std::size_t domain_size = 512; std::vector public_input; @@ -438,11 +477,17 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_pow public_input.push_back(joint_combiner_val); var joint_combiner = var(0, public_input.size() - 1, false, var::column_type::public_input); + public_input.push_back(zeta_val); + var zeta = var(0, public_input.size() - 1, false, var::column_type::public_input); + + public_input.push_back(omega_val); + var omega = var(0, public_input.size() - 1, false, var::column_type::public_input); + using evaluations_type = typename zk::components::kimchi_proof_evaluations; std::array evals; evals[0].w[3] = gamma; - typename component_type::params_type params = {s, alpha, beta, gamma, joint_combiner, evals}; + typename component_type::params_type params = {s, zeta, alpha, beta, gamma, joint_combiner, evals, omega, domain_size}; auto result_check = [&gamma_val, &beta_val](AssignmentType &assignment, component_type::result_type &real_res) { assert((gamma_val * gamma_val) == assignment.var_value(real_res.output)); @@ -488,8 +533,8 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_com public_input_size, prev_chal_size>; constexpr const char *s = "Cell(Variable { col: Witness(10), row: Curr });Cell(Variable { col: Witness(2), row: Curr });Cell(Variable { col: Witness(0), row: Curr });Sub;Store;Mul;Literal 0000000000000000000000000000000000000000000000000000000000000001;Cell(Variable { col: Witness(7), row: Curr });Sub;Sub;Alpha;Pow(1);Cell(Variable { col: Witness(7), row: Curr });Load(0);Mul;Mul;Add;Alpha;Pow(2);Cell(Variable { col: Witness(7), row: Curr });Cell(Variable { col: Witness(8), row: Curr });Dup;Add;Cell(Variable { col: Witness(1), row: Curr });Mul;Cell(Variable { col: Witness(0), row: Curr });Cell(Variable { col: Witness(0), row: Curr });Mul;Store;Dup;Add;Sub;Load(1);Sub;Mul;Literal 0000000000000000000000000000000000000000000000000000000000000001;Cell(Variable { col: Witness(7), row: Curr });Sub;Load(0);Cell(Variable { col: Witness(8), row: Curr });Mul;Cell(Variable { col: Witness(3), row: Curr });Cell(Variable { col: Witness(1), row: Curr });Sub;Store;Sub;Mul;Add;Mul;Add;Alpha;Pow(3);Cell(Variable { col: Witness(0), row: Curr });Cell(Variable { col: Witness(2), row: Curr });Add;Cell(Variable { col: Witness(4), row: Curr });Add;Cell(Variable { col: Witness(8), row: Curr });Cell(Variable { col: Witness(8), row: Curr });Mul;Sub;Mul;Add;Alpha;Pow(4);Cell(Variable { col: Witness(8), row: Curr });Cell(Variable { col: Witness(0), row: Curr });Cell(Variable { col: Witness(4), row: Curr });Sub;Mul;Cell(Variable { col: Witness(1), row: Curr });Sub;Cell(Variable { col: Witness(5), row: Curr });Sub;Mul;Add;Alpha;Pow(5);Load(2);Cell(Variable { col: Witness(7), row: Curr });Cell(Variable { col: Witness(6), row: Curr });Sub;Mul;Mul;Add;Alpha;Pow(6);Load(2);Cell(Variable { col: Witness(9), row: Curr });Mul;Cell(Variable { col: Witness(6), row: Curr });Sub;Mul;Add;\0"; - const std::size_t array_size = count_delimiters(s); - const std::size_t N = rpn_component_rows(s); + const std::size_t array_size = zk::components::count_delimiters(s); + const std::size_t N = zk::components::rpn_component_rows(s); using component_type = zk::components::rpn_expression; @@ -503,6 +548,9 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_com 0x0000000000000000000000000000000005321CB83A4BCD5C63F489B5BF95A8DC_cppui256; typename BlueprintFieldType::value_type zeta_val = 0x0000000000000000000000000000000062F9AE3696EA8F0A85043221DE133E32_cppui256; + typename BlueprintFieldType::value_type omega_val = + 0x0CB8102D0128EBB25343154773101EAF1A9DAEF679667EB4BD1E06B973E985E4_cppui256; + std::size_t domain_size = 512; std::vector public_input; @@ -518,11 +566,17 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_detail_rpn_expression_test_suite_com public_input.push_back(joint_combiner_val); var joint_combiner = var(0, public_input.size() - 1, false, var::column_type::public_input); + public_input.push_back(zeta_val); + var zeta = var(0, public_input.size() - 1, false, var::column_type::public_input); + + public_input.push_back(omega_val); + var omega = var(0, public_input.size() - 1, false, var::column_type::public_input); + using evaluations_type = typename zk::components::kimchi_proof_evaluations; std::array evals; evals[0].w[3] = gamma; - typename component_type::params_type params = {s, alpha, beta, gamma, joint_combiner, evals}; + typename component_type::params_type params = {s, zeta, alpha, beta, gamma, joint_combiner, evals, omega, domain_size}; auto result_check = [&gamma_val, &beta_val](AssignmentType &assignment, component_type::result_type &real_res) { diff --git a/test/verifiers/kimchi/detail/constraints/unnormalized_lagrange_basis.cpp b/test/verifiers/kimchi/detail/constraints/unnormalized_lagrange_basis.cpp new file mode 100644 index 0000000000..0f5d0e6ea8 --- /dev/null +++ b/test/verifiers/kimchi/detail/constraints/unnormalized_lagrange_basis.cpp @@ -0,0 +1,140 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2022 Polina Chernyshova +// Copyright (c) 2022 Ilia Shirobokov +// +// 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_kimchi_details_vanishes_on_last_4_rows + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include "test_plonk_component.hpp" + +using namespace nil::crypto3; + +BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) + +BOOST_AUTO_TEST_CASE(blueprint_plonk_unnormalized_lagrange_basis_positive_power) { + auto start = std::chrono::high_resolution_clock::now(); + + using curve_type = algebra::curves::vesta; + using BlueprintFieldType = typename curve_type::scalar_field_type; + constexpr std::size_t WitnessColumns = 15; + constexpr std::size_t PublicInputColumns = 1; + constexpr std::size_t ConstantColumns = 1; + constexpr std::size_t SelectorColumns = 4; + using ArithmetizationParams = + zk::snark::plonk_arithmetization_params; + using ArithmetizationType = zk::snark::plonk_constraint_system; + using AssignmentType = zk::blueprint_assignment_table; + using hash_type = nil::crypto3::hashes::keccak_1600<256>; + constexpr std::size_t Lambda = 40; + + using var = zk::snark::plonk_variable; + + using component_type = zk::components::unnormalized_lagrange_basis; + + typename BlueprintFieldType::value_type group_gen = 0x0CB8102D0128EBB25343154773101EAF1A9DAEF679667EB4BD1E06B973E985E4_cppui256; + std::size_t domain_size = 512; + int ith = 5; + typename BlueprintFieldType::value_type x = algebra::random_element(); + typename BlueprintFieldType::value_type group_gen_pow = group_gen.pow(ith); + typename BlueprintFieldType::value_type expected_res = (x.pow(domain_size) - 1) * (x - group_gen_pow).inversed(); + + std::vector public_input = {group_gen, x, expected_res}; + + typename component_type::params_type params = { + var(0, 0, false, var::column_type::public_input), domain_size, var(0, 1, false, var::column_type::public_input), ith}; + + auto result_check = [&expected_res](AssignmentType &assignment, + component_type::result_type &real_res) { + assert(expected_res == assignment.var_value(real_res.output)); + }; + + test_component(params, public_input, result_check); + + auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); + std::cout << "vanishes_on_last_4_rows: " << duration.count() << "ms" << std::endl; +} + +BOOST_AUTO_TEST_CASE(blueprint_plonk_unnormalized_lagrange_basis_negative_power) { + auto start = std::chrono::high_resolution_clock::now(); + + using curve_type = algebra::curves::vesta; + using BlueprintFieldType = typename curve_type::scalar_field_type; + constexpr std::size_t WitnessColumns = 15; + constexpr std::size_t PublicInputColumns = 1; + constexpr std::size_t ConstantColumns = 1; + constexpr std::size_t SelectorColumns = 4; + using ArithmetizationParams = + zk::snark::plonk_arithmetization_params; + using ArithmetizationType = zk::snark::plonk_constraint_system; + using AssignmentType = zk::blueprint_assignment_table; + using hash_type = nil::crypto3::hashes::keccak_1600<256>; + constexpr std::size_t Lambda = 40; + + using var = zk::snark::plonk_variable; + + using component_type = zk::components::unnormalized_lagrange_basis; + + typename BlueprintFieldType::value_type group_gen = 0x0CB8102D0128EBB25343154773101EAF1A9DAEF679667EB4BD1E06B973E985E4_cppui256; + std::size_t domain_size = 512; + int ith = -5; + typename BlueprintFieldType::value_type x = algebra::random_element(); + typename BlueprintFieldType::value_type group_gen_pow = group_gen.pow(-ith).inversed(); + typename BlueprintFieldType::value_type expected_res = (x.pow(domain_size) - 1) * (x - group_gen_pow).inversed(); + + std::vector public_input = {group_gen, x, expected_res}; + + typename component_type::params_type params = { + var(0, 0, false, var::column_type::public_input), domain_size, var(0, 1, false, var::column_type::public_input), ith}; + + auto result_check = [&expected_res](AssignmentType &assignment, + component_type::result_type &real_res) { + assert(expected_res == assignment.var_value(real_res.output)); + }; + + test_component(params, public_input, result_check); + + auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); + std::cout << "vanishes_on_last_4_rows: " << duration.count() << "ms" << std::endl; +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/verifiers/kimchi/detail/constraints/vanishes_on_last_4_rows.cpp b/test/verifiers/kimchi/detail/constraints/vanishes_on_last_4_rows.cpp new file mode 100644 index 0000000000..8abf886da0 --- /dev/null +++ b/test/verifiers/kimchi/detail/constraints/vanishes_on_last_4_rows.cpp @@ -0,0 +1,97 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2022 Polina Chernyshova +// Copyright (c) 2022 Ilia Shirobokov +// +// 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_kimchi_details_vanishes_on_last_4_rows + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include "test_plonk_component.hpp" + +using namespace nil::crypto3; + +BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) + +BOOST_AUTO_TEST_CASE(blueprint_plonk_zkpm) { + auto start = std::chrono::high_resolution_clock::now(); + + using curve_type = algebra::curves::pallas; + using BlueprintFieldType = typename curve_type::scalar_field_type; + constexpr std::size_t WitnessColumns = 15; + constexpr std::size_t PublicInputColumns = 1; + constexpr std::size_t ConstantColumns = 1; + constexpr std::size_t SelectorColumns = 4; + using ArithmetizationParams = + zk::snark::plonk_arithmetization_params; + using ArithmetizationType = zk::snark::plonk_constraint_system; + using AssignmentType = zk::blueprint_assignment_table; + using hash_type = nil::crypto3::hashes::keccak_1600<256>; + constexpr std::size_t Lambda = 40; + + using var = zk::snark::plonk_variable; + + using component_type = zk::components::vanishes_on_last_4_rows; + + typename BlueprintFieldType::value_type group_gen = algebra::random_element(); + std::size_t domain_size = 1000; + typename BlueprintFieldType::value_type x = algebra::random_element(); + typename BlueprintFieldType::value_type group_gen_pow = group_gen.pow(domain_size - 3 - 1); + typename BlueprintFieldType::value_type expected_res = (x - group_gen_pow) * (x - group_gen_pow * group_gen) * + (x - group_gen_pow * group_gen * group_gen) * + (x - group_gen_pow * group_gen * group_gen * group_gen); + + std::vector public_input = {group_gen, x, expected_res}; + + typename component_type::params_type params = { + var(0, 0, false, var::column_type::public_input), domain_size, var(0, 1, false, var::column_type::public_input)}; + + auto result_check = [&expected_res](AssignmentType &assignment, + component_type::result_type &real_res) { + assert(expected_res == assignment.var_value(real_res.output)); + }; + + test_component(params, public_input, result_check); + + auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); + std::cout << "vanishes_on_last_4_rows: " << duration.count() << "ms" << std::endl; +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/verifiers/kimchi/detail/public_evaluations.cpp b/test/verifiers/kimchi/detail/public_evaluations.cpp index 66dd5ce69e..c17a8fc9d3 100644 --- a/test/verifiers/kimchi/detail/public_evaluations.cpp +++ b/test/verifiers/kimchi/detail/public_evaluations.cpp @@ -140,7 +140,7 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_publuc_evaluations) { auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); - std::cout << "lagrange_base_component: " << duration.count() << "ms" << std::endl; + std::cout << "public_evaluations_component: " << duration.count() << "ms" << std::endl; } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file