iden3/circom

Error generating the proof in Groth16

hdvanegasm opened this issue · 2 comments

Hi everyone,

I have the following circuit:

// The circuit proves that we know a secret and a polynomial such that the
// Shamir shares are indeed generated from the input secret and the
// input polynomial. Parties are identified as P_1, ..., P_4. The input to the
// circuit are the secret, the coefficients of the polynomial [a_1, a_2]
// used to share the secret, and the number of parties.
pragma circom  2.0.0;

template SecretSharing() {

    signal input secret;
    signal input coefficients[2];

    signal output shares[4];

    for(var i = 1; i <= 4; i++) {
        var eval = 0;
        for(var exp = 0; exp <= 2; exp++) {
            if (exp == 0) {
                eval += secret;
            } else {
                eval += coefficients[exp - 1] * (i ** exp);
            }
        }

        shares[i - 1] <== eval;
    }
}

component main = SecretSharing();

The input of the circuit is:

{
    "secret": "4",
    "coefficients": [
        "3",
        "4"
    ]
}

The circuit compiles correctly, however, when I generate the proof with the command:

snarkjs groth16 prove secret-sharing_0001.zkey witness.wtns proof.json public.json

The output is the following error:

[ERROR] snarkJS: Error: Scalar size does not match
    at _multiExp (/usr/local/lib/node_modules/snarkjs/node_modules/ffjavascript/build/main.cjs:4971:19)
    at WasmCurve.multiExpAffine (/usr/local/lib/node_modules/snarkjs/node_modules/ffjavascript/build/main.cjs:5008:22)
    at groth16Prove$1 (/usr/local/lib/node_modules/snarkjs/build/cli.cjs:5768:33)
    at async Object.groth16Prove [as action] (/usr/local/lib/node_modules/snarkjs/build/cli.cjs:12975:36)
    at async clProcessor (/usr/local/lib/node_modules/snarkjs/build/cli.cjs:481:27)

How can I solve this error? Thanks.

If the circuit compiles correctly as well as the witness computation, the problem is probably in the interaction with snarkJS, you should open the issue here https://github.com/iden3/snarkjs

Hey @hdvanegasm, the issue is that circom interprets += operator as a non-constraint since you are just working with var. So the actual constraint shares[i - 1] <== eval becomes a non-constraint as it is no longer quadratic.

The solution is to add a "dummy" input enable that forces the constraint to be generated:

pragma circom 2.0.0;

template SecretSharing() {
    signal input enable; // 0 or 1
    signal input secret;
    signal input coefficients[2];

    signal output shares[4];

    for(var i = 1; i <= 4; i++) {
        var eval = 0;
        for(var exp = 0; exp <= 2; exp++) {
            if (exp == 0) {
                eval += secret;
            } else {
                eval += coefficients[exp - 1] * (i ** exp);
            }
        }

        shares[i - 1] <== eval * enable; // force the constraint
    }
}

component main = SecretSharing();

New inputs:

{
  enable: "1",
  secret: "4",
  coefficients: ["3", "4"],
}

Hope that helps.