Skip to content

Commit

Permalink
Fix: handle $
Browse files Browse the repository at this point in the history
  • Loading branch information
Bisht13 committed May 17, 2024
1 parent 6f2a5d0 commit 6aac440
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 16 deletions.
42 changes: 31 additions & 11 deletions packages/compiler/src/circom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ use std::fs::File;
use std::io::Write;
use std::path::PathBuf;

fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str) -> String {
fn gen_circom_allstr(
dfa_graph: &DFAGraph,
template_name: &str,
regex_str: &str,
end_anchor: bool,
) -> String {
let n = dfa_graph.states.len();
let mut rev_graph = BTreeMap::<usize, BTreeMap<usize, Vec<u8>>>::new();
let mut to_init_graph = vec![];
Expand Down Expand Up @@ -104,7 +109,10 @@ fn gen_circom_allstr(dfa_graph: &DFAGraph, template_name: &str, regex_str: &str)
lines.push("\tfor (var i = 0; i < num_bytes; i++) {".to_string());
lines.push(format!("\t\tstate_changed[i] = MultiOR({});", n - 1));
lines.push(format!("\t\tstates[i][0] <== 1;"));
assert!(rev_graph.get(&0).unwrap().len() == 0, "state transition to the 0-th state is not allowed");
assert!(
rev_graph.get(&0).unwrap().len() == 0,
"state transition to the 0-th state is not allowed"
);
for i in 1..n {
let mut outputs = vec![];
zero_starting_and_idxes.insert(i, vec![]);
Expand Down Expand Up @@ -442,7 +450,12 @@ impl RegexAndDFA {
template_name: &str,
gen_substrs: bool,
) -> Result<(), CompilerError> {
let circom = gen_circom_allstr(&self.dfa_val, template_name, &self.regex_str);
let circom = gen_circom_allstr(
&self.dfa_val,
template_name,
&self.regex_str,
self.end_anchor,
);
let mut circom_file = File::create(circom_path)?;
write!(circom_file, "{}", circom)?;
if gen_substrs {
Expand All @@ -454,7 +467,12 @@ impl RegexAndDFA {
}

pub fn gen_circom_str(&self, template_name: &str) -> Result<String, CompilerError> {
let circom = gen_circom_allstr(&self.dfa_val, template_name, &self.regex_str);
let circom = gen_circom_allstr(
&self.dfa_val,
template_name,
&self.regex_str,
self.end_anchor,
);
let substrs = self.add_substrs_constraints()?;
let result = circom + &substrs;
Ok(result)
Expand All @@ -479,7 +497,7 @@ impl RegexAndDFA {
);
for (idx, defs) in substr_defs_array.into_iter().enumerate() {
let num_defs = defs.len();
circom += &format!("\tsignal prev_states{}[{}][msg_bytes];\n", idx,defs.len());
circom += &format!("\tsignal prev_states{}[{}][msg_bytes];\n", idx, defs.len());
circom += &format!("\tsignal is_substr{}[msg_bytes];\n", idx);
circom += &format!("\tsignal is_reveal{}[msg_bytes];\n", idx);
circom += &format!("\tsignal output reveal{}[msg_bytes];\n", idx);
Expand All @@ -496,13 +514,11 @@ impl RegexAndDFA {
}
});
circom += &format!("\t\t // the {}-th substring transitions: {:?}\n", idx, defs);
for (trans_idx, (cur,_)) in defs.iter().enumerate() {
for (trans_idx, (cur, _)) in defs.iter().enumerate() {
if *cur == 0 {
circom += &format!(
"\t\tprev_states{}[{}][i] <== from_zero_enabled[i+1] * states[i+1][{}];\n",
idx,
trans_idx,
cur
idx, trans_idx, cur
);
} else {
circom += &format!(
Expand All @@ -517,8 +533,12 @@ impl RegexAndDFA {
"\t\tis_substr{}[i] <== MultiOR({})([{}]);\n",
idx,
num_defs,
defs.iter().enumerate()
.map(|(trans_idx, (_, next))| format!("prev_states{}[{}][i] * states[i+2][{}]", idx, trans_idx, next))
defs.iter()
.enumerate()
.map(|(trans_idx, (_, next))| format!(
"prev_states{}[{}][i] * states[i+2][{}]",
idx, trans_idx, next
))
.collect::<Vec<_>>()
.join(", ")
);
Expand Down
2 changes: 2 additions & 0 deletions packages/compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ pub struct RegexAndDFA {
// Original regex string, only here to be printed in generated file to make it more reproducible
pub regex_str: String,
pub dfa_val: DFAGraph,
pub end_anchor: bool,
pub substrs_defs: SubstrsDefs,
}

Expand Down Expand Up @@ -116,6 +117,7 @@ impl RegexAndDFA {
// max_byte_size,
regex_str: regex_str.to_string(),
dfa_val,
end_anchor: regex_str.ends_with('$'),
substrs_defs,
})
}
Expand Down
40 changes: 35 additions & 5 deletions packages/compiler/src/regex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ pub fn regex_and_dfa(decomposed_regex: &mut DecomposedRegexConfig) -> RegexAndDF

let mut net_dfa = DFAGraph { states: Vec::new() };
let mut substr_defs_array = Vec::new();

let caret_regex_index = {
let first_regex = decomposed_regex.parts[0].regex_def.as_bytes();
let mut is_in_parenthesis = false;
Expand Down Expand Up @@ -305,10 +305,32 @@ pub fn regex_and_dfa(decomposed_regex: &mut DecomposedRegexConfig) -> RegexAndDF
is_public: false,
regex_def: caret_regex,
});
decomposed_regex.parts[1].regex_def = decomposed_regex.parts[1].regex_def[index..].to_string();
decomposed_regex.parts[1].regex_def =
decomposed_regex.parts[1].regex_def[index..].to_string();
}

let mut end_anchor = false;

for (idx, regex) in decomposed_regex.parts.iter().enumerate() {
end_anchor = match decomposed_regex.parts.len() {
1 => regex.regex_def.ends_with("$"),
2 => {
if idx == 0 && regex.regex_def.ends_with("$") {
panic!("Invalid regex");
}
idx == 1 && regex.regex_def.ends_with("$")
}
_ => match idx {
0 | _ if idx == decomposed_regex.parts.len() - 1 => {
if regex.regex_def.ends_with("$") {
if idx == 0 {
panic!("Invalid regex");
}
true
}
}
},
};
let re = DFA::builder()
.configure(config.clone())
.build(&format!(r"^({})$", regex.regex_def.as_str()))
Expand All @@ -329,16 +351,23 @@ pub fn regex_and_dfa(decomposed_regex: &mut DecomposedRegexConfig) -> RegexAndDF
r#type: "accept".to_string(),
edges: BTreeMap::new(),
state: 1,
}
},
],
}
} else {
graph.states[0].r#type = "".to_string();
let accepted_state = graph.states.iter().find(|state| state.r#type == "accept").unwrap().clone();
let accepted_state = graph
.states
.iter()
.find(|state| state.r#type == "accept")
.unwrap()
.clone();
if let Some(edge) = graph.states[0].edges.get_mut(&accepted_state.state) {
edge.insert(255u8);
} else {
graph.states[0].edges.insert(accepted_state.state, BTreeSet::from([255u8]));
graph.states[0]
.edges
.insert(accepted_state.state, BTreeSet::from([255u8]));
}
}
}
Expand Down Expand Up @@ -406,6 +435,7 @@ pub fn regex_and_dfa(decomposed_regex: &mut DecomposedRegexConfig) -> RegexAndDF
RegexAndDFA {
regex_str: regex_str,
dfa_val: net_dfa,
end_anchor,
substrs_defs: SubstrsDefs {
substr_defs_array: substr_defs_array,
substr_endpoints_array: None,
Expand Down

0 comments on commit 6aac440

Please sign in to comment.