66from pathlib import Path
77from zkregex_fuzzer .logger import logger
88from zkregex_fuzzer .runner .base_runner import Runner , RegexCompileError , RegexRunError
9-
10- class ZkRegexSubprocess :
11-
12- @classmethod
13- def get_installed_version (cls ) -> str :
14- """
15- Get the installed version of zk-regex.
16- """
17- if shutil .which ("zk-regex" ):
18- cmd = ["zk-regex" , "--version" ]
19- result = subprocess .run (cmd , capture_output = True , text = True )
20- return result .stdout .strip ()
21- else :
22- raise ValueError ("zk-regex is not installed" )
23-
24- @classmethod
25- def compile (cls , json_file_path : str , output_file_path : str , template_name : str = "TestRegex" , substr = True ):
26- """
27- Compile a regex using zk-regex.
28- """
29- cmd = [
30- "zk-regex" , "decomposed" ,
31- "-d" , json_file_path ,
32- "-c" , output_file_path ,
33- "-t" , template_name ,
34- "-g" , "true" if substr else "false"
35- ]
36- result = subprocess .run (cmd , capture_output = True , text = True )
37-
38- if result .returncode != 0 :
39- raise RegexCompileError (f"Error compiling with zk-regex: { result .stderr } " )
40-
41- class CircomSubprocess :
42-
43- @classmethod
44- def get_installed_version (cls ) -> str :
45- """
46- Get the installed version of Circom.
47- """
48- if shutil .which ("circom" ):
49- cmd = ["circom" , "--version" ]
50- result = subprocess .run (cmd , capture_output = True , text = True )
51- return result .stdout .strip ()
52- else :
53- raise ValueError ("Circom is not installed" )
54-
55- @classmethod
56- def compile (cls , circom_file_path : str , link_path : list [str ]) -> tuple [str , str ]:
57- """
58- Compile a circom file to r1cs and wasm.
59- """
60-
61- base_name = Path (circom_file_path ).stem
62- base_dir = Path (circom_file_path ).parent
63-
64- cmd = [
65- "circom" , circom_file_path , "--wasm" , "--r1cs" , "-o" , str (base_dir )
66- ]
67- for path in link_path :
68- cmd .append ("-l" )
69- cmd .append (path )
70-
71- logger .debug (" " .join (cmd ))
72- result = subprocess .run (cmd , capture_output = True , text = True )
73-
74- if result .returncode != 0 :
75- raise RegexCompileError (f"Error compiling with Circom: { result .stderr } " )
76-
77- r1cs_file_path = base_dir / f"{ base_name } .r1cs"
78- wasm_file_path = base_dir / f"{ base_name } _js/{ base_name } .wasm"
79- return str (wasm_file_path ), str (r1cs_file_path )
80-
81- class SnarkjsSubprocess :
82-
83- @classmethod
84- def get_installed_version (cls ) -> str :
85- """
86- Get the installed version of SnarkJS.
87- """
88- if shutil .which ("snarkjs" ):
89- cmd = ["snarkjs" , "--help" ]
90- result = subprocess .run (cmd , capture_output = True , text = True )
91- return result .stdout .split ('\n ' )[0 ]
92- else :
93- raise ValueError ("SnarkJS is not installed" )
94-
95- @classmethod
96- def setup_zkey (cls , circuit_path : str , ptau_path : str ) -> str :
97- """
98- Setup the circuit with the powers of tau.
99- """
100-
101- base_name = Path (circuit_path ).stem
102- output_path = str (Path (circuit_path ).parent / f"{ base_name } .zkey" )
103-
104- cmd = [
105- "snarkjs" , "groth16" , "setup" ,
106- circuit_path ,
107- ptau_path ,
108- output_path
109- ]
110- result = subprocess .run (cmd , capture_output = True , text = True )
111-
112- if result .returncode != 0 :
113- raise RegexRunError (f"Error running with SnarkJS: { result .stderr } " )
114-
115- return str (output_path )
116-
117- @classmethod
118- def export_verification_key (cls , zkey_path : str ) -> str :
119- """
120- Export the verification key from the zkey.
121- """
122-
123- base_name = Path (zkey_path ).stem
124- output_path = str (Path (zkey_path ).parent / f"{ base_name } .vkey.json" )
125-
126- cmd = [
127- "snarkjs" , "zkey" , "export" , "verificationkey" ,
128- zkey_path ,
129- output_path
130- ]
131- result = subprocess .run (cmd , capture_output = True , text = True )
132-
133- if result .returncode != 0 :
134- raise RegexRunError (f"Error running with SnarkJS: { result .stdout } " )
135-
136- return str (output_path )
137-
138- @classmethod
139- def witness_gen (cls , wasm_file_path : str , input_path : str ) -> str :
140- """
141- Generate a witness for the wasm file.
142- """
143-
144- base_name = Path (wasm_file_path ).stem
145- output_path = str (Path (input_path ).parent / f"{ base_name } .wtns" )
146-
147- cmd = [
148- "snarkjs" , "wtns" , "calculate" ,
149- wasm_file_path ,
150- input_path ,
151- output_path
152- ]
153- result = subprocess .run (cmd , capture_output = True , text = True )
154-
155- logger .debug (" " .join (cmd ))
156- if result .returncode != 0 :
157- raise RegexRunError (f"Error running with SnarkJS: { result .stdout } " )
158-
159- return str (output_path )
160-
161- @classmethod
162- def prove (cls , zkey_path : str , witness_path : str ) -> tuple [str , str ]:
163- """
164- geenrate proof from the witness with the zkey.
165- """
166-
167- base_name = Path (zkey_path ).stem
168- proof_path = str (Path (witness_path ).parent / f"{ base_name } .proof.json" )
169- public_input_path = str (Path (witness_path ).parent / f"{ base_name } .public.json" )
170-
171- cmd = [
172- "snarkjs" , "groth16" , "prove" ,
173- zkey_path ,
174- witness_path ,
175- proof_path ,
176- public_input_path
177- ]
178- result = subprocess .run (cmd , capture_output = True , text = True )
179-
180- if result .returncode != 0 :
181- raise RegexRunError (f"Error running with SnarkJS: { result .stdout } " )
182-
183- return proof_path , public_input_path
184-
185- @classmethod
186- def verify (cls , vkey_path : str , proof_path : str , public_input_path : str ) -> bool :
187- """
188- Verify the proof with the verification key.
189- """
190-
191- cmd = [
192- "snarkjs" , "groth16" , "verify" ,
193- vkey_path ,
194- public_input_path ,
195- proof_path ,
196- ]
197- result = subprocess .run (cmd , capture_output = True , text = True )
198-
199- if result .returncode != 0 :
200- raise RegexRunError (f"Error running with SnarkJS: { result .stdout } " )
201-
202- return "OK" in result .stdout
203-
204- @classmethod
205- def extract_witness (cls , witness_path : str ) -> dict :
206- """
207- Extract the witness from the witness file.
208- """
209-
210- base_name = Path (witness_path ).stem
211- output_path = str (Path (witness_path ).parent / f"{ base_name } .json" )
212-
213- cmd = [
214- "snarkjs" , "wtns" , "export" , "json" ,
215- witness_path ,
216- output_path ,
217- ]
218- result = subprocess .run (cmd , capture_output = True , text = True )
219-
220- logger .debug (" " .join (cmd ))
221- if result .returncode != 0 :
222- logger .debug (result .stdout )
223- raise RegexRunError (f"Error running with SnarkJS: { result .stdout } " )
224-
225- json_result = json .loads (open (output_path , 'r' ).read ())
226- Path (output_path ).unlink ()
227-
228- return json_result
229-
9+ from zkregex_fuzzer .runner .subprocess import ZkRegexSubprocess , CircomSubprocess , SnarkjsSubprocess
23010
23111class CircomRunner (Runner ):
23212 """
@@ -244,7 +24,7 @@ def __init__(self, regex: str, kwargs: dict):
24424 self ._run_the_prover = kwargs .get ("circom_prove" , False )
24525 self ._ptau_path = kwargs .get ("circom_ptau" , None )
24626 self ._link_path = kwargs .get ("circom_library" , [])
247- self ._circom_max_input_size = kwargs .get ("circom_max_input_size " , 200 )
27+ self ._circom_max_input_size = kwargs .get ("max_input_size " , 200 )
24828 self ._template_name = "TestRegex"
24929 super ().__init__ (regex , kwargs )
25030 self ._runner = "Circom"
@@ -274,7 +54,7 @@ def compile(self, regex: str) -> None:
27454
27555 # Call zk-regex to generate the circom code
27656 logger .debug (f"Generating circom code starts" )
277- ZkRegexSubprocess .compile (json_file_path , circom_file_path , self ._template_name )
57+ ZkRegexSubprocess .compile_to_circom (json_file_path , circom_file_path , self ._template_name )
27858 logger .debug (f"Generating circom code ends" )
27959
28060 # Append the circom file to include the main function
0 commit comments