NilFoundation / zkLLVM

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

[Possible bug] non-obvious restrictions on loop iterations #520

Closed ETatuzova closed 8 months ago

ETatuzova commented 8 months ago

On this example:

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

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

[[circuit]] typename pallas::base_field_type::value_type
    field_for_example(
        typename pallas::base_field_type::value_type a,
        typename pallas::base_field_type::value_type b
) {
    for( std::size_t i = 0; i < 100; i*2){
        a = a + b;
    }
    return a;
}

Assigner outputs Unsupported opcode type: unreachable error.

akokoshn commented 8 months ago

The reason of fail - invalid loop:

for( std::size_t i = 0; i < 100; i =i*2)

if initial value of i 0, i*2 always 0, so we have infinity loop. In case of forces unroll it leads unreachable instruction which is wrong for circuit compilation Right example:

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

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

[[circuit]] int for_example(int a) {
    for(std::size_t i = 1; i < 100; i=i*2){
        a++;
    }
    return a;
}