From ee3a61424964900dd7699eba62bf6433f955796a Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Tue, 30 Jul 2024 05:34:22 -0400 Subject: [PATCH 1/7] Make some types public so that other projects can use Circom libraries to compile circuits and access their intermediate representation. --- .../address_type.rs | 18 +++++++++++++++++- .../branch_bucket.rs | 2 +- .../compute_bucket.rs | 2 +- compiler/src/lib.rs | 4 ++-- parser/Cargo.toml | 2 +- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/compiler/src/intermediate_representation/address_type.rs b/compiler/src/intermediate_representation/address_type.rs index ec05b3e90..cfdb3bc11 100644 --- a/compiler/src/intermediate_representation/address_type.rs +++ b/compiler/src/intermediate_representation/address_type.rs @@ -13,6 +13,22 @@ pub enum InputInformation { Input {status: StatusInput}, } +impl ToString for InputInformation { + fn to_string(&self) -> String { + use InputInformation::*; + match self { + NoInput => "NO_INPUT".to_string(), + Input { status } => { + match status { + StatusInput::Last => "LAST".to_string(), + StatusInput::NoLast => "NO_LAST".to_string(), + StatusInput::Unknown => "UNKNOWN".to_string(), + } + } + } + } +} + #[derive(Clone)] pub enum AddressType { Variable, @@ -26,7 +42,7 @@ impl ToString for AddressType { match self { Variable => "VARIABLE".to_string(), Signal => "SIGNAL".to_string(), - SubcmpSignal { cmp_address, .. } => format!("SUBCOMPONENT:{}", cmp_address.to_string()), + SubcmpSignal { cmp_address, input_information, .. } => format!("SUBCOMPONENT:{}:{}", cmp_address.to_string(), input_information.to_string()), } } } diff --git a/compiler/src/intermediate_representation/branch_bucket.rs b/compiler/src/intermediate_representation/branch_bucket.rs index 830b361ef..e0de88c19 100644 --- a/compiler/src/intermediate_representation/branch_bucket.rs +++ b/compiler/src/intermediate_representation/branch_bucket.rs @@ -46,7 +46,7 @@ impl ToString for BranchBucket { else_body = format!("{}{};", else_body, i.to_string()); } format!( - "IF(line:{},template_id:{},cond:{},if:{},else{})", + "IF(line:{},template_id:{},cond:{},if:{},else:{})", line, template_id, cond, if_body, else_body ) } diff --git a/compiler/src/intermediate_representation/compute_bucket.rs b/compiler/src/intermediate_representation/compute_bucket.rs index 1f14a1ffa..31a4498cb 100644 --- a/compiler/src/intermediate_representation/compute_bucket.rs +++ b/compiler/src/intermediate_representation/compute_bucket.rs @@ -3,7 +3,7 @@ use crate::translating_traits::*; use code_producers::c_elements::*; use code_producers::wasm_elements::*; -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] pub enum OperatorType { Mul, Div, diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index a9c4871e0..d7f2352ac 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -1,6 +1,6 @@ #[allow(dead_code)] -mod circuit_design; -mod intermediate_representation; +pub mod circuit_design; +pub mod intermediate_representation; mod ir_processing; pub extern crate num_bigint_dig as num_bigint; pub extern crate num_traits; diff --git a/parser/Cargo.toml b/parser/Cargo.toml index 02a86510b..38c94f9bb 100644 --- a/parser/Cargo.toml +++ b/parser/Cargo.toml @@ -13,7 +13,7 @@ num-traits = "0.2.6" [dependencies] program_structure = {path = "../program_structure"} -lalrpop-util = "0.19.9" +lalrpop-util = { version="0.19.9", features = ["lexer"]} regex = "1.1.2" rustc-hex = "2.0.1" num-bigint-dig = "0.6.0" From 838b6d27d9e1f8e57204d1caec934027c6c4a56c Mon Sep 17 00:00:00 2001 From: erhant Date: Mon, 30 Sep 2024 16:55:50 +0300 Subject: [PATCH 2/7] Add Circomkit to README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5d6790777..a6f82a3e6 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ TOOLS + [PICUS: a static analyzer for verifying weak and strong safety for circom circuits](https://github.com/Veridise/Picus) + [Hardhat-zkit: the ultimate typescript environment for circom development](https://github.com/dl-solarity/hardhat-zkit) ++ ++ [Circomkit: a testing & development environment for circom](https://github.com/erhant/circomkit) More information about the notions of weak and strong safety in circom circuits [here](https://ieeexplore.ieee.org/document/10002421). From 46868140d6658736d48c82bbace905b8ec29af58 Mon Sep 17 00:00:00 2001 From: miguelis Date: Fri, 4 Oct 2024 12:49:28 +0200 Subject: [PATCH 3/7] --O1 is now the default option. Updating the documentation accordingly. --- .../circom-insight/simplification.md | 8 +++++--- .../circom-language/formats/constraints-json.md | 17 +++++++++-------- .../formats/simplification-json.md | 12 ++++++------ mkdocs/docs/circom-language/formats/sym.md | 10 +++++----- .../docs/getting-started/compilation-options.md | 2 +- 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/mkdocs/docs/circom-language/circom-insight/simplification.md b/mkdocs/docs/circom-language/circom-insight/simplification.md index 244025ccb..06273cfda 100644 --- a/mkdocs/docs/circom-language/circom-insight/simplification.md +++ b/mkdocs/docs/circom-language/circom-insight/simplification.md @@ -1,6 +1,6 @@ # Constraint simplification -Constraint simplification is a key part of the `circom` compiler. Full simplification is activated by default, and its associated flag is `--O2` (see the [compilation options](../../getting-started/compilation-options.md)). Simplification is not applied when the flag `--O0` is activated, and a weaker (and faster) form of simplification is applied when using the flag `--O1`. +Constraint simplification is a key part of the `circom` compiler. A fast simplification `--O1` is activated by default (it only applies constant and renaming simplifications), and its associated flag is `--O1` (see the [compilation options](../../getting-started/compilation-options.md)). Simplification is not applied when the flag `--O0` is activated, and a full form of simplification is applied when using the flag `--O2`. Let us explain the performed simplification in detail. @@ -16,7 +16,7 @@ In the context of [Groth16], the statement to be proved is that given the public In case we are using the PLONK proof system (instead of Groth16), since additions are not free we cannot remove linear constraints anymore. Still we can remove equalities between signals or equalities between signals and constants which is made with the flag --O1 (see below). Moreover, note that if we apply linear simplification to a constraint system in PLONK format, the resulting constraints will in general not be in PLONK format anymore, and transforming the result back to PLONK format may lead to a worse result than the original. For this reason, when using PLONK, it is always recommended to use the --O1 flag. -Once we have explained why removing any private signal (including the private inputs) and applying linear simplification is correct, let us explain what kind of simplification is applied when we enable the flag `--O1` or the flag `--O2` (which is activated by default). Notice that if we do not want to apply any simplification we must use the flag `--O0`. +Once we have explained why removing any private signal (including the private inputs) and applying linear simplification is correct, let us explain what kind of simplification is applied when we enable the flag `--O1` (which is activated by default) or the flag `--O2`. Notice that if we do not want to apply any simplification we must use the flag `--O0`. * Flag ```--O1``` removes two kinds of simple constraints: a) ```signal = K```, being K is a constant in $F_p$ and b) ```signal1 = signal2```. In both cases, at least one of the signals must be private, and it is the one that will be replaced by the other side. Note that there are usually many equalities between two signals in constraints defined by circom programs as they are many times used to connect components with their sub components. @@ -30,6 +30,8 @@ Only one of these flags/options can be enabled in the compilation. In case we want to see the simplification applied we can use the flag [```--simplification_substitution```](../../getting-started/compilation-options.md) to obtain a json file whose format is described [here](../formats/simplification-json.md). -Note that, although the full simplification applied `--O2` can significantly reduce the number of constraints and signals, which has a positive impact in the time and space needed to compute the proof, this is the most time and space consuming phase of the compilation process. Hence, with large circuits, say with millions of constraints, compilation can take a long time (even minutes or hours) and can run in out-of-memory exceptions. In such cases, it is recommended to only use the `--O2` flag in the final steps of the project development. +Starting with circom 2.2.0, we have set `--O1` as the default simplification option. This decision aligns with the growing use of Plonk, as `--O2` is not compatible with it. + +Note that, using the full simplification `--O2` can significantly reduce the number of constraints and signals, which has a positive impact in the time and space needed to compute the proof. However, this is the most time and space consuming phase of the compilation process. Hence, with large circuits, say with millions of constraints, compilation can take a long time (even minutes or hours) and can run in out-of-memory exceptions. In such cases, it is recommended to only use the `--O2` flag in the final steps of the project development. [Groth16] Jens Groth. "On the Size of Pairing-Based Non-interactive Arguments". Advances in Cryptology -- EUROCRYPT 2016, pages 305--326. Springer Berlin Heidelberg, 2016. diff --git a/mkdocs/docs/circom-language/formats/constraints-json.md b/mkdocs/docs/circom-language/formats/constraints-json.md index cff7e63dc..31b9be1a7 100644 --- a/mkdocs/docs/circom-language/formats/constraints-json.md +++ b/mkdocs/docs/circom-language/formats/constraints-json.md @@ -47,19 +47,21 @@ template Main() { if we run ```text -circom simplify.circom --json --wasm +circom basic.circom --json --wasm ``` -a file 'basic_contraints.json' is generated that contains +a file 'basic_contraints.json' is generated and it contains two constraints: ```text { "constraints": [ -[{"2":"21888242871839275222246405745257275088548364400416034343698204186575808495616"},{"0":"1","2":"2","3":"1"},{"1":"21888242871839275222246405745257275088548364400416034343698204186575808495616"}] +[{"2":"21888242871839275222246405745257275088548364400416034343698204186575808495616"},{"4":"1"},{"1":"21888242871839275222246405745257275088548364400416034343698204186575808495616"}], +[{},{},{"0":"1","2":"2","3":"1","4":"21888242871839275222246405745257275088548364400416034343698204186575808495616"}] ] } ``` -where we can see that only one constraint is taken after applying the simplification (since the --O2 simplification is the default). + As we can see, only constant and renaming (equalities between signals) simplifications have been aplied +(since the --O1 simplification is the default). Instead, if we run @@ -82,16 +84,15 @@ to indicate that we do not want to apply any simplification the generated file ' Finaly, if we run ```text -circom basic.circom --json --wasm --O1 +circom basic.circom --json --wasm --O2 ``` -to indicate that we only want to apply constant and renaming (equalities between signals) simplifications, the generated file 'basic_constraints.json' contains +we can see that only one constraint is taken after applying the full simplification: ```text { "constraints": [ -[{"2":"21888242871839275222246405745257275088548364400416034343698204186575808495616"},{"4":"1"},{"1":"21888242871839275222246405745257275088548364400416034343698204186575808495616"}], -[{},{},{"0":"1","2":"2","3":"1","4":"21888242871839275222246405745257275088548364400416034343698204186575808495616"}] +[{"2":"21888242871839275222246405745257275088548364400416034343698204186575808495616"},{"0":"1","2":"2","3":"1"},{"1":"21888242871839275222246405745257275088548364400416034343698204186575808495616"}] ] } ``` diff --git a/mkdocs/docs/circom-language/formats/simplification-json.md b/mkdocs/docs/circom-language/formats/simplification-json.md index 7e582f6fc..4d1034e83 100644 --- a/mkdocs/docs/circom-language/formats/simplification-json.md +++ b/mkdocs/docs/circom-language/formats/simplification-json.md @@ -47,12 +47,11 @@ a file 'simplify_substitutions.json' is generated that contains ```text { "5" : {"2":"1"}, -"4" : {"1":"1"}, -"6" : {"0":"1","2":"2","3":"1"} +"4" : {"1":"1"} } ``` -where we can see that three signals have been substituted (since the --O2 simplification is the default). +where we can see that two signals have been substituted (since the `--O1` simplification is the default). Instead, if we run @@ -69,14 +68,15 @@ to indicate that we do not want to apply any simplification, the generated file Finally, if we run ```text -circom simplify.circom --r1cs --wasm --simplification_substitution --O1 +circom simplify.circom --r1cs --wasm --simplification_substitution --O2 ``` -to indicate that we only want to apply constant and renaming (equalities between signals) simplifications, the generated file 'simplify_substitutions.json' contains +to indicate that we want to apply the full form of simplification, the generated file 'simplify_substitutions.json' contains: ```text { "5" : {"2":"1"}, -"4" : {"1":"1"} +"4" : {"1":"1"}, +"6" : {"0":"1","2":"2","3":"1"} } ``` diff --git a/mkdocs/docs/circom-language/formats/sym.md b/mkdocs/docs/circom-language/formats/sym.md index a64cfc0a7..ea7dd7cf9 100644 --- a/mkdocs/docs/circom-language/formats/sym.md +++ b/mkdocs/docs/circom-language/formats/sym.md @@ -48,10 +48,10 @@ a file 'symbols.sym' is generated that contains 3,3,1,main.in[1] 4,-1,0,main.c.out 5,-1,0,main.c.in[0] -6,-1,0,main.c.in[1] +6,4,0,main.c.in[1] ``` -where we can see that three signals have been eliminated (since the --O2 simplification is the default). +where we can see that two signals have been eliminated (since the `--O1` simplification is the default). Instead, if we run @@ -72,10 +72,10 @@ to indicate that we do not want to apply any simplification the generated file ' Finally, if we run ```text -circom symbols.circom --r1cs --wasm --sym --O1 +circom symbols.circom --r1cs --wasm --sym --O2 ``` -to indicate that we only want to apply constant and renaming (equalities between signals) simplifications the generated file 'symbols.sym' contains +to indicate that we want to apply the full form of simplification, the generated file 'symbols.sym' contains ```text 1,1,1,main.out @@ -83,5 +83,5 @@ to indicate that we only want to apply constant and renaming (equalities between 3,3,1,main.in[1] 4,-1,0,main.c.out 5,-1,0,main.c.in[0] -6,4,0,main.c.in[1] +6,-1,0,main.c.in[1] ``` diff --git a/mkdocs/docs/getting-started/compilation-options.md b/mkdocs/docs/getting-started/compilation-options.md index 229e4628e..aec3befd1 100644 --- a/mkdocs/docs/getting-started/compilation-options.md +++ b/mkdocs/docs/getting-started/compilation-options.md @@ -39,7 +39,7 @@ In the following, we explain these options. ##### Flags and options related to the compiler's output * Flag ```--r1cs``` outputs the constraints in binary R1CS format (see the detailed format [here](https://github.com/iden3/r1csfile/blob/master/doc/r1cs_bin_format.md)). * Flag ```--sym``` outputs for every signal of the circuit: the unique number given by the compiler, the circom qualified name, the number of the witness signal that contains it and the (unique) number of the component (given by the compiler) it belongs (see the detailed format and examples [here](../circom-language/formats/sym.md)). -* Flag ```--simplification_substitution``` outputs the substitutions performed by the --O1 and --O2 (default) constraint simplification options in json format (see the detailed format [here](../circom-language/formats/simplification-json.md)). +* Flag ```--simplification_substitution``` outputs the substitutions performed by the --O1 (default) and --O2 constraint simplification options in json format (see the detailed format [here](../circom-language/formats/simplification-json.md)). * Flag ```--wasm``` produces a WebAssembly program that receives the private and public inputs and generates the circuit witness. * Flag ```-c / --c``` produces a C++ program that receives the private and public inputs and generates the circuit witness. * Flag ```--wat``` compiles the circuit to wat. From 1f3bb1263467e9de1afc7aead3c447e5c9dd2c99 Mon Sep 17 00:00:00 2001 From: Miguel Isabel Date: Fri, 4 Oct 2024 13:14:07 +0200 Subject: [PATCH 4/7] Update RELEASES.md --- RELEASES.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 182e2b6ed..f991c7e35 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,4 +1,21 @@ # Release notes +## October 04, 2024 circom 2.2.0 +#### New features +- Buses: more information [here](https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/buses.md). + +#### Extensions +- input/output declaration can now be made before signal keyword, though the previous way remains supported. +- Allowing array assignments of different sizes. +- Improving error reports when parsing. +- Improving documentation. + +#### Fixed bugs +- Main with no inputs is now executed once. +- Fixing complement function to depend on the prime number used. +- Applying modulo prime number to any constant in the circuit. +- Fixing minor panic: the number of signals passed to the anonymous component must be equal to the actual number of inputs. + + ## April 23, 2024 circom 2.1.9 #### Extensions From 71a368c4b2378630ee740f6237b0bcb03bca8a8e Mon Sep 17 00:00:00 2001 From: Albert Rubio <34064782+alrubio@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:48:02 +0200 Subject: [PATCH 5/7] Update simplification.md --- mkdocs/docs/circom-language/circom-insight/simplification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs/docs/circom-language/circom-insight/simplification.md b/mkdocs/docs/circom-language/circom-insight/simplification.md index 06273cfda..d74329f09 100644 --- a/mkdocs/docs/circom-language/circom-insight/simplification.md +++ b/mkdocs/docs/circom-language/circom-insight/simplification.md @@ -2,7 +2,7 @@ Constraint simplification is a key part of the `circom` compiler. A fast simplification `--O1` is activated by default (it only applies constant and renaming simplifications), and its associated flag is `--O1` (see the [compilation options](../../getting-started/compilation-options.md)). Simplification is not applied when the flag `--O0` is activated, and a full form of simplification is applied when using the flag `--O2`. -Let us explain the performed simplification in detail. +Let us explain the kind of simplification we can perform in detail. As pointed out in Section 2.3 (Quadratic arithmetic programs) of the [Groth16 paper](https://eprint.iacr.org/2016/260) (where ZK-SNARKs based on arithmetic circuits were introduced): From 6f6bfed1100ad115e7d3af37c0d9c5d8ffcbaff2 Mon Sep 17 00:00:00 2001 From: Albert Rubio <34064782+alrubio@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:49:46 +0200 Subject: [PATCH 6/7] Update RELEASES.md --- RELEASES.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index f991c7e35..69204ddd2 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -2,9 +2,12 @@ ## October 04, 2024 circom 2.2.0 #### New features - Buses: more information [here](https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/buses.md). - + +#### Changes +- input/output keywords are the first token in declarations (though having it after "signal" is still accepted). +- The default option for constraint simplification is --O1 (instead of --O2 which was the default until now). More information in [here](https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/circom-insight/simplification.md). + #### Extensions -- input/output declaration can now be made before signal keyword, though the previous way remains supported. - Allowing array assignments of different sizes. - Improving error reports when parsing. - Improving documentation. From 503a54e2e3db058ba58ae0da8272a808e1e7b795 Mon Sep 17 00:00:00 2001 From: Albert Rubio <34064782+alrubio@users.noreply.github.com> Date: Fri, 4 Oct 2024 14:14:07 +0200 Subject: [PATCH 7/7] Update simplification.md --- mkdocs/docs/circom-language/circom-insight/simplification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs/docs/circom-language/circom-insight/simplification.md b/mkdocs/docs/circom-language/circom-insight/simplification.md index d74329f09..5b99baec7 100644 --- a/mkdocs/docs/circom-language/circom-insight/simplification.md +++ b/mkdocs/docs/circom-language/circom-insight/simplification.md @@ -30,7 +30,7 @@ Only one of these flags/options can be enabled in the compilation. In case we want to see the simplification applied we can use the flag [```--simplification_substitution```](../../getting-started/compilation-options.md) to obtain a json file whose format is described [here](../formats/simplification-json.md). -Starting with circom 2.2.0, we have set `--O1` as the default simplification option. This decision aligns with the growing use of Plonk, as `--O2` is not compatible with it. +Since circom 2.2.0, we have set `--O1` as the default simplification option. This decision aligns with the growing use of Plonk, as `--O2` is not compatible with it. Note that, using the full simplification `--O2` can significantly reduce the number of constraints and signals, which has a positive impact in the time and space needed to compute the proof. However, this is the most time and space consuming phase of the compilation process. Hence, with large circuits, say with millions of constraints, compilation can take a long time (even minutes or hours) and can run in out-of-memory exceptions. In such cases, it is recommended to only use the `--O2` flag in the final steps of the project development.