Coder Social home page Coder Social logo

circom's People

Contributors

a6-dou avatar alinush avatar alrubio avatar amit0617 avatar antimatter15 avatar clararod9 avatar eduadiez avatar ermyas avatar fasteater avatar hecmas avatar hung-ngm avatar infiniteswerve avatar jbaylina avatar jlmunoz77 avatar judiciouscoder avatar khuzama98 avatar lispc avatar miguelis avatar mmilenkovic avatar neuodev avatar nullity00 avatar phated avatar remind-me-later avatar rubydusa avatar savio-sou avatar shuoer86 avatar vuittont60 avatar wp-lai avatar xavi-pinsach avatar yoyoismee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

circom's Issues

modified inputs

Hello !

I'm trying to verify a commitment of a rescue function. The problem is when I write the commit in the inputs, it's directly modified by the circuit without reasons (the value is less than bn128's elliptic curve group order).
Here is my simple circuit :

pragma circom 2.0.0;

include "./rescue.circom";

template test(){
signal input in;
signal input commit;
signal output out;

component hash = rescue(1);

hash.entree[0] <== in;

out <== hash.sortie;

}

component main {public [commit]} = test();

This is what the public file and the input files looks like :
input : 15522569492626651840248353495983403506074603540762064124302882378518279710261 (commit)
public : 15522569492626651840248353495983403506074603540762064124302882378518279710261 (hash result)
and 15522569492626650996385962682425768945933593965259583670031600469260676104192 (wrong copy of my input)

Can someone tell me if it's an error from me or not?

Thomas

Bug in the cpp witness calculator

Description

Hello,

I have encountered a bug while running this circom implementation of RSA.
You can find a proof of concept circuit and input here. You can reproduce it if you clone the repository and run:

circom poc.circom --c
cd poc_cpp/
make -j 8
./poc ../poc.json w.wtns

Generating a proof with the wasm witness calculator works as expected, and produces a valid proof. But calculating a witness with the cpp circuit crashes and throws the following assertion exception:

./poc ../poc.json w.wtns
poc: fr.cpp:166: void Fr_fail(): Assertion `false' failed.
[1]    249859 IOT instruction (core dumped)  ./poc ../poc.json w.wtns

While debugging the issue, I found that it is most likely caused by the use of the array initialized on line 89. I tested a similar implementation that does not use the IsZero() component, and therefore the array, but does pretty much the same operations as in IsZero(), and the circuit generates a correct witness.

I initially thought it was connected to the way the index of the array was calculated, because when I log the operation that calculates the array index, it prints "0", while it should print "473". But even with a constant array size, it crashed with the unexpected assertion failed message.

However, I tried substituting the operation that calculates indexes of this array dynamically (var idx = (i - (base_len + 8)) / 8 on line 96) with a constant number that is decreased after each iteration of the loop, and then the incorrect assertion is no longer thrown.

It is worth noting that logging idx prints the expected value. But I still think it might be related to the - operation.

Let me know if you need more information.
Thanks in advance.

docs.circom.io seems to be outdated ?

Hello,

The doc seems to have changed in the last days and the getting started does not seems to work anymore ?
I can notice in the https://docs.circom.io/1.-an-introduction/getting-started the installation of the old circom npm package that is now deprecated in favor of the circom rust compiler.
and some signal private input a; in the Multiplier example, that don't seem to compile.

I remember trying the getting started that works well last week. When i searched in my history the docs URL was not the same : https://docs.circom.io/getting-started/compiling-circuits/

Do you know what happens ?
Thanks a lot !

Wrong witness generated with c with integer division

pragma circom 2.0.3;

template Hash() {
  signal output out;
  out <== 256 \ 256;
}

component main = Hash();

When I generate the witness for this circuit with wasm. I get the correct result witness with ["1","1"]. But when I generate it with c, the value is zero ["1", "0"].

Confusing by `Out of bounds exception`

The circuits is:

pragma circom 2.0.3;

function add(left_operand, right_operand){
    return left_operand + right_operand;
}

template uvm(CODE_SIZE) {
    signal input code[CODE_SIZE];
    var pc = 0;

    var MEM_SIZE = 8;
    var memory[MEM_SIZE] = [0,0,0,0,0,0,0,0];
    var STACK_SIZE = 8;
    var stack[STACK_SIZE] =  [0, 0, 0, 0, 0, 0, 0, 0];
    var op;
    var sp = -1;

    while (pc < CODE_SIZE) {
        op = code[pc];
        pc = pc + 1;

        if (pc == 0x0) {
            pc = CODE_SIZE;
        }

        if(op == 0x1){
            stack[sp - 1] = add(stack[sp], stack[sp - 1]);
            sp = sp - 1;
        }

        // push
        if (op == 0x60) {
            if(sp + 1 < STACK_SIZE){
                stack[sp + 1] = code[pc];
                sp = sp + 1;
                pc = pc + 1;
            }
        }
    }
    //...
}

circom: 2.0.3
The error:

error[T3001]: Out of bounds exception
   ┌─ "circuits/vm2.circom":27:13
   │
27 │             stack[sp - 1] = add(stack[sp], stack[sp - 1]);
   │             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found here
   │
   = call trace:
     ->uvm

previous errors were found

Question: Is this a must to check if sp is -1 at any condition?

Symfile optimization loses signal association in any optimization pass

When running with -O1 (or any optimization level above zero), some signal association is lost due to optimizations. This wouldn't happen with -O0; however, some large circuits are not able to compile with no optimizations due to size limitations.

Can the symfile keep the signal associations for values optimized away by the compiler?

Integer division template

Is it possible to do integer division in circom? For example, something like this would be great:

pragma circom 2.0.0;

function div(a, b) {
    var r = a;
    var q = 0;
    while (r >= b) {
        r = r - b;
        q = q + 1;
    }
    return q;
}

template test() {
    signal input a;
    signal input b;
    signal output c;
    c <== div(a, b);
}
component main = test();

It will not work because "non quadratic constraint" error. However, I tried other kinds of division algorithm, but still cannot remove such error.

cant pass an array of inputs

Hi, I get an error during witness generation

(node:4036550) UnhandledPromiseRejectionWarning: Error: Too many values for input signal in[0]

my input.json is


{
    "in[0]" : 2222,
    "in[1]" : 2222
}

the circuit is:

pragma circom 2.0.0;
template Main() {
    signal output out;
    signal input in[2];

    out <== in[0]*in[1];
}
component main = Main();

Doesn't this syntax of passing arrays work anymore?
Thanks.

Does --wasm switch work?

circom2 circuits/c.circom --r1cs --wasm --sym --c does not spit out a wasm file. The best error message I could find is previous errors were found. Is this part working at all?

According to https://twitter.com/railgun_project/status/1500966895733850117 they've also had problems that they had to put out a bounty for it.

Also I don't have the best experience working with circom2, a lot of documentation's outdated, makes me sad:(

[Performance] Using Hashbrown instead of std::collections::HashMap

In places like

use std::collections::HashMap;

use std::collections::HashMap;

use std::collections::HashMap;

use std::collections::HashMap;


use std::collections::{BTreeMap, HashMap, HashSet, LinkedList};

use std::collections::HashMap;

use std::collections::HashMap;

use std::collections::HashMap;

We use std::collections::HashMap on even more places across the workspace. Not sure how much data it's included in there, but what would definitely speed up a lot this is to use hashbrown which supports no-std and should be perfectly compatible.

I can make a PR if you want 😄

Compilation mode that removes all log statements

When developing a circuit, an author will likely include many log statements. It would be ideal to have a compilation mode that removes all of these log statements from the output when compiling for production.

Compilation error on generated C++ witness generation file

pragma circom 2.0.0;
function x(inp)
{
	var t[4];

	t = [1, 2, 3, 4];

	return t[inp];
}

template Main()
{
	signal input in;
	signal s;
	signal output out;

	s <-- x(in);
	out <== 2*s;
}

component main = Main();

For the above circuit, I am able to generate witness using wasm.
But when I try to compile the C++ witness generator for the same, I get the following errors:

g++ -c main.cpp -std=c++11 -O3 -I.
main.cpp:116:2: error: expected declaration before ‘}’ token
  116 |  }
      |  ^
main.cpp:117:20: error: expected constructor, destructor, or type conversion before ‘(’ token
  117 |     Fr_str2element (&v, s.c_str());
      |                    ^
main.cpp:118:5: error: ‘vval’ does not name a type
  118 |     vval.push_back(v);
      |     ^~~~
main.cpp:119:3: error: expected declaration before ‘}’ token
  119 |   } else {
      |   ^
main.cpp:119:5: error: expected unqualified-id before ‘else’
  119 |   } else {
      |     ^~~~
main.cpp:124:1: error: expected declaration before ‘}’ token
  124 | }
      | ^
main.cpp: In function ‘void loadJson(Circom_CalcWit*, std::string)’:
main.cpp:128:34: error: variable ‘std::ifstream inStream’ has initializer but incomplete type
  128 |   std::ifstream inStream(filename);
      |                                  ^
main.cpp:129:3: error: ‘json’ was not declared in this scope
  129 |   json j;
      |   ^~~~
main.cpp:130:15: error: ‘j’ was not declared in this scope
  130 |   inStream >> j;
      |               ^
main.cpp:134:8: error: ‘json’ is not a class, namespace, or enumeration
  134 |   for (json::iterator it = j.begin(); it != j.end(); ++it) {
      |        ^~~~
main.cpp:134:39: error: ‘it’ was not declared in this scope; did you mean ‘int’?
  134 |   for (json::iterator it = j.begin(); it != j.end(); ++it) {
      |                                       ^~
      |                                       int
main.cpp:137:10: error: ‘vector’ is not a member of ‘std’
  137 |     std::vector<FrElement> v;
      |          ^~~~~~
main.cpp:6:1: note: ‘std::vector’ is defined in header ‘<vector>’; did you forget to ‘#include <vector>’?
    5 | #include "calcwit.hpp"
  +++ |+#include <vector>
    6 | void Main_0_create(uint soffset,uint coffset,Circom_CalcWit* ctx,std::string componentName,uint componentFather);
main.cpp:137:26: error: expected primary-expression before ‘>’ token
  137 |     std::vector<FrElement> v;
      |                          ^
main.cpp:137:28: error: ‘v’ was not declared in this scope
  137 |     std::vector<FrElement> v;
      |                            ^
main.cpp:138:5: error: ‘json2FrElements’ was not declared in this scope
  138 |     json2FrElements(it.value(),v);
      |     ^~~~~~~~~~~~~~~
main.cpp:141:21: error: aggregate ‘std::ostringstream errStrStream’ has incomplete type and cannot be defined
  141 |  std::ostringstream errStrStream;
      |                     ^~~~~~~~~~~~
main.cpp:146:21: error: aggregate ‘std::ostringstream errStrStream’ has incomplete type and cannot be defined
  146 |  std::ostringstream errStrStream;
      |                     ^~~~~~~~~~~~
main.cpp:155:21: error: aggregate ‘std::ostringstream errStrStream’ has incomplete type and cannot be defined
  155 |  std::ostringstream errStrStream;
      |                     ^~~~~~~~~~~~
main.cpp: In function ‘int main(int, char**)’:
main.cpp:222:30: error: ‘loadCircuit’ was not declared in this scope
  222 |    Circom_Circuit *circuit = loadCircuit(datfile);
      |                              ^~~~~~~~~~~
make: *** [Makefile:16: main.o] Error 1

Illegal hardware instruction on Mac OS if using C++ witness calculator

I was trying to follow the example from the official documentation https://docs.circom.io/getting-started/computing-the-witness/#computing-the-witness-with-c. I was able to compile the C++ witness calculator on Mac OS thanks to #12. However, when I tried to generate the witness I got an error:

zsh: illegal hardware instruction  ./circuit input.json witness.wtns

The code to reproduce the issue is in the repo: alxkzmn/zk-wordle@5690ffc

Steps to reproduce:

cd circuit_cpp
make
./circuit input.json witness.wtns

Please update the tutorial

Since the snarkjs update, a lot of code in the tutorial has been broken, such as:

// error code:
snarkjs printconstraints -r circuit.r1cs -s circuit.sym
// right code
snarkjs r1cs print circuit.r1cs circuit.sym

// error code:
snarkjs setup -r circuit.r1cs
// right code:
snarkjs plonk setup circuit.r1cs pot12_final.ptau circuit_final.zkey

And the running order of snarkjs is no longer as it is in the tutorial, I'm glad to submit a pr to fix this bug, but I didn't find the repository for this tutorial, please tell me which repository can submit pr, I will solve these problems

happy to help

Circom outputs to incorrect paths

I've been chasing this issue for a while now, trying to figure out why circom_tester is failing when I'm using temp files for circuits. For some reason, circom is removing a portion of the base file name, and circom_tester assumes a given file name.

Basic reproducible example

Test steps:

  • echo "pragma circom 2.0.0; template foo () {} component main = foo();" > /tmp/test2021104-13814-o1so8j.x9v4k.circom
  • circom --wasm --sym --r1cs --output $(mktemp -d) /tmp/test2021104-13814-o1so8j.x9v4k.circom

Note the input file name, which is a format that common temp file generation libraries use (in this case node-temp)

Expected:

template instances: 1
non-linear constraints: 0
linear constraints: 0
public inputs: 0
public outputs: 0
private inputs: 0
private outputs: 0
wires: 1
labels: 1
Written successfully: /tmp/tmp.xvLoOJQNqm/test2021104-13814-o1so8j.x9v4k.r1cs
Written successfully: /tmp/tmp.xvLoOJQNqm/test2021104-13814-o1so8j.x9v4k.sym
Written successfully: /tmp/tmp.xvLoOJQNqm/test2021104-13814-o1so8j.x9v4k_js/test2021104-13814-o1so8j.x9v4k.wasm
Everything went okay, circom safe

Actual:

template instances: 1
non-linear constraints: 0
linear constraints: 0
public inputs: 0
public outputs: 0
private inputs: 0
private outputs: 0
wires: 1
labels: 1
Written successfully: /tmp/tmp.xvLoOJQNqm/test2021104-13814-o1so8j.r1cs
Written successfully: /tmp/tmp.xvLoOJQNqm/test2021104-13814-o1so8j.sym
Written successfully: /tmp/tmp.xvLoOJQNqm/test2021104-13814-o1so8j.x9v4k_js/test2021104-13814-o1so8j.wasm
Everything went okay, circom safe

bug?: circom should optimize out unused signals

Given this simple circuit

template C() {
signal input a;
signal input b;
b === 3;
}
component main = C();

The info of r1cs compiled by old js circom is

[INFO]  snarkJS: Curve: bn-128
[INFO]  snarkJS: # of Wires: 1
[INFO]  snarkJS: # of Constraints: 0
[INFO]  snarkJS: # of Private Inputs: 0
[INFO]  snarkJS: # of Public Inputs: 0
[INFO]  snarkJS: # of Outputs: 0

The info of r1cs compiled by new rust circom is

[INFO]  snarkJS: Curve: bn-128
[INFO]  snarkJS: # of Wires: 2
[INFO]  snarkJS: # of Constraints: 0
[INFO]  snarkJS: # of Private Inputs: 2
[INFO]  snarkJS: # of Public Inputs: 0
[INFO]  snarkJS: # of Outputs: 0

I guess it is better to remove unused signals as the old circom?

How to use two independent outputs in one circuit?

Hello circom people! I've tried to find a similar issue or a documentation for my case, but didn't succeed. Please help 🥲

I'm trying to create a simple circuit which has two inputs: secret (private) and wallet (public). In this circuit i calculate mimc hash for wallet + secret and secret. But when i try to verify it, i get the following error:

[ERROR] snarkJS: Error: Invalid witness length. Circuit: 276, witness: 549

But if i calculate only one hash with single output it works ok. What am i doing wrong?

This is my circuit:

pragma circom 2.0.7;

include "../../node_modules/circomlib/circuits/mimcsponge.circom";

template Hash() {
  signal input preimage;
  signal output out;

  component mimc = MiMCSponge(1, 91, 1); // (nInputs, nRounds, nOutputs)
  mimc.k <== 1;
  mimc.ins[0] <== preimage;

  out <== mimc.outs[0];
}

template Main() {
    signal input secret;
    signal input wallet;
    signal output outs[2];

    component walletSecretHash = Hash();
    walletSecretHash.preimage <== secret + wallet;
    outs[0] <== walletSecretHash.out;

    component secretHash = Hash();
    secretHash.preimage <== secret;
    outs[1] <== secretHash.out;
}

component main {public [wallet]} = Main();

Better error handling for conditional(unknown)

The following circuit fails with an error on a seemingly unrelated line:

template ItFails() {
    signal output out1;
    signal output out2;
    out1 <== 1;

    if ( out1 ) {
        out2 <-- 1;
    } else {
        out2 <-- 1; // ERROR HERE: Exception caused by invalid assignment
    }
}

Strangely, compiler doesn't complain at:

template ItFails() {
    signal output out1;
    signal output out2;
    out1 <== 1;

    if ( out1 ) {
        out2 <-- 1;
    }
}

It's unclear whether:

  1. compiler doesn't allow conditionals on unknowns PERIOD... OR
  2. compiler doesn't allow conditionals on unknowns iff its inner scope sets a constraint.

[Question] Pass the array into and retrieve the array from a function

Hello everyone~ 😀

Recently, I'm writing circom version of my python functions.
(To make the zk proof of python functions' output)

If I have a python function, I can easily pass the array into and retrieve the array from that function.

def myFunc(in_array):
    # Some calculations
    return out_array

if __name__ == "__main__":
    in_array = [1, 2, 3];
    out_array = myFunc(in_array);

However, according to docs, I cannot find examples or somewhere else that talking about passing array into a function.
Currently, I guess that it might be something like this:

function myFunc(in_array) {
    // Some calculations
    return out_array;
}

template mainFunc() {
	signal private input in_array; // A fixed length array
	signal private input b;
	signal output out;
	
	var out_array = myFunc(in_array);
}

component main = mainFunc();

Thanks for anyone willing to give me the answer or some clues about how I could develop in this situation. 🙏❤

-l operator at the end doesn't work

If the -l parameter (include dir) is at the last parameter it doesn't work. If it's at the first one it does.

Example:

This doesn't work:

 ~/git/zkevm/pil-stark/ [main*] circom --wasm --sym --r1cs --output outdir --prime goldilocks --O1 -l circuits.gl circuit.circom
invalid input file
previous errors were found

But this does:
 ~/git/zkevm/pil-stark/ [main*] circom --wasm -l circuits.gl --sym --r1cs --output outdir --prime goldilocks --O1 circuit.circom

Recursive construction support

Thanks for this repo! I am very excited to see that you are going to add recursive plonk support.

Can you please share the timeline of adding recursive SNARK support?

circom breaks when a multi-line comment is closed with **/

Having a multi-line comment closed with **/ breaks circom, the errors shown may be misleading.

Working example:

pragma circom 2.0.0;
/*
*/
template test() {
    signal input in;
    signal output out;
    out <== in * 2;
}
component main = test();

An example to reproduce the issue:

pragma circom 2.0.0;
/*
**/
template test() {
    signal input in;
    signal output out;
    out <== in * 2;
}
component main = test();

In the example above, the displayed compilation error is error[P1001]: No main specified in the project structure.

If a comment closed with **/ happens to be inside a template, the compiler seems to think the comment was never closed.

error[P1000]: UnrecognizedEOF { location: 38, expected: ["\"!\"", "\"(\"", "\"-\"", "\"[\"", "\"assert\"", "\"component\"", "\"for\"", "\"if\"", "\"log\"", "\"return\"", "\"signal\"", "\"var\"", "\"while\"", "\"{\"", "\"}\"", "\"~\"", "r#\"0x[0-9A-Fa-f]*\"#", "r#\"[$_]*[a-zA-Z][a-zA-Z$_0-9]*\"#", "r#\"[0-9]+\"#"] }
  ┌─ "/home/whyamiroot/test.circom":1:1
  │
1 │ pragma circom 2.0.0;
  │ ^ Invalid syntax

Here's an example to reproduce the error message above:

pragma circom 2.0.0;
template test() {
    /*
    **/
    signal input in;
    signal output out;
    out <== in * 2;
}

Other conditions that I tried to trigger this issue:

  • inline comment /**/ - doesn't trigger
  • inline comment /***/ - triggers
  • inline comment // ... - doesn't trigger with any combination of asterisks and slashes
  • multiline comment with /*, *, and */ on separate lines - doesn't trigger

Environment:

  • OS: Ubuntu 18.04
  • cargo version: 1.58.0 (f01b232bc 2022-01-19)
  • circom version: 2.0.3
  • circom flags: --r1cs --wasm --sym

Conditional statement inside a loop while instantiating components causing the compiler to panic

I have this piece of code -

template Main(){
        signal input in;
        signal output out;
        component num2bits[4], xor[3];
        for(var i=0; i<4; i++)
        {
                num2bits[i] = Num2Bits(32);
                if (i<3) xor[i] = XOR();
         }
}

It is causing the compiler to panic while writing the cpp and js files -

template instances: 3
non-linear constraints: 131
linear constraints: 0
public inputs: 0
public outputs: 1
private inputs: 1
private outputs: 0
wires: 139
labels: 144
Written successfully: ./main.r1cs
Written successfully: ./main.sym
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', compiler/src/ir_processing/set_arena_size.rs:41:69
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Although, rewriting the code as following solves the problem -

template Main(){
        signal input in;
        signal output out;
        component num2bits[4], xor[3];
        for(var i=0; i<4; i++) num2bits[i] = Num2Bits(32);
        for(var i=0; i<3; i++) xor[i] = XOR();
}

Flaky witness generation: `Illegal instruction (core dumped)`

Witness generation fails for the MACI circuit sometimes and sometimes it succeeds with the exact same condition(environments, tools, step). Following logs are printed when it fails:

Illegal instruction (core dumped)

Error: Error executing ./zkeys/ProcessMessages_10-2-1-2_test /tmp/tmp-7501-O0FLciBuSEkX/input.json /tmp/tmp-7501-O0FLciBuSEkX/output.wtns

Reproduce Procedure

Run the following script on the new Ubuntu 21.04 instance. When it comes to Ubuntu 20.04, install glibc 2.33 by using this script.

#!/bin/bash

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

nvm install 16
nvm use 16



sudo apt-get update
sudo apt-get install --yes build-essential libgmp-dev libsodium-dev nlohmann-json3-dev  nasm git


# Get rapidsnark
mkdir -p ~/rapidsnark/build
wget -O ~/rapidsnark/build/prover https://maci-devops-zkeys.s3.ap-northeast-2.amazonaws.com/rapidsnark-linux-amd64-1c137

chmod +x ~/rapidsnark/build/prover


# Get circom
mkdir -p ~/.local/bin
wget -O ~/.local/bin/circom https://maci-devops-zkeys.s3.ap-northeast-2.amazonaws.com/circom-linux-amd64-v2.0.3

chmod +x ~/.local/bin/circom

cd ~
git config --global url."https://github.com/".insteadOf git://github.com/

# Install MACI
git clone https://github.com/appliedzkp/maci.git
cd maci
git checkout v1
git reset --hard a069145cc339c92689c3c2793c70b1b93f208572

npm install
npm run bootstrap
npm run build



# Test
cd contracts
npm run compileSol

cd ~/maci/contracts/
nohup npx hardhat node \
    --hostname 0.0.0.0 \
    --port 8545 > /dev/null 2>&1 &



cd ~/maci/cli

mkdir -p zkeys

wget -O zkeys.tar.gz https://maci-devops.s3.ap-northeast-2.amazonaws.com/zkeys.tar.gz
tar -xzvf zkeys.tar.gz

chmod -R 777 zkeys




node build/index.js deployVkRegistry && \
node build/index.js setVerifyingKeys -s 10 -i 1 -m 2 -v 2 -b 1 \
    -p ./zkeys/ProcessMessages_10-2-1-2_test.0.zkey \
    -t ./zkeys/TallyVotes_10-1-2_test.0.zkey \
    -k 0x8CdaF0CD259887258Bc13a92C0a6dA92698644C0

node build/index.js create \
    -r 0x8CdaF0CD259887258Bc13a92C0a6dA92698644C0 && \
node ./build/index.js deployPoll -x 0xf204a4Ef082f5c04bB89F7D5E6568B796096735a \
    -pk macipk.c974f4f168b79727ac98bfd53a65ea0b4e45dc2552fe73df9f8b51ebb0930330 \
    -t 20 -g 25 -mv 25 -i 1 -m 2 -b 1 -v 2 && \
node ./build/index.js signup \
    -p macipk.3e7bb2d7f0a1b7e980f1b6f363d1e3b7a12b9ae354c2cd60a9cfa9fd12917391 \
    -x 0xf204a4Ef082f5c04bB89F7D5E6568B796096735a && \
node build/index.js publish \
    -p macipk.3e7bb2d7f0a1b7e980f1b6f363d1e3b7a12b9ae354c2cd60a9cfa9fd12917391 \
    -sk macisk.fd7aa614ec4a82716ffc219c24fd7e7b52a2b63b5afb17e81c22fe21515539c \
    -x 0xf204a4Ef082f5c04bB89F7D5E6568B796096735a \
    -i 1 -v 0 -w 9 -n 1 -o 0
    
node build/index.js timeTravel -s 30 && \
node build/index.js mergeMessages -x 0xf204a4Ef082f5c04bB89F7D5E6568B796096735a -o 0 && \
node build/index.js mergeSignups -x 0xf204a4Ef082f5c04bB89F7D5E6568B796096735a -o 0 && \
rm -rf proofs tally.json 


# Repeat tests until it fails
cat <<EOF | sh -c 'set -e
while true
do 
    node build/index.js genProofs -x 0xf204a4Ef082f5c04bB89F7D5E6568B796096735a \
        -sk macisk.49953af3585856f539d194b46c82f4ed54ec508fb9b882940cbe68bbc57e59e \
        -o 0 \
        -r ~/rapidsnark/build/prover \
        -wp ./zkeys/ProcessMessages_10-2-1-2_test \
        -wt ./zkeys/TallyVotes_10-1-2_test \
        -zp ./zkeys/ProcessMessages_10-2-1-2_test.0.zkey \
        -zt ./zkeys/TallyVotes_10-1-2_test.0.zkey \
        -t tally.json \
        -f proofs
done'
EOF

Environment

OS: Ubuntu 21.04 (x86_64)
Circom: 2.0.3

Background

privacy-scaling-explorations/maci#402

Question: Why is <== considered safer than <-- ?

The docs [1] state that "using <-- and --> is, in general, dangerous". Could someone please elaborate on the reason behind this statement?
Is it "safer" to use <== instead of <-- followed by ===?
Some students in crypto class (myself included) are curious about this. 🤓

[1]

Signals can only be assigned using the operations `<--` or `<==` (see [Basic operators](../basic-operators)) with the signal on the left hand side and and `-->` or `==>` (see [Basic operators](../basic-operators)) with the signal on the right hand side. The safe options are `<==` and `==>`, since they assign values and also generate constraints at the same time. Using `<--` and `-->` is, in general, dangerous and should only be used when the assigned expression cannot be included in a constraint, like in the following example.

How can I modify GLOBAL_FIELD_P in circom?

Hi!I'm a novice about circom.
I want to modify GLOBAL_FIELD_P, but don't know how to do it.
Can someone help me with this problem with an example?This is important to my research.

A figure of an F_7-arithmetic circuit is missing

The "Background" part of the documentation says:

In the figure below, we have defined an F_7-arithmetic circuit that performs the operation...

https://github.com/iden3/circom/blob/master/mkdocs/docs/background/background.md

However, no image actually shows up. The reason is that the following link to the image is dead:
https://gblobscdn.gitbook.com/assets%2F-MDt-cjMfCLyy351MraT%2F-MHR5icu-Jxuas-UC7DY%2F-MHR60RuAQK6qNzhOPgE%2Foutput.jpg?alt=media&token=39d3d332-cac5-4546-ab43-9f489241ae50

Fails to compile in M1

It can be temporally fixed by compling, keeping the arm64 code from the libwabt.a fat binary and compile again

# for commit a9a4a24e4e95debb0230a233c259fac7d3e1e186
cargo build --release
lipo target/release/build/wabt-sys-ccf4f394b6bb7490/out/build/libwabt.a -thin arm64 -output target/release/build/wabt-sys-ccf4f394b6bb7490/out/build/libwabt.a
cargo build --release

"previous errors were found"

When I compile my circuits, if there is an error, there is always a line in the error message which says "previous errors were found". Is it possible to eventually expand that error message to point to which previous errors?

Changing the GLOBAL_FIELD_P and the elliptic curve

(Yes, I have seen #49)
I would love to be able to generate proofs using the BLS12-381 curve. Snarkjs already supports this curve.

R1CS file

Changing the curve for the R1CS file is rather straightforward, since BN128's group order is hardcoded as a string here. I changed it to BLS12-381's group order and checked using snarkjs that the R1CS's curve had changed. It works 🎉

Witness file

Using the C++ witness generator, calculations for the witness are done in the fr.asm assembly file, and from what I gather using Montgomery representation. Below are the constants defined in the section .data at the end of the file:

section .data
Fr_q:
        dd      0
        dd      0x80000000
Fr_rawq:
q       dq      0x43e1f593f0000001,0x2833e84879b97091,0xb85045b68181585d,0x30644e72e131a029
half    dq      0xa1f0fac9f8000000,0x9419f4243cdcb848,0xdc2822db40c0ac2e,0x183227397098d014
R2      dq      0x1bb8e645ae216da7,0x53fe3ab1e35c59e3,0x8c49833d53bb8085,0x0216d0b17f4e44a5
Fr_R3:
        dd      0
        dd      0x80000000
Fr_rawR3:
R3      dq      0x5e94d8e1b4bf0040,0x2a489cbe1cfbb6b8,0x893cc664a19fcfed,0x0cf8594b7fcc657c
lboMask dq      0x3fffffffffffffff
np      dq      0xc2e1f593efffffff

I understand that q is BN128's group order and the modulo for all operations and that half = (q-1)/2 (used for comparisons).

R2 and R3 must be Montgomery coefficients, R2 being used for conversion to Montgomery representation and R3 being used for multiplication. However, I do not understand what they actually represent, since they are smaller that q and are not inverses of one another.

I also do not understand what lboMask (a mask for the two most significant bits?) and np are for.

I would love to make a PR to define the prime modulus using a command-line argument for example. I would just need help to understand these last things.

Feature request: Trace mode

A lot of logging in circuits is primarily used for generating "stack traces" of the execution when generating a witness. Ideally, circom should have a "trace" mode that injects log statements for:

  1. entering template
  2. all template inputs
  3. all template outputs
  4. exiting templates

These would then be logged (or traced some other way?) recursively as the witness is generated.

[Question] About GLOBAL_FIELD_P

Hello everyone~ 😀

These days, I have been studying about arithmetic in Circom, in order to implement UQ number with saturation arithmetic.
But some weird outcomes really bothered me.

(1) Why did the relational operator x > y fail?

var p_minus_one = 21888242871839275222246405745257275088548364400416034343698204186575808495616;
assert(p_minus_one > 0); // I got compiled error msg: error[T3001]: False assert reached

According to the docs, relational operators are based on a math function val(z).

In this case, p_minus_one would be val(p_minus_one) = 2188...5616, which is literally GLOBAL_FIELD_P minus integer one.
Hence, the condition p_minus_one > 0 should be hold and passed the assertion.

I believe that there must be something I have not understood, so I inaccurately think about how the above codes work.

(2) Is it available to access GLOBAL_FIELD_P in Circom language?
It doesn't a big problem.
I can do the some things like the above which just hard-coded numbers.
But I think there must be a more elegant way to achieve this task.

Thanks for anyone willing to reply me or give me the clues. 🙏❤

Circom should not forcibly exit on success

In b953bf9, @miguelis made circom forcibly exit on success, which makes many workflows (such as using the circom tool inside a script or when using it in WASM) break. It would probably be fine to forcibly exit with a code if there is an error but never should you forcibly exit with 0 on a success.

I tried removing the exit and circom hits an unreachable in the code, so more fixes will need to be applied to make the code work correctly.

Generate input/output interface for circom.

Motivation

We are using snarkjs as backend for circom.

     const { proof, publicSignals } = await snarkjs.groth16.fullProve(
            inputs,
            circuitWasmPath,
            zkeyPath
     )

Variable inputs have type any. Every time we changed circom file we need to update inputs structs. However any make us hard to remember and easy to create error/bugs.
I think we should create function for auto gen inputs/outputs interface of circom. It's help developer easy to test and use circom.

Proposal

Create new interface command line to generate inputs/outputs interface.

Example

circom merkle_tree.circom --types types.ts

Circom file

include "../../../node_modules/circomlib/circuits/comparators.circom";

template Example() {
    signal input first_input;
    signal input second_input[100];
    signal output first_output;
}

We will generate inputs interface like bellow:

interface ExampleInput {
    first_input: bigint;
    second_input: bigint[];
}

Samething for outputs interface.

Thank Iden3 for awesome work!

Exit with message when circuit too large for wasm

For circuits larger than ~1M constraints, it would be helpful if the witness generation exited with error when it detects a proof that is too large for wasm, and suggests compiling in C++ instead.

Add version tags

It seems that the repository does not follow any version tagging strategy.

I believe adding version tags would be helpful for many users given that one may want to pin circom installation to specific a version in order to maintain compatibility with other dependencies.

One example is performing circom installation through Docker.

Feature request: Log function should allow labels

It would really help in developing and debugging huge circuits if the log() function would accept a string label, such as log("myLabel", 0)

An even better improvement would be to allow log to be variadic, but I'm not sure how hard that would be.

Hexadecimal numbers as json string input

Hello,
I have the following minimal circuit that uses a hexadecimal number as an input from a json file:

pragma circom 2.0.0;

template POC() {
    signal input a;
    signal input b;
    signal input c;

    log(a);
    log(b);
    log(c);
}

component main = POC();

Using the following json as an input file:

{"a": "0x42", "b": 100, "c": "110"}

The circuit logs the following:

0
100
110

I am fairly certain hexadecimal numbers worked as an input in previous versions of circom. Is this functionality still supported, or is this now the intended behavior?

The --wasm option produces three JavaScript files?

The "Getting started" part of the documentation says:

Let us start with the Wasm code. Using the generated Wasm binary and three JavaScript files, we simply need to provide...

https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/computing-the-witness.md

However, the command circom multiplier2.circom --wasm only produces two JavaScript files:

$ ls -1 multiplier2_js
generate_witness.js
multiplier2.wasm
witness_calculator.js

I would be happy if I could know this was simply a typo.

Just so you know, I'm using circom 2.0.4, and the full content of multiplier2.circom is the following.

pragma circom 2.0.4;

template Multiplier2() {
    signal input a;
    signal input b;
    signal output c;
    c <== a*b;
 }

 component main = Multiplier2();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.