diff --git a/packages/apis/src/decomposed_defs/body_hash.json b/packages/apis/src/decomposed_defs/body_hash.json index f53b8a5..354421e 100644 --- a/packages/apis/src/decomposed_defs/body_hash.json +++ b/packages/apis/src/decomposed_defs/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/apis/src/decomposed_defs/email_addr.json b/packages/apis/src/decomposed_defs/email_addr.json index 0842165..2b45be1 100644 --- a/packages/apis/src/decomposed_defs/email_addr.json +++ b/packages/apis/src/decomposed_defs/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.\\-]+" } ] -} +} \ No newline at end of file diff --git a/packages/apis/src/decomposed_defs/email_addr_with_name.json b/packages/apis/src/decomposed_defs/email_addr_with_name.json index 31607a3..999ea3e 100644 --- a/packages/apis/src/decomposed_defs/email_addr_with_name.json +++ b/packages/apis/src/decomposed_defs/email_addr_with_name.json @@ -6,11 +6,11 @@ }, { "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, "regex_def": ">" } ] -} +} \ No newline at end of file diff --git a/packages/apis/src/decomposed_defs/email_domain.json b/packages/apis/src/decomposed_defs/email_domain.json index 82f0330..7051e3a 100644 --- a/packages/apis/src/decomposed_defs/email_domain.json +++ b/packages/apis/src/decomposed_defs/email_domain.json @@ -2,15 +2,11 @@ "parts": [ { "is_public": false, - "regex_def": "[A-Za-z0-9!#$%&'*+-/=?^_`{\\|}~\\.]+" - }, - { - "is_public": false, - "regex_def": "@" + "regex_def": "[A-Za-z0-9!#$%&'*+=?\\-\\^_`{|}~./]+@" }, { "is_public": true, - "regex_def": "[A-Za-z0-9\\.-]+" + "regex_def": "[A-Za-z0-9.\\-@]+" } ] -} +} \ No newline at end of file diff --git a/packages/apis/src/decomposed_defs/from_addr.json b/packages/apis/src/decomposed_defs/from_addr.json index 7fdc28e..82fefdd 100644 --- a/packages/apis/src/decomposed_defs/from_addr.json +++ b/packages/apis/src/decomposed_defs/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,11 +10,11 @@ }, { "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, "regex_def": ">?\r\n" } ] -} +} \ No newline at end of file diff --git a/packages/apis/src/decomposed_defs/from_all.json b/packages/apis/src/decomposed_defs/from_all.json index a774997..a38aa7e 100644 --- a/packages/apis/src/decomposed_defs/from_all.json +++ b/packages/apis/src/decomposed_defs/from_all.json @@ -1,16 +1,16 @@ { - "parts": [ - { - "is_public": false, - "regex_def": "((\r\n)|^)from:" - }, - { - "is_public": true, - "regex_def": "[^\r\n]+" - }, - { - "is_public": false, - "regex_def": "\r\n" - } - ] -} + "parts": [ + { + "is_public": false, + "regex_def": "(\r\n|^)from:" + }, + { + "is_public": true, + "regex_def": "[^\r\n]+" + }, + { + "is_public": false, + "regex_def": "\r\n" + } + ] +} \ No newline at end of file diff --git a/packages/apis/src/decomposed_defs/message_id.json b/packages/apis/src/decomposed_defs/message_id.json index f71f0ee..b9d1227 100644 --- a/packages/apis/src/decomposed_defs/message_id.json +++ b/packages/apis/src/decomposed_defs/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/apis/src/decomposed_defs/subject_all.json b/packages/apis/src/decomposed_defs/subject_all.json index ed7d761..9b54447 100644 --- a/packages/apis/src/decomposed_defs/subject_all.json +++ b/packages/apis/src/decomposed_defs/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/apis/src/decomposed_defs/timestamp.json b/packages/apis/src/decomposed_defs/timestamp.json index 4e2895e..a3c945b 100644 --- a/packages/apis/src/decomposed_defs/timestamp.json +++ b/packages/apis/src/decomposed_defs/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/apis/src/decomposed_defs/to_addr.json b/packages/apis/src/decomposed_defs/to_addr.json index 43384d7..9c7a4b1 100644 --- a/packages/apis/src/decomposed_defs/to_addr.json +++ b/packages/apis/src/decomposed_defs/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,11 +10,11 @@ }, { "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, "regex_def": ">?\r\n" } ] -} +} \ No newline at end of file diff --git a/packages/apis/src/decomposed_defs/to_all.json b/packages/apis/src/decomposed_defs/to_all.json index eeb616f..76be9fd 100644 --- a/packages/apis/src/decomposed_defs/to_all.json +++ b/packages/apis/src/decomposed_defs/to_all.json @@ -1,16 +1,16 @@ { - "parts": [ - { - "is_public": false, - "regex_def": "((\r\n)|^)to:" - }, - { - "is_public": true, - "regex_def": "[^\r\n]+" - }, - { - "is_public": false, - "regex_def": "\r\n" - } - ] -} + "parts": [ + { + "is_public": false, + "regex_def": "(\r\n|^)to:" + }, + { + "is_public": true, + "regex_def": "[^\r\n]+" + }, + { + "is_public": false, + "regex_def": "\r\n" + } + ] +} \ No newline at end of file diff --git a/packages/circom/README.md b/packages/circom/README.md index 5a6589a..eb9bffb 100644 --- a/packages/circom/README.md +++ b/packages/circom/README.md @@ -2,4 +2,6 @@ Circom circuits for regex verification in [zk-regex](https://github.com/zkemail/zk-regex/tree/main). This package contains circom circuits and decomposed regex definitions for common regexes in `./circuits/common` folder. - \ No newline at end of file + +## Note +Our `email_domain_regex.circom` circuit cannot capture an email address that contains "@" in the name part before the domain part, e.g., "alice@gmail.com@dummy.com", due to limitation of our circuit construction. For example, when "alice@gmail.com@dummy.com" is given, that circuit outputs not "dummy.com" but "gmail.com@dummy.com" as an exposed substring for the domain. However, an adversary cannot exploit this feature to expose a fake domain since the true domain at the end will also be revealed along with it. \ 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 ed2489e..2b45be1 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.\\-]+" } ] -} +} \ No newline at end of file diff --git a/packages/circom/circuits/common/email_addr_regex.circom b/packages/circom/circuits/common/email_addr_regex.circom index b42d937..8f7005f 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[23][num_bytes]; - component lt[6][num_bytes]; - component and[8][num_bytes]; - component multi_or[3][num_bytes]; + component eq[31][num_bytes]; + component lt[8][num_bytes]; + component and[13][num_bytes]; + component multi_or[7][num_bytes]; signal states[num_bytes+1][4]; signal states_tmp[num_bytes+1][4]; signal from_zero_enabled[num_bytes+1]; @@ -32,7 +32,7 @@ template EmailAddrRegex(msg_bytes) { state_changed[i] = MultiOR(3); states[i][0] <== 1; lt[0][i] = LessEqThan(8); - lt[0][i].in[0] <== 65; + lt[0][i].in[0] <== 63; lt[0][i].in[1] <== in[i]; lt[1][i] = LessEqThan(8); lt[1][i].in[0] <== in[i]; @@ -75,46 +75,49 @@ template EmailAddrRegex(msg_bytes) { eq[7][i].in[1] <== 43; eq[8][i] = IsEqual(); eq[8][i].in[0] <== in[i]; - eq[8][i].in[1] <== 46; + eq[8][i].in[1] <== 45; eq[9][i] = IsEqual(); eq[9][i].in[0] <== in[i]; - eq[9][i].in[1] <== 48; + eq[9][i].in[1] <== 46; eq[10][i] = IsEqual(); eq[10][i].in[0] <== in[i]; - eq[10][i].in[1] <== 49; + eq[10][i].in[1] <== 47; eq[11][i] = IsEqual(); eq[11][i].in[0] <== in[i]; - eq[11][i].in[1] <== 50; + eq[11][i].in[1] <== 48; eq[12][i] = IsEqual(); eq[12][i].in[0] <== in[i]; - eq[12][i].in[1] <== 51; + eq[12][i].in[1] <== 49; eq[13][i] = IsEqual(); eq[13][i].in[0] <== in[i]; - eq[13][i].in[1] <== 52; + eq[13][i].in[1] <== 50; eq[14][i] = IsEqual(); eq[14][i].in[0] <== in[i]; - eq[14][i].in[1] <== 53; + eq[14][i].in[1] <== 51; eq[15][i] = IsEqual(); eq[15][i].in[0] <== in[i]; - eq[15][i].in[1] <== 54; + eq[15][i].in[1] <== 52; eq[16][i] = IsEqual(); eq[16][i].in[0] <== in[i]; - eq[16][i].in[1] <== 55; + eq[16][i].in[1] <== 53; eq[17][i] = IsEqual(); eq[17][i].in[0] <== in[i]; - eq[17][i].in[1] <== 56; + eq[17][i].in[1] <== 54; eq[18][i] = IsEqual(); eq[18][i].in[0] <== in[i]; - eq[18][i].in[1] <== 57; + eq[18][i].in[1] <== 55; eq[19][i] = IsEqual(); eq[19][i].in[0] <== in[i]; - eq[19][i].in[1] <== 61; + eq[19][i].in[1] <== 56; eq[20][i] = IsEqual(); eq[20][i].in[0] <== in[i]; - eq[20][i].in[1] <== 63; + eq[20][i].in[1] <== 57; + eq[21][i] = IsEqual(); + eq[21][i].in[0] <== in[i]; + eq[21][i].in[1] <== 61; and[2][i] = AND(); and[2][i].a <== states[i][0]; - multi_or[0][i] = MultiOR(23); + multi_or[0][i] = MultiOR(24); 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; @@ -138,55 +141,151 @@ 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] <== 97; + lt[4][i].in[0] <== 65; lt[4][i].in[1] <== in[i]; lt[5][i] = LessEqThan(8); lt[5][i].in[0] <== in[i]; - 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; + lt[5][i].in[1] <== 90; + and[3][i] = AND(); + and[3][i].a <== lt[4][i].out; + and[3][i].b <== lt[5][i].out; eq[22][i] = IsEqual(); eq[22][i].in[0] <== in[i]; - eq[22][i].in[1] <== 45; + eq[22][i].in[1] <== 63; + and[4][i] = AND(); + and[4][i].a <== states[i][1]; + multi_or[1][i] = MultiOR(25); + multi_or[1][i].in[0] <== and[3][i].out; + multi_or[1][i].in[1] <== and[1][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; + and[4][i].b <== multi_or[1][i].out; + eq[23][i] = IsEqual(); + eq[23][i].in[0] <== in[i]; + eq[23][i].in[1] <== 94; + eq[24][i] = IsEqual(); + eq[24][i].in[0] <== in[i]; + eq[24][i].in[1] <== 95; + eq[25][i] = IsEqual(); + eq[25][i].in[0] <== in[i]; + eq[25][i].in[1] <== 96; + eq[26][i] = IsEqual(); + eq[26][i].in[0] <== in[i]; + eq[26][i].in[1] <== 123; + eq[27][i] = IsEqual(); + eq[27][i].in[0] <== in[i]; + eq[27][i].in[1] <== 124; + eq[28][i] = IsEqual(); + eq[28][i].in[0] <== in[i]; + eq[28][i].in[1] <== 125; + eq[29][i] = IsEqual(); + eq[29][i].in[0] <== in[i]; + eq[29][i].in[1] <== 126; + and[5][i] = AND(); + and[5][i].a <== states[i][2]; + multi_or[2][i] = MultiOR(18); + multi_or[2][i].in[0] <== eq[0][i].out; + multi_or[2][i].in[1] <== eq[1][i].out; + multi_or[2][i].in[2] <== eq[2][i].out; + multi_or[2][i].in[3] <== eq[3][i].out; + multi_or[2][i].in[4] <== eq[4][i].out; + multi_or[2][i].in[5] <== eq[5][i].out; + multi_or[2][i].in[6] <== eq[6][i].out; + multi_or[2][i].in[7] <== eq[7][i].out; + multi_or[2][i].in[8] <== eq[10][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; + multi_or[2][i].in[14] <== eq[26][i].out; + multi_or[2][i].in[15] <== eq[27][i].out; + multi_or[2][i].in[16] <== eq[28][i].out; + multi_or[2][i].in[17] <== eq[29][i].out; + and[5][i].b <== multi_or[2][i].out; and[6][i] = AND(); - 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[6][i].a <== states[i][3]; + and[6][i].b <== multi_or[2][i].out; + multi_or[3][i] = MultiOR(3); + multi_or[3][i].in[0] <== and[4][i].out; + multi_or[3][i].in[1] <== and[5][i].out; + multi_or[3][i].in[2] <== and[6][i].out; + states_tmp[i+1][1] <== multi_or[3][i].out; + eq[30][i] = IsEqual(); + eq[30][i].in[0] <== in[i]; + eq[30][i].in[1] <== 64; and[7][i] = AND(); - 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; + and[7][i].a <== states[i][1]; + and[7][i].b <== eq[30][i].out; + and[8][i] = AND(); + and[8][i].a <== states[i][2]; + and[8][i].b <== eq[30][i].out; + and[9][i] = AND(); + and[9][i].a <== states[i][3]; + and[9][i].b <== eq[30][i].out; + multi_or[4][i] = MultiOR(3); + multi_or[4][i].in[0] <== and[7][i].out; + multi_or[4][i].in[1] <== and[8][i].out; + multi_or[4][i].in[2] <== and[9][i].out; + states[i+1][2] <== multi_or[4][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[10][i] = AND(); + and[10][i].a <== lt[6][i].out; + and[10][i].b <== lt[7][i].out; + and[11][i] = AND(); + and[11][i].a <== states[i][2]; + multi_or[5][i] = MultiOR(14); + multi_or[5][i].in[0] <== and[3][i].out; + multi_or[5][i].in[1] <== and[10][i].out; + multi_or[5][i].in[2] <== eq[8][i].out; + multi_or[5][i].in[3] <== eq[9][i].out; + multi_or[5][i].in[4] <== eq[11][i].out; + multi_or[5][i].in[5] <== eq[12][i].out; + multi_or[5][i].in[6] <== eq[13][i].out; + multi_or[5][i].in[7] <== eq[14][i].out; + multi_or[5][i].in[8] <== eq[15][i].out; + multi_or[5][i].in[9] <== eq[16][i].out; + multi_or[5][i].in[10] <== eq[17][i].out; + multi_or[5][i].in[11] <== eq[18][i].out; + multi_or[5][i].in[12] <== eq[19][i].out; + multi_or[5][i].in[13] <== eq[20][i].out; + and[11][i].b <== multi_or[5][i].out; + and[12][i] = AND(); + and[12][i].a <== states[i][3]; + and[12][i].b <== multi_or[5][i].out; + multi_or[6][i] = MultiOR(2); + multi_or[6][i].in[0] <== and[11][i].out; + multi_or[6][i].in[1] <== and[12][i].out; + states[i+1][3] <== multi_or[6][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]; @@ -206,19 +305,23 @@ template EmailAddrRegex(msg_bytes) { 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]; + // substrings calculated: [{(0, 1), (1, 1), (1, 2), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)}] + signal prev_states0[9][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)] + // the 0-th substring transitions: [(0, 1), (1, 1), (1, 2), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 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][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]]); + 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][3]; + prev_states0[7][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + is_substr0[i] <== MultiOR(9)([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][1], prev_states0[4][i] * states[i+2][2], prev_states0[5][i] * states[i+2][3], prev_states0[6][i] * states[i+2][1], prev_states0[7][i] * states[i+2][2], prev_states0[8][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]; } diff --git a/packages/circom/circuits/common/email_addr_with_name.json b/packages/circom/circuits/common/email_addr_with_name.json index d1bd578..999ea3e 100644 --- a/packages/circom/circuits/common/email_addr_with_name.json +++ b/packages/circom/circuits/common/email_addr_with_name.json @@ -6,7 +6,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/email_addr_with_name_regex.circom b/packages/circom/circuits/common/email_addr_with_name_regex.circom index ff8a8c1..f212271 100644 --- a/packages/circom/circuits/common/email_addr_with_name_regex.circom +++ b/packages/circom/circuits/common/email_addr_with_name_regex.circom @@ -2,7 +2,7 @@ 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_\.-]+> +// regex: [^\r\n]+<[A-Za-z0-9!#$%&'*+=?\-\^_`{|}~./@]+@[a-zA-Z0-9.\-]+> template EmailAddrWithNameRegex(msg_bytes) { signal input msg[msg_bytes]; signal output out; @@ -14,10 +14,10 @@ template EmailAddrWithNameRegex(msg_bytes) { in[i+1] <== msg[i]; } - component eq[85][num_bytes]; - component lt[24][num_bytes]; - component and[51][num_bytes]; - component multi_or[19][num_bytes]; + component eq[91][num_bytes]; + component lt[26][num_bytes]; + component and[56][num_bytes]; + component multi_or[22][num_bytes]; signal states[num_bytes+1][14]; signal states_tmp[num_bytes+1][14]; signal from_zero_enabled[num_bytes+1]; @@ -156,16 +156,16 @@ template EmailAddrWithNameRegex(msg_bytes) { eq[13][i].in[1] <== 41; eq[14][i] = IsEqual(); eq[14][i].in[0] <== in[i]; - eq[14][i].in[1] <== 58; + eq[14][i].in[1] <== 44; eq[15][i] = IsEqual(); eq[15][i].in[0] <== in[i]; - eq[15][i].in[1] <== 59; + eq[15][i].in[1] <== 58; eq[16][i] = IsEqual(); eq[16][i].in[0] <== in[i]; - eq[16][i].in[1] <== 62; + eq[16][i].in[1] <== 59; eq[17][i] = IsEqual(); eq[17][i].in[0] <== in[i]; - eq[17][i].in[1] <== 64; + eq[17][i].in[1] <== 62; eq[18][i] = IsEqual(); eq[18][i].in[0] <== in[i]; eq[18][i].in[1] <== 91; @@ -522,7 +522,7 @@ template EmailAddrWithNameRegex(msg_bytes) { 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[0] <== 63; lt[18][i].in[1] <== in[i]; lt[19][i] = LessEqThan(8); lt[19][i].in[0] <== in[i]; @@ -565,55 +565,49 @@ template EmailAddrWithNameRegex(msg_bytes) { eq[67][i].in[1] <== 43; eq[68][i] = IsEqual(); eq[68][i].in[0] <== in[i]; - eq[68][i].in[1] <== 44; + eq[68][i].in[1] <== 45; eq[69][i] = IsEqual(); eq[69][i].in[0] <== in[i]; - eq[69][i].in[1] <== 45; + eq[69][i].in[1] <== 46; eq[70][i] = IsEqual(); eq[70][i].in[0] <== in[i]; - eq[70][i].in[1] <== 46; + eq[70][i].in[1] <== 47; eq[71][i] = IsEqual(); eq[71][i].in[0] <== in[i]; - eq[71][i].in[1] <== 47; + eq[71][i].in[1] <== 48; eq[72][i] = IsEqual(); eq[72][i].in[0] <== in[i]; - eq[72][i].in[1] <== 48; + eq[72][i].in[1] <== 49; eq[73][i] = IsEqual(); eq[73][i].in[0] <== in[i]; - eq[73][i].in[1] <== 49; + eq[73][i].in[1] <== 50; eq[74][i] = IsEqual(); eq[74][i].in[0] <== in[i]; - eq[74][i].in[1] <== 50; + eq[74][i].in[1] <== 51; eq[75][i] = IsEqual(); eq[75][i].in[0] <== in[i]; - eq[75][i].in[1] <== 51; + eq[75][i].in[1] <== 52; eq[76][i] = IsEqual(); eq[76][i].in[0] <== in[i]; - eq[76][i].in[1] <== 52; + eq[76][i].in[1] <== 53; eq[77][i] = IsEqual(); eq[77][i].in[0] <== in[i]; - eq[77][i].in[1] <== 53; + eq[77][i].in[1] <== 54; eq[78][i] = IsEqual(); eq[78][i].in[0] <== in[i]; - eq[78][i].in[1] <== 54; + eq[78][i].in[1] <== 55; eq[79][i] = IsEqual(); eq[79][i].in[0] <== in[i]; - eq[79][i].in[1] <== 55; + eq[79][i].in[1] <== 56; eq[80][i] = IsEqual(); eq[80][i].in[0] <== in[i]; - eq[80][i].in[1] <== 56; + eq[80][i].in[1] <== 57; eq[81][i] = IsEqual(); eq[81][i].in[0] <== in[i]; - eq[81][i].in[1] <== 57; - eq[82][i] = IsEqual(); - eq[82][i].in[0] <== in[i]; - eq[82][i].in[1] <== 61; - eq[83][i] = IsEqual(); - eq[83][i].in[0] <== in[i]; - eq[83][i].in[1] <== 63; + eq[81][i].in[1] <== 61; and[44][i] = AND(); and[44][i].a <== states[i][9]; - multi_or[15][i] = MultiOR(26); + multi_or[15][i] = MultiOR(24); 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; @@ -638,62 +632,155 @@ template EmailAddrWithNameRegex(msg_bytes) { 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][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 <== eq[17][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[0] <== 65; 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 <== lt[22][i].out; - and[47][i].b <== lt[23][i].out; + lt[23][i].in[1] <== 90; + and[45][i] = AND(); + and[45][i].a <== lt[22][i].out; + and[45][i].b <== lt[23][i].out; + eq[82][i] = IsEqual(); + eq[82][i].in[0] <== in[i]; + eq[82][i].in[1] <== 63; + and[46][i] = AND(); + and[46][i].a <== states[i][10]; + multi_or[16][i] = MultiOR(25); + multi_or[16][i].in[0] <== and[45][i].out; + multi_or[16][i].in[1] <== and[43][i].out; + multi_or[16][i].in[2] <== eq[60][i].out; + multi_or[16][i].in[3] <== eq[61][i].out; + multi_or[16][i].in[4] <== eq[62][i].out; + multi_or[16][i].in[5] <== eq[63][i].out; + multi_or[16][i].in[6] <== eq[64][i].out; + multi_or[16][i].in[7] <== eq[65][i].out; + multi_or[16][i].in[8] <== eq[66][i].out; + multi_or[16][i].in[9] <== eq[67][i].out; + multi_or[16][i].in[10] <== eq[68][i].out; + multi_or[16][i].in[11] <== eq[69][i].out; + multi_or[16][i].in[12] <== eq[70][i].out; + multi_or[16][i].in[13] <== eq[71][i].out; + multi_or[16][i].in[14] <== eq[72][i].out; + multi_or[16][i].in[15] <== eq[73][i].out; + multi_or[16][i].in[16] <== eq[74][i].out; + multi_or[16][i].in[17] <== eq[75][i].out; + multi_or[16][i].in[18] <== eq[76][i].out; + multi_or[16][i].in[19] <== eq[77][i].out; + multi_or[16][i].in[20] <== eq[78][i].out; + multi_or[16][i].in[21] <== eq[79][i].out; + multi_or[16][i].in[22] <== eq[80][i].out; + multi_or[16][i].in[23] <== eq[81][i].out; + multi_or[16][i].in[24] <== eq[82][i].out; + and[46][i].b <== multi_or[16][i].out; + eq[83][i] = IsEqual(); + eq[83][i].in[0] <== in[i]; + eq[83][i].in[1] <== 94; eq[84][i] = IsEqual(); eq[84][i].in[0] <== in[i]; eq[84][i].in[1] <== 95; + eq[85][i] = IsEqual(); + eq[85][i].in[0] <== in[i]; + eq[85][i].in[1] <== 96; + eq[86][i] = IsEqual(); + eq[86][i].in[0] <== in[i]; + eq[86][i].in[1] <== 123; + eq[87][i] = IsEqual(); + eq[87][i].in[0] <== in[i]; + eq[87][i].in[1] <== 124; + eq[88][i] = IsEqual(); + eq[88][i].in[0] <== in[i]; + eq[88][i].in[1] <== 125; + eq[89][i] = IsEqual(); + eq[89][i].in[0] <== in[i]; + eq[89][i].in[1] <== 126; + and[47][i] = AND(); + and[47][i].a <== states[i][11]; + multi_or[17][i] = MultiOR(18); + multi_or[17][i].in[0] <== eq[60][i].out; + multi_or[17][i].in[1] <== eq[61][i].out; + multi_or[17][i].in[2] <== eq[62][i].out; + multi_or[17][i].in[3] <== eq[63][i].out; + multi_or[17][i].in[4] <== eq[64][i].out; + multi_or[17][i].in[5] <== eq[65][i].out; + multi_or[17][i].in[6] <== eq[66][i].out; + multi_or[17][i].in[7] <== eq[67][i].out; + multi_or[17][i].in[8] <== eq[70][i].out; + multi_or[17][i].in[9] <== eq[81][i].out; + multi_or[17][i].in[10] <== eq[82][i].out; + multi_or[17][i].in[11] <== eq[83][i].out; + multi_or[17][i].in[12] <== eq[84][i].out; + multi_or[17][i].in[13] <== eq[85][i].out; + multi_or[17][i].in[14] <== eq[86][i].out; + multi_or[17][i].in[15] <== eq[87][i].out; + multi_or[17][i].in[16] <== eq[88][i].out; + multi_or[17][i].in[17] <== eq[89][i].out; + and[47][i].b <== multi_or[17][i].out; and[48][i] = AND(); - 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].a <== states[i][12]; and[48][i].b <== multi_or[17][i].out; + multi_or[18][i] = MultiOR(4); + multi_or[18][i].in[0] <== and[44][i].out; + multi_or[18][i].in[1] <== and[46][i].out; + multi_or[18][i].in[2] <== and[47][i].out; + multi_or[18][i].in[3] <== and[48][i].out; + states[i+1][10] <== multi_or[18][i].out; + eq[90][i] = IsEqual(); + eq[90][i].in[0] <== in[i]; + eq[90][i].in[1] <== 64; and[49][i] = AND(); - 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[49][i].a <== states[i][10]; + and[49][i].b <== eq[90][i].out; and[50][i] = AND(); - and[50][i].a <== states[i][12]; - and[50][i].b <== eq[16][i].out; - states[i+1][13] <== and[50][i].out; + and[50][i].a <== states[i][11]; + and[50][i].b <== eq[90][i].out; + and[51][i] = AND(); + and[51][i].a <== states[i][12]; + and[51][i].b <== eq[90][i].out; + multi_or[19][i] = MultiOR(3); + multi_or[19][i].in[0] <== and[49][i].out; + multi_or[19][i].in[1] <== and[50][i].out; + multi_or[19][i].in[2] <== and[51][i].out; + states[i+1][11] <== multi_or[19][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[52][i] = AND(); + and[52][i].a <== lt[24][i].out; + and[52][i].b <== lt[25][i].out; + and[53][i] = AND(); + and[53][i].a <== states[i][11]; + multi_or[20][i] = MultiOR(14); + multi_or[20][i].in[0] <== and[45][i].out; + multi_or[20][i].in[1] <== and[52][i].out; + multi_or[20][i].in[2] <== eq[68][i].out; + multi_or[20][i].in[3] <== eq[69][i].out; + multi_or[20][i].in[4] <== eq[71][i].out; + multi_or[20][i].in[5] <== eq[72][i].out; + multi_or[20][i].in[6] <== eq[73][i].out; + multi_or[20][i].in[7] <== eq[74][i].out; + multi_or[20][i].in[8] <== eq[75][i].out; + multi_or[20][i].in[9] <== eq[76][i].out; + multi_or[20][i].in[10] <== eq[77][i].out; + multi_or[20][i].in[11] <== eq[78][i].out; + multi_or[20][i].in[12] <== eq[79][i].out; + multi_or[20][i].in[13] <== eq[80][i].out; + and[53][i].b <== multi_or[20][i].out; + and[54][i] = AND(); + and[54][i].a <== states[i][12]; + and[54][i].b <== multi_or[20][i].out; + multi_or[21][i] = MultiOR(2); + multi_or[21][i].in[0] <== and[53][i].out; + multi_or[21][i].in[1] <== and[54][i].out; + states[i+1][12] <== multi_or[21][i].out; + and[55][i] = AND(); + and[55][i].a <== states[i][12]; + and[55][i].b <== eq[17][i].out; + states[i+1][13] <== and[55][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[10][i].out]); @@ -730,19 +817,23 @@ template EmailAddrWithNameRegex(msg_bytes) { 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]; + // substrings calculated: [{(9, 10), (10, 10), (10, 11), (11, 10), (11, 11), (11, 12), (12, 10), (12, 11), (12, 12)}] + signal prev_states0[9][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)] + // the 0-th substring transitions: [(9, 10), (10, 10), (10, 11), (11, 10), (11, 11), (11, 12), (12, 10), (12, 11), (12, 12)] 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]]); + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][11]; + prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][11]; + prev_states0[6][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][12]; + prev_states0[7][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][12]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][12]; + is_substr0[i] <== MultiOR(9)([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][10], prev_states0[4][i] * states[i+2][11], prev_states0[5][i] * states[i+2][12], prev_states0[6][i] * states[i+2][10], prev_states0[7][i] * states[i+2][11], prev_states0[8][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]; } diff --git a/packages/circom/circuits/common/email_domain.json b/packages/circom/circuits/common/email_domain.json index e20587e..7051e3a 100644 --- a/packages/circom/circuits/common/email_domain.json +++ b/packages/circom/circuits/common/email_domain.json @@ -2,15 +2,11 @@ "parts": [ { "is_public": false, - "regex_def": "[A-Za-z0-9!#$%&'*+-/=?\\^_`{\\|}~\\.]+" - }, - { - "is_public": false, - "regex_def": "@" + "regex_def": "[A-Za-z0-9!#$%&'*+=?\\-\\^_`{|}~./]+@" }, { "is_public": true, - "regex_def": "[A-Za-z0-9\\.-]+" + "regex_def": "[A-Za-z0-9.\\-@]+" } ] -} +} \ No newline at end of file diff --git a/packages/circom/circuits/common/email_domain_regex.circom b/packages/circom/circuits/common/email_domain_regex.circom index 8fd4ca7..a1e0e61 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,9 +14,9 @@ template EmailDomainRegex(msg_bytes) { in[i+1] <== msg[i]; } - component eq[25][num_bytes]; - component lt[6][num_bytes]; - component and[8][num_bytes]; + component eq[24][num_bytes]; + component lt[8][num_bytes]; + component and[9][num_bytes]; component multi_or[3][num_bytes]; signal states[num_bytes+1][4]; signal states_tmp[num_bytes+1][4]; @@ -75,55 +75,52 @@ template EmailDomainRegex(msg_bytes) { eq[7][i].in[1] <== 43; eq[8][i] = IsEqual(); eq[8][i].in[0] <== in[i]; - eq[8][i].in[1] <== 44; + eq[8][i].in[1] <== 45; eq[9][i] = IsEqual(); eq[9][i].in[0] <== in[i]; - eq[9][i].in[1] <== 45; + eq[9][i].in[1] <== 46; eq[10][i] = IsEqual(); eq[10][i].in[0] <== in[i]; - eq[10][i].in[1] <== 46; + eq[10][i].in[1] <== 47; eq[11][i] = IsEqual(); eq[11][i].in[0] <== in[i]; - eq[11][i].in[1] <== 47; + eq[11][i].in[1] <== 48; eq[12][i] = IsEqual(); eq[12][i].in[0] <== in[i]; - eq[12][i].in[1] <== 48; + eq[12][i].in[1] <== 49; eq[13][i] = IsEqual(); eq[13][i].in[0] <== in[i]; - eq[13][i].in[1] <== 49; + eq[13][i].in[1] <== 50; eq[14][i] = IsEqual(); eq[14][i].in[0] <== in[i]; - eq[14][i].in[1] <== 50; + eq[14][i].in[1] <== 51; eq[15][i] = IsEqual(); eq[15][i].in[0] <== in[i]; - eq[15][i].in[1] <== 51; + eq[15][i].in[1] <== 52; eq[16][i] = IsEqual(); eq[16][i].in[0] <== in[i]; - eq[16][i].in[1] <== 52; + eq[16][i].in[1] <== 53; eq[17][i] = IsEqual(); eq[17][i].in[0] <== in[i]; - eq[17][i].in[1] <== 53; + eq[17][i].in[1] <== 54; eq[18][i] = IsEqual(); eq[18][i].in[0] <== in[i]; - eq[18][i].in[1] <== 54; + eq[18][i].in[1] <== 55; eq[19][i] = IsEqual(); eq[19][i].in[0] <== in[i]; - eq[19][i].in[1] <== 55; + eq[19][i].in[1] <== 56; eq[20][i] = IsEqual(); eq[20][i].in[0] <== in[i]; - eq[20][i].in[1] <== 56; + eq[20][i].in[1] <== 57; eq[21][i] = IsEqual(); eq[21][i].in[0] <== in[i]; - eq[21][i].in[1] <== 57; + eq[21][i].in[1] <== 61; eq[22][i] = IsEqual(); eq[22][i].in[0] <== in[i]; - eq[22][i].in[1] <== 61; - eq[23][i] = IsEqual(); - eq[23][i].in[0] <== in[i]; - eq[23][i].in[1] <== 63; + eq[22][i].in[1] <== 63; and[2][i] = AND(); and[2][i].a <== states[i][0]; - multi_or[0][i] = MultiOR(26); + multi_or[0][i] = MultiOR(25); 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; @@ -149,52 +146,60 @@ template EmailDomainRegex(msg_bytes) { multi_or[0][i].in[22] <== eq[20][i].out; 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; 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; + eq[23][i] = IsEqual(); + eq[23][i].in[0] <== in[i]; + eq[23][i].in[1] <== 64; and[4][i] = AND(); and[4][i].a <== states[i][1]; - and[4][i].b <== eq[24][i].out; + and[4][i].b <== eq[23][i].out; states[i+1][2] <== and[4][i].out; lt[4][i] = LessEqThan(8); - lt[4][i].in[0] <== 97; + lt[4][i].in[0] <== 64; lt[4][i].in[1] <== in[i]; lt[5][i] = LessEqThan(8); lt[5][i].in[0] <== in[i]; - lt[5][i].in[1] <== 122; + lt[5][i].in[1] <== 90; and[5][i] = AND(); and[5][i].a <== lt[4][i].out; and[5][i].b <== lt[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[6][i] = AND(); - 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[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][3]; + and[7][i].a <== states[i][2]; + multi_or[1][i] = MultiOR(14); + multi_or[1][i].in[0] <== and[5][i].out; + multi_or[1][i].in[1] <== and[6][i].out; + multi_or[1][i].in[2] <== eq[8][i].out; + multi_or[1][i].in[3] <== eq[9][i].out; + multi_or[1][i].in[4] <== eq[11][i].out; + multi_or[1][i].in[5] <== eq[12][i].out; + multi_or[1][i].in[6] <== eq[13][i].out; + multi_or[1][i].in[7] <== eq[14][i].out; + multi_or[1][i].in[8] <== eq[15][i].out; + multi_or[1][i].in[9] <== eq[16][i].out; + multi_or[1][i].in[10] <== eq[17][i].out; + multi_or[1][i].in[11] <== eq[18][i].out; + multi_or[1][i].in[12] <== eq[19][i].out; + multi_or[1][i].in[13] <== eq[20][i].out; and[7][i].b <== multi_or[1][i].out; + and[8][i] = AND(); + and[8][i].a <== states[i][3]; + and[8][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; + multi_or[2][i].in[0] <== and[7][i].out; + multi_or[2][i].in[1] <== and[8][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]); diff --git a/packages/circom/circuits/common/from_addr.json b/packages/circom/circuits/common/from_addr.json index 3019ca0..82fefdd 100644 --- a/packages/circom/circuits/common/from_addr.json +++ b/packages/circom/circuits/common/from_addr.json @@ -10,11 +10,11 @@ }, { "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, "regex_def": ">?\r\n" } ] -} +} \ 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 a41aca3..9c7a4b1 100644 --- a/packages/circom/circuits/common/to_addr.json +++ b/packages/circom/circuits/common/to_addr.json @@ -10,11 +10,11 @@ }, { "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, "regex_def": ">?\r\n" } ] -} +} \ No newline at end of file diff --git a/packages/circom/tests/email_addr.test.js b/packages/circom/tests/email_addr.test.js index dcf9999..a118930 100644 --- a/packages/circom/tests/email_addr.test.js +++ b/packages/circom/tests/email_addr.test.js @@ -69,4 +69,46 @@ describe("Email Address Regex", () => { } } }); + + it("@ inside the name part", async () => { + const prefix = "subject:"; + const emailAddr = "suegamisora@gmail.com@dummy.com"; + const string = prefix + emailAddr; + const paddedStr = apis.padString(string, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractEmailAddrIdxes(string)[0]; + for (let idx = 0; idx < 256; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("starts from @", async () => { + const prefix = "subject:"; + const emailAddr = "@gmail.com@dummy.com"; + const string = prefix + emailAddr; + const paddedStr = apis.padString(string, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractEmailAddrIdxes(string)[0]; + for (let idx = 0; idx < 256; ++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/email_domain.test.js b/packages/circom/tests/email_domain.test.js index a73173b..0c33612 100644 --- a/packages/circom/tests/email_domain.test.js +++ b/packages/circom/tests/email_domain.test.js @@ -39,10 +39,47 @@ describe("Email Domain Regex", () => { const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); expect(1n).toEqual(witness[1]); - for (let idx = 0; idx < 12; ++idx) { - expect(0n).toEqual(witness[2 + idx]); + const prefixIdxes = apis.extractEmailDomainIdxes(emailAddr)[0]; + for (let idx = 0; idx < 256; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } } + }); + + it("@ inside the name part", async () => { + const emailAddr = "suegamisora@gmail.com@dummy.com"; + const paddedStr = apis.padString(emailAddr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractEmailDomainIdxes(emailAddr)[0]; + expect("gmail.com@dummy.com").toEqual(emailAddr.slice(prefixIdxes[0], prefixIdxes[1])); + for (let idx = 0; idx < 256; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("starts from @", async () => { + const emailAddr = "@gmail.com@dummy.com"; + const paddedStr = apis.padString(emailAddr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(1n).toEqual(witness[1]); const prefixIdxes = apis.extractEmailDomainIdxes(emailAddr)[0]; + expect("dummy.com").toEqual(emailAddr.slice(prefixIdxes[0], prefixIdxes[1])); for (let idx = 0; idx < 256; ++idx) { if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); diff --git a/packages/circom/tests/from_addr.test.js b/packages/circom/tests/from_addr.test.js index 234abd9..dba8b0a 100644 --- a/packages/circom/tests/from_addr.test.js +++ b/packages/circom/tests/from_addr.test.js @@ -228,4 +228,44 @@ describe("From Addr Regex", () => { await expect(failFn).rejects.toThrow(); }); + it("from field containing @ in the name part", async () => { + const fromStr = "from:Sora Suegami \r\n"; + const paddedStr = apis.padString(fromStr, 1024); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractFromAddrIdxes(fromStr)[0]; + expect("suegamisora@gmail.com@dummy.com").toEqual(fromStr.slice(prefixIdxes[0], prefixIdxes[1])); + for (let idx = 0; idx < 1024; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("from field starting from @", async () => { + const fromStr = "from:Sora Suegami <@gmail.com@dummy.com>\r\n"; + const paddedStr = apis.padString(fromStr, 1024); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractFromAddrIdxes(fromStr)[0]; + expect("@gmail.com@dummy.com").toEqual(fromStr.slice(prefixIdxes[0], prefixIdxes[1])); + for (let idx = 0; idx < 1024; ++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/to_addr.test.js b/packages/circom/tests/to_addr.test.js index e981147..f6b3a62 100644 --- a/packages/circom/tests/to_addr.test.js +++ b/packages/circom/tests/to_addr.test.js @@ -226,4 +226,44 @@ describe("To Addr Regex", () => { } await expect(failFn).rejects.toThrow(); }); + + it("to field containing @ in the name part", async () => { + const toStr = "to:Aditya Bisht \r\n"; + const paddedStr = apis.padString(toStr, 1024); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractToAddrIdxes(toStr)[0]; + expect("adityabisht@gmail.com@dummy.com").toEqual(toStr.slice(prefixIdxes[0], prefixIdxes[1])); + for (let idx = 0; idx < 1024; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); + + it("to field starting from @", async () => { + const toStr = "to:Aditya Bisht <@gmail.com@dummy.com>\r\n"; + const paddedStr = apis.padString(toStr, 1024); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(1n).toEqual(witness[1]); + const prefixIdxes = apis.extractToAddrIdxes(toStr)[0]; + expect("@gmail.com@dummy.com").toEqual(toStr.slice(prefixIdxes[0], prefixIdxes[1])); + for (let idx = 0; idx < 1024; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(0n).toEqual(witness[2 + idx]); + } + } + }); });