Skip to content
Draft
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8ded16e
feat: initial noir support (#1)
olehmisar Sep 17, 2024
db2e129
Added gen_substrs support for Noir. This works both in decomposed & r…
ewynx Sep 17, 2024
33736ca
Set gen_substrs to false by default for raw.
ewynx Sep 17, 2024
f7ae186
Per state 1 or more substrings will be extracted, depending on the re…
ewynx Sep 19, 2024
3a853e7
Take transitions into account for extracting substrings.
ewynx Sep 26, 2024
8e6aa14
$ and ^ support
ewynx Sep 30, 2024
9f3acd6
Added the "reset" flow when a shortcut is made from any state to the …
ewynx Oct 1, 2024
4137890
Removed old code
ewynx Oct 1, 2024
cd14d89
Escape newline and carriage return characters in regex patterns
ewynx Oct 1, 2024
01231c2
Noir support edit
ewynx Dec 5, 2024
80df487
add explicit type for table
jp4g Jan 27, 2025
2d11aec
sparse array comptime
jp4g Jan 28, 2025
5965f1c
remove conditional access of s_next_temp for optimized gates
jp4g Jan 28, 2025
6e6a7f0
compiler issue
jp4g Jan 29, 2025
c895c92
poc
jp4g Feb 4, 2025
d717095
kinda works pretty well
jp4g Feb 4, 2025
d5568f6
update path
jp4g Feb 4, 2025
6184139
fix first char
jp4g Feb 4, 2025
8575a95
stash working fix to arr length 1 input
jp4g Feb 4, 2025
20e1c4f
handle length 1 failures
jp4g Feb 5, 2025
2d6d036
compiler fixes to past hc test suite
jp4g Feb 7, 2025
a1af188
upgraded for efficient arrays
jp4g Feb 9, 2025
524636c
optimized checks over substring construction
jp4g Feb 12, 2025
2afd271
passing with stronger constraints
jp4g Feb 12, 2025
cdf62fb
segregate logic and refactor codegen
jp4g Feb 16, 2025
9255c69
cli can optionally force match & generate common or not
jp4g Feb 16, 2025
d53b82e
to_addr_regex workin pretty well bruv
jp4g Feb 18, 2025
39adcf1
update to use match-only regexes where possible
jp4g Feb 18, 2025
b725d3a
from and to addr regex added
jp4g Feb 18, 2025
e9cbe2e
composite functions for perfect extraction of certain regexes
jp4g Feb 18, 2025
cdd6014
e2e zkemail integration fully working
jp4g Feb 18, 2025
2a79db9
add in conditional start to substr index if not first substr
jp4g Mar 3, 2025
20de93b
fix first condition set
jp4g Mar 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
members = ["packages/*"]
exclude = ["packages/circom", "test"]
exclude = ["packages/circom", "test", "packages/noir"]

# [patch."https://github.com/stalwartlabs/mail-builder"]
# mail-builder = { version = "0.2.5", git = "https://github.com/stalwartlabs//mail-builder", tag = "0.2.5" }
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# zk-regex

A library to compile regex verification in circom. Explained on [our blog post](https://prove.email/blog/zkregex). You can use regex to specify how to parse an email in a ZK Email proof when defining a new patterm on [the ZK Email SDK registry](https://sdk.prove.email/). Noir coming soon.
A library to compile regex verification in circom. Explained on [our blog post](https://prove.email/blog/zkregex). You can use regex to specify how to parse an email in a ZK Email proof when defining a new patterm on [the ZK Email SDK registry](https://sdk.prove.email/). Noir support is also available.

<!-- We've forked [min-dfa into a UI here](https://mindfa.onrender.com/min_dfa) to create a UI that converts existing regexes with [] support, as well as escapes \_, and the character classes a-z, A-Z, and 0-9. It also shows the DFA states very clearly so you can choose accept states easily. This should make converting regexes into DFA form way cleaner. -->

Expand Down
2 changes: 1 addition & 1 deletion packages/circom/tests/simple_regex.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe("Simple Regex", () => {
for (let idx = 0; idx < 64; ++idx) {
if (revealedIdx[substr_idx].includes(idx)) {
expect(BigInt(paddedStr[idx])).toEqual(
witness[2 + 64 * substr_idx + idx]
witness[2 + 64 * substr_idx + idx]
);
} else {
expect(0n).toEqual(witness[2 + 64 * substr_idx + idx]);
Expand Down
2 changes: 2 additions & 0 deletions packages/compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ regex = "=1.10.6"
getrandom = { version = "0.2", features = ["js"] }
wasm-bindgen = "0.2"
serde-wasm-bindgen = "0.6.5"
comptime = { git = "https://github.com/jp4g/sparse_array", branch = "feat/comptime-codegen" }
# comptime = { path = "../../../../aztec/sparse_array/comptime" }
20 changes: 18 additions & 2 deletions packages/compiler/src/bin/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,28 +60,36 @@ enum Commands {
Decomposed {
#[arg(short, long)]
decomposed_regex_path: String,
#[arg(short, long)]
#[arg(long)]
halo2_dir_path: Option<String>,
#[arg(short, long)]
circom_file_path: Option<String>,
#[arg(short, long)]
template_name: Option<String>,
#[arg(long)]
noir_file_path: Option<String>,
#[arg(short, long)]
gen_substrs: Option<bool>,
#[arg(short, long)]
sparse_array: Option<bool>,
},
Raw {
#[arg(short, long)]
raw_regex: String,
#[arg(short, long)]
substrs_json_path: Option<String>,
#[arg(short, long)]
#[arg(long)]
halo2_dir_path: Option<String>,
#[arg(short, long)]
circom_file_path: Option<String>,
#[arg(short, long)]
template_name: Option<String>,
#[arg(long)]
noir_file_path: Option<String>,
#[arg(short, long)]
gen_substrs: Option<bool>,
#[arg(short, long)]
sparse_array: Option<bool>,
},
}

Expand All @@ -99,15 +107,19 @@ fn process_decomposed(cli: Cli) {
halo2_dir_path,
circom_file_path,
template_name,
noir_file_path,
gen_substrs,
sparse_array,
} = cli.command
{
if let Err(e) = gen_from_decomposed(
&decomposed_regex_path,
halo2_dir_path.as_deref(),
circom_file_path.as_deref(),
template_name.as_deref(),
noir_file_path.as_deref(),
gen_substrs,
sparse_array
) {
eprintln!("Error: {}", e);
std::process::exit(1);
Expand All @@ -122,7 +134,9 @@ fn process_raw(cli: Cli) {
halo2_dir_path,
circom_file_path,
template_name,
noir_file_path,
gen_substrs,
sparse_array,
} = cli.command
{
if let Err(e) = gen_from_raw(
Expand All @@ -131,7 +145,9 @@ fn process_raw(cli: Cli) {
halo2_dir_path.as_deref(),
circom_file_path.as_deref(),
template_name.as_deref(),
noir_file_path.as_deref(),
gen_substrs,
sparse_array
) {
eprintln!("Error: {}", e);
std::process::exit(1);
Expand Down
20 changes: 19 additions & 1 deletion packages/compiler/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
mod circom;
mod errors;
mod halo2;
mod noir;
mod regex;
mod structs;
mod wasm;


use circom::gen_circom_template;
use errors::CompilerError;
use halo2::gen_halo2_tables;
use itertools::Itertools;
use noir::gen_noir_fn;
use regex::{create_regex_and_dfa_from_str_and_defs, get_regex_and_dfa};
use std::{fs::File, path::PathBuf};
use structs::{DecomposedRegexConfig, RegexAndDFA, SubstringDefinitionsJson};
Expand Down Expand Up @@ -46,6 +49,7 @@ fn load_substring_definitions_json(
/// * `circom_template_name` - An optional name for the Circom template.
/// * `num_public_parts` - The number of public parts in the regex.
/// * `gen_substrs` - A boolean indicating whether to generate substrings.
/// * `sparse_array` - A boolean indicating whether to use a sparse array for the DFA. (TEST UTILITY)
///
/// # Returns
///
Expand All @@ -55,8 +59,10 @@ fn generate_outputs(
halo2_dir_path: Option<&str>,
circom_file_path: Option<&str>,
circom_template_name: Option<&str>,
noir_file_path: Option<&str>,
num_public_parts: usize,
gen_substrs: bool,
sparse_array: Option<bool>
) -> Result<(), CompilerError> {
if let Some(halo2_dir_path) = halo2_dir_path {
let halo2_dir_path = PathBuf::from(halo2_dir_path);
Expand Down Expand Up @@ -86,6 +92,10 @@ fn generate_outputs(
)?;
}

if let Some(noir_file_path) = noir_file_path {
gen_noir_fn(regex_and_dfa, &PathBuf::from(noir_file_path), gen_substrs, sparse_array)?;
}

Ok(())
}

Expand All @@ -107,7 +117,9 @@ pub fn gen_from_decomposed(
halo2_dir_path: Option<&str>,
circom_file_path: Option<&str>,
circom_template_name: Option<&str>,
noir_file_path: Option<&str>,
gen_substrs: Option<bool>,
sparse_array: Option<bool>
) -> Result<(), CompilerError> {
let mut decomposed_regex_config: DecomposedRegexConfig =
serde_json::from_reader(File::open(decomposed_regex_path)?)?;
Expand All @@ -126,8 +138,10 @@ pub fn gen_from_decomposed(
halo2_dir_path,
circom_file_path,
circom_template_name,
noir_file_path,
num_public_parts,
gen_substrs,
sparse_array
)?;

Ok(())
Expand All @@ -153,22 +167,26 @@ pub fn gen_from_raw(
halo2_dir_path: Option<&str>,
circom_file_path: Option<&str>,
template_name: Option<&str>,
noir_file_path: Option<&str>,
gen_substrs: Option<bool>,
sparse_array: Option<bool>
) -> Result<(), CompilerError> {
let substrs_defs_json = load_substring_definitions_json(substrs_json_path)?;
let num_public_parts = substrs_defs_json.transitions.len();

let regex_and_dfa = create_regex_and_dfa_from_str_and_defs(raw_regex, substrs_defs_json)?;

let gen_substrs = gen_substrs.unwrap_or(true);
let gen_substrs = gen_substrs.unwrap_or(false);

generate_outputs(
&regex_and_dfa,
halo2_dir_path,
circom_file_path,
template_name,
noir_file_path,
num_public_parts,
gen_substrs,
sparse_array
)?;

Ok(())
Expand Down
Loading