### Prepare Phase 2 of Trusted Setup Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/proving-circuits.md Prepares the circuit-specific phase 2 of the trusted setup using the contributions from the previous phase. ```bash snarkjs powersoftau prepare phase2 pot12_0001.ptau pot12_final.ptau -v ``` -------------------------------- ### Install Circom and SnarkJS Source: https://context7.com/iden3/circom/llms.txt Installs the Rust toolchain, builds and installs the circom binary from source, and installs snarkjs via npm for proof generation. Verify installation with `circom --version`. ```shell curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh git clone https://github.com/iden3/circom.git cd circom cargo build --release cargo install --path circom circom --version # circom compiler 2.2.3 npm install -g snarkjs ``` -------------------------------- ### Install MkDocs Source: https://github.com/iden3/circom/blob/master/mkdocs/README-MKDOCS.md Installs the MkDocs package using pip. ```bash pip3 install mkdocs ``` -------------------------------- ### Install MkDocs Material Theme Source: https://github.com/iden3/circom/blob/master/mkdocs/README-MKDOCS.md Installs the Material theme for MkDocs. ```bash pip install mkdocs-material ``` -------------------------------- ### Run MkDocs Webserver Source: https://github.com/iden3/circom/blob/master/mkdocs/README-MKDOCS.md Starts the local MkDocs development server to preview documentation. ```bash mkdocs serve ``` -------------------------------- ### Groth16 Trusted Setup with snarkjs Source: https://context7.com/iden3/circom/llms.txt Perform the Powers of Tau trusted setup, which is circuit-independent, followed by the circuit-specific Groth16 setup. This generates the necessary `.zkey` files for proof generation. ```shell # === Trusted Setup === # Phase 1: Powers of Tau (circuit-independent) snarkjs powersoftau new bn128 12 pot12_0000.ptau -v snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau \ --name="First contribution" -v # Prepare Phase 2 transition snarkjs powersoftau prepare phase2 pot12_0001.ptau pot12_final.ptau -v # Phase 2: circuit-specific setup snarkjs groth16 setup multiplier2.r1cs pot12_final.ptau multiplier2_0000.zkey snarkjs zkey contribute multiplier2_0000.zkey multiplier2_0001.zkey \ --name="1st Contributor" -v # Export verification key snarkjs zkey export verificationkey multiplier2_0001.zkey verification_key.json ``` -------------------------------- ### Contribute to Phase 2 of Trusted Setup Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/proving-circuits.md Adds a contribution to the phase 2 of the trusted setup ceremony for the specific circuit. This is an anonymous contribution. ```bash snarkjs zkey contribute multiplier2_0000.zkey multiplier2_0001.zkey --name="1st Contributor Name" -v ``` -------------------------------- ### Install Circom Binary Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/installation.md Installs the compiled circom binary globally using Cargo. This makes the 'circom' command available in your system's PATH. Ensure you are still in the circom directory. ```text cargo install --path circom ``` -------------------------------- ### Parallel Component Instantiation in Rollup Example Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/templates-and-components.md Provides a practical example from rollup code, demonstrating the instantiation of an array of components ('rollupTx') where each component is declared with the 'parallel' tag for optimized witness generation. ```circom component rollupTx[nTx]; for (var i = 0; i < nTx; i++) { rollupTx[i] = parallel RollupTx(nLevels, maxFeeTx); } ``` -------------------------------- ### Install Rustup Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/installation.md Installs Rustup, the toolchain installer for Rust, which is a core dependency for the circom compiler. Run this command in your Linux or macOS terminal. ```shell curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh ``` -------------------------------- ### Input Signal Tag Example Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/tags.md Example of an input signal array declared with the 'binary' tag in the circomlib. This tag enforces that each signal in the array must be 0 or 1. ```circom template Bits2Num(n) { signal input {binary} in[n]; signal output out; var lc1=0; var e2 = 1; for (var i = 0; i out; } template A(){ ... component b = Bits2Num(10); b.in <== a; ... } ``` -------------------------------- ### Example Main Component Instantiation in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/the-main-component.md Illustrates the instantiation of the main component with a template, declaring 'in1' as public and 'in2' as private. Output signals are always public. ```circom pragma circom 2.0.0; template A(){ signal input in1; signal input in2; signal output out; out <== in1 * in2; } component main {public [in1]}= A(); ``` -------------------------------- ### Circom Circuit Example Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/formats/simplification-json.md A simple Circom circuit demonstrating internal and main components, used to illustrate the simplification substitution JSON output. ```circom pragma circom 2.0.0; template Internal() { signal input in[2]; signal output out; out <== in[0]*in[1]; } template Main() { signal input in[2]; signal output out; component c = Internal (); c.in[0] <== in[0]; c.in[1] <== in[1]+2*in[0]+1; c.out ==> out; } ``` -------------------------------- ### Generate Groth16 Setup (zkey) Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/proving-circuits.md Generates the .zkey file, which contains the proving and verification keys, along with phase 2 contributions. Requires the circuit's R1CS file and the final powers of tau file. ```bash snarkjs groth16 setup multiplier2.r1cs pot12_final.ptau multiplier2_0000.zkey ``` -------------------------------- ### Generate Quadratic Constraint with Intermediate Variable Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/constraint-generation.md This example shows how to use intermediate variables to build up an expression that is then assigned to an output signal, resulting in a quadratic constraint. ```circom signal input a; signal output b; var x = a*a; x += 3; b <== x; ``` -------------------------------- ### Inline Arrays with Buses in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/data-types.md Shows how to use inline arrays where elements are buses. This example demonstrates assigning elements from an input bus array to an output bus array, reordering them. ```circom bus A(){ signal x; } template B(){ input A a[3]; output A b[3]; b <== [a[2], a[0], a[1]]; } ``` -------------------------------- ### Clone Circom Repository Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/installation.md Clones the circom repository from GitHub to install the compiler from its sources. Ensure you are in the desired directory before running this command. ```text git clone https://github.com/iden3/circom.git ``` -------------------------------- ### Conditional Component Instantiation in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/templates-and-components.md Shows how to conditionally instantiate components based on input parameters. This example demonstrates that components are immutable and must be instantiated with matching types, even across different execution paths. ```circom template A(N){ signal input in; signal output out; out <== in; } template C(N){ signal output out; out <== N; } template B(N){ signal output out; component a; if(N > 0){ a = A(N); } else{ a = A(0); } a.in <== 1; a.out ==> out; } component main = B(1); ``` -------------------------------- ### Tag Inheritance Example Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/tags.md Demonstrates how tags are inherited. The 'intermediate' signal inherits the 'binary' tag from 'in', and 'out' also receives the tag. ```circom template A() { signal input {binary} in; signal intermediate; signal {binary} out; intermediate <== in; out <== intermediate; } ``` -------------------------------- ### Install snarkjs npm Package Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/installation.md Install the 'snarkjs' package globally using npm. This tool is required for generating and validating ZK proofs. ```text npm install -g snarkjs ``` -------------------------------- ### Circom Constraint Generation Operators Source: https://context7.com/iden3/circom/llms.txt Illustrates R1CS constraint generation using `===` for explicit quadratic constraints, and `<==`/`==>` for combined assignment and constraint. Includes examples for binary checks and range proofs. ```circom pragma circom 2.0.0; template BinaryCheck() { signal input in; signal output out; // Explicit quadratic constraint: in*(in-1) = 0 // Only satisfied when in ∈ {0, 1} in * (in - 1) === 0; out <== in; } template RangeProof() { signal input in; // must be < 2^8 signal output bits[8]; // Non-quadratic assignment (bit decomposition): use <-- then constrain for (var k = 0; k < 8; k++) { bits[k] <-- (in >> k) & 1; bits[k] * (bits[k] - 1) === 0; // enforce binary } // Reconstruct and constrain equality to original input var lc = 0; for (var k = 0; k < 8; k++) { lc += bits[k] * (1 << k); } lc === in; } template And2() { signal input in1, in2; signal output out; component b0 = BinaryCheck(); component b1 = BinaryCheck(); b0.in <== in1; b1.in <== in2; // AND is multiplication for binary signals out <== b0.out * b1.out; } component main = And2(); ``` -------------------------------- ### Simplification Substitution JSON with O0 Simplification Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/formats/simplification-json.md Example JSON output when running Circom with --simplification_substitution and --O0 flags, indicating no simplification is applied. ```json { } ``` -------------------------------- ### Groth16 Proof Generation with snarkjs Source: https://context7.com/iden3/circom/llms.txt Generate a Groth16 zk-SNARK proof using the compiled circuit, witness, and trusted setup key. This step produces the proof and public inputs/outputs. ```shell # === Proof Generation === # witness.wtns computed in previous step snarkjs groth16 prove multiplier2_0001.zkey witness.wtns proof.json public.json # proof.json — the zk-SNARK proof # public.json — public inputs and outputs ``` -------------------------------- ### Simplification Substitution JSON with O2 Simplification Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/formats/simplification-json.md Example JSON output when running Circom with --simplification_substitution and --O2 flags, showing full simplification with multiple substituted signals and complex linear expressions. ```json { "5" : {"2":"1"}, "4" : {"1":"1"}, "6" : {"0":"1","2":"2","3":"1"} } ``` -------------------------------- ### Compile C++ witness generator Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/computing-the-witness.md Use 'make' within the C++ directory to compile the witness generation executable. This requires specific development libraries to be installed. ```bash make ``` -------------------------------- ### Simplification Substitution JSON with O1 Simplification Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/formats/simplification-json.md Example JSON output when running Circom with the --simplification_substitution flag and default O1 simplification, showing two substituted signals. ```json { "5" : {"2":"1"}, "4" : {"1":"1"} } ``` -------------------------------- ### Anonymous Component with Named Inputs in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/anonymous-components-and-tuples.md This example illustrates the use of named inputs when instantiating an anonymous component, allowing for a more readable and flexible assignment of signals, regardless of their order. ```circom template A(n){ signal input a, b; signal output c; c <== a*b; } template B(n){ signal input in[n]; signal out <== A(n)(b <== in[1], a <== in[0]); } component main = B(2); ``` -------------------------------- ### Using Anonymous Components to Ignore Outputs Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/code-quality/inspect.md This concise example demonstrates using an anonymous component instantiation combined with the underscore notation to ignore all outputs, effectively silencing --inspect warnings for unused subcomponent signals. ```circom template check_bits(n){ signal input in; _ <== Num2Bits(n)(in); } ``` -------------------------------- ### Handling Unused Subcomponent Outputs Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/code-quality/inspect.md This example illustrates a common scenario where a subcomponent's outputs are not used. The --inspect option warns about unused signals like 'check.out'. Use `_ <== check.out;` to ignore them. ```circom include "bitify.circom"; template check_bits(n) { signal input in; component check = Num2Bits(n); check.in <== in; } component main = check_bits(10); ``` -------------------------------- ### Use Buses in a Circom Template Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/buses.md Utilize the 'Point' bus for template inputs and outputs. This example shows how buses can represent structured data like points in different formats (Edwards and Montgomery). ```circom template Edwards2Montgomery () { input Point() { edwards_point } in ; output Point() { montgomery_point } out ; out.x <–- (1 + in.y ) / (1 - in.y ) ; out.y <–- out.x / in.x ; out.x * (1 - in.y ) === (1 + in.y ) ; out.y * in.x === out.x ; } ``` -------------------------------- ### Tuple Assignment with Var Declarations in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/anonymous-components-and-tuples.md This example shows tuple assignment with pre-declared variables, including instances of templates. The assignments are performed element-wise, and intermediate values are updated sequentially. ```circom var v1, ..., vK; (v1,...,vK) = temp_name(a1,...,aN)(i1,...,iM); ``` -------------------------------- ### Partially Used Subcomponent Outputs Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/code-quality/inspect.md This example shows a case where only a portion of a subcomponent's output array ('check.out[0]') is used. The --inspect option will still warn about the unused elements of the array. ```circom include "bitify.circom"; template parity(n) { signal input in; signal output out; component check = Num2Bits(n); check.in <== in; out <== check.out[0]; } component main = parity(10); ``` -------------------------------- ### Circom Identifier Examples Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/identifiers.md Demonstrates valid identifier formats in Circom. Identifiers must start with underscores or an alphabetic character, followed by alphanumeric characters, underscores, or dollar signs. ```text signal input _in; var o_u_t; var o$o; ``` -------------------------------- ### Standard Component Instantiation in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/anonymous-components-and-tuples.md This demonstrates the traditional way of instantiating a component and connecting its signals. Use this when explicit signal assignments are preferred for clarity. ```circom template A(n){ signal input a, b; signal output c; c <== a*b; } template B(n){ signal input in[n]; signal out; component temp_a = A(n); temp_a.a <== in[0]; temp_a.b <== in[1]; out <== temp_a.c; } component main = B(2); ``` -------------------------------- ### Instantiate Array of Components in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/data-types.md Demonstrates how to instantiate an array of components using a template. Each component in the array can be initialized with potentially different parameters. ```circom pragma circom 2.0.0; template fun(N){ signal output out; out <== N; } template all(N){ component c[N]; for(var i = 0; i < N; i++){ c[i] = fun(i); } } component main = all(5); ``` -------------------------------- ### Component Instantiation Order Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/control-flow.md Demonstrates how component instantiation order in Circom may not strictly follow sequential code execution due to signal dependencies. ```circom template mult(){ signal input in[2]; signal output out; out <== in[0] * in[1]; } template mult4(){ signal input in[4]; component comp1 = mult(); component comp2 = mult(); comp1.in[0] = in[0]; comp2.in[0] = in[1]; comp2.in[1] = in[2]; comp1.in[1] = in[3]; } ``` -------------------------------- ### Redefine Buses for Input Examples in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/buses.md This section redefines the 'Film', 'Date', and 'Person' buses, likely to illustrate input formats for a 'Person' bus with different signal sizes than the initial example. ```circom bus Film() { signal title[2]; signal director[2]; signal year; } bus Date() { signal day; signal month; signal year; } bus Person() { signal name[2]; Film() films[2]; Date() birthday; } ``` -------------------------------- ### Circom Signal Tags for Type Safety Source: https://context7.com/iden3/circom/llms.txt Signal tags like {binary} and {maxbit} provide semantic metadata for signals. The compiler enforces these tags at instantiation boundaries, ensuring type correctness. This example demonstrates the IsZero and Bits2Num templates and their usage within an Example template. ```circom pragma circom 2.0.0; // IsZero template guarantees its output is always binary template IsZero() { signal input in; signal output {binary} out; signal inv; inv <-- in != 0 ? 1/in : 0; out <== -in * inv + 1; in * out === 0; } // Bits2Num expects binary inputs and annotates the output with maxbit template Bits2Num(n) { signal input {binary} in[n]; signal output {maxbit} out; var lc = 0; var e2 = 1; for (var i = 0; i < n; i++) { lc += in[i] * e2; e2 = e2 + e2; } out.maxbit = n; // set the tag value (must be before signal assignment) lc ==> out; } template Example() { signal input x; // isZero.out carries the {binary} tag; passing it to Bits2Num is type-safe signal output {binary} flag <== IsZero()(x); // Compiler error if a non-{binary} signal were passed to Bits2Num signal bits[1]; bits[0] <== flag; signal num <== Bits2Num(1)(bits); } component main {public [x]} = Example(); ``` -------------------------------- ### Valued Tag Declaration Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/tags.md Example of a valued tag 'maxbit' declared on an output signal. The tag value 'n' is assigned during the template execution. ```circom template Bits2Num(n) { signal input {binary} in[n]; signal output {maxbit} out; var lc1=0; var e2 = 1; for (var i = 0; i out; } ``` -------------------------------- ### Generate witness using C++ Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/computing-the-witness.md Run the compiled C++ executable to generate the witness file. This method is generally faster than the WASM approach for large circuits. ```bash ./multiplier2 input.json witness.wtns ``` -------------------------------- ### Invalid Array Declaration in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/data-types.md This example shows an invalid array declaration in Circom where the size is not explicitly given, which will result in a compilation error. ```circom var z = [2,8,4]; ``` -------------------------------- ### Circom Compiler Help Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/compiling-circuits.md Displays all available options and usage instructions for the Circom compiler. Use this to understand the full range of compilation flags. ```console circom --help ``` -------------------------------- ### Contribute to Powers of Tau Ceremony Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/proving-circuits.md Adds a contribution to the ongoing "powers of tau" ceremony. This step is crucial for generating the trusted setup. ```bash snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v ``` -------------------------------- ### Define Parameterized Buses in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/buses.md Shows how to define parameterized buses like 'PointN' which takes a dimension parameter. This allows for creating flexible bus structures that can be adapted at compile time. ```circom bus PointN(dim){ signal x[dim]; } ``` -------------------------------- ### Output Signal Tag for Validity Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/tags.md An example of a template that guarantees the output signal is always binary. This is achieved using constraints and an intermediate signal 'inv'. ```circom template IsZero() { signal input in; signal output {binary} out; signal inv; inv <-- in!=0 ? 1/in : 0; out <== -in*inv +1; in*out === 0; } ``` -------------------------------- ### Generate Call Parameters for Solidity Verifier Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/proving-circuits.md Use this command to generate parameters for calling the 'verifyProof' function in the deployed Solidity Verifier contract. Paste the output into the parameters field in Remix. ```text snarkjs generatecall ``` -------------------------------- ### Generate witness using WebAssembly Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/computing-the-witness.md Execute the generated JavaScript file to compute the witness from the WASM binary and input JSON. This command creates the 'witness.wtns' file. ```bash node generate_witness.js multiplier2.wasm input.json witness.wtns ``` -------------------------------- ### Conditional Compilation Error: Unknown Condition Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/control-flow.md This example shows a compilation error when a condition in an if statement depends on an unknown input signal, and constraints are generated within the block. ```circom pragma circom 2.0.0; template A(){} template wrong(N1){ signal input in; component c; if(in > N1){ c = A(); } } component main {public [in]} = wrong(1); ``` -------------------------------- ### Parallel Component Instantiation in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/templates-and-components.md Shows how to use the 'parallel' tag at the component level, right before calling a template. This allows for parallel execution of individual component instantiations, enhancing performance for witness generation. ```circom component comp = parallel NameTemplate(...){...} ``` -------------------------------- ### Compile with Specific Options Source: https://context7.com/iden3/circom/llms.txt Compiles a circuit using the BLS12-381 prime, O2 simplification, and no assembly generation for C++ code. Output is directed to the ./out directory. ```shell circom circuit.circom --r1cs --wasm --c --O2 --prime bls12381 --no_asm -o ./out ``` -------------------------------- ### Compile-Time Assert Failure in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/code-quality/code-assertion.md This example demonstrates a compile-time assertion that fails because the condition 'n > 0' is false when 'n' is 0. This will cause the compilation to fail with an error. ```circom template A(n) { signal input in; assert(n>0); in * in === n; } component main = A(0); ``` -------------------------------- ### Define Specific Figure Buses Using Parameters in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/buses.md Demonstrates defining concrete bus types like 'Triangle2D' and 'Square3D' by instantiating parameterized buses with specific values for their parameters. ```circom bus Triangle2D(){ Figure(3,2) {well_defined} triangle; } bus Square3D(){ Figure(4,3) {well_defined} square; } ``` -------------------------------- ### Custom Template Declaration Source: https://context7.com/iden3/circom/llms.txt Declares a custom template requiring Circom version 2.0.6 or higher. This example shows a placeholder for a PLONK custom gate, which does not generate R1CS constraints. ```circom // Require version 2.0.6+ for custom templates pragma circom 2.0.6; pragma custom_templates; template custom MyGate() { signal input in; signal output out; // PLONK custom gate — no R1CS constraints generated here } ``` -------------------------------- ### Build an N-Input AND Gate Circuit Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/more-circuits/more-basic-circuits.md This Circom template defines an N-input AND gate, generalizing the 2-input version. It uses loops to instantiate binaryCheck and Multiplier2 components for each input and intermediate multiplication. ```circom pragma circom 2.0.0; template binaryCheck () { /*Code from previous example*/ } template Multiplier2 () { /*Code from previous example*/ } template AndN (N){ //Declaration of signals and components. signal input in[N]; signal output out; component mult[N-1]; component binCheck[N]; //Statements. for(var i = 0; i < N; i++){ binCheck[i] = binaryCheck(); binCheck[i].in <== in[i]; } for(var i = 0; i < N-1; i++){ mult[i] = Multiplier2(); } mult[0].in1 <== binCheck[0].out; mult[0].in2 <== binCheck[1].out; for(var i = 0; i < N-2; i++){ mult[i+1].in1 <== mult[i].out; mult[i+1].in2 <== binCheck[i+2].out; } out <== mult[N-2].out; } component main = AndN(4); ``` -------------------------------- ### Generate Witness with C++ Source: https://context7.com/iden3/circom/llms.txt For large circuits, the C++ witness generator offers significantly faster performance than WASM. Compile with `--c`, build the executable with `make`, then run it with an input JSON file. ```shell # Step 1: compile to C++ (use --no_asm for portability) circom multiplier2.circom --r1cs --c --sym --no_asm -o ./build # Step 2: build the witness generator executable # Requires: nlohmann-json3-dev, libgmp-dev, nasm cd build/multiplier2_cpp make # Step 3: compute witness cat > input.json << 'EOF' {"a": "3", "b": "11"} EOF ./multiplier2 input.json witness.wtns # Produces witness.wtns — same format as WASM generator ``` -------------------------------- ### Signal Immutability Error in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/signals.md Signals in Circom are immutable. Assigning a value to a signal more than once will cause a compilation error. This example demonstrates an attempt to assign a value to 'out' twice. ```circom pragma circom 2.0.0; template A(){ signal input in; signal output outA; outA <== in; } template B(){ //Declaration of signals signal output out; out <== 0; component comp = A(); comp.in <== 0; out <== comp.outA; } component main = B(); ``` -------------------------------- ### Generate Witness with WebAssembly Source: https://context7.com/iden3/circom/llms.txt After compiling with `--wasm`, use the generated JavaScript helper to compute circuit signals from a JSON input file, producing a `.wtns` binary witness for snarkjs. ```shell # Step 1: compile to WASM circom multiplier2.circom --r1cs --wasm --sym -o ./build # Step 2: create input.json (use strings for large integers) cat > build/multiplier2_js/input.json << 'EOF' {"a": "3", "b": "11"} EOF # Step 3: compute witness cd build/multiplier2_js node generate_witness.js multiplier2.wasm input.json witness.wtns # Produces witness.wtns — binary format compatible with snarkjs ``` -------------------------------- ### Circom Template Instantiation Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/templates-and-components.md Shows how to instantiate a template 'tempid' with specific parameter values 'v1' through 'vn'. The parameters must be known constants at compile time. ```circom component c = tempid(v1,...,vn); ``` -------------------------------- ### Circom Template with Invalid Input Assignment Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/templates-and-components.md This example demonstrates an error where an input signal 'a' is assigned a value within its own template definition. This is not allowed and will result in an 'invalid assignment' error during compilation. ```circom pragma circom 2.0.0; template wrong (N) { signal input a; signal output b; a <== N; } component main = wrong(1); ``` -------------------------------- ### Circom Sub-component Signal Access Restriction Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/scoping.md This example illustrates Circom's restriction on accessing intermediate or nested signals of sub-components. Only input and output signals of a direct sub-component are accessible. ```circom pragma circom 2.0.0; template d(){ signal output x; x <== 1; } template c(){ signal output out2; out2 <== 2; component comp2 = d(); } template t(){ signal out; component c3 = c(); out <== c3.comp2.x; } component main = t(); ``` -------------------------------- ### Circom Compiler Help Output Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/getting-started/compilation-options.md Displays all available flags and options for the Circom compiler. Use this to understand the full range of compilation controls. ```console USAGE: circom [FLAGS] [OPTIONS] [--] [input] FLAGS: --r1cs Outputs the constraints in r1cs format --sym Outputs witness in sym format --wasm Compiles the circuit to wasm --json Outputs the constraints in json format --wat Compiles the circuit to wat -c, --c Compiles the circuit to C++ --O0 No simplification is applied --O1 Only applies signal to signal and signal to constant simplification. This is the default option --O2 Full constraint simplification --verbose Shows logs during compilation --inspect Does an additional check over the constraints produced --use_old_simplification_heuristics Applies the old version of the heuristics when performing linear simplification --simplification_substitution Outputs the substitution applied in the simplification phase in json format --no_asm Does not use asm files in witness generation code in C++ --no_init Removes initializations to 0 of variables ("var") in the witness generation code -h, --help Prints help information -V, --version Prints version information OPTIONS: -o, --output Path to the directory where the output will be written [default: .] -p, --prime To choose the prime number to use to generate the circuit. Receives the name of the curve (bn128, bls12377, bls12381, goldilocks, grumpkin, pallas, secq256r1, vesta) [default: bn128] -l ... Adds directory to library search path --O2round Maximum number of rounds of the simplification process --sanity_check Selects the level of sanity checks to be included in the witness generation code generated. It receives the value 0, 1, or 2. [default: 2] ARGS: Path to a circuit with a main component [default: ./circuit.circom] ``` -------------------------------- ### Circom Template with Signal Declaration in Loop Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/scoping.md This example demonstrates a valid Circom template where a signal 'aux' is declared outside the for loop. Signals declared within a for loop block are not allowed. ```circom pragma circom 2.1.5; template Cubes (N) { //Declaration of signals. signal input in[N]; signal output out[N]; //Statements. for (var i = 0; i < N; i++) { signal aux; aux <== in[i]*in[i]; out[i] <== aux*in[i]; } } component main = Cubes(5); ``` -------------------------------- ### Define Buses Using Parameterized Buses in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/buses.md Illustrates using parameterized buses to define other buses, such as 'Line' which uses 'PointN', and 'Figure' which uses 'Line'. This enables the creation of complex, parameterized data structures. ```circom bus Line(dim){ PointN(dim) start; PointN(dim) end; } bus Figure(num_sides, dim){ Line(dim) side[num_sides]; } ``` -------------------------------- ### Main Component Syntax in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/the-main-component.md Defines the general syntax for creating the main component, optionally specifying public input signals. Signals not listed are private. ```text component main {public [signal_list]} = tempid(v1,...,vn); ``` -------------------------------- ### Circom Template Definitions Source: https://context7.com/iden3/circom/llms.txt Shows how to define reusable circuit components using templates, including a generic N-input multiplier built from 2-input multipliers and a parallel version for potential thread optimization. ```circom pragma circom 2.0.0; // A generic N-input multiplier built from 2-input multipliers template Multiplier2() { signal input in1; signal input in2; signal output out; out <== in1 * in2; } template MultiplierN(N) { signal input in[N]; signal output out; component comp[N-1]; for (var i = 0; i < N-1; i++) { comp[i] = Multiplier2(); } comp[0].in1 <== in[0]; comp[0].in2 <== in[1]; for (var i = 0; i < N-2; i++) { comp[i+1].in1 <== comp[i].out; comp[i+1].in2 <== in[i+2]; } out <== comp[N-2].out; } // Parallel template: C++ witness generator will run templates in parallel threads template parallel ParallelMultiplierN(N) { signal input in[N]; signal output out; component comp[N-1]; for (var i = 0; i < N-1; i++) { comp[i] = parallel Multiplier2(); } comp[0].in1 <== in[0]; comp[0].in2 <== in[1]; for (var i = 0; i < N-2; i++) { comp[i+1].in1 <== comp[i].out; comp[i+1].in2 <== in[i+2]; } out <== comp[N-2].out; } component main {public [in]} = MultiplierN(4); // Proves knowledge of in[0]*in[1]*in[2]*in[3] without revealing the factors ``` -------------------------------- ### Valued Tag Assignment in Array Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/tags.md Example of assigning a valued tag to an array. The tag 'max' is assigned to the 'out' array. This code will throw an error because 'out[0]' is initialized before 'out.max' is assigned. ```circom template A(){ signal output {max} out[100]; out[0] <== 1; out.max = 10; } ``` -------------------------------- ### Circom Compile-Time Functions Source: https://context7.com/iden3/circom/llms.txt Demonstrates pure compile-time computations using functions for tasks like calculating the ceiling of log2 or recursive factorial. These functions cannot declare signals or generate constraints. ```circom pragma circom 2.0.0; // Compute ceiling of log2(a) function nbits(a) { var n = 1; var r = 0; while (n - 1 < a) { r++; n *= 2; } return r; } // Recursive factorial (computed at compile time) function factorial(n) { if (n == 0) { return 1; } return n * factorial(n - 1); } template UseFunction(N) { signal input in[N]; signal output out; var bits = nbits(N); // e.g. nbits(8) == 3 var fact = factorial(bits); // Use compile-time constants in constraints var lc = 0; for (var i = 0; i < N; i++) { lc += in[i]; } out <== lc * fact; } component main = UseFunction(8); // nbits(8)=3, factorial(3)=6, out = sum(in[0..7]) * 6 ``` -------------------------------- ### Template Using a Tagged Book Bus Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/buses.md Instantiate a template that uses the 'Book' bus and applies tags to its fields. This example checks if a book sold over 1 million copies and was published in 2024. ```circom template BestSeller2024(){ input Book() book; output Book() {best_seller2024} best_book; signal check_copies <== LessThan(book.sold_copies.maxvalue)([1000000,book.sold_copies]); check_copies === 1; signal check_2024 <== IsEqual()([book.year,2024]); check_2024 === 1; best_book <== book; } ``` -------------------------------- ### Initialize Output Signals in Circom Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/signals.md Initialize intermediate and output signals immediately after their declaration. This syntax is available since circom 2.0.4. ```circom pragma circom 2.0.0; template Multiplier2(){ //Declaration of signals signal input in1; signal input in2; signal output out <== in1 * in2; } component main {public [in1,in2]} = Multiplier2(); ``` -------------------------------- ### Build a 2-Input AND Gate Circuit Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/more-circuits/more-basic-circuits.md This Circom template defines a 2-input AND gate using Multiplier2 and binaryCheck templates. Ensure inputs are binary before multiplication. ```circom pragma circom 2.0.0; template Multiplier2(){ //Declaration of signals signal input in1; signal input in2; signal output out; //Statements. out <== in1 * in2; } template binaryCheck () { //Declaration of signals. signal input in; signal output out; //Statements. in * (in-1) === 0; out <== in; } template And2(){ //Declaration of signals and components. signal input in1; signal input in2; signal output out; component mult = Multiplier2(); component binCheck[2]; //Statements. binCheck[0] = binaryCheck(); binCheck[0].in <== in1; binCheck[1] = binaryCheck(); binCheck[1].in <== in2; mult.in1 <== binCheck[0].out; mult.in2 <== binCheck[1].out; out <== mult.out; } component main = And2(); ``` -------------------------------- ### Circom Function Error: Template Operator Found Source: https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/functions.md This example demonstrates an invalid Circom function that attempts to declare signals and generate constraints, which is not allowed. It will produce a 'Template operator found' error. ```text function nbits(a) { signal input in; //This is not allowed. var n = 1; var r = 0; while (n-1