mirror of
https://github.com/zkemail/zk-regex.git
synced 2026-01-09 13:48:00 -05:00
Merge pull request #86 from zkemail/dimidumo/zk-1138-zk-regex-dfa-check
Dimidumo/zk 1138 zk regex dfa check
This commit is contained in:
@@ -27,3 +27,4 @@ wasm-bindgen = "0.2"
|
||||
serde-wasm-bindgen = "0.6.5"
|
||||
js-sys = "0.3.69"
|
||||
wasm-bindgen-test = "0.3.42"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
use crate::extract_substrs::*;
|
||||
use crate::*;
|
||||
use console_error_panic_hook;
|
||||
use js_sys::Array;
|
||||
use serde_json::Value;
|
||||
use std::panic;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn init_panic_hook() {
|
||||
panic::set_hook(Box::new(console_error_panic_hook::hook));
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn padString(str: &str, paddedBytesSize: usize) -> Array {
|
||||
|
||||
3474
packages/circom/pnpm-lock.yaml
generated
Normal file
3474
packages/circom/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -36,3 +36,4 @@ regex = "=1.10.6"
|
||||
getrandom = { version = "0.2", features = ["js"] }
|
||||
wasm-bindgen = "0.2"
|
||||
serde-wasm-bindgen = "0.6.5"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
|
||||
@@ -22,17 +22,17 @@ use std::{
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A tuple containing:
|
||||
/// A Result tuple containing:
|
||||
/// * The reverse graph as a `BTreeMap<usize, BTreeMap<usize, Vec<u8>>>`.
|
||||
/// * A `BTreeSet<usize>` of accepting state IDs.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns a `CompilerError::NoAcceptedState` if no accepting states are found.
|
||||
/// Returns a `CompilerError::AcceptNodesError` if no accepting states are found.
|
||||
fn build_reverse_graph(
|
||||
state_len: usize,
|
||||
dfa_graph: &DFAGraph,
|
||||
) -> (BTreeMap<usize, BTreeMap<usize, Vec<u8>>>, BTreeSet<usize>) {
|
||||
) -> Result<(BTreeMap<usize, BTreeMap<usize, Vec<u8>>>, BTreeSet<usize>), CompilerError> {
|
||||
let mut rev_graph = BTreeMap::<usize, BTreeMap<usize, Vec<u8>>>::new();
|
||||
let mut accept_nodes = BTreeSet::<usize>::new();
|
||||
|
||||
@@ -52,10 +52,12 @@ fn build_reverse_graph(
|
||||
}
|
||||
|
||||
if accept_nodes.is_empty() {
|
||||
panic!("Accept node must exist");
|
||||
return Err(CompilerError::AcceptNodesError(
|
||||
"Accept node must exist".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
(rev_graph, accept_nodes)
|
||||
Ok((rev_graph, accept_nodes))
|
||||
}
|
||||
|
||||
/// Optimizes character ranges by grouping consecutive characters and identifying individual characters.
|
||||
@@ -659,20 +661,25 @@ fn generate_init_code(state_len: usize) -> Vec<String> {
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A Vec of Strings containing the generated acceptance logic code.
|
||||
/// A Result Vec of Strings containing the generated acceptance logic code.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if there are no accept nodes or if there is more than one accept node.
|
||||
fn generate_accept_logic(accept_nodes: BTreeSet<usize>, end_anchor: bool) -> Vec<String> {
|
||||
/// Returns error if there are no accept nodes or if there is more than one accept node.
|
||||
fn generate_accept_logic(
|
||||
accept_nodes: BTreeSet<usize>,
|
||||
end_anchor: bool,
|
||||
) -> Result<Vec<String>, CompilerError> {
|
||||
let mut accept_lines = vec![];
|
||||
|
||||
if accept_nodes.is_empty() {
|
||||
panic!("Accept node must exist");
|
||||
return Err(CompilerError::AcceptNodesError(
|
||||
"Accept node must exist".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if accept_nodes.len() != 1 {
|
||||
panic!("The size of accept nodes must be one");
|
||||
return Err(CompilerError::AcceptNodesError(
|
||||
"The size of accept nodes must be one".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let accept_node = *accept_nodes.iter().next().unwrap();
|
||||
@@ -704,7 +711,7 @@ fn generate_accept_logic(accept_nodes: BTreeSet<usize>, end_anchor: bool) -> Vec
|
||||
accept_lines.push("\tout <== is_accepted.out;".to_string());
|
||||
}
|
||||
|
||||
accept_lines
|
||||
Ok(accept_lines)
|
||||
}
|
||||
|
||||
/// Generates the complete Circom circuit as a string.
|
||||
@@ -727,10 +734,10 @@ fn gen_circom_allstr(
|
||||
template_name: &str,
|
||||
regex_str: &str,
|
||||
end_anchor: bool,
|
||||
) -> String {
|
||||
) -> Result<String, CompilerError> {
|
||||
let state_len = dfa_graph.states.len();
|
||||
|
||||
let (rev_graph, accept_nodes) = build_reverse_graph(state_len, dfa_graph);
|
||||
let (rev_graph, accept_nodes) = build_reverse_graph(state_len, dfa_graph)?;
|
||||
|
||||
let (eq_i, lt_i, and_i, multi_or_i, lines) =
|
||||
generate_state_transition_logic(&rev_graph, state_len, end_anchor);
|
||||
@@ -748,11 +755,11 @@ fn gen_circom_allstr(
|
||||
|
||||
let init_code = generate_init_code(state_len);
|
||||
|
||||
let accept_lines = generate_accept_logic(accept_nodes, end_anchor);
|
||||
let accept_lines = generate_accept_logic(accept_nodes, end_anchor)?;
|
||||
|
||||
let final_code = [declarations, init_code, lines, accept_lines].concat();
|
||||
|
||||
final_code.join("\n")
|
||||
Ok(final_code.join("\n"))
|
||||
}
|
||||
|
||||
/// Writes the consecutive logic for the Circom circuit.
|
||||
@@ -965,7 +972,7 @@ pub(crate) fn gen_circom_template(
|
||||
template_name,
|
||||
®ex_and_dfa.regex_pattern,
|
||||
regex_and_dfa.has_end_anchor,
|
||||
);
|
||||
)?;
|
||||
|
||||
let mut file = File::create(circom_path)?;
|
||||
file.write_all(circom.as_bytes())?;
|
||||
@@ -1000,7 +1007,7 @@ pub(crate) fn gen_circom_string(
|
||||
template_name,
|
||||
®ex_and_dfa.regex_pattern,
|
||||
regex_and_dfa.has_end_anchor,
|
||||
);
|
||||
)?;
|
||||
let substrs = add_substrs_constraints(regex_and_dfa)?;
|
||||
let result = circom + &substrs;
|
||||
Ok(result)
|
||||
|
||||
@@ -24,4 +24,6 @@ pub enum CompilerError {
|
||||
GraphError(String),
|
||||
#[error("No accepted state found in DFA")]
|
||||
NoAcceptedState,
|
||||
#[error("Accept Nodes Error: {0}")]
|
||||
AcceptNodesError(String),
|
||||
}
|
||||
|
||||
@@ -215,3 +215,6 @@ pub fn gen_circom_from_decomposed_regex(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub use crate::wasm::*;
|
||||
|
||||
@@ -1,17 +1,36 @@
|
||||
use crate::*;
|
||||
use console_error_panic_hook;
|
||||
use serde_wasm_bindgen::from_value;
|
||||
use std::panic;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use self::circom::gen_circom_string;
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn init_panic_hook() {
|
||||
panic::set_hook(Box::new(console_error_panic_hook::hook));
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn genFromDecomposed(decomposedRegexJson: &str, circomTemplateName: &str) -> String {
|
||||
pub fn genFromDecomposed(
|
||||
decomposedRegexJson: &str,
|
||||
circomTemplateName: &str,
|
||||
) -> Result<String, JsValue> {
|
||||
let mut decomposed_regex_config: DecomposedRegexConfig =
|
||||
serde_json::from_str(decomposedRegexJson).expect("failed to parse decomposed_regex json");
|
||||
let regex_and_dfa = get_regex_and_dfa(&mut decomposed_regex_config)
|
||||
.expect("failed to convert the decomposed regex to dfa");
|
||||
gen_circom_string(®ex_and_dfa, circomTemplateName).expect("failed to generate circom")
|
||||
serde_json::from_str(decomposedRegexJson).map_err(|e| {
|
||||
JsValue::from_str(&format!("failed to parse decomposed_regex json: {}", e))
|
||||
})?;
|
||||
|
||||
let regex_and_dfa = get_regex_and_dfa(&mut decomposed_regex_config).map_err(|e| {
|
||||
JsValue::from_str(&format!(
|
||||
"failed to convert the decomposed regex to dfa: {}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
|
||||
gen_circom_string(®ex_and_dfa, circomTemplateName)
|
||||
.map_err(|e| JsValue::from_str(&format!("Failed to generate Circom string: {}", e)))
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
|
||||
Reference in New Issue
Block a user