JSTprove 1.0.0__py3-none-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of JSTprove might be problematic. Click here for more details.
- jstprove-1.0.0.dist-info/METADATA +397 -0
- jstprove-1.0.0.dist-info/RECORD +81 -0
- jstprove-1.0.0.dist-info/WHEEL +5 -0
- jstprove-1.0.0.dist-info/entry_points.txt +2 -0
- jstprove-1.0.0.dist-info/licenses/LICENSE +26 -0
- jstprove-1.0.0.dist-info/top_level.txt +1 -0
- python/__init__.py +0 -0
- python/core/__init__.py +3 -0
- python/core/binaries/__init__.py +0 -0
- python/core/binaries/expander-exec +0 -0
- python/core/binaries/onnx_generic_circuit_1-0-0 +0 -0
- python/core/circuit_models/__init__.py +0 -0
- python/core/circuit_models/generic_onnx.py +231 -0
- python/core/circuit_models/simple_circuit.py +133 -0
- python/core/circuits/__init__.py +0 -0
- python/core/circuits/base.py +1000 -0
- python/core/circuits/errors.py +188 -0
- python/core/circuits/zk_model_base.py +25 -0
- python/core/model_processing/__init__.py +0 -0
- python/core/model_processing/converters/__init__.py +0 -0
- python/core/model_processing/converters/base.py +143 -0
- python/core/model_processing/converters/onnx_converter.py +1181 -0
- python/core/model_processing/errors.py +147 -0
- python/core/model_processing/onnx_custom_ops/__init__.py +16 -0
- python/core/model_processing/onnx_custom_ops/conv.py +111 -0
- python/core/model_processing/onnx_custom_ops/custom_helpers.py +56 -0
- python/core/model_processing/onnx_custom_ops/gemm.py +91 -0
- python/core/model_processing/onnx_custom_ops/maxpool.py +79 -0
- python/core/model_processing/onnx_custom_ops/onnx_helpers.py +173 -0
- python/core/model_processing/onnx_custom_ops/relu.py +43 -0
- python/core/model_processing/onnx_quantizer/__init__.py +0 -0
- python/core/model_processing/onnx_quantizer/exceptions.py +168 -0
- python/core/model_processing/onnx_quantizer/layers/__init__.py +0 -0
- python/core/model_processing/onnx_quantizer/layers/base.py +396 -0
- python/core/model_processing/onnx_quantizer/layers/constant.py +118 -0
- python/core/model_processing/onnx_quantizer/layers/conv.py +180 -0
- python/core/model_processing/onnx_quantizer/layers/gemm.py +171 -0
- python/core/model_processing/onnx_quantizer/layers/maxpool.py +140 -0
- python/core/model_processing/onnx_quantizer/layers/relu.py +76 -0
- python/core/model_processing/onnx_quantizer/onnx_op_quantizer.py +200 -0
- python/core/model_templates/__init__.py +0 -0
- python/core/model_templates/circuit_template.py +57 -0
- python/core/utils/__init__.py +0 -0
- python/core/utils/benchmarking_helpers.py +163 -0
- python/core/utils/constants.py +4 -0
- python/core/utils/errors.py +117 -0
- python/core/utils/general_layer_functions.py +268 -0
- python/core/utils/helper_functions.py +1138 -0
- python/core/utils/model_registry.py +166 -0
- python/core/utils/scratch_tests.py +66 -0
- python/core/utils/witness_utils.py +291 -0
- python/frontend/__init__.py +0 -0
- python/frontend/cli.py +115 -0
- python/frontend/commands/__init__.py +17 -0
- python/frontend/commands/args.py +100 -0
- python/frontend/commands/base.py +199 -0
- python/frontend/commands/bench/__init__.py +54 -0
- python/frontend/commands/bench/list.py +42 -0
- python/frontend/commands/bench/model.py +172 -0
- python/frontend/commands/bench/sweep.py +212 -0
- python/frontend/commands/compile.py +58 -0
- python/frontend/commands/constants.py +5 -0
- python/frontend/commands/model_check.py +53 -0
- python/frontend/commands/prove.py +50 -0
- python/frontend/commands/verify.py +73 -0
- python/frontend/commands/witness.py +64 -0
- python/scripts/__init__.py +0 -0
- python/scripts/benchmark_runner.py +833 -0
- python/scripts/gen_and_bench.py +482 -0
- python/tests/__init__.py +0 -0
- python/tests/circuit_e2e_tests/__init__.py +0 -0
- python/tests/circuit_e2e_tests/circuit_model_developer_test.py +1158 -0
- python/tests/circuit_e2e_tests/helper_fns_for_tests.py +190 -0
- python/tests/circuit_e2e_tests/other_e2e_test.py +217 -0
- python/tests/circuit_parent_classes/__init__.py +0 -0
- python/tests/circuit_parent_classes/test_circuit.py +969 -0
- python/tests/circuit_parent_classes/test_onnx_converter.py +201 -0
- python/tests/circuit_parent_classes/test_ort_custom_layers.py +116 -0
- python/tests/test_cli.py +1021 -0
- python/tests/utils_testing/__init__.py +0 -0
- python/tests/utils_testing/test_helper_functions.py +891 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from typing import TYPE_CHECKING, ClassVar
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
import argparse
|
|
8
|
+
|
|
9
|
+
from python.core.utils.helper_functions import run_subprocess
|
|
10
|
+
from python.frontend.commands.args import ArgSpec
|
|
11
|
+
from python.frontend.commands.base import BaseCommand
|
|
12
|
+
|
|
13
|
+
SWEEP_CHOICES: tuple[str, ...] = ("depth", "breadth", "lenet")
|
|
14
|
+
|
|
15
|
+
DEPTH_MIN = ArgSpec(
|
|
16
|
+
name="depth_min",
|
|
17
|
+
flag="--depth-min",
|
|
18
|
+
help_text="(depth) minimum conv depth",
|
|
19
|
+
arg_type=int,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
DEPTH_MAX = ArgSpec(
|
|
23
|
+
name="depth_max",
|
|
24
|
+
flag="--depth-max",
|
|
25
|
+
help_text="(depth) maximum conv depth",
|
|
26
|
+
arg_type=int,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
INPUT_HW = ArgSpec(
|
|
30
|
+
name="input_hw",
|
|
31
|
+
flag="--input-hw",
|
|
32
|
+
help_text="(depth) input H=W (e.g., 56)",
|
|
33
|
+
arg_type=int,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
ARCH_DEPTH = ArgSpec(
|
|
37
|
+
name="arch_depth",
|
|
38
|
+
flag="--arch-depth",
|
|
39
|
+
help_text="(breadth) conv blocks at fixed topology",
|
|
40
|
+
arg_type=int,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
INPUT_HW_LIST = ArgSpec(
|
|
44
|
+
name="input_hw_list",
|
|
45
|
+
flag="--input-hw-list",
|
|
46
|
+
help_text="(breadth) sizes like '28,56,84,112' or '32:160:32'",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
ITERATIONS = ArgSpec(
|
|
50
|
+
name="iterations",
|
|
51
|
+
flag="--iterations",
|
|
52
|
+
help_text="E2E loops per model (default 3 in sweeps)",
|
|
53
|
+
arg_type=int,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
RESULTS = ArgSpec(
|
|
57
|
+
name="results",
|
|
58
|
+
flag="--results",
|
|
59
|
+
help_text="Path to JSONL results (e.g., benchmarking/depth_sweep.jsonl)",
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
ONNX_DIR = ArgSpec(
|
|
63
|
+
name="onnx_dir",
|
|
64
|
+
flag="--onnx-dir",
|
|
65
|
+
help_text="Override ONNX output dir (else chosen by sweep)",
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
INPUTS_DIR = ArgSpec(
|
|
69
|
+
name="inputs_dir",
|
|
70
|
+
flag="--inputs-dir",
|
|
71
|
+
help_text="Override inputs output dir (else chosen by sweep)",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
POOL_CAP = ArgSpec(
|
|
75
|
+
name="pool_cap",
|
|
76
|
+
flag="--pool-cap",
|
|
77
|
+
help_text="Max pool blocks at start (Lenet-like: 2)",
|
|
78
|
+
arg_type=int,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
STOP_AT_HW = ArgSpec(
|
|
82
|
+
name="stop_at_hw",
|
|
83
|
+
flag="--stop-at-hw",
|
|
84
|
+
help_text="Allow pooling while H >= this",
|
|
85
|
+
arg_type=int,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
CONV_OUT_CH = ArgSpec(
|
|
89
|
+
name="conv_out_ch",
|
|
90
|
+
flag="--conv-out-ch",
|
|
91
|
+
help_text="Conv output channels",
|
|
92
|
+
arg_type=int,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
FC_HIDDEN = ArgSpec(
|
|
96
|
+
name="fc_hidden",
|
|
97
|
+
flag="--fc-hidden",
|
|
98
|
+
help_text="Fully-connected hidden size",
|
|
99
|
+
arg_type=int,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
N_ACTIONS = ArgSpec(
|
|
103
|
+
name="n_actions",
|
|
104
|
+
flag="--n-actions",
|
|
105
|
+
help_text="Classifier outputs (classes)",
|
|
106
|
+
arg_type=int,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
TAG = ArgSpec(
|
|
110
|
+
name="tag",
|
|
111
|
+
flag="--tag",
|
|
112
|
+
help_text="Optional tag suffix for filenames",
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
MODE = ArgSpec(
|
|
116
|
+
name="mode",
|
|
117
|
+
flag="mode",
|
|
118
|
+
help_text="Sweep type: depth, breadth, or lenet.",
|
|
119
|
+
extra_kwargs={"choices": list(SWEEP_CHOICES)},
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class SweepCommand(BaseCommand):
|
|
124
|
+
"""Generate ONNX models and benchmark parameter sweeps (depth/breadth)."""
|
|
125
|
+
|
|
126
|
+
name: ClassVar[str] = "sweep"
|
|
127
|
+
aliases: ClassVar[list[str]] = []
|
|
128
|
+
help: ClassVar[str] = (
|
|
129
|
+
"Generate ONNX models and benchmark parameter sweeps (depth/breadth)."
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
SCRIPT_GEN_AND_BENCH: ClassVar[str] = "python.scripts.gen_and_bench"
|
|
133
|
+
|
|
134
|
+
DEPTH_DEFAULTS: ClassVar[tuple[tuple[ArgSpec, str], ...]] = (
|
|
135
|
+
(DEPTH_MIN, "1"),
|
|
136
|
+
(DEPTH_MAX, "16"),
|
|
137
|
+
(ITERATIONS, "3"),
|
|
138
|
+
(RESULTS, "benchmarking/depth_sweep.jsonl"),
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
BREADTH_DEFAULTS: ClassVar[tuple[tuple[ArgSpec, str], ...]] = (
|
|
142
|
+
(ARCH_DEPTH, "5"),
|
|
143
|
+
(INPUT_HW_LIST, "28,56,84,112"),
|
|
144
|
+
(ITERATIONS, "3"),
|
|
145
|
+
(RESULTS, "benchmarking/breadth_sweep.jsonl"),
|
|
146
|
+
(POOL_CAP, "2"),
|
|
147
|
+
(CONV_OUT_CH, "16"),
|
|
148
|
+
(FC_HIDDEN, "256"),
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
SWEEP_CONFIGS: ClassVar[dict[str, tuple[tuple[ArgSpec, str], ...]]] = {
|
|
152
|
+
SWEEP_CHOICES[0]: DEPTH_DEFAULTS,
|
|
153
|
+
SWEEP_CHOICES[1]: BREADTH_DEFAULTS,
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
SWEEP_ARGS: ClassVar[tuple[ArgSpec, ...]] = (
|
|
157
|
+
DEPTH_MIN,
|
|
158
|
+
DEPTH_MAX,
|
|
159
|
+
INPUT_HW,
|
|
160
|
+
ARCH_DEPTH,
|
|
161
|
+
INPUT_HW_LIST,
|
|
162
|
+
ITERATIONS,
|
|
163
|
+
RESULTS,
|
|
164
|
+
ONNX_DIR,
|
|
165
|
+
INPUTS_DIR,
|
|
166
|
+
POOL_CAP,
|
|
167
|
+
STOP_AT_HW,
|
|
168
|
+
CONV_OUT_CH,
|
|
169
|
+
FC_HIDDEN,
|
|
170
|
+
N_ACTIONS,
|
|
171
|
+
TAG,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
OPTIONAL_SWEEP_ARGS: ClassVar[tuple[ArgSpec, ...]] = (ONNX_DIR, INPUTS_DIR, TAG)
|
|
175
|
+
|
|
176
|
+
@classmethod
|
|
177
|
+
def configure_parser(
|
|
178
|
+
cls: type[SweepCommand],
|
|
179
|
+
parser: argparse.ArgumentParser,
|
|
180
|
+
) -> None:
|
|
181
|
+
MODE.add_to_parser(parser)
|
|
182
|
+
|
|
183
|
+
for arg_spec in cls.SWEEP_ARGS:
|
|
184
|
+
arg_spec.add_to_parser(parser)
|
|
185
|
+
|
|
186
|
+
@classmethod
|
|
187
|
+
def run(cls: type[SweepCommand], args: argparse.Namespace) -> None:
|
|
188
|
+
if not args.mode:
|
|
189
|
+
msg = "Specify sweep type: depth, breadth, or lenet"
|
|
190
|
+
raise ValueError(msg)
|
|
191
|
+
|
|
192
|
+
cls._run_sweep_benchmark(args, args.mode)
|
|
193
|
+
|
|
194
|
+
@classmethod
|
|
195
|
+
def _run_sweep_benchmark(
|
|
196
|
+
cls: type[SweepCommand],
|
|
197
|
+
args: argparse.Namespace,
|
|
198
|
+
sweep: str,
|
|
199
|
+
) -> None:
|
|
200
|
+
provided_knobs = [getattr(args, spec.name, None) for spec in cls.SWEEP_ARGS]
|
|
201
|
+
simple = all(v is None for v in provided_knobs)
|
|
202
|
+
|
|
203
|
+
cmd = [sys.executable, "-m", cls.SCRIPT_GEN_AND_BENCH, "--sweep", sweep]
|
|
204
|
+
|
|
205
|
+
if simple:
|
|
206
|
+
defaults = cls.SWEEP_CONFIGS.get(sweep, ())
|
|
207
|
+
BaseCommand.append_args_from_specs(cmd, defaults)
|
|
208
|
+
BaseCommand.append_args_from_namespace(cmd, args, cls.OPTIONAL_SWEEP_ARGS)
|
|
209
|
+
else:
|
|
210
|
+
BaseCommand.append_args_from_namespace(cmd, args, cls.SWEEP_ARGS)
|
|
211
|
+
|
|
212
|
+
run_subprocess(cmd)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import TYPE_CHECKING, ClassVar
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
import argparse
|
|
8
|
+
|
|
9
|
+
from python.core.circuits.errors import CircuitRunError
|
|
10
|
+
from python.core.utils.helper_functions import CircuitExecutionConfig, RunType
|
|
11
|
+
from python.frontend.commands.args import CIRCUIT_PATH, MODEL_PATH
|
|
12
|
+
from python.frontend.commands.base import BaseCommand
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CompileCommand(BaseCommand):
|
|
16
|
+
"""Compile an ONNX model to a circuit."""
|
|
17
|
+
|
|
18
|
+
name: ClassVar[str] = "compile"
|
|
19
|
+
aliases: ClassVar[list[str]] = ["comp"]
|
|
20
|
+
help: ClassVar[str] = (
|
|
21
|
+
"Compile a circuit (writes circuit + quantized model + weights)."
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def configure_parser(
|
|
26
|
+
cls: type[CompileCommand],
|
|
27
|
+
parser: argparse.ArgumentParser,
|
|
28
|
+
) -> None:
|
|
29
|
+
MODEL_PATH.add_to_parser(parser)
|
|
30
|
+
CIRCUIT_PATH.add_to_parser(
|
|
31
|
+
parser,
|
|
32
|
+
"Output path for the compiled circuit (e.g., circuit.txt).",
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
@BaseCommand.validate_required(MODEL_PATH, CIRCUIT_PATH)
|
|
37
|
+
@BaseCommand.validate_paths(MODEL_PATH)
|
|
38
|
+
@BaseCommand.validate_parent_paths(CIRCUIT_PATH)
|
|
39
|
+
def run(cls: type[CompileCommand], args: argparse.Namespace) -> None:
|
|
40
|
+
model_name_hint = Path(args.model_path).stem
|
|
41
|
+
circuit = cls._build_circuit(model_name_hint)
|
|
42
|
+
|
|
43
|
+
circuit.model_file_name = args.model_path
|
|
44
|
+
circuit.onnx_path = args.model_path
|
|
45
|
+
circuit.model_path = args.model_path
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
circuit.base_testing(
|
|
49
|
+
CircuitExecutionConfig(
|
|
50
|
+
run_type=RunType.COMPILE_CIRCUIT,
|
|
51
|
+
circuit_path=args.circuit_path,
|
|
52
|
+
dev_mode=False,
|
|
53
|
+
),
|
|
54
|
+
)
|
|
55
|
+
except CircuitRunError as e:
|
|
56
|
+
raise RuntimeError(e) from e
|
|
57
|
+
|
|
58
|
+
print(f"[compile] done → circuit={args.circuit_path}") # noqa: T201
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, ClassVar
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
import argparse
|
|
7
|
+
|
|
8
|
+
from python.frontend.commands.args import MODEL_PATH
|
|
9
|
+
from python.frontend.commands.base import BaseCommand
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ModelCheckCommand(BaseCommand):
|
|
13
|
+
"""Check if a model is supported for quantization."""
|
|
14
|
+
|
|
15
|
+
name: ClassVar[str] = "model_check"
|
|
16
|
+
aliases: ClassVar[list[str]] = ["check"]
|
|
17
|
+
help: ClassVar[str] = "Check if the model is supported for quantization."
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def configure_parser(
|
|
21
|
+
cls: type[ModelCheckCommand],
|
|
22
|
+
parser: argparse.ArgumentParser,
|
|
23
|
+
) -> None:
|
|
24
|
+
MODEL_PATH.add_to_parser(parser)
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
@BaseCommand.validate_required(MODEL_PATH)
|
|
28
|
+
@BaseCommand.validate_paths(MODEL_PATH)
|
|
29
|
+
def run(cls: type[ModelCheckCommand], args: argparse.Namespace) -> None:
|
|
30
|
+
import onnx # noqa: PLC0415
|
|
31
|
+
|
|
32
|
+
from python.core.model_processing.onnx_quantizer.exceptions import ( # noqa: PLC0415
|
|
33
|
+
InvalidParamError,
|
|
34
|
+
UnsupportedOpError,
|
|
35
|
+
)
|
|
36
|
+
from python.core.model_processing.onnx_quantizer.onnx_op_quantizer import ( # noqa: PLC0415
|
|
37
|
+
ONNXOpQuantizer,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
model = onnx.load(args.model_path)
|
|
41
|
+
quantizer = ONNXOpQuantizer()
|
|
42
|
+
try:
|
|
43
|
+
quantizer.check_model(model)
|
|
44
|
+
print(f"Model {args.model_path} is supported.") # noqa: T201
|
|
45
|
+
except UnsupportedOpError as e:
|
|
46
|
+
msg = (
|
|
47
|
+
f"Model {args.model_path} is NOT supported: "
|
|
48
|
+
f"Unsupported operations {e.unsupported_ops}"
|
|
49
|
+
)
|
|
50
|
+
raise RuntimeError(msg) from e
|
|
51
|
+
except InvalidParamError as e:
|
|
52
|
+
msg = f"Model {args.model_path} is NOT supported: {e.message}"
|
|
53
|
+
raise RuntimeError(msg) from e
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, ClassVar
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
import argparse
|
|
7
|
+
|
|
8
|
+
from python.core.circuits.errors import CircuitRunError
|
|
9
|
+
from python.core.utils.helper_functions import CircuitExecutionConfig, RunType
|
|
10
|
+
from python.frontend.commands.args import CIRCUIT_PATH, PROOF_PATH, WITNESS_PATH
|
|
11
|
+
from python.frontend.commands.base import BaseCommand
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ProveCommand(BaseCommand):
|
|
15
|
+
"""Generate proof from witness."""
|
|
16
|
+
|
|
17
|
+
name: ClassVar[str] = "prove"
|
|
18
|
+
aliases: ClassVar[list[str]] = ["prov"]
|
|
19
|
+
help: ClassVar[str] = "Generate a proof from a circuit and witness."
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def configure_parser(
|
|
23
|
+
cls: type[ProveCommand],
|
|
24
|
+
parser: argparse.ArgumentParser,
|
|
25
|
+
) -> None:
|
|
26
|
+
CIRCUIT_PATH.add_to_parser(parser)
|
|
27
|
+
WITNESS_PATH.add_to_parser(parser, "Path to an existing witness.")
|
|
28
|
+
PROOF_PATH.add_to_parser(parser)
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
@BaseCommand.validate_required(CIRCUIT_PATH, WITNESS_PATH, PROOF_PATH)
|
|
32
|
+
@BaseCommand.validate_paths(CIRCUIT_PATH, WITNESS_PATH)
|
|
33
|
+
@BaseCommand.validate_parent_paths(PROOF_PATH)
|
|
34
|
+
def run(cls: type[ProveCommand], args: argparse.Namespace) -> None:
|
|
35
|
+
circuit = cls._build_circuit("cli")
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
circuit.base_testing(
|
|
39
|
+
CircuitExecutionConfig(
|
|
40
|
+
run_type=RunType.PROVE_WITNESS,
|
|
41
|
+
circuit_path=args.circuit_path,
|
|
42
|
+
witness_file=args.witness_path,
|
|
43
|
+
proof_file=args.proof_path,
|
|
44
|
+
ecc=False,
|
|
45
|
+
),
|
|
46
|
+
)
|
|
47
|
+
except CircuitRunError as e:
|
|
48
|
+
raise RuntimeError(e) from e
|
|
49
|
+
|
|
50
|
+
print(f"[prove] wrote proof → {args.proof_path}") # noqa: T201
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, ClassVar
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
import argparse
|
|
7
|
+
|
|
8
|
+
from python.core.circuits.errors import CircuitRunError
|
|
9
|
+
from python.core.utils.helper_functions import CircuitExecutionConfig, RunType
|
|
10
|
+
from python.frontend.commands.args import (
|
|
11
|
+
CIRCUIT_PATH,
|
|
12
|
+
INPUT_PATH,
|
|
13
|
+
OUTPUT_PATH,
|
|
14
|
+
PROOF_PATH,
|
|
15
|
+
WITNESS_PATH,
|
|
16
|
+
)
|
|
17
|
+
from python.frontend.commands.base import BaseCommand
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class VerifyCommand(BaseCommand):
|
|
21
|
+
"""Verify a proof."""
|
|
22
|
+
|
|
23
|
+
name: ClassVar[str] = "verify"
|
|
24
|
+
aliases: ClassVar[list[str]] = ["ver"]
|
|
25
|
+
help: ClassVar[str] = "Verify a proof."
|
|
26
|
+
|
|
27
|
+
@classmethod
|
|
28
|
+
def configure_parser(
|
|
29
|
+
cls: type[VerifyCommand],
|
|
30
|
+
parser: argparse.ArgumentParser,
|
|
31
|
+
) -> None:
|
|
32
|
+
CIRCUIT_PATH.add_to_parser(parser)
|
|
33
|
+
INPUT_PATH.add_to_parser(parser)
|
|
34
|
+
OUTPUT_PATH.add_to_parser(parser, "Path to expected outputs JSON.")
|
|
35
|
+
WITNESS_PATH.add_to_parser(parser)
|
|
36
|
+
PROOF_PATH.add_to_parser(parser)
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
@BaseCommand.validate_required(
|
|
40
|
+
CIRCUIT_PATH,
|
|
41
|
+
INPUT_PATH,
|
|
42
|
+
OUTPUT_PATH,
|
|
43
|
+
WITNESS_PATH,
|
|
44
|
+
PROOF_PATH,
|
|
45
|
+
)
|
|
46
|
+
@BaseCommand.validate_paths(
|
|
47
|
+
CIRCUIT_PATH,
|
|
48
|
+
INPUT_PATH,
|
|
49
|
+
OUTPUT_PATH,
|
|
50
|
+
WITNESS_PATH,
|
|
51
|
+
PROOF_PATH,
|
|
52
|
+
)
|
|
53
|
+
def run(cls: type[VerifyCommand], args: argparse.Namespace) -> None:
|
|
54
|
+
circuit = cls._build_circuit("cli")
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
circuit.base_testing(
|
|
58
|
+
CircuitExecutionConfig(
|
|
59
|
+
run_type=RunType.GEN_VERIFY,
|
|
60
|
+
circuit_path=args.circuit_path,
|
|
61
|
+
input_file=args.input_path,
|
|
62
|
+
output_file=args.output_path,
|
|
63
|
+
witness_file=args.witness_path,
|
|
64
|
+
proof_file=args.proof_path,
|
|
65
|
+
ecc=False,
|
|
66
|
+
),
|
|
67
|
+
)
|
|
68
|
+
except CircuitRunError as e:
|
|
69
|
+
raise RuntimeError(e) from e
|
|
70
|
+
|
|
71
|
+
print( # noqa: T201
|
|
72
|
+
f"[verify] verification complete for proof → {args.proof_path}",
|
|
73
|
+
)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, ClassVar
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
import argparse
|
|
7
|
+
|
|
8
|
+
from python.core.circuits.errors import CircuitRunError
|
|
9
|
+
from python.core.utils.helper_functions import CircuitExecutionConfig, RunType
|
|
10
|
+
from python.frontend.commands.args import (
|
|
11
|
+
CIRCUIT_PATH,
|
|
12
|
+
INPUT_PATH,
|
|
13
|
+
OUTPUT_PATH,
|
|
14
|
+
WITNESS_PATH,
|
|
15
|
+
)
|
|
16
|
+
from python.frontend.commands.base import BaseCommand
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class WitnessCommand(BaseCommand):
|
|
20
|
+
"""Generate witness from circuit and inputs."""
|
|
21
|
+
|
|
22
|
+
name: ClassVar[str] = "witness"
|
|
23
|
+
aliases: ClassVar[list[str]] = ["wit"]
|
|
24
|
+
help: ClassVar[str] = "Generate witness using a compiled circuit."
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
def configure_parser(
|
|
28
|
+
cls: type[WitnessCommand],
|
|
29
|
+
parser: argparse.ArgumentParser,
|
|
30
|
+
) -> None:
|
|
31
|
+
CIRCUIT_PATH.add_to_parser(parser)
|
|
32
|
+
INPUT_PATH.add_to_parser(parser)
|
|
33
|
+
OUTPUT_PATH.add_to_parser(parser)
|
|
34
|
+
WITNESS_PATH.add_to_parser(parser)
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
@BaseCommand.validate_required(
|
|
38
|
+
CIRCUIT_PATH,
|
|
39
|
+
INPUT_PATH,
|
|
40
|
+
OUTPUT_PATH,
|
|
41
|
+
WITNESS_PATH,
|
|
42
|
+
)
|
|
43
|
+
@BaseCommand.validate_paths(CIRCUIT_PATH, INPUT_PATH)
|
|
44
|
+
@BaseCommand.validate_parent_paths(OUTPUT_PATH, WITNESS_PATH)
|
|
45
|
+
def run(cls: type[WitnessCommand], args: argparse.Namespace) -> None:
|
|
46
|
+
circuit = cls._build_circuit("cli")
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
circuit.base_testing(
|
|
50
|
+
CircuitExecutionConfig(
|
|
51
|
+
run_type=RunType.GEN_WITNESS,
|
|
52
|
+
circuit_path=args.circuit_path,
|
|
53
|
+
input_file=args.input_path,
|
|
54
|
+
output_file=args.output_path,
|
|
55
|
+
witness_file=args.witness_path,
|
|
56
|
+
),
|
|
57
|
+
)
|
|
58
|
+
except CircuitRunError as e:
|
|
59
|
+
raise RuntimeError(e) from e
|
|
60
|
+
|
|
61
|
+
print( # noqa: T201
|
|
62
|
+
f"[witness] wrote witness → {args.witness_path} "
|
|
63
|
+
f"and outputs → {args.output_path}",
|
|
64
|
+
)
|
|
File without changes
|