iden3/circom

WASM/JS witness generator cannot handle large numbers

bkomuves opened this issue · 2 comments

The witness generator, when reading the circuit inputs from the JSON file, parses numbers larger than approx 2^53 wrong.

This is really bad in practice, as you cannot use actual field elements as inputs.

This in fact happens already when reading in the JSON file, as numbers are apparently parsed as double-precision floating point numbers... (and then how these get converted to field elements is another fun mystery!)

Example circom code:

pragma circom 2.0.0;

template Sum(n) {
  
  signal input  inp[n];
  signal output out;

  var sum = 0;
  for(var i=0; i<n; i++) {
    log(inp[i]);
    sum += inp[i];
  }

  out <== sum;
  log("sum =",out);
}

component main {public [inp]} = Sum(3);

example input.json:

{ "inp": 
    [ 1234567890
    , 12345678901234567890
    , 123456789012345678901234567890
    ]     
}

log output when running the WASM witness generator:

1234567890
12345678901234567168
123456789012345677877719597056
sum = 123456789024691356780188732114

Hi!

In order to use numbers larger than 2^53 as inputs, you need to represent them in the json file using strings instead of integers as JavaScript does not work accurately with large integers.

After modifying the input.json file:

{ "inp": 
    [ "1234567890"
    , "12345678901234567890"
    , "123456789012345678901234567890"
    ]     
}

the circuit outputs the expected values:

1234567890
12345678901234567890
123456789012345678901234567890
sum = 123456789024691357803703703670

You can find more documentation on how to generate the witness here: [https://docs.circom.io/getting-started/computing-the-witness/#what-is-a-witness]

Thank you for reporting this issue!

Thanks, this will presumably solve my problem!

However, silently corrupting the input is still bad.