Skip to content

Bug in r1cs is_valid() check #198

Open
@johannes-reinhart

Description

@johannes-reinhart

bool r1cs_constraint_system::is_valid() returns false for correct setups.

Minimal Example:

#include <libff/common/default_types/ec_pp.hpp>
#include <libsnark/gadgetlib1/protoboard.hpp>
#include <libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp>

typedef libff::default_ec_pp ExampleEllipticCurve;
typedef libff::Fr<ExampleEllipticCurve> ExampleFieldType;


int main() {
    libsnark::protoboard<ExampleFieldType> pb;
    libsnark::pb_variable<ExampleFieldType> a;
    libsnark::pb_variable<ExampleFieldType> b;
    libsnark::pb_variable<ExampleFieldType> c;

    a.allocate(pb, "a");
    b.allocate(pb, "b");
    c.allocate(pb, "c");

    pb.add_r1cs_constraint(libsnark::r1cs_constraint<ExampleFieldType>(a, b, c), "a*b=c");

    libsnark::r1cs_constraint_system<ExampleFieldType> cs = pb.get_constraint_system();
    assert(cs.is_valid());
}

Expected behaviour: cs.is_valid() returns true
Observed behaviour: cs.is_valid() returns false

I think the issue is in libsnark/relations/variable.tcc, in

bool linear_combination<FieldT>::is_valid(const size_t num_variables) const
...
if ((--terms.end())->index >= num_variables)

which checks the largest index used. It should probably be

if ((--terms.end())->index > num_variables)

to account for the additional row representing ONE in the constraint system.

Additionally in libsnark/gadgetlib2/gadget.cpp

R1P_InnerProduct_Gadget::R1P_InnerProduct_Gadget(ProtoboardPtr pb,
                                                 const VariableArray& A,
                                                 const VariableArray& B,
                                                 const Variable& result) : Gadget(pb), InnerProduct_GadgetBase(pb), R1P_Gadget(pb), partialSums_(A.size(), "partialSums"), A_(A), B_(B), result_(result)

Should initialize partialSums with size A.size() - 1, as the last element is never used within the constraints. This was probably the reason, that the assert(cs.is_valid) in libsnark/gadgetlib2/examples/simple_example.cpp never triggered.

Do you agree?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions