@@ -31,11 +31,6 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str)
31
31
rev_graph. get_mut ( k) . unwrap ( ) . insert ( i, chars. clone ( ) ) ;
32
32
33
33
if i == 0 {
34
- if let Some ( index) = chars. iter ( ) . position ( |& x| x == 94 ) {
35
- init_going_state = Some ( * k) ;
36
- rev_graph. get_mut ( & k) . unwrap ( ) . get_mut ( & i) . unwrap ( ) [ index] = 255 ;
37
- }
38
-
39
34
for j in rev_graph. get ( & k) . unwrap ( ) . get ( & i) . unwrap ( ) {
40
35
if * j == 255 {
41
36
continue ;
@@ -83,9 +78,9 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str)
83
78
84
79
let accept_nodes_array: Vec < usize > = accept_nodes. into_iter ( ) . collect ( ) ;
85
80
86
- if accept_nodes_array. len ( ) != 1 {
87
- panic ! ( "The size of accept nodes must be one" ) ;
88
- }
81
+ // if accept_nodes_array.len() != 1 {
82
+ // panic!("The size of accept nodes must be one");
83
+ // }
89
84
90
85
let mut eq_i = 0 ;
91
86
let mut lt_i = 0 ;
@@ -96,25 +91,17 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str)
96
91
let mut eq_checks = vec ! [ None ; 256 ] ;
97
92
let mut multi_or_checks1 = BTreeMap :: < String , usize > :: new ( ) ;
98
93
let mut multi_or_checks2 = BTreeMap :: < String , usize > :: new ( ) ;
99
- let mut zero_starting_states = vec ! [ ] ;
100
- let mut zero_starting_and_idxes = BTreeMap :: < usize , Vec < usize > > :: new ( ) ;
101
94
102
95
let mut lines = vec ! [ ] ;
103
- // let mut zero_starting_lines = vec![];
104
96
105
- lines. push ( "\t for (var i = 0; i < num_bytes ; i++) {" . to_string ( ) ) ;
106
- lines. push ( format ! ( "\t \t state_changed[i] = MultiOR({});" , n - 1 ) ) ;
107
- lines . push ( format ! ( " \t \t states[i][0] <== 1;" ) ) ;
97
+ lines. push ( "\t for (var i = 0; i < msg_bytes ; i++) {" . to_string ( ) ) ;
98
+ lines. push ( "\t \t states[i+1][0] <== 0;" . to_string ( ) ) ;
99
+
108
100
for i in 1 ..n {
109
101
let mut outputs = vec ! [ ] ;
110
- zero_starting_and_idxes. insert ( i, vec ! [ ] ) ;
111
- // let mut state_change_lines = vec![];
112
102
113
103
for ( prev_i, k) in rev_graph. get ( & ( i as usize ) ) . unwrap ( ) . iter ( ) {
114
104
let prev_i_num = * prev_i;
115
- if prev_i_num == 0 {
116
- zero_starting_states. push ( i) ;
117
- }
118
105
let mut k = k. clone ( ) ;
119
106
k. sort ( ) ;
120
107
@@ -196,6 +183,7 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str)
196
183
}
197
184
}
198
185
}
186
+
199
187
lines. push ( format ! ( "\t \t and[{}][i] = AND();" , and_i) ) ;
200
188
lines. push ( format ! (
201
189
"\t \t and[{}][i].a <== states[i][{}];" ,
@@ -207,9 +195,6 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str)
207
195
"\t \t and[{}][i].b <== {}[{}][i].out;" ,
208
196
and_i, eq_outputs[ 0 ] . 0 , eq_outputs[ 0 ] . 1
209
197
) ) ;
210
- if prev_i_num == 0 {
211
- zero_starting_and_idxes. get_mut ( & i) . unwrap ( ) . push ( and_i) ;
212
- }
213
198
} else if eq_outputs. len ( ) > 1 {
214
199
let eq_outputs_key = serde_json:: to_string ( & eq_outputs) . unwrap ( ) ;
215
200
@@ -231,9 +216,6 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str)
231
216
"\t \t and[{}][i].b <== multi_or[{}][i].out;" ,
232
217
and_i, multi_or_i
233
218
) ) ;
234
- if prev_i_num == 0 {
235
- zero_starting_and_idxes. get_mut ( & i) . unwrap ( ) . push ( and_i) ;
236
- }
237
219
multi_or_checks1. insert ( eq_outputs_key, multi_or_i) ;
238
220
multi_or_i += 1 ;
239
221
} else {
@@ -242,29 +224,19 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str)
242
224
"\t \t and[{}][i].b <== multi_or[{}][i].out;" ,
243
225
and_i, multi_or_i
244
226
) ) ;
245
- if prev_i_num == 0 {
246
- zero_starting_and_idxes. get_mut ( & i) . unwrap ( ) . push ( and_i) ;
247
- }
248
227
}
249
228
}
250
229
}
251
- if prev_i_num != 0 {
252
- outputs. push ( and_i) ;
253
- }
230
+
231
+ outputs. push ( and_i) ;
254
232
and_i += 1 ;
255
233
}
234
+
256
235
if outputs. len ( ) == 1 {
257
- if zero_starting_states. contains ( & i) {
258
- lines. push ( format ! (
259
- "\t \t states_tmp[i+1][{}] <== and[{}][i].out;" ,
260
- i, outputs[ 0 ]
261
- ) ) ;
262
- } else {
263
- lines. push ( format ! (
264
- "\t \t states[i+1][{}] <== and[{}][i].out;" ,
265
- i, outputs[ 0 ]
266
- ) ) ;
267
- }
236
+ lines. push ( format ! (
237
+ "\t \t states[i+1][{}] <== and[{}][i].out;" ,
238
+ i, outputs[ 0 ]
239
+ ) ) ;
268
240
} else if outputs. len ( ) > 1 {
269
241
let outputs_key = serde_json:: to_string ( & outputs) . unwrap ( ) ;
270
242
@@ -281,87 +253,34 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str)
281
253
multi_or_i, output_i, and_i
282
254
) ) ;
283
255
}
284
- if zero_starting_states. contains ( & i) {
285
- lines. push ( format ! (
286
- "\t \t states_tmp[i+1][{}] <== multi_or[{}][i].out;" ,
287
- i, multi_or_i
288
- ) ) ;
289
- } else {
290
- lines. push ( format ! (
291
- "\t \t states[i+1][{}] <== multi_or[{}][i].out;" ,
292
- i, multi_or_i
293
- ) ) ;
294
- }
256
+
257
+ lines. push ( format ! (
258
+ "\t \t states[i+1][{}] <== multi_or[{}][i].out;" ,
259
+ i, multi_or_i
260
+ ) ) ;
295
261
multi_or_checks2. insert ( outputs_key, multi_or_i) ;
296
262
multi_or_i += 1 ;
297
263
} else {
298
- if let Some ( multi_or_i) = multi_or_checks2. get ( & outputs_key) {
299
- if zero_starting_states. contains ( & i) {
300
- lines. push ( format ! (
301
- "\t \t states_tmp[i+1][{}] <== multi_or[{}][i].out;" ,
302
- i, multi_or_i
303
- ) ) ;
304
- } else {
305
- lines. push ( format ! (
306
- "\t \t states[i+1][{}] <== multi_or[{}][i].out;" ,
307
- i, multi_or_i
308
- ) ) ;
309
- }
264
+ if let Some ( multi_or_i_) = multi_or_checks2. get ( & outputs_key) {
265
+ lines. push ( format ! (
266
+ "\t \t states[i+1][{}] <== multi_or[{}][i].out;" ,
267
+ i, multi_or_i_
268
+ ) ) ;
310
269
}
311
270
}
312
- } else {
313
- if zero_starting_states. contains ( & i) {
314
- lines. push ( format ! ( "\t \t states_tmp[i+1][{}] <== 0;" , i) ) ;
315
- } else {
316
- lines. push ( format ! ( "\t \t states[i+1][{}] <== 0;" , i) ) ;
317
- }
318
271
}
319
-
320
- // if zero_starting_states.contains(&i) {
321
- // zero_starting_lines.append(&mut state_change_lines);
322
- // } else {
323
- // lines.append(&mut state_change_lines);
324
- // }
325
272
}
326
- // let not_zero_starting_states = (1..n)
327
- // .filter(|i| !zero_starting_states.contains(&i))
328
- // .collect_vec();
329
- lines. push ( format ! (
330
- "\t \t from_zero_enabled[i] <== MultiNOR({})([{}]);" ,
331
- n - 1 ,
332
- ( 1 ..n)
333
- . map( |i| if zero_starting_states. contains( & i) {
334
- format!( "states_tmp[i+1][{}]" , i)
335
- } else {
336
- format!( "states[i+1][{}]" , i)
337
- } )
338
- . collect:: <Vec <_>>( )
339
- . join( ", " )
340
- ) ) ;
341
- for ( i, vec) in zero_starting_and_idxes. iter ( ) {
342
- if vec. len ( ) == 0 {
273
+
274
+ let mut acc_transitions_update = "\t \t acc_transitions[i+1] <== acc_transitions[i]" . to_string ( ) ;
275
+ for i in 0 ..n {
276
+ if i == 0 {
343
277
continue ;
344
278
}
345
- lines. push ( format ! (
346
- "\t \t states[i+1][{}] <== MultiOR({})([states_tmp[i+1][{}], {}]);" ,
347
- i,
348
- vec. len( ) + 1 ,
349
- i,
350
- vec. iter( )
351
- . map( |and_i| format!( "from_zero_enabled[i] * and[{}][i].out" , and_i) )
352
- . collect:: <Vec <_>>( )
353
- . join( ", " )
354
- ) ) ;
355
- }
356
- for i in 1 ..n {
357
- lines. push ( format ! (
358
- "\t \t state_changed[i].in[{}] <== states[i+1][{}];" ,
359
- i - 1 ,
360
- i
361
- ) ) ;
362
- }
363
279
364
- // lines.push("\t\tstates[i+1][0] <== 1 - state_changed[i].out;".to_string());
280
+ acc_transitions_update. push_str ( & format ! ( " + states[i+1][{}]" , i) ) ;
281
+ }
282
+ acc_transitions_update. push_str ( ";" ) ;
283
+ lines. push ( acc_transitions_update) ;
365
284
366
285
let mut declarations = vec ! [ ] ;
367
286
declarations. push ( "pragma circom 2.1.5;\n " . to_string ( ) ) ;
@@ -374,40 +293,37 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str)
374
293
declarations. push ( format ! ( "template {}(msg_bytes) {{" , template_name) ) ;
375
294
declarations. push ( "\t signal input msg[msg_bytes];" . to_string ( ) ) ;
376
295
declarations. push ( "\t signal output out;\n " . to_string ( ) ) ;
377
- declarations. push ( "\t var num_bytes = msg_bytes+1;" . to_string ( ) ) ;
378
- declarations. push ( "\t signal in[num_bytes];" . to_string ( ) ) ;
379
- declarations. push ( "\t in[0]<==255;" . to_string ( ) ) ;
296
+ declarations. push ( "\t var num_state_trace = msg_bytes+1;" . to_string ( ) ) ;
297
+ declarations. push ( "\t signal in[msg_bytes];" . to_string ( ) ) ;
380
298
declarations. push ( "\t for (var i = 0; i < msg_bytes; i++) {" . to_string ( ) ) ;
381
- declarations. push ( "\t \t in[i+1 ] <== msg[i];" . to_string ( ) ) ;
299
+ declarations. push ( "\t \t in[i] <== msg[i];" . to_string ( ) ) ;
382
300
declarations. push ( "\t }\n " . to_string ( ) ) ;
383
301
384
302
if eq_i > 0 {
385
- declarations. push ( format ! ( "\t component eq[{}][num_bytes ];" , eq_i) ) ;
303
+ declarations. push ( format ! ( "\t component eq[{}][msg_bytes ];" , eq_i) ) ;
386
304
}
387
305
388
306
if lt_i > 0 {
389
- declarations. push ( format ! ( "\t component lt[{}][num_bytes ];" , lt_i) ) ;
307
+ declarations. push ( format ! ( "\t component lt[{}][msg_bytes ];" , lt_i) ) ;
390
308
}
391
309
392
310
if and_i > 0 {
393
- declarations. push ( format ! ( "\t component and[{}][num_bytes ];" , and_i) ) ;
311
+ declarations. push ( format ! ( "\t component and[{}][msg_bytes ];" , and_i) ) ;
394
312
}
395
313
396
314
if multi_or_i > 0 {
397
- declarations. push ( format ! ( "\t component multi_or[{}][num_bytes ];" , multi_or_i) ) ;
315
+ declarations. push ( format ! ( "\t component multi_or[{}][msg_bytes ];" , multi_or_i) ) ;
398
316
}
399
317
400
- declarations. push ( format ! ( "\t signal states[num_bytes+1][{}];" , n) ) ;
401
- declarations. push ( format ! ( "\t signal states_tmp[num_bytes+1][{}];" , n) ) ;
402
- declarations. push ( format ! ( "\t signal from_zero_enabled[num_bytes+1];" ) ) ;
403
- declarations. push ( format ! ( "\t from_zero_enabled[num_bytes] <== 0;" ) ) ;
404
- declarations. push ( "\t component state_changed[num_bytes];\n " . to_string ( ) ) ;
318
+ declarations. push ( format ! ( "\t signal states[num_state_trace][{}];" , n) ) ;
319
+ declarations. push ( format ! ( "\t signal acc_transitions[num_state_trace];\n " ) ) ;
405
320
406
321
let mut init_code = vec ! [ ] ;
407
- // init_code.push("\tstates[0][0] <== 1;".to_string());
322
+ init_code. push ( "\t states[0][0] <== 1;" . to_string ( ) ) ;
408
323
init_code. push ( format ! ( "\t for (var i = 1; i < {}; i++) {{" , n) ) ;
409
324
init_code. push ( "\t \t states[0][i] <== 0;" . to_string ( ) ) ;
410
- init_code. push ( "\t }\n " . to_string ( ) ) ;
325
+ init_code. push ( "\t }" . to_string ( ) ) ;
326
+ init_code. push ( "\t acc_transitions[0] <== 0;\n " . to_string ( ) ) ;
411
327
412
328
let mut final_code = declarations
413
329
. into_iter ( )
@@ -416,18 +332,37 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str)
416
332
. collect :: < Vec < String > > ( ) ;
417
333
final_code. push ( "\t }" . to_string ( ) ) ;
418
334
419
- let accept_node = accept_nodes_array[ 0 ] ;
420
335
let mut accept_lines = vec ! [ ] ;
421
336
422
337
accept_lines. push ( "" . to_string ( ) ) ;
423
- accept_lines. push ( "\t component final_state_result = MultiOR(num_bytes+1);" . to_string ( ) ) ;
424
- accept_lines. push ( "\t for (var i = 0; i <= num_bytes; i++) {" . to_string ( ) ) ;
425
- accept_lines. push ( format ! (
426
- "\t \t final_state_result.in[i] <== states[i][{}];" ,
427
- accept_node
428
- ) ) ;
338
+ accept_lines. push ( "\t component final_state_result = MultiOR(msg_bytes+1);" . to_string ( ) ) ;
339
+ accept_lines. push ( "\t for (var i = 0; i <= msg_bytes; i++) {" . to_string ( ) ) ;
340
+ if accept_nodes_array. len ( ) == 1 {
341
+ accept_lines. push ( format ! (
342
+ "\t \t final_state_result.in[i] <== states[i][{}];" ,
343
+ accept_nodes_array[ 0 ]
344
+ ) ) ;
345
+ } else {
346
+ let mut accept_outputs = vec ! [ ] ;
347
+ let mut accept_outputs_str = String :: new ( ) ;
348
+ let mut accept_outputs_str = format ! ( "MultiOR({})([" , accept_nodes_array. len( ) ) ;
349
+ for accept_node in & accept_nodes_array {
350
+ accept_outputs. push ( format ! ( "states[i][{}]" , accept_node) ) ;
351
+ }
352
+ accept_outputs_str. push_str ( & accept_outputs. join ( ", " ) ) ;
353
+ accept_outputs_str. push_str ( "])" ) ;
354
+ accept_lines. push ( format ! (
355
+ "\t \t final_state_result.in[i] <== {};" ,
356
+ accept_outputs_str
357
+ ) ) ;
358
+ }
429
359
accept_lines. push ( "\t }" . to_string ( ) ) ;
430
- accept_lines. push ( "\t out <== final_state_result.out;" . to_string ( ) ) ;
360
+ accept_lines. push (
361
+ "\t signal is_acc_valid <== IsEqual()([acc_transitions[num_state_trace-1], msg_bytes]);"
362
+ . to_string ( ) ,
363
+ ) ;
364
+ accept_lines. push ( "\t out <== final_state_result.out * is_acc_valid;" . to_string ( ) ) ;
365
+ accept_lines. push ( "}" . to_string ( ) ) ;
431
366
432
367
final_code. extend ( accept_lines) ;
433
368
0 commit comments