Skip to content

Bug in r1cs is_valid() check #198

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?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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