NilFoundation / zkLLVM

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

[Possible bug] Multi prover example seg fault in assigner #446

Closed CblPOK-git closed 8 months ago

CblPOK-git commented 9 months ago

If remove pragma, then everything works fine. Added this example to branch 446

`#include <nil/crypto3/hash/algorithm/hash.hpp>

include <nil/crypto3/hash/poseidon.hpp>

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

[[circuit]] bool check_root ( typename pallas::base_field_type::value_type expected_root, [[private_input]] std::array<typename pallas::base_field_type::value_type, 0x8> layer_0_leaves) {

    std::array<typename pallas::base_field_type::value_type, 0x4> layer_1_leaves;
    std::size_t layer_1_size = 0x4;
    std::array<typename pallas::base_field_type::value_type, 0x2> layer_2_leaves;
    std::size_t layer_2_size = 0x2;
    typename pallas::base_field_type::value_type real_root;

for (std::size_t leaf_index = 0; leaf_index < layer_1_size; leaf_index++) {
    layer_1_leaves[leaf_index] =
        hash<hashes::poseidon>(layer_0_leaves[2 * leaf_index], layer_0_leaves[2 * leaf_index + 1]);
}

pragma zk_multi_prover 1

{
    for (std::size_t leaf_index = 0; leaf_index < layer_2_size; leaf_index++) {
        layer_2_leaves[leaf_index] =
            hash<hashes::poseidon>(layer_1_leaves[2 * leaf_index], layer_1_leaves[2 * leaf_index + 1]);
    }
}

pragma zk_multi_prover 2

{
    real_root = hash<hashes::poseidon>(layer_2_leaves[0], layer_2_leaves[1]);
}

bool res = (real_root == expected_root);
// __builtin_assigner_exit_check(res);

return res;

} `

akokoshn commented 9 months ago

public input

[ {"field":"12445356689065428535224357029694133050596198304994846910611190413916374968144"} ]

private input

[ {"array": [
    {"field":1},
    {"field":2},
    {"field":3},
    {"field":4},
    {"field":5},
    {"field":6},
    {"field":7},
    {"field":8}] } ]
akokoshn commented 9 months ago

#pragma zk_multi_prover 1 doesn't works before for loop. As result assigner try to switch currProverIdx from 0 to 2 => out of range access to assigments/circuits. https://github.com/NilFoundation/zkllvm-assigner/pull/165 - avoid seg fault on assigner side, but still need to fix clang

akokoshn commented 8 months ago

clang issue reproduces on simple example

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

[[circuit]] uint32_t test(uint32_t a) {
    uint32_t out = a >> 1;
#pragma zk_multi_prover 1
    for (int i = 0; i < 10; i++)
    {
        out = out + 1;
    }
    return out;
}
akokoshn commented 8 months ago

Fix clang issue: https://github.com/NilFoundation/zkllvm-circifier/pull/99 CI: https://github.com/NilFoundation/zkLLVM/pull/451

akokoshn commented 8 months ago

merged