Skip to content

Commit 63b0f37

Browse files
authored
Merge pull request #311 from Sacul231/master
Adding improvements circom 2.2.1
2 parents d199164 + faf69bd commit 63b0f37

File tree

29 files changed

+1440
-940
lines changed

29 files changed

+1440
-940
lines changed

RELEASES.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
11
# Release notes
2+
## November 12, 2024 circom 2.2.1
3+
#### Improvements:
4+
- Improving the use and heritance of tags inside buses. Now the values are propagated correctly following the same rules as arrays.
5+
- Unassigned inputs: do not executing the circuit twice in C++.
6+
- Allowing tag accesses of subcomponent input/output signals.
7+
- Handling equality checks with dynamic size in witness generation code.
8+
- Improving error messages.
9+
- Improving error recovery in parser.
10+
- Adding flag --constraint_assert_dissabled. When this flag is activated the compiler does not add asserts in the generated code (C++, WASM) for === constraint equalities
11+
12+
13+
#### Fixed bugs:
14+
- Importing function printDebug removed from WASM (circom tests from circomlib working now).
15+
16+
217
## October 07, 2024 circom 2.2.0
318
#### New features
419
- Buses: more information [here](https://github.com/iden3/circom/blob/master/mkdocs/docs/circom-language/buses.md).

circom/src/compilation_user.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub struct CompilerConfig {
2121
pub c_flag: bool,
2222
pub debug_output: bool,
2323
pub produce_input_log: bool,
24+
pub constraint_assert_dissabled_flag: bool,
2425
pub vcp: VCP,
2526
}
2627

@@ -30,7 +31,12 @@ pub fn compile(config: CompilerConfig) -> Result<(), ()> {
3031
if config.c_flag || config.wat_flag || config.wasm_flag{
3132
let circuit = compiler_interface::run_compiler(
3233
config.vcp,
33-
Config { debug_output: config.debug_output, produce_input_log: config.produce_input_log, wat_flag: config.wat_flag },
34+
Config {
35+
debug_output: config.debug_output,
36+
produce_input_log: config.produce_input_log,
37+
wat_flag: config.wat_flag,
38+
constraint_assert_dissabled_flag: config.constraint_assert_dissabled_flag,
39+
},
3440
VERSION
3541
)?;
3642

circom/src/input_user.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub struct Input {
2727
pub fast_flag: bool,
2828
pub reduced_simplification_flag: bool,
2929
pub parallel_simplification_flag: bool,
30+
pub constraint_assert_dissabled_flag: bool,
3031
pub flag_old_heuristics: bool,
3132
pub inspect_constraints_flag: bool,
3233
pub no_rounds: usize,
@@ -101,6 +102,7 @@ impl Input {
101102
fast_flag: o_style == SimplificationStyle::O0,
102103
reduced_simplification_flag: o_style == SimplificationStyle::O1,
103104
parallel_simplification_flag: input_processing::get_parallel_simplification(&matches),
105+
constraint_assert_dissabled_flag: input_processing::get_constraint_assert_dissabled(&matches),
104106
inspect_constraints_flag: input_processing::get_inspect_constraints(&matches),
105107
flag_old_heuristics: input_processing::get_flag_old_heuristics(&matches),
106108
flag_verbose: input_processing::get_flag_verbose(&matches),
@@ -209,6 +211,9 @@ impl Input {
209211
pub fn parallel_simplification_flag(&self) -> bool {
210212
self.parallel_simplification_flag
211213
}
214+
pub fn constraint_assert_dissabled_flag(&self) -> bool {
215+
self.constraint_assert_dissabled_flag
216+
}
212217
pub fn flag_old_heuristics(&self) -> bool {
213218
self.flag_old_heuristics
214219
}
@@ -304,6 +309,10 @@ mod input_processing {
304309
matches.is_present("parallel_simplification")
305310
}
306311

312+
pub fn get_constraint_assert_dissabled(matches: &ArgMatches) -> bool {
313+
matches.is_present("constraint_assert_dissabled")
314+
}
315+
307316
pub fn get_ir(matches: &ArgMatches) -> bool {
308317
matches.is_present("print_ir")
309318
}
@@ -477,6 +486,14 @@ mod input_processing {
477486
.display_order(180)
478487
.help("Runs non-linear simplification in parallel"),
479488
)
489+
.arg(
490+
Arg::with_name("constraint_assert_dissabled")
491+
.long("constraint_assert_dissabled")
492+
.takes_value(false)
493+
.hidden(false)
494+
.display_order(810)
495+
.help("Does not add asserts in the generated code for === constraint equalities"),
496+
)
480497
.arg(
481498
Arg::with_name("main_inputs_log")
482499
.long("inputs")

circom/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ fn start() -> Result<(), ()> {
6161
wat_file: user_input.wat_file().to_string(),
6262
wasm_file: user_input.wasm_file().to_string(),
6363
produce_input_log: user_input.main_inputs_flag(),
64+
constraint_assert_dissabled_flag: user_input.constraint_assert_dissabled_flag()
6465
};
6566
compilation_user::compile(compilation_config)?;
6667
Result::Ok(())

compiler/src/circuit_design/build.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ fn build_template_instances(
2525
c_info: &CircuitInfo,
2626
ti: Vec<TemplateInstance>,
2727
mut field_tracker: FieldTracker,
28+
constraint_assert_dissabled_flag: bool
2829
) -> (FieldTracker, HashMap<String,usize>) {
2930

3031
fn compute_jump(lengths: &Vec<usize>, indexes: &[usize]) -> usize {
@@ -99,6 +100,7 @@ fn build_template_instances(
99100
template_database: &c_info.template_database,
100101
string_table : string_table,
101102
signals_to_tags: template.signals_to_tags,
103+
constraint_assert_dissabled_flag
102104
};
103105
let mut template_info = TemplateCodeInfo {
104106
name,
@@ -134,7 +136,8 @@ fn build_function_instances(
134136
c_info: &CircuitInfo,
135137
instances: Vec<VCF>,
136138
mut field_tracker: FieldTracker,
137-
mut string_table : HashMap<String,usize>
139+
mut string_table : HashMap<String,usize>,
140+
constraint_assert_dissabled_flag: bool,
138141
) -> (FieldTracker, HashMap<String, usize>, HashMap<String, usize>) {
139142
let mut function_to_arena_size = HashMap::new();
140143
for instance in instances {
@@ -162,8 +165,9 @@ fn build_function_instances(
162165
component_to_parallel: HashMap::with_capacity(0),
163166
template_database: &c_info.template_database,
164167
string_table : string_table,
165-
signals_to_tags: BTreeMap::new(),
166-
buses: &c_info.buses
168+
signals_to_tags: HashMap::new(),
169+
buses: &c_info.buses,
170+
constraint_assert_dissabled_flag
167171
};
168172
let mut function_info = FunctionCodeInfo {
169173
name,
@@ -598,9 +602,9 @@ pub fn build_circuit(vcp: VCP, flag: CompilationFlags, version: &str) -> Circuit
598602
};
599603

600604
let (field_tracker, string_table) =
601-
build_template_instances(&mut circuit, &circuit_info, vcp.templates, field_tracker);
605+
build_template_instances(&mut circuit, &circuit_info, vcp.templates, field_tracker, flag.constraint_assert_dissabled_flag);
602606
let (field_tracker, function_to_arena_size, table_string_to_usize) =
603-
build_function_instances(&mut circuit, &circuit_info, vcp.functions, field_tracker,string_table);
607+
build_function_instances(&mut circuit, &circuit_info, vcp.functions, field_tracker,string_table, flag.constraint_assert_dissabled_flag);
604608

605609
let table_usize_to_string = create_table_usize_to_string(table_string_to_usize);
606610
circuit.wasm_producer.set_string_table(table_usize_to_string.clone());

compiler/src/circuit_design/circuit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::io::Write;
1010
pub struct CompilationFlags {
1111
pub main_inputs_log: bool,
1212
pub wat_flag:bool,
13+
pub constraint_assert_dissabled_flag: bool
1314
}
1415

1516
pub struct Circuit {

compiler/src/circuit_design/template.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,9 @@ impl TemplateCodeInfo {
290290
run_body.push(format!("{};", declare_lvar(self.var_stack_depth)));
291291
run_body.push(format!("{};", declare_sub_component_aux()));
292292
run_body.push(format!("{};", declare_index_multiple_eq()));
293+
run_body.push(format!("int cmp_index_ref_load = -1;"));
294+
295+
293296

294297
for t in &self.body {
295298
let (mut instructions_body, _) = t.produce_c(producer, Some(parallel));

compiler/src/compiler_interface.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ pub struct Config {
77
pub debug_output: bool,
88
pub produce_input_log: bool,
99
pub wat_flag: bool,
10+
pub constraint_assert_dissabled_flag: bool
1011
}
1112

1213
pub fn run_compiler(vcp: VCP, config: Config, version: &str) -> Result<Circuit, ()> {
13-
let flags = CompilationFlags { main_inputs_log: config.produce_input_log, wat_flag: config.wat_flag };
14+
let flags = CompilationFlags {
15+
main_inputs_log: config.produce_input_log,
16+
wat_flag: config.wat_flag,
17+
constraint_assert_dissabled_flag: config.constraint_assert_dissabled_flag
18+
};
1419
let circuit = Circuit::build(vcp, flags, version);
1520
if config.debug_output {
1621
produce_debug_output(&circuit)?;

compiler/src/hir/very_concrete_program.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ pub struct TemplateInstance {
196196
pub number_of_outputs: usize,
197197
pub number_of_intermediates: usize,
198198
pub wires: Vec<Wire>,
199-
pub signals_to_tags: BTreeMap<String, TagInfo>,
199+
pub signals_to_tags: HashMap<Vec<String>, BigInt>,
200200
pub components: Vec<Component>,
201201
pub number_of_components: usize,
202202
pub triggers: Vec<Trigger>,
@@ -216,7 +216,7 @@ pub struct TemplateConfig {
216216
pub clusters: Vec<TriggerCluster>,
217217
pub components: Vec<Component>,
218218
pub arguments: Vec<Argument>,
219-
pub signals_to_tags: BTreeMap<String, TagInfo>,
219+
pub signals_to_tags: HashMap<Vec<String>, BigInt>,
220220
}
221221
impl TemplateInstance {
222222
pub fn new(config: TemplateConfig) -> TemplateInstance {

compiler/src/intermediate_representation/compute_bucket.rs

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::translating_traits::*;
33
use code_producers::c_elements::*;
44
use code_producers::wasm_elements::*;
55

6-
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
6+
#[derive(Clone, PartialEq, Eq)]
77
pub enum OperatorType {
88
Mul,
99
Div,
@@ -18,7 +18,7 @@ pub enum OperatorType {
1818
GreaterEq,
1919
Lesser,
2020
Greater,
21-
Eq(usize),
21+
Eq(SizeOption),
2222
NotEq,
2323
BoolOr,
2424
BoolAnd,
@@ -42,7 +42,8 @@ impl OperatorType {
4242

4343
pub fn is_multiple_eq(&self) -> bool {
4444
match self {
45-
OperatorType::Eq(n) => *n > 1,
45+
OperatorType::Eq(SizeOption::Single(n)) => *n > 1,
46+
OperatorType::Eq(SizeOption::Multiple(_)) => true,
4647
_ => false
4748
}
4849
}
@@ -52,7 +53,7 @@ impl ToString for OperatorType {
5253
fn to_string(&self) -> String {
5354
use OperatorType::*;
5455
if let Eq(n) = self {
55-
format!("EQ({})", n)
56+
format!("EQ({:?})", n)
5657
} else {
5758
match self {
5859
Mul => "MUL",
@@ -170,7 +171,7 @@ impl WriteWasm for ComputeBucket {
170171
instructions.push(call("$Fr_toInt"));
171172
}
172173
_ => {
173-
match self.op {
174+
match &self.op {
174175
OperatorType::Add => {
175176
instructions.push(call("$Fr_add")); // Result, Argument, Argument
176177
}
@@ -211,15 +212,31 @@ impl WriteWasm for ComputeBucket {
211212
instructions.push(call("$Fr_gt"));
212213
}
213214
OperatorType::Eq(n) => {
214-
assert!(n != 0);
215-
if n == 1 {
215+
let mut is_multiple = false;
216+
let (length,values) = match n{
217+
SizeOption::Single(v) => (*v,vec![]),
218+
SizeOption::Multiple(v) => {
219+
is_multiple = true;
220+
(v.len(),v.clone())
221+
}
222+
};
223+
assert!(length != 0);
224+
if !is_multiple && length == 1 {
216225
instructions.push(call("$Fr_eq"));
217226
} else {
218-
instructions.push(set_local(producer.get_aux_2_tag()));
219-
instructions.push(set_local(producer.get_aux_1_tag()));
220-
instructions.push(set_local(producer.get_aux_0_tag()));
221-
instructions.push(set_constant(&n.to_string()));
227+
if is_multiple { //create a nested if-else with all cases
228+
instructions.push(get_local(producer.get_sub_cmp_load_tag()));
229+
instructions.push(load32(None)); // get template id
230+
instructions.push(set_local(producer.get_aux_0_tag()));
231+
let mut instr_if = create_if_selection(&values,producer.get_aux_0_tag());
232+
instructions.append(&mut instr_if);
233+
} else {
234+
instructions.push(set_constant(&length.to_string()));
235+
}
222236
instructions.push(set_local(producer.get_counter_tag()));
237+
instructions.push(set_local(producer.get_aux_2_tag())); // second argument initial position
238+
instructions.push(set_local(producer.get_aux_1_tag())); // first argument initial position
239+
instructions.push(set_local(producer.get_aux_0_tag())); // resut position
223240
instructions.push(add_block());
224241
instructions.push(add_loop());
225242
instructions.push(get_local(producer.get_aux_0_tag()));
@@ -295,7 +312,7 @@ impl WriteWasm for ComputeBucket {
295312
impl WriteC for ComputeBucket {
296313
fn produce_c(&self, producer: &CProducer, parallel: Option<bool>) -> (Vec<String>, String) {
297314
use c_code_generator::*;
298-
fn get_fr_op(op_type: OperatorType) -> String {
315+
fn get_fr_op(op_type: &OperatorType) -> String {
299316
match op_type {
300317
OperatorType::Add => "Fr_add".to_string(),
301318
OperatorType::Div => "Fr_div".to_string(),
@@ -346,15 +363,32 @@ impl WriteC for ComputeBucket {
346363

347364
OperatorType::Eq(n) => {
348365
let exp_aux_index = self.op_aux_no.to_string();
349-
let operator = get_fr_op(self.op);
366+
let operator = get_fr_op(&self.op);
350367
let result_ref = format!("&{}", expaux(exp_aux_index.clone()));
351368
let mut arguments = vec![result_ref.clone()];
352369
let operands_copy = operands.clone();
353370
arguments.append(&mut operands);
371+
compute_c.push("{{".to_string());
354372
compute_c.push(format!("{}; // line circom {}", build_call(operator.clone(), arguments),self.line.to_string()));
355-
if *n > 1 {
373+
374+
// We compute the possible sizes, case multiple sizes
375+
let expr_size = match &n{
376+
SizeOption::Single(value) => value.to_string(),
377+
SizeOption::Multiple(values) => {
378+
let cmp_index_ref = "cmp_index_ref_load".to_string();
379+
380+
compute_c.push(format!("std::map<int,int> size_eq {};",
381+
set_list_tuple(values.clone())
382+
));
383+
let sub_component_pos_in_memory = format!("{}[{}]", MY_SUBCOMPONENTS, cmp_index_ref);
384+
let temp_id = template_id_in_component(sub_component_pos_in_memory);
385+
format!("size_eq[{}]", temp_id)
386+
}
387+
};
388+
389+
if expr_size != "1" {
356390
compute_c.push(format!("{} = 1;", index_multiple_eq()));
357-
compute_c.push(format!("while({} < {} && Fr_isTrue({})) {{", index_multiple_eq(), n, result_ref));
391+
compute_c.push(format!("while({} < {} && Fr_isTrue({})) {{", index_multiple_eq(), expr_size, result_ref));
358392
operands = vec![];
359393
arguments = vec![result_ref.clone()];
360394
for operand in &operands_copy {
@@ -366,6 +400,8 @@ impl WriteC for ComputeBucket {
366400
compute_c.push(format!("}}"));
367401

368402
}
403+
compute_c.push("}}".to_string());
404+
369405
result = result_ref;
370406

371407

@@ -374,7 +410,7 @@ impl WriteC for ComputeBucket {
374410
_ => {
375411
let exp_aux_index = self.op_aux_no.to_string();
376412
// build assign
377-
let operator = get_fr_op(self.op);
413+
let operator = get_fr_op(&self.op);
378414
let result_ref = format!("&{}", expaux(exp_aux_index.clone()));
379415
let mut arguments = vec![result_ref.clone()];
380416
arguments.append(&mut operands);

0 commit comments

Comments
 (0)