Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 62 additions & 0 deletions circuits/benchmarks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Circuit benchmarks

Benchmark the ZK circuits. Configuration is in `config.json` (circuit list, mode, oracles, metrics).

## How to run

From the **benchmarks** directory:

```bash
./run_benchmarks.sh [options]
```

Or from **scripts**:

```bash
./scripts/run_benchmarks.sh [options]
```

Both use `config.json` in the benchmarks directory by default.

### Options

| Option | Description |
| --------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `--mode insecure \| secure` | Run in insecure (default) or secure mode. Overrides `config.json`’s `mode`. |
| `--circuit <path>` | Run only this circuit (e.g. `dkg/pk` or `config`). If not in `config.json`, runs anyway if the path exists. |
| `--config <file>` | Use a different config file instead of `config.json`. |
| `--skip-compile` | Reuse existing build artifacts; skip compilation. |
| `--clean` | Remove circuit `target/` directories after the run. |

### Examples

```bash
# Default: insecure mode, all circuits from config (config circuit is skipped)
./run_benchmarks.sh

# Secure mode (includes the config circuit)
./run_benchmarks.sh --mode secure

# Single circuit
./run_benchmarks.sh --circuit threshold/pk_generation
./run_benchmarks.sh --mode secure --circuit config

# Re-run without recompiling
./run_benchmarks.sh --skip-compile
```

### Results

Output goes under `results_<mode>/` (e.g. `results_insecure/`, `results_secure/`). A Markdown report
is written to `results_<mode>/report.md`. Raw JSON is kept in `results_<mode>/raw/` so that a run
with `--circuit` only overwrites that circuit’s file and the report is regenerated from all data
(existing + updated). View the report with `cat results_<mode>/report.md` or
`open results_<mode>/report.md` (macOS).

## Secure-only circuits

The **config** circuit (validates secure configs only) is listed in `config.json` with
`"modes": ["secure"]` so it is only run in secure mode. With the default `"mode": "insecure"` it is
skipped. The script `scripts/run_benchmarks.sh` respects this by filtering circuits by the `modes`
field in `config.json` before running; see the “Circuit-specific modes” comment and the loop that
builds `RUN_CIRCUITS` there.
2 changes: 1 addition & 1 deletion circuits/benchmarks/config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"circuits": [
"config",
{ "name": "config", "modes": ["secure"] },
"dkg/pk",
"dkg/sk_share_computation",
"dkg/e_sm_share_computation",
Expand Down
43 changes: 27 additions & 16 deletions circuits/benchmarks/scripts/run_benchmarks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ echo "║ Enclave ZK Circuit Benchmark Suite ║"
echo "╚════════════════════════════════════════════════╝"
echo ""

# Read configuration
ALL_CIRCUITS=$(jq -r '.circuits[]' "$CONFIG_FILE")
# Read configuration (circuits may be strings or {name, modes[]}; see config.json)
ALL_CIRCUITS=$(jq -r '.circuits[] | (if type == "string" then . else .name end)' "$CONFIG_FILE")
ORACLES=$(jq -r '.oracles[]' "$CONFIG_FILE")
OUTPUT_DIR_BASE=$(jq -r '.output_dir // "results"' "$CONFIG_FILE")
BIN_DIR=$(jq -r '.bin_dir // "../bin"' "$CONFIG_FILE")
Expand Down Expand Up @@ -130,9 +130,24 @@ echo " Output Directory: ${OUTPUT_DIR}"
echo ""

# decrypted_shares_aggregation_mod is for insecure only (Q < 128bit); _bn is for secure (large Q)
# config validates secure configs only, so run only in secure mode
# Circuit-specific modes come from config.json (e.g. "config" has "modes": ["secure"]); see circuits/benchmarks/config.json
RUN_CIRCUITS=""
for c in $CIRCUITS; do
CIRCUIT_MODES=$(jq -r '.circuits[] | (if type == "string" then . else .name end) as $path | (if type == "object" and (.modes != null) then (.modes | join(",")) else "insecure,secure" end) | "\($path)\t\(.)"' "$CONFIG_FILE")
Comment thread
0xjei marked this conversation as resolved.
while IFS= read -r line; do
[ -z "$line" ] && continue
c="${line%% *}"
modes="${line#* }"
# If --circuit filter is set, we iterate over CIRCUITS (one path) and may not have entry in CIRCUIT_MODES; then run it
if [ -n "$CIRCUIT_FILTER" ]; then
[ "$c" != "$CIRCUIT_FILTER" ] && continue
fi
# Skip if this circuit is restricted to other mode(s) (see config.json "modes" field)
if [ -n "$modes" ] && [ "${modes}" != "insecure,secure" ]; then
if [[ ",${modes}," != *",${MODE},"* ]]; then
echo " Skipping $c (config.json restricts to mode(s): $modes; current mode: $MODE)"
continue
fi
fi
if [ "$MODE" = "secure" ] && [ "$c" = "threshold/decrypted_shares_aggregation_mod" ]; then
echo " Skipping $c (modular variant is insecure-only, Q < 128bit)"
continue
Expand All @@ -141,12 +156,12 @@ for c in $CIRCUITS; do
echo " Skipping $c (BigNum variant is for secure/large Q only)"
continue
fi
if [ "$MODE" = "insecure" ] && [ "$c" = "config" ]; then
echo " Skipping $c (config circuit validates secure configs only)"
continue
fi
RUN_CIRCUITS="${RUN_CIRCUITS} ${c}"
done
done <<< "$CIRCUIT_MODES"
# When --circuit was given but not in config.json, no line matched; run it anyway if path exists (see note above)
if [ -n "$CIRCUIT_FILTER" ] && [ -z "$RUN_CIRCUITS" ] && ! echo "$ALL_CIRCUITS" | grep -qx "$CIRCUIT_FILTER" 2>/dev/null; then
RUN_CIRCUITS="$CIRCUIT_FILTER"
fi
RUN_CIRCUITS=$(echo "$RUN_CIRCUITS" | xargs)
echo ""

Expand Down Expand Up @@ -218,13 +233,9 @@ REPORT_FILE="${BENCHMARKS_DIR}/${OUTPUT_DIR}/report.md"
echo "✓ Report generated: ${REPORT_FILE}"
echo ""

# Remove raw JSON folder after report is generated
RAW_DIR="${BENCHMARKS_DIR}/${OUTPUT_DIR}/raw"
if [ -d "$RAW_DIR" ]; then
rm -rf "$RAW_DIR"
echo "✓ Removed raw data: ${RAW_DIR}"
echo ""
fi
# Keep raw/ so that a later run with --circuit only overwrites that circuit's JSON and the
# report is regenerated from the full set (existing + updated). Delete results_<mode>/raw
# manually if you want a clean slate for the next full run.

# Clean artifacts if requested
if [ "$CLEAN_ARTIFACTS" = true ]; then
Expand Down
7 changes: 3 additions & 4 deletions circuits/bin/threshold/pk_generation/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
// or FITNESS FOR A PARTICULAR PURPOSE.

use lib::configs::default::threshold::{
L, N, PK_GENERATION_BIT_E_SM, PK_GENERATION_BIT_EEK, PK_GENERATION_BIT_PK, PK_GENERATION_BIT_R1,
PK_GENERATION_BIT_R2, PK_GENERATION_BIT_SK, PK_GENERATION_CONFIGS,
CRP, L, N, PK_GENERATION_BIT_E_SM, PK_GENERATION_BIT_EEK, PK_GENERATION_BIT_PK,
PK_GENERATION_BIT_R1, PK_GENERATION_BIT_R2, PK_GENERATION_BIT_SK, PK_GENERATION_CONFIGS,
};
use lib::core::threshold::pk_generation::PkGeneration;
use lib::math::polynomial::Polynomial;

fn main(
a: pub [Polynomial<N>; L],
eek: Polynomial<N>,
sk: Polynomial<N>,
e_sm: [Polynomial<N>; L],
Expand All @@ -23,7 +22,7 @@ fn main(
) -> pub (Field, Field, Field) {
let pk_generation: PkGeneration<N, L, PK_GENERATION_BIT_EEK, PK_GENERATION_BIT_SK, PK_GENERATION_BIT_E_SM, PK_GENERATION_BIT_R1, PK_GENERATION_BIT_R2, PK_GENERATION_BIT_PK> = PkGeneration::new(
PK_GENERATION_CONFIGS,
a,
CRP,
eek,
sk,
e_sm,
Expand Down
Loading