NilFoundation / zkLLVM

Zero-Knowledge Proof Systems Circuit Compiler
https://docs.nil.foundation/zkllvm
285 stars 48 forks source link

[Possible bug] Operator == with constants assigned wrong #548

Open ETatuzova opened 7 months ago

ETatuzova commented 7 months ago

This piece of code cannot be assigned

Foud strange behaivour during work on recursive verifier.

#include <nil/crypto3/hash/algorithm/hash.hpp>
#include <nil/crypto3/hash/poseidon.hpp>
#include <nil/crypto3/algebra/curves/pallas.hpp>

using namespace nil::crypto3;
using namespace nil::crypto3::algebra::curves;

namespace placeholder_verifier{

const size_t witness_amount = 15;
const size_t public_input_amount = 1;
const size_t constant_amount = 35;
const size_t selector_amount = 56;
const std::array<std::size_t, public_input_amount> public_input_sizes = {50};
const std::size_t full_public_input_size = 50;

const bool use_lookups = false;
const size_t batches_num = 4;
const size_t commitments_num = 3;
const size_t points_num = 301;
const size_t poly_num = 166;
const size_t initial_proof_points_num = 332;
const size_t round_proof_points_num = 18;
const size_t fri_roots_num = 9;
const size_t initial_merkle_proofs_num = 36;
const size_t initial_merkle_proofs_position_num = 11;
const size_t initial_merkle_proofs_hash_num = 44;
const size_t round_merkle_proofs_position_num = 63;
const size_t round_merkle_proofs_hash_num = 63;
const size_t final_polynomial_size = 2;
const size_t lambda = 9;
const size_t rows_amount = 1024;
const size_t rows_log = 10;
const size_t total_columns = 107;
const size_t sorted_columns = 0;
const size_t permutation_size = 18;
const std::array<size_t, total_columns> zero_indices = {260, 262, 264, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 256, 258};
const size_t table_values_num = 201;
const size_t gates_amount = 11;
constexpr std::array<std::size_t, gates_amount> gates_selector_indices = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
const size_t constraints_amount = 165;
const size_t quotient_polys_start = 281;
const size_t quotient_polys_amount = 20;
const size_t lookup_sorted_polys_start = 301;
const size_t D0_size = 4096;
const size_t D0_log = 12;
const pallas::base_field_type::value_type D0_omega = pallas::base_field_type::value_type(0x291917312f33e5239161008fab331deeb7292c5c6cf6e088c29b8d7491fcb2a4_cppui255);
const pallas::base_field_type::value_type omega = pallas::base_field_type::value_type(0x2ebbfd0093d6cb763b4ade66b66e653bd9786c8a7b47604b73e211ee3dd8df75_cppui255);
const size_t fri_rounds = 9;
const std::array<int, gates_amount> gates_sizes = {15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15};
const size_t unique_points = 3;
const size_t singles_amount = 3;
const std::array<std::size_t, batches_num> batches_amount_list = {129, 16, 1, 20};
pallas::base_field_type::value_type vk0 = pallas::base_field_type::value_type(0x20d01c0edcb22bbb3bac70aaea41eb831d9bc2686780d0ed801da27500375bc0_cppui255);
pallas::base_field_type::value_type vk1 = pallas::base_field_type::value_type(0x3f95d80619825b7cba2a78d3c8b850c14928e30306a13fac3e6b7a6a75750944_cppui255);

struct placeholder_challenges_type{
    pallas::base_field_type::value_type eta;
    pallas::base_field_type::value_type perm_beta;
    pallas::base_field_type::value_type perm_gamma;
    pallas::base_field_type::value_type lookup_theta;
    pallas::base_field_type::value_type lookup_gamma;
    pallas::base_field_type::value_type lookup_beta;
    std::array<pallas::base_field_type::value_type, 1> lookup_alphas;
    pallas::base_field_type::value_type gate_theta;
    std::array<pallas::base_field_type::value_type, 8> alphas;
    std::array<pallas::base_field_type::value_type, fri_roots_num> fri_alphas;
    std::array<pallas::base_field_type::value_type, lambda> fri_x_indices;
    pallas::base_field_type::value_type lpc_theta;
    pallas::base_field_type::value_type xi;
};

placeholder_challenges_type generate_challenges(){
    placeholder_challenges_type challenges;

    challenges.eta = vk0;
    challenges.xi = vk1;

    return challenges;
}

[[circuit]] bool placeholder_verifier(
) {
    placeholder_challenges_type challenges = generate_challenges();
    std::array<pallas::base_field_type::value_type, 50> Omegas = {1};
    __builtin_assigner_exit_check(vk1 == pallas::base_field_type::value_type(0x3f95d80619825b7cba2a78d3c8b850c14928e30306a13fac3e6b7a6a75750944_cppui255));
    return true;
}

}

An error is: assigner_exit_check_input -> assigner_exit_check input is false, verification will fail!

But if you remove declaration of Omegas array, this example will be assigned successfully. I understand that I can initialize array in other way. But it definitely shouldn't modify existing constants.