From 5396ec44cdf6a4579662b9442fc11210049ab520 Mon Sep 17 00:00:00 2001 From: Sora Suegami <31360991+SoraSuegami@users.noreply.github.com> Date: Tue, 21 May 2024 14:45:28 +0900 Subject: [PATCH] Feat/audit fix 0513 (#63) * Fix is_consecutive init value. * Debugging * fixes * Debugging. * Fix question tests. * Modify tests and remove unused files. * Fix caret bugs. * Pass most tests * Fix all bugs * Add negate2 tests * Fix: handle $ * fix * chore: add errors * Add dollar support * Fix compile error. * Add more dollar tests * Remove unused test regex and circoms. * Add regex limitations to README --------- Co-authored-by: Aditya Bisht --- .gitignore | 1 + packages/apis/src/extract_substrs.rs | 60 +- .../circom/circuits/common/body_hash.json | 2 +- .../circuits/common/body_hash_regex.circom | 552 +++++------ .../circom/circuits/common/email_addr.json | 2 +- .../circuits/common/email_addr_regex.circom | 149 ++- .../circuits/common/email_addr_with_name.json | 2 +- .../common/email_addr_with_name_regex.circom | 911 +++++++++--------- .../circom/circuits/common/email_domain.json | 2 +- .../circuits/common/email_domain_regex.circom | 145 ++- .../circom/circuits/common/from_addr.json | 4 +- packages/circom/circuits/common/from_all.json | 2 +- .../circuits/common/from_all_regex.circom | 321 +++--- .../circom/circuits/common/message_id.json | 2 +- .../circuits/common/message_id_regex.circom | 206 ++-- .../circom/circuits/common/subject_all.json | 2 +- .../circuits/common/subject_all_regex.circom | 345 +++---- .../circom/circuits/common/timestamp.json | 2 +- .../circuits/common/timestamp_regex.circom | 458 ++++----- packages/circom/circuits/common/to_addr.json | 4 +- packages/circom/circuits/common/to_all.json | 2 +- .../circuits/common/to_all_regex.circom | 305 +++--- packages/circom/circuits/regex_helpers.circom | 11 + .../circom/email_addr_with_name_main.circom | 764 +++++++++++++++ packages/circom/tests/asterisk.test.js | 627 ++++++++++++ packages/circom/tests/body_hash_regex.test.js | 16 +- packages/circom/tests/caret.test.js | 564 +++++++++++ packages/circom/tests/circuits/asterisk1.json | 16 + .../tests/circuits/asterisk1_regex.circom | 82 ++ packages/circom/tests/circuits/asterisk2.json | 12 + .../tests/circuits/asterisk2_regex.circom | 74 ++ packages/circom/tests/circuits/asterisk3.json | 16 + .../tests/circuits/asterisk3_regex.circom | 89 ++ packages/circom/tests/circuits/caret1.json | 8 + .../circom/tests/circuits/caret1_regex.circom | 76 ++ packages/circom/tests/circuits/caret2.json | 8 + .../circom/tests/circuits/caret2_regex.circom | 87 ++ packages/circom/tests/circuits/caret3.json | 12 + .../circom/tests/circuits/caret3_regex.circom | 90 ++ packages/circom/tests/circuits/caret4.json | 12 + .../circom/tests/circuits/caret4_regex.circom | 104 ++ packages/circom/tests/circuits/caret5.json | 12 + .../circom/tests/circuits/caret5_regex.circom | 435 +++++++++ packages/circom/tests/circuits/dollar1.json | 8 + .../tests/circuits/dollar1_regex.circom | 93 ++ packages/circom/tests/circuits/dollar2.json | 12 + .../tests/circuits/dollar2_regex.circom | 115 +++ packages/circom/tests/circuits/dot1.json | 8 + .../circom/tests/circuits/dot1_regex.circom | 391 ++++++++ packages/circom/tests/circuits/dot2.json | 16 + .../circom/tests/circuits/dot2_regex.circom | 405 ++++++++ .../international_chars_decomposed.circom | 66 +- .../invitation_code_with_prefix_regex.circom | 23 +- .../tests/circuits/negate1_regex.circom | 38 +- packages/circom/tests/circuits/negate2.json | 8 + .../tests/circuits/negate2_regex.circom | 365 +++++++ packages/circom/tests/circuits/plus1.json | 12 + .../circom/tests/circuits/plus1_regex.circom | 80 ++ packages/circom/tests/circuits/plus2.json | 12 + .../circom/tests/circuits/plus2_regex.circom | 90 ++ packages/circom/tests/circuits/plus3.json | 12 + .../circom/tests/circuits/plus3_regex.circom | 93 ++ packages/circom/tests/circuits/plus4.json | 12 + .../circom/tests/circuits/plus4_regex.circom | 123 +++ packages/circom/tests/circuits/question1.json | 12 + .../tests/circuits/question1_regex.circom | 80 ++ packages/circom/tests/circuits/question2.json | 12 + .../tests/circuits/question2_regex.circom | 106 ++ packages/circom/tests/circuits/question3.json | 16 + .../tests/circuits/question3_regex.circom | 105 ++ .../circom/tests/circuits/reveal_check1.json | 8 + .../tests/circuits/reveal_check1_regex.circom | 83 ++ .../circom/tests/circuits/reveal_check2.json | 8 + .../tests/circuits/reveal_check2_regex.circom | 81 ++ .../circom/tests/circuits/simple_regex.circom | 27 +- .../circuits/simple_regex_decomposed.circom | 15 +- .../circuits/test_asterisk1_regex.circom | 3 + .../circuits/test_asterisk2_regex.circom | 3 + .../circuits/test_asterisk3_regex.circom | 3 + .../tests/circuits/test_caret1_regex.circom | 3 + .../tests/circuits/test_caret2_regex.circom | 3 + .../tests/circuits/test_caret3_regex.circom | 3 + .../tests/circuits/test_caret4_regex.circom | 3 + .../tests/circuits/test_caret5_regex.circom | 3 + .../tests/circuits/test_dollar1_regex.circom | 3 + .../tests/circuits/test_dollar2_regex.circom | 3 + .../tests/circuits/test_dot1_regex.circom | 3 + .../tests/circuits/test_dot2_regex.circom | 3 + .../tests/circuits/test_negate2_regex.circom | 2 + .../tests/circuits/test_plus1_regex.circom | 3 + .../tests/circuits/test_plus2_regex.circom | 3 + .../tests/circuits/test_plus3_regex.circom | 3 + .../tests/circuits/test_plus4_regex.circom | 3 + .../circuits/test_question1_regex.circom | 3 + .../circuits/test_question2_regex.circom | 3 + .../circuits/test_question3_regex.circom | 3 + .../circuits/test_reveal_check1_regex.circom | 3 + .../circuits/test_reveal_check2_regex.circom | 3 + packages/circom/tests/dollar.test.js | 191 ++++ packages/circom/tests/dot.test.js | 174 ++++ packages/circom/tests/from_addr.test.js | 13 + .../circom/tests/message_id_regex.test.js | 16 +- packages/circom/tests/negate_regex.test.js | 84 +- packages/circom/tests/plus.test.js | 652 +++++++++++++ packages/circom/tests/question.test.js | 385 ++++++++ packages/circom/tests/reveal_check.test.js | 249 +++++ packages/circom/tests/subject_all.test.js | 14 + packages/circom/tests/timestamp.test.js | 15 + packages/circom/tests/to_addr.test.js | 12 + packages/compiler/README.md | 9 + packages/compiler/src/bin/compiler.rs | 52 +- packages/compiler/src/circom.rs | 145 ++- packages/compiler/src/halo2.rs | 100 -- packages/compiler/src/lib.rs | 47 +- packages/compiler/src/regex.rs | 143 ++- packages/compiler/src/wasm.rs | 11 +- 116 files changed, 9481 insertions(+), 2025 deletions(-) create mode 100644 packages/circom/email_addr_with_name_main.circom create mode 100644 packages/circom/tests/asterisk.test.js create mode 100644 packages/circom/tests/caret.test.js create mode 100644 packages/circom/tests/circuits/asterisk1.json create mode 100644 packages/circom/tests/circuits/asterisk1_regex.circom create mode 100644 packages/circom/tests/circuits/asterisk2.json create mode 100644 packages/circom/tests/circuits/asterisk2_regex.circom create mode 100644 packages/circom/tests/circuits/asterisk3.json create mode 100644 packages/circom/tests/circuits/asterisk3_regex.circom create mode 100644 packages/circom/tests/circuits/caret1.json create mode 100644 packages/circom/tests/circuits/caret1_regex.circom create mode 100644 packages/circom/tests/circuits/caret2.json create mode 100644 packages/circom/tests/circuits/caret2_regex.circom create mode 100644 packages/circom/tests/circuits/caret3.json create mode 100644 packages/circom/tests/circuits/caret3_regex.circom create mode 100644 packages/circom/tests/circuits/caret4.json create mode 100644 packages/circom/tests/circuits/caret4_regex.circom create mode 100644 packages/circom/tests/circuits/caret5.json create mode 100644 packages/circom/tests/circuits/caret5_regex.circom create mode 100644 packages/circom/tests/circuits/dollar1.json create mode 100644 packages/circom/tests/circuits/dollar1_regex.circom create mode 100644 packages/circom/tests/circuits/dollar2.json create mode 100644 packages/circom/tests/circuits/dollar2_regex.circom create mode 100644 packages/circom/tests/circuits/dot1.json create mode 100644 packages/circom/tests/circuits/dot1_regex.circom create mode 100644 packages/circom/tests/circuits/dot2.json create mode 100644 packages/circom/tests/circuits/dot2_regex.circom create mode 100644 packages/circom/tests/circuits/negate2.json create mode 100644 packages/circom/tests/circuits/negate2_regex.circom create mode 100644 packages/circom/tests/circuits/plus1.json create mode 100644 packages/circom/tests/circuits/plus1_regex.circom create mode 100644 packages/circom/tests/circuits/plus2.json create mode 100644 packages/circom/tests/circuits/plus2_regex.circom create mode 100644 packages/circom/tests/circuits/plus3.json create mode 100644 packages/circom/tests/circuits/plus3_regex.circom create mode 100644 packages/circom/tests/circuits/plus4.json create mode 100644 packages/circom/tests/circuits/plus4_regex.circom create mode 100644 packages/circom/tests/circuits/question1.json create mode 100644 packages/circom/tests/circuits/question1_regex.circom create mode 100644 packages/circom/tests/circuits/question2.json create mode 100644 packages/circom/tests/circuits/question2_regex.circom create mode 100644 packages/circom/tests/circuits/question3.json create mode 100644 packages/circom/tests/circuits/question3_regex.circom create mode 100644 packages/circom/tests/circuits/reveal_check1.json create mode 100644 packages/circom/tests/circuits/reveal_check1_regex.circom create mode 100644 packages/circom/tests/circuits/reveal_check2.json create mode 100644 packages/circom/tests/circuits/reveal_check2_regex.circom create mode 100644 packages/circom/tests/circuits/test_asterisk1_regex.circom create mode 100644 packages/circom/tests/circuits/test_asterisk2_regex.circom create mode 100644 packages/circom/tests/circuits/test_asterisk3_regex.circom create mode 100644 packages/circom/tests/circuits/test_caret1_regex.circom create mode 100644 packages/circom/tests/circuits/test_caret2_regex.circom create mode 100644 packages/circom/tests/circuits/test_caret3_regex.circom create mode 100644 packages/circom/tests/circuits/test_caret4_regex.circom create mode 100644 packages/circom/tests/circuits/test_caret5_regex.circom create mode 100644 packages/circom/tests/circuits/test_dollar1_regex.circom create mode 100644 packages/circom/tests/circuits/test_dollar2_regex.circom create mode 100644 packages/circom/tests/circuits/test_dot1_regex.circom create mode 100644 packages/circom/tests/circuits/test_dot2_regex.circom create mode 100644 packages/circom/tests/circuits/test_negate2_regex.circom create mode 100644 packages/circom/tests/circuits/test_plus1_regex.circom create mode 100644 packages/circom/tests/circuits/test_plus2_regex.circom create mode 100644 packages/circom/tests/circuits/test_plus3_regex.circom create mode 100644 packages/circom/tests/circuits/test_plus4_regex.circom create mode 100644 packages/circom/tests/circuits/test_question1_regex.circom create mode 100644 packages/circom/tests/circuits/test_question2_regex.circom create mode 100644 packages/circom/tests/circuits/test_question3_regex.circom create mode 100644 packages/circom/tests/circuits/test_reveal_check1_regex.circom create mode 100644 packages/circom/tests/circuits/test_reveal_check2_regex.circom create mode 100644 packages/circom/tests/dollar.test.js create mode 100644 packages/circom/tests/dot.test.js create mode 100644 packages/circom/tests/plus.test.js create mode 100644 packages/circom/tests/question.test.js create mode 100644 packages/circom/tests/reveal_check.test.js delete mode 100644 packages/compiler/src/halo2.rs diff --git a/.gitignore b/.gitignore index caaf8d2..a233986 100644 --- a/.gitignore +++ b/.gitignore @@ -111,3 +111,4 @@ packages/*/build package-lock.json yarn.lock +index.node diff --git a/packages/apis/src/extract_substrs.rs b/packages/apis/src/extract_substrs.rs index b05c828..b28665c 100644 --- a/packages/apis/src/extract_substrs.rs +++ b/packages/apis/src/extract_substrs.rs @@ -48,18 +48,16 @@ pub fn extract_substr_idxes( ExtractSubstrssError::SubstringOfEntireNotFound(entire_regex, input_str.to_string()) })?; let mut start = entire_found.start(); - let entire_end = entire_found.end(); + // let entire_end: usize = entire_found.end(); let mut public_idxes = vec![]; for part_idx in 0..regex_config.parts.len() { - let regex = Regex::new(®ex_config.parts[part_idx].regex_def.as_str())?; - let found = regex.find_from_pos(&input_str, start)?.ok_or_else(|| { - ExtractSubstrssError::SubstringNotFound( - regex.clone(), - input_str[start..entire_end].to_string(), - ) - })?; - let end = found.end(); + let regex_def = regex_config.parts[part_idx].regex_def.as_str(); + let regex = Regex::new(®ex_def)?; + let end = match regex.find_from_pos(&input_str, start)? { + Some(found) => found.end(), + None => start, + }; if regex_config.parts[part_idx].is_public { public_idxes.push((start, end)); } @@ -234,4 +232,48 @@ mod test { let idxes = extract_message_id_idxes(input_str).unwrap(); assert_eq!(idxes, vec![(11, 79)]); } + + + #[test] + fn test_dot_plus_valid() { + let code_regex = DecomposedRegexConfig { + parts: vec![ + RegexPartConfig { + is_public: false, + regex_def: "a".to_string(), + }, + RegexPartConfig { + is_public: true, + regex_def: ".+?".to_string(), + }, + RegexPartConfig { + is_public: false, + regex_def: "b".to_string(), + }, + ], + }; + let input_str = "azb"; + let idxes = extract_substr_idxes(input_str, &code_regex).unwrap(); + assert_eq!(idxes, vec![(1, 2)]); + } + + #[test] + fn test_dot_question_valid() { + let code_regex = DecomposedRegexConfig { + parts: vec![ + RegexPartConfig { + is_public: true, + regex_def: ".??".to_string(), + }, + RegexPartConfig { + is_public: false, + regex_def: "b".to_string(), + }, + ], + }; + let input_str = "b"; + let idxes = extract_substr_idxes(input_str, &code_regex).unwrap(); + assert_eq!(idxes, vec![(0, 0)]); + } + } diff --git a/packages/circom/circuits/common/body_hash.json b/packages/circom/circuits/common/body_hash.json index f53b8a5..354421e 100644 --- a/packages/circom/circuits/common/body_hash.json +++ b/packages/circom/circuits/common/body_hash.json @@ -2,7 +2,7 @@ "parts": [ { "is_public": false, - "regex_def": "((\r\n)|^)dkim-signature:" + "regex_def": "(\r\n|^)dkim-signature:" }, { "is_public": false, diff --git a/packages/circom/circuits/common/body_hash_regex.circom b/packages/circom/circuits/common/body_hash_regex.circom index 2ef1771..97ea1ee 100644 --- a/packages/circom/circuits/common/body_hash_regex.circom +++ b/packages/circom/circuits/common/body_hash_regex.circom @@ -2,7 +2,7 @@ pragma circom 2.1.5; include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; -// regex: ((\r\n)|^)dkim-signature:([a-z]+=[^;]+; )+bh=[a-zA-Z0-9+/=]+; +// regex: (\r\n|^)dkim-signature:([a-z]+=[^;]+; )+bh=[a-zA-Z0-9+/=]+; template BodyHashRegex(msg_bytes) { signal input msg[msg_bytes]; signal output out; @@ -14,7 +14,7 @@ template BodyHashRegex(msg_bytes) { in[i+1] <== msg[i]; } - component eq[89][num_bytes]; + component eq[90][num_bytes]; component lt[24][num_bytes]; component and[76][num_bytes]; component multi_or[19][num_bytes]; @@ -33,122 +33,125 @@ template BodyHashRegex(msg_bytes) { states[i][0] <== 1; eq[0][i] = IsEqual(); eq[0][i].in[0] <== in[i]; - eq[0][i].in[1] <== 100; + eq[0][i].in[1] <== 13; and[0][i] = AND(); and[0][i].a <== states[i][0]; and[0][i].b <== eq[0][i].out; - and[1][i] = AND(); - and[1][i].a <== states[i][4]; - and[1][i].b <== eq[0][i].out; - states_tmp[i+1][1] <== and[1][i].out; + states_tmp[i+1][1] <== 0; eq[1][i] = IsEqual(); eq[1][i].in[0] <== in[i]; - eq[1][i].in[1] <== 13; - and[2][i] = AND(); - and[2][i].a <== states[i][0]; - and[2][i].b <== eq[1][i].out; - states_tmp[i+1][2] <== 0; + eq[1][i].in[1] <== 255; + and[1][i] = AND(); + and[1][i].a <== states[i][0]; + and[1][i].b <== eq[1][i].out; eq[2][i] = IsEqual(); eq[2][i].in[0] <== in[i]; - eq[2][i].in[1] <== 107; - and[3][i] = AND(); - and[3][i].a <== states[i][1]; - and[3][i].b <== eq[2][i].out; - states[i+1][3] <== and[3][i].out; + eq[2][i].in[1] <== 10; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== eq[2][i].out; + states_tmp[i+1][2] <== and[2][i].out; eq[3][i] = IsEqual(); eq[3][i].in[0] <== in[i]; - eq[3][i].in[1] <== 10; - and[4][i] = AND(); - and[4][i].a <== states[i][2]; - and[4][i].b <== eq[3][i].out; - states[i+1][4] <== and[4][i].out; + eq[3][i].in[1] <== 100; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== eq[3][i].out; + states[i+1][3] <== and[3][i].out; eq[4][i] = IsEqual(); eq[4][i].in[0] <== in[i]; - eq[4][i].in[1] <== 105; - and[5][i] = AND(); - and[5][i].a <== states[i][3]; - and[5][i].b <== eq[4][i].out; - states[i+1][5] <== and[5][i].out; + eq[4][i].in[1] <== 107; + and[4][i] = AND(); + and[4][i].a <== states[i][3]; + and[4][i].b <== eq[4][i].out; + states[i+1][4] <== and[4][i].out; eq[5][i] = IsEqual(); eq[5][i].in[0] <== in[i]; - eq[5][i].in[1] <== 109; + eq[5][i].in[1] <== 105; + and[5][i] = AND(); + and[5][i].a <== states[i][4]; + and[5][i].b <== eq[5][i].out; + states[i+1][5] <== and[5][i].out; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 109; and[6][i] = AND(); and[6][i].a <== states[i][5]; - and[6][i].b <== eq[5][i].out; + and[6][i].b <== eq[6][i].out; states[i+1][6] <== and[6][i].out; - eq[6][i] = IsEqual(); - eq[6][i].in[0] <== in[i]; - eq[6][i].in[1] <== 45; + eq[7][i] = IsEqual(); + eq[7][i].in[0] <== in[i]; + eq[7][i].in[1] <== 45; and[7][i] = AND(); and[7][i].a <== states[i][6]; - and[7][i].b <== eq[6][i].out; + and[7][i].b <== eq[7][i].out; states[i+1][7] <== and[7][i].out; - eq[7][i] = IsEqual(); - eq[7][i].in[0] <== in[i]; - eq[7][i].in[1] <== 115; + eq[8][i] = IsEqual(); + eq[8][i].in[0] <== in[i]; + eq[8][i].in[1] <== 115; and[8][i] = AND(); and[8][i].a <== states[i][7]; - and[8][i].b <== eq[7][i].out; + and[8][i].b <== eq[8][i].out; states[i+1][8] <== and[8][i].out; and[9][i] = AND(); and[9][i].a <== states[i][8]; - and[9][i].b <== eq[4][i].out; + and[9][i].b <== eq[5][i].out; states[i+1][9] <== and[9][i].out; - eq[8][i] = IsEqual(); - eq[8][i].in[0] <== in[i]; - eq[8][i].in[1] <== 103; + eq[9][i] = IsEqual(); + eq[9][i].in[0] <== in[i]; + eq[9][i].in[1] <== 103; and[10][i] = AND(); and[10][i].a <== states[i][9]; - and[10][i].b <== eq[8][i].out; + and[10][i].b <== eq[9][i].out; states[i+1][10] <== and[10][i].out; - eq[9][i] = IsEqual(); - eq[9][i].in[0] <== in[i]; - eq[9][i].in[1] <== 110; + eq[10][i] = IsEqual(); + eq[10][i].in[0] <== in[i]; + eq[10][i].in[1] <== 110; and[11][i] = AND(); and[11][i].a <== states[i][10]; - and[11][i].b <== eq[9][i].out; + and[11][i].b <== eq[10][i].out; states[i+1][11] <== and[11][i].out; - eq[10][i] = IsEqual(); - eq[10][i].in[0] <== in[i]; - eq[10][i].in[1] <== 97; + eq[11][i] = IsEqual(); + eq[11][i].in[0] <== in[i]; + eq[11][i].in[1] <== 97; and[12][i] = AND(); and[12][i].a <== states[i][11]; - and[12][i].b <== eq[10][i].out; + and[12][i].b <== eq[11][i].out; states[i+1][12] <== and[12][i].out; - eq[11][i] = IsEqual(); - eq[11][i].in[0] <== in[i]; - eq[11][i].in[1] <== 116; + eq[12][i] = IsEqual(); + eq[12][i].in[0] <== in[i]; + eq[12][i].in[1] <== 116; and[13][i] = AND(); and[13][i].a <== states[i][12]; - and[13][i].b <== eq[11][i].out; + and[13][i].b <== eq[12][i].out; states[i+1][13] <== and[13][i].out; - eq[12][i] = IsEqual(); - eq[12][i].in[0] <== in[i]; - eq[12][i].in[1] <== 117; + eq[13][i] = IsEqual(); + eq[13][i].in[0] <== in[i]; + eq[13][i].in[1] <== 117; and[14][i] = AND(); and[14][i].a <== states[i][13]; - and[14][i].b <== eq[12][i].out; + and[14][i].b <== eq[13][i].out; states[i+1][14] <== and[14][i].out; - eq[13][i] = IsEqual(); - eq[13][i].in[0] <== in[i]; - eq[13][i].in[1] <== 114; + eq[14][i] = IsEqual(); + eq[14][i].in[0] <== in[i]; + eq[14][i].in[1] <== 114; and[15][i] = AND(); and[15][i].a <== states[i][14]; - and[15][i].b <== eq[13][i].out; + and[15][i].b <== eq[14][i].out; states[i+1][15] <== and[15][i].out; - eq[14][i] = IsEqual(); - eq[14][i].in[0] <== in[i]; - eq[14][i].in[1] <== 101; + eq[15][i] = IsEqual(); + eq[15][i].in[0] <== in[i]; + eq[15][i].in[1] <== 101; and[16][i] = AND(); and[16][i].a <== states[i][15]; - and[16][i].b <== eq[14][i].out; + and[16][i].b <== eq[15][i].out; states[i+1][16] <== and[16][i].out; - eq[15][i] = IsEqual(); - eq[15][i].in[0] <== in[i]; - eq[15][i].in[1] <== 58; + eq[16][i] = IsEqual(); + eq[16][i].in[0] <== in[i]; + eq[16][i].in[1] <== 58; and[17][i] = AND(); and[17][i].a <== states[i][16]; - and[17][i].b <== eq[15][i].out; + and[17][i].b <== eq[16][i].out; states[i+1][17] <== and[17][i].out; lt[0][i] = LessEqThan(8); lt[0][i].in[0] <== 97; @@ -178,7 +181,7 @@ template BodyHashRegex(msg_bytes) { and[22][i].a <== states[i][29]; multi_or[0][i] = MultiOR(2); multi_or[0][i].in[0] <== and[21][i].out; - multi_or[0][i].in[1] <== eq[10][i].out; + multi_or[0][i].in[1] <== eq[11][i].out; and[22][i].b <== multi_or[0][i].out; lt[4][i] = LessEqThan(8); lt[4][i].in[0] <== 105; @@ -189,26 +192,26 @@ template BodyHashRegex(msg_bytes) { and[23][i] = AND(); and[23][i].a <== lt[4][i].out; and[23][i].b <== lt[5][i].out; - eq[16][i] = IsEqual(); - eq[16][i].in[0] <== in[i]; - eq[16][i].in[1] <== 98; eq[17][i] = IsEqual(); eq[17][i].in[0] <== in[i]; - eq[17][i].in[1] <== 99; + eq[17][i].in[1] <== 98; eq[18][i] = IsEqual(); eq[18][i].in[0] <== in[i]; - eq[18][i].in[1] <== 102; + eq[18][i].in[1] <== 99; + eq[19][i] = IsEqual(); + eq[19][i].in[0] <== in[i]; + eq[19][i].in[1] <== 102; and[24][i] = AND(); and[24][i].a <== states[i][30]; multi_or[1][i] = MultiOR(8); multi_or[1][i].in[0] <== and[23][i].out; - multi_or[1][i].in[1] <== eq[10][i].out; - multi_or[1][i].in[2] <== eq[16][i].out; - multi_or[1][i].in[3] <== eq[17][i].out; - multi_or[1][i].in[4] <== eq[0][i].out; - multi_or[1][i].in[5] <== eq[14][i].out; - multi_or[1][i].in[6] <== eq[18][i].out; - multi_or[1][i].in[7] <== eq[8][i].out; + multi_or[1][i].in[1] <== eq[11][i].out; + multi_or[1][i].in[2] <== eq[17][i].out; + multi_or[1][i].in[3] <== eq[18][i].out; + multi_or[1][i].in[4] <== eq[3][i].out; + multi_or[1][i].in[5] <== eq[15][i].out; + multi_or[1][i].in[6] <== eq[19][i].out; + multi_or[1][i].in[7] <== eq[9][i].out; and[24][i].b <== multi_or[1][i].out; and[25][i] = AND(); and[25][i].a <== states[i][31]; @@ -220,21 +223,21 @@ template BodyHashRegex(msg_bytes) { multi_or[2][i].in[3] <== and[24][i].out; multi_or[2][i].in[4] <== and[25][i].out; states[i+1][18] <== multi_or[2][i].out; - eq[19][i] = IsEqual(); - eq[19][i].in[0] <== in[i]; - eq[19][i].in[1] <== 61; + eq[20][i] = IsEqual(); + eq[20][i].in[0] <== in[i]; + eq[20][i].in[1] <== 61; and[26][i] = AND(); and[26][i].a <== states[i][18]; - and[26][i].b <== eq[19][i].out; + and[26][i].b <== eq[20][i].out; and[27][i] = AND(); and[27][i].a <== states[i][30]; - and[27][i].b <== eq[19][i].out; + and[27][i].b <== eq[20][i].out; multi_or[3][i] = MultiOR(2); multi_or[3][i].in[0] <== and[26][i].out; multi_or[3][i].in[1] <== and[27][i].out; states[i+1][19] <== multi_or[3][i].out; lt[6][i] = LessEqThan(8); - lt[6][i].in[0] <== 0; + lt[6][i].in[0] <== 1; lt[6][i].in[1] <== in[i]; lt[7][i] = LessEqThan(8); lt[7][i].in[0] <== in[i]; @@ -273,7 +276,7 @@ template BodyHashRegex(msg_bytes) { and[33][i].a <== states[i][21]; and[33][i].b <== and[32][i].out; lt[12][i] = LessEqThan(8); - lt[12][i].in[0] <== 0; + lt[12][i].in[0] <== 1; lt[12][i].in[1] <== in[i]; lt[13][i] = LessEqThan(8); lt[13][i].in[0] <== in[i]; @@ -281,80 +284,80 @@ template BodyHashRegex(msg_bytes) { and[34][i] = AND(); and[34][i].a <== lt[12][i].out; and[34][i].b <== lt[13][i].out; - eq[20][i] = IsEqual(); - eq[20][i].in[0] <== in[i]; - eq[20][i].in[1] <== 44; eq[21][i] = IsEqual(); eq[21][i].in[0] <== in[i]; - eq[21][i].in[1] <== 46; + eq[21][i].in[1] <== 44; eq[22][i] = IsEqual(); eq[22][i].in[0] <== in[i]; - eq[22][i].in[1] <== 60; + eq[22][i].in[1] <== 46; eq[23][i] = IsEqual(); eq[23][i].in[0] <== in[i]; - eq[23][i].in[1] <== 62; + eq[23][i].in[1] <== 60; eq[24][i] = IsEqual(); eq[24][i].in[0] <== in[i]; - eq[24][i].in[1] <== 63; + eq[24][i].in[1] <== 62; eq[25][i] = IsEqual(); eq[25][i].in[0] <== in[i]; - eq[25][i].in[1] <== 64; + eq[25][i].in[1] <== 63; eq[26][i] = IsEqual(); eq[26][i].in[0] <== in[i]; - eq[26][i].in[1] <== 91; + eq[26][i].in[1] <== 64; eq[27][i] = IsEqual(); eq[27][i].in[0] <== in[i]; - eq[27][i].in[1] <== 92; + eq[27][i].in[1] <== 91; eq[28][i] = IsEqual(); eq[28][i].in[0] <== in[i]; - eq[28][i].in[1] <== 93; + eq[28][i].in[1] <== 92; eq[29][i] = IsEqual(); eq[29][i].in[0] <== in[i]; - eq[29][i].in[1] <== 94; + eq[29][i].in[1] <== 93; eq[30][i] = IsEqual(); eq[30][i].in[0] <== in[i]; - eq[30][i].in[1] <== 95; + eq[30][i].in[1] <== 94; eq[31][i] = IsEqual(); eq[31][i].in[0] <== in[i]; - eq[31][i].in[1] <== 96; + eq[31][i].in[1] <== 95; eq[32][i] = IsEqual(); eq[32][i].in[0] <== in[i]; - eq[32][i].in[1] <== 123; + eq[32][i].in[1] <== 96; eq[33][i] = IsEqual(); eq[33][i].in[0] <== in[i]; - eq[33][i].in[1] <== 124; + eq[33][i].in[1] <== 123; eq[34][i] = IsEqual(); eq[34][i].in[0] <== in[i]; - eq[34][i].in[1] <== 125; + eq[34][i].in[1] <== 124; eq[35][i] = IsEqual(); eq[35][i].in[0] <== in[i]; - eq[35][i].in[1] <== 126; + eq[35][i].in[1] <== 125; eq[36][i] = IsEqual(); eq[36][i].in[0] <== in[i]; - eq[36][i].in[1] <== 127; + eq[36][i].in[1] <== 126; + eq[37][i] = IsEqual(); + eq[37][i].in[0] <== in[i]; + eq[37][i].in[1] <== 127; and[35][i] = AND(); and[35][i].a <== states[i][32]; multi_or[5][i] = MultiOR(20); multi_or[5][i].in[0] <== and[34][i].out; - multi_or[5][i].in[1] <== eq[20][i].out; - multi_or[5][i].in[2] <== eq[6][i].out; - multi_or[5][i].in[3] <== eq[21][i].out; - multi_or[5][i].in[4] <== eq[15][i].out; - multi_or[5][i].in[5] <== eq[22][i].out; - multi_or[5][i].in[6] <== eq[23][i].out; - multi_or[5][i].in[7] <== eq[24][i].out; - multi_or[5][i].in[8] <== eq[25][i].out; - multi_or[5][i].in[9] <== eq[26][i].out; - multi_or[5][i].in[10] <== eq[27][i].out; - multi_or[5][i].in[11] <== eq[28][i].out; - multi_or[5][i].in[12] <== eq[29][i].out; - multi_or[5][i].in[13] <== eq[30][i].out; - multi_or[5][i].in[14] <== eq[31][i].out; - multi_or[5][i].in[15] <== eq[32][i].out; - multi_or[5][i].in[16] <== eq[33][i].out; - multi_or[5][i].in[17] <== eq[34][i].out; - multi_or[5][i].in[18] <== eq[35][i].out; - multi_or[5][i].in[19] <== eq[36][i].out; + multi_or[5][i].in[1] <== eq[21][i].out; + multi_or[5][i].in[2] <== eq[7][i].out; + multi_or[5][i].in[3] <== eq[22][i].out; + multi_or[5][i].in[4] <== eq[16][i].out; + multi_or[5][i].in[5] <== eq[23][i].out; + multi_or[5][i].in[6] <== eq[24][i].out; + multi_or[5][i].in[7] <== eq[25][i].out; + multi_or[5][i].in[8] <== eq[26][i].out; + multi_or[5][i].in[9] <== eq[27][i].out; + multi_or[5][i].in[10] <== eq[28][i].out; + multi_or[5][i].in[11] <== eq[29][i].out; + multi_or[5][i].in[12] <== eq[30][i].out; + multi_or[5][i].in[13] <== eq[31][i].out; + multi_or[5][i].in[14] <== eq[32][i].out; + multi_or[5][i].in[15] <== eq[33][i].out; + multi_or[5][i].in[16] <== eq[34][i].out; + multi_or[5][i].in[17] <== eq[35][i].out; + multi_or[5][i].in[18] <== eq[36][i].out; + multi_or[5][i].in[19] <== eq[37][i].out; and[35][i].b <== multi_or[5][i].out; multi_or[6][i] = MultiOR(4); multi_or[6][i].in[0] <== and[30][i].out; @@ -415,82 +418,82 @@ template BodyHashRegex(msg_bytes) { multi_or[7][i].in[4] <== and[43][i].out; multi_or[7][i].in[5] <== and[44][i].out; states[i+1][21] <== multi_or[7][i].out; - eq[37][i] = IsEqual(); - eq[37][i].in[0] <== in[i]; - eq[37][i].in[1] <== 224; + eq[38][i] = IsEqual(); + eq[38][i].in[0] <== in[i]; + eq[38][i].in[1] <== 224; and[45][i] = AND(); and[45][i].a <== states[i][19]; - and[45][i].b <== eq[37][i].out; + and[45][i].b <== eq[38][i].out; and[46][i] = AND(); and[46][i].a <== states[i][20]; - and[46][i].b <== eq[37][i].out; + and[46][i].b <== eq[38][i].out; and[47][i] = AND(); and[47][i].a <== states[i][32]; - and[47][i].b <== eq[37][i].out; + and[47][i].b <== eq[38][i].out; multi_or[8][i] = MultiOR(3); multi_or[8][i].in[0] <== and[45][i].out; multi_or[8][i].in[1] <== and[46][i].out; multi_or[8][i].in[2] <== and[47][i].out; states[i+1][22] <== multi_or[8][i].out; - eq[38][i] = IsEqual(); - eq[38][i].in[0] <== in[i]; - eq[38][i].in[1] <== 225; eq[39][i] = IsEqual(); eq[39][i].in[0] <== in[i]; - eq[39][i].in[1] <== 226; + eq[39][i].in[1] <== 225; eq[40][i] = IsEqual(); eq[40][i].in[0] <== in[i]; - eq[40][i].in[1] <== 227; + eq[40][i].in[1] <== 226; eq[41][i] = IsEqual(); eq[41][i].in[0] <== in[i]; - eq[41][i].in[1] <== 228; + eq[41][i].in[1] <== 227; eq[42][i] = IsEqual(); eq[42][i].in[0] <== in[i]; - eq[42][i].in[1] <== 229; + eq[42][i].in[1] <== 228; eq[43][i] = IsEqual(); eq[43][i].in[0] <== in[i]; - eq[43][i].in[1] <== 230; + eq[43][i].in[1] <== 229; eq[44][i] = IsEqual(); eq[44][i].in[0] <== in[i]; - eq[44][i].in[1] <== 231; + eq[44][i].in[1] <== 230; eq[45][i] = IsEqual(); eq[45][i].in[0] <== in[i]; - eq[45][i].in[1] <== 232; + eq[45][i].in[1] <== 231; eq[46][i] = IsEqual(); eq[46][i].in[0] <== in[i]; - eq[46][i].in[1] <== 233; + eq[46][i].in[1] <== 232; eq[47][i] = IsEqual(); eq[47][i].in[0] <== in[i]; - eq[47][i].in[1] <== 234; + eq[47][i].in[1] <== 233; eq[48][i] = IsEqual(); eq[48][i].in[0] <== in[i]; - eq[48][i].in[1] <== 235; + eq[48][i].in[1] <== 234; eq[49][i] = IsEqual(); eq[49][i].in[0] <== in[i]; - eq[49][i].in[1] <== 236; + eq[49][i].in[1] <== 235; eq[50][i] = IsEqual(); eq[50][i].in[0] <== in[i]; - eq[50][i].in[1] <== 238; + eq[50][i].in[1] <== 236; eq[51][i] = IsEqual(); eq[51][i].in[0] <== in[i]; - eq[51][i].in[1] <== 239; + eq[51][i].in[1] <== 238; + eq[52][i] = IsEqual(); + eq[52][i].in[0] <== in[i]; + eq[52][i].in[1] <== 239; and[48][i] = AND(); and[48][i].a <== states[i][19]; multi_or[9][i] = MultiOR(14); - multi_or[9][i].in[0] <== eq[38][i].out; - multi_or[9][i].in[1] <== eq[39][i].out; - multi_or[9][i].in[2] <== eq[40][i].out; - multi_or[9][i].in[3] <== eq[41][i].out; - multi_or[9][i].in[4] <== eq[42][i].out; - multi_or[9][i].in[5] <== eq[43][i].out; - multi_or[9][i].in[6] <== eq[44][i].out; - multi_or[9][i].in[7] <== eq[45][i].out; - multi_or[9][i].in[8] <== eq[46][i].out; - multi_or[9][i].in[9] <== eq[47][i].out; - multi_or[9][i].in[10] <== eq[48][i].out; - multi_or[9][i].in[11] <== eq[49][i].out; - multi_or[9][i].in[12] <== eq[50][i].out; - multi_or[9][i].in[13] <== eq[51][i].out; + multi_or[9][i].in[0] <== eq[39][i].out; + multi_or[9][i].in[1] <== eq[40][i].out; + multi_or[9][i].in[2] <== eq[41][i].out; + multi_or[9][i].in[3] <== eq[42][i].out; + multi_or[9][i].in[4] <== eq[43][i].out; + multi_or[9][i].in[5] <== eq[44][i].out; + multi_or[9][i].in[6] <== eq[45][i].out; + multi_or[9][i].in[7] <== eq[46][i].out; + multi_or[9][i].in[8] <== eq[47][i].out; + multi_or[9][i].in[9] <== eq[48][i].out; + multi_or[9][i].in[10] <== eq[49][i].out; + multi_or[9][i].in[11] <== eq[50][i].out; + multi_or[9][i].in[12] <== eq[51][i].out; + multi_or[9][i].in[13] <== eq[52][i].out; and[48][i].b <== multi_or[9][i].out; and[49][i] = AND(); and[49][i].a <== states[i][20]; @@ -510,73 +513,73 @@ template BodyHashRegex(msg_bytes) { and[52][i] = AND(); and[52][i].a <== states[i][26]; and[52][i].b <== and[32][i].out; - eq[52][i] = IsEqual(); - eq[52][i].in[0] <== in[i]; - eq[52][i].in[1] <== 128; eq[53][i] = IsEqual(); eq[53][i].in[0] <== in[i]; - eq[53][i].in[1] <== 129; + eq[53][i].in[1] <== 128; eq[54][i] = IsEqual(); eq[54][i].in[0] <== in[i]; - eq[54][i].in[1] <== 130; + eq[54][i].in[1] <== 129; eq[55][i] = IsEqual(); eq[55][i].in[0] <== in[i]; - eq[55][i].in[1] <== 131; + eq[55][i].in[1] <== 130; eq[56][i] = IsEqual(); eq[56][i].in[0] <== in[i]; - eq[56][i].in[1] <== 132; + eq[56][i].in[1] <== 131; eq[57][i] = IsEqual(); eq[57][i].in[0] <== in[i]; - eq[57][i].in[1] <== 133; + eq[57][i].in[1] <== 132; eq[58][i] = IsEqual(); eq[58][i].in[0] <== in[i]; - eq[58][i].in[1] <== 134; + eq[58][i].in[1] <== 133; eq[59][i] = IsEqual(); eq[59][i].in[0] <== in[i]; - eq[59][i].in[1] <== 135; + eq[59][i].in[1] <== 134; eq[60][i] = IsEqual(); eq[60][i].in[0] <== in[i]; - eq[60][i].in[1] <== 136; + eq[60][i].in[1] <== 135; eq[61][i] = IsEqual(); eq[61][i].in[0] <== in[i]; - eq[61][i].in[1] <== 137; + eq[61][i].in[1] <== 136; eq[62][i] = IsEqual(); eq[62][i].in[0] <== in[i]; - eq[62][i].in[1] <== 138; + eq[62][i].in[1] <== 137; eq[63][i] = IsEqual(); eq[63][i].in[0] <== in[i]; - eq[63][i].in[1] <== 139; + eq[63][i].in[1] <== 138; eq[64][i] = IsEqual(); eq[64][i].in[0] <== in[i]; - eq[64][i].in[1] <== 140; + eq[64][i].in[1] <== 139; eq[65][i] = IsEqual(); eq[65][i].in[0] <== in[i]; - eq[65][i].in[1] <== 141; + eq[65][i].in[1] <== 140; eq[66][i] = IsEqual(); eq[66][i].in[0] <== in[i]; - eq[66][i].in[1] <== 142; + eq[66][i].in[1] <== 141; eq[67][i] = IsEqual(); eq[67][i].in[0] <== in[i]; - eq[67][i].in[1] <== 143; + eq[67][i].in[1] <== 142; + eq[68][i] = IsEqual(); + eq[68][i].in[0] <== in[i]; + eq[68][i].in[1] <== 143; and[53][i] = AND(); and[53][i].a <== states[i][27]; multi_or[10][i] = MultiOR(16); - multi_or[10][i].in[0] <== eq[52][i].out; - multi_or[10][i].in[1] <== eq[53][i].out; - multi_or[10][i].in[2] <== eq[54][i].out; - multi_or[10][i].in[3] <== eq[55][i].out; - multi_or[10][i].in[4] <== eq[56][i].out; - multi_or[10][i].in[5] <== eq[57][i].out; - multi_or[10][i].in[6] <== eq[58][i].out; - multi_or[10][i].in[7] <== eq[59][i].out; - multi_or[10][i].in[8] <== eq[60][i].out; - multi_or[10][i].in[9] <== eq[61][i].out; - multi_or[10][i].in[10] <== eq[62][i].out; - multi_or[10][i].in[11] <== eq[63][i].out; - multi_or[10][i].in[12] <== eq[64][i].out; - multi_or[10][i].in[13] <== eq[65][i].out; - multi_or[10][i].in[14] <== eq[66][i].out; - multi_or[10][i].in[15] <== eq[67][i].out; + multi_or[10][i].in[0] <== eq[53][i].out; + multi_or[10][i].in[1] <== eq[54][i].out; + multi_or[10][i].in[2] <== eq[55][i].out; + multi_or[10][i].in[3] <== eq[56][i].out; + multi_or[10][i].in[4] <== eq[57][i].out; + multi_or[10][i].in[5] <== eq[58][i].out; + multi_or[10][i].in[6] <== eq[59][i].out; + multi_or[10][i].in[7] <== eq[60][i].out; + multi_or[10][i].in[8] <== eq[61][i].out; + multi_or[10][i].in[9] <== eq[62][i].out; + multi_or[10][i].in[10] <== eq[63][i].out; + multi_or[10][i].in[11] <== eq[64][i].out; + multi_or[10][i].in[12] <== eq[65][i].out; + multi_or[10][i].in[13] <== eq[66][i].out; + multi_or[10][i].in[14] <== eq[67][i].out; + multi_or[10][i].in[15] <== eq[68][i].out; and[53][i].b <== multi_or[10][i].out; and[54][i] = AND(); and[54][i].a <== states[i][32]; @@ -589,55 +592,55 @@ template BodyHashRegex(msg_bytes) { multi_or[11][i].in[4] <== and[53][i].out; multi_or[11][i].in[5] <== and[54][i].out; states[i+1][23] <== multi_or[11][i].out; - eq[68][i] = IsEqual(); - eq[68][i].in[0] <== in[i]; - eq[68][i].in[1] <== 237; + eq[69][i] = IsEqual(); + eq[69][i].in[0] <== in[i]; + eq[69][i].in[1] <== 237; and[55][i] = AND(); and[55][i].a <== states[i][19]; - and[55][i].b <== eq[68][i].out; + and[55][i].b <== eq[69][i].out; and[56][i] = AND(); and[56][i].a <== states[i][20]; - and[56][i].b <== eq[68][i].out; + and[56][i].b <== eq[69][i].out; and[57][i] = AND(); and[57][i].a <== states[i][32]; - and[57][i].b <== eq[68][i].out; + and[57][i].b <== eq[69][i].out; multi_or[12][i] = MultiOR(3); multi_or[12][i].in[0] <== and[55][i].out; multi_or[12][i].in[1] <== and[56][i].out; multi_or[12][i].in[2] <== and[57][i].out; states[i+1][24] <== multi_or[12][i].out; - eq[69][i] = IsEqual(); - eq[69][i].in[0] <== in[i]; - eq[69][i].in[1] <== 240; + eq[70][i] = IsEqual(); + eq[70][i].in[0] <== in[i]; + eq[70][i].in[1] <== 240; and[58][i] = AND(); and[58][i].a <== states[i][19]; - and[58][i].b <== eq[69][i].out; + and[58][i].b <== eq[70][i].out; and[59][i] = AND(); and[59][i].a <== states[i][20]; - and[59][i].b <== eq[69][i].out; + and[59][i].b <== eq[70][i].out; and[60][i] = AND(); and[60][i].a <== states[i][32]; - and[60][i].b <== eq[69][i].out; + and[60][i].b <== eq[70][i].out; multi_or[13][i] = MultiOR(3); multi_or[13][i].in[0] <== and[58][i].out; multi_or[13][i].in[1] <== and[59][i].out; multi_or[13][i].in[2] <== and[60][i].out; states[i+1][25] <== multi_or[13][i].out; - eq[70][i] = IsEqual(); - eq[70][i].in[0] <== in[i]; - eq[70][i].in[1] <== 241; eq[71][i] = IsEqual(); eq[71][i].in[0] <== in[i]; - eq[71][i].in[1] <== 242; + eq[71][i].in[1] <== 241; eq[72][i] = IsEqual(); eq[72][i].in[0] <== in[i]; - eq[72][i].in[1] <== 243; + eq[72][i].in[1] <== 242; + eq[73][i] = IsEqual(); + eq[73][i].in[0] <== in[i]; + eq[73][i].in[1] <== 243; and[61][i] = AND(); and[61][i].a <== states[i][19]; multi_or[14][i] = MultiOR(3); - multi_or[14][i].in[0] <== eq[70][i].out; - multi_or[14][i].in[1] <== eq[71][i].out; - multi_or[14][i].in[2] <== eq[72][i].out; + multi_or[14][i].in[0] <== eq[71][i].out; + multi_or[14][i].in[1] <== eq[72][i].out; + multi_or[14][i].in[2] <== eq[73][i].out; and[61][i].b <== multi_or[14][i].out; and[62][i] = AND(); and[62][i].a <== states[i][20]; @@ -650,51 +653,51 @@ template BodyHashRegex(msg_bytes) { multi_or[15][i].in[1] <== and[62][i].out; multi_or[15][i].in[2] <== and[63][i].out; states[i+1][26] <== multi_or[15][i].out; - eq[73][i] = IsEqual(); - eq[73][i].in[0] <== in[i]; - eq[73][i].in[1] <== 244; + eq[74][i] = IsEqual(); + eq[74][i].in[0] <== in[i]; + eq[74][i].in[1] <== 244; and[64][i] = AND(); and[64][i].a <== states[i][19]; - and[64][i].b <== eq[73][i].out; + and[64][i].b <== eq[74][i].out; and[65][i] = AND(); and[65][i].a <== states[i][20]; - and[65][i].b <== eq[73][i].out; + and[65][i].b <== eq[74][i].out; and[66][i] = AND(); and[66][i].a <== states[i][32]; - and[66][i].b <== eq[73][i].out; + and[66][i].b <== eq[74][i].out; multi_or[16][i] = MultiOR(3); multi_or[16][i].in[0] <== and[64][i].out; multi_or[16][i].in[1] <== and[65][i].out; multi_or[16][i].in[2] <== and[66][i].out; states[i+1][27] <== multi_or[16][i].out; - eq[74][i] = IsEqual(); - eq[74][i].in[0] <== in[i]; - eq[74][i].in[1] <== 59; + eq[75][i] = IsEqual(); + eq[75][i].in[0] <== in[i]; + eq[75][i].in[1] <== 59; and[67][i] = AND(); and[67][i].a <== states[i][20]; - and[67][i].b <== eq[74][i].out; + and[67][i].b <== eq[75][i].out; states[i+1][28] <== and[67][i].out; - eq[75][i] = IsEqual(); - eq[75][i].in[0] <== in[i]; - eq[75][i].in[1] <== 32; + eq[76][i] = IsEqual(); + eq[76][i].in[0] <== in[i]; + eq[76][i].in[1] <== 32; and[68][i] = AND(); and[68][i].a <== states[i][28]; - and[68][i].b <== eq[75][i].out; + and[68][i].b <== eq[76][i].out; states[i+1][29] <== and[68][i].out; and[69][i] = AND(); and[69][i].a <== states[i][29]; - and[69][i].b <== eq[16][i].out; + and[69][i].b <== eq[17][i].out; states[i+1][30] <== and[69][i].out; - eq[76][i] = IsEqual(); - eq[76][i].in[0] <== in[i]; - eq[76][i].in[1] <== 104; + eq[77][i] = IsEqual(); + eq[77][i].in[0] <== in[i]; + eq[77][i].in[1] <== 104; and[70][i] = AND(); and[70][i].a <== states[i][30]; - and[70][i].b <== eq[76][i].out; + and[70][i].b <== eq[77][i].out; states[i+1][31] <== and[70][i].out; and[71][i] = AND(); and[71][i].a <== states[i][31]; - and[71][i].b <== eq[19][i].out; + and[71][i].b <== eq[20][i].out; states[i+1][32] <== and[71][i].out; lt[22][i] = LessEqThan(8); lt[22][i].in[0] <== 65; @@ -705,60 +708,60 @@ template BodyHashRegex(msg_bytes) { and[72][i] = AND(); and[72][i].a <== lt[22][i].out; and[72][i].b <== lt[23][i].out; - eq[77][i] = IsEqual(); - eq[77][i].in[0] <== in[i]; - eq[77][i].in[1] <== 43; eq[78][i] = IsEqual(); eq[78][i].in[0] <== in[i]; - eq[78][i].in[1] <== 47; + eq[78][i].in[1] <== 43; eq[79][i] = IsEqual(); eq[79][i].in[0] <== in[i]; - eq[79][i].in[1] <== 48; + eq[79][i].in[1] <== 47; eq[80][i] = IsEqual(); eq[80][i].in[0] <== in[i]; - eq[80][i].in[1] <== 49; + eq[80][i].in[1] <== 48; eq[81][i] = IsEqual(); eq[81][i].in[0] <== in[i]; - eq[81][i].in[1] <== 50; + eq[81][i].in[1] <== 49; eq[82][i] = IsEqual(); eq[82][i].in[0] <== in[i]; - eq[82][i].in[1] <== 51; + eq[82][i].in[1] <== 50; eq[83][i] = IsEqual(); eq[83][i].in[0] <== in[i]; - eq[83][i].in[1] <== 52; + eq[83][i].in[1] <== 51; eq[84][i] = IsEqual(); eq[84][i].in[0] <== in[i]; - eq[84][i].in[1] <== 53; + eq[84][i].in[1] <== 52; eq[85][i] = IsEqual(); eq[85][i].in[0] <== in[i]; - eq[85][i].in[1] <== 54; + eq[85][i].in[1] <== 53; eq[86][i] = IsEqual(); eq[86][i].in[0] <== in[i]; - eq[86][i].in[1] <== 55; + eq[86][i].in[1] <== 54; eq[87][i] = IsEqual(); eq[87][i].in[0] <== in[i]; - eq[87][i].in[1] <== 56; + eq[87][i].in[1] <== 55; eq[88][i] = IsEqual(); eq[88][i].in[0] <== in[i]; - eq[88][i].in[1] <== 57; + eq[88][i].in[1] <== 56; + eq[89][i] = IsEqual(); + eq[89][i].in[0] <== in[i]; + eq[89][i].in[1] <== 57; and[73][i] = AND(); and[73][i].a <== states[i][32]; multi_or[17][i] = MultiOR(15); multi_or[17][i].in[0] <== and[72][i].out; multi_or[17][i].in[1] <== and[18][i].out; - multi_or[17][i].in[2] <== eq[77][i].out; - multi_or[17][i].in[3] <== eq[78][i].out; - multi_or[17][i].in[4] <== eq[79][i].out; - multi_or[17][i].in[5] <== eq[80][i].out; - multi_or[17][i].in[6] <== eq[81][i].out; - multi_or[17][i].in[7] <== eq[82][i].out; - multi_or[17][i].in[8] <== eq[83][i].out; - multi_or[17][i].in[9] <== eq[84][i].out; - multi_or[17][i].in[10] <== eq[85][i].out; - multi_or[17][i].in[11] <== eq[86][i].out; - multi_or[17][i].in[12] <== eq[87][i].out; - multi_or[17][i].in[13] <== eq[88][i].out; - multi_or[17][i].in[14] <== eq[19][i].out; + multi_or[17][i].in[2] <== eq[78][i].out; + multi_or[17][i].in[3] <== eq[79][i].out; + multi_or[17][i].in[4] <== eq[80][i].out; + multi_or[17][i].in[5] <== eq[81][i].out; + multi_or[17][i].in[6] <== eq[82][i].out; + multi_or[17][i].in[7] <== eq[83][i].out; + multi_or[17][i].in[8] <== eq[84][i].out; + multi_or[17][i].in[9] <== eq[85][i].out; + multi_or[17][i].in[10] <== eq[86][i].out; + multi_or[17][i].in[11] <== eq[87][i].out; + multi_or[17][i].in[12] <== eq[88][i].out; + multi_or[17][i].in[13] <== eq[89][i].out; + multi_or[17][i].in[14] <== eq[20][i].out; and[73][i].b <== multi_or[17][i].out; and[74][i] = AND(); and[74][i].a <== states[i][33]; @@ -769,11 +772,11 @@ template BodyHashRegex(msg_bytes) { states[i+1][33] <== multi_or[18][i].out; and[75][i] = AND(); and[75][i].a <== states[i][33]; - and[75][i].b <== eq[74][i].out; + and[75][i].b <== eq[75][i].out; states[i+1][34] <== and[75][i].out; from_zero_enabled[i] <== MultiNOR(34)([states_tmp[i+1][1], states_tmp[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7], states[i+1][8], states[i+1][9], states[i+1][10], states[i+1][11], states[i+1][12], states[i+1][13], states[i+1][14], states[i+1][15], states[i+1][16], states[i+1][17], states[i+1][18], states[i+1][19], states[i+1][20], states[i+1][21], states[i+1][22], states[i+1][23], states[i+1][24], states[i+1][25], states[i+1][26], states[i+1][27], states[i+1][28], states[i+1][29], states[i+1][30], states[i+1][31], states[i+1][32], states[i+1][33], states[i+1][34]]); states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); - states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[2][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[1][i].out]); state_changed[i].in[0] <== states[i+1][1]; state_changed[i].in[1] <== states[i+1][2]; state_changed[i].in[2] <== states[i+1][3]; @@ -810,26 +813,29 @@ template BodyHashRegex(msg_bytes) { state_changed[i].in[33] <== states[i+1][34]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][34]; + is_accepted.in[i] <== states[i][34]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][34] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][34], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(32, 33), (33, 33)}] + signal prev_states0[2][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(32, 33), (33, 33)] - is_substr0[i] <== MultiOR(2)([states[i+1][32] * states[i+2][33], states[i+1][33] * states[i+2][33]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][32]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][33]; + is_substr0[i] <== MultiOR(2)([prev_states0[0][i] * states[i+2][33], prev_states0[1][i] * states[i+2][33]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } } \ No newline at end of file diff --git a/packages/circom/circuits/common/email_addr.json b/packages/circom/circuits/common/email_addr.json index 0842165..ed2489e 100644 --- a/packages/circom/circuits/common/email_addr.json +++ b/packages/circom/circuits/common/email_addr.json @@ -2,7 +2,7 @@ "parts": [ { "is_public": true, - "regex_def": "[A-Za-z0-9!#$%&'*+=?^_`{|}~.]+@[A-Za-z0-9.-]+" + "regex_def": "[A-Za-z0-9!#$%&'*+=?\\^_`{|}~.]+@[A-Za-z0-9.-]+" } ] } diff --git a/packages/circom/circuits/common/email_addr_regex.circom b/packages/circom/circuits/common/email_addr_regex.circom index 502820b..b42d937 100644 --- a/packages/circom/circuits/common/email_addr_regex.circom +++ b/packages/circom/circuits/common/email_addr_regex.circom @@ -2,7 +2,7 @@ pragma circom 2.1.5; include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; -// regex: [A-Za-z0-9!#$%&'*+=?^_`{|}~.]+@[A-Za-z0-9.-]+ +// regex: [A-Za-z0-9!#$%&'*+=?\^_`{|}~.]+@[A-Za-z0-9.-]+ template EmailAddrRegex(msg_bytes) { signal input msg[msg_bytes]; signal output out; @@ -14,10 +14,10 @@ template EmailAddrRegex(msg_bytes) { in[i+1] <== msg[i]; } - component eq[24][num_bytes]; - component lt[8][num_bytes]; - component and[9][num_bytes]; - component multi_or[4][num_bytes]; + component eq[23][num_bytes]; + component lt[6][num_bytes]; + component and[8][num_bytes]; + component multi_or[3][num_bytes]; signal states[num_bytes+1][4]; signal states_tmp[num_bytes+1][4]; signal from_zero_enabled[num_bytes+1]; @@ -41,7 +41,7 @@ template EmailAddrRegex(msg_bytes) { and[0][i].a <== lt[0][i].out; and[0][i].b <== lt[1][i].out; lt[2][i] = LessEqThan(8); - lt[2][i].in[0] <== 95; + lt[2][i].in[0] <== 94; lt[2][i].in[1] <== in[i]; lt[3][i] = LessEqThan(8); lt[3][i].in[0] <== in[i]; @@ -112,12 +112,9 @@ template EmailAddrRegex(msg_bytes) { eq[20][i] = IsEqual(); eq[20][i].in[0] <== in[i]; eq[20][i].in[1] <== 63; - eq[21][i] = IsEqual(); - eq[21][i].in[0] <== in[i]; - eq[21][i].in[1] <== 255; and[2][i] = AND(); and[2][i].a <== states[i][0]; - multi_or[0][i] = MultiOR(24); + multi_or[0][i] = MultiOR(23); multi_or[0][i].in[0] <== and[0][i].out; multi_or[0][i].in[1] <== and[1][i].out; multi_or[0][i].in[2] <== eq[0][i].out; @@ -141,89 +138,55 @@ template EmailAddrRegex(msg_bytes) { multi_or[0][i].in[20] <== eq[18][i].out; multi_or[0][i].in[21] <== eq[19][i].out; multi_or[0][i].in[22] <== eq[20][i].out; - multi_or[0][i].in[23] <== eq[21][i].out; and[2][i].b <== multi_or[0][i].out; + and[3][i] = AND(); + and[3][i].a <== states[i][1]; + and[3][i].b <== multi_or[0][i].out; + states_tmp[i+1][1] <== and[3][i].out; + eq[21][i] = IsEqual(); + eq[21][i].in[0] <== in[i]; + eq[21][i].in[1] <== 64; + and[4][i] = AND(); + and[4][i].a <== states[i][1]; + and[4][i].b <== eq[21][i].out; + states[i+1][2] <== and[4][i].out; lt[4][i] = LessEqThan(8); - lt[4][i].in[0] <== 94; + lt[4][i].in[0] <== 97; lt[4][i].in[1] <== in[i]; lt[5][i] = LessEqThan(8); lt[5][i].in[0] <== in[i]; - lt[5][i].in[1] <== 126; - and[3][i] = AND(); - and[3][i].a <== lt[4][i].out; - and[3][i].b <== lt[5][i].out; - and[4][i] = AND(); - and[4][i].a <== states[i][1]; - multi_or[1][i] = MultiOR(23); - multi_or[1][i].in[0] <== and[0][i].out; - multi_or[1][i].in[1] <== and[3][i].out; - multi_or[1][i].in[2] <== eq[0][i].out; - multi_or[1][i].in[3] <== eq[1][i].out; - multi_or[1][i].in[4] <== eq[2][i].out; - multi_or[1][i].in[5] <== eq[3][i].out; - multi_or[1][i].in[6] <== eq[4][i].out; - multi_or[1][i].in[7] <== eq[5][i].out; - multi_or[1][i].in[8] <== eq[6][i].out; - multi_or[1][i].in[9] <== eq[7][i].out; - multi_or[1][i].in[10] <== eq[8][i].out; - multi_or[1][i].in[11] <== eq[9][i].out; - multi_or[1][i].in[12] <== eq[10][i].out; - multi_or[1][i].in[13] <== eq[11][i].out; - multi_or[1][i].in[14] <== eq[12][i].out; - multi_or[1][i].in[15] <== eq[13][i].out; - multi_or[1][i].in[16] <== eq[14][i].out; - multi_or[1][i].in[17] <== eq[15][i].out; - multi_or[1][i].in[18] <== eq[16][i].out; - multi_or[1][i].in[19] <== eq[17][i].out; - multi_or[1][i].in[20] <== eq[18][i].out; - multi_or[1][i].in[21] <== eq[19][i].out; - multi_or[1][i].in[22] <== eq[20][i].out; - and[4][i].b <== multi_or[1][i].out; - states_tmp[i+1][1] <== and[4][i].out; + lt[5][i].in[1] <== 122; + and[5][i] = AND(); + and[5][i].a <== lt[4][i].out; + and[5][i].b <== lt[5][i].out; eq[22][i] = IsEqual(); eq[22][i].in[0] <== in[i]; - eq[22][i].in[1] <== 64; - and[5][i] = AND(); - and[5][i].a <== states[i][1]; - and[5][i].b <== eq[22][i].out; - states[i+1][2] <== and[5][i].out; - lt[6][i] = LessEqThan(8); - lt[6][i].in[0] <== 97; - lt[6][i].in[1] <== in[i]; - lt[7][i] = LessEqThan(8); - lt[7][i].in[0] <== in[i]; - lt[7][i].in[1] <== 122; + eq[22][i].in[1] <== 45; and[6][i] = AND(); - and[6][i].a <== lt[6][i].out; - and[6][i].b <== lt[7][i].out; - eq[23][i] = IsEqual(); - eq[23][i].in[0] <== in[i]; - eq[23][i].in[1] <== 45; + and[6][i].a <== states[i][2]; + multi_or[1][i] = MultiOR(14); + multi_or[1][i].in[0] <== and[0][i].out; + multi_or[1][i].in[1] <== and[5][i].out; + multi_or[1][i].in[2] <== eq[22][i].out; + multi_or[1][i].in[3] <== eq[8][i].out; + multi_or[1][i].in[4] <== eq[9][i].out; + multi_or[1][i].in[5] <== eq[10][i].out; + multi_or[1][i].in[6] <== eq[11][i].out; + multi_or[1][i].in[7] <== eq[12][i].out; + multi_or[1][i].in[8] <== eq[13][i].out; + multi_or[1][i].in[9] <== eq[14][i].out; + multi_or[1][i].in[10] <== eq[15][i].out; + multi_or[1][i].in[11] <== eq[16][i].out; + multi_or[1][i].in[12] <== eq[17][i].out; + multi_or[1][i].in[13] <== eq[18][i].out; + and[6][i].b <== multi_or[1][i].out; and[7][i] = AND(); - and[7][i].a <== states[i][2]; - multi_or[2][i] = MultiOR(14); - multi_or[2][i].in[0] <== and[0][i].out; - multi_or[2][i].in[1] <== and[6][i].out; - multi_or[2][i].in[2] <== eq[23][i].out; - multi_or[2][i].in[3] <== eq[8][i].out; - multi_or[2][i].in[4] <== eq[9][i].out; - multi_or[2][i].in[5] <== eq[10][i].out; - multi_or[2][i].in[6] <== eq[11][i].out; - multi_or[2][i].in[7] <== eq[12][i].out; - multi_or[2][i].in[8] <== eq[13][i].out; - multi_or[2][i].in[9] <== eq[14][i].out; - multi_or[2][i].in[10] <== eq[15][i].out; - multi_or[2][i].in[11] <== eq[16][i].out; - multi_or[2][i].in[12] <== eq[17][i].out; - multi_or[2][i].in[13] <== eq[18][i].out; - and[7][i].b <== multi_or[2][i].out; - and[8][i] = AND(); - and[8][i].a <== states[i][3]; - and[8][i].b <== multi_or[2][i].out; - multi_or[3][i] = MultiOR(2); - multi_or[3][i].in[0] <== and[7][i].out; - multi_or[3][i].in[1] <== and[8][i].out; - states[i+1][3] <== multi_or[3][i].out; + and[7][i].a <== states[i][3]; + and[7][i].b <== multi_or[1][i].out; + multi_or[2][i] = MultiOR(2); + multi_or[2][i].in[0] <== and[6][i].out; + multi_or[2][i].in[1] <== and[7][i].out; + states[i+1][3] <== multi_or[2][i].out; from_zero_enabled[i] <== MultiNOR(3)([states_tmp[i+1][1], states[i+1][2], states[i+1][3]]); states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[2][i].out]); state_changed[i].in[0] <== states[i+1][1]; @@ -231,26 +194,32 @@ template EmailAddrRegex(msg_bytes) { state_changed[i].in[2] <== states[i+1][3]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][3]; + is_accepted.in[i] <== states[i][3]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][3] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][3], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(0, 1), (1, 1), (1, 2), (2, 3), (3, 3)}] + signal prev_states0[5][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(0, 1), (1, 1), (1, 2), (2, 3), (3, 3)] - is_substr0[i] <== MultiOR(5)([states[i+1][0] * states[i+2][1], states[i+1][1] * states[i+2][1], states[i+1][1] * states[i+2][2], states[i+1][2] * states[i+2][3], states[i+1][3] * states[i+2][3]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + is_substr0[i] <== MultiOR(5)([prev_states0[0][i] * states[i+2][1], prev_states0[1][i] * states[i+2][1], prev_states0[2][i] * states[i+2][2], prev_states0[3][i] * states[i+2][3], prev_states0[4][i] * states[i+2][3]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } } \ No newline at end of file diff --git a/packages/circom/circuits/common/email_addr_with_name.json b/packages/circom/circuits/common/email_addr_with_name.json index 31607a3..d1bd578 100644 --- a/packages/circom/circuits/common/email_addr_with_name.json +++ b/packages/circom/circuits/common/email_addr_with_name.json @@ -13,4 +13,4 @@ "regex_def": ">" } ] -} +} \ No newline at end of file diff --git a/packages/circom/circuits/common/email_addr_with_name_regex.circom b/packages/circom/circuits/common/email_addr_with_name_regex.circom index c98d82e..0ac23ef 100644 --- a/packages/circom/circuits/common/email_addr_with_name_regex.circom +++ b/packages/circom/circuits/common/email_addr_with_name_regex.circom @@ -14,10 +14,10 @@ template EmailAddrWithNameRegex(msg_bytes) { in[i+1] <== msg[i]; } - component eq[86][num_bytes]; - component lt[26][num_bytes]; - component and[52][num_bytes]; - component multi_or[20][num_bytes]; + component eq[85][num_bytes]; + component lt[24][num_bytes]; + component and[51][num_bytes]; + component multi_or[19][num_bytes]; signal states[num_bytes+1][14]; signal states_tmp[num_bytes+1][14]; signal from_zero_enabled[num_bytes+1]; @@ -79,651 +79,630 @@ template EmailAddrWithNameRegex(msg_bytes) { and[7][i] = AND(); and[7][i].a <== states[i][4]; and[7][i].b <== and[6][i].out; - lt[8][i] = LessEqThan(8); - lt[8][i].in[0] <== 49; - lt[8][i].in[1] <== in[i]; - lt[9][i] = LessEqThan(8); - lt[9][i].in[0] <== in[i]; - lt[9][i].in[1] <== 223; and[8][i] = AND(); - and[8][i].a <== lt[8][i].out; - and[8][i].b <== lt[9][i].out; + and[8][i].a <== states[i][8]; + and[8][i].b <== and[0][i].out; and[9][i] = AND(); - and[9][i].a <== states[i][8]; - and[9][i].b <== and[8][i].out; - lt[10][i] = LessEqThan(8); - lt[10][i].in[0] <== 127; - lt[10][i].in[1] <== in[i]; - lt[11][i] = LessEqThan(8); - lt[11][i].in[0] <== in[i]; - lt[11][i].in[1] <== 223; - and[10][i] = AND(); - and[10][i].a <== lt[10][i].out; - and[10][i].b <== lt[11][i].out; + and[9][i].a <== states[i][9]; + and[9][i].b <== and[0][i].out; + multi_or[0][i] = MultiOR(5); + multi_or[0][i].in[0] <== and[3][i].out; + multi_or[0][i].in[1] <== and[5][i].out; + multi_or[0][i].in[2] <== and[7][i].out; + multi_or[0][i].in[3] <== and[8][i].out; + multi_or[0][i].in[4] <== and[9][i].out; + states_tmp[i+1][1] <== multi_or[0][i].out; eq[0][i] = IsEqual(); eq[0][i].in[0] <== in[i]; - eq[0][i].in[1] <== 58; + eq[0][i].in[1] <== 224; + and[10][i] = AND(); + and[10][i].a <== states[i][0]; + and[10][i].b <== eq[0][i].out; + and[11][i] = AND(); + and[11][i].a <== states[i][8]; + and[11][i].b <== eq[0][i].out; + and[12][i] = AND(); + and[12][i].a <== states[i][9]; + and[12][i].b <== eq[0][i].out; + multi_or[1][i] = MultiOR(2); + multi_or[1][i].in[0] <== and[11][i].out; + multi_or[1][i].in[1] <== and[12][i].out; + states_tmp[i+1][2] <== multi_or[1][i].out; eq[1][i] = IsEqual(); eq[1][i].in[0] <== in[i]; - eq[1][i].in[1] <== 59; + eq[1][i].in[1] <== 225; eq[2][i] = IsEqual(); eq[2][i].in[0] <== in[i]; - eq[2][i].in[1] <== 60; + eq[2][i].in[1] <== 226; eq[3][i] = IsEqual(); eq[3][i].in[0] <== in[i]; - eq[3][i].in[1] <== 62; + eq[3][i].in[1] <== 227; eq[4][i] = IsEqual(); eq[4][i].in[0] <== in[i]; - eq[4][i].in[1] <== 64; + eq[4][i].in[1] <== 228; eq[5][i] = IsEqual(); eq[5][i].in[0] <== in[i]; - eq[5][i].in[1] <== 91; + eq[5][i].in[1] <== 229; eq[6][i] = IsEqual(); eq[6][i].in[0] <== in[i]; - eq[6][i].in[1] <== 92; + eq[6][i].in[1] <== 230; eq[7][i] = IsEqual(); eq[7][i].in[0] <== in[i]; - eq[7][i].in[1] <== 93; - and[11][i] = AND(); - and[11][i].a <== states[i][9]; - multi_or[0][i] = MultiOR(9); - multi_or[0][i].in[0] <== and[10][i].out; - multi_or[0][i].in[1] <== eq[0][i].out; - multi_or[0][i].in[2] <== eq[1][i].out; - multi_or[0][i].in[3] <== eq[2][i].out; - multi_or[0][i].in[4] <== eq[3][i].out; - multi_or[0][i].in[5] <== eq[4][i].out; - multi_or[0][i].in[6] <== eq[5][i].out; - multi_or[0][i].in[7] <== eq[6][i].out; - multi_or[0][i].in[8] <== eq[7][i].out; - and[11][i].b <== multi_or[0][i].out; - multi_or[1][i] = MultiOR(5); - multi_or[1][i].in[0] <== and[3][i].out; - multi_or[1][i].in[1] <== and[5][i].out; - multi_or[1][i].in[2] <== and[7][i].out; - multi_or[1][i].in[3] <== and[9][i].out; - multi_or[1][i].in[4] <== and[11][i].out; - states_tmp[i+1][1] <== multi_or[1][i].out; + eq[7][i].in[1] <== 231; eq[8][i] = IsEqual(); eq[8][i].in[0] <== in[i]; - eq[8][i].in[1] <== 224; - and[12][i] = AND(); - and[12][i].a <== states[i][0]; - and[12][i].b <== eq[8][i].out; - and[13][i] = AND(); - and[13][i].a <== states[i][8]; - and[13][i].b <== eq[8][i].out; - and[14][i] = AND(); - and[14][i].a <== states[i][9]; - and[14][i].b <== eq[8][i].out; - multi_or[2][i] = MultiOR(2); - multi_or[2][i].in[0] <== and[13][i].out; - multi_or[2][i].in[1] <== and[14][i].out; - states_tmp[i+1][2] <== multi_or[2][i].out; + eq[8][i].in[1] <== 232; eq[9][i] = IsEqual(); eq[9][i].in[0] <== in[i]; - eq[9][i].in[1] <== 225; + eq[9][i].in[1] <== 233; eq[10][i] = IsEqual(); eq[10][i].in[0] <== in[i]; - eq[10][i].in[1] <== 226; + eq[10][i].in[1] <== 234; eq[11][i] = IsEqual(); eq[11][i].in[0] <== in[i]; - eq[11][i].in[1] <== 227; + eq[11][i].in[1] <== 235; eq[12][i] = IsEqual(); eq[12][i].in[0] <== in[i]; - eq[12][i].in[1] <== 228; + eq[12][i].in[1] <== 236; eq[13][i] = IsEqual(); eq[13][i].in[0] <== in[i]; - eq[13][i].in[1] <== 229; + eq[13][i].in[1] <== 238; eq[14][i] = IsEqual(); eq[14][i].in[0] <== in[i]; - eq[14][i].in[1] <== 230; + eq[14][i].in[1] <== 239; + and[13][i] = AND(); + and[13][i].a <== states[i][0]; + multi_or[2][i] = MultiOR(14); + multi_or[2][i].in[0] <== eq[1][i].out; + multi_or[2][i].in[1] <== eq[2][i].out; + multi_or[2][i].in[2] <== eq[3][i].out; + multi_or[2][i].in[3] <== eq[4][i].out; + multi_or[2][i].in[4] <== eq[5][i].out; + multi_or[2][i].in[5] <== eq[6][i].out; + multi_or[2][i].in[6] <== eq[7][i].out; + multi_or[2][i].in[7] <== eq[8][i].out; + multi_or[2][i].in[8] <== eq[9][i].out; + multi_or[2][i].in[9] <== eq[10][i].out; + multi_or[2][i].in[10] <== eq[11][i].out; + multi_or[2][i].in[11] <== eq[12][i].out; + multi_or[2][i].in[12] <== eq[13][i].out; + multi_or[2][i].in[13] <== eq[14][i].out; + and[13][i].b <== multi_or[2][i].out; + lt[8][i] = LessEqThan(8); + lt[8][i].in[0] <== 144; + lt[8][i].in[1] <== in[i]; + lt[9][i] = LessEqThan(8); + lt[9][i].in[0] <== in[i]; + lt[9][i].in[1] <== 191; + and[14][i] = AND(); + and[14][i].a <== lt[8][i].out; + and[14][i].b <== lt[9][i].out; + and[15][i] = AND(); + and[15][i].a <== states[i][5]; + and[15][i].b <== and[14][i].out; + and[16][i] = AND(); + and[16][i].a <== states[i][6]; + and[16][i].b <== and[4][i].out; eq[15][i] = IsEqual(); eq[15][i].in[0] <== in[i]; - eq[15][i].in[1] <== 231; + eq[15][i].in[1] <== 128; eq[16][i] = IsEqual(); eq[16][i].in[0] <== in[i]; - eq[16][i].in[1] <== 232; + eq[16][i].in[1] <== 129; eq[17][i] = IsEqual(); eq[17][i].in[0] <== in[i]; - eq[17][i].in[1] <== 233; + eq[17][i].in[1] <== 130; eq[18][i] = IsEqual(); eq[18][i].in[0] <== in[i]; - eq[18][i].in[1] <== 234; + eq[18][i].in[1] <== 131; eq[19][i] = IsEqual(); eq[19][i].in[0] <== in[i]; - eq[19][i].in[1] <== 235; + eq[19][i].in[1] <== 132; eq[20][i] = IsEqual(); eq[20][i].in[0] <== in[i]; - eq[20][i].in[1] <== 236; + eq[20][i].in[1] <== 133; eq[21][i] = IsEqual(); eq[21][i].in[0] <== in[i]; - eq[21][i].in[1] <== 238; + eq[21][i].in[1] <== 134; eq[22][i] = IsEqual(); eq[22][i].in[0] <== in[i]; - eq[22][i].in[1] <== 239; - and[15][i] = AND(); - and[15][i].a <== states[i][0]; - multi_or[3][i] = MultiOR(14); - multi_or[3][i].in[0] <== eq[9][i].out; - multi_or[3][i].in[1] <== eq[10][i].out; - multi_or[3][i].in[2] <== eq[11][i].out; - multi_or[3][i].in[3] <== eq[12][i].out; - multi_or[3][i].in[4] <== eq[13][i].out; - multi_or[3][i].in[5] <== eq[14][i].out; - multi_or[3][i].in[6] <== eq[15][i].out; - multi_or[3][i].in[7] <== eq[16][i].out; - multi_or[3][i].in[8] <== eq[17][i].out; - multi_or[3][i].in[9] <== eq[18][i].out; - multi_or[3][i].in[10] <== eq[19][i].out; - multi_or[3][i].in[11] <== eq[20][i].out; - multi_or[3][i].in[12] <== eq[21][i].out; - multi_or[3][i].in[13] <== eq[22][i].out; - and[15][i].b <== multi_or[3][i].out; - lt[12][i] = LessEqThan(8); - lt[12][i].in[0] <== 144; - lt[12][i].in[1] <== in[i]; - lt[13][i] = LessEqThan(8); - lt[13][i].in[0] <== in[i]; - lt[13][i].in[1] <== 191; - and[16][i] = AND(); - and[16][i].a <== lt[12][i].out; - and[16][i].b <== lt[13][i].out; - and[17][i] = AND(); - and[17][i].a <== states[i][5]; - and[17][i].b <== and[16][i].out; - and[18][i] = AND(); - and[18][i].a <== states[i][6]; - and[18][i].b <== and[4][i].out; + eq[22][i].in[1] <== 135; eq[23][i] = IsEqual(); eq[23][i].in[0] <== in[i]; - eq[23][i].in[1] <== 128; + eq[23][i].in[1] <== 136; eq[24][i] = IsEqual(); eq[24][i].in[0] <== in[i]; - eq[24][i].in[1] <== 129; + eq[24][i].in[1] <== 137; eq[25][i] = IsEqual(); eq[25][i].in[0] <== in[i]; - eq[25][i].in[1] <== 130; + eq[25][i].in[1] <== 138; eq[26][i] = IsEqual(); eq[26][i].in[0] <== in[i]; - eq[26][i].in[1] <== 131; + eq[26][i].in[1] <== 139; eq[27][i] = IsEqual(); eq[27][i].in[0] <== in[i]; - eq[27][i].in[1] <== 132; + eq[27][i].in[1] <== 140; eq[28][i] = IsEqual(); eq[28][i].in[0] <== in[i]; - eq[28][i].in[1] <== 133; + eq[28][i].in[1] <== 141; eq[29][i] = IsEqual(); eq[29][i].in[0] <== in[i]; - eq[29][i].in[1] <== 134; + eq[29][i].in[1] <== 142; eq[30][i] = IsEqual(); eq[30][i].in[0] <== in[i]; - eq[30][i].in[1] <== 135; + eq[30][i].in[1] <== 143; + and[17][i] = AND(); + and[17][i].a <== states[i][7]; + multi_or[3][i] = MultiOR(16); + multi_or[3][i].in[0] <== eq[15][i].out; + multi_or[3][i].in[1] <== eq[16][i].out; + multi_or[3][i].in[2] <== eq[17][i].out; + multi_or[3][i].in[3] <== eq[18][i].out; + multi_or[3][i].in[4] <== eq[19][i].out; + multi_or[3][i].in[5] <== eq[20][i].out; + multi_or[3][i].in[6] <== eq[21][i].out; + multi_or[3][i].in[7] <== eq[22][i].out; + multi_or[3][i].in[8] <== eq[23][i].out; + multi_or[3][i].in[9] <== eq[24][i].out; + multi_or[3][i].in[10] <== eq[25][i].out; + multi_or[3][i].in[11] <== eq[26][i].out; + multi_or[3][i].in[12] <== eq[27][i].out; + multi_or[3][i].in[13] <== eq[28][i].out; + multi_or[3][i].in[14] <== eq[29][i].out; + multi_or[3][i].in[15] <== eq[30][i].out; + and[17][i].b <== multi_or[3][i].out; + and[18][i] = AND(); + and[18][i].a <== states[i][8]; + and[18][i].b <== multi_or[2][i].out; + and[19][i] = AND(); + and[19][i].a <== states[i][9]; + and[19][i].b <== multi_or[2][i].out; + multi_or[4][i] = MultiOR(5); + multi_or[4][i].in[0] <== and[15][i].out; + multi_or[4][i].in[1] <== and[16][i].out; + multi_or[4][i].in[2] <== and[17][i].out; + multi_or[4][i].in[3] <== and[18][i].out; + multi_or[4][i].in[4] <== and[19][i].out; + states_tmp[i+1][3] <== multi_or[4][i].out; eq[31][i] = IsEqual(); eq[31][i].in[0] <== in[i]; - eq[31][i].in[1] <== 136; + eq[31][i].in[1] <== 237; + and[20][i] = AND(); + and[20][i].a <== states[i][0]; + and[20][i].b <== eq[31][i].out; + and[21][i] = AND(); + and[21][i].a <== states[i][8]; + and[21][i].b <== eq[31][i].out; + and[22][i] = AND(); + and[22][i].a <== states[i][9]; + and[22][i].b <== eq[31][i].out; + multi_or[5][i] = MultiOR(2); + multi_or[5][i].in[0] <== and[21][i].out; + multi_or[5][i].in[1] <== and[22][i].out; + states_tmp[i+1][4] <== multi_or[5][i].out; eq[32][i] = IsEqual(); eq[32][i].in[0] <== in[i]; - eq[32][i].in[1] <== 137; + eq[32][i].in[1] <== 240; + and[23][i] = AND(); + and[23][i].a <== states[i][0]; + and[23][i].b <== eq[32][i].out; + and[24][i] = AND(); + and[24][i].a <== states[i][8]; + and[24][i].b <== eq[32][i].out; + and[25][i] = AND(); + and[25][i].a <== states[i][9]; + and[25][i].b <== eq[32][i].out; + multi_or[6][i] = MultiOR(2); + multi_or[6][i].in[0] <== and[24][i].out; + multi_or[6][i].in[1] <== and[25][i].out; + states_tmp[i+1][5] <== multi_or[6][i].out; eq[33][i] = IsEqual(); eq[33][i].in[0] <== in[i]; - eq[33][i].in[1] <== 138; + eq[33][i].in[1] <== 241; eq[34][i] = IsEqual(); eq[34][i].in[0] <== in[i]; - eq[34][i].in[1] <== 139; + eq[34][i].in[1] <== 242; eq[35][i] = IsEqual(); eq[35][i].in[0] <== in[i]; - eq[35][i].in[1] <== 140; + eq[35][i].in[1] <== 243; + and[26][i] = AND(); + and[26][i].a <== states[i][0]; + multi_or[7][i] = MultiOR(3); + multi_or[7][i].in[0] <== eq[33][i].out; + multi_or[7][i].in[1] <== eq[34][i].out; + multi_or[7][i].in[2] <== eq[35][i].out; + and[26][i].b <== multi_or[7][i].out; + and[27][i] = AND(); + and[27][i].a <== states[i][8]; + and[27][i].b <== multi_or[7][i].out; + and[28][i] = AND(); + and[28][i].a <== states[i][9]; + and[28][i].b <== multi_or[7][i].out; + multi_or[8][i] = MultiOR(2); + multi_or[8][i].in[0] <== and[27][i].out; + multi_or[8][i].in[1] <== and[28][i].out; + states_tmp[i+1][6] <== multi_or[8][i].out; eq[36][i] = IsEqual(); eq[36][i].in[0] <== in[i]; - eq[36][i].in[1] <== 141; + eq[36][i].in[1] <== 244; + and[29][i] = AND(); + and[29][i].a <== states[i][0]; + and[29][i].b <== eq[36][i].out; + and[30][i] = AND(); + and[30][i].a <== states[i][8]; + and[30][i].b <== eq[36][i].out; + and[31][i] = AND(); + and[31][i].a <== states[i][9]; + and[31][i].b <== eq[36][i].out; + multi_or[9][i] = MultiOR(2); + multi_or[9][i].in[0] <== and[30][i].out; + multi_or[9][i].in[1] <== and[31][i].out; + states_tmp[i+1][7] <== multi_or[9][i].out; + lt[10][i] = LessEqThan(8); + lt[10][i].in[0] <== 14; + lt[10][i].in[1] <== in[i]; + lt[11][i] = LessEqThan(8); + lt[11][i].in[0] <== in[i]; + lt[11][i].in[1] <== 127; + and[32][i] = AND(); + and[32][i].a <== lt[10][i].out; + and[32][i].b <== lt[11][i].out; eq[37][i] = IsEqual(); eq[37][i].in[0] <== in[i]; - eq[37][i].in[1] <== 142; + eq[37][i].in[1] <== 1; eq[38][i] = IsEqual(); eq[38][i].in[0] <== in[i]; - eq[38][i].in[1] <== 143; - and[19][i] = AND(); - and[19][i].a <== states[i][7]; - multi_or[4][i] = MultiOR(16); - multi_or[4][i].in[0] <== eq[23][i].out; - multi_or[4][i].in[1] <== eq[24][i].out; - multi_or[4][i].in[2] <== eq[25][i].out; - multi_or[4][i].in[3] <== eq[26][i].out; - multi_or[4][i].in[4] <== eq[27][i].out; - multi_or[4][i].in[5] <== eq[28][i].out; - multi_or[4][i].in[6] <== eq[29][i].out; - multi_or[4][i].in[7] <== eq[30][i].out; - multi_or[4][i].in[8] <== eq[31][i].out; - multi_or[4][i].in[9] <== eq[32][i].out; - multi_or[4][i].in[10] <== eq[33][i].out; - multi_or[4][i].in[11] <== eq[34][i].out; - multi_or[4][i].in[12] <== eq[35][i].out; - multi_or[4][i].in[13] <== eq[36][i].out; - multi_or[4][i].in[14] <== eq[37][i].out; - multi_or[4][i].in[15] <== eq[38][i].out; - and[19][i].b <== multi_or[4][i].out; - and[20][i] = AND(); - and[20][i].a <== states[i][8]; - and[20][i].b <== multi_or[3][i].out; - and[21][i] = AND(); - and[21][i].a <== states[i][9]; - and[21][i].b <== multi_or[3][i].out; - multi_or[5][i] = MultiOR(5); - multi_or[5][i].in[0] <== and[17][i].out; - multi_or[5][i].in[1] <== and[18][i].out; - multi_or[5][i].in[2] <== and[19][i].out; - multi_or[5][i].in[3] <== and[20][i].out; - multi_or[5][i].in[4] <== and[21][i].out; - states_tmp[i+1][3] <== multi_or[5][i].out; + eq[38][i].in[1] <== 2; eq[39][i] = IsEqual(); eq[39][i].in[0] <== in[i]; - eq[39][i].in[1] <== 237; - and[22][i] = AND(); - and[22][i].a <== states[i][0]; - and[22][i].b <== eq[39][i].out; - and[23][i] = AND(); - and[23][i].a <== states[i][8]; - and[23][i].b <== eq[39][i].out; - and[24][i] = AND(); - and[24][i].a <== states[i][9]; - and[24][i].b <== eq[39][i].out; - multi_or[6][i] = MultiOR(2); - multi_or[6][i].in[0] <== and[23][i].out; - multi_or[6][i].in[1] <== and[24][i].out; - states_tmp[i+1][4] <== multi_or[6][i].out; + eq[39][i].in[1] <== 3; eq[40][i] = IsEqual(); eq[40][i].in[0] <== in[i]; - eq[40][i].in[1] <== 240; - and[25][i] = AND(); - and[25][i].a <== states[i][0]; - and[25][i].b <== eq[40][i].out; - and[26][i] = AND(); - and[26][i].a <== states[i][8]; - and[26][i].b <== eq[40][i].out; - and[27][i] = AND(); - and[27][i].a <== states[i][9]; - and[27][i].b <== eq[40][i].out; - multi_or[7][i] = MultiOR(2); - multi_or[7][i].in[0] <== and[26][i].out; - multi_or[7][i].in[1] <== and[27][i].out; - states_tmp[i+1][5] <== multi_or[7][i].out; + eq[40][i].in[1] <== 4; eq[41][i] = IsEqual(); eq[41][i].in[0] <== in[i]; - eq[41][i].in[1] <== 241; + eq[41][i].in[1] <== 5; eq[42][i] = IsEqual(); eq[42][i].in[0] <== in[i]; - eq[42][i].in[1] <== 242; + eq[42][i].in[1] <== 6; eq[43][i] = IsEqual(); eq[43][i].in[0] <== in[i]; - eq[43][i].in[1] <== 243; - and[28][i] = AND(); - and[28][i].a <== states[i][0]; - multi_or[8][i] = MultiOR(3); - multi_or[8][i].in[0] <== eq[41][i].out; - multi_or[8][i].in[1] <== eq[42][i].out; - multi_or[8][i].in[2] <== eq[43][i].out; - and[28][i].b <== multi_or[8][i].out; - and[29][i] = AND(); - and[29][i].a <== states[i][8]; - and[29][i].b <== multi_or[8][i].out; - and[30][i] = AND(); - and[30][i].a <== states[i][9]; - and[30][i].b <== multi_or[8][i].out; - multi_or[9][i] = MultiOR(2); - multi_or[9][i].in[0] <== and[29][i].out; - multi_or[9][i].in[1] <== and[30][i].out; - states_tmp[i+1][6] <== multi_or[9][i].out; + eq[43][i].in[1] <== 7; eq[44][i] = IsEqual(); eq[44][i].in[0] <== in[i]; - eq[44][i].in[1] <== 244; - and[31][i] = AND(); - and[31][i].a <== states[i][0]; - and[31][i].b <== eq[44][i].out; - and[32][i] = AND(); - and[32][i].a <== states[i][8]; - and[32][i].b <== eq[44][i].out; + eq[44][i].in[1] <== 8; + eq[45][i] = IsEqual(); + eq[45][i].in[0] <== in[i]; + eq[45][i].in[1] <== 9; + eq[46][i] = IsEqual(); + eq[46][i].in[0] <== in[i]; + eq[46][i].in[1] <== 11; + eq[47][i] = IsEqual(); + eq[47][i].in[0] <== in[i]; + eq[47][i].in[1] <== 12; and[33][i] = AND(); - and[33][i].a <== states[i][9]; - and[33][i].b <== eq[44][i].out; - multi_or[10][i] = MultiOR(2); + and[33][i].a <== states[i][0]; + multi_or[10][i] = MultiOR(12); multi_or[10][i].in[0] <== and[32][i].out; - multi_or[10][i].in[1] <== and[33][i].out; - states_tmp[i+1][7] <== multi_or[10][i].out; + multi_or[10][i].in[1] <== eq[37][i].out; + multi_or[10][i].in[2] <== eq[38][i].out; + multi_or[10][i].in[3] <== eq[39][i].out; + multi_or[10][i].in[4] <== eq[40][i].out; + multi_or[10][i].in[5] <== eq[41][i].out; + multi_or[10][i].in[6] <== eq[42][i].out; + multi_or[10][i].in[7] <== eq[43][i].out; + multi_or[10][i].in[8] <== eq[44][i].out; + multi_or[10][i].in[9] <== eq[45][i].out; + multi_or[10][i].in[10] <== eq[46][i].out; + multi_or[10][i].in[11] <== eq[47][i].out; + and[33][i].b <== multi_or[10][i].out; + and[34][i] = AND(); + and[34][i].a <== states[i][1]; + and[34][i].b <== and[4][i].out; + lt[12][i] = LessEqThan(8); + lt[12][i].in[0] <== 14; + lt[12][i].in[1] <== in[i]; + lt[13][i] = LessEqThan(8); + lt[13][i].in[0] <== in[i]; + lt[13][i].in[1] <== 59; + and[35][i] = AND(); + and[35][i].a <== lt[12][i].out; + and[35][i].b <== lt[13][i].out; lt[14][i] = LessEqThan(8); - lt[14][i].in[0] <== 14; + lt[14][i].in[0] <== 61; lt[14][i].in[1] <== in[i]; lt[15][i] = LessEqThan(8); lt[15][i].in[0] <== in[i]; - lt[15][i].in[1] <== 93; - and[34][i] = AND(); - and[34][i].a <== lt[14][i].out; - and[34][i].b <== lt[15][i].out; + lt[15][i].in[1] <== 127; + and[36][i] = AND(); + and[36][i].a <== lt[14][i].out; + and[36][i].b <== lt[15][i].out; + and[37][i] = AND(); + and[37][i].a <== states[i][8]; + multi_or[11][i] = MultiOR(13); + multi_or[11][i].in[0] <== and[35][i].out; + multi_or[11][i].in[1] <== and[36][i].out; + multi_or[11][i].in[2] <== eq[37][i].out; + multi_or[11][i].in[3] <== eq[38][i].out; + multi_or[11][i].in[4] <== eq[39][i].out; + multi_or[11][i].in[5] <== eq[40][i].out; + multi_or[11][i].in[6] <== eq[41][i].out; + multi_or[11][i].in[7] <== eq[42][i].out; + multi_or[11][i].in[8] <== eq[43][i].out; + multi_or[11][i].in[9] <== eq[44][i].out; + multi_or[11][i].in[10] <== eq[45][i].out; + multi_or[11][i].in[11] <== eq[46][i].out; + multi_or[11][i].in[12] <== eq[47][i].out; + and[37][i].b <== multi_or[11][i].out; lt[16][i] = LessEqThan(8); - lt[16][i].in[0] <== 95; + lt[16][i].in[0] <== 14; lt[16][i].in[1] <== in[i]; lt[17][i] = LessEqThan(8); lt[17][i].in[0] <== in[i]; - lt[17][i].in[1] <== 127; - and[35][i] = AND(); - and[35][i].a <== lt[16][i].out; - and[35][i].b <== lt[17][i].out; - eq[45][i] = IsEqual(); - eq[45][i].in[0] <== in[i]; - eq[45][i].in[1] <== 0; - eq[46][i] = IsEqual(); - eq[46][i].in[0] <== in[i]; - eq[46][i].in[1] <== 1; - eq[47][i] = IsEqual(); - eq[47][i].in[0] <== in[i]; - eq[47][i].in[1] <== 2; + lt[17][i].in[1] <== 32; + and[38][i] = AND(); + and[38][i].a <== lt[16][i].out; + and[38][i].b <== lt[17][i].out; eq[48][i] = IsEqual(); eq[48][i].in[0] <== in[i]; - eq[48][i].in[1] <== 3; + eq[48][i].in[1] <== 34; eq[49][i] = IsEqual(); eq[49][i].in[0] <== in[i]; - eq[49][i].in[1] <== 4; + eq[49][i].in[1] <== 40; eq[50][i] = IsEqual(); eq[50][i].in[0] <== in[i]; - eq[50][i].in[1] <== 5; + eq[50][i].in[1] <== 41; eq[51][i] = IsEqual(); eq[51][i].in[0] <== in[i]; - eq[51][i].in[1] <== 6; + eq[51][i].in[1] <== 58; eq[52][i] = IsEqual(); eq[52][i].in[0] <== in[i]; - eq[52][i].in[1] <== 7; + eq[52][i].in[1] <== 59; eq[53][i] = IsEqual(); eq[53][i].in[0] <== in[i]; - eq[53][i].in[1] <== 8; + eq[53][i].in[1] <== 62; eq[54][i] = IsEqual(); eq[54][i].in[0] <== in[i]; - eq[54][i].in[1] <== 9; + eq[54][i].in[1] <== 64; eq[55][i] = IsEqual(); eq[55][i].in[0] <== in[i]; - eq[55][i].in[1] <== 11; + eq[55][i].in[1] <== 91; eq[56][i] = IsEqual(); eq[56][i].in[0] <== in[i]; - eq[56][i].in[1] <== 12; + eq[56][i].in[1] <== 92; eq[57][i] = IsEqual(); eq[57][i].in[0] <== in[i]; - eq[57][i].in[1] <== 255; - and[36][i] = AND(); - and[36][i].a <== states[i][0]; - multi_or[11][i] = MultiOR(15); - multi_or[11][i].in[0] <== and[34][i].out; - multi_or[11][i].in[1] <== and[35][i].out; - multi_or[11][i].in[2] <== eq[45][i].out; - multi_or[11][i].in[3] <== eq[46][i].out; - multi_or[11][i].in[4] <== eq[47][i].out; - multi_or[11][i].in[5] <== eq[48][i].out; - multi_or[11][i].in[6] <== eq[49][i].out; - multi_or[11][i].in[7] <== eq[50][i].out; - multi_or[11][i].in[8] <== eq[51][i].out; - multi_or[11][i].in[9] <== eq[52][i].out; - multi_or[11][i].in[10] <== eq[53][i].out; - multi_or[11][i].in[11] <== eq[54][i].out; - multi_or[11][i].in[12] <== eq[55][i].out; - multi_or[11][i].in[13] <== eq[56][i].out; - multi_or[11][i].in[14] <== eq[57][i].out; - and[36][i].b <== multi_or[11][i].out; - and[37][i] = AND(); - and[37][i].a <== states[i][1]; - and[37][i].b <== and[4][i].out; - and[38][i] = AND(); - and[38][i].a <== states[i][8]; - multi_or[12][i] = MultiOR(14); - multi_or[12][i].in[0] <== and[34][i].out; - multi_or[12][i].in[1] <== and[35][i].out; - multi_or[12][i].in[2] <== eq[45][i].out; - multi_or[12][i].in[3] <== eq[46][i].out; - multi_or[12][i].in[4] <== eq[47][i].out; - multi_or[12][i].in[5] <== eq[48][i].out; - multi_or[12][i].in[6] <== eq[49][i].out; - multi_or[12][i].in[7] <== eq[50][i].out; - multi_or[12][i].in[8] <== eq[51][i].out; - multi_or[12][i].in[9] <== eq[52][i].out; - multi_or[12][i].in[10] <== eq[53][i].out; - multi_or[12][i].in[11] <== eq[54][i].out; - multi_or[12][i].in[12] <== eq[55][i].out; - multi_or[12][i].in[13] <== eq[56][i].out; - and[38][i].b <== multi_or[12][i].out; - lt[18][i] = LessEqThan(8); - lt[18][i].in[0] <== 14; - lt[18][i].in[1] <== in[i]; - lt[19][i] = LessEqThan(8); - lt[19][i].in[0] <== in[i]; - lt[19][i].in[1] <== 32; - and[39][i] = AND(); - and[39][i].a <== lt[18][i].out; - and[39][i].b <== lt[19][i].out; + eq[57][i].in[1] <== 93; eq[58][i] = IsEqual(); eq[58][i].in[0] <== in[i]; - eq[58][i].in[1] <== 34; + eq[58][i].in[1] <== 127; + and[39][i] = AND(); + and[39][i].a <== states[i][9]; + multi_or[12][i] = MultiOR(23); + multi_or[12][i].in[0] <== and[38][i].out; + multi_or[12][i].in[1] <== eq[37][i].out; + multi_or[12][i].in[2] <== eq[38][i].out; + multi_or[12][i].in[3] <== eq[39][i].out; + multi_or[12][i].in[4] <== eq[40][i].out; + multi_or[12][i].in[5] <== eq[41][i].out; + multi_or[12][i].in[6] <== eq[42][i].out; + multi_or[12][i].in[7] <== eq[43][i].out; + multi_or[12][i].in[8] <== eq[44][i].out; + multi_or[12][i].in[9] <== eq[45][i].out; + multi_or[12][i].in[10] <== eq[46][i].out; + multi_or[12][i].in[11] <== eq[47][i].out; + multi_or[12][i].in[12] <== eq[48][i].out; + multi_or[12][i].in[13] <== eq[49][i].out; + multi_or[12][i].in[14] <== eq[50][i].out; + multi_or[12][i].in[15] <== eq[51][i].out; + multi_or[12][i].in[16] <== eq[52][i].out; + multi_or[12][i].in[17] <== eq[53][i].out; + multi_or[12][i].in[18] <== eq[54][i].out; + multi_or[12][i].in[19] <== eq[55][i].out; + multi_or[12][i].in[20] <== eq[56][i].out; + multi_or[12][i].in[21] <== eq[57][i].out; + multi_or[12][i].in[22] <== eq[58][i].out; + and[39][i].b <== multi_or[12][i].out; + multi_or[13][i] = MultiOR(3); + multi_or[13][i].in[0] <== and[34][i].out; + multi_or[13][i].in[1] <== and[37][i].out; + multi_or[13][i].in[2] <== and[39][i].out; + states_tmp[i+1][8] <== multi_or[13][i].out; eq[59][i] = IsEqual(); eq[59][i].in[0] <== in[i]; - eq[59][i].in[1] <== 40; - eq[60][i] = IsEqual(); - eq[60][i].in[0] <== in[i]; - eq[60][i].in[1] <== 41; + eq[59][i].in[1] <== 60; and[40][i] = AND(); - and[40][i].a <== states[i][9]; - multi_or[13][i] = MultiOR(18); - multi_or[13][i].in[0] <== and[39][i].out; - multi_or[13][i].in[1] <== eq[45][i].out; - multi_or[13][i].in[2] <== eq[46][i].out; - multi_or[13][i].in[3] <== eq[47][i].out; - multi_or[13][i].in[4] <== eq[48][i].out; - multi_or[13][i].in[5] <== eq[49][i].out; - multi_or[13][i].in[6] <== eq[50][i].out; - multi_or[13][i].in[7] <== eq[51][i].out; - multi_or[13][i].in[8] <== eq[52][i].out; - multi_or[13][i].in[9] <== eq[53][i].out; - multi_or[13][i].in[10] <== eq[54][i].out; - multi_or[13][i].in[11] <== eq[55][i].out; - multi_or[13][i].in[12] <== eq[56][i].out; - multi_or[13][i].in[13] <== eq[58][i].out; - multi_or[13][i].in[14] <== eq[59][i].out; - multi_or[13][i].in[15] <== eq[60][i].out; - multi_or[13][i].in[16] <== eq[0][i].out; - multi_or[13][i].in[17] <== eq[1][i].out; - and[40][i].b <== multi_or[13][i].out; - multi_or[14][i] = MultiOR(3); - multi_or[14][i].in[0] <== and[37][i].out; - multi_or[14][i].in[1] <== and[38][i].out; - multi_or[14][i].in[2] <== and[40][i].out; - states_tmp[i+1][8] <== multi_or[14][i].out; + and[40][i].a <== states[i][8]; + and[40][i].b <== eq[59][i].out; and[41][i] = AND(); - and[41][i].a <== states[i][8]; - and[41][i].b <== eq[2][i].out; + and[41][i].a <== states[i][9]; + and[41][i].b <== eq[59][i].out; + multi_or[14][i] = MultiOR(2); + multi_or[14][i].in[0] <== and[40][i].out; + multi_or[14][i].in[1] <== and[41][i].out; + states[i+1][9] <== multi_or[14][i].out; + lt[18][i] = LessEqThan(8); + lt[18][i].in[0] <== 65; + lt[18][i].in[1] <== in[i]; + lt[19][i] = LessEqThan(8); + lt[19][i].in[0] <== in[i]; + lt[19][i].in[1] <== 90; and[42][i] = AND(); - and[42][i].a <== states[i][9]; - and[42][i].b <== eq[2][i].out; - multi_or[15][i] = MultiOR(2); - multi_or[15][i].in[0] <== and[41][i].out; - multi_or[15][i].in[1] <== and[42][i].out; - states[i+1][9] <== multi_or[15][i].out; + and[42][i].a <== lt[18][i].out; + and[42][i].b <== lt[19][i].out; lt[20][i] = LessEqThan(8); - lt[20][i].in[0] <== 65; + lt[20][i].in[0] <== 94; lt[20][i].in[1] <== in[i]; lt[21][i] = LessEqThan(8); lt[21][i].in[0] <== in[i]; - lt[21][i].in[1] <== 90; + lt[21][i].in[1] <== 126; and[43][i] = AND(); and[43][i].a <== lt[20][i].out; and[43][i].b <== lt[21][i].out; - lt[22][i] = LessEqThan(8); - lt[22][i].in[0] <== 94; - lt[22][i].in[1] <== in[i]; - lt[23][i] = LessEqThan(8); - lt[23][i].in[0] <== in[i]; - lt[23][i].in[1] <== 126; - and[44][i] = AND(); - and[44][i].a <== lt[22][i].out; - and[44][i].b <== lt[23][i].out; + eq[60][i] = IsEqual(); + eq[60][i].in[0] <== in[i]; + eq[60][i].in[1] <== 33; eq[61][i] = IsEqual(); eq[61][i].in[0] <== in[i]; - eq[61][i].in[1] <== 33; + eq[61][i].in[1] <== 35; eq[62][i] = IsEqual(); eq[62][i].in[0] <== in[i]; - eq[62][i].in[1] <== 35; + eq[62][i].in[1] <== 36; eq[63][i] = IsEqual(); eq[63][i].in[0] <== in[i]; - eq[63][i].in[1] <== 36; + eq[63][i].in[1] <== 37; eq[64][i] = IsEqual(); eq[64][i].in[0] <== in[i]; - eq[64][i].in[1] <== 37; + eq[64][i].in[1] <== 38; eq[65][i] = IsEqual(); eq[65][i].in[0] <== in[i]; - eq[65][i].in[1] <== 38; + eq[65][i].in[1] <== 39; eq[66][i] = IsEqual(); eq[66][i].in[0] <== in[i]; - eq[66][i].in[1] <== 39; + eq[66][i].in[1] <== 42; eq[67][i] = IsEqual(); eq[67][i].in[0] <== in[i]; - eq[67][i].in[1] <== 42; + eq[67][i].in[1] <== 43; eq[68][i] = IsEqual(); eq[68][i].in[0] <== in[i]; - eq[68][i].in[1] <== 43; + eq[68][i].in[1] <== 44; eq[69][i] = IsEqual(); eq[69][i].in[0] <== in[i]; - eq[69][i].in[1] <== 44; + eq[69][i].in[1] <== 45; eq[70][i] = IsEqual(); eq[70][i].in[0] <== in[i]; - eq[70][i].in[1] <== 45; + eq[70][i].in[1] <== 46; eq[71][i] = IsEqual(); eq[71][i].in[0] <== in[i]; - eq[71][i].in[1] <== 46; + eq[71][i].in[1] <== 47; eq[72][i] = IsEqual(); eq[72][i].in[0] <== in[i]; - eq[72][i].in[1] <== 47; + eq[72][i].in[1] <== 48; eq[73][i] = IsEqual(); eq[73][i].in[0] <== in[i]; - eq[73][i].in[1] <== 48; + eq[73][i].in[1] <== 49; eq[74][i] = IsEqual(); eq[74][i].in[0] <== in[i]; - eq[74][i].in[1] <== 49; + eq[74][i].in[1] <== 50; eq[75][i] = IsEqual(); eq[75][i].in[0] <== in[i]; - eq[75][i].in[1] <== 50; + eq[75][i].in[1] <== 51; eq[76][i] = IsEqual(); eq[76][i].in[0] <== in[i]; - eq[76][i].in[1] <== 51; + eq[76][i].in[1] <== 52; eq[77][i] = IsEqual(); eq[77][i].in[0] <== in[i]; - eq[77][i].in[1] <== 52; + eq[77][i].in[1] <== 53; eq[78][i] = IsEqual(); eq[78][i].in[0] <== in[i]; - eq[78][i].in[1] <== 53; + eq[78][i].in[1] <== 54; eq[79][i] = IsEqual(); eq[79][i].in[0] <== in[i]; - eq[79][i].in[1] <== 54; + eq[79][i].in[1] <== 55; eq[80][i] = IsEqual(); eq[80][i].in[0] <== in[i]; - eq[80][i].in[1] <== 55; + eq[80][i].in[1] <== 56; eq[81][i] = IsEqual(); eq[81][i].in[0] <== in[i]; - eq[81][i].in[1] <== 56; + eq[81][i].in[1] <== 57; eq[82][i] = IsEqual(); eq[82][i].in[0] <== in[i]; - eq[82][i].in[1] <== 57; + eq[82][i].in[1] <== 61; eq[83][i] = IsEqual(); eq[83][i].in[0] <== in[i]; - eq[83][i].in[1] <== 61; - eq[84][i] = IsEqual(); - eq[84][i].in[0] <== in[i]; - eq[84][i].in[1] <== 63; + eq[83][i].in[1] <== 63; + and[44][i] = AND(); + and[44][i].a <== states[i][9]; + multi_or[15][i] = MultiOR(26); + multi_or[15][i].in[0] <== and[42][i].out; + multi_or[15][i].in[1] <== and[43][i].out; + multi_or[15][i].in[2] <== eq[60][i].out; + multi_or[15][i].in[3] <== eq[61][i].out; + multi_or[15][i].in[4] <== eq[62][i].out; + multi_or[15][i].in[5] <== eq[63][i].out; + multi_or[15][i].in[6] <== eq[64][i].out; + multi_or[15][i].in[7] <== eq[65][i].out; + multi_or[15][i].in[8] <== eq[66][i].out; + multi_or[15][i].in[9] <== eq[67][i].out; + multi_or[15][i].in[10] <== eq[68][i].out; + multi_or[15][i].in[11] <== eq[69][i].out; + multi_or[15][i].in[12] <== eq[70][i].out; + multi_or[15][i].in[13] <== eq[71][i].out; + multi_or[15][i].in[14] <== eq[72][i].out; + multi_or[15][i].in[15] <== eq[73][i].out; + multi_or[15][i].in[16] <== eq[74][i].out; + multi_or[15][i].in[17] <== eq[75][i].out; + multi_or[15][i].in[18] <== eq[76][i].out; + multi_or[15][i].in[19] <== eq[77][i].out; + multi_or[15][i].in[20] <== eq[78][i].out; + multi_or[15][i].in[21] <== eq[79][i].out; + multi_or[15][i].in[22] <== eq[80][i].out; + multi_or[15][i].in[23] <== eq[81][i].out; + multi_or[15][i].in[24] <== eq[82][i].out; + multi_or[15][i].in[25] <== eq[83][i].out; + and[44][i].b <== multi_or[15][i].out; and[45][i] = AND(); - and[45][i].a <== states[i][9]; - multi_or[16][i] = MultiOR(26); - multi_or[16][i].in[0] <== and[43][i].out; - multi_or[16][i].in[1] <== and[44][i].out; - multi_or[16][i].in[2] <== eq[61][i].out; - multi_or[16][i].in[3] <== eq[62][i].out; - multi_or[16][i].in[4] <== eq[63][i].out; - multi_or[16][i].in[5] <== eq[64][i].out; - multi_or[16][i].in[6] <== eq[65][i].out; - multi_or[16][i].in[7] <== eq[66][i].out; - multi_or[16][i].in[8] <== eq[67][i].out; - multi_or[16][i].in[9] <== eq[68][i].out; - multi_or[16][i].in[10] <== eq[69][i].out; - multi_or[16][i].in[11] <== eq[70][i].out; - multi_or[16][i].in[12] <== eq[71][i].out; - multi_or[16][i].in[13] <== eq[72][i].out; - multi_or[16][i].in[14] <== eq[73][i].out; - multi_or[16][i].in[15] <== eq[74][i].out; - multi_or[16][i].in[16] <== eq[75][i].out; - multi_or[16][i].in[17] <== eq[76][i].out; - multi_or[16][i].in[18] <== eq[77][i].out; - multi_or[16][i].in[19] <== eq[78][i].out; - multi_or[16][i].in[20] <== eq[79][i].out; - multi_or[16][i].in[21] <== eq[80][i].out; - multi_or[16][i].in[22] <== eq[81][i].out; - multi_or[16][i].in[23] <== eq[82][i].out; - multi_or[16][i].in[24] <== eq[83][i].out; - multi_or[16][i].in[25] <== eq[84][i].out; - and[45][i].b <== multi_or[16][i].out; + and[45][i].a <== states[i][10]; + and[45][i].b <== multi_or[15][i].out; + multi_or[16][i] = MultiOR(2); + multi_or[16][i].in[0] <== and[44][i].out; + multi_or[16][i].in[1] <== and[45][i].out; + states[i+1][10] <== multi_or[16][i].out; and[46][i] = AND(); and[46][i].a <== states[i][10]; - and[46][i].b <== multi_or[16][i].out; - multi_or[17][i] = MultiOR(2); - multi_or[17][i].in[0] <== and[45][i].out; - multi_or[17][i].in[1] <== and[46][i].out; - states[i+1][10] <== multi_or[17][i].out; + and[46][i].b <== eq[54][i].out; + states[i+1][11] <== and[46][i].out; + lt[22][i] = LessEqThan(8); + lt[22][i].in[0] <== 97; + lt[22][i].in[1] <== in[i]; + lt[23][i] = LessEqThan(8); + lt[23][i].in[0] <== in[i]; + lt[23][i].in[1] <== 122; and[47][i] = AND(); - and[47][i].a <== states[i][10]; - and[47][i].b <== eq[4][i].out; - states[i+1][11] <== and[47][i].out; - lt[24][i] = LessEqThan(8); - lt[24][i].in[0] <== 97; - lt[24][i].in[1] <== in[i]; - lt[25][i] = LessEqThan(8); - lt[25][i].in[0] <== in[i]; - lt[25][i].in[1] <== 122; + and[47][i].a <== lt[22][i].out; + and[47][i].b <== lt[23][i].out; + eq[84][i] = IsEqual(); + eq[84][i].in[0] <== in[i]; + eq[84][i].in[1] <== 95; and[48][i] = AND(); - and[48][i].a <== lt[24][i].out; - and[48][i].b <== lt[25][i].out; - eq[85][i] = IsEqual(); - eq[85][i].in[0] <== in[i]; - eq[85][i].in[1] <== 95; + and[48][i].a <== states[i][11]; + multi_or[17][i] = MultiOR(15); + multi_or[17][i].in[0] <== and[42][i].out; + multi_or[17][i].in[1] <== and[47][i].out; + multi_or[17][i].in[2] <== eq[69][i].out; + multi_or[17][i].in[3] <== eq[70][i].out; + multi_or[17][i].in[4] <== eq[72][i].out; + multi_or[17][i].in[5] <== eq[73][i].out; + multi_or[17][i].in[6] <== eq[74][i].out; + multi_or[17][i].in[7] <== eq[75][i].out; + multi_or[17][i].in[8] <== eq[76][i].out; + multi_or[17][i].in[9] <== eq[77][i].out; + multi_or[17][i].in[10] <== eq[78][i].out; + multi_or[17][i].in[11] <== eq[79][i].out; + multi_or[17][i].in[12] <== eq[80][i].out; + multi_or[17][i].in[13] <== eq[81][i].out; + multi_or[17][i].in[14] <== eq[84][i].out; + and[48][i].b <== multi_or[17][i].out; and[49][i] = AND(); - and[49][i].a <== states[i][11]; - multi_or[18][i] = MultiOR(15); - multi_or[18][i].in[0] <== and[43][i].out; - multi_or[18][i].in[1] <== and[48][i].out; - multi_or[18][i].in[2] <== eq[70][i].out; - multi_or[18][i].in[3] <== eq[71][i].out; - multi_or[18][i].in[4] <== eq[73][i].out; - multi_or[18][i].in[5] <== eq[74][i].out; - multi_or[18][i].in[6] <== eq[75][i].out; - multi_or[18][i].in[7] <== eq[76][i].out; - multi_or[18][i].in[8] <== eq[77][i].out; - multi_or[18][i].in[9] <== eq[78][i].out; - multi_or[18][i].in[10] <== eq[79][i].out; - multi_or[18][i].in[11] <== eq[80][i].out; - multi_or[18][i].in[12] <== eq[81][i].out; - multi_or[18][i].in[13] <== eq[82][i].out; - multi_or[18][i].in[14] <== eq[85][i].out; - and[49][i].b <== multi_or[18][i].out; + and[49][i].a <== states[i][12]; + and[49][i].b <== multi_or[17][i].out; + multi_or[18][i] = MultiOR(2); + multi_or[18][i].in[0] <== and[48][i].out; + multi_or[18][i].in[1] <== and[49][i].out; + states[i+1][12] <== multi_or[18][i].out; and[50][i] = AND(); and[50][i].a <== states[i][12]; - and[50][i].b <== multi_or[18][i].out; - multi_or[19][i] = MultiOR(2); - multi_or[19][i].in[0] <== and[49][i].out; - multi_or[19][i].in[1] <== and[50][i].out; - states[i+1][12] <== multi_or[19][i].out; - and[51][i] = AND(); - and[51][i].a <== states[i][12]; - and[51][i].b <== eq[3][i].out; - states[i+1][13] <== and[51][i].out; + and[50][i].b <== eq[53][i].out; + states[i+1][13] <== and[50][i].out; from_zero_enabled[i] <== MultiNOR(13)([states_tmp[i+1][1], states_tmp[i+1][2], states_tmp[i+1][3], states_tmp[i+1][4], states_tmp[i+1][5], states_tmp[i+1][6], states_tmp[i+1][7], states_tmp[i+1][8], states[i+1][9], states[i+1][10], states[i+1][11], states[i+1][12], states[i+1][13]]); states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[1][i].out]); - states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[12][i].out]); - states[i+1][3] <== MultiOR(2)([states_tmp[i+1][3], from_zero_enabled[i] * and[15][i].out]); - states[i+1][4] <== MultiOR(2)([states_tmp[i+1][4], from_zero_enabled[i] * and[22][i].out]); - states[i+1][5] <== MultiOR(2)([states_tmp[i+1][5], from_zero_enabled[i] * and[25][i].out]); - states[i+1][6] <== MultiOR(2)([states_tmp[i+1][6], from_zero_enabled[i] * and[28][i].out]); - states[i+1][7] <== MultiOR(2)([states_tmp[i+1][7], from_zero_enabled[i] * and[31][i].out]); - states[i+1][8] <== MultiOR(2)([states_tmp[i+1][8], from_zero_enabled[i] * and[36][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[10][i].out]); + states[i+1][3] <== MultiOR(2)([states_tmp[i+1][3], from_zero_enabled[i] * and[13][i].out]); + states[i+1][4] <== MultiOR(2)([states_tmp[i+1][4], from_zero_enabled[i] * and[20][i].out]); + states[i+1][5] <== MultiOR(2)([states_tmp[i+1][5], from_zero_enabled[i] * and[23][i].out]); + states[i+1][6] <== MultiOR(2)([states_tmp[i+1][6], from_zero_enabled[i] * and[26][i].out]); + states[i+1][7] <== MultiOR(2)([states_tmp[i+1][7], from_zero_enabled[i] * and[29][i].out]); + states[i+1][8] <== MultiOR(2)([states_tmp[i+1][8], from_zero_enabled[i] * and[33][i].out]); state_changed[i].in[0] <== states[i+1][1]; state_changed[i].in[1] <== states[i+1][2]; state_changed[i].in[2] <== states[i+1][3]; @@ -739,26 +718,32 @@ template EmailAddrWithNameRegex(msg_bytes) { state_changed[i].in[12] <== states[i+1][13]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][13]; + is_accepted.in[i] <== states[i][13]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][13] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][13], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(9, 10), (10, 10), (10, 11), (11, 12), (12, 12)}] + signal prev_states0[5][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(9, 10), (10, 10), (10, 11), (11, 12), (12, 12)] - is_substr0[i] <== MultiOR(5)([states[i+1][9] * states[i+2][10], states[i+1][10] * states[i+2][10], states[i+1][10] * states[i+2][11], states[i+1][11] * states[i+2][12], states[i+1][12] * states[i+2][12]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][9]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][11]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][12]; + is_substr0[i] <== MultiOR(5)([prev_states0[0][i] * states[i+2][10], prev_states0[1][i] * states[i+2][10], prev_states0[2][i] * states[i+2][11], prev_states0[3][i] * states[i+2][12], prev_states0[4][i] * states[i+2][12]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } } \ No newline at end of file diff --git a/packages/circom/circuits/common/email_domain.json b/packages/circom/circuits/common/email_domain.json index 82f0330..e20587e 100644 --- a/packages/circom/circuits/common/email_domain.json +++ b/packages/circom/circuits/common/email_domain.json @@ -2,7 +2,7 @@ "parts": [ { "is_public": false, - "regex_def": "[A-Za-z0-9!#$%&'*+-/=?^_`{\\|}~\\.]+" + "regex_def": "[A-Za-z0-9!#$%&'*+-/=?\\^_`{\\|}~\\.]+" }, { "is_public": false, diff --git a/packages/circom/circuits/common/email_domain_regex.circom b/packages/circom/circuits/common/email_domain_regex.circom index a55ee03..8fd4ca7 100644 --- a/packages/circom/circuits/common/email_domain_regex.circom +++ b/packages/circom/circuits/common/email_domain_regex.circom @@ -2,7 +2,7 @@ pragma circom 2.1.5; include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; -// regex: [A-Za-z0-9!#$%&'*+-/=?^_`{\|}~\.]+@[A-Za-z0-9\.-]+ +// regex: [A-Za-z0-9!#$%&'*+-/=?\^_`{\|}~\.]+@[A-Za-z0-9\.-]+ template EmailDomainRegex(msg_bytes) { signal input msg[msg_bytes]; signal output out; @@ -14,10 +14,10 @@ template EmailDomainRegex(msg_bytes) { in[i+1] <== msg[i]; } - component eq[26][num_bytes]; - component lt[8][num_bytes]; - component and[9][num_bytes]; - component multi_or[4][num_bytes]; + component eq[25][num_bytes]; + component lt[6][num_bytes]; + component and[8][num_bytes]; + component multi_or[3][num_bytes]; signal states[num_bytes+1][4]; signal states_tmp[num_bytes+1][4]; signal from_zero_enabled[num_bytes+1]; @@ -41,7 +41,7 @@ template EmailDomainRegex(msg_bytes) { and[0][i].a <== lt[0][i].out; and[0][i].b <== lt[1][i].out; lt[2][i] = LessEqThan(8); - lt[2][i].in[0] <== 95; + lt[2][i].in[0] <== 94; lt[2][i].in[1] <== in[i]; lt[3][i] = LessEqThan(8); lt[3][i].in[0] <== in[i]; @@ -121,12 +121,9 @@ template EmailDomainRegex(msg_bytes) { eq[23][i] = IsEqual(); eq[23][i].in[0] <== in[i]; eq[23][i].in[1] <== 63; - eq[24][i] = IsEqual(); - eq[24][i].in[0] <== in[i]; - eq[24][i].in[1] <== 255; and[2][i] = AND(); and[2][i].a <== states[i][0]; - multi_or[0][i] = MultiOR(27); + multi_or[0][i] = MultiOR(26); multi_or[0][i].in[0] <== and[0][i].out; multi_or[0][i].in[1] <== and[1][i].out; multi_or[0][i].in[2] <== eq[0][i].out; @@ -153,89 +150,52 @@ template EmailDomainRegex(msg_bytes) { multi_or[0][i].in[23] <== eq[21][i].out; multi_or[0][i].in[24] <== eq[22][i].out; multi_or[0][i].in[25] <== eq[23][i].out; - multi_or[0][i].in[26] <== eq[24][i].out; and[2][i].b <== multi_or[0][i].out; + and[3][i] = AND(); + and[3][i].a <== states[i][1]; + and[3][i].b <== multi_or[0][i].out; + states_tmp[i+1][1] <== and[3][i].out; + eq[24][i] = IsEqual(); + eq[24][i].in[0] <== in[i]; + eq[24][i].in[1] <== 64; + and[4][i] = AND(); + and[4][i].a <== states[i][1]; + and[4][i].b <== eq[24][i].out; + states[i+1][2] <== and[4][i].out; lt[4][i] = LessEqThan(8); - lt[4][i].in[0] <== 94; + lt[4][i].in[0] <== 97; lt[4][i].in[1] <== in[i]; lt[5][i] = LessEqThan(8); lt[5][i].in[0] <== in[i]; - lt[5][i].in[1] <== 126; - and[3][i] = AND(); - and[3][i].a <== lt[4][i].out; - and[3][i].b <== lt[5][i].out; - and[4][i] = AND(); - and[4][i].a <== states[i][1]; - multi_or[1][i] = MultiOR(26); - multi_or[1][i].in[0] <== and[0][i].out; - multi_or[1][i].in[1] <== and[3][i].out; - multi_or[1][i].in[2] <== eq[0][i].out; - multi_or[1][i].in[3] <== eq[1][i].out; - multi_or[1][i].in[4] <== eq[2][i].out; - multi_or[1][i].in[5] <== eq[3][i].out; - multi_or[1][i].in[6] <== eq[4][i].out; - multi_or[1][i].in[7] <== eq[5][i].out; - multi_or[1][i].in[8] <== eq[6][i].out; - multi_or[1][i].in[9] <== eq[7][i].out; - multi_or[1][i].in[10] <== eq[8][i].out; - multi_or[1][i].in[11] <== eq[9][i].out; - multi_or[1][i].in[12] <== eq[10][i].out; - multi_or[1][i].in[13] <== eq[11][i].out; - multi_or[1][i].in[14] <== eq[12][i].out; - multi_or[1][i].in[15] <== eq[13][i].out; - multi_or[1][i].in[16] <== eq[14][i].out; - multi_or[1][i].in[17] <== eq[15][i].out; - multi_or[1][i].in[18] <== eq[16][i].out; - multi_or[1][i].in[19] <== eq[17][i].out; - multi_or[1][i].in[20] <== eq[18][i].out; - multi_or[1][i].in[21] <== eq[19][i].out; - multi_or[1][i].in[22] <== eq[20][i].out; - multi_or[1][i].in[23] <== eq[21][i].out; - multi_or[1][i].in[24] <== eq[22][i].out; - multi_or[1][i].in[25] <== eq[23][i].out; - and[4][i].b <== multi_or[1][i].out; - states_tmp[i+1][1] <== and[4][i].out; - eq[25][i] = IsEqual(); - eq[25][i].in[0] <== in[i]; - eq[25][i].in[1] <== 64; + lt[5][i].in[1] <== 122; and[5][i] = AND(); - and[5][i].a <== states[i][1]; - and[5][i].b <== eq[25][i].out; - states[i+1][2] <== and[5][i].out; - lt[6][i] = LessEqThan(8); - lt[6][i].in[0] <== 97; - lt[6][i].in[1] <== in[i]; - lt[7][i] = LessEqThan(8); - lt[7][i].in[0] <== in[i]; - lt[7][i].in[1] <== 122; + and[5][i].a <== lt[4][i].out; + and[5][i].b <== lt[5][i].out; and[6][i] = AND(); - and[6][i].a <== lt[6][i].out; - and[6][i].b <== lt[7][i].out; + and[6][i].a <== states[i][2]; + multi_or[1][i] = MultiOR(14); + multi_or[1][i].in[0] <== and[0][i].out; + multi_or[1][i].in[1] <== and[5][i].out; + multi_or[1][i].in[2] <== eq[9][i].out; + multi_or[1][i].in[3] <== eq[10][i].out; + multi_or[1][i].in[4] <== eq[12][i].out; + multi_or[1][i].in[5] <== eq[13][i].out; + multi_or[1][i].in[6] <== eq[14][i].out; + multi_or[1][i].in[7] <== eq[15][i].out; + multi_or[1][i].in[8] <== eq[16][i].out; + multi_or[1][i].in[9] <== eq[17][i].out; + multi_or[1][i].in[10] <== eq[18][i].out; + multi_or[1][i].in[11] <== eq[19][i].out; + multi_or[1][i].in[12] <== eq[20][i].out; + multi_or[1][i].in[13] <== eq[21][i].out; + and[6][i].b <== multi_or[1][i].out; and[7][i] = AND(); - and[7][i].a <== states[i][2]; - multi_or[2][i] = MultiOR(14); - multi_or[2][i].in[0] <== and[0][i].out; - multi_or[2][i].in[1] <== and[6][i].out; - multi_or[2][i].in[2] <== eq[9][i].out; - multi_or[2][i].in[3] <== eq[10][i].out; - multi_or[2][i].in[4] <== eq[12][i].out; - multi_or[2][i].in[5] <== eq[13][i].out; - multi_or[2][i].in[6] <== eq[14][i].out; - multi_or[2][i].in[7] <== eq[15][i].out; - multi_or[2][i].in[8] <== eq[16][i].out; - multi_or[2][i].in[9] <== eq[17][i].out; - multi_or[2][i].in[10] <== eq[18][i].out; - multi_or[2][i].in[11] <== eq[19][i].out; - multi_or[2][i].in[12] <== eq[20][i].out; - multi_or[2][i].in[13] <== eq[21][i].out; - and[7][i].b <== multi_or[2][i].out; - and[8][i] = AND(); - and[8][i].a <== states[i][3]; - and[8][i].b <== multi_or[2][i].out; - multi_or[3][i] = MultiOR(2); - multi_or[3][i].in[0] <== and[7][i].out; - multi_or[3][i].in[1] <== and[8][i].out; - states[i+1][3] <== multi_or[3][i].out; + and[7][i].a <== states[i][3]; + and[7][i].b <== multi_or[1][i].out; + multi_or[2][i] = MultiOR(2); + multi_or[2][i].in[0] <== and[6][i].out; + multi_or[2][i].in[1] <== and[7][i].out; + states[i+1][3] <== multi_or[2][i].out; from_zero_enabled[i] <== MultiNOR(3)([states_tmp[i+1][1], states[i+1][2], states[i+1][3]]); states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[2][i].out]); state_changed[i].in[0] <== states[i+1][1]; @@ -243,26 +203,29 @@ template EmailDomainRegex(msg_bytes) { state_changed[i].in[2] <== states[i+1][3]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][3]; + is_accepted.in[i] <== states[i][3]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][3] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][3], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(2, 3), (3, 3)}] + signal prev_states0[2][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(2, 3), (3, 3)] - is_substr0[i] <== MultiOR(2)([states[i+1][2] * states[i+2][3], states[i+1][3] * states[i+2][3]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + is_substr0[i] <== MultiOR(2)([prev_states0[0][i] * states[i+2][3], prev_states0[1][i] * states[i+2][3]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } } \ No newline at end of file diff --git a/packages/circom/circuits/common/from_addr.json b/packages/circom/circuits/common/from_addr.json index 7fdc28e..3019ca0 100644 --- a/packages/circom/circuits/common/from_addr.json +++ b/packages/circom/circuits/common/from_addr.json @@ -2,7 +2,7 @@ "parts": [ { "is_public": false, - "regex_def": "((\r\n)|^)from:" + "regex_def": "(\r\n|^)from:" }, { "is_public": false, @@ -10,7 +10,7 @@ }, { "is_public": true, - "regex_def": "[A-Za-z0-9!#$%&'\\*\\+-/=\\?^_`{\\|}~\\.]+@[A-Za-z0-9\\.-]+" + "regex_def": "[A-Za-z0-9!#$%&'\\*\\+-/=\\?\\^_`{\\|}~\\.]+@[A-Za-z0-9\\.-]+" }, { "is_public": false, diff --git a/packages/circom/circuits/common/from_all.json b/packages/circom/circuits/common/from_all.json index 3ec0f84..a38aa7e 100644 --- a/packages/circom/circuits/common/from_all.json +++ b/packages/circom/circuits/common/from_all.json @@ -2,7 +2,7 @@ "parts": [ { "is_public": false, - "regex_def": "((\r\n)|^)from:" + "regex_def": "(\r\n|^)from:" }, { "is_public": true, diff --git a/packages/circom/circuits/common/from_all_regex.circom b/packages/circom/circuits/common/from_all_regex.circom index c7758e5..bdafa99 100644 --- a/packages/circom/circuits/common/from_all_regex.circom +++ b/packages/circom/circuits/common/from_all_regex.circom @@ -2,7 +2,7 @@ pragma circom 2.1.5; include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; -// regex: ((\r\n)|^)from:[^\r\n]+\r\n +// regex: (\r\n|^)from:[^\r\n]+\r\n template FromAllRegex(msg_bytes) { signal input msg[msg_bytes]; signal output out; @@ -33,55 +33,58 @@ template FromAllRegex(msg_bytes) { states[i][0] <== 1; eq[0][i] = IsEqual(); eq[0][i].in[0] <== in[i]; - eq[0][i].in[1] <== 102; + eq[0][i].in[1] <== 13; and[0][i] = AND(); and[0][i].a <== states[i][0]; and[0][i].b <== eq[0][i].out; - and[1][i] = AND(); - and[1][i].a <== states[i][4]; - and[1][i].b <== eq[0][i].out; - states_tmp[i+1][1] <== and[1][i].out; + states_tmp[i+1][1] <== 0; eq[1][i] = IsEqual(); eq[1][i].in[0] <== in[i]; - eq[1][i].in[1] <== 13; - and[2][i] = AND(); - and[2][i].a <== states[i][0]; - and[2][i].b <== eq[1][i].out; - states_tmp[i+1][2] <== 0; + eq[1][i].in[1] <== 255; + and[1][i] = AND(); + and[1][i].a <== states[i][0]; + and[1][i].b <== eq[1][i].out; eq[2][i] = IsEqual(); eq[2][i].in[0] <== in[i]; - eq[2][i].in[1] <== 114; - and[3][i] = AND(); - and[3][i].a <== states[i][1]; - and[3][i].b <== eq[2][i].out; - states[i+1][3] <== and[3][i].out; + eq[2][i].in[1] <== 10; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== eq[2][i].out; + states_tmp[i+1][2] <== and[2][i].out; eq[3][i] = IsEqual(); eq[3][i].in[0] <== in[i]; - eq[3][i].in[1] <== 10; - and[4][i] = AND(); - and[4][i].a <== states[i][2]; - and[4][i].b <== eq[3][i].out; - states[i+1][4] <== and[4][i].out; + eq[3][i].in[1] <== 102; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== eq[3][i].out; + states[i+1][3] <== and[3][i].out; eq[4][i] = IsEqual(); eq[4][i].in[0] <== in[i]; - eq[4][i].in[1] <== 111; - and[5][i] = AND(); - and[5][i].a <== states[i][3]; - and[5][i].b <== eq[4][i].out; - states[i+1][5] <== and[5][i].out; + eq[4][i].in[1] <== 114; + and[4][i] = AND(); + and[4][i].a <== states[i][3]; + and[4][i].b <== eq[4][i].out; + states[i+1][4] <== and[4][i].out; eq[5][i] = IsEqual(); eq[5][i].in[0] <== in[i]; - eq[5][i].in[1] <== 109; + eq[5][i].in[1] <== 111; + and[5][i] = AND(); + and[5][i].a <== states[i][4]; + and[5][i].b <== eq[5][i].out; + states[i+1][5] <== and[5][i].out; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 109; and[6][i] = AND(); and[6][i].a <== states[i][5]; - and[6][i].b <== eq[5][i].out; + and[6][i].b <== eq[6][i].out; states[i+1][6] <== and[6][i].out; - eq[6][i] = IsEqual(); - eq[6][i].in[0] <== in[i]; - eq[6][i].in[1] <== 58; + eq[7][i] = IsEqual(); + eq[7][i].in[0] <== in[i]; + eq[7][i].in[1] <== 58; and[7][i] = AND(); and[7][i].a <== states[i][6]; - and[7][i].b <== eq[6][i].out; + and[7][i].b <== eq[7][i].out; states[i+1][7] <== and[7][i].out; lt[0][i] = LessEqThan(8); lt[0][i].in[0] <== 194; @@ -141,78 +144,78 @@ template FromAllRegex(msg_bytes) { multi_or[0][i].in[3] <== and[15][i].out; multi_or[0][i].in[4] <== and[16][i].out; states[i+1][8] <== multi_or[0][i].out; - eq[7][i] = IsEqual(); - eq[7][i].in[0] <== in[i]; - eq[7][i].in[1] <== 224; + eq[8][i] = IsEqual(); + eq[8][i].in[0] <== in[i]; + eq[8][i].in[1] <== 224; and[17][i] = AND(); and[17][i].a <== states[i][7]; - and[17][i].b <== eq[7][i].out; + and[17][i].b <== eq[8][i].out; and[18][i] = AND(); and[18][i].a <== states[i][15]; - and[18][i].b <== eq[7][i].out; + and[18][i].b <== eq[8][i].out; multi_or[1][i] = MultiOR(2); multi_or[1][i].in[0] <== and[17][i].out; multi_or[1][i].in[1] <== and[18][i].out; states[i+1][9] <== multi_or[1][i].out; - eq[8][i] = IsEqual(); - eq[8][i].in[0] <== in[i]; - eq[8][i].in[1] <== 225; eq[9][i] = IsEqual(); eq[9][i].in[0] <== in[i]; - eq[9][i].in[1] <== 226; + eq[9][i].in[1] <== 225; eq[10][i] = IsEqual(); eq[10][i].in[0] <== in[i]; - eq[10][i].in[1] <== 227; + eq[10][i].in[1] <== 226; eq[11][i] = IsEqual(); eq[11][i].in[0] <== in[i]; - eq[11][i].in[1] <== 228; + eq[11][i].in[1] <== 227; eq[12][i] = IsEqual(); eq[12][i].in[0] <== in[i]; - eq[12][i].in[1] <== 229; + eq[12][i].in[1] <== 228; eq[13][i] = IsEqual(); eq[13][i].in[0] <== in[i]; - eq[13][i].in[1] <== 230; + eq[13][i].in[1] <== 229; eq[14][i] = IsEqual(); eq[14][i].in[0] <== in[i]; - eq[14][i].in[1] <== 231; + eq[14][i].in[1] <== 230; eq[15][i] = IsEqual(); eq[15][i].in[0] <== in[i]; - eq[15][i].in[1] <== 232; + eq[15][i].in[1] <== 231; eq[16][i] = IsEqual(); eq[16][i].in[0] <== in[i]; - eq[16][i].in[1] <== 233; + eq[16][i].in[1] <== 232; eq[17][i] = IsEqual(); eq[17][i].in[0] <== in[i]; - eq[17][i].in[1] <== 234; + eq[17][i].in[1] <== 233; eq[18][i] = IsEqual(); eq[18][i].in[0] <== in[i]; - eq[18][i].in[1] <== 235; + eq[18][i].in[1] <== 234; eq[19][i] = IsEqual(); eq[19][i].in[0] <== in[i]; - eq[19][i].in[1] <== 236; + eq[19][i].in[1] <== 235; eq[20][i] = IsEqual(); eq[20][i].in[0] <== in[i]; - eq[20][i].in[1] <== 238; + eq[20][i].in[1] <== 236; eq[21][i] = IsEqual(); eq[21][i].in[0] <== in[i]; - eq[21][i].in[1] <== 239; + eq[21][i].in[1] <== 238; + eq[22][i] = IsEqual(); + eq[22][i].in[0] <== in[i]; + eq[22][i].in[1] <== 239; and[19][i] = AND(); and[19][i].a <== states[i][7]; multi_or[2][i] = MultiOR(14); - multi_or[2][i].in[0] <== eq[8][i].out; - multi_or[2][i].in[1] <== eq[9][i].out; - multi_or[2][i].in[2] <== eq[10][i].out; - multi_or[2][i].in[3] <== eq[11][i].out; - multi_or[2][i].in[4] <== eq[12][i].out; - multi_or[2][i].in[5] <== eq[13][i].out; - multi_or[2][i].in[6] <== eq[14][i].out; - multi_or[2][i].in[7] <== eq[15][i].out; - multi_or[2][i].in[8] <== eq[16][i].out; - multi_or[2][i].in[9] <== eq[17][i].out; - multi_or[2][i].in[10] <== eq[18][i].out; - multi_or[2][i].in[11] <== eq[19][i].out; - multi_or[2][i].in[12] <== eq[20][i].out; - multi_or[2][i].in[13] <== eq[21][i].out; + multi_or[2][i].in[0] <== eq[9][i].out; + multi_or[2][i].in[1] <== eq[10][i].out; + multi_or[2][i].in[2] <== eq[11][i].out; + multi_or[2][i].in[3] <== eq[12][i].out; + multi_or[2][i].in[4] <== eq[13][i].out; + multi_or[2][i].in[5] <== eq[14][i].out; + multi_or[2][i].in[6] <== eq[15][i].out; + multi_or[2][i].in[7] <== eq[16][i].out; + multi_or[2][i].in[8] <== eq[17][i].out; + multi_or[2][i].in[9] <== eq[18][i].out; + multi_or[2][i].in[10] <== eq[19][i].out; + multi_or[2][i].in[11] <== eq[20][i].out; + multi_or[2][i].in[12] <== eq[21][i].out; + multi_or[2][i].in[13] <== eq[22][i].out; and[19][i].b <== multi_or[2][i].out; lt[8][i] = LessEqThan(8); lt[8][i].in[0] <== 144; @@ -229,73 +232,73 @@ template FromAllRegex(msg_bytes) { and[22][i] = AND(); and[22][i].a <== states[i][13]; and[22][i].b <== and[12][i].out; - eq[22][i] = IsEqual(); - eq[22][i].in[0] <== in[i]; - eq[22][i].in[1] <== 128; eq[23][i] = IsEqual(); eq[23][i].in[0] <== in[i]; - eq[23][i].in[1] <== 129; + eq[23][i].in[1] <== 128; eq[24][i] = IsEqual(); eq[24][i].in[0] <== in[i]; - eq[24][i].in[1] <== 130; + eq[24][i].in[1] <== 129; eq[25][i] = IsEqual(); eq[25][i].in[0] <== in[i]; - eq[25][i].in[1] <== 131; + eq[25][i].in[1] <== 130; eq[26][i] = IsEqual(); eq[26][i].in[0] <== in[i]; - eq[26][i].in[1] <== 132; + eq[26][i].in[1] <== 131; eq[27][i] = IsEqual(); eq[27][i].in[0] <== in[i]; - eq[27][i].in[1] <== 133; + eq[27][i].in[1] <== 132; eq[28][i] = IsEqual(); eq[28][i].in[0] <== in[i]; - eq[28][i].in[1] <== 134; + eq[28][i].in[1] <== 133; eq[29][i] = IsEqual(); eq[29][i].in[0] <== in[i]; - eq[29][i].in[1] <== 135; + eq[29][i].in[1] <== 134; eq[30][i] = IsEqual(); eq[30][i].in[0] <== in[i]; - eq[30][i].in[1] <== 136; + eq[30][i].in[1] <== 135; eq[31][i] = IsEqual(); eq[31][i].in[0] <== in[i]; - eq[31][i].in[1] <== 137; + eq[31][i].in[1] <== 136; eq[32][i] = IsEqual(); eq[32][i].in[0] <== in[i]; - eq[32][i].in[1] <== 138; + eq[32][i].in[1] <== 137; eq[33][i] = IsEqual(); eq[33][i].in[0] <== in[i]; - eq[33][i].in[1] <== 139; + eq[33][i].in[1] <== 138; eq[34][i] = IsEqual(); eq[34][i].in[0] <== in[i]; - eq[34][i].in[1] <== 140; + eq[34][i].in[1] <== 139; eq[35][i] = IsEqual(); eq[35][i].in[0] <== in[i]; - eq[35][i].in[1] <== 141; + eq[35][i].in[1] <== 140; eq[36][i] = IsEqual(); eq[36][i].in[0] <== in[i]; - eq[36][i].in[1] <== 142; + eq[36][i].in[1] <== 141; eq[37][i] = IsEqual(); eq[37][i].in[0] <== in[i]; - eq[37][i].in[1] <== 143; + eq[37][i].in[1] <== 142; + eq[38][i] = IsEqual(); + eq[38][i].in[0] <== in[i]; + eq[38][i].in[1] <== 143; and[23][i] = AND(); and[23][i].a <== states[i][14]; multi_or[3][i] = MultiOR(16); - multi_or[3][i].in[0] <== eq[22][i].out; - multi_or[3][i].in[1] <== eq[23][i].out; - multi_or[3][i].in[2] <== eq[24][i].out; - multi_or[3][i].in[3] <== eq[25][i].out; - multi_or[3][i].in[4] <== eq[26][i].out; - multi_or[3][i].in[5] <== eq[27][i].out; - multi_or[3][i].in[6] <== eq[28][i].out; - multi_or[3][i].in[7] <== eq[29][i].out; - multi_or[3][i].in[8] <== eq[30][i].out; - multi_or[3][i].in[9] <== eq[31][i].out; - multi_or[3][i].in[10] <== eq[32][i].out; - multi_or[3][i].in[11] <== eq[33][i].out; - multi_or[3][i].in[12] <== eq[34][i].out; - multi_or[3][i].in[13] <== eq[35][i].out; - multi_or[3][i].in[14] <== eq[36][i].out; - multi_or[3][i].in[15] <== eq[37][i].out; + multi_or[3][i].in[0] <== eq[23][i].out; + multi_or[3][i].in[1] <== eq[24][i].out; + multi_or[3][i].in[2] <== eq[25][i].out; + multi_or[3][i].in[3] <== eq[26][i].out; + multi_or[3][i].in[4] <== eq[27][i].out; + multi_or[3][i].in[5] <== eq[28][i].out; + multi_or[3][i].in[6] <== eq[29][i].out; + multi_or[3][i].in[7] <== eq[30][i].out; + multi_or[3][i].in[8] <== eq[31][i].out; + multi_or[3][i].in[9] <== eq[32][i].out; + multi_or[3][i].in[10] <== eq[33][i].out; + multi_or[3][i].in[11] <== eq[34][i].out; + multi_or[3][i].in[12] <== eq[35][i].out; + multi_or[3][i].in[13] <== eq[36][i].out; + multi_or[3][i].in[14] <== eq[37][i].out; + multi_or[3][i].in[15] <== eq[38][i].out; and[23][i].b <== multi_or[3][i].out; and[24][i] = AND(); and[24][i].a <== states[i][15]; @@ -307,47 +310,47 @@ template FromAllRegex(msg_bytes) { multi_or[4][i].in[3] <== and[23][i].out; multi_or[4][i].in[4] <== and[24][i].out; states[i+1][10] <== multi_or[4][i].out; - eq[38][i] = IsEqual(); - eq[38][i].in[0] <== in[i]; - eq[38][i].in[1] <== 237; + eq[39][i] = IsEqual(); + eq[39][i].in[0] <== in[i]; + eq[39][i].in[1] <== 237; and[25][i] = AND(); and[25][i].a <== states[i][7]; - and[25][i].b <== eq[38][i].out; + and[25][i].b <== eq[39][i].out; and[26][i] = AND(); and[26][i].a <== states[i][15]; - and[26][i].b <== eq[38][i].out; + and[26][i].b <== eq[39][i].out; multi_or[5][i] = MultiOR(2); multi_or[5][i].in[0] <== and[25][i].out; multi_or[5][i].in[1] <== and[26][i].out; states[i+1][11] <== multi_or[5][i].out; - eq[39][i] = IsEqual(); - eq[39][i].in[0] <== in[i]; - eq[39][i].in[1] <== 240; + eq[40][i] = IsEqual(); + eq[40][i].in[0] <== in[i]; + eq[40][i].in[1] <== 240; and[27][i] = AND(); and[27][i].a <== states[i][7]; - and[27][i].b <== eq[39][i].out; + and[27][i].b <== eq[40][i].out; and[28][i] = AND(); and[28][i].a <== states[i][15]; - and[28][i].b <== eq[39][i].out; + and[28][i].b <== eq[40][i].out; multi_or[6][i] = MultiOR(2); multi_or[6][i].in[0] <== and[27][i].out; multi_or[6][i].in[1] <== and[28][i].out; states[i+1][12] <== multi_or[6][i].out; - eq[40][i] = IsEqual(); - eq[40][i].in[0] <== in[i]; - eq[40][i].in[1] <== 241; eq[41][i] = IsEqual(); eq[41][i].in[0] <== in[i]; - eq[41][i].in[1] <== 242; + eq[41][i].in[1] <== 241; eq[42][i] = IsEqual(); eq[42][i].in[0] <== in[i]; - eq[42][i].in[1] <== 243; + eq[42][i].in[1] <== 242; + eq[43][i] = IsEqual(); + eq[43][i].in[0] <== in[i]; + eq[43][i].in[1] <== 243; and[29][i] = AND(); and[29][i].a <== states[i][7]; multi_or[7][i] = MultiOR(3); - multi_or[7][i].in[0] <== eq[40][i].out; - multi_or[7][i].in[1] <== eq[41][i].out; - multi_or[7][i].in[2] <== eq[42][i].out; + multi_or[7][i].in[0] <== eq[41][i].out; + multi_or[7][i].in[1] <== eq[42][i].out; + multi_or[7][i].in[2] <== eq[43][i].out; and[29][i].b <== multi_or[7][i].out; and[30][i] = AND(); and[30][i].a <== states[i][15]; @@ -356,15 +359,15 @@ template FromAllRegex(msg_bytes) { multi_or[8][i].in[0] <== and[29][i].out; multi_or[8][i].in[1] <== and[30][i].out; states[i+1][13] <== multi_or[8][i].out; - eq[43][i] = IsEqual(); - eq[43][i].in[0] <== in[i]; - eq[43][i].in[1] <== 244; + eq[44][i] = IsEqual(); + eq[44][i].in[0] <== in[i]; + eq[44][i].in[1] <== 244; and[31][i] = AND(); and[31][i].a <== states[i][7]; - and[31][i].b <== eq[43][i].out; + and[31][i].b <== eq[44][i].out; and[32][i] = AND(); and[32][i].a <== states[i][15]; - and[32][i].b <== eq[43][i].out; + and[32][i].b <== eq[44][i].out; multi_or[9][i] = MultiOR(2); multi_or[9][i].in[0] <== and[31][i].out; multi_or[9][i].in[1] <== and[32][i].out; @@ -378,9 +381,6 @@ template FromAllRegex(msg_bytes) { and[33][i] = AND(); and[33][i].a <== lt[10][i].out; and[33][i].b <== lt[11][i].out; - eq[44][i] = IsEqual(); - eq[44][i].in[0] <== in[i]; - eq[44][i].in[1] <== 0; eq[45][i] = IsEqual(); eq[45][i].in[0] <== in[i]; eq[45][i].in[1] <== 1; @@ -416,20 +416,19 @@ template FromAllRegex(msg_bytes) { eq[55][i].in[1] <== 12; and[34][i] = AND(); and[34][i].a <== states[i][7]; - multi_or[10][i] = MultiOR(13); + multi_or[10][i] = MultiOR(12); multi_or[10][i].in[0] <== and[33][i].out; - multi_or[10][i].in[1] <== eq[44][i].out; - multi_or[10][i].in[2] <== eq[45][i].out; - multi_or[10][i].in[3] <== eq[46][i].out; - multi_or[10][i].in[4] <== eq[47][i].out; - multi_or[10][i].in[5] <== eq[48][i].out; - multi_or[10][i].in[6] <== eq[49][i].out; - multi_or[10][i].in[7] <== eq[50][i].out; - multi_or[10][i].in[8] <== eq[51][i].out; - multi_or[10][i].in[9] <== eq[52][i].out; - multi_or[10][i].in[10] <== eq[53][i].out; - multi_or[10][i].in[11] <== eq[54][i].out; - multi_or[10][i].in[12] <== eq[55][i].out; + multi_or[10][i].in[1] <== eq[45][i].out; + multi_or[10][i].in[2] <== eq[46][i].out; + multi_or[10][i].in[3] <== eq[47][i].out; + multi_or[10][i].in[4] <== eq[48][i].out; + multi_or[10][i].in[5] <== eq[49][i].out; + multi_or[10][i].in[6] <== eq[50][i].out; + multi_or[10][i].in[7] <== eq[51][i].out; + multi_or[10][i].in[8] <== eq[52][i].out; + multi_or[10][i].in[9] <== eq[53][i].out; + multi_or[10][i].in[10] <== eq[54][i].out; + multi_or[10][i].in[11] <== eq[55][i].out; and[34][i].b <== multi_or[10][i].out; and[35][i] = AND(); and[35][i].a <== states[i][8]; @@ -444,15 +443,15 @@ template FromAllRegex(msg_bytes) { states[i+1][15] <== multi_or[11][i].out; and[37][i] = AND(); and[37][i].a <== states[i][15]; - and[37][i].b <== eq[1][i].out; + and[37][i].b <== eq[0][i].out; states[i+1][16] <== and[37][i].out; and[38][i] = AND(); and[38][i].a <== states[i][16]; - and[38][i].b <== eq[3][i].out; + and[38][i].b <== eq[2][i].out; states[i+1][17] <== and[38][i].out; from_zero_enabled[i] <== MultiNOR(17)([states_tmp[i+1][1], states_tmp[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7], states[i+1][8], states[i+1][9], states[i+1][10], states[i+1][11], states[i+1][12], states[i+1][13], states[i+1][14], states[i+1][15], states[i+1][16], states[i+1][17]]); states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); - states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[2][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[1][i].out]); state_changed[i].in[0] <== states[i+1][1]; state_changed[i].in[1] <== states[i+1][2]; state_changed[i].in[2] <== states[i+1][3]; @@ -472,26 +471,50 @@ template FromAllRegex(msg_bytes) { state_changed[i].in[16] <== states[i+1][17]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][17]; + is_accepted.in[i] <== states[i][17]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][17] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][17], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(7, 8), (7, 9), (7, 10), (7, 11), (7, 12), (7, 13), (7, 14), (7, 15), (8, 15), (9, 8), (10, 8), (11, 8), (12, 10), (13, 10), (14, 10), (15, 8), (15, 9), (15, 10), (15, 11), (15, 12), (15, 13), (15, 14), (15, 15)}] + signal prev_states0[23][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(7, 8), (7, 9), (7, 10), (7, 11), (7, 12), (7, 13), (7, 14), (7, 15), (8, 15), (9, 8), (10, 8), (11, 8), (12, 10), (13, 10), (14, 10), (15, 8), (15, 9), (15, 10), (15, 11), (15, 12), (15, 13), (15, 14), (15, 15)] - is_substr0[i] <== MultiOR(23)([states[i+1][7] * states[i+2][8], states[i+1][7] * states[i+2][9], states[i+1][7] * states[i+2][10], states[i+1][7] * states[i+2][11], states[i+1][7] * states[i+2][12], states[i+1][7] * states[i+2][13], states[i+1][7] * states[i+2][14], states[i+1][7] * states[i+2][15], states[i+1][8] * states[i+2][15], states[i+1][9] * states[i+2][8], states[i+1][10] * states[i+2][8], states[i+1][11] * states[i+2][8], states[i+1][12] * states[i+2][10], states[i+1][13] * states[i+2][10], states[i+1][14] * states[i+2][10], states[i+1][15] * states[i+2][8], states[i+1][15] * states[i+2][9], states[i+1][15] * states[i+2][10], states[i+1][15] * states[i+2][11], states[i+1][15] * states[i+2][12], states[i+1][15] * states[i+2][13], states[i+1][15] * states[i+2][14], states[i+1][15] * states[i+2][15]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + prev_states0[6][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + prev_states0[7][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][8]; + prev_states0[9][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][9]; + prev_states0[10][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[11][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][11]; + prev_states0[12][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][12]; + prev_states0[13][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][13]; + prev_states0[14][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][14]; + prev_states0[15][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][15]; + prev_states0[16][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][15]; + prev_states0[17][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][15]; + prev_states0[18][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][15]; + prev_states0[19][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][15]; + prev_states0[20][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][15]; + prev_states0[21][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][15]; + prev_states0[22][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][15]; + is_substr0[i] <== MultiOR(23)([prev_states0[0][i] * states[i+2][8], prev_states0[1][i] * states[i+2][9], prev_states0[2][i] * states[i+2][10], prev_states0[3][i] * states[i+2][11], prev_states0[4][i] * states[i+2][12], prev_states0[5][i] * states[i+2][13], prev_states0[6][i] * states[i+2][14], prev_states0[7][i] * states[i+2][15], prev_states0[8][i] * states[i+2][15], prev_states0[9][i] * states[i+2][8], prev_states0[10][i] * states[i+2][8], prev_states0[11][i] * states[i+2][8], prev_states0[12][i] * states[i+2][10], prev_states0[13][i] * states[i+2][10], prev_states0[14][i] * states[i+2][10], prev_states0[15][i] * states[i+2][8], prev_states0[16][i] * states[i+2][9], prev_states0[17][i] * states[i+2][10], prev_states0[18][i] * states[i+2][11], prev_states0[19][i] * states[i+2][12], prev_states0[20][i] * states[i+2][13], prev_states0[21][i] * states[i+2][14], prev_states0[22][i] * states[i+2][15]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } } \ No newline at end of file diff --git a/packages/circom/circuits/common/message_id.json b/packages/circom/circuits/common/message_id.json index f71f0ee..b9d1227 100644 --- a/packages/circom/circuits/common/message_id.json +++ b/packages/circom/circuits/common/message_id.json @@ -2,7 +2,7 @@ "parts": [ { "is_public": false, - "regex_def": "((\r\n)|^)message-id:" + "regex_def": "(\r\n|^)message-id:" }, { "is_public": true, diff --git a/packages/circom/circuits/common/message_id_regex.circom b/packages/circom/circuits/common/message_id_regex.circom index 9ee8272..418d7cc 100644 --- a/packages/circom/circuits/common/message_id_regex.circom +++ b/packages/circom/circuits/common/message_id_regex.circom @@ -2,7 +2,7 @@ pragma circom 2.1.5; include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; -// regex: ((\r\n)|^)message-id:<[A-Za-z0-9=@\.\+_-]+>\r\n +// regex: (\r\n|^)message-id:<[A-Za-z0-9=@\.\+_-]+>\r\n template MessageIdRegex(msg_bytes) { signal input msg[msg_bytes]; signal output out; @@ -14,7 +14,7 @@ template MessageIdRegex(msg_bytes) { in[i+1] <== msg[i]; } - component eq[27][num_bytes]; + component eq[28][num_bytes]; component lt[4][num_bytes]; component and[22][num_bytes]; component multi_or[2][num_bytes]; @@ -33,98 +33,101 @@ template MessageIdRegex(msg_bytes) { states[i][0] <== 1; eq[0][i] = IsEqual(); eq[0][i].in[0] <== in[i]; - eq[0][i].in[1] <== 109; + eq[0][i].in[1] <== 13; and[0][i] = AND(); and[0][i].a <== states[i][0]; and[0][i].b <== eq[0][i].out; - and[1][i] = AND(); - and[1][i].a <== states[i][4]; - and[1][i].b <== eq[0][i].out; - states_tmp[i+1][1] <== and[1][i].out; + states_tmp[i+1][1] <== 0; eq[1][i] = IsEqual(); eq[1][i].in[0] <== in[i]; - eq[1][i].in[1] <== 13; - and[2][i] = AND(); - and[2][i].a <== states[i][0]; - and[2][i].b <== eq[1][i].out; - states_tmp[i+1][2] <== 0; + eq[1][i].in[1] <== 255; + and[1][i] = AND(); + and[1][i].a <== states[i][0]; + and[1][i].b <== eq[1][i].out; eq[2][i] = IsEqual(); eq[2][i].in[0] <== in[i]; - eq[2][i].in[1] <== 101; - and[3][i] = AND(); - and[3][i].a <== states[i][1]; - and[3][i].b <== eq[2][i].out; - states[i+1][3] <== and[3][i].out; + eq[2][i].in[1] <== 10; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== eq[2][i].out; + states_tmp[i+1][2] <== and[2][i].out; eq[3][i] = IsEqual(); eq[3][i].in[0] <== in[i]; - eq[3][i].in[1] <== 10; - and[4][i] = AND(); - and[4][i].a <== states[i][2]; - and[4][i].b <== eq[3][i].out; - states[i+1][4] <== and[4][i].out; + eq[3][i].in[1] <== 109; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== eq[3][i].out; + states[i+1][3] <== and[3][i].out; eq[4][i] = IsEqual(); eq[4][i].in[0] <== in[i]; - eq[4][i].in[1] <== 115; + eq[4][i].in[1] <== 101; + and[4][i] = AND(); + and[4][i].a <== states[i][3]; + and[4][i].b <== eq[4][i].out; + states[i+1][4] <== and[4][i].out; + eq[5][i] = IsEqual(); + eq[5][i].in[0] <== in[i]; + eq[5][i].in[1] <== 115; and[5][i] = AND(); - and[5][i].a <== states[i][3]; - and[5][i].b <== eq[4][i].out; + and[5][i].a <== states[i][4]; + and[5][i].b <== eq[5][i].out; states[i+1][5] <== and[5][i].out; and[6][i] = AND(); and[6][i].a <== states[i][5]; - and[6][i].b <== eq[4][i].out; + and[6][i].b <== eq[5][i].out; states[i+1][6] <== and[6][i].out; - eq[5][i] = IsEqual(); - eq[5][i].in[0] <== in[i]; - eq[5][i].in[1] <== 97; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 97; and[7][i] = AND(); and[7][i].a <== states[i][6]; - and[7][i].b <== eq[5][i].out; + and[7][i].b <== eq[6][i].out; states[i+1][7] <== and[7][i].out; - eq[6][i] = IsEqual(); - eq[6][i].in[0] <== in[i]; - eq[6][i].in[1] <== 103; + eq[7][i] = IsEqual(); + eq[7][i].in[0] <== in[i]; + eq[7][i].in[1] <== 103; and[8][i] = AND(); and[8][i].a <== states[i][7]; - and[8][i].b <== eq[6][i].out; + and[8][i].b <== eq[7][i].out; states[i+1][8] <== and[8][i].out; and[9][i] = AND(); and[9][i].a <== states[i][8]; - and[9][i].b <== eq[2][i].out; + and[9][i].b <== eq[4][i].out; states[i+1][9] <== and[9][i].out; - eq[7][i] = IsEqual(); - eq[7][i].in[0] <== in[i]; - eq[7][i].in[1] <== 45; + eq[8][i] = IsEqual(); + eq[8][i].in[0] <== in[i]; + eq[8][i].in[1] <== 45; and[10][i] = AND(); and[10][i].a <== states[i][9]; - and[10][i].b <== eq[7][i].out; + and[10][i].b <== eq[8][i].out; states[i+1][10] <== and[10][i].out; - eq[8][i] = IsEqual(); - eq[8][i].in[0] <== in[i]; - eq[8][i].in[1] <== 105; + eq[9][i] = IsEqual(); + eq[9][i].in[0] <== in[i]; + eq[9][i].in[1] <== 105; and[11][i] = AND(); and[11][i].a <== states[i][10]; - and[11][i].b <== eq[8][i].out; + and[11][i].b <== eq[9][i].out; states[i+1][11] <== and[11][i].out; - eq[9][i] = IsEqual(); - eq[9][i].in[0] <== in[i]; - eq[9][i].in[1] <== 100; + eq[10][i] = IsEqual(); + eq[10][i].in[0] <== in[i]; + eq[10][i].in[1] <== 100; and[12][i] = AND(); and[12][i].a <== states[i][11]; - and[12][i].b <== eq[9][i].out; + and[12][i].b <== eq[10][i].out; states[i+1][12] <== and[12][i].out; - eq[10][i] = IsEqual(); - eq[10][i].in[0] <== in[i]; - eq[10][i].in[1] <== 58; + eq[11][i] = IsEqual(); + eq[11][i].in[0] <== in[i]; + eq[11][i].in[1] <== 58; and[13][i] = AND(); and[13][i].a <== states[i][12]; - and[13][i].b <== eq[10][i].out; + and[13][i].b <== eq[11][i].out; states[i+1][13] <== and[13][i].out; - eq[11][i] = IsEqual(); - eq[11][i].in[0] <== in[i]; - eq[11][i].in[1] <== 60; + eq[12][i] = IsEqual(); + eq[12][i].in[0] <== in[i]; + eq[12][i].in[1] <== 60; and[14][i] = AND(); and[14][i].a <== states[i][13]; - and[14][i].b <== eq[11][i].out; + and[14][i].b <== eq[12][i].out; states[i+1][14] <== and[14][i].out; lt[0][i] = LessEqThan(8); lt[0][i].in[0] <== 64; @@ -144,68 +147,68 @@ template MessageIdRegex(msg_bytes) { and[16][i] = AND(); and[16][i].a <== lt[2][i].out; and[16][i].b <== lt[3][i].out; - eq[12][i] = IsEqual(); - eq[12][i].in[0] <== in[i]; - eq[12][i].in[1] <== 43; eq[13][i] = IsEqual(); eq[13][i].in[0] <== in[i]; - eq[13][i].in[1] <== 46; + eq[13][i].in[1] <== 43; eq[14][i] = IsEqual(); eq[14][i].in[0] <== in[i]; - eq[14][i].in[1] <== 48; + eq[14][i].in[1] <== 46; eq[15][i] = IsEqual(); eq[15][i].in[0] <== in[i]; - eq[15][i].in[1] <== 49; + eq[15][i].in[1] <== 48; eq[16][i] = IsEqual(); eq[16][i].in[0] <== in[i]; - eq[16][i].in[1] <== 50; + eq[16][i].in[1] <== 49; eq[17][i] = IsEqual(); eq[17][i].in[0] <== in[i]; - eq[17][i].in[1] <== 51; + eq[17][i].in[1] <== 50; eq[18][i] = IsEqual(); eq[18][i].in[0] <== in[i]; - eq[18][i].in[1] <== 52; + eq[18][i].in[1] <== 51; eq[19][i] = IsEqual(); eq[19][i].in[0] <== in[i]; - eq[19][i].in[1] <== 53; + eq[19][i].in[1] <== 52; eq[20][i] = IsEqual(); eq[20][i].in[0] <== in[i]; - eq[20][i].in[1] <== 54; + eq[20][i].in[1] <== 53; eq[21][i] = IsEqual(); eq[21][i].in[0] <== in[i]; - eq[21][i].in[1] <== 55; + eq[21][i].in[1] <== 54; eq[22][i] = IsEqual(); eq[22][i].in[0] <== in[i]; - eq[22][i].in[1] <== 56; + eq[22][i].in[1] <== 55; eq[23][i] = IsEqual(); eq[23][i].in[0] <== in[i]; - eq[23][i].in[1] <== 57; + eq[23][i].in[1] <== 56; eq[24][i] = IsEqual(); eq[24][i].in[0] <== in[i]; - eq[24][i].in[1] <== 61; + eq[24][i].in[1] <== 57; eq[25][i] = IsEqual(); eq[25][i].in[0] <== in[i]; - eq[25][i].in[1] <== 95; + eq[25][i].in[1] <== 61; + eq[26][i] = IsEqual(); + eq[26][i].in[0] <== in[i]; + eq[26][i].in[1] <== 95; and[17][i] = AND(); and[17][i].a <== states[i][14]; multi_or[0][i] = MultiOR(17); multi_or[0][i].in[0] <== and[15][i].out; multi_or[0][i].in[1] <== and[16][i].out; - multi_or[0][i].in[2] <== eq[12][i].out; - multi_or[0][i].in[3] <== eq[7][i].out; - multi_or[0][i].in[4] <== eq[13][i].out; - multi_or[0][i].in[5] <== eq[14][i].out; - multi_or[0][i].in[6] <== eq[15][i].out; - multi_or[0][i].in[7] <== eq[16][i].out; - multi_or[0][i].in[8] <== eq[17][i].out; - multi_or[0][i].in[9] <== eq[18][i].out; - multi_or[0][i].in[10] <== eq[19][i].out; - multi_or[0][i].in[11] <== eq[20][i].out; - multi_or[0][i].in[12] <== eq[21][i].out; - multi_or[0][i].in[13] <== eq[22][i].out; - multi_or[0][i].in[14] <== eq[23][i].out; - multi_or[0][i].in[15] <== eq[24][i].out; - multi_or[0][i].in[16] <== eq[25][i].out; + multi_or[0][i].in[2] <== eq[13][i].out; + multi_or[0][i].in[3] <== eq[8][i].out; + multi_or[0][i].in[4] <== eq[14][i].out; + multi_or[0][i].in[5] <== eq[15][i].out; + multi_or[0][i].in[6] <== eq[16][i].out; + multi_or[0][i].in[7] <== eq[17][i].out; + multi_or[0][i].in[8] <== eq[18][i].out; + multi_or[0][i].in[9] <== eq[19][i].out; + multi_or[0][i].in[10] <== eq[20][i].out; + multi_or[0][i].in[11] <== eq[21][i].out; + multi_or[0][i].in[12] <== eq[22][i].out; + multi_or[0][i].in[13] <== eq[23][i].out; + multi_or[0][i].in[14] <== eq[24][i].out; + multi_or[0][i].in[15] <== eq[25][i].out; + multi_or[0][i].in[16] <== eq[26][i].out; and[17][i].b <== multi_or[0][i].out; and[18][i] = AND(); and[18][i].a <== states[i][15]; @@ -214,24 +217,24 @@ template MessageIdRegex(msg_bytes) { multi_or[1][i].in[0] <== and[17][i].out; multi_or[1][i].in[1] <== and[18][i].out; states[i+1][15] <== multi_or[1][i].out; - eq[26][i] = IsEqual(); - eq[26][i].in[0] <== in[i]; - eq[26][i].in[1] <== 62; + eq[27][i] = IsEqual(); + eq[27][i].in[0] <== in[i]; + eq[27][i].in[1] <== 62; and[19][i] = AND(); and[19][i].a <== states[i][15]; - and[19][i].b <== eq[26][i].out; + and[19][i].b <== eq[27][i].out; states[i+1][16] <== and[19][i].out; and[20][i] = AND(); and[20][i].a <== states[i][16]; - and[20][i].b <== eq[1][i].out; + and[20][i].b <== eq[0][i].out; states[i+1][17] <== and[20][i].out; and[21][i] = AND(); and[21][i].a <== states[i][17]; - and[21][i].b <== eq[3][i].out; + and[21][i].b <== eq[2][i].out; states[i+1][18] <== and[21][i].out; from_zero_enabled[i] <== MultiNOR(18)([states_tmp[i+1][1], states_tmp[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7], states[i+1][8], states[i+1][9], states[i+1][10], states[i+1][11], states[i+1][12], states[i+1][13], states[i+1][14], states[i+1][15], states[i+1][16], states[i+1][17], states[i+1][18]]); states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); - states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[2][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[1][i].out]); state_changed[i].in[0] <== states[i+1][1]; state_changed[i].in[1] <== states[i+1][2]; state_changed[i].in[2] <== states[i+1][3]; @@ -252,26 +255,31 @@ template MessageIdRegex(msg_bytes) { state_changed[i].in[17] <== states[i+1][18]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][18]; + is_accepted.in[i] <== states[i][18]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][18] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][18], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(13, 14), (14, 15), (15, 15), (15, 16)}] + signal prev_states0[4][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(13, 14), (14, 15), (15, 15), (15, 16)] - is_substr0[i] <== MultiOR(4)([states[i+1][13] * states[i+2][14], states[i+1][14] * states[i+2][15], states[i+1][15] * states[i+2][15], states[i+1][15] * states[i+2][16]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][13]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][14]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][15]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][15]; + is_substr0[i] <== MultiOR(4)([prev_states0[0][i] * states[i+2][14], prev_states0[1][i] * states[i+2][15], prev_states0[2][i] * states[i+2][15], prev_states0[3][i] * states[i+2][16]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } } \ No newline at end of file diff --git a/packages/circom/circuits/common/subject_all.json b/packages/circom/circuits/common/subject_all.json index ed7d761..9b54447 100644 --- a/packages/circom/circuits/common/subject_all.json +++ b/packages/circom/circuits/common/subject_all.json @@ -2,7 +2,7 @@ "parts": [ { "is_public": false, - "regex_def": "((\r\n)|^)subject:" + "regex_def": "(\r\n|^)subject:" }, { "is_public": true, diff --git a/packages/circom/circuits/common/subject_all_regex.circom b/packages/circom/circuits/common/subject_all_regex.circom index be59bbc..e3d5b41 100644 --- a/packages/circom/circuits/common/subject_all_regex.circom +++ b/packages/circom/circuits/common/subject_all_regex.circom @@ -2,7 +2,7 @@ pragma circom 2.1.5; include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; -// regex: ((\r\n)|^)subject:[^\r\n]+\r\n +// regex: (\r\n|^)subject:[^\r\n]+\r\n template SubjectAllRegex(msg_bytes) { signal input msg[msg_bytes]; signal output out; @@ -33,76 +33,79 @@ template SubjectAllRegex(msg_bytes) { states[i][0] <== 1; eq[0][i] = IsEqual(); eq[0][i].in[0] <== in[i]; - eq[0][i].in[1] <== 115; + eq[0][i].in[1] <== 13; and[0][i] = AND(); and[0][i].a <== states[i][0]; and[0][i].b <== eq[0][i].out; - and[1][i] = AND(); - and[1][i].a <== states[i][4]; - and[1][i].b <== eq[0][i].out; - states_tmp[i+1][1] <== and[1][i].out; + states_tmp[i+1][1] <== 0; eq[1][i] = IsEqual(); eq[1][i].in[0] <== in[i]; - eq[1][i].in[1] <== 13; - and[2][i] = AND(); - and[2][i].a <== states[i][0]; - and[2][i].b <== eq[1][i].out; - states_tmp[i+1][2] <== 0; + eq[1][i].in[1] <== 255; + and[1][i] = AND(); + and[1][i].a <== states[i][0]; + and[1][i].b <== eq[1][i].out; eq[2][i] = IsEqual(); eq[2][i].in[0] <== in[i]; - eq[2][i].in[1] <== 117; - and[3][i] = AND(); - and[3][i].a <== states[i][1]; - and[3][i].b <== eq[2][i].out; - states[i+1][3] <== and[3][i].out; + eq[2][i].in[1] <== 10; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== eq[2][i].out; + states_tmp[i+1][2] <== and[2][i].out; eq[3][i] = IsEqual(); eq[3][i].in[0] <== in[i]; - eq[3][i].in[1] <== 10; - and[4][i] = AND(); - and[4][i].a <== states[i][2]; - and[4][i].b <== eq[3][i].out; - states[i+1][4] <== and[4][i].out; + eq[3][i].in[1] <== 115; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== eq[3][i].out; + states[i+1][3] <== and[3][i].out; eq[4][i] = IsEqual(); eq[4][i].in[0] <== in[i]; - eq[4][i].in[1] <== 98; - and[5][i] = AND(); - and[5][i].a <== states[i][3]; - and[5][i].b <== eq[4][i].out; - states[i+1][5] <== and[5][i].out; + eq[4][i].in[1] <== 117; + and[4][i] = AND(); + and[4][i].a <== states[i][3]; + and[4][i].b <== eq[4][i].out; + states[i+1][4] <== and[4][i].out; eq[5][i] = IsEqual(); eq[5][i].in[0] <== in[i]; - eq[5][i].in[1] <== 106; + eq[5][i].in[1] <== 98; + and[5][i] = AND(); + and[5][i].a <== states[i][4]; + and[5][i].b <== eq[5][i].out; + states[i+1][5] <== and[5][i].out; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 106; and[6][i] = AND(); and[6][i].a <== states[i][5]; - and[6][i].b <== eq[5][i].out; + and[6][i].b <== eq[6][i].out; states[i+1][6] <== and[6][i].out; - eq[6][i] = IsEqual(); - eq[6][i].in[0] <== in[i]; - eq[6][i].in[1] <== 101; + eq[7][i] = IsEqual(); + eq[7][i].in[0] <== in[i]; + eq[7][i].in[1] <== 101; and[7][i] = AND(); and[7][i].a <== states[i][6]; - and[7][i].b <== eq[6][i].out; + and[7][i].b <== eq[7][i].out; states[i+1][7] <== and[7][i].out; - eq[7][i] = IsEqual(); - eq[7][i].in[0] <== in[i]; - eq[7][i].in[1] <== 99; + eq[8][i] = IsEqual(); + eq[8][i].in[0] <== in[i]; + eq[8][i].in[1] <== 99; and[8][i] = AND(); and[8][i].a <== states[i][7]; - and[8][i].b <== eq[7][i].out; + and[8][i].b <== eq[8][i].out; states[i+1][8] <== and[8][i].out; - eq[8][i] = IsEqual(); - eq[8][i].in[0] <== in[i]; - eq[8][i].in[1] <== 116; + eq[9][i] = IsEqual(); + eq[9][i].in[0] <== in[i]; + eq[9][i].in[1] <== 116; and[9][i] = AND(); and[9][i].a <== states[i][8]; - and[9][i].b <== eq[8][i].out; + and[9][i].b <== eq[9][i].out; states[i+1][9] <== and[9][i].out; - eq[9][i] = IsEqual(); - eq[9][i].in[0] <== in[i]; - eq[9][i].in[1] <== 58; + eq[10][i] = IsEqual(); + eq[10][i].in[0] <== in[i]; + eq[10][i].in[1] <== 58; and[10][i] = AND(); and[10][i].a <== states[i][9]; - and[10][i].b <== eq[9][i].out; + and[10][i].b <== eq[10][i].out; states[i+1][10] <== and[10][i].out; lt[0][i] = LessEqThan(8); lt[0][i].in[0] <== 194; @@ -162,78 +165,78 @@ template SubjectAllRegex(msg_bytes) { multi_or[0][i].in[3] <== and[18][i].out; multi_or[0][i].in[4] <== and[19][i].out; states[i+1][11] <== multi_or[0][i].out; - eq[10][i] = IsEqual(); - eq[10][i].in[0] <== in[i]; - eq[10][i].in[1] <== 224; + eq[11][i] = IsEqual(); + eq[11][i].in[0] <== in[i]; + eq[11][i].in[1] <== 224; and[20][i] = AND(); and[20][i].a <== states[i][10]; - and[20][i].b <== eq[10][i].out; + and[20][i].b <== eq[11][i].out; and[21][i] = AND(); and[21][i].a <== states[i][18]; - and[21][i].b <== eq[10][i].out; + and[21][i].b <== eq[11][i].out; multi_or[1][i] = MultiOR(2); multi_or[1][i].in[0] <== and[20][i].out; multi_or[1][i].in[1] <== and[21][i].out; states[i+1][12] <== multi_or[1][i].out; - eq[11][i] = IsEqual(); - eq[11][i].in[0] <== in[i]; - eq[11][i].in[1] <== 225; eq[12][i] = IsEqual(); eq[12][i].in[0] <== in[i]; - eq[12][i].in[1] <== 226; + eq[12][i].in[1] <== 225; eq[13][i] = IsEqual(); eq[13][i].in[0] <== in[i]; - eq[13][i].in[1] <== 227; + eq[13][i].in[1] <== 226; eq[14][i] = IsEqual(); eq[14][i].in[0] <== in[i]; - eq[14][i].in[1] <== 228; + eq[14][i].in[1] <== 227; eq[15][i] = IsEqual(); eq[15][i].in[0] <== in[i]; - eq[15][i].in[1] <== 229; + eq[15][i].in[1] <== 228; eq[16][i] = IsEqual(); eq[16][i].in[0] <== in[i]; - eq[16][i].in[1] <== 230; + eq[16][i].in[1] <== 229; eq[17][i] = IsEqual(); eq[17][i].in[0] <== in[i]; - eq[17][i].in[1] <== 231; + eq[17][i].in[1] <== 230; eq[18][i] = IsEqual(); eq[18][i].in[0] <== in[i]; - eq[18][i].in[1] <== 232; + eq[18][i].in[1] <== 231; eq[19][i] = IsEqual(); eq[19][i].in[0] <== in[i]; - eq[19][i].in[1] <== 233; + eq[19][i].in[1] <== 232; eq[20][i] = IsEqual(); eq[20][i].in[0] <== in[i]; - eq[20][i].in[1] <== 234; + eq[20][i].in[1] <== 233; eq[21][i] = IsEqual(); eq[21][i].in[0] <== in[i]; - eq[21][i].in[1] <== 235; + eq[21][i].in[1] <== 234; eq[22][i] = IsEqual(); eq[22][i].in[0] <== in[i]; - eq[22][i].in[1] <== 236; + eq[22][i].in[1] <== 235; eq[23][i] = IsEqual(); eq[23][i].in[0] <== in[i]; - eq[23][i].in[1] <== 238; + eq[23][i].in[1] <== 236; eq[24][i] = IsEqual(); eq[24][i].in[0] <== in[i]; - eq[24][i].in[1] <== 239; + eq[24][i].in[1] <== 238; + eq[25][i] = IsEqual(); + eq[25][i].in[0] <== in[i]; + eq[25][i].in[1] <== 239; and[22][i] = AND(); and[22][i].a <== states[i][10]; multi_or[2][i] = MultiOR(14); - multi_or[2][i].in[0] <== eq[11][i].out; - multi_or[2][i].in[1] <== eq[12][i].out; - multi_or[2][i].in[2] <== eq[13][i].out; - multi_or[2][i].in[3] <== eq[14][i].out; - multi_or[2][i].in[4] <== eq[15][i].out; - multi_or[2][i].in[5] <== eq[16][i].out; - multi_or[2][i].in[6] <== eq[17][i].out; - multi_or[2][i].in[7] <== eq[18][i].out; - multi_or[2][i].in[8] <== eq[19][i].out; - multi_or[2][i].in[9] <== eq[20][i].out; - multi_or[2][i].in[10] <== eq[21][i].out; - multi_or[2][i].in[11] <== eq[22][i].out; - multi_or[2][i].in[12] <== eq[23][i].out; - multi_or[2][i].in[13] <== eq[24][i].out; + multi_or[2][i].in[0] <== eq[12][i].out; + multi_or[2][i].in[1] <== eq[13][i].out; + multi_or[2][i].in[2] <== eq[14][i].out; + multi_or[2][i].in[3] <== eq[15][i].out; + multi_or[2][i].in[4] <== eq[16][i].out; + multi_or[2][i].in[5] <== eq[17][i].out; + multi_or[2][i].in[6] <== eq[18][i].out; + multi_or[2][i].in[7] <== eq[19][i].out; + multi_or[2][i].in[8] <== eq[20][i].out; + multi_or[2][i].in[9] <== eq[21][i].out; + multi_or[2][i].in[10] <== eq[22][i].out; + multi_or[2][i].in[11] <== eq[23][i].out; + multi_or[2][i].in[12] <== eq[24][i].out; + multi_or[2][i].in[13] <== eq[25][i].out; and[22][i].b <== multi_or[2][i].out; lt[8][i] = LessEqThan(8); lt[8][i].in[0] <== 144; @@ -250,73 +253,73 @@ template SubjectAllRegex(msg_bytes) { and[25][i] = AND(); and[25][i].a <== states[i][16]; and[25][i].b <== and[15][i].out; - eq[25][i] = IsEqual(); - eq[25][i].in[0] <== in[i]; - eq[25][i].in[1] <== 128; eq[26][i] = IsEqual(); eq[26][i].in[0] <== in[i]; - eq[26][i].in[1] <== 129; + eq[26][i].in[1] <== 128; eq[27][i] = IsEqual(); eq[27][i].in[0] <== in[i]; - eq[27][i].in[1] <== 130; + eq[27][i].in[1] <== 129; eq[28][i] = IsEqual(); eq[28][i].in[0] <== in[i]; - eq[28][i].in[1] <== 131; + eq[28][i].in[1] <== 130; eq[29][i] = IsEqual(); eq[29][i].in[0] <== in[i]; - eq[29][i].in[1] <== 132; + eq[29][i].in[1] <== 131; eq[30][i] = IsEqual(); eq[30][i].in[0] <== in[i]; - eq[30][i].in[1] <== 133; + eq[30][i].in[1] <== 132; eq[31][i] = IsEqual(); eq[31][i].in[0] <== in[i]; - eq[31][i].in[1] <== 134; + eq[31][i].in[1] <== 133; eq[32][i] = IsEqual(); eq[32][i].in[0] <== in[i]; - eq[32][i].in[1] <== 135; + eq[32][i].in[1] <== 134; eq[33][i] = IsEqual(); eq[33][i].in[0] <== in[i]; - eq[33][i].in[1] <== 136; + eq[33][i].in[1] <== 135; eq[34][i] = IsEqual(); eq[34][i].in[0] <== in[i]; - eq[34][i].in[1] <== 137; + eq[34][i].in[1] <== 136; eq[35][i] = IsEqual(); eq[35][i].in[0] <== in[i]; - eq[35][i].in[1] <== 138; + eq[35][i].in[1] <== 137; eq[36][i] = IsEqual(); eq[36][i].in[0] <== in[i]; - eq[36][i].in[1] <== 139; + eq[36][i].in[1] <== 138; eq[37][i] = IsEqual(); eq[37][i].in[0] <== in[i]; - eq[37][i].in[1] <== 140; + eq[37][i].in[1] <== 139; eq[38][i] = IsEqual(); eq[38][i].in[0] <== in[i]; - eq[38][i].in[1] <== 141; + eq[38][i].in[1] <== 140; eq[39][i] = IsEqual(); eq[39][i].in[0] <== in[i]; - eq[39][i].in[1] <== 142; + eq[39][i].in[1] <== 141; eq[40][i] = IsEqual(); eq[40][i].in[0] <== in[i]; - eq[40][i].in[1] <== 143; + eq[40][i].in[1] <== 142; + eq[41][i] = IsEqual(); + eq[41][i].in[0] <== in[i]; + eq[41][i].in[1] <== 143; and[26][i] = AND(); and[26][i].a <== states[i][17]; multi_or[3][i] = MultiOR(16); - multi_or[3][i].in[0] <== eq[25][i].out; - multi_or[3][i].in[1] <== eq[26][i].out; - multi_or[3][i].in[2] <== eq[27][i].out; - multi_or[3][i].in[3] <== eq[28][i].out; - multi_or[3][i].in[4] <== eq[29][i].out; - multi_or[3][i].in[5] <== eq[30][i].out; - multi_or[3][i].in[6] <== eq[31][i].out; - multi_or[3][i].in[7] <== eq[32][i].out; - multi_or[3][i].in[8] <== eq[33][i].out; - multi_or[3][i].in[9] <== eq[34][i].out; - multi_or[3][i].in[10] <== eq[35][i].out; - multi_or[3][i].in[11] <== eq[36][i].out; - multi_or[3][i].in[12] <== eq[37][i].out; - multi_or[3][i].in[13] <== eq[38][i].out; - multi_or[3][i].in[14] <== eq[39][i].out; - multi_or[3][i].in[15] <== eq[40][i].out; + multi_or[3][i].in[0] <== eq[26][i].out; + multi_or[3][i].in[1] <== eq[27][i].out; + multi_or[3][i].in[2] <== eq[28][i].out; + multi_or[3][i].in[3] <== eq[29][i].out; + multi_or[3][i].in[4] <== eq[30][i].out; + multi_or[3][i].in[5] <== eq[31][i].out; + multi_or[3][i].in[6] <== eq[32][i].out; + multi_or[3][i].in[7] <== eq[33][i].out; + multi_or[3][i].in[8] <== eq[34][i].out; + multi_or[3][i].in[9] <== eq[35][i].out; + multi_or[3][i].in[10] <== eq[36][i].out; + multi_or[3][i].in[11] <== eq[37][i].out; + multi_or[3][i].in[12] <== eq[38][i].out; + multi_or[3][i].in[13] <== eq[39][i].out; + multi_or[3][i].in[14] <== eq[40][i].out; + multi_or[3][i].in[15] <== eq[41][i].out; and[26][i].b <== multi_or[3][i].out; and[27][i] = AND(); and[27][i].a <== states[i][18]; @@ -328,47 +331,47 @@ template SubjectAllRegex(msg_bytes) { multi_or[4][i].in[3] <== and[26][i].out; multi_or[4][i].in[4] <== and[27][i].out; states[i+1][13] <== multi_or[4][i].out; - eq[41][i] = IsEqual(); - eq[41][i].in[0] <== in[i]; - eq[41][i].in[1] <== 237; + eq[42][i] = IsEqual(); + eq[42][i].in[0] <== in[i]; + eq[42][i].in[1] <== 237; and[28][i] = AND(); and[28][i].a <== states[i][10]; - and[28][i].b <== eq[41][i].out; + and[28][i].b <== eq[42][i].out; and[29][i] = AND(); and[29][i].a <== states[i][18]; - and[29][i].b <== eq[41][i].out; + and[29][i].b <== eq[42][i].out; multi_or[5][i] = MultiOR(2); multi_or[5][i].in[0] <== and[28][i].out; multi_or[5][i].in[1] <== and[29][i].out; states[i+1][14] <== multi_or[5][i].out; - eq[42][i] = IsEqual(); - eq[42][i].in[0] <== in[i]; - eq[42][i].in[1] <== 240; + eq[43][i] = IsEqual(); + eq[43][i].in[0] <== in[i]; + eq[43][i].in[1] <== 240; and[30][i] = AND(); and[30][i].a <== states[i][10]; - and[30][i].b <== eq[42][i].out; + and[30][i].b <== eq[43][i].out; and[31][i] = AND(); and[31][i].a <== states[i][18]; - and[31][i].b <== eq[42][i].out; + and[31][i].b <== eq[43][i].out; multi_or[6][i] = MultiOR(2); multi_or[6][i].in[0] <== and[30][i].out; multi_or[6][i].in[1] <== and[31][i].out; states[i+1][15] <== multi_or[6][i].out; - eq[43][i] = IsEqual(); - eq[43][i].in[0] <== in[i]; - eq[43][i].in[1] <== 241; eq[44][i] = IsEqual(); eq[44][i].in[0] <== in[i]; - eq[44][i].in[1] <== 242; + eq[44][i].in[1] <== 241; eq[45][i] = IsEqual(); eq[45][i].in[0] <== in[i]; - eq[45][i].in[1] <== 243; + eq[45][i].in[1] <== 242; + eq[46][i] = IsEqual(); + eq[46][i].in[0] <== in[i]; + eq[46][i].in[1] <== 243; and[32][i] = AND(); and[32][i].a <== states[i][10]; multi_or[7][i] = MultiOR(3); - multi_or[7][i].in[0] <== eq[43][i].out; - multi_or[7][i].in[1] <== eq[44][i].out; - multi_or[7][i].in[2] <== eq[45][i].out; + multi_or[7][i].in[0] <== eq[44][i].out; + multi_or[7][i].in[1] <== eq[45][i].out; + multi_or[7][i].in[2] <== eq[46][i].out; and[32][i].b <== multi_or[7][i].out; and[33][i] = AND(); and[33][i].a <== states[i][18]; @@ -377,15 +380,15 @@ template SubjectAllRegex(msg_bytes) { multi_or[8][i].in[0] <== and[32][i].out; multi_or[8][i].in[1] <== and[33][i].out; states[i+1][16] <== multi_or[8][i].out; - eq[46][i] = IsEqual(); - eq[46][i].in[0] <== in[i]; - eq[46][i].in[1] <== 244; + eq[47][i] = IsEqual(); + eq[47][i].in[0] <== in[i]; + eq[47][i].in[1] <== 244; and[34][i] = AND(); and[34][i].a <== states[i][10]; - and[34][i].b <== eq[46][i].out; + and[34][i].b <== eq[47][i].out; and[35][i] = AND(); and[35][i].a <== states[i][18]; - and[35][i].b <== eq[46][i].out; + and[35][i].b <== eq[47][i].out; multi_or[9][i] = MultiOR(2); multi_or[9][i].in[0] <== and[34][i].out; multi_or[9][i].in[1] <== and[35][i].out; @@ -399,9 +402,6 @@ template SubjectAllRegex(msg_bytes) { and[36][i] = AND(); and[36][i].a <== lt[10][i].out; and[36][i].b <== lt[11][i].out; - eq[47][i] = IsEqual(); - eq[47][i].in[0] <== in[i]; - eq[47][i].in[1] <== 0; eq[48][i] = IsEqual(); eq[48][i].in[0] <== in[i]; eq[48][i].in[1] <== 1; @@ -437,20 +437,19 @@ template SubjectAllRegex(msg_bytes) { eq[58][i].in[1] <== 12; and[37][i] = AND(); and[37][i].a <== states[i][10]; - multi_or[10][i] = MultiOR(13); + multi_or[10][i] = MultiOR(12); multi_or[10][i].in[0] <== and[36][i].out; - multi_or[10][i].in[1] <== eq[47][i].out; - multi_or[10][i].in[2] <== eq[48][i].out; - multi_or[10][i].in[3] <== eq[49][i].out; - multi_or[10][i].in[4] <== eq[50][i].out; - multi_or[10][i].in[5] <== eq[51][i].out; - multi_or[10][i].in[6] <== eq[52][i].out; - multi_or[10][i].in[7] <== eq[53][i].out; - multi_or[10][i].in[8] <== eq[54][i].out; - multi_or[10][i].in[9] <== eq[55][i].out; - multi_or[10][i].in[10] <== eq[56][i].out; - multi_or[10][i].in[11] <== eq[57][i].out; - multi_or[10][i].in[12] <== eq[58][i].out; + multi_or[10][i].in[1] <== eq[48][i].out; + multi_or[10][i].in[2] <== eq[49][i].out; + multi_or[10][i].in[3] <== eq[50][i].out; + multi_or[10][i].in[4] <== eq[51][i].out; + multi_or[10][i].in[5] <== eq[52][i].out; + multi_or[10][i].in[6] <== eq[53][i].out; + multi_or[10][i].in[7] <== eq[54][i].out; + multi_or[10][i].in[8] <== eq[55][i].out; + multi_or[10][i].in[9] <== eq[56][i].out; + multi_or[10][i].in[10] <== eq[57][i].out; + multi_or[10][i].in[11] <== eq[58][i].out; and[37][i].b <== multi_or[10][i].out; and[38][i] = AND(); and[38][i].a <== states[i][11]; @@ -465,15 +464,15 @@ template SubjectAllRegex(msg_bytes) { states[i+1][18] <== multi_or[11][i].out; and[40][i] = AND(); and[40][i].a <== states[i][18]; - and[40][i].b <== eq[1][i].out; + and[40][i].b <== eq[0][i].out; states[i+1][19] <== and[40][i].out; and[41][i] = AND(); and[41][i].a <== states[i][19]; - and[41][i].b <== eq[3][i].out; + and[41][i].b <== eq[2][i].out; states[i+1][20] <== and[41][i].out; from_zero_enabled[i] <== MultiNOR(20)([states_tmp[i+1][1], states_tmp[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7], states[i+1][8], states[i+1][9], states[i+1][10], states[i+1][11], states[i+1][12], states[i+1][13], states[i+1][14], states[i+1][15], states[i+1][16], states[i+1][17], states[i+1][18], states[i+1][19], states[i+1][20]]); states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); - states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[2][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[1][i].out]); state_changed[i].in[0] <== states[i+1][1]; state_changed[i].in[1] <== states[i+1][2]; state_changed[i].in[2] <== states[i+1][3]; @@ -496,26 +495,50 @@ template SubjectAllRegex(msg_bytes) { state_changed[i].in[19] <== states[i+1][20]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][20]; + is_accepted.in[i] <== states[i][20]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][20] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][20], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(10, 11), (10, 12), (10, 13), (10, 14), (10, 15), (10, 16), (10, 17), (10, 18), (11, 18), (12, 11), (13, 11), (14, 11), (15, 13), (16, 13), (17, 13), (18, 11), (18, 12), (18, 13), (18, 14), (18, 15), (18, 16), (18, 17), (18, 18)}] + signal prev_states0[23][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(10, 11), (10, 12), (10, 13), (10, 14), (10, 15), (10, 16), (10, 17), (10, 18), (11, 18), (12, 11), (13, 11), (14, 11), (15, 13), (16, 13), (17, 13), (18, 11), (18, 12), (18, 13), (18, 14), (18, 15), (18, 16), (18, 17), (18, 18)] - is_substr0[i] <== MultiOR(23)([states[i+1][10] * states[i+2][11], states[i+1][10] * states[i+2][12], states[i+1][10] * states[i+2][13], states[i+1][10] * states[i+2][14], states[i+1][10] * states[i+2][15], states[i+1][10] * states[i+2][16], states[i+1][10] * states[i+2][17], states[i+1][10] * states[i+2][18], states[i+1][11] * states[i+2][18], states[i+1][12] * states[i+2][11], states[i+1][13] * states[i+2][11], states[i+1][14] * states[i+2][11], states[i+1][15] * states[i+2][13], states[i+1][16] * states[i+2][13], states[i+1][17] * states[i+2][13], states[i+1][18] * states[i+2][11], states[i+1][18] * states[i+2][12], states[i+1][18] * states[i+2][13], states[i+1][18] * states[i+2][14], states[i+1][18] * states[i+2][15], states[i+1][18] * states[i+2][16], states[i+1][18] * states[i+2][17], states[i+1][18] * states[i+2][18]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[6][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[7][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][11]; + prev_states0[9][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][12]; + prev_states0[10][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][13]; + prev_states0[11][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][14]; + prev_states0[12][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][15]; + prev_states0[13][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][16]; + prev_states0[14][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][17]; + prev_states0[15][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][18]; + prev_states0[16][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][18]; + prev_states0[17][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][18]; + prev_states0[18][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][18]; + prev_states0[19][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][18]; + prev_states0[20][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][18]; + prev_states0[21][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][18]; + prev_states0[22][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][18]; + is_substr0[i] <== MultiOR(23)([prev_states0[0][i] * states[i+2][11], prev_states0[1][i] * states[i+2][12], prev_states0[2][i] * states[i+2][13], prev_states0[3][i] * states[i+2][14], prev_states0[4][i] * states[i+2][15], prev_states0[5][i] * states[i+2][16], prev_states0[6][i] * states[i+2][17], prev_states0[7][i] * states[i+2][18], prev_states0[8][i] * states[i+2][18], prev_states0[9][i] * states[i+2][11], prev_states0[10][i] * states[i+2][11], prev_states0[11][i] * states[i+2][11], prev_states0[12][i] * states[i+2][13], prev_states0[13][i] * states[i+2][13], prev_states0[14][i] * states[i+2][13], prev_states0[15][i] * states[i+2][11], prev_states0[16][i] * states[i+2][12], prev_states0[17][i] * states[i+2][13], prev_states0[18][i] * states[i+2][14], prev_states0[19][i] * states[i+2][15], prev_states0[20][i] * states[i+2][16], prev_states0[21][i] * states[i+2][17], prev_states0[22][i] * states[i+2][18]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } } \ No newline at end of file diff --git a/packages/circom/circuits/common/timestamp.json b/packages/circom/circuits/common/timestamp.json index 4e2895e..a3c945b 100644 --- a/packages/circom/circuits/common/timestamp.json +++ b/packages/circom/circuits/common/timestamp.json @@ -2,7 +2,7 @@ "parts": [ { "is_public": false, - "regex_def": "((\r\n)|^)dkim-signature:" + "regex_def": "(\r\n|^)dkim-signature:" }, { "is_public": false, diff --git a/packages/circom/circuits/common/timestamp_regex.circom b/packages/circom/circuits/common/timestamp_regex.circom index 0f745e3..d0f909a 100644 --- a/packages/circom/circuits/common/timestamp_regex.circom +++ b/packages/circom/circuits/common/timestamp_regex.circom @@ -2,7 +2,7 @@ pragma circom 2.1.5; include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; -// regex: ((\r\n)|^)dkim-signature:([a-z]+=[^;]+; )+t=[0-9]+; +// regex: (\r\n|^)dkim-signature:([a-z]+=[^;]+; )+t=[0-9]+; template TimestampRegex(msg_bytes) { signal input msg[msg_bytes]; signal output out; @@ -14,7 +14,7 @@ template TimestampRegex(msg_bytes) { in[i+1] <== msg[i]; } - component eq[71][num_bytes]; + component eq[72][num_bytes]; component lt[20][num_bytes]; component and[71][num_bytes]; component multi_or[17][num_bytes]; @@ -33,122 +33,125 @@ template TimestampRegex(msg_bytes) { states[i][0] <== 1; eq[0][i] = IsEqual(); eq[0][i].in[0] <== in[i]; - eq[0][i].in[1] <== 100; + eq[0][i].in[1] <== 13; and[0][i] = AND(); and[0][i].a <== states[i][0]; and[0][i].b <== eq[0][i].out; - and[1][i] = AND(); - and[1][i].a <== states[i][4]; - and[1][i].b <== eq[0][i].out; - states_tmp[i+1][1] <== and[1][i].out; + states_tmp[i+1][1] <== 0; eq[1][i] = IsEqual(); eq[1][i].in[0] <== in[i]; - eq[1][i].in[1] <== 13; - and[2][i] = AND(); - and[2][i].a <== states[i][0]; - and[2][i].b <== eq[1][i].out; - states_tmp[i+1][2] <== 0; + eq[1][i].in[1] <== 255; + and[1][i] = AND(); + and[1][i].a <== states[i][0]; + and[1][i].b <== eq[1][i].out; eq[2][i] = IsEqual(); eq[2][i].in[0] <== in[i]; - eq[2][i].in[1] <== 107; - and[3][i] = AND(); - and[3][i].a <== states[i][1]; - and[3][i].b <== eq[2][i].out; - states[i+1][3] <== and[3][i].out; + eq[2][i].in[1] <== 10; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== eq[2][i].out; + states_tmp[i+1][2] <== and[2][i].out; eq[3][i] = IsEqual(); eq[3][i].in[0] <== in[i]; - eq[3][i].in[1] <== 10; - and[4][i] = AND(); - and[4][i].a <== states[i][2]; - and[4][i].b <== eq[3][i].out; - states[i+1][4] <== and[4][i].out; + eq[3][i].in[1] <== 100; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== eq[3][i].out; + states[i+1][3] <== and[3][i].out; eq[4][i] = IsEqual(); eq[4][i].in[0] <== in[i]; - eq[4][i].in[1] <== 105; - and[5][i] = AND(); - and[5][i].a <== states[i][3]; - and[5][i].b <== eq[4][i].out; - states[i+1][5] <== and[5][i].out; + eq[4][i].in[1] <== 107; + and[4][i] = AND(); + and[4][i].a <== states[i][3]; + and[4][i].b <== eq[4][i].out; + states[i+1][4] <== and[4][i].out; eq[5][i] = IsEqual(); eq[5][i].in[0] <== in[i]; - eq[5][i].in[1] <== 109; + eq[5][i].in[1] <== 105; + and[5][i] = AND(); + and[5][i].a <== states[i][4]; + and[5][i].b <== eq[5][i].out; + states[i+1][5] <== and[5][i].out; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 109; and[6][i] = AND(); and[6][i].a <== states[i][5]; - and[6][i].b <== eq[5][i].out; + and[6][i].b <== eq[6][i].out; states[i+1][6] <== and[6][i].out; - eq[6][i] = IsEqual(); - eq[6][i].in[0] <== in[i]; - eq[6][i].in[1] <== 45; + eq[7][i] = IsEqual(); + eq[7][i].in[0] <== in[i]; + eq[7][i].in[1] <== 45; and[7][i] = AND(); and[7][i].a <== states[i][6]; - and[7][i].b <== eq[6][i].out; + and[7][i].b <== eq[7][i].out; states[i+1][7] <== and[7][i].out; - eq[7][i] = IsEqual(); - eq[7][i].in[0] <== in[i]; - eq[7][i].in[1] <== 115; + eq[8][i] = IsEqual(); + eq[8][i].in[0] <== in[i]; + eq[8][i].in[1] <== 115; and[8][i] = AND(); and[8][i].a <== states[i][7]; - and[8][i].b <== eq[7][i].out; + and[8][i].b <== eq[8][i].out; states[i+1][8] <== and[8][i].out; and[9][i] = AND(); and[9][i].a <== states[i][8]; - and[9][i].b <== eq[4][i].out; + and[9][i].b <== eq[5][i].out; states[i+1][9] <== and[9][i].out; - eq[8][i] = IsEqual(); - eq[8][i].in[0] <== in[i]; - eq[8][i].in[1] <== 103; + eq[9][i] = IsEqual(); + eq[9][i].in[0] <== in[i]; + eq[9][i].in[1] <== 103; and[10][i] = AND(); and[10][i].a <== states[i][9]; - and[10][i].b <== eq[8][i].out; + and[10][i].b <== eq[9][i].out; states[i+1][10] <== and[10][i].out; - eq[9][i] = IsEqual(); - eq[9][i].in[0] <== in[i]; - eq[9][i].in[1] <== 110; + eq[10][i] = IsEqual(); + eq[10][i].in[0] <== in[i]; + eq[10][i].in[1] <== 110; and[11][i] = AND(); and[11][i].a <== states[i][10]; - and[11][i].b <== eq[9][i].out; + and[11][i].b <== eq[10][i].out; states[i+1][11] <== and[11][i].out; - eq[10][i] = IsEqual(); - eq[10][i].in[0] <== in[i]; - eq[10][i].in[1] <== 97; + eq[11][i] = IsEqual(); + eq[11][i].in[0] <== in[i]; + eq[11][i].in[1] <== 97; and[12][i] = AND(); and[12][i].a <== states[i][11]; - and[12][i].b <== eq[10][i].out; + and[12][i].b <== eq[11][i].out; states[i+1][12] <== and[12][i].out; - eq[11][i] = IsEqual(); - eq[11][i].in[0] <== in[i]; - eq[11][i].in[1] <== 116; + eq[12][i] = IsEqual(); + eq[12][i].in[0] <== in[i]; + eq[12][i].in[1] <== 116; and[13][i] = AND(); and[13][i].a <== states[i][12]; - and[13][i].b <== eq[11][i].out; + and[13][i].b <== eq[12][i].out; states[i+1][13] <== and[13][i].out; - eq[12][i] = IsEqual(); - eq[12][i].in[0] <== in[i]; - eq[12][i].in[1] <== 117; + eq[13][i] = IsEqual(); + eq[13][i].in[0] <== in[i]; + eq[13][i].in[1] <== 117; and[14][i] = AND(); and[14][i].a <== states[i][13]; - and[14][i].b <== eq[12][i].out; + and[14][i].b <== eq[13][i].out; states[i+1][14] <== and[14][i].out; - eq[13][i] = IsEqual(); - eq[13][i].in[0] <== in[i]; - eq[13][i].in[1] <== 114; + eq[14][i] = IsEqual(); + eq[14][i].in[0] <== in[i]; + eq[14][i].in[1] <== 114; and[15][i] = AND(); and[15][i].a <== states[i][14]; - and[15][i].b <== eq[13][i].out; + and[15][i].b <== eq[14][i].out; states[i+1][15] <== and[15][i].out; - eq[14][i] = IsEqual(); - eq[14][i].in[0] <== in[i]; - eq[14][i].in[1] <== 101; + eq[15][i] = IsEqual(); + eq[15][i].in[0] <== in[i]; + eq[15][i].in[1] <== 101; and[16][i] = AND(); and[16][i].a <== states[i][15]; - and[16][i].b <== eq[14][i].out; + and[16][i].b <== eq[15][i].out; states[i+1][16] <== and[16][i].out; - eq[15][i] = IsEqual(); - eq[15][i].in[0] <== in[i]; - eq[15][i].in[1] <== 58; + eq[16][i] = IsEqual(); + eq[16][i].in[0] <== in[i]; + eq[16][i].in[1] <== 58; and[17][i] = AND(); and[17][i].a <== states[i][16]; - and[17][i].b <== eq[15][i].out; + and[17][i].b <== eq[16][i].out; states[i+1][17] <== and[17][i].out; lt[0][i] = LessEqThan(8); lt[0][i].in[0] <== 97; @@ -174,31 +177,31 @@ template TimestampRegex(msg_bytes) { and[21][i] = AND(); and[21][i].a <== lt[2][i].out; and[21][i].b <== lt[3][i].out; - eq[16][i] = IsEqual(); - eq[16][i].in[0] <== in[i]; - eq[16][i].in[1] <== 118; eq[17][i] = IsEqual(); eq[17][i].in[0] <== in[i]; - eq[17][i].in[1] <== 119; + eq[17][i].in[1] <== 118; eq[18][i] = IsEqual(); eq[18][i].in[0] <== in[i]; - eq[18][i].in[1] <== 120; + eq[18][i].in[1] <== 119; eq[19][i] = IsEqual(); eq[19][i].in[0] <== in[i]; - eq[19][i].in[1] <== 121; + eq[19][i].in[1] <== 120; eq[20][i] = IsEqual(); eq[20][i].in[0] <== in[i]; - eq[20][i].in[1] <== 122; + eq[20][i].in[1] <== 121; + eq[21][i] = IsEqual(); + eq[21][i].in[0] <== in[i]; + eq[21][i].in[1] <== 122; and[22][i] = AND(); and[22][i].a <== states[i][29]; multi_or[0][i] = MultiOR(7); multi_or[0][i].in[0] <== and[21][i].out; - multi_or[0][i].in[1] <== eq[12][i].out; - multi_or[0][i].in[2] <== eq[16][i].out; - multi_or[0][i].in[3] <== eq[17][i].out; - multi_or[0][i].in[4] <== eq[18][i].out; - multi_or[0][i].in[5] <== eq[19][i].out; - multi_or[0][i].in[6] <== eq[20][i].out; + multi_or[0][i].in[1] <== eq[13][i].out; + multi_or[0][i].in[2] <== eq[17][i].out; + multi_or[0][i].in[3] <== eq[18][i].out; + multi_or[0][i].in[4] <== eq[19][i].out; + multi_or[0][i].in[5] <== eq[20][i].out; + multi_or[0][i].in[6] <== eq[21][i].out; and[22][i].b <== multi_or[0][i].out; and[23][i] = AND(); and[23][i].a <== states[i][30]; @@ -209,15 +212,15 @@ template TimestampRegex(msg_bytes) { multi_or[1][i].in[2] <== and[22][i].out; multi_or[1][i].in[3] <== and[23][i].out; states[i+1][18] <== multi_or[1][i].out; - eq[21][i] = IsEqual(); - eq[21][i].in[0] <== in[i]; - eq[21][i].in[1] <== 61; + eq[22][i] = IsEqual(); + eq[22][i].in[0] <== in[i]; + eq[22][i].in[1] <== 61; and[24][i] = AND(); and[24][i].a <== states[i][18]; - and[24][i].b <== eq[21][i].out; + and[24][i].b <== eq[22][i].out; states[i+1][19] <== and[24][i].out; lt[4][i] = LessEqThan(8); - lt[4][i].in[0] <== 0; + lt[4][i].in[0] <== 1; lt[4][i].in[1] <== in[i]; lt[5][i] = LessEqThan(8); lt[5][i].in[0] <== in[i]; @@ -256,7 +259,7 @@ template TimestampRegex(msg_bytes) { and[30][i].a <== states[i][21]; and[30][i].b <== and[29][i].out; lt[10][i] = LessEqThan(8); - lt[10][i].in[0] <== 0; + lt[10][i].in[0] <== 1; lt[10][i].in[1] <== in[i]; lt[11][i] = LessEqThan(8); lt[11][i].in[0] <== in[i]; @@ -269,7 +272,7 @@ template TimestampRegex(msg_bytes) { multi_or[3][i] = MultiOR(3); multi_or[3][i].in[0] <== and[31][i].out; multi_or[3][i].in[1] <== and[26][i].out; - multi_or[3][i].in[2] <== eq[15][i].out; + multi_or[3][i].in[2] <== eq[16][i].out; and[32][i].b <== multi_or[3][i].out; multi_or[4][i] = MultiOR(4); multi_or[4][i].in[0] <== and[27][i].out; @@ -330,82 +333,82 @@ template TimestampRegex(msg_bytes) { multi_or[5][i].in[4] <== and[40][i].out; multi_or[5][i].in[5] <== and[41][i].out; states[i+1][21] <== multi_or[5][i].out; - eq[22][i] = IsEqual(); - eq[22][i].in[0] <== in[i]; - eq[22][i].in[1] <== 224; + eq[23][i] = IsEqual(); + eq[23][i].in[0] <== in[i]; + eq[23][i].in[1] <== 224; and[42][i] = AND(); and[42][i].a <== states[i][19]; - and[42][i].b <== eq[22][i].out; + and[42][i].b <== eq[23][i].out; and[43][i] = AND(); and[43][i].a <== states[i][20]; - and[43][i].b <== eq[22][i].out; + and[43][i].b <== eq[23][i].out; and[44][i] = AND(); and[44][i].a <== states[i][31]; - and[44][i].b <== eq[22][i].out; + and[44][i].b <== eq[23][i].out; multi_or[6][i] = MultiOR(3); multi_or[6][i].in[0] <== and[42][i].out; multi_or[6][i].in[1] <== and[43][i].out; multi_or[6][i].in[2] <== and[44][i].out; states[i+1][22] <== multi_or[6][i].out; - eq[23][i] = IsEqual(); - eq[23][i].in[0] <== in[i]; - eq[23][i].in[1] <== 225; eq[24][i] = IsEqual(); eq[24][i].in[0] <== in[i]; - eq[24][i].in[1] <== 226; + eq[24][i].in[1] <== 225; eq[25][i] = IsEqual(); eq[25][i].in[0] <== in[i]; - eq[25][i].in[1] <== 227; + eq[25][i].in[1] <== 226; eq[26][i] = IsEqual(); eq[26][i].in[0] <== in[i]; - eq[26][i].in[1] <== 228; + eq[26][i].in[1] <== 227; eq[27][i] = IsEqual(); eq[27][i].in[0] <== in[i]; - eq[27][i].in[1] <== 229; + eq[27][i].in[1] <== 228; eq[28][i] = IsEqual(); eq[28][i].in[0] <== in[i]; - eq[28][i].in[1] <== 230; + eq[28][i].in[1] <== 229; eq[29][i] = IsEqual(); eq[29][i].in[0] <== in[i]; - eq[29][i].in[1] <== 231; + eq[29][i].in[1] <== 230; eq[30][i] = IsEqual(); eq[30][i].in[0] <== in[i]; - eq[30][i].in[1] <== 232; + eq[30][i].in[1] <== 231; eq[31][i] = IsEqual(); eq[31][i].in[0] <== in[i]; - eq[31][i].in[1] <== 233; + eq[31][i].in[1] <== 232; eq[32][i] = IsEqual(); eq[32][i].in[0] <== in[i]; - eq[32][i].in[1] <== 234; + eq[32][i].in[1] <== 233; eq[33][i] = IsEqual(); eq[33][i].in[0] <== in[i]; - eq[33][i].in[1] <== 235; + eq[33][i].in[1] <== 234; eq[34][i] = IsEqual(); eq[34][i].in[0] <== in[i]; - eq[34][i].in[1] <== 236; + eq[34][i].in[1] <== 235; eq[35][i] = IsEqual(); eq[35][i].in[0] <== in[i]; - eq[35][i].in[1] <== 238; + eq[35][i].in[1] <== 236; eq[36][i] = IsEqual(); eq[36][i].in[0] <== in[i]; - eq[36][i].in[1] <== 239; + eq[36][i].in[1] <== 238; + eq[37][i] = IsEqual(); + eq[37][i].in[0] <== in[i]; + eq[37][i].in[1] <== 239; and[45][i] = AND(); and[45][i].a <== states[i][19]; multi_or[7][i] = MultiOR(14); - multi_or[7][i].in[0] <== eq[23][i].out; - multi_or[7][i].in[1] <== eq[24][i].out; - multi_or[7][i].in[2] <== eq[25][i].out; - multi_or[7][i].in[3] <== eq[26][i].out; - multi_or[7][i].in[4] <== eq[27][i].out; - multi_or[7][i].in[5] <== eq[28][i].out; - multi_or[7][i].in[6] <== eq[29][i].out; - multi_or[7][i].in[7] <== eq[30][i].out; - multi_or[7][i].in[8] <== eq[31][i].out; - multi_or[7][i].in[9] <== eq[32][i].out; - multi_or[7][i].in[10] <== eq[33][i].out; - multi_or[7][i].in[11] <== eq[34][i].out; - multi_or[7][i].in[12] <== eq[35][i].out; - multi_or[7][i].in[13] <== eq[36][i].out; + multi_or[7][i].in[0] <== eq[24][i].out; + multi_or[7][i].in[1] <== eq[25][i].out; + multi_or[7][i].in[2] <== eq[26][i].out; + multi_or[7][i].in[3] <== eq[27][i].out; + multi_or[7][i].in[4] <== eq[28][i].out; + multi_or[7][i].in[5] <== eq[29][i].out; + multi_or[7][i].in[6] <== eq[30][i].out; + multi_or[7][i].in[7] <== eq[31][i].out; + multi_or[7][i].in[8] <== eq[32][i].out; + multi_or[7][i].in[9] <== eq[33][i].out; + multi_or[7][i].in[10] <== eq[34][i].out; + multi_or[7][i].in[11] <== eq[35][i].out; + multi_or[7][i].in[12] <== eq[36][i].out; + multi_or[7][i].in[13] <== eq[37][i].out; and[45][i].b <== multi_or[7][i].out; and[46][i] = AND(); and[46][i].a <== states[i][20]; @@ -425,73 +428,73 @@ template TimestampRegex(msg_bytes) { and[49][i] = AND(); and[49][i].a <== states[i][26]; and[49][i].b <== and[29][i].out; - eq[37][i] = IsEqual(); - eq[37][i].in[0] <== in[i]; - eq[37][i].in[1] <== 128; eq[38][i] = IsEqual(); eq[38][i].in[0] <== in[i]; - eq[38][i].in[1] <== 129; + eq[38][i].in[1] <== 128; eq[39][i] = IsEqual(); eq[39][i].in[0] <== in[i]; - eq[39][i].in[1] <== 130; + eq[39][i].in[1] <== 129; eq[40][i] = IsEqual(); eq[40][i].in[0] <== in[i]; - eq[40][i].in[1] <== 131; + eq[40][i].in[1] <== 130; eq[41][i] = IsEqual(); eq[41][i].in[0] <== in[i]; - eq[41][i].in[1] <== 132; + eq[41][i].in[1] <== 131; eq[42][i] = IsEqual(); eq[42][i].in[0] <== in[i]; - eq[42][i].in[1] <== 133; + eq[42][i].in[1] <== 132; eq[43][i] = IsEqual(); eq[43][i].in[0] <== in[i]; - eq[43][i].in[1] <== 134; + eq[43][i].in[1] <== 133; eq[44][i] = IsEqual(); eq[44][i].in[0] <== in[i]; - eq[44][i].in[1] <== 135; + eq[44][i].in[1] <== 134; eq[45][i] = IsEqual(); eq[45][i].in[0] <== in[i]; - eq[45][i].in[1] <== 136; + eq[45][i].in[1] <== 135; eq[46][i] = IsEqual(); eq[46][i].in[0] <== in[i]; - eq[46][i].in[1] <== 137; + eq[46][i].in[1] <== 136; eq[47][i] = IsEqual(); eq[47][i].in[0] <== in[i]; - eq[47][i].in[1] <== 138; + eq[47][i].in[1] <== 137; eq[48][i] = IsEqual(); eq[48][i].in[0] <== in[i]; - eq[48][i].in[1] <== 139; + eq[48][i].in[1] <== 138; eq[49][i] = IsEqual(); eq[49][i].in[0] <== in[i]; - eq[49][i].in[1] <== 140; + eq[49][i].in[1] <== 139; eq[50][i] = IsEqual(); eq[50][i].in[0] <== in[i]; - eq[50][i].in[1] <== 141; + eq[50][i].in[1] <== 140; eq[51][i] = IsEqual(); eq[51][i].in[0] <== in[i]; - eq[51][i].in[1] <== 142; + eq[51][i].in[1] <== 141; eq[52][i] = IsEqual(); eq[52][i].in[0] <== in[i]; - eq[52][i].in[1] <== 143; + eq[52][i].in[1] <== 142; + eq[53][i] = IsEqual(); + eq[53][i].in[0] <== in[i]; + eq[53][i].in[1] <== 143; and[50][i] = AND(); and[50][i].a <== states[i][27]; multi_or[8][i] = MultiOR(16); - multi_or[8][i].in[0] <== eq[37][i].out; - multi_or[8][i].in[1] <== eq[38][i].out; - multi_or[8][i].in[2] <== eq[39][i].out; - multi_or[8][i].in[3] <== eq[40][i].out; - multi_or[8][i].in[4] <== eq[41][i].out; - multi_or[8][i].in[5] <== eq[42][i].out; - multi_or[8][i].in[6] <== eq[43][i].out; - multi_or[8][i].in[7] <== eq[44][i].out; - multi_or[8][i].in[8] <== eq[45][i].out; - multi_or[8][i].in[9] <== eq[46][i].out; - multi_or[8][i].in[10] <== eq[47][i].out; - multi_or[8][i].in[11] <== eq[48][i].out; - multi_or[8][i].in[12] <== eq[49][i].out; - multi_or[8][i].in[13] <== eq[50][i].out; - multi_or[8][i].in[14] <== eq[51][i].out; - multi_or[8][i].in[15] <== eq[52][i].out; + multi_or[8][i].in[0] <== eq[38][i].out; + multi_or[8][i].in[1] <== eq[39][i].out; + multi_or[8][i].in[2] <== eq[40][i].out; + multi_or[8][i].in[3] <== eq[41][i].out; + multi_or[8][i].in[4] <== eq[42][i].out; + multi_or[8][i].in[5] <== eq[43][i].out; + multi_or[8][i].in[6] <== eq[44][i].out; + multi_or[8][i].in[7] <== eq[45][i].out; + multi_or[8][i].in[8] <== eq[46][i].out; + multi_or[8][i].in[9] <== eq[47][i].out; + multi_or[8][i].in[10] <== eq[48][i].out; + multi_or[8][i].in[11] <== eq[49][i].out; + multi_or[8][i].in[12] <== eq[50][i].out; + multi_or[8][i].in[13] <== eq[51][i].out; + multi_or[8][i].in[14] <== eq[52][i].out; + multi_or[8][i].in[15] <== eq[53][i].out; and[50][i].b <== multi_or[8][i].out; and[51][i] = AND(); and[51][i].a <== states[i][31]; @@ -504,55 +507,55 @@ template TimestampRegex(msg_bytes) { multi_or[9][i].in[4] <== and[50][i].out; multi_or[9][i].in[5] <== and[51][i].out; states[i+1][23] <== multi_or[9][i].out; - eq[53][i] = IsEqual(); - eq[53][i].in[0] <== in[i]; - eq[53][i].in[1] <== 237; + eq[54][i] = IsEqual(); + eq[54][i].in[0] <== in[i]; + eq[54][i].in[1] <== 237; and[52][i] = AND(); and[52][i].a <== states[i][19]; - and[52][i].b <== eq[53][i].out; + and[52][i].b <== eq[54][i].out; and[53][i] = AND(); and[53][i].a <== states[i][20]; - and[53][i].b <== eq[53][i].out; + and[53][i].b <== eq[54][i].out; and[54][i] = AND(); and[54][i].a <== states[i][31]; - and[54][i].b <== eq[53][i].out; + and[54][i].b <== eq[54][i].out; multi_or[10][i] = MultiOR(3); multi_or[10][i].in[0] <== and[52][i].out; multi_or[10][i].in[1] <== and[53][i].out; multi_or[10][i].in[2] <== and[54][i].out; states[i+1][24] <== multi_or[10][i].out; - eq[54][i] = IsEqual(); - eq[54][i].in[0] <== in[i]; - eq[54][i].in[1] <== 240; + eq[55][i] = IsEqual(); + eq[55][i].in[0] <== in[i]; + eq[55][i].in[1] <== 240; and[55][i] = AND(); and[55][i].a <== states[i][19]; - and[55][i].b <== eq[54][i].out; + and[55][i].b <== eq[55][i].out; and[56][i] = AND(); and[56][i].a <== states[i][20]; - and[56][i].b <== eq[54][i].out; + and[56][i].b <== eq[55][i].out; and[57][i] = AND(); and[57][i].a <== states[i][31]; - and[57][i].b <== eq[54][i].out; + and[57][i].b <== eq[55][i].out; multi_or[11][i] = MultiOR(3); multi_or[11][i].in[0] <== and[55][i].out; multi_or[11][i].in[1] <== and[56][i].out; multi_or[11][i].in[2] <== and[57][i].out; states[i+1][25] <== multi_or[11][i].out; - eq[55][i] = IsEqual(); - eq[55][i].in[0] <== in[i]; - eq[55][i].in[1] <== 241; eq[56][i] = IsEqual(); eq[56][i].in[0] <== in[i]; - eq[56][i].in[1] <== 242; + eq[56][i].in[1] <== 241; eq[57][i] = IsEqual(); eq[57][i].in[0] <== in[i]; - eq[57][i].in[1] <== 243; + eq[57][i].in[1] <== 242; + eq[58][i] = IsEqual(); + eq[58][i].in[0] <== in[i]; + eq[58][i].in[1] <== 243; and[58][i] = AND(); and[58][i].a <== states[i][19]; multi_or[12][i] = MultiOR(3); - multi_or[12][i].in[0] <== eq[55][i].out; - multi_or[12][i].in[1] <== eq[56][i].out; - multi_or[12][i].in[2] <== eq[57][i].out; + multi_or[12][i].in[0] <== eq[56][i].out; + multi_or[12][i].in[1] <== eq[57][i].out; + multi_or[12][i].in[2] <== eq[58][i].out; and[58][i].b <== multi_or[12][i].out; and[59][i] = AND(); and[59][i].a <== states[i][20]; @@ -565,88 +568,88 @@ template TimestampRegex(msg_bytes) { multi_or[13][i].in[1] <== and[59][i].out; multi_or[13][i].in[2] <== and[60][i].out; states[i+1][26] <== multi_or[13][i].out; - eq[58][i] = IsEqual(); - eq[58][i].in[0] <== in[i]; - eq[58][i].in[1] <== 244; + eq[59][i] = IsEqual(); + eq[59][i].in[0] <== in[i]; + eq[59][i].in[1] <== 244; and[61][i] = AND(); and[61][i].a <== states[i][19]; - and[61][i].b <== eq[58][i].out; + and[61][i].b <== eq[59][i].out; and[62][i] = AND(); and[62][i].a <== states[i][20]; - and[62][i].b <== eq[58][i].out; + and[62][i].b <== eq[59][i].out; and[63][i] = AND(); and[63][i].a <== states[i][31]; - and[63][i].b <== eq[58][i].out; + and[63][i].b <== eq[59][i].out; multi_or[14][i] = MultiOR(3); multi_or[14][i].in[0] <== and[61][i].out; multi_or[14][i].in[1] <== and[62][i].out; multi_or[14][i].in[2] <== and[63][i].out; states[i+1][27] <== multi_or[14][i].out; - eq[59][i] = IsEqual(); - eq[59][i].in[0] <== in[i]; - eq[59][i].in[1] <== 59; + eq[60][i] = IsEqual(); + eq[60][i].in[0] <== in[i]; + eq[60][i].in[1] <== 59; and[64][i] = AND(); and[64][i].a <== states[i][20]; - and[64][i].b <== eq[59][i].out; + and[64][i].b <== eq[60][i].out; states[i+1][28] <== and[64][i].out; - eq[60][i] = IsEqual(); - eq[60][i].in[0] <== in[i]; - eq[60][i].in[1] <== 32; + eq[61][i] = IsEqual(); + eq[61][i].in[0] <== in[i]; + eq[61][i].in[1] <== 32; and[65][i] = AND(); and[65][i].a <== states[i][28]; - and[65][i].b <== eq[60][i].out; + and[65][i].b <== eq[61][i].out; states[i+1][29] <== and[65][i].out; and[66][i] = AND(); and[66][i].a <== states[i][29]; - and[66][i].b <== eq[11][i].out; + and[66][i].b <== eq[12][i].out; states[i+1][30] <== and[66][i].out; and[67][i] = AND(); and[67][i].a <== states[i][30]; - and[67][i].b <== eq[21][i].out; + and[67][i].b <== eq[22][i].out; states[i+1][31] <== and[67][i].out; - eq[61][i] = IsEqual(); - eq[61][i].in[0] <== in[i]; - eq[61][i].in[1] <== 48; eq[62][i] = IsEqual(); eq[62][i].in[0] <== in[i]; - eq[62][i].in[1] <== 49; + eq[62][i].in[1] <== 48; eq[63][i] = IsEqual(); eq[63][i].in[0] <== in[i]; - eq[63][i].in[1] <== 50; + eq[63][i].in[1] <== 49; eq[64][i] = IsEqual(); eq[64][i].in[0] <== in[i]; - eq[64][i].in[1] <== 51; + eq[64][i].in[1] <== 50; eq[65][i] = IsEqual(); eq[65][i].in[0] <== in[i]; - eq[65][i].in[1] <== 52; + eq[65][i].in[1] <== 51; eq[66][i] = IsEqual(); eq[66][i].in[0] <== in[i]; - eq[66][i].in[1] <== 53; + eq[66][i].in[1] <== 52; eq[67][i] = IsEqual(); eq[67][i].in[0] <== in[i]; - eq[67][i].in[1] <== 54; + eq[67][i].in[1] <== 53; eq[68][i] = IsEqual(); eq[68][i].in[0] <== in[i]; - eq[68][i].in[1] <== 55; + eq[68][i].in[1] <== 54; eq[69][i] = IsEqual(); eq[69][i].in[0] <== in[i]; - eq[69][i].in[1] <== 56; + eq[69][i].in[1] <== 55; eq[70][i] = IsEqual(); eq[70][i].in[0] <== in[i]; - eq[70][i].in[1] <== 57; + eq[70][i].in[1] <== 56; + eq[71][i] = IsEqual(); + eq[71][i].in[0] <== in[i]; + eq[71][i].in[1] <== 57; and[68][i] = AND(); and[68][i].a <== states[i][31]; multi_or[15][i] = MultiOR(10); - multi_or[15][i].in[0] <== eq[61][i].out; - multi_or[15][i].in[1] <== eq[62][i].out; - multi_or[15][i].in[2] <== eq[63][i].out; - multi_or[15][i].in[3] <== eq[64][i].out; - multi_or[15][i].in[4] <== eq[65][i].out; - multi_or[15][i].in[5] <== eq[66][i].out; - multi_or[15][i].in[6] <== eq[67][i].out; - multi_or[15][i].in[7] <== eq[68][i].out; - multi_or[15][i].in[8] <== eq[69][i].out; - multi_or[15][i].in[9] <== eq[70][i].out; + multi_or[15][i].in[0] <== eq[62][i].out; + multi_or[15][i].in[1] <== eq[63][i].out; + multi_or[15][i].in[2] <== eq[64][i].out; + multi_or[15][i].in[3] <== eq[65][i].out; + multi_or[15][i].in[4] <== eq[66][i].out; + multi_or[15][i].in[5] <== eq[67][i].out; + multi_or[15][i].in[6] <== eq[68][i].out; + multi_or[15][i].in[7] <== eq[69][i].out; + multi_or[15][i].in[8] <== eq[70][i].out; + multi_or[15][i].in[9] <== eq[71][i].out; and[68][i].b <== multi_or[15][i].out; and[69][i] = AND(); and[69][i].a <== states[i][32]; @@ -657,11 +660,11 @@ template TimestampRegex(msg_bytes) { states[i+1][32] <== multi_or[16][i].out; and[70][i] = AND(); and[70][i].a <== states[i][32]; - and[70][i].b <== eq[59][i].out; + and[70][i].b <== eq[60][i].out; states[i+1][33] <== and[70][i].out; from_zero_enabled[i] <== MultiNOR(33)([states_tmp[i+1][1], states_tmp[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7], states[i+1][8], states[i+1][9], states[i+1][10], states[i+1][11], states[i+1][12], states[i+1][13], states[i+1][14], states[i+1][15], states[i+1][16], states[i+1][17], states[i+1][18], states[i+1][19], states[i+1][20], states[i+1][21], states[i+1][22], states[i+1][23], states[i+1][24], states[i+1][25], states[i+1][26], states[i+1][27], states[i+1][28], states[i+1][29], states[i+1][30], states[i+1][31], states[i+1][32], states[i+1][33]]); states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); - states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[2][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[1][i].out]); state_changed[i].in[0] <== states[i+1][1]; state_changed[i].in[1] <== states[i+1][2]; state_changed[i].in[2] <== states[i+1][3]; @@ -697,26 +700,29 @@ template TimestampRegex(msg_bytes) { state_changed[i].in[32] <== states[i+1][33]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][33]; + is_accepted.in[i] <== states[i][33]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][33] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][33], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(31, 32), (32, 32)}] + signal prev_states0[2][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(31, 32), (32, 32)] - is_substr0[i] <== MultiOR(2)([states[i+1][31] * states[i+2][32], states[i+1][32] * states[i+2][32]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][31]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][32]; + is_substr0[i] <== MultiOR(2)([prev_states0[0][i] * states[i+2][32], prev_states0[1][i] * states[i+2][32]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } } \ No newline at end of file diff --git a/packages/circom/circuits/common/to_addr.json b/packages/circom/circuits/common/to_addr.json index 43384d7..a41aca3 100644 --- a/packages/circom/circuits/common/to_addr.json +++ b/packages/circom/circuits/common/to_addr.json @@ -2,7 +2,7 @@ "parts": [ { "is_public": false, - "regex_def": "((\r\n)|^)to:" + "regex_def": "(\r\n|^)to:" }, { "is_public": false, @@ -10,7 +10,7 @@ }, { "is_public": true, - "regex_def": "[a-zA-Z0-9!#$%&'\\*\\+-/=\\?^_`{\\|}~\\.]+@[a-zA-Z0-9_\\.-]+" + "regex_def": "[a-zA-Z0-9!#$%&'\\*\\+-/=\\?\\^_`{\\|}~\\.]+@[a-zA-Z0-9_\\.-]+" }, { "is_public": false, diff --git a/packages/circom/circuits/common/to_all.json b/packages/circom/circuits/common/to_all.json index f601fbd..76be9fd 100644 --- a/packages/circom/circuits/common/to_all.json +++ b/packages/circom/circuits/common/to_all.json @@ -2,7 +2,7 @@ "parts": [ { "is_public": false, - "regex_def": "((\r\n)|^)to:" + "regex_def": "(\r\n|^)to:" }, { "is_public": true, diff --git a/packages/circom/circuits/common/to_all_regex.circom b/packages/circom/circuits/common/to_all_regex.circom index 2c638a7..456b6dc 100644 --- a/packages/circom/circuits/common/to_all_regex.circom +++ b/packages/circom/circuits/common/to_all_regex.circom @@ -2,7 +2,7 @@ pragma circom 2.1.5; include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; -// regex: ((\r\n)|^)to:[^\r\n]+\r\n +// regex: (\r\n|^)to:[^\r\n]+\r\n template ToAllRegex(msg_bytes) { signal input msg[msg_bytes]; signal output out; @@ -33,41 +33,44 @@ template ToAllRegex(msg_bytes) { states[i][0] <== 1; eq[0][i] = IsEqual(); eq[0][i].in[0] <== in[i]; - eq[0][i].in[1] <== 116; + eq[0][i].in[1] <== 13; and[0][i] = AND(); and[0][i].a <== states[i][0]; and[0][i].b <== eq[0][i].out; - and[1][i] = AND(); - and[1][i].a <== states[i][4]; - and[1][i].b <== eq[0][i].out; - states_tmp[i+1][1] <== and[1][i].out; + states_tmp[i+1][1] <== 0; eq[1][i] = IsEqual(); eq[1][i].in[0] <== in[i]; - eq[1][i].in[1] <== 13; - and[2][i] = AND(); - and[2][i].a <== states[i][0]; - and[2][i].b <== eq[1][i].out; - states_tmp[i+1][2] <== 0; + eq[1][i].in[1] <== 255; + and[1][i] = AND(); + and[1][i].a <== states[i][0]; + and[1][i].b <== eq[1][i].out; eq[2][i] = IsEqual(); eq[2][i].in[0] <== in[i]; - eq[2][i].in[1] <== 111; - and[3][i] = AND(); - and[3][i].a <== states[i][1]; - and[3][i].b <== eq[2][i].out; - states[i+1][3] <== and[3][i].out; + eq[2][i].in[1] <== 10; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== eq[2][i].out; + states_tmp[i+1][2] <== and[2][i].out; eq[3][i] = IsEqual(); eq[3][i].in[0] <== in[i]; - eq[3][i].in[1] <== 10; - and[4][i] = AND(); - and[4][i].a <== states[i][2]; - and[4][i].b <== eq[3][i].out; - states[i+1][4] <== and[4][i].out; + eq[3][i].in[1] <== 116; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== eq[3][i].out; + states[i+1][3] <== and[3][i].out; eq[4][i] = IsEqual(); eq[4][i].in[0] <== in[i]; - eq[4][i].in[1] <== 58; + eq[4][i].in[1] <== 111; + and[4][i] = AND(); + and[4][i].a <== states[i][3]; + and[4][i].b <== eq[4][i].out; + states[i+1][4] <== and[4][i].out; + eq[5][i] = IsEqual(); + eq[5][i].in[0] <== in[i]; + eq[5][i].in[1] <== 58; and[5][i] = AND(); - and[5][i].a <== states[i][3]; - and[5][i].b <== eq[4][i].out; + and[5][i].a <== states[i][4]; + and[5][i].b <== eq[5][i].out; states[i+1][5] <== and[5][i].out; lt[0][i] = LessEqThan(8); lt[0][i].in[0] <== 194; @@ -127,78 +130,78 @@ template ToAllRegex(msg_bytes) { multi_or[0][i].in[3] <== and[13][i].out; multi_or[0][i].in[4] <== and[14][i].out; states[i+1][6] <== multi_or[0][i].out; - eq[5][i] = IsEqual(); - eq[5][i].in[0] <== in[i]; - eq[5][i].in[1] <== 224; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 224; and[15][i] = AND(); and[15][i].a <== states[i][5]; - and[15][i].b <== eq[5][i].out; + and[15][i].b <== eq[6][i].out; and[16][i] = AND(); and[16][i].a <== states[i][13]; - and[16][i].b <== eq[5][i].out; + and[16][i].b <== eq[6][i].out; multi_or[1][i] = MultiOR(2); multi_or[1][i].in[0] <== and[15][i].out; multi_or[1][i].in[1] <== and[16][i].out; states[i+1][7] <== multi_or[1][i].out; - eq[6][i] = IsEqual(); - eq[6][i].in[0] <== in[i]; - eq[6][i].in[1] <== 225; eq[7][i] = IsEqual(); eq[7][i].in[0] <== in[i]; - eq[7][i].in[1] <== 226; + eq[7][i].in[1] <== 225; eq[8][i] = IsEqual(); eq[8][i].in[0] <== in[i]; - eq[8][i].in[1] <== 227; + eq[8][i].in[1] <== 226; eq[9][i] = IsEqual(); eq[9][i].in[0] <== in[i]; - eq[9][i].in[1] <== 228; + eq[9][i].in[1] <== 227; eq[10][i] = IsEqual(); eq[10][i].in[0] <== in[i]; - eq[10][i].in[1] <== 229; + eq[10][i].in[1] <== 228; eq[11][i] = IsEqual(); eq[11][i].in[0] <== in[i]; - eq[11][i].in[1] <== 230; + eq[11][i].in[1] <== 229; eq[12][i] = IsEqual(); eq[12][i].in[0] <== in[i]; - eq[12][i].in[1] <== 231; + eq[12][i].in[1] <== 230; eq[13][i] = IsEqual(); eq[13][i].in[0] <== in[i]; - eq[13][i].in[1] <== 232; + eq[13][i].in[1] <== 231; eq[14][i] = IsEqual(); eq[14][i].in[0] <== in[i]; - eq[14][i].in[1] <== 233; + eq[14][i].in[1] <== 232; eq[15][i] = IsEqual(); eq[15][i].in[0] <== in[i]; - eq[15][i].in[1] <== 234; + eq[15][i].in[1] <== 233; eq[16][i] = IsEqual(); eq[16][i].in[0] <== in[i]; - eq[16][i].in[1] <== 235; + eq[16][i].in[1] <== 234; eq[17][i] = IsEqual(); eq[17][i].in[0] <== in[i]; - eq[17][i].in[1] <== 236; + eq[17][i].in[1] <== 235; eq[18][i] = IsEqual(); eq[18][i].in[0] <== in[i]; - eq[18][i].in[1] <== 238; + eq[18][i].in[1] <== 236; eq[19][i] = IsEqual(); eq[19][i].in[0] <== in[i]; - eq[19][i].in[1] <== 239; + eq[19][i].in[1] <== 238; + eq[20][i] = IsEqual(); + eq[20][i].in[0] <== in[i]; + eq[20][i].in[1] <== 239; and[17][i] = AND(); and[17][i].a <== states[i][5]; multi_or[2][i] = MultiOR(14); - multi_or[2][i].in[0] <== eq[6][i].out; - multi_or[2][i].in[1] <== eq[7][i].out; - multi_or[2][i].in[2] <== eq[8][i].out; - multi_or[2][i].in[3] <== eq[9][i].out; - multi_or[2][i].in[4] <== eq[10][i].out; - multi_or[2][i].in[5] <== eq[11][i].out; - multi_or[2][i].in[6] <== eq[12][i].out; - multi_or[2][i].in[7] <== eq[13][i].out; - multi_or[2][i].in[8] <== eq[14][i].out; - multi_or[2][i].in[9] <== eq[15][i].out; - multi_or[2][i].in[10] <== eq[16][i].out; - multi_or[2][i].in[11] <== eq[17][i].out; - multi_or[2][i].in[12] <== eq[18][i].out; - multi_or[2][i].in[13] <== eq[19][i].out; + multi_or[2][i].in[0] <== eq[7][i].out; + multi_or[2][i].in[1] <== eq[8][i].out; + multi_or[2][i].in[2] <== eq[9][i].out; + multi_or[2][i].in[3] <== eq[10][i].out; + multi_or[2][i].in[4] <== eq[11][i].out; + multi_or[2][i].in[5] <== eq[12][i].out; + multi_or[2][i].in[6] <== eq[13][i].out; + multi_or[2][i].in[7] <== eq[14][i].out; + multi_or[2][i].in[8] <== eq[15][i].out; + multi_or[2][i].in[9] <== eq[16][i].out; + multi_or[2][i].in[10] <== eq[17][i].out; + multi_or[2][i].in[11] <== eq[18][i].out; + multi_or[2][i].in[12] <== eq[19][i].out; + multi_or[2][i].in[13] <== eq[20][i].out; and[17][i].b <== multi_or[2][i].out; lt[8][i] = LessEqThan(8); lt[8][i].in[0] <== 144; @@ -215,73 +218,73 @@ template ToAllRegex(msg_bytes) { and[20][i] = AND(); and[20][i].a <== states[i][11]; and[20][i].b <== and[10][i].out; - eq[20][i] = IsEqual(); - eq[20][i].in[0] <== in[i]; - eq[20][i].in[1] <== 128; eq[21][i] = IsEqual(); eq[21][i].in[0] <== in[i]; - eq[21][i].in[1] <== 129; + eq[21][i].in[1] <== 128; eq[22][i] = IsEqual(); eq[22][i].in[0] <== in[i]; - eq[22][i].in[1] <== 130; + eq[22][i].in[1] <== 129; eq[23][i] = IsEqual(); eq[23][i].in[0] <== in[i]; - eq[23][i].in[1] <== 131; + eq[23][i].in[1] <== 130; eq[24][i] = IsEqual(); eq[24][i].in[0] <== in[i]; - eq[24][i].in[1] <== 132; + eq[24][i].in[1] <== 131; eq[25][i] = IsEqual(); eq[25][i].in[0] <== in[i]; - eq[25][i].in[1] <== 133; + eq[25][i].in[1] <== 132; eq[26][i] = IsEqual(); eq[26][i].in[0] <== in[i]; - eq[26][i].in[1] <== 134; + eq[26][i].in[1] <== 133; eq[27][i] = IsEqual(); eq[27][i].in[0] <== in[i]; - eq[27][i].in[1] <== 135; + eq[27][i].in[1] <== 134; eq[28][i] = IsEqual(); eq[28][i].in[0] <== in[i]; - eq[28][i].in[1] <== 136; + eq[28][i].in[1] <== 135; eq[29][i] = IsEqual(); eq[29][i].in[0] <== in[i]; - eq[29][i].in[1] <== 137; + eq[29][i].in[1] <== 136; eq[30][i] = IsEqual(); eq[30][i].in[0] <== in[i]; - eq[30][i].in[1] <== 138; + eq[30][i].in[1] <== 137; eq[31][i] = IsEqual(); eq[31][i].in[0] <== in[i]; - eq[31][i].in[1] <== 139; + eq[31][i].in[1] <== 138; eq[32][i] = IsEqual(); eq[32][i].in[0] <== in[i]; - eq[32][i].in[1] <== 140; + eq[32][i].in[1] <== 139; eq[33][i] = IsEqual(); eq[33][i].in[0] <== in[i]; - eq[33][i].in[1] <== 141; + eq[33][i].in[1] <== 140; eq[34][i] = IsEqual(); eq[34][i].in[0] <== in[i]; - eq[34][i].in[1] <== 142; + eq[34][i].in[1] <== 141; eq[35][i] = IsEqual(); eq[35][i].in[0] <== in[i]; - eq[35][i].in[1] <== 143; + eq[35][i].in[1] <== 142; + eq[36][i] = IsEqual(); + eq[36][i].in[0] <== in[i]; + eq[36][i].in[1] <== 143; and[21][i] = AND(); and[21][i].a <== states[i][12]; multi_or[3][i] = MultiOR(16); - multi_or[3][i].in[0] <== eq[20][i].out; - multi_or[3][i].in[1] <== eq[21][i].out; - multi_or[3][i].in[2] <== eq[22][i].out; - multi_or[3][i].in[3] <== eq[23][i].out; - multi_or[3][i].in[4] <== eq[24][i].out; - multi_or[3][i].in[5] <== eq[25][i].out; - multi_or[3][i].in[6] <== eq[26][i].out; - multi_or[3][i].in[7] <== eq[27][i].out; - multi_or[3][i].in[8] <== eq[28][i].out; - multi_or[3][i].in[9] <== eq[29][i].out; - multi_or[3][i].in[10] <== eq[30][i].out; - multi_or[3][i].in[11] <== eq[31][i].out; - multi_or[3][i].in[12] <== eq[32][i].out; - multi_or[3][i].in[13] <== eq[33][i].out; - multi_or[3][i].in[14] <== eq[34][i].out; - multi_or[3][i].in[15] <== eq[35][i].out; + multi_or[3][i].in[0] <== eq[21][i].out; + multi_or[3][i].in[1] <== eq[22][i].out; + multi_or[3][i].in[2] <== eq[23][i].out; + multi_or[3][i].in[3] <== eq[24][i].out; + multi_or[3][i].in[4] <== eq[25][i].out; + multi_or[3][i].in[5] <== eq[26][i].out; + multi_or[3][i].in[6] <== eq[27][i].out; + multi_or[3][i].in[7] <== eq[28][i].out; + multi_or[3][i].in[8] <== eq[29][i].out; + multi_or[3][i].in[9] <== eq[30][i].out; + multi_or[3][i].in[10] <== eq[31][i].out; + multi_or[3][i].in[11] <== eq[32][i].out; + multi_or[3][i].in[12] <== eq[33][i].out; + multi_or[3][i].in[13] <== eq[34][i].out; + multi_or[3][i].in[14] <== eq[35][i].out; + multi_or[3][i].in[15] <== eq[36][i].out; and[21][i].b <== multi_or[3][i].out; and[22][i] = AND(); and[22][i].a <== states[i][13]; @@ -293,47 +296,47 @@ template ToAllRegex(msg_bytes) { multi_or[4][i].in[3] <== and[21][i].out; multi_or[4][i].in[4] <== and[22][i].out; states[i+1][8] <== multi_or[4][i].out; - eq[36][i] = IsEqual(); - eq[36][i].in[0] <== in[i]; - eq[36][i].in[1] <== 237; + eq[37][i] = IsEqual(); + eq[37][i].in[0] <== in[i]; + eq[37][i].in[1] <== 237; and[23][i] = AND(); and[23][i].a <== states[i][5]; - and[23][i].b <== eq[36][i].out; + and[23][i].b <== eq[37][i].out; and[24][i] = AND(); and[24][i].a <== states[i][13]; - and[24][i].b <== eq[36][i].out; + and[24][i].b <== eq[37][i].out; multi_or[5][i] = MultiOR(2); multi_or[5][i].in[0] <== and[23][i].out; multi_or[5][i].in[1] <== and[24][i].out; states[i+1][9] <== multi_or[5][i].out; - eq[37][i] = IsEqual(); - eq[37][i].in[0] <== in[i]; - eq[37][i].in[1] <== 240; + eq[38][i] = IsEqual(); + eq[38][i].in[0] <== in[i]; + eq[38][i].in[1] <== 240; and[25][i] = AND(); and[25][i].a <== states[i][5]; - and[25][i].b <== eq[37][i].out; + and[25][i].b <== eq[38][i].out; and[26][i] = AND(); and[26][i].a <== states[i][13]; - and[26][i].b <== eq[37][i].out; + and[26][i].b <== eq[38][i].out; multi_or[6][i] = MultiOR(2); multi_or[6][i].in[0] <== and[25][i].out; multi_or[6][i].in[1] <== and[26][i].out; states[i+1][10] <== multi_or[6][i].out; - eq[38][i] = IsEqual(); - eq[38][i].in[0] <== in[i]; - eq[38][i].in[1] <== 241; eq[39][i] = IsEqual(); eq[39][i].in[0] <== in[i]; - eq[39][i].in[1] <== 242; + eq[39][i].in[1] <== 241; eq[40][i] = IsEqual(); eq[40][i].in[0] <== in[i]; - eq[40][i].in[1] <== 243; + eq[40][i].in[1] <== 242; + eq[41][i] = IsEqual(); + eq[41][i].in[0] <== in[i]; + eq[41][i].in[1] <== 243; and[27][i] = AND(); and[27][i].a <== states[i][5]; multi_or[7][i] = MultiOR(3); - multi_or[7][i].in[0] <== eq[38][i].out; - multi_or[7][i].in[1] <== eq[39][i].out; - multi_or[7][i].in[2] <== eq[40][i].out; + multi_or[7][i].in[0] <== eq[39][i].out; + multi_or[7][i].in[1] <== eq[40][i].out; + multi_or[7][i].in[2] <== eq[41][i].out; and[27][i].b <== multi_or[7][i].out; and[28][i] = AND(); and[28][i].a <== states[i][13]; @@ -342,15 +345,15 @@ template ToAllRegex(msg_bytes) { multi_or[8][i].in[0] <== and[27][i].out; multi_or[8][i].in[1] <== and[28][i].out; states[i+1][11] <== multi_or[8][i].out; - eq[41][i] = IsEqual(); - eq[41][i].in[0] <== in[i]; - eq[41][i].in[1] <== 244; + eq[42][i] = IsEqual(); + eq[42][i].in[0] <== in[i]; + eq[42][i].in[1] <== 244; and[29][i] = AND(); and[29][i].a <== states[i][5]; - and[29][i].b <== eq[41][i].out; + and[29][i].b <== eq[42][i].out; and[30][i] = AND(); and[30][i].a <== states[i][13]; - and[30][i].b <== eq[41][i].out; + and[30][i].b <== eq[42][i].out; multi_or[9][i] = MultiOR(2); multi_or[9][i].in[0] <== and[29][i].out; multi_or[9][i].in[1] <== and[30][i].out; @@ -364,9 +367,6 @@ template ToAllRegex(msg_bytes) { and[31][i] = AND(); and[31][i].a <== lt[10][i].out; and[31][i].b <== lt[11][i].out; - eq[42][i] = IsEqual(); - eq[42][i].in[0] <== in[i]; - eq[42][i].in[1] <== 0; eq[43][i] = IsEqual(); eq[43][i].in[0] <== in[i]; eq[43][i].in[1] <== 1; @@ -402,20 +402,19 @@ template ToAllRegex(msg_bytes) { eq[53][i].in[1] <== 12; and[32][i] = AND(); and[32][i].a <== states[i][5]; - multi_or[10][i] = MultiOR(13); + multi_or[10][i] = MultiOR(12); multi_or[10][i].in[0] <== and[31][i].out; - multi_or[10][i].in[1] <== eq[42][i].out; - multi_or[10][i].in[2] <== eq[43][i].out; - multi_or[10][i].in[3] <== eq[44][i].out; - multi_or[10][i].in[4] <== eq[45][i].out; - multi_or[10][i].in[5] <== eq[46][i].out; - multi_or[10][i].in[6] <== eq[47][i].out; - multi_or[10][i].in[7] <== eq[48][i].out; - multi_or[10][i].in[8] <== eq[49][i].out; - multi_or[10][i].in[9] <== eq[50][i].out; - multi_or[10][i].in[10] <== eq[51][i].out; - multi_or[10][i].in[11] <== eq[52][i].out; - multi_or[10][i].in[12] <== eq[53][i].out; + multi_or[10][i].in[1] <== eq[43][i].out; + multi_or[10][i].in[2] <== eq[44][i].out; + multi_or[10][i].in[3] <== eq[45][i].out; + multi_or[10][i].in[4] <== eq[46][i].out; + multi_or[10][i].in[5] <== eq[47][i].out; + multi_or[10][i].in[6] <== eq[48][i].out; + multi_or[10][i].in[7] <== eq[49][i].out; + multi_or[10][i].in[8] <== eq[50][i].out; + multi_or[10][i].in[9] <== eq[51][i].out; + multi_or[10][i].in[10] <== eq[52][i].out; + multi_or[10][i].in[11] <== eq[53][i].out; and[32][i].b <== multi_or[10][i].out; and[33][i] = AND(); and[33][i].a <== states[i][6]; @@ -430,15 +429,15 @@ template ToAllRegex(msg_bytes) { states[i+1][13] <== multi_or[11][i].out; and[35][i] = AND(); and[35][i].a <== states[i][13]; - and[35][i].b <== eq[1][i].out; + and[35][i].b <== eq[0][i].out; states[i+1][14] <== and[35][i].out; and[36][i] = AND(); and[36][i].a <== states[i][14]; - and[36][i].b <== eq[3][i].out; + and[36][i].b <== eq[2][i].out; states[i+1][15] <== and[36][i].out; from_zero_enabled[i] <== MultiNOR(15)([states_tmp[i+1][1], states_tmp[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7], states[i+1][8], states[i+1][9], states[i+1][10], states[i+1][11], states[i+1][12], states[i+1][13], states[i+1][14], states[i+1][15]]); states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); - states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[2][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[1][i].out]); state_changed[i].in[0] <== states[i+1][1]; state_changed[i].in[1] <== states[i+1][2]; state_changed[i].in[2] <== states[i+1][3]; @@ -456,26 +455,50 @@ template ToAllRegex(msg_bytes) { state_changed[i].in[14] <== states[i+1][15]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][15]; + is_accepted.in[i] <== states[i][15]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][15] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][15], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (5, 11), (5, 12), (5, 13), (6, 13), (7, 6), (8, 6), (9, 6), (10, 8), (11, 8), (12, 8), (13, 6), (13, 7), (13, 8), (13, 9), (13, 10), (13, 11), (13, 12), (13, 13)}] + signal prev_states0[23][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (5, 11), (5, 12), (5, 13), (6, 13), (7, 6), (8, 6), (9, 6), (10, 8), (11, 8), (12, 8), (13, 6), (13, 7), (13, 8), (13, 9), (13, 10), (13, 11), (13, 12), (13, 13)] - is_substr0[i] <== MultiOR(23)([states[i+1][5] * states[i+2][6], states[i+1][5] * states[i+2][7], states[i+1][5] * states[i+2][8], states[i+1][5] * states[i+2][9], states[i+1][5] * states[i+2][10], states[i+1][5] * states[i+2][11], states[i+1][5] * states[i+2][12], states[i+1][5] * states[i+2][13], states[i+1][6] * states[i+2][13], states[i+1][7] * states[i+2][6], states[i+1][8] * states[i+2][6], states[i+1][9] * states[i+2][6], states[i+1][10] * states[i+2][8], states[i+1][11] * states[i+2][8], states[i+1][12] * states[i+2][8], states[i+1][13] * states[i+2][6], states[i+1][13] * states[i+2][7], states[i+1][13] * states[i+2][8], states[i+1][13] * states[i+2][9], states[i+1][13] * states[i+2][10], states[i+1][13] * states[i+2][11], states[i+1][13] * states[i+2][12], states[i+1][13] * states[i+2][13]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[6][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[7][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][6]; + prev_states0[9][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + prev_states0[10][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][8]; + prev_states0[11][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][9]; + prev_states0[12][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[13][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][11]; + prev_states0[14][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][12]; + prev_states0[15][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][13]; + prev_states0[16][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][13]; + prev_states0[17][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][13]; + prev_states0[18][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][13]; + prev_states0[19][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][13]; + prev_states0[20][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][13]; + prev_states0[21][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][13]; + prev_states0[22][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][13]; + is_substr0[i] <== MultiOR(23)([prev_states0[0][i] * states[i+2][6], prev_states0[1][i] * states[i+2][7], prev_states0[2][i] * states[i+2][8], prev_states0[3][i] * states[i+2][9], prev_states0[4][i] * states[i+2][10], prev_states0[5][i] * states[i+2][11], prev_states0[6][i] * states[i+2][12], prev_states0[7][i] * states[i+2][13], prev_states0[8][i] * states[i+2][13], prev_states0[9][i] * states[i+2][6], prev_states0[10][i] * states[i+2][6], prev_states0[11][i] * states[i+2][6], prev_states0[12][i] * states[i+2][8], prev_states0[13][i] * states[i+2][8], prev_states0[14][i] * states[i+2][8], prev_states0[15][i] * states[i+2][6], prev_states0[16][i] * states[i+2][7], prev_states0[17][i] * states[i+2][8], prev_states0[18][i] * states[i+2][9], prev_states0[19][i] * states[i+2][10], prev_states0[20][i] * states[i+2][11], prev_states0[21][i] * states[i+2][12], prev_states0[22][i] * states[i+2][13]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } } \ No newline at end of file diff --git a/packages/circom/circuits/regex_helpers.circom b/packages/circom/circuits/regex_helpers.circom index bbddfbd..c5a4eaa 100644 --- a/packages/circom/circuits/regex_helpers.circom +++ b/packages/circom/circuits/regex_helpers.circom @@ -54,10 +54,21 @@ template MultiNOR(n) { out <== 1 - or; } + + template ORAnd() { signal input in[3]; signal output out; signal or <== OR()(in[0], in[1]); out <== AND()(or, in[2]); +} + +template IsNotZeroAcc() { + signal input acc; + signal input in; + signal output out; + + signal is_zero <== IsZero()(in); + out <== acc + (1 - is_zero); } \ No newline at end of file diff --git a/packages/circom/email_addr_with_name_main.circom b/packages/circom/email_addr_with_name_main.circom new file mode 100644 index 0000000..c98d82e --- /dev/null +++ b/packages/circom/email_addr_with_name_main.circom @@ -0,0 +1,764 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: [^\r\n]+<[a-zA-Z0-9!#$%&'*+-/=?^_`{\|}~\.]+@[a-zA-Z0-9_\.-]+> +template EmailAddrWithNameRegex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[86][num_bytes]; + component lt[26][num_bytes]; + component and[52][num_bytes]; + component multi_or[20][num_bytes]; + signal states[num_bytes+1][14]; + signal states_tmp[num_bytes+1][14]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 14; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(13); + states[i][0] <== 1; + lt[0][i] = LessEqThan(8); + lt[0][i].in[0] <== 194; + lt[0][i].in[1] <== in[i]; + lt[1][i] = LessEqThan(8); + lt[1][i].in[0] <== in[i]; + lt[1][i].in[1] <== 223; + and[0][i] = AND(); + and[0][i].a <== lt[0][i].out; + and[0][i].b <== lt[1][i].out; + and[1][i] = AND(); + and[1][i].a <== states[i][0]; + and[1][i].b <== and[0][i].out; + lt[2][i] = LessEqThan(8); + lt[2][i].in[0] <== 160; + lt[2][i].in[1] <== in[i]; + lt[3][i] = LessEqThan(8); + lt[3][i].in[0] <== in[i]; + lt[3][i].in[1] <== 191; + and[2][i] = AND(); + and[2][i].a <== lt[2][i].out; + and[2][i].b <== lt[3][i].out; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== and[2][i].out; + lt[4][i] = LessEqThan(8); + lt[4][i].in[0] <== 128; + lt[4][i].in[1] <== in[i]; + lt[5][i] = LessEqThan(8); + lt[5][i].in[0] <== in[i]; + lt[5][i].in[1] <== 191; + and[4][i] = AND(); + and[4][i].a <== lt[4][i].out; + and[4][i].b <== lt[5][i].out; + and[5][i] = AND(); + and[5][i].a <== states[i][3]; + and[5][i].b <== and[4][i].out; + lt[6][i] = LessEqThan(8); + lt[6][i].in[0] <== 128; + lt[6][i].in[1] <== in[i]; + lt[7][i] = LessEqThan(8); + lt[7][i].in[0] <== in[i]; + lt[7][i].in[1] <== 159; + and[6][i] = AND(); + and[6][i].a <== lt[6][i].out; + and[6][i].b <== lt[7][i].out; + and[7][i] = AND(); + and[7][i].a <== states[i][4]; + and[7][i].b <== and[6][i].out; + lt[8][i] = LessEqThan(8); + lt[8][i].in[0] <== 49; + lt[8][i].in[1] <== in[i]; + lt[9][i] = LessEqThan(8); + lt[9][i].in[0] <== in[i]; + lt[9][i].in[1] <== 223; + and[8][i] = AND(); + and[8][i].a <== lt[8][i].out; + and[8][i].b <== lt[9][i].out; + and[9][i] = AND(); + and[9][i].a <== states[i][8]; + and[9][i].b <== and[8][i].out; + lt[10][i] = LessEqThan(8); + lt[10][i].in[0] <== 127; + lt[10][i].in[1] <== in[i]; + lt[11][i] = LessEqThan(8); + lt[11][i].in[0] <== in[i]; + lt[11][i].in[1] <== 223; + and[10][i] = AND(); + and[10][i].a <== lt[10][i].out; + and[10][i].b <== lt[11][i].out; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 58; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 59; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 60; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 62; + eq[4][i] = IsEqual(); + eq[4][i].in[0] <== in[i]; + eq[4][i].in[1] <== 64; + eq[5][i] = IsEqual(); + eq[5][i].in[0] <== in[i]; + eq[5][i].in[1] <== 91; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 92; + eq[7][i] = IsEqual(); + eq[7][i].in[0] <== in[i]; + eq[7][i].in[1] <== 93; + and[11][i] = AND(); + and[11][i].a <== states[i][9]; + multi_or[0][i] = MultiOR(9); + multi_or[0][i].in[0] <== and[10][i].out; + multi_or[0][i].in[1] <== eq[0][i].out; + multi_or[0][i].in[2] <== eq[1][i].out; + multi_or[0][i].in[3] <== eq[2][i].out; + multi_or[0][i].in[4] <== eq[3][i].out; + multi_or[0][i].in[5] <== eq[4][i].out; + multi_or[0][i].in[6] <== eq[5][i].out; + multi_or[0][i].in[7] <== eq[6][i].out; + multi_or[0][i].in[8] <== eq[7][i].out; + and[11][i].b <== multi_or[0][i].out; + multi_or[1][i] = MultiOR(5); + multi_or[1][i].in[0] <== and[3][i].out; + multi_or[1][i].in[1] <== and[5][i].out; + multi_or[1][i].in[2] <== and[7][i].out; + multi_or[1][i].in[3] <== and[9][i].out; + multi_or[1][i].in[4] <== and[11][i].out; + states_tmp[i+1][1] <== multi_or[1][i].out; + eq[8][i] = IsEqual(); + eq[8][i].in[0] <== in[i]; + eq[8][i].in[1] <== 224; + and[12][i] = AND(); + and[12][i].a <== states[i][0]; + and[12][i].b <== eq[8][i].out; + and[13][i] = AND(); + and[13][i].a <== states[i][8]; + and[13][i].b <== eq[8][i].out; + and[14][i] = AND(); + and[14][i].a <== states[i][9]; + and[14][i].b <== eq[8][i].out; + multi_or[2][i] = MultiOR(2); + multi_or[2][i].in[0] <== and[13][i].out; + multi_or[2][i].in[1] <== and[14][i].out; + states_tmp[i+1][2] <== multi_or[2][i].out; + eq[9][i] = IsEqual(); + eq[9][i].in[0] <== in[i]; + eq[9][i].in[1] <== 225; + eq[10][i] = IsEqual(); + eq[10][i].in[0] <== in[i]; + eq[10][i].in[1] <== 226; + eq[11][i] = IsEqual(); + eq[11][i].in[0] <== in[i]; + eq[11][i].in[1] <== 227; + eq[12][i] = IsEqual(); + eq[12][i].in[0] <== in[i]; + eq[12][i].in[1] <== 228; + eq[13][i] = IsEqual(); + eq[13][i].in[0] <== in[i]; + eq[13][i].in[1] <== 229; + eq[14][i] = IsEqual(); + eq[14][i].in[0] <== in[i]; + eq[14][i].in[1] <== 230; + eq[15][i] = IsEqual(); + eq[15][i].in[0] <== in[i]; + eq[15][i].in[1] <== 231; + eq[16][i] = IsEqual(); + eq[16][i].in[0] <== in[i]; + eq[16][i].in[1] <== 232; + eq[17][i] = IsEqual(); + eq[17][i].in[0] <== in[i]; + eq[17][i].in[1] <== 233; + eq[18][i] = IsEqual(); + eq[18][i].in[0] <== in[i]; + eq[18][i].in[1] <== 234; + eq[19][i] = IsEqual(); + eq[19][i].in[0] <== in[i]; + eq[19][i].in[1] <== 235; + eq[20][i] = IsEqual(); + eq[20][i].in[0] <== in[i]; + eq[20][i].in[1] <== 236; + eq[21][i] = IsEqual(); + eq[21][i].in[0] <== in[i]; + eq[21][i].in[1] <== 238; + eq[22][i] = IsEqual(); + eq[22][i].in[0] <== in[i]; + eq[22][i].in[1] <== 239; + and[15][i] = AND(); + and[15][i].a <== states[i][0]; + multi_or[3][i] = MultiOR(14); + multi_or[3][i].in[0] <== eq[9][i].out; + multi_or[3][i].in[1] <== eq[10][i].out; + multi_or[3][i].in[2] <== eq[11][i].out; + multi_or[3][i].in[3] <== eq[12][i].out; + multi_or[3][i].in[4] <== eq[13][i].out; + multi_or[3][i].in[5] <== eq[14][i].out; + multi_or[3][i].in[6] <== eq[15][i].out; + multi_or[3][i].in[7] <== eq[16][i].out; + multi_or[3][i].in[8] <== eq[17][i].out; + multi_or[3][i].in[9] <== eq[18][i].out; + multi_or[3][i].in[10] <== eq[19][i].out; + multi_or[3][i].in[11] <== eq[20][i].out; + multi_or[3][i].in[12] <== eq[21][i].out; + multi_or[3][i].in[13] <== eq[22][i].out; + and[15][i].b <== multi_or[3][i].out; + lt[12][i] = LessEqThan(8); + lt[12][i].in[0] <== 144; + lt[12][i].in[1] <== in[i]; + lt[13][i] = LessEqThan(8); + lt[13][i].in[0] <== in[i]; + lt[13][i].in[1] <== 191; + and[16][i] = AND(); + and[16][i].a <== lt[12][i].out; + and[16][i].b <== lt[13][i].out; + and[17][i] = AND(); + and[17][i].a <== states[i][5]; + and[17][i].b <== and[16][i].out; + and[18][i] = AND(); + and[18][i].a <== states[i][6]; + and[18][i].b <== and[4][i].out; + eq[23][i] = IsEqual(); + eq[23][i].in[0] <== in[i]; + eq[23][i].in[1] <== 128; + eq[24][i] = IsEqual(); + eq[24][i].in[0] <== in[i]; + eq[24][i].in[1] <== 129; + eq[25][i] = IsEqual(); + eq[25][i].in[0] <== in[i]; + eq[25][i].in[1] <== 130; + eq[26][i] = IsEqual(); + eq[26][i].in[0] <== in[i]; + eq[26][i].in[1] <== 131; + eq[27][i] = IsEqual(); + eq[27][i].in[0] <== in[i]; + eq[27][i].in[1] <== 132; + eq[28][i] = IsEqual(); + eq[28][i].in[0] <== in[i]; + eq[28][i].in[1] <== 133; + eq[29][i] = IsEqual(); + eq[29][i].in[0] <== in[i]; + eq[29][i].in[1] <== 134; + eq[30][i] = IsEqual(); + eq[30][i].in[0] <== in[i]; + eq[30][i].in[1] <== 135; + eq[31][i] = IsEqual(); + eq[31][i].in[0] <== in[i]; + eq[31][i].in[1] <== 136; + eq[32][i] = IsEqual(); + eq[32][i].in[0] <== in[i]; + eq[32][i].in[1] <== 137; + eq[33][i] = IsEqual(); + eq[33][i].in[0] <== in[i]; + eq[33][i].in[1] <== 138; + eq[34][i] = IsEqual(); + eq[34][i].in[0] <== in[i]; + eq[34][i].in[1] <== 139; + eq[35][i] = IsEqual(); + eq[35][i].in[0] <== in[i]; + eq[35][i].in[1] <== 140; + eq[36][i] = IsEqual(); + eq[36][i].in[0] <== in[i]; + eq[36][i].in[1] <== 141; + eq[37][i] = IsEqual(); + eq[37][i].in[0] <== in[i]; + eq[37][i].in[1] <== 142; + eq[38][i] = IsEqual(); + eq[38][i].in[0] <== in[i]; + eq[38][i].in[1] <== 143; + and[19][i] = AND(); + and[19][i].a <== states[i][7]; + multi_or[4][i] = MultiOR(16); + multi_or[4][i].in[0] <== eq[23][i].out; + multi_or[4][i].in[1] <== eq[24][i].out; + multi_or[4][i].in[2] <== eq[25][i].out; + multi_or[4][i].in[3] <== eq[26][i].out; + multi_or[4][i].in[4] <== eq[27][i].out; + multi_or[4][i].in[5] <== eq[28][i].out; + multi_or[4][i].in[6] <== eq[29][i].out; + multi_or[4][i].in[7] <== eq[30][i].out; + multi_or[4][i].in[8] <== eq[31][i].out; + multi_or[4][i].in[9] <== eq[32][i].out; + multi_or[4][i].in[10] <== eq[33][i].out; + multi_or[4][i].in[11] <== eq[34][i].out; + multi_or[4][i].in[12] <== eq[35][i].out; + multi_or[4][i].in[13] <== eq[36][i].out; + multi_or[4][i].in[14] <== eq[37][i].out; + multi_or[4][i].in[15] <== eq[38][i].out; + and[19][i].b <== multi_or[4][i].out; + and[20][i] = AND(); + and[20][i].a <== states[i][8]; + and[20][i].b <== multi_or[3][i].out; + and[21][i] = AND(); + and[21][i].a <== states[i][9]; + and[21][i].b <== multi_or[3][i].out; + multi_or[5][i] = MultiOR(5); + multi_or[5][i].in[0] <== and[17][i].out; + multi_or[5][i].in[1] <== and[18][i].out; + multi_or[5][i].in[2] <== and[19][i].out; + multi_or[5][i].in[3] <== and[20][i].out; + multi_or[5][i].in[4] <== and[21][i].out; + states_tmp[i+1][3] <== multi_or[5][i].out; + eq[39][i] = IsEqual(); + eq[39][i].in[0] <== in[i]; + eq[39][i].in[1] <== 237; + and[22][i] = AND(); + and[22][i].a <== states[i][0]; + and[22][i].b <== eq[39][i].out; + and[23][i] = AND(); + and[23][i].a <== states[i][8]; + and[23][i].b <== eq[39][i].out; + and[24][i] = AND(); + and[24][i].a <== states[i][9]; + and[24][i].b <== eq[39][i].out; + multi_or[6][i] = MultiOR(2); + multi_or[6][i].in[0] <== and[23][i].out; + multi_or[6][i].in[1] <== and[24][i].out; + states_tmp[i+1][4] <== multi_or[6][i].out; + eq[40][i] = IsEqual(); + eq[40][i].in[0] <== in[i]; + eq[40][i].in[1] <== 240; + and[25][i] = AND(); + and[25][i].a <== states[i][0]; + and[25][i].b <== eq[40][i].out; + and[26][i] = AND(); + and[26][i].a <== states[i][8]; + and[26][i].b <== eq[40][i].out; + and[27][i] = AND(); + and[27][i].a <== states[i][9]; + and[27][i].b <== eq[40][i].out; + multi_or[7][i] = MultiOR(2); + multi_or[7][i].in[0] <== and[26][i].out; + multi_or[7][i].in[1] <== and[27][i].out; + states_tmp[i+1][5] <== multi_or[7][i].out; + eq[41][i] = IsEqual(); + eq[41][i].in[0] <== in[i]; + eq[41][i].in[1] <== 241; + eq[42][i] = IsEqual(); + eq[42][i].in[0] <== in[i]; + eq[42][i].in[1] <== 242; + eq[43][i] = IsEqual(); + eq[43][i].in[0] <== in[i]; + eq[43][i].in[1] <== 243; + and[28][i] = AND(); + and[28][i].a <== states[i][0]; + multi_or[8][i] = MultiOR(3); + multi_or[8][i].in[0] <== eq[41][i].out; + multi_or[8][i].in[1] <== eq[42][i].out; + multi_or[8][i].in[2] <== eq[43][i].out; + and[28][i].b <== multi_or[8][i].out; + and[29][i] = AND(); + and[29][i].a <== states[i][8]; + and[29][i].b <== multi_or[8][i].out; + and[30][i] = AND(); + and[30][i].a <== states[i][9]; + and[30][i].b <== multi_or[8][i].out; + multi_or[9][i] = MultiOR(2); + multi_or[9][i].in[0] <== and[29][i].out; + multi_or[9][i].in[1] <== and[30][i].out; + states_tmp[i+1][6] <== multi_or[9][i].out; + eq[44][i] = IsEqual(); + eq[44][i].in[0] <== in[i]; + eq[44][i].in[1] <== 244; + and[31][i] = AND(); + and[31][i].a <== states[i][0]; + and[31][i].b <== eq[44][i].out; + and[32][i] = AND(); + and[32][i].a <== states[i][8]; + and[32][i].b <== eq[44][i].out; + and[33][i] = AND(); + and[33][i].a <== states[i][9]; + and[33][i].b <== eq[44][i].out; + multi_or[10][i] = MultiOR(2); + multi_or[10][i].in[0] <== and[32][i].out; + multi_or[10][i].in[1] <== and[33][i].out; + states_tmp[i+1][7] <== multi_or[10][i].out; + lt[14][i] = LessEqThan(8); + lt[14][i].in[0] <== 14; + lt[14][i].in[1] <== in[i]; + lt[15][i] = LessEqThan(8); + lt[15][i].in[0] <== in[i]; + lt[15][i].in[1] <== 93; + and[34][i] = AND(); + and[34][i].a <== lt[14][i].out; + and[34][i].b <== lt[15][i].out; + lt[16][i] = LessEqThan(8); + lt[16][i].in[0] <== 95; + lt[16][i].in[1] <== in[i]; + lt[17][i] = LessEqThan(8); + lt[17][i].in[0] <== in[i]; + lt[17][i].in[1] <== 127; + and[35][i] = AND(); + and[35][i].a <== lt[16][i].out; + and[35][i].b <== lt[17][i].out; + eq[45][i] = IsEqual(); + eq[45][i].in[0] <== in[i]; + eq[45][i].in[1] <== 0; + eq[46][i] = IsEqual(); + eq[46][i].in[0] <== in[i]; + eq[46][i].in[1] <== 1; + eq[47][i] = IsEqual(); + eq[47][i].in[0] <== in[i]; + eq[47][i].in[1] <== 2; + eq[48][i] = IsEqual(); + eq[48][i].in[0] <== in[i]; + eq[48][i].in[1] <== 3; + eq[49][i] = IsEqual(); + eq[49][i].in[0] <== in[i]; + eq[49][i].in[1] <== 4; + eq[50][i] = IsEqual(); + eq[50][i].in[0] <== in[i]; + eq[50][i].in[1] <== 5; + eq[51][i] = IsEqual(); + eq[51][i].in[0] <== in[i]; + eq[51][i].in[1] <== 6; + eq[52][i] = IsEqual(); + eq[52][i].in[0] <== in[i]; + eq[52][i].in[1] <== 7; + eq[53][i] = IsEqual(); + eq[53][i].in[0] <== in[i]; + eq[53][i].in[1] <== 8; + eq[54][i] = IsEqual(); + eq[54][i].in[0] <== in[i]; + eq[54][i].in[1] <== 9; + eq[55][i] = IsEqual(); + eq[55][i].in[0] <== in[i]; + eq[55][i].in[1] <== 11; + eq[56][i] = IsEqual(); + eq[56][i].in[0] <== in[i]; + eq[56][i].in[1] <== 12; + eq[57][i] = IsEqual(); + eq[57][i].in[0] <== in[i]; + eq[57][i].in[1] <== 255; + and[36][i] = AND(); + and[36][i].a <== states[i][0]; + multi_or[11][i] = MultiOR(15); + multi_or[11][i].in[0] <== and[34][i].out; + multi_or[11][i].in[1] <== and[35][i].out; + multi_or[11][i].in[2] <== eq[45][i].out; + multi_or[11][i].in[3] <== eq[46][i].out; + multi_or[11][i].in[4] <== eq[47][i].out; + multi_or[11][i].in[5] <== eq[48][i].out; + multi_or[11][i].in[6] <== eq[49][i].out; + multi_or[11][i].in[7] <== eq[50][i].out; + multi_or[11][i].in[8] <== eq[51][i].out; + multi_or[11][i].in[9] <== eq[52][i].out; + multi_or[11][i].in[10] <== eq[53][i].out; + multi_or[11][i].in[11] <== eq[54][i].out; + multi_or[11][i].in[12] <== eq[55][i].out; + multi_or[11][i].in[13] <== eq[56][i].out; + multi_or[11][i].in[14] <== eq[57][i].out; + and[36][i].b <== multi_or[11][i].out; + and[37][i] = AND(); + and[37][i].a <== states[i][1]; + and[37][i].b <== and[4][i].out; + and[38][i] = AND(); + and[38][i].a <== states[i][8]; + multi_or[12][i] = MultiOR(14); + multi_or[12][i].in[0] <== and[34][i].out; + multi_or[12][i].in[1] <== and[35][i].out; + multi_or[12][i].in[2] <== eq[45][i].out; + multi_or[12][i].in[3] <== eq[46][i].out; + multi_or[12][i].in[4] <== eq[47][i].out; + multi_or[12][i].in[5] <== eq[48][i].out; + multi_or[12][i].in[6] <== eq[49][i].out; + multi_or[12][i].in[7] <== eq[50][i].out; + multi_or[12][i].in[8] <== eq[51][i].out; + multi_or[12][i].in[9] <== eq[52][i].out; + multi_or[12][i].in[10] <== eq[53][i].out; + multi_or[12][i].in[11] <== eq[54][i].out; + multi_or[12][i].in[12] <== eq[55][i].out; + multi_or[12][i].in[13] <== eq[56][i].out; + and[38][i].b <== multi_or[12][i].out; + lt[18][i] = LessEqThan(8); + lt[18][i].in[0] <== 14; + lt[18][i].in[1] <== in[i]; + lt[19][i] = LessEqThan(8); + lt[19][i].in[0] <== in[i]; + lt[19][i].in[1] <== 32; + and[39][i] = AND(); + and[39][i].a <== lt[18][i].out; + and[39][i].b <== lt[19][i].out; + eq[58][i] = IsEqual(); + eq[58][i].in[0] <== in[i]; + eq[58][i].in[1] <== 34; + eq[59][i] = IsEqual(); + eq[59][i].in[0] <== in[i]; + eq[59][i].in[1] <== 40; + eq[60][i] = IsEqual(); + eq[60][i].in[0] <== in[i]; + eq[60][i].in[1] <== 41; + and[40][i] = AND(); + and[40][i].a <== states[i][9]; + multi_or[13][i] = MultiOR(18); + multi_or[13][i].in[0] <== and[39][i].out; + multi_or[13][i].in[1] <== eq[45][i].out; + multi_or[13][i].in[2] <== eq[46][i].out; + multi_or[13][i].in[3] <== eq[47][i].out; + multi_or[13][i].in[4] <== eq[48][i].out; + multi_or[13][i].in[5] <== eq[49][i].out; + multi_or[13][i].in[6] <== eq[50][i].out; + multi_or[13][i].in[7] <== eq[51][i].out; + multi_or[13][i].in[8] <== eq[52][i].out; + multi_or[13][i].in[9] <== eq[53][i].out; + multi_or[13][i].in[10] <== eq[54][i].out; + multi_or[13][i].in[11] <== eq[55][i].out; + multi_or[13][i].in[12] <== eq[56][i].out; + multi_or[13][i].in[13] <== eq[58][i].out; + multi_or[13][i].in[14] <== eq[59][i].out; + multi_or[13][i].in[15] <== eq[60][i].out; + multi_or[13][i].in[16] <== eq[0][i].out; + multi_or[13][i].in[17] <== eq[1][i].out; + and[40][i].b <== multi_or[13][i].out; + multi_or[14][i] = MultiOR(3); + multi_or[14][i].in[0] <== and[37][i].out; + multi_or[14][i].in[1] <== and[38][i].out; + multi_or[14][i].in[2] <== and[40][i].out; + states_tmp[i+1][8] <== multi_or[14][i].out; + and[41][i] = AND(); + and[41][i].a <== states[i][8]; + and[41][i].b <== eq[2][i].out; + and[42][i] = AND(); + and[42][i].a <== states[i][9]; + and[42][i].b <== eq[2][i].out; + multi_or[15][i] = MultiOR(2); + multi_or[15][i].in[0] <== and[41][i].out; + multi_or[15][i].in[1] <== and[42][i].out; + states[i+1][9] <== multi_or[15][i].out; + lt[20][i] = LessEqThan(8); + lt[20][i].in[0] <== 65; + lt[20][i].in[1] <== in[i]; + lt[21][i] = LessEqThan(8); + lt[21][i].in[0] <== in[i]; + lt[21][i].in[1] <== 90; + and[43][i] = AND(); + and[43][i].a <== lt[20][i].out; + and[43][i].b <== lt[21][i].out; + lt[22][i] = LessEqThan(8); + lt[22][i].in[0] <== 94; + lt[22][i].in[1] <== in[i]; + lt[23][i] = LessEqThan(8); + lt[23][i].in[0] <== in[i]; + lt[23][i].in[1] <== 126; + and[44][i] = AND(); + and[44][i].a <== lt[22][i].out; + and[44][i].b <== lt[23][i].out; + eq[61][i] = IsEqual(); + eq[61][i].in[0] <== in[i]; + eq[61][i].in[1] <== 33; + eq[62][i] = IsEqual(); + eq[62][i].in[0] <== in[i]; + eq[62][i].in[1] <== 35; + eq[63][i] = IsEqual(); + eq[63][i].in[0] <== in[i]; + eq[63][i].in[1] <== 36; + eq[64][i] = IsEqual(); + eq[64][i].in[0] <== in[i]; + eq[64][i].in[1] <== 37; + eq[65][i] = IsEqual(); + eq[65][i].in[0] <== in[i]; + eq[65][i].in[1] <== 38; + eq[66][i] = IsEqual(); + eq[66][i].in[0] <== in[i]; + eq[66][i].in[1] <== 39; + eq[67][i] = IsEqual(); + eq[67][i].in[0] <== in[i]; + eq[67][i].in[1] <== 42; + eq[68][i] = IsEqual(); + eq[68][i].in[0] <== in[i]; + eq[68][i].in[1] <== 43; + eq[69][i] = IsEqual(); + eq[69][i].in[0] <== in[i]; + eq[69][i].in[1] <== 44; + eq[70][i] = IsEqual(); + eq[70][i].in[0] <== in[i]; + eq[70][i].in[1] <== 45; + eq[71][i] = IsEqual(); + eq[71][i].in[0] <== in[i]; + eq[71][i].in[1] <== 46; + eq[72][i] = IsEqual(); + eq[72][i].in[0] <== in[i]; + eq[72][i].in[1] <== 47; + eq[73][i] = IsEqual(); + eq[73][i].in[0] <== in[i]; + eq[73][i].in[1] <== 48; + eq[74][i] = IsEqual(); + eq[74][i].in[0] <== in[i]; + eq[74][i].in[1] <== 49; + eq[75][i] = IsEqual(); + eq[75][i].in[0] <== in[i]; + eq[75][i].in[1] <== 50; + eq[76][i] = IsEqual(); + eq[76][i].in[0] <== in[i]; + eq[76][i].in[1] <== 51; + eq[77][i] = IsEqual(); + eq[77][i].in[0] <== in[i]; + eq[77][i].in[1] <== 52; + eq[78][i] = IsEqual(); + eq[78][i].in[0] <== in[i]; + eq[78][i].in[1] <== 53; + eq[79][i] = IsEqual(); + eq[79][i].in[0] <== in[i]; + eq[79][i].in[1] <== 54; + eq[80][i] = IsEqual(); + eq[80][i].in[0] <== in[i]; + eq[80][i].in[1] <== 55; + eq[81][i] = IsEqual(); + eq[81][i].in[0] <== in[i]; + eq[81][i].in[1] <== 56; + eq[82][i] = IsEqual(); + eq[82][i].in[0] <== in[i]; + eq[82][i].in[1] <== 57; + eq[83][i] = IsEqual(); + eq[83][i].in[0] <== in[i]; + eq[83][i].in[1] <== 61; + eq[84][i] = IsEqual(); + eq[84][i].in[0] <== in[i]; + eq[84][i].in[1] <== 63; + and[45][i] = AND(); + and[45][i].a <== states[i][9]; + multi_or[16][i] = MultiOR(26); + multi_or[16][i].in[0] <== and[43][i].out; + multi_or[16][i].in[1] <== and[44][i].out; + multi_or[16][i].in[2] <== eq[61][i].out; + multi_or[16][i].in[3] <== eq[62][i].out; + multi_or[16][i].in[4] <== eq[63][i].out; + multi_or[16][i].in[5] <== eq[64][i].out; + multi_or[16][i].in[6] <== eq[65][i].out; + multi_or[16][i].in[7] <== eq[66][i].out; + multi_or[16][i].in[8] <== eq[67][i].out; + multi_or[16][i].in[9] <== eq[68][i].out; + multi_or[16][i].in[10] <== eq[69][i].out; + multi_or[16][i].in[11] <== eq[70][i].out; + multi_or[16][i].in[12] <== eq[71][i].out; + multi_or[16][i].in[13] <== eq[72][i].out; + multi_or[16][i].in[14] <== eq[73][i].out; + multi_or[16][i].in[15] <== eq[74][i].out; + multi_or[16][i].in[16] <== eq[75][i].out; + multi_or[16][i].in[17] <== eq[76][i].out; + multi_or[16][i].in[18] <== eq[77][i].out; + multi_or[16][i].in[19] <== eq[78][i].out; + multi_or[16][i].in[20] <== eq[79][i].out; + multi_or[16][i].in[21] <== eq[80][i].out; + multi_or[16][i].in[22] <== eq[81][i].out; + multi_or[16][i].in[23] <== eq[82][i].out; + multi_or[16][i].in[24] <== eq[83][i].out; + multi_or[16][i].in[25] <== eq[84][i].out; + and[45][i].b <== multi_or[16][i].out; + and[46][i] = AND(); + and[46][i].a <== states[i][10]; + and[46][i].b <== multi_or[16][i].out; + multi_or[17][i] = MultiOR(2); + multi_or[17][i].in[0] <== and[45][i].out; + multi_or[17][i].in[1] <== and[46][i].out; + states[i+1][10] <== multi_or[17][i].out; + and[47][i] = AND(); + and[47][i].a <== states[i][10]; + and[47][i].b <== eq[4][i].out; + states[i+1][11] <== and[47][i].out; + lt[24][i] = LessEqThan(8); + lt[24][i].in[0] <== 97; + lt[24][i].in[1] <== in[i]; + lt[25][i] = LessEqThan(8); + lt[25][i].in[0] <== in[i]; + lt[25][i].in[1] <== 122; + and[48][i] = AND(); + and[48][i].a <== lt[24][i].out; + and[48][i].b <== lt[25][i].out; + eq[85][i] = IsEqual(); + eq[85][i].in[0] <== in[i]; + eq[85][i].in[1] <== 95; + and[49][i] = AND(); + and[49][i].a <== states[i][11]; + multi_or[18][i] = MultiOR(15); + multi_or[18][i].in[0] <== and[43][i].out; + multi_or[18][i].in[1] <== and[48][i].out; + multi_or[18][i].in[2] <== eq[70][i].out; + multi_or[18][i].in[3] <== eq[71][i].out; + multi_or[18][i].in[4] <== eq[73][i].out; + multi_or[18][i].in[5] <== eq[74][i].out; + multi_or[18][i].in[6] <== eq[75][i].out; + multi_or[18][i].in[7] <== eq[76][i].out; + multi_or[18][i].in[8] <== eq[77][i].out; + multi_or[18][i].in[9] <== eq[78][i].out; + multi_or[18][i].in[10] <== eq[79][i].out; + multi_or[18][i].in[11] <== eq[80][i].out; + multi_or[18][i].in[12] <== eq[81][i].out; + multi_or[18][i].in[13] <== eq[82][i].out; + multi_or[18][i].in[14] <== eq[85][i].out; + and[49][i].b <== multi_or[18][i].out; + and[50][i] = AND(); + and[50][i].a <== states[i][12]; + and[50][i].b <== multi_or[18][i].out; + multi_or[19][i] = MultiOR(2); + multi_or[19][i].in[0] <== and[49][i].out; + multi_or[19][i].in[1] <== and[50][i].out; + states[i+1][12] <== multi_or[19][i].out; + and[51][i] = AND(); + and[51][i].a <== states[i][12]; + and[51][i].b <== eq[3][i].out; + states[i+1][13] <== and[51][i].out; + from_zero_enabled[i] <== MultiNOR(13)([states_tmp[i+1][1], states_tmp[i+1][2], states_tmp[i+1][3], states_tmp[i+1][4], states_tmp[i+1][5], states_tmp[i+1][6], states_tmp[i+1][7], states_tmp[i+1][8], states[i+1][9], states[i+1][10], states[i+1][11], states[i+1][12], states[i+1][13]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[1][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[12][i].out]); + states[i+1][3] <== MultiOR(2)([states_tmp[i+1][3], from_zero_enabled[i] * and[15][i].out]); + states[i+1][4] <== MultiOR(2)([states_tmp[i+1][4], from_zero_enabled[i] * and[22][i].out]); + states[i+1][5] <== MultiOR(2)([states_tmp[i+1][5], from_zero_enabled[i] * and[25][i].out]); + states[i+1][6] <== MultiOR(2)([states_tmp[i+1][6], from_zero_enabled[i] * and[28][i].out]); + states[i+1][7] <== MultiOR(2)([states_tmp[i+1][7], from_zero_enabled[i] * and[31][i].out]); + states[i+1][8] <== MultiOR(2)([states_tmp[i+1][8], from_zero_enabled[i] * and[36][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + state_changed[i].in[3] <== states[i+1][4]; + state_changed[i].in[4] <== states[i+1][5]; + state_changed[i].in[5] <== states[i+1][6]; + state_changed[i].in[6] <== states[i+1][7]; + state_changed[i].in[7] <== states[i+1][8]; + state_changed[i].in[8] <== states[i+1][9]; + state_changed[i].in[9] <== states[i+1][10]; + state_changed[i].in[10] <== states[i+1][11]; + state_changed[i].in[11] <== states[i+1][12]; + state_changed[i].in[12] <== states[i+1][13]; + } + + component final_state_result = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + final_state_result.in[i] <== states[i][13]; + } + out <== final_state_result.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 1; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][13] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][13], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(9, 10), (10, 10), (10, 11), (11, 12), (12, 12)}] + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(9, 10), (10, 10), (10, 11), (11, 12), (12, 12)] + is_substr0[i] <== MultiOR(5)([states[i+1][9] * states[i+2][10], states[i+1][10] * states[i+2][10], states[i+1][10] * states[i+2][11], states[i+1][11] * states[i+2][12], states[i+1][12] * states[i+2][12]]); + is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/asterisk.test.js b/packages/circom/tests/asterisk.test.js new file mode 100644 index 0000000..9b936ff --- /dev/null +++ b/packages/circom/tests/asterisk.test.js @@ -0,0 +1,627 @@ +import circom_tester from "circom_tester"; +import * as path from "path"; +import { readFileSync, writeFileSync } from "fs"; +import apis from "../../apis/pkg"; +import compiler from "../../compiler/pkg"; +const option = { + include: path.join(__dirname, "../../../node_modules"), +}; +const wasm_tester = circom_tester.wasm; + +jest.setTimeout(600000); +describe("Asterisk Regex", () => { + let circuit1; + let circuit2; + let circuit3; + // let circuit4; + // let circuit5; + // let circuit6; + beforeAll(async () => { + writeFileSync( + path.join(__dirname, "./circuits/asterisk1_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/asterisk1.json"), + "utf8" + ), + "Asterisk1Regex" + ) + ); + circuit1 = await wasm_tester( + path.join(__dirname, "./circuits/test_asterisk1_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/asterisk2_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/asterisk2.json"), + "utf8" + ), + "Asterisk2Regex" + ) + ); + circuit2 = await wasm_tester( + path.join(__dirname, "./circuits/test_asterisk2_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/asterisk3_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/asterisk3.json"), + "utf8" + ), + "Asterisk3Regex" + ) + ); + circuit3 = await wasm_tester( + path.join(__dirname, "./circuits/test_asterisk3_regex.circom"), + option + ); + + // writeFileSync( + // path.join(__dirname, "./circuits/asterisk4_regex.circom"), + // compiler.genFromDecomposed( + // readFileSync( + // path.join(__dirname, "./circuits/asterisk4.json"), + // "utf8" + // ), + // "Asterisk4Regex" + // ) + // ); + // circuit4 = await wasm_tester( + // path.join(__dirname, "./circuits/test_asterisk4_regex.circom"), + // option + // ); + + // writeFileSync( + // path.join(__dirname, "./circuits/asterisk5_regex.circom"), + // compiler.genFromDecomposed( + // readFileSync( + // path.join(__dirname, "./circuits/asterisk5.json"), + // "utf8" + // ), + // "Asterisk5Regex" + // ) + // ); + // circuit5 = await wasm_tester( + // path.join(__dirname, "./circuits/test_asterisk5_regex.circom"), + // option + // ); + + // writeFileSync( + // path.join(__dirname, "./circuits/asterisk6_regex.circom"), + // compiler.genFromDecomposed( + // readFileSync( + // path.join(__dirname, "./circuits/asterisk6.json"), + // "utf8" + // ), + // "Asterisk6Regex" + // ) + // ); + // circuit6 = await wasm_tester( + // path.join(__dirname, "./circuits/test_asterisk6_regex.circom"), + // option + // ); + }); + + it("asterisk1 valid case 1", async () => { + const inputStr = `xb`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/asterisk1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("asterisk1 valid case 2", async () => { + const inputStr = `xab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/asterisk1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("asterisk1 valid case 3", async () => { + const inputStr = `xaab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/asterisk1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("asterisk1 valid case 4", async () => { + const inputStr = `710xab98`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/asterisk1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + + it("asterisk1 invalid case 1", async () => { + const inputStr = `xaaa`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("asterisk1 invalid case 2", async () => { + const inputStr = `aaabx`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + + it("asterisk2 valid case 1", async () => { + const inputStr = `aaa`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/asterisk2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("asterisk2 valid case 2", async () => { + const inputStr = `ab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/asterisk2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("asterisk2 valid case 3", async () => { + const inputStr = `abbba`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/asterisk2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + + it("asterisk2 valid case 4", async () => { + const inputStr = `717abb9`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/asterisk2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("asterisk2 invalid case 1", async () => { + const inputStr = `bbb`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("asterisk2 invalid case 2", async () => { + const inputStr = `19bd7`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("asterisk3 valid case 1", async () => { + const inputStr = `ab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/asterisk3.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("asterisk3 valid case 2", async () => { + const inputStr = `xaxxyxby`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/asterisk3.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("asterisk3 invalid case 1", async () => { + const inputStr = `axyxyyyx`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("asterisk3 invalid case 2", async () => { + const inputStr = `xyyxxyba`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + // it("asterisk4 valid case 1", async () => { + // const inputStr = `b099`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit4.calculateWitness(circuitInputs); + // await circuit4.checkConstraints(witness); + // expect(1n).toEqual(witness[1]); + // const prefixIdxes = apis.extractSubstrIdxes( + // inputStr, + // readFileSync( + // path.join(__dirname, "./circuits/asterisk4.json"), + // "utf8" + // ) + // )[0]; + // for (let idx = 0; idx < 8; ++idx) { + // if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + // expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + // } else { + // expect(0n).toEqual(witness[2 + idx]); + // } + // } + // }); + + // it("asterisk4 invalid case 1", async () => { + // const inputStr = `192ue2iw`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit4.calculateWitness(circuitInputs); + // await circuit4.checkConstraints(witness); + // expect(0n).toEqual(witness[1]); + // for (let idx = 0; idx < 8; ++idx) { + // expect(0n).toEqual(witness[2 + idx]); + // } + // }); + + // it("asterisk5 valid case 1", async () => { + // const inputStr = `a`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit5.calculateWitness(circuitInputs); + // await circuit5.checkConstraints(witness); + // expect(1n).toEqual(witness[1]); + // const prefixIdxes = apis.extractSubstrIdxes( + // inputStr, + // readFileSync( + // path.join(__dirname, "./circuits/asterisk5.json"), + // "utf8" + // ) + // )[0]; + // for (let idx = 0; idx < 8; ++idx) { + // if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + // expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + // } else { + // expect(0n).toEqual(witness[2 + idx]); + // } + // } + // }); + + // it("asterisk5 valid case 2", async () => { + // const inputStr = `218aaaa2`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit5.calculateWitness(circuitInputs); + // await circuit5.checkConstraints(witness); + // expect(1n).toEqual(witness[1]); + // const prefixIdxes = apis.extractSubstrIdxes( + // inputStr, + // readFileSync( + // path.join(__dirname, "./circuits/asterisk5.json"), + // "utf8" + // ) + // )[0]; + // for (let idx = 0; idx < 8; ++idx) { + // if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + // expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + // } else { + // expect(0n).toEqual(witness[2 + idx]); + // } + // } + // }); + + // it("asterisk5 invalid case 1", async () => { + // const inputStr = `bbbbcccc`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit5.calculateWitness(circuitInputs); + // await circuit5.checkConstraints(witness); + // expect(0n).toEqual(witness[1]); + // for (let idx = 0; idx < 8; ++idx) { + // expect(0n).toEqual(witness[2 + idx]); + // } + // }); + + // it("asterisk6 valid case 1", async () => { + // const inputStr = ``; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit6.calculateWitness(circuitInputs); + // await circuit6.checkConstraints(witness); + // expect(1n).toEqual(witness[1]); + // const prefixIdxes = apis.extractSubstrIdxes( + // inputStr, + // readFileSync( + // path.join(__dirname, "./circuits/asterisk6.json"), + // "utf8" + // ) + // )[0]; + // for (let idx = 0; idx < 8; ++idx) { + // if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + // expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + // } else { + // expect(0n).toEqual(witness[2 + idx]); + // } + // } + // }); + + // it("asterisk6 valid case 2", async () => { + // const inputStr = `a`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit6.calculateWitness(circuitInputs); + // await circuit6.checkConstraints(witness); + // expect(1n).toEqual(witness[1]); + // const prefixIdxes = apis.extractSubstrIdxes( + // inputStr, + // readFileSync( + // path.join(__dirname, "./circuits/asterisk6.json"), + // "utf8" + // ) + // )[0]; + // for (let idx = 0; idx < 8; ++idx) { + // if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + // expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + // } else { + // expect(0n).toEqual(witness[2 + idx]); + // } + // } + // }); + + // it("asterisk6 valid case 3", async () => { + // const inputStr = `1921 abw`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit6.calculateWitness(circuitInputs); + // await circuit6.checkConstraints(witness); + // expect(1n).toEqual(witness[1]); + // const prefixIdxes = apis.extractSubstrIdxes( + // inputStr, + // readFileSync( + // path.join(__dirname, "./circuits/asterisk6.json"), + // "utf8" + // ) + // )[0]; + // for (let idx = 0; idx < 8; ++idx) { + // if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + // expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + // } else { + // expect(0n).toEqual(witness[2 + idx]); + // } + // } + // }); + + +}); diff --git a/packages/circom/tests/body_hash_regex.test.js b/packages/circom/tests/body_hash_regex.test.js index b2ace1e..af6e24e 100644 --- a/packages/circom/tests/body_hash_regex.test.js +++ b/packages/circom/tests/body_hash_regex.test.js @@ -56,7 +56,7 @@ describe("Bodyhash Regex", () => { } }); - it("timestamp after new line", async () => { + it("bodyhash after new line", async () => { const signatureField = `\r\ndkim-signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694989812; x=1695594612; dara=google.com; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; b=`; const paddedStr = apis.padString(signatureField, 1024); const circuitInputs = { @@ -80,4 +80,18 @@ describe("Bodyhash Regex", () => { } } }); + + it("invalid bodyhash", async () => { + const signatureField = `\r\nto: dkim-signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694989812; x=1695594612; dara=google.com; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; b=`; + const paddedStr = apis.padString(signatureField, 1024); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 1024; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); }); diff --git a/packages/circom/tests/caret.test.js b/packages/circom/tests/caret.test.js new file mode 100644 index 0000000..d4ffdfd --- /dev/null +++ b/packages/circom/tests/caret.test.js @@ -0,0 +1,564 @@ +import circom_tester from "circom_tester"; +import * as path from "path"; +import { readFileSync, writeFileSync } from "fs"; +import apis from "../../apis/pkg"; +import compiler from "../../compiler/pkg"; +const option = { + include: path.join(__dirname, "../../../node_modules"), +}; +const wasm_tester = circom_tester.wasm; + +jest.setTimeout(600000); +describe("Caret Regex", () => { + let circuit1; + let circuit2; + let circuit3; + let circuit4; + let circuit5; + beforeAll(async () => { + writeFileSync( + path.join(__dirname, "./circuits/caret1_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/caret1.json"), + "utf8" + ), + "Caret1Regex" + ) + ); + circuit1 = await wasm_tester( + path.join(__dirname, "./circuits/test_caret1_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/caret2_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/caret2.json"), + "utf8" + ), + "Caret2Regex" + ) + ); + circuit2 = await wasm_tester( + path.join(__dirname, "./circuits/test_caret2_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/caret3_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/caret3.json"), + "utf8" + ), + "Caret3Regex" + ) + ); + circuit3 = await wasm_tester( + path.join(__dirname, "./circuits/test_caret3_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/caret4_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/caret4.json"), + "utf8" + ), + "Caret4Regex" + ) + ); + circuit4 = await wasm_tester( + path.join(__dirname, "./circuits/test_caret4_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/caret5_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/caret5.json"), + "utf8" + ), + "Caret5Regex" + ) + ); + circuit5 = await wasm_tester( + path.join(__dirname, "./circuits/test_caret5_regex.circom"), + option + ); + }); + + it("caret1 valid case 1", async () => { + const inputStr = `a`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("caret1 valid case 2", async () => { + const inputStr = `abnjknda`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("caret1 invalid case 1", async () => { + const inputStr = `ba`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("caret1 invalid case 2", async () => { + const inputStr = `bav`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + + it("caret2 valid case 1", async () => { + const inputStr = `abc`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("caret2 valid case 2", async () => { + const inputStr = `bca`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("caret2 valid case 3", async () => { + const inputStr = `cab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("caret2 invalid case 1", async () => { + const inputStr = `7abc9mna`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("caret3 valid case 1", async () => { + const inputStr = `bb817267`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret3.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("caret3 valid case 2", async () => { + const inputStr = `818abbb9`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret3.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("caret3 invalid case 1", async () => { + const inputStr = `81b`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("caret4 valid case 1", async () => { + const inputStr = `xabaaabb`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit4.calculateWitness(circuitInputs); + await circuit4.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret4.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("caret4 valid case 2", async () => { + const inputStr = `xbaab82a`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit4.calculateWitness(circuitInputs); + await circuit4.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret4.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("caret4 valid case 3", async () => { + const inputStr = `7w1\nxabb`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit4.calculateWitness(circuitInputs); + await circuit4.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret4.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("caret4 valid case 4", async () => { + const inputStr = `7w\nxbbb9`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit4.calculateWitness(circuitInputs); + await circuit4.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret4.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + + it("caret4 invalid case 1", async () => { + const inputStr = `7w1nxaba`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit4.calculateWitness(circuitInputs); + await circuit4.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("caret4 invalid case 2", async () => { + const inputStr = `abba\nx`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit4.calculateWitness(circuitInputs); + await circuit4.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("caret5 valid case 1", async () => { + const inputStr = `xdefabc1`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit5.calculateWitness(circuitInputs); + await circuit5.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret5.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("caret5 valid case 2", async () => { + const inputStr = `9\nx9eabc`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit5.calculateWitness(circuitInputs); + await circuit5.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/caret5.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("caret5 invalid case 1", async () => { + const inputStr = `xabc`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit5.calculateWitness(circuitInputs); + await circuit5.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("caret5 invalid case 2", async () => { + const inputStr = `1\ndef`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit5.calculateWitness(circuitInputs); + await circuit5.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + + + it("caret5 invalid case 3", async () => { + const inputStr = `a8abc8`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit5.calculateWitness(circuitInputs); + await circuit5.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("caret5 invalid case 4", async () => { + const inputStr = `71\na81ma`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit5.calculateWitness(circuitInputs); + await circuit5.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + +}); diff --git a/packages/circom/tests/circuits/asterisk1.json b/packages/circom/tests/circuits/asterisk1.json new file mode 100644 index 0000000..474215e --- /dev/null +++ b/packages/circom/tests/circuits/asterisk1.json @@ -0,0 +1,16 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "x" + }, + { + "is_public": true, + "regex_def": "a*" + }, + { + "is_public": false, + "regex_def": "b" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/asterisk1_regex.circom b/packages/circom/tests/circuits/asterisk1_regex.circom new file mode 100644 index 0000000..84cfa9d --- /dev/null +++ b/packages/circom/tests/circuits/asterisk1_regex.circom @@ -0,0 +1,82 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: xa*b +template Asterisk1Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[3][num_bytes]; + component and[3][num_bytes]; + signal states[num_bytes+1][3]; + signal states_tmp[num_bytes+1][3]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 3; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(2); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 120; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 97; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + and[1][i].b <== eq[1][i].out; + states_tmp[i+1][1] <== and[1][i].out; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 98; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== eq[2][i].out; + states[i+1][2] <== and[2][i].out; + from_zero_enabled[i] <== MultiNOR(2)([states_tmp[i+1][1], states[i+1][2]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][2]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][2] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][2], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(1, 1)}] + signal prev_states0[1][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(1, 1)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + is_substr0[i] <== MultiOR(1)([prev_states0[0][i] * states[i+2][1]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/asterisk2.json b/packages/circom/tests/circuits/asterisk2.json new file mode 100644 index 0000000..45ecec7 --- /dev/null +++ b/packages/circom/tests/circuits/asterisk2.json @@ -0,0 +1,12 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "a" + }, + { + "is_public": true, + "regex_def": "b*" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/asterisk2_regex.circom b/packages/circom/tests/circuits/asterisk2_regex.circom new file mode 100644 index 0000000..5c82fbc --- /dev/null +++ b/packages/circom/tests/circuits/asterisk2_regex.circom @@ -0,0 +1,74 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: ab* +template Asterisk2Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[2][num_bytes]; + component and[2][num_bytes]; + signal states[num_bytes+1][2]; + signal states_tmp[num_bytes+1][2]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 2; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(1); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 97; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 98; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + and[1][i].b <== eq[1][i].out; + states_tmp[i+1][1] <== and[1][i].out; + from_zero_enabled[i] <== MultiNOR(1)([states_tmp[i+1][1]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][1]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][1] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][1], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(1, 1)}] + signal prev_states0[1][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(1, 1)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + is_substr0[i] <== MultiOR(1)([prev_states0[0][i] * states[i+2][1]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/asterisk3.json b/packages/circom/tests/circuits/asterisk3.json new file mode 100644 index 0000000..6406bae --- /dev/null +++ b/packages/circom/tests/circuits/asterisk3.json @@ -0,0 +1,16 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "a" + }, + { + "is_public": true, + "regex_def": "(x|y)*" + }, + { + "is_public": false, + "regex_def": "b" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/asterisk3_regex.circom b/packages/circom/tests/circuits/asterisk3_regex.circom new file mode 100644 index 0000000..29b5ecd --- /dev/null +++ b/packages/circom/tests/circuits/asterisk3_regex.circom @@ -0,0 +1,89 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: a(x|y)*b +template Asterisk3Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[4][num_bytes]; + component and[3][num_bytes]; + component multi_or[1][num_bytes]; + signal states[num_bytes+1][3]; + signal states_tmp[num_bytes+1][3]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 3; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(2); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 97; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 120; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 121; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== eq[1][i].out; + multi_or[0][i].in[1] <== eq[2][i].out; + and[1][i].b <== multi_or[0][i].out; + states_tmp[i+1][1] <== and[1][i].out; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 98; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== eq[3][i].out; + states[i+1][2] <== and[2][i].out; + from_zero_enabled[i] <== MultiNOR(2)([states_tmp[i+1][1], states[i+1][2]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][2]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][2] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][2], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(1, 1)}] + signal prev_states0[1][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(1, 1)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + is_substr0[i] <== MultiOR(1)([prev_states0[0][i] * states[i+2][1]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/caret1.json b/packages/circom/tests/circuits/caret1.json new file mode 100644 index 0000000..758524a --- /dev/null +++ b/packages/circom/tests/circuits/caret1.json @@ -0,0 +1,8 @@ +{ + "parts": [ + { + "is_public": true, + "regex_def": "^a" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/caret1_regex.circom b/packages/circom/tests/circuits/caret1_regex.circom new file mode 100644 index 0000000..c308f41 --- /dev/null +++ b/packages/circom/tests/circuits/caret1_regex.circom @@ -0,0 +1,76 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: ^a +template Caret1Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[2][num_bytes]; + component and[2][num_bytes]; + signal states[num_bytes+1][3]; + signal states_tmp[num_bytes+1][3]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 3; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(2); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 255; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 97; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + and[1][i].b <== eq[1][i].out; + states[i+1][2] <== and[1][i].out; + from_zero_enabled[i] <== MultiNOR(2)([states_tmp[i+1][1], states[i+1][2]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][2]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][2] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][2], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(1, 2)}] + signal prev_states0[1][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(1, 2)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + is_substr0[i] <== MultiOR(1)([prev_states0[0][i] * states[i+2][2]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/caret2.json b/packages/circom/tests/circuits/caret2.json new file mode 100644 index 0000000..38c744f --- /dev/null +++ b/packages/circom/tests/circuits/caret2.json @@ -0,0 +1,8 @@ +{ + "parts": [ + { + "is_public": true, + "regex_def": "^(a|b|c)" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/caret2_regex.circom b/packages/circom/tests/circuits/caret2_regex.circom new file mode 100644 index 0000000..4da9f95 --- /dev/null +++ b/packages/circom/tests/circuits/caret2_regex.circom @@ -0,0 +1,87 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: ^(a|b|c) +template Caret2Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[4][num_bytes]; + component and[2][num_bytes]; + component multi_or[1][num_bytes]; + signal states[num_bytes+1][3]; + signal states_tmp[num_bytes+1][3]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 3; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(2); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 255; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 97; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 98; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 99; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + multi_or[0][i] = MultiOR(3); + multi_or[0][i].in[0] <== eq[1][i].out; + multi_or[0][i].in[1] <== eq[2][i].out; + multi_or[0][i].in[2] <== eq[3][i].out; + and[1][i].b <== multi_or[0][i].out; + states[i+1][2] <== and[1][i].out; + from_zero_enabled[i] <== MultiNOR(2)([states_tmp[i+1][1], states[i+1][2]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][2]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][2] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][2], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(1, 2)}] + signal prev_states0[1][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(1, 2)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + is_substr0[i] <== MultiOR(1)([prev_states0[0][i] * states[i+2][2]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/caret3.json b/packages/circom/tests/circuits/caret3.json new file mode 100644 index 0000000..8d1c6e6 --- /dev/null +++ b/packages/circom/tests/circuits/caret3.json @@ -0,0 +1,12 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "(^|a)" + }, + { + "is_public": true, + "regex_def": "b+" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/caret3_regex.circom b/packages/circom/tests/circuits/caret3_regex.circom new file mode 100644 index 0000000..9cf377d --- /dev/null +++ b/packages/circom/tests/circuits/caret3_regex.circom @@ -0,0 +1,90 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: (^|a)b+ +template Caret3Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[3][num_bytes]; + component and[3][num_bytes]; + component multi_or[2][num_bytes]; + signal states[num_bytes+1][3]; + signal states_tmp[num_bytes+1][3]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 3; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(2); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 97; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 255; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== eq[0][i].out; + multi_or[0][i].in[1] <== eq[1][i].out; + and[0][i].b <== multi_or[0][i].out; + states_tmp[i+1][1] <== 0; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 98; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + and[1][i].b <== eq[2][i].out; + and[2][i] = AND(); + and[2][i].a <== states[i][2]; + and[2][i].b <== eq[2][i].out; + multi_or[1][i] = MultiOR(2); + multi_or[1][i].in[0] <== and[1][i].out; + multi_or[1][i].in[1] <== and[2][i].out; + states[i+1][2] <== multi_or[1][i].out; + from_zero_enabled[i] <== MultiNOR(2)([states_tmp[i+1][1], states[i+1][2]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][2]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][2] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][2], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(1, 2), (2, 2)}] + signal prev_states0[2][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(1, 2), (2, 2)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + is_substr0[i] <== MultiOR(2)([prev_states0[0][i] * states[i+2][2], prev_states0[1][i] * states[i+2][2]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/caret4.json b/packages/circom/tests/circuits/caret4.json new file mode 100644 index 0000000..a8d097f --- /dev/null +++ b/packages/circom/tests/circuits/caret4.json @@ -0,0 +1,12 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "(\n|^)x" + }, + { + "is_public": true, + "regex_def": "(a|b)+" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/caret4_regex.circom b/packages/circom/tests/circuits/caret4_regex.circom new file mode 100644 index 0000000..79f53c2 --- /dev/null +++ b/packages/circom/tests/circuits/caret4_regex.circom @@ -0,0 +1,104 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: (\n|^)x(a|b)+ +template Caret4Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[5][num_bytes]; + component and[4][num_bytes]; + component multi_or[3][num_bytes]; + signal states[num_bytes+1][4]; + signal states_tmp[num_bytes+1][4]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 4; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(3); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 10; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 255; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== eq[0][i].out; + multi_or[0][i].in[1] <== eq[1][i].out; + and[0][i].b <== multi_or[0][i].out; + states_tmp[i+1][1] <== 0; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 120; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + and[1][i].b <== eq[2][i].out; + states[i+1][2] <== and[1][i].out; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 97; + eq[4][i] = IsEqual(); + eq[4][i].in[0] <== in[i]; + eq[4][i].in[1] <== 98; + and[2][i] = AND(); + and[2][i].a <== states[i][2]; + multi_or[1][i] = MultiOR(2); + multi_or[1][i].in[0] <== eq[3][i].out; + multi_or[1][i].in[1] <== eq[4][i].out; + and[2][i].b <== multi_or[1][i].out; + and[3][i] = AND(); + and[3][i].a <== states[i][3]; + and[3][i].b <== multi_or[1][i].out; + multi_or[2][i] = MultiOR(2); + multi_or[2][i].in[0] <== and[2][i].out; + multi_or[2][i].in[1] <== and[3][i].out; + states[i+1][3] <== multi_or[2][i].out; + from_zero_enabled[i] <== MultiNOR(3)([states_tmp[i+1][1], states[i+1][2], states[i+1][3]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][3]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][3] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][3], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(2, 3), (3, 3)}] + signal prev_states0[2][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(2, 3), (3, 3)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + is_substr0[i] <== MultiOR(2)([prev_states0[0][i] * states[i+2][3], prev_states0[1][i] * states[i+2][3]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/caret5.json b/packages/circom/tests/circuits/caret5.json new file mode 100644 index 0000000..6d18627 --- /dev/null +++ b/packages/circom/tests/circuits/caret5.json @@ -0,0 +1,12 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "(\n|^)x" + }, + { + "is_public": true, + "regex_def": "[^abc]+" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/caret5_regex.circom b/packages/circom/tests/circuits/caret5_regex.circom new file mode 100644 index 0000000..6bcbda4 --- /dev/null +++ b/packages/circom/tests/circuits/caret5_regex.circom @@ -0,0 +1,435 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: (\n|^)x[^abc]+ +template Caret5Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[40][num_bytes]; + component lt[14][num_bytes]; + component and[32][num_bytes]; + component multi_or[13][num_bytes]; + signal states[num_bytes+1][11]; + signal states_tmp[num_bytes+1][11]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 11; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(10); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 10; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 255; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== eq[0][i].out; + multi_or[0][i].in[1] <== eq[1][i].out; + and[0][i].b <== multi_or[0][i].out; + states_tmp[i+1][1] <== 0; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 120; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + and[1][i].b <== eq[2][i].out; + states[i+1][2] <== and[1][i].out; + lt[0][i] = LessEqThan(8); + lt[0][i].in[0] <== 194; + lt[0][i].in[1] <== in[i]; + lt[1][i] = LessEqThan(8); + lt[1][i].in[0] <== in[i]; + lt[1][i].in[1] <== 223; + and[2][i] = AND(); + and[2][i].a <== lt[0][i].out; + and[2][i].b <== lt[1][i].out; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== and[2][i].out; + lt[2][i] = LessEqThan(8); + lt[2][i].in[0] <== 160; + lt[2][i].in[1] <== in[i]; + lt[3][i] = LessEqThan(8); + lt[3][i].in[0] <== in[i]; + lt[3][i].in[1] <== 191; + and[4][i] = AND(); + and[4][i].a <== lt[2][i].out; + and[4][i].b <== lt[3][i].out; + and[5][i] = AND(); + and[5][i].a <== states[i][4]; + and[5][i].b <== and[4][i].out; + lt[4][i] = LessEqThan(8); + lt[4][i].in[0] <== 128; + lt[4][i].in[1] <== in[i]; + lt[5][i] = LessEqThan(8); + lt[5][i].in[0] <== in[i]; + lt[5][i].in[1] <== 191; + and[6][i] = AND(); + and[6][i].a <== lt[4][i].out; + and[6][i].b <== lt[5][i].out; + and[7][i] = AND(); + and[7][i].a <== states[i][5]; + and[7][i].b <== and[6][i].out; + lt[6][i] = LessEqThan(8); + lt[6][i].in[0] <== 128; + lt[6][i].in[1] <== in[i]; + lt[7][i] = LessEqThan(8); + lt[7][i].in[0] <== in[i]; + lt[7][i].in[1] <== 159; + and[8][i] = AND(); + and[8][i].a <== lt[6][i].out; + and[8][i].b <== lt[7][i].out; + and[9][i] = AND(); + and[9][i].a <== states[i][6]; + and[9][i].b <== and[8][i].out; + and[10][i] = AND(); + and[10][i].a <== states[i][10]; + and[10][i].b <== and[2][i].out; + multi_or[1][i] = MultiOR(5); + multi_or[1][i].in[0] <== and[3][i].out; + multi_or[1][i].in[1] <== and[5][i].out; + multi_or[1][i].in[2] <== and[7][i].out; + multi_or[1][i].in[3] <== and[9][i].out; + multi_or[1][i].in[4] <== and[10][i].out; + states[i+1][3] <== multi_or[1][i].out; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 224; + and[11][i] = AND(); + and[11][i].a <== states[i][2]; + and[11][i].b <== eq[3][i].out; + and[12][i] = AND(); + and[12][i].a <== states[i][10]; + and[12][i].b <== eq[3][i].out; + multi_or[2][i] = MultiOR(2); + multi_or[2][i].in[0] <== and[11][i].out; + multi_or[2][i].in[1] <== and[12][i].out; + states[i+1][4] <== multi_or[2][i].out; + eq[4][i] = IsEqual(); + eq[4][i].in[0] <== in[i]; + eq[4][i].in[1] <== 225; + eq[5][i] = IsEqual(); + eq[5][i].in[0] <== in[i]; + eq[5][i].in[1] <== 226; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 227; + eq[7][i] = IsEqual(); + eq[7][i].in[0] <== in[i]; + eq[7][i].in[1] <== 228; + eq[8][i] = IsEqual(); + eq[8][i].in[0] <== in[i]; + eq[8][i].in[1] <== 229; + eq[9][i] = IsEqual(); + eq[9][i].in[0] <== in[i]; + eq[9][i].in[1] <== 230; + eq[10][i] = IsEqual(); + eq[10][i].in[0] <== in[i]; + eq[10][i].in[1] <== 231; + eq[11][i] = IsEqual(); + eq[11][i].in[0] <== in[i]; + eq[11][i].in[1] <== 232; + eq[12][i] = IsEqual(); + eq[12][i].in[0] <== in[i]; + eq[12][i].in[1] <== 233; + eq[13][i] = IsEqual(); + eq[13][i].in[0] <== in[i]; + eq[13][i].in[1] <== 234; + eq[14][i] = IsEqual(); + eq[14][i].in[0] <== in[i]; + eq[14][i].in[1] <== 235; + eq[15][i] = IsEqual(); + eq[15][i].in[0] <== in[i]; + eq[15][i].in[1] <== 236; + eq[16][i] = IsEqual(); + eq[16][i].in[0] <== in[i]; + eq[16][i].in[1] <== 238; + eq[17][i] = IsEqual(); + eq[17][i].in[0] <== in[i]; + eq[17][i].in[1] <== 239; + and[13][i] = AND(); + and[13][i].a <== states[i][2]; + multi_or[3][i] = MultiOR(14); + multi_or[3][i].in[0] <== eq[4][i].out; + multi_or[3][i].in[1] <== eq[5][i].out; + multi_or[3][i].in[2] <== eq[6][i].out; + multi_or[3][i].in[3] <== eq[7][i].out; + multi_or[3][i].in[4] <== eq[8][i].out; + multi_or[3][i].in[5] <== eq[9][i].out; + multi_or[3][i].in[6] <== eq[10][i].out; + multi_or[3][i].in[7] <== eq[11][i].out; + multi_or[3][i].in[8] <== eq[12][i].out; + multi_or[3][i].in[9] <== eq[13][i].out; + multi_or[3][i].in[10] <== eq[14][i].out; + multi_or[3][i].in[11] <== eq[15][i].out; + multi_or[3][i].in[12] <== eq[16][i].out; + multi_or[3][i].in[13] <== eq[17][i].out; + and[13][i].b <== multi_or[3][i].out; + lt[8][i] = LessEqThan(8); + lt[8][i].in[0] <== 144; + lt[8][i].in[1] <== in[i]; + lt[9][i] = LessEqThan(8); + lt[9][i].in[0] <== in[i]; + lt[9][i].in[1] <== 191; + and[14][i] = AND(); + and[14][i].a <== lt[8][i].out; + and[14][i].b <== lt[9][i].out; + and[15][i] = AND(); + and[15][i].a <== states[i][7]; + and[15][i].b <== and[14][i].out; + and[16][i] = AND(); + and[16][i].a <== states[i][8]; + and[16][i].b <== and[6][i].out; + eq[18][i] = IsEqual(); + eq[18][i].in[0] <== in[i]; + eq[18][i].in[1] <== 128; + eq[19][i] = IsEqual(); + eq[19][i].in[0] <== in[i]; + eq[19][i].in[1] <== 129; + eq[20][i] = IsEqual(); + eq[20][i].in[0] <== in[i]; + eq[20][i].in[1] <== 130; + eq[21][i] = IsEqual(); + eq[21][i].in[0] <== in[i]; + eq[21][i].in[1] <== 131; + eq[22][i] = IsEqual(); + eq[22][i].in[0] <== in[i]; + eq[22][i].in[1] <== 132; + eq[23][i] = IsEqual(); + eq[23][i].in[0] <== in[i]; + eq[23][i].in[1] <== 133; + eq[24][i] = IsEqual(); + eq[24][i].in[0] <== in[i]; + eq[24][i].in[1] <== 134; + eq[25][i] = IsEqual(); + eq[25][i].in[0] <== in[i]; + eq[25][i].in[1] <== 135; + eq[26][i] = IsEqual(); + eq[26][i].in[0] <== in[i]; + eq[26][i].in[1] <== 136; + eq[27][i] = IsEqual(); + eq[27][i].in[0] <== in[i]; + eq[27][i].in[1] <== 137; + eq[28][i] = IsEqual(); + eq[28][i].in[0] <== in[i]; + eq[28][i].in[1] <== 138; + eq[29][i] = IsEqual(); + eq[29][i].in[0] <== in[i]; + eq[29][i].in[1] <== 139; + eq[30][i] = IsEqual(); + eq[30][i].in[0] <== in[i]; + eq[30][i].in[1] <== 140; + eq[31][i] = IsEqual(); + eq[31][i].in[0] <== in[i]; + eq[31][i].in[1] <== 141; + eq[32][i] = IsEqual(); + eq[32][i].in[0] <== in[i]; + eq[32][i].in[1] <== 142; + eq[33][i] = IsEqual(); + eq[33][i].in[0] <== in[i]; + eq[33][i].in[1] <== 143; + and[17][i] = AND(); + and[17][i].a <== states[i][9]; + multi_or[4][i] = MultiOR(16); + multi_or[4][i].in[0] <== eq[18][i].out; + multi_or[4][i].in[1] <== eq[19][i].out; + multi_or[4][i].in[2] <== eq[20][i].out; + multi_or[4][i].in[3] <== eq[21][i].out; + multi_or[4][i].in[4] <== eq[22][i].out; + multi_or[4][i].in[5] <== eq[23][i].out; + multi_or[4][i].in[6] <== eq[24][i].out; + multi_or[4][i].in[7] <== eq[25][i].out; + multi_or[4][i].in[8] <== eq[26][i].out; + multi_or[4][i].in[9] <== eq[27][i].out; + multi_or[4][i].in[10] <== eq[28][i].out; + multi_or[4][i].in[11] <== eq[29][i].out; + multi_or[4][i].in[12] <== eq[30][i].out; + multi_or[4][i].in[13] <== eq[31][i].out; + multi_or[4][i].in[14] <== eq[32][i].out; + multi_or[4][i].in[15] <== eq[33][i].out; + and[17][i].b <== multi_or[4][i].out; + and[18][i] = AND(); + and[18][i].a <== states[i][10]; + and[18][i].b <== multi_or[3][i].out; + multi_or[5][i] = MultiOR(5); + multi_or[5][i].in[0] <== and[13][i].out; + multi_or[5][i].in[1] <== and[15][i].out; + multi_or[5][i].in[2] <== and[16][i].out; + multi_or[5][i].in[3] <== and[17][i].out; + multi_or[5][i].in[4] <== and[18][i].out; + states[i+1][5] <== multi_or[5][i].out; + eq[34][i] = IsEqual(); + eq[34][i].in[0] <== in[i]; + eq[34][i].in[1] <== 237; + and[19][i] = AND(); + and[19][i].a <== states[i][2]; + and[19][i].b <== eq[34][i].out; + and[20][i] = AND(); + and[20][i].a <== states[i][10]; + and[20][i].b <== eq[34][i].out; + multi_or[6][i] = MultiOR(2); + multi_or[6][i].in[0] <== and[19][i].out; + multi_or[6][i].in[1] <== and[20][i].out; + states[i+1][6] <== multi_or[6][i].out; + eq[35][i] = IsEqual(); + eq[35][i].in[0] <== in[i]; + eq[35][i].in[1] <== 240; + and[21][i] = AND(); + and[21][i].a <== states[i][2]; + and[21][i].b <== eq[35][i].out; + and[22][i] = AND(); + and[22][i].a <== states[i][10]; + and[22][i].b <== eq[35][i].out; + multi_or[7][i] = MultiOR(2); + multi_or[7][i].in[0] <== and[21][i].out; + multi_or[7][i].in[1] <== and[22][i].out; + states[i+1][7] <== multi_or[7][i].out; + eq[36][i] = IsEqual(); + eq[36][i].in[0] <== in[i]; + eq[36][i].in[1] <== 241; + eq[37][i] = IsEqual(); + eq[37][i].in[0] <== in[i]; + eq[37][i].in[1] <== 242; + eq[38][i] = IsEqual(); + eq[38][i].in[0] <== in[i]; + eq[38][i].in[1] <== 243; + and[23][i] = AND(); + and[23][i].a <== states[i][2]; + multi_or[8][i] = MultiOR(3); + multi_or[8][i].in[0] <== eq[36][i].out; + multi_or[8][i].in[1] <== eq[37][i].out; + multi_or[8][i].in[2] <== eq[38][i].out; + and[23][i].b <== multi_or[8][i].out; + and[24][i] = AND(); + and[24][i].a <== states[i][10]; + and[24][i].b <== multi_or[8][i].out; + multi_or[9][i] = MultiOR(2); + multi_or[9][i].in[0] <== and[23][i].out; + multi_or[9][i].in[1] <== and[24][i].out; + states[i+1][8] <== multi_or[9][i].out; + eq[39][i] = IsEqual(); + eq[39][i].in[0] <== in[i]; + eq[39][i].in[1] <== 244; + and[25][i] = AND(); + and[25][i].a <== states[i][2]; + and[25][i].b <== eq[39][i].out; + and[26][i] = AND(); + and[26][i].a <== states[i][10]; + and[26][i].b <== eq[39][i].out; + multi_or[10][i] = MultiOR(2); + multi_or[10][i].in[0] <== and[25][i].out; + multi_or[10][i].in[1] <== and[26][i].out; + states[i+1][9] <== multi_or[10][i].out; + lt[10][i] = LessEqThan(8); + lt[10][i].in[0] <== 1; + lt[10][i].in[1] <== in[i]; + lt[11][i] = LessEqThan(8); + lt[11][i].in[0] <== in[i]; + lt[11][i].in[1] <== 96; + and[27][i] = AND(); + and[27][i].a <== lt[10][i].out; + and[27][i].b <== lt[11][i].out; + lt[12][i] = LessEqThan(8); + lt[12][i].in[0] <== 100; + lt[12][i].in[1] <== in[i]; + lt[13][i] = LessEqThan(8); + lt[13][i].in[0] <== in[i]; + lt[13][i].in[1] <== 127; + and[28][i] = AND(); + and[28][i].a <== lt[12][i].out; + and[28][i].b <== lt[13][i].out; + and[29][i] = AND(); + and[29][i].a <== states[i][2]; + multi_or[11][i] = MultiOR(2); + multi_or[11][i].in[0] <== and[27][i].out; + multi_or[11][i].in[1] <== and[28][i].out; + and[29][i].b <== multi_or[11][i].out; + and[30][i] = AND(); + and[30][i].a <== states[i][3]; + and[30][i].b <== and[6][i].out; + and[31][i] = AND(); + and[31][i].a <== states[i][10]; + and[31][i].b <== multi_or[11][i].out; + multi_or[12][i] = MultiOR(3); + multi_or[12][i].in[0] <== and[29][i].out; + multi_or[12][i].in[1] <== and[30][i].out; + multi_or[12][i].in[2] <== and[31][i].out; + states[i+1][10] <== multi_or[12][i].out; + from_zero_enabled[i] <== MultiNOR(10)([states_tmp[i+1][1], states[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7], states[i+1][8], states[i+1][9], states[i+1][10]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + state_changed[i].in[3] <== states[i+1][4]; + state_changed[i].in[4] <== states[i+1][5]; + state_changed[i].in[5] <== states[i+1][6]; + state_changed[i].in[6] <== states[i+1][7]; + state_changed[i].in[7] <== states[i+1][8]; + state_changed[i].in[8] <== states[i+1][9]; + state_changed[i].in[9] <== states[i+1][10]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][10]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][10] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][10], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 10), (4, 3), (5, 3), (6, 3), (7, 5), (8, 5), (9, 5), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9), (10, 10)}] + signal prev_states0[23][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 10), (4, 3), (5, 3), (6, 3), (7, 5), (8, 5), (9, 5), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9), (10, 10)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[6][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[7][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + prev_states0[9][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][4]; + prev_states0[10][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[11][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][6]; + prev_states0[12][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + prev_states0[13][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][8]; + prev_states0[14][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][9]; + prev_states0[15][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[16][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[17][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[18][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[19][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[20][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[21][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[22][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + is_substr0[i] <== MultiOR(23)([prev_states0[0][i] * states[i+2][3], prev_states0[1][i] * states[i+2][4], prev_states0[2][i] * states[i+2][5], prev_states0[3][i] * states[i+2][6], prev_states0[4][i] * states[i+2][7], prev_states0[5][i] * states[i+2][8], prev_states0[6][i] * states[i+2][9], prev_states0[7][i] * states[i+2][10], prev_states0[8][i] * states[i+2][10], prev_states0[9][i] * states[i+2][3], prev_states0[10][i] * states[i+2][3], prev_states0[11][i] * states[i+2][3], prev_states0[12][i] * states[i+2][5], prev_states0[13][i] * states[i+2][5], prev_states0[14][i] * states[i+2][5], prev_states0[15][i] * states[i+2][3], prev_states0[16][i] * states[i+2][4], prev_states0[17][i] * states[i+2][5], prev_states0[18][i] * states[i+2][6], prev_states0[19][i] * states[i+2][7], prev_states0[20][i] * states[i+2][8], prev_states0[21][i] * states[i+2][9], prev_states0[22][i] * states[i+2][10]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/dollar1.json b/packages/circom/tests/circuits/dollar1.json new file mode 100644 index 0000000..6b1546c --- /dev/null +++ b/packages/circom/tests/circuits/dollar1.json @@ -0,0 +1,8 @@ +{ + "parts": [ + { + "is_public": true, + "regex_def": "a[bc]$" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/dollar1_regex.circom b/packages/circom/tests/circuits/dollar1_regex.circom new file mode 100644 index 0000000..e8e8aee --- /dev/null +++ b/packages/circom/tests/circuits/dollar1_regex.circom @@ -0,0 +1,93 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: a[bc]$ +template Dollar1Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[3][num_bytes]; + component and[2][num_bytes]; + component multi_or[1][num_bytes]; + signal states[num_bytes+1][3]; + signal states_tmp[num_bytes+1][3]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + signal padding_start[num_bytes+1]; + padding_start[0] <== 0; + for (var i = 1; i < 3; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(2); + states[i][0] <== 1; + padding_start[i+1] <== IsNotZeroAcc()(padding_start[i], in[i]); + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 97; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 98; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 99; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== eq[1][i].out; + multi_or[0][i].in[1] <== eq[2][i].out; + and[1][i].b <== multi_or[0][i].out; + states[i+1][2] <== and[1][i].out; + from_zero_enabled[i] <== MultiNOR(2)([states_tmp[i+1][1], states[i+1][2]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][2]; + } + signal end_anchor_check[num_bytes+1][2]; + end_anchor_check[0][1] <== 0; + for (var i = 0; i < num_bytes; i++) { + end_anchor_check[i+1][0] <== IsEqual()([i, padding_start[num_bytes]]); + end_anchor_check[i+1][1] <== end_anchor_check[i][1] + states[i][2] * end_anchor_check[i+1][0]; + } + out <== is_accepted.out * end_anchor_check[num_bytes][1]; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][2] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][2], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(0, 1), (1, 2)}] + signal prev_states0[2][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(0, 1), (1, 2)] + prev_states0[0][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + is_substr0[i] <== MultiOR(2)([prev_states0[0][i] * states[i+2][1], prev_states0[1][i] * states[i+2][2]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/dollar2.json b/packages/circom/tests/circuits/dollar2.json new file mode 100644 index 0000000..0b5adb3 --- /dev/null +++ b/packages/circom/tests/circuits/dollar2.json @@ -0,0 +1,12 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "(\n|^)x" + }, + { + "is_public": true, + "regex_def": "a[bc]$" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/dollar2_regex.circom b/packages/circom/tests/circuits/dollar2_regex.circom new file mode 100644 index 0000000..6a621a3 --- /dev/null +++ b/packages/circom/tests/circuits/dollar2_regex.circom @@ -0,0 +1,115 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: (\n|^)xa[bc]$ +template Dollar2Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[6][num_bytes]; + component and[4][num_bytes]; + component multi_or[2][num_bytes]; + signal states[num_bytes+1][5]; + signal states_tmp[num_bytes+1][5]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + signal padding_start[num_bytes+1]; + padding_start[0] <== 0; + for (var i = 1; i < 5; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(4); + states[i][0] <== 1; + padding_start[i+1] <== IsNotZeroAcc()(padding_start[i], in[i]); + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 10; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 255; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== eq[0][i].out; + multi_or[0][i].in[1] <== eq[1][i].out; + and[0][i].b <== multi_or[0][i].out; + states_tmp[i+1][1] <== 0; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 120; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + and[1][i].b <== eq[2][i].out; + states[i+1][2] <== and[1][i].out; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 97; + and[2][i] = AND(); + and[2][i].a <== states[i][2]; + and[2][i].b <== eq[3][i].out; + states[i+1][3] <== and[2][i].out; + eq[4][i] = IsEqual(); + eq[4][i].in[0] <== in[i]; + eq[4][i].in[1] <== 98; + eq[5][i] = IsEqual(); + eq[5][i].in[0] <== in[i]; + eq[5][i].in[1] <== 99; + and[3][i] = AND(); + and[3][i].a <== states[i][3]; + multi_or[1][i] = MultiOR(2); + multi_or[1][i].in[0] <== eq[4][i].out; + multi_or[1][i].in[1] <== eq[5][i].out; + and[3][i].b <== multi_or[1][i].out; + states[i+1][4] <== and[3][i].out; + from_zero_enabled[i] <== MultiNOR(4)([states_tmp[i+1][1], states[i+1][2], states[i+1][3], states[i+1][4]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + state_changed[i].in[3] <== states[i+1][4]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][4]; + } + signal end_anchor_check[num_bytes+1][2]; + end_anchor_check[0][1] <== 0; + for (var i = 0; i < num_bytes; i++) { + end_anchor_check[i+1][0] <== IsEqual()([i, padding_start[num_bytes]]); + end_anchor_check[i+1][1] <== end_anchor_check[i][1] + states[i][4] * end_anchor_check[i+1][0]; + } + out <== is_accepted.out * end_anchor_check[num_bytes][1]; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][4] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][4], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(2, 3), (3, 4)}] + signal prev_states0[2][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(2, 3), (3, 4)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + is_substr0[i] <== MultiOR(2)([prev_states0[0][i] * states[i+2][3], prev_states0[1][i] * states[i+2][4]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/dot1.json b/packages/circom/tests/circuits/dot1.json new file mode 100644 index 0000000..c411676 --- /dev/null +++ b/packages/circom/tests/circuits/dot1.json @@ -0,0 +1,8 @@ +{ + "parts": [ + { + "is_public": true, + "regex_def": "." + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/dot1_regex.circom b/packages/circom/tests/circuits/dot1_regex.circom new file mode 100644 index 0000000..774b9a0 --- /dev/null +++ b/packages/circom/tests/circuits/dot1_regex.circom @@ -0,0 +1,391 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: . +template Dot1Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[46][num_bytes]; + component lt[12][num_bytes]; + component and[21][num_bytes]; + component multi_or[6][num_bytes]; + signal states[num_bytes+1][9]; + signal states_tmp[num_bytes+1][9]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 9; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(8); + states[i][0] <== 1; + lt[0][i] = LessEqThan(8); + lt[0][i].in[0] <== 194; + lt[0][i].in[1] <== in[i]; + lt[1][i] = LessEqThan(8); + lt[1][i].in[0] <== in[i]; + lt[1][i].in[1] <== 223; + and[0][i] = AND(); + and[0][i].a <== lt[0][i].out; + and[0][i].b <== lt[1][i].out; + and[1][i] = AND(); + and[1][i].a <== states[i][0]; + and[1][i].b <== and[0][i].out; + lt[2][i] = LessEqThan(8); + lt[2][i].in[0] <== 160; + lt[2][i].in[1] <== in[i]; + lt[3][i] = LessEqThan(8); + lt[3][i].in[0] <== in[i]; + lt[3][i].in[1] <== 191; + and[2][i] = AND(); + and[2][i].a <== lt[2][i].out; + and[2][i].b <== lt[3][i].out; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== and[2][i].out; + lt[4][i] = LessEqThan(8); + lt[4][i].in[0] <== 128; + lt[4][i].in[1] <== in[i]; + lt[5][i] = LessEqThan(8); + lt[5][i].in[0] <== in[i]; + lt[5][i].in[1] <== 191; + and[4][i] = AND(); + and[4][i].a <== lt[4][i].out; + and[4][i].b <== lt[5][i].out; + and[5][i] = AND(); + and[5][i].a <== states[i][3]; + and[5][i].b <== and[4][i].out; + lt[6][i] = LessEqThan(8); + lt[6][i].in[0] <== 128; + lt[6][i].in[1] <== in[i]; + lt[7][i] = LessEqThan(8); + lt[7][i].in[0] <== in[i]; + lt[7][i].in[1] <== 159; + and[6][i] = AND(); + and[6][i].a <== lt[6][i].out; + and[6][i].b <== lt[7][i].out; + and[7][i] = AND(); + and[7][i].a <== states[i][4]; + and[7][i].b <== and[6][i].out; + multi_or[0][i] = MultiOR(3); + multi_or[0][i].in[0] <== and[3][i].out; + multi_or[0][i].in[1] <== and[5][i].out; + multi_or[0][i].in[2] <== and[7][i].out; + states_tmp[i+1][1] <== multi_or[0][i].out; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 224; + and[8][i] = AND(); + and[8][i].a <== states[i][0]; + and[8][i].b <== eq[0][i].out; + states_tmp[i+1][2] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 225; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 226; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 227; + eq[4][i] = IsEqual(); + eq[4][i].in[0] <== in[i]; + eq[4][i].in[1] <== 228; + eq[5][i] = IsEqual(); + eq[5][i].in[0] <== in[i]; + eq[5][i].in[1] <== 229; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 230; + eq[7][i] = IsEqual(); + eq[7][i].in[0] <== in[i]; + eq[7][i].in[1] <== 231; + eq[8][i] = IsEqual(); + eq[8][i].in[0] <== in[i]; + eq[8][i].in[1] <== 232; + eq[9][i] = IsEqual(); + eq[9][i].in[0] <== in[i]; + eq[9][i].in[1] <== 233; + eq[10][i] = IsEqual(); + eq[10][i].in[0] <== in[i]; + eq[10][i].in[1] <== 234; + eq[11][i] = IsEqual(); + eq[11][i].in[0] <== in[i]; + eq[11][i].in[1] <== 235; + eq[12][i] = IsEqual(); + eq[12][i].in[0] <== in[i]; + eq[12][i].in[1] <== 236; + eq[13][i] = IsEqual(); + eq[13][i].in[0] <== in[i]; + eq[13][i].in[1] <== 238; + eq[14][i] = IsEqual(); + eq[14][i].in[0] <== in[i]; + eq[14][i].in[1] <== 239; + and[9][i] = AND(); + and[9][i].a <== states[i][0]; + multi_or[1][i] = MultiOR(14); + multi_or[1][i].in[0] <== eq[1][i].out; + multi_or[1][i].in[1] <== eq[2][i].out; + multi_or[1][i].in[2] <== eq[3][i].out; + multi_or[1][i].in[3] <== eq[4][i].out; + multi_or[1][i].in[4] <== eq[5][i].out; + multi_or[1][i].in[5] <== eq[6][i].out; + multi_or[1][i].in[6] <== eq[7][i].out; + multi_or[1][i].in[7] <== eq[8][i].out; + multi_or[1][i].in[8] <== eq[9][i].out; + multi_or[1][i].in[9] <== eq[10][i].out; + multi_or[1][i].in[10] <== eq[11][i].out; + multi_or[1][i].in[11] <== eq[12][i].out; + multi_or[1][i].in[12] <== eq[13][i].out; + multi_or[1][i].in[13] <== eq[14][i].out; + and[9][i].b <== multi_or[1][i].out; + lt[8][i] = LessEqThan(8); + lt[8][i].in[0] <== 144; + lt[8][i].in[1] <== in[i]; + lt[9][i] = LessEqThan(8); + lt[9][i].in[0] <== in[i]; + lt[9][i].in[1] <== 191; + and[10][i] = AND(); + and[10][i].a <== lt[8][i].out; + and[10][i].b <== lt[9][i].out; + and[11][i] = AND(); + and[11][i].a <== states[i][5]; + and[11][i].b <== and[10][i].out; + and[12][i] = AND(); + and[12][i].a <== states[i][6]; + and[12][i].b <== and[4][i].out; + eq[15][i] = IsEqual(); + eq[15][i].in[0] <== in[i]; + eq[15][i].in[1] <== 128; + eq[16][i] = IsEqual(); + eq[16][i].in[0] <== in[i]; + eq[16][i].in[1] <== 129; + eq[17][i] = IsEqual(); + eq[17][i].in[0] <== in[i]; + eq[17][i].in[1] <== 130; + eq[18][i] = IsEqual(); + eq[18][i].in[0] <== in[i]; + eq[18][i].in[1] <== 131; + eq[19][i] = IsEqual(); + eq[19][i].in[0] <== in[i]; + eq[19][i].in[1] <== 132; + eq[20][i] = IsEqual(); + eq[20][i].in[0] <== in[i]; + eq[20][i].in[1] <== 133; + eq[21][i] = IsEqual(); + eq[21][i].in[0] <== in[i]; + eq[21][i].in[1] <== 134; + eq[22][i] = IsEqual(); + eq[22][i].in[0] <== in[i]; + eq[22][i].in[1] <== 135; + eq[23][i] = IsEqual(); + eq[23][i].in[0] <== in[i]; + eq[23][i].in[1] <== 136; + eq[24][i] = IsEqual(); + eq[24][i].in[0] <== in[i]; + eq[24][i].in[1] <== 137; + eq[25][i] = IsEqual(); + eq[25][i].in[0] <== in[i]; + eq[25][i].in[1] <== 138; + eq[26][i] = IsEqual(); + eq[26][i].in[0] <== in[i]; + eq[26][i].in[1] <== 139; + eq[27][i] = IsEqual(); + eq[27][i].in[0] <== in[i]; + eq[27][i].in[1] <== 140; + eq[28][i] = IsEqual(); + eq[28][i].in[0] <== in[i]; + eq[28][i].in[1] <== 141; + eq[29][i] = IsEqual(); + eq[29][i].in[0] <== in[i]; + eq[29][i].in[1] <== 142; + eq[30][i] = IsEqual(); + eq[30][i].in[0] <== in[i]; + eq[30][i].in[1] <== 143; + and[13][i] = AND(); + and[13][i].a <== states[i][7]; + multi_or[2][i] = MultiOR(16); + multi_or[2][i].in[0] <== eq[15][i].out; + multi_or[2][i].in[1] <== eq[16][i].out; + multi_or[2][i].in[2] <== eq[17][i].out; + multi_or[2][i].in[3] <== eq[18][i].out; + multi_or[2][i].in[4] <== eq[19][i].out; + multi_or[2][i].in[5] <== eq[20][i].out; + multi_or[2][i].in[6] <== eq[21][i].out; + multi_or[2][i].in[7] <== eq[22][i].out; + multi_or[2][i].in[8] <== eq[23][i].out; + multi_or[2][i].in[9] <== eq[24][i].out; + multi_or[2][i].in[10] <== eq[25][i].out; + multi_or[2][i].in[11] <== eq[26][i].out; + multi_or[2][i].in[12] <== eq[27][i].out; + multi_or[2][i].in[13] <== eq[28][i].out; + multi_or[2][i].in[14] <== eq[29][i].out; + multi_or[2][i].in[15] <== eq[30][i].out; + and[13][i].b <== multi_or[2][i].out; + multi_or[3][i] = MultiOR(3); + multi_or[3][i].in[0] <== and[11][i].out; + multi_or[3][i].in[1] <== and[12][i].out; + multi_or[3][i].in[2] <== and[13][i].out; + states_tmp[i+1][3] <== multi_or[3][i].out; + eq[31][i] = IsEqual(); + eq[31][i].in[0] <== in[i]; + eq[31][i].in[1] <== 237; + and[14][i] = AND(); + and[14][i].a <== states[i][0]; + and[14][i].b <== eq[31][i].out; + states_tmp[i+1][4] <== 0; + eq[32][i] = IsEqual(); + eq[32][i].in[0] <== in[i]; + eq[32][i].in[1] <== 240; + and[15][i] = AND(); + and[15][i].a <== states[i][0]; + and[15][i].b <== eq[32][i].out; + states_tmp[i+1][5] <== 0; + eq[33][i] = IsEqual(); + eq[33][i].in[0] <== in[i]; + eq[33][i].in[1] <== 241; + eq[34][i] = IsEqual(); + eq[34][i].in[0] <== in[i]; + eq[34][i].in[1] <== 242; + eq[35][i] = IsEqual(); + eq[35][i].in[0] <== in[i]; + eq[35][i].in[1] <== 243; + and[16][i] = AND(); + and[16][i].a <== states[i][0]; + multi_or[4][i] = MultiOR(3); + multi_or[4][i].in[0] <== eq[33][i].out; + multi_or[4][i].in[1] <== eq[34][i].out; + multi_or[4][i].in[2] <== eq[35][i].out; + and[16][i].b <== multi_or[4][i].out; + states_tmp[i+1][6] <== 0; + eq[36][i] = IsEqual(); + eq[36][i].in[0] <== in[i]; + eq[36][i].in[1] <== 244; + and[17][i] = AND(); + and[17][i].a <== states[i][0]; + and[17][i].b <== eq[36][i].out; + states_tmp[i+1][7] <== 0; + lt[10][i] = LessEqThan(8); + lt[10][i].in[0] <== 11; + lt[10][i].in[1] <== in[i]; + lt[11][i] = LessEqThan(8); + lt[11][i].in[0] <== in[i]; + lt[11][i].in[1] <== 127; + and[18][i] = AND(); + and[18][i].a <== lt[10][i].out; + and[18][i].b <== lt[11][i].out; + eq[37][i] = IsEqual(); + eq[37][i].in[0] <== in[i]; + eq[37][i].in[1] <== 1; + eq[38][i] = IsEqual(); + eq[38][i].in[0] <== in[i]; + eq[38][i].in[1] <== 2; + eq[39][i] = IsEqual(); + eq[39][i].in[0] <== in[i]; + eq[39][i].in[1] <== 3; + eq[40][i] = IsEqual(); + eq[40][i].in[0] <== in[i]; + eq[40][i].in[1] <== 4; + eq[41][i] = IsEqual(); + eq[41][i].in[0] <== in[i]; + eq[41][i].in[1] <== 5; + eq[42][i] = IsEqual(); + eq[42][i].in[0] <== in[i]; + eq[42][i].in[1] <== 6; + eq[43][i] = IsEqual(); + eq[43][i].in[0] <== in[i]; + eq[43][i].in[1] <== 7; + eq[44][i] = IsEqual(); + eq[44][i].in[0] <== in[i]; + eq[44][i].in[1] <== 8; + eq[45][i] = IsEqual(); + eq[45][i].in[0] <== in[i]; + eq[45][i].in[1] <== 9; + and[19][i] = AND(); + and[19][i].a <== states[i][0]; + multi_or[5][i] = MultiOR(10); + multi_or[5][i].in[0] <== and[18][i].out; + multi_or[5][i].in[1] <== eq[37][i].out; + multi_or[5][i].in[2] <== eq[38][i].out; + multi_or[5][i].in[3] <== eq[39][i].out; + multi_or[5][i].in[4] <== eq[40][i].out; + multi_or[5][i].in[5] <== eq[41][i].out; + multi_or[5][i].in[6] <== eq[42][i].out; + multi_or[5][i].in[7] <== eq[43][i].out; + multi_or[5][i].in[8] <== eq[44][i].out; + multi_or[5][i].in[9] <== eq[45][i].out; + and[19][i].b <== multi_or[5][i].out; + and[20][i] = AND(); + and[20][i].a <== states[i][1]; + and[20][i].b <== and[4][i].out; + states_tmp[i+1][8] <== and[20][i].out; + from_zero_enabled[i] <== MultiNOR(8)([states_tmp[i+1][1], states_tmp[i+1][2], states_tmp[i+1][3], states_tmp[i+1][4], states_tmp[i+1][5], states_tmp[i+1][6], states_tmp[i+1][7], states_tmp[i+1][8]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[1][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[8][i].out]); + states[i+1][3] <== MultiOR(2)([states_tmp[i+1][3], from_zero_enabled[i] * and[9][i].out]); + states[i+1][4] <== MultiOR(2)([states_tmp[i+1][4], from_zero_enabled[i] * and[14][i].out]); + states[i+1][5] <== MultiOR(2)([states_tmp[i+1][5], from_zero_enabled[i] * and[15][i].out]); + states[i+1][6] <== MultiOR(2)([states_tmp[i+1][6], from_zero_enabled[i] * and[16][i].out]); + states[i+1][7] <== MultiOR(2)([states_tmp[i+1][7], from_zero_enabled[i] * and[17][i].out]); + states[i+1][8] <== MultiOR(2)([states_tmp[i+1][8], from_zero_enabled[i] * and[19][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + state_changed[i].in[3] <== states[i+1][4]; + state_changed[i].in[4] <== states[i+1][5]; + state_changed[i].in[5] <== states[i+1][6]; + state_changed[i].in[6] <== states[i+1][7]; + state_changed[i].in[7] <== states[i+1][8]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][8]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][8] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][8], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (1, 8), (2, 1), (3, 1), (4, 1), (5, 3), (6, 3), (7, 3)}] + signal prev_states0[15][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (1, 8), (2, 1), (3, 1), (4, 1), (5, 3), (6, 3), (7, 3)] + prev_states0[0][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[1][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[2][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[3][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[4][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[5][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[6][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[7][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[9][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[10][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + prev_states0[11][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][4]; + prev_states0[12][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[13][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][6]; + prev_states0[14][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + is_substr0[i] <== MultiOR(15)([prev_states0[0][i] * states[i+2][1], prev_states0[1][i] * states[i+2][2], prev_states0[2][i] * states[i+2][3], prev_states0[3][i] * states[i+2][4], prev_states0[4][i] * states[i+2][5], prev_states0[5][i] * states[i+2][6], prev_states0[6][i] * states[i+2][7], prev_states0[7][i] * states[i+2][8], prev_states0[8][i] * states[i+2][8], prev_states0[9][i] * states[i+2][1], prev_states0[10][i] * states[i+2][1], prev_states0[11][i] * states[i+2][1], prev_states0[12][i] * states[i+2][3], prev_states0[13][i] * states[i+2][3], prev_states0[14][i] * states[i+2][3]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/dot2.json b/packages/circom/tests/circuits/dot2.json new file mode 100644 index 0000000..89fb77d --- /dev/null +++ b/packages/circom/tests/circuits/dot2.json @@ -0,0 +1,16 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "a" + }, + { + "is_public": true, + "regex_def": "." + }, + { + "is_public": false, + "regex_def": "b" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/dot2_regex.circom b/packages/circom/tests/circuits/dot2_regex.circom new file mode 100644 index 0000000..855b946 --- /dev/null +++ b/packages/circom/tests/circuits/dot2_regex.circom @@ -0,0 +1,405 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: a.b +template Dot2Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[48][num_bytes]; + component lt[12][num_bytes]; + component and[23][num_bytes]; + component multi_or[7][num_bytes]; + signal states[num_bytes+1][11]; + signal states_tmp[num_bytes+1][11]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 11; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(10); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 97; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + lt[0][i] = LessEqThan(8); + lt[0][i].in[0] <== 194; + lt[0][i].in[1] <== in[i]; + lt[1][i] = LessEqThan(8); + lt[1][i].in[0] <== in[i]; + lt[1][i].in[1] <== 223; + and[1][i] = AND(); + and[1][i].a <== lt[0][i].out; + and[1][i].b <== lt[1][i].out; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== and[1][i].out; + lt[2][i] = LessEqThan(8); + lt[2][i].in[0] <== 160; + lt[2][i].in[1] <== in[i]; + lt[3][i] = LessEqThan(8); + lt[3][i].in[0] <== in[i]; + lt[3][i].in[1] <== 191; + and[3][i] = AND(); + and[3][i].a <== lt[2][i].out; + and[3][i].b <== lt[3][i].out; + and[4][i] = AND(); + and[4][i].a <== states[i][3]; + and[4][i].b <== and[3][i].out; + lt[4][i] = LessEqThan(8); + lt[4][i].in[0] <== 128; + lt[4][i].in[1] <== in[i]; + lt[5][i] = LessEqThan(8); + lt[5][i].in[0] <== in[i]; + lt[5][i].in[1] <== 191; + and[5][i] = AND(); + and[5][i].a <== lt[4][i].out; + and[5][i].b <== lt[5][i].out; + and[6][i] = AND(); + and[6][i].a <== states[i][4]; + and[6][i].b <== and[5][i].out; + lt[6][i] = LessEqThan(8); + lt[6][i].in[0] <== 128; + lt[6][i].in[1] <== in[i]; + lt[7][i] = LessEqThan(8); + lt[7][i].in[0] <== in[i]; + lt[7][i].in[1] <== 159; + and[7][i] = AND(); + and[7][i].a <== lt[6][i].out; + and[7][i].b <== lt[7][i].out; + and[8][i] = AND(); + and[8][i].a <== states[i][5]; + and[8][i].b <== and[7][i].out; + multi_or[0][i] = MultiOR(4); + multi_or[0][i].in[0] <== and[2][i].out; + multi_or[0][i].in[1] <== and[4][i].out; + multi_or[0][i].in[2] <== and[6][i].out; + multi_or[0][i].in[3] <== and[8][i].out; + states[i+1][2] <== multi_or[0][i].out; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 224; + and[9][i] = AND(); + and[9][i].a <== states[i][1]; + and[9][i].b <== eq[1][i].out; + states[i+1][3] <== and[9][i].out; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 225; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 226; + eq[4][i] = IsEqual(); + eq[4][i].in[0] <== in[i]; + eq[4][i].in[1] <== 227; + eq[5][i] = IsEqual(); + eq[5][i].in[0] <== in[i]; + eq[5][i].in[1] <== 228; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 229; + eq[7][i] = IsEqual(); + eq[7][i].in[0] <== in[i]; + eq[7][i].in[1] <== 230; + eq[8][i] = IsEqual(); + eq[8][i].in[0] <== in[i]; + eq[8][i].in[1] <== 231; + eq[9][i] = IsEqual(); + eq[9][i].in[0] <== in[i]; + eq[9][i].in[1] <== 232; + eq[10][i] = IsEqual(); + eq[10][i].in[0] <== in[i]; + eq[10][i].in[1] <== 233; + eq[11][i] = IsEqual(); + eq[11][i].in[0] <== in[i]; + eq[11][i].in[1] <== 234; + eq[12][i] = IsEqual(); + eq[12][i].in[0] <== in[i]; + eq[12][i].in[1] <== 235; + eq[13][i] = IsEqual(); + eq[13][i].in[0] <== in[i]; + eq[13][i].in[1] <== 236; + eq[14][i] = IsEqual(); + eq[14][i].in[0] <== in[i]; + eq[14][i].in[1] <== 238; + eq[15][i] = IsEqual(); + eq[15][i].in[0] <== in[i]; + eq[15][i].in[1] <== 239; + and[10][i] = AND(); + and[10][i].a <== states[i][1]; + multi_or[1][i] = MultiOR(14); + multi_or[1][i].in[0] <== eq[2][i].out; + multi_or[1][i].in[1] <== eq[3][i].out; + multi_or[1][i].in[2] <== eq[4][i].out; + multi_or[1][i].in[3] <== eq[5][i].out; + multi_or[1][i].in[4] <== eq[6][i].out; + multi_or[1][i].in[5] <== eq[7][i].out; + multi_or[1][i].in[6] <== eq[8][i].out; + multi_or[1][i].in[7] <== eq[9][i].out; + multi_or[1][i].in[8] <== eq[10][i].out; + multi_or[1][i].in[9] <== eq[11][i].out; + multi_or[1][i].in[10] <== eq[12][i].out; + multi_or[1][i].in[11] <== eq[13][i].out; + multi_or[1][i].in[12] <== eq[14][i].out; + multi_or[1][i].in[13] <== eq[15][i].out; + and[10][i].b <== multi_or[1][i].out; + lt[8][i] = LessEqThan(8); + lt[8][i].in[0] <== 144; + lt[8][i].in[1] <== in[i]; + lt[9][i] = LessEqThan(8); + lt[9][i].in[0] <== in[i]; + lt[9][i].in[1] <== 191; + and[11][i] = AND(); + and[11][i].a <== lt[8][i].out; + and[11][i].b <== lt[9][i].out; + and[12][i] = AND(); + and[12][i].a <== states[i][6]; + and[12][i].b <== and[11][i].out; + and[13][i] = AND(); + and[13][i].a <== states[i][7]; + and[13][i].b <== and[5][i].out; + eq[16][i] = IsEqual(); + eq[16][i].in[0] <== in[i]; + eq[16][i].in[1] <== 128; + eq[17][i] = IsEqual(); + eq[17][i].in[0] <== in[i]; + eq[17][i].in[1] <== 129; + eq[18][i] = IsEqual(); + eq[18][i].in[0] <== in[i]; + eq[18][i].in[1] <== 130; + eq[19][i] = IsEqual(); + eq[19][i].in[0] <== in[i]; + eq[19][i].in[1] <== 131; + eq[20][i] = IsEqual(); + eq[20][i].in[0] <== in[i]; + eq[20][i].in[1] <== 132; + eq[21][i] = IsEqual(); + eq[21][i].in[0] <== in[i]; + eq[21][i].in[1] <== 133; + eq[22][i] = IsEqual(); + eq[22][i].in[0] <== in[i]; + eq[22][i].in[1] <== 134; + eq[23][i] = IsEqual(); + eq[23][i].in[0] <== in[i]; + eq[23][i].in[1] <== 135; + eq[24][i] = IsEqual(); + eq[24][i].in[0] <== in[i]; + eq[24][i].in[1] <== 136; + eq[25][i] = IsEqual(); + eq[25][i].in[0] <== in[i]; + eq[25][i].in[1] <== 137; + eq[26][i] = IsEqual(); + eq[26][i].in[0] <== in[i]; + eq[26][i].in[1] <== 138; + eq[27][i] = IsEqual(); + eq[27][i].in[0] <== in[i]; + eq[27][i].in[1] <== 139; + eq[28][i] = IsEqual(); + eq[28][i].in[0] <== in[i]; + eq[28][i].in[1] <== 140; + eq[29][i] = IsEqual(); + eq[29][i].in[0] <== in[i]; + eq[29][i].in[1] <== 141; + eq[30][i] = IsEqual(); + eq[30][i].in[0] <== in[i]; + eq[30][i].in[1] <== 142; + eq[31][i] = IsEqual(); + eq[31][i].in[0] <== in[i]; + eq[31][i].in[1] <== 143; + and[14][i] = AND(); + and[14][i].a <== states[i][8]; + multi_or[2][i] = MultiOR(16); + multi_or[2][i].in[0] <== eq[16][i].out; + multi_or[2][i].in[1] <== eq[17][i].out; + multi_or[2][i].in[2] <== eq[18][i].out; + multi_or[2][i].in[3] <== eq[19][i].out; + multi_or[2][i].in[4] <== eq[20][i].out; + multi_or[2][i].in[5] <== eq[21][i].out; + multi_or[2][i].in[6] <== eq[22][i].out; + multi_or[2][i].in[7] <== eq[23][i].out; + multi_or[2][i].in[8] <== eq[24][i].out; + multi_or[2][i].in[9] <== eq[25][i].out; + multi_or[2][i].in[10] <== eq[26][i].out; + multi_or[2][i].in[11] <== eq[27][i].out; + multi_or[2][i].in[12] <== eq[28][i].out; + multi_or[2][i].in[13] <== eq[29][i].out; + multi_or[2][i].in[14] <== eq[30][i].out; + multi_or[2][i].in[15] <== eq[31][i].out; + and[14][i].b <== multi_or[2][i].out; + multi_or[3][i] = MultiOR(4); + multi_or[3][i].in[0] <== and[10][i].out; + multi_or[3][i].in[1] <== and[12][i].out; + multi_or[3][i].in[2] <== and[13][i].out; + multi_or[3][i].in[3] <== and[14][i].out; + states[i+1][4] <== multi_or[3][i].out; + eq[32][i] = IsEqual(); + eq[32][i].in[0] <== in[i]; + eq[32][i].in[1] <== 237; + and[15][i] = AND(); + and[15][i].a <== states[i][1]; + and[15][i].b <== eq[32][i].out; + states[i+1][5] <== and[15][i].out; + eq[33][i] = IsEqual(); + eq[33][i].in[0] <== in[i]; + eq[33][i].in[1] <== 240; + and[16][i] = AND(); + and[16][i].a <== states[i][1]; + and[16][i].b <== eq[33][i].out; + states[i+1][6] <== and[16][i].out; + eq[34][i] = IsEqual(); + eq[34][i].in[0] <== in[i]; + eq[34][i].in[1] <== 241; + eq[35][i] = IsEqual(); + eq[35][i].in[0] <== in[i]; + eq[35][i].in[1] <== 242; + eq[36][i] = IsEqual(); + eq[36][i].in[0] <== in[i]; + eq[36][i].in[1] <== 243; + and[17][i] = AND(); + and[17][i].a <== states[i][1]; + multi_or[4][i] = MultiOR(3); + multi_or[4][i].in[0] <== eq[34][i].out; + multi_or[4][i].in[1] <== eq[35][i].out; + multi_or[4][i].in[2] <== eq[36][i].out; + and[17][i].b <== multi_or[4][i].out; + states[i+1][7] <== and[17][i].out; + eq[37][i] = IsEqual(); + eq[37][i].in[0] <== in[i]; + eq[37][i].in[1] <== 244; + and[18][i] = AND(); + and[18][i].a <== states[i][1]; + and[18][i].b <== eq[37][i].out; + states[i+1][8] <== and[18][i].out; + lt[10][i] = LessEqThan(8); + lt[10][i].in[0] <== 11; + lt[10][i].in[1] <== in[i]; + lt[11][i] = LessEqThan(8); + lt[11][i].in[0] <== in[i]; + lt[11][i].in[1] <== 127; + and[19][i] = AND(); + and[19][i].a <== lt[10][i].out; + and[19][i].b <== lt[11][i].out; + eq[38][i] = IsEqual(); + eq[38][i].in[0] <== in[i]; + eq[38][i].in[1] <== 1; + eq[39][i] = IsEqual(); + eq[39][i].in[0] <== in[i]; + eq[39][i].in[1] <== 2; + eq[40][i] = IsEqual(); + eq[40][i].in[0] <== in[i]; + eq[40][i].in[1] <== 3; + eq[41][i] = IsEqual(); + eq[41][i].in[0] <== in[i]; + eq[41][i].in[1] <== 4; + eq[42][i] = IsEqual(); + eq[42][i].in[0] <== in[i]; + eq[42][i].in[1] <== 5; + eq[43][i] = IsEqual(); + eq[43][i].in[0] <== in[i]; + eq[43][i].in[1] <== 6; + eq[44][i] = IsEqual(); + eq[44][i].in[0] <== in[i]; + eq[44][i].in[1] <== 7; + eq[45][i] = IsEqual(); + eq[45][i].in[0] <== in[i]; + eq[45][i].in[1] <== 8; + eq[46][i] = IsEqual(); + eq[46][i].in[0] <== in[i]; + eq[46][i].in[1] <== 9; + and[20][i] = AND(); + and[20][i].a <== states[i][1]; + multi_or[5][i] = MultiOR(10); + multi_or[5][i].in[0] <== and[19][i].out; + multi_or[5][i].in[1] <== eq[38][i].out; + multi_or[5][i].in[2] <== eq[39][i].out; + multi_or[5][i].in[3] <== eq[40][i].out; + multi_or[5][i].in[4] <== eq[41][i].out; + multi_or[5][i].in[5] <== eq[42][i].out; + multi_or[5][i].in[6] <== eq[43][i].out; + multi_or[5][i].in[7] <== eq[44][i].out; + multi_or[5][i].in[8] <== eq[45][i].out; + multi_or[5][i].in[9] <== eq[46][i].out; + and[20][i].b <== multi_or[5][i].out; + and[21][i] = AND(); + and[21][i].a <== states[i][2]; + and[21][i].b <== and[5][i].out; + multi_or[6][i] = MultiOR(2); + multi_or[6][i].in[0] <== and[20][i].out; + multi_or[6][i].in[1] <== and[21][i].out; + states[i+1][9] <== multi_or[6][i].out; + eq[47][i] = IsEqual(); + eq[47][i].in[0] <== in[i]; + eq[47][i].in[1] <== 98; + and[22][i] = AND(); + and[22][i].a <== states[i][9]; + and[22][i].b <== eq[47][i].out; + states[i+1][10] <== and[22][i].out; + from_zero_enabled[i] <== MultiNOR(10)([states_tmp[i+1][1], states[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7], states[i+1][8], states[i+1][9], states[i+1][10]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + state_changed[i].in[3] <== states[i+1][4]; + state_changed[i].in[4] <== states[i+1][5]; + state_changed[i].in[5] <== states[i+1][6]; + state_changed[i].in[6] <== states[i+1][7]; + state_changed[i].in[7] <== states[i+1][8]; + state_changed[i].in[8] <== states[i+1][9]; + state_changed[i].in[9] <== states[i+1][10]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][10]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][10] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][10], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 9), (3, 2), (4, 2), (5, 2), (6, 4), (7, 4), (8, 4)}] + signal prev_states0[15][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 9), (3, 2), (4, 2), (5, 2), (6, 4), (7, 4), (8, 4)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[6][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[7][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[9][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + prev_states0[10][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][4]; + prev_states0[11][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[12][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][6]; + prev_states0[13][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + prev_states0[14][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][8]; + is_substr0[i] <== MultiOR(15)([prev_states0[0][i] * states[i+2][2], prev_states0[1][i] * states[i+2][3], prev_states0[2][i] * states[i+2][4], prev_states0[3][i] * states[i+2][5], prev_states0[4][i] * states[i+2][6], prev_states0[5][i] * states[i+2][7], prev_states0[6][i] * states[i+2][8], prev_states0[7][i] * states[i+2][9], prev_states0[8][i] * states[i+2][9], prev_states0[9][i] * states[i+2][2], prev_states0[10][i] * states[i+2][2], prev_states0[11][i] * states[i+2][2], prev_states0[12][i] * states[i+2][4], prev_states0[13][i] * states[i+2][4], prev_states0[14][i] * states[i+2][4]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/international_chars_decomposed.circom b/packages/circom/tests/circuits/international_chars_decomposed.circom index 619fa92..a663ca8 100644 --- a/packages/circom/tests/circuits/international_chars_decomposed.circom +++ b/packages/circom/tests/circuits/international_chars_decomposed.circom @@ -815,71 +815,105 @@ template InternationalCharsDecomposed(msg_bytes) { state_changed[i].in[88] <== states[i+1][89]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][89]; + is_accepted.in[i] <== states[i][89]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][89] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][89], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(16, 17), (16, 18), (17, 19), (18, 19), (19, 17), (19, 18)}, {(26, 27), (26, 28), (27, 29), (28, 29), (29, 27), (29, 28)}, {(39, 40), (40, 41), (41, 40)}, {(49, 50), (50, 51), (51, 50)}, {(63, 64), (64, 65), (65, 66), (66, 64)}, {(85, 86), (86, 87), (86, 88), (87, 89), (88, 89), (89, 86)}] + signal prev_states0[6][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(16, 17), (16, 18), (17, 19), (18, 19), (19, 17), (19, 18)] - is_substr0[i] <== MultiOR(6)([states[i+1][16] * states[i+2][17], states[i+1][16] * states[i+2][18], states[i+1][17] * states[i+2][19], states[i+1][18] * states[i+2][19], states[i+1][19] * states[i+2][17], states[i+1][19] * states[i+2][18]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][16]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][16]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][17]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][18]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][19]; + prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][19]; + is_substr0[i] <== MultiOR(6)([prev_states0[0][i] * states[i+2][17], prev_states0[1][i] * states[i+2][18], prev_states0[2][i] * states[i+2][19], prev_states0[3][i] * states[i+2][19], prev_states0[4][i] * states[i+2][17], prev_states0[5][i] * states[i+2][18]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } + signal prev_states1[6][msg_bytes]; signal is_substr1[msg_bytes]; signal is_reveal1[msg_bytes]; signal output reveal1[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 1-th substring transitions: [(26, 27), (26, 28), (27, 29), (28, 29), (29, 27), (29, 28)] - is_substr1[i] <== MultiOR(6)([states[i+1][26] * states[i+2][27], states[i+1][26] * states[i+2][28], states[i+1][27] * states[i+2][29], states[i+1][28] * states[i+2][29], states[i+1][29] * states[i+2][27], states[i+1][29] * states[i+2][28]]); - is_reveal1[i] <== is_substr1[i] * is_consecutive[i][2]; + prev_states1[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][26]; + prev_states1[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][26]; + prev_states1[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][27]; + prev_states1[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][28]; + prev_states1[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][29]; + prev_states1[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][29]; + is_substr1[i] <== MultiOR(6)([prev_states1[0][i] * states[i+2][27], prev_states1[1][i] * states[i+2][28], prev_states1[2][i] * states[i+2][29], prev_states1[3][i] * states[i+2][29], prev_states1[4][i] * states[i+2][27], prev_states1[5][i] * states[i+2][28]]); + is_reveal1[i] <== MultiAND(3)([out, is_substr1[i], is_consecutive[i][2]]); reveal1[i] <== in[i+1] * is_reveal1[i]; } + signal prev_states2[3][msg_bytes]; signal is_substr2[msg_bytes]; signal is_reveal2[msg_bytes]; signal output reveal2[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 2-th substring transitions: [(39, 40), (40, 41), (41, 40)] - is_substr2[i] <== MultiOR(3)([states[i+1][39] * states[i+2][40], states[i+1][40] * states[i+2][41], states[i+1][41] * states[i+2][40]]); - is_reveal2[i] <== is_substr2[i] * is_consecutive[i][2]; + prev_states2[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][39]; + prev_states2[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][40]; + prev_states2[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][41]; + is_substr2[i] <== MultiOR(3)([prev_states2[0][i] * states[i+2][40], prev_states2[1][i] * states[i+2][41], prev_states2[2][i] * states[i+2][40]]); + is_reveal2[i] <== MultiAND(3)([out, is_substr2[i], is_consecutive[i][2]]); reveal2[i] <== in[i+1] * is_reveal2[i]; } + signal prev_states3[3][msg_bytes]; signal is_substr3[msg_bytes]; signal is_reveal3[msg_bytes]; signal output reveal3[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 3-th substring transitions: [(49, 50), (50, 51), (51, 50)] - is_substr3[i] <== MultiOR(3)([states[i+1][49] * states[i+2][50], states[i+1][50] * states[i+2][51], states[i+1][51] * states[i+2][50]]); - is_reveal3[i] <== is_substr3[i] * is_consecutive[i][2]; + prev_states3[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][49]; + prev_states3[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][50]; + prev_states3[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][51]; + is_substr3[i] <== MultiOR(3)([prev_states3[0][i] * states[i+2][50], prev_states3[1][i] * states[i+2][51], prev_states3[2][i] * states[i+2][50]]); + is_reveal3[i] <== MultiAND(3)([out, is_substr3[i], is_consecutive[i][2]]); reveal3[i] <== in[i+1] * is_reveal3[i]; } + signal prev_states4[4][msg_bytes]; signal is_substr4[msg_bytes]; signal is_reveal4[msg_bytes]; signal output reveal4[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 4-th substring transitions: [(63, 64), (64, 65), (65, 66), (66, 64)] - is_substr4[i] <== MultiOR(4)([states[i+1][63] * states[i+2][64], states[i+1][64] * states[i+2][65], states[i+1][65] * states[i+2][66], states[i+1][66] * states[i+2][64]]); - is_reveal4[i] <== is_substr4[i] * is_consecutive[i][2]; + prev_states4[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][63]; + prev_states4[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][64]; + prev_states4[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][65]; + prev_states4[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][66]; + is_substr4[i] <== MultiOR(4)([prev_states4[0][i] * states[i+2][64], prev_states4[1][i] * states[i+2][65], prev_states4[2][i] * states[i+2][66], prev_states4[3][i] * states[i+2][64]]); + is_reveal4[i] <== MultiAND(3)([out, is_substr4[i], is_consecutive[i][2]]); reveal4[i] <== in[i+1] * is_reveal4[i]; } + signal prev_states5[6][msg_bytes]; signal is_substr5[msg_bytes]; signal is_reveal5[msg_bytes]; signal output reveal5[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 5-th substring transitions: [(85, 86), (86, 87), (86, 88), (87, 89), (88, 89), (89, 86)] - is_substr5[i] <== MultiOR(6)([states[i+1][85] * states[i+2][86], states[i+1][86] * states[i+2][87], states[i+1][86] * states[i+2][88], states[i+1][87] * states[i+2][89], states[i+1][88] * states[i+2][89], states[i+1][89] * states[i+2][86]]); - is_reveal5[i] <== is_substr5[i] * is_consecutive[i][2]; + prev_states5[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][85]; + prev_states5[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][86]; + prev_states5[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][86]; + prev_states5[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][87]; + prev_states5[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][88]; + prev_states5[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][89]; + is_substr5[i] <== MultiOR(6)([prev_states5[0][i] * states[i+2][86], prev_states5[1][i] * states[i+2][87], prev_states5[2][i] * states[i+2][88], prev_states5[3][i] * states[i+2][89], prev_states5[4][i] * states[i+2][89], prev_states5[5][i] * states[i+2][86]]); + is_reveal5[i] <== MultiAND(3)([out, is_substr5[i], is_consecutive[i][2]]); reveal5[i] <== in[i+1] * is_reveal5[i]; } } \ No newline at end of file diff --git a/packages/circom/tests/circuits/invitation_code_with_prefix_regex.circom b/packages/circom/tests/circuits/invitation_code_with_prefix_regex.circom index 5855ead..979a9a5 100644 --- a/packages/circom/tests/circuits/invitation_code_with_prefix_regex.circom +++ b/packages/circom/tests/circuits/invitation_code_with_prefix_regex.circom @@ -160,26 +160,37 @@ template InvitationCodeWithPrefixRegex(msg_bytes) { state_changed[i].in[6] <== states[i+1][7]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][7]; + is_accepted.in[i] <== states[i][7]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][7] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][7], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(0, 1), (0, 2), (1, 3), (2, 1), (3, 4), (4, 5), (5, 6), (5, 7), (6, 7), (7, 7)}] + signal prev_states0[10][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(0, 1), (0, 2), (1, 3), (2, 1), (3, 4), (4, 5), (5, 6), (5, 7), (6, 7), (7, 7)] - is_substr0[i] <== MultiOR(10)([states[i+1][0] * states[i+2][1], states[i+1][0] * states[i+2][2], states[i+1][1] * states[i+2][3], states[i+1][2] * states[i+2][1], states[i+1][3] * states[i+2][4], states[i+1][4] * states[i+2][5], states[i+1][5] * states[i+2][6], states[i+1][5] * states[i+2][7], states[i+1][6] * states[i+2][7], states[i+1][7] * states[i+2][7]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[1][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][4]; + prev_states0[6][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[7][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][6]; + prev_states0[9][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + is_substr0[i] <== MultiOR(10)([prev_states0[0][i] * states[i+2][1], prev_states0[1][i] * states[i+2][2], prev_states0[2][i] * states[i+2][3], prev_states0[3][i] * states[i+2][1], prev_states0[4][i] * states[i+2][4], prev_states0[5][i] * states[i+2][5], prev_states0[6][i] * states[i+2][6], prev_states0[7][i] * states[i+2][7], prev_states0[8][i] * states[i+2][7], prev_states0[9][i] * states[i+2][7]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } } \ No newline at end of file diff --git a/packages/circom/tests/circuits/negate1_regex.circom b/packages/circom/tests/circuits/negate1_regex.circom index 33d8294..e54b21f 100644 --- a/packages/circom/tests/circuits/negate1_regex.circom +++ b/packages/circom/tests/circuits/negate1_regex.circom @@ -332,7 +332,7 @@ template Negate1Regex(msg_bytes) { multi_or[9][i].in[1] <== and[26][i].out; states[i+1][9] <== multi_or[9][i].out; lt[10][i] = LessEqThan(8); - lt[10][i].in[0] <== 0; + lt[10][i].in[0] <== 1; lt[10][i].in[1] <== in[i]; lt[11][i] = LessEqThan(8); lt[11][i].in[0] <== in[i]; @@ -408,26 +408,50 @@ template Negate1Regex(msg_bytes) { state_changed[i].in[10] <== states[i+1][11]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][11]; + is_accepted.in[i] <== states[i][11]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][11] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][11], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 10), (4, 3), (5, 3), (6, 3), (7, 5), (8, 5), (9, 5), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9), (10, 10)}] + signal prev_states0[23][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 10), (4, 3), (5, 3), (6, 3), (7, 5), (8, 5), (9, 5), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9), (10, 10)] - is_substr0[i] <== MultiOR(23)([states[i+1][2] * states[i+2][3], states[i+1][2] * states[i+2][4], states[i+1][2] * states[i+2][5], states[i+1][2] * states[i+2][6], states[i+1][2] * states[i+2][7], states[i+1][2] * states[i+2][8], states[i+1][2] * states[i+2][9], states[i+1][2] * states[i+2][10], states[i+1][3] * states[i+2][10], states[i+1][4] * states[i+2][3], states[i+1][5] * states[i+2][3], states[i+1][6] * states[i+2][3], states[i+1][7] * states[i+2][5], states[i+1][8] * states[i+2][5], states[i+1][9] * states[i+2][5], states[i+1][10] * states[i+2][3], states[i+1][10] * states[i+2][4], states[i+1][10] * states[i+2][5], states[i+1][10] * states[i+2][6], states[i+1][10] * states[i+2][7], states[i+1][10] * states[i+2][8], states[i+1][10] * states[i+2][9], states[i+1][10] * states[i+2][10]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[6][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[7][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + prev_states0[9][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][4]; + prev_states0[10][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[11][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][6]; + prev_states0[12][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + prev_states0[13][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][8]; + prev_states0[14][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][9]; + prev_states0[15][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[16][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[17][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[18][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[19][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[20][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[21][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + prev_states0[22][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][10]; + is_substr0[i] <== MultiOR(23)([prev_states0[0][i] * states[i+2][3], prev_states0[1][i] * states[i+2][4], prev_states0[2][i] * states[i+2][5], prev_states0[3][i] * states[i+2][6], prev_states0[4][i] * states[i+2][7], prev_states0[5][i] * states[i+2][8], prev_states0[6][i] * states[i+2][9], prev_states0[7][i] * states[i+2][10], prev_states0[8][i] * states[i+2][10], prev_states0[9][i] * states[i+2][3], prev_states0[10][i] * states[i+2][3], prev_states0[11][i] * states[i+2][3], prev_states0[12][i] * states[i+2][5], prev_states0[13][i] * states[i+2][5], prev_states0[14][i] * states[i+2][5], prev_states0[15][i] * states[i+2][3], prev_states0[16][i] * states[i+2][4], prev_states0[17][i] * states[i+2][5], prev_states0[18][i] * states[i+2][6], prev_states0[19][i] * states[i+2][7], prev_states0[20][i] * states[i+2][8], prev_states0[21][i] * states[i+2][9], prev_states0[22][i] * states[i+2][10]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } } \ No newline at end of file diff --git a/packages/circom/tests/circuits/negate2.json b/packages/circom/tests/circuits/negate2.json new file mode 100644 index 0000000..136b611 --- /dev/null +++ b/packages/circom/tests/circuits/negate2.json @@ -0,0 +1,8 @@ +{ + "parts": [ + { + "is_public": true, + "regex_def": "[^ab]" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/negate2_regex.circom b/packages/circom/tests/circuits/negate2_regex.circom new file mode 100644 index 0000000..ecfefec --- /dev/null +++ b/packages/circom/tests/circuits/negate2_regex.circom @@ -0,0 +1,365 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: [^ab] +template Negate2Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[37][num_bytes]; + component lt[14][num_bytes]; + component and[22][num_bytes]; + component multi_or[6][num_bytes]; + signal states[num_bytes+1][9]; + signal states_tmp[num_bytes+1][9]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 9; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(8); + states[i][0] <== 1; + lt[0][i] = LessEqThan(8); + lt[0][i].in[0] <== 194; + lt[0][i].in[1] <== in[i]; + lt[1][i] = LessEqThan(8); + lt[1][i].in[0] <== in[i]; + lt[1][i].in[1] <== 223; + and[0][i] = AND(); + and[0][i].a <== lt[0][i].out; + and[0][i].b <== lt[1][i].out; + and[1][i] = AND(); + and[1][i].a <== states[i][0]; + and[1][i].b <== and[0][i].out; + lt[2][i] = LessEqThan(8); + lt[2][i].in[0] <== 160; + lt[2][i].in[1] <== in[i]; + lt[3][i] = LessEqThan(8); + lt[3][i].in[0] <== in[i]; + lt[3][i].in[1] <== 191; + and[2][i] = AND(); + and[2][i].a <== lt[2][i].out; + and[2][i].b <== lt[3][i].out; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== and[2][i].out; + lt[4][i] = LessEqThan(8); + lt[4][i].in[0] <== 128; + lt[4][i].in[1] <== in[i]; + lt[5][i] = LessEqThan(8); + lt[5][i].in[0] <== in[i]; + lt[5][i].in[1] <== 191; + and[4][i] = AND(); + and[4][i].a <== lt[4][i].out; + and[4][i].b <== lt[5][i].out; + and[5][i] = AND(); + and[5][i].a <== states[i][3]; + and[5][i].b <== and[4][i].out; + lt[6][i] = LessEqThan(8); + lt[6][i].in[0] <== 128; + lt[6][i].in[1] <== in[i]; + lt[7][i] = LessEqThan(8); + lt[7][i].in[0] <== in[i]; + lt[7][i].in[1] <== 159; + and[6][i] = AND(); + and[6][i].a <== lt[6][i].out; + and[6][i].b <== lt[7][i].out; + and[7][i] = AND(); + and[7][i].a <== states[i][4]; + and[7][i].b <== and[6][i].out; + multi_or[0][i] = MultiOR(3); + multi_or[0][i].in[0] <== and[3][i].out; + multi_or[0][i].in[1] <== and[5][i].out; + multi_or[0][i].in[2] <== and[7][i].out; + states_tmp[i+1][1] <== multi_or[0][i].out; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 224; + and[8][i] = AND(); + and[8][i].a <== states[i][0]; + and[8][i].b <== eq[0][i].out; + states_tmp[i+1][2] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 225; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 226; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 227; + eq[4][i] = IsEqual(); + eq[4][i].in[0] <== in[i]; + eq[4][i].in[1] <== 228; + eq[5][i] = IsEqual(); + eq[5][i].in[0] <== in[i]; + eq[5][i].in[1] <== 229; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 230; + eq[7][i] = IsEqual(); + eq[7][i].in[0] <== in[i]; + eq[7][i].in[1] <== 231; + eq[8][i] = IsEqual(); + eq[8][i].in[0] <== in[i]; + eq[8][i].in[1] <== 232; + eq[9][i] = IsEqual(); + eq[9][i].in[0] <== in[i]; + eq[9][i].in[1] <== 233; + eq[10][i] = IsEqual(); + eq[10][i].in[0] <== in[i]; + eq[10][i].in[1] <== 234; + eq[11][i] = IsEqual(); + eq[11][i].in[0] <== in[i]; + eq[11][i].in[1] <== 235; + eq[12][i] = IsEqual(); + eq[12][i].in[0] <== in[i]; + eq[12][i].in[1] <== 236; + eq[13][i] = IsEqual(); + eq[13][i].in[0] <== in[i]; + eq[13][i].in[1] <== 238; + eq[14][i] = IsEqual(); + eq[14][i].in[0] <== in[i]; + eq[14][i].in[1] <== 239; + and[9][i] = AND(); + and[9][i].a <== states[i][0]; + multi_or[1][i] = MultiOR(14); + multi_or[1][i].in[0] <== eq[1][i].out; + multi_or[1][i].in[1] <== eq[2][i].out; + multi_or[1][i].in[2] <== eq[3][i].out; + multi_or[1][i].in[3] <== eq[4][i].out; + multi_or[1][i].in[4] <== eq[5][i].out; + multi_or[1][i].in[5] <== eq[6][i].out; + multi_or[1][i].in[6] <== eq[7][i].out; + multi_or[1][i].in[7] <== eq[8][i].out; + multi_or[1][i].in[8] <== eq[9][i].out; + multi_or[1][i].in[9] <== eq[10][i].out; + multi_or[1][i].in[10] <== eq[11][i].out; + multi_or[1][i].in[11] <== eq[12][i].out; + multi_or[1][i].in[12] <== eq[13][i].out; + multi_or[1][i].in[13] <== eq[14][i].out; + and[9][i].b <== multi_or[1][i].out; + lt[8][i] = LessEqThan(8); + lt[8][i].in[0] <== 144; + lt[8][i].in[1] <== in[i]; + lt[9][i] = LessEqThan(8); + lt[9][i].in[0] <== in[i]; + lt[9][i].in[1] <== 191; + and[10][i] = AND(); + and[10][i].a <== lt[8][i].out; + and[10][i].b <== lt[9][i].out; + and[11][i] = AND(); + and[11][i].a <== states[i][5]; + and[11][i].b <== and[10][i].out; + and[12][i] = AND(); + and[12][i].a <== states[i][6]; + and[12][i].b <== and[4][i].out; + eq[15][i] = IsEqual(); + eq[15][i].in[0] <== in[i]; + eq[15][i].in[1] <== 128; + eq[16][i] = IsEqual(); + eq[16][i].in[0] <== in[i]; + eq[16][i].in[1] <== 129; + eq[17][i] = IsEqual(); + eq[17][i].in[0] <== in[i]; + eq[17][i].in[1] <== 130; + eq[18][i] = IsEqual(); + eq[18][i].in[0] <== in[i]; + eq[18][i].in[1] <== 131; + eq[19][i] = IsEqual(); + eq[19][i].in[0] <== in[i]; + eq[19][i].in[1] <== 132; + eq[20][i] = IsEqual(); + eq[20][i].in[0] <== in[i]; + eq[20][i].in[1] <== 133; + eq[21][i] = IsEqual(); + eq[21][i].in[0] <== in[i]; + eq[21][i].in[1] <== 134; + eq[22][i] = IsEqual(); + eq[22][i].in[0] <== in[i]; + eq[22][i].in[1] <== 135; + eq[23][i] = IsEqual(); + eq[23][i].in[0] <== in[i]; + eq[23][i].in[1] <== 136; + eq[24][i] = IsEqual(); + eq[24][i].in[0] <== in[i]; + eq[24][i].in[1] <== 137; + eq[25][i] = IsEqual(); + eq[25][i].in[0] <== in[i]; + eq[25][i].in[1] <== 138; + eq[26][i] = IsEqual(); + eq[26][i].in[0] <== in[i]; + eq[26][i].in[1] <== 139; + eq[27][i] = IsEqual(); + eq[27][i].in[0] <== in[i]; + eq[27][i].in[1] <== 140; + eq[28][i] = IsEqual(); + eq[28][i].in[0] <== in[i]; + eq[28][i].in[1] <== 141; + eq[29][i] = IsEqual(); + eq[29][i].in[0] <== in[i]; + eq[29][i].in[1] <== 142; + eq[30][i] = IsEqual(); + eq[30][i].in[0] <== in[i]; + eq[30][i].in[1] <== 143; + and[13][i] = AND(); + and[13][i].a <== states[i][7]; + multi_or[2][i] = MultiOR(16); + multi_or[2][i].in[0] <== eq[15][i].out; + multi_or[2][i].in[1] <== eq[16][i].out; + multi_or[2][i].in[2] <== eq[17][i].out; + multi_or[2][i].in[3] <== eq[18][i].out; + multi_or[2][i].in[4] <== eq[19][i].out; + multi_or[2][i].in[5] <== eq[20][i].out; + multi_or[2][i].in[6] <== eq[21][i].out; + multi_or[2][i].in[7] <== eq[22][i].out; + multi_or[2][i].in[8] <== eq[23][i].out; + multi_or[2][i].in[9] <== eq[24][i].out; + multi_or[2][i].in[10] <== eq[25][i].out; + multi_or[2][i].in[11] <== eq[26][i].out; + multi_or[2][i].in[12] <== eq[27][i].out; + multi_or[2][i].in[13] <== eq[28][i].out; + multi_or[2][i].in[14] <== eq[29][i].out; + multi_or[2][i].in[15] <== eq[30][i].out; + and[13][i].b <== multi_or[2][i].out; + multi_or[3][i] = MultiOR(3); + multi_or[3][i].in[0] <== and[11][i].out; + multi_or[3][i].in[1] <== and[12][i].out; + multi_or[3][i].in[2] <== and[13][i].out; + states_tmp[i+1][3] <== multi_or[3][i].out; + eq[31][i] = IsEqual(); + eq[31][i].in[0] <== in[i]; + eq[31][i].in[1] <== 237; + and[14][i] = AND(); + and[14][i].a <== states[i][0]; + and[14][i].b <== eq[31][i].out; + states_tmp[i+1][4] <== 0; + eq[32][i] = IsEqual(); + eq[32][i].in[0] <== in[i]; + eq[32][i].in[1] <== 240; + and[15][i] = AND(); + and[15][i].a <== states[i][0]; + and[15][i].b <== eq[32][i].out; + states_tmp[i+1][5] <== 0; + eq[33][i] = IsEqual(); + eq[33][i].in[0] <== in[i]; + eq[33][i].in[1] <== 241; + eq[34][i] = IsEqual(); + eq[34][i].in[0] <== in[i]; + eq[34][i].in[1] <== 242; + eq[35][i] = IsEqual(); + eq[35][i].in[0] <== in[i]; + eq[35][i].in[1] <== 243; + and[16][i] = AND(); + and[16][i].a <== states[i][0]; + multi_or[4][i] = MultiOR(3); + multi_or[4][i].in[0] <== eq[33][i].out; + multi_or[4][i].in[1] <== eq[34][i].out; + multi_or[4][i].in[2] <== eq[35][i].out; + and[16][i].b <== multi_or[4][i].out; + states_tmp[i+1][6] <== 0; + eq[36][i] = IsEqual(); + eq[36][i].in[0] <== in[i]; + eq[36][i].in[1] <== 244; + and[17][i] = AND(); + and[17][i].a <== states[i][0]; + and[17][i].b <== eq[36][i].out; + states_tmp[i+1][7] <== 0; + lt[10][i] = LessEqThan(8); + lt[10][i].in[0] <== 1; + lt[10][i].in[1] <== in[i]; + lt[11][i] = LessEqThan(8); + lt[11][i].in[0] <== in[i]; + lt[11][i].in[1] <== 96; + and[18][i] = AND(); + and[18][i].a <== lt[10][i].out; + and[18][i].b <== lt[11][i].out; + lt[12][i] = LessEqThan(8); + lt[12][i].in[0] <== 99; + lt[12][i].in[1] <== in[i]; + lt[13][i] = LessEqThan(8); + lt[13][i].in[0] <== in[i]; + lt[13][i].in[1] <== 127; + and[19][i] = AND(); + and[19][i].a <== lt[12][i].out; + and[19][i].b <== lt[13][i].out; + and[20][i] = AND(); + and[20][i].a <== states[i][0]; + multi_or[5][i] = MultiOR(2); + multi_or[5][i].in[0] <== and[18][i].out; + multi_or[5][i].in[1] <== and[19][i].out; + and[20][i].b <== multi_or[5][i].out; + and[21][i] = AND(); + and[21][i].a <== states[i][1]; + and[21][i].b <== and[4][i].out; + states_tmp[i+1][8] <== and[21][i].out; + from_zero_enabled[i] <== MultiNOR(8)([states_tmp[i+1][1], states_tmp[i+1][2], states_tmp[i+1][3], states_tmp[i+1][4], states_tmp[i+1][5], states_tmp[i+1][6], states_tmp[i+1][7], states_tmp[i+1][8]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[1][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[8][i].out]); + states[i+1][3] <== MultiOR(2)([states_tmp[i+1][3], from_zero_enabled[i] * and[9][i].out]); + states[i+1][4] <== MultiOR(2)([states_tmp[i+1][4], from_zero_enabled[i] * and[14][i].out]); + states[i+1][5] <== MultiOR(2)([states_tmp[i+1][5], from_zero_enabled[i] * and[15][i].out]); + states[i+1][6] <== MultiOR(2)([states_tmp[i+1][6], from_zero_enabled[i] * and[16][i].out]); + states[i+1][7] <== MultiOR(2)([states_tmp[i+1][7], from_zero_enabled[i] * and[17][i].out]); + states[i+1][8] <== MultiOR(2)([states_tmp[i+1][8], from_zero_enabled[i] * and[20][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + state_changed[i].in[3] <== states[i+1][4]; + state_changed[i].in[4] <== states[i+1][5]; + state_changed[i].in[5] <== states[i+1][6]; + state_changed[i].in[6] <== states[i+1][7]; + state_changed[i].in[7] <== states[i+1][8]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][8]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][8] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][8], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (1, 8), (2, 1), (3, 1), (4, 1), (5, 3), (6, 3), (7, 3)}] + signal prev_states0[15][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (1, 8), (2, 1), (3, 1), (4, 1), (5, 3), (6, 3), (7, 3)] + prev_states0[0][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[1][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[2][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[3][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[4][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[5][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[6][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[7][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[9][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[10][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + prev_states0[11][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][4]; + prev_states0[12][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; + prev_states0[13][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][6]; + prev_states0[14][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + is_substr0[i] <== MultiOR(15)([prev_states0[0][i] * states[i+2][1], prev_states0[1][i] * states[i+2][2], prev_states0[2][i] * states[i+2][3], prev_states0[3][i] * states[i+2][4], prev_states0[4][i] * states[i+2][5], prev_states0[5][i] * states[i+2][6], prev_states0[6][i] * states[i+2][7], prev_states0[7][i] * states[i+2][8], prev_states0[8][i] * states[i+2][8], prev_states0[9][i] * states[i+2][1], prev_states0[10][i] * states[i+2][1], prev_states0[11][i] * states[i+2][1], prev_states0[12][i] * states[i+2][3], prev_states0[13][i] * states[i+2][3], prev_states0[14][i] * states[i+2][3]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/plus1.json b/packages/circom/tests/circuits/plus1.json new file mode 100644 index 0000000..bf9e1e7 --- /dev/null +++ b/packages/circom/tests/circuits/plus1.json @@ -0,0 +1,12 @@ +{ + "parts": [ + { + "is_public": true, + "regex_def": "a+" + }, + { + "is_public": false, + "regex_def": "b" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/plus1_regex.circom b/packages/circom/tests/circuits/plus1_regex.circom new file mode 100644 index 0000000..8e07bca --- /dev/null +++ b/packages/circom/tests/circuits/plus1_regex.circom @@ -0,0 +1,80 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: a+b +template Plus1Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[2][num_bytes]; + component and[3][num_bytes]; + signal states[num_bytes+1][3]; + signal states_tmp[num_bytes+1][3]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 3; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(2); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 97; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + and[1][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== and[1][i].out; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 98; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== eq[1][i].out; + states[i+1][2] <== and[2][i].out; + from_zero_enabled[i] <== MultiNOR(2)([states_tmp[i+1][1], states[i+1][2]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][2]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][2] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][2], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(0, 1), (1, 1)}] + signal prev_states0[2][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(0, 1), (1, 1)] + prev_states0[0][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + is_substr0[i] <== MultiOR(2)([prev_states0[0][i] * states[i+2][1], prev_states0[1][i] * states[i+2][1]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/plus2.json b/packages/circom/tests/circuits/plus2.json new file mode 100644 index 0000000..0b6a251 --- /dev/null +++ b/packages/circom/tests/circuits/plus2.json @@ -0,0 +1,12 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "a" + }, + { + "is_public": true, + "regex_def": "(b|c)+" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/plus2_regex.circom b/packages/circom/tests/circuits/plus2_regex.circom new file mode 100644 index 0000000..446ef9d --- /dev/null +++ b/packages/circom/tests/circuits/plus2_regex.circom @@ -0,0 +1,90 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: a(b|c)+ +template Plus2Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[3][num_bytes]; + component and[3][num_bytes]; + component multi_or[2][num_bytes]; + signal states[num_bytes+1][3]; + signal states_tmp[num_bytes+1][3]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 3; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(2); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 97; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 98; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 99; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== eq[1][i].out; + multi_or[0][i].in[1] <== eq[2][i].out; + and[1][i].b <== multi_or[0][i].out; + and[2][i] = AND(); + and[2][i].a <== states[i][2]; + and[2][i].b <== multi_or[0][i].out; + multi_or[1][i] = MultiOR(2); + multi_or[1][i].in[0] <== and[1][i].out; + multi_or[1][i].in[1] <== and[2][i].out; + states[i+1][2] <== multi_or[1][i].out; + from_zero_enabled[i] <== MultiNOR(2)([states_tmp[i+1][1], states[i+1][2]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][2]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][2] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][2], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(1, 2), (2, 2)}] + signal prev_states0[2][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(1, 2), (2, 2)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + is_substr0[i] <== MultiOR(2)([prev_states0[0][i] * states[i+2][2], prev_states0[1][i] * states[i+2][2]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/plus3.json b/packages/circom/tests/circuits/plus3.json new file mode 100644 index 0000000..c1b168b --- /dev/null +++ b/packages/circom/tests/circuits/plus3.json @@ -0,0 +1,12 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "a" + }, + { + "is_public": true, + "regex_def": "(bc)+" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/plus3_regex.circom b/packages/circom/tests/circuits/plus3_regex.circom new file mode 100644 index 0000000..6c1d829 --- /dev/null +++ b/packages/circom/tests/circuits/plus3_regex.circom @@ -0,0 +1,93 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: a(bc)+ +template Plus3Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[3][num_bytes]; + component and[4][num_bytes]; + component multi_or[1][num_bytes]; + signal states[num_bytes+1][4]; + signal states_tmp[num_bytes+1][4]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 4; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(3); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 97; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 98; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + and[1][i].b <== eq[1][i].out; + and[2][i] = AND(); + and[2][i].a <== states[i][3]; + and[2][i].b <== eq[1][i].out; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== and[1][i].out; + multi_or[0][i].in[1] <== and[2][i].out; + states[i+1][2] <== multi_or[0][i].out; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 99; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== eq[2][i].out; + states[i+1][3] <== and[3][i].out; + from_zero_enabled[i] <== MultiNOR(3)([states_tmp[i+1][1], states[i+1][2], states[i+1][3]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][3]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][3] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][3], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(1, 2), (2, 3), (3, 2)}] + signal prev_states0[3][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(1, 2), (2, 3), (3, 2)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + is_substr0[i] <== MultiOR(3)([prev_states0[0][i] * states[i+2][2], prev_states0[1][i] * states[i+2][3], prev_states0[2][i] * states[i+2][2]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/plus4.json b/packages/circom/tests/circuits/plus4.json new file mode 100644 index 0000000..e1c9e26 --- /dev/null +++ b/packages/circom/tests/circuits/plus4.json @@ -0,0 +1,12 @@ +{ + "parts": [ + { + "is_public": true, + "regex_def": "(12|345)+" + }, + { + "is_public": false, + "regex_def": "b" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/plus4_regex.circom b/packages/circom/tests/circuits/plus4_regex.circom new file mode 100644 index 0000000..b8ec65e --- /dev/null +++ b/packages/circom/tests/circuits/plus4_regex.circom @@ -0,0 +1,123 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: (12|345)+b +template Plus4Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[6][num_bytes]; + component and[8][num_bytes]; + component multi_or[1][num_bytes]; + signal states[num_bytes+1][6]; + signal states_tmp[num_bytes+1][6]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 6; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(5); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 51; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + and[1][i] = AND(); + and[1][i].a <== states[i][4]; + and[1][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== and[1][i].out; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 49; + and[2][i] = AND(); + and[2][i].a <== states[i][0]; + and[2][i].b <== eq[1][i].out; + and[3][i] = AND(); + and[3][i].a <== states[i][4]; + and[3][i].b <== eq[1][i].out; + states_tmp[i+1][2] <== and[3][i].out; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 52; + and[4][i] = AND(); + and[4][i].a <== states[i][1]; + and[4][i].b <== eq[2][i].out; + states[i+1][3] <== and[4][i].out; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 50; + and[5][i] = AND(); + and[5][i].a <== states[i][2]; + and[5][i].b <== eq[3][i].out; + eq[4][i] = IsEqual(); + eq[4][i].in[0] <== in[i]; + eq[4][i].in[1] <== 53; + and[6][i] = AND(); + and[6][i].a <== states[i][3]; + and[6][i].b <== eq[4][i].out; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== and[5][i].out; + multi_or[0][i].in[1] <== and[6][i].out; + states[i+1][4] <== multi_or[0][i].out; + eq[5][i] = IsEqual(); + eq[5][i].in[0] <== in[i]; + eq[5][i].in[1] <== 98; + and[7][i] = AND(); + and[7][i].a <== states[i][4]; + and[7][i].b <== eq[5][i].out; + states[i+1][5] <== and[7][i].out; + from_zero_enabled[i] <== MultiNOR(5)([states_tmp[i+1][1], states_tmp[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[2][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + state_changed[i].in[3] <== states[i+1][4]; + state_changed[i].in[4] <== states[i+1][5]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][5]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][5] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][5], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(0, 1), (0, 2), (1, 3), (2, 4), (3, 4), (4, 1), (4, 2)}] + signal prev_states0[7][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(0, 1), (0, 2), (1, 3), (2, 4), (3, 4), (4, 1), (4, 2)] + prev_states0[0][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[1][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][4]; + prev_states0[6][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][4]; + is_substr0[i] <== MultiOR(7)([prev_states0[0][i] * states[i+2][1], prev_states0[1][i] * states[i+2][2], prev_states0[2][i] * states[i+2][3], prev_states0[3][i] * states[i+2][4], prev_states0[4][i] * states[i+2][4], prev_states0[5][i] * states[i+2][1], prev_states0[6][i] * states[i+2][2]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/question1.json b/packages/circom/tests/circuits/question1.json new file mode 100644 index 0000000..2858b1d --- /dev/null +++ b/packages/circom/tests/circuits/question1.json @@ -0,0 +1,12 @@ +{ + "parts": [ + { + "is_public": true, + "regex_def": "a?" + }, + { + "is_public": false, + "regex_def": "b" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/question1_regex.circom b/packages/circom/tests/circuits/question1_regex.circom new file mode 100644 index 0000000..f6cd3f0 --- /dev/null +++ b/packages/circom/tests/circuits/question1_regex.circom @@ -0,0 +1,80 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: a?b +template Question1Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[2][num_bytes]; + component and[3][num_bytes]; + signal states[num_bytes+1][3]; + signal states_tmp[num_bytes+1][3]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 3; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(2); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 97; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 98; + and[1][i] = AND(); + and[1][i].a <== states[i][0]; + and[1][i].b <== eq[1][i].out; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== eq[1][i].out; + states_tmp[i+1][2] <== and[2][i].out; + from_zero_enabled[i] <== MultiNOR(2)([states_tmp[i+1][1], states_tmp[i+1][2]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[1][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][2]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][2] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][2], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(0, 1)}] + signal prev_states0[1][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(0, 1)] + prev_states0[0][i] <== from_zero_enabled[i+1] * states[i+1][0]; + is_substr0[i] <== MultiOR(1)([prev_states0[0][i] * states[i+2][1]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/question2.json b/packages/circom/tests/circuits/question2.json new file mode 100644 index 0000000..a027a05 --- /dev/null +++ b/packages/circom/tests/circuits/question2.json @@ -0,0 +1,12 @@ +{ + "parts": [ + { + "is_public": true, + "regex_def": "(1x?2)+" + }, + { + "is_public": false, + "regex_def": "b" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/question2_regex.circom b/packages/circom/tests/circuits/question2_regex.circom new file mode 100644 index 0000000..c717812 --- /dev/null +++ b/packages/circom/tests/circuits/question2_regex.circom @@ -0,0 +1,106 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: (1x?2)+b +template Question2Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[4][num_bytes]; + component and[6][num_bytes]; + component multi_or[1][num_bytes]; + signal states[num_bytes+1][5]; + signal states_tmp[num_bytes+1][5]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 5; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(4); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 49; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + and[1][i] = AND(); + and[1][i].a <== states[i][2]; + and[1][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== and[1][i].out; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 50; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== eq[1][i].out; + and[3][i] = AND(); + and[3][i].a <== states[i][3]; + and[3][i].b <== eq[1][i].out; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== and[2][i].out; + multi_or[0][i].in[1] <== and[3][i].out; + states[i+1][2] <== multi_or[0][i].out; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 120; + and[4][i] = AND(); + and[4][i].a <== states[i][1]; + and[4][i].b <== eq[2][i].out; + states[i+1][3] <== and[4][i].out; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 98; + and[5][i] = AND(); + and[5][i].a <== states[i][2]; + and[5][i].b <== eq[3][i].out; + states[i+1][4] <== and[5][i].out; + from_zero_enabled[i] <== MultiNOR(4)([states_tmp[i+1][1], states[i+1][2], states[i+1][3], states[i+1][4]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + state_changed[i].in[3] <== states[i+1][4]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][4]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][4] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][4], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(0, 1), (1, 2), (1, 3), (2, 1), (3, 2)}] + signal prev_states0[5][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(0, 1), (1, 2), (1, 3), (2, 1), (3, 2)] + prev_states0[0][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + is_substr0[i] <== MultiOR(5)([prev_states0[0][i] * states[i+2][1], prev_states0[1][i] * states[i+2][2], prev_states0[2][i] * states[i+2][3], prev_states0[3][i] * states[i+2][1], prev_states0[4][i] * states[i+2][2]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/question3.json b/packages/circom/tests/circuits/question3.json new file mode 100644 index 0000000..60c37ec --- /dev/null +++ b/packages/circom/tests/circuits/question3.json @@ -0,0 +1,16 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "12" + }, + { + "is_public": true, + "regex_def": "(a|b)?" + }, + { + "is_public": false, + "regex_def": "c" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/question3_regex.circom b/packages/circom/tests/circuits/question3_regex.circom new file mode 100644 index 0000000..0f62662 --- /dev/null +++ b/packages/circom/tests/circuits/question3_regex.circom @@ -0,0 +1,105 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: 12(a|b)?c +template Question3Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[5][num_bytes]; + component and[5][num_bytes]; + component multi_or[2][num_bytes]; + signal states[num_bytes+1][5]; + signal states_tmp[num_bytes+1][5]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 5; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(4); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 49; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 50; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + and[1][i].b <== eq[1][i].out; + states[i+1][2] <== and[1][i].out; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 97; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 98; + and[2][i] = AND(); + and[2][i].a <== states[i][2]; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== eq[2][i].out; + multi_or[0][i].in[1] <== eq[3][i].out; + and[2][i].b <== multi_or[0][i].out; + states[i+1][3] <== and[2][i].out; + eq[4][i] = IsEqual(); + eq[4][i].in[0] <== in[i]; + eq[4][i].in[1] <== 99; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== eq[4][i].out; + and[4][i] = AND(); + and[4][i].a <== states[i][3]; + and[4][i].b <== eq[4][i].out; + multi_or[1][i] = MultiOR(2); + multi_or[1][i].in[0] <== and[3][i].out; + multi_or[1][i].in[1] <== and[4][i].out; + states[i+1][4] <== multi_or[1][i].out; + from_zero_enabled[i] <== MultiNOR(4)([states_tmp[i+1][1], states[i+1][2], states[i+1][3], states[i+1][4]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + state_changed[i].in[3] <== states[i+1][4]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][4]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][4] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][4], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(2, 3)}] + signal prev_states0[1][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(2, 3)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + is_substr0[i] <== MultiOR(1)([prev_states0[0][i] * states[i+2][3]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/reveal_check1.json b/packages/circom/tests/circuits/reveal_check1.json new file mode 100644 index 0000000..fb97dab --- /dev/null +++ b/packages/circom/tests/circuits/reveal_check1.json @@ -0,0 +1,8 @@ +{ + "parts": [ + { + "is_public": true, + "regex_def": "aba" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/reveal_check1_regex.circom b/packages/circom/tests/circuits/reveal_check1_regex.circom new file mode 100644 index 0000000..998cb03 --- /dev/null +++ b/packages/circom/tests/circuits/reveal_check1_regex.circom @@ -0,0 +1,83 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: aba +template RevealCheck1Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[2][num_bytes]; + component and[3][num_bytes]; + signal states[num_bytes+1][4]; + signal states_tmp[num_bytes+1][4]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 4; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(3); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 97; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 98; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + and[1][i].b <== eq[1][i].out; + states[i+1][2] <== and[1][i].out; + and[2][i] = AND(); + and[2][i].a <== states[i][2]; + and[2][i].b <== eq[0][i].out; + states[i+1][3] <== and[2][i].out; + from_zero_enabled[i] <== MultiNOR(3)([states_tmp[i+1][1], states[i+1][2], states[i+1][3]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][3]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][3] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][3], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(0, 1), (1, 2), (2, 3)}] + signal prev_states0[3][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(0, 1), (1, 2), (2, 3)] + prev_states0[0][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + is_substr0[i] <== MultiOR(3)([prev_states0[0][i] * states[i+2][1], prev_states0[1][i] * states[i+2][2], prev_states0[2][i] * states[i+2][3]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/reveal_check2.json b/packages/circom/tests/circuits/reveal_check2.json new file mode 100644 index 0000000..971730a --- /dev/null +++ b/packages/circom/tests/circuits/reveal_check2.json @@ -0,0 +1,8 @@ +{ + "parts": [ + { + "is_public": true, + "regex_def": "a[ab]" + } + ] +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/reveal_check2_regex.circom b/packages/circom/tests/circuits/reveal_check2_regex.circom new file mode 100644 index 0000000..c646035 --- /dev/null +++ b/packages/circom/tests/circuits/reveal_check2_regex.circom @@ -0,0 +1,81 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: a[ab] +template RevealCheck2Regex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + in[i+1] <== msg[i]; + } + + component eq[2][num_bytes]; + component and[2][num_bytes]; + component multi_or[1][num_bytes]; + signal states[num_bytes+1][3]; + signal states_tmp[num_bytes+1][3]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 3; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(2); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 97; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 98; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== eq[0][i].out; + multi_or[0][i].in[1] <== eq[1][i].out; + and[1][i].b <== multi_or[0][i].out; + states[i+1][2] <== and[1][i].out; + from_zero_enabled[i] <== MultiNOR(2)([states_tmp[i+1][1], states[i+1][2]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][2]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][2] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][2], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(0, 1), (1, 2)}] + signal prev_states0[2][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(0, 1), (1, 2)] + prev_states0[0][i] <== from_zero_enabled[i+1] * states[i+1][0]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + is_substr0[i] <== MultiOR(2)([prev_states0[0][i] * states[i+2][1], prev_states0[1][i] * states[i+2][2]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circom/tests/circuits/simple_regex.circom b/packages/circom/tests/circuits/simple_regex.circom index e179ba0..4f8f6d4 100644 --- a/packages/circom/tests/circuits/simple_regex.circom +++ b/packages/circom/tests/circuits/simple_regex.circom @@ -121,44 +121,51 @@ template SimpleRegex(msg_bytes) { state_changed[i].in[8] <== states[i+1][9]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][9]; + is_accepted.in[i] <== states[i][9]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][9] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][9], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(2, 3)}, {(6, 7), (7, 7)}, {(8, 9)}] + signal prev_states0[1][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(2, 3)] - is_substr0[i] <== MultiOR(1)([states[i+1][2] * states[i+2][3]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + is_substr0[i] <== MultiOR(1)([prev_states0[0][i] * states[i+2][3]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } + signal prev_states1[2][msg_bytes]; signal is_substr1[msg_bytes]; signal is_reveal1[msg_bytes]; signal output reveal1[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 1-th substring transitions: [(6, 7), (7, 7)] - is_substr1[i] <== MultiOR(2)([states[i+1][6] * states[i+2][7], states[i+1][7] * states[i+2][7]]); - is_reveal1[i] <== is_substr1[i] * is_consecutive[i][2]; + prev_states1[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][6]; + prev_states1[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + is_substr1[i] <== MultiOR(2)([prev_states1[0][i] * states[i+2][7], prev_states1[1][i] * states[i+2][7]]); + is_reveal1[i] <== MultiAND(3)([out, is_substr1[i], is_consecutive[i][2]]); reveal1[i] <== in[i+1] * is_reveal1[i]; } + signal prev_states2[1][msg_bytes]; signal is_substr2[msg_bytes]; signal is_reveal2[msg_bytes]; signal output reveal2[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 2-th substring transitions: [(8, 9)] - is_substr2[i] <== MultiOR(1)([states[i+1][8] * states[i+2][9]]); - is_reveal2[i] <== is_substr2[i] * is_consecutive[i][2]; + prev_states2[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][8]; + is_substr2[i] <== MultiOR(1)([prev_states2[0][i] * states[i+2][9]]); + is_reveal2[i] <== MultiAND(3)([out, is_substr2[i], is_consecutive[i][2]]); reveal2[i] <== in[i+1] * is_reveal2[i]; } } \ No newline at end of file diff --git a/packages/circom/tests/circuits/simple_regex_decomposed.circom b/packages/circom/tests/circuits/simple_regex_decomposed.circom index 5bbe334..2bef8e7 100644 --- a/packages/circom/tests/circuits/simple_regex_decomposed.circom +++ b/packages/circom/tests/circuits/simple_regex_decomposed.circom @@ -266,26 +266,29 @@ template SimpleRegexDecomposed(msg_bytes) { state_changed[i].in[22] <== states[i+1][23]; } - component final_state_result = MultiOR(num_bytes+1); + component is_accepted = MultiOR(num_bytes+1); for (var i = 0; i <= num_bytes; i++) { - final_state_result.in[i] <== states[i][23]; + is_accepted.in[i] <== states[i][23]; } - out <== final_state_result.out; + out <== is_accepted.out; signal is_consecutive[msg_bytes+1][3]; - is_consecutive[msg_bytes][2] <== 1; + is_consecutive[msg_bytes][2] <== 0; for (var i = 0; i < msg_bytes; i++) { is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][23] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][23], is_consecutive[msg_bytes-1-i][1]]); } // substrings calculated: [{(21, 22), (22, 22)}] + signal prev_states0[2][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { // the 0-th substring transitions: [(21, 22), (22, 22)] - is_substr0[i] <== MultiOR(2)([states[i+1][21] * states[i+2][22], states[i+1][22] * states[i+2][22]]); - is_reveal0[i] <== is_substr0[i] * is_consecutive[i][2]; + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][21]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][22]; + is_substr0[i] <== MultiOR(2)([prev_states0[0][i] * states[i+2][22], prev_states0[1][i] * states[i+2][22]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } } \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_asterisk1_regex.circom b/packages/circom/tests/circuits/test_asterisk1_regex.circom new file mode 100644 index 0000000..dd58f8c --- /dev/null +++ b/packages/circom/tests/circuits/test_asterisk1_regex.circom @@ -0,0 +1,3 @@ +include "./asterisk1_regex.circom"; + +component main = Asterisk1Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_asterisk2_regex.circom b/packages/circom/tests/circuits/test_asterisk2_regex.circom new file mode 100644 index 0000000..271b997 --- /dev/null +++ b/packages/circom/tests/circuits/test_asterisk2_regex.circom @@ -0,0 +1,3 @@ +include "./asterisk2_regex.circom"; + +component main = Asterisk2Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_asterisk3_regex.circom b/packages/circom/tests/circuits/test_asterisk3_regex.circom new file mode 100644 index 0000000..0744f94 --- /dev/null +++ b/packages/circom/tests/circuits/test_asterisk3_regex.circom @@ -0,0 +1,3 @@ +include "./asterisk3_regex.circom"; + +component main = Asterisk3Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_caret1_regex.circom b/packages/circom/tests/circuits/test_caret1_regex.circom new file mode 100644 index 0000000..75c867a --- /dev/null +++ b/packages/circom/tests/circuits/test_caret1_regex.circom @@ -0,0 +1,3 @@ +include "./caret1_regex.circom"; + +component main = Caret1Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_caret2_regex.circom b/packages/circom/tests/circuits/test_caret2_regex.circom new file mode 100644 index 0000000..52d18be --- /dev/null +++ b/packages/circom/tests/circuits/test_caret2_regex.circom @@ -0,0 +1,3 @@ +include "./caret2_regex.circom"; + +component main = Caret2Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_caret3_regex.circom b/packages/circom/tests/circuits/test_caret3_regex.circom new file mode 100644 index 0000000..8f4a6de --- /dev/null +++ b/packages/circom/tests/circuits/test_caret3_regex.circom @@ -0,0 +1,3 @@ +include "./caret3_regex.circom"; + +component main = Caret3Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_caret4_regex.circom b/packages/circom/tests/circuits/test_caret4_regex.circom new file mode 100644 index 0000000..71118e7 --- /dev/null +++ b/packages/circom/tests/circuits/test_caret4_regex.circom @@ -0,0 +1,3 @@ +include "./caret4_regex.circom"; + +component main = Caret4Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_caret5_regex.circom b/packages/circom/tests/circuits/test_caret5_regex.circom new file mode 100644 index 0000000..695afc4 --- /dev/null +++ b/packages/circom/tests/circuits/test_caret5_regex.circom @@ -0,0 +1,3 @@ +include "./caret5_regex.circom"; + +component main = Caret5Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_dollar1_regex.circom b/packages/circom/tests/circuits/test_dollar1_regex.circom new file mode 100644 index 0000000..bf96b77 --- /dev/null +++ b/packages/circom/tests/circuits/test_dollar1_regex.circom @@ -0,0 +1,3 @@ +include "./dollar1_regex.circom"; + +component main = Dollar1Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_dollar2_regex.circom b/packages/circom/tests/circuits/test_dollar2_regex.circom new file mode 100644 index 0000000..12f41ae --- /dev/null +++ b/packages/circom/tests/circuits/test_dollar2_regex.circom @@ -0,0 +1,3 @@ +include "./dollar2_regex.circom"; + +component main = Dollar2Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_dot1_regex.circom b/packages/circom/tests/circuits/test_dot1_regex.circom new file mode 100644 index 0000000..d0f1663 --- /dev/null +++ b/packages/circom/tests/circuits/test_dot1_regex.circom @@ -0,0 +1,3 @@ +include "./dot1_regex.circom"; + +component main = Dot1Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_dot2_regex.circom b/packages/circom/tests/circuits/test_dot2_regex.circom new file mode 100644 index 0000000..b57d5be --- /dev/null +++ b/packages/circom/tests/circuits/test_dot2_regex.circom @@ -0,0 +1,3 @@ +include "./dot2_regex.circom"; + +component main = Dot2Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_negate2_regex.circom b/packages/circom/tests/circuits/test_negate2_regex.circom new file mode 100644 index 0000000..5fe46a7 --- /dev/null +++ b/packages/circom/tests/circuits/test_negate2_regex.circom @@ -0,0 +1,2 @@ +include "./negate2_regex.circom"; +component main = Negate2Regex(64); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_plus1_regex.circom b/packages/circom/tests/circuits/test_plus1_regex.circom new file mode 100644 index 0000000..b08577f --- /dev/null +++ b/packages/circom/tests/circuits/test_plus1_regex.circom @@ -0,0 +1,3 @@ +include "./plus1_regex.circom"; + +component main = Plus1Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_plus2_regex.circom b/packages/circom/tests/circuits/test_plus2_regex.circom new file mode 100644 index 0000000..9f7b6dc --- /dev/null +++ b/packages/circom/tests/circuits/test_plus2_regex.circom @@ -0,0 +1,3 @@ +include "./plus2_regex.circom"; + +component main = Plus2Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_plus3_regex.circom b/packages/circom/tests/circuits/test_plus3_regex.circom new file mode 100644 index 0000000..ae2aee7 --- /dev/null +++ b/packages/circom/tests/circuits/test_plus3_regex.circom @@ -0,0 +1,3 @@ +include "./plus3_regex.circom"; + +component main = Plus3Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_plus4_regex.circom b/packages/circom/tests/circuits/test_plus4_regex.circom new file mode 100644 index 0000000..6e7d760 --- /dev/null +++ b/packages/circom/tests/circuits/test_plus4_regex.circom @@ -0,0 +1,3 @@ +include "./plus4_regex.circom"; + +component main = Plus4Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_question1_regex.circom b/packages/circom/tests/circuits/test_question1_regex.circom new file mode 100644 index 0000000..e9f5cbd --- /dev/null +++ b/packages/circom/tests/circuits/test_question1_regex.circom @@ -0,0 +1,3 @@ +include "./question1_regex.circom"; + +component main = Question1Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_question2_regex.circom b/packages/circom/tests/circuits/test_question2_regex.circom new file mode 100644 index 0000000..be7b302 --- /dev/null +++ b/packages/circom/tests/circuits/test_question2_regex.circom @@ -0,0 +1,3 @@ +include "./question2_regex.circom"; + +component main = Question2Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_question3_regex.circom b/packages/circom/tests/circuits/test_question3_regex.circom new file mode 100644 index 0000000..9648de6 --- /dev/null +++ b/packages/circom/tests/circuits/test_question3_regex.circom @@ -0,0 +1,3 @@ +include "./question3_regex.circom"; + +component main = Question3Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_reveal_check1_regex.circom b/packages/circom/tests/circuits/test_reveal_check1_regex.circom new file mode 100644 index 0000000..c10af39 --- /dev/null +++ b/packages/circom/tests/circuits/test_reveal_check1_regex.circom @@ -0,0 +1,3 @@ +include "./reveal_check1_regex.circom"; + +component main = RevealCheck1Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/circuits/test_reveal_check2_regex.circom b/packages/circom/tests/circuits/test_reveal_check2_regex.circom new file mode 100644 index 0000000..c6c9062 --- /dev/null +++ b/packages/circom/tests/circuits/test_reveal_check2_regex.circom @@ -0,0 +1,3 @@ +include "./reveal_check2_regex.circom"; + +component main = RevealCheck2Regex(8); \ No newline at end of file diff --git a/packages/circom/tests/dollar.test.js b/packages/circom/tests/dollar.test.js new file mode 100644 index 0000000..6a2cdbd --- /dev/null +++ b/packages/circom/tests/dollar.test.js @@ -0,0 +1,191 @@ +import circom_tester from "circom_tester"; +import * as path from "path"; +import { readFileSync, writeFileSync } from "fs"; +import apis from "../../apis/pkg"; +import compiler from "../../compiler/pkg"; +const option = { + include: path.join(__dirname, "../../../node_modules"), +}; +const wasm_tester = circom_tester.wasm; + +jest.setTimeout(600000); +describe("Caret Regex", () => { + let circuit1; + let circuit2; + beforeAll(async () => { + writeFileSync( + path.join(__dirname, "./circuits/dollar1_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/dollar1.json"), + "utf8" + ), + "Dollar1Regex" + ) + ); + circuit1 = await wasm_tester( + path.join(__dirname, "./circuits/test_dollar1_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/dollar2_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/dollar2.json"), + "utf8" + ), + "Dollar2Regex" + ) + ); + circuit2 = await wasm_tester( + path.join(__dirname, "./circuits/test_dollar2_regex.circom"), + option + ); + }); + + it("dollar1 valid case 1", async () => { + const inputStr = `ab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/dollar1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("dollar1 invalid case 1", async () => { + const inputStr = `abg`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("dollar1 invalid case 2", async () => { + const inputStr = `18abcg`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("dollar2 valid case 1", async () => { + const inputStr = `xab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/dollar2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("dollar2 valid case 2", async () => { + const inputStr = `ak\nxab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/dollar2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("dollar2 invalid case 1", async () => { + const inputStr = `abg`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("dollar2 invalid case 2", async () => { + const inputStr = `\nabg`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("dollar2 invalid case 2", async () => { + const inputStr = `\nabg`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); +}); diff --git a/packages/circom/tests/dot.test.js b/packages/circom/tests/dot.test.js new file mode 100644 index 0000000..5bfcc8b --- /dev/null +++ b/packages/circom/tests/dot.test.js @@ -0,0 +1,174 @@ +import circom_tester from "circom_tester"; +import * as path from "path"; +import { readFileSync, writeFileSync } from "fs"; +import apis from "../../apis/pkg"; +import compiler from "../../compiler/pkg"; +const option = { + include: path.join(__dirname, "../../../node_modules"), +}; +const wasm_tester = circom_tester.wasm; + +jest.setTimeout(600000); +describe("Dot Regex", () => { + let circuit1; + let circuit2; + beforeAll(async () => { + writeFileSync( + path.join(__dirname, "./circuits/dot1_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/dot1.json"), + "utf8" + ), + "Dot1Regex" + ) + ); + circuit1 = await wasm_tester( + path.join(__dirname, "./circuits/test_dot1_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/dot2_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/dot2.json"), + "utf8" + ), + "Dot2Regex" + ) + ); + circuit2 = await wasm_tester( + path.join(__dirname, "./circuits/test_dot2_regex.circom"), + option + ); + }); + + it("dot1 valid case 1", async () => { + const inputStr = `a`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/dot1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + // it("dot1 valid case 2", async () => { + // const inputStr = `aaaa`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit1.calculateWitness(circuitInputs); + // await circuit1.checkConstraints(witness); + // expect(1n).toEqual(witness[1]); + // const prefixIdxes = apis.extractSubstrIdxes( + // inputStr, + // readFileSync( + // path.join(__dirname, "./circuits/dot1.json"), + // "utf8" + // ) + // )[0]; + // for (let idx = 0; idx < 8; ++idx) { + // if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + // expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + // } else { + // expect(0n).toEqual(witness[2 + idx]); + // } + // } + // }); + + it("dot2 valid case 1", async () => { + const inputStr = `a6b`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/dot2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + // it("dot2 valid case 2", async () => { + // const inputStr = `aa6b`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit2.calculateWitness(circuitInputs); + // await circuit2.checkConstraints(witness); + // expect(1n).toEqual(witness[1]); + // const prefixIdxes = apis.extractSubstrIdxes( + // inputStr, + // readFileSync( + // path.join(__dirname, "./circuits/dot2.json"), + // "utf8" + // ) + // )[0]; + // for (let idx = 0; idx < 8; ++idx) { + // if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + // expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + // } else { + // expect(0n).toEqual(witness[2 + idx]); + // } + // } + // }); + + it("dot2 invalid case 1", async () => { + const inputStr = `819nc8b8`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("dot2 invalid case 2", async () => { + const inputStr = `78aa6cc8`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); +}); diff --git a/packages/circom/tests/from_addr.test.js b/packages/circom/tests/from_addr.test.js index 1b0adc7..234abd9 100644 --- a/packages/circom/tests/from_addr.test.js +++ b/packages/circom/tests/from_addr.test.js @@ -215,4 +215,17 @@ describe("From Addr Regex", () => { } } }); + + it("invalid from field", async () => { + const fromStr = "\r\nto:from:Sora Suegami \r\n"; + const paddedStr = apis.padString(fromStr, 1024); + const circuitInputs = { + msg: paddedStr, + }; + async function failFn() { + await circuit.calculateWitness(circuitInputs); + } + await expect(failFn).rejects.toThrow(); + }); + }); diff --git a/packages/circom/tests/message_id_regex.test.js b/packages/circom/tests/message_id_regex.test.js index 52960ee..3c992a6 100644 --- a/packages/circom/tests/message_id_regex.test.js +++ b/packages/circom/tests/message_id_regex.test.js @@ -49,7 +49,7 @@ describe("Message Id Regex", () => { } }); - it("subject after new line", async () => { + it("message id after new line", async () => { const messageIdStr = "dummy\r\nmessage-id:\r\n"; const paddedStr = apis.padString(messageIdStr, 256); @@ -68,4 +68,18 @@ describe("Message Id Regex", () => { } } }); + + it("invalid message id", async () => { + const messageIdStr = `to:message-id:\r\n`; + const paddedStr = apis.padString(messageIdStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 256; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); }); diff --git a/packages/circom/tests/negate_regex.test.js b/packages/circom/tests/negate_regex.test.js index 13593e4..ccef68f 100644 --- a/packages/circom/tests/negate_regex.test.js +++ b/packages/circom/tests/negate_regex.test.js @@ -10,24 +10,37 @@ const wasm_tester = circom_tester.wasm; jest.setTimeout(120000); describe("Negate Regex", () => { - let circuit; + let circuit1; + let circuit2; beforeAll(async () => { - const email_addr_json = readFileSync( - path.join(__dirname, "./circuits/negate1.json"), - "utf8" - ); - const circom = compiler.genFromDecomposed( - email_addr_json, - "Negate1Regex" - ); writeFileSync( path.join(__dirname, "./circuits/negate1_regex.circom"), - circom + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/negate1.json"), + "utf8" + ), + "Negate1Regex" + ) ); - circuit = await wasm_tester( + circuit1 = await wasm_tester( path.join(__dirname, "./circuits/test_negate1_regex.circom"), option ); + writeFileSync( + path.join(__dirname, "./circuits/negate2_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/negate2.json"), + "utf8" + ), + "Negate2Regex" + ) + ); + circuit2 = await wasm_tester( + path.join(__dirname, "./circuits/test_negate2_regex.circom"), + option + ); }); it("case 1 with regex 1", async () => { @@ -36,8 +49,8 @@ describe("Negate Regex", () => { const circuitInputs = { msg: paddedStr, }; - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); expect(1n).toEqual(witness[1]); const revealedIdx = [[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]]; for (let substr_idx = 0; substr_idx < 1; ++substr_idx) { @@ -59,8 +72,8 @@ describe("Negate Regex", () => { const circuitInputs = { msg: paddedStr, }; - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); expect(1n).toEqual(witness[1]); const revealedIdx = [[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]]; for (let substr_idx = 0; substr_idx < 1; ++substr_idx) { @@ -82,8 +95,8 @@ describe("Negate Regex", () => { const circuitInputs = { msg: paddedStr, }; - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); expect(1n).toEqual(witness[1]); const revealedIdx = [[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]]; for (let substr_idx = 0; substr_idx < 1; ++substr_idx) { @@ -105,8 +118,8 @@ describe("Negate Regex", () => { const circuitInputs = { msg: paddedStr, }; - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); expect(1n).toEqual(witness[1]); const revealedIdx = [[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]; for (let substr_idx = 0; substr_idx < 1; ++substr_idx) { @@ -121,4 +134,37 @@ describe("Negate Regex", () => { } } }); + + it("case 1 with regex 2", async () => { + const input = "abdefia"; + const paddedStr = apis.padString(input, 64); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const revealedIdx = [2,3,4,5]; + for (let idx = 0; idx < 64; ++idx) { + if (revealedIdx.includes(idx)) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("invalid case 1 with regex 2", async () => { + const input = "a"; + const paddedStr = apis.padString(input, 64); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 64; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); }); diff --git a/packages/circom/tests/plus.test.js b/packages/circom/tests/plus.test.js new file mode 100644 index 0000000..869e11b --- /dev/null +++ b/packages/circom/tests/plus.test.js @@ -0,0 +1,652 @@ +import circom_tester from "circom_tester"; +import * as path from "path"; +import { readFileSync, writeFileSync } from "fs"; +import apis from "../../apis/pkg"; +import compiler from "../../compiler/pkg"; +const option = { + include: path.join(__dirname, "../../../node_modules"), +}; +const wasm_tester = circom_tester.wasm; + +jest.setTimeout(600000); +describe("Plus Regex", () => { + let circuit1; + let circuit2; + let circuit3; + let circuit4; + // let circuit5; + // let circuit6; + beforeAll(async () => { + writeFileSync( + path.join(__dirname, "./circuits/plus1_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/plus1.json"), + "utf8" + ), + "Plus1Regex" + ) + ); + circuit1 = await wasm_tester( + path.join(__dirname, "./circuits/test_plus1_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/plus2_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/plus2.json"), + "utf8" + ), + "Plus2Regex" + ) + ); + circuit2 = await wasm_tester( + path.join(__dirname, "./circuits/test_plus2_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/plus3_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/plus3.json"), + "utf8" + ), + "Plus3Regex" + ) + ); + circuit3 = await wasm_tester( + path.join(__dirname, "./circuits/test_plus3_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/plus4_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/plus4.json"), + "utf8" + ), + "Plus4Regex" + ) + ); + circuit4 = await wasm_tester( + path.join(__dirname, "./circuits/test_plus4_regex.circom"), + option + ); + + // writeFileSync( + // path.join(__dirname, "./circuits/plus5_regex.circom"), + // compiler.genFromDecomposed( + // readFileSync( + // path.join(__dirname, "./circuits/plus5.json"), + // "utf8" + // ), + // "Plus5Regex" + // ) + // ); + // circuit5 = await wasm_tester( + // path.join(__dirname, "./circuits/test_plus5_regex.circom"), + // option + // ); + + // writeFileSync( + // path.join(__dirname, "./circuits/plus6_regex.circom"), + // compiler.genFromDecomposed( + // readFileSync( + // path.join(__dirname, "./circuits/plus6.json"), + // "utf8" + // ), + // "Plus6Regex" + // ) + // ); + // circuit6 = await wasm_tester( + // path.join(__dirname, "./circuits/test_plus6_regex.circom"), + // option + // ); + }); + + it("plus1 valid case 1", async () => { + const inputStr = `ab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/plus1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + + it("plus1 valid case 2", async () => { + const inputStr = `aaaab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/plus1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("plus1 valid case 3", async () => { + const inputStr = `7aab89ac`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/plus1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("plus1 invalid case 1", async () => { + const inputStr = `b`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("plus1 invalid case 2", async () => { + const inputStr = `aacaadae`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("plus1 invalid case 3", async () => { + const inputStr = `aaaaaaaa`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("plus2 valid case 1", async () => { + const inputStr = `ab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/plus2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("plus2 valid case 2", async () => { + const inputStr = `ac`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/plus2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("plus2 valid case 3", async () => { + const inputStr = `abccbbcc`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/plus2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("plus2 valid case 4", async () => { + const inputStr = `7abbcaa`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/plus2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("plus2 invalid case 1", async () => { + const inputStr = `adefghij`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("plus3 valid case 1", async () => { + const inputStr = `abcbcbc`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/plus3.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("plus3 valid case 2", async () => { + const inputStr = `acbabcbc`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/plus3.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("plus3 valid case 3", async () => { + const inputStr = `abccbcbb`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/plus3.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("plus3 invalid case 1", async () => { + const inputStr = `abab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("plus4 valid case 1", async () => { + const inputStr = `1234512b`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit4.calculateWitness(circuitInputs); + await circuit4.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/plus4.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("plus4 valid case 2", async () => { + const inputStr = `2134512b`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit4.calculateWitness(circuitInputs); + await circuit4.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/plus4.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("plus4 invalid case 1", async () => { + const inputStr = `1234b`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit4.calculateWitness(circuitInputs); + await circuit4.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("plus4 invalid case 2", async () => { + const inputStr = `34512`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit4.calculateWitness(circuitInputs); + await circuit4.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + // it("plus5 valid case 1", async () => { + // const inputStr = `aa`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit5.calculateWitness(circuitInputs); + // await circuit5.checkConstraints(witness); + // expect(1n).toEqual(witness[1]); + // const prefixIdxes = apis.extractSubstrIdxes( + // inputStr, + // readFileSync( + // path.join(__dirname, "./circuits/plus5.json"), + // "utf8" + // ) + // )[0]; + // for (let idx = 0; idx < 8; ++idx) { + // if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + // expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + // } else { + // expect(0n).toEqual(witness[2 + idx]); + // } + // } + // }); + + // it("plus5 valid case 2", async () => { + // const inputStr = `aaaababb`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit5.calculateWitness(circuitInputs); + // await circuit5.checkConstraints(witness); + // expect(1n).toEqual(witness[1]); + // const prefixIdxes = apis.extractSubstrIdxes( + // inputStr, + // readFileSync( + // path.join(__dirname, "./circuits/plus5.json"), + // "utf8" + // ) + // )[0]; + // for (let idx = 0; idx < 8; ++idx) { + // if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + // expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + // } else { + // expect(0n).toEqual(witness[2 + idx]); + // } + // } + // }); + + // it("plus5 valid case 3", async () => { + // const inputStr = `bbcw2cab`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit5.calculateWitness(circuitInputs); + // await circuit5.checkConstraints(witness); + // expect(1n).toEqual(witness[1]); + // const prefixIdxes = apis.extractSubstrIdxes( + // inputStr, + // readFileSync( + // path.join(__dirname, "./circuits/plus5.json"), + // "utf8" + // ) + // )[0]; + // for (let idx = 0; idx < 8; ++idx) { + // if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + // expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + // } else { + // expect(0n).toEqual(witness[2 + idx]); + // } + // } + // }); + + // it("plus5 invalid case 1", async () => { + // const inputStr = `872jdiua`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit5.calculateWitness(circuitInputs); + // await circuit5.checkConstraints(witness); + // expect(0n).toEqual(witness[1]); + // for (let idx = 0; idx < 8; ++idx) { + // expect(0n).toEqual(witness[2 + idx]); + // } + // }); + + // it("plus5 invalid case 2", async () => { + // const inputStr = `872jdiu7`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit5.calculateWitness(circuitInputs); + // await circuit5.checkConstraints(witness); + // expect(0n).toEqual(witness[1]); + // for (let idx = 0; idx < 8; ++idx) { + // expect(0n).toEqual(witness[2 + idx]); + // } + // }); + + + // it("plus6 valid case 1", async () => { + // const inputStr = `aaaabbbb`; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit6.calculateWitness(circuitInputs); + // await circuit6.checkConstraints(witness); + // expect(1n).toEqual(witness[1]); + // const prefixIdxes = apis.extractSubstrIdxes( + // inputStr, + // readFileSync( + // path.join(__dirname, "./circuits/plus6.json"), + // "utf8" + // ) + // )[0]; + // for (let idx = 0; idx < 8; ++idx) { + // if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + // expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + // } else { + // expect(0n).toEqual(witness[2 + idx]); + // } + // } + // }); + + // it("plus6 invalid case 1", async () => { + // const inputStr = ``; + // const paddedStr = apis.padString(inputStr, 8); + // const circuitInputs = { + // msg: paddedStr, + // }; + // const witness = await circuit6.calculateWitness(circuitInputs); + // await circuit6.checkConstraints(witness); + // expect(0n).toEqual(witness[1]); + // for (let idx = 0; idx < 8; ++idx) { + // expect(0n).toEqual(witness[2 + idx]); + // } + // }); +}); diff --git a/packages/circom/tests/question.test.js b/packages/circom/tests/question.test.js new file mode 100644 index 0000000..573358a --- /dev/null +++ b/packages/circom/tests/question.test.js @@ -0,0 +1,385 @@ +import circom_tester from "circom_tester"; +import * as path from "path"; +import { readFileSync, writeFileSync } from "fs"; +import apis from "../../apis/pkg"; +import compiler from "../../compiler/pkg"; +const option = { + include: path.join(__dirname, "../../../node_modules"), +}; +const wasm_tester = circom_tester.wasm; + +jest.setTimeout(600000); +describe("Question Regex", () => { + let circuit1; + let circuit2; + let circuit3; + beforeAll(async () => { + writeFileSync( + path.join(__dirname, "./circuits/question1_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/question1.json"), + "utf8" + ), + "Question1Regex" + ) + ); + circuit1 = await wasm_tester( + path.join(__dirname, "./circuits/test_question1_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/question2_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/question2.json"), + "utf8" + ), + "Question2Regex" + ) + ); + circuit2 = await wasm_tester( + path.join(__dirname, "./circuits/test_question2_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/question3_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/question3.json"), + "utf8" + ), + "Question3Regex" + ) + ); + circuit3 = await wasm_tester( + path.join(__dirname, "./circuits/test_question3_regex.circom"), + option + ); + }); + + it("question1 valid case 1", async () => { + const inputStr = `b`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/question1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("question1 valid case 2", async () => { + const inputStr = `ab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/question1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("question1 valid case 3", async () => { + const inputStr = `199aabb`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/question1.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("question1 invalid case 1", async () => { + const inputStr = `aaaaaaaa`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("question1 invalid case 2", async () => { + const inputStr = `cccccccc`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("question2 valid case 1", async () => { + const inputStr = `12b`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/question2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("question2 valid case 2", async () => { + const inputStr = `11x2bb`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/question2.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("question2 invalid case 1", async () => { + const inputStr = `1x2`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("question2 invalid case 2", async () => { + const inputStr = `1xb`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("question3 valid case 1", async () => { + const inputStr = `12c`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/question3.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("question3 valid case 2", async () => { + const inputStr = `12ac`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/question3.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("question3 valid case 2", async () => { + const inputStr = `12bc`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/question3.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("question3 valid case 4", async () => { + const inputStr = `12a12bc1`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/question3.json"), + "utf8" + ) + )[0]; + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("question3 invalid case 1", async () => { + const inputStr = `1ac`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("question3 invalid case 2", async () => { + const inputStr = `12abc`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("question3 invalid case 3", async () => { + const inputStr = `12a12b`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit3.calculateWitness(circuitInputs); + await circuit3.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); +}); diff --git a/packages/circom/tests/reveal_check.test.js b/packages/circom/tests/reveal_check.test.js new file mode 100644 index 0000000..695ebf8 --- /dev/null +++ b/packages/circom/tests/reveal_check.test.js @@ -0,0 +1,249 @@ +import circom_tester from "circom_tester"; +import * as path from "path"; +import { readFileSync, writeFileSync } from "fs"; +import apis from "../../apis/pkg"; +import compiler from "../../compiler/pkg"; +const option = { + include: path.join(__dirname, "../../../node_modules"), +}; +const wasm_tester = circom_tester.wasm; + +jest.setTimeout(600000); +describe("Revealed Chars Check", () => { + let circuit1; + let circuit2; + beforeAll(async () => { + writeFileSync( + path.join(__dirname, "./circuits/reveal_check1_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/reveal_check1.json"), + "utf8" + ), + "RevealCheck1Regex" + ) + ); + circuit1 = await wasm_tester( + path.join(__dirname, "./circuits/test_reveal_check1_regex.circom"), + option + ); + + writeFileSync( + path.join(__dirname, "./circuits/reveal_check2_regex.circom"), + compiler.genFromDecomposed( + readFileSync( + path.join(__dirname, "./circuits/reveal_check2.json"), + "utf8" + ), + "RevealCheck2Regex" + ) + ); + circuit2 = await wasm_tester( + path.join(__dirname, "./circuits/test_reveal_check2_regex.circom"), + option + ); + }); + + it("reveal check1 valid case 1", async () => { + const inputStr = `aba`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/reveal_check1.json"), + "utf8" + ) + )[0]; + expect(prefixIdxes).toEqual([0,3]); + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + + it("reveal check1 valid case 2", async () => { + const inputStr = `7abaab9`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/reveal_check1.json"), + "utf8" + ) + )[0]; + expect(prefixIdxes).toEqual([1,4]); + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("reveal check1 invalid case 1", async () => { + const inputStr = `aca`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("reveal check1 invalid case 2", async () => { + const inputStr = `aaa`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit1.calculateWitness(circuitInputs); + await circuit1.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("reveal check2 valid case 1", async () => { + const inputStr = `aa`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/reveal_check2.json"), + "utf8" + ) + )[0]; + expect(prefixIdxes).toEqual([0,2]); + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("reveal check2 valid case 2", async () => { + const inputStr = `ab`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/reveal_check2.json"), + "utf8" + ) + )[0]; + expect(prefixIdxes).toEqual([0,2]); + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("reveal check2 valid case 3", async () => { + const inputStr = `aba`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractSubstrIdxes( + inputStr, + readFileSync( + path.join(__dirname, "./circuits/reveal_check2.json"), + "utf8" + ) + )[0]; + expect(prefixIdxes).toEqual([0,2]); + for (let idx = 0; idx < 8; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("reveal check2 invalid case 1", async () => { + const inputStr = `ac`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("reveal check2 invalid case 2", async () => { + const inputStr = `bad`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + it("reveal check2 invalid case 3", async () => { + const inputStr = `bad`; + const paddedStr = apis.padString(inputStr, 8); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit2.calculateWitness(circuitInputs); + await circuit2.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 8; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); + + +}); diff --git a/packages/circom/tests/subject_all.test.js b/packages/circom/tests/subject_all.test.js index c28c70d..d1d8d5c 100644 --- a/packages/circom/tests/subject_all.test.js +++ b/packages/circom/tests/subject_all.test.js @@ -86,4 +86,18 @@ describe("Subject All Regex", () => { } } }); + + it("invalid subject", async () => { + const subjectStr = "\r\nto:subject:This is a subject in To field.\r\n"; + const paddedStr = apis.padString(subjectStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 256; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); }); diff --git a/packages/circom/tests/timestamp.test.js b/packages/circom/tests/timestamp.test.js index 14afd0c..dd022e8 100644 --- a/packages/circom/tests/timestamp.test.js +++ b/packages/circom/tests/timestamp.test.js @@ -67,4 +67,19 @@ describe("Timestamp Regex", () => { } } }); + + + it("invalid timestamp", async () => { + const signatureField = `to:dkim-signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694989812; x=1695594612; dara=google.com; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; b=`; + const paddedStr = apis.padString(signatureField, 1024); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(0n).toEqual(witness[1]); + for (let idx = 0; idx < 1024; ++idx) { + expect(0n).toEqual(witness[2 + idx]); + } + }); }); diff --git a/packages/circom/tests/to_addr.test.js b/packages/circom/tests/to_addr.test.js index 7d97adf..e981147 100644 --- a/packages/circom/tests/to_addr.test.js +++ b/packages/circom/tests/to_addr.test.js @@ -214,4 +214,16 @@ describe("To Addr Regex", () => { } } }); + + it("invalid to field", async () => { + const toStr = "subject:to:adityabisht@gmail.com\r\n"; + const paddedStr = apis.padString(toStr, 1024); + const circuitInputs = { + msg: paddedStr, + }; + async function failFn() { + await circuit.calculateWitness(circuitInputs); + } + await expect(failFn).rejects.toThrow(); + }); }); diff --git a/packages/compiler/README.md b/packages/compiler/README.md index 8759458..30c055b 100644 --- a/packages/compiler/README.md +++ b/packages/compiler/README.md @@ -120,3 +120,12 @@ The Rust library's main module. ### target/ Binary artifacts generated by the Rust build. + +## Regex Limitations +The regular expressions supported by our compiler have the following limitations: + +- Regular expressions where the results differ between greedy and lazy matching (e.g., .+, .+?) are **not** supported. +- The beginning anchor ^ must either appear at the beginning of the regular expression or be in the format (|^). Additionally, the section containing this ^ must be non-public (`is_public: false`). +- The end anchor $ must appear at the end of the regular expression. +- Regular expressions that, when converted to DFA (Deterministic Finite Automaton), include transitions to the initial state are **not** supported (e.g., .*). +- Regular expressions that, when converted to DFA, have multiple accepting states are **not** supported. diff --git a/packages/compiler/src/bin/compiler.rs b/packages/compiler/src/bin/compiler.rs index 18b95e8..0985c76 100644 --- a/packages/compiler/src/bin/compiler.rs +++ b/packages/compiler/src/bin/compiler.rs @@ -14,8 +14,6 @@ enum Commands { Decomposed { #[arg(short, long)] decomposed_regex_path: String, - // #[arg(short, long)] - // halo2_dir_path: Option, #[arg(short, long)] circom_file_path: Option, #[arg(short, long)] @@ -26,12 +24,8 @@ enum Commands { Raw { #[arg(short, long)] raw_regex: String, - // #[arg(short, long)] - // max_bytes: usize, #[arg(short, long)] substrs_json_path: Option, - // #[arg(short, long)] - // halo2_dir_path: Option, #[arg(short, long)] circom_file_path: Option, #[arg(short, long)] @@ -46,14 +40,12 @@ fn main() { match cli.command { Commands::Decomposed { decomposed_regex_path, - // halo2_dir_path, circom_file_path, template_name, gen_substrs, } => { gen_from_decomposed( &decomposed_regex_path, - // halo2_dir_path.as_ref().map(|s| s.as_str()), circom_file_path.as_ref().map(|s| s.as_str()), template_name.as_ref().map(|s| s.as_str()), gen_substrs, @@ -61,60 +53,18 @@ fn main() { } Commands::Raw { raw_regex, - // max_bytes, substrs_json_path, - // halo2_dir_path, circom_file_path, template_name, gen_substrs, } => { gen_from_raw( &raw_regex, - // max_bytes, substrs_json_path.as_ref().map(|s| s.as_str()), - // halo2_dir_path.as_ref().map(|s| s.as_str()), circom_file_path.as_ref().map(|s| s.as_str()), template_name.as_ref().map(|s| s.as_str()), gen_substrs, ); - } // Commands::GenHalo2Texts { - // decomposed_regex_path, - // allstr_file_path, - // substrs_dir_path, - // } => { - // let regex_decomposed: DecomposedRegexConfig = - // serde_json::from_reader(File::open(decomposed_regex_path).unwrap()).unwrap(); - // let num_public_part = regex_decomposed - // .parts - // .iter() - // .filter(|part| part.is_public) - // .collect_vec() - // .len(); - // let substr_file_pathes = (0..num_public_part) - // .map(|idx| { - // PathBuf::new() - // .join(&substrs_dir_path) - // .join(&format!("substr{}.txt", idx)) - // }) - // .collect_vec(); - // regex_decomposed - // .gen_regex_files( - // &Path::new(&allstr_file_path).to_path_buf(), - // &substr_file_pathes, - // ) - // .unwrap(); - // } - // Commands::GenCircom { - // decomposed_regex_path, - // circom_file_path, - // template_name, - // } => { - // let regex_decomposed: DecomposedRegexConfig = - // serde_json::from_reader(File::open(decomposed_regex_path).unwrap()).unwrap(); - // let circom_path = PathBuf::from(circom_file_path); - // regex_decomposed - // .gen_circom(&circom_path, &template_name) - // .unwrap(); - // } + } } } diff --git a/packages/compiler/src/circom.rs b/packages/compiler/src/circom.rs index b85ee7a..a9e0ce0 100644 --- a/packages/compiler/src/circom.rs +++ b/packages/compiler/src/circom.rs @@ -6,16 +6,20 @@ use crate::DFAGraph; use crate::RegexAndDFA; use std::collections::{BTreeMap, BTreeSet}; -use std::fmt::format; use std::fs::File; use std::io::Write; use std::path::PathBuf; -fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str) -> String { +fn gen_circom_allstr( + dfa_graph: &DFAGraph, + template_name: &str, + regex_str: &str, + end_anchor: bool, +) -> String { let n = dfa_graph.states.len(); let mut rev_graph = BTreeMap::>>::new(); let mut to_init_graph = vec![]; - let mut init_going_state: Option = None; + // let mut init_going_state: Option = None; for i in 0..n { rev_graph.insert(i, BTreeMap::new()); @@ -31,10 +35,10 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str) rev_graph.get_mut(k).unwrap().insert(i, chars.clone()); if i == 0 { - if let Some(index) = chars.iter().position(|&x| x == 94) { - init_going_state = Some(*k); - rev_graph.get_mut(&k).unwrap().get_mut(&i).unwrap()[index] = 255; - } + // if let Some(index) = chars.iter().position(|&x| x == 94) { + // init_going_state = Some(*k); + // rev_graph.get_mut(&k).unwrap().get_mut(&i).unwrap()[index] = 255; + // } for j in rev_graph.get(&k).unwrap().get(&i).unwrap() { if *j == 255 { @@ -50,32 +54,32 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str) } } - if let Some(init_going_state) = init_going_state { - for (going_state, chars) in to_init_graph.iter().enumerate() { - if chars.is_empty() { - continue; - } - - if rev_graph - .get_mut(&(going_state as usize)) - .unwrap() - .get_mut(&init_going_state) - .is_none() - { - rev_graph - .get_mut(&(going_state as usize)) - .unwrap() - .insert(init_going_state, vec![]); - } - - rev_graph - .get_mut(&(going_state as usize)) - .unwrap() - .get_mut(&init_going_state) - .unwrap() - .extend_from_slice(chars); - } - } + // if let Some(init_going_state) = init_going_state { + // for (going_state, chars) in to_init_graph.iter().enumerate() { + // if chars.is_empty() { + // continue; + // } + + // if rev_graph + // .get_mut(&(going_state as usize)) + // .unwrap() + // .get_mut(&init_going_state) + // .is_none() + // { + // rev_graph + // .get_mut(&(going_state as usize)) + // .unwrap() + // .insert(init_going_state, vec![]); + // } + + // rev_graph + // .get_mut(&(going_state as usize)) + // .unwrap() + // .get_mut(&init_going_state) + // .unwrap() + // .extend_from_slice(chars); + // } + // } if accept_nodes.is_empty() { panic!("Accept node must exist"); @@ -105,6 +109,13 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str) lines.push("\tfor (var i = 0; i < num_bytes; i++) {".to_string()); lines.push(format!("\t\tstate_changed[i] = MultiOR({});", n - 1)); lines.push(format!("\t\tstates[i][0] <== 1;")); + assert!( + rev_graph.get(&0).unwrap().len() == 0, + "state transition to the 0-th state is not allowed" + ); + if end_anchor { + lines.push(format!("\t\tpadding_start[i+1] <== IsNotZeroAcc()(padding_start[i], in[i]);")); + } for i in 1..n { let mut outputs = vec![]; zero_starting_and_idxes.insert(i, vec![]); @@ -116,6 +127,7 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str) zero_starting_states.push(i); } let mut k = k.clone(); + k.retain(|&x| x != 0); k.sort(); let mut eq_outputs = vec![]; @@ -402,6 +414,10 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str) declarations.push(format!("\tsignal from_zero_enabled[num_bytes+1];")); declarations.push(format!("\tfrom_zero_enabled[num_bytes] <== 0;")); declarations.push("\tcomponent state_changed[num_bytes];\n".to_string()); + if end_anchor { + declarations.push("\tsignal padding_start[num_bytes+1];".to_string()); + declarations.push("\tpadding_start[0] <== 0;".to_string()); + } let mut init_code = vec![]; // init_code.push("\tstates[0][0] <== 1;".to_string()); @@ -420,15 +436,30 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str) let mut accept_lines = vec![]; accept_lines.push("".to_string()); - accept_lines.push("\tcomponent final_state_result = MultiOR(num_bytes+1);".to_string()); + accept_lines.push("\tcomponent is_accepted = MultiOR(num_bytes+1);".to_string()); accept_lines.push("\tfor (var i = 0; i <= num_bytes; i++) {".to_string()); accept_lines.push(format!( - "\t\tfinal_state_result.in[i] <== states[i][{}];", + "\t\tis_accepted.in[i] <== states[i][{}];", accept_node )); accept_lines.push("\t}".to_string()); - accept_lines.push("\tout <== final_state_result.out;".to_string()); - + if end_anchor { + accept_lines.push("\tsignal end_anchor_check[num_bytes+1][2];".to_string()); + accept_lines.push("\tend_anchor_check[0][1] <== 0;".to_string()); + accept_lines.push("\tfor (var i = 0; i < num_bytes; i++) {".to_string()); + accept_lines.push(format!( + "\t\tend_anchor_check[i+1][0] <== IsEqual()([i, padding_start[num_bytes]]);", + )); + accept_lines.push(format!( + "\t\tend_anchor_check[i+1][1] <== end_anchor_check[i][1] + states[i][{}] * end_anchor_check[i+1][0];", + accept_node + )); + accept_lines.push("\t}".to_string()); + accept_lines.push("\tout <== is_accepted.out * end_anchor_check[num_bytes][1];".to_string()); + } else { + accept_lines.push("\tout <== is_accepted.out;".to_string()); + } + final_code.extend(accept_lines); final_code.join("\n") @@ -441,7 +472,12 @@ impl RegexAndDFA { template_name: &str, gen_substrs: bool, ) -> Result<(), CompilerError> { - let circom = gen_circom_allstr(&self.dfa_val, template_name, &self.regex_str); + let circom = gen_circom_allstr( + &self.dfa_val, + template_name, + &self.regex_str, + self.end_anchor, + ); let mut circom_file = File::create(circom_path)?; write!(circom_file, "{}", circom)?; if gen_substrs { @@ -453,7 +489,12 @@ impl RegexAndDFA { } pub fn gen_circom_str(&self, template_name: &str) -> Result { - let circom = gen_circom_allstr(&self.dfa_val, template_name, &self.regex_str); + let circom = gen_circom_allstr( + &self.dfa_val, + template_name, + &self.regex_str, + self.end_anchor, + ); let substrs = self.add_substrs_constraints()?; let result = circom + &substrs; Ok(result) @@ -464,7 +505,7 @@ impl RegexAndDFA { let mut circom: String = "".to_string(); circom += "\n"; circom += "\tsignal is_consecutive[msg_bytes+1][3];\n"; - circom += "\tis_consecutive[msg_bytes][2] <== 1;\n"; + circom += "\tis_consecutive[msg_bytes][2] <== 0;\n"; circom += "\tfor (var i = 0; i < msg_bytes; i++) {\n"; circom += &format!("\t\tis_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][{}] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2];\n", accepted_state); circom += "\t\tis_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0];\n"; @@ -478,6 +519,7 @@ impl RegexAndDFA { ); for (idx, defs) in substr_defs_array.into_iter().enumerate() { let num_defs = defs.len(); + circom += &format!("\tsignal prev_states{}[{}][msg_bytes];\n", idx, defs.len()); circom += &format!("\tsignal is_substr{}[msg_bytes];\n", idx); circom += &format!("\tsignal is_reveal{}[msg_bytes];\n", idx); circom += &format!("\tsignal output reveal{}[msg_bytes];\n", idx); @@ -494,12 +536,31 @@ impl RegexAndDFA { } }); circom += &format!("\t\t // the {}-th substring transitions: {:?}\n", idx, defs); + for (trans_idx, (cur, _)) in defs.iter().enumerate() { + if *cur == 0 { + circom += &format!( + "\t\tprev_states{}[{}][i] <== from_zero_enabled[i+1] * states[i+1][{}];\n", + idx, trans_idx, cur + ); + } else { + circom += &format!( + "\t\tprev_states{}[{}][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][{}];\n", + idx, + trans_idx, + cur + ); + } + } circom += &format!( "\t\tis_substr{}[i] <== MultiOR({})([{}]);\n", idx, num_defs, defs.iter() - .map(|(cur, next)| format!("states[i+1][{}] * states[i+2][{}]", cur, next)) + .enumerate() + .map(|(trans_idx, (_, next))| format!( + "prev_states{}[{}][i] * states[i+2][{}]", + idx, trans_idx, next + )) .collect::>() .join(", ") ); @@ -519,7 +580,7 @@ impl RegexAndDFA { // // } // } circom += &format!( - "\t\tis_reveal{}[i] <== is_substr{}[i] * is_consecutive[i][2];\n", + "\t\tis_reveal{}[i] <== MultiAND(3)([out, is_substr{}[i], is_consecutive[i][2]]);\n", idx, idx ); circom += &format!("\t\treveal{}[i] <== in[i+1] * is_reveal{}[i];\n", idx, idx); diff --git a/packages/compiler/src/halo2.rs b/packages/compiler/src/halo2.rs deleted file mode 100644 index 568657e..0000000 --- a/packages/compiler/src/halo2.rs +++ /dev/null @@ -1,100 +0,0 @@ -// use crate::js_caller::*; -// use crate::*; - -// use itertools::Itertools; - -// use std::io::BufWriter; -// use std::io::Write; - -// use std::path::PathBuf; -// use std::{fs::File}; - -// impl RegexAndDFA { -// pub fn gen_halo2_tables( -// &self, -// allstr_file_path: &PathBuf, -// substr_file_pathes: &[PathBuf], -// gen_substrs: bool, -// ) -> Result<(), CompilerError> { -// let regex_text = self.dfa_to_regex_def_text()?; -// let mut regex_file = File::create(allstr_file_path)?; -// write!(regex_file, "{}", regex_text)?; -// regex_file.flush()?; -// if !gen_substrs { -// return Ok(()); -// } -// let substr_endpoints_array = self.substrs_defs.substr_endpoints_array.as_ref().unwrap(); -// // let max_bytes = self.substrs_defs.max_bytes.as_ref().unwrap(); -// for (idx, defs) in self.substrs_defs.substr_defs_array.iter().enumerate() { -// let mut writer = BufWriter::new(File::create(&substr_file_pathes[idx])?); -// // let max_size = max_bytes[idx]; -// // writer.write_fmt(format_args!("{}\n", &max_size))?; -// // writer.write_fmt(format_args!("0\n{}\n", self.max_byte_size - 1))?; -// let mut starts_str = "".to_string(); -// let starts = substr_endpoints_array[idx] -// .0 -// .iter() -// .sorted_by(|a, b| a.cmp(b)); -// for start in starts { -// starts_str += &format!("{} ", start); -// } -// writer.write_fmt(format_args!("{}\n", starts_str))?; -// let mut ends_str = "".to_string(); -// let ends = substr_endpoints_array[idx] -// .1 -// .iter() -// .sorted_by(|a, b| a.cmp(b)); -// for end in ends { -// ends_str += &format!("{} ", end); -// } -// writer.write_fmt(format_args!("{}\n", ends_str))?; -// let mut defs = defs.iter().collect::>(); -// defs.sort_by(|a, b| { -// let start_cmp = a.0.cmp(&b.0); -// let end_cmp = a.1.cmp(&b.1); -// if start_cmp == std::cmp::Ordering::Equal { -// end_cmp -// } else { -// start_cmp -// } -// }); -// for (cur, next) in defs.iter() { -// writer.write_fmt(format_args!("{} {}\n", cur, next))?; -// } -// } -// Ok(()) -// } - -// pub fn dfa_to_regex_def_text(&self) -> Result { -// let accepted_state = -// get_accepted_state(&self.dfa_val).ok_or(JsCallerError::NoAcceptedState)?; -// let max_state = get_max_state(&self.dfa_val)?; -// let mut text = "0\n".to_string(); -// text += &format!("{}\n", accepted_state.to_string()); -// text += &format!("{}\n", max_state.to_string()); -// for (i, val) in self.dfa_val.iter().enumerate() { -// for (key, next_node_val) in val["edges"] -// .as_object() -// .ok_or(JsCallerError::InvalidEdges(val["edges"].clone()))? -// .iter() -// { -// let key_list: Vec = serde_json::from_str(&key)?; -// for key_char in key_list.iter() { -// let key_char: char = key_char.chars().collect::>()[0]; -// let next_node = next_node_val -// .as_u64() -// .ok_or(JsCallerError::InvalidNodeValue(next_node_val.clone()))? -// as usize; -// // println!("i {} next {} char {}", i, next_node, key_char as u8); -// text += &format!( -// "{} {} {}\n", -// i.to_string(), -// next_node.to_string(), -// (key_char as u8).to_string() -// ); -// } -// } -// } -// Ok(text) -// } -// } diff --git a/packages/compiler/src/lib.rs b/packages/compiler/src/lib.rs index 5cd55e7..c4fbe45 100644 --- a/packages/compiler/src/lib.rs +++ b/packages/compiler/src/lib.rs @@ -1,7 +1,6 @@ use std::fs::File; use std::iter::FromIterator; pub mod circom; -pub mod halo2; pub mod regex; #[cfg(target_arch = "wasm32")] mod wasm; @@ -14,7 +13,7 @@ use crate::regex::*; use itertools::Itertools; use petgraph::prelude::*; use serde::{Deserialize, Serialize}; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::{BTreeMap, BTreeSet, VecDeque}; use std::path::PathBuf; use thiserror::Error; @@ -27,12 +26,14 @@ pub enum CompilerError { IoError(#[from] std::io::Error), #[error(transparent)] RegexError(#[from] fancy_regex::Error), + #[error("Generic error: {0}")] + GenericError(String), } /// A configuration of decomposed regexes. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DecomposedRegexConfig { - pub parts: Vec, + pub parts: VecDeque, } /// Decomposed regex part. @@ -65,7 +66,7 @@ pub struct DFAState { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DFAGraph { - states: Vec, + pub states: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -74,6 +75,7 @@ pub struct RegexAndDFA { // Original regex string, only here to be printed in generated file to make it more reproducible pub regex_str: String, pub dfa_val: DFAGraph, + pub end_anchor: bool, pub substrs_defs: SubstrsDefs, } @@ -90,8 +92,8 @@ pub struct SubstrsDefsJson { } impl DecomposedRegexConfig { - pub fn to_regex_and_dfa(&self) -> Result { - Ok(regex_and_dfa(self)) + pub fn to_regex_and_dfa(&mut self) -> Result { + regex_and_dfa(self) } } @@ -117,6 +119,7 @@ impl RegexAndDFA { // max_byte_size, regex_str: regex_str.to_string(), dfa_val, + end_anchor: regex_str.ends_with('$'), substrs_defs, }) } @@ -124,33 +127,16 @@ impl RegexAndDFA { pub fn gen_from_decomposed( decomposed_regex_path: &str, - // halo2_dir_path: Option<&str>, circom_file_path: Option<&str>, circom_template_name: Option<&str>, gen_substrs: Option, ) { - let decomposed_regex_config: DecomposedRegexConfig = + let mut decomposed_regex_config: DecomposedRegexConfig = serde_json::from_reader(File::open(decomposed_regex_path).unwrap()).unwrap(); let regex_and_dfa = decomposed_regex_config .to_regex_and_dfa() .expect("failed to convert the decomposed regex to dfa"); let gen_substrs = gen_substrs.unwrap_or(true); - // if let Some(halo2_dir_path) = halo2_dir_path { - // let halo2_dir_path = PathBuf::from(halo2_dir_path); - // let allstr_file_path = halo2_dir_path.join("allstr.txt"); - // let mut num_public_parts = 0usize; - // for part in decomposed_regex_config.parts.iter() { - // if part.is_public { - // num_public_parts += 1; - // } - // } - // let substr_file_paths = (0..num_public_parts) - // .map(|idx| halo2_dir_path.join(format!("substr_{}.txt", idx))) - // .collect_vec(); - // regex_and_dfa - // .gen_halo2_tables(&allstr_file_path, &substr_file_paths, gen_substrs) - // .expect("failed to generate halo2 tables"); - // } if let Some(circom_file_path) = circom_file_path { let circom_file_path = PathBuf::from(circom_file_path); let circom_template_name = circom_template_name @@ -163,9 +149,7 @@ pub fn gen_from_decomposed( pub fn gen_from_raw( raw_regex: &str, - // max_bytes: usize, substrs_json_path: Option<&str>, - // halo2_dir_path: Option<&str>, circom_file_path: Option<&str>, template_name: Option<&str>, gen_substrs: Option, @@ -184,16 +168,7 @@ pub fn gen_from_raw( let regex_and_dfa = RegexAndDFA::from_regex_str_and_substr_defs(raw_regex, substrs_defs_json) .expect("failed to convert the raw regex and state transitions to dfa"); let gen_substrs = gen_substrs.unwrap_or(true); - // if let Some(halo2_dir_path) = halo2_dir_path { - // let halo2_dir_path = PathBuf::from(halo2_dir_path); - // let allstr_file_path = halo2_dir_path.join("allstr.txt"); - // let substr_file_paths = (0..num_public_parts) - // .map(|idx| halo2_dir_path.join(format!("substr_{}.txt", idx))) - // .collect_vec(); - // regex_and_dfa - // .gen_halo2_tables(&allstr_file_path, &substr_file_paths, gen_substrs) - // .expect("failed to generate halo2 tables"); - // } + if let Some(circom_file_path) = circom_file_path { let circom_file_path = PathBuf::from(circom_file_path); let template_name = template_name diff --git a/packages/compiler/src/regex.rs b/packages/compiler/src/regex.rs index 02ae9d3..0070e45 100644 --- a/packages/compiler/src/regex.rs +++ b/packages/compiler/src/regex.rs @@ -1,4 +1,5 @@ -use crate::{DFAGraph, DFAState, DecomposedRegexConfig, RegexAndDFA, SubstrsDefs}; +use super::CompilerError; +use crate::{DFAGraph, DFAState, DecomposedRegexConfig, RegexAndDFA, RegexPartConfig, SubstrsDefs}; use regex::Regex; use regex_automata::dfa::{dense::DFA, StartKind}; use std::collections::{BTreeMap, BTreeSet}; @@ -29,7 +30,7 @@ fn parse_dfa_output(output: &str) -> DFAGraphInfo { if &captures[0][0..1] == "*" { state.typ = String::from("accept"); } - for transition in Regex::new(r"\s+[^=]+\s*=>\s*(\d+)+\s*|\s+=+\s*=>\s*(\d+)+") + for transition in Regex::new(r"\s+[^=]+\s*=>\s*(\d+)+\s*|\s+=+\s*=>\s*(\d+)+|\s+=-[^=]+=>\s*\s*(\d+)+\s*|\s+[^=]+-=\s*=>\s*(\d+)+\s*") .unwrap() .captures_iter(&captures[0].to_string()) { @@ -237,6 +238,9 @@ fn add_dfa(net_dfa: &DFAGraph, graph: &DFAGraph) -> DFAGraph { state.edges.insert(*k, v.clone()); } state.r#type = "".to_string(); + if start_state.r#type == "accept" { + state.r#type = "accept".to_string(); + } } } @@ -249,7 +253,9 @@ fn add_dfa(net_dfa: &DFAGraph, graph: &DFAGraph) -> DFAGraph { net_dfa } -pub fn regex_and_dfa(decomposed_regex: &DecomposedRegexConfig) -> RegexAndDFA { +pub fn regex_and_dfa( + decomposed_regex: &mut DecomposedRegexConfig, +) -> Result { let mut config = DFA::config().minimize(true); config = config.start_kind(StartKind::Anchored); config = config.byte_classes(false); @@ -258,14 +264,129 @@ pub fn regex_and_dfa(decomposed_regex: &DecomposedRegexConfig) -> RegexAndDFA { let mut net_dfa = DFAGraph { states: Vec::new() }; let mut substr_defs_array = Vec::new(); - for regex in decomposed_regex.parts.iter() { + let caret_regex_index = { + let first_regex = decomposed_regex.parts[0].regex_def.as_bytes(); + let mut is_in_parenthesis = false; + let mut caret_found = false; + let mut idx = 0; + while idx < first_regex.len() { + let byte = first_regex[idx]; + if byte == b'\\' { + idx += 2; + } else if byte == b'(' { + is_in_parenthesis = true; + idx += 1; + } else if byte == b'[' { + idx += 2; + } else if byte == b')' { + debug_assert!(is_in_parenthesis, "Unmatched parenthesis"); + is_in_parenthesis = false; + idx += 1; + if caret_found { + break; + } + } else if byte == b'^' { + caret_found = true; + idx += 1; + if !is_in_parenthesis { + break; + } + } else { + idx += 1; + } + } + + if caret_found { + Some(idx) + } else { + None + } + }; + if let Some(index) = caret_regex_index { + let caret_regex = decomposed_regex.parts[0].regex_def[0..index].to_string(); + decomposed_regex.parts.push_front(RegexPartConfig { + is_public: false, + regex_def: caret_regex, + }); + decomposed_regex.parts[1].regex_def = + decomposed_regex.parts[1].regex_def[index..].to_string(); + } + + let mut end_anchor = false; + + for (idx, regex) in decomposed_regex.parts.iter().enumerate() { + end_anchor = match decomposed_regex.parts.len() { + 1 => regex.regex_def.ends_with("$"), + 2 => { + if idx == 0 && regex.regex_def.ends_with("$") { + return Err(CompilerError::GenericError( + "Invalid regex, $ can only be at the end of the regex".to_string(), + )); + } + idx == 1 && regex.regex_def.ends_with("$") + } + _ => match idx { + 0 | _ if idx == decomposed_regex.parts.len() - 1 => { + if regex.regex_def.ends_with("$") { + if idx == 0 { + return Err(CompilerError::GenericError( + "Invalid regex, $ can only be at the end of the regex".to_string(), + )); + } + true + } else { + false + } + } + _ => false, + }, + }; let re = DFA::builder() .configure(config.clone()) - .build(&format!(r"^{}$", regex.regex_def)) - .unwrap(); - let re_str = format!("{:?}", re); + .build(&format!(r"^({})$", regex.regex_def.as_str())); + if re.is_err() { + return Err(CompilerError::GenericError(format!( + "Failed to build DFA for regex: \"{}\", please check your regex", + regex.regex_def + ))); + } + let re_str = format!("{:?}", re.unwrap()); + // println!("{:?}", re_str); let mut graph = dfa_to_graph(&parse_dfa_output(&re_str)); - + if idx == 0 && caret_regex_index.is_some() { + if regex.regex_def.as_str() == "^" { + graph = DFAGraph { + states: vec![ + DFAState { + r#type: "".to_string(), + edges: BTreeMap::from([(1, BTreeSet::from([255u8]))]), + state: 0, + }, + DFAState { + r#type: "accept".to_string(), + edges: BTreeMap::new(), + state: 1, + }, + ], + } + } else { + graph.states[0].r#type = "".to_string(); + let accepted_state = graph + .states + .iter() + .find(|state| state.r#type == "accept") + .unwrap() + .clone(); + if let Some(edge) = graph.states[0].edges.get_mut(&accepted_state.state) { + edge.insert(255u8); + } else { + graph.states[0] + .edges + .insert(accepted_state.state, BTreeSet::from([255u8])); + } + } + } + // println!("{:?}", graph); // Find max state in net_dfa let mut max_state_index = 0; for state in net_dfa.states.iter() { @@ -319,20 +440,22 @@ pub fn regex_and_dfa(decomposed_regex: &DecomposedRegexConfig) -> RegexAndDFA { net_dfa = add_dfa(&net_dfa, &graph); } + println!("{:?}", net_dfa); let mut regex_str = String::new(); for regex in decomposed_regex.parts.iter() { regex_str += ®ex.regex_def; } - RegexAndDFA { + Ok(RegexAndDFA { regex_str: regex_str, dfa_val: net_dfa, + end_anchor, substrs_defs: SubstrsDefs { substr_defs_array: substr_defs_array, substr_endpoints_array: None, }, - } + }) } pub fn dfa_from_regex_str(regex: &str) -> DFAGraph { diff --git a/packages/compiler/src/wasm.rs b/packages/compiler/src/wasm.rs index ce79661..dcc0634 100644 --- a/packages/compiler/src/wasm.rs +++ b/packages/compiler/src/wasm.rs @@ -5,7 +5,7 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] #[allow(non_snake_case)] pub fn genFromDecomposed(decomposedRegexJson: &str, circomTemplateName: &str) -> String { - let decomposed_regex_config: DecomposedRegexConfig = + let mut decomposed_regex_config: DecomposedRegexConfig = serde_json::from_str(decomposedRegexJson).expect("failed to parse decomposed_regex json"); let regex_and_dfa = decomposed_regex_config .to_regex_and_dfa() @@ -30,8 +30,8 @@ pub fn genFromRaw(rawRegex: &str, substrsJson: &str, circomTemplateName: &str) - #[wasm_bindgen] #[allow(non_snake_case)] pub fn genRegexAndDfa(decomposedRegex: JsValue) -> JsValue { - let decomposed_regex_config: DecomposedRegexConfig = from_value(decomposedRegex).unwrap(); - let regex_and_dfa = regex_and_dfa(&decomposed_regex_config); + let mut decomposed_regex_config: DecomposedRegexConfig = from_value(decomposedRegex).unwrap(); + let regex_and_dfa = regex_and_dfa(&mut decomposed_regex_config).unwrap(); let dfa_val_str = serde_json::to_string(®ex_and_dfa).unwrap(); JsValue::from_str(&dfa_val_str) } @@ -39,9 +39,10 @@ pub fn genRegexAndDfa(decomposedRegex: JsValue) -> JsValue { #[wasm_bindgen] #[allow(non_snake_case)] pub fn genCircom(decomposedRegex: JsValue, circomTemplateName: &str) -> String { - let decomposed_regex_config: DecomposedRegexConfig = from_value(decomposedRegex).unwrap(); - let regex_and_dfa = regex_and_dfa(&decomposed_regex_config); + let mut decomposed_regex_config: DecomposedRegexConfig = from_value(decomposedRegex).unwrap(); + let regex_and_dfa = regex_and_dfa(&mut decomposed_regex_config); regex_and_dfa + .expect("failed to convert the decomposed regex to dfa") .gen_circom_str(&circomTemplateName) .expect("failed to generate circom") }