From 7fa0f6fbcb8fd8370f4cf3cfa96a8269a713b1df Mon Sep 17 00:00:00 2001 From: megonen Date: Fri, 26 Jun 2026 23:07:33 +0300 Subject: [PATCH] pq-bench-rpi5: consolidated PQ benchmark snapshot (KEM + sig + TLS) Post-quantum primitive benchmark harness with two consolidated baselines, each measuring KEM + signatures + TLS 1.3 handshakes in one pass: - RPi5 (cortex-a76, baseline-grade): the validator reference baseline (performance governor, core-pinned, no throttling). - Apple M3 (apple-m3, is_baseline_grade=false by design): cross-platform reference, full reps=5 auto-calibrated run. Candidates: ML-KEM 512/768/1024, Classic McEliece (6 sets) and FrodoKEM (3 AES variants), ML-DSA, Falcon, SLH-DSA, plus the X25519/Ed25519 classical baseline and a TLS hybrid-group x PQ-signature handshake matrix. Both runs share liboqs 0.15.0 (97f6b86) + oqs-provider 0.9.0; provenance is stamped into each results JSON. Includes the static dashboard with the merged dataset. Supersedes the earlier add-pq-bench-rpi5 import. --- pq-bench-rpi5/.gitignore | 41 + pq-bench-rpi5/Dockerfile | 41 + pq-bench-rpi5/README.md | 424 + pq-bench-rpi5/RUNNING-ON-YOUR-RPI5.md | 86 + pq-bench-rpi5/analyze/merge.py | 145 + pq-bench-rpi5/analyze/plot.py | 162 + pq-bench-rpi5/analyze/requirements.txt | 1 + pq-bench-rpi5/bench/kem_sig/Makefile | 26 + pq-bench-rpi5/bench/kem_sig/bench_pq.c | 656 + pq-bench-rpi5/bench/lib/assemble.py | 245 + pq-bench-rpi5/bench/lib/list_algs.py | 59 + pq-bench-rpi5/bench/lib/miniyaml.py | 151 + pq-bench-rpi5/bench/tls/Makefile | 17 + pq-bench-rpi5/bench/tls/bench_tls.c | 194 + pq-bench-rpi5/bench/tls/run_tls.sh | 157 + pq-bench-rpi5/config.yaml | 163 + pq-bench-rpi5/dashboard/app.js | 304 + pq-bench-rpi5/dashboard/data/merged.json | 4322 +++++ pq-bench-rpi5/dashboard/index.html | 68 + pq-bench-rpi5/dashboard/style.css | 40 + pq-bench-rpi5/results/.gitkeep | 0 .../results/mehmetmac-20260625T220618Z.json | 13829 ++++++++++++++++ .../results/rasberrypi5-20260625T202356Z.json | 10825 ++++++++++++ pq-bench-rpi5/run.sh | 290 + pq-bench-rpi5/setup/lib_platform.sh | 227 + pq-bench-rpi5/setup/setup.sh | 205 + pq-bench-rpi5/setup/versions.env | 40 + 27 files changed, 32718 insertions(+) create mode 100644 pq-bench-rpi5/.gitignore create mode 100644 pq-bench-rpi5/Dockerfile create mode 100644 pq-bench-rpi5/README.md create mode 100644 pq-bench-rpi5/RUNNING-ON-YOUR-RPI5.md create mode 100644 pq-bench-rpi5/analyze/merge.py create mode 100644 pq-bench-rpi5/analyze/plot.py create mode 100644 pq-bench-rpi5/analyze/requirements.txt create mode 100644 pq-bench-rpi5/bench/kem_sig/Makefile create mode 100644 pq-bench-rpi5/bench/kem_sig/bench_pq.c create mode 100644 pq-bench-rpi5/bench/lib/assemble.py create mode 100644 pq-bench-rpi5/bench/lib/list_algs.py create mode 100644 pq-bench-rpi5/bench/lib/miniyaml.py create mode 100644 pq-bench-rpi5/bench/tls/Makefile create mode 100644 pq-bench-rpi5/bench/tls/bench_tls.c create mode 100755 pq-bench-rpi5/bench/tls/run_tls.sh create mode 100644 pq-bench-rpi5/config.yaml create mode 100644 pq-bench-rpi5/dashboard/app.js create mode 100644 pq-bench-rpi5/dashboard/data/merged.json create mode 100644 pq-bench-rpi5/dashboard/index.html create mode 100644 pq-bench-rpi5/dashboard/style.css create mode 100644 pq-bench-rpi5/results/.gitkeep create mode 100644 pq-bench-rpi5/results/mehmetmac-20260625T220618Z.json create mode 100644 pq-bench-rpi5/results/rasberrypi5-20260625T202356Z.json create mode 100755 pq-bench-rpi5/run.sh create mode 100644 pq-bench-rpi5/setup/lib_platform.sh create mode 100755 pq-bench-rpi5/setup/setup.sh create mode 100644 pq-bench-rpi5/setup/versions.env diff --git a/pq-bench-rpi5/.gitignore b/pq-bench-rpi5/.gitignore new file mode 100644 index 0000000..ef144b9 --- /dev/null +++ b/pq-bench-rpi5/.gitignore @@ -0,0 +1,41 @@ +# Build trees / vendored deps (rebuilt by setup/setup.sh) +/vendor/ +/build/ +setup/versions.lock + +# Compiled harness binaries +bench/kem_sig/bench_pq +bench/tls/bench_tls +*.o + +# Generated TLS material +bench/tls/pki/ + +# Per-run scratch dirs (intermediate artifacts; never committed) +results/.work-*/ + +# Local results are kept by users, not committed by default. +# Comment the next line out if you DO want to commit your machine's results. +results/*.json +# Consolidated baseline-grade RPi5 run (KEM + sig + TLS in one pass): the Pi +# validator reference baseline. +!results/rasberrypi5-20260625T202356Z.json +# Consolidated Apple M3 cross-platform run (apple-m3, KEM + sig + TLS in one +# pass): is_baseline_grade=false by design, kept as the cross-platform reference. +!results/mehmetmac-20260625T220618Z.json + +# Merged dataset consumed by the dashboard. Tracked: ships the published +# baselines so a fresh clone renders charts out-of-the-box. Contributors who +# re-merge overwrite it locally (modified file they can commit or discard). +analyze/png/ + +# Python venv (matplotlib lives here; system python stays clean) +analyze/.venv/ + +# Machine-local Claude Code settings (never shared) +.claude/settings.local.json + +# Python / OS cruft +__pycache__/ +*.pyc +.DS_Store diff --git a/pq-bench-rpi5/Dockerfile b/pq-bench-rpi5/Dockerfile new file mode 100644 index 0000000..c23673b --- /dev/null +++ b/pq-bench-rpi5/Dockerfile @@ -0,0 +1,41 @@ +# ============================================================================= +# Reproducible BUILD of the PQ benchmark toolchain on Debian aarch64 (the same +# OS family as Raspberry Pi OS / Ubuntu on the RPi5). +# +# This image is for BUILDING ONLY — it pins and compiles liboqs / OpenSSL / +# oqs-provider reproducibly. It is NOT for running the benchmark. +# +# docker build -t pq-bench-rpi5 . # build + pin the toolchain +# +# Run the MEASUREMENT bare-metal on the host, never in the container. A +# container cannot reliably control the CPU governor, pin to an isolated core, +# or read the Pi's SoC thermal/throttle sensors (vcgencmd) — the three knobs the +# reference-grade gate depends on — so an in-container run could never be +# baseline-grade and would only add noise. Build here if you like; then: +# +# ./run.sh # on the host (see README) +# ============================================================================= +FROM debian:bookworm-slim + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential cmake ninja-build git perl pkg-config \ + python3 python3-venv ca-certificates \ + libssl-dev cpufrequtils util-linux \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app +COPY . /app + +# Build + pin the toolchain at image-build time so the image is self-contained. +# (Comment this out to keep the image thin and run setup.sh at container start.) +RUN ./setup/setup.sh all || (echo "setup failed — see log above" && exit 1) + +# Optional: matplotlib PNG export in an isolated venv. +RUN python3 -m venv analyze/.venv \ + && analyze/.venv/bin/pip install --no-cache-dir -r analyze/requirements.txt + +ENTRYPOINT ["/bin/bash", "-lc"] +# This image builds the toolchain; it does not run the benchmark. The default +# command just says so — run the measurement bare-metal on the host (see README). +CMD ["echo 'Toolchain built. Run the benchmark BARE-METAL on the host (./run.sh) — Docker is for reproducible builds only; a container cannot meet the baseline-grade gate.'"] diff --git a/pq-bench-rpi5/README.md b/pq-bench-rpi5/README.md new file mode 100644 index 0000000..131318e --- /dev/null +++ b/pq-bench-rpi5/README.md @@ -0,0 +1,424 @@ +# pq-bench-rpi5 + +A reproducible, general-purpose **post-quantum cryptography benchmark** whose +baseline target is the **Raspberry Pi 5** (Broadcom BCM2712, Cortex-A76, +aarch64). Anyone can run it on their own Pi 5 and the results aggregate and +compare apples-to-apples. + +**Framing — migration cost.** How much does moving from the cryptography Logos +uses *today* (X25519 key exchange + Ed25519 signatures) to PQ candidates cost on +validator-grade hardware? Every chart draws that classical baseline as the +reference line, so the PQ "tax" is always visible. + +Phase 1 covers **PQ KEMs**, **PQ signatures**, and **PQ TLS 1.3 handshakes**. +Hooks are left for a later SNARK/STARK phase (see `config.yaml`); it is not +implemented yet. + +--- + +## What gets measured + +| Layer | Metrics | +|-------|---------| +| **KEM** | keygen / encaps / decaps wall-clock (median, MAD, IQR, min, max, mean, stddev, ops/sec) · pk/sk/ct sizes · heap high-water | +| **Signature** | keygen / sign / verify wall-clock (same stats) · pk/sig sizes | +| **TLS 1.3** | full-handshake latency · handshakes/sec · bytes-on-wire · ClientHello size (+ fragmentation flag) — as a matrix of (KEM group × signature) | + +The **classical baseline** (X25519 / Ed25519 / X25519+Ed25519) is always +included as the reference point — measured as a real primitive via OpenSSL, not +hand-waved. + +--- + +## Project layout + +``` +pq-bench-rpi5/ + setup/ build + pin liboqs, OpenSSL 3.5+, oqs-provider (versions.env / versions.lock) + bench/kem_sig/ bench_pq.c primitive KEM/sig harness (liboqs + OpenSSL EVP baselines) + bench/tls/ bench_tls.c in-process TLS 1.3 handshake harness (OpenSSL API) + run_tls.sh PKI generation + (KEM × sig) matrix driver + bench/lib/ assemble.py / merge helpers / miniyaml.py (zero-dep YAML) + results/ results/-.json (one per run, full metadata) + analyze/ merge.py (combine machines) + plot.py (matplotlib PNGs, optional venv) + dashboard/ static HTML/JS (Chart.js) — no backend, GitHub-Pages deployable + run.sh governor + taskset + thermal wrapper + orchestrator + config.yaml candidate lists (extend here) + Dockerfile reproducible Debian-aarch64 build +``` + +--- + +## Quick start + +### On a Raspberry Pi 5 (the real measurement target) + +```bash +git clone && cd pq-bench-rpi5 +./setup/setup.sh # build + pin liboqs, OpenSSL 3.5+, oqs-provider +sudo ./run.sh # sudo only to set the performance governor (see below) +python3 analyze/merge.py results/*.json -o dashboard/data/merged.json +# open dashboard/index.html (or deploy dashboard/ to GitHub Pages) +``` + +**On `sudo`:** it is **optional, not a prerequisite.** The only thing it does is +set the CPU governor to `performance` — none of the crypto needs root. `./run.sh` +runs fine without it: it warns, skips the governor step, completes the run, and +the results JSON is automatically stamped `is_baseline_grade=false` (governor +demerit). So use `sudo` when you want a baseline-grade reference run; drop it for +a quick local run you don't intend to submit. + +`./run.sh --smoke` runs tiny iteration counts as a fast pipeline check. +`./run.sh --kemsig-only` / `--tls-only` scope the run. `--iters/--warmup/--reps` +override the `config.yaml` knobs. + +### On macOS (development / smoke testing only) + +```bash +brew install cmake openssl@3 git +./setup/setup.sh +./run.sh --smoke # produces valid JSON; stamped is_baseline_grade=false +``` + +> **macOS runs are cross-platform / smoke data, never baseline-grade — by +> design, for three concrete reasons:** +> 1. **Not a Raspberry Pi**, so it fails the gate's first condition outright. +> 2. **No userspace cycle counter, and ~1 µs timer granularity.** macOS exposes +> no readable PMU cycle counter and its wall-clock quantizes to ~1 µs steps — +> a ~10% floor on the fastest ops (ML-KEM ~10 µs), negligible for anything +> ≥100 µs (McEliece, FrodoKEM). (See "Timing source" above.) +> 3. **No Linux cpufreq governor, and core-pinning isn't guaranteed.** Two of the +> noise-control knobs the gate relies on — `performance` governor and a pinned +> core — aren't available, and the build flags aren't `cortex-a76` either. +> +> Every macOS results file records `is_baseline_grade=false` with the exact +> reasons, and the dashboard hides such runs by default. They still produce +> **useful cross-platform numbers** (the heavier McEliece/FrodoKEM ops are barely +> affected by the timer floor) — they just can't meet the controlled reference +> bar, hence smoke-only. + +### Docker (reproducible build — build only, never run) + +Docker is for reproducibly **building** the pinned toolchain (liboqs / OpenSSL / +oqs-provider), not for running the benchmark: + +```bash +docker build -t pq-bench-rpi5 . # builds + pins the toolchain inside the image +``` + +**Run the measurement bare-metal on the host.** A container can't reliably set +the CPU governor, pin to an isolated core, or read the Pi's thermal/throttle +sensors — the noise-control knobs the reference-grade gate relies on — so an +in-container run could never be baseline-grade and would only add jitter. Build +in Docker if you like; then run `./run.sh` on the host. + +--- + +## Measurement methodology (why the numbers are credible) + +`run.sh` is the wrapper that makes a number defensible: + +- **CPU governor → `performance`** (Linux; needs `sudo`). Recorded before/after. + If it can't be set (e.g. not root) the run **continues anyway**: it warns, + proceeds, and the missing governor becomes an `is_baseline_grade=false` + demerit. `sudo` is only ever for this step — never for the crypto. +- **Core pinning via `taskset -c 3`.** This is a **single-operation latency** + benchmark (one keygen, one encaps, one sign — timed in isolation), not a + parallel-throughput one, so pinning the whole sweep to one core keeps that + core's cache warm and removes cross-core migration scheduling noise, which + tightens the median and MAD. The Pi 5 has 4 cores (0–3); core **3** is chosen + because core 0 typically absorbs the most OS/IRQ/RPS work. The pinned core and + exact `taskset` command are recorded. + - *Planned (separate axis):* a multi-core **throughput/scaling** mode — run an + op across 1..N cores and report ops/sec plus scaling efficiency per + algorithm. Some schemes (SLH-DSA, and later STARK proving) parallelize far + better than others, so it's a worthwhile dimension — but kept **separate** + from these per-op latency numbers, not mixed into them. +- **Thermal/clock trace.** A background sampler logs ARM clock + (`vcgencmd measure_clock arm`) and SoC temperature (`vcgencmd measure_temp`) + ~once a second for the whole run. The full trace is embedded in the results + JSON, and **thermal throttling** (`vcgencmd get_throttled`, plus a clock-droop + heuristic) is detected and flagged — a throttled run is not baseline-grade. +- **Warmup + N timed iterations, multiple repetitions.** Primary metric is + wall-clock nanoseconds via `clock_gettime(CLOCK_MONOTONIC)`. We report + **median, MAD, IQR, min, max, mean, stddev, ops/sec**, plus per-repetition + medians — not just a mean. +- **Timing source — two clocks, honestly recorded.** There are two ways to time + an op: + 1. **Cycle-based** via the ARM hardware cycle counter (`PMCCNTR_EL0`) — the + most precise, but on Linux **userspace can't read it by default**: the + register traps unless a kernel module enables the userspace PMU (e.g. + `enable_arm_pmu`). + 2. **Time-based** wall-clock via `clock_gettime(CLOCK_MONOTONIC)` — always + available, and accurate enough for the millisecond/microsecond ranges here. + + The harness probes the cycle counter and, when it isn't available, **falls + back to wall-clock and records exactly that** in the JSON + (`run.cycles_available=false` + the reason). **On a stock machine the cycle + counter is not available, so runs use the wall-clock timer by default** — and + both published runs reflect this: the RPi5 baseline and the macOS run *both* + have `cycles_available=false` (both wall-clock). The remaining difference + between them is wall-clock **granularity**, not clock *type*: the Pi's + wall-clock lands on fractional microseconds, while macOS quantizes to ~1 µs + steps — a ~10% resolution floor on the fastest ops (ML-KEM keygen ~10 µs), + negligible for anything ≥100 µs (McEliece, FrodoKEM). +- **CPU features / Keccak acceleration.** NEON, SHA2, SHA3, SHA512, AES, PMULL + are detected (`/proc/cpuinfo` on Linux, `sysctl` on macOS). **Note:** the + Cortex-A76 has the SHA2/AES extensions but **not** the ARMv8.2 SHA3 + extension, so on the Pi 5 Keccak runs on NEON/scalar code — the results record + both the hardware capability and whether liboqs was compiled with SHA3 + instructions, so this is explicit rather than assumed. + +### The AArch64-optimized backend + +liboqs is built with `OQS_DIST_BUILD=OFF` and the pinned flags so the optimized +aarch64 ML-KEM backend (`mlkem-native`) and Falcon/Keccak asm are compiled in. +`setup/setup.sh` extracts the proof from the generated `oqsconfig.h` (e.g. +`OQS_ENABLE_KEM_ml_kem_768_aarch64 1`) into `versions.lock`, which is stamped +into every results file under `toolchain.liboqs_opt_defines`. + +--- + +## Methodology & trustworthiness (verify it yourself) + +Every claim below points at the exact code so you can read it, not take our word. +All `bench_pq.c` references are `bench/kem_sig/bench_pq.c`. + +1. **Correctness gate — broken crypto emits *zero* numbers.** Before any timing, + each algorithm runs a full round-trip and asserts it: for KEM, + keygen→encaps→decaps then `memcmp(ss_encaps, ss_decaps)` + (`bench_pq.c:357-363`); for signatures, keygen→sign→`verify` must succeed + (`bench_pq.c:428-434`). On any failure, `die()` prints to **stderr** and + `exit(3)` (`bench_pq.c:303-307`) — and the JSON is only printed *after* all + measurement (`bench_pq.c:372-381`), so a failed gate yields **no stdout at + all**. The gate runs once, *outside* the timed loop. A runtime guard + (`must_measure`, `bench_pq.c:311-315`) also aborts if a timed op ever fails + mid-run. *Verify it:* flip one byte of the decaps shared secret right before + `bench_pq.c:362`, rebuild, run — the process exits `3` with empty stdout. + +2. **No dead-code elimination — the `volatile` sink.** At `-O3` the compiler may + delete work whose result is never observed. Each timed op folds an output + byte into a file-scope `volatile uint64_t g_sink` (`bench_pq.c:300`; uses at + `:333,:336,:339,:407,:410,:486`), forcing the store to be materialized so the + crypto call **cannot** be optimized away. Without it the loop could time + nothing and report meaningless near-zero numbers. + +3. **What is timed — only the op, never setup.** The timed region brackets a + single `fn(ctx)` call between two `now_ns()` reads (`bench_pq.c:274-281`); + per-rep warmup runs *outside* it (`bench_pq.c:272-273`). Inputs are canonical + and pre-validated, so e.g. KEM decaps (`bench_pq.c:337-339`) times one + `OQS_KEM_decaps` and nothing else. For the X25519 baseline, keygen is timed + separately (`bench_pq.c:507`), a stable key is re-primed *outside* timing + (`bench_pq.c:509`), then derive is timed alone (`bench_pq.c:510`) — setup is + never folded into a measured number. + +4. **Per-op auto-calibration with clamps.** `calibrate_op` (`bench_pq.c:209-250`) + runs a doubling probe (`:223-230`, also cache warmup) to estimate per-op cost + `est_ns` (`:231`), then picks iterations to hit `target_time_ms` of real work + (`:234-235`), clamped to `[min_samples, max_iters]` (`:236-237`). So a fast + 18 µs keygen and a 0.74 s SLH-DSA sign each get the iteration count *they* + need: slow ops floor at `min_samples` (30), fast ops ceil at `max_iters` + (20000). The chosen `timed_iters` and `calib_est_ns` are recorded per op. + +5. **Robust statistics — median + MAD.** `compute_stats` (`bench_pq.c:111-146`) + reports median, MAD, IQR, q1/q3, min, max, mean, stddev, ops/sec, plus + per-repetition medians (`print_stats_json`, `bench_pq.c:184-203`). The + headline metric is the **median**, with **MAD** as spread: timing + distributions are right-skewed with a hard floor (true cost) and a long tail + of OS-scheduling/interrupt contamination that drags mean/stddev but not + median/MAD. Mean and stddev are kept in the JSON so the skew is visible. The + clock is `clock_gettime(CLOCK_MONOTONIC)` (`bench_pq.c:44-48`); userspace PMU + cycles are probed and honestly reported absent when they trap + (`probe_pmu`, `bench_pq.c:66-86`). + +6. **`is_baseline_grade` demerit gate.** Computed in + `bench/lib/assemble.py:155-168` as a demerit accumulator — the flag is `true` + only if *every* condition holds: real Pi (`:157`), `performance` governor + (`:160`), core-pinned (`:162`), `cortex-a76` build flags (`:164`), and no + thermal throttling (`:166`). Throttling is read from `vcgencmd get_throttled` + bits 2/18 plus a clock-droop heuristic (`assemble.py:91-98,:110-113`). Any + failure appends a human-readable reason and flips the flag to `false`; the + dashboard and `plot.py` default to baseline-grade runs only. + +--- + +## Reproducibility & provenance + +- **Pinned versions** live in `setup/versions.env` (liboqs `0.15.0`, OpenSSL + `3.5.0`/`≥3.5`, oqs-provider `0.9.0`). After cloning, `setup.sh` records the + **actually resolved git commits** and the **exact build flags + compiler + version** into `setup/versions.lock`. +- **Every results JSON carries full environment metadata**: RPi model, RAM, + kernel, OS, governor, the clock/temp trace during the run, compiler version, + liboqs/oqs-provider/OpenSSL versions+commits, build flags, and the candidate + list. A macOS smoke file and an RPi5 baseline file can never be confused. +- **Identical flags for every candidate:** `-O3 -mcpu=cortex-a76` on the Pi. + Document your `gcc`/`clang` version — it is auto-captured in `versions.lock` + (`CC_VERSION`). + +### `is_baseline_grade` + +A **reference-measurement quality gate**, not a deployment requirement. It marks +whether a run was produced under controlled, reproducible *reference* conditions, +so the numbers are comparable across algorithms and across machines. It is `true` +**only** when all hold: real Raspberry Pi · `performance` governor · core-pinned · +`cortex-a76` build flags · no thermal throttling. Otherwise it is `false` with a +list of reasons. + +- **What it is:** a label that says "this run is clean enough to sit in the + cross-algorithm / cross-machine reference comparison." The dashboard and + `plot.py` default to baseline-grade runs only, so noisy runs don't distort the + picture. +- **What it is *not*:** a claim about how nodes must be configured in production. + Real deployments are heterogeneous (different SoCs, governors, thermals) — + that's a separate question this flag does not speak to. +- A run that doesn't meet the gate **isn't wrong** — it's just flagged + `is_baseline_grade=false` with the reasons and kept out of the reference set. + The macOS cross-platform runs are exactly this: useful, honest numbers that + simply aren't reference-grade. + +--- + +## Candidates (edit `config.yaml`) + +- **KEM:** ML-KEM-512/768/1024; hybrids X25519MLKEM768, SecP256r1MLKEM768 + (hybrids are benchmarked in the TLS layer; at the primitive layer liboqs + exposes them only as TLS groups, so they show as `enabled:false` there). + Code-based + conservative-LWE backups: Classic McEliece + 348864/460896/460896f/6688128/6960119/8192128 (tiny ciphertext, slow keygen) + and FrodoKEM 640/976/1344-AES (unstructured LWE). Baseline: **X25519**. +- **Signatures:** ML-DSA-44/65/87; SLH-DSA (SPHINCS+) variants; + Falcon/FN-DSA-512/1024. Baseline: **Ed25519**. +- **TLS:** matrix of configured KEM groups × signature algorithms, always + including the classical **X25519 + Ed25519** pair. + +Classic McEliece and FrodoKEM are now measured (above). **HQC** is not — it is +not enabled in the linked liboqs 0.15.0 build (disabled upstream after the +IND-CCA2 implementation issue), so it is intentionally omitted rather than +listed-and-disabled; re-add it once linked against a liboqs that re-enables it. +Add further algorithms by uncommenting/adding entries — the harness skips +anything your liboqs build doesn't enable (and says so). + +--- + +## Output & analysis + +- `results/-.json` — one self-describing file per run. +- `analyze/merge.py results/*.json -o dashboard/data/merged.json` — merge runs + from many machines into one dataset (keeps each run distinct; never mixes + baseline with smoke). +- `analyze/plot.py` — matplotlib PNGs for papers (optional; install into + `analyze/.venv` via `analyze/requirements.txt` to keep system python clean — + it gracefully skips if matplotlib is absent). +- `dashboard/` — static, no-backend dashboard: grouped bars by security level, + size-vs-speed scatter, TLS handshakes/sec, and ClientHello size — each with + the classical baseline drawn as a reference line. Deploy the folder to GitHub + Pages, or open `index.html` via any static server. + +--- + +## Contributing your RPi5 results + +The whole point is a **shared, aggregated baseline**: the more Raspberry Pi 5 +results we collect under identical conditions, the more confident the migration- +cost picture. If you have a Pi 5, please contribute a run — it takes one command +and a pull request. + +### 1. Run under baseline conditions + +For your numbers to count as baseline-grade, the run must satisfy the +`is_baseline_grade` gate (real Pi 5 · `performance` governor · core-pinned · +`cortex-a76` flags · no thermal throttling). To give it the best shot: + +- **Use a Raspberry Pi 5** with active cooling (the official Active Cooler or a + fan). PQ signing (esp. SLH-DSA) runs the core hot for a while; without cooling + you *will* throttle and the run is flagged non-baseline. +- **Use the official 27 W USB-C PSU.** Under-voltage also trips the throttle flag. +- **Run on a quiet machine** (close other workloads) so core 3 stays clean. +- **Don't edit `config.yaml`'s candidate list** if you want your run to be + directly comparable to others. (Extending it is fine — just say so in your PR; + extra algorithms simply add columns.) + +```bash +git clone && cd pq-bench-rpi5 +./setup/setup.sh # build + pin liboqs / OpenSSL 3.5+ / oqs-provider +sudo ./run.sh # sudo lets it set the performance governor +``` + +A full run takes a while (SLH-DSA signing dominates). To check the pipeline +first without committing to the full run, use `sudo ./run.sh --smoke` — but only +a **full** run (not `--smoke`) counts as a submission. + +### 2. Confirm it's baseline-grade + +When the run finishes, the summary prints `baseline-grade (RPi5): True`. Verify +in the JSON too: + +```bash +f=$(ls -t results/*.json | head -1) +python3 -c "import json;d=json.load(open('$f'));print('baseline_grade:',d['is_baseline_grade']);\ +print('reasons:',d['baseline_grade_reasons']);\ +print('throttled:',d['thermal_trace']['throttling_detected']);\ +print('aarch64 ML-KEM backend:', 'ml_kem_768_aarch64 1' in d['toolchain']['liboqs_opt_defines'])" +``` + +You want `baseline_grade: True`, `reasons: []`, `throttled: False`, and the +backend line `True`. If `is_baseline_grade` is false, the printed reasons tell +you what to fix (usually cooling/PSU/governor) — fix and re-run. + +### 3. Submit it + +Your `results/-.json` is fully self-describing (host model, +kernel, OS, governor, clock/temp trace, compiler + liboqs/oqs-provider/OpenSSL +commits, build flags). It contains your **hostname** and Pi model and nothing +else identifying — if you'd rather not share the hostname, set a name first with +`HOSTNAME=mypi5 sudo ./run.sh`, or just rename the file before submitting. + +`results/*.json` is git-ignored by default (so you never accidentally commit +local experiments), so add yours explicitly: + +```bash +git checkout -b results/-pi5 +git add -f results/-.json +git commit -m "results: RPi5 baseline from " +# push to your fork and open a PR +``` + +**PR checklist** (maintainers will look for these): + +- [ ] `is_baseline_grade: true` with empty `baseline_grade_reasons` +- [ ] `thermal_trace.throttling_detected: false` +- [ ] `host.is_rpi: true` and `host.rpi_model` mentions "Raspberry Pi 5" +- [ ] `run.governor_after: performance` and `run.pinned: true` +- [ ] `toolchain.cflags_target: cortex-a76` +- [ ] full run (not `--smoke`): `run.timed_iters` is the `config.yaml` value, not 25 +- [ ] unmodified candidate list (or extensions noted in the PR description) + +Once merged, your file joins `results/`; anyone can regenerate the aggregated +dataset and dashboard with +`python3 analyze/merge.py results/*.json -o dashboard/data/merged.json`. The +dashboard's run selector will then include your Pi alongside everyone else's. + +> Prefer not to use GitHub? Open an issue and attach the JSON file instead — a +> maintainer will add it. + +--- + +## Limitations + +- **macOS is smoke-only** (see above): coarse timer, no governor/pinning, + fallback flags. +- **Userspace cycle counts** require a kernel PMU module; default is time-based. +- **Heap/stack memory** is best-effort (`mallinfo2` on glibc; reported + unavailable elsewhere); pk/sk/ct/sig **sizes** are authoritative. +- **TLS handshakes are in-process over memory BIOs** — this isolates crypto + cost cleanly (no socket/scheduler noise) but is not a network RTT model; + ClientHello fragmentation is flagged against a typical 1400-byte MSS. +- **Docker is build-only.** The benchmark is not run in a container — a + container can't reliably control the governor, core pinning, or throttle + detection, so measurement runs bare-metal on the host (see the Docker section). + +## Future phase (not implemented) + +`config.yaml` reserves a `zk:` section for SNARK/STARK proving/verification +benchmarks; the results schema and dashboard are structured to absorb it later. diff --git a/pq-bench-rpi5/RUNNING-ON-YOUR-RPI5.md b/pq-bench-rpi5/RUNNING-ON-YOUR-RPI5.md new file mode 100644 index 0000000..c8e8866 --- /dev/null +++ b/pq-bench-rpi5/RUNNING-ON-YOUR-RPI5.md @@ -0,0 +1,86 @@ +# Running pq-bench-rpi5 on Your Own Raspberry Pi 5 + +This benchmark measures post-quantum KEMs, signatures, and TLS 1.3 handshakes +against the classical baseline Logos uses today (X25519 / Ed25519), so every +chart shows the **migration cost** of moving to PQ on validator-grade hardware. + +There's no manual tuning: the benchmark **auto-calibrates the iteration count +per operation** to your Pi's speed, so results stay comparable across machines. + +## Prerequisites + +- **Raspberry Pi 5** (Cortex-A76, aarch64), ideally the 8GB model, with + **active cooling** so it doesn't thermal-throttle mid-run. +- **Raspberry Pi OS / Debian Trixie or newer** — system OpenSSL 3.5+ so PQ TLS + works without a source build. +- **Internet access** and **sudo**. + +## Step 1 — Clone (public repo, no auth) + +```sh +git clone +cd pq-bench-rpi5 +``` + +## Step 2 — Build the toolchain + +```sh +./setup/setup.sh all +``` + +Takes 5–15 min: installs dependencies and builds liboqs + oqs-provider. Run it +inside `tmux` so it survives an SSH disconnect. + +## Step 3 — Run + +```sh +sudo ./run.sh +``` + +`sudo` is needed to set the performance governor, pin cores, and read the +temperature. The run takes ~4–5 min, with no iteration counts to set. + +Output lands in `results/-.json`, stamped with full +provenance (Pi model, RAM, kernel, governor, thermal trace, library versions) +and an `is_baseline_grade` flag. + +## Step 4 — View results + +```sh +cd dashboard +python3 -m http.server 8765 +# then open http://:8765 +``` + +The charts show KEM, signature, and TLS results with the classical X25519 / +Ed25519 baseline drawn as a reference line. + +## Step 5 — Contribute (optional) + +Share your `results/*.json` (open a PR or send it over). To merge results from +multiple machines: + +```sh +python3 analyze/merge.py results/*.json -o dashboard/data/merged.json +``` + +The dashboard then shows every Pi side by side. + +## What the results tell you + +PQ is not so much *slower* as *bigger*. Lattice schemes (ML-KEM, ML-DSA) run +close to classical in speed but have much larger keys and signatures, while the +hash-based SLH-DSA (SPHINCS+) is an outlier in both signing time and signature +size. On TLS, the classical baseline fits in a single packet, while PQ and +hybrid handshakes grow past it and fragment. + +## Notes and limitations + +- Measures **liboqs** (C / assembly) implementations — a pure-Rust backend is a + separate, optional axis. +- Userspace PMU cycle counts are usually unavailable, so the primary metric is + **wall-clock time + ops/sec**. +- SNARK / STARK benchmarking is **out of scope** for this phase (`config.yaml` + reserves a hook for it). +- The candidate list lives in `config.yaml` — use the exact liboqs algorithm + names. diff --git a/pq-bench-rpi5/analyze/merge.py b/pq-bench-rpi5/analyze/merge.py new file mode 100644 index 0000000..29efb01 --- /dev/null +++ b/pq-bench-rpi5/analyze/merge.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 +"""merge.py — merge many results/-.json files into one dataset the +dashboard (and PNG export) consume. + + python3 analyze/merge.py results/*.json -o dashboard/data/merged.json + +The merged file keeps every run as a separate record (so multiple machines / +repetitions can be compared) plus a flat index for quick charting. It never +collapses RPi5 baseline-grade runs together with non-baseline (e.g. macOS smoke) +runs — each record carries its own `is_baseline_grade` flag and host, and the +dashboard filters on it by default. +""" +from __future__ import annotations +import argparse +import glob +import json +import os +import sys + +MERGED_SCHEMA = "1.0.0" + + +def load_runs(paths): + runs = [] + for p in paths: + try: + with open(p) as f: + d = json.load(f) + d["_source_file"] = os.path.basename(p) + runs.append(d) + except (json.JSONDecodeError, OSError) as e: + print(f"[merge] skipping {p}: {e}", file=sys.stderr) + return runs + + +def run_id(run): + h = run.get("host", {}) + return f"{h.get('hostname','?')}/{h.get('cpu_brand','?')}@{run.get('generated_utc','?')}" + + +def flatten(runs): + """Produce flat per-(run, algorithm, operation) rows for easy charting.""" + kem_rows, sig_rows, tls_rows = [], [], [] + for run in runs: + rid = run_id(run) + host = run.get("host", {}) + meta = { + "run_id": rid, + "hostname": host.get("hostname"), + "cpu_brand": host.get("cpu_brand"), + "is_rpi": host.get("is_rpi"), + "is_baseline_grade": run.get("is_baseline_grade"), + "source_file": run.get("_source_file"), + } + for k in run.get("kem", []): + if not k.get("enabled"): + continue + for op, st in (k.get("operations") or {}).items(): + kem_rows.append({**meta, + "alg": k["alg"], "backend": k.get("backend"), + "classical": bool(k.get("classical")), + "nist_level": k.get("claimed_nist_level"), + "operation": op, + "median_ns": st.get("median"), "mad_ns": st.get("mad"), + "iqr_ns": st.get("iqr"), "min_ns": st.get("min"), + "stddev_ns": st.get("stddev"), "ops_per_sec": st.get("ops_per_sec"), + "sizes": k.get("sizes")}) + for s in run.get("sig", []): + if not s.get("enabled"): + continue + for op, st in (s.get("operations") or {}).items(): + sig_rows.append({**meta, + "alg": s["alg"], "backend": s.get("backend"), + "classical": bool(s.get("classical")), + "nist_level": s.get("claimed_nist_level"), + "operation": op, + "median_ns": st.get("median"), "mad_ns": st.get("mad"), + "iqr_ns": st.get("iqr"), "min_ns": st.get("min"), + "stddev_ns": st.get("stddev"), "ops_per_sec": st.get("ops_per_sec"), + "sizes": s.get("sizes")}) + tls = run.get("tls") or {} + for cell in (tls.get("matrix") or []): + if not cell.get("enabled"): + continue + tls_rows.append({**meta, + "label": cell.get("label"), "group": cell.get("group"), + "is_baseline_pair": cell.get("label") == (tls.get("baseline") or {}).get("label"), + "handshakes_per_sec": cell.get("handshakes_per_sec"), + "median_ns": (cell.get("handshake_latency_ns") or {}).get("median"), + "bytes_total": (cell.get("bytes_on_wire") or {}).get("total"), + "client_hello_bytes": cell.get("client_hello_bytes"), + "client_hello_fragmented": cell.get("client_hello_fragmented")}) + return kem_rows, sig_rows, tls_rows + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("inputs", nargs="+", help="results JSON files or globs") + ap.add_argument("-o", "--out", default="dashboard/data/merged.json") + args = ap.parse_args() + + paths = [] + for pat in args.inputs: + paths.extend(sorted(glob.glob(pat)) if any(c in pat for c in "*?[") else [pat]) + paths = [p for p in paths if os.path.isfile(p)] + if not paths: + sys.exit("no input files matched") + + runs = load_runs(paths) + kem_rows, sig_rows, tls_rows = flatten(runs) + + merged = { + "merged_schema": MERGED_SCHEMA, + "n_runs": len(runs), + "runs": [{ + "run_id": run_id(r), + "host": r.get("host"), + "is_baseline_grade": r.get("is_baseline_grade"), + "baseline_grade_reasons": r.get("baseline_grade_reasons", []), + "toolchain": r.get("toolchain"), + "cpu_features": r.get("cpu_features"), + "run": r.get("run"), + "thermal_summary": { + "temp_c": (r.get("thermal_trace") or {}).get("temp_c"), + "throttling_detected": (r.get("thermal_trace") or {}).get("throttling_detected"), + }, + "generated_utc": r.get("generated_utc"), + "source_file": r.get("_source_file"), + } for r in runs], + "kem": kem_rows, + "sig": sig_rows, + "tls": tls_rows, + } + + os.makedirs(os.path.dirname(args.out) or ".", exist_ok=True) + with open(args.out, "w") as f: + json.dump(merged, f, indent=2) + n_base = sum(1 for r in runs if r.get("is_baseline_grade")) + print(f"merged {len(runs)} run(s) -> {args.out} " + f"({n_base} baseline-grade, {len(runs)-n_base} smoke/other)") + print(f" kem rows: {len(kem_rows)} sig rows: {len(sig_rows)} tls rows: {len(tls_rows)}") + + +if __name__ == "__main__": + main() diff --git a/pq-bench-rpi5/analyze/plot.py b/pq-bench-rpi5/analyze/plot.py new file mode 100644 index 0000000..a1f7715 --- /dev/null +++ b/pq-bench-rpi5/analyze/plot.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +"""plot.py — export publication-ready PNGs from a merged dataset. + + python3 analyze/plot.py dashboard/data/merged.json -o analyze/png + +matplotlib is an OPTIONAL dependency. If it is not installed this prints a clear +hint and exits 0 (the HTML dashboard remains the primary, dependency-free view). + +By default it plots only baseline-grade (RPi5) runs so paper figures are never +polluted with macOS smoke data; pass --include-smoke to override. The classical +Logos baseline (X25519 / Ed25519) is drawn as a reference line on every chart. +""" +from __future__ import annotations +import argparse +import json +import os +import sys + +try: + import matplotlib + matplotlib.use("Agg") + import matplotlib.pyplot as plt +except ImportError: + print("matplotlib not installed — skipping PNG export.\n" + " enable it in a project venv (keeps your system python clean):\n" + " python3 -m venv analyze/.venv\n" + " analyze/.venv/bin/pip install -r analyze/requirements.txt\n" + " analyze/.venv/bin/python analyze/plot.py dashboard/data/merged.json\n" + " (the HTML dashboard works without it)", file=sys.stderr) + sys.exit(0) + + +def median_ms(ns): + return (ns or 0) / 1e6 + + +def pick_runs(merged, include_smoke): + ids = set() + for r in merged.get("runs", []): + if include_smoke or r.get("is_baseline_grade"): + ids.add(r["run_id"]) + return ids + + +def grouped_bar_by_level(rows, op, title, outpath): + """Grouped bars of median latency per algorithm, grouped by NIST level.""" + data = [r for r in rows if r["operation"] == op] + if not data: + return + # one bar per algorithm; baseline highlighted + data.sort(key=lambda r: (r.get("nist_level") or 0, r["median_ns"])) + labels = [r["alg"] for r in data] + vals = [median_ms(r["median_ns"]) for r in data] + colors = ["#888" if r.get("classical") else "#3b6" for r in data] + + fig, ax = plt.subplots(figsize=(max(6, len(labels) * 0.55), 4)) + ax.bar(range(len(labels)), vals, color=colors) + # baseline reference line + base = next((r for r in data if r.get("classical")), None) + if base: + ax.axhline(median_ms(base["median_ns"]), color="#c33", ls="--", lw=1, + label=f"classical baseline ({base['alg']})") + ax.legend(fontsize=8) + ax.set_xticks(range(len(labels))) + ax.set_xticklabels(labels, rotation=45, ha="right", fontsize=8) + ax.set_ylabel("median latency (ms)") + ax.set_title(title) + ax.grid(axis="y", alpha=0.3) + fig.tight_layout() + fig.savefig(outpath, dpi=150) + plt.close(fig) + print("wrote", outpath) + + +def size_speed_scatter(rows, op, size_key, title, outpath): + data = [r for r in rows if r["operation"] == op and r.get("sizes")] + pts = [] + for r in data: + sz = (r["sizes"] or {}).get(size_key) + if sz: + pts.append((sz, median_ms(r["median_ns"]), r["alg"], r.get("classical"))) + if not pts: + return + fig, ax = plt.subplots(figsize=(7, 5)) + for sz, lat, alg, classical in pts: + ax.scatter(sz, lat, c="#c33" if classical else "#3b6", + s=60, edgecolors="k", linewidths=0.4, zorder=3) + ax.annotate(alg, (sz, lat), fontsize=7, xytext=(4, 3), + textcoords="offset points") + ax.set_xlabel(f"{size_key} size (bytes)") + ax.set_ylabel("median latency (ms)") + ax.set_title(title) + ax.grid(alpha=0.3) + fig.tight_layout() + fig.savefig(outpath, dpi=150) + plt.close(fig) + print("wrote", outpath) + + +def tls_bar(tls_rows, outpath): + if not tls_rows: + return + tls_rows = sorted(tls_rows, key=lambda r: -(r.get("handshakes_per_sec") or 0)) + labels = [r["label"] for r in tls_rows] + vals = [r.get("handshakes_per_sec") or 0 for r in tls_rows] + colors = ["#c33" if r.get("is_baseline_pair") else "#36c" for r in tls_rows] + fig, ax = plt.subplots(figsize=(max(6, len(labels) * 0.5), 4.5)) + ax.barh(range(len(labels)), vals, color=colors) + base = next((r for r in tls_rows if r.get("is_baseline_pair")), None) + if base: + ax.axvline(base.get("handshakes_per_sec") or 0, color="#c33", ls="--", lw=1, + label=f"classical baseline ({base['label']})") + ax.legend(fontsize=8) + ax.set_yticks(range(len(labels))) + ax.set_yticklabels(labels, fontsize=7) + ax.invert_yaxis() + ax.set_xlabel("handshakes / sec") + ax.set_title("TLS 1.3 handshake throughput (higher is better)") + ax.grid(axis="x", alpha=0.3) + fig.tight_layout() + fig.savefig(outpath, dpi=150) + plt.close(fig) + print("wrote", outpath) + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("merged") + ap.add_argument("-o", "--outdir", default="analyze/png") + ap.add_argument("--include-smoke", action="store_true") + args = ap.parse_args() + + with open(args.merged) as f: + merged = json.load(f) + ids = pick_runs(merged, args.include_smoke) + if not ids: + print("no baseline-grade runs to plot (use --include-smoke for macOS/dev data)", + file=sys.stderr) + return + + def keep(rows): + return [r for r in rows if r["run_id"] in ids] + + kem, sig, tls = keep(merged["kem"]), keep(merged["sig"]), keep(merged["tls"]) + os.makedirs(args.outdir, exist_ok=True) + O = args.outdir + + grouped_bar_by_level(kem, "keygen", "KEM keygen latency by algorithm", f"{O}/kem_keygen.png") + grouped_bar_by_level(kem, "encaps", "KEM encapsulation latency", f"{O}/kem_encaps.png") + grouped_bar_by_level(kem, "decaps", "KEM decapsulation latency", f"{O}/kem_decaps.png") + grouped_bar_by_level(sig, "sign", "Signature signing latency", f"{O}/sig_sign.png") + grouped_bar_by_level(sig, "verify", "Signature verification latency", f"{O}/sig_verify.png") + size_speed_scatter(kem, "encaps", "public_key", + "KEM: public-key size vs encaps latency", f"{O}/kem_size_speed.png") + size_speed_scatter(sig, "sign", "signature", + "Signature: signature size vs sign latency", f"{O}/sig_size_speed.png") + tls_bar(tls, f"{O}/tls_throughput.png") + print(f"PNGs in {O}/ ({'incl. smoke' if args.include_smoke else 'baseline-grade only'})") + + +if __name__ == "__main__": + main() diff --git a/pq-bench-rpi5/analyze/requirements.txt b/pq-bench-rpi5/analyze/requirements.txt new file mode 100644 index 0000000..3cf9f81 --- /dev/null +++ b/pq-bench-rpi5/analyze/requirements.txt @@ -0,0 +1 @@ +matplotlib>=3.7 diff --git a/pq-bench-rpi5/bench/kem_sig/Makefile b/pq-bench-rpi5/bench/kem_sig/Makefile new file mode 100644 index 0000000..6561049 --- /dev/null +++ b/pq-bench-rpi5/bench/kem_sig/Makefile @@ -0,0 +1,26 @@ +# Build the primitive KEM/sig harness against the pinned liboqs + system OpenSSL. +# +# Paths/flags default to the vendored toolchain but are overridable so run.sh can +# pass the exact values from setup/versions.lock (single source of truth): +# make LIBOQS_PREFIX=... OPENSSL_PREFIX=... BENCH_CFLAGS="-O3 -mcpu=cortex-a76" + +ROOT := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))../..) +LIBOQS_PREFIX ?= $(ROOT)/vendor/install +# OpenSSL: prefer Homebrew openssl@3 on macOS, else system. +OPENSSL_PREFIX ?= $(shell brew --prefix openssl@3 2>/dev/null || echo /usr) +BENCH_CFLAGS ?= -O3 + +CC ?= cc +CFLAGS := $(BENCH_CFLAGS) -std=c11 -Wall -Wextra \ + -I$(LIBOQS_PREFIX)/include -I$(OPENSSL_PREFIX)/include +LDFLAGS := -L$(LIBOQS_PREFIX)/lib -L$(OPENSSL_PREFIX)/lib \ + -Wl,-rpath,$(LIBOQS_PREFIX)/lib -Wl,-rpath,$(OPENSSL_PREFIX)/lib +LDLIBS := -loqs -lcrypto -lm + +bench_pq: bench_pq.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDLIBS) + +clean: + rm -f bench_pq + +.PHONY: clean diff --git a/pq-bench-rpi5/bench/kem_sig/bench_pq.c b/pq-bench-rpi5/bench/kem_sig/bench_pq.c new file mode 100644 index 0000000..1e740bb --- /dev/null +++ b/pq-bench-rpi5/bench/kem_sig/bench_pq.c @@ -0,0 +1,656 @@ +/* =========================================================================== + * bench_pq.c — primitive-level KEM / signature benchmark harness. + * + * One algorithm per invocation (fresh process keeps cache state clean): + * bench_pq --kind kem --alg ML-KEM-768 --warmup 1000 --iters 10000 --reps 5 + * bench_pq --kind sig --alg ML-DSA-65 ... + * + * Emits a single JSON object describing the algorithm to stdout. The orchestrator + * (run.sh / assemble.py) wraps these with environment metadata. + * + * Two backends, selected by algorithm name: + * - liboqs : all PQ candidates (ML-KEM, ML-DSA, Falcon, SLH-DSA, ...) + * - OpenSSL EVP : the classical Logos baselines X25519 (KEM-analog) and + * Ed25519 (signature), which liboqs does not implement. + * This lets the classical reference be drawn on the same primitive charts. + * + * Metrics per operation: full per-iteration wall-clock nanosecond distribution + * -> median, MAD, IQR, min, max, mean, stddev, ops/sec, plus per-repetition + * medians. Optional userspace PMU cycle counts when available. Heap high-water + * via mallinfo2 on glibc (the RPi5 target); honestly reported unavailable + * elsewhere (e.g. the macOS smoke box). + * ===========================================================================*/ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#if defined(__linux__) && defined(__GLIBC__) +#include +#define HAVE_MALLINFO2 1 +#endif + +/* ---- timing ------------------------------------------------------------- */ +static inline uint64_t now_ns(void) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t)ts.tv_sec * 1000000000ull + (uint64_t)ts.tv_nsec; +} + +/* ---- userspace PMU cycle counter probe (aarch64) ------------------------ */ +static sigjmp_buf g_sigill_jmp; +static volatile sig_atomic_t g_pmu_ok = 0; +static void sigill_handler(int sig) { (void)sig; siglongjmp(g_sigill_jmp, 1); } + +static inline uint64_t read_cycles(void) { +#if defined(__aarch64__) + uint64_t v; + __asm__ volatile("mrs %0, pmccntr_el0" : "=r"(v)); + return v; +#else + return 0; +#endif +} + +/* Returns 1 and a reason string if userspace cycle counting works. */ +static int probe_pmu(const char **reason) { +#if defined(__aarch64__) + struct sigaction sa, old; + memset(&sa, 0, sizeof sa); + sa.sa_handler = sigill_handler; + sigaction(SIGILL, &sa, &old); + if (sigsetjmp(g_sigill_jmp, 1) == 0) { + (void)read_cycles(); + g_pmu_ok = 1; + } else { + g_pmu_ok = 0; + } + sigaction(SIGILL, &old, NULL); + if (g_pmu_ok) { *reason = "PMCCNTR_EL0 readable from userspace"; return 1; } + *reason = "PMCCNTR_EL0 traps (kernel module not loaded; needs e.g. enable_arm_pmu)"; + return 0; +#else + *reason = "not aarch64"; + return 0; +#endif +} + +/* ---- statistics --------------------------------------------------------- */ +typedef struct { + double median, mad, iqr, q1, q3, min, max, mean, stddev; + double ops_per_sec; + uint64_t n; +} stats_t; + +static int cmp_u64(const void *a, const void *b) { + uint64_t x = *(const uint64_t *)a, y = *(const uint64_t *)b; + return (x > y) - (x < y); +} + +/* percentile on an already-sorted array (linear interpolation) */ +static double pct_sorted(const uint64_t *s, uint64_t n, double p) { + if (n == 0) return 0; + if (n == 1) return (double)s[0]; + double idx = p * (double)(n - 1); + uint64_t lo = (uint64_t)idx; + double frac = idx - (double)lo; + if (lo + 1 >= n) return (double)s[n - 1]; + return (double)s[lo] + frac * ((double)s[lo + 1] - (double)s[lo]); +} + +static stats_t compute_stats(uint64_t *samples, uint64_t n) { + stats_t st; memset(&st, 0, sizeof st); + st.n = n; + if (n == 0) return st; + qsort(samples, n, sizeof(uint64_t), cmp_u64); + st.min = (double)samples[0]; + st.max = (double)samples[n - 1]; + st.median = pct_sorted(samples, n, 0.5); + st.q1 = pct_sorted(samples, n, 0.25); + st.q3 = pct_sorted(samples, n, 0.75); + st.iqr = st.q3 - st.q1; + + double sum = 0; + for (uint64_t i = 0; i < n; i++) sum += (double)samples[i]; + st.mean = sum / (double)n; + double ss = 0; + for (uint64_t i = 0; i < n; i++) { + double d = (double)samples[i] - st.mean; + ss += d * d; + } + st.stddev = (n > 1) ? sqrt(ss / (double)(n - 1)) : 0; + + /* MAD = median(|x - median|); needs a second sorted buffer */ + uint64_t *dev = malloc(n * sizeof(uint64_t)); + if (dev) { + for (uint64_t i = 0; i < n; i++) { + double d = (double)samples[i] - st.median; + dev[i] = (uint64_t)(d < 0 ? -d : d); + } + qsort(dev, n, sizeof(uint64_t), cmp_u64); + st.mad = pct_sorted(dev, n, 0.5); + free(dev); + } + st.ops_per_sec = st.median > 0 ? 1e9 / st.median : 0; + return st; +} + +/* ---- measurement configuration + generic loop --------------------------- */ +/* A closure-ish: the caller provides a function pointer that runs one op. */ +typedef int (*op_fn)(void *ctx); + +/* How each op is sized. Two modes, decided per invocation: + * - fixed-count (fixed_iters > 0): exactly fixed_iters timed iters per rep, + * with the configured fixed-mode warmup. This is the explicit + * `--iters N` override / fixed-count fallback. + * - auto-calibrate(fixed_iters == 0): each op is timed long enough to put + * ~target_ns of aggregate timed work on it, so a 18 us keygen + * and a 750 ms SLH-DSA sign both yield a stable median. The + * chosen count is clamped to [min_samples, max_iters]: + * fast ops hit max_iters, slow ops hit min_samples. + * Auto mode estimates per-op cost with a short doubling calibration (which also + * serves as cache warmup), then derives the timed count + a per-rep re-warm. */ +typedef struct { + uint64_t fixed_iters; /* >0 => fixed-count mode; 0 => auto-calibrate */ + uint64_t target_ns; /* auto: per-op aggregate timed-work target */ + uint64_t min_samples; /* auto: floor on timed iters per rep */ + uint64_t max_iters; /* auto: ceiling on timed iters per rep */ + uint64_t warmup; /* fixed-mode warmup count per rep */ + uint64_t reps; +} bench_cfg; + +typedef struct { + uint64_t *all; /* all samples across reps */ + uint64_t all_n; + double per_rep_median[64]; + int n_rep_med; + uint64_t timed_iters; /* timed iters per rep actually used */ + uint64_t warmup_iters; /* warmup iters per rep actually used */ + uint64_t reps; + int calibrated; /* 1 if auto-calibrated, 0 if fixed-count */ + double est_ns; /* per-op cost estimate from calibration (auto) */ +} measure_out; + +static void print_stats_json(FILE *f, const char *name, stats_t st, + const measure_out *m) { + fprintf(f, "\"%s\":{", name); + fprintf(f, "\"unit\":\"ns\",\"warmup_iters\":%llu,\"timed_iters\":%llu,\"repetitions\":%llu,", + (unsigned long long)m->warmup_iters, (unsigned long long)m->timed_iters, + (unsigned long long)m->reps); + fprintf(f, "\"calibrated\":%s,", m->calibrated ? "true" : "false"); + if (m->calibrated) + fprintf(f, "\"calib_est_ns\":%.2f,", m->est_ns); + fprintf(f, "\"samples\":%llu,", (unsigned long long)st.n); + fprintf(f, "\"median\":%.2f,\"mad\":%.2f,\"iqr\":%.2f,\"q1\":%.2f,\"q3\":%.2f,", + st.median, st.mad, st.iqr, st.q1, st.q3); + fprintf(f, "\"min\":%.2f,\"max\":%.2f,\"mean\":%.2f,\"stddev\":%.2f,", + st.min, st.max, st.mean, st.stddev); + fprintf(f, "\"ops_per_sec\":%.2f,", st.ops_per_sec); + fprintf(f, "\"per_rep_median\":["); + for (int i = 0; i < m->n_rep_med; i++) + fprintf(f, "%s%.2f", i ? "," : "", m->per_rep_median[i]); + fprintf(f, "]}"); +} + +/* Pick the timed-iter count (and per-rep warmup) for one op under cfg. + * In auto mode this runs a doubling calibration loop on fn (which warms caches) + * to estimate per-op cost, then solves for the count that hits target_ns. + * Returns 0 on success, -2 if the op ever fails during calibration. */ +static int calibrate_op(op_fn fn, void *ctx, const bench_cfg *cfg, + uint64_t *timed_out, uint64_t *warm_out, + double *est_ns_out, int *calibrated_out) { + if (cfg->fixed_iters > 0) { + *timed_out = cfg->fixed_iters; + *warm_out = cfg->warmup; + *est_ns_out = 0.0; + *calibrated_out = 0; + return 0; + } + /* doubling calibration: run batches 1,2,4,... until ~CALIB_BUDGET elapses, + * capped at max_iters so a sub-microsecond op can't spin forever. */ + const uint64_t CALIB_BUDGET_NS = 30ull * 1000 * 1000; /* 30 ms */ + uint64_t cops = 0, cel = 0, batch = 1; + while (cel < CALIB_BUDGET_NS && cops < cfg->max_iters) { + uint64_t t0 = now_ns(); + for (uint64_t i = 0; i < batch; i++) + if (fn(ctx) != 0) return -2; + cel += now_ns() - t0; + cops += batch; + batch *= 2; + } + double est_ns = cops ? (double)cel / (double)cops : 1.0; + if (est_ns < 1.0) est_ns = 1.0; + + double want = (double)cfg->target_ns / est_ns; + uint64_t n = (uint64_t)(want + 0.5); + if (n < cfg->min_samples) n = cfg->min_samples; /* slow ops floor here */ + if (n > cfg->max_iters) n = cfg->max_iters; /* fast ops ceil here */ + + /* per-rep re-warm ~= 20% of the timed budget, at least 1, capped. */ + double w = ((double)cfg->target_ns * 0.2) / est_ns; + uint64_t warm = (uint64_t)(w + 0.5); + if (warm < 1) warm = 1; + if (warm > cfg->max_iters) warm = cfg->max_iters; + + *timed_out = n; + *warm_out = warm; + *est_ns_out = est_ns; + *calibrated_out = 1; + return 0; +} + +/* Returns 0 on success. Fills out with samples. Re-warms before each rep. */ +static int measure_op(op_fn fn, void *ctx, const bench_cfg *cfg, measure_out *out) { + uint64_t iters, warmup; + double est_ns; int calibrated; + if (calibrate_op(fn, ctx, cfg, &iters, &warmup, &est_ns, &calibrated) != 0) + return -2; + + out->all = malloc(iters * cfg->reps * sizeof(uint64_t)); + if (!out->all) return -1; + out->all_n = 0; + out->n_rep_med = 0; + out->timed_iters = iters; + out->warmup_iters = warmup; + out->reps = cfg->reps; + out->calibrated = calibrated; + out->est_ns = est_ns; + uint64_t *rep_buf = malloc(iters * sizeof(uint64_t)); + if (!rep_buf) { free(out->all); return -1; } + + for (uint64_t r = 0; r < cfg->reps; r++) { + for (uint64_t i = 0; i < warmup; i++) + if (fn(ctx) != 0) { free(rep_buf); free(out->all); return -2; } + for (uint64_t i = 0; i < iters; i++) { + uint64_t t0 = now_ns(); + int rc = fn(ctx); + uint64_t dt = now_ns() - t0; + if (rc != 0) { free(rep_buf); free(out->all); return -2; } + rep_buf[i] = dt; + out->all[out->all_n++] = dt; + } + /* per-rep median (sorts a copy of this rep's slice) */ + uint64_t *copy = malloc(iters * sizeof(uint64_t)); + if (copy) { + memcpy(copy, rep_buf, iters * sizeof(uint64_t)); + qsort(copy, iters, sizeof(uint64_t), cmp_u64); + if (out->n_rep_med < 64) + out->per_rep_median[out->n_rep_med++] = pct_sorted(copy, iters, 0.5); + free(copy); + } + } + free(rep_buf); + return 0; +} + +/* ---- anti-DCE sink + fatal helpers -------------------------------------- */ +/* File-scope volatile: the compiler must materialize every store, so it cannot + * dead-code-eliminate the crypto outputs we feed into it. Every timed op sinks + * one output byte here. */ +static volatile uint64_t g_sink = 0; + +/* Abort the whole run: a broken build must NEVER silently emit timing numbers. */ +static void die(const char *alg, const char *what) { + fprintf(stderr, "[bench_pq] FATAL: %s: %s — aborting so no numbers are emitted\n", + alg, what); + exit(3); +} + +/* measure_op wrapper: if any timed op ever returns failure (e.g. a verify that + * stopped succeeding), abort instead of reading freed/partial buffers. */ +static void must_measure(const char *alg, const char *op, op_fn fn, void *ctx, + const bench_cfg *cfg, measure_out *out) { + if (measure_op(fn, ctx, cfg, out) != 0) + die(alg, op); +} + +#define MSGLEN 32 + +/* ======================= liboqs KEM ====================================== */ +/* Timed ops consume canonical, pre-validated inputs; keygen/encaps write to + * scratch buffers so they never clobber the matched (pk,sk,ct) that the other + * timed ops depend on. Each op sinks an output byte into g_sink. */ +typedef struct { + OQS_KEM *kem; + uint8_t *pk, *sk; /* canonical matched keypair (encaps/decaps inputs) */ + uint8_t *ct; /* canonical ciphertext (decaps input) */ + uint8_t *pk_s, *sk_s; /* scratch: keygen outputs */ + uint8_t *ct_s, *ss_s; /* scratch: encaps outputs */ + uint8_t *ss_d; /* scratch: decaps output */ +} kem_ctx; +static int kem_keygen(void *c){ kem_ctx*x=c; + if (OQS_KEM_keypair(x->kem, x->pk_s, x->sk_s) != OQS_SUCCESS) return 1; + g_sink += x->pk_s[0]; return 0; } +static int kem_encaps(void *c){ kem_ctx*x=c; + if (OQS_KEM_encaps(x->kem, x->ct_s, x->ss_s, x->pk) != OQS_SUCCESS) return 1; + g_sink += (uint64_t)x->ss_s[0] ^ x->ct_s[0]; return 0; } +static int kem_decaps(void *c){ kem_ctx*x=c; + if (OQS_KEM_decaps(x->kem, x->ss_d, x->ct, x->sk) != OQS_SUCCESS) return 1; + g_sink += x->ss_d[0]; return 0; } + +static int run_kem(const char *alg, const bench_cfg *cfg) { + OQS_KEM *kem = OQS_KEM_new(alg); + if (!kem) { + printf("{\"alg\":\"%s\",\"kind\":\"kem\",\"backend\":\"liboqs\",\"enabled\":false," + "\"reason\":\"not enabled in this liboqs build\"}\n", alg); + return 0; + } + kem_ctx x; memset(&x, 0, sizeof x); x.kem = kem; + x.pk = malloc(kem->length_public_key); x.sk = malloc(kem->length_secret_key); + x.ct = malloc(kem->length_ciphertext); + x.pk_s = malloc(kem->length_public_key); x.sk_s = malloc(kem->length_secret_key); + x.ct_s = malloc(kem->length_ciphertext); + x.ss_s = malloc(kem->length_shared_secret); + x.ss_d = malloc(kem->length_shared_secret); + if (!x.pk||!x.sk||!x.ct||!x.pk_s||!x.sk_s||!x.ct_s||!x.ss_s||!x.ss_d) die(alg,"out of memory"); + + /* ---- correctness check (ONCE, outside the timed loop) ---- + * keygen -> encaps -> decaps, then assert the shared secrets match. */ + if (OQS_KEM_keypair(kem, x.pk, x.sk) != OQS_SUCCESS) die(alg, "keygen failed"); + if (OQS_KEM_encaps(kem, x.ct, x.ss_s, x.pk) != OQS_SUCCESS) die(alg, "encaps failed"); + if (OQS_KEM_decaps(kem, x.ss_d, x.ct, x.sk) != OQS_SUCCESS) die(alg, "decaps failed"); + if (memcmp(x.ss_s, x.ss_d, kem->length_shared_secret) != 0) + die(alg, "KEM shared-secret mismatch (ss_encaps != ss_decaps)"); + + /* timed phases run on the canonical, validated (pk,sk,ct); any op failure + * during timing aborts via must_measure. */ + measure_out kg={0}, en={0}, de={0}; + must_measure(alg,"keygen",kem_keygen,&x,cfg,&kg); + must_measure(alg,"encaps",kem_encaps,&x,cfg,&en); + must_measure(alg,"decaps",kem_decaps,&x,cfg,&de); + + printf("{\"alg\":\"%s\",\"kind\":\"kem\",\"backend\":\"liboqs\",\"enabled\":true,", alg); + printf("\"claimed_nist_level\":%d,", kem->claimed_nist_level); + printf("\"sizes\":{\"public_key\":%zu,\"secret_key\":%zu,\"ciphertext\":%zu,\"shared_secret\":%zu},", + kem->length_public_key, kem->length_secret_key, kem->length_ciphertext, kem->length_shared_secret); + printf("\"operations\":{"); + stats_t s; + s=compute_stats(kg.all,kg.all_n); print_stats_json(stdout,"keygen",s,&kg); printf(","); + s=compute_stats(en.all,en.all_n); print_stats_json(stdout,"encaps",s,&en); printf(","); + s=compute_stats(de.all,de.all_n); print_stats_json(stdout,"decaps",s,&de); + printf("}}\n"); + + free(kg.all); free(en.all); free(de.all); + free(x.pk); free(x.sk); free(x.ct); + free(x.pk_s); free(x.sk_s); free(x.ct_s); free(x.ss_s); free(x.ss_d); + OQS_KEM_free(kem); + return 0; +} + +/* ======================= liboqs SIG ====================================== */ +/* sign writes a scratch signature; verify reads the canonical (sg,sglen) over + * the canonical msg with the canonical pk — all pre-validated. */ +typedef struct { + OQS_SIG *sig; + uint8_t *pk, *sk; /* canonical keypair (sign/verify inputs) */ + uint8_t *msg; /* canonical message */ + uint8_t *sg; size_t sglen; /* canonical signature (verify input) */ + uint8_t *pk_s, *sk_s; /* scratch: keygen outputs */ + uint8_t *sg_s; size_t sg_s_len;/* scratch: sign output */ +} sig_ctx; +static int sig_keygen(void *c){ sig_ctx*x=c; + if (OQS_SIG_keypair(x->sig, x->pk_s, x->sk_s) != OQS_SUCCESS) return 1; + g_sink += x->pk_s[0]; return 0; } +static int sig_sign(void *c){ sig_ctx*x=c; + x->sg_s_len = x->sig->length_signature; + if (OQS_SIG_sign(x->sig, x->sg_s, &x->sg_s_len, x->msg, MSGLEN, x->sk) != OQS_SUCCESS) return 1; + g_sink += x->sg_s[0]; return 0; } +static int sig_verify(void *c){ sig_ctx*x=c; + if (OQS_SIG_verify(x->sig, x->msg, MSGLEN, x->sg, x->sglen, x->pk) != OQS_SUCCESS) return 1; + g_sink += 1; return 0; } + +static int run_sig(const char *alg, const bench_cfg *cfg) { + OQS_SIG *sig = OQS_SIG_new(alg); + if (!sig) { + printf("{\"alg\":\"%s\",\"kind\":\"sig\",\"backend\":\"liboqs\",\"enabled\":false," + "\"reason\":\"not enabled in this liboqs build\"}\n", alg); + return 0; + } + sig_ctx x; memset(&x,0,sizeof x); x.sig=sig; + x.pk = malloc(sig->length_public_key); x.sk = malloc(sig->length_secret_key); + x.msg = malloc(MSGLEN); + x.sg = malloc(sig->length_signature); + x.pk_s = malloc(sig->length_public_key); x.sk_s = malloc(sig->length_secret_key); + x.sg_s = malloc(sig->length_signature); + if (!x.pk||!x.sk||!x.msg||!x.sg||!x.pk_s||!x.sk_s||!x.sg_s) die(alg,"out of memory"); + memset(x.msg, 0xA5, MSGLEN); + + /* ---- correctness check (ONCE, outside the timed loop) ---- + * keygen -> sign -> verify; the verify MUST succeed on a valid signature. */ + if (OQS_SIG_keypair(sig, x.pk, x.sk) != OQS_SUCCESS) die(alg, "keygen failed"); + x.sglen = sig->length_signature; + if (OQS_SIG_sign(sig, x.sg, &x.sglen, x.msg, MSGLEN, x.sk) != OQS_SUCCESS) die(alg, "sign failed"); + if (OQS_SIG_verify(sig, x.msg, MSGLEN, x.sg, x.sglen, x.pk) != OQS_SUCCESS) + die(alg, "signature verify failed on a valid signature (broken build)"); + + measure_out kg={0}, sg={0}, vf={0}; + must_measure(alg,"keygen",sig_keygen,&x,cfg,&kg); + must_measure(alg,"sign", sig_sign, &x,cfg,&sg); + must_measure(alg,"verify",sig_verify,&x,cfg,&vf); + + printf("{\"alg\":\"%s\",\"kind\":\"sig\",\"backend\":\"liboqs\",\"enabled\":true,", alg); + printf("\"claimed_nist_level\":%d,", sig->claimed_nist_level); + printf("\"sizes\":{\"public_key\":%zu,\"secret_key\":%zu,\"signature\":%zu},", + sig->length_public_key, sig->length_secret_key, sig->length_signature); + printf("\"operations\":{"); + stats_t s; + s=compute_stats(kg.all,kg.all_n); print_stats_json(stdout,"keygen",s,&kg); printf(","); + s=compute_stats(sg.all,sg.all_n); print_stats_json(stdout,"sign",s,&sg); printf(","); + s=compute_stats(vf.all,vf.all_n); print_stats_json(stdout,"verify",s,&vf); + printf("}}\n"); + + free(kg.all); free(sg.all); free(vf.all); + free(x.pk); free(x.sk); free(x.msg); free(x.sg); + free(x.pk_s); free(x.sk_s); free(x.sg_s); + OQS_SIG_free(sig); + return 0; +} + +/* ======================= OpenSSL classical baselines ===================== */ +/* X25519 as a KEM-analog: keygen + ECDH derive (one shared-secret derivation). */ +typedef struct { EVP_PKEY *self; EVP_PKEY *peer; } x25519_ctx; +static int x25519_keygen(void *c){ + x25519_ctx*x=c; + if (x->self) { EVP_PKEY_free(x->self); x->self=NULL; } + EVP_PKEY_CTX *p = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519,NULL); + if(!p) return 1; + int ok = EVP_PKEY_keygen_init(p)>0 && EVP_PKEY_keygen(p,&x->self)>0; + EVP_PKEY_CTX_free(p); + return ok?0:1; +} +/* derive shared secret a·b into out[32]; returns 1 on success */ +static int x25519_derive_into(EVP_PKEY *a, EVP_PKEY *b, unsigned char out[32]){ + EVP_PKEY_CTX *p = EVP_PKEY_CTX_new(a,NULL); + if(!p) return 0; + size_t slen=32; + int ok = EVP_PKEY_derive_init(p)>0 && + EVP_PKEY_derive_set_peer(p,b)>0 && + EVP_PKEY_derive(p,out,&slen)>0; + EVP_PKEY_CTX_free(p); + return ok; +} +static int x25519_derive(void *c){ + x25519_ctx*x=c; + unsigned char secret[32]; + if(!x25519_derive_into(x->self,x->peer,secret)) return 1; + g_sink += secret[0]; /* sink the derived shared secret */ + return 0; +} + +static int run_x25519(const bench_cfg *cfg) { + x25519_ctx x={0}; + if (x25519_keygen(&x) != 0) die("X25519","keygen failed"); /* self */ + /* a fixed peer key for derive */ + EVP_PKEY_CTX *p = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519,NULL); + if(!p || EVP_PKEY_keygen_init(p)<=0 || EVP_PKEY_keygen(p,&x.peer)<=0) die("X25519","peer keygen failed"); + EVP_PKEY_CTX_free(p); + + /* ---- correctness check (ONCE, outside timing): ECDH must agree ---- */ + { + unsigned char sa[32], sb[32]; + if (!x25519_derive_into(x.self, x.peer, sa)) die("X25519","derive(self,peer) failed"); + if (!x25519_derive_into(x.peer, x.self, sb)) die("X25519","derive(peer,self) failed"); + if (memcmp(sa, sb, 32) != 0) die("X25519","ECDH shared-secret mismatch"); + } + + measure_out kg={0}, dv={0}; + must_measure("X25519","keygen",x25519_keygen,&x,cfg,&kg); + /* keygen frees+replaces self each call; re-make a stable self for derive */ + if (x25519_keygen(&x) != 0) die("X25519","keygen failed"); + must_measure("X25519","derive",x25519_derive,&x,cfg,&dv); + + printf("{\"alg\":\"X25519\",\"kind\":\"kem\",\"backend\":\"openssl\",\"classical\":true,\"enabled\":true,"); + printf("\"claimed_nist_level\":1,"); + printf("\"sizes\":{\"public_key\":32,\"secret_key\":32,\"ciphertext\":null,\"shared_secret\":32},"); + printf("\"operations\":{"); + stats_t s; + s=compute_stats(kg.all,kg.all_n); print_stats_json(stdout,"keygen",s,&kg); printf(","); + s=compute_stats(dv.all,dv.all_n); print_stats_json(stdout,"derive",s,&dv); + printf("}}\n"); + free(kg.all); free(dv.all); + if(x.self)EVP_PKEY_free(x.self); if(x.peer)EVP_PKEY_free(x.peer); + return 0; +} + +/* Ed25519 signature baseline. */ +typedef struct { EVP_PKEY *key; unsigned char msg[32]; unsigned char sig[64]; size_t siglen; } ed_ctx; +static int ed_keygen(void *c){ + ed_ctx*x=c; + if(x->key){EVP_PKEY_free(x->key);x->key=NULL;} + EVP_PKEY_CTX *p=EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519,NULL); + if(!p)return 1; + int ok=EVP_PKEY_keygen_init(p)>0 && EVP_PKEY_keygen(p,&x->key)>0; + EVP_PKEY_CTX_free(p); + return ok?0:1; +} +static int ed_sign(void *c){ + ed_ctx*x=c; + EVP_MD_CTX *m=EVP_MD_CTX_new(); if(!m)return 1; + x->siglen=sizeof x->sig; + int ok = EVP_DigestSignInit(m,NULL,NULL,NULL,x->key)>0 && + EVP_DigestSign(m,x->sig,&x->siglen,x->msg,sizeof x->msg)>0; + EVP_MD_CTX_free(m); + if(!ok) return 1; + g_sink += x->sig[0]; /* sink the signature */ + return 0; +} +static int ed_verify(void *c){ + ed_ctx*x=c; + EVP_MD_CTX *m=EVP_MD_CTX_new(); if(!m)return 1; + int ok = EVP_DigestVerifyInit(m,NULL,NULL,NULL,x->key)>0 && + EVP_DigestVerify(m,x->sig,x->siglen,x->msg,sizeof x->msg)>0; + EVP_MD_CTX_free(m); + if(!ok) return 1; + g_sink += 1; /* sink the (successful) verify result */ + return 0; +} + +static int run_ed25519(const bench_cfg *cfg) { + ed_ctx x; memset(&x,0,sizeof x); memset(x.msg,0xA5,sizeof x.msg); + + /* ---- correctness check (ONCE, outside timing): verify MUST succeed ---- */ + if (ed_keygen(&x) != 0) die("Ed25519","keygen failed"); + if (ed_sign(&x) != 0) die("Ed25519","sign failed"); + if (ed_verify(&x) != 0) die("Ed25519","verify failed on a valid signature (broken build)"); + + measure_out kg={0}, sg={0}, vf={0}; + must_measure("Ed25519","keygen",ed_keygen,&x,cfg,&kg); + if (ed_keygen(&x)!=0 || ed_sign(&x)!=0) die("Ed25519","re-priming key+sig failed"); + must_measure("Ed25519","sign", ed_sign, &x,cfg,&sg); + must_measure("Ed25519","verify",ed_verify,&x,cfg,&vf); + + printf("{\"alg\":\"Ed25519\",\"kind\":\"sig\",\"backend\":\"openssl\",\"classical\":true,\"enabled\":true,"); + printf("\"claimed_nist_level\":1,"); + printf("\"sizes\":{\"public_key\":32,\"secret_key\":32,\"signature\":64},"); + printf("\"operations\":{"); + stats_t s; + s=compute_stats(kg.all,kg.all_n); print_stats_json(stdout,"keygen",s,&kg); printf(","); + s=compute_stats(sg.all,sg.all_n); print_stats_json(stdout,"sign",s,&sg); printf(","); + s=compute_stats(vf.all,vf.all_n); print_stats_json(stdout,"verify",s,&vf); + printf("}}\n"); + free(kg.all); free(sg.all); free(vf.all); + if(x.key)EVP_PKEY_free(x.key); + return 0; +} + +/* ---- main --------------------------------------------------------------- */ +static void usage(void){ + fprintf(stderr, + "usage: bench_pq --kind kem|sig --alg NAME [options]\n" + " auto-calibration (default): each op is timed to ~--target-time-ms of\n" + " aggregate work, clamped to [--min-samples, --max-iters].\n" + " --target-time-ms N per-op timed-work target (default 250)\n" + " --min-samples N floor on timed iters per rep (default 30)\n" + " --max-iters N ceiling on timed iters per rep (default 20000)\n" + " --reps N independent repetitions (default 5)\n" + " --iters N FIXED-count fallback: exactly N timed iters/rep\n" + " (disables calibration; pairs with --warmup)\n" + " --warmup N warmup iters/rep in fixed-count mode (default 1000)\n"); +} + +int main(int argc, char **argv) { + const char *kind=NULL, *alg=NULL; + /* fixed-count fallback knobs */ + uint64_t warmup=1000, iters=0, reps=5; /* iters=0 => auto-calibrate */ + /* auto-calibration knobs */ + uint64_t target_time_ms=250, min_samples=30, max_iters=20000; + for (int i=1;i0 => fixed-count mode */ + .target_ns = target_time_ms * 1000000ull, + .min_samples = min_samples, + .max_iters = max_iters, + .warmup = warmup, + .reps = reps, + }; + if (iters>0) + fprintf(stderr,"[bench_pq] mode=fixed-count reps=%llu warmup=%llu iters=%llu\n", + (unsigned long long)reps,(unsigned long long)warmup,(unsigned long long)iters); + else + fprintf(stderr,"[bench_pq] mode=auto-calibrate reps=%llu target=%llums min_samples=%llu max_iters=%llu\n", + (unsigned long long)reps,(unsigned long long)target_time_ms, + (unsigned long long)min_samples,(unsigned long long)max_iters); + + /* PMU cycle availability probe (reported once via stderr-free channel: + * embedded into the JSON header line below). */ + const char *pmu_reason=NULL; + int pmu_ok = probe_pmu(&pmu_reason); + fprintf(stderr,"[bench_pq] cycles_available=%d (%s)\n", pmu_ok, pmu_reason); + + OQS_init(); + int rc; + if(!strcmp(kind,"kem")){ + if(!strcmp(alg,"X25519")) rc=run_x25519(&cfg); + else rc=run_kem(alg,&cfg); + } else if(!strcmp(kind,"sig")){ + if(!strcmp(alg,"Ed25519")) rc=run_ed25519(&cfg); + else rc=run_sig(alg,&cfg); + } else { usage(); rc=2; } + OQS_destroy(); + return rc; +} diff --git a/pq-bench-rpi5/bench/lib/assemble.py b/pq-bench-rpi5/bench/lib/assemble.py new file mode 100644 index 0000000..9fc5c8b --- /dev/null +++ b/pq-bench-rpi5/bench/lib/assemble.py @@ -0,0 +1,245 @@ +#!/usr/bin/env python3 +"""assemble.py — merge harness outputs + thermal trace + environment metadata +into one results JSON with full provenance. + +Inputs (all paths): + --meta meta.env KEY=VALUE run/host facts collected by run.sh + --lock versions.lock toolchain provenance from setup.sh + --features cpu_features.json CPU/crypto-extension detection (from run.sh) + --kemsig kemsig.jsonl one JSON object per algorithm from bench_pq + --tls tls.json output of the TLS harness (optional) + --thermal thermal.csv epoch_s,arm_clock_hz,temp_c,throttled_hex samples + --out results/-.json + +The single most important output field is `is_baseline_grade`: true ONLY on a +real RPi5 with performance governor, core pinning, A76-targeted flags, and no +thermal throttling. Everything else (notably macOS smoke runs) is false, with +reasons recorded — so smoke output can never be mistaken for the baseline. +""" +from __future__ import annotations +import argparse +import json +import os +import statistics +import sys + +SCHEMA_VERSION = "1.0.0" + + +def parse_envfile(path: str) -> dict: + """Parse KEY=VALUE / KEY="value" lines (shared format of meta.env + versions.lock).""" + out = {} + if not path or not os.path.exists(path): + return out + with open(path) as f: + for line in f: + line = line.strip() + if not line or line.startswith("#") or "=" not in line: + continue + k, v = line.split("=", 1) + v = v.strip() + if len(v) >= 2 and v[0] == v[-1] and v[0] in "\"'": + v = v[1:-1] + out[k.strip()] = v + return out + + +def load_jsonl(path: str) -> list: + items = [] + if not path or not os.path.exists(path): + return items + with open(path) as f: + for line in f: + line = line.strip() + if line: + try: + items.append(json.loads(line)) + except json.JSONDecodeError as e: + print(f"[assemble] skipping bad JSONL line: {e}", file=sys.stderr) + return items + + +def load_json(path: str): + if path and os.path.exists(path): + with open(path) as f: + return json.load(f) + return None + + +def parse_thermal(path: str) -> dict: + """Reduce the raw CSV trace to a compact embedded record + summary.""" + cols = ["epoch_s", "arm_clock_hz", "temp_c", "throttled_hex"] + samples, temps, clocks = [], [], [] + throttling_detected = False + if path and os.path.exists(path): + with open(path) as f: + for line in f: + parts = line.strip().split(",") + if len(parts) != 4: + continue + ep, clk, temp, thr = parts + samples.append([ + int(ep) if ep else None, + int(clk) if clk else None, + float(temp) if temp else None, + thr or None, + ]) + if temp: + temps.append(float(temp)) + if clk: + clocks.append(int(clk)) + if thr: + try: + v = int(thr, 16) + # bit2 = throttling now, bit18 = throttling has occurred + if v & 0x4 or v & 0x40000: + throttling_detected = True + except ValueError: + pass + + def summarize(vals): + if not vals: + return None + return { + "min": min(vals), "max": max(vals), + "mean": round(statistics.fmean(vals), 3), + "samples": len(vals), + } + + clock_summary = summarize(clocks) + # Detect frequency droop as a secondary throttling signal. + if clock_summary and clocks: + spread = (max(clocks) - min(clocks)) / max(clocks) + clock_summary["spread_frac"] = round(spread, 4) + + return { + "columns": cols, + "samples": samples, + "temp_c": summarize(temps), + "arm_clock_hz": clock_summary, + "throttling_detected": throttling_detected, + } + + +def to_int(s, default=None): + try: + return int(s) + except (TypeError, ValueError): + return default + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--meta", required=True) + ap.add_argument("--lock", default="") + ap.add_argument("--features", default="") + ap.add_argument("--kemsig", default="") + ap.add_argument("--tls", default="") + ap.add_argument("--thermal", default="") + ap.add_argument("--config", default="") + ap.add_argument("--out", required=True) + args = ap.parse_args() + + meta = parse_envfile(args.meta) + lock = parse_envfile(args.lock) + features = load_json(args.features) or {} + kemsig = load_jsonl(args.kemsig) + tls = load_json(args.tls) + thermal = parse_thermal(args.thermal) + + is_rpi = meta.get("IS_RPI") == "1" + governor = meta.get("GOVERNOR_AFTER") or meta.get("GOVERNOR_BEFORE") or "unknown" + pinned = meta.get("PINNED") == "1" + cflags_target = lock.get("CFLAGS_TARGET", "unknown") + + # ---- the anti-confusion gate ----------------------------------------- + baseline_reasons = [] + if not is_rpi: + baseline_reasons.append( + f"host is not a Raspberry Pi (model='{meta.get('RPI_MODEL','')}', os={meta.get('OS')})") + if governor != "performance": + baseline_reasons.append(f"CPU governor is '{governor}', not 'performance'") + if not pinned: + baseline_reasons.append("benchmark was not pinned to a dedicated core (no taskset)") + if cflags_target != "cortex-a76": + baseline_reasons.append(f"build flags targeted '{cflags_target}', not cortex-a76") + if thermal.get("throttling_detected"): + baseline_reasons.append("thermal throttling was detected during the run") + is_baseline_grade = len(baseline_reasons) == 0 + + warnings = [] + raw_warn = meta.get("WARNINGS", "") + if raw_warn: + warnings.extend([w for w in raw_warn.split("||") if w]) + if not is_baseline_grade: + warnings.append("NOT RPi5-baseline-grade: " + "; ".join(baseline_reasons)) + + result = { + "schema_version": SCHEMA_VERSION, + "tool_version": meta.get("TOOL_VERSION", "0.1.0"), + "generated_utc": meta.get("TS_END_UTC", ""), + "is_baseline_grade": is_baseline_grade, + "baseline_grade_reasons": baseline_reasons, + "host": { + "hostname": meta.get("HOSTNAME", ""), + "os": meta.get("OS", ""), + "os_pretty": meta.get("OS_PRETTY", ""), + "arch": meta.get("ARCH", ""), + "kernel": meta.get("KERNEL", ""), + "is_rpi": is_rpi, + "rpi_model": meta.get("RPI_MODEL", ""), + "cpu_brand": meta.get("CPU_BRAND", ""), + "ncpu": to_int(meta.get("NCPU")), + "ram_bytes": to_int(meta.get("RAM_BYTES")), + }, + "cpu_features": features, + "run": { + "timestamp_start_utc": meta.get("TS_START_UTC", ""), + "timestamp_end_utc": meta.get("TS_END_UTC", ""), + "duration_s": to_int(meta.get("DURATION_S")), + "governor_requested": meta.get("GOVERNOR_REQUESTED", ""), + "governor_before": meta.get("GOVERNOR_BEFORE", ""), + "governor_after": meta.get("GOVERNOR_AFTER", ""), + "bench_core": to_int(meta.get("BENCH_CORE")), + "pinned": pinned, + "taskset_cmd": meta.get("TASKSET_CMD", ""), + # Per-op sizing. In auto-calibration mode warmup_iters/timed_iters are + # chosen per operation (see each entry under kem/sig "operations"); + # the run-level target/min/max below describe how they were derived. + "calibration_mode": meta.get("CALIB_MODE", "auto"), + "target_time_ms": to_int(meta.get("TARGET_TIME_MS")), + "min_samples": to_int(meta.get("MIN_SAMPLES")), + "max_iters": to_int(meta.get("MAX_ITERS")), + "warmup_iters": to_int(meta.get("WARMUP")), + "timed_iters": to_int(meta.get("ITERS")), + "repetitions": to_int(meta.get("REPS")), + "cycles_mode": meta.get("CYCLES_MODE", ""), + "cycles_available": meta.get("CYCLES_AVAILABLE") == "1", + "cycles_reason": meta.get("CYCLES_REASON", ""), + }, + "toolchain": { + "cc_version": lock.get("CC_VERSION", ""), + "bench_cflags": lock.get("BENCH_CFLAGS", ""), + "cflags_target": cflags_target, + "liboqs_ref": lock.get("LIBOQS_REF", ""), + "liboqs_commit": lock.get("LIBOQS_COMMIT", ""), + "liboqs_opt_defines": lock.get("LIBOQS_OPT_DEFINES", ""), + "openssl": lock.get("OPENSSL_COMMIT", ""), + "oqsprovider_ref": lock.get("OQSPROVIDER_REF", ""), + "oqsprovider_commit": lock.get("OQSPROVIDER_COMMIT", ""), + }, + "thermal_trace": thermal, + "warnings": warnings, + "kem": [r for r in kemsig if r.get("kind") == "kem"], + "sig": [r for r in kemsig if r.get("kind") == "sig"], + "tls": tls, + } + + os.makedirs(os.path.dirname(args.out) or ".", exist_ok=True) + with open(args.out, "w") as f: + json.dump(result, f, indent=2) + print(args.out) + + +if __name__ == "__main__": + main() diff --git a/pq-bench-rpi5/bench/lib/list_algs.py b/pq-bench-rpi5/bench/lib/list_algs.py new file mode 100644 index 0000000..5dcbc63 --- /dev/null +++ b/pq-bench-rpi5/bench/lib/list_algs.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +"""list_algs.py — expand config.yaml into shell-consumable lines for run.sh. + +Modes: + measurement -> KEY=VALUE lines (auto-calib: target/min_samples/max_iters/ + reps/cycles_mode; plus warmup/iters fixed-count fallback) + kemsig -> one "kindalgis_classical" line per algorithm, + baselines first (so charts always have the reference point) + tls -> emits the TLS matrix as JSON on one line + +Uses the dependency-free miniyaml parser so no PyYAML is required. +""" +import os +import sys +import json + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +import miniyaml # noqa: E402 + + +def main(): + mode = sys.argv[1] if len(sys.argv) > 1 else "kemsig" + cfg_path = sys.argv[2] if len(sys.argv) > 2 else "config.yaml" + cfg = miniyaml.load_file(cfg_path) + + if mode == "measurement": + m = cfg.get("measurement", {}) or {} + # auto-calibration knobs (default path) + print(f"TARGET_TIME_MS={m.get('target_time_ms', 250)}") + print(f"MIN_SAMPLES={m.get('min_samples', 30)}") + print(f"MAX_ITERS={m.get('max_iters', 20000)}") + print(f"REPS={m.get('repetitions', 5)}") + print(f"CYCLES_MODE={m.get('cycles_mode', 'auto')}") + # fixed-count fallback knobs (used only with ./run.sh --iters) + print(f"WARMUP={m.get('warmup_iters', 1000)}") + print(f"ITERS={m.get('timed_iters', 10000)}") + + elif mode == "kemsig": + for kind in ("kem", "sig"): + section = cfg.get(kind, {}) or {} + for grp in ("baseline", "candidates"): + for item in (section.get(grp) or []): + if isinstance(item, dict): + name = item.get("name") + classical = "1" if item.get("classical") else "0" + else: + name, classical = item, "0" + if name: + print(f"{kind}\t{name}\t{classical}") + + elif mode == "tls": + print(json.dumps(cfg.get("tls", {}))) + + else: + sys.exit(f"unknown mode: {mode}") + + +if __name__ == "__main__": + main() diff --git a/pq-bench-rpi5/bench/lib/miniyaml.py b/pq-bench-rpi5/bench/lib/miniyaml.py new file mode 100644 index 0000000..03ee6be --- /dev/null +++ b/pq-bench-rpi5/bench/lib/miniyaml.py @@ -0,0 +1,151 @@ +"""miniyaml — a dependency-free parser for the restricted YAML subset used by +config.yaml. + +We deliberately avoid a PyYAML runtime dependency so the core pipeline runs on a +stock Python 3 (the RPi5 / Mac smoke box both have only stdlib by default). + +Supported subset (sufficient for config.yaml): + - nested mappings via indentation (2 spaces per level by convention) + - lists of scalars: "- value" + - lists of mappings: "- key: value" then indented "key: value" + - scalars: int, float, bool (true/false), null/~, quoted or bare strings + - "# comment" to end of line (outside quotes) + +It is NOT a general YAML implementation. If a user needs full YAML they can +install PyYAML and set PQB_USE_PYYAML=1. +""" +from __future__ import annotations +import os +import re + + +def _scalar(tok: str): + s = tok.strip() + if s == "" or s in ("~", "null", "Null", "NULL"): + return None + if (s[0] == '"' and s[-1] == '"') or (s[0] == "'" and s[-1] == "'"): + return s[1:-1] + low = s.lower() + if low in ("true", "yes"): + return True + if low in ("false", "no"): + return False + if re.fullmatch(r"[+-]?\d+", s): + return int(s) + if re.fullmatch(r"[+-]?\d*\.\d+([eE][+-]?\d+)?", s): + return float(s) + return s + + +def _strip_comment(line: str) -> str: + out, q = [], None + for ch in line: + if q: + out.append(ch) + if ch == q: + q = None + elif ch in ("'", '"'): + q = ch + out.append(ch) + elif ch == "#": + break + else: + out.append(ch) + return "".join(out).rstrip() + + +def _indent(line: str) -> int: + return len(line) - len(line.lstrip(" ")) + + +def loads(text: str): + # Tokenize into (indent, content) ignoring blank/comment-only lines. + lines = [] + for raw in text.splitlines(): + c = _strip_comment(raw) + if c.strip() == "": + continue + lines.append((_indent(c), c.strip(), c)) + pos = [0] + + def parse_block(min_indent: int): + if pos[0] >= len(lines): + return None + indent = lines[pos[0]][0] + if lines[pos[0]][1].startswith("- "): + return parse_list(indent) + return parse_map(indent) + + def parse_map(indent: int): + obj = {} + while pos[0] < len(lines): + ind, stripped, _ = lines[pos[0]] + if ind < indent or stripped.startswith("- "): + break + if ind > indent: # malformed; skip + pos[0] += 1 + continue + m = re.match(r"^([^:]+):\s*(.*)$", stripped) + if not m: + pos[0] += 1 + continue + key, val = m.group(1).strip(), m.group(2) + pos[0] += 1 + if val == "": + # nested block or empty + if pos[0] < len(lines) and lines[pos[0]][0] > indent: + obj[key] = parse_block(indent + 1) + else: + obj[key] = None + else: + obj[key] = _scalar(val) + return obj + + def parse_list(indent: int): + arr = [] + while pos[0] < len(lines): + ind, stripped, _ = lines[pos[0]] + if ind < indent or not stripped.startswith("- "): + break + if ind > indent: + break + item = stripped[2:].strip() + pos[0] += 1 + if ":" in item and not (item[0] in "'\""): + # list of mappings — first pair is inline, rest are indented deeper + sub = {} + m = re.match(r"^([^:]+):\s*(.*)$", item) + key, val = m.group(1).strip(), m.group(2) + sub[key] = _scalar(val) if val != "" else None + child_indent = indent + 2 + while pos[0] < len(lines) and lines[pos[0]][0] >= child_indent \ + and not lines[pos[0]][1].startswith("- "): + ind2, strip2, _ = lines[pos[0]] + m2 = re.match(r"^([^:]+):\s*(.*)$", strip2) + if not m2: + pos[0] += 1 + continue + k2, v2 = m2.group(1).strip(), m2.group(2) + pos[0] += 1 + sub[k2] = _scalar(v2) if v2 != "" else None + arr.append(sub) + else: + arr.append(_scalar(item)) + return arr + + return parse_block(0) or {} + + +def load_file(path: str): + if os.environ.get("PQB_USE_PYYAML") == "1": + import yaml # type: ignore + with open(path) as f: + return yaml.safe_load(f) + with open(path) as f: + return loads(f.read()) + + +if __name__ == "__main__": + import json + import sys + print(json.dumps(load_file(sys.argv[1]), indent=2)) diff --git a/pq-bench-rpi5/bench/tls/Makefile b/pq-bench-rpi5/bench/tls/Makefile new file mode 100644 index 0000000..5fcaf03 --- /dev/null +++ b/pq-bench-rpi5/bench/tls/Makefile @@ -0,0 +1,17 @@ +# Build the TLS handshake harness against the OpenSSL that has oqs-provider. +# make OPENSSL_PREFIX=... (defaults to Homebrew openssl@3, else system) + +OPENSSL_PREFIX ?= $(shell brew --prefix openssl@3 2>/dev/null || echo /usr) + +CC ?= cc +CFLAGS := -O3 -std=c11 -Wall -Wextra -I$(OPENSSL_PREFIX)/include +LDFLAGS := -L$(OPENSSL_PREFIX)/lib -Wl,-rpath,$(OPENSSL_PREFIX)/lib +LDLIBS := -lssl -lcrypto -lm + +bench_tls: bench_tls.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDLIBS) + +clean: + rm -f bench_tls + +.PHONY: clean diff --git a/pq-bench-rpi5/bench/tls/bench_tls.c b/pq-bench-rpi5/bench/tls/bench_tls.c new file mode 100644 index 0000000..6d2481e --- /dev/null +++ b/pq-bench-rpi5/bench/tls/bench_tls.c @@ -0,0 +1,194 @@ +/* =========================================================================== + * bench_tls.c — TLS 1.3 handshake benchmark via the OpenSSL API. + * + * Performs full TLS 1.3 handshakes entirely in-process over a pair of memory + * BIOs (no sockets, no CLI scraping). This gives: + * - clean per-handshake wall-clock latency (no socket/scheduler noise) + * - exact bytes-on-the-wire each direction + * - the precise ClientHello flight size (with a fragmentation note vs MSS) + * - real server-cert signature verification cost (client verifies the chain), + * which is the whole point of sweeping PQ signature algorithms. + * + * bench_tls --group X25519MLKEM768 --ca ca.pem \ + * --cert server.pem --key server.key --connections 1000 \ + * --label "X25519MLKEM768+mldsa65" + * + * Emits one JSON object. PQ groups/sigs require oqs-provider to be loadable + * (point OPENSSL_MODULES at its directory); if it cannot load, we say so. + * ===========================================================================*/ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define TYPICAL_MSS 1400 /* note fragmentation when ClientHello exceeds this */ + +static inline uint64_t now_ns(void) { + struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t)ts.tv_sec * 1000000000ull + (uint64_t)ts.tv_nsec; +} + +static int cmp_u64(const void *a, const void *b) { + uint64_t x = *(const uint64_t *)a, y = *(const uint64_t *)b; + return (x > y) - (x < y); +} +static double pct(const uint64_t *s, uint64_t n, double p) { + if (!n) return 0; if (n == 1) return (double)s[0]; + double idx = p * (double)(n - 1); uint64_t lo = (uint64_t)idx; double f = idx - lo; + if (lo + 1 >= n) return (double)s[n - 1]; + return (double)s[lo] + f * ((double)s[lo + 1] - (double)s[lo]); +} + +/* Shuttle all pending bytes from src's mem BIO into dst's mem BIO. + * Returns bytes moved. */ +static size_t pump(BIO *src, BIO *dst) { + char buf[16384]; size_t total = 0; int n; + while ((n = BIO_read(src, buf, sizeof buf)) > 0) { + BIO_write(dst, buf, n); + total += (size_t)n; + } + return total; +} + +/* One full handshake. Records bytes each way and ClientHello size (first flight). + * Returns 0 on success. */ +static int one_handshake(SSL_CTX *cctx, SSL_CTX *sctx, + size_t *c2s_bytes, size_t *s2c_bytes, size_t *chello) { + SSL *cli = SSL_new(cctx), *srv = SSL_new(sctx); + if (!cli || !srv) { if (cli) SSL_free(cli); if (srv) SSL_free(srv); return -1; } + BIO *cli_rb = BIO_new(BIO_s_mem()), *cli_wb = BIO_new(BIO_s_mem()); + BIO *srv_rb = BIO_new(BIO_s_mem()), *srv_wb = BIO_new(BIO_s_mem()); + SSL_set_bio(cli, cli_rb, cli_wb); /* takes ownership */ + SSL_set_bio(srv, srv_rb, srv_wb); + SSL_set_connect_state(cli); + SSL_set_accept_state(srv); + + *c2s_bytes = *s2c_bytes = *chello = 0; + int first_flight = 1, rc = 0; + for (int i = 0; i < 64; i++) { + int r_c = SSL_do_handshake(cli); + size_t moved = pump(cli_wb, srv_rb); + if (first_flight && moved > 0) { *chello = moved; first_flight = 0; } + *c2s_bytes += moved; + (void)r_c; + + int r_s = SSL_do_handshake(srv); + *s2c_bytes += pump(srv_wb, cli_rb); + (void)r_s; + + if (SSL_is_init_finished(cli) && SSL_is_init_finished(srv)) break; + /* if both stalled with nothing to transfer, it's a failure */ + if (BIO_ctrl_pending(cli_wb) == 0 && BIO_ctrl_pending(srv_wb) == 0 && + !SSL_is_init_finished(cli) && i > 4) { rc = -2; break; } + } + if (!SSL_is_init_finished(cli) || !SSL_is_init_finished(srv)) rc = -2; + SSL_free(cli); SSL_free(srv); + return rc; +} + +int main(int argc, char **argv) { + const char *group = "X25519", *ca = NULL, *cert = NULL, *key = NULL, *label = ""; + uint64_t connections = 1000, warmup = 20; + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "--group") && i+1 exercises PQ signature verify cost */ + int verify_setup = 1; + if (ca) { + if (SSL_CTX_load_verify_locations(cctx, ca, NULL) != 1) verify_setup = 0; + SSL_CTX_set_verify(cctx, SSL_VERIFY_PEER, NULL); + } else { + SSL_CTX_set_verify(cctx, SSL_VERIFY_NONE, NULL); + } + + if (!group_ok || !cert_ok || !verify_setup) { + printf("{\"label\":\"%s\",\"group\":\"%s\",\"enabled\":false,\"have_oqs_provider\":%s," + "\"reason\":\"%s%s%s\"}\n", + label, group, have_oqs?"true":"false", + group_ok?"":"group-not-supported ", + cert_ok?"":"cert-load-failed ", + verify_setup?"":"ca-load-failed"); + ERR_print_errors_fp(stderr); + return 0; + } + + /* warmup */ + size_t c2s, s2c, ch; + for (uint64_t i = 0; i < warmup; i++) { + if (one_handshake(cctx, sctx, &c2s, &s2c, &ch) != 0) { + printf("{\"label\":\"%s\",\"group\":\"%s\",\"enabled\":false," + "\"have_oqs_provider\":%s,\"reason\":\"handshake failed\"}\n", + label, group, have_oqs?"true":"false"); + ERR_print_errors_fp(stderr); + return 0; + } + } + + uint64_t *lat = malloc(connections * sizeof(uint64_t)); + size_t ch_last = 0, c2s_last = 0, s2c_last = 0; + uint64_t ok = 0; + for (uint64_t i = 0; i < connections; i++) { + uint64_t t0 = now_ns(); + int rc = one_handshake(cctx, sctx, &c2s, &s2c, &ch); + uint64_t dt = now_ns() - t0; + if (rc == 0) { lat[ok++] = dt; ch_last = ch; c2s_last = c2s; s2c_last = s2c; } + } + if (ok == 0) { fprintf(stderr,"all handshakes failed\n"); return 1; } + qsort(lat, ok, sizeof(uint64_t), cmp_u64); + double median = pct(lat, ok, 0.5); + double p95 = pct(lat, ok, 0.95); + double mn = (double)lat[0], mx = (double)lat[ok-1]; + double sum=0; for (uint64_t i=0;i1?sqrt(ss/(ok-1)):0; + double hs_per_sec = median>0 ? 1e9/median : 0; + + printf("{\"label\":\"%s\",\"group\":\"%s\",\"enabled\":true,\"have_oqs_provider\":%s,", + label, group, have_oqs?"true":"false"); + printf("\"connections\":%llu,\"succeeded\":%llu,", (unsigned long long)connections,(unsigned long long)ok); + printf("\"handshake_latency_ns\":{\"median\":%.1f,\"p95\":%.1f,\"min\":%.1f,\"max\":%.1f,\"mean\":%.1f,\"stddev\":%.1f},", + median,p95,mn,mx,mean,stddev); + printf("\"handshakes_per_sec\":%.1f,", hs_per_sec); + printf("\"bytes_on_wire\":{\"client_to_server\":%zu,\"server_to_client\":%zu,\"total\":%zu},", + c2s_last, s2c_last, c2s_last+s2c_last); + printf("\"client_hello_bytes\":%zu,\"client_hello_fragmented\":%s,\"mss_assumed\":%d}\n", + ch_last, ch_last>TYPICAL_MSS?"true":"false", TYPICAL_MSS); + free(lat); + return 0; +} diff --git a/pq-bench-rpi5/bench/tls/run_tls.sh b/pq-bench-rpi5/bench/tls/run_tls.sh new file mode 100755 index 0000000..82466f2 --- /dev/null +++ b/pq-bench-rpi5/bench/tls/run_tls.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash +# ============================================================================= +# run_tls.sh — generate PKI and run the TLS 1.3 (KEM-group x signature) matrix. +# +# Always benchmarks the classical Logos baseline (X25519 key exchange + Ed25519 +# server auth) using stock OpenSSL. PQ rows additionally require oqs-provider to +# be loadable; if it is not present we record those rows as unavailable (with a +# reason) rather than failing — so this still smoke-tests cleanly on a dev box. +# +# ./run_tls.sh --out tls.json --connections 1000 +# +# Honors $PQB_TASKSET (a taskset/numactl prefix) to pin bench_tls to a core. +# ============================================================================= +set -euo pipefail + +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT="$(cd "$HERE/../.." && pwd)" +# shellcheck source=setup/lib_platform.sh +source "$ROOT/setup/lib_platform.sh" +LOCK="$ROOT/setup/versions.lock" +# shellcheck disable=SC1090 +[ -f "$LOCK" ] && source "$LOCK" || true +pqb_detect_platform + +OUT=""; CONNS=1000; WARMUP=20 +while [ $# -gt 0 ]; do + case "$1" in + --out) OUT="$2"; shift ;; + --connections) CONNS="$2"; shift ;; + --warmup) WARMUP="$2"; shift ;; + *) pqb_err "unknown arg: $1"; exit 2 ;; + esac + shift +done +[ -n "$OUT" ] || { pqb_err "--out required"; exit 2; } + +TASKSET="${PQB_TASKSET:-}" + +# ---- choose the OpenSSL that has the provider ------------------------------ +OSSL="${OPENSSL_BIN:-$(command -v openssl)}" +OSSL_PREFIX="${OPENSSL_PREFIX:-$(brew --prefix openssl@3 2>/dev/null || echo /usr)}" +PROV_MODULE="${OQSPROVIDER_MODULE:-}" +PROV_ARGS="" +HAVE_OQS=0 +if [ -n "$PROV_MODULE" ] && [ -f "$PROV_MODULE" ]; then + export OPENSSL_MODULES="$(dirname "$PROV_MODULE")" + if "$OSSL" list -providers -provider oqsprovider -provider default >/dev/null 2>&1; then + PROV_ARGS="-provider oqsprovider -provider default" + HAVE_OQS=1 + pqb_log "oqs-provider available: $PROV_MODULE" + fi +fi +[ "$HAVE_OQS" = 0 ] && pqb_warn "oqs-provider not available — PQ TLS rows will be marked unavailable (classical baseline still runs)" + +# ---- build the harness ----------------------------------------------------- +make -C "$HERE" OPENSSL_PREFIX="$OSSL_PREFIX" >/dev/null +BENCH="$HERE/bench_tls" +[ -n "$TASKSET" ] && export OPENSSL_MODULES="${OPENSSL_MODULES:-}" + +# ---- PKI workspace --------------------------------------------------------- +PKI="$HERE/pki"; rm -rf "$PKI"; mkdir -p "$PKI" + +# gen_cert [provider] -> CA + server cert/key of that alg +gen_cert() { + local alg="$1" pfx="$2" prov="${3:-}" + local ca_key="$PKI/${pfx}_ca.key" ca_crt="$PKI/${pfx}_ca.pem" + local sv_key="$PKI/${pfx}_server.key" sv_csr="$PKI/${pfx}_server.csr" sv_crt="$PKI/${pfx}_server.pem" + # CA + "$OSSL" req -x509 -new -newkey "$alg" -nodes $prov \ + -keyout "$ca_key" -out "$ca_crt" -days 3650 \ + -subj "/CN=PQB Test CA ($alg)" >/dev/null 2>&1 || return 1 + # server key + CSR + cert signed by CA + "$OSSL" genpkey -algorithm "$alg" $prov -out "$sv_key" >/dev/null 2>&1 || return 1 + "$OSSL" req -new -key "$sv_key" $prov -out "$sv_csr" -subj "/CN=localhost" >/dev/null 2>&1 || return 1 + "$OSSL" x509 -req -in "$sv_csr" -CA "$ca_crt" -CAkey "$ca_key" $prov \ + -out "$sv_crt" -days 3650 -CAcreateserial >/dev/null 2>&1 || return 1 + return 0 +} + +# ---- read config ----------------------------------------------------------- +TLS_JSON="$(python3 "$ROOT/bench/lib/list_algs.py" tls "$ROOT/config.yaml")" +read_list() { python3 -c "import json,sys; print('\n'.join(json.loads(sys.argv[1]).get(sys.argv[2],[])))" "$TLS_JSON" "$1"; } +BASE_KEM="$(python3 -c "import json,sys;print(json.loads(sys.argv[1])['baseline']['kem_group'])" "$TLS_JSON")" +BASE_SIG="$(python3 -c "import json,sys;print(json.loads(sys.argv[1])['baseline']['sig_alg'])" "$TLS_JSON")" + +# ---- generate certs -------------------------------------------------------- +declare -a SIG_OK_ALGS=() +# classical baseline cert (always) +if gen_cert "$BASE_SIG" "base_$BASE_SIG"; then + pqb_log "generated baseline cert ($BASE_SIG)" +else + pqb_err "failed to generate classical baseline cert ($BASE_SIG) — TLS layer cannot run" + echo '{"available":false,"reason":"baseline cert generation failed"}' > "$OUT"; exit 0 +fi +if [ "$HAVE_OQS" = 1 ]; then + while IFS= read -r s; do + [ -z "$s" ] && continue + if gen_cert "$s" "pq_$s" "$PROV_ARGS"; then + SIG_OK_ALGS+=("$s"); pqb_log "generated PQ cert ($s)" + else + pqb_warn "could not generate cert for sig alg '$s' (skipping)" + fi + done < <(read_list sig_algs) +fi + +# cert path helpers +ca_for() { case "$1" in "$BASE_SIG") echo "$PKI/base_${BASE_SIG}_ca.pem";; *) echo "$PKI/pq_${1}_ca.pem";; esac; } +crt_for() { case "$1" in "$BASE_SIG") echo "$PKI/base_${BASE_SIG}_server.pem";; *) echo "$PKI/pq_${1}_server.pem";; esac; } +key_for() { case "$1" in "$BASE_SIG") echo "$PKI/base_${BASE_SIG}_server.key";; *) echo "$PKI/pq_${1}_server.key";; esac; } + +# run one matrix cell -> appends JSON object to $ROWS file +run_cell() { + local kem="$1" sig="$2" + local label="${kem}+${sig}" + # shellcheck disable=SC2086 + $TASKSET "$BENCH" --group "$kem" --ca "$(ca_for "$sig")" \ + --cert "$(crt_for "$sig")" --key "$(key_for "$sig")" \ + --connections "$CONNS" --warmup "$WARMUP" --label "$label" 2>>"$PKI/bench_tls.err" +} + +ROWS="$PKI/rows.jsonl"; : > "$ROWS" + +# baseline row always first +pqb_log "TLS baseline: $BASE_KEM + $BASE_SIG ($CONNS handshakes)" +run_cell "$BASE_KEM" "$BASE_SIG" >> "$ROWS" || pqb_warn "baseline TLS cell failed" + +# PQ matrix: (kem_groups x sig_algs) — only cells whose cert exists +if [ "$HAVE_OQS" = 1 ] && [ "${#SIG_OK_ALGS[@]}" -gt 0 ]; then + while IFS= read -r kem; do + [ -z "$kem" ] && continue + for sig in "${SIG_OK_ALGS[@]}"; do + pqb_log "TLS cell: $kem + $sig" + run_cell "$kem" "$sig" >> "$ROWS" || pqb_warn "cell $kem+$sig failed" + done + done < <(read_list kem_groups) +fi + +# ---- assemble tls.json ----------------------------------------------------- +python3 - "$ROWS" "$OUT" "$HAVE_OQS" "$BASE_KEM" "$BASE_SIG" <<'PY' +import json,sys +rows_path, out_path, have_oqs, base_kem, base_sig = sys.argv[1:6] +rows=[] +with open(rows_path) as f: + for line in f: + line=line.strip() + if line: + try: rows.append(json.loads(line)) + except json.JSONDecodeError: pass +out={ + "available": True, + "have_oqs_provider": have_oqs=="1", + "baseline": {"kem_group": base_kem, "sig_alg": base_sig, "label": f"{base_kem}+{base_sig}"}, + "matrix": rows, +} +json.dump(out, open(out_path,"w"), indent=2) +print(f"wrote {out_path}: {len(rows)} cells (have_oqs={have_oqs})") +PY diff --git a/pq-bench-rpi5/config.yaml b/pq-bench-rpi5/config.yaml new file mode 100644 index 0000000..924d8d9 --- /dev/null +++ b/pq-bench-rpi5/config.yaml @@ -0,0 +1,163 @@ +# ============================================================================= +# pq-bench-rpi5 candidate configuration +# +# This file is the single place users edit to extend the benchmark. The harness +# reads it with a dependency-free YAML subset parser (bench/lib/miniyaml.py), so +# keep to the simple shape used below: top-level maps, lists of scalars, and +# lists of "- key: value" maps. Comments (#) and quotes are fine. +# +# Algorithm names must match liboqs / oqs-provider identifiers exactly. To see +# what your built liboqs supports: ./vendor/liboqs/build/tests/test_kem (lists) +# or check the dashboard's "available algorithms" note after a run. +# ============================================================================= + +# ---- measurement knobs ------------------------------------------------------ +# Default sizing is PER-OPERATION AUTO-CALIBRATION: each op (keygen/encaps/sign/ +# ...) is timed long enough to accumulate ~target_time_ms of work, clamped to +# [min_samples, max_iters]. This makes an 18 us ML-KEM keygen and a ~750 ms +# SLH-DSA sign both yield a stable median without a hand-tuned per-alg count: +# - fast ops are bounded by max_iters +# - slow ops are bounded by min_samples (so even ~1 op per target still gets +# enough samples for a stable median/MAD) +# To force FIXED counts instead, pass `./run.sh --iters N` — that disables +# calibration and uses the warmup_iters/timed_iters fallback below. +measurement: + target_time_ms: 250 # auto: aggregate timed work to put on each op + min_samples: 30 # auto: floor on timed iters/rep (stable median+MAD) + max_iters: 20000 # auto: ceiling on timed iters/rep (caps fast ops) + repetitions: 5 # independent repetitions (fresh process each time) + cycles_mode: auto # auto | on | off (PMU userspace cycle counting) + # ---- fixed-count fallback (only used when ./run.sh --iters is given) ---- + warmup_iters: 1000 # untimed iterations to settle caches/branch predictors + timed_iters: 10000 # timed iterations per repetition + +# ---- security_level (NIST category) ---------------------------------------- +# Every candidate carries `security_level: N` — the NIST PQC category the +# parameter set targets (1/2/3/5) — used only to group algorithms on the charts. +# The mapping is PER-SCHEME, so different schemes reach the same security target +# with different-looking sets: a level 1 sitting next to a level 2 is the real +# NIST categorization, not a typo. Notably: +# - ML-KEM-512, Falcon-512, X25519 -> Category 1 +# - ML-DSA-44 -> Category 2 (FIPS 204 defines NO +# Category-1 ML-DSA; -44 is its +# smallest set and lands at Cat 2) +# - ML-KEM-768 / ML-DSA-65 -> Category 3 +# - ML-KEM-1024 / ML-DSA-87 / Falcon-1024 -> Category 5 +# (NIST levels: 1 ~ AES-128, 2 ~ SHA-256 collision, 3 ~ AES-192, 5 ~ AES-256.) + +# ---- KEMs ------------------------------------------------------------------ +# baseline = the classical reference Logos uses TODAY (drawn on every chart). +kem: + baseline: + - name: X25519 + classical: true + security_level: 1 # NIST category (see "security_level" note above) + candidates: + - name: ML-KEM-512 + security_level: 1 + - name: ML-KEM-768 + security_level: 3 + - name: ML-KEM-1024 + security_level: 5 + # Hybrids (classical + PQ) — these are oqs-provider TLS group names; for the + # raw KEM bench they are skipped unless liboqs exposes them as a KEM. + - name: X25519MLKEM768 + security_level: 3 + hybrid: true + - name: SecP256r1MLKEM768 + security_level: 3 + hybrid: true + # --- Code-based + conservative-LWE backup candidates (added 2026-06) ------- + # Verified enabled in the linked liboqs 0.15.0 build via OQS_KEM_alg_is_enabled + # (oqsconfig.h + runtime cross-check). Keygen/encaps/decaps are reported as + # separate ops so the docs' "keygen is a one-time setup cost" argument can show + # the (slow) McEliece keygen explicitly next to its tiny ciphertext. + # + # Classic McEliece — code-based. Huge public key, TINY ciphertext, very slow + # keygen on the Pi (auto-calibration clamps keygen to min_samples=30, like + # SLH-DSA sign); encaps/decaps are fast and calibrate normally. Standard sets, + # plus the 460896f fast-keygen variant directly next to standard 460896: same + # params and same tiny ciphertext but a faster keygen, so the pair gives the + # keygen trade-off directly (the most useful McEliece data point for the + # migration doc). Other f-variants omitted as redundant. + - name: Classic-McEliece-348864 + security_level: 1 + - name: Classic-McEliece-460896 + security_level: 3 + - name: Classic-McEliece-460896f + security_level: 3 + - name: Classic-McEliece-6688128 + security_level: 5 + - name: Classic-McEliece-6960119 + security_level: 5 + - name: Classic-McEliece-8192128 + security_level: 5 + # FrodoKEM — conservative (unstructured) LWE. ~100x slower encaps/decaps than + # ML-KEM and ~15x larger ciphertext. AES variant (uses ARM AES instructions, + # which this build compiles in); SHAKE variants also available if needed. + - name: FrodoKEM-640-AES + security_level: 1 + - name: FrodoKEM-976-AES + security_level: 3 + - name: FrodoKEM-1344-AES + security_level: 5 + # HQC-128/192/256: NOT enabled in this liboqs 0.15.0 build (disabled upstream + # after the IND-CCA2 implementation issue; oqsconfig.h has it #undef and the + # runtime OQS_KEM_alg_is_enabled returns 0). Intentionally omitted rather than + # listed-and-disabled. Re-add once linked against a liboqs with HQC re-enabled. + +# ---- Signatures ------------------------------------------------------------ +sig: + baseline: + - name: Ed25519 + classical: true + security_level: 1 + candidates: + - name: ML-DSA-44 + security_level: 2 # Cat 2, not 1 — FIPS 204 has no Cat-1 ML-DSA (see note above) + - name: ML-DSA-65 + security_level: 3 + - name: ML-DSA-87 + security_level: 5 + - name: Falcon-512 + security_level: 1 + - name: Falcon-1024 + security_level: 5 + # SLH-DSA (SPHINCS+) — many parameter sets; a representative spread. + - name: SPHINCS+-SHA2-128f-simple + security_level: 1 + - name: SPHINCS+-SHA2-128s-simple + security_level: 1 + - name: SPHINCS+-SHA2-192f-simple + security_level: 3 + - name: SPHINCS+-SHA2-256f-simple + security_level: 5 + # --- extend here --- + +# ---- TLS 1.3 handshake matrix ---------------------------------------------- +# The bench runs (kem_group x sig_alg). The classical baseline pair is ALWAYS +# included as the reference point regardless of what is listed here. +tls: + baseline: + kem_group: X25519 + sig_alg: ed25519 # OpenSSL classical auth Logos uses today + # PQ key-exchange groups to test (oqs-provider TLS group names) + kem_groups: + - X25519MLKEM768 + - SecP256r1MLKEM768 + - mlkem512 + - mlkem768 + - mlkem1024 + # PQ signature algorithms for the server/CA cert (oqs-provider names) + sig_algs: + - mldsa44 + - mldsa65 + - mldsa87 + - falcon512 + - sphincssha2128fsimple + connections: 1000 # handshakes timed against a persistent s_server + +# ---- future phase (NOT implemented now — hooks only) ----------------------- +# zk: +# snark: [] # e.g. groth16, plonk, halo2 +# stark: [] # e.g. risc0, winterfell diff --git a/pq-bench-rpi5/dashboard/app.js b/pq-bench-rpi5/dashboard/app.js new file mode 100644 index 0000000..aaa3c62 --- /dev/null +++ b/pq-bench-rpi5/dashboard/app.js @@ -0,0 +1,304 @@ +/* pq-bench-rpi5 dashboard — pure client-side, reads a merged.json produced by + * analyze/merge.py. No backend. Renders KEM/sig/TLS charts with the classical + * Logos baseline as a reference line on each. Defaults to baseline-grade (RPi5) + * runs only; a toggle includes macOS/dev smoke runs. */ + +const LEVEL_COLORS = { 1:"#3bd67a", 2:"#46c0c0", 3:"#3a7bff", 5:"#b06bff", 0:"#888" }; +const BASE_COLOR = "#e0533d", PQ_COLOR = "#3a7bff"; +let MERGED = null, CHARTS = []; + +const $ = (id) => document.getElementById(id); +const nsToMs = (ns) => (ns || 0) / 1e6; +/* compact ms label: more decimals for small values, fewer for large. Guards its + * input — Chart.js may hand a value-label formatter a parsed {x,y} point or a + * non-number; extract the numeric value without coercing an object (Number() on + * a null-prototype object would itself throw), and return "" for anything not + * finite so the value-label draw never throws and halts later charts. */ +const fmtMs = (v) => { + const ms = typeof v === "number" ? v + : (v && typeof v === "object") ? (typeof v.y === "number" ? v.y : NaN) + : Number(v); + if (!Number.isFinite(ms)) return ""; + return ms>=100?ms.toFixed(0):ms>=10?ms.toFixed(1):ms>=1?ms.toFixed(2):ms.toFixed(3); +}; + +/* Inline Chart.js plugin: draw each bar's value just above the bar. Enabled + * per-chart via options.plugins.valueLabels.formatter; charts that don't set it + * are untouched (TLS/scatter stay clean). No external dependency, so it works + * even when only the Chart.js core CDN is reachable. */ +const valueLabels = { + id: "valueLabels", + afterDatasetsDraw(chart) { + const opt = (chart.options.plugins||{}).valueLabels; + if (!opt || !opt.formatter) return; + const ctx = chart.ctx; + ctx.save(); + ctx.fillStyle = "#e6e8ee"; ctx.font = "10px sans-serif"; + ctx.textAlign = "center"; ctx.textBaseline = "bottom"; + chart.data.datasets.forEach((ds, di) => { + const meta = chart.getDatasetMeta(di); + if (meta.hidden) return; + meta.data.forEach((el, i) => { + const v = ds.data[i]; + if (v == null) return; + ctx.fillText(opt.formatter(v, i), el.x, el.y - 3); + }); + }); + ctx.restore(); + } +}; +if (window.Chart) Chart.register(valueLabels); + +async function boot() { + $("fileInput").addEventListener("change", onFile); + $("includeSmoke").addEventListener("change", render); + $("runSelect").addEventListener("change", render); + try { + const r = await fetch("data/merged.json", { cache: "no-store" }); + if (r.ok) { MERGED = await r.json(); afterLoad(); } + else showEmpty("No data/merged.json yet. Run a benchmark, then: " + + "python3 analyze/merge.py results/*.json -o dashboard/data/merged.json " + + "— or load a results file above."); + } catch (e) { + showEmpty("Could not auto-load data/merged.json (open via a local server or use the file picker)."); + } +} + +function onFile(ev) { + const f = ev.target.files[0]; if (!f) return; + const rd = new FileReader(); + rd.onload = () => { + const d = JSON.parse(rd.result); + // accept either a merged file or a single results file + MERGED = d.merged_schema ? d : wrapSingle(d); + afterLoad(); + }; + rd.readAsText(f); +} + +/* wrap a single results JSON into the merged shape so the picker works too */ +function wrapSingle(d) { + const rid = `${(d.host||{}).hostname}@${d.generated_utc}`; + const meta = { run_id: rid, hostname:(d.host||{}).hostname, cpu_brand:(d.host||{}).cpu_brand, + is_rpi:(d.host||{}).is_rpi, is_baseline_grade:d.is_baseline_grade }; + const kem=[], sig=[], tls=[]; + (d.kem||[]).forEach(k=>{ if(k.enabled) Object.entries(k.operations||{}).forEach(([op,st])=> + kem.push({...meta, alg:k.alg, classical:!!k.classical, nist_level:k.claimed_nist_level, + operation:op, median_ns:st.median, sizes:k.sizes})); }); + (d.sig||[]).forEach(s=>{ if(s.enabled) Object.entries(s.operations||{}).forEach(([op,st])=> + sig.push({...meta, alg:s.alg, classical:!!s.classical, nist_level:s.claimed_nist_level, + operation:op, median_ns:st.median, sizes:s.sizes})); }); + ((d.tls||{}).matrix||[]).forEach(c=>{ if(c.enabled) tls.push({...meta, label:c.label, group:c.group, + is_baseline_pair:c.label===((d.tls||{}).baseline||{}).label, + handshakes_per_sec:c.handshakes_per_sec, median_ns:(c.handshake_latency_ns||{}).median, + bytes_total:(c.bytes_on_wire||{}).total, client_hello_bytes:c.client_hello_bytes, + client_hello_fragmented:c.client_hello_fragmented}); }); + return { merged_schema:"single", n_runs:1, + runs:[{run_id:rid, host:d.host, is_baseline_grade:d.is_baseline_grade, + baseline_grade_reasons:d.baseline_grade_reasons||[], toolchain:d.toolchain, + cpu_features:d.cpu_features, run:d.run, + thermal_summary:{temp_c:(d.thermal_trace||{}).temp_c, + throttling_detected:(d.thermal_trace||{}).throttling_detected}, + generated_utc:d.generated_utc}], + kem, sig, tls }; +} + +function afterLoad() { + const sel = $("runSelect"); + sel.innerHTML = ""; + MERGED.runs.forEach(r => { + const o = document.createElement("option"); + o.value = r.run_id; + o.textContent = `${(r.host||{}).cpu_brand||"?"} — ${r.is_baseline_grade?"✅ baseline":"⚠ smoke"} — ${r.generated_utc||""}`; + sel.appendChild(o); + }); + render(); +} + +function currentRun() { + const id = $("runSelect").value; + return MERGED.runs.find(r => r.run_id === id) || MERGED.runs[0]; +} + +function render() { + if (!MERGED) return; + CHARTS.forEach(c => c.destroy()); CHARTS = []; + const run = currentRun(); + const includeSmoke = $("includeSmoke").checked; + const allowed = new Set(MERGED.runs + .filter(r => includeSmoke || r.is_baseline_grade) + .map(r => r.run_id)); + // chart the selected run if allowed, else fall back to allowed set + const rid = allowed.has(run.run_id) ? run.run_id : null; + const filt = (rows) => rows.filter(r => rid ? r.run_id === rid : allowed.has(r.run_id)); + + renderBanner(run); + renderEnv(run); + + const kem = filt(MERGED.kem), sig = filt(MERGED.sig), tls = filt(MERGED.tls); + + barByLevel("kem_keygen", kem, "keygen", "KEM keygen — median latency (ms)"); + barByLevel("kem_encaps", kem, "encaps", "KEM encaps — median latency (ms)", "derive"); + barByLevel("kem_decaps", kem, "decaps", "KEM decaps — median latency (ms)", "derive"); + scatter("kem_scatter", kem, "encaps", "public_key", "KEM size vs speed (encaps)", "public key (B)"); + barByLevel("sig_sign", sig, "sign", "Signature sign — median latency (ms)", "sign", true); + barByLevel("sig_verify", sig, "verify", "Signature verify — median latency (ms)", "verify", true); + scatter("sig_scatter", sig, "sign", "signature", "Signature size vs speed (sign)", "signature (B)", true); + tlsThroughput("tls_hs", tls); + tlsClientHello("tls_chello", tls); +} + +function renderBanner(run) { + const el = $("quality-banner"); + if (run.is_baseline_grade) { + el.className = "banner-good"; + el.innerHTML = "✅ RPi5 baseline-grade run — performance governor, core-pinned, " + + "cortex-a76 flags, no thermal throttling."; + } else { + el.className = "banner-warn"; + const rs = (run.baseline_grade_reasons||[]).map(r=>`
  • ${r}
  • `).join(""); + el.innerHTML = "⚠ NOT RPi5 baseline-grade — treat as a pipeline smoke test, not measurement data." + + (rs ? `
      ${rs}
    ` : ""); + } +} + +function renderEnv(run) { + const h = run.host||{}, t = run.toolchain||{}, f = run.cpu_features||{}, rn = run.run||{}; + const chip = (label, val) => `${label} ${val}`; + const sha3 = f.sha3 ? "SHA3 hw ✓" : "SHA3 hw ✗ (Keccak on NEON)"; + $("env-summary").innerHTML = [ + chip("host", `${h.cpu_brand||"?"} (${h.os_pretty||h.os||"?"})`), + chip("governor", rn.governor_after||"?"), + chip("pinned core", rn.pinned ? rn.bench_core : "no"), + chip("flags", `${t.bench_cflags||"?"} → ${t.cflags_target||"?"}`), + chip("liboqs", `${t.liboqs_ref||"?"} ${(t.liboqs_commit||"").slice(0,8)}`), + chip("crypto-ext", `${f.neon?"NEON ":""}${f.sha2?"SHA2 ":""}${sha3}`), + chip("cycles", rn.cycles_available ? "PMU ✓" : "time-based"), + chip("temp", run.thermal_summary && run.thermal_summary.temp_c + ? `${run.thermal_summary.temp_c.mean}°C` + (run.thermal_summary.throttling_detected?" ⚠throttled":"") + : "n/a"), + ].join(""); +} + +/* ---- chart builders ----------------------------------------------------- */ +function baselineAnnotation(value, label) { + if (value == null) return {}; + return { annotations: { base: { + type:"line", yMin:value, yMax:value, borderColor:BASE_COLOR, + borderWidth:2, borderDash:[6,4], + label:{ display:true, content:label, position:"end", + backgroundColor:BASE_COLOR, font:{size:10} } } } }; +} + +function barByLevel(canvasId, rows, op, title, baselineOp = op, logY = false) { + const data = rows.filter(r => r.operation === op) + .sort((a,b)=>(a.nist_level||0)-(b.nist_level||0) || a.median_ns-b.median_ns); + if (!data.length) return drawEmpty(canvasId, title); + /* Baseline reference line: the classical row for baselineOp (defaults to this + * chart's own op). KEM encaps/decaps have no classical encaps/decaps op, so + * they map to the X25519 key-agreement (derive) timing instead. */ + const base = rows.find(r => r.classical && r.operation === baselineOp); + const ctx = $(canvasId).getContext("2d"); + CHARTS.push(new Chart(ctx, { + type:"bar", + data:{ labels:data.map(r=>r.alg), + datasets:[{ label:title, + data:data.map(r=>nsToMs(r.median_ns)), + backgroundColor:data.map(r=> r.classical?BASE_COLOR:(LEVEL_COLORS[r.nist_level]||PQ_COLOR)) }] }, + options:{ responsive:true, plugins:{ + title:{display:true,text:title,color:"#e6e8ee"}, + legend:{display:false}, + valueLabels:{ formatter:(v)=>fmtMs(v) }, + tooltip:{callbacks:{ + label:(it)=>`median ${it.raw.toFixed(4)} ms (${Math.round(it.raw*1e6).toLocaleString()} ns)`, + afterLabel:(it)=>{ + const r=data[it.dataIndex]; return `NIST L${r.nist_level} · ${r.classical?"classical baseline":"PQ"}`; }}}, + annotation: base ? baselineAnnotation(nsToMs(base.median_ns), + baselineOp === op ? `baseline ${base.alg}` : `baseline ${base.alg} ${base.operation}`) : {} }, + scales:{ x:{ticks:{color:"#9aa3b2",maxRotation:50,minRotation:40}}, + y:{ type: logY?"logarithmic":"linear", + title:{display:true,text:logY?"ms (log)":"ms",color:"#9aa3b2"},ticks:{color:"#9aa3b2"}} } } + })); +} + +function scatter(canvasId, rows, op, sizeKey, title, xlabel, logScale = false) { + const data = rows.filter(r => r.operation === op && r.sizes && r.sizes[sizeKey]); + if (!data.length) return drawEmpty(canvasId, title); + const pts = data.map(r => ({ x:r.sizes[sizeKey], y:nsToMs(r.median_ns), alg:r.alg, classical:r.classical })); + const ctx = $(canvasId).getContext("2d"); + CHARTS.push(new Chart(ctx, { + type:"scatter", + data:{ datasets:[{ label:title, data:pts, pointRadius:6, + backgroundColor:pts.map(p=>p.classical?BASE_COLOR:PQ_COLOR) }] }, + options:{ responsive:true, plugins:{ + title:{display:true,text:title,color:"#e6e8ee"}, legend:{display:false}, + tooltip:{callbacks:{label:(it)=>`${it.raw.alg}: ${it.raw.x} B, ${it.raw.y.toFixed(3)} ms`}} }, + scales:{ x:{ type: logScale?"logarithmic":"linear", + title:{display:true,text:logScale?`${xlabel} (log)`:xlabel,color:"#9aa3b2"},ticks:{color:"#9aa3b2"}}, + y:{ type: logScale?"logarithmic":"linear", + title:{display:true,text:logScale?"median latency (ms, log)":"median latency (ms)",color:"#9aa3b2"},ticks:{color:"#9aa3b2"}} } } + })); +} + +function tlsThroughput(canvasId, rows) { + if (!rows.length) return drawEmpty(canvasId, "TLS handshakes/sec — run the TLS layer"); + const data = rows.slice().sort((a,b)=>(b.handshakes_per_sec||0)-(a.handshakes_per_sec||0)); + const base = data.find(r => r.is_baseline_pair); + const ctx = $(canvasId).getContext("2d"); + CHARTS.push(new Chart(ctx, { + type:"bar", + data:{ labels:data.map(r=>r.label), + datasets:[{ label:"handshakes/sec", + data:data.map(r=>r.handshakes_per_sec), + backgroundColor:data.map(r=>r.is_baseline_pair?BASE_COLOR:PQ_COLOR) }] }, + options:{ indexAxis:"y", responsive:true, plugins:{ + title:{display:true,text:"TLS 1.3 handshake throughput (higher = better)",color:"#e6e8ee"}, + legend:{display:false}, + annotation: base ? { annotations:{ base:{ type:"line", + xMin:base.handshakes_per_sec, xMax:base.handshakes_per_sec, + borderColor:BASE_COLOR, borderWidth:2, borderDash:[6,4], + label:{display:true,content:`baseline ${base.label}`,position:"end", + backgroundColor:BASE_COLOR,font:{size:10}} } } } : {} }, + scales:{ x:{title:{display:true,text:"handshakes/sec",color:"#9aa3b2"},ticks:{color:"#9aa3b2"}}, + y:{ticks:{color:"#9aa3b2",font:{size:10}}} } } + })); +} + +function tlsClientHello(canvasId, rows) { + if (!rows.length) return drawEmpty(canvasId, "ClientHello size — run the TLS layer"); + const data = rows.slice().sort((a,b)=>(b.client_hello_bytes||0)-(a.client_hello_bytes||0)); + const base = data.find(r => r.is_baseline_pair); + const ctx = $(canvasId).getContext("2d"); + CHARTS.push(new Chart(ctx, { + type:"bar", + data:{ labels:data.map(r=>r.label), + datasets:[{ label:"ClientHello bytes", + data:data.map(r=>r.client_hello_bytes), + backgroundColor:data.map(r=> r.is_baseline_pair?BASE_COLOR + : (r.client_hello_fragmented?"#d98b2b":PQ_COLOR)) }] }, + options:{ indexAxis:"y", responsive:true, plugins:{ + title:{display:true,text:"ClientHello size (orange = exceeds ~1400B MSS → fragments)",color:"#e6e8ee"}, + legend:{display:false}, + annotation:{ annotations:{ mss:{ type:"line", xMin:1400, xMax:1400, + borderColor:"#d98b2b", borderWidth:1, borderDash:[4,4], + label:{display:true,content:"~MSS 1400B",position:"start",backgroundColor:"#d98b2b",font:{size:9}} }, + ...(base?{base:{type:"line",xMin:base.client_hello_bytes,xMax:base.client_hello_bytes, + borderColor:BASE_COLOR,borderWidth:2,borderDash:[6,4], + label:{display:true,content:`baseline ${base.label}`,position:"end",backgroundColor:BASE_COLOR,font:{size:10}}}}:{}) } } }, + scales:{ x:{title:{display:true,text:"bytes",color:"#9aa3b2"},ticks:{color:"#9aa3b2"}}, + y:{ticks:{color:"#9aa3b2",font:{size:10}}} } } + })); +} + +function drawEmpty(canvasId, msg) { + const c = $(canvasId); const ctx = c.getContext("2d"); + ctx.clearRect(0,0,c.width,c.height); + ctx.fillStyle = "#9aa3b2"; ctx.font = "13px sans-serif"; ctx.textAlign="center"; + ctx.fillText(msg, c.width/2, c.height/2); +} + +function showEmpty(html) { + document.querySelector("main").innerHTML = `
    ${html}
    `; +} + +boot(); diff --git a/pq-bench-rpi5/dashboard/data/merged.json b/pq-bench-rpi5/dashboard/data/merged.json new file mode 100644 index 0000000..c1d5c71 --- /dev/null +++ b/pq-bench-rpi5/dashboard/data/merged.json @@ -0,0 +1,4322 @@ +{ + "merged_schema": "1.0.0", + "n_runs": 2, + "runs": [ + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "host": { + "hostname": "rasberrypi5", + "os": "linux", + "os_pretty": "Debian GNU/Linux 13 (trixie)", + "arch": "aarch64", + "kernel": "6.18.33+rpt-rpi-2712", + "is_rpi": true, + "rpi_model": "Raspberry Pi 5 Model B Rev 1.1", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "ncpu": 4, + "ram_bytes": 8454029312 + }, + "is_baseline_grade": true, + "baseline_grade_reasons": [], + "toolchain": { + "cc_version": "cc (Debian 14.2.0-19) 14.2.0", + "bench_cflags": "-O3 -mcpu=cortex-a76", + "cflags_target": "cortex-a76", + "liboqs_ref": "0.15.0", + "liboqs_commit": "97f6b86b1b6d109cfd43cf276ae39c2e776aed80", + "liboqs_opt_defines": "OQS_COMPILE_BUILD_TARGET aarch64-Linux-6.12.47+rpt-rpi-2712;ARCH_ARM64v8 1;OQS_OPT_TARGET auto;OQS_USE_ARM_AES_INSTRUCTIONS 1;OQS_USE_ARM_SHA2_INSTRUCTIONS 1;OQS_USE_ARM_NEON_INSTRUCTIONS 1;OQS_ENABLE_KEM_kyber_512_aarch64 1;OQS_ENABLE_KEM_kyber_768_aarch64 1;OQS_ENABLE_KEM_kyber_1024_aarch64 1;OQS_ENABLE_KEM_ml_kem_512_aarch64 1;OQS_ENABLE_KEM_ml_kem_768_aarch64 1;OQS_ENABLE_KEM_ml_kem_1024_aarch64 1;OQS_ENABLE_SIG_falcon_512_aarch64 1;OQS_ENABLE_SIG_falcon_1024_aarch64 1;OQS_ENABLE_SIG_falcon_padded_512_aarch64 1;OQS_ENABLE_SIG_falcon_padded_1024_aarch64 1;", + "openssl": "system:3.5.6", + "oqsprovider_ref": "0.9.0", + "oqsprovider_commit": "848b4e6abaa89e769c4db46ca78f91000f67ca52" + }, + "cpu_features": { + "source": "/proc/cpuinfo", + "neon": true, + "sha2": true, + "sha3": false, + "sha512": false, + "aes": true, + "pmull": true + }, + "run": { + "timestamp_start_utc": "2026-06-25T20:23:57Z", + "timestamp_end_utc": "2026-06-25T20:46:28Z", + "duration_s": 1351, + "governor_requested": "performance", + "governor_before": "ondemand", + "governor_after": "performance", + "bench_core": 3, + "pinned": true, + "taskset_cmd": "taskset -c 3", + "calibration_mode": "auto", + "target_time_ms": 250, + "min_samples": 30, + "max_iters": 20000, + "warmup_iters": null, + "timed_iters": null, + "repetitions": 5, + "cycles_mode": "auto", + "cycles_available": false, + "cycles_reason": "PMCCNTR_EL0 traps (kernel module not loaded; needs e.g. enable_arm_pmu)" + }, + "thermal_summary": { + "temp_c": { + "min": 49.9, + "max": 68.1, + "mean": 61.914, + "samples": 1326 + }, + "throttling_detected": false + }, + "generated_utc": "2026-06-25T20:46:28Z", + "source_file": "rasberrypi5-20260625T202356Z.json" + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "host": { + "hostname": "mehmetmac", + "os": "macos", + "os_pretty": "macOS 26.3.1 (25D771280a)", + "arch": "arm64", + "kernel": "25.3.0", + "is_rpi": false, + "rpi_model": "", + "cpu_brand": "Apple M3", + "ncpu": 8, + "ram_bytes": 17179869184 + }, + "is_baseline_grade": false, + "baseline_grade_reasons": [ + "host is not a Raspberry Pi (model='', os=macos)", + "CPU governor is 'unavailable', not 'performance'", + "benchmark was not pinned to a dedicated core (no taskset)", + "build flags targeted 'apple-m3', not cortex-a76" + ], + "toolchain": { + "cc_version": "Apple clang version 17.0.0 (clang-1700.6.4.2)", + "bench_cflags": "-O3 -mcpu=native", + "cflags_target": "apple-m3", + "liboqs_ref": "0.15.0", + "liboqs_commit": "97f6b86b1b6d109cfd43cf276ae39c2e776aed80", + "liboqs_opt_defines": "OQS_COMPILE_BUILD_TARGET arm64-Darwin-25.3.0;ARCH_ARM64v8 1;OQS_OPT_TARGET auto;OQS_USE_ARM_AES_INSTRUCTIONS 1;OQS_USE_ARM_SHA2_INSTRUCTIONS 1;OQS_USE_ARM_SHA3_INSTRUCTIONS 1;OQS_USE_ARM_NEON_INSTRUCTIONS 1;OQS_ENABLE_KEM_kyber_512_aarch64 1;OQS_ENABLE_KEM_kyber_768_aarch64 1;OQS_ENABLE_KEM_kyber_1024_aarch64 1;OQS_ENABLE_KEM_ml_kem_512_aarch64 1;OQS_ENABLE_KEM_ml_kem_768_aarch64 1;OQS_ENABLE_KEM_ml_kem_1024_aarch64 1;OQS_ENABLE_SIG_falcon_512_aarch64 1;OQS_ENABLE_SIG_falcon_1024_aarch64 1;OQS_ENABLE_SIG_falcon_padded_512_aarch64 1;OQS_ENABLE_SIG_falcon_padded_1024_aarch64 1;", + "openssl": "system:3.6.0", + "oqsprovider_ref": "0.9.0", + "oqsprovider_commit": "848b4e6abaa89e769c4db46ca78f91000f67ca52" + }, + "cpu_features": { + "source": "sysctl", + "neon": true, + "sha2": true, + "sha3": true, + "sha512": true, + "aes": true, + "pmull": true + }, + "run": { + "timestamp_start_utc": "2026-06-25T22:06:18Z", + "timestamp_end_utc": "2026-06-25T22:37:08Z", + "duration_s": 1850, + "governor_requested": "performance", + "governor_before": "unavailable", + "governor_after": "unavailable", + "bench_core": 3, + "pinned": false, + "taskset_cmd": "", + "calibration_mode": "auto", + "target_time_ms": 250, + "min_samples": 30, + "max_iters": 20000, + "warmup_iters": null, + "timed_iters": null, + "repetitions": 5, + "cycles_mode": "auto", + "cycles_available": false, + "cycles_reason": "PMCCNTR_EL0 traps (kernel module not loaded; needs e.g. enable_arm_pmu)" + }, + "thermal_summary": { + "temp_c": null, + "throttling_detected": false + }, + "generated_utc": "2026-06-25T22:37:08Z", + "source_file": "mehmetmac-20260625T220618Z.json" + } + ], + "kem": [ + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "X25519", + "backend": "openssl", + "classical": true, + "nist_level": 1, + "operation": "keygen", + "median_ns": 56907.0, + "mad_ns": 37.0, + "iqr_ns": 111.0, + "min_ns": 56777.0, + "stddev_ns": 986.98, + "ops_per_sec": 17572.53, + "sizes": { + "public_key": 32, + "secret_key": 32, + "ciphertext": null, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "X25519", + "backend": "openssl", + "classical": true, + "nist_level": 1, + "operation": "derive", + "median_ns": 165610.0, + "mad_ns": 167.0, + "iqr_ns": 352.0, + "min_ns": 164703.0, + "stddev_ns": 969.55, + "ops_per_sec": 6038.28, + "sizes": { + "public_key": 32, + "secret_key": 32, + "ciphertext": null, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-KEM-512", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "keygen", + "median_ns": 18278.0, + "mad_ns": 19.0, + "iqr_ns": 38.0, + "min_ns": 18185.0, + "stddev_ns": 593.56, + "ops_per_sec": 54710.58, + "sizes": { + "public_key": 800, + "secret_key": 1632, + "ciphertext": 768, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-KEM-512", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "encaps", + "median_ns": 20611.0, + "mad_ns": 18.0, + "iqr_ns": 37.0, + "min_ns": 20519.0, + "stddev_ns": 836.34, + "ops_per_sec": 48517.78, + "sizes": { + "public_key": 800, + "secret_key": 1632, + "ciphertext": 768, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-KEM-512", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "decaps", + "median_ns": 23926.0, + "mad_ns": 19.0, + "iqr_ns": 37.0, + "min_ns": 23851.0, + "stddev_ns": 395.66, + "ops_per_sec": 41795.54, + "sizes": { + "public_key": 800, + "secret_key": 1632, + "ciphertext": 768, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-KEM-768", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "keygen", + "median_ns": 29852.0, + "mad_ns": 36.0, + "iqr_ns": 56.0, + "min_ns": 29722.0, + "stddev_ns": 849.83, + "ops_per_sec": 33498.59, + "sizes": { + "public_key": 1184, + "secret_key": 2400, + "ciphertext": 1088, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-KEM-768", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "encaps", + "median_ns": 31981.0, + "mad_ns": 19.0, + "iqr_ns": 37.0, + "min_ns": 31870.0, + "stddev_ns": 792.16, + "ops_per_sec": 31268.57, + "sizes": { + "public_key": 1184, + "secret_key": 2400, + "ciphertext": 1088, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-KEM-768", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "decaps", + "median_ns": 37352.0, + "mad_ns": 19.0, + "iqr_ns": 56.0, + "min_ns": 37240.0, + "stddev_ns": 720.66, + "ops_per_sec": 26772.33, + "sizes": { + "public_key": 1184, + "secret_key": 2400, + "ciphertext": 1088, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-KEM-1024", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 44074.0, + "mad_ns": 37.0, + "iqr_ns": 92.0, + "min_ns": 43907.0, + "stddev_ns": 1057.79, + "ops_per_sec": 22689.11, + "sizes": { + "public_key": 1568, + "secret_key": 3168, + "ciphertext": 1568, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-KEM-1024", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "encaps", + "median_ns": 47703.0, + "mad_ns": 19.0, + "iqr_ns": 55.0, + "min_ns": 47573.0, + "stddev_ns": 1026.98, + "ops_per_sec": 20963.04, + "sizes": { + "public_key": 1568, + "secret_key": 3168, + "ciphertext": 1568, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-KEM-1024", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "decaps", + "median_ns": 55370.0, + "mad_ns": 37.0, + "iqr_ns": 56.0, + "min_ns": 55240.0, + "stddev_ns": 973.64, + "ops_per_sec": 18060.32, + "sizes": { + "public_key": 1568, + "secret_key": 3168, + "ciphertext": 1568, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-348864", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "keygen", + "median_ns": 149235702.5, + "mad_ns": 70675909.5, + "iqr_ns": 141485404.0, + "min_ns": 78418431.0, + "stddev_ns": 99898990.43, + "ops_per_sec": 6.7, + "sizes": { + "public_key": 261120, + "secret_key": 6492, + "ciphertext": 96, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-348864", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "encaps", + "median_ns": 65833.0, + "mad_ns": 352.0, + "iqr_ns": 5667.0, + "min_ns": 65333.0, + "stddev_ns": 6651.05, + "ops_per_sec": 15189.95, + "sizes": { + "public_key": 261120, + "secret_key": 6492, + "ciphertext": 96, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-348864", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "decaps", + "median_ns": 25696957.5, + "mad_ns": 3416.5, + "iqr_ns": 8458.25, + "min_ns": 25688883.0, + "stddev_ns": 14293.3, + "ops_per_sec": 38.92, + "sizes": { + "public_key": 261120, + "secret_key": 6492, + "ciphertext": 96, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-460896", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "keygen", + "median_ns": 344270731.0, + "mad_ns": 112890557.0, + "iqr_ns": 447106044.25, + "min_ns": 231301254.0, + "stddev_ns": 355212346.2, + "ops_per_sec": 2.9, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-460896", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "encaps", + "median_ns": 130573.0, + "mad_ns": 11111.0, + "iqr_ns": 24999.5, + "min_ns": 118296.0, + "stddev_ns": 24092.04, + "ops_per_sec": 7658.55, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-460896", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "decaps", + "median_ns": 58731815.0, + "mad_ns": 198230.0, + "iqr_ns": 391173.5, + "min_ns": 58064673.0, + "stddev_ns": 301818.0, + "ops_per_sec": 17.03, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-460896f", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "keygen", + "median_ns": 229025837.5, + "mad_ns": 231686.0, + "iqr_ns": 537439.0, + "min_ns": 228593097.0, + "stddev_ns": 1310206.78, + "ops_per_sec": 4.37, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-460896f", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "encaps", + "median_ns": 130555.0, + "mad_ns": 11130.0, + "iqr_ns": 32388.0, + "min_ns": 118666.0, + "stddev_ns": 24620.96, + "ops_per_sec": 7659.61, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-460896f", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "decaps", + "median_ns": 58675112.0, + "mad_ns": 107547.0, + "iqr_ns": 436073.0, + "min_ns": 58208284.0, + "stddev_ns": 306995.23, + "ops_per_sec": 17.04, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-6688128", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 711956854.0, + "mad_ns": 297199934.0, + "iqr_ns": 1178005657.5, + "min_ns": 414436967.0, + "stddev_ns": 860148030.94, + "ops_per_sec": 1.4, + "sizes": { + "public_key": 1044992, + "secret_key": 13932, + "ciphertext": 208, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-6688128", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "encaps", + "median_ns": 230702.0, + "mad_ns": 22741.0, + "iqr_ns": 67426.0, + "min_ns": 207368.0, + "stddev_ns": 49646.61, + "ops_per_sec": 4334.6, + "sizes": { + "public_key": 1044992, + "secret_key": 13932, + "ciphertext": 208, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-6688128", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "decaps", + "median_ns": 112689252.5, + "mad_ns": 305340.0, + "iqr_ns": 570195.0, + "min_ns": 111602532.0, + "stddev_ns": 597991.9, + "ops_per_sec": 8.87, + "sizes": { + "public_key": 1044992, + "secret_key": 13932, + "ciphertext": 208, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-6960119", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 867865263.0, + "mad_ns": 448701486.5, + "iqr_ns": 1194514298.25, + "min_ns": 418071136.0, + "stddev_ns": 866967412.04, + "ops_per_sec": 1.15, + "sizes": { + "public_key": 1047319, + "secret_key": 13948, + "ciphertext": 194, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-6960119", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "encaps", + "median_ns": 357089.0, + "mad_ns": 15277.0, + "iqr_ns": 44463.0, + "min_ns": 340682.0, + "stddev_ns": 34150.91, + "ops_per_sec": 2800.42, + "sizes": { + "public_key": 1047319, + "secret_key": 13948, + "ciphertext": 194, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-6960119", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "decaps", + "median_ns": 109112241.5, + "mad_ns": 298757.5, + "iqr_ns": 745878.75, + "min_ns": 107746815.0, + "stddev_ns": 630895.56, + "ops_per_sec": 9.16, + "sizes": { + "public_key": 1047319, + "secret_key": 13948, + "ciphertext": 194, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-8192128", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 1106148730.5, + "mad_ns": 654945765.5, + "iqr_ns": 1233033015.0, + "min_ns": 447539262.0, + "stddev_ns": 904925749.54, + "ops_per_sec": 0.9, + "sizes": { + "public_key": 1357824, + "secret_key": 14120, + "ciphertext": 208, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-8192128", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "encaps", + "median_ns": 260942.0, + "mad_ns": 16388.0, + "iqr_ns": 48073.0, + "min_ns": 243276.0, + "stddev_ns": 34841.85, + "ops_per_sec": 3832.27, + "sizes": { + "public_key": 1357824, + "secret_key": 14120, + "ciphertext": 208, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Classic-McEliece-8192128", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "decaps", + "median_ns": 136533873.5, + "mad_ns": 275228.5, + "iqr_ns": 555321.5, + "min_ns": 135999211.0, + "stddev_ns": 313444.07, + "ops_per_sec": 7.32, + "sizes": { + "public_key": 1357824, + "secret_key": 14120, + "ciphertext": 208, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "FrodoKEM-640-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "keygen", + "median_ns": 785400.0, + "mad_ns": 241.0, + "iqr_ns": 556.0, + "min_ns": 784289.0, + "stddev_ns": 3289.01, + "ops_per_sec": 1273.24, + "sizes": { + "public_key": 9616, + "secret_key": 19888, + "ciphertext": 9720, + "shared_secret": 16 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "FrodoKEM-640-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "encaps", + "median_ns": 923214.0, + "mad_ns": 278.0, + "iqr_ns": 1588.25, + "min_ns": 922381.0, + "stddev_ns": 3085.86, + "ops_per_sec": 1083.17, + "sizes": { + "public_key": 9616, + "secret_key": 19888, + "ciphertext": 9720, + "shared_secret": 16 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "FrodoKEM-640-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "decaps", + "median_ns": 901214.0, + "mad_ns": 240.0, + "iqr_ns": 1056.0, + "min_ns": 899844.0, + "stddev_ns": 3933.11, + "ops_per_sec": 1109.61, + "sizes": { + "public_key": 9616, + "secret_key": 19888, + "ciphertext": 9720, + "shared_secret": 16 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "FrodoKEM-976-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "keygen", + "median_ns": 1684883.0, + "mad_ns": 1787.0, + "iqr_ns": 4005.5, + "min_ns": 1682466.0, + "stddev_ns": 7405.79, + "ops_per_sec": 593.51, + "sizes": { + "public_key": 15632, + "secret_key": 31296, + "ciphertext": 15744, + "shared_secret": 24 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "FrodoKEM-976-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "encaps", + "median_ns": 1933260.0, + "mad_ns": 1259.0, + "iqr_ns": 2352.0, + "min_ns": 1929908.0, + "stddev_ns": 6204.44, + "ops_per_sec": 517.26, + "sizes": { + "public_key": 15632, + "secret_key": 31296, + "ciphertext": 15744, + "shared_secret": 24 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "FrodoKEM-976-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "decaps", + "median_ns": 1882020.0, + "mad_ns": 1241.0, + "iqr_ns": 2555.0, + "min_ns": 1878594.0, + "stddev_ns": 7521.83, + "ops_per_sec": 531.34, + "sizes": { + "public_key": 15632, + "secret_key": 31296, + "ciphertext": 15744, + "shared_secret": 24 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "FrodoKEM-1344-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 3071787.0, + "mad_ns": 945.0, + "iqr_ns": 1908.0, + "min_ns": 3067658.0, + "stddev_ns": 9157.53, + "ops_per_sec": 325.54, + "sizes": { + "public_key": 21520, + "secret_key": 43088, + "ciphertext": 21632, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "FrodoKEM-1344-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "encaps", + "median_ns": 3467339.0, + "mad_ns": 982.0, + "iqr_ns": 2203.5, + "min_ns": 3460820.0, + "stddev_ns": 9870.01, + "ops_per_sec": 288.41, + "sizes": { + "public_key": 21520, + "secret_key": 43088, + "ciphertext": 21632, + "shared_secret": 32 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "FrodoKEM-1344-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "decaps", + "median_ns": 3407821.0, + "mad_ns": 1223.0, + "iqr_ns": 2760.0, + "min_ns": 3403876.0, + "stddev_ns": 12647.71, + "ops_per_sec": 293.44, + "sizes": { + "public_key": 21520, + "secret_key": 43088, + "ciphertext": 21632, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "X25519", + "backend": "openssl", + "classical": true, + "nist_level": 1, + "operation": "keygen", + "median_ns": 45000.0, + "mad_ns": 0.0, + "iqr_ns": 1000.0, + "min_ns": 44000.0, + "stddev_ns": 11022.5, + "ops_per_sec": 22222.22, + "sizes": { + "public_key": 32, + "secret_key": 32, + "ciphertext": null, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "X25519", + "backend": "openssl", + "classical": true, + "nist_level": 1, + "operation": "derive", + "median_ns": 43000.0, + "mad_ns": 0.0, + "iqr_ns": 0.0, + "min_ns": 42000.0, + "stddev_ns": 7839.77, + "ops_per_sec": 23255.81, + "sizes": { + "public_key": 32, + "secret_key": 32, + "ciphertext": null, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-KEM-512", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "keygen", + "median_ns": 10000.0, + "mad_ns": 0.0, + "iqr_ns": 1000.0, + "min_ns": 9000.0, + "stddev_ns": 1779.86, + "ops_per_sec": 100000.0, + "sizes": { + "public_key": 800, + "secret_key": 1632, + "ciphertext": 768, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-KEM-512", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "encaps", + "median_ns": 11000.0, + "mad_ns": 0.0, + "iqr_ns": 1000.0, + "min_ns": 10000.0, + "stddev_ns": 988.61, + "ops_per_sec": 90909.09, + "sizes": { + "public_key": 800, + "secret_key": 1632, + "ciphertext": 768, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-KEM-512", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "decaps", + "median_ns": 13000.0, + "mad_ns": 0.0, + "iqr_ns": 1000.0, + "min_ns": 12000.0, + "stddev_ns": 2696.01, + "ops_per_sec": 76923.08, + "sizes": { + "public_key": 800, + "secret_key": 1632, + "ciphertext": 768, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-KEM-768", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "keygen", + "median_ns": 16000.0, + "mad_ns": 0.0, + "iqr_ns": 0.0, + "min_ns": 15000.0, + "stddev_ns": 1273.26, + "ops_per_sec": 62500.0, + "sizes": { + "public_key": 1184, + "secret_key": 2400, + "ciphertext": 1088, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-KEM-768", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "encaps", + "median_ns": 17000.0, + "mad_ns": 0.0, + "iqr_ns": 0.0, + "min_ns": 16000.0, + "stddev_ns": 1374.89, + "ops_per_sec": 58823.53, + "sizes": { + "public_key": 1184, + "secret_key": 2400, + "ciphertext": 1088, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-KEM-768", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "decaps", + "median_ns": 20000.0, + "mad_ns": 0.0, + "iqr_ns": 1000.0, + "min_ns": 19000.0, + "stddev_ns": 20041.25, + "ops_per_sec": 50000.0, + "sizes": { + "public_key": 1184, + "secret_key": 2400, + "ciphertext": 1088, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-KEM-1024", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 24000.0, + "mad_ns": 0.0, + "iqr_ns": 1000.0, + "min_ns": 23000.0, + "stddev_ns": 251531.54, + "ops_per_sec": 41666.67, + "sizes": { + "public_key": 1568, + "secret_key": 3168, + "ciphertext": 1568, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-KEM-1024", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "encaps", + "median_ns": 26000.0, + "mad_ns": 0.0, + "iqr_ns": 1000.0, + "min_ns": 25000.0, + "stddev_ns": 1264.28, + "ops_per_sec": 38461.54, + "sizes": { + "public_key": 1568, + "secret_key": 3168, + "ciphertext": 1568, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-KEM-1024", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "decaps", + "median_ns": 30000.0, + "mad_ns": 0.0, + "iqr_ns": 0.0, + "min_ns": 29000.0, + "stddev_ns": 3876.22, + "ops_per_sec": 33333.33, + "sizes": { + "public_key": 1568, + "secret_key": 3168, + "ciphertext": 1568, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-348864", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "keygen", + "median_ns": 178485000.0, + "mad_ns": 77284500.0, + "iqr_ns": 231150500.0, + "min_ns": 100654000.0, + "stddev_ns": 247897979.08, + "ops_per_sec": 5.6, + "sizes": { + "public_key": 261120, + "secret_key": 6492, + "ciphertext": 96, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-348864", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "encaps", + "median_ns": 22000.0, + "mad_ns": 1000.0, + "iqr_ns": 5000.0, + "min_ns": 21000.0, + "stddev_ns": 4915.04, + "ops_per_sec": 45454.55, + "sizes": { + "public_key": 261120, + "secret_key": 6492, + "ciphertext": 96, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-348864", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "decaps", + "median_ns": 25759000.0, + "mad_ns": 19000.0, + "iqr_ns": 44500.0, + "min_ns": 25700000.0, + "stddev_ns": 36363.66, + "ops_per_sec": 38.82, + "sizes": { + "public_key": 261120, + "secret_key": 6492, + "ciphertext": 96, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-460896", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "keygen", + "median_ns": 717814500.0, + "mad_ns": 391387000.0, + "iqr_ns": 970404500.0, + "min_ns": 324753000.0, + "stddev_ns": 674289516.54, + "ops_per_sec": 1.39, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-460896", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "encaps", + "median_ns": 48000.0, + "mad_ns": 9000.0, + "iqr_ns": 26000.0, + "min_ns": 38000.0, + "stddev_ns": 19062.83, + "ops_per_sec": 20833.33, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-460896", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "decaps", + "median_ns": 59398000.0, + "mad_ns": 28500.0, + "iqr_ns": 70500.0, + "min_ns": 59260000.0, + "stddev_ns": 476148.58, + "ops_per_sec": 16.84, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-460896f", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "keygen", + "median_ns": 341787500.0, + "mad_ns": 451500.0, + "iqr_ns": 911250.0, + "min_ns": 340589000.0, + "stddev_ns": 1695918.52, + "ops_per_sec": 2.93, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-460896f", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "encaps", + "median_ns": 48000.0, + "mad_ns": 9000.0, + "iqr_ns": 26000.0, + "min_ns": 38000.0, + "stddev_ns": 20163.02, + "ops_per_sec": 20833.33, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-460896f", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "decaps", + "median_ns": 59391000.0, + "mad_ns": 38500.0, + "iqr_ns": 97000.0, + "min_ns": 59268000.0, + "stddev_ns": 1107932.34, + "ops_per_sec": 16.84, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-6688128", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 2078429500.0, + "mad_ns": 1339938500.0, + "iqr_ns": 2702899000.0, + "min_ns": 735976000.0, + "stddev_ns": 2308475757.57, + "ops_per_sec": 0.48, + "sizes": { + "public_key": 1044992, + "secret_key": 13932, + "ciphertext": 208, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-6688128", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "encaps", + "median_ns": 120000.0, + "mad_ns": 26000.0, + "iqr_ns": 53000.0, + "min_ns": 93000.0, + "stddev_ns": 38274.07, + "ops_per_sec": 8333.33, + "sizes": { + "public_key": 1044992, + "secret_key": 13932, + "ciphertext": 208, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-6688128", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "decaps", + "median_ns": 114067000.0, + "mad_ns": 65500.0, + "iqr_ns": 153750.0, + "min_ns": 113919000.0, + "stddev_ns": 31672668.02, + "ops_per_sec": 8.77, + "sizes": { + "public_key": 1044992, + "secret_key": 13932, + "ciphertext": 208, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-6960119", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 1871076000.0, + "mad_ns": 619611500.0, + "iqr_ns": 1224627000.0, + "min_ns": 667361000.0, + "stddev_ns": 1736141421.73, + "ops_per_sec": 0.53, + "sizes": { + "public_key": 1047319, + "secret_key": 13948, + "ciphertext": 194, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-6960119", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "encaps", + "median_ns": 158000.0, + "mad_ns": 12000.0, + "iqr_ns": 33000.0, + "min_ns": 145000.0, + "stddev_ns": 28004.93, + "ops_per_sec": 6329.11, + "sizes": { + "public_key": 1047319, + "secret_key": 13948, + "ciphertext": 194, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-6960119", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "decaps", + "median_ns": 110526000.0, + "mad_ns": 45500.0, + "iqr_ns": 102750.0, + "min_ns": 110340000.0, + "stddev_ns": 621170.36, + "ops_per_sec": 9.05, + "sizes": { + "public_key": 1047319, + "secret_key": 13948, + "ciphertext": 194, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-8192128", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 1691580500.0, + "mad_ns": 815511500.0, + "iqr_ns": 2435046500.0, + "min_ns": 875041000.0, + "stddev_ns": 2167686375.47, + "ops_per_sec": 0.59, + "sizes": { + "public_key": 1357824, + "secret_key": 14120, + "ciphertext": 208, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-8192128", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "encaps", + "median_ns": 93000.0, + "mad_ns": 13000.0, + "iqr_ns": 37000.0, + "min_ns": 79000.0, + "stddev_ns": 30270.57, + "ops_per_sec": 10752.69, + "sizes": { + "public_key": 1357824, + "secret_key": 14120, + "ciphertext": 208, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Classic-McEliece-8192128", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "decaps", + "median_ns": 139695500.0, + "mad_ns": 58000.0, + "iqr_ns": 126000.0, + "min_ns": 139446000.0, + "stddev_ns": 393654.91, + "ops_per_sec": 7.16, + "sizes": { + "public_key": 1357824, + "secret_key": 14120, + "ciphertext": 208, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "FrodoKEM-640-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "keygen", + "median_ns": 275000.0, + "mad_ns": 1000.0, + "iqr_ns": 2000.0, + "min_ns": 271000.0, + "stddev_ns": 24144.22, + "ops_per_sec": 3636.36, + "sizes": { + "public_key": 9616, + "secret_key": 19888, + "ciphertext": 9720, + "shared_secret": 16 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "FrodoKEM-640-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "encaps", + "median_ns": 368000.0, + "mad_ns": 1000.0, + "iqr_ns": 1000.0, + "min_ns": 365000.0, + "stddev_ns": 14898.96, + "ops_per_sec": 2717.39, + "sizes": { + "public_key": 9616, + "secret_key": 19888, + "ciphertext": 9720, + "shared_secret": 16 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "FrodoKEM-640-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "decaps", + "median_ns": 348000.0, + "mad_ns": 0.0, + "iqr_ns": 1000.0, + "min_ns": 346000.0, + "stddev_ns": 4557.01, + "ops_per_sec": 2873.56, + "sizes": { + "public_key": 9616, + "secret_key": 19888, + "ciphertext": 9720, + "shared_secret": 16 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "FrodoKEM-976-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "keygen", + "median_ns": 542000.0, + "mad_ns": 2000.0, + "iqr_ns": 3000.0, + "min_ns": 538000.0, + "stddev_ns": 3375.2, + "ops_per_sec": 1845.02, + "sizes": { + "public_key": 15632, + "secret_key": 31296, + "ciphertext": 15744, + "shared_secret": 24 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "FrodoKEM-976-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "encaps", + "median_ns": 719000.0, + "mad_ns": 1000.0, + "iqr_ns": 3000.0, + "min_ns": 715000.0, + "stddev_ns": 24148.78, + "ops_per_sec": 1390.82, + "sizes": { + "public_key": 15632, + "secret_key": 31296, + "ciphertext": 15744, + "shared_secret": 24 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "FrodoKEM-976-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "decaps", + "median_ns": 682000.0, + "mad_ns": 2000.0, + "iqr_ns": 4000.0, + "min_ns": 678000.0, + "stddev_ns": 29420.64, + "ops_per_sec": 1466.28, + "sizes": { + "public_key": 15632, + "secret_key": 31296, + "ciphertext": 15744, + "shared_secret": 24 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "FrodoKEM-1344-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 954000.0, + "mad_ns": 3000.0, + "iqr_ns": 4000.0, + "min_ns": 949000.0, + "stddev_ns": 20047.37, + "ops_per_sec": 1048.22, + "sizes": { + "public_key": 21520, + "secret_key": 43088, + "ciphertext": 21632, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "FrodoKEM-1344-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "encaps", + "median_ns": 1236000.0, + "mad_ns": 2000.0, + "iqr_ns": 5000.0, + "min_ns": 1233000.0, + "stddev_ns": 5471.56, + "ops_per_sec": 809.06, + "sizes": { + "public_key": 21520, + "secret_key": 43088, + "ciphertext": 21632, + "shared_secret": 32 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "FrodoKEM-1344-AES", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "decaps", + "median_ns": 1187000.0, + "mad_ns": 2000.0, + "iqr_ns": 5000.0, + "min_ns": 1183000.0, + "stddev_ns": 12913.82, + "ops_per_sec": 842.46, + "sizes": { + "public_key": 21520, + "secret_key": 43088, + "ciphertext": 21632, + "shared_secret": 32 + } + } + ], + "sig": [ + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Ed25519", + "backend": "openssl", + "classical": true, + "nist_level": 1, + "operation": "keygen", + "median_ns": 58222.0, + "mad_ns": 19.0, + "iqr_ns": 56.0, + "min_ns": 58129.0, + "stddev_ns": 649.41, + "ops_per_sec": 17175.64, + "sizes": { + "public_key": 32, + "secret_key": 32, + "signature": 64 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Ed25519", + "backend": "openssl", + "classical": true, + "nist_level": 1, + "operation": "sign", + "median_ns": 57684.0, + "mad_ns": 36.0, + "iqr_ns": 73.0, + "min_ns": 57555.0, + "stddev_ns": 738.96, + "ops_per_sec": 17335.83, + "sizes": { + "public_key": 32, + "secret_key": 32, + "signature": 64 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Ed25519", + "backend": "openssl", + "classical": true, + "nist_level": 1, + "operation": "verify", + "median_ns": 143535.0, + "mad_ns": 56.0, + "iqr_ns": 129.0, + "min_ns": 143239.0, + "stddev_ns": 941.39, + "ops_per_sec": 6966.94, + "sizes": { + "public_key": 32, + "secret_key": 32, + "signature": 64 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-DSA-44", + "backend": "liboqs", + "classical": false, + "nist_level": 2, + "operation": "keygen", + "median_ns": 107462.0, + "mad_ns": 593.0, + "iqr_ns": 1185.0, + "min_ns": 104703.0, + "stddev_ns": 1323.69, + "ops_per_sec": 9305.62, + "sizes": { + "public_key": 1312, + "secret_key": 2560, + "signature": 2420 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-DSA-44", + "backend": "liboqs", + "classical": false, + "nist_level": 2, + "operation": "sign", + "median_ns": 398672.0, + "mad_ns": 180878.0, + "iqr_ns": 343158.25, + "min_ns": 215942.0, + "stddev_ns": 321778.38, + "ops_per_sec": 2508.33, + "sizes": { + "public_key": 1312, + "secret_key": 2560, + "signature": 2420 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-DSA-44", + "backend": "liboqs", + "classical": false, + "nist_level": 2, + "operation": "verify", + "median_ns": 119166.0, + "mad_ns": 167.0, + "iqr_ns": 1000.0, + "min_ns": 118666.0, + "stddev_ns": 1048.95, + "ops_per_sec": 8391.66, + "sizes": { + "public_key": 1312, + "secret_key": 2560, + "signature": 2420 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-DSA-65", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "keygen", + "median_ns": 191072.0, + "mad_ns": 408.0, + "iqr_ns": 834.0, + "min_ns": 189128.0, + "stddev_ns": 1399.44, + "ops_per_sec": 5233.63, + "sizes": { + "public_key": 1952, + "secret_key": 4032, + "signature": 3309 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-DSA-65", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "sign", + "median_ns": 675188.5, + "mad_ns": 314654.0, + "iqr_ns": 658063.5, + "min_ns": 320275.0, + "stddev_ns": 619084.12, + "ops_per_sec": 1481.07, + "sizes": { + "public_key": 1952, + "secret_key": 4032, + "signature": 3309 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-DSA-65", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "verify", + "median_ns": 189332.0, + "mad_ns": 519.0, + "iqr_ns": 1926.0, + "min_ns": 188387.0, + "stddev_ns": 1575.3, + "ops_per_sec": 5281.73, + "sizes": { + "public_key": 1952, + "secret_key": 4032, + "signature": 3309 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-DSA-87", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 288460.0, + "mad_ns": 945.0, + "iqr_ns": 1982.0, + "min_ns": 284127.0, + "stddev_ns": 2375.56, + "ops_per_sec": 3466.69, + "sizes": { + "public_key": 2592, + "secret_key": 4896, + "signature": 4627 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-DSA-87", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "sign", + "median_ns": 834214.0, + "mad_ns": 345663.0, + "iqr_ns": 731530.0, + "min_ns": 484514.0, + "stddev_ns": 582947.9, + "ops_per_sec": 1198.73, + "sizes": { + "public_key": 2592, + "secret_key": 4896, + "signature": 4627 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "ML-DSA-87", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "verify", + "median_ns": 306090.0, + "mad_ns": 649.0, + "iqr_ns": 3945.0, + "min_ns": 305183.0, + "stddev_ns": 2464.56, + "ops_per_sec": 3267.01, + "sizes": { + "public_key": 2592, + "secret_key": 4896, + "signature": 4627 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Falcon-512", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "keygen", + "median_ns": 9062871.0, + "mad_ns": 1285784.5, + "iqr_ns": 2792910.0, + "min_ns": 7270397.0, + "stddev_ns": 2711677.39, + "ops_per_sec": 110.34, + "sizes": { + "public_key": 897, + "secret_key": 1281, + "signature": 752 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Falcon-512", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "sign", + "median_ns": 290294.0, + "mad_ns": 2223.0, + "iqr_ns": 4166.0, + "min_ns": 278831.0, + "stddev_ns": 3632.86, + "ops_per_sec": 3444.78, + "sizes": { + "public_key": 897, + "secret_key": 1281, + "signature": 752 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Falcon-512", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "verify", + "median_ns": 50870.0, + "mad_ns": 56.0, + "iqr_ns": 111.0, + "min_ns": 50629.0, + "stddev_ns": 458.8, + "ops_per_sec": 19657.95, + "sizes": { + "public_key": 897, + "secret_key": 1281, + "signature": 752 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Falcon-1024", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 26303324.5, + "mad_ns": 2618234.5, + "iqr_ns": 6390821.25, + "min_ns": 22847754.0, + "stddev_ns": 7198912.67, + "ops_per_sec": 38.02, + "sizes": { + "public_key": 1793, + "secret_key": 2305, + "signature": 1462 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Falcon-1024", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "sign", + "median_ns": 584374.0, + "mad_ns": 3148.5, + "iqr_ns": 6282.75, + "min_ns": 568995.0, + "stddev_ns": 5613.37, + "ops_per_sec": 1711.23, + "sizes": { + "public_key": 1793, + "secret_key": 2305, + "signature": 1462 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "Falcon-1024", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "verify", + "median_ns": 99722.0, + "mad_ns": 167.0, + "iqr_ns": 370.0, + "min_ns": 99166.0, + "stddev_ns": 713.85, + "ops_per_sec": 10027.88, + "sizes": { + "public_key": 1793, + "secret_key": 2305, + "signature": 1462 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "SPHINCS+-SHA2-128f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "keygen", + "median_ns": 1558819.0, + "mad_ns": 1778.0, + "iqr_ns": 3592.0, + "min_ns": 1553004.0, + "stddev_ns": 4938.67, + "ops_per_sec": 641.51, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 17088 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "SPHINCS+-SHA2-128f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "sign", + "median_ns": 36348426.0, + "mad_ns": 41028.0, + "iqr_ns": 83601.5, + "min_ns": 36301464.0, + "stddev_ns": 45043.6, + "ops_per_sec": 27.51, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 17088 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "SPHINCS+-SHA2-128f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "verify", + "median_ns": 2100610.0, + "mad_ns": 1982.0, + "iqr_ns": 4241.0, + "min_ns": 2098166.0, + "stddev_ns": 5578.92, + "ops_per_sec": 476.05, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 17088 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "SPHINCS+-SHA2-128s-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "keygen", + "median_ns": 96928665.0, + "mad_ns": 10536.5, + "iqr_ns": 29902.5, + "min_ns": 96797056.0, + "stddev_ns": 89923.75, + "ops_per_sec": 10.32, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 7856 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "SPHINCS+-SHA2-128s-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "sign", + "median_ns": 738998757.5, + "mad_ns": 923577.5, + "iqr_ns": 1535087.5, + "min_ns": 735828404.0, + "stddev_ns": 1875209.33, + "ops_per_sec": 1.35, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 7856 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "SPHINCS+-SHA2-128s-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "verify", + "median_ns": 746771.0, + "mad_ns": 352.0, + "iqr_ns": 870.0, + "min_ns": 744585.0, + "stddev_ns": 2815.47, + "ops_per_sec": 1339.1, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 7856 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "SPHINCS+-SHA2-192f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "keygen", + "median_ns": 2332849.0, + "mad_ns": 4778.0, + "iqr_ns": 29926.0, + "min_ns": 2301145.0, + "stddev_ns": 16600.87, + "ops_per_sec": 428.66, + "sizes": { + "public_key": 48, + "secret_key": 96, + "signature": 35664 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "SPHINCS+-SHA2-192f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "sign", + "median_ns": 61899440.0, + "mad_ns": 48527.0, + "iqr_ns": 86388.75, + "min_ns": 61726329.0, + "stddev_ns": 77985.71, + "ops_per_sec": 16.16, + "sizes": { + "public_key": 48, + "secret_key": 96, + "signature": 35664 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "SPHINCS+-SHA2-192f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "verify", + "median_ns": 3373866.0, + "mad_ns": 1185.5, + "iqr_ns": 3740.0, + "min_ns": 3336209.0, + "stddev_ns": 8082.8, + "ops_per_sec": 296.4, + "sizes": { + "public_key": 48, + "secret_key": 96, + "signature": 35664 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "SPHINCS+-SHA2-256f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 6275960.0, + "mad_ns": 6815.0, + "iqr_ns": 12944.0, + "min_ns": 6226626.0, + "stddev_ns": 28336.27, + "ops_per_sec": 159.34, + "sizes": { + "public_key": 64, + "secret_key": 128, + "signature": 49856 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "SPHINCS+-SHA2-256f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "sign", + "median_ns": 128728266.0, + "mad_ns": 129795.5, + "iqr_ns": 241107.75, + "min_ns": 128307036.0, + "stddev_ns": 389204.74, + "ops_per_sec": 7.77, + "sizes": { + "public_key": 64, + "secret_key": 128, + "signature": 49856 + } + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "alg": "SPHINCS+-SHA2-256f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "verify", + "median_ns": 3320580.0, + "mad_ns": 3797.0, + "iqr_ns": 8731.0, + "min_ns": 3311209.0, + "stddev_ns": 7414.38, + "ops_per_sec": 301.15, + "sizes": { + "public_key": 64, + "secret_key": 128, + "signature": 49856 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Ed25519", + "backend": "openssl", + "classical": true, + "nist_level": 1, + "operation": "keygen", + "median_ns": 45000.0, + "mad_ns": 0.0, + "iqr_ns": 0.0, + "min_ns": 44000.0, + "stddev_ns": 859.41, + "ops_per_sec": 22222.22, + "sizes": { + "public_key": 32, + "secret_key": 32, + "signature": 64 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Ed25519", + "backend": "openssl", + "classical": true, + "nist_level": 1, + "operation": "sign", + "median_ns": 45000.0, + "mad_ns": 0.0, + "iqr_ns": 0.0, + "min_ns": 44000.0, + "stddev_ns": 807.75, + "ops_per_sec": 22222.22, + "sizes": { + "public_key": 32, + "secret_key": 32, + "signature": 64 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Ed25519", + "backend": "openssl", + "classical": true, + "nist_level": 1, + "operation": "verify", + "median_ns": 124000.0, + "mad_ns": 0.0, + "iqr_ns": 0.0, + "min_ns": 123000.0, + "stddev_ns": 1201.97, + "ops_per_sec": 8064.52, + "sizes": { + "public_key": 32, + "secret_key": 32, + "signature": 64 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-DSA-44", + "backend": "liboqs", + "classical": false, + "nist_level": 2, + "operation": "keygen", + "median_ns": 62000.0, + "mad_ns": 0.0, + "iqr_ns": 1000.0, + "min_ns": 60000.0, + "stddev_ns": 1121.81, + "ops_per_sec": 16129.03, + "sizes": { + "public_key": 1312, + "secret_key": 2560, + "signature": 2420 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-DSA-44", + "backend": "liboqs", + "classical": false, + "nist_level": 2, + "operation": "sign", + "median_ns": 227000.0, + "mad_ns": 112000.0, + "iqr_ns": 224000.0, + "min_ns": 114000.0, + "stddev_ns": 1364832.25, + "ops_per_sec": 4405.29, + "sizes": { + "public_key": 1312, + "secret_key": 2560, + "signature": 2420 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-DSA-44", + "backend": "liboqs", + "classical": false, + "nist_level": 2, + "operation": "verify", + "median_ns": 67000.0, + "mad_ns": 0.0, + "iqr_ns": 0.0, + "min_ns": 66000.0, + "stddev_ns": 966.53, + "ops_per_sec": 14925.37, + "sizes": { + "public_key": 1312, + "secret_key": 2560, + "signature": 2420 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-DSA-65", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "keygen", + "median_ns": 121000.0, + "mad_ns": 1000.0, + "iqr_ns": 1000.0, + "min_ns": 119000.0, + "stddev_ns": 1373.02, + "ops_per_sec": 8264.46, + "sizes": { + "public_key": 1952, + "secret_key": 4032, + "signature": 3309 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-DSA-65", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "sign", + "median_ns": 376000.0, + "mad_ns": 156000.0, + "iqr_ns": 362000.0, + "min_ns": 172000.0, + "stddev_ns": 329222.43, + "ops_per_sec": 2659.57, + "sizes": { + "public_key": 1952, + "secret_key": 4032, + "signature": 3309 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-DSA-65", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "verify", + "median_ns": 109000.0, + "mad_ns": 0.0, + "iqr_ns": 1000.0, + "min_ns": 108000.0, + "stddev_ns": 1211.34, + "ops_per_sec": 9174.31, + "sizes": { + "public_key": 1952, + "secret_key": 4032, + "signature": 3309 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-DSA-87", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 172000.0, + "mad_ns": 1000.0, + "iqr_ns": 1000.0, + "min_ns": 169000.0, + "stddev_ns": 1537.99, + "ops_per_sec": 5813.95, + "sizes": { + "public_key": 2592, + "secret_key": 4896, + "signature": 4627 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-DSA-87", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "sign", + "median_ns": 475000.0, + "mad_ns": 206000.0, + "iqr_ns": 420000.0, + "min_ns": 267000.0, + "stddev_ns": 339779.55, + "ops_per_sec": 2105.26, + "sizes": { + "public_key": 2592, + "secret_key": 4896, + "signature": 4627 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "ML-DSA-87", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "verify", + "median_ns": 181000.0, + "mad_ns": 0.0, + "iqr_ns": 0.0, + "min_ns": 180000.0, + "stddev_ns": 2213.84, + "ops_per_sec": 5524.86, + "sizes": { + "public_key": 2592, + "secret_key": 4896, + "signature": 4627 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Falcon-512", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "keygen", + "median_ns": 6557000.0, + "mad_ns": 675000.0, + "iqr_ns": 1273000.0, + "min_ns": 5572000.0, + "stddev_ns": 1442365.12, + "ops_per_sec": 152.51, + "sizes": { + "public_key": 897, + "secret_key": 1281, + "signature": 752 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Falcon-512", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "sign", + "median_ns": 204000.0, + "mad_ns": 2000.0, + "iqr_ns": 5000.0, + "min_ns": 189000.0, + "stddev_ns": 3838.04, + "ops_per_sec": 4901.96, + "sizes": { + "public_key": 897, + "secret_key": 1281, + "signature": 752 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Falcon-512", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "verify", + "median_ns": 32000.0, + "mad_ns": 0.0, + "iqr_ns": 1000.0, + "min_ns": 30000.0, + "stddev_ns": 4108.49, + "ops_per_sec": 31250.0, + "sizes": { + "public_key": 897, + "secret_key": 1281, + "signature": 752 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Falcon-1024", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 20948500.0, + "mad_ns": 1365500.0, + "iqr_ns": 3289000.0, + "min_ns": 19066000.0, + "stddev_ns": 5075415.28, + "ops_per_sec": 47.74, + "sizes": { + "public_key": 1793, + "secret_key": 2305, + "signature": 1462 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Falcon-1024", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "sign", + "median_ns": 409000.0, + "mad_ns": 4000.0, + "iqr_ns": 7000.0, + "min_ns": 389000.0, + "stddev_ns": 5801.4, + "ops_per_sec": 2444.99, + "sizes": { + "public_key": 1793, + "secret_key": 2305, + "signature": 1462 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "Falcon-1024", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "verify", + "median_ns": 62000.0, + "mad_ns": 0.0, + "iqr_ns": 1000.0, + "min_ns": 60000.0, + "stddev_ns": 1002.52, + "ops_per_sec": 16129.03, + "sizes": { + "public_key": 1793, + "secret_key": 2305, + "signature": 1462 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "SPHINCS+-SHA2-128f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "keygen", + "median_ns": 866000.0, + "mad_ns": 3000.0, + "iqr_ns": 5000.0, + "min_ns": 859000.0, + "stddev_ns": 6262.42, + "ops_per_sec": 1154.73, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 17088 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "SPHINCS+-SHA2-128f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "sign", + "median_ns": 20155000.0, + "mad_ns": 34000.0, + "iqr_ns": 69750.0, + "min_ns": 20090000.0, + "stddev_ns": 76688.4, + "ops_per_sec": 49.62, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 17088 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "SPHINCS+-SHA2-128f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "verify", + "median_ns": 1211000.0, + "mad_ns": 2000.0, + "iqr_ns": 6000.0, + "min_ns": 1207000.0, + "stddev_ns": 14223.64, + "ops_per_sec": 825.76, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 17088 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "SPHINCS+-SHA2-128s-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "keygen", + "median_ns": 55436500.0, + "mad_ns": 257500.0, + "iqr_ns": 517000.0, + "min_ns": 54966000.0, + "stddev_ns": 452267.54, + "ops_per_sec": 18.04, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 7856 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "SPHINCS+-SHA2-128s-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "sign", + "median_ns": 422006500.0, + "mad_ns": 1661000.0, + "iqr_ns": 3570500.0, + "min_ns": 418755000.0, + "stddev_ns": 15250616.04, + "ops_per_sec": 2.37, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 7856 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "SPHINCS+-SHA2-128s-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 1, + "operation": "verify", + "median_ns": 395000.0, + "mad_ns": 1000.0, + "iqr_ns": 3000.0, + "min_ns": 392000.0, + "stddev_ns": 3498.24, + "ops_per_sec": 2531.65, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 7856 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "SPHINCS+-SHA2-192f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "keygen", + "median_ns": 1255000.0, + "mad_ns": 3000.0, + "iqr_ns": 7000.0, + "min_ns": 1246000.0, + "stddev_ns": 6316.24, + "ops_per_sec": 796.81, + "sizes": { + "public_key": 48, + "secret_key": 96, + "signature": 35664 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "SPHINCS+-SHA2-192f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "sign", + "median_ns": 33370000.0, + "mad_ns": 51000.0, + "iqr_ns": 106500.0, + "min_ns": 33117000.0, + "stddev_ns": 369561.85, + "ops_per_sec": 29.97, + "sizes": { + "public_key": 48, + "secret_key": 96, + "signature": 35664 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "SPHINCS+-SHA2-192f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 3, + "operation": "verify", + "median_ns": 1773000.0, + "mad_ns": 5000.0, + "iqr_ns": 15000.0, + "min_ns": 1761000.0, + "stddev_ns": 14463.47, + "ops_per_sec": 564.02, + "sizes": { + "public_key": 48, + "secret_key": 96, + "signature": 35664 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "SPHINCS+-SHA2-256f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "keygen", + "median_ns": 3320000.0, + "mad_ns": 6000.0, + "iqr_ns": 13000.0, + "min_ns": 3306000.0, + "stddev_ns": 10971.57, + "ops_per_sec": 301.2, + "sizes": { + "public_key": 64, + "secret_key": 128, + "signature": 49856 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "SPHINCS+-SHA2-256f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "sign", + "median_ns": 68626500.0, + "mad_ns": 105000.0, + "iqr_ns": 228000.0, + "min_ns": 68385000.0, + "stddev_ns": 395205.03, + "ops_per_sec": 14.57, + "sizes": { + "public_key": 64, + "secret_key": 128, + "signature": 49856 + } + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "alg": "SPHINCS+-SHA2-256f-simple", + "backend": "liboqs", + "classical": false, + "nist_level": 5, + "operation": "verify", + "median_ns": 1784000.0, + "mad_ns": 3000.0, + "iqr_ns": 6000.0, + "min_ns": 1775000.0, + "stddev_ns": 6416.59, + "ops_per_sec": 560.54, + "sizes": { + "public_key": 64, + "secret_key": 128, + "signature": 49856 + } + } + ], + "tls": [ + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "X25519+ed25519", + "group": "X25519", + "is_baseline_pair": true, + "handshakes_per_sec": 752.6, + "median_ns": 1328747.0, + "bytes_total": 1571, + "client_hello_bytes": 302, + "client_hello_fragmented": false + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "X25519MLKEM768+mldsa44", + "group": "X25519MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 373.8, + "median_ns": 2674910.5, + "bytes_total": 9852, + "client_hello_bytes": 1478, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "X25519MLKEM768+mldsa65", + "group": "X25519MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 279.4, + "median_ns": 3578901.5, + "bytes_total": 12270, + "client_hello_bytes": 1478, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "X25519MLKEM768+mldsa87", + "group": "X25519MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 236.7, + "median_ns": 4225339.5, + "bytes_total": 15546, + "client_hello_bytes": 1478, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "X25519MLKEM768+falcon512", + "group": "X25519MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 314.1, + "median_ns": 3184164.5, + "bytes_total": 5894, + "client_hello_bytes": 1478, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "X25519MLKEM768+sphincssha2128fsimple", + "group": "X25519MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 22.7, + "median_ns": 44119685.5, + "bytes_total": 37952, + "client_hello_bytes": 1478, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "SecP256r1MLKEM768+mldsa44", + "group": "SecP256r1MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 368.6, + "median_ns": 2712761.5, + "bytes_total": 9918, + "client_hello_bytes": 1511, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "SecP256r1MLKEM768+mldsa65", + "group": "SecP256r1MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 275.1, + "median_ns": 3634613.5, + "bytes_total": 12336, + "client_hello_bytes": 1511, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "SecP256r1MLKEM768+mldsa87", + "group": "SecP256r1MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 233.8, + "median_ns": 4277496.0, + "bytes_total": 15612, + "client_hello_bytes": 1511, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "SecP256r1MLKEM768+falcon512", + "group": "SecP256r1MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 300.3, + "median_ns": 3329811.0, + "bytes_total": 5961, + "client_hello_bytes": 1511, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "SecP256r1MLKEM768+sphincssha2128fsimple", + "group": "SecP256r1MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 22.4, + "median_ns": 44574336.0, + "bytes_total": 38018, + "client_hello_bytes": 1511, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem512+mldsa44", + "group": "mlkem512", + "is_baseline_pair": false, + "handshakes_per_sec": 475.0, + "median_ns": 2105128.0, + "bytes_total": 9084, + "client_hello_bytes": 1062, + "client_hello_fragmented": false + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem512+mldsa65", + "group": "mlkem512", + "is_baseline_pair": false, + "handshakes_per_sec": 332.8, + "median_ns": 3004971.0, + "bytes_total": 11502, + "client_hello_bytes": 1062, + "client_hello_fragmented": false + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem512+mldsa87", + "group": "mlkem512", + "is_baseline_pair": false, + "handshakes_per_sec": 274.1, + "median_ns": 3648058.0, + "bytes_total": 14778, + "client_hello_bytes": 1062, + "client_hello_fragmented": false + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem512+falcon512", + "group": "mlkem512", + "is_baseline_pair": false, + "handshakes_per_sec": 385.7, + "median_ns": 2592753.0, + "bytes_total": 5128, + "client_hello_bytes": 1062, + "client_hello_fragmented": false + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem512+sphincssha2128fsimple", + "group": "mlkem512", + "is_baseline_pair": false, + "handshakes_per_sec": 23.4, + "median_ns": 42806832.0, + "bytes_total": 37184, + "client_hello_bytes": 1062, + "client_hello_fragmented": false + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem768+mldsa44", + "group": "mlkem768", + "is_baseline_pair": false, + "handshakes_per_sec": 456.2, + "median_ns": 2192238.5, + "bytes_total": 9788, + "client_hello_bytes": 1446, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem768+mldsa65", + "group": "mlkem768", + "is_baseline_pair": false, + "handshakes_per_sec": 321.0, + "median_ns": 3115081.5, + "bytes_total": 12206, + "client_hello_bytes": 1446, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem768+mldsa87", + "group": "mlkem768", + "is_baseline_pair": false, + "handshakes_per_sec": 265.0, + "median_ns": 3773140.0, + "bytes_total": 15482, + "client_hello_bytes": 1446, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem768+falcon512", + "group": "mlkem768", + "is_baseline_pair": false, + "handshakes_per_sec": 373.5, + "median_ns": 2677252.0, + "bytes_total": 5834, + "client_hello_bytes": 1446, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem768+sphincssha2128fsimple", + "group": "mlkem768", + "is_baseline_pair": false, + "handshakes_per_sec": 22.9, + "median_ns": 43591286.0, + "bytes_total": 37888, + "client_hello_bytes": 1446, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem1024+mldsa44", + "group": "mlkem1024", + "is_baseline_pair": false, + "handshakes_per_sec": 430.5, + "median_ns": 2322727.5, + "bytes_total": 10652, + "client_hello_bytes": 1830, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem1024+mldsa65", + "group": "mlkem1024", + "is_baseline_pair": false, + "handshakes_per_sec": 310.7, + "median_ns": 3218598.5, + "bytes_total": 13070, + "client_hello_bytes": 1830, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem1024+mldsa87", + "group": "mlkem1024", + "is_baseline_pair": false, + "handshakes_per_sec": 259.0, + "median_ns": 3860833.5, + "bytes_total": 16346, + "client_hello_bytes": 1830, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem1024+falcon512", + "group": "mlkem1024", + "is_baseline_pair": false, + "handshakes_per_sec": 356.1, + "median_ns": 2808501.0, + "bytes_total": 6695, + "client_hello_bytes": 1830, + "client_hello_fragmented": true + }, + { + "run_id": "rasberrypi5/Raspberry Pi 5 Model B Rev 1.1@2026-06-25T20:46:28Z", + "hostname": "rasberrypi5", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "is_rpi": true, + "is_baseline_grade": true, + "source_file": "rasberrypi5-20260625T202356Z.json", + "label": "mlkem1024+sphincssha2128fsimple", + "group": "mlkem1024", + "is_baseline_pair": false, + "handshakes_per_sec": 23.1, + "median_ns": 43234843.0, + "bytes_total": 38752, + "client_hello_bytes": 1830, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "X25519+ed25519", + "group": "X25519", + "is_baseline_pair": true, + "handshakes_per_sec": 1406.5, + "median_ns": 711000.0, + "bytes_total": 1560, + "client_hello_bytes": 291, + "client_hello_fragmented": false + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "X25519MLKEM768+mldsa44", + "group": "X25519MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 860.2, + "median_ns": 1162500.0, + "bytes_total": 9843, + "client_hello_bytes": 1469, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "X25519MLKEM768+mldsa65", + "group": "X25519MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 644.7, + "median_ns": 1551000.0, + "bytes_total": 12261, + "client_hello_bytes": 1469, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "X25519MLKEM768+mldsa87", + "group": "X25519MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 541.1, + "median_ns": 1848000.0, + "bytes_total": 15537, + "client_hello_bytes": 1469, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "X25519MLKEM768+falcon512", + "group": "X25519MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 600.2, + "median_ns": 1666000.0, + "bytes_total": 5888, + "client_hello_bytes": 1469, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "X25519MLKEM768+sphincssha2128fsimple", + "group": "X25519MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 40.6, + "median_ns": 24625500.0, + "bytes_total": 37943, + "client_hello_bytes": 1469, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "SecP256r1MLKEM768+mldsa44", + "group": "SecP256r1MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 864.3, + "median_ns": 1157000.0, + "bytes_total": 9909, + "client_hello_bytes": 1502, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "SecP256r1MLKEM768+mldsa65", + "group": "SecP256r1MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 648.1, + "median_ns": 1543000.0, + "bytes_total": 12327, + "client_hello_bytes": 1502, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "SecP256r1MLKEM768+mldsa87", + "group": "SecP256r1MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 541.1, + "median_ns": 1848000.0, + "bytes_total": 15603, + "client_hello_bytes": 1502, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "SecP256r1MLKEM768+falcon512", + "group": "SecP256r1MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 604.2, + "median_ns": 1655000.0, + "bytes_total": 5960, + "client_hello_bytes": 1502, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "SecP256r1MLKEM768+sphincssha2128fsimple", + "group": "SecP256r1MLKEM768", + "is_baseline_pair": false, + "handshakes_per_sec": 40.3, + "median_ns": 24819500.0, + "bytes_total": 38009, + "client_hello_bytes": 1502, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem512+mldsa44", + "group": "mlkem512", + "is_baseline_pair": false, + "handshakes_per_sec": 1081.1, + "median_ns": 925000.0, + "bytes_total": 9075, + "client_hello_bytes": 1053, + "client_hello_fragmented": false + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem512+mldsa65", + "group": "mlkem512", + "is_baseline_pair": false, + "handshakes_per_sec": 759.9, + "median_ns": 1316000.0, + "bytes_total": 11493, + "client_hello_bytes": 1053, + "client_hello_fragmented": false + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem512+mldsa87", + "group": "mlkem512", + "is_baseline_pair": false, + "handshakes_per_sec": 620.3, + "median_ns": 1612000.0, + "bytes_total": 14769, + "client_hello_bytes": 1053, + "client_hello_fragmented": false + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem512+falcon512", + "group": "mlkem512", + "is_baseline_pair": false, + "handshakes_per_sec": 700.8, + "median_ns": 1427000.0, + "bytes_total": 5122, + "client_hello_bytes": 1053, + "client_hello_fragmented": false + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem512+sphincssha2128fsimple", + "group": "mlkem512", + "is_baseline_pair": false, + "handshakes_per_sec": 40.5, + "median_ns": 24697000.0, + "bytes_total": 37175, + "client_hello_bytes": 1053, + "client_hello_fragmented": false + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem768+mldsa44", + "group": "mlkem768", + "is_baseline_pair": false, + "handshakes_per_sec": 1028.8, + "median_ns": 972000.0, + "bytes_total": 9779, + "client_hello_bytes": 1437, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem768+mldsa65", + "group": "mlkem768", + "is_baseline_pair": false, + "handshakes_per_sec": 734.8, + "median_ns": 1361000.0, + "bytes_total": 12197, + "client_hello_bytes": 1437, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem768+mldsa87", + "group": "mlkem768", + "is_baseline_pair": false, + "handshakes_per_sec": 602.8, + "median_ns": 1659000.0, + "bytes_total": 15473, + "client_hello_bytes": 1437, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem768+falcon512", + "group": "mlkem768", + "is_baseline_pair": false, + "handshakes_per_sec": 680.3, + "median_ns": 1470000.0, + "bytes_total": 5822, + "client_hello_bytes": 1437, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem768+sphincssha2128fsimple", + "group": "mlkem768", + "is_baseline_pair": false, + "handshakes_per_sec": 40.6, + "median_ns": 24603000.0, + "bytes_total": 37879, + "client_hello_bytes": 1437, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem1024+mldsa44", + "group": "mlkem1024", + "is_baseline_pair": false, + "handshakes_per_sec": 967.1, + "median_ns": 1034000.0, + "bytes_total": 10643, + "client_hello_bytes": 1821, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem1024+mldsa65", + "group": "mlkem1024", + "is_baseline_pair": false, + "handshakes_per_sec": 701.8, + "median_ns": 1425000.0, + "bytes_total": 13061, + "client_hello_bytes": 1821, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem1024+mldsa87", + "group": "mlkem1024", + "is_baseline_pair": false, + "handshakes_per_sec": 580.2, + "median_ns": 1723500.0, + "bytes_total": 16337, + "client_hello_bytes": 1821, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem1024+falcon512", + "group": "mlkem1024", + "is_baseline_pair": false, + "handshakes_per_sec": 654.5, + "median_ns": 1528000.0, + "bytes_total": 6692, + "client_hello_bytes": 1821, + "client_hello_fragmented": true + }, + { + "run_id": "mehmetmac/Apple M3@2026-06-25T22:37:08Z", + "hostname": "mehmetmac", + "cpu_brand": "Apple M3", + "is_rpi": false, + "is_baseline_grade": false, + "source_file": "mehmetmac-20260625T220618Z.json", + "label": "mlkem1024+sphincssha2128fsimple", + "group": "mlkem1024", + "is_baseline_pair": false, + "handshakes_per_sec": 40.8, + "median_ns": 24511000.0, + "bytes_total": 38743, + "client_hello_bytes": 1821, + "client_hello_fragmented": true + } + ] +} \ No newline at end of file diff --git a/pq-bench-rpi5/dashboard/index.html b/pq-bench-rpi5/dashboard/index.html new file mode 100644 index 0000000..520a1dd --- /dev/null +++ b/pq-bench-rpi5/dashboard/index.html @@ -0,0 +1,68 @@ + + + + + +PQ Benchmark — RPi5 baseline + + + + + + +
    +

    Post-Quantum Crypto Benchmark Raspberry Pi 5 baseline

    +

    Migration cost: moving from what Logos uses today + (X25519 + Ed25519) to PQ candidates, on validator-grade hardware. The + classical baseline is drawn as a reference line on every chart.

    +
    + +
    + + + +
    + +
    +
    + +
    +

    Key Encapsulation (KEM)

    +
    +
    +
    +
    +
    +
    + +

    Signatures

    +
    +
    +
    +
    +
    + +

    TLS 1.3 Handshakes (KEM group × signature)

    +
    +
    +
    +
    +
    + +
    +

    Generated by pq-bench-rpi5. Numbers are only RPi5-baseline-grade + when the run banner says so (real Pi 5 · performance governor · core-pinned · + cortex-a76 flags · no thermal throttling). Everything else is a pipeline smoke test.

    +
    + + + + diff --git a/pq-bench-rpi5/dashboard/style.css b/pq-bench-rpi5/dashboard/style.css new file mode 100644 index 0000000..018a304 --- /dev/null +++ b/pq-bench-rpi5/dashboard/style.css @@ -0,0 +1,40 @@ +:root { + --bg:#0f1115; --panel:#181b22; --ink:#e6e8ee; --muted:#9aa3b2; + --accent:#3bd67a; --base:#e0533d; --pq:#3a7bff; --line:#2a2f3a; +} +* { box-sizing:border-box; } +body { margin:0; font:15px/1.5 -apple-system,Segoe UI,Roboto,sans-serif; + background:var(--bg); color:var(--ink); } +header { padding:24px 28px 8px; } +h1 { margin:0; font-size:22px; } +h1 .sub, h2 .sub { color:var(--muted); font-weight:400; font-size:0.7em; } +.framing { color:var(--muted); max-width:760px; } +h2 { margin:30px 28px 8px; border-bottom:1px solid var(--line); padding-bottom:6px; } + +#controls { display:flex; flex-wrap:wrap; gap:18px; align-items:center; + padding:12px 28px; background:var(--panel); margin:8px 0; } +#controls label { color:var(--muted); font-size:14px; } +#controls .hint { font-size:12px; opacity:.7; } +select, input[type=file] { color:var(--ink); background:#0c0e12; + border:1px solid var(--line); border-radius:6px; padding:4px 6px; } + +#quality-banner { margin:8px 28px; padding:12px 16px; border-radius:8px; font-weight:600; } +.banner-good { background:#12331f; border:1px solid #1f7a44; color:#7df0a8; } +.banner-warn { background:#3a2410; border:1px solid #aa6a1f; color:#ffce8a; } +.banner-warn ul { font-weight:400; margin:6px 0 0; color:#ffd9a8; } + +#env-summary { margin:0 28px 8px; color:var(--muted); font-size:13px; + display:flex; flex-wrap:wrap; gap:6px 18px; } +#env-summary b { color:var(--ink); } +#env-summary .chip { background:var(--panel); padding:3px 9px; border-radius:20px; + border:1px solid var(--line); } + +.chart-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(420px,1fr)); + gap:18px; padding:14px 28px; } +figure { margin:0; background:var(--panel); border:1px solid var(--line); + border-radius:10px; padding:12px; min-height:320px; } +canvas { max-height:340px; } + +footer { color:var(--muted); font-size:12px; padding:18px 28px 40px; max-width:820px; } +code { background:#0c0e12; padding:1px 5px; border-radius:4px; } +.empty { color:var(--muted); padding:30px; text-align:center; } diff --git a/pq-bench-rpi5/results/.gitkeep b/pq-bench-rpi5/results/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/pq-bench-rpi5/results/mehmetmac-20260625T220618Z.json b/pq-bench-rpi5/results/mehmetmac-20260625T220618Z.json new file mode 100644 index 0000000..077b314 --- /dev/null +++ b/pq-bench-rpi5/results/mehmetmac-20260625T220618Z.json @@ -0,0 +1,13829 @@ +{ + "schema_version": "1.0.0", + "tool_version": "0.1.0", + "generated_utc": "2026-06-25T22:37:08Z", + "is_baseline_grade": false, + "baseline_grade_reasons": [ + "host is not a Raspberry Pi (model='', os=macos)", + "CPU governor is 'unavailable', not 'performance'", + "benchmark was not pinned to a dedicated core (no taskset)", + "build flags targeted 'apple-m3', not cortex-a76" + ], + "host": { + "hostname": "mehmetmac", + "os": "macos", + "os_pretty": "macOS 26.3.1 (25D771280a)", + "arch": "arm64", + "kernel": "25.3.0", + "is_rpi": false, + "rpi_model": "", + "cpu_brand": "Apple M3", + "ncpu": 8, + "ram_bytes": 17179869184 + }, + "cpu_features": { + "source": "sysctl", + "neon": true, + "sha2": true, + "sha3": true, + "sha512": true, + "aes": true, + "pmull": true + }, + "run": { + "timestamp_start_utc": "2026-06-25T22:06:18Z", + "timestamp_end_utc": "2026-06-25T22:37:08Z", + "duration_s": 1850, + "governor_requested": "performance", + "governor_before": "unavailable", + "governor_after": "unavailable", + "bench_core": 3, + "pinned": false, + "taskset_cmd": "", + "calibration_mode": "auto", + "target_time_ms": 250, + "min_samples": 30, + "max_iters": 20000, + "warmup_iters": null, + "timed_iters": null, + "repetitions": 5, + "cycles_mode": "auto", + "cycles_available": false, + "cycles_reason": "PMCCNTR_EL0 traps (kernel module not loaded; needs e.g. enable_arm_pmu)" + }, + "toolchain": { + "cc_version": "Apple clang version 17.0.0 (clang-1700.6.4.2)", + "bench_cflags": "-O3 -mcpu=native", + "cflags_target": "apple-m3", + "liboqs_ref": "0.15.0", + "liboqs_commit": "97f6b86b1b6d109cfd43cf276ae39c2e776aed80", + "liboqs_opt_defines": "OQS_COMPILE_BUILD_TARGET arm64-Darwin-25.3.0;ARCH_ARM64v8 1;OQS_OPT_TARGET auto;OQS_USE_ARM_AES_INSTRUCTIONS 1;OQS_USE_ARM_SHA2_INSTRUCTIONS 1;OQS_USE_ARM_SHA3_INSTRUCTIONS 1;OQS_USE_ARM_NEON_INSTRUCTIONS 1;OQS_ENABLE_KEM_kyber_512_aarch64 1;OQS_ENABLE_KEM_kyber_768_aarch64 1;OQS_ENABLE_KEM_kyber_1024_aarch64 1;OQS_ENABLE_KEM_ml_kem_512_aarch64 1;OQS_ENABLE_KEM_ml_kem_768_aarch64 1;OQS_ENABLE_KEM_ml_kem_1024_aarch64 1;OQS_ENABLE_SIG_falcon_512_aarch64 1;OQS_ENABLE_SIG_falcon_1024_aarch64 1;OQS_ENABLE_SIG_falcon_padded_512_aarch64 1;OQS_ENABLE_SIG_falcon_padded_1024_aarch64 1;", + "openssl": "system:3.6.0", + "oqsprovider_ref": "0.9.0", + "oqsprovider_commit": "848b4e6abaa89e769c4db46ca78f91000f67ca52" + }, + "thermal_trace": { + "columns": [ + "epoch_s", + "arm_clock_hz", + "temp_c", + "throttled_hex" + ], + "samples": [ + [ + 1782425178, + null, + null, + null + ], + [ + 1782425178, + null, + null, + null + ], + [ + 1782425179, + null, + null, + null + ], + [ + 1782425180, + null, + null, + null + ], + [ + 1782425181, + null, + null, + null + ], + [ + 1782425182, + null, + null, + null + ], + [ + 1782425183, + null, + null, + null + ], + [ + 1782425184, + null, + null, + null + ], + [ + 1782425185, + null, + null, + null + ], + [ + 1782425186, + null, + null, + null + ], + [ + 1782425187, + null, + null, + null + ], + [ + 1782425188, + null, + null, + null + ], + [ + 1782425189, + null, + null, + null + ], + [ + 1782425190, + null, + null, + null + ], + [ + 1782425191, + null, + null, + null + ], + [ + 1782425192, + null, + null, + null + ], + [ + 1782425193, + null, + null, + null + ], + [ + 1782425194, + null, + null, + null + ], + [ + 1782425195, + null, + null, + null + ], + [ + 1782425196, + null, + null, + null + ], + [ + 1782425197, + null, + null, + null + ], + [ + 1782425198, + null, + null, + null + ], + [ + 1782425199, + null, + null, + null + ], + [ + 1782425200, + null, + null, + null + ], + [ + 1782425201, + null, + null, + null + ], + [ + 1782425202, + null, + null, + null + ], + [ + 1782425203, + null, + null, + null + ], + [ + 1782425204, + null, + null, + null + ], + [ + 1782425205, + null, + null, + null + ], + [ + 1782425206, + null, + null, + null + ], + [ + 1782425207, + null, + null, + null + ], + [ + 1782425208, + null, + null, + null + ], + [ + 1782425209, + null, + null, + null + ], + [ + 1782425210, + null, + null, + null + ], + [ + 1782425211, + null, + null, + null + ], + [ + 1782425212, + null, + null, + null + ], + [ + 1782425213, + null, + null, + null + ], + [ + 1782425214, + null, + null, + null + ], + [ + 1782425215, + null, + null, + null + ], + [ + 1782425216, + null, + null, + null + ], + [ + 1782425217, + null, + null, + null + ], + [ + 1782425218, + null, + null, + null + ], + [ + 1782425219, + null, + null, + null + ], + [ + 1782425221, + null, + null, + null + ], + [ + 1782425222, + null, + null, + null + ], + [ + 1782425223, + null, + null, + null + ], + [ + 1782425224, + null, + null, + null + ], + [ + 1782425225, + null, + null, + null + ], + [ + 1782425226, + null, + null, + null + ], + [ + 1782425227, + null, + null, + null + ], + [ + 1782425228, + null, + null, + null + ], + [ + 1782425229, + null, + null, + null + ], + [ + 1782425230, + null, + null, + null + ], + [ + 1782425231, + null, + null, + null + ], + [ + 1782425232, + null, + null, + null + ], + [ + 1782425233, + null, + null, + null + ], + [ + 1782425234, + null, + null, + null + ], + [ + 1782425235, + null, + null, + null + ], + [ + 1782425236, + null, + null, + null + ], + [ + 1782425237, + null, + null, + null + ], + [ + 1782425238, + null, + null, + null + ], + [ + 1782425239, + null, + null, + null + ], + [ + 1782425240, + null, + null, + null + ], + [ + 1782425241, + null, + null, + null + ], + [ + 1782425242, + null, + null, + null + ], + [ + 1782425243, + null, + null, + null + ], + [ + 1782425244, + null, + null, + null + ], + [ + 1782425245, + null, + null, + null + ], + [ + 1782425246, + null, + null, + null + ], + [ + 1782425247, + null, + null, + null + ], + [ + 1782425248, + null, + null, + null + ], + [ + 1782425249, + null, + null, + null + ], + [ + 1782425250, + null, + null, + null + ], + [ + 1782425251, + null, + null, + null + ], + [ + 1782425252, + null, + null, + null + ], + [ + 1782425253, + null, + null, + null + ], + [ + 1782425254, + null, + null, + null + ], + [ + 1782425255, + null, + null, + null + ], + [ + 1782425256, + null, + null, + null + ], + [ + 1782425257, + null, + null, + null + ], + [ + 1782425258, + null, + null, + null + ], + [ + 1782425259, + null, + null, + null + ], + [ + 1782425260, + null, + null, + null + ], + [ + 1782425261, + null, + null, + null + ], + [ + 1782425262, + null, + null, + null + ], + [ + 1782425263, + null, + null, + null + ], + [ + 1782425264, + null, + null, + null + ], + [ + 1782425265, + null, + null, + null + ], + [ + 1782425266, + null, + null, + null + ], + [ + 1782425267, + null, + null, + null + ], + [ + 1782425268, + null, + null, + null + ], + [ + 1782425269, + null, + null, + null + ], + [ + 1782425270, + null, + null, + null + ], + [ + 1782425271, + null, + null, + null + ], + [ + 1782425272, + null, + null, + null + ], + [ + 1782425273, + null, + null, + null + ], + [ + 1782425274, + null, + null, + null + ], + [ + 1782425275, + null, + null, + null + ], + [ + 1782425276, + null, + null, + null + ], + [ + 1782425277, + null, + null, + null + ], + [ + 1782425278, + null, + null, + null + ], + [ + 1782425279, + null, + null, + null + ], + [ + 1782425280, + null, + null, + null + ], + [ + 1782425281, + null, + null, + null + ], + [ + 1782425282, + null, + null, + null + ], + [ + 1782425283, + null, + null, + null + ], + [ + 1782425284, + null, + null, + null + ], + [ + 1782425285, + null, + null, + null + ], + [ + 1782425286, + null, + null, + null + ], + [ + 1782425287, + null, + null, + null + ], + [ + 1782425288, + null, + null, + null + ], + [ + 1782425289, + null, + null, + null + ], + [ + 1782425290, + null, + null, + null + ], + [ + 1782425291, + null, + null, + null + ], + [ + 1782425292, + null, + null, + null + ], + [ + 1782425293, + null, + null, + null + ], + [ + 1782425294, + null, + null, + null + ], + [ + 1782425295, + null, + null, + null + ], + [ + 1782425296, + null, + null, + null + ], + [ + 1782425297, + null, + null, + null + ], + [ + 1782425298, + null, + null, + null + ], + [ + 1782425299, + null, + null, + null + ], + [ + 1782425300, + null, + null, + null + ], + [ + 1782425301, + null, + null, + null + ], + [ + 1782425302, + null, + null, + null + ], + [ + 1782425303, + null, + null, + null + ], + [ + 1782425304, + null, + null, + null + ], + [ + 1782425305, + null, + null, + null + ], + [ + 1782425306, + null, + null, + null + ], + [ + 1782425307, + null, + null, + null + ], + [ + 1782425308, + null, + null, + null + ], + [ + 1782425309, + null, + null, + null + ], + [ + 1782425310, + null, + null, + null + ], + [ + 1782425312, + null, + null, + null + ], + [ + 1782425313, + null, + null, + null + ], + [ + 1782425314, + null, + null, + null + ], + [ + 1782425315, + null, + null, + null + ], + [ + 1782425316, + null, + null, + null + ], + [ + 1782425317, + null, + null, + null + ], + [ + 1782425318, + null, + null, + null + ], + [ + 1782425319, + null, + null, + null + ], + [ + 1782425320, + null, + null, + null + ], + [ + 1782425321, + null, + null, + null + ], + [ + 1782425322, + null, + null, + null + ], + [ + 1782425323, + null, + null, + null + ], + [ + 1782425324, + null, + null, + null + ], + [ + 1782425325, + null, + null, + null + ], + [ + 1782425326, + null, + null, + null + ], + [ + 1782425327, + null, + null, + null + ], + [ + 1782425328, + null, + null, + null + ], + [ + 1782425329, + null, + null, + null + ], + [ + 1782425330, + null, + null, + null + ], + [ + 1782425331, + null, + null, + null + ], + [ + 1782425332, + null, + null, + null + ], + [ + 1782425333, + null, + null, + null + ], + [ + 1782425334, + null, + null, + null + ], + [ + 1782425335, + null, + null, + null + ], + [ + 1782425336, + null, + null, + null + ], + [ + 1782425337, + null, + null, + null + ], + [ + 1782425338, + null, + null, + null + ], + [ + 1782425339, + null, + null, + null + ], + [ + 1782425340, + null, + null, + null + ], + [ + 1782425341, + null, + null, + null + ], + [ + 1782425342, + null, + null, + null + ], + [ + 1782425343, + null, + null, + null + ], + [ + 1782425344, + null, + null, + null + ], + [ + 1782425345, + null, + null, + null + ], + [ + 1782425346, + null, + null, + null + ], + [ + 1782425347, + null, + null, + null + ], + [ + 1782425348, + null, + null, + null + ], + [ + 1782425349, + null, + null, + null + ], + [ + 1782425350, + null, + null, + null + ], + [ + 1782425351, + null, + null, + null + ], + [ + 1782425352, + null, + null, + null + ], + [ + 1782425353, + null, + null, + null + ], + [ + 1782425354, + null, + null, + null + ], + [ + 1782425355, + null, + null, + null + ], + [ + 1782425356, + null, + null, + null + ], + [ + 1782425357, + null, + null, + null + ], + [ + 1782425358, + null, + null, + null + ], + [ + 1782425359, + null, + null, + null + ], + [ + 1782425360, + null, + null, + null + ], + [ + 1782425361, + null, + null, + null + ], + [ + 1782425362, + null, + null, + null + ], + [ + 1782425363, + null, + null, + null + ], + [ + 1782425364, + null, + null, + null + ], + [ + 1782425365, + null, + null, + null + ], + [ + 1782425366, + null, + null, + null + ], + [ + 1782425367, + null, + null, + null + ], + [ + 1782425368, + null, + null, + null + ], + [ + 1782425369, + null, + null, + null + ], + [ + 1782425370, + null, + null, + null + ], + [ + 1782425371, + null, + null, + null + ], + [ + 1782425372, + null, + null, + null + ], + [ + 1782425373, + null, + null, + null + ], + [ + 1782425374, + null, + null, + null + ], + [ + 1782425375, + null, + null, + null + ], + [ + 1782425376, + null, + null, + null + ], + [ + 1782425377, + null, + null, + null + ], + [ + 1782425378, + null, + null, + null + ], + [ + 1782425379, + null, + null, + null + ], + [ + 1782425380, + null, + null, + null + ], + [ + 1782425381, + null, + null, + null + ], + [ + 1782425382, + null, + null, + null + ], + [ + 1782425383, + null, + null, + null + ], + [ + 1782425384, + null, + null, + null + ], + [ + 1782425385, + null, + null, + null + ], + [ + 1782425386, + null, + null, + null + ], + [ + 1782425387, + null, + null, + null + ], + [ + 1782425388, + null, + null, + null + ], + [ + 1782425389, + null, + null, + null + ], + [ + 1782425390, + null, + null, + null + ], + [ + 1782425391, + null, + null, + null + ], + [ + 1782425392, + null, + null, + null + ], + [ + 1782425393, + null, + null, + null + ], + [ + 1782425394, + null, + null, + null + ], + [ + 1782425395, + null, + null, + null + ], + [ + 1782425396, + null, + null, + null + ], + [ + 1782425397, + null, + null, + null + ], + [ + 1782425398, + null, + null, + null + ], + [ + 1782425399, + null, + null, + null + ], + [ + 1782425400, + null, + null, + null + ], + [ + 1782425401, + null, + null, + null + ], + [ + 1782425402, + null, + null, + null + ], + [ + 1782425403, + null, + null, + null + ], + [ + 1782425404, + null, + null, + null + ], + [ + 1782425406, + null, + null, + null + ], + [ + 1782425407, + null, + null, + null + ], + [ + 1782425408, + null, + null, + null + ], + [ + 1782425409, + null, + null, + null + ], + [ + 1782425410, + null, + null, + null + ], + [ + 1782425411, + null, + null, + null + ], + [ + 1782425412, + null, + null, + null + ], + [ + 1782425413, + null, + null, + null + ], + [ + 1782425414, + null, + null, + null + ], + [ + 1782425415, + null, + null, + null + ], + [ + 1782425416, + null, + null, + null + ], + [ + 1782425417, + null, + null, + null + ], + [ + 1782425418, + null, + null, + null + ], + [ + 1782425419, + null, + null, + null + ], + [ + 1782425420, + null, + null, + null + ], + [ + 1782425421, + null, + null, + null + ], + [ + 1782425422, + null, + null, + null + ], + [ + 1782425423, + null, + null, + null + ], + [ + 1782425424, + null, + null, + null + ], + [ + 1782425425, + null, + null, + null + ], + [ + 1782425426, + null, + null, + null + ], + [ + 1782425427, + null, + null, + null + ], + [ + 1782425428, + null, + null, + null + ], + [ + 1782425429, + null, + null, + null + ], + [ + 1782425430, + null, + null, + null + ], + [ + 1782425431, + null, + null, + null + ], + [ + 1782425432, + null, + null, + null + ], + [ + 1782425433, + null, + null, + null + ], + [ + 1782425434, + null, + null, + null + ], + [ + 1782425435, + null, + null, + null + ], + [ + 1782425436, + null, + null, + null + ], + [ + 1782425437, + null, + null, + null + ], + [ + 1782425438, + null, + null, + null + ], + [ + 1782425439, + null, + null, + null + ], + [ + 1782425440, + null, + null, + null + ], + [ + 1782425441, + null, + null, + null + ], + [ + 1782425442, + null, + null, + null + ], + [ + 1782425443, + null, + null, + null + ], + [ + 1782425444, + null, + null, + null + ], + [ + 1782425445, + null, + null, + null + ], + [ + 1782425446, + null, + null, + null + ], + [ + 1782425447, + null, + null, + null + ], + [ + 1782425448, + null, + null, + null + ], + [ + 1782425449, + null, + null, + null + ], + [ + 1782425450, + null, + null, + null + ], + [ + 1782425451, + null, + null, + null + ], + [ + 1782425452, + null, + null, + null + ], + [ + 1782425453, + null, + null, + null + ], + [ + 1782425454, + null, + null, + null + ], + [ + 1782425455, + null, + null, + null + ], + [ + 1782425456, + null, + null, + null + ], + [ + 1782425457, + null, + null, + null + ], + [ + 1782425458, + null, + null, + null + ], + [ + 1782425459, + null, + null, + null + ], + [ + 1782425460, + null, + null, + null + ], + [ + 1782425461, + null, + null, + null + ], + [ + 1782425462, + null, + null, + null + ], + [ + 1782425463, + null, + null, + null + ], + [ + 1782425464, + null, + null, + null + ], + [ + 1782425465, + null, + null, + null + ], + [ + 1782425466, + null, + null, + null + ], + [ + 1782425467, + null, + null, + null + ], + [ + 1782425468, + null, + null, + null + ], + [ + 1782425469, + null, + null, + null + ], + [ + 1782425470, + null, + null, + null + ], + [ + 1782425471, + null, + null, + null + ], + [ + 1782425472, + null, + null, + null + ], + [ + 1782425473, + null, + null, + null + ], + [ + 1782425474, + null, + null, + null + ], + [ + 1782425475, + null, + null, + null + ], + [ + 1782425476, + null, + null, + null + ], + [ + 1782425477, + null, + null, + null + ], + [ + 1782425478, + null, + null, + null + ], + [ + 1782425479, + null, + null, + null + ], + [ + 1782425480, + null, + null, + null + ], + [ + 1782425481, + null, + null, + null + ], + [ + 1782425482, + null, + null, + null + ], + [ + 1782425483, + null, + null, + null + ], + [ + 1782425484, + null, + null, + null + ], + [ + 1782425485, + null, + null, + null + ], + [ + 1782425486, + null, + null, + null + ], + [ + 1782425487, + null, + null, + null + ], + [ + 1782425488, + null, + null, + null + ], + [ + 1782425489, + null, + null, + null + ], + [ + 1782425490, + null, + null, + null + ], + [ + 1782425491, + null, + null, + null + ], + [ + 1782425493, + null, + null, + null + ], + [ + 1782425494, + null, + null, + null + ], + [ + 1782425495, + null, + null, + null + ], + [ + 1782425496, + null, + null, + null + ], + [ + 1782425497, + null, + null, + null + ], + [ + 1782425498, + null, + null, + null + ], + [ + 1782425499, + null, + null, + null + ], + [ + 1782425500, + null, + null, + null + ], + [ + 1782425501, + null, + null, + null + ], + [ + 1782425502, + null, + null, + null + ], + [ + 1782425503, + null, + null, + null + ], + [ + 1782425504, + null, + null, + null + ], + [ + 1782425505, + null, + null, + null + ], + [ + 1782425506, + null, + null, + null + ], + [ + 1782425507, + null, + null, + null + ], + [ + 1782425508, + null, + null, + null + ], + [ + 1782425509, + null, + null, + null + ], + [ + 1782425510, + null, + null, + null + ], + [ + 1782425511, + null, + null, + null + ], + [ + 1782425512, + null, + null, + null + ], + [ + 1782425513, + null, + null, + null + ], + [ + 1782425514, + null, + null, + null + ], + [ + 1782425515, + null, + null, + null + ], + [ + 1782425516, + null, + null, + null + ], + [ + 1782425517, + null, + null, + null + ], + [ + 1782425518, + null, + null, + null + ], + [ + 1782425519, + null, + null, + null + ], + [ + 1782425520, + null, + null, + null + ], + [ + 1782425521, + null, + null, + null + ], + [ + 1782425522, + null, + null, + null + ], + [ + 1782425523, + null, + null, + null + ], + [ + 1782425524, + null, + null, + null + ], + [ + 1782425525, + null, + null, + null + ], + [ + 1782425526, + null, + null, + null + ], + [ + 1782425527, + null, + null, + null + ], + [ + 1782425528, + null, + null, + null + ], + [ + 1782425529, + null, + null, + null + ], + [ + 1782425530, + null, + null, + null + ], + [ + 1782425531, + null, + null, + null + ], + [ + 1782425532, + null, + null, + null + ], + [ + 1782425533, + null, + null, + null + ], + [ + 1782425534, + null, + null, + null + ], + [ + 1782425535, + null, + null, + null + ], + [ + 1782425536, + null, + null, + null + ], + [ + 1782425537, + null, + null, + null + ], + [ + 1782425538, + null, + null, + null + ], + [ + 1782425539, + null, + null, + null + ], + [ + 1782425540, + null, + null, + null + ], + [ + 1782425541, + null, + null, + null + ], + [ + 1782425542, + null, + null, + null + ], + [ + 1782425543, + null, + null, + null + ], + [ + 1782425544, + null, + null, + null + ], + [ + 1782425545, + null, + null, + null + ], + [ + 1782425546, + null, + null, + null + ], + [ + 1782425547, + null, + null, + null + ], + [ + 1782425548, + null, + null, + null + ], + [ + 1782425549, + null, + null, + null + ], + [ + 1782425550, + null, + null, + null + ], + [ + 1782425551, + null, + null, + null + ], + [ + 1782425552, + null, + null, + null + ], + [ + 1782425553, + null, + null, + null + ], + [ + 1782425554, + null, + null, + null + ], + [ + 1782425555, + null, + null, + null + ], + [ + 1782425556, + null, + null, + null + ], + [ + 1782425557, + null, + null, + null + ], + [ + 1782425558, + null, + null, + null + ], + [ + 1782425559, + null, + null, + null + ], + [ + 1782425560, + null, + null, + null + ], + [ + 1782425562, + null, + null, + null + ], + [ + 1782425563, + null, + null, + null + ], + [ + 1782425564, + null, + null, + null + ], + [ + 1782425565, + null, + null, + null + ], + [ + 1782425566, + null, + null, + null + ], + [ + 1782425567, + null, + null, + null + ], + [ + 1782425568, + null, + null, + null + ], + [ + 1782425569, + null, + null, + null + ], + [ + 1782425570, + null, + null, + null + ], + [ + 1782425571, + null, + null, + null + ], + [ + 1782425572, + null, + null, + null + ], + [ + 1782425573, + null, + null, + null + ], + [ + 1782425574, + null, + null, + null + ], + [ + 1782425575, + null, + null, + null + ], + [ + 1782425576, + null, + null, + null + ], + [ + 1782425577, + null, + null, + null + ], + [ + 1782425578, + null, + null, + null + ], + [ + 1782425579, + null, + null, + null + ], + [ + 1782425580, + null, + null, + null + ], + [ + 1782425581, + null, + null, + null + ], + [ + 1782425582, + null, + null, + null + ], + [ + 1782425583, + null, + null, + null + ], + [ + 1782425584, + null, + null, + null + ], + [ + 1782425585, + null, + null, + null + ], + [ + 1782425586, + null, + null, + null + ], + [ + 1782425587, + null, + null, + null + ], + [ + 1782425588, + null, + null, + null + ], + [ + 1782425589, + null, + null, + null + ], + [ + 1782425590, + null, + null, + null + ], + [ + 1782425591, + null, + null, + null + ], + [ + 1782425592, + null, + null, + null + ], + [ + 1782425593, + null, + null, + null + ], + [ + 1782425594, + null, + null, + null + ], + [ + 1782425595, + null, + null, + null + ], + [ + 1782425596, + null, + null, + null + ], + [ + 1782425597, + null, + null, + null + ], + [ + 1782425598, + null, + null, + null + ], + [ + 1782425599, + null, + null, + null + ], + [ + 1782425600, + null, + null, + null + ], + [ + 1782425601, + null, + null, + null + ], + [ + 1782425602, + null, + null, + null + ], + [ + 1782425603, + null, + null, + null + ], + [ + 1782425604, + null, + null, + null + ], + [ + 1782425605, + null, + null, + null + ], + [ + 1782425606, + null, + null, + null + ], + [ + 1782425607, + null, + null, + null + ], + [ + 1782425608, + null, + null, + null + ], + [ + 1782425609, + null, + null, + null + ], + [ + 1782425610, + null, + null, + null + ], + [ + 1782425611, + null, + null, + null + ], + [ + 1782425612, + null, + null, + null + ], + [ + 1782425613, + null, + null, + null + ], + [ + 1782425614, + null, + null, + null + ], + [ + 1782425615, + null, + null, + null + ], + [ + 1782425616, + null, + null, + null + ], + [ + 1782425617, + null, + null, + null + ], + [ + 1782425618, + null, + null, + null + ], + [ + 1782425619, + null, + null, + null + ], + [ + 1782425620, + null, + null, + null + ], + [ + 1782425621, + null, + null, + null + ], + [ + 1782425622, + null, + null, + null + ], + [ + 1782425623, + null, + null, + null + ], + [ + 1782425624, + null, + null, + null + ], + [ + 1782425625, + null, + null, + null + ], + [ + 1782425626, + null, + null, + null + ], + [ + 1782425628, + null, + null, + null + ], + [ + 1782425629, + null, + null, + null + ], + [ + 1782425630, + null, + null, + null + ], + [ + 1782425631, + null, + null, + null + ], + [ + 1782425632, + null, + null, + null + ], + [ + 1782425633, + null, + null, + null + ], + [ + 1782425634, + null, + null, + null + ], + [ + 1782425635, + null, + null, + null + ], + [ + 1782425636, + null, + null, + null + ], + [ + 1782425637, + null, + null, + null + ], + [ + 1782425638, + null, + null, + null + ], + [ + 1782425639, + null, + null, + null + ], + [ + 1782425640, + null, + null, + null + ], + [ + 1782425641, + null, + null, + null + ], + [ + 1782425642, + null, + null, + null + ], + [ + 1782425643, + null, + null, + null + ], + [ + 1782425644, + null, + null, + null + ], + [ + 1782425645, + null, + null, + null + ], + [ + 1782425646, + null, + null, + null + ], + [ + 1782425647, + null, + null, + null + ], + [ + 1782425648, + null, + null, + null + ], + [ + 1782425649, + null, + null, + null + ], + [ + 1782425650, + null, + null, + null + ], + [ + 1782425651, + null, + null, + null + ], + [ + 1782425652, + null, + null, + null + ], + [ + 1782425653, + null, + null, + null + ], + [ + 1782425654, + null, + null, + null + ], + [ + 1782425655, + null, + null, + null + ], + [ + 1782425656, + null, + null, + null + ], + [ + 1782425657, + null, + null, + null + ], + [ + 1782425658, + null, + null, + null + ], + [ + 1782425659, + null, + null, + null + ], + [ + 1782425660, + null, + null, + null + ], + [ + 1782425661, + null, + null, + null + ], + [ + 1782425662, + null, + null, + null + ], + [ + 1782425663, + null, + null, + null + ], + [ + 1782425664, + null, + null, + null + ], + [ + 1782425665, + null, + null, + null + ], + [ + 1782425666, + null, + null, + null + ], + [ + 1782425667, + null, + null, + null + ], + [ + 1782425668, + null, + null, + null + ], + [ + 1782425669, + null, + null, + null + ], + [ + 1782425670, + null, + null, + null + ], + [ + 1782425671, + null, + null, + null + ], + [ + 1782425672, + null, + null, + null + ], + [ + 1782425673, + null, + null, + null + ], + [ + 1782425674, + null, + null, + null + ], + [ + 1782425675, + null, + null, + null + ], + [ + 1782425676, + null, + null, + null + ], + [ + 1782425677, + null, + null, + null + ], + [ + 1782425678, + null, + null, + null + ], + [ + 1782425679, + null, + null, + null + ], + [ + 1782425680, + null, + null, + null + ], + [ + 1782425681, + null, + null, + null + ], + [ + 1782425682, + null, + null, + null + ], + [ + 1782425683, + null, + null, + null + ], + [ + 1782425684, + null, + null, + null + ], + [ + 1782425685, + null, + null, + null + ], + [ + 1782425686, + null, + null, + null + ], + [ + 1782425687, + null, + null, + null + ], + [ + 1782425688, + null, + null, + null + ], + [ + 1782425689, + null, + null, + null + ], + [ + 1782425690, + null, + null, + null + ], + [ + 1782425691, + null, + null, + null + ], + [ + 1782425692, + null, + null, + null + ], + [ + 1782425693, + null, + null, + null + ], + [ + 1782425694, + null, + null, + null + ], + [ + 1782425696, + null, + null, + null + ], + [ + 1782425697, + null, + null, + null + ], + [ + 1782425698, + null, + null, + null + ], + [ + 1782425699, + null, + null, + null + ], + [ + 1782425700, + null, + null, + null + ], + [ + 1782425701, + null, + null, + null + ], + [ + 1782425702, + null, + null, + null + ], + [ + 1782425703, + null, + null, + null + ], + [ + 1782425704, + null, + null, + null + ], + [ + 1782425705, + null, + null, + null + ], + [ + 1782425706, + null, + null, + null + ], + [ + 1782425707, + null, + null, + null + ], + [ + 1782425708, + null, + null, + null + ], + [ + 1782425709, + null, + null, + null + ], + [ + 1782425710, + null, + null, + null + ], + [ + 1782425711, + null, + null, + null + ], + [ + 1782425712, + null, + null, + null + ], + [ + 1782425713, + null, + null, + null + ], + [ + 1782425714, + null, + null, + null + ], + [ + 1782425715, + null, + null, + null + ], + [ + 1782425716, + null, + null, + null + ], + [ + 1782425717, + null, + null, + null + ], + [ + 1782425718, + null, + null, + null + ], + [ + 1782425719, + null, + null, + null + ], + [ + 1782425720, + null, + null, + null + ], + [ + 1782425721, + null, + null, + null + ], + [ + 1782425722, + null, + null, + null + ], + [ + 1782425723, + null, + null, + null + ], + [ + 1782425724, + null, + null, + null + ], + [ + 1782425725, + null, + null, + null + ], + [ + 1782425726, + null, + null, + null + ], + [ + 1782425727, + null, + null, + null + ], + [ + 1782425728, + null, + null, + null + ], + [ + 1782425729, + null, + null, + null + ], + [ + 1782425730, + null, + null, + null + ], + [ + 1782425731, + null, + null, + null + ], + [ + 1782425732, + null, + null, + null + ], + [ + 1782425733, + null, + null, + null + ], + [ + 1782425734, + null, + null, + null + ], + [ + 1782425735, + null, + null, + null + ], + [ + 1782425736, + null, + null, + null + ], + [ + 1782425737, + null, + null, + null + ], + [ + 1782425738, + null, + null, + null + ], + [ + 1782425739, + null, + null, + null + ], + [ + 1782425740, + null, + null, + null + ], + [ + 1782425741, + null, + null, + null + ], + [ + 1782425742, + null, + null, + null + ], + [ + 1782425743, + null, + null, + null + ], + [ + 1782425744, + null, + null, + null + ], + [ + 1782425745, + null, + null, + null + ], + [ + 1782425746, + null, + null, + null + ], + [ + 1782425747, + null, + null, + null + ], + [ + 1782425748, + null, + null, + null + ], + [ + 1782425749, + null, + null, + null + ], + [ + 1782425750, + null, + null, + null + ], + [ + 1782425751, + null, + null, + null + ], + [ + 1782425752, + null, + null, + null + ], + [ + 1782425753, + null, + null, + null + ], + [ + 1782425754, + null, + null, + null + ], + [ + 1782425755, + null, + null, + null + ], + [ + 1782425756, + null, + null, + null + ], + [ + 1782425757, + null, + null, + null + ], + [ + 1782425758, + null, + null, + null + ], + [ + 1782425759, + null, + null, + null + ], + [ + 1782425760, + null, + null, + null + ], + [ + 1782425761, + null, + null, + null + ], + [ + 1782425762, + null, + null, + null + ], + [ + 1782425763, + null, + null, + null + ], + [ + 1782425765, + null, + null, + null + ], + [ + 1782425766, + null, + null, + null + ], + [ + 1782425767, + null, + null, + null + ], + [ + 1782425768, + null, + null, + null + ], + [ + 1782425769, + null, + null, + null + ], + [ + 1782425770, + null, + null, + null + ], + [ + 1782425771, + null, + null, + null + ], + [ + 1782425772, + null, + null, + null + ], + [ + 1782425773, + null, + null, + null + ], + [ + 1782425774, + null, + null, + null + ], + [ + 1782425775, + null, + null, + null + ], + [ + 1782425776, + null, + null, + null + ], + [ + 1782425777, + null, + null, + null + ], + [ + 1782425778, + null, + null, + null + ], + [ + 1782425779, + null, + null, + null + ], + [ + 1782425780, + null, + null, + null + ], + [ + 1782425781, + null, + null, + null + ], + [ + 1782425782, + null, + null, + null + ], + [ + 1782425783, + null, + null, + null + ], + [ + 1782425784, + null, + null, + null + ], + [ + 1782425785, + null, + null, + null + ], + [ + 1782425786, + null, + null, + null + ], + [ + 1782425787, + null, + null, + null + ], + [ + 1782425788, + null, + null, + null + ], + [ + 1782425789, + null, + null, + null + ], + [ + 1782425790, + null, + null, + null + ], + [ + 1782425791, + null, + null, + null + ], + [ + 1782425792, + null, + null, + null + ], + [ + 1782425793, + null, + null, + null + ], + [ + 1782425794, + null, + null, + null + ], + [ + 1782425795, + null, + null, + null + ], + [ + 1782425796, + null, + null, + null + ], + [ + 1782425797, + null, + null, + null + ], + [ + 1782425798, + null, + null, + null + ], + [ + 1782425799, + null, + null, + null + ], + [ + 1782425800, + null, + null, + null + ], + [ + 1782425801, + null, + null, + null + ], + [ + 1782425802, + null, + null, + null + ], + [ + 1782425803, + null, + null, + null + ], + [ + 1782425804, + null, + null, + null + ], + [ + 1782425805, + null, + null, + null + ], + [ + 1782425806, + null, + null, + null + ], + [ + 1782425807, + null, + null, + null + ], + [ + 1782425808, + null, + null, + null + ], + [ + 1782425809, + null, + null, + null + ], + [ + 1782425810, + null, + null, + null + ], + [ + 1782425811, + null, + null, + null + ], + [ + 1782425812, + null, + null, + null + ], + [ + 1782425813, + null, + null, + null + ], + [ + 1782425814, + null, + null, + null + ], + [ + 1782425815, + null, + null, + null + ], + [ + 1782425816, + null, + null, + null + ], + [ + 1782425817, + null, + null, + null + ], + [ + 1782425818, + null, + null, + null + ], + [ + 1782425819, + null, + null, + null + ], + [ + 1782425820, + null, + null, + null + ], + [ + 1782425821, + null, + null, + null + ], + [ + 1782425822, + null, + null, + null + ], + [ + 1782425823, + null, + null, + null + ], + [ + 1782425824, + null, + null, + null + ], + [ + 1782425825, + null, + null, + null + ], + [ + 1782425826, + null, + null, + null + ], + [ + 1782425827, + null, + null, + null + ], + [ + 1782425828, + null, + null, + null + ], + [ + 1782425829, + null, + null, + null + ], + [ + 1782425830, + null, + null, + null + ], + [ + 1782425832, + null, + null, + null + ], + [ + 1782425833, + null, + null, + null + ], + [ + 1782425834, + null, + null, + null + ], + [ + 1782425835, + null, + null, + null + ], + [ + 1782425836, + null, + null, + null + ], + [ + 1782425837, + null, + null, + null + ], + [ + 1782425838, + null, + null, + null + ], + [ + 1782425839, + null, + null, + null + ], + [ + 1782425840, + null, + null, + null + ], + [ + 1782425841, + null, + null, + null + ], + [ + 1782425842, + null, + null, + null + ], + [ + 1782425843, + null, + null, + null + ], + [ + 1782425844, + null, + null, + null + ], + [ + 1782425845, + null, + null, + null + ], + [ + 1782425846, + null, + null, + null + ], + [ + 1782425847, + null, + null, + null + ], + [ + 1782425848, + null, + null, + null + ], + [ + 1782425849, + null, + null, + null + ], + [ + 1782425850, + null, + null, + null + ], + [ + 1782425851, + null, + null, + null + ], + [ + 1782425852, + null, + null, + null + ], + [ + 1782425853, + null, + null, + null + ], + [ + 1782425854, + null, + null, + null + ], + [ + 1782425855, + null, + null, + null + ], + [ + 1782425856, + null, + null, + null + ], + [ + 1782425857, + null, + null, + null + ], + [ + 1782425858, + null, + null, + null + ], + [ + 1782425859, + null, + null, + null + ], + [ + 1782425860, + null, + null, + null + ], + [ + 1782425861, + null, + null, + null + ], + [ + 1782425862, + null, + null, + null + ], + [ + 1782425863, + null, + null, + null + ], + [ + 1782425864, + null, + null, + null + ], + [ + 1782425865, + null, + null, + null + ], + [ + 1782425866, + null, + null, + null + ], + [ + 1782425867, + null, + null, + null + ], + [ + 1782425868, + null, + null, + null + ], + [ + 1782425869, + null, + null, + null + ], + [ + 1782425870, + null, + null, + null + ], + [ + 1782425871, + null, + null, + null + ], + [ + 1782425872, + null, + null, + null + ], + [ + 1782425873, + null, + null, + null + ], + [ + 1782425874, + null, + null, + null + ], + [ + 1782425875, + null, + null, + null + ], + [ + 1782425876, + null, + null, + null + ], + [ + 1782425877, + null, + null, + null + ], + [ + 1782425878, + null, + null, + null + ], + [ + 1782425879, + null, + null, + null + ], + [ + 1782425880, + null, + null, + null + ], + [ + 1782425881, + null, + null, + null + ], + [ + 1782425882, + null, + null, + null + ], + [ + 1782425883, + null, + null, + null + ], + [ + 1782425884, + null, + null, + null + ], + [ + 1782425885, + null, + null, + null + ], + [ + 1782425886, + null, + null, + null + ], + [ + 1782425887, + null, + null, + null + ], + [ + 1782425888, + null, + null, + null + ], + [ + 1782425889, + null, + null, + null + ], + [ + 1782425890, + null, + null, + null + ], + [ + 1782425891, + null, + null, + null + ], + [ + 1782425892, + null, + null, + null + ], + [ + 1782425893, + null, + null, + null + ], + [ + 1782425894, + null, + null, + null + ], + [ + 1782425895, + null, + null, + null + ], + [ + 1782425896, + null, + null, + null + ], + [ + 1782425897, + null, + null, + null + ], + [ + 1782425899, + null, + null, + null + ], + [ + 1782425900, + null, + null, + null + ], + [ + 1782425901, + null, + null, + null + ], + [ + 1782425902, + null, + null, + null + ], + [ + 1782425903, + null, + null, + null + ], + [ + 1782425904, + null, + null, + null + ], + [ + 1782425905, + null, + null, + null + ], + [ + 1782425906, + null, + null, + null + ], + [ + 1782425907, + null, + null, + null + ], + [ + 1782425908, + null, + null, + null + ], + [ + 1782425909, + null, + null, + null + ], + [ + 1782425910, + null, + null, + null + ], + [ + 1782425911, + null, + null, + null + ], + [ + 1782425912, + null, + null, + null + ], + [ + 1782425913, + null, + null, + null + ], + [ + 1782425914, + null, + null, + null + ], + [ + 1782425915, + null, + null, + null + ], + [ + 1782425916, + null, + null, + null + ], + [ + 1782425917, + null, + null, + null + ], + [ + 1782425918, + null, + null, + null + ], + [ + 1782425919, + null, + null, + null + ], + [ + 1782425920, + null, + null, + null + ], + [ + 1782425921, + null, + null, + null + ], + [ + 1782425922, + null, + null, + null + ], + [ + 1782425923, + null, + null, + null + ], + [ + 1782425924, + null, + null, + null + ], + [ + 1782425925, + null, + null, + null + ], + [ + 1782425926, + null, + null, + null + ], + [ + 1782425927, + null, + null, + null + ], + [ + 1782425928, + null, + null, + null + ], + [ + 1782425929, + null, + null, + null + ], + [ + 1782425930, + null, + null, + null + ], + [ + 1782425931, + null, + null, + null + ], + [ + 1782425932, + null, + null, + null + ], + [ + 1782425933, + null, + null, + null + ], + [ + 1782425934, + null, + null, + null + ], + [ + 1782425935, + null, + null, + null + ], + [ + 1782425936, + null, + null, + null + ], + [ + 1782425937, + null, + null, + null + ], + [ + 1782425938, + null, + null, + null + ], + [ + 1782425939, + null, + null, + null + ], + [ + 1782425940, + null, + null, + null + ], + [ + 1782425941, + null, + null, + null + ], + [ + 1782425942, + null, + null, + null + ], + [ + 1782425943, + null, + null, + null + ], + [ + 1782425944, + null, + null, + null + ], + [ + 1782425945, + null, + null, + null + ], + [ + 1782425946, + null, + null, + null + ], + [ + 1782425947, + null, + null, + null + ], + [ + 1782425948, + null, + null, + null + ], + [ + 1782425949, + null, + null, + null + ], + [ + 1782425950, + null, + null, + null + ], + [ + 1782425951, + null, + null, + null + ], + [ + 1782425952, + null, + null, + null + ], + [ + 1782425953, + null, + null, + null + ], + [ + 1782425954, + null, + null, + null + ], + [ + 1782425955, + null, + null, + null + ], + [ + 1782425956, + null, + null, + null + ], + [ + 1782425957, + null, + null, + null + ], + [ + 1782425958, + null, + null, + null + ], + [ + 1782425959, + null, + null, + null + ], + [ + 1782425960, + null, + null, + null + ], + [ + 1782425961, + null, + null, + null + ], + [ + 1782425962, + null, + null, + null + ], + [ + 1782425963, + null, + null, + null + ], + [ + 1782425964, + null, + null, + null + ], + [ + 1782425965, + null, + null, + null + ], + [ + 1782425967, + null, + null, + null + ], + [ + 1782425968, + null, + null, + null + ], + [ + 1782425969, + null, + null, + null + ], + [ + 1782425970, + null, + null, + null + ], + [ + 1782425971, + null, + null, + null + ], + [ + 1782425972, + null, + null, + null + ], + [ + 1782425973, + null, + null, + null + ], + [ + 1782425974, + null, + null, + null + ], + [ + 1782425975, + null, + null, + null + ], + [ + 1782425976, + null, + null, + null + ], + [ + 1782425977, + null, + null, + null + ], + [ + 1782425978, + null, + null, + null + ], + [ + 1782425979, + null, + null, + null + ], + [ + 1782425980, + null, + null, + null + ], + [ + 1782425981, + null, + null, + null + ], + [ + 1782425982, + null, + null, + null + ], + [ + 1782425983, + null, + null, + null + ], + [ + 1782425984, + null, + null, + null + ], + [ + 1782425985, + null, + null, + null + ], + [ + 1782425986, + null, + null, + null + ], + [ + 1782425987, + null, + null, + null + ], + [ + 1782425988, + null, + null, + null + ], + [ + 1782425989, + null, + null, + null + ], + [ + 1782425990, + null, + null, + null + ], + [ + 1782425991, + null, + null, + null + ], + [ + 1782425992, + null, + null, + null + ], + [ + 1782425993, + null, + null, + null + ], + [ + 1782425994, + null, + null, + null + ], + [ + 1782425995, + null, + null, + null + ], + [ + 1782425996, + null, + null, + null + ], + [ + 1782425997, + null, + null, + null + ], + [ + 1782425998, + null, + null, + null + ], + [ + 1782425999, + null, + null, + null + ], + [ + 1782426000, + null, + null, + null + ], + [ + 1782426001, + null, + null, + null + ], + [ + 1782426002, + null, + null, + null + ], + [ + 1782426003, + null, + null, + null + ], + [ + 1782426004, + null, + null, + null + ], + [ + 1782426005, + null, + null, + null + ], + [ + 1782426006, + null, + null, + null + ], + [ + 1782426007, + null, + null, + null + ], + [ + 1782426008, + null, + null, + null + ], + [ + 1782426009, + null, + null, + null + ], + [ + 1782426010, + null, + null, + null + ], + [ + 1782426011, + null, + null, + null + ], + [ + 1782426012, + null, + null, + null + ], + [ + 1782426013, + null, + null, + null + ], + [ + 1782426014, + null, + null, + null + ], + [ + 1782426015, + null, + null, + null + ], + [ + 1782426016, + null, + null, + null + ], + [ + 1782426017, + null, + null, + null + ], + [ + 1782426018, + null, + null, + null + ], + [ + 1782426019, + null, + null, + null + ], + [ + 1782426020, + null, + null, + null + ], + [ + 1782426021, + null, + null, + null + ], + [ + 1782426022, + null, + null, + null + ], + [ + 1782426023, + null, + null, + null + ], + [ + 1782426024, + null, + null, + null + ], + [ + 1782426025, + null, + null, + null + ], + [ + 1782426026, + null, + null, + null + ], + [ + 1782426027, + null, + null, + null + ], + [ + 1782426028, + null, + null, + null + ], + [ + 1782426029, + null, + null, + null + ], + [ + 1782426030, + null, + null, + null + ], + [ + 1782426031, + null, + null, + null + ], + [ + 1782426032, + null, + null, + null + ], + [ + 1782426033, + null, + null, + null + ], + [ + 1782426034, + null, + null, + null + ], + [ + 1782426035, + null, + null, + null + ], + [ + 1782426036, + null, + null, + null + ], + [ + 1782426037, + null, + null, + null + ], + [ + 1782426038, + null, + null, + null + ], + [ + 1782426039, + null, + null, + null + ], + [ + 1782426040, + null, + null, + null + ], + [ + 1782426041, + null, + null, + null + ], + [ + 1782426042, + null, + null, + null + ], + [ + 1782426043, + null, + null, + null + ], + [ + 1782426044, + null, + null, + null + ], + [ + 1782426045, + null, + null, + null + ], + [ + 1782426046, + null, + null, + null + ], + [ + 1782426047, + null, + null, + null + ], + [ + 1782426048, + null, + null, + null + ], + [ + 1782426049, + null, + null, + null + ], + [ + 1782426050, + null, + null, + null + ], + [ + 1782426051, + null, + null, + null + ], + [ + 1782426052, + null, + null, + null + ], + [ + 1782426053, + null, + null, + null + ], + [ + 1782426054, + null, + null, + null + ], + [ + 1782426055, + null, + null, + null + ], + [ + 1782426056, + null, + null, + null + ], + [ + 1782426057, + null, + null, + null + ], + [ + 1782426058, + null, + null, + null + ], + [ + 1782426059, + null, + null, + null + ], + [ + 1782426060, + null, + null, + null + ], + [ + 1782426061, + null, + null, + null + ], + [ + 1782426062, + null, + null, + null + ], + [ + 1782426063, + null, + null, + null + ], + [ + 1782426064, + null, + null, + null + ], + [ + 1782426065, + null, + null, + null + ], + [ + 1782426066, + null, + null, + null + ], + [ + 1782426068, + null, + null, + null + ], + [ + 1782426069, + null, + null, + null + ], + [ + 1782426070, + null, + null, + null + ], + [ + 1782426071, + null, + null, + null + ], + [ + 1782426072, + null, + null, + null + ], + [ + 1782426073, + null, + null, + null + ], + [ + 1782426074, + null, + null, + null + ], + [ + 1782426075, + null, + null, + null + ], + [ + 1782426076, + null, + null, + null + ], + [ + 1782426077, + null, + null, + null + ], + [ + 1782426078, + null, + null, + null + ], + [ + 1782426079, + null, + null, + null + ], + [ + 1782426080, + null, + null, + null + ], + [ + 1782426081, + null, + null, + null + ], + [ + 1782426082, + null, + null, + null + ], + [ + 1782426083, + null, + null, + null + ], + [ + 1782426084, + null, + null, + null + ], + [ + 1782426085, + null, + null, + null + ], + [ + 1782426086, + null, + null, + null + ], + [ + 1782426087, + null, + null, + null + ], + [ + 1782426088, + null, + null, + null + ], + [ + 1782426089, + null, + null, + null + ], + [ + 1782426090, + null, + null, + null + ], + [ + 1782426091, + null, + null, + null + ], + [ + 1782426092, + null, + null, + null + ], + [ + 1782426093, + null, + null, + null + ], + [ + 1782426094, + null, + null, + null + ], + [ + 1782426095, + null, + null, + null + ], + [ + 1782426096, + null, + null, + null + ], + [ + 1782426097, + null, + null, + null + ], + [ + 1782426098, + null, + null, + null + ], + [ + 1782426099, + null, + null, + null + ], + [ + 1782426100, + null, + null, + null + ], + [ + 1782426101, + null, + null, + null + ], + [ + 1782426102, + null, + null, + null + ], + [ + 1782426103, + null, + null, + null + ], + [ + 1782426104, + null, + null, + null + ], + [ + 1782426105, + null, + null, + null + ], + [ + 1782426106, + null, + null, + null + ], + [ + 1782426107, + null, + null, + null + ], + [ + 1782426108, + null, + null, + null + ], + [ + 1782426109, + null, + null, + null + ], + [ + 1782426110, + null, + null, + null + ], + [ + 1782426111, + null, + null, + null + ], + [ + 1782426112, + null, + null, + null + ], + [ + 1782426113, + null, + null, + null + ], + [ + 1782426114, + null, + null, + null + ], + [ + 1782426115, + null, + null, + null + ], + [ + 1782426116, + null, + null, + null + ], + [ + 1782426117, + null, + null, + null + ], + [ + 1782426118, + null, + null, + null + ], + [ + 1782426119, + null, + null, + null + ], + [ + 1782426120, + null, + null, + null + ], + [ + 1782426121, + null, + null, + null + ], + [ + 1782426122, + null, + null, + null + ], + [ + 1782426123, + null, + null, + null + ], + [ + 1782426124, + null, + null, + null + ], + [ + 1782426125, + null, + null, + null + ], + [ + 1782426126, + null, + null, + null + ], + [ + 1782426127, + null, + null, + null + ], + [ + 1782426128, + null, + null, + null + ], + [ + 1782426129, + null, + null, + null + ], + [ + 1782426130, + null, + null, + null + ], + [ + 1782426131, + null, + null, + null + ], + [ + 1782426132, + null, + null, + null + ], + [ + 1782426133, + null, + null, + null + ], + [ + 1782426134, + null, + null, + null + ], + [ + 1782426135, + null, + null, + null + ], + [ + 1782426136, + null, + null, + null + ], + [ + 1782426137, + null, + null, + null + ], + [ + 1782426138, + null, + null, + null + ], + [ + 1782426139, + null, + null, + null + ], + [ + 1782426140, + null, + null, + null + ], + [ + 1782426141, + null, + null, + null + ], + [ + 1782426142, + null, + null, + null + ], + [ + 1782426143, + null, + null, + null + ], + [ + 1782426144, + null, + null, + null + ], + [ + 1782426145, + null, + null, + null + ], + [ + 1782426146, + null, + null, + null + ], + [ + 1782426147, + null, + null, + null + ], + [ + 1782426148, + null, + null, + null + ], + [ + 1782426149, + null, + null, + null + ], + [ + 1782426150, + null, + null, + null + ], + [ + 1782426152, + null, + null, + null + ], + [ + 1782426153, + null, + null, + null + ], + [ + 1782426154, + null, + null, + null + ], + [ + 1782426155, + null, + null, + null + ], + [ + 1782426156, + null, + null, + null + ], + [ + 1782426157, + null, + null, + null + ], + [ + 1782426158, + null, + null, + null + ], + [ + 1782426159, + null, + null, + null + ], + [ + 1782426160, + null, + null, + null + ], + [ + 1782426161, + null, + null, + null + ], + [ + 1782426162, + null, + null, + null + ], + [ + 1782426163, + null, + null, + null + ], + [ + 1782426164, + null, + null, + null + ], + [ + 1782426165, + null, + null, + null + ], + [ + 1782426166, + null, + null, + null + ], + [ + 1782426167, + null, + null, + null + ], + [ + 1782426168, + null, + null, + null + ], + [ + 1782426169, + null, + null, + null + ], + [ + 1782426170, + null, + null, + null + ], + [ + 1782426171, + null, + null, + null + ], + [ + 1782426172, + null, + null, + null + ], + [ + 1782426173, + null, + null, + null + ], + [ + 1782426174, + null, + null, + null + ], + [ + 1782426175, + null, + null, + null + ], + [ + 1782426176, + null, + null, + null + ], + [ + 1782426177, + null, + null, + null + ], + [ + 1782426178, + null, + null, + null + ], + [ + 1782426179, + null, + null, + null + ], + [ + 1782426180, + null, + null, + null + ], + [ + 1782426181, + null, + null, + null + ], + [ + 1782426182, + null, + null, + null + ], + [ + 1782426183, + null, + null, + null + ], + [ + 1782426184, + null, + null, + null + ], + [ + 1782426185, + null, + null, + null + ], + [ + 1782426186, + null, + null, + null + ], + [ + 1782426187, + null, + null, + null + ], + [ + 1782426188, + null, + null, + null + ], + [ + 1782426189, + null, + null, + null + ], + [ + 1782426190, + null, + null, + null + ], + [ + 1782426191, + null, + null, + null + ], + [ + 1782426192, + null, + null, + null + ], + [ + 1782426193, + null, + null, + null + ], + [ + 1782426194, + null, + null, + null + ], + [ + 1782426195, + null, + null, + null + ], + [ + 1782426196, + null, + null, + null + ], + [ + 1782426197, + null, + null, + null + ], + [ + 1782426198, + null, + null, + null + ], + [ + 1782426199, + null, + null, + null + ], + [ + 1782426200, + null, + null, + null + ], + [ + 1782426201, + null, + null, + null + ], + [ + 1782426202, + null, + null, + null + ], + [ + 1782426203, + null, + null, + null + ], + [ + 1782426204, + null, + null, + null + ], + [ + 1782426205, + null, + null, + null + ], + [ + 1782426206, + null, + null, + null + ], + [ + 1782426207, + null, + null, + null + ], + [ + 1782426208, + null, + null, + null + ], + [ + 1782426209, + null, + null, + null + ], + [ + 1782426210, + null, + null, + null + ], + [ + 1782426211, + null, + null, + null + ], + [ + 1782426212, + null, + null, + null + ], + [ + 1782426213, + null, + null, + null + ], + [ + 1782426214, + null, + null, + null + ], + [ + 1782426215, + null, + null, + null + ], + [ + 1782426216, + null, + null, + null + ], + [ + 1782426217, + null, + null, + null + ], + [ + 1782426218, + null, + null, + null + ], + [ + 1782426219, + null, + null, + null + ], + [ + 1782426220, + null, + null, + null + ], + [ + 1782426221, + null, + null, + null + ], + [ + 1782426222, + null, + null, + null + ], + [ + 1782426223, + null, + null, + null + ], + [ + 1782426225, + null, + null, + null + ], + [ + 1782426226, + null, + null, + null + ], + [ + 1782426227, + null, + null, + null + ], + [ + 1782426228, + null, + null, + null + ], + [ + 1782426229, + null, + null, + null + ], + [ + 1782426230, + null, + null, + null + ], + [ + 1782426231, + null, + null, + null + ], + [ + 1782426232, + null, + null, + null + ], + [ + 1782426233, + null, + null, + null + ], + [ + 1782426234, + null, + null, + null + ], + [ + 1782426235, + null, + null, + null + ], + [ + 1782426236, + null, + null, + null + ], + [ + 1782426237, + null, + null, + null + ], + [ + 1782426238, + null, + null, + null + ], + [ + 1782426239, + null, + null, + null + ], + [ + 1782426240, + null, + null, + null + ], + [ + 1782426241, + null, + null, + null + ], + [ + 1782426242, + null, + null, + null + ], + [ + 1782426243, + null, + null, + null + ], + [ + 1782426244, + null, + null, + null + ], + [ + 1782426245, + null, + null, + null + ], + [ + 1782426246, + null, + null, + null + ], + [ + 1782426247, + null, + null, + null + ], + [ + 1782426248, + null, + null, + null + ], + [ + 1782426249, + null, + null, + null + ], + [ + 1782426250, + null, + null, + null + ], + [ + 1782426251, + null, + null, + null + ], + [ + 1782426252, + null, + null, + null + ], + [ + 1782426253, + null, + null, + null + ], + [ + 1782426254, + null, + null, + null + ], + [ + 1782426255, + null, + null, + null + ], + [ + 1782426256, + null, + null, + null + ], + [ + 1782426257, + null, + null, + null + ], + [ + 1782426258, + null, + null, + null + ], + [ + 1782426259, + null, + null, + null + ], + [ + 1782426260, + null, + null, + null + ], + [ + 1782426261, + null, + null, + null + ], + [ + 1782426262, + null, + null, + null + ], + [ + 1782426263, + null, + null, + null + ], + [ + 1782426264, + null, + null, + null + ], + [ + 1782426265, + null, + null, + null + ], + [ + 1782426266, + null, + null, + null + ], + [ + 1782426267, + null, + null, + null + ], + [ + 1782426268, + null, + null, + null + ], + [ + 1782426269, + null, + null, + null + ], + [ + 1782426270, + null, + null, + null + ], + [ + 1782426271, + null, + null, + null + ], + [ + 1782426272, + null, + null, + null + ], + [ + 1782426273, + null, + null, + null + ], + [ + 1782426274, + null, + null, + null + ], + [ + 1782426275, + null, + null, + null + ], + [ + 1782426276, + null, + null, + null + ], + [ + 1782426277, + null, + null, + null + ], + [ + 1782426278, + null, + null, + null + ], + [ + 1782426279, + null, + null, + null + ], + [ + 1782426280, + null, + null, + null + ], + [ + 1782426281, + null, + null, + null + ], + [ + 1782426282, + null, + null, + null + ], + [ + 1782426283, + null, + null, + null + ], + [ + 1782426284, + null, + null, + null + ], + [ + 1782426285, + null, + null, + null + ], + [ + 1782426286, + null, + null, + null + ], + [ + 1782426287, + null, + null, + null + ], + [ + 1782426288, + null, + null, + null + ], + [ + 1782426289, + null, + null, + null + ], + [ + 1782426290, + null, + null, + null + ], + [ + 1782426291, + null, + null, + null + ], + [ + 1782426292, + null, + null, + null + ], + [ + 1782426293, + null, + null, + null + ], + [ + 1782426294, + null, + null, + null + ], + [ + 1782426295, + null, + null, + null + ], + [ + 1782426296, + null, + null, + null + ], + [ + 1782426297, + null, + null, + null + ], + [ + 1782426298, + null, + null, + null + ], + [ + 1782426299, + null, + null, + null + ], + [ + 1782426300, + null, + null, + null + ], + [ + 1782426301, + null, + null, + null + ], + [ + 1782426302, + null, + null, + null + ], + [ + 1782426303, + null, + null, + null + ], + [ + 1782426304, + null, + null, + null + ], + [ + 1782426305, + null, + null, + null + ], + [ + 1782426306, + null, + null, + null + ], + [ + 1782426307, + null, + null, + null + ], + [ + 1782426308, + null, + null, + null + ], + [ + 1782426309, + null, + null, + null + ], + [ + 1782426310, + null, + null, + null + ], + [ + 1782426311, + null, + null, + null + ], + [ + 1782426312, + null, + null, + null + ], + [ + 1782426313, + null, + null, + null + ], + [ + 1782426314, + null, + null, + null + ], + [ + 1782426315, + null, + null, + null + ], + [ + 1782426316, + null, + null, + null + ], + [ + 1782426317, + null, + null, + null + ], + [ + 1782426318, + null, + null, + null + ], + [ + 1782426320, + null, + null, + null + ], + [ + 1782426321, + null, + null, + null + ], + [ + 1782426322, + null, + null, + null + ], + [ + 1782426323, + null, + null, + null + ], + [ + 1782426324, + null, + null, + null + ], + [ + 1782426325, + null, + null, + null + ], + [ + 1782426326, + null, + null, + null + ], + [ + 1782426327, + null, + null, + null + ], + [ + 1782426328, + null, + null, + null + ], + [ + 1782426329, + null, + null, + null + ], + [ + 1782426330, + null, + null, + null + ], + [ + 1782426331, + null, + null, + null + ], + [ + 1782426332, + null, + null, + null + ], + [ + 1782426333, + null, + null, + null + ], + [ + 1782426334, + null, + null, + null + ], + [ + 1782426335, + null, + null, + null + ], + [ + 1782426336, + null, + null, + null + ], + [ + 1782426337, + null, + null, + null + ], + [ + 1782426338, + null, + null, + null + ], + [ + 1782426339, + null, + null, + null + ], + [ + 1782426340, + null, + null, + null + ], + [ + 1782426341, + null, + null, + null + ], + [ + 1782426342, + null, + null, + null + ], + [ + 1782426343, + null, + null, + null + ], + [ + 1782426344, + null, + null, + null + ], + [ + 1782426345, + null, + null, + null + ], + [ + 1782426346, + null, + null, + null + ], + [ + 1782426347, + null, + null, + null + ], + [ + 1782426348, + null, + null, + null + ], + [ + 1782426349, + null, + null, + null + ], + [ + 1782426350, + null, + null, + null + ], + [ + 1782426351, + null, + null, + null + ], + [ + 1782426352, + null, + null, + null + ], + [ + 1782426353, + null, + null, + null + ], + [ + 1782426354, + null, + null, + null + ], + [ + 1782426355, + null, + null, + null + ], + [ + 1782426356, + null, + null, + null + ], + [ + 1782426357, + null, + null, + null + ], + [ + 1782426358, + null, + null, + null + ], + [ + 1782426359, + null, + null, + null + ], + [ + 1782426360, + null, + null, + null + ], + [ + 1782426361, + null, + null, + null + ], + [ + 1782426362, + null, + null, + null + ], + [ + 1782426363, + null, + null, + null + ], + [ + 1782426364, + null, + null, + null + ], + [ + 1782426365, + null, + null, + null + ], + [ + 1782426366, + null, + null, + null + ], + [ + 1782426367, + null, + null, + null + ], + [ + 1782426368, + null, + null, + null + ], + [ + 1782426369, + null, + null, + null + ], + [ + 1782426370, + null, + null, + null + ], + [ + 1782426371, + null, + null, + null + ], + [ + 1782426372, + null, + null, + null + ], + [ + 1782426373, + null, + null, + null + ], + [ + 1782426374, + null, + null, + null + ], + [ + 1782426375, + null, + null, + null + ], + [ + 1782426376, + null, + null, + null + ], + [ + 1782426377, + null, + null, + null + ], + [ + 1782426378, + null, + null, + null + ], + [ + 1782426379, + null, + null, + null + ], + [ + 1782426380, + null, + null, + null + ], + [ + 1782426381, + null, + null, + null + ], + [ + 1782426382, + null, + null, + null + ], + [ + 1782426383, + null, + null, + null + ], + [ + 1782426384, + null, + null, + null + ], + [ + 1782426385, + null, + null, + null + ], + [ + 1782426386, + null, + null, + null + ], + [ + 1782426387, + null, + null, + null + ], + [ + 1782426388, + null, + null, + null + ], + [ + 1782426389, + null, + null, + null + ], + [ + 1782426390, + null, + null, + null + ], + [ + 1782426391, + null, + null, + null + ], + [ + 1782426392, + null, + null, + null + ], + [ + 1782426393, + null, + null, + null + ], + [ + 1782426394, + null, + null, + null + ], + [ + 1782426395, + null, + null, + null + ], + [ + 1782426396, + null, + null, + null + ], + [ + 1782426397, + null, + null, + null + ], + [ + 1782426398, + null, + null, + null + ], + [ + 1782426399, + null, + null, + null + ], + [ + 1782426400, + null, + null, + null + ], + [ + 1782426401, + null, + null, + null + ], + [ + 1782426402, + null, + null, + null + ], + [ + 1782426403, + null, + null, + null + ], + [ + 1782426404, + null, + null, + null + ], + [ + 1782426405, + null, + null, + null + ], + [ + 1782426406, + null, + null, + null + ], + [ + 1782426407, + null, + null, + null + ], + [ + 1782426408, + null, + null, + null + ], + [ + 1782426409, + null, + null, + null + ], + [ + 1782426410, + null, + null, + null + ], + [ + 1782426411, + null, + null, + null + ], + [ + 1782426412, + null, + null, + null + ], + [ + 1782426413, + null, + null, + null + ], + [ + 1782426414, + null, + null, + null + ], + [ + 1782426415, + null, + null, + null + ], + [ + 1782426416, + null, + null, + null + ], + [ + 1782426417, + null, + null, + null + ], + [ + 1782426418, + null, + null, + null + ], + [ + 1782426419, + null, + null, + null + ], + [ + 1782426420, + null, + null, + null + ], + [ + 1782426421, + null, + null, + null + ], + [ + 1782426423, + null, + null, + null + ], + [ + 1782426424, + null, + null, + null + ], + [ + 1782426425, + null, + null, + null + ], + [ + 1782426426, + null, + null, + null + ], + [ + 1782426427, + null, + null, + null + ], + [ + 1782426428, + null, + null, + null + ], + [ + 1782426429, + null, + null, + null + ], + [ + 1782426430, + null, + null, + null + ], + [ + 1782426431, + null, + null, + null + ], + [ + 1782426432, + null, + null, + null + ], + [ + 1782426433, + null, + null, + null + ], + [ + 1782426434, + null, + null, + null + ], + [ + 1782426435, + null, + null, + null + ], + [ + 1782426436, + null, + null, + null + ], + [ + 1782426437, + null, + null, + null + ], + [ + 1782426438, + null, + null, + null + ], + [ + 1782426439, + null, + null, + null + ], + [ + 1782426440, + null, + null, + null + ], + [ + 1782426441, + null, + null, + null + ], + [ + 1782426442, + null, + null, + null + ], + [ + 1782426443, + null, + null, + null + ], + [ + 1782426444, + null, + null, + null + ], + [ + 1782426445, + null, + null, + null + ], + [ + 1782426446, + null, + null, + null + ], + [ + 1782426447, + null, + null, + null + ], + [ + 1782426448, + null, + null, + null + ], + [ + 1782426449, + null, + null, + null + ], + [ + 1782426450, + null, + null, + null + ], + [ + 1782426451, + null, + null, + null + ], + [ + 1782426452, + null, + null, + null + ], + [ + 1782426453, + null, + null, + null + ], + [ + 1782426454, + null, + null, + null + ], + [ + 1782426455, + null, + null, + null + ], + [ + 1782426456, + null, + null, + null + ], + [ + 1782426457, + null, + null, + null + ], + [ + 1782426458, + null, + null, + null + ], + [ + 1782426459, + null, + null, + null + ], + [ + 1782426460, + null, + null, + null + ], + [ + 1782426461, + null, + null, + null + ], + [ + 1782426462, + null, + null, + null + ], + [ + 1782426463, + null, + null, + null + ], + [ + 1782426464, + null, + null, + null + ], + [ + 1782426465, + null, + null, + null + ], + [ + 1782426466, + null, + null, + null + ], + [ + 1782426467, + null, + null, + null + ], + [ + 1782426468, + null, + null, + null + ], + [ + 1782426469, + null, + null, + null + ], + [ + 1782426470, + null, + null, + null + ], + [ + 1782426471, + null, + null, + null + ], + [ + 1782426472, + null, + null, + null + ], + [ + 1782426473, + null, + null, + null + ], + [ + 1782426474, + null, + null, + null + ], + [ + 1782426475, + null, + null, + null + ], + [ + 1782426476, + null, + null, + null + ], + [ + 1782426477, + null, + null, + null + ], + [ + 1782426478, + null, + null, + null + ], + [ + 1782426479, + null, + null, + null + ], + [ + 1782426480, + null, + null, + null + ], + [ + 1782426481, + null, + null, + null + ], + [ + 1782426482, + null, + null, + null + ], + [ + 1782426483, + null, + null, + null + ], + [ + 1782426484, + null, + null, + null + ], + [ + 1782426485, + null, + null, + null + ], + [ + 1782426486, + null, + null, + null + ], + [ + 1782426487, + null, + null, + null + ], + [ + 1782426488, + null, + null, + null + ], + [ + 1782426489, + null, + null, + null + ], + [ + 1782426490, + null, + null, + null + ], + [ + 1782426491, + null, + null, + null + ], + [ + 1782426492, + null, + null, + null + ], + [ + 1782426493, + null, + null, + null + ], + [ + 1782426494, + null, + null, + null + ], + [ + 1782426495, + null, + null, + null + ], + [ + 1782426496, + null, + null, + null + ], + [ + 1782426497, + null, + null, + null + ], + [ + 1782426498, + null, + null, + null + ], + [ + 1782426499, + null, + null, + null + ], + [ + 1782426500, + null, + null, + null + ], + [ + 1782426501, + null, + null, + null + ], + [ + 1782426502, + null, + null, + null + ], + [ + 1782426503, + null, + null, + null + ], + [ + 1782426504, + null, + null, + null + ], + [ + 1782426505, + null, + null, + null + ], + [ + 1782426506, + null, + null, + null + ], + [ + 1782426507, + null, + null, + null + ], + [ + 1782426508, + null, + null, + null + ], + [ + 1782426509, + null, + null, + null + ], + [ + 1782426510, + null, + null, + null + ], + [ + 1782426511, + null, + null, + null + ], + [ + 1782426512, + null, + null, + null + ], + [ + 1782426513, + null, + null, + null + ], + [ + 1782426514, + null, + null, + null + ], + [ + 1782426515, + null, + null, + null + ], + [ + 1782426516, + null, + null, + null + ], + [ + 1782426517, + null, + null, + null + ], + [ + 1782426518, + null, + null, + null + ], + [ + 1782426519, + null, + null, + null + ], + [ + 1782426520, + null, + null, + null + ], + [ + 1782426521, + null, + null, + null + ], + [ + 1782426523, + null, + null, + null + ], + [ + 1782426524, + null, + null, + null + ], + [ + 1782426525, + null, + null, + null + ], + [ + 1782426526, + null, + null, + null + ], + [ + 1782426527, + null, + null, + null + ], + [ + 1782426528, + null, + null, + null + ], + [ + 1782426529, + null, + null, + null + ], + [ + 1782426530, + null, + null, + null + ], + [ + 1782426531, + null, + null, + null + ], + [ + 1782426532, + null, + null, + null + ], + [ + 1782426533, + null, + null, + null + ], + [ + 1782426534, + null, + null, + null + ], + [ + 1782426535, + null, + null, + null + ], + [ + 1782426536, + null, + null, + null + ], + [ + 1782426537, + null, + null, + null + ], + [ + 1782426538, + null, + null, + null + ], + [ + 1782426539, + null, + null, + null + ], + [ + 1782426540, + null, + null, + null + ], + [ + 1782426541, + null, + null, + null + ], + [ + 1782426542, + null, + null, + null + ], + [ + 1782426543, + null, + null, + null + ], + [ + 1782426544, + null, + null, + null + ], + [ + 1782426545, + null, + null, + null + ], + [ + 1782426546, + null, + null, + null + ], + [ + 1782426547, + null, + null, + null + ], + [ + 1782426548, + null, + null, + null + ], + [ + 1782426549, + null, + null, + null + ], + [ + 1782426550, + null, + null, + null + ], + [ + 1782426551, + null, + null, + null + ], + [ + 1782426552, + null, + null, + null + ], + [ + 1782426553, + null, + null, + null + ], + [ + 1782426554, + null, + null, + null + ], + [ + 1782426555, + null, + null, + null + ], + [ + 1782426556, + null, + null, + null + ], + [ + 1782426557, + null, + null, + null + ], + [ + 1782426558, + null, + null, + null + ], + [ + 1782426559, + null, + null, + null + ], + [ + 1782426560, + null, + null, + null + ], + [ + 1782426561, + null, + null, + null + ], + [ + 1782426562, + null, + null, + null + ], + [ + 1782426563, + null, + null, + null + ], + [ + 1782426564, + null, + null, + null + ], + [ + 1782426565, + null, + null, + null + ], + [ + 1782426566, + null, + null, + null + ], + [ + 1782426567, + null, + null, + null + ], + [ + 1782426568, + null, + null, + null + ], + [ + 1782426569, + null, + null, + null + ], + [ + 1782426570, + null, + null, + null + ], + [ + 1782426571, + null, + null, + null + ], + [ + 1782426572, + null, + null, + null + ], + [ + 1782426573, + null, + null, + null + ], + [ + 1782426574, + null, + null, + null + ], + [ + 1782426575, + null, + null, + null + ], + [ + 1782426576, + null, + null, + null + ], + [ + 1782426577, + null, + null, + null + ], + [ + 1782426578, + null, + null, + null + ], + [ + 1782426579, + null, + null, + null + ], + [ + 1782426580, + null, + null, + null + ], + [ + 1782426581, + null, + null, + null + ], + [ + 1782426582, + null, + null, + null + ], + [ + 1782426583, + null, + null, + null + ], + [ + 1782426584, + null, + null, + null + ], + [ + 1782426585, + null, + null, + null + ], + [ + 1782426586, + null, + null, + null + ], + [ + 1782426587, + null, + null, + null + ], + [ + 1782426588, + null, + null, + null + ], + [ + 1782426589, + null, + null, + null + ], + [ + 1782426590, + null, + null, + null + ], + [ + 1782426591, + null, + null, + null + ], + [ + 1782426593, + null, + null, + null + ], + [ + 1782426594, + null, + null, + null + ], + [ + 1782426595, + null, + null, + null + ], + [ + 1782426596, + null, + null, + null + ], + [ + 1782426597, + null, + null, + null + ], + [ + 1782426598, + null, + null, + null + ], + [ + 1782426599, + null, + null, + null + ], + [ + 1782426600, + null, + null, + null + ], + [ + 1782426601, + null, + null, + null + ], + [ + 1782426602, + null, + null, + null + ], + [ + 1782426603, + null, + null, + null + ], + [ + 1782426604, + null, + null, + null + ], + [ + 1782426605, + null, + null, + null + ], + [ + 1782426606, + null, + null, + null + ], + [ + 1782426607, + null, + null, + null + ], + [ + 1782426608, + null, + null, + null + ], + [ + 1782426609, + null, + null, + null + ], + [ + 1782426610, + null, + null, + null + ], + [ + 1782426611, + null, + null, + null + ], + [ + 1782426612, + null, + null, + null + ], + [ + 1782426613, + null, + null, + null + ], + [ + 1782426614, + null, + null, + null + ], + [ + 1782426615, + null, + null, + null + ], + [ + 1782426616, + null, + null, + null + ], + [ + 1782426617, + null, + null, + null + ], + [ + 1782426618, + null, + null, + null + ], + [ + 1782426619, + null, + null, + null + ], + [ + 1782426620, + null, + null, + null + ], + [ + 1782426621, + null, + null, + null + ], + [ + 1782426622, + null, + null, + null + ], + [ + 1782426623, + null, + null, + null + ], + [ + 1782426624, + null, + null, + null + ], + [ + 1782426625, + null, + null, + null + ], + [ + 1782426626, + null, + null, + null + ], + [ + 1782426627, + null, + null, + null + ], + [ + 1782426628, + null, + null, + null + ], + [ + 1782426629, + null, + null, + null + ], + [ + 1782426630, + null, + null, + null + ], + [ + 1782426631, + null, + null, + null + ], + [ + 1782426632, + null, + null, + null + ], + [ + 1782426633, + null, + null, + null + ], + [ + 1782426634, + null, + null, + null + ], + [ + 1782426635, + null, + null, + null + ], + [ + 1782426636, + null, + null, + null + ], + [ + 1782426637, + null, + null, + null + ], + [ + 1782426638, + null, + null, + null + ], + [ + 1782426639, + null, + null, + null + ], + [ + 1782426640, + null, + null, + null + ], + [ + 1782426641, + null, + null, + null + ], + [ + 1782426642, + null, + null, + null + ], + [ + 1782426643, + null, + null, + null + ], + [ + 1782426644, + null, + null, + null + ], + [ + 1782426645, + null, + null, + null + ], + [ + 1782426646, + null, + null, + null + ], + [ + 1782426647, + null, + null, + null + ], + [ + 1782426648, + null, + null, + null + ], + [ + 1782426649, + null, + null, + null + ], + [ + 1782426650, + null, + null, + null + ], + [ + 1782426651, + null, + null, + null + ], + [ + 1782426652, + null, + null, + null + ], + [ + 1782426653, + null, + null, + null + ], + [ + 1782426654, + null, + null, + null + ], + [ + 1782426655, + null, + null, + null + ], + [ + 1782426656, + null, + null, + null + ], + [ + 1782426657, + null, + null, + null + ], + [ + 1782426658, + null, + null, + null + ], + [ + 1782426660, + null, + null, + null + ], + [ + 1782426661, + null, + null, + null + ], + [ + 1782426662, + null, + null, + null + ], + [ + 1782426663, + null, + null, + null + ], + [ + 1782426664, + null, + null, + null + ], + [ + 1782426665, + null, + null, + null + ], + [ + 1782426666, + null, + null, + null + ], + [ + 1782426667, + null, + null, + null + ], + [ + 1782426668, + null, + null, + null + ], + [ + 1782426669, + null, + null, + null + ], + [ + 1782426670, + null, + null, + null + ], + [ + 1782426671, + null, + null, + null + ], + [ + 1782426672, + null, + null, + null + ], + [ + 1782426673, + null, + null, + null + ], + [ + 1782426674, + null, + null, + null + ], + [ + 1782426675, + null, + null, + null + ], + [ + 1782426676, + null, + null, + null + ], + [ + 1782426677, + null, + null, + null + ], + [ + 1782426678, + null, + null, + null + ], + [ + 1782426679, + null, + null, + null + ], + [ + 1782426680, + null, + null, + null + ], + [ + 1782426681, + null, + null, + null + ], + [ + 1782426682, + null, + null, + null + ], + [ + 1782426683, + null, + null, + null + ], + [ + 1782426684, + null, + null, + null + ], + [ + 1782426685, + null, + null, + null + ], + [ + 1782426686, + null, + null, + null + ], + [ + 1782426687, + null, + null, + null + ], + [ + 1782426688, + null, + null, + null + ], + [ + 1782426689, + null, + null, + null + ], + [ + 1782426690, + null, + null, + null + ], + [ + 1782426691, + null, + null, + null + ], + [ + 1782426692, + null, + null, + null + ], + [ + 1782426693, + null, + null, + null + ], + [ + 1782426694, + null, + null, + null + ], + [ + 1782426695, + null, + null, + null + ], + [ + 1782426696, + null, + null, + null + ], + [ + 1782426697, + null, + null, + null + ], + [ + 1782426698, + null, + null, + null + ], + [ + 1782426699, + null, + null, + null + ], + [ + 1782426700, + null, + null, + null + ], + [ + 1782426701, + null, + null, + null + ], + [ + 1782426702, + null, + null, + null + ], + [ + 1782426703, + null, + null, + null + ], + [ + 1782426704, + null, + null, + null + ], + [ + 1782426705, + null, + null, + null + ], + [ + 1782426706, + null, + null, + null + ], + [ + 1782426707, + null, + null, + null + ], + [ + 1782426708, + null, + null, + null + ], + [ + 1782426709, + null, + null, + null + ], + [ + 1782426710, + null, + null, + null + ], + [ + 1782426711, + null, + null, + null + ], + [ + 1782426712, + null, + null, + null + ], + [ + 1782426713, + null, + null, + null + ], + [ + 1782426714, + null, + null, + null + ], + [ + 1782426715, + null, + null, + null + ], + [ + 1782426716, + null, + null, + null + ], + [ + 1782426717, + null, + null, + null + ], + [ + 1782426718, + null, + null, + null + ], + [ + 1782426719, + null, + null, + null + ], + [ + 1782426720, + null, + null, + null + ], + [ + 1782426721, + null, + null, + null + ], + [ + 1782426722, + null, + null, + null + ], + [ + 1782426723, + null, + null, + null + ], + [ + 1782426724, + null, + null, + null + ], + [ + 1782426725, + null, + null, + null + ], + [ + 1782426726, + null, + null, + null + ], + [ + 1782426728, + null, + null, + null + ], + [ + 1782426729, + null, + null, + null + ], + [ + 1782426730, + null, + null, + null + ], + [ + 1782426731, + null, + null, + null + ], + [ + 1782426732, + null, + null, + null + ], + [ + 1782426733, + null, + null, + null + ], + [ + 1782426734, + null, + null, + null + ], + [ + 1782426735, + null, + null, + null + ], + [ + 1782426736, + null, + null, + null + ], + [ + 1782426737, + null, + null, + null + ], + [ + 1782426738, + null, + null, + null + ], + [ + 1782426739, + null, + null, + null + ], + [ + 1782426740, + null, + null, + null + ], + [ + 1782426741, + null, + null, + null + ], + [ + 1782426742, + null, + null, + null + ], + [ + 1782426743, + null, + null, + null + ], + [ + 1782426744, + null, + null, + null + ], + [ + 1782426745, + null, + null, + null + ], + [ + 1782426746, + null, + null, + null + ], + [ + 1782426747, + null, + null, + null + ], + [ + 1782426748, + null, + null, + null + ], + [ + 1782426749, + null, + null, + null + ], + [ + 1782426750, + null, + null, + null + ], + [ + 1782426751, + null, + null, + null + ], + [ + 1782426752, + null, + null, + null + ], + [ + 1782426753, + null, + null, + null + ], + [ + 1782426754, + null, + null, + null + ], + [ + 1782426755, + null, + null, + null + ], + [ + 1782426756, + null, + null, + null + ], + [ + 1782426757, + null, + null, + null + ], + [ + 1782426758, + null, + null, + null + ], + [ + 1782426759, + null, + null, + null + ], + [ + 1782426760, + null, + null, + null + ], + [ + 1782426761, + null, + null, + null + ], + [ + 1782426762, + null, + null, + null + ], + [ + 1782426763, + null, + null, + null + ], + [ + 1782426764, + null, + null, + null + ], + [ + 1782426765, + null, + null, + null + ], + [ + 1782426766, + null, + null, + null + ], + [ + 1782426767, + null, + null, + null + ], + [ + 1782426768, + null, + null, + null + ], + [ + 1782426769, + null, + null, + null + ], + [ + 1782426770, + null, + null, + null + ], + [ + 1782426771, + null, + null, + null + ], + [ + 1782426772, + null, + null, + null + ], + [ + 1782426773, + null, + null, + null + ], + [ + 1782426774, + null, + null, + null + ], + [ + 1782426775, + null, + null, + null + ], + [ + 1782426776, + null, + null, + null + ], + [ + 1782426777, + null, + null, + null + ], + [ + 1782426778, + null, + null, + null + ], + [ + 1782426779, + null, + null, + null + ], + [ + 1782426780, + null, + null, + null + ], + [ + 1782426782, + null, + null, + null + ], + [ + 1782426783, + null, + null, + null + ], + [ + 1782426784, + null, + null, + null + ], + [ + 1782426785, + null, + null, + null + ], + [ + 1782426786, + null, + null, + null + ], + [ + 1782426787, + null, + null, + null + ], + [ + 1782426788, + null, + null, + null + ], + [ + 1782426789, + null, + null, + null + ], + [ + 1782426790, + null, + null, + null + ], + [ + 1782426791, + null, + null, + null + ], + [ + 1782426792, + null, + null, + null + ], + [ + 1782426793, + null, + null, + null + ], + [ + 1782426794, + null, + null, + null + ], + [ + 1782426795, + null, + null, + null + ], + [ + 1782426796, + null, + null, + null + ], + [ + 1782426797, + null, + null, + null + ], + [ + 1782426798, + null, + null, + null + ], + [ + 1782426799, + null, + null, + null + ], + [ + 1782426800, + null, + null, + null + ], + [ + 1782426801, + null, + null, + null + ], + [ + 1782426802, + null, + null, + null + ], + [ + 1782426803, + null, + null, + null + ], + [ + 1782426804, + null, + null, + null + ], + [ + 1782426805, + null, + null, + null + ], + [ + 1782426806, + null, + null, + null + ], + [ + 1782426807, + null, + null, + null + ], + [ + 1782426808, + null, + null, + null + ], + [ + 1782426809, + null, + null, + null + ], + [ + 1782426810, + null, + null, + null + ], + [ + 1782426811, + null, + null, + null + ], + [ + 1782426812, + null, + null, + null + ], + [ + 1782426813, + null, + null, + null + ], + [ + 1782426814, + null, + null, + null + ], + [ + 1782426815, + null, + null, + null + ], + [ + 1782426816, + null, + null, + null + ], + [ + 1782426817, + null, + null, + null + ], + [ + 1782426818, + null, + null, + null + ], + [ + 1782426819, + null, + null, + null + ], + [ + 1782426820, + null, + null, + null + ], + [ + 1782426821, + null, + null, + null + ], + [ + 1782426822, + null, + null, + null + ], + [ + 1782426823, + null, + null, + null + ], + [ + 1782426824, + null, + null, + null + ], + [ + 1782426825, + null, + null, + null + ], + [ + 1782426826, + null, + null, + null + ], + [ + 1782426827, + null, + null, + null + ], + [ + 1782426828, + null, + null, + null + ], + [ + 1782426829, + null, + null, + null + ], + [ + 1782426830, + null, + null, + null + ], + [ + 1782426831, + null, + null, + null + ], + [ + 1782426832, + null, + null, + null + ], + [ + 1782426833, + null, + null, + null + ], + [ + 1782426834, + null, + null, + null + ], + [ + 1782426835, + null, + null, + null + ], + [ + 1782426836, + null, + null, + null + ], + [ + 1782426837, + null, + null, + null + ], + [ + 1782426838, + null, + null, + null + ], + [ + 1782426839, + null, + null, + null + ], + [ + 1782426840, + null, + null, + null + ], + [ + 1782426841, + null, + null, + null + ], + [ + 1782426842, + null, + null, + null + ], + [ + 1782426843, + null, + null, + null + ], + [ + 1782426844, + null, + null, + null + ], + [ + 1782426845, + null, + null, + null + ], + [ + 1782426847, + null, + null, + null + ], + [ + 1782426848, + null, + null, + null + ], + [ + 1782426849, + null, + null, + null + ], + [ + 1782426850, + null, + null, + null + ], + [ + 1782426851, + null, + null, + null + ], + [ + 1782426852, + null, + null, + null + ], + [ + 1782426853, + null, + null, + null + ], + [ + 1782426854, + null, + null, + null + ], + [ + 1782426855, + null, + null, + null + ], + [ + 1782426856, + null, + null, + null + ], + [ + 1782426857, + null, + null, + null + ], + [ + 1782426858, + null, + null, + null + ], + [ + 1782426859, + null, + null, + null + ], + [ + 1782426860, + null, + null, + null + ], + [ + 1782426861, + null, + null, + null + ], + [ + 1782426862, + null, + null, + null + ], + [ + 1782426863, + null, + null, + null + ], + [ + 1782426864, + null, + null, + null + ], + [ + 1782426865, + null, + null, + null + ], + [ + 1782426866, + null, + null, + null + ], + [ + 1782426867, + null, + null, + null + ], + [ + 1782426868, + null, + null, + null + ], + [ + 1782426869, + null, + null, + null + ], + [ + 1782426870, + null, + null, + null + ], + [ + 1782426871, + null, + null, + null + ], + [ + 1782426872, + null, + null, + null + ], + [ + 1782426873, + null, + null, + null + ], + [ + 1782426874, + null, + null, + null + ], + [ + 1782426875, + null, + null, + null + ], + [ + 1782426876, + null, + null, + null + ], + [ + 1782426877, + null, + null, + null + ], + [ + 1782426878, + null, + null, + null + ], + [ + 1782426879, + null, + null, + null + ], + [ + 1782426880, + null, + null, + null + ], + [ + 1782426881, + null, + null, + null + ], + [ + 1782426882, + null, + null, + null + ], + [ + 1782426883, + null, + null, + null + ], + [ + 1782426884, + null, + null, + null + ], + [ + 1782426885, + null, + null, + null + ], + [ + 1782426886, + null, + null, + null + ], + [ + 1782426887, + null, + null, + null + ], + [ + 1782426888, + null, + null, + null + ], + [ + 1782426889, + null, + null, + null + ], + [ + 1782426890, + null, + null, + null + ], + [ + 1782426891, + null, + null, + null + ], + [ + 1782426892, + null, + null, + null + ], + [ + 1782426893, + null, + null, + null + ], + [ + 1782426894, + null, + null, + null + ], + [ + 1782426895, + null, + null, + null + ], + [ + 1782426896, + null, + null, + null + ], + [ + 1782426897, + null, + null, + null + ], + [ + 1782426898, + null, + null, + null + ], + [ + 1782426899, + null, + null, + null + ], + [ + 1782426900, + null, + null, + null + ], + [ + 1782426901, + null, + null, + null + ], + [ + 1782426902, + null, + null, + null + ], + [ + 1782426903, + null, + null, + null + ], + [ + 1782426904, + null, + null, + null + ], + [ + 1782426905, + null, + null, + null + ], + [ + 1782426906, + null, + null, + null + ], + [ + 1782426907, + null, + null, + null + ], + [ + 1782426908, + null, + null, + null + ], + [ + 1782426909, + null, + null, + null + ], + [ + 1782426910, + null, + null, + null + ], + [ + 1782426911, + null, + null, + null + ], + [ + 1782426912, + null, + null, + null + ], + [ + 1782426914, + null, + null, + null + ], + [ + 1782426915, + null, + null, + null + ], + [ + 1782426916, + null, + null, + null + ], + [ + 1782426917, + null, + null, + null + ], + [ + 1782426918, + null, + null, + null + ], + [ + 1782426919, + null, + null, + null + ], + [ + 1782426920, + null, + null, + null + ], + [ + 1782426921, + null, + null, + null + ], + [ + 1782426922, + null, + null, + null + ], + [ + 1782426923, + null, + null, + null + ], + [ + 1782426924, + null, + null, + null + ], + [ + 1782426925, + null, + null, + null + ], + [ + 1782426926, + null, + null, + null + ], + [ + 1782426927, + null, + null, + null + ], + [ + 1782426928, + null, + null, + null + ], + [ + 1782426929, + null, + null, + null + ], + [ + 1782426930, + null, + null, + null + ], + [ + 1782426931, + null, + null, + null + ], + [ + 1782426932, + null, + null, + null + ], + [ + 1782426933, + null, + null, + null + ], + [ + 1782426934, + null, + null, + null + ], + [ + 1782426935, + null, + null, + null + ], + [ + 1782426936, + null, + null, + null + ], + [ + 1782426937, + null, + null, + null + ], + [ + 1782426938, + null, + null, + null + ], + [ + 1782426939, + null, + null, + null + ], + [ + 1782426940, + null, + null, + null + ], + [ + 1782426941, + null, + null, + null + ], + [ + 1782426942, + null, + null, + null + ], + [ + 1782426943, + null, + null, + null + ], + [ + 1782426944, + null, + null, + null + ], + [ + 1782426945, + null, + null, + null + ], + [ + 1782426946, + null, + null, + null + ], + [ + 1782426947, + null, + null, + null + ], + [ + 1782426948, + null, + null, + null + ], + [ + 1782426949, + null, + null, + null + ], + [ + 1782426950, + null, + null, + null + ], + [ + 1782426951, + null, + null, + null + ], + [ + 1782426952, + null, + null, + null + ], + [ + 1782426953, + null, + null, + null + ], + [ + 1782426954, + null, + null, + null + ], + [ + 1782426955, + null, + null, + null + ], + [ + 1782426956, + null, + null, + null + ], + [ + 1782426957, + null, + null, + null + ], + [ + 1782426958, + null, + null, + null + ], + [ + 1782426959, + null, + null, + null + ], + [ + 1782426960, + null, + null, + null + ], + [ + 1782426961, + null, + null, + null + ], + [ + 1782426962, + null, + null, + null + ], + [ + 1782426963, + null, + null, + null + ], + [ + 1782426964, + null, + null, + null + ], + [ + 1782426965, + null, + null, + null + ], + [ + 1782426966, + null, + null, + null + ], + [ + 1782426967, + null, + null, + null + ], + [ + 1782426968, + null, + null, + null + ], + [ + 1782426969, + null, + null, + null + ], + [ + 1782426970, + null, + null, + null + ], + [ + 1782426971, + null, + null, + null + ], + [ + 1782426972, + null, + null, + null + ], + [ + 1782426973, + null, + null, + null + ], + [ + 1782426974, + null, + null, + null + ], + [ + 1782426975, + null, + null, + null + ], + [ + 1782426976, + null, + null, + null + ], + [ + 1782426977, + null, + null, + null + ], + [ + 1782426979, + null, + null, + null + ], + [ + 1782426980, + null, + null, + null + ], + [ + 1782426981, + null, + null, + null + ], + [ + 1782426982, + null, + null, + null + ], + [ + 1782426983, + null, + null, + null + ], + [ + 1782426984, + null, + null, + null + ], + [ + 1782426985, + null, + null, + null + ], + [ + 1782426986, + null, + null, + null + ], + [ + 1782426987, + null, + null, + null + ], + [ + 1782426988, + null, + null, + null + ], + [ + 1782426989, + null, + null, + null + ], + [ + 1782426990, + null, + null, + null + ], + [ + 1782426991, + null, + null, + null + ], + [ + 1782426992, + null, + null, + null + ], + [ + 1782426993, + null, + null, + null + ], + [ + 1782426994, + null, + null, + null + ], + [ + 1782426995, + null, + null, + null + ], + [ + 1782426996, + null, + null, + null + ], + [ + 1782426997, + null, + null, + null + ], + [ + 1782426998, + null, + null, + null + ], + [ + 1782426999, + null, + null, + null + ], + [ + 1782427000, + null, + null, + null + ], + [ + 1782427001, + null, + null, + null + ], + [ + 1782427002, + null, + null, + null + ], + [ + 1782427003, + null, + null, + null + ], + [ + 1782427004, + null, + null, + null + ], + [ + 1782427005, + null, + null, + null + ], + [ + 1782427006, + null, + null, + null + ], + [ + 1782427007, + null, + null, + null + ], + [ + 1782427008, + null, + null, + null + ], + [ + 1782427009, + null, + null, + null + ], + [ + 1782427010, + null, + null, + null + ], + [ + 1782427011, + null, + null, + null + ], + [ + 1782427012, + null, + null, + null + ], + [ + 1782427013, + null, + null, + null + ], + [ + 1782427014, + null, + null, + null + ], + [ + 1782427015, + null, + null, + null + ], + [ + 1782427016, + null, + null, + null + ], + [ + 1782427017, + null, + null, + null + ], + [ + 1782427018, + null, + null, + null + ], + [ + 1782427019, + null, + null, + null + ], + [ + 1782427020, + null, + null, + null + ], + [ + 1782427021, + null, + null, + null + ], + [ + 1782427022, + null, + null, + null + ], + [ + 1782427023, + null, + null, + null + ], + [ + 1782427024, + null, + null, + null + ], + [ + 1782427025, + null, + null, + null + ], + [ + 1782427026, + null, + null, + null + ], + [ + 1782427027, + null, + null, + null + ] + ], + "temp_c": null, + "arm_clock_hz": null, + "throttling_detected": false + }, + "warnings": [ + "governor is 'unavailable', not 'performance' (need root on Linux, or unsupported on macOS)", + "core pinning unavailable (no taskset/numactl) \u2014 results will be noisier", + "NOT RPi5-baseline-grade: host is not a Raspberry Pi (model='', os=macos); CPU governor is 'unavailable', not 'performance'; benchmark was not pinned to a dedicated core (no taskset); build flags targeted 'apple-m3', not cortex-a76" + ], + "kem": [ + { + "alg": "X25519", + "kind": "kem", + "backend": "openssl", + "classical": true, + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 32, + "secret_key": 32, + "ciphertext": null, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1075, + "timed_iters": 5374, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 46521.02, + "samples": 26870, + "median": 45000.0, + "mad": 0.0, + "iqr": 1000.0, + "q1": 44000.0, + "q3": 45000.0, + "min": 44000.0, + "max": 1007000.0, + "mean": 45261.63, + "stddev": 11022.5, + "ops_per_sec": 22222.22, + "per_rep_median": [ + 45000.0, + 45000.0, + 45000.0, + 45000.0, + 45000.0 + ] + }, + "derive": { + "unit": "ns", + "warmup_iters": 1157, + "timed_iters": 5784, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 43224.83, + "samples": 28920, + "median": 43000.0, + "mad": 0.0, + "iqr": 0.0, + "q1": 43000.0, + "q3": 43000.0, + "min": 42000.0, + "max": 685000.0, + "mean": 43489.07, + "stddev": 7839.77, + "ops_per_sec": 23255.81, + "per_rep_median": [ + 43000.0, + 43000.0, + 43000.0, + 43000.0, + 43000.0 + ] + } + } + }, + { + "alg": "ML-KEM-512", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 800, + "secret_key": 1632, + "ciphertext": 768, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 5189, + "timed_iters": 20000, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 9636.14, + "samples": 100000, + "median": 10000.0, + "mad": 0.0, + "iqr": 1000.0, + "q1": 9000.0, + "q3": 10000.0, + "min": 9000.0, + "max": 387000.0, + "mean": 9625.33, + "stddev": 1779.86, + "ops_per_sec": 100000.0, + "per_rep_median": [ + 10000.0, + 10000.0, + 10000.0, + 10000.0, + 10000.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 4661, + "timed_iters": 20000, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 10727.72, + "samples": 100000, + "median": 11000.0, + "mad": 0.0, + "iqr": 1000.0, + "q1": 10000.0, + "q3": 11000.0, + "min": 10000.0, + "max": 92000.0, + "mean": 10788.22, + "stddev": 988.61, + "ops_per_sec": 90909.09, + "per_rep_median": [ + 11000.0, + 11000.0, + 11000.0, + 11000.0, + 11000.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 3976, + "timed_iters": 19882, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 12574.36, + "samples": 99410, + "median": 13000.0, + "mad": 0.0, + "iqr": 1000.0, + "q1": 12000.0, + "q3": 13000.0, + "min": 12000.0, + "max": 608000.0, + "mean": 12646.51, + "stddev": 2696.01, + "ops_per_sec": 76923.08, + "per_rep_median": [ + 13000.0, + 13000.0, + 13000.0, + 13000.0, + 13000.0 + ] + } + } + }, + { + "alg": "ML-KEM-768", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 3, + "sizes": { + "public_key": 1184, + "secret_key": 2400, + "ciphertext": 1088, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 3106, + "timed_iters": 15531, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 16097.22, + "samples": 77655, + "median": 16000.0, + "mad": 0.0, + "iqr": 0.0, + "q1": 16000.0, + "q3": 16000.0, + "min": 15000.0, + "max": 128000.0, + "mean": 16081.42, + "stddev": 1273.26, + "ops_per_sec": 62500.0, + "per_rep_median": [ + 16000.0, + 16000.0, + 16000.0, + 16000.0, + 16000.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 2868, + "timed_iters": 14341, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 17432.34, + "samples": 71705, + "median": 17000.0, + "mad": 0.0, + "iqr": 0.0, + "q1": 17000.0, + "q3": 17000.0, + "min": 16000.0, + "max": 106000.0, + "mean": 17042.34, + "stddev": 1374.89, + "ops_per_sec": 58823.53, + "per_rep_median": [ + 17000.0, + 17000.0, + 17000.0, + 17000.0, + 17000.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 2543, + "timed_iters": 12716, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 19660.97, + "samples": 63580, + "median": 20000.0, + "mad": 0.0, + "iqr": 1000.0, + "q1": 19000.0, + "q3": 20000.0, + "min": 19000.0, + "max": 2659000.0, + "mean": 20179.6, + "stddev": 20041.25, + "ops_per_sec": 50000.0, + "per_rep_median": [ + 20000.0, + 20000.0, + 20000.0, + 20000.0, + 20000.0 + ] + } + } + }, + { + "alg": "ML-KEM-1024", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 1568, + "secret_key": 3168, + "ciphertext": 1568, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 2001, + "timed_iters": 10007, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 24981.92, + "samples": 50035, + "median": 24000.0, + "mad": 0.0, + "iqr": 1000.0, + "q1": 23000.0, + "q3": 24000.0, + "min": 23000.0, + "max": 41574000.0, + "mean": 28119.14, + "stddev": 251531.54, + "ops_per_sec": 41666.67, + "per_rep_median": [ + 25000.0, + 24000.0, + 24000.0, + 24000.0, + 24000.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 1939, + "timed_iters": 9697, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 25780.65, + "samples": 48485, + "median": 26000.0, + "mad": 0.0, + "iqr": 1000.0, + "q1": 25000.0, + "q3": 26000.0, + "min": 25000.0, + "max": 145000.0, + "mean": 25801.65, + "stddev": 1264.28, + "ops_per_sec": 38461.54, + "per_rep_median": [ + 26000.0, + 26000.0, + 26000.0, + 26000.0, + 26000.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 1664, + "timed_iters": 8319, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 30052.79, + "samples": 41595, + "median": 30000.0, + "mad": 0.0, + "iqr": 0.0, + "q1": 30000.0, + "q3": 30000.0, + "min": 29000.0, + "max": 542000.0, + "mean": 30205.46, + "stddev": 3876.22, + "ops_per_sec": 33333.33, + "per_rep_median": [ + 30000.0, + 30000.0, + 30000.0, + 30000.0, + 30000.0 + ] + } + } + }, + { + "alg": "X25519MLKEM768", + "kind": "kem", + "backend": "liboqs", + "enabled": false, + "reason": "not enabled in this liboqs build" + }, + { + "alg": "SecP256r1MLKEM768", + "kind": "kem", + "backend": "liboqs", + "enabled": false, + "reason": "not enabled in this liboqs build" + }, + { + "alg": "Classic-McEliece-348864", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 261120, + "secret_key": 6492, + "ciphertext": 96, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 100925000.0, + "samples": 150, + "median": 178485000.0, + "mad": 77284500.0, + "iqr": 231150500.0, + "q1": 101414500.0, + "q3": 332565000.0, + "min": 100654000.0, + "max": 1486052000.0, + "mean": 289599746.67, + "stddev": 247897979.08, + "ops_per_sec": 5.6, + "per_rep_median": [ + 255157000.0, + 216411000.0, + 177790500.0, + 178384500.0, + 331343500.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 2000, + "timed_iters": 10001, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 24996.58, + "samples": 50005, + "median": 22000.0, + "mad": 1000.0, + "iqr": 5000.0, + "q1": 21000.0, + "q3": 26000.0, + "min": 21000.0, + "max": 80000.0, + "mean": 24691.65, + "stddev": 4915.04, + "ops_per_sec": 45454.55, + "per_rep_median": [ + 22000.0, + 22000.0, + 22000.0, + 22000.0, + 22000.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 2, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 25752000.0, + "samples": 150, + "median": 25759000.0, + "mad": 19000.0, + "iqr": 44500.0, + "q1": 25730250.0, + "q3": 25774750.0, + "min": 25700000.0, + "max": 26016000.0, + "mean": 25757373.33, + "stddev": 36363.66, + "ops_per_sec": 38.82, + "per_rep_median": [ + 25763500.0, + 25763500.0, + 25755000.0, + 25755000.0, + 25748500.0 + ] + } + } + }, + { + "alg": "Classic-McEliece-460896", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 3, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 584744000.0, + "samples": 150, + "median": 717814500.0, + "mad": 391387000.0, + "iqr": 970404500.0, + "q1": 326465000.0, + "q3": 1296869500.0, + "min": 324753000.0, + "max": 3177431000.0, + "mean": 937807760.0, + "stddev": 674289516.54, + "ops_per_sec": 1.39, + "per_rep_median": [ + 717814500.0, + 585954500.0, + 844827500.0, + 586253500.0, + 717738000.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 908, + "timed_iters": 4540, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 55065.49, + "samples": 22700, + "median": 48000.0, + "mad": 9000.0, + "iqr": 26000.0, + "q1": 39000.0, + "q3": 65000.0, + "min": 38000.0, + "max": 259000.0, + "mean": 54390.97, + "stddev": 19062.83, + "ops_per_sec": 20833.33, + "per_rep_median": [ + 48000.0, + 48000.0, + 48000.0, + 48000.0, + 48000.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 59265000.0, + "samples": 150, + "median": 59398000.0, + "mad": 28500.0, + "iqr": 70500.0, + "q1": 59352250.0, + "q3": 59422750.0, + "min": 59260000.0, + "max": 64566000.0, + "mean": 59444553.33, + "stddev": 476148.58, + "ops_per_sec": 16.84, + "per_rep_median": [ + 59397000.0, + 59398500.0, + 59405500.0, + 59387000.0, + 59395000.0 + ] + } + } + }, + { + "alg": "Classic-McEliece-460896f", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 3, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 341390000.0, + "samples": 150, + "median": 341787500.0, + "mad": 451500.0, + "iqr": 911250.0, + "q1": 341355000.0, + "q3": 342266250.0, + "min": 340589000.0, + "max": 353790000.0, + "mean": 342111633.33, + "stddev": 1695918.52, + "ops_per_sec": 2.93, + "per_rep_median": [ + 341404000.0, + 341963500.0, + 341924500.0, + 341820500.0, + 341904500.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 917, + "timed_iters": 4585, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 54528.84, + "samples": 22925, + "median": 48000.0, + "mad": 9000.0, + "iqr": 26000.0, + "q1": 39000.0, + "q3": 65000.0, + "min": 38000.0, + "max": 469000.0, + "mean": 54823.34, + "stddev": 20163.02, + "ops_per_sec": 20833.33, + "per_rep_median": [ + 48000.0, + 48000.0, + 48000.0, + 48000.0, + 48000.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 59475000.0, + "samples": 150, + "median": 59391000.0, + "mad": 38500.0, + "iqr": 97000.0, + "q1": 59323000.0, + "q3": 59420000.0, + "min": 59268000.0, + "max": 72541000.0, + "mean": 59499606.67, + "stddev": 1107932.34, + "ops_per_sec": 16.84, + "per_rep_median": [ + 59373000.0, + 59387000.0, + 59390000.0, + 59405500.0, + 59386500.0 + ] + } + } + }, + { + "alg": "Classic-McEliece-6688128", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 1044992, + "secret_key": 13932, + "ciphertext": 208, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 2082895000.0, + "samples": 150, + "median": 2078429500.0, + "mad": 1339938500.0, + "iqr": 2702899000.0, + "q1": 739608250.0, + "q3": 3442507250.0, + "min": 735976000.0, + "max": 12138910000.0, + "mean": 2685279200.0, + "stddev": 2308475757.57, + "ops_per_sec": 0.48, + "per_rep_median": [ + 2080959000.0, + 2415120500.0, + 2079610000.0, + 1405587000.0, + 2087484500.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 389, + "timed_iters": 1946, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 128454.9, + "samples": 9730, + "median": 120000.0, + "mad": 26000.0, + "iqr": 53000.0, + "q1": 94000.0, + "q3": 147000.0, + "min": 93000.0, + "max": 428000.0, + "mean": 126612.85, + "stddev": 38274.07, + "ops_per_sec": 8333.33, + "per_rep_median": [ + 120000.0, + 120000.0, + 120000.0, + 120000.0, + 109000.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 114042000.0, + "samples": 150, + "median": 114067000.0, + "mad": 65500.0, + "iqr": 153750.0, + "q1": 114020250.0, + "q3": 114174000.0, + "min": 113919000.0, + "max": 482118000.0, + "mean": 117548113.33, + "stddev": 31672668.02, + "ops_per_sec": 8.77, + "per_rep_median": [ + 114031000.0, + 114028000.0, + 114096000.0, + 114149500.0, + 114179000.0 + ] + } + } + }, + { + "alg": "Classic-McEliece-6960119", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 1047319, + "secret_key": 13948, + "ciphertext": 194, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 2469350000.0, + "samples": 150, + "median": 1871076000.0, + "mad": 619611500.0, + "iqr": 1224627000.0, + "q1": 1268002750.0, + "q3": 2492629750.0, + "min": 667361000.0, + "max": 9700768000.0, + "mean": 2206371146.67, + "stddev": 1736141421.73, + "ops_per_sec": 0.53, + "per_rep_median": [ + 1271024500.0, + 1874400000.0, + 1271720000.0, + 1871026500.0, + 1871354000.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 281, + "timed_iters": 1407, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 177686.27, + "samples": 7035, + "median": 158000.0, + "mad": 12000.0, + "iqr": 33000.0, + "q1": 147000.0, + "q3": 180000.0, + "min": 145000.0, + "max": 830000.0, + "mean": 167553.38, + "stddev": 28004.93, + "ops_per_sec": 6329.11, + "per_rep_median": [ + 158000.0, + 158000.0, + 159000.0, + 159000.0, + 159000.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 110531000.0, + "samples": 150, + "median": 110526000.0, + "mad": 45500.0, + "iqr": 102750.0, + "q1": 110460250.0, + "q3": 110563000.0, + "min": 110340000.0, + "max": 114608000.0, + "mean": 110635220.0, + "stddev": 621170.36, + "ops_per_sec": 9.05, + "per_rep_median": [ + 110540000.0, + 110520000.0, + 110550500.0, + 110524000.0, + 110532000.0 + ] + } + } + }, + { + "alg": "Classic-McEliece-8192128", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 1357824, + "secret_key": 14120, + "ciphertext": 208, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1690644000.0, + "samples": 150, + "median": 1691580500.0, + "mad": 815511500.0, + "iqr": 2435046500.0, + "q1": 878912750.0, + "q3": 3313959250.0, + "min": 875041000.0, + "max": 10603396000.0, + "mean": 2708152340.0, + "stddev": 2167686375.47, + "ops_per_sec": 0.59, + "per_rep_median": [ + 1690336000.0, + 2502437000.0, + 2092296500.0, + 1683476500.0, + 1689066000.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 490, + "timed_iters": 2450, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 102027.4, + "samples": 12250, + "median": 93000.0, + "mad": 13000.0, + "iqr": 37000.0, + "q1": 81000.0, + "q3": 118000.0, + "min": 79000.0, + "max": 1187000.0, + "mean": 103094.45, + "stddev": 30270.57, + "ops_per_sec": 10752.69, + "per_rep_median": [ + 93000.0, + 93000.0, + 93000.0, + 93000.0, + 93000.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 139715000.0, + "samples": 150, + "median": 139695500.0, + "mad": 58000.0, + "iqr": 126000.0, + "q1": 139617500.0, + "q3": 139743500.0, + "min": 139446000.0, + "max": 142958000.0, + "mean": 139740900.0, + "stddev": 393654.91, + "ops_per_sec": 7.16, + "per_rep_median": [ + 139671000.0, + 139689500.0, + 139719000.0, + 139707500.0, + 139700000.0 + ] + } + } + }, + { + "alg": "FrodoKEM-640-AES", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 9616, + "secret_key": 19888, + "ciphertext": 9720, + "shared_secret": 16 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 181, + "timed_iters": 907, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 275614.17, + "samples": 4535, + "median": 275000.0, + "mad": 1000.0, + "iqr": 2000.0, + "q1": 274000.0, + "q3": 276000.0, + "min": 271000.0, + "max": 918000.0, + "mean": 277030.65, + "stddev": 24144.22, + "ops_per_sec": 3636.36, + "per_rep_median": [ + 275000.0, + 275000.0, + 275000.0, + 275000.0, + 275000.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 134, + "timed_iters": 669, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 373889.76, + "samples": 3345, + "median": 368000.0, + "mad": 1000.0, + "iqr": 1000.0, + "q1": 367000.0, + "q3": 368000.0, + "min": 365000.0, + "max": 1195000.0, + "mean": 368920.78, + "stddev": 14898.96, + "ops_per_sec": 2717.39, + "per_rep_median": [ + 369000.0, + 368000.0, + 367000.0, + 367000.0, + 367000.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 142, + "timed_iters": 712, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 350984.25, + "samples": 3560, + "median": 348000.0, + "mad": 0.0, + "iqr": 1000.0, + "q1": 348000.0, + "q3": 349000.0, + "min": 346000.0, + "max": 551000.0, + "mean": 348960.39, + "stddev": 4557.01, + "ops_per_sec": 2873.56, + "per_rep_median": [ + 348000.0, + 348000.0, + 348000.0, + 349000.0, + 348000.0 + ] + } + } + }, + { + "alg": "FrodoKEM-976-AES", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 3, + "sizes": { + "public_key": 15632, + "secret_key": 31296, + "ciphertext": 15744, + "shared_secret": 24 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 92, + "timed_iters": 461, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 541841.27, + "samples": 2305, + "median": 542000.0, + "mad": 2000.0, + "iqr": 3000.0, + "q1": 540000.0, + "q3": 543000.0, + "min": 538000.0, + "max": 569000.0, + "mean": 542247.29, + "stddev": 3375.2, + "ops_per_sec": 1845.02, + "per_rep_median": [ + 542000.0, + 542000.0, + 542000.0, + 542000.0, + 542000.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 69, + "timed_iters": 347, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 719873.02, + "samples": 1735, + "median": 719000.0, + "mad": 1000.0, + "iqr": 3000.0, + "q1": 717000.0, + "q3": 720000.0, + "min": 715000.0, + "max": 1405000.0, + "mean": 720536.6, + "stddev": 24148.78, + "ops_per_sec": 1390.82, + "per_rep_median": [ + 719000.0, + 718000.0, + 719000.0, + 719000.0, + 719000.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 73, + "timed_iters": 366, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 683841.27, + "samples": 1830, + "median": 682000.0, + "mad": 2000.0, + "iqr": 4000.0, + "q1": 680000.0, + "q3": 684000.0, + "min": 678000.0, + "max": 1129000.0, + "mean": 686081.42, + "stddev": 29420.64, + "ops_per_sec": 1466.28, + "per_rep_median": [ + 683000.0, + 682000.0, + 682000.0, + 682000.0, + 682000.0 + ] + } + } + }, + { + "alg": "FrodoKEM-1344-AES", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 21520, + "secret_key": 43088, + "ciphertext": 21632, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 52, + "timed_iters": 262, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 954571.43, + "samples": 1310, + "median": 954000.0, + "mad": 3000.0, + "iqr": 4000.0, + "q1": 951000.0, + "q3": 955000.0, + "min": 949000.0, + "max": 1373000.0, + "mean": 955759.54, + "stddev": 20047.37, + "ops_per_sec": 1048.22, + "per_rep_median": [ + 954000.0, + 954000.0, + 954000.0, + 953000.0, + 953000.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 40, + "timed_iters": 202, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1239806.45, + "samples": 1010, + "median": 1236000.0, + "mad": 2000.0, + "iqr": 5000.0, + "q1": 1234000.0, + "q3": 1239000.0, + "min": 1233000.0, + "max": 1273000.0, + "mean": 1237884.16, + "stddev": 5471.56, + "ops_per_sec": 809.06, + "per_rep_median": [ + 1237000.0, + 1236000.0, + 1236000.0, + 1236000.0, + 1236500.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 42, + "timed_iters": 210, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1188258.06, + "samples": 1050, + "median": 1187000.0, + "mad": 2000.0, + "iqr": 5000.0, + "q1": 1185000.0, + "q3": 1190000.0, + "min": 1183000.0, + "max": 1291000.0, + "mean": 1190085.71, + "stddev": 12913.82, + "ops_per_sec": 842.46, + "per_rep_median": [ + 1188000.0, + 1187000.0, + 1187000.0, + 1187000.0, + 1187000.0 + ] + } + } + } + ], + "sig": [ + { + "alg": "Ed25519", + "kind": "sig", + "backend": "openssl", + "classical": true, + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 32, + "secret_key": 32, + "signature": 64 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1107, + "timed_iters": 5535, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 45171.07, + "samples": 27675, + "median": 45000.0, + "mad": 0.0, + "iqr": 0.0, + "q1": 45000.0, + "q3": 45000.0, + "min": 44000.0, + "max": 58000.0, + "mean": 44846.21, + "stddev": 859.41, + "ops_per_sec": 22222.22, + "per_rep_median": [ + 45000.0, + 45000.0, + 45000.0, + 45000.0, + 45000.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 1115, + "timed_iters": 5574, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 44854.35, + "samples": 27870, + "median": 45000.0, + "mad": 0.0, + "iqr": 0.0, + "q1": 45000.0, + "q3": 45000.0, + "min": 44000.0, + "max": 58000.0, + "mean": 44865.34, + "stddev": 807.75, + "ops_per_sec": 22222.22, + "per_rep_median": [ + 45000.0, + 45000.0, + 45000.0, + 45000.0, + 45000.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 402, + "timed_iters": 2011, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 124313.73, + "samples": 10055, + "median": 124000.0, + "mad": 0.0, + "iqr": 0.0, + "q1": 124000.0, + "q3": 124000.0, + "min": 123000.0, + "max": 143000.0, + "mean": 124169.47, + "stddev": 1201.97, + "ops_per_sec": 8064.52, + "per_rep_median": [ + 124000.0, + 124000.0, + 124000.0, + 124000.0, + 124000.0 + ] + } + } + }, + { + "alg": "ML-DSA-44", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 2, + "sizes": { + "public_key": 1312, + "secret_key": 2560, + "signature": 2420 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 801, + "timed_iters": 4003, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 62448.14, + "samples": 20015, + "median": 62000.0, + "mad": 0.0, + "iqr": 1000.0, + "q1": 61000.0, + "q3": 62000.0, + "min": 60000.0, + "max": 93000.0, + "mean": 61891.18, + "stddev": 1121.81, + "ops_per_sec": 16129.03, + "per_rep_median": [ + 62000.0, + 62000.0, + 62000.0, + 62000.0, + 62000.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 176, + "timed_iters": 879, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 284275.59, + "samples": 4395, + "median": 227000.0, + "mad": 112000.0, + "iqr": 224000.0, + "q1": 160000.0, + "q3": 384000.0, + "min": 114000.0, + "max": 49069000.0, + "mean": 400433.67, + "stddev": 1364832.25, + "ops_per_sec": 4405.29, + "per_rep_median": [ + 216000.0, + 217000.0, + 216000.0, + 216000.0, + 322000.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 662, + "timed_iters": 3310, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 75526.42, + "samples": 16550, + "median": 67000.0, + "mad": 0.0, + "iqr": 0.0, + "q1": 67000.0, + "q3": 67000.0, + "min": 66000.0, + "max": 88000.0, + "mean": 67143.81, + "stddev": 966.53, + "ops_per_sec": 14925.37, + "per_rep_median": [ + 67000.0, + 67000.0, + 67000.0, + 67000.0, + 67000.0 + ] + } + } + }, + { + "alg": "ML-DSA-65", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 3, + "sizes": { + "public_key": 1952, + "secret_key": 4032, + "signature": 3309 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 410, + "timed_iters": 2050, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 121968.63, + "samples": 10250, + "median": 121000.0, + "mad": 1000.0, + "iqr": 1000.0, + "q1": 121000.0, + "q3": 122000.0, + "min": 119000.0, + "max": 138000.0, + "mean": 121558.54, + "stddev": 1373.02, + "ops_per_sec": 8264.46, + "per_rep_median": [ + 121000.0, + 121000.0, + 121000.0, + 121000.0, + 121000.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 108, + "timed_iters": 541, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 461716.54, + "samples": 2705, + "median": 376000.0, + "mad": 156000.0, + "iqr": 362000.0, + "q1": 236000.0, + "q3": 598000.0, + "min": 172000.0, + "max": 3253000.0, + "mean": 474120.89, + "stddev": 329222.43, + "ops_per_sec": 2659.57, + "per_rep_median": [ + 376000.0, + 376000.0, + 392000.0, + 375000.0, + 391000.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 457, + "timed_iters": 2286, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 109371.82, + "samples": 11430, + "median": 109000.0, + "mad": 0.0, + "iqr": 1000.0, + "q1": 109000.0, + "q3": 110000.0, + "min": 108000.0, + "max": 137000.0, + "mean": 109489.76, + "stddev": 1211.34, + "ops_per_sec": 9174.31, + "per_rep_median": [ + 109000.0, + 109000.0, + 109000.0, + 109000.0, + 110000.0 + ] + } + } + }, + { + "alg": "ML-DSA-87", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 2592, + "secret_key": 4896, + "signature": 4627 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 287, + "timed_iters": 1435, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 174211.76, + "samples": 7175, + "median": 172000.0, + "mad": 1000.0, + "iqr": 1000.0, + "q1": 172000.0, + "q3": 173000.0, + "min": 169000.0, + "max": 193000.0, + "mean": 172359.16, + "stddev": 1537.99, + "ops_per_sec": 5813.95, + "per_rep_median": [ + 172000.0, + 172000.0, + 172000.0, + 172000.0, + 172000.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 75, + "timed_iters": 377, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 662841.27, + "samples": 1885, + "median": 475000.0, + "mad": 206000.0, + "iqr": 420000.0, + "q1": 272000.0, + "q3": 692000.0, + "min": 267000.0, + "max": 2696000.0, + "mean": 561211.67, + "stddev": 339779.55, + "ops_per_sec": 2105.26, + "per_rep_median": [ + 454000.0, + 496000.0, + 476000.0, + 475000.0, + 453000.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 276, + "timed_iters": 1380, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 181160.78, + "samples": 6900, + "median": 181000.0, + "mad": 0.0, + "iqr": 0.0, + "q1": 181000.0, + "q3": 181000.0, + "min": 180000.0, + "max": 257000.0, + "mean": 181143.62, + "stddev": 2213.84, + "ops_per_sec": 5524.86, + "per_rep_median": [ + 181000.0, + 181000.0, + 181000.0, + 181000.0, + 181000.0 + ] + } + } + }, + { + "alg": "Falcon-512", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 897, + "secret_key": 1281, + "signature": 752 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 7, + "timed_iters": 35, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 7111000.0, + "samples": 175, + "median": 6557000.0, + "mad": 675000.0, + "iqr": 1273000.0, + "q1": 5991500.0, + "q3": 7264500.0, + "min": 5572000.0, + "max": 15023000.0, + "mean": 6938411.43, + "stddev": 1442365.12, + "ops_per_sec": 152.51, + "per_rep_median": [ + 6555000.0, + 6694000.0, + 6422000.0, + 6559000.0, + 6426000.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 245, + "timed_iters": 1224, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 204227.45, + "samples": 6120, + "median": 204000.0, + "mad": 2000.0, + "iqr": 5000.0, + "q1": 201000.0, + "q3": 206000.0, + "min": 189000.0, + "max": 223000.0, + "mean": 203931.21, + "stddev": 3838.04, + "ops_per_sec": 4901.96, + "per_rep_median": [ + 204000.0, + 204000.0, + 204000.0, + 203000.0, + 203000.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 1586, + "timed_iters": 7931, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 31521.02, + "samples": 39655, + "median": 32000.0, + "mad": 0.0, + "iqr": 1000.0, + "q1": 31000.0, + "q3": 32000.0, + "min": 30000.0, + "max": 473000.0, + "mean": 31718.9, + "stddev": 4108.49, + "ops_per_sec": 31250.0, + "per_rep_median": [ + 32000.0, + 32000.0, + 32000.0, + 32000.0, + 32000.0 + ] + } + } + }, + { + "alg": "Falcon-1024", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 1793, + "secret_key": 2305, + "signature": 1462 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 2, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 21524333.33, + "samples": 150, + "median": 20948500.0, + "mad": 1365500.0, + "iqr": 3289000.0, + "q1": 19789500.0, + "q3": 23078500.0, + "min": 19066000.0, + "max": 54086000.0, + "mean": 22651240.0, + "stddev": 5075415.28, + "ops_per_sec": 47.74, + "per_rep_median": [ + 20468000.0, + 20957000.0, + 21640500.0, + 20989000.0, + 20981500.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 122, + "timed_iters": 609, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 410527.56, + "samples": 3045, + "median": 409000.0, + "mad": 4000.0, + "iqr": 7000.0, + "q1": 405000.0, + "q3": 412000.0, + "min": 389000.0, + "max": 436000.0, + "mean": 409052.55, + "stddev": 5801.4, + "ops_per_sec": 2444.99, + "per_rep_median": [ + 410000.0, + 409000.0, + 409000.0, + 408000.0, + 408000.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 811, + "timed_iters": 4053, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 61686.89, + "samples": 20265, + "median": 62000.0, + "mad": 0.0, + "iqr": 1000.0, + "q1": 61000.0, + "q3": 62000.0, + "min": 60000.0, + "max": 73000.0, + "mean": 61775.13, + "stddev": 1002.52, + "ops_per_sec": 16129.03, + "per_rep_median": [ + 62000.0, + 62000.0, + 62000.0, + 62000.0, + 62000.0 + ] + } + } + }, + { + "alg": "SPHINCS+-SHA2-128f-simple", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 17088 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 57, + "timed_iters": 286, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 872920.63, + "samples": 1430, + "median": 866000.0, + "mad": 3000.0, + "iqr": 5000.0, + "q1": 863000.0, + "q3": 868000.0, + "min": 859000.0, + "max": 920000.0, + "mean": 867146.15, + "stddev": 6262.42, + "ops_per_sec": 1154.73, + "per_rep_median": [ + 868000.0, + 866000.0, + 862000.0, + 865000.0, + 865000.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 2, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 20203333.33, + "samples": 150, + "median": 20155000.0, + "mad": 34000.0, + "iqr": 69750.0, + "q1": 20132000.0, + "q3": 20201750.0, + "min": 20090000.0, + "max": 20517000.0, + "mean": 20179473.33, + "stddev": 76688.4, + "ops_per_sec": 49.62, + "per_rep_median": [ + 20206500.0, + 20147500.0, + 20274500.0, + 20116500.0, + 20141000.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 41, + "timed_iters": 206, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1212548.39, + "samples": 1030, + "median": 1211000.0, + "mad": 2000.0, + "iqr": 6000.0, + "q1": 1209000.0, + "q3": 1215000.0, + "min": 1207000.0, + "max": 1283000.0, + "mean": 1216231.07, + "stddev": 14223.64, + "ops_per_sec": 825.76, + "per_rep_median": [ + 1210000.0, + 1211000.0, + 1210000.0, + 1210000.0, + 1243000.0 + ] + } + } + }, + { + "alg": "SPHINCS+-SHA2-128s-simple", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 7856 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 55334000.0, + "samples": 150, + "median": 55436500.0, + "mad": 257500.0, + "iqr": 517000.0, + "q1": 55213750.0, + "q3": 55730750.0, + "min": 54966000.0, + "max": 57524000.0, + "mean": 55557473.33, + "stddev": 452267.54, + "ops_per_sec": 18.04, + "per_rep_median": [ + 55632000.0, + 55429500.0, + 55614000.0, + 55193500.0, + 55121000.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 424461000.0, + "samples": 150, + "median": 422006500.0, + "mad": 1661000.0, + "iqr": 3570500.0, + "q1": 420549000.0, + "q3": 424119500.0, + "min": 418755000.0, + "max": 606566000.0, + "mean": 423844466.67, + "stddev": 15250616.04, + "ops_per_sec": 2.37, + "per_rep_median": [ + 423611000.0, + 421329000.0, + 421705500.0, + 421372500.0, + 422424500.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 125, + "timed_iters": 625, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 399787.4, + "samples": 3125, + "median": 395000.0, + "mad": 1000.0, + "iqr": 3000.0, + "q1": 394000.0, + "q3": 397000.0, + "min": 392000.0, + "max": 446000.0, + "mean": 395872.96, + "stddev": 3498.24, + "ops_per_sec": 2531.65, + "per_rep_median": [ + 395000.0, + 394000.0, + 400000.0, + 394000.0, + 394000.0 + ] + } + } + }, + { + "alg": "SPHINCS+-SHA2-192f-simple", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 3, + "sizes": { + "public_key": 48, + "secret_key": 96, + "signature": 35664 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 39, + "timed_iters": 196, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1273967.74, + "samples": 980, + "median": 1255000.0, + "mad": 3000.0, + "iqr": 7000.0, + "q1": 1253000.0, + "q3": 1260000.0, + "min": 1246000.0, + "max": 1291000.0, + "mean": 1257083.67, + "stddev": 6316.24, + "ops_per_sec": 796.81, + "per_rep_median": [ + 1256000.0, + 1256000.0, + 1256000.0, + 1255000.0, + 1253000.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 2, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 33240000.0, + "samples": 150, + "median": 33370000.0, + "mad": 51000.0, + "iqr": 106500.0, + "q1": 33322500.0, + "q3": 33429000.0, + "min": 33117000.0, + "max": 37018000.0, + "mean": 33456106.67, + "stddev": 369561.85, + "ops_per_sec": 29.97, + "per_rep_median": [ + 33619500.0, + 33408000.0, + 33352500.0, + 33342500.0, + 33371000.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 28, + "timed_iters": 141, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1777612.9, + "samples": 705, + "median": 1773000.0, + "mad": 5000.0, + "iqr": 15000.0, + "q1": 1769000.0, + "q3": 1784000.0, + "min": 1761000.0, + "max": 1860000.0, + "mean": 1778225.53, + "stddev": 14463.47, + "ops_per_sec": 564.02, + "per_rep_median": [ + 1774000.0, + 1791000.0, + 1773000.0, + 1770000.0, + 1770000.0 + ] + } + } + }, + { + "alg": "SPHINCS+-SHA2-256f-simple", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 64, + "secret_key": 128, + "signature": 49856 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 15, + "timed_iters": 75, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 3330466.67, + "samples": 375, + "median": 3320000.0, + "mad": 6000.0, + "iqr": 13000.0, + "q1": 3314000.0, + "q3": 3327000.0, + "min": 3306000.0, + "max": 3386000.0, + "mean": 3321840.0, + "stddev": 10971.57, + "ops_per_sec": 301.2, + "per_rep_median": [ + 3324000.0, + 3320000.0, + 3319000.0, + 3315000.0, + 3319000.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 68615000.0, + "samples": 150, + "median": 68626500.0, + "mad": 105000.0, + "iqr": 228000.0, + "q1": 68531250.0, + "q3": 68759250.0, + "min": 68385000.0, + "max": 71147000.0, + "mean": 68727526.67, + "stddev": 395205.03, + "ops_per_sec": 14.57, + "per_rep_median": [ + 68539500.0, + 68672500.0, + 68546000.0, + 68567000.0, + 68762500.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 28, + "timed_iters": 139, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1795064.52, + "samples": 695, + "median": 1784000.0, + "mad": 3000.0, + "iqr": 6000.0, + "q1": 1781000.0, + "q3": 1787000.0, + "min": 1775000.0, + "max": 1818000.0, + "mean": 1785132.37, + "stddev": 6416.59, + "ops_per_sec": 560.54, + "per_rep_median": [ + 1785000.0, + 1786000.0, + 1786000.0, + 1781000.0, + 1780000.0 + ] + } + } + } + ], + "tls": { + "available": true, + "have_oqs_provider": true, + "baseline": { + "kem_group": "X25519", + "sig_alg": "ed25519", + "label": "X25519+ed25519" + }, + "matrix": [ + { + "label": "X25519+ed25519", + "group": "X25519", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 711000.0, + "p95": 722000.0, + "min": 706000.0, + "max": 835000.0, + "mean": 712783.0, + "stddev": 6393.8 + }, + "handshakes_per_sec": 1406.5, + "bytes_on_wire": { + "client_to_server": 371, + "server_to_client": 1189, + "total": 1560 + }, + "client_hello_bytes": 291, + "client_hello_fragmented": false, + "mss_assumed": 1400 + }, + { + "label": "X25519MLKEM768+mldsa44", + "group": "X25519MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1162500.0, + "p95": 1969050.0, + "min": 975000.0, + "max": 3226000.0, + "mean": 1292954.0, + "stddev": 335163.0 + }, + "handshakes_per_sec": 860.2, + "bytes_on_wire": { + "client_to_server": 1549, + "server_to_client": 8294, + "total": 9843 + }, + "client_hello_bytes": 1469, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "X25519MLKEM768+mldsa65", + "group": "X25519MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1551000.0, + "p95": 2794050.0, + "min": 1176000.0, + "max": 4901000.0, + "mean": 1713766.0, + "stddev": 564566.2 + }, + "handshakes_per_sec": 644.7, + "bytes_on_wire": { + "client_to_server": 1549, + "server_to_client": 10712, + "total": 12261 + }, + "client_hello_bytes": 1469, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "X25519MLKEM768+mldsa87", + "group": "X25519MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1848000.0, + "p95": 3275000.0, + "min": 1487000.0, + "max": 5062000.0, + "mean": 2008523.0, + "stddev": 583159.4 + }, + "handshakes_per_sec": 541.1, + "bytes_on_wire": { + "client_to_server": 1549, + "server_to_client": 13988, + "total": 15537 + }, + "client_hello_bytes": 1469, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "X25519MLKEM768+falcon512", + "group": "X25519MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1666000.0, + "p95": 1683000.0, + "min": 1649000.0, + "max": 2841000.0, + "mean": 1669097.0, + "stddev": 41557.4 + }, + "handshakes_per_sec": 600.2, + "bytes_on_wire": { + "client_to_server": 1549, + "server_to_client": 4339, + "total": 5888 + }, + "client_hello_bytes": 1469, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "X25519MLKEM768+sphincssha2128fsimple", + "group": "X25519MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 24625500.0, + "p95": 25097050.0, + "min": 23995000.0, + "max": 31304000.0, + "mean": 24620496.0, + "stddev": 412492.6 + }, + "handshakes_per_sec": 40.6, + "bytes_on_wire": { + "client_to_server": 1549, + "server_to_client": 36394, + "total": 37943 + }, + "client_hello_bytes": 1469, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "SecP256r1MLKEM768+mldsa44", + "group": "SecP256r1MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1157000.0, + "p95": 1958050.0, + "min": 968000.0, + "max": 4268000.0, + "mean": 1288673.0, + "stddev": 370312.4 + }, + "handshakes_per_sec": 864.3, + "bytes_on_wire": { + "client_to_server": 1582, + "server_to_client": 8327, + "total": 9909 + }, + "client_hello_bytes": 1502, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "SecP256r1MLKEM768+mldsa65", + "group": "SecP256r1MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1543000.0, + "p95": 2908050.0, + "min": 1168000.0, + "max": 4522000.0, + "mean": 1688849.0, + "stddev": 566143.3 + }, + "handshakes_per_sec": 648.1, + "bytes_on_wire": { + "client_to_server": 1582, + "server_to_client": 10745, + "total": 12327 + }, + "client_hello_bytes": 1502, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "SecP256r1MLKEM768+mldsa87", + "group": "SecP256r1MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1848000.0, + "p95": 3448200.0, + "min": 1485000.0, + "max": 6342000.0, + "mean": 2027265.0, + "stddev": 652400.1 + }, + "handshakes_per_sec": 541.1, + "bytes_on_wire": { + "client_to_server": 1582, + "server_to_client": 14021, + "total": 15603 + }, + "client_hello_bytes": 1502, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "SecP256r1MLKEM768+falcon512", + "group": "SecP256r1MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1655000.0, + "p95": 1686050.0, + "min": 1638000.0, + "max": 3671000.0, + "mean": 1667737.0, + "stddev": 103101.4 + }, + "handshakes_per_sec": 604.2, + "bytes_on_wire": { + "client_to_server": 1582, + "server_to_client": 4378, + "total": 5960 + }, + "client_hello_bytes": 1502, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "SecP256r1MLKEM768+sphincssha2128fsimple", + "group": "SecP256r1MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 24819500.0, + "p95": 25310050.0, + "min": 24227000.0, + "max": 27278000.0, + "mean": 24786145.0, + "stddev": 323190.6 + }, + "handshakes_per_sec": 40.3, + "bytes_on_wire": { + "client_to_server": 1582, + "server_to_client": 36427, + "total": 38009 + }, + "client_hello_bytes": 1502, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem512+mldsa44", + "group": "mlkem512", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 925000.0, + "p95": 1640050.0, + "min": 740000.0, + "max": 3634000.0, + "mean": 1045272.0, + "stddev": 339437.3 + }, + "handshakes_per_sec": 1081.1, + "bytes_on_wire": { + "client_to_server": 1133, + "server_to_client": 7942, + "total": 9075 + }, + "client_hello_bytes": 1053, + "client_hello_fragmented": false, + "mss_assumed": 1400 + }, + { + "label": "mlkem512+mldsa65", + "group": "mlkem512", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1316000.0, + "p95": 2447400.0, + "min": 941000.0, + "max": 5057000.0, + "mean": 1450007.0, + "stddev": 543135.4 + }, + "handshakes_per_sec": 759.9, + "bytes_on_wire": { + "client_to_server": 1133, + "server_to_client": 10360, + "total": 11493 + }, + "client_hello_bytes": 1053, + "client_hello_fragmented": false, + "mss_assumed": 1400 + }, + { + "label": "mlkem512+mldsa87", + "group": "mlkem512", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1612000.0, + "p95": 3039100.0, + "min": 1250000.0, + "max": 6789000.0, + "mean": 1783615.0, + "stddev": 604958.7 + }, + "handshakes_per_sec": 620.3, + "bytes_on_wire": { + "client_to_server": 1133, + "server_to_client": 13636, + "total": 14769 + }, + "client_hello_bytes": 1053, + "client_hello_fragmented": false, + "mss_assumed": 1400 + }, + { + "label": "mlkem512+falcon512", + "group": "mlkem512", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1427000.0, + "p95": 1459100.0, + "min": 1410000.0, + "max": 2716000.0, + "mean": 1438196.0, + "stddev": 79132.3 + }, + "handshakes_per_sec": 700.8, + "bytes_on_wire": { + "client_to_server": 1133, + "server_to_client": 3989, + "total": 5122 + }, + "client_hello_bytes": 1053, + "client_hello_fragmented": false, + "mss_assumed": 1400 + }, + { + "label": "mlkem512+sphincssha2128fsimple", + "group": "mlkem512", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 24697000.0, + "p95": 25165100.0, + "min": 23943000.0, + "max": 32026000.0, + "mean": 24686483.0, + "stddev": 406141.2 + }, + "handshakes_per_sec": 40.5, + "bytes_on_wire": { + "client_to_server": 1133, + "server_to_client": 36042, + "total": 37175 + }, + "client_hello_bytes": 1053, + "client_hello_fragmented": false, + "mss_assumed": 1400 + }, + { + "label": "mlkem768+mldsa44", + "group": "mlkem768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 972000.0, + "p95": 1772000.0, + "min": 790000.0, + "max": 3369000.0, + "mean": 1087896.0, + "stddev": 346252.1 + }, + "handshakes_per_sec": 1028.8, + "bytes_on_wire": { + "client_to_server": 1517, + "server_to_client": 8262, + "total": 9779 + }, + "client_hello_bytes": 1437, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem768+mldsa65", + "group": "mlkem768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1361000.0, + "p95": 2614050.0, + "min": 987000.0, + "max": 5334000.0, + "mean": 1514568.0, + "stddev": 566912.4 + }, + "handshakes_per_sec": 734.8, + "bytes_on_wire": { + "client_to_server": 1517, + "server_to_client": 10680, + "total": 12197 + }, + "client_hello_bytes": 1437, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem768+mldsa87", + "group": "mlkem768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1659000.0, + "p95": 3082000.0, + "min": 1298000.0, + "max": 5597000.0, + "mean": 1830573.0, + "stddev": 596462.5 + }, + "handshakes_per_sec": 602.8, + "bytes_on_wire": { + "client_to_server": 1517, + "server_to_client": 13956, + "total": 15473 + }, + "client_hello_bytes": 1437, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem768+falcon512", + "group": "mlkem768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1470000.0, + "p95": 1490050.0, + "min": 1457000.0, + "max": 1611000.0, + "mean": 1474078.0, + "stddev": 19375.4 + }, + "handshakes_per_sec": 680.3, + "bytes_on_wire": { + "client_to_server": 1517, + "server_to_client": 4305, + "total": 5822 + }, + "client_hello_bytes": 1437, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem768+sphincssha2128fsimple", + "group": "mlkem768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 24603000.0, + "p95": 25079100.0, + "min": 24053000.0, + "max": 157458000.0, + "mean": 24854192.0, + "stddev": 4716531.1 + }, + "handshakes_per_sec": 40.6, + "bytes_on_wire": { + "client_to_server": 1517, + "server_to_client": 36362, + "total": 37879 + }, + "client_hello_bytes": 1437, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem1024+mldsa44", + "group": "mlkem1024", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1034000.0, + "p95": 1744000.0, + "min": 851000.0, + "max": 2746000.0, + "mean": 1135006.0, + "stddev": 303208.8 + }, + "handshakes_per_sec": 967.1, + "bytes_on_wire": { + "client_to_server": 1901, + "server_to_client": 8742, + "total": 10643 + }, + "client_hello_bytes": 1821, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem1024+mldsa65", + "group": "mlkem1024", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1425000.0, + "p95": 2674000.0, + "min": 1050000.0, + "max": 5034000.0, + "mean": 1575114.0, + "stddev": 551475.8 + }, + "handshakes_per_sec": 701.8, + "bytes_on_wire": { + "client_to_server": 1901, + "server_to_client": 11160, + "total": 13061 + }, + "client_hello_bytes": 1821, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem1024+mldsa87", + "group": "mlkem1024", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1723500.0, + "p95": 2999500.0, + "min": 1361000.0, + "max": 4772000.0, + "mean": 1883920.0, + "stddev": 556616.3 + }, + "handshakes_per_sec": 580.2, + "bytes_on_wire": { + "client_to_server": 1901, + "server_to_client": 14436, + "total": 16337 + }, + "client_hello_bytes": 1821, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem1024+falcon512", + "group": "mlkem1024", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1528000.0, + "p95": 1541050.0, + "min": 1516000.0, + "max": 1572000.0, + "mean": 1529399.0, + "stddev": 6727.0 + }, + "handshakes_per_sec": 654.5, + "bytes_on_wire": { + "client_to_server": 1901, + "server_to_client": 4791, + "total": 6692 + }, + "client_hello_bytes": 1821, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem1024+sphincssha2128fsimple", + "group": "mlkem1024", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 24511000.0, + "p95": 25007050.0, + "min": 23924000.0, + "max": 33493000.0, + "mean": 24546099.0, + "stddev": 448598.6 + }, + "handshakes_per_sec": 40.8, + "bytes_on_wire": { + "client_to_server": 1901, + "server_to_client": 36842, + "total": 38743 + }, + "client_hello_bytes": 1821, + "client_hello_fragmented": true, + "mss_assumed": 1400 + } + ] + } +} \ No newline at end of file diff --git a/pq-bench-rpi5/results/rasberrypi5-20260625T202356Z.json b/pq-bench-rpi5/results/rasberrypi5-20260625T202356Z.json new file mode 100644 index 0000000..d6beada --- /dev/null +++ b/pq-bench-rpi5/results/rasberrypi5-20260625T202356Z.json @@ -0,0 +1,10825 @@ +{ + "schema_version": "1.0.0", + "tool_version": "0.1.0", + "generated_utc": "2026-06-25T20:46:28Z", + "is_baseline_grade": true, + "baseline_grade_reasons": [], + "host": { + "hostname": "rasberrypi5", + "os": "linux", + "os_pretty": "Debian GNU/Linux 13 (trixie)", + "arch": "aarch64", + "kernel": "6.18.33+rpt-rpi-2712", + "is_rpi": true, + "rpi_model": "Raspberry Pi 5 Model B Rev 1.1", + "cpu_brand": "Raspberry Pi 5 Model B Rev 1.1", + "ncpu": 4, + "ram_bytes": 8454029312 + }, + "cpu_features": { + "source": "/proc/cpuinfo", + "neon": true, + "sha2": true, + "sha3": false, + "sha512": false, + "aes": true, + "pmull": true + }, + "run": { + "timestamp_start_utc": "2026-06-25T20:23:57Z", + "timestamp_end_utc": "2026-06-25T20:46:28Z", + "duration_s": 1351, + "governor_requested": "performance", + "governor_before": "ondemand", + "governor_after": "performance", + "bench_core": 3, + "pinned": true, + "taskset_cmd": "taskset -c 3", + "calibration_mode": "auto", + "target_time_ms": 250, + "min_samples": 30, + "max_iters": 20000, + "warmup_iters": null, + "timed_iters": null, + "repetitions": 5, + "cycles_mode": "auto", + "cycles_available": false, + "cycles_reason": "PMCCNTR_EL0 traps (kernel module not loaded; needs e.g. enable_arm_pmu)" + }, + "toolchain": { + "cc_version": "cc (Debian 14.2.0-19) 14.2.0", + "bench_cflags": "-O3 -mcpu=cortex-a76", + "cflags_target": "cortex-a76", + "liboqs_ref": "0.15.0", + "liboqs_commit": "97f6b86b1b6d109cfd43cf276ae39c2e776aed80", + "liboqs_opt_defines": "OQS_COMPILE_BUILD_TARGET aarch64-Linux-6.12.47+rpt-rpi-2712;ARCH_ARM64v8 1;OQS_OPT_TARGET auto;OQS_USE_ARM_AES_INSTRUCTIONS 1;OQS_USE_ARM_SHA2_INSTRUCTIONS 1;OQS_USE_ARM_NEON_INSTRUCTIONS 1;OQS_ENABLE_KEM_kyber_512_aarch64 1;OQS_ENABLE_KEM_kyber_768_aarch64 1;OQS_ENABLE_KEM_kyber_1024_aarch64 1;OQS_ENABLE_KEM_ml_kem_512_aarch64 1;OQS_ENABLE_KEM_ml_kem_768_aarch64 1;OQS_ENABLE_KEM_ml_kem_1024_aarch64 1;OQS_ENABLE_SIG_falcon_512_aarch64 1;OQS_ENABLE_SIG_falcon_1024_aarch64 1;OQS_ENABLE_SIG_falcon_padded_512_aarch64 1;OQS_ENABLE_SIG_falcon_padded_1024_aarch64 1;", + "openssl": "system:3.5.6", + "oqsprovider_ref": "0.9.0", + "oqsprovider_commit": "848b4e6abaa89e769c4db46ca78f91000f67ca52" + }, + "thermal_trace": { + "columns": [ + "epoch_s", + "arm_clock_hz", + "temp_c", + "throttled_hex" + ], + "samples": [ + [ + 1782419036, + 2400020480, + 49.9, + "0x0" + ], + [ + 1782419036, + 2400033792, + 49.9, + "0x0" + ], + [ + 1782419037, + 2400027136, + 50.5, + "0x0" + ], + [ + 1782419038, + 2400023808, + 51.6, + "0x0" + ], + [ + 1782419040, + 2400027136, + 51.0, + "0x0" + ], + [ + 1782419041, + 2400020480, + 52.1, + "0x0" + ], + [ + 1782419042, + 2400033792, + 52.1, + "0x0" + ], + [ + 1782419043, + 2400027136, + 52.7, + "0x0" + ], + [ + 1782419044, + 2400030464, + 53.2, + "0x0" + ], + [ + 1782419045, + 2400030464, + 52.7, + "0x0" + ], + [ + 1782419046, + 2400023808, + 52.7, + "0x0" + ], + [ + 1782419047, + 2400030464, + 52.7, + "0x0" + ], + [ + 1782419048, + 2400037120, + 52.7, + "0x0" + ], + [ + 1782419049, + 2400023808, + 53.2, + "0x0" + ], + [ + 1782419050, + 2400027136, + 53.2, + "0x0" + ], + [ + 1782419051, + 2400030464, + 52.1, + "0x0" + ], + [ + 1782419052, + 2400023808, + 53.2, + "0x0" + ], + [ + 1782419053, + 2400037120, + 53.2, + "0x0" + ], + [ + 1782419054, + 2400023808, + 52.7, + "0x0" + ], + [ + 1782419055, + 2400027136, + 53.2, + "0x0" + ], + [ + 1782419056, + 2400020480, + 54.3, + "0x0" + ], + [ + 1782419057, + 2400020480, + 53.2, + "0x0" + ], + [ + 1782419058, + 2400027136, + 53.2, + "0x0" + ], + [ + 1782419059, + 2400030464, + 54.9, + "0x0" + ], + [ + 1782419060, + 2400023808, + 54.9, + "0x0" + ], + [ + 1782419061, + 2400020480, + 54.9, + "0x0" + ], + [ + 1782419062, + 2400023808, + 54.3, + "0x0" + ], + [ + 1782419063, + 2400030464, + 53.8, + "0x0" + ], + [ + 1782419064, + 2400030464, + 54.3, + "0x0" + ], + [ + 1782419065, + 2400020480, + 54.3, + "0x0" + ], + [ + 1782419066, + 2400027136, + 54.3, + "0x0" + ], + [ + 1782419067, + 2400037120, + 54.3, + "0x0" + ], + [ + 1782419068, + 2400020480, + 55.4, + "0x0" + ], + [ + 1782419069, + 2400037120, + 54.9, + "0x0" + ], + [ + 1782419070, + 2400020480, + 54.9, + "0x0" + ], + [ + 1782419071, + 2400030464, + 54.3, + "0x0" + ], + [ + 1782419072, + 2400033792, + 54.9, + "0x0" + ], + [ + 1782419073, + 2400033792, + 54.3, + "0x0" + ], + [ + 1782419074, + 2400030464, + 55.4, + "0x0" + ], + [ + 1782419075, + 2400037120, + 54.9, + "0x0" + ], + [ + 1782419076, + 2400017408, + 54.9, + "0x0" + ], + [ + 1782419077, + 2400037120, + 54.3, + "0x0" + ], + [ + 1782419078, + 2400030464, + 54.9, + "0x0" + ], + [ + 1782419079, + 2400027136, + 54.9, + "0x0" + ], + [ + 1782419080, + 2400020480, + 54.9, + "0x0" + ], + [ + 1782419081, + 2400020480, + 54.3, + "0x0" + ], + [ + 1782419083, + 2400030464, + 54.3, + "0x0" + ], + [ + 1782419084, + 2400027136, + 53.8, + "0x0" + ], + [ + 1782419085, + 2400030464, + 54.3, + "0x0" + ], + [ + 1782419086, + 2400030464, + 53.8, + "0x0" + ], + [ + 1782419087, + 2400023808, + 54.3, + "0x0" + ], + [ + 1782419088, + 2400027136, + 55.4, + "0x0" + ], + [ + 1782419089, + 2400030464, + 55.4, + "0x0" + ], + [ + 1782419090, + 2400023808, + 55.4, + "0x0" + ], + [ + 1782419091, + 2400020480, + 56.0, + "0x0" + ], + [ + 1782419092, + 2400023808, + 56.0, + "0x0" + ], + [ + 1782419093, + 2400023808, + 56.5, + "0x0" + ], + [ + 1782419094, + 2400027136, + 56.5, + "0x0" + ], + [ + 1782419095, + 2400033792, + 56.5, + "0x0" + ], + [ + 1782419096, + 2400027136, + 56.0, + "0x0" + ], + [ + 1782419097, + 2400023808, + 57.1, + "0x0" + ], + [ + 1782419098, + 2400027136, + 56.5, + "0x0" + ], + [ + 1782419099, + 2400033792, + 55.4, + "0x0" + ], + [ + 1782419100, + 2400023808, + 57.1, + "0x0" + ], + [ + 1782419101, + 2400030464, + 56.5, + "0x0" + ], + [ + 1782419102, + 2400030464, + 57.1, + "0x0" + ], + [ + 1782419103, + 2400033792, + 56.0, + "0x0" + ], + [ + 1782419104, + 2400033792, + 57.1, + "0x0" + ], + [ + 1782419105, + 2400023808, + 57.6, + "0x0" + ], + [ + 1782419106, + 2400020480, + 56.5, + "0x0" + ], + [ + 1782419107, + 2400037120, + 56.5, + "0x0" + ], + [ + 1782419108, + 2400030464, + 57.6, + "0x0" + ], + [ + 1782419109, + 2400030464, + 57.1, + "0x0" + ], + [ + 1782419110, + 2400017408, + 58.2, + "0x0" + ], + [ + 1782419111, + 2400020480, + 56.5, + "0x0" + ], + [ + 1782419112, + 2400030464, + 58.2, + "0x0" + ], + [ + 1782419113, + 2400033792, + 57.1, + "0x0" + ], + [ + 1782419114, + 2400017408, + 57.1, + "0x0" + ], + [ + 1782419115, + 2400033792, + 58.2, + "0x0" + ], + [ + 1782419116, + 2400027136, + 57.1, + "0x0" + ], + [ + 1782419117, + 2400037120, + 57.6, + "0x0" + ], + [ + 1782419118, + 2400027136, + 56.5, + "0x0" + ], + [ + 1782419119, + 2400017408, + 57.1, + "0x0" + ], + [ + 1782419120, + 2400030464, + 57.1, + "0x0" + ], + [ + 1782419121, + 2400027136, + 57.1, + "0x0" + ], + [ + 1782419122, + 2400027136, + 56.5, + "0x0" + ], + [ + 1782419123, + 2400020480, + 57.6, + "0x0" + ], + [ + 1782419124, + 2400023808, + 58.2, + "0x0" + ], + [ + 1782419125, + 2400020480, + 57.1, + "0x0" + ], + [ + 1782419126, + 2400020480, + 58.2, + "0x0" + ], + [ + 1782419127, + 2400020480, + 58.2, + "0x0" + ], + [ + 1782419129, + 2400033792, + 57.1, + "0x0" + ], + [ + 1782419130, + 2400020480, + 57.6, + "0x0" + ], + [ + 1782419131, + 2400027136, + 58.2, + "0x0" + ], + [ + 1782419132, + 2400027136, + 58.2, + "0x0" + ], + [ + 1782419133, + 2400030464, + 57.6, + "0x0" + ], + [ + 1782419134, + 2400017408, + 57.6, + "0x0" + ], + [ + 1782419135, + 2400030464, + 57.6, + "0x0" + ], + [ + 1782419136, + 2400030464, + 57.6, + "0x0" + ], + [ + 1782419137, + 2400020480, + 57.6, + "0x0" + ], + [ + 1782419138, + 2400027136, + 58.7, + "0x0" + ], + [ + 1782419139, + 2400017408, + 57.6, + "0x0" + ], + [ + 1782419140, + 2400020480, + 58.7, + "0x0" + ], + [ + 1782419141, + 2400027136, + 58.2, + "0x0" + ], + [ + 1782419142, + 2400027136, + 58.2, + "0x0" + ], + [ + 1782419143, + 2400037120, + 58.2, + "0x0" + ], + [ + 1782419144, + 2400020480, + 58.7, + "0x0" + ], + [ + 1782419145, + 2400017408, + 58.7, + "0x0" + ], + [ + 1782419146, + 2400020480, + 58.7, + "0x0" + ], + [ + 1782419147, + 2400033792, + 57.6, + "0x0" + ], + [ + 1782419148, + 2400017408, + 58.7, + "0x0" + ], + [ + 1782419149, + 2400027136, + 59.3, + "0x0" + ], + [ + 1782419150, + 2400030464, + 58.2, + "0x0" + ], + [ + 1782419151, + 2400023808, + 59.3, + "0x0" + ], + [ + 1782419152, + 2400033792, + 58.2, + "0x0" + ], + [ + 1782419153, + 2400027136, + 59.3, + "0x0" + ], + [ + 1782419154, + 2400030464, + 58.2, + "0x0" + ], + [ + 1782419155, + 2400030464, + 59.3, + "0x0" + ], + [ + 1782419156, + 2400020480, + 59.3, + "0x0" + ], + [ + 1782419157, + 2400030464, + 59.3, + "0x0" + ], + [ + 1782419158, + 2400030464, + 58.7, + "0x0" + ], + [ + 1782419159, + 2400023808, + 58.7, + "0x0" + ], + [ + 1782419160, + 2400023808, + 59.8, + "0x0" + ], + [ + 1782419161, + 2400030464, + 58.7, + "0x0" + ], + [ + 1782419162, + 2400020480, + 59.8, + "0x0" + ], + [ + 1782419163, + 2400037120, + 57.6, + "0x0" + ], + [ + 1782419164, + 2400033792, + 59.3, + "0x0" + ], + [ + 1782419165, + 2400023808, + 59.8, + "0x0" + ], + [ + 1782419166, + 2400030464, + 59.3, + "0x0" + ], + [ + 1782419167, + 2400020480, + 58.2, + "0x0" + ], + [ + 1782419168, + 2400023808, + 59.8, + "0x0" + ], + [ + 1782419169, + 2400020480, + 58.2, + "0x0" + ], + [ + 1782419170, + 2400027136, + 58.2, + "0x0" + ], + [ + 1782419171, + 2400033792, + 57.1, + "0x0" + ], + [ + 1782419172, + 2400033792, + 57.6, + "0x0" + ], + [ + 1782419173, + 2400033792, + 57.1, + "0x0" + ], + [ + 1782419174, + 2400023808, + 57.1, + "0x0" + ], + [ + 1782419176, + 2400033792, + 57.1, + "0x0" + ], + [ + 1782419177, + 2400030464, + 56.5, + "0x0" + ], + [ + 1782419178, + 2400020480, + 57.1, + "0x0" + ], + [ + 1782419179, + 2400027136, + 57.1, + "0x0" + ], + [ + 1782419180, + 2400020480, + 57.1, + "0x0" + ], + [ + 1782419181, + 2400033792, + 58.7, + "0x0" + ], + [ + 1782419182, + 2400020480, + 58.2, + "0x0" + ], + [ + 1782419183, + 2400020480, + 58.2, + "0x0" + ], + [ + 1782419184, + 2400017408, + 58.7, + "0x0" + ], + [ + 1782419185, + 2400027136, + 57.6, + "0x0" + ], + [ + 1782419186, + 2400017408, + 58.2, + "0x0" + ], + [ + 1782419187, + 2400027136, + 58.7, + "0x0" + ], + [ + 1782419188, + 2400027136, + 59.3, + "0x0" + ], + [ + 1782419189, + 2400023808, + 58.7, + "0x0" + ], + [ + 1782419190, + 2400020480, + 58.7, + "0x0" + ], + [ + 1782419191, + 2400017408, + 59.3, + "0x0" + ], + [ + 1782419192, + 2400033792, + 58.7, + "0x0" + ], + [ + 1782419193, + 2400037120, + 58.7, + "0x0" + ], + [ + 1782419194, + 2400030464, + 59.3, + "0x0" + ], + [ + 1782419195, + 2400017408, + 58.7, + "0x0" + ], + [ + 1782419196, + 2400020480, + 59.8, + "0x0" + ], + [ + 1782419197, + 2400037120, + 58.2, + "0x0" + ], + [ + 1782419198, + 2400033792, + 59.8, + "0x0" + ], + [ + 1782419199, + 2400017408, + 59.8, + "0x0" + ], + [ + 1782419200, + 2400023808, + 59.3, + "0x0" + ], + [ + 1782419201, + 2400037120, + 57.6, + "0x0" + ], + [ + 1782419202, + 2400017408, + 58.7, + "0x0" + ], + [ + 1782419203, + 2400023808, + 59.3, + "0x0" + ], + [ + 1782419204, + 2400023808, + 58.7, + "0x0" + ], + [ + 1782419205, + 2400027136, + 59.8, + "0x0" + ], + [ + 1782419206, + 2400023808, + 59.3, + "0x0" + ], + [ + 1782419207, + 2400030464, + 59.3, + "0x0" + ], + [ + 1782419208, + 2400020480, + 58.7, + "0x0" + ], + [ + 1782419209, + 2400020480, + 59.3, + "0x0" + ], + [ + 1782419210, + 2400027136, + 59.3, + "0x0" + ], + [ + 1782419211, + 2400023808, + 58.7, + "0x0" + ], + [ + 1782419212, + 2400017408, + 58.7, + "0x0" + ], + [ + 1782419213, + 2400020480, + 59.8, + "0x0" + ], + [ + 1782419214, + 2400020480, + 58.7, + "0x0" + ], + [ + 1782419215, + 2400030464, + 59.8, + "0x0" + ], + [ + 1782419216, + 2400017408, + 59.8, + "0x0" + ], + [ + 1782419218, + 2400017408, + 58.7, + "0x0" + ], + [ + 1782419219, + 2400027136, + 57.6, + "0x0" + ], + [ + 1782419220, + 2400020480, + 58.7, + "0x0" + ], + [ + 1782419221, + 2400037120, + 57.6, + "0x0" + ], + [ + 1782419222, + 2400027136, + 58.2, + "0x0" + ], + [ + 1782419223, + 2400017408, + 57.1, + "0x0" + ], + [ + 1782419224, + 2400020480, + 57.6, + "0x0" + ], + [ + 1782419225, + 2400030464, + 57.6, + "0x0" + ], + [ + 1782419226, + 2400037120, + 57.1, + "0x0" + ], + [ + 1782419227, + 2400023808, + 59.8, + "0x0" + ], + [ + 1782419228, + 2400023808, + 59.8, + "0x0" + ], + [ + 1782419229, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782419230, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782419231, + 2400017408, + 60.4, + "0x0" + ], + [ + 1782419232, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419233, + 2400033792, + 59.8, + "0x0" + ], + [ + 1782419234, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782419235, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782419236, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782419237, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782419238, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782419239, + 2400017408, + 60.4, + "0x0" + ], + [ + 1782419240, + 2400023808, + 59.8, + "0x0" + ], + [ + 1782419241, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782419242, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782419243, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782419244, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782419245, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782419246, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419247, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419248, + 2400033792, + 62.0, + "0x0" + ], + [ + 1782419249, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782419250, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782419251, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419252, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782419253, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419254, + 2400020480, + 59.8, + "0x0" + ], + [ + 1782419255, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782419256, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419257, + 2400017408, + 60.4, + "0x0" + ], + [ + 1782419258, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419259, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419260, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782419261, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782419262, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782419263, + 2400033792, + 62.0, + "0x0" + ], + [ + 1782419264, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782419265, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419266, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782419268, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782419269, + 2400017408, + 60.9, + "0x0" + ], + [ + 1782419270, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419271, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419272, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419273, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419274, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782419275, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419276, + 2400017408, + 60.4, + "0x0" + ], + [ + 1782419277, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782419278, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419279, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419280, + 2400017408, + 62.0, + "0x0" + ], + [ + 1782419281, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419282, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419283, + 2400030464, + 63.1, + "0x0" + ], + [ + 1782419284, + 2400027136, + 59.8, + "0x0" + ], + [ + 1782419285, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419286, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782419287, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419288, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782419289, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419290, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419291, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419292, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782419293, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419294, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782419295, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419296, + 2400037120, + 62.6, + "0x0" + ], + [ + 1782419297, + 2400017408, + 61.5, + "0x0" + ], + [ + 1782419298, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419299, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419300, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419301, + 2400037120, + 63.1, + "0x0" + ], + [ + 1782419302, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419303, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419304, + 2400030464, + 63.1, + "0x0" + ], + [ + 1782419305, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419306, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419307, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419308, + 2400033792, + 63.1, + "0x0" + ], + [ + 1782419309, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419310, + 2400033792, + 61.5, + "0x0" + ], + [ + 1782419311, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419313, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419314, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419315, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419316, + 2400030464, + 63.7, + "0x0" + ], + [ + 1782419317, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782419318, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419319, + 2400037120, + 62.6, + "0x0" + ], + [ + 1782419320, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419321, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419322, + 2400017408, + 61.5, + "0x0" + ], + [ + 1782419323, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782419324, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782419325, + 2400033792, + 62.6, + "0x0" + ], + [ + 1782419326, + 2400017408, + 62.6, + "0x0" + ], + [ + 1782419327, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419328, + 2400017408, + 63.1, + "0x0" + ], + [ + 1782419329, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419330, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419331, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419332, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419333, + 2400030464, + 63.7, + "0x0" + ], + [ + 1782419334, + 2400033792, + 62.6, + "0x0" + ], + [ + 1782419335, + 2400033792, + 63.1, + "0x0" + ], + [ + 1782419336, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419337, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419338, + 2400020480, + 64.2, + "0x0" + ], + [ + 1782419339, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419340, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419341, + 2400017408, + 61.5, + "0x0" + ], + [ + 1782419342, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419343, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419344, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419345, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419346, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419347, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419348, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419349, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419350, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419351, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419352, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419353, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419354, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419355, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419356, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419357, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419358, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419359, + 2400033792, + 62.6, + "0x0" + ], + [ + 1782419361, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419362, + 2400033792, + 63.1, + "0x0" + ], + [ + 1782419363, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419364, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419365, + 2400017408, + 63.7, + "0x0" + ], + [ + 1782419366, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419367, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419368, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419369, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419370, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419371, + 2400017408, + 63.7, + "0x0" + ], + [ + 1782419372, + 2400037120, + 62.0, + "0x0" + ], + [ + 1782419373, + 2400027136, + 64.2, + "0x0" + ], + [ + 1782419374, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419375, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419376, + 2400037120, + 63.7, + "0x0" + ], + [ + 1782419377, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419378, + 2400030464, + 63.7, + "0x0" + ], + [ + 1782419379, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419380, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419381, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419382, + 2400027136, + 64.2, + "0x0" + ], + [ + 1782419383, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419384, + 2400037120, + 62.6, + "0x0" + ], + [ + 1782419385, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419386, + 2400030464, + 63.1, + "0x0" + ], + [ + 1782419387, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419388, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419389, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419390, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419391, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419392, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419393, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419394, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419395, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419396, + 2400037120, + 63.7, + "0x0" + ], + [ + 1782419397, + 2400017408, + 63.7, + "0x0" + ], + [ + 1782419398, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419399, + 2400017408, + 62.6, + "0x0" + ], + [ + 1782419400, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419401, + 2400017408, + 60.9, + "0x0" + ], + [ + 1782419402, + 2400030464, + 64.2, + "0x0" + ], + [ + 1782419403, + 2400033792, + 64.2, + "0x0" + ], + [ + 1782419405, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419406, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419407, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419408, + 2400030464, + 63.1, + "0x0" + ], + [ + 1782419409, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419410, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782419411, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419412, + 2400037120, + 59.8, + "0x0" + ], + [ + 1782419413, + 2400037120, + 59.8, + "0x0" + ], + [ + 1782419414, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782419415, + 2400037120, + 60.4, + "0x0" + ], + [ + 1782419416, + 2400030464, + 59.3, + "0x0" + ], + [ + 1782419417, + 2400027136, + 59.3, + "0x0" + ], + [ + 1782419418, + 2400033792, + 60.4, + "0x0" + ], + [ + 1782419419, + 2400037120, + 59.3, + "0x0" + ], + [ + 1782419420, + 2400027136, + 59.3, + "0x0" + ], + [ + 1782419421, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782419422, + 2400023808, + 59.3, + "0x0" + ], + [ + 1782419423, + 2400030464, + 58.7, + "0x0" + ], + [ + 1782419424, + 2400020480, + 59.8, + "0x0" + ], + [ + 1782419425, + 2400020480, + 59.3, + "0x0" + ], + [ + 1782419426, + 2400033792, + 59.3, + "0x0" + ], + [ + 1782419427, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782419428, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782419429, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782419430, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419431, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419432, + 2400037120, + 62.0, + "0x0" + ], + [ + 1782419433, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419434, + 2400017408, + 62.0, + "0x0" + ], + [ + 1782419435, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419436, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419437, + 2400033792, + 62.6, + "0x0" + ], + [ + 1782419438, + 2400017408, + 62.6, + "0x0" + ], + [ + 1782419439, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419440, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419441, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782419442, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419443, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419444, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419445, + 2400030464, + 63.1, + "0x0" + ], + [ + 1782419446, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419447, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419448, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419449, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419450, + 2400033792, + 62.6, + "0x0" + ], + [ + 1782419451, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419452, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419453, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419455, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419456, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419457, + 2400033792, + 63.1, + "0x0" + ], + [ + 1782419458, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419459, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419460, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782419461, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419462, + 2400037120, + 63.7, + "0x0" + ], + [ + 1782419463, + 2400020480, + 64.2, + "0x0" + ], + [ + 1782419464, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419465, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419466, + 2400033792, + 63.7, + "0x0" + ], + [ + 1782419467, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419468, + 2400020480, + 64.2, + "0x0" + ], + [ + 1782419469, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419470, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419471, + 2400017408, + 63.7, + "0x0" + ], + [ + 1782419472, + 2400030464, + 63.1, + "0x0" + ], + [ + 1782419473, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419474, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419475, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419476, + 2400033792, + 63.7, + "0x0" + ], + [ + 1782419477, + 2400033792, + 63.7, + "0x0" + ], + [ + 1782419478, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419479, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419480, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419481, + 2400030464, + 64.2, + "0x0" + ], + [ + 1782419482, + 2400030464, + 63.1, + "0x0" + ], + [ + 1782419483, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419484, + 2400037120, + 63.1, + "0x0" + ], + [ + 1782419485, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419486, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419487, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419488, + 2400037120, + 64.2, + "0x0" + ], + [ + 1782419489, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419490, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419491, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419492, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419493, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419494, + 2400020480, + 64.2, + "0x0" + ], + [ + 1782419495, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419496, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419497, + 2400037120, + 63.7, + "0x0" + ], + [ + 1782419498, + 2400030464, + 63.7, + "0x0" + ], + [ + 1782419500, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419501, + 2400033792, + 64.2, + "0x0" + ], + [ + 1782419502, + 2400027136, + 65.3, + "0x0" + ], + [ + 1782419503, + 2400033792, + 64.2, + "0x0" + ], + [ + 1782419504, + 2400027136, + 64.2, + "0x0" + ], + [ + 1782419505, + 2400030464, + 64.2, + "0x0" + ], + [ + 1782419506, + 2400030464, + 64.2, + "0x0" + ], + [ + 1782419507, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419508, + 2400027136, + 64.8, + "0x0" + ], + [ + 1782419509, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419510, + 2400033792, + 63.7, + "0x0" + ], + [ + 1782419511, + 2400037120, + 64.2, + "0x0" + ], + [ + 1782419512, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419513, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419514, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419515, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419516, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419517, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419518, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419519, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419520, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419521, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419522, + 2400030464, + 63.7, + "0x0" + ], + [ + 1782419523, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419524, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419525, + 2400027136, + 64.8, + "0x0" + ], + [ + 1782419526, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419527, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419528, + 2400030464, + 64.2, + "0x0" + ], + [ + 1782419529, + 2400033792, + 64.2, + "0x0" + ], + [ + 1782419530, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419531, + 2400027136, + 64.8, + "0x0" + ], + [ + 1782419532, + 2400030464, + 64.8, + "0x0" + ], + [ + 1782419533, + 2400033792, + 63.7, + "0x0" + ], + [ + 1782419534, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419535, + 2400017408, + 63.7, + "0x0" + ], + [ + 1782419536, + 2400023808, + 64.8, + "0x0" + ], + [ + 1782419537, + 2400033792, + 63.7, + "0x0" + ], + [ + 1782419538, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419539, + 2400020480, + 64.2, + "0x0" + ], + [ + 1782419540, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419541, + 2400017408, + 63.7, + "0x0" + ], + [ + 1782419542, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419543, + 2400027136, + 64.8, + "0x0" + ], + [ + 1782419544, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419545, + 2400030464, + 64.2, + "0x0" + ], + [ + 1782419546, + 2400017408, + 64.2, + "0x0" + ], + [ + 1782419547, + 2400037120, + 64.8, + "0x0" + ], + [ + 1782419549, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419550, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419551, + 2400037120, + 63.1, + "0x0" + ], + [ + 1782419552, + 2400030464, + 63.1, + "0x0" + ], + [ + 1782419553, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419554, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419555, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419556, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419557, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419558, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419559, + 2400037120, + 63.7, + "0x0" + ], + [ + 1782419560, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419561, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419562, + 2400037120, + 64.2, + "0x0" + ], + [ + 1782419563, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419564, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419565, + 2400033792, + 63.7, + "0x0" + ], + [ + 1782419566, + 2400020480, + 64.2, + "0x0" + ], + [ + 1782419567, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419568, + 2400023808, + 64.8, + "0x0" + ], + [ + 1782419569, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419570, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419571, + 2400030464, + 63.7, + "0x0" + ], + [ + 1782419572, + 2400017408, + 64.2, + "0x0" + ], + [ + 1782419573, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419574, + 2400030464, + 64.2, + "0x0" + ], + [ + 1782419575, + 2400030464, + 64.2, + "0x0" + ], + [ + 1782419576, + 2400030464, + 65.3, + "0x0" + ], + [ + 1782419577, + 2400030464, + 64.2, + "0x0" + ], + [ + 1782419578, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419579, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419580, + 2400020480, + 64.8, + "0x0" + ], + [ + 1782419581, + 2400030464, + 65.3, + "0x0" + ], + [ + 1782419582, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419583, + 2400030464, + 64.8, + "0x0" + ], + [ + 1782419584, + 2400030464, + 63.1, + "0x0" + ], + [ + 1782419585, + 2400020480, + 65.3, + "0x0" + ], + [ + 1782419586, + 2400030464, + 64.8, + "0x0" + ], + [ + 1782419587, + 2400027136, + 64.8, + "0x0" + ], + [ + 1782419588, + 2400027136, + 64.8, + "0x0" + ], + [ + 1782419589, + 2400020480, + 65.3, + "0x0" + ], + [ + 1782419590, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419591, + 2400023808, + 64.8, + "0x0" + ], + [ + 1782419592, + 2400037120, + 64.8, + "0x0" + ], + [ + 1782419593, + 2400030464, + 65.3, + "0x0" + ], + [ + 1782419594, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419595, + 2400033792, + 64.8, + "0x0" + ], + [ + 1782419596, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419597, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419599, + 2400017408, + 65.3, + "0x0" + ], + [ + 1782419600, + 2400027136, + 64.8, + "0x0" + ], + [ + 1782419601, + 2400020480, + 64.8, + "0x0" + ], + [ + 1782419602, + 2400027136, + 65.3, + "0x0" + ], + [ + 1782419603, + 2400037120, + 64.2, + "0x0" + ], + [ + 1782419604, + 2400030464, + 63.7, + "0x0" + ], + [ + 1782419605, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419606, + 2400033792, + 63.7, + "0x0" + ], + [ + 1782419607, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419608, + 2400027136, + 64.2, + "0x0" + ], + [ + 1782419609, + 2400020480, + 64.2, + "0x0" + ], + [ + 1782419610, + 2400030464, + 64.8, + "0x0" + ], + [ + 1782419611, + 2400027136, + 64.2, + "0x0" + ], + [ + 1782419612, + 2400030464, + 64.8, + "0x0" + ], + [ + 1782419613, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419614, + 2400027136, + 64.2, + "0x0" + ], + [ + 1782419615, + 2400027136, + 64.8, + "0x0" + ], + [ + 1782419616, + 2400030464, + 64.2, + "0x0" + ], + [ + 1782419617, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419618, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782419619, + 2400033792, + 62.0, + "0x0" + ], + [ + 1782419620, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419621, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419622, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782419623, + 2400017408, + 61.5, + "0x0" + ], + [ + 1782419624, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782419625, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782419626, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782419627, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782419628, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782419629, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782419630, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782419631, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782419632, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782419633, + 2400037120, + 60.9, + "0x0" + ], + [ + 1782419634, + 2400030464, + 63.1, + "0x0" + ], + [ + 1782419635, + 2400020480, + 64.2, + "0x0" + ], + [ + 1782419636, + 2400027136, + 64.8, + "0x0" + ], + [ + 1782419637, + 2400027136, + 64.8, + "0x0" + ], + [ + 1782419638, + 2400030464, + 64.2, + "0x0" + ], + [ + 1782419639, + 2400033792, + 63.7, + "0x0" + ], + [ + 1782419640, + 2400023808, + 64.2, + "0x0" + ], + [ + 1782419641, + 2400033792, + 64.2, + "0x0" + ], + [ + 1782419642, + 2400023808, + 64.8, + "0x0" + ], + [ + 1782419643, + 2400020480, + 64.2, + "0x0" + ], + [ + 1782419644, + 2400023808, + 63.7, + "0x0" + ], + [ + 1782419645, + 2400030464, + 65.3, + "0x0" + ], + [ + 1782419646, + 2400027136, + 65.3, + "0x0" + ], + [ + 1782419647, + 2400037120, + 64.8, + "0x0" + ], + [ + 1782419649, + 2400030464, + 64.8, + "0x0" + ], + [ + 1782419650, + 2400017408, + 65.3, + "0x0" + ], + [ + 1782419651, + 2400020480, + 64.8, + "0x0" + ], + [ + 1782419652, + 2400030464, + 65.3, + "0x0" + ], + [ + 1782419653, + 2400030464, + 64.8, + "0x0" + ], + [ + 1782419654, + 2400017408, + 64.2, + "0x0" + ], + [ + 1782419655, + 2400030464, + 65.3, + "0x0" + ], + [ + 1782419656, + 2400020480, + 65.3, + "0x0" + ], + [ + 1782419657, + 2400020480, + 64.8, + "0x0" + ], + [ + 1782419658, + 2400030464, + 64.8, + "0x0" + ], + [ + 1782419659, + 2400030464, + 65.9, + "0x0" + ], + [ + 1782419660, + 2400030464, + 65.9, + "0x0" + ], + [ + 1782419661, + 2400020480, + 64.8, + "0x0" + ], + [ + 1782419662, + 2400023808, + 64.8, + "0x0" + ], + [ + 1782419663, + 2400027136, + 64.8, + "0x0" + ], + [ + 1782419664, + 2400023808, + 65.3, + "0x0" + ], + [ + 1782419665, + 2400027136, + 65.3, + "0x0" + ], + [ + 1782419666, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419667, + 2400020480, + 65.9, + "0x0" + ], + [ + 1782419668, + 2400023808, + 65.3, + "0x0" + ], + [ + 1782419669, + 2400027136, + 65.3, + "0x0" + ], + [ + 1782419670, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419671, + 2400017408, + 64.2, + "0x0" + ], + [ + 1782419672, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782419673, + 2400020480, + 65.3, + "0x0" + ], + [ + 1782419674, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419675, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419676, + 2400017408, + 64.2, + "0x0" + ], + [ + 1782419677, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419678, + 2400023808, + 65.3, + "0x0" + ], + [ + 1782419679, + 2400020480, + 65.3, + "0x0" + ], + [ + 1782419680, + 2400023808, + 64.8, + "0x0" + ], + [ + 1782419681, + 2400020480, + 64.8, + "0x0" + ], + [ + 1782419682, + 2400030464, + 65.9, + "0x0" + ], + [ + 1782419683, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419684, + 2400020480, + 65.9, + "0x0" + ], + [ + 1782419685, + 2400027136, + 67.0, + "0x0" + ], + [ + 1782419686, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419687, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419688, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419689, + 2400027136, + 65.3, + "0x0" + ], + [ + 1782419691, + 2400030464, + 64.8, + "0x0" + ], + [ + 1782419692, + 2400030464, + 64.8, + "0x0" + ], + [ + 1782419693, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419694, + 2400027136, + 65.3, + "0x0" + ], + [ + 1782419695, + 2400037120, + 65.3, + "0x0" + ], + [ + 1782419696, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419697, + 2400020480, + 64.2, + "0x0" + ], + [ + 1782419698, + 2400023808, + 65.3, + "0x0" + ], + [ + 1782419699, + 2400023808, + 66.4, + "0x0" + ], + [ + 1782419700, + 2400017408, + 65.9, + "0x0" + ], + [ + 1782419701, + 2400017408, + 65.3, + "0x0" + ], + [ + 1782419702, + 2400033792, + 64.2, + "0x0" + ], + [ + 1782419703, + 2400023808, + 65.3, + "0x0" + ], + [ + 1782419704, + 2400037120, + 65.9, + "0x0" + ], + [ + 1782419705, + 2400023808, + 66.4, + "0x0" + ], + [ + 1782419706, + 2400030464, + 65.3, + "0x0" + ], + [ + 1782419707, + 2400023808, + 66.4, + "0x0" + ], + [ + 1782419708, + 2400023808, + 66.4, + "0x0" + ], + [ + 1782419709, + 2400023808, + 65.3, + "0x0" + ], + [ + 1782419710, + 2400033792, + 65.3, + "0x0" + ], + [ + 1782419711, + 2400020480, + 65.9, + "0x0" + ], + [ + 1782419712, + 2400020480, + 65.9, + "0x0" + ], + [ + 1782419713, + 2400033792, + 67.0, + "0x0" + ], + [ + 1782419714, + 2400020480, + 65.9, + "0x0" + ], + [ + 1782419715, + 2400033792, + 65.9, + "0x0" + ], + [ + 1782419716, + 2400030464, + 65.3, + "0x0" + ], + [ + 1782419717, + 2400023808, + 64.8, + "0x0" + ], + [ + 1782419718, + 2400027136, + 66.4, + "0x0" + ], + [ + 1782419719, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419720, + 2400027136, + 65.3, + "0x0" + ], + [ + 1782419721, + 2400030464, + 66.4, + "0x0" + ], + [ + 1782419722, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419723, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419724, + 2400030464, + 65.9, + "0x0" + ], + [ + 1782419725, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419726, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419727, + 2400030464, + 65.9, + "0x0" + ], + [ + 1782419728, + 2400033792, + 65.9, + "0x0" + ], + [ + 1782419729, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419730, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419731, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419732, + 2400020480, + 65.9, + "0x0" + ], + [ + 1782419734, + 2400037120, + 66.4, + "0x0" + ], + [ + 1782419735, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419736, + 2400030464, + 64.8, + "0x0" + ], + [ + 1782419737, + 2400023808, + 65.3, + "0x0" + ], + [ + 1782419738, + 2400033792, + 65.9, + "0x0" + ], + [ + 1782419739, + 2400027136, + 65.3, + "0x0" + ], + [ + 1782419740, + 2400030464, + 65.9, + "0x0" + ], + [ + 1782419741, + 2400020480, + 65.9, + "0x0" + ], + [ + 1782419742, + 2400020480, + 64.2, + "0x0" + ], + [ + 1782419743, + 2400037120, + 65.3, + "0x0" + ], + [ + 1782419744, + 2400030464, + 65.9, + "0x0" + ], + [ + 1782419745, + 2400033792, + 65.3, + "0x0" + ], + [ + 1782419746, + 2400037120, + 65.3, + "0x0" + ], + [ + 1782419747, + 2400027136, + 66.4, + "0x0" + ], + [ + 1782419748, + 2400020480, + 65.3, + "0x0" + ], + [ + 1782419749, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419750, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419751, + 2400017408, + 65.9, + "0x0" + ], + [ + 1782419752, + 2400030464, + 66.4, + "0x0" + ], + [ + 1782419753, + 2400020480, + 65.3, + "0x0" + ], + [ + 1782419754, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419755, + 2400030464, + 67.0, + "0x0" + ], + [ + 1782419756, + 2400033792, + 66.4, + "0x0" + ], + [ + 1782419757, + 2400023808, + 67.0, + "0x0" + ], + [ + 1782419758, + 2400033792, + 65.9, + "0x0" + ], + [ + 1782419759, + 2400017408, + 66.4, + "0x0" + ], + [ + 1782419760, + 2400037120, + 66.4, + "0x0" + ], + [ + 1782419761, + 2400027136, + 66.4, + "0x0" + ], + [ + 1782419762, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419763, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419764, + 2400020480, + 65.3, + "0x0" + ], + [ + 1782419765, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419766, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419767, + 2400030464, + 65.9, + "0x0" + ], + [ + 1782419768, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419769, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419770, + 2400023808, + 66.4, + "0x0" + ], + [ + 1782419771, + 2400017408, + 65.3, + "0x0" + ], + [ + 1782419772, + 2400027136, + 66.4, + "0x0" + ], + [ + 1782419773, + 2400023808, + 66.4, + "0x0" + ], + [ + 1782419774, + 2400020480, + 67.5, + "0x0" + ], + [ + 1782419775, + 2400020480, + 65.3, + "0x0" + ], + [ + 1782419777, + 2400030464, + 64.8, + "0x0" + ], + [ + 1782419778, + 2400033792, + 66.4, + "0x0" + ], + [ + 1782419779, + 2400027136, + 66.4, + "0x0" + ], + [ + 1782419780, + 2400037120, + 65.3, + "0x0" + ], + [ + 1782419781, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419782, + 2400023808, + 67.0, + "0x0" + ], + [ + 1782419783, + 2400023808, + 67.0, + "0x0" + ], + [ + 1782419784, + 2400027136, + 66.4, + "0x0" + ], + [ + 1782419785, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419786, + 2400033792, + 66.4, + "0x0" + ], + [ + 1782419787, + 2400023808, + 67.0, + "0x0" + ], + [ + 1782419788, + 2400020480, + 64.8, + "0x0" + ], + [ + 1782419789, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419790, + 2400027136, + 66.4, + "0x0" + ], + [ + 1782419791, + 2400027136, + 67.0, + "0x0" + ], + [ + 1782419792, + 2400020480, + 67.0, + "0x0" + ], + [ + 1782419793, + 2400033792, + 67.0, + "0x0" + ], + [ + 1782419794, + 2400027136, + 67.0, + "0x0" + ], + [ + 1782419795, + 2400030464, + 67.0, + "0x0" + ], + [ + 1782419796, + 2400023808, + 67.0, + "0x0" + ], + [ + 1782419797, + 2400030464, + 65.9, + "0x0" + ], + [ + 1782419798, + 2400030464, + 66.4, + "0x0" + ], + [ + 1782419799, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419800, + 2400027136, + 65.9, + "0x0" + ], + [ + 1782419801, + 2400033792, + 64.8, + "0x0" + ], + [ + 1782419802, + 2400037120, + 66.4, + "0x0" + ], + [ + 1782419803, + 2400030464, + 66.4, + "0x0" + ], + [ + 1782419804, + 2400033792, + 66.4, + "0x0" + ], + [ + 1782419805, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419806, + 2400027136, + 66.4, + "0x0" + ], + [ + 1782419807, + 2400030464, + 66.4, + "0x0" + ], + [ + 1782419808, + 2400023808, + 67.0, + "0x0" + ], + [ + 1782419809, + 2400023808, + 66.4, + "0x0" + ], + [ + 1782419810, + 2400030464, + 66.4, + "0x0" + ], + [ + 1782419811, + 2400030464, + 66.4, + "0x0" + ], + [ + 1782419812, + 2400030464, + 67.0, + "0x0" + ], + [ + 1782419813, + 2400020480, + 67.0, + "0x0" + ], + [ + 1782419814, + 2400033792, + 65.3, + "0x0" + ], + [ + 1782419815, + 2400017408, + 66.4, + "0x0" + ], + [ + 1782419816, + 2400023808, + 67.0, + "0x0" + ], + [ + 1782419817, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419819, + 2400020480, + 67.0, + "0x0" + ], + [ + 1782419820, + 2400023808, + 67.0, + "0x0" + ], + [ + 1782419821, + 2400020480, + 68.1, + "0x0" + ], + [ + 1782419822, + 2400020480, + 67.0, + "0x0" + ], + [ + 1782419823, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419824, + 2400023808, + 67.5, + "0x0" + ], + [ + 1782419825, + 2400030464, + 67.5, + "0x0" + ], + [ + 1782419826, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419827, + 2400027136, + 66.4, + "0x0" + ], + [ + 1782419828, + 2400037120, + 66.4, + "0x0" + ], + [ + 1782419829, + 2400033792, + 65.9, + "0x0" + ], + [ + 1782419830, + 2400027136, + 66.4, + "0x0" + ], + [ + 1782419831, + 2400030464, + 67.5, + "0x0" + ], + [ + 1782419832, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419833, + 2400020480, + 67.5, + "0x0" + ], + [ + 1782419834, + 2400033792, + 65.9, + "0x0" + ], + [ + 1782419835, + 2400030464, + 66.4, + "0x0" + ], + [ + 1782419836, + 2400027136, + 67.0, + "0x0" + ], + [ + 1782419837, + 2400027136, + 67.0, + "0x0" + ], + [ + 1782419838, + 2400027136, + 67.0, + "0x0" + ], + [ + 1782419839, + 2400023808, + 67.5, + "0x0" + ], + [ + 1782419840, + 2400033792, + 66.4, + "0x0" + ], + [ + 1782419841, + 2400027136, + 67.0, + "0x0" + ], + [ + 1782419842, + 2400030464, + 65.9, + "0x0" + ], + [ + 1782419843, + 2400017408, + 66.4, + "0x0" + ], + [ + 1782419844, + 2400027136, + 66.4, + "0x0" + ], + [ + 1782419845, + 2400023808, + 65.9, + "0x0" + ], + [ + 1782419846, + 2400020480, + 66.4, + "0x0" + ], + [ + 1782419847, + 2400033792, + 65.9, + "0x0" + ], + [ + 1782419848, + 2400027136, + 66.4, + "0x0" + ], + [ + 1782419849, + 2400027136, + 64.2, + "0x0" + ], + [ + 1782419850, + 2400030464, + 63.7, + "0x0" + ], + [ + 1782419851, + 2400017408, + 63.1, + "0x0" + ], + [ + 1782419852, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419853, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419854, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419855, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419856, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419857, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419858, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419859, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782419860, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419861, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419862, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419863, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419864, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419865, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419866, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419868, + 2400017408, + 61.5, + "0x0" + ], + [ + 1782419869, + 2400033792, + 62.0, + "0x0" + ], + [ + 1782419870, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782419871, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419872, + 2400033792, + 62.6, + "0x0" + ], + [ + 1782419873, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419874, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419875, + 2400033792, + 62.6, + "0x0" + ], + [ + 1782419876, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419877, + 2400030464, + 63.7, + "0x0" + ], + [ + 1782419878, + 2400017408, + 63.1, + "0x0" + ], + [ + 1782419879, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419880, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419881, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419882, + 2400020480, + 63.7, + "0x0" + ], + [ + 1782419883, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419884, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419885, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419886, + 2400033792, + 63.1, + "0x0" + ], + [ + 1782419887, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419888, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419889, + 2400033792, + 63.1, + "0x0" + ], + [ + 1782419890, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419891, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419892, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419893, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419894, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419895, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419896, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419897, + 2400030464, + 64.2, + "0x0" + ], + [ + 1782419898, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419899, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419900, + 2400033792, + 63.1, + "0x0" + ], + [ + 1782419901, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419902, + 2400017408, + 63.1, + "0x0" + ], + [ + 1782419903, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419904, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419905, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419906, + 2400017408, + 62.6, + "0x0" + ], + [ + 1782419907, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419908, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419909, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419910, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419911, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782419912, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782419913, + 2400037120, + 62.6, + "0x0" + ], + [ + 1782419914, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782419915, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419916, + 2400033792, + 62.0, + "0x0" + ], + [ + 1782419917, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419918, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419919, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782419920, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782419921, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419923, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419924, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419925, + 2400033792, + 62.6, + "0x0" + ], + [ + 1782419926, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782419927, + 2400017408, + 62.6, + "0x0" + ], + [ + 1782419928, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419929, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419930, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419931, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419932, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419933, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419934, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419935, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419936, + 2400033792, + 62.6, + "0x0" + ], + [ + 1782419937, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419938, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419939, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419940, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419941, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419942, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419943, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419944, + 2400037120, + 63.7, + "0x0" + ], + [ + 1782419945, + 2400030464, + 63.1, + "0x0" + ], + [ + 1782419946, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419947, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419948, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419949, + 2400033792, + 62.6, + "0x0" + ], + [ + 1782419950, + 2400037120, + 62.6, + "0x0" + ], + [ + 1782419951, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419952, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419953, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419954, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419955, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419956, + 2400037120, + 62.0, + "0x0" + ], + [ + 1782419957, + 2400033792, + 62.6, + "0x0" + ], + [ + 1782419958, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419959, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782419960, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419961, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782419962, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782419963, + 2400037120, + 62.6, + "0x0" + ], + [ + 1782419964, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419965, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419966, + 2400023808, + 63.1, + "0x0" + ], + [ + 1782419967, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419968, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782419969, + 2400020480, + 63.1, + "0x0" + ], + [ + 1782419970, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782419971, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419972, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419973, + 2400033792, + 62.0, + "0x0" + ], + [ + 1782419974, + 2400027136, + 63.1, + "0x0" + ], + [ + 1782419975, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419977, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782419978, + 2400033792, + 62.0, + "0x0" + ], + [ + 1782419979, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419980, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419981, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419982, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782419983, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419984, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419985, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782419986, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419987, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419988, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419989, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782419990, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782419991, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782419992, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419993, + 2400037120, + 62.0, + "0x0" + ], + [ + 1782419994, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782419995, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419996, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782419997, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782419998, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782419999, + 2400037120, + 62.0, + "0x0" + ], + [ + 1782420000, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782420001, + 2400017408, + 62.0, + "0x0" + ], + [ + 1782420002, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782420003, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420004, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782420005, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420006, + 2400033792, + 61.5, + "0x0" + ], + [ + 1782420007, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782420008, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782420009, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782420010, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782420011, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420012, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782420013, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420014, + 2400033792, + 62.0, + "0x0" + ], + [ + 1782420015, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782420016, + 2400017408, + 62.0, + "0x0" + ], + [ + 1782420017, + 2400027136, + 63.7, + "0x0" + ], + [ + 1782420018, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420019, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782420020, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782420021, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420022, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782420023, + 2400017408, + 62.0, + "0x0" + ], + [ + 1782420024, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420025, + 2400023808, + 62.6, + "0x0" + ], + [ + 1782420026, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782420027, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782420028, + 2400017408, + 62.6, + "0x0" + ], + [ + 1782420029, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782420031, + 2400027136, + 62.6, + "0x0" + ], + [ + 1782420032, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782420033, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782420034, + 2400020480, + 62.6, + "0x0" + ], + [ + 1782420035, + 2400037120, + 62.0, + "0x0" + ], + [ + 1782420036, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420037, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782420038, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420039, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420040, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782420041, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420042, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420043, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420044, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420045, + 2400033792, + 61.5, + "0x0" + ], + [ + 1782420046, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420047, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420048, + 2400030464, + 62.6, + "0x0" + ], + [ + 1782420049, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420050, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420051, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420052, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420053, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420054, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420055, + 2400033792, + 62.0, + "0x0" + ], + [ + 1782420056, + 2400017408, + 60.9, + "0x0" + ], + [ + 1782420057, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420058, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420059, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420060, + 2400033792, + 61.5, + "0x0" + ], + [ + 1782420061, + 2400017408, + 61.5, + "0x0" + ], + [ + 1782420062, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782420063, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420064, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782420065, + 2400033792, + 60.4, + "0x0" + ], + [ + 1782420066, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782420067, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420068, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782420069, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420070, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782420071, + 2400030464, + 59.8, + "0x0" + ], + [ + 1782420072, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782420073, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782420074, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420075, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782420076, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420077, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420078, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420079, + 2400033792, + 61.5, + "0x0" + ], + [ + 1782420080, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420081, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420082, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420083, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420084, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782420086, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420087, + 2400017408, + 62.0, + "0x0" + ], + [ + 1782420088, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420089, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420090, + 2400027136, + 62.0, + "0x0" + ], + [ + 1782420091, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420092, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420093, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782420094, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420095, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420096, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420097, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420098, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782420099, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782420100, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420101, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420102, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782420103, + 2400033792, + 59.8, + "0x0" + ], + [ + 1782420104, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420105, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420106, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420107, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420108, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420109, + 2400017408, + 60.4, + "0x0" + ], + [ + 1782420110, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782420111, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420112, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420113, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420114, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420115, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420116, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420117, + 2400017408, + 61.5, + "0x0" + ], + [ + 1782420118, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782420119, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420120, + 2400030464, + 59.8, + "0x0" + ], + [ + 1782420121, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420122, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420123, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420124, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420125, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420126, + 2400037120, + 60.9, + "0x0" + ], + [ + 1782420127, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420128, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420129, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420130, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420131, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420132, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420134, + 2400017408, + 60.9, + "0x0" + ], + [ + 1782420135, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420136, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782420137, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420138, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420139, + 2400030464, + 62.0, + "0x0" + ], + [ + 1782420140, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420141, + 2400037120, + 62.0, + "0x0" + ], + [ + 1782420142, + 2400037120, + 60.9, + "0x0" + ], + [ + 1782420143, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782420144, + 2400037120, + 60.9, + "0x0" + ], + [ + 1782420145, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420146, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420147, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420148, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782420149, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420150, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420151, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420152, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420153, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420154, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420155, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420156, + 2400037120, + 60.9, + "0x0" + ], + [ + 1782420157, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420158, + 2400017408, + 60.4, + "0x0" + ], + [ + 1782420159, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420160, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420161, + 2400030464, + 60.4, + "0x0" + ], + [ + 1782420162, + 2400030464, + 59.8, + "0x0" + ], + [ + 1782420163, + 2400023808, + 59.8, + "0x0" + ], + [ + 1782420164, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420165, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420166, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420167, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782420168, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420169, + 2400017408, + 60.9, + "0x0" + ], + [ + 1782420170, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420171, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420172, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420173, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420174, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420175, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420176, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420177, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420178, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420179, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782420180, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420181, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420182, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420183, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420184, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420185, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420187, + 2400030464, + 60.4, + "0x0" + ], + [ + 1782420188, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420189, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782420190, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420191, + 2400017408, + 60.9, + "0x0" + ], + [ + 1782420192, + 2400017408, + 60.9, + "0x0" + ], + [ + 1782420193, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420194, + 2400033792, + 61.5, + "0x0" + ], + [ + 1782420195, + 2400033792, + 60.4, + "0x0" + ], + [ + 1782420196, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420197, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420198, + 2400017408, + 61.5, + "0x0" + ], + [ + 1782420199, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782420200, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420201, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420202, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420203, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782420204, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420205, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420206, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420207, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420208, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420209, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420210, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420211, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420212, + 2400033792, + 61.5, + "0x0" + ], + [ + 1782420213, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420214, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420215, + 2400030464, + 60.4, + "0x0" + ], + [ + 1782420216, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420217, + 2400033792, + 60.4, + "0x0" + ], + [ + 1782420218, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420219, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420220, + 2400033792, + 60.4, + "0x0" + ], + [ + 1782420221, + 2400023808, + 59.8, + "0x0" + ], + [ + 1782420222, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420223, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420224, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420225, + 2400030464, + 60.4, + "0x0" + ], + [ + 1782420226, + 2400030464, + 60.4, + "0x0" + ], + [ + 1782420227, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420228, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420229, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420230, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420231, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420232, + 2400017408, + 61.5, + "0x0" + ], + [ + 1782420233, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420234, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420235, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420236, + 2400027136, + 59.8, + "0x0" + ], + [ + 1782420237, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420238, + 2400037120, + 60.9, + "0x0" + ], + [ + 1782420240, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420241, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420242, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420243, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420244, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420245, + 2400037120, + 61.5, + "0x0" + ], + [ + 1782420246, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420247, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420248, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420249, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420250, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420251, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420252, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420253, + 2400017408, + 61.5, + "0x0" + ], + [ + 1782420254, + 2400023808, + 62.0, + "0x0" + ], + [ + 1782420255, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420256, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420257, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420258, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420259, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420260, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420261, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420262, + 2400020480, + 62.0, + "0x0" + ], + [ + 1782420263, + 2400017408, + 60.9, + "0x0" + ], + [ + 1782420264, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420265, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420266, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420267, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420268, + 2400037120, + 60.9, + "0x0" + ], + [ + 1782420269, + 2400017408, + 60.9, + "0x0" + ], + [ + 1782420270, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420271, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420272, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420273, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420274, + 2400023808, + 59.8, + "0x0" + ], + [ + 1782420275, + 2400037120, + 60.4, + "0x0" + ], + [ + 1782420276, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420277, + 2400017408, + 60.4, + "0x0" + ], + [ + 1782420278, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782420279, + 2400037120, + 59.8, + "0x0" + ], + [ + 1782420280, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420281, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420282, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420283, + 2400033792, + 60.4, + "0x0" + ], + [ + 1782420284, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420285, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420286, + 2400017408, + 61.5, + "0x0" + ], + [ + 1782420287, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420288, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420289, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420290, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420291, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420292, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420294, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420295, + 2400037120, + 60.9, + "0x0" + ], + [ + 1782420296, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420297, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420298, + 2400017408, + 59.8, + "0x0" + ], + [ + 1782420299, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420300, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420301, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420302, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420303, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420304, + 2400023808, + 59.8, + "0x0" + ], + [ + 1782420305, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420306, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420307, + 2400033792, + 60.4, + "0x0" + ], + [ + 1782420308, + 2400033792, + 59.8, + "0x0" + ], + [ + 1782420309, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420310, + 2400023808, + 61.5, + "0x0" + ], + [ + 1782420311, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420312, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420313, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420314, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420315, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420316, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420317, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782420318, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420319, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420320, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420321, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420322, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420323, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420324, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420325, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420326, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420327, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420328, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420329, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420330, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420331, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420332, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420333, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420334, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420335, + 2400030464, + 59.8, + "0x0" + ], + [ + 1782420336, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420337, + 2400023808, + 59.8, + "0x0" + ], + [ + 1782420338, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782420339, + 2400030464, + 59.8, + "0x0" + ], + [ + 1782420340, + 2400027136, + 59.3, + "0x0" + ], + [ + 1782420342, + 2400017408, + 59.8, + "0x0" + ], + [ + 1782420343, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782420344, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420345, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420346, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420347, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420348, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420349, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420350, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782420351, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420352, + 2400027136, + 60.4, + "0x0" + ], + [ + 1782420353, + 2400020480, + 60.4, + "0x0" + ], + [ + 1782420354, + 2400033792, + 60.9, + "0x0" + ], + [ + 1782420355, + 2400037120, + 60.9, + "0x0" + ], + [ + 1782420356, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420357, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420358, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420359, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420360, + 2400030464, + 61.5, + "0x0" + ], + [ + 1782420361, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420362, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420363, + 2400037120, + 60.9, + "0x0" + ], + [ + 1782420364, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420365, + 2400023808, + 60.4, + "0x0" + ], + [ + 1782420366, + 2400037120, + 60.9, + "0x0" + ], + [ + 1782420367, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420368, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420369, + 2400020480, + 59.3, + "0x0" + ], + [ + 1782420370, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420371, + 2400030464, + 60.4, + "0x0" + ], + [ + 1782420372, + 2400037120, + 60.9, + "0x0" + ], + [ + 1782420373, + 2400020480, + 61.5, + "0x0" + ], + [ + 1782420374, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420375, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420376, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420377, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420378, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420379, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420380, + 2400017408, + 61.5, + "0x0" + ], + [ + 1782420381, + 2400027136, + 61.5, + "0x0" + ], + [ + 1782420382, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420383, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420384, + 2400030464, + 60.9, + "0x0" + ], + [ + 1782420385, + 2400020480, + 60.9, + "0x0" + ], + [ + 1782420386, + 2400027136, + 60.9, + "0x0" + ], + [ + 1782420387, + 2400023808, + 60.9, + "0x0" + ], + [ + 1782420388, + 2400017408, + 60.9, + "0x0" + ] + ], + "temp_c": { + "min": 49.9, + "max": 68.1, + "mean": 61.914, + "samples": 1326 + }, + "arm_clock_hz": { + "min": 2400017408, + "max": 2400037120, + "mean": 2400026263.94, + "samples": 1326, + "spread_frac": 0.0 + }, + "throttling_detected": false + }, + "warnings": [], + "kem": [ + { + "alg": "X25519", + "kind": "kem", + "backend": "openssl", + "classical": true, + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 32, + "secret_key": 32, + "ciphertext": null, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 875, + "timed_iters": 4374, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 57154.98, + "samples": 21870, + "median": 56907.0, + "mad": 37.0, + "iqr": 111.0, + "q1": 56870.0, + "q3": 56981.0, + "min": 56777.0, + "max": 114870.0, + "mean": 57050.76, + "stddev": 986.98, + "ops_per_sec": 17572.53, + "per_rep_median": [ + 56907.0, + 56889.0, + 56907.0, + 56889.0, + 56945.0 + ] + }, + "derive": { + "unit": "ns", + "warmup_iters": 302, + "timed_iters": 1509, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 165680.19, + "samples": 7545, + "median": 165610.0, + "mad": 167.0, + "iqr": 352.0, + "q1": 165444.0, + "q3": 165796.0, + "min": 164703.0, + "max": 194906.0, + "mean": 165761.44, + "stddev": 969.55, + "ops_per_sec": 6038.28, + "per_rep_median": [ + 165610.0, + 165592.0, + 165443.0, + 165629.0, + 165647.0 + ] + } + } + }, + { + "alg": "ML-KEM-512", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 800, + "secret_key": 1632, + "ciphertext": 768, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 2719, + "timed_iters": 13593, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 18391.76, + "samples": 67965, + "median": 18278.0, + "mad": 19.0, + "iqr": 38.0, + "q1": 18259.0, + "q3": 18297.0, + "min": 18185.0, + "max": 51666.0, + "mean": 18383.26, + "stddev": 593.56, + "ops_per_sec": 54710.58, + "per_rep_median": [ + 18278.0, + 18277.0, + 18278.0, + 18277.0, + 18296.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 2426, + "timed_iters": 12128, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 20613.95, + "samples": 60640, + "median": 20611.0, + "mad": 18.0, + "iqr": 37.0, + "q1": 20593.0, + "q3": 20630.0, + "min": 20519.0, + "max": 66314.0, + "mean": 20694.34, + "stddev": 836.34, + "ops_per_sec": 48517.78, + "per_rep_median": [ + 20629.0, + 20593.0, + 20611.0, + 20611.0, + 20611.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 2091, + "timed_iters": 10454, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 23915.12, + "samples": 52270, + "median": 23926.0, + "mad": 19.0, + "iqr": 37.0, + "q1": 23907.0, + "q3": 23944.0, + "min": 23851.0, + "max": 54963.0, + "mean": 23951.23, + "stddev": 395.66, + "ops_per_sec": 41795.54, + "per_rep_median": [ + 23926.0, + 23926.0, + 23926.0, + 23925.0, + 23926.0 + ] + } + } + }, + { + "alg": "ML-KEM-768", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 3, + "sizes": { + "public_key": 1184, + "secret_key": 2400, + "ciphertext": 1088, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1662, + "timed_iters": 8309, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 30086.88, + "samples": 41545, + "median": 29852.0, + "mad": 36.0, + "iqr": 56.0, + "q1": 29833.0, + "q3": 29889.0, + "min": 29722.0, + "max": 62166.0, + "mean": 30050.62, + "stddev": 849.83, + "ops_per_sec": 33498.59, + "per_rep_median": [ + 29852.0, + 29851.0, + 29852.0, + 29852.0, + 29834.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 1562, + "timed_iters": 7811, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 32007.82, + "samples": 39055, + "median": 31981.0, + "mad": 19.0, + "iqr": 37.0, + "q1": 31963.0, + "q3": 32000.0, + "min": 31870.0, + "max": 70092.0, + "mean": 32074.93, + "stddev": 792.16, + "ops_per_sec": 31268.57, + "per_rep_median": [ + 31981.0, + 31982.0, + 31982.0, + 31981.0, + 31981.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 1336, + "timed_iters": 6680, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 37422.65, + "samples": 33400, + "median": 37352.0, + "mad": 19.0, + "iqr": 56.0, + "q1": 37333.0, + "q3": 37389.0, + "min": 37240.0, + "max": 82833.0, + "mean": 37419.54, + "stddev": 720.66, + "ops_per_sec": 26772.33, + "per_rep_median": [ + 37370.0, + 37352.0, + 37352.0, + 37370.0, + 37352.0 + ] + } + } + }, + { + "alg": "ML-KEM-1024", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 1568, + "secret_key": 3168, + "ciphertext": 1568, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1123, + "timed_iters": 5613, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 44537.27, + "samples": 28065, + "median": 44074.0, + "mad": 37.0, + "iqr": 92.0, + "q1": 44037.0, + "q3": 44129.0, + "min": 43907.0, + "max": 77111.0, + "mean": 44415.98, + "stddev": 1057.79, + "ops_per_sec": 22689.11, + "per_rep_median": [ + 44074.0, + 44074.0, + 44074.0, + 44074.0, + 44074.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 1046, + "timed_iters": 5230, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 47800.1, + "samples": 26150, + "median": 47703.0, + "mad": 19.0, + "iqr": 55.0, + "q1": 47667.0, + "q3": 47722.0, + "min": 47573.0, + "max": 88684.0, + "mean": 47838.4, + "stddev": 1026.98, + "ops_per_sec": 20963.04, + "per_rep_median": [ + 47703.0, + 47685.0, + 47703.0, + 47703.0, + 47703.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 903, + "timed_iters": 4513, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 55401.08, + "samples": 22565, + "median": 55370.0, + "mad": 37.0, + "iqr": 56.0, + "q1": 55333.0, + "q3": 55389.0, + "min": 55240.0, + "max": 105111.0, + "mean": 55470.25, + "stddev": 973.64, + "ops_per_sec": 18060.32, + "per_rep_median": [ + 55370.0, + 55370.0, + 55370.0, + 55352.0, + 55370.0 + ] + } + } + }, + { + "alg": "X25519MLKEM768", + "kind": "kem", + "backend": "liboqs", + "enabled": false, + "reason": "not enabled in this liboqs build" + }, + { + "alg": "SecP256r1MLKEM768", + "kind": "kem", + "backend": "liboqs", + "enabled": false, + "reason": "not enabled in this liboqs build" + }, + { + "alg": "Classic-McEliece-348864", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 261120, + "secret_key": 6492, + "ciphertext": 96, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 149749809.0, + "samples": 150, + "median": 149235702.5, + "mad": 70675909.5, + "iqr": 141485404.0, + "q1": 78576727.5, + "q3": 220062131.5, + "min": 78418431.0, + "max": 646083950.0, + "mean": 163473782.95, + "stddev": 99898990.43, + "ops_per_sec": 6.7, + "per_rep_median": [ + 131725594.5, + 149755504.5, + 113948890.5, + 149276463.5, + 113966602.5 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 714, + "timed_iters": 3569, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 70051.26, + "samples": 17845, + "median": 65833.0, + "mad": 352.0, + "iqr": 5667.0, + "q1": 65648.0, + "q3": 71315.0, + "min": 65333.0, + "max": 126869.0, + "mean": 70106.09, + "stddev": 6651.05, + "ops_per_sec": 15189.95, + "per_rep_median": [ + 65833.0, + 65870.0, + 65815.0, + 65703.0, + 65833.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 2, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 25717655.67, + "samples": 150, + "median": 25696957.5, + "mad": 3416.5, + "iqr": 8458.25, + "q1": 25694314.25, + "q3": 25702772.5, + "min": 25688883.0, + "max": 25770050.0, + "mean": 25702188.51, + "stddev": 14293.3, + "ops_per_sec": 38.92, + "per_rep_median": [ + 25695190.0, + 25696902.0, + 25696319.0, + 25699318.5, + 25696790.5 + ] + } + } + }, + { + "alg": "Classic-McEliece-460896", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 3, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 345101192.0, + "samples": 150, + "median": 344270731.0, + "mad": 112890557.0, + "iqr": 447106044.25, + "q1": 232004846.5, + "q3": 679110890.75, + "min": 231301254.0, + "max": 1794926449.0, + "mean": 531179584.93, + "stddev": 355212346.2, + "ops_per_sec": 2.9, + "per_rep_median": [ + 518653138.5, + 342885442.5, + 344045984.0, + 399572191.5, + 343019984.5 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 357, + "timed_iters": 1787, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 139870.76, + "samples": 8935, + "median": 130573.0, + "mad": 11111.0, + "iqr": 24999.5, + "q1": 119611.0, + "q3": 144610.5, + "min": 118296.0, + "max": 330201.0, + "mean": 138390.09, + "stddev": 24092.04, + "ops_per_sec": 7658.55, + "per_rep_median": [ + 130665.0, + 130499.0, + 130406.0, + 130740.0, + 130388.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 58247783.0, + "samples": 150, + "median": 58731815.0, + "mad": 198230.0, + "iqr": 391173.5, + "q1": 58529423.0, + "q3": 58920596.5, + "min": 58064673.0, + "max": 59455662.0, + "mean": 58726895.85, + "stddev": 301818.0, + "ops_per_sec": 17.03, + "per_rep_median": [ + 58724039.0, + 58639576.0, + 58763064.5, + 58757629.0, + 58606277.0 + ] + } + } + }, + { + "alg": "Classic-McEliece-460896f", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 3, + "sizes": { + "public_key": 524160, + "secret_key": 13608, + "ciphertext": 156, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 229384031.0, + "samples": 150, + "median": 229025837.5, + "mad": 231686.0, + "iqr": 537439.0, + "q1": 228843061.25, + "q3": 229380500.25, + "min": 228593097.0, + "max": 243918160.0, + "mean": 229294858.13, + "stddev": 1310206.78, + "ops_per_sec": 4.37, + "per_rep_median": [ + 228960213.0, + 228953276.0, + 228891952.0, + 229167594.0, + 229274284.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 359, + "timed_iters": 1794, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 139386.4, + "samples": 8970, + "median": 130555.0, + "mad": 11130.0, + "iqr": 32388.0, + "q1": 119518.0, + "q3": 151906.0, + "min": 118666.0, + "max": 440590.0, + "mean": 138896.43, + "stddev": 24620.96, + "ops_per_sec": 7659.61, + "per_rep_median": [ + 130591.5, + 130555.0, + 130518.0, + 130573.0, + 130545.5 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 58761355.0, + "samples": 150, + "median": 58675112.0, + "mad": 107547.0, + "iqr": 436073.0, + "q1": 58314559.5, + "q3": 58750632.5, + "min": 58208284.0, + "max": 61217689.0, + "mean": 58579718.35, + "stddev": 306995.23, + "ops_per_sec": 17.04, + "per_rep_median": [ + 58746929.0, + 58745095.0, + 58323106.5, + 58688483.5, + 58567428.0 + ] + } + } + }, + { + "alg": "Classic-McEliece-6688128", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 1044992, + "secret_key": 13932, + "ciphertext": 208, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 709136679.0, + "samples": 150, + "median": 711956854.0, + "mad": 297199934.0, + "iqr": 1178005657.5, + "q1": 416856208.5, + "q3": 1594861866.0, + "min": 414436967.0, + "max": 6024257606.0, + "mean": 1134308027.63, + "stddev": 860148030.94, + "ops_per_sec": 1.4, + "per_rep_median": [ + 712262148.0, + 1007454407.5, + 711790374.0, + 712104610.0, + 710965429.5 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 198, + "timed_iters": 991, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 252341.99, + "samples": 4955, + "median": 230702.0, + "mad": 22741.0, + "iqr": 67426.0, + "q1": 208331.0, + "q3": 275757.0, + "min": 207368.0, + "max": 686420.0, + "mean": 249568.48, + "stddev": 49646.61, + "ops_per_sec": 4334.6, + "per_rep_median": [ + 228702.0, + 237813.0, + 228147.0, + 228054.0, + 241813.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 114132605.0, + "samples": 150, + "median": 112689252.5, + "mad": 305340.0, + "iqr": 570195.0, + "q1": 112375156.75, + "q3": 112945351.75, + "min": 111602532.0, + "max": 114134190.0, + "mean": 112739428.27, + "stddev": 597991.9, + "ops_per_sec": 8.87, + "per_rep_median": [ + 112534451.5, + 112681485.5, + 112840362.5, + 112685945.5, + 112690480.5 + ] + } + } + }, + { + "alg": "Classic-McEliece-6960119", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 1047319, + "secret_key": 13948, + "ciphertext": 194, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1019779332.0, + "samples": 150, + "median": 867865263.0, + "mad": 448701486.5, + "iqr": 1194514298.25, + "q1": 421011370.25, + "q3": 1615525668.5, + "min": 418071136.0, + "max": 4310940622.0, + "mean": 1197770820.8, + "stddev": 866967412.04, + "ops_per_sec": 1.15, + "per_rep_median": [ + 1017120768.0, + 867865263.0, + 719231858.5, + 1017248809.0, + 717776590.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 135, + "timed_iters": 677, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 369297.24, + "samples": 3385, + "median": 357089.0, + "mad": 15277.0, + "iqr": 44463.0, + "q1": 342071.0, + "q3": 386534.0, + "min": 340682.0, + "max": 655013.0, + "mean": 370458.07, + "stddev": 34150.91, + "ops_per_sec": 2800.42, + "per_rep_median": [ + 356775.0, + 357719.0, + 357311.0, + 357145.0, + 357108.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 109830802.0, + "samples": 150, + "median": 109112241.5, + "mad": 298757.5, + "iqr": 745878.75, + "q1": 108492816.25, + "q3": 109238695.0, + "min": 107746815.0, + "max": 110387279.0, + "mean": 108956810.23, + "stddev": 630895.56, + "ops_per_sec": 9.16, + "per_rep_median": [ + 109149317.5, + 109134492.5, + 108485599.0, + 109193333.0, + 108859186.0 + ] + } + } + }, + { + "alg": "Classic-McEliece-8192128", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 1357824, + "secret_key": 14120, + "ciphertext": 208, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1762833605.0, + "samples": 150, + "median": 1106148730.5, + "mad": 654945765.5, + "iqr": 1233033015.0, + "q1": 532867286.0, + "q3": 1765900301.0, + "min": 447539262.0, + "max": 5417925327.0, + "mean": 1320995240.49, + "stddev": 904925749.54, + "ops_per_sec": 0.9, + "per_rep_median": [ + 1437115641.0, + 1106486809.0, + 943001498.0, + 778945595.5, + 778502861.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 184, + "timed_iters": 918, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 272227.35, + "samples": 4590, + "median": 260942.0, + "mad": 16388.0, + "iqr": 48073.0, + "q1": 244776.0, + "q3": 292849.0, + "min": 243276.0, + "max": 537940.0, + "mean": 273216.62, + "stddev": 34841.85, + "ops_per_sec": 3832.27, + "per_rep_median": [ + 261146.0, + 260859.0, + 261016.0, + 260914.5, + 260840.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 136215508.0, + "samples": 150, + "median": 136533873.5, + "mad": 275228.5, + "iqr": 555321.5, + "q1": 136231903.0, + "q3": 136787224.5, + "min": 135999211.0, + "max": 137017627.0, + "mean": 136499833.52, + "stddev": 313444.07, + "ops_per_sec": 7.32, + "per_rep_median": [ + 136586069.0, + 136553031.5, + 136550336.0, + 136514223.5, + 136139967.0 + ] + } + } + }, + { + "alg": "FrodoKEM-640-AES", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 9616, + "secret_key": 19888, + "ciphertext": 9720, + "shared_secret": 16 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 64, + "timed_iters": 318, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 786872.33, + "samples": 1590, + "median": 785400.0, + "mad": 241.0, + "iqr": 556.0, + "q1": 785215.0, + "q3": 785771.0, + "min": 784289.0, + "max": 857955.0, + "mean": 786032.9, + "stddev": 3289.01, + "ops_per_sec": 1273.24, + "per_rep_median": [ + 785474.5, + 785363.0, + 785428.0, + 785400.0, + 785345.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 54, + "timed_iters": 270, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 924920.76, + "samples": 1350, + "median": 923214.0, + "mad": 278.0, + "iqr": 1588.25, + "q1": 923029.0, + "q3": 924617.25, + "min": 922381.0, + "max": 960787.0, + "mean": 924094.8, + "stddev": 3085.86, + "ops_per_sec": 1083.17, + "per_rep_median": [ + 923232.0, + 923167.5, + 923158.0, + 923279.0, + 923288.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 55, + "timed_iters": 277, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 901357.76, + "samples": 1385, + "median": 901214.0, + "mad": 240.0, + "iqr": 1056.0, + "q1": 901066.0, + "q3": 902122.0, + "min": 899844.0, + "max": 985251.0, + "mean": 902040.38, + "stddev": 3933.11, + "ops_per_sec": 1109.61, + "per_rep_median": [ + 901214.0, + 901196.0, + 901400.0, + 901177.0, + 901158.0 + ] + } + } + }, + { + "alg": "FrodoKEM-976-AES", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 3, + "sizes": { + "public_key": 15632, + "secret_key": 31296, + "ciphertext": 15744, + "shared_secret": 24 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 30, + "timed_iters": 148, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1687547.94, + "samples": 740, + "median": 1684883.0, + "mad": 1787.0, + "iqr": 4005.5, + "q1": 1683114.0, + "q3": 1687119.5, + "min": 1682466.0, + "max": 1748595.0, + "mean": 1687057.71, + "stddev": 7405.79, + "ops_per_sec": 593.51, + "per_rep_median": [ + 1684985.0, + 1683678.5, + 1684827.0, + 1685503.5, + 1685040.5 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 26, + "timed_iters": 129, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1933215.39, + "samples": 645, + "median": 1933260.0, + "mad": 1259.0, + "iqr": 2352.0, + "q1": 1931908.0, + "q3": 1934260.0, + "min": 1929908.0, + "max": 2008945.0, + "mean": 1933986.31, + "stddev": 6204.44, + "ops_per_sec": 517.26, + "per_rep_median": [ + 1932723.0, + 1933649.0, + 1933168.0, + 1932983.0, + 1933482.0 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 27, + "timed_iters": 133, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1882070.68, + "samples": 665, + "median": 1882020.0, + "mad": 1241.0, + "iqr": 2555.0, + "q1": 1880576.0, + "q3": 1883131.0, + "min": 1878594.0, + "max": 1967705.0, + "mean": 1882907.49, + "stddev": 7521.83, + "ops_per_sec": 531.34, + "per_rep_median": [ + 1882168.0, + 1882001.0, + 1882075.0, + 1882186.0, + 1881631.0 + ] + } + } + }, + { + "alg": "FrodoKEM-1344-AES", + "kind": "kem", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 21520, + "secret_key": 43088, + "ciphertext": 21632, + "shared_secret": 32 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 16, + "timed_iters": 81, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 3076098.0, + "samples": 405, + "median": 3071787.0, + "mad": 945.0, + "iqr": 1908.0, + "q1": 3070842.0, + "q3": 3072750.0, + "min": 3067658.0, + "max": 3161471.0, + "mean": 3073163.14, + "stddev": 9157.53, + "ops_per_sec": 325.54, + "per_rep_median": [ + 3072157.0, + 3071565.0, + 3071287.0, + 3071639.0, + 3072268.0 + ] + }, + "encaps": { + "unit": "ns", + "warmup_iters": 14, + "timed_iters": 72, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 3491955.87, + "samples": 360, + "median": 3467339.0, + "mad": 982.0, + "iqr": 2203.5, + "q1": 3466468.75, + "q3": 3468672.25, + "min": 3460820.0, + "max": 3584004.0, + "mean": 3468751.85, + "stddev": 9870.01, + "ops_per_sec": 288.41, + "per_rep_median": [ + 3467617.0, + 3466774.0, + 3467274.0, + 3468403.5, + 3467718.5 + ] + }, + "decaps": { + "unit": "ns", + "warmup_iters": 15, + "timed_iters": 73, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 3408318.4, + "samples": 365, + "median": 3407821.0, + "mad": 1223.0, + "iqr": 2760.0, + "q1": 3406987.0, + "q3": 3409747.0, + "min": 3403876.0, + "max": 3531746.0, + "mean": 3410382.58, + "stddev": 12647.71, + "ops_per_sec": 293.44, + "per_rep_median": [ + 3407525.0, + 3408895.0, + 3407765.0, + 3407506.0, + 3407951.0 + ] + } + } + } + ], + "sig": [ + { + "alg": "Ed25519", + "kind": "sig", + "backend": "openssl", + "classical": true, + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 32, + "secret_key": 32, + "signature": 64 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 855, + "timed_iters": 4277, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 58445.52, + "samples": 21385, + "median": 58222.0, + "mad": 19.0, + "iqr": 56.0, + "q1": 58203.0, + "q3": 58259.0, + "min": 58129.0, + "max": 94314.0, + "mean": 58302.65, + "stddev": 649.41, + "ops_per_sec": 17175.64, + "per_rep_median": [ + 58222.0, + 58222.0, + 58222.0, + 58240.0, + 58222.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 866, + "timed_iters": 4329, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 57756.2, + "samples": 21645, + "median": 57684.0, + "mad": 36.0, + "iqr": 73.0, + "q1": 57648.0, + "q3": 57721.0, + "min": 57555.0, + "max": 98981.0, + "mean": 57762.32, + "stddev": 738.96, + "ops_per_sec": 17335.83, + "per_rep_median": [ + 57666.0, + 57703.0, + 57685.0, + 57685.0, + 57666.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 348, + "timed_iters": 1739, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 143780.24, + "samples": 8695, + "median": 143535.0, + "mad": 56.0, + "iqr": 129.0, + "q1": 143462.0, + "q3": 143591.0, + "min": 143239.0, + "max": 178888.0, + "mean": 143653.68, + "stddev": 941.39, + "ops_per_sec": 6966.94, + "per_rep_median": [ + 143592.0, + 143517.0, + 143517.0, + 143499.0, + 143535.0 + ] + } + } + }, + { + "alg": "ML-DSA-44", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 2, + "sizes": { + "public_key": 1312, + "secret_key": 2560, + "signature": 2420 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 464, + "timed_iters": 2320, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 107768.9, + "samples": 11600, + "median": 107462.0, + "mad": 593.0, + "iqr": 1185.0, + "q1": 106888.0, + "q3": 108073.0, + "min": 104703.0, + "max": 144554.0, + "mean": 107547.2, + "stddev": 1323.69, + "ops_per_sec": 9305.62, + "per_rep_median": [ + 107517.0, + 107499.0, + 107424.5, + 107444.0, + 107481.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 103, + "timed_iters": 514, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 486121.98, + "samples": 2570, + "median": 398672.0, + "mad": 180878.0, + "iqr": 343158.25, + "q1": 296983.75, + "q3": 640142.0, + "min": 215942.0, + "max": 2900603.0, + "mean": 505995.47, + "stddev": 321778.38, + "ops_per_sec": 2508.33, + "per_rep_median": [ + 398792.5, + 399200.0, + 397200.0, + 417107.0, + 398033.5 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 420, + "timed_iters": 2099, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 119119.02, + "samples": 10495, + "median": 119166.0, + "mad": 167.0, + "iqr": 1000.0, + "q1": 119036.0, + "q3": 120036.0, + "min": 118666.0, + "max": 158257.0, + "mean": 119493.77, + "stddev": 1048.95, + "ops_per_sec": 8391.66, + "per_rep_median": [ + 119018.0, + 120110.0, + 119147.0, + 119240.0, + 119073.0 + ] + } + } + }, + { + "alg": "ML-DSA-65", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 3, + "sizes": { + "public_key": 1952, + "secret_key": 4032, + "signature": 3309 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 261, + "timed_iters": 1303, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 191900.79, + "samples": 6515, + "median": 191072.0, + "mad": 408.0, + "iqr": 834.0, + "q1": 190702.0, + "q3": 191536.0, + "min": 189128.0, + "max": 229165.0, + "mean": 191352.71, + "stddev": 1399.44, + "ops_per_sec": 5233.63, + "per_rep_median": [ + 191165.0, + 191109.0, + 191035.0, + 191035.0, + 191035.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 50, + "timed_iters": 248, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1007438.87, + "samples": 1240, + "median": 675188.5, + "mad": 314654.0, + "iqr": 658063.5, + "q1": 429653.25, + "q3": 1087716.75, + "min": 320275.0, + "max": 5584801.0, + "mean": 855900.67, + "stddev": 619084.12, + "ops_per_sec": 1481.07, + "per_rep_median": [ + 596753.5, + 705355.0, + 703095.5, + 702688.0, + 597754.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 263, + "timed_iters": 1315, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 190115.69, + "samples": 6575, + "median": 189332.0, + "mad": 519.0, + "iqr": 1926.0, + "q1": 188887.0, + "q3": 190813.0, + "min": 188387.0, + "max": 241405.0, + "mean": 189796.34, + "stddev": 1575.3, + "ops_per_sec": 5281.73, + "per_rep_median": [ + 189462.0, + 189406.0, + 188888.0, + 188943.0, + 189220.0 + ] + } + } + }, + { + "alg": "ML-DSA-87", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 2592, + "secret_key": 4896, + "signature": 4627 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 173, + "timed_iters": 863, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 289718.25, + "samples": 4315, + "median": 288460.0, + "mad": 945.0, + "iqr": 1982.0, + "q1": 287608.0, + "q3": 289590.0, + "min": 284127.0, + "max": 330479.0, + "mean": 288910.7, + "stddev": 2375.56, + "ops_per_sec": 3466.69, + "per_rep_median": [ + 288127.0, + 288423.0, + 288590.0, + 288460.0, + 288775.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 51, + "timed_iters": 253, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 986720.83, + "samples": 1265, + "median": 834214.0, + "mad": 345663.0, + "iqr": 731530.0, + "q1": 491255.0, + "q3": 1222785.0, + "min": 484514.0, + "max": 4603458.0, + "mean": 992938.6, + "stddev": 582947.9, + "ops_per_sec": 1198.73, + "per_rep_median": [ + 833066.0, + 804344.0, + 796881.0, + 837604.0, + 834733.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 163, + "timed_iters": 817, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 305851.24, + "samples": 4085, + "median": 306090.0, + "mad": 649.0, + "iqr": 3945.0, + "q1": 305738.0, + "q3": 309683.0, + "min": 305183.0, + "max": 341330.0, + "mean": 307758.0, + "stddev": 2464.56, + "ops_per_sec": 3267.01, + "per_rep_median": [ + 305794.0, + 309775.0, + 309293.0, + 305757.0, + 309627.0 + ] + } + } + }, + { + "alg": "Falcon-512", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 897, + "secret_key": 1281, + "signature": 752 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 5, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 9415170.71, + "samples": 150, + "median": 9062871.0, + "mad": 1285784.5, + "iqr": 2792910.0, + "q1": 7797729.25, + "q3": 10590639.25, + "min": 7270397.0, + "max": 21594099.0, + "mean": 9790589.07, + "stddev": 2711677.39, + "ops_per_sec": 110.34, + "per_rep_median": [ + 8577634.5, + 9192064.5, + 8826937.5, + 9221980.5, + 8949937.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 172, + "timed_iters": 861, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 290373.98, + "samples": 4305, + "median": 290294.0, + "mad": 2223.0, + "iqr": 4166.0, + "q1": 288775.0, + "q3": 292941.0, + "min": 278831.0, + "max": 326812.0, + "mean": 290684.42, + "stddev": 3632.86, + "ops_per_sec": 3444.78, + "per_rep_median": [ + 290424.0, + 290238.0, + 290164.0, + 290312.0, + 290368.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 979, + "timed_iters": 4895, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 51076.81, + "samples": 24475, + "median": 50870.0, + "mad": 56.0, + "iqr": 111.0, + "q1": 50833.0, + "q3": 50944.0, + "min": 50629.0, + "max": 70777.0, + "mean": 50932.32, + "stddev": 458.8, + "ops_per_sec": 19657.95, + "per_rep_median": [ + 51055.0, + 50889.0, + 50870.0, + 50833.0, + 50833.0 + ] + } + } + }, + { + "alg": "Falcon-1024", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 1793, + "secret_key": 2305, + "signature": 1462 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 2, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 26146945.67, + "samples": 150, + "median": 26303324.5, + "mad": 2618234.5, + "iqr": 6390821.25, + "q1": 24250116.0, + "q3": 30640937.25, + "min": 22847754.0, + "max": 61011646.0, + "mean": 28973269.54, + "stddev": 7198912.67, + "ops_per_sec": 38.02, + "per_rep_median": [ + 26532489.0, + 25732107.5, + 27121113.0, + 24859800.0, + 27400842.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 86, + "timed_iters": 428, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 584101.05, + "samples": 2140, + "median": 584374.0, + "mad": 3148.5, + "iqr": 6282.75, + "q1": 581217.0, + "q3": 587499.75, + "min": 568995.0, + "max": 644438.0, + "mean": 584544.67, + "stddev": 5613.37, + "ops_per_sec": 1711.23, + "per_rep_median": [ + 584161.0, + 584782.0, + 584013.5, + 584310.0, + 584726.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 497, + "timed_iters": 2487, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 100521.26, + "samples": 12435, + "median": 99722.0, + "mad": 167.0, + "iqr": 370.0, + "q1": 99555.0, + "q3": 99925.0, + "min": 99166.0, + "max": 133036.0, + "mean": 99837.26, + "stddev": 713.85, + "ops_per_sec": 10027.88, + "per_rep_median": [ + 100203.0, + 99814.0, + 99758.0, + 99592.0, + 99463.0 + ] + } + } + }, + { + "alg": "SPHINCS+-SHA2-128f-simple", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 17088 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 32, + "timed_iters": 158, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 1582520.74, + "samples": 790, + "median": 1558819.0, + "mad": 1778.0, + "iqr": 3592.0, + "q1": 1556986.0, + "q3": 1560578.0, + "min": 1553004.0, + "max": 1633411.0, + "mean": 1559050.27, + "stddev": 4938.67, + "ops_per_sec": 641.51, + "per_rep_median": [ + 1560523.0, + 1558837.5, + 1558856.0, + 1555736.0, + 1557032.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 36452444.0, + "samples": 150, + "median": 36348426.0, + "mad": 41028.0, + "iqr": 83601.5, + "q1": 36308343.25, + "q3": 36391944.75, + "min": 36301464.0, + "max": 36479574.0, + "mean": 36349942.0, + "stddev": 45043.6, + "ops_per_sec": 27.51, + "per_rep_median": [ + 36396907.5, + 36349704.0, + 36322593.5, + 36347675.5, + 36309231.5 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 24, + "timed_iters": 119, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 2102152.33, + "samples": 595, + "median": 2100610.0, + "mad": 1982.0, + "iqr": 4241.0, + "q1": 2098286.0, + "q3": 2102527.0, + "min": 2098166.0, + "max": 2186054.0, + "mean": 2101209.27, + "stddev": 5578.92, + "ops_per_sec": 476.05, + "per_rep_median": [ + 2103277.0, + 2100222.0, + 2100703.0, + 2100184.0, + 2100111.0 + ] + } + } + }, + { + "alg": "SPHINCS+-SHA2-128s-simple", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 1, + "sizes": { + "public_key": 32, + "secret_key": 64, + "signature": 7856 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 97225479.0, + "samples": 150, + "median": 96928665.0, + "mad": 10536.5, + "iqr": 29902.5, + "q1": 96921429.5, + "q3": 96951332.0, + "min": 96797056.0, + "max": 97280756.0, + "mean": 96943576.41, + "stddev": 89923.75, + "ops_per_sec": 10.32, + "per_rep_median": [ + 96926879.0, + 96926351.0, + 96926517.0, + 96933387.0, + 96930710.5 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 737849992.0, + "samples": 150, + "median": 738998757.5, + "mad": 923577.5, + "iqr": 1535087.5, + "q1": 738417853.0, + "q3": 739952940.5, + "min": 735828404.0, + "max": 746650664.0, + "mean": 739355528.6, + "stddev": 1875209.33, + "ops_per_sec": 1.35, + "per_rep_median": [ + 738952442.0, + 739659145.5, + 738482800.5, + 742241466.0, + 738683691.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 67, + "timed_iters": 335, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 745322.56, + "samples": 1675, + "median": 746771.0, + "mad": 352.0, + "iqr": 870.0, + "q1": 746734.0, + "q3": 747604.0, + "min": 744585.0, + "max": 819770.0, + "mean": 747099.62, + "stddev": 2815.47, + "ops_per_sec": 1339.1, + "per_rep_median": [ + 744623.0, + 747622.0, + 746771.0, + 746771.0, + 746771.0 + ] + } + } + }, + { + "alg": "SPHINCS+-SHA2-192f-simple", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 3, + "sizes": { + "public_key": 48, + "secret_key": 96, + "signature": 35664 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 21, + "timed_iters": 105, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 2374561.73, + "samples": 525, + "median": 2332849.0, + "mad": 4778.0, + "iqr": 29926.0, + "q1": 2306237.0, + "q3": 2336163.0, + "min": 2301145.0, + "max": 2398422.0, + "mean": 2324577.41, + "stddev": 16600.87, + "ops_per_sec": 428.66, + "per_rep_median": [ + 2333200.0, + 2335960.0, + 2336200.0, + 2306664.0, + 2305052.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 62106715.0, + "samples": 150, + "median": 61899440.0, + "mad": 48527.0, + "iqr": 86388.75, + "q1": 61875494.5, + "q3": 61961883.25, + "min": 61726329.0, + "max": 62223178.0, + "mean": 61915262.67, + "stddev": 77985.71, + "ops_per_sec": 16.16, + "per_rep_median": [ + 62000115.0, + 61899375.0, + 61837921.5, + 61901272.5, + 61916920.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 15, + "timed_iters": 74, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 3376886.93, + "samples": 370, + "median": 3373866.0, + "mad": 1185.5, + "iqr": 3740.0, + "q1": 3373210.0, + "q3": 3376950.0, + "min": 3336209.0, + "max": 3411042.0, + "mean": 3373587.78, + "stddev": 8082.8, + "ops_per_sec": 296.4, + "per_rep_median": [ + 3377153.5, + 3373440.5, + 3374301.5, + 3373413.0, + 3373468.0 + ] + } + } + }, + { + "alg": "SPHINCS+-SHA2-256f-simple", + "kind": "sig", + "backend": "liboqs", + "enabled": true, + "claimed_nist_level": 5, + "sizes": { + "public_key": 64, + "secret_key": 128, + "signature": 49856 + }, + "operations": { + "keygen": { + "unit": "ns", + "warmup_iters": 8, + "timed_iters": 39, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 6350943.29, + "samples": 195, + "median": 6275960.0, + "mad": 6815.0, + "iqr": 12944.0, + "q1": 6270450.5, + "q3": 6283394.5, + "min": 6226626.0, + "max": 6375440.0, + "mean": 6279887.72, + "stddev": 28336.27, + "ops_per_sec": 159.34, + "per_rep_median": [ + 6312867.0, + 6276145.0, + 6275997.0, + 6269256.0, + 6230367.0 + ] + }, + "sign": { + "unit": "ns", + "warmup_iters": 1, + "timed_iters": 30, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 130789831.0, + "samples": 150, + "median": 128728266.0, + "mad": 129795.5, + "iqr": 241107.75, + "q1": 128575873.25, + "q3": 128816981.0, + "min": 128307036.0, + "max": 131083215.0, + "mean": 128755858.35, + "stddev": 389204.74, + "ops_per_sec": 7.77, + "per_rep_median": [ + 128740701.5, + 128751728.5, + 128721330.0, + 128656913.5, + 128822337.0 + ] + }, + "verify": { + "unit": "ns", + "warmup_iters": 15, + "timed_iters": 75, + "repetitions": 5, + "calibrated": true, + "calib_est_ns": 3321141.67, + "samples": 375, + "median": 3320580.0, + "mad": 3797.0, + "iqr": 8731.0, + "q1": 3313478.0, + "q3": 3322209.0, + "min": 3311209.0, + "max": 3392265.0, + "mean": 3319290.82, + "stddev": 7414.38, + "ops_per_sec": 301.15, + "per_rep_median": [ + 3320765.0, + 3324265.0, + 3320617.0, + 3313284.0, + 3315136.0 + ] + } + } + } + ], + "tls": { + "available": true, + "have_oqs_provider": true, + "baseline": { + "kem_group": "X25519", + "sig_alg": "ed25519", + "label": "X25519+ed25519" + }, + "matrix": [ + { + "label": "X25519+ed25519", + "group": "X25519", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 1328747.0, + "p95": 1341701.2, + "min": 1322321.0, + "max": 1843353.0, + "mean": 1334789.3, + "stddev": 38745.9 + }, + "handshakes_per_sec": 752.6, + "bytes_on_wire": { + "client_to_server": 382, + "server_to_client": 1189, + "total": 1571 + }, + "client_hello_bytes": 302, + "client_hello_fragmented": false, + "mss_assumed": 1400 + }, + { + "label": "X25519MLKEM768+mldsa44", + "group": "X25519MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 2674910.5, + "p95": 4547616.8, + "min": 2244738.0, + "max": 7464226.0, + "mean": 2921183.2, + "stddev": 758173.6 + }, + "handshakes_per_sec": 373.8, + "bytes_on_wire": { + "client_to_server": 1558, + "server_to_client": 8294, + "total": 9852 + }, + "client_hello_bytes": 1478, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "X25519MLKEM768+mldsa65", + "group": "X25519MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 3578901.5, + "p95": 6786274.8, + "min": 2693104.0, + "max": 10607474.0, + "mean": 3922772.2, + "stddev": 1322237.5 + }, + "handshakes_per_sec": 279.4, + "bytes_on_wire": { + "client_to_server": 1558, + "server_to_client": 10712, + "total": 12270 + }, + "client_hello_bytes": 1478, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "X25519MLKEM768+mldsa87", + "group": "X25519MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 4225339.5, + "p95": 7568932.7, + "min": 3377635.0, + "max": 14674436.0, + "mean": 4624577.4, + "stddev": 1414723.7 + }, + "handshakes_per_sec": 236.7, + "bytes_on_wire": { + "client_to_server": 1558, + "server_to_client": 13988, + "total": 15546 + }, + "client_hello_bytes": 1478, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "X25519MLKEM768+falcon512", + "group": "X25519MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 3184164.5, + "p95": 3216625.5, + "min": 3158396.0, + "max": 4250941.0, + "mean": 3197203.8, + "stddev": 88533.1 + }, + "handshakes_per_sec": 314.1, + "bytes_on_wire": { + "client_to_server": 1558, + "server_to_client": 4336, + "total": 5894 + }, + "client_hello_bytes": 1478, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "X25519MLKEM768+sphincssha2128fsimple", + "group": "X25519MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 44119685.5, + "p95": 44669304.1, + "min": 43577293.0, + "max": 47016001.0, + "mean": 44162754.9, + "stddev": 283326.8 + }, + "handshakes_per_sec": 22.7, + "bytes_on_wire": { + "client_to_server": 1558, + "server_to_client": 36394, + "total": 37952 + }, + "client_hello_bytes": 1478, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "SecP256r1MLKEM768+mldsa44", + "group": "SecP256r1MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 2712761.5, + "p95": 4586659.2, + "min": 2279756.0, + "max": 8335903.0, + "mean": 2980401.8, + "stddev": 793472.6 + }, + "handshakes_per_sec": 368.6, + "bytes_on_wire": { + "client_to_server": 1591, + "server_to_client": 8327, + "total": 9918 + }, + "client_hello_bytes": 1511, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "SecP256r1MLKEM768+mldsa65", + "group": "SecP256r1MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 3634613.5, + "p95": 6847175.1, + "min": 2746752.0, + "max": 11254597.0, + "mean": 4008027.3, + "stddev": 1351918.3 + }, + "handshakes_per_sec": 275.1, + "bytes_on_wire": { + "client_to_server": 1591, + "server_to_client": 10745, + "total": 12336 + }, + "client_hello_bytes": 1511, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "SecP256r1MLKEM768+mldsa87", + "group": "SecP256r1MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 4277496.0, + "p95": 7300544.8, + "min": 3427394.0, + "max": 14713157.0, + "mean": 4706221.0, + "stddev": 1479870.4 + }, + "handshakes_per_sec": 233.8, + "bytes_on_wire": { + "client_to_server": 1591, + "server_to_client": 14021, + "total": 15612 + }, + "client_hello_bytes": 1511, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "SecP256r1MLKEM768+falcon512", + "group": "SecP256r1MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 3329811.0, + "p95": 3500111.4, + "min": 3296524.0, + "max": 4461606.0, + "mean": 3357918.1, + "stddev": 109986.7 + }, + "handshakes_per_sec": 300.3, + "bytes_on_wire": { + "client_to_server": 1591, + "server_to_client": 4370, + "total": 5961 + }, + "client_hello_bytes": 1511, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "SecP256r1MLKEM768+sphincssha2128fsimple", + "group": "SecP256r1MLKEM768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 44574336.0, + "p95": 45137110.7, + "min": 43965361.0, + "max": 47645862.0, + "mean": 44626364.2, + "stddev": 305818.7 + }, + "handshakes_per_sec": 22.4, + "bytes_on_wire": { + "client_to_server": 1591, + "server_to_client": 36427, + "total": 38018 + }, + "client_hello_bytes": 1511, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem512+mldsa44", + "group": "mlkem512", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 2105128.0, + "p95": 3971338.2, + "min": 1670484.0, + "max": 6703714.0, + "mean": 2391208.2, + "stddev": 775109.0 + }, + "handshakes_per_sec": 475.0, + "bytes_on_wire": { + "client_to_server": 1142, + "server_to_client": 7942, + "total": 9084 + }, + "client_hello_bytes": 1062, + "client_hello_fragmented": false, + "mss_assumed": 1400 + }, + { + "label": "mlkem512+mldsa65", + "group": "mlkem512", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 3004971.0, + "p95": 6508967.2, + "min": 2122313.0, + "max": 11480299.0, + "mean": 3354059.5, + "stddev": 1357035.0 + }, + "handshakes_per_sec": 332.8, + "bytes_on_wire": { + "client_to_server": 1142, + "server_to_client": 10360, + "total": 11502 + }, + "client_hello_bytes": 1062, + "client_hello_fragmented": false, + "mss_assumed": 1400 + }, + { + "label": "mlkem512+mldsa87", + "group": "mlkem512", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 3648058.0, + "p95": 6995478.8, + "min": 2798455.0, + "max": 12398715.0, + "mean": 4063084.0, + "stddev": 1408206.1 + }, + "handshakes_per_sec": 274.1, + "bytes_on_wire": { + "client_to_server": 1142, + "server_to_client": 13636, + "total": 14778 + }, + "client_hello_bytes": 1062, + "client_hello_fragmented": false, + "mss_assumed": 1400 + }, + { + "label": "mlkem512+falcon512", + "group": "mlkem512", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 2592753.0, + "p95": 2621475.9, + "min": 2568420.0, + "max": 3673484.0, + "mean": 2600842.7, + "stddev": 67465.5 + }, + "handshakes_per_sec": 385.7, + "bytes_on_wire": { + "client_to_server": 1142, + "server_to_client": 3986, + "total": 5128 + }, + "client_hello_bytes": 1062, + "client_hello_fragmented": false, + "mss_assumed": 1400 + }, + { + "label": "mlkem512+sphincssha2128fsimple", + "group": "mlkem512", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 42806832.0, + "p95": 43216107.5, + "min": 42350965.0, + "max": 45853285.0, + "mean": 42824792.6, + "stddev": 241070.6 + }, + "handshakes_per_sec": 23.4, + "bytes_on_wire": { + "client_to_server": 1142, + "server_to_client": 36042, + "total": 37184 + }, + "client_hello_bytes": 1062, + "client_hello_fragmented": false, + "mss_assumed": 1400 + }, + { + "label": "mlkem768+mldsa44", + "group": "mlkem768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 2192238.5, + "p95": 3900309.5, + "min": 1761520.0, + "max": 7819981.0, + "mean": 2453754.0, + "stddev": 779251.1 + }, + "handshakes_per_sec": 456.2, + "bytes_on_wire": { + "client_to_server": 1526, + "server_to_client": 8262, + "total": 9788 + }, + "client_hello_bytes": 1446, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem768+mldsa65", + "group": "mlkem768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 3115081.5, + "p95": 6342347.8, + "min": 2235293.0, + "max": 12468547.0, + "mean": 3440788.2, + "stddev": 1391897.2 + }, + "handshakes_per_sec": 321.0, + "bytes_on_wire": { + "client_to_server": 1526, + "server_to_client": 10680, + "total": 12206 + }, + "client_hello_bytes": 1446, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem768+mldsa87", + "group": "mlkem768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 3773140.0, + "p95": 7115532.5, + "min": 2924694.0, + "max": 13790886.0, + "mean": 4142801.1, + "stddev": 1479622.7 + }, + "handshakes_per_sec": 265.0, + "bytes_on_wire": { + "client_to_server": 1526, + "server_to_client": 13956, + "total": 15482 + }, + "client_hello_bytes": 1446, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem768+falcon512", + "group": "mlkem768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 2677252.0, + "p95": 2705182.7, + "min": 2654678.0, + "max": 3599966.0, + "mean": 2685900.6, + "stddev": 63825.8 + }, + "handshakes_per_sec": 373.5, + "bytes_on_wire": { + "client_to_server": 1526, + "server_to_client": 4308, + "total": 5834 + }, + "client_hello_bytes": 1446, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem768+sphincssha2128fsimple", + "group": "mlkem768", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 43591286.0, + "p95": 44102441.1, + "min": 43007310.0, + "max": 46733514.0, + "mean": 43619459.1, + "stddev": 302764.6 + }, + "handshakes_per_sec": 22.9, + "bytes_on_wire": { + "client_to_server": 1526, + "server_to_client": 36362, + "total": 37888 + }, + "client_hello_bytes": 1446, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem1024+mldsa44", + "group": "mlkem1024", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 2322727.5, + "p95": 4189684.5, + "min": 1885611.0, + "max": 7954275.0, + "mean": 2610924.0, + "stddev": 770009.3 + }, + "handshakes_per_sec": 430.5, + "bytes_on_wire": { + "client_to_server": 1910, + "server_to_client": 8742, + "total": 10652 + }, + "client_hello_bytes": 1830, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem1024+mldsa65", + "group": "mlkem1024", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 3218598.5, + "p95": 5867511.6, + "min": 2331755.0, + "max": 10805489.0, + "mean": 3517722.5, + "stddev": 1267592.2 + }, + "handshakes_per_sec": 310.7, + "bytes_on_wire": { + "client_to_server": 1910, + "server_to_client": 11160, + "total": 13070 + }, + "client_hello_bytes": 1830, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem1024+mldsa87", + "group": "mlkem1024", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 3860833.5, + "p95": 6797086.7, + "min": 3012878.0, + "max": 13488223.0, + "mean": 4226793.4, + "stddev": 1393307.5 + }, + "handshakes_per_sec": 259.0, + "bytes_on_wire": { + "client_to_server": 1910, + "server_to_client": 14436, + "total": 16346 + }, + "client_hello_bytes": 1830, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem1024+falcon512", + "group": "mlkem1024", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 2808501.0, + "p95": 2857909.1, + "min": 2783640.0, + "max": 3929629.0, + "mean": 2822505.4, + "stddev": 86394.6 + }, + "handshakes_per_sec": 356.1, + "bytes_on_wire": { + "client_to_server": 1910, + "server_to_client": 4785, + "total": 6695 + }, + "client_hello_bytes": 1830, + "client_hello_fragmented": true, + "mss_assumed": 1400 + }, + { + "label": "mlkem1024+sphincssha2128fsimple", + "group": "mlkem1024", + "enabled": true, + "have_oqs_provider": true, + "connections": 1000, + "succeeded": 1000, + "handshake_latency_ns": { + "median": 43234843.0, + "p95": 43621617.6, + "min": 42746089.0, + "max": 46301757.0, + "mean": 43265752.0, + "stddev": 222157.2 + }, + "handshakes_per_sec": 23.1, + "bytes_on_wire": { + "client_to_server": 1910, + "server_to_client": 36842, + "total": 38752 + }, + "client_hello_bytes": 1830, + "client_hello_fragmented": true, + "mss_assumed": 1400 + } + ] + } +} \ No newline at end of file diff --git a/pq-bench-rpi5/run.sh b/pq-bench-rpi5/run.sh new file mode 100755 index 0000000..55138b8 --- /dev/null +++ b/pq-bench-rpi5/run.sh @@ -0,0 +1,290 @@ +#!/usr/bin/env bash +# ============================================================================= +# run.sh — measurement wrapper + orchestrator. +# +# Does the things that make a number credible: +# * sets the CPU governor to `performance` (Linux; warns elsewhere) +# * pins the benchmark to a single isolated core via taskset (core 3 on RPi5; +# core 3 stays clear of CPU0 where the kernel steers IRQs/RPS) +# * logs ARM clock + SoC temperature throughout, embeds the trace in results, +# and warns on thermal throttling +# * runs every candidate from config.yaml, then assembles one results JSON +# stamped with full host + toolchain provenance. +# +# Usage: +# ./run.sh # full run using config.yaml knobs +# ./run.sh --smoke # tiny iteration counts: pipeline smoke test +# ./run.sh --kemsig-only # skip the TLS layer +# ./run.sh --tls-only # only the TLS layer +# ./run.sh --iters N --warmup N --reps N # override measurement knobs +# sudo ./run.sh # needed on Linux to set the governor +# ============================================================================= +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +TOOL_VERSION="0.1.0" +# shellcheck source=setup/lib_platform.sh +source "$ROOT/setup/lib_platform.sh" +# shellcheck source=setup/versions.env +source "$ROOT/setup/versions.env" +LOCK="$ROOT/setup/versions.lock" +[ -f "$LOCK" ] && source "$LOCK" || pqb_warn "no versions.lock — run ./setup/setup.sh first" + +pqb_detect_platform + +# ---- args ------------------------------------------------------------------ +SMOKE=0; DO_KEMSIG=1; DO_TLS=1 +OVR_ITERS=""; OVR_WARMUP=""; OVR_REPS="" +while [ $# -gt 0 ]; do + case "$1" in + --smoke) SMOKE=1 ;; + --kemsig-only) DO_TLS=0 ;; + --tls-only) DO_KEMSIG=0 ;; + --no-tls) DO_TLS=0 ;; + --iters) OVR_ITERS="$2"; shift ;; + --warmup) OVR_WARMUP="$2"; shift ;; + --reps) OVR_REPS="$2"; shift ;; + -h|--help) grep '^#' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; + *) pqb_err "unknown arg: $1"; exit 2 ;; + esac + shift +done + +# ---- measurement knobs (config.yaml, overridable) -------------------------- +# Sets TARGET_TIME_MS MIN_SAMPLES MAX_ITERS REPS CYCLES_MODE (auto-calibration, +# the default path) plus WARMUP ITERS (the fixed-count fallback). +eval "$(python3 "$ROOT/bench/lib/list_algs.py" measurement "$ROOT/config.yaml")" + +# Mode: auto-calibrate per op (default) unless --iters forces a fixed count. +CALIB_MODE="auto" +if [ -n "$OVR_ITERS" ]; then CALIB_MODE="fixed"; ITERS="$OVR_ITERS"; fi +[ -n "$OVR_WARMUP" ] && WARMUP="$OVR_WARMUP" +[ -n "$OVR_REPS" ] && REPS="$OVR_REPS" +if [ "$SMOKE" = 1 ]; then + # Keep auto-calibration (so each op still reaches target) but a single rep, so + # the sweep stays short. This is a pipeline test, NOT measurement data. + REPS=1 + pqb_warn "SMOKE MODE: reps=1 — pipeline test only, NOT measurement data" +fi + +# Assemble the per-op sizing args passed to every bench_pq invocation. +if [ "$CALIB_MODE" = "fixed" ]; then + BENCH_SIZE_ARGS=(--warmup "$WARMUP" --iters "$ITERS" --reps "$REPS") + pqb_log "sizing: FIXED-count warmup=$WARMUP iters=$ITERS reps=$REPS" +else + BENCH_SIZE_ARGS=(--target-time-ms "$TARGET_TIME_MS" --min-samples "$MIN_SAMPLES" \ + --max-iters "$MAX_ITERS" --reps "$REPS") + pqb_log "sizing: AUTO-calibrate target=${TARGET_TIME_MS}ms min_samples=$MIN_SAMPLES max_iters=$MAX_ITERS reps=$REPS" +fi +BENCH_CORE="${BENCH_CORE:-3}" +export PQB_BENCH_CORE="$BENCH_CORE" + +# ---- work directory -------------------------------------------------------- +HOST="$(pqb_resolve_hostname)" +TS="$(date -u +%Y%m%dT%H%M%SZ)" +WORK="$ROOT/results/.work-$HOST-$TS" +mkdir -p "$WORK" "$ROOT/results" +KEMSIG_OUT="$WORK/kemsig.jsonl"; : > "$KEMSIG_OUT" +TLS_OUT="$WORK/tls.json" +THERMAL="$WORK/thermal.csv"; : > "$THERMAL" +META="$WORK/meta.env" +FEATURES="$WORK/cpu_features.json" +WARN_ACC="" + +add_warn() { WARN_ACC="${WARN_ACC:+$WARN_ACC||}$1"; pqb_warn "$1"; } + +# ---- governor -------------------------------------------------------------- +GOV_BEFORE="$(pqb_get_governor)" +GOV_AFTER="$(pqb_set_governor_performance || true)" +GOV_REQUESTED="performance" +if [ "$GOV_AFTER" != "performance" ]; then + add_warn "governor is '$GOV_AFTER', not 'performance' (need root on Linux, or unsupported on macOS)" +fi + +# ---- core pinning ---------------------------------------------------------- +TASKSET="$(pqb_taskset_prefix "$BENCH_CORE")" +if [ -n "$TASKSET" ]; then + PINNED=1; pqb_log "pinning to core $BENCH_CORE via: $TASKSET" +else + PINNED=0; add_warn "core pinning unavailable (no taskset/numactl) — results will be noisier" +fi + +# ---- thermal sampler (background) ------------------------------------------ +SAMPLE_INTERVAL="${SAMPLE_INTERVAL:-1}" +pqb_log "starting thermal/clock sampler (every ${SAMPLE_INTERVAL}s) -> $THERMAL" +( while :; do pqb_sample_thermal >> "$THERMAL" 2>/dev/null; sleep "$SAMPLE_INTERVAL"; done ) & +SAMPLER_PID=$! +disown "$SAMPLER_PID" 2>/dev/null || true # suppress job-control "Terminated" noise on kill +# shellcheck disable=SC2064 +trap "kill $SAMPLER_PID 2>/dev/null || true" EXIT +pqb_sample_thermal >> "$THERMAL" 2>/dev/null # one immediate sample + +# ---- CPU features ---------------------------------------------------------- +pqb_cpu_features_json > "$FEATURES" +pqb_log "cpu features: $(cat "$FEATURES")" +# Report whether Keccak/SHA3 *instruction* acceleration is available + compiled. +SHA3_HW="$(python3 -c "import json;print(json.load(open('$FEATURES'))['sha3'])" 2>/dev/null || echo unknown)" +case "${LIBOQS_OPT_DEFINES:-}" in + *"OQS_USE_ARM_SHA3_INSTRUCTIONS 1"*) SHA3_COMPILED=1 ;; + *) SHA3_COMPILED=0 ;; +esac +pqb_log "Keccak/SHA3: hw_instructions=$SHA3_HW liboqs_compiled_sha3=$SHA3_COMPILED (A76 has no SHA3 ext; Keccak runs on NEON there)" + +TS_START="$(date -u +%Y-%m-%dT%H:%M:%SZ)" +START_EPOCH="$(date +%s)" + +# ---- build harness if needed ----------------------------------------------- +OSSL_PREFIX_FOR_BUILD="${OPENSSL_PREFIX:-$(brew --prefix openssl@3 2>/dev/null || echo /usr)}" +if [ ! -x "$ROOT/bench/kem_sig/bench_pq" ] || [ "$ROOT/bench/kem_sig/bench_pq.c" -nt "$ROOT/bench/kem_sig/bench_pq" ]; then + pqb_log "building bench_pq harness" + make -C "$ROOT/bench/kem_sig" \ + LIBOQS_PREFIX="${PREFIX:-$ROOT/vendor/install}" \ + OPENSSL_PREFIX="$OSSL_PREFIX_FOR_BUILD" \ + BENCH_CFLAGS="${BENCH_CFLAGS:--O3}" >/dev/null +fi + +# ---- KEM/sig sweep --------------------------------------------------------- +CYCLES_AVAILABLE=0; CYCLES_REASON="not probed" +if [ "$DO_KEMSIG" = 1 ]; then + if [ "$CALIB_MODE" = "fixed" ]; then + pqb_log "running KEM/sig sweep (fixed: warmup=$WARMUP iters=$ITERS reps=$REPS)" + else + pqb_log "running KEM/sig sweep (auto-calibrate: target=${TARGET_TIME_MS}ms min_samples=$MIN_SAMPLES max_iters=$MAX_ITERS reps=$REPS)" + fi + while IFS=$'\t' read -r kind alg classical; do + [ -z "$alg" ] && continue + pqb_log " $kind $alg" + ERRF="$WORK/err.$kind.$alg.txt" + # shellcheck disable=SC2086 + if $TASKSET "$ROOT/bench/kem_sig/bench_pq" --kind "$kind" --alg "$alg" \ + "${BENCH_SIZE_ARGS[@]}" >> "$KEMSIG_OUT" 2>"$ERRF"; then + : + else + add_warn "harness failed for $kind $alg (see $ERRF)" + fi + # capture PMU availability from the harness's stderr (first occurrence) + if grep -q 'cycles_available=1' "$ERRF" 2>/dev/null; then + CYCLES_AVAILABLE=1; CYCLES_REASON="$(sed -n 's/.*cycles_available=1 (\(.*\))/\1/p' "$ERRF" | head -1)" + elif [ "$CYCLES_AVAILABLE" = 0 ] && grep -q 'cycles_available=0' "$ERRF" 2>/dev/null; then + CYCLES_REASON="$(sed -n 's/.*cycles_available=0 (\(.*\))/\1/p' "$ERRF" | head -1)" + fi + done < <(python3 "$ROOT/bench/lib/list_algs.py" kemsig "$ROOT/config.yaml") +fi + +# ---- TLS layer ------------------------------------------------------------- +if [ "$DO_TLS" = 1 ]; then + if [ -x "$ROOT/bench/tls/run_tls.sh" ]; then + TLS_CONNS="$(python3 -c "import json,sys;print(json.loads(sys.argv[1]).get('connections',1000))" \ + "$(python3 "$ROOT/bench/lib/list_algs.py" tls "$ROOT/config.yaml")")" + [ "$SMOKE" = 1 ] && TLS_CONNS=50 + pqb_log "running TLS handshake matrix ($TLS_CONNS handshakes/cell)" + if PQB_TASKSET="$TASKSET" "$ROOT/bench/tls/run_tls.sh" \ + --out "$TLS_OUT" --connections "$TLS_CONNS" >"$WORK/tls.log" 2>&1; then + pqb_log "TLS layer done ($(grep -c '"label"' "$TLS_OUT" 2>/dev/null || echo 0) cells)" + else + add_warn "TLS layer failed or unavailable (see $WORK/tls.log) — continuing without it" + TLS_OUT="" + fi + else + pqb_warn "TLS harness not present yet — skipping (will be added)" + TLS_OUT="" + fi +fi + +# ---- stop sampler, gather timing ------------------------------------------- +kill "$SAMPLER_PID" 2>/dev/null || true +trap - EXIT +TS_END="$(date -u +%Y-%m-%dT%H:%M:%SZ)" +DURATION=$(( $(date +%s) - START_EPOCH )) +GOV_AFTER_END="$(pqb_get_governor)" + +# ---- host facts ------------------------------------------------------------ +collect_host_facts() { + local cpu_brand="" ncpu="" ram="" os_pretty="" kernel + kernel="$(uname -r)" + if [ "$PQB_OS" = "macos" ]; then + cpu_brand="$(sysctl -n machdep.cpu.brand_string 2>/dev/null)" + ncpu="$(sysctl -n hw.ncpu 2>/dev/null)" + ram="$(sysctl -n hw.memsize 2>/dev/null)" + os_pretty="macOS $(sw_vers -productVersion 2>/dev/null) ($(sw_vers -buildVersion 2>/dev/null))" + else + # aarch64 /proc/cpuinfo has no 'model name' line, so this grep misses; the + # trailing `|| true` keeps `set -o pipefail` from aborting the run (errexit) + # before the PQB_RPI_MODEL fallback below can supply the brand. + cpu_brand="$(grep -m1 'model name' /proc/cpuinfo 2>/dev/null | sed 's/.*: //' || true)" + [ -z "$cpu_brand" ] && cpu_brand="$PQB_RPI_MODEL" + ncpu="$( (command -v nproc >/dev/null && nproc) || grep -c ^processor /proc/cpuinfo)" + ram="$(( $(grep -m1 MemTotal /proc/meminfo 2>/dev/null | awk '{print $2}') * 1024 ))" + os_pretty="$(. /etc/os-release 2>/dev/null; echo "$PRETTY_NAME")" + fi + { + echo "TOOL_VERSION=$TOOL_VERSION" + echo "HOSTNAME=$HOST" + echo "OS=$PQB_OS" + echo "ARCH=$PQB_ARCH" + echo "KERNEL=$kernel" + echo "OS_PRETTY=\"$os_pretty\"" + echo "IS_RPI=$PQB_IS_RPI" + echo "RPI_MODEL=\"$PQB_RPI_MODEL\"" + echo "CPU_BRAND=\"$cpu_brand\"" + echo "NCPU=$ncpu" + echo "RAM_BYTES=$ram" + echo "GOVERNOR_REQUESTED=$GOV_REQUESTED" + echo "GOVERNOR_BEFORE=$GOV_BEFORE" + echo "GOVERNOR_AFTER=$GOV_AFTER_END" + echo "BENCH_CORE=$BENCH_CORE" + echo "PINNED=$PINNED" + echo "TASKSET_CMD=\"$TASKSET\"" + echo "CALIB_MODE=$CALIB_MODE" + echo "TARGET_TIME_MS=$TARGET_TIME_MS" + echo "MIN_SAMPLES=$MIN_SAMPLES" + echo "MAX_ITERS=$MAX_ITERS" + echo "REPS=$REPS" + # warmup/timed_iters are single values only in fixed-count mode; in auto mode + # they are chosen per-op and recorded in each operation's JSON instead. + if [ "$CALIB_MODE" = "fixed" ]; then + echo "WARMUP=$WARMUP" + echo "ITERS=$ITERS" + else + echo "WARMUP=" + echo "ITERS=" + fi + echo "CYCLES_MODE=$CYCLES_MODE" + echo "CYCLES_AVAILABLE=$CYCLES_AVAILABLE" + echo "CYCLES_REASON=\"$CYCLES_REASON\"" + echo "TS_START_UTC=$TS_START" + echo "TS_END_UTC=$TS_END" + echo "DURATION_S=$DURATION" + echo "WARNINGS=\"$WARN_ACC\"" + } > "$META" +} +collect_host_facts + +# ---- assemble final results JSON ------------------------------------------- +OUT="$ROOT/results/${HOST}-${TS}.json" +python3 "$ROOT/bench/lib/assemble.py" \ + --meta "$META" --lock "$LOCK" --features "$FEATURES" \ + --kemsig "$KEMSIG_OUT" ${TLS_OUT:+--tls "$TLS_OUT"} \ + --thermal "$THERMAL" --config "$ROOT/config.yaml" \ + --out "$OUT" >/dev/null + +# ---- summary --------------------------------------------------------------- +echo +pqb_log "================ RUN COMPLETE ================" +python3 - "$OUT" <<'PY' +import json,sys +d=json.load(open(sys.argv[1])) +g=d["is_baseline_grade"] +print(f" results: {sys.argv[1]}") +print(f" host: {d['host']['cpu_brand']} ({d['host']['os_pretty']})") +print(f" baseline-grade (RPi5): {g}") +if not g: + for r in d['baseline_grade_reasons']: + print(f" - {r}") +tt=d['thermal_trace'] +print(f" thermal: {tt.get('temp_c')} throttling={tt.get('throttling_detected')}") +print(f" kem algos: {sum(1 for x in d['kem'] if x.get('enabled'))} enabled / {len(d['kem'])}") +print(f" sig algos: {sum(1 for x in d['sig'] if x.get('enabled'))} enabled / {len(d['sig'])}") +print(f" cycles available: {d['run']['cycles_available']}") +PY +pqb_log "keep raw work dir? -> $WORK (safe to delete)" diff --git a/pq-bench-rpi5/setup/lib_platform.sh b/pq-bench-rpi5/setup/lib_platform.sh new file mode 100644 index 0000000..6285f77 --- /dev/null +++ b/pq-bench-rpi5/setup/lib_platform.sh @@ -0,0 +1,227 @@ +# shellcheck shell=bash +# ============================================================================= +# lib_platform.sh — portable platform abstraction +# +# Sourced by setup/setup.sh and run.sh. Every operation that differs between the +# RPi5 (Debian/Ubuntu aarch64) measurement target and the macOS/Apple-Silicon +# dev box is funneled through one of these functions, so the *identical* codebase +# runs unchanged on both. Where a capability does not exist on a platform +# (governor control, core pinning, on-die thermal sensors), the function degrades +# gracefully and the caller records that it was unavailable — it never silently +# pretends the action happened. +# ============================================================================= + +# ---- platform detection ---------------------------------------------------- +# Sets: PQB_OS (macos|linux), PQB_ARCH, PQB_IS_RPI (1|0), PQB_RPI_MODEL +pqb_detect_platform() { + PQB_ARCH="$(uname -m)" + case "$(uname -s)" in + Darwin) PQB_OS="macos" ;; + Linux) PQB_OS="linux" ;; + *) PQB_OS="unknown" ;; + esac + + PQB_IS_RPI=0 + PQB_RPI_MODEL="" + if [ "$PQB_OS" = "linux" ] && [ -r /proc/device-tree/model ]; then + # /proc/device-tree/model is NUL-terminated + PQB_RPI_MODEL="$(tr -d '\0' < /proc/device-tree/model 2>/dev/null)" + case "$PQB_RPI_MODEL" in + *"Raspberry Pi"*) PQB_IS_RPI=1 ;; + esac + fi + export PQB_OS PQB_ARCH PQB_IS_RPI PQB_RPI_MODEL +} + +# ---- friendly logging ------------------------------------------------------ +pqb_log() { printf '\033[1;34m[pqb]\033[0m %s\n' "$*" >&2; } +pqb_warn() { printf '\033[1;33m[pqb WARN]\033[0m %s\n' "$*" >&2; } +pqb_err() { printf '\033[1;31m[pqb ERR]\033[0m %s\n' "$*" >&2; } + +# ---- hostname resolution --------------------------------------------------- +# A "good" host id is non-empty, not localhost, and not an avahi/macOS +# auto-assigned "unknown" placeholder (which is what shows up when no +# real hostname is set — that produced the ugly results filename before). +_pqb_good_host() { + local h="$1" + [ -n "$h" ] || return 1 + case "$h" in + localhost|localhost.*) return 1 ;; + esac + printf '%s' "$h" | grep -Eq '^[Uu]nknown[0-9a-fA-F]{6,}$' && return 1 + return 0 +} + +# Resolve a readable, stable host identifier, falling through: +# $HOSTNAME -> `hostname` -> hostnamectl --static (Linux) / +# scutil --get LocalHostName (macOS) -> short machine id (last resort). +# Domain suffixes (.home/.local/...) are stripped. On the RPi5 this yields the +# actual pi hostname; on this Mac it falls through to LocalHostName. +pqb_resolve_hostname() { + local cands=() c h + cands+=("${HOSTNAME:-}") + cands+=("$(hostname 2>/dev/null || true)") + if [ "${PQB_OS:-}" = "linux" ]; then + cands+=("$(hostnamectl --static 2>/dev/null || true)") + elif [ "${PQB_OS:-}" = "macos" ]; then + cands+=("$(scutil --get LocalHostName 2>/dev/null || true)") + fi + for c in "${cands[@]}"; do + h="${c%%.*}" # strip domain suffix + if _pqb_good_host "$h"; then echo "$h"; return 0; fi + done + # last resort: a short, stable machine id so files never collide as "unknown" + local mid="" + if [ -r /etc/machine-id ]; then + mid="$(cut -c1-12 /etc/machine-id 2>/dev/null)" + elif [ "${PQB_OS:-}" = "macos" ]; then + mid="$(ioreg -rd1 -c IOPlatformExpertDevice 2>/dev/null \ + | awk -F'"' '/IOPlatformUUID/{print $4}' | tr -d '-' | cut -c1-12)" + fi + echo "host-${mid:-unknown}" +} + +# ---- CPU governor ---------------------------------------------------------- +# Returns 0 if it set 'performance', 1 if unavailable. Prints the governor it +# left the system in on stdout. +pqb_set_governor_performance() { + if [ "$PQB_OS" = "linux" ] && [ -d /sys/devices/system/cpu/cpu0/cpufreq ]; then + local ok=1 g + for g in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do + [ -w "$g" ] || { ok=0; continue; } + echo performance > "$g" 2>/dev/null || ok=0 + done + if [ "$ok" = 1 ]; then + cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null + return 0 + fi + # try cpupower as a fallback (may need sudo) + if command -v cpupower >/dev/null 2>&1 && cpupower frequency-set -g performance >/dev/null 2>&1; then + echo performance; return 0 + fi + pqb_warn "could not set governor to performance (need root? try: sudo ./run.sh)" + cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null || echo "unknown" + return 1 + fi + # macOS / other: no userspace governor control. + echo "unavailable" + return 1 +} + +pqb_get_governor() { + if [ "$PQB_OS" = "linux" ] && [ -r /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ]; then + cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor + else + echo "unavailable" + fi +} + +# ---- core pinning ---------------------------------------------------------- +# pqb_taskset_prefix -> echoes a command prefix to pin to that core, or +# empty string if pinning is unavailable (caller warns). +pqb_taskset_prefix() { + local core="$1" + if command -v taskset >/dev/null 2>&1; then + echo "taskset -c $core" + elif command -v numactl >/dev/null 2>&1; then + echo "numactl --physcpubind=$core" + else + echo "" # no pinning available (e.g. macOS) + fi +} + +# ---- thermal / clock sampling ---------------------------------------------- +# pqb_sample_thermal -> one CSV line: epoch_s,arm_clock_hz,temp_c,throttled_hex +# Fields that cannot be read on a platform are emitted as empty (no fake zeros). +pqb_sample_thermal() { + local ts clk temp thr + ts="$(date +%s)" + clk=""; temp=""; thr="" + + if command -v vcgencmd >/dev/null 2>&1; then + # Raspberry Pi: authoritative SoC sensors. + clk="$(vcgencmd measure_clock arm 2>/dev/null | sed -n 's/.*=//p')" + temp="$(vcgencmd measure_temp 2>/dev/null | sed -n "s/temp=\([0-9.]*\).*/\1/p")" + thr="$(vcgencmd get_throttled 2>/dev/null | sed -n 's/.*=//p')" + elif [ "$PQB_OS" = "linux" ]; then + # Generic Linux fallback (cpufreq + thermal_zone). + local f + f=/sys/devices/system/cpu/cpu${PQB_BENCH_CORE:-0}/cpufreq/scaling_cur_freq + [ -r "$f" ] && clk="$(( $(cat "$f") * 1000 ))" # kHz -> Hz + if [ -r /sys/class/thermal/thermal_zone0/temp ]; then + local milli; milli="$(cat /sys/class/thermal/thermal_zone0/temp)" + temp="$(awk -v m="$milli" 'BEGIN{printf "%.1f", m/1000}')" + fi + fi + # macOS: live per-core freq/temp require sudo powermetrics; we intentionally + # leave them empty rather than emit misleading values. (Smoke test only.) + + printf '%s,%s,%s,%s\n' "$ts" "$clk" "$temp" "$thr" +} + +# pqb_throttled_active -> 0 if thermal throttling currently/has +# occurred, 1 otherwise. RPi get_throttled bit 0 = under-voltage now, +# bit 1 = arm freq capped now, bit 2 = currently throttled, +# bit 3 = soft temp limit active (and bits 16-19 = "has occurred" latches). +pqb_throttled_active() { + local hex="${1#0x}" + [ -z "$hex" ] && return 1 + local val=$(( 16#$hex )) + # bit2 (throttling now) or bit18 (throttling has occurred) + if [ $(( val & 0x4 )) -ne 0 ] || [ $(( val & 0x40000 )) -ne 0 ]; then + return 0 + fi + return 1 +} + +# ---- CPU feature / crypto-extension detection ------------------------------ +# Echoes a JSON object describing NEON + SHA3/SHA512 acceleration. Consumed +# verbatim by env metadata so results record whether Keccak accel is in use. +pqb_cpu_features_json() { + local neon=false sha2=false sha3=false sha512=false aes=false pmull=false src="unknown" + if [ "$PQB_OS" = "linux" ] && [ -r /proc/cpuinfo ]; then + src="/proc/cpuinfo" + local feats; feats="$(grep -m1 -i '^Features' /proc/cpuinfo | tr 'A-Z' 'a-z')" + case "$feats" in *" asimd"*|*"neon"*) neon=true;; esac + case "$feats" in *" sha2"*) sha2=true;; esac + case "$feats" in *" sha3"*) sha3=true;; esac + case "$feats" in *" sha512"*) sha512=true;; esac + case "$feats" in *" aes"*) aes=true;; esac + case "$feats" in *" pmull"*) pmull=true;; esac + elif [ "$PQB_OS" = "macos" ]; then + src="sysctl" + neon=true # all Apple Silicon has NEON/ASIMD + [ "$(sysctl -n hw.optional.arm.FEAT_SHA256 2>/dev/null)" = 1 ] && sha2=true + [ "$(sysctl -n hw.optional.arm.FEAT_SHA3 2>/dev/null)" = 1 ] && sha3=true + [ "$(sysctl -n hw.optional.arm.FEAT_SHA512 2>/dev/null)" = 1 ] && sha512=true + [ "$(sysctl -n hw.optional.arm.FEAT_AES 2>/dev/null)" = 1 ] && aes=true + [ "$(sysctl -n hw.optional.arm.FEAT_PMULL 2>/dev/null)" = 1 ] && pmull=true + fi + printf '{"source":"%s","neon":%s,"sha2":%s,"sha3":%s,"sha512":%s,"aes":%s,"pmull":%s}' \ + "$src" "$neon" "$sha2" "$sha3" "$sha512" "$aes" "$pmull" +} + +# ---- package installation -------------------------------------------------- +# pqb_install_build_deps -> installs compiler/cmake/openssl headers per platform. +pqb_install_build_deps() { + if [ "$PQB_OS" = "macos" ]; then + command -v brew >/dev/null 2>&1 || { pqb_err "Homebrew required on macOS: https://brew.sh"; return 1; } + pqb_log "installing build deps via Homebrew" + brew install cmake ninja openssl@3 git python3 >/dev/null || true + elif [ "$PQB_OS" = "linux" ]; then + if command -v apt-get >/dev/null 2>&1; then + pqb_log "installing build deps via apt" + local SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo" + $SUDO apt-get update -qq + # linux-cpupower provides the `cpupower` binary used by + # pqb_set_governor_performance. (Older releases shipped cpufrequtils, which + # was dropped in Debian 13/trixie — cpupower is the supported replacement.) + $SUDO apt-get install -y -qq \ + build-essential cmake ninja-build git python3 perl \ + libssl-dev pkg-config astyle doxygen \ + linux-cpupower util-linux >/dev/null + else + pqb_warn "no apt-get found; install cmake/ninja/gcc/libssl-dev manually" + fi + fi +} diff --git a/pq-bench-rpi5/setup/setup.sh b/pq-bench-rpi5/setup/setup.sh new file mode 100755 index 0000000..a34cad9 --- /dev/null +++ b/pq-bench-rpi5/setup/setup.sh @@ -0,0 +1,205 @@ +#!/usr/bin/env bash +# ============================================================================= +# setup.sh — build + pin the full PQ toolchain from scratch. +# +# ./setup/setup.sh # everything: deps, liboqs, openssl(if needed), oqs-provider +# ./setup/setup.sh liboqs # just liboqs +# ./setup/setup.sh openssl # just openssl (forced from source) +# ./setup/setup.sh provider # just oqs-provider +# ./setup/setup.sh deps # just OS packages +# +# Everything is installed under ./vendor/install (no system pollution). The exact +# resolved git commits + the optimization flags actually used are written to +# setup/versions.lock, which run.sh stamps into every results JSON. +# +# Identical flags for every candidate: -O3 -mcpu=cortex-a76 on the RPi5. On a +# non-A76 host (the macOS smoke box) we fall back to -O3 and RECORD that, so +# smoke-test numbers can never masquerade as the RPi5 baseline. +# ============================================================================= +set -euo pipefail + +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT="$(cd "$HERE/.." && pwd)" +# shellcheck source=setup/lib_platform.sh +source "$HERE/lib_platform.sh" +# shellcheck source=setup/versions.env +source "$HERE/versions.env" + +pqb_detect_platform + +VENDOR="$ROOT/vendor" +SRC="$VENDOR/src" +PREFIX="$VENDOR/install" +mkdir -p "$SRC" "$PREFIX" + +JOBS="$( (command -v nproc >/dev/null && nproc) || sysctl -n hw.ncpu 2>/dev/null || echo 4)" + +# ---- decide the real optimization flags for THIS host ---------------------- +# We only use -mcpu=cortex-a76 if the compiler accepts it AND we're on aarch64. +choose_cflags() { + local cc="${CC:-cc}" probe="$SRC/.flagprobe.c" + echo 'int main(void){return 0;}' > "$probe" + if [ "$PQB_ARCH" = "aarch64" ] && $cc $TARGET_CFLAGS_RPI5 "$probe" -o "$probe.out" 2>/dev/null; then + BENCH_CFLAGS="$TARGET_CFLAGS_RPI5"; CFLAGS_TARGET="cortex-a76" + else + BENCH_CFLAGS="$TARGET_CFLAGS_FALLBACK"; CFLAGS_TARGET="generic-fallback" + fi + rm -f "$probe" "$probe.out" +} + +cc_version_string() { + local cc="${CC:-cc}" + "$cc" --version 2>/dev/null | head -1 +} + +git_pin() { # repo ref destdir + local repo="$1" ref="$2" dest="$3" + if [ -d "$dest/.git" ]; then + pqb_log "updating $(basename "$dest") -> $ref" + git -C "$dest" fetch -q --depth 1 origin "$ref" || git -C "$dest" fetch -q --tags origin + else + pqb_log "cloning $(basename "$dest") @ $ref" + git clone -q --depth 1 --branch "$ref" "$repo" "$dest" 2>/dev/null \ + || git clone -q "$repo" "$dest" + fi + git -C "$dest" checkout -q "$ref" 2>/dev/null || true + git -C "$dest" rev-parse HEAD +} + +# --------------------------------------------------------------------------- +build_liboqs() { + choose_cflags + local dest="$SRC/liboqs" commit + commit="$(git_pin "$LIBOQS_REPO" "$LIBOQS_REF" "$dest")" + pqb_log "building liboqs ($LIBOQS_REF @ ${commit:0:12}) flags: $BENCH_CFLAGS" + + # OQS_DIST_BUILD=OFF -> native build for the fixed target (no runtime CPU + # dispatch), so -mcpu=cortex-a76 fully drives codegen. The AArch64-optimized + # ML-KEM (mlkem-native) and AArch64 asm backends are enabled by default on + # aarch64 when DIST_BUILD is OFF (compile-time CPU features); verified post-build. + local GEN=(); command -v ninja >/dev/null 2>&1 && GEN=(-G Ninja) + cmake -S "$dest" -B "$dest/build" ${GEN[@]+"${GEN[@]}"} \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DCMAKE_BUILD_TYPE=Release \ + -DOQS_DIST_BUILD=OFF \ + -DOQS_BUILD_ONLY_LIB=OFF \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_C_FLAGS="$BENCH_CFLAGS" >/dev/null + cmake --build "$dest/build" --parallel "$JOBS" >/dev/null + cmake --install "$dest/build" >/dev/null + + # Prove the optimized backend: capture the aarch64/native defines from the + # generated build config so versions.lock can show what was actually compiled. + local cfg="$dest/build/include/oqs/oqsconfig.h" + LIBOQS_OPT_DEFINES="(oqsconfig.h not found)" + if [ -r "$cfg" ]; then + # strip embedded double-quotes so the value stays valid in versions.lock + LIBOQS_OPT_DEFINES="$(grep -Ei 'AARCH64|ARM|_ASM|MLKEM_NATIVE|OPT_TARGET|CPU_EXT' "$cfg" \ + | grep -i 'define' | sed 's/^#define //' | tr -d '"' | tr '\n' ';' || true)" + fi + LIBOQS_COMMIT="$commit" +} + +# --------------------------------------------------------------------------- +locate_or_build_openssl() { + # Prefer an existing >= 3.5 openssl (Homebrew on macOS, distro on Linux) unless + # BUILD_OPENSSL=1. PQ sig certs for TLS only need >= 3.5.0. + local want_major=3 want_minor=5 + if [ "${1:-}" != "force" ] && [ "${BUILD_OPENSSL:-0}" != 1 ]; then + local cand + for cand in "$(command -v openssl || true)" /opt/homebrew/opt/openssl@3/bin/openssl /usr/bin/openssl; do + [ -x "$cand" ] || continue + local v; v="$("$cand" version 2>/dev/null | awk '{print $2}')" + # NB: assign on separate lines. A single `local a=.. b=.. c="${b..}"` makes + # bash 5.2 declare all names (unset) *before* expanding any RHS, so the + # reference to `rest` here trips `set -u` (unbound variable) on the Pi. + local maj rest min + maj="${v%%.*}"; rest="${v#*.}"; min="${rest%%.*}" + if [ "${maj:-0}" -gt "$want_major" ] 2>/dev/null || \ + { [ "${maj:-0}" -eq "$want_major" ] && [ "${min:-0}" -ge "$want_minor" ]; } 2>/dev/null; then + OPENSSL_BIN="$cand" + OPENSSL_PREFIX="$(dirname "$(dirname "$cand")")" + OPENSSL_COMMIT="system:$v" + pqb_log "using existing OpenSSL $v at $cand" + return 0 + fi + done + fi + pqb_log "building OpenSSL $OPENSSL_REF from source" + local dest="$SRC/openssl" commit + commit="$(git_pin "$OPENSSL_REPO" "$OPENSSL_REF" "$dest")" + ( cd "$dest" && ./Configure --prefix="$PREFIX" --openssldir="$PREFIX/ssl" shared \ + && make -j"$JOBS" >/dev/null && make install_sw >/dev/null ) + OPENSSL_BIN="$PREFIX/bin/openssl" + OPENSSL_PREFIX="$PREFIX" + OPENSSL_COMMIT="$commit" +} + +# --------------------------------------------------------------------------- +build_oqs_provider() { + [ -n "${OPENSSL_PREFIX:-}" ] || locate_or_build_openssl + local dest="$SRC/oqs-provider" commit + commit="$(git_pin "$OQSPROVIDER_REPO" "$OQSPROVIDER_REF" "$dest")" + pqb_log "building oqs-provider ($OQSPROVIDER_REF @ ${commit:0:12})" + local GEN=(); command -v ninja >/dev/null 2>&1 && GEN=(-G Ninja) + cmake -S "$dest" -B "$dest/build" ${GEN[@]+"${GEN[@]}"} \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DCMAKE_BUILD_TYPE=Release \ + -DOPENSSL_ROOT_DIR="$OPENSSL_PREFIX" \ + -Dliboqs_DIR="$PREFIX/lib/cmake/liboqs" \ + -DCMAKE_C_FLAGS="${BENCH_CFLAGS:-$TARGET_CFLAGS_FALLBACK}" >/dev/null + cmake --build "$dest/build" --parallel "$JOBS" >/dev/null + cmake --install "$dest/build" >/dev/null 2>&1 || true + # Provider .so lands under .../lib/ossl-modules or .../oqsprovider + OQSPROVIDER_MODULE="$(find "$PREFIX" "$dest/build" -name 'oqsprovider.*' \( -name '*.so' -o -name '*.dylib' \) 2>/dev/null | head -1)" + OQSPROVIDER_COMMIT="$commit" +} + +# --------------------------------------------------------------------------- +write_lock() { + choose_cflags 2>/dev/null || true + local lock="$HERE/versions.lock" + { + echo "# Auto-generated by setup.sh — exact toolchain provenance. Stamped into results JSON." + echo "PQB_BUILD_HOST_OS=$PQB_OS" + echo "PQB_BUILD_HOST_ARCH=$PQB_ARCH" + echo "PQB_IS_RPI=$PQB_IS_RPI" + echo "PQB_RPI_MODEL=\"${PQB_RPI_MODEL}\"" + echo "BENCH_CFLAGS=\"${BENCH_CFLAGS:-unknown}\"" + echo "CFLAGS_TARGET=\"${CFLAGS_TARGET:-unknown}\"" + echo "CC_VERSION=\"$(cc_version_string)\"" + echo "LIBOQS_REF=\"$LIBOQS_REF\"" + echo "LIBOQS_COMMIT=\"${LIBOQS_COMMIT:-not-built}\"" + echo "LIBOQS_OPT_DEFINES=\"${LIBOQS_OPT_DEFINES:-}\"" + echo "OPENSSL_BIN=\"${OPENSSL_BIN:-}\"" + echo "OPENSSL_PREFIX=\"${OPENSSL_PREFIX:-}\"" + echo "OPENSSL_COMMIT=\"${OPENSSL_COMMIT:-not-built}\"" + echo "OQSPROVIDER_REF=\"$OQSPROVIDER_REF\"" + echo "OQSPROVIDER_COMMIT=\"${OQSPROVIDER_COMMIT:-not-built}\"" + echo "OQSPROVIDER_MODULE=\"${OQSPROVIDER_MODULE:-}\"" + echo "PREFIX=\"$PREFIX\"" + } > "$lock" + pqb_log "wrote $lock" + cat "$lock" >&2 +} + +# ---- dispatch -------------------------------------------------------------- +main() { + local what="${1:-all}" + case "$what" in + deps) pqb_install_build_deps ;; + liboqs) build_liboqs; write_lock ;; + openssl) locate_or_build_openssl force; write_lock ;; + provider) build_oqs_provider; write_lock ;; + all) + pqb_install_build_deps + build_liboqs + locate_or_build_openssl + build_oqs_provider + write_lock + pqb_log "setup complete. Next: ./run.sh --smoke" + ;; + *) pqb_err "unknown target: $what (deps|liboqs|openssl|provider|all)"; exit 2 ;; + esac +} +main "$@" diff --git a/pq-bench-rpi5/setup/versions.env b/pq-bench-rpi5/setup/versions.env new file mode 100644 index 0000000..362d3c7 --- /dev/null +++ b/pq-bench-rpi5/setup/versions.env @@ -0,0 +1,40 @@ +# ============================================================================= +# Pinned upstream versions for the PQ benchmark toolchain. +# +# These are the *intended* refs. setup/setup.sh clones each at the tag below +# and then records the *actually resolved* commit hash into setup/versions.lock, +# which is stamped verbatim into every results JSON. That way a results file is +# always traceable to exact source, even if a tag is ever re-pointed upstream. +# +# Override any of these from the environment, e.g.: +# LIBOQS_REF=main ./setup/setup.sh +# ============================================================================= + +# liboqs: KEM/signature implementations. >= 0.15.0 ships the AArch64-optimized +# ML-KEM backend (mlkem-native). We enable it explicitly in setup.sh. +LIBOQS_REPO="${LIBOQS_REPO:-https://github.com/open-quantum-safe/liboqs.git}" +LIBOQS_REF="${LIBOQS_REF:-0.15.0}" + +# OpenSSL >= 3.5.0 — required for PQ signatures in TLS 1.3 server auth. +# On macOS dev boxes we prefer the Homebrew openssl@3 if it is already >= 3.5; +# setup.sh only builds OpenSSL from source when the system one is too old or +# BUILD_OPENSSL=1 is set. +OPENSSL_REPO="${OPENSSL_REPO:-https://github.com/openssl/openssl.git}" +OPENSSL_REF="${OPENSSL_REF:-openssl-3.5.0}" + +# oqs-provider >= 0.9.0 — wires liboqs algorithms into OpenSSL as a provider, +# giving us PQ KEM groups and PQ signature certs for the TLS layer. +OQSPROVIDER_REPO="${OQSPROVIDER_REPO:-https://github.com/open-quantum-safe/oqs-provider.git}" +OQSPROVIDER_REF="${OQSPROVIDER_REF:-0.9.0}" + +# Identical optimization flags for every candidate (the credibility anchor). +# cortex-a76 is the RPi5 core. On non-A76 hosts (e.g. the macOS smoke box) +# setup.sh substitutes a safe fallback and records which flags were *actually* +# used in versions.lock + results JSON, so smoke numbers are never mistaken for +# the RPi5 baseline. +TARGET_CFLAGS_RPI5="${TARGET_CFLAGS_RPI5:--O3 -mcpu=cortex-a76}" +TARGET_CFLAGS_FALLBACK="${TARGET_CFLAGS_FALLBACK:--O3}" + +# Pinned core for taskset on the RPi5 (4 cores: 0-3). Core 3 is chosen to stay +# away from CPU0 where the kernel tends to steer IRQs/RPS. Documented in README. +BENCH_CORE="${BENCH_CORE:-3}"