mirror of
https://github.com/zkemail/zk-regex.git
synced 2026-01-09 13:48:00 -05:00
feat: Add to_addr field in API (#48)
* feat: add to_addr * test: replace code test * fix tests change apis package.json change apis package.json
This commit is contained in:
@@ -1 +1,4 @@
|
||||
paths = ["./"]
|
||||
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
rustflags = ["-Clink-arg=-Wl,--allow-multiple-definition"]
|
||||
9
.github/workflows/test.yaml
vendored
9
.github/workflows/test.yaml
vendored
@@ -12,11 +12,12 @@ jobs:
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
- name: "Setup Rust"
|
||||
uses: ATiltedTree/setup-rust@v1
|
||||
- name: Setup Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
rust-version: nightly
|
||||
components: clippy
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: Download circom (Linux)
|
||||
run: wget https://github.com/iden3/circom/releases/latest/download/circom-linux-amd64 -O /usr/local/bin/circom && chmod +x /usr/local/bin/circom
|
||||
- name: Install yarn
|
||||
|
||||
@@ -23,6 +23,7 @@ itertools = "0.10.3"
|
||||
thiserror = "1.0.40"
|
||||
serde_json = "1.0.95"
|
||||
|
||||
|
||||
[dependencies.neon]
|
||||
version = "0.10"
|
||||
default-features = false
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
"build": "cargo-cp-artifact -nc index.node -- cargo build --message-format=json-render-diagnostics",
|
||||
"build-debug": "npm run build --",
|
||||
"build-release": "npm run build -- --release",
|
||||
"install": "node-pre-gyp install --update-binary --fallback-to-build=false || npm run build-release",
|
||||
"install": "npm run build-debug",
|
||||
"install-release": "node-pre-gyp install --update-binary --fallback-to-build=false || npm run build-release",
|
||||
"test": "cargo test",
|
||||
"package": "node-pre-gyp package",
|
||||
"upload-binary": "npm run package && node-pre-gyp-github publish"
|
||||
@@ -35,4 +36,4 @@
|
||||
"package_name": "apis-{node_abi}-{platform}-{arch}.tar.gz",
|
||||
"module_path": "./"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
20
packages/apis/src/decomposed_defs/to_addr.json
Normal file
20
packages/apis/src/decomposed_defs/to_addr.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"parts": [
|
||||
{
|
||||
"is_public": false,
|
||||
"regex_def": "((\r\n)|^)to:"
|
||||
},
|
||||
{
|
||||
"is_public": false,
|
||||
"regex_def": "([^\r\n]+<)?"
|
||||
},
|
||||
{
|
||||
"is_public": true,
|
||||
"regex_def": "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|0|1|2|3|4|5|6|7|8|9|!|#|$|%|&|'|\\*|\\+|-|/|=|\\?|^|_|`|{|\\||}|~|\\.)+@(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|0|1|2|3|4|5|6|7|8|9|_|\\.|-)+"
|
||||
},
|
||||
{
|
||||
"is_public": false,
|
||||
"regex_def": ">?\r\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
16
packages/apis/src/decomposed_defs/to_all.json
Normal file
16
packages/apis/src/decomposed_defs/to_all.json
Normal file
@@ -0,0 +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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
use zk_regex_compiler::DecomposedRegexConfig;
|
||||
use fancy_regex::Regex;
|
||||
|
||||
use neon::prelude::*;
|
||||
use serde_json;
|
||||
use thiserror::Error;
|
||||
use zk_regex_compiler::DecomposedRegexConfig;
|
||||
|
||||
/// Error definitions of the compiler.
|
||||
#[derive(Error, Debug)]
|
||||
@@ -102,6 +101,17 @@ pub fn extract_from_addr_idxes(
|
||||
extract_substr_idxes(input_str, ®ex_config)
|
||||
}
|
||||
|
||||
pub fn extract_to_all_idxes(input_str: &str) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
|
||||
let regex_config = serde_json::from_str(include_str!("./decomposed_defs/to_all.json")).unwrap();
|
||||
extract_substr_idxes(input_str, ®ex_config)
|
||||
}
|
||||
|
||||
pub fn extract_to_addr_idxes(input_str: &str) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
|
||||
let regex_config =
|
||||
serde_json::from_str(include_str!("./decomposed_defs/to_addr.json")).unwrap();
|
||||
extract_substr_idxes(input_str, ®ex_config)
|
||||
}
|
||||
|
||||
pub fn extract_subject_all_idxes(
|
||||
input_str: &str,
|
||||
) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
|
||||
@@ -247,6 +257,49 @@ pub fn extract_from_addr_idxes_node(mut cx: FunctionContext) -> JsResult<JsArray
|
||||
Ok(js_array)
|
||||
}
|
||||
|
||||
pub fn extract_to_all_idxes_node(mut cx: FunctionContext) -> JsResult<JsArray> {
|
||||
let input_str = cx.argument::<JsString>(0)?.value(&mut cx);
|
||||
|
||||
let substr_idxes = match extract_to_all_idxes(&input_str) {
|
||||
Ok(substr_idxes) => substr_idxes,
|
||||
Err(e) => return cx.throw_error(e.to_string()),
|
||||
};
|
||||
|
||||
let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32);
|
||||
|
||||
for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() {
|
||||
let start_end_array = JsArray::new(&mut cx, 2u32);
|
||||
|
||||
let start_idx = cx.number(*start_idx as f64);
|
||||
start_end_array.set(&mut cx, 0, start_idx)?;
|
||||
|
||||
let end_idx = cx.number(*end_idx as f64);
|
||||
start_end_array.set(&mut cx, 1, end_idx)?;
|
||||
|
||||
js_array.set(&mut cx, i as u32, start_end_array)?;
|
||||
}
|
||||
|
||||
Ok(js_array)
|
||||
}
|
||||
|
||||
pub fn extract_to_addr_idxes_node(mut cx: FunctionContext) -> JsResult<JsArray> {
|
||||
let input_str = cx.argument::<JsString>(0)?.value(&mut cx);
|
||||
let substr_idxes = match extract_to_addr_idxes(&input_str) {
|
||||
Ok(substr_idxes) => substr_idxes,
|
||||
Err(e) => return cx.throw_error(e.to_string()),
|
||||
};
|
||||
let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32);
|
||||
for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() {
|
||||
let start_end_array = JsArray::new(&mut cx, 2u32);
|
||||
let start_idx = cx.number(*start_idx as f64);
|
||||
start_end_array.set(&mut cx, 0, start_idx)?;
|
||||
let end_idx = cx.number(*end_idx as f64);
|
||||
start_end_array.set(&mut cx, 1, end_idx)?;
|
||||
js_array.set(&mut cx, i as u32, start_end_array)?;
|
||||
}
|
||||
Ok(js_array)
|
||||
}
|
||||
|
||||
pub fn extract_subject_all_idxes_node(mut cx: FunctionContext) -> JsResult<JsArray> {
|
||||
let input_str = cx.argument::<JsString>(0)?.value(&mut cx);
|
||||
let substr_idxes = match extract_subject_all_idxes(&input_str) {
|
||||
@@ -369,13 +422,13 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_code_in_subject_valid() {
|
||||
fn test_code_in_email_address_valid() {
|
||||
let code_regex = DecomposedRegexConfig {
|
||||
// max_byte_size: 1024,
|
||||
parts: vec![
|
||||
RegexPartConfig {
|
||||
is_public: false,
|
||||
regex_def: "CODE:0x".to_string(),
|
||||
regex_def: "ACCOUNTKEY.0x".to_string(),
|
||||
// max_size: 7,
|
||||
// solidity: None
|
||||
},
|
||||
@@ -387,9 +440,9 @@ mod test {
|
||||
},
|
||||
],
|
||||
};
|
||||
let input_str = "subject:Email Wallet CODE:0x123abc";
|
||||
let input_str = "sepolia+ACCOUNTKEY.0xabc123@sendeth.org";
|
||||
let idxes = extract_substr_idxes(input_str, &code_regex).unwrap();
|
||||
assert_eq!(idxes, vec![(28, 34)]);
|
||||
assert_eq!(idxes, vec![(21, 27)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -17,6 +17,8 @@ fn main(mut cx: ModuleContext) -> NeonResult<()> {
|
||||
)?;
|
||||
cx.export_function("extractFromAllIdxes", extract_from_all_idxes_node)?;
|
||||
cx.export_function("extractFromAddrIdxes", extract_from_addr_idxes_node)?;
|
||||
cx.export_function("extractToAllIdxes", extract_to_all_idxes_node)?;
|
||||
cx.export_function("extractToAddrIdxes", extract_to_addr_idxes_node)?;
|
||||
cx.export_function("extractSubjectAllIdxes", extract_subject_all_idxes_node)?;
|
||||
cx.export_function("extractBodyHashIdxes", extract_body_hash_idxes_node)?;
|
||||
cx.export_function("extractTimestampIdxes", extract_timestamp_idxes_node)?;
|
||||
|
||||
20
packages/circom/circuits/common/to_addr.json
Normal file
20
packages/circom/circuits/common/to_addr.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"parts": [
|
||||
{
|
||||
"is_public": false,
|
||||
"regex_def": "((\r\n)|^)to:"
|
||||
},
|
||||
{
|
||||
"is_public": false,
|
||||
"regex_def": "([^\r\n]+<)?"
|
||||
},
|
||||
{
|
||||
"is_public": true,
|
||||
"regex_def": "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|0|1|2|3|4|5|6|7|8|9|!|#|$|%|&|'|\\*|\\+|-|/|=|\\?|^|_|`|{|\\||}|~|\\.)+@(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|0|1|2|3|4|5|6|7|8|9|_|\\.|-)+"
|
||||
},
|
||||
{
|
||||
"is_public": false,
|
||||
"regex_def": ">?\r\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
31
packages/circom/circuits/common/to_addr_regex.circom
Normal file
31
packages/circom/circuits/common/to_addr_regex.circom
Normal file
@@ -0,0 +1,31 @@
|
||||
pragma circom 2.1.5;
|
||||
|
||||
include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom";
|
||||
include "@zk-email/zk-regex-circom/circuits/common/to_all_regex.circom";
|
||||
include "@zk-email/zk-regex-circom/circuits/common/email_addr_regex.circom";
|
||||
include "@zk-email/zk-regex-circom/circuits/common/email_addr_with_name_regex.circom";
|
||||
|
||||
|
||||
template ToAddrRegex(msg_bytes) {
|
||||
signal input msg[msg_bytes];
|
||||
signal output out;
|
||||
signal output reveal0[msg_bytes];
|
||||
|
||||
signal toOut;
|
||||
signal toReveal[msg_bytes];
|
||||
(toOut, toReveal) <== ToAllRegex(msg_bytes)(msg);
|
||||
toOut === 1;
|
||||
|
||||
signal emailNameOut;
|
||||
signal emailNameReveal[msg_bytes];
|
||||
(emailNameOut, emailNameReveal) <== EmailAddrWithNameRegex(msg_bytes)(toReveal);
|
||||
|
||||
signal emailAddrOut;
|
||||
signal emailAddrReveal[msg_bytes];
|
||||
(emailAddrOut, emailAddrReveal) <== EmailAddrRegex(msg_bytes)(toReveal);
|
||||
|
||||
out <== MultiOR(2)([emailNameOut, emailAddrOut]);
|
||||
for(var i=0; i<msg_bytes; i++) {
|
||||
reveal0[i] <== emailNameOut * (emailNameReveal[i] - emailAddrReveal[i]) + emailAddrReveal[i];
|
||||
}
|
||||
}
|
||||
16
packages/circom/circuits/common/to_all.json
Normal file
16
packages/circom/circuits/common/to_all.json
Normal file
@@ -0,0 +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"
|
||||
}
|
||||
]
|
||||
}
|
||||
190
packages/circom/circuits/common/to_all_regex.circom
Normal file
190
packages/circom/circuits/common/to_all_regex.circom
Normal file
@@ -0,0 +1,190 @@
|
||||
pragma circom 2.1.5;
|
||||
|
||||
include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom";
|
||||
|
||||
template ToAllRegex(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[18][num_bytes];
|
||||
component lt[2][num_bytes];
|
||||
component and[12][num_bytes];
|
||||
component multi_or[4][num_bytes];
|
||||
signal states[num_bytes+1][9];
|
||||
component state_changed[num_bytes];
|
||||
|
||||
states[0][0] <== 1;
|
||||
for (var i = 1; i < 9; i++) {
|
||||
states[0][i] <== 0;
|
||||
}
|
||||
|
||||
for (var i = 0; i < num_bytes; i++) {
|
||||
state_changed[i] = MultiOR(8);
|
||||
lt[0][i] = LessEqThan(8);
|
||||
lt[0][i].in[0] <== 14;
|
||||
lt[0][i].in[1] <== in[i];
|
||||
lt[1][i] = LessEqThan(8);
|
||||
lt[1][i].in[0] <== in[i];
|
||||
lt[1][i].in[1] <== 254;
|
||||
and[0][i] = AND();
|
||||
and[0][i].a <== lt[0][i].out;
|
||||
and[0][i].b <== lt[1][i].out;
|
||||
eq[0][i] = IsEqual();
|
||||
eq[0][i].in[0] <== in[i];
|
||||
eq[0][i].in[1] <== 0;
|
||||
eq[1][i] = IsEqual();
|
||||
eq[1][i].in[0] <== in[i];
|
||||
eq[1][i].in[1] <== 1;
|
||||
eq[2][i] = IsEqual();
|
||||
eq[2][i].in[0] <== in[i];
|
||||
eq[2][i].in[1] <== 2;
|
||||
eq[3][i] = IsEqual();
|
||||
eq[3][i].in[0] <== in[i];
|
||||
eq[3][i].in[1] <== 3;
|
||||
eq[4][i] = IsEqual();
|
||||
eq[4][i].in[0] <== in[i];
|
||||
eq[4][i].in[1] <== 4;
|
||||
eq[5][i] = IsEqual();
|
||||
eq[5][i].in[0] <== in[i];
|
||||
eq[5][i].in[1] <== 5;
|
||||
eq[6][i] = IsEqual();
|
||||
eq[6][i].in[0] <== in[i];
|
||||
eq[6][i].in[1] <== 6;
|
||||
eq[7][i] = IsEqual();
|
||||
eq[7][i].in[0] <== in[i];
|
||||
eq[7][i].in[1] <== 7;
|
||||
eq[8][i] = IsEqual();
|
||||
eq[8][i].in[0] <== in[i];
|
||||
eq[8][i].in[1] <== 8;
|
||||
eq[9][i] = IsEqual();
|
||||
eq[9][i].in[0] <== in[i];
|
||||
eq[9][i].in[1] <== 9;
|
||||
eq[10][i] = IsEqual();
|
||||
eq[10][i].in[0] <== in[i];
|
||||
eq[10][i].in[1] <== 11;
|
||||
eq[11][i] = IsEqual();
|
||||
eq[11][i].in[0] <== in[i];
|
||||
eq[11][i].in[1] <== 12;
|
||||
and[1][i] = AND();
|
||||
and[1][i].a <== states[i][1];
|
||||
multi_or[0][i] = MultiOR(13);
|
||||
multi_or[0][i].in[0] <== and[0][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;
|
||||
multi_or[0][i].in[9] <== eq[8][i].out;
|
||||
multi_or[0][i].in[10] <== eq[9][i].out;
|
||||
multi_or[0][i].in[11] <== eq[10][i].out;
|
||||
multi_or[0][i].in[12] <== eq[11][i].out;
|
||||
and[1][i].b <== multi_or[0][i].out;
|
||||
and[2][i] = AND();
|
||||
and[2][i].a <== states[i][6];
|
||||
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][1] <== multi_or[1][i].out;
|
||||
state_changed[i].in[0] <== states[i+1][1];
|
||||
eq[12][i] = IsEqual();
|
||||
eq[12][i].in[0] <== in[i];
|
||||
eq[12][i].in[1] <== 13;
|
||||
and[3][i] = AND();
|
||||
and[3][i].a <== states[i][0];
|
||||
and[3][i].b <== eq[12][i].out;
|
||||
and[4][i] = AND();
|
||||
and[4][i].a <== states[i][3];
|
||||
and[4][i].b <== eq[12][i].out;
|
||||
multi_or[2][i] = MultiOR(2);
|
||||
multi_or[2][i].in[0] <== and[3][i].out;
|
||||
multi_or[2][i].in[1] <== and[4][i].out;
|
||||
states[i+1][2] <== multi_or[2][i].out;
|
||||
state_changed[i].in[1] <== states[i+1][2];
|
||||
eq[13][i] = IsEqual();
|
||||
eq[13][i].in[0] <== in[i];
|
||||
eq[13][i].in[1] <== 255;
|
||||
and[5][i] = AND();
|
||||
and[5][i].a <== states[i][0];
|
||||
and[5][i].b <== eq[13][i].out;
|
||||
eq[14][i] = IsEqual();
|
||||
eq[14][i].in[0] <== in[i];
|
||||
eq[14][i].in[1] <== 10;
|
||||
and[6][i] = AND();
|
||||
and[6][i].a <== states[i][2];
|
||||
and[6][i].b <== eq[14][i].out;
|
||||
multi_or[3][i] = MultiOR(2);
|
||||
multi_or[3][i].in[0] <== and[5][i].out;
|
||||
multi_or[3][i].in[1] <== and[6][i].out;
|
||||
states[i+1][3] <== multi_or[3][i].out;
|
||||
state_changed[i].in[2] <== states[i+1][3];
|
||||
eq[15][i] = IsEqual();
|
||||
eq[15][i].in[0] <== in[i];
|
||||
eq[15][i].in[1] <== 116;
|
||||
and[7][i] = AND();
|
||||
and[7][i].a <== states[i][3];
|
||||
and[7][i].b <== eq[15][i].out;
|
||||
states[i+1][4] <== and[7][i].out;
|
||||
state_changed[i].in[3] <== states[i+1][4];
|
||||
eq[16][i] = IsEqual();
|
||||
eq[16][i].in[0] <== in[i];
|
||||
eq[16][i].in[1] <== 111;
|
||||
and[8][i] = AND();
|
||||
and[8][i].a <== states[i][4];
|
||||
and[8][i].b <== eq[16][i].out;
|
||||
states[i+1][5] <== and[8][i].out;
|
||||
state_changed[i].in[4] <== states[i+1][5];
|
||||
eq[17][i] = IsEqual();
|
||||
eq[17][i].in[0] <== in[i];
|
||||
eq[17][i].in[1] <== 58;
|
||||
and[9][i] = AND();
|
||||
and[9][i].a <== states[i][5];
|
||||
and[9][i].b <== eq[17][i].out;
|
||||
states[i+1][6] <== and[9][i].out;
|
||||
state_changed[i].in[5] <== states[i+1][6];
|
||||
and[10][i] = AND();
|
||||
and[10][i].a <== states[i][1];
|
||||
and[10][i].b <== eq[12][i].out;
|
||||
states[i+1][7] <== and[10][i].out;
|
||||
state_changed[i].in[6] <== states[i+1][7];
|
||||
and[11][i] = AND();
|
||||
and[11][i].a <== states[i][7];
|
||||
and[11][i].b <== eq[14][i].out;
|
||||
states[i+1][8] <== and[11][i].out;
|
||||
state_changed[i].in[7] <== states[i+1][8];
|
||||
states[i+1][0] <== 1 - state_changed[i].out;
|
||||
}
|
||||
|
||||
component final_state_result = MultiOR(num_bytes+1);
|
||||
for (var i = 0; i <= num_bytes; i++) {
|
||||
final_state_result.in[i] <== states[i][8];
|
||||
}
|
||||
out <== final_state_result.out;
|
||||
|
||||
signal is_consecutive[msg_bytes+1][2];
|
||||
is_consecutive[msg_bytes][1] <== 1;
|
||||
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][1]) + is_consecutive[msg_bytes-i][1];
|
||||
is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0];
|
||||
}
|
||||
signal is_substr0[msg_bytes][3];
|
||||
signal is_reveal0[msg_bytes];
|
||||
signal output reveal0[msg_bytes];
|
||||
for (var i = 0; i < msg_bytes; i++) {
|
||||
is_substr0[i][0] <== 0;
|
||||
is_substr0[i][1] <== is_substr0[i][0] + states[i+1][1] * states[i+2][1];
|
||||
is_substr0[i][2] <== is_substr0[i][1] + states[i+1][6] * states[i+2][1];
|
||||
is_reveal0[i] <== is_substr0[i][2] * is_consecutive[i][1];
|
||||
reveal0[i] <== in[i+1] * is_reveal0[i];
|
||||
}
|
||||
}
|
||||
3
packages/circom/tests/circuits/test_to_addr_regex.circom
Normal file
3
packages/circom/tests/circuits/test_to_addr_regex.circom
Normal file
@@ -0,0 +1,3 @@
|
||||
include "../../circuits/common/to_addr_regex.circom";
|
||||
|
||||
component main = ToAddrRegex(1024);
|
||||
184
packages/circom/tests/to_addr.test.ts
Normal file
184
packages/circom/tests/to_addr.test.ts
Normal file
@@ -0,0 +1,184 @@
|
||||
const circom_tester = require("circom_tester");
|
||||
const wasm_tester = circom_tester.wasm;
|
||||
import * as path from "path";
|
||||
const apis = require("../../apis");
|
||||
const option = {
|
||||
include: path.join(__dirname, "../../../node_modules")
|
||||
};
|
||||
const compiler = require("../../compiler");
|
||||
|
||||
jest.setTimeout(240000);
|
||||
describe("To Addr Regex", () => {
|
||||
let circuit;
|
||||
beforeAll(async () => {
|
||||
compiler.genFromDecomposed(path.join(__dirname, "../circuits/common/to_all.json"), {
|
||||
circomFilePath: path.join(__dirname, "../circuits/common/to_all_regex.circom"),
|
||||
templateName: "ToAllRegex",
|
||||
genSubstrs: true
|
||||
});
|
||||
compiler.genFromDecomposed(path.join(__dirname, "../circuits/common/email_addr_with_name.json"), {
|
||||
circomFilePath: path.join(__dirname, "../circuits/common/email_addr_with_name_regex.circom"),
|
||||
templateName: "EmailAddrWithNameRegex",
|
||||
genSubstrs: true
|
||||
});
|
||||
compiler.genFromDecomposed(path.join(__dirname, "../circuits/common/email_addr.json"), {
|
||||
circomFilePath: path.join(__dirname, "../circuits/common/email_addr_regex.circom"),
|
||||
templateName: "EmailAddrRegex",
|
||||
genSubstrs: true
|
||||
});
|
||||
circuit = await wasm_tester(path.join(__dirname, "./circuits/test_to_addr_regex.circom"), option);
|
||||
});
|
||||
|
||||
it("to field from beginning case 1", async () => {
|
||||
const toStr = "to:adityabisht@gmail.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];
|
||||
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 from beginning case 2", async () => {
|
||||
const toStr = "to:Aditya Bisht <adityabisht@gmail.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];
|
||||
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 from beginning case 3 (email address as a name)", async () => {
|
||||
const toStr = "to:dummy@example.com<adityabisht@gmail.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];
|
||||
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 from beginning case 4 (non-English string is used as a name)", async () => {
|
||||
const toStr = "to: \"末神奏宙\" <adityabisht@gmail.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];
|
||||
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 after new line case 1", async () => {
|
||||
const toStr = "dummy\r\nto:adityabisht@gmail.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];
|
||||
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 after new line case 2", async () => {
|
||||
const toStr = "dummy\r\nto:Sora Suegami <adityabisht@gmail.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];
|
||||
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 after new line case 3 (email address as a name)", async () => {
|
||||
const toStr = "dummy\r\nto:dummy@example.com<adityabisht@gmail.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];
|
||||
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 after new line case 4 (non-English string is used as a name)", async () => {
|
||||
const toStr = "dummy\r\nto: \"末神奏宙\" <adityabisht@gmail.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];
|
||||
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]);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -17,7 +17,8 @@
|
||||
"build": "npx tsc && cargo-cp-artifact -nc index.node -- cargo build --message-format=json-render-diagnostics",
|
||||
"build-debug": "npx tsc && npm run build --",
|
||||
"build-release": "npx tsc && npm run build -- --release",
|
||||
"install": "npx tsc && node-pre-gyp install --fallback-to-build=false || npm run build-release",
|
||||
"install": "npm run build-debug",
|
||||
"install-release": "node-pre-gyp install --update-binary --fallback-to-build=false || npm run build-release",
|
||||
"test": "npx tsc && cargo test",
|
||||
"package": "npx tsc && node-pre-gyp package",
|
||||
"upload-binary": "npx tsc && npm run package && node-pre-gyp-github publish"
|
||||
@@ -36,4 +37,4 @@
|
||||
"package_name": "compiler-{node_abi}-{platform}-{arch}.tar.gz",
|
||||
"module_path": "./"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user