synta 0.1.6

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
# Introduction

This book documents benchmark results and performance analysis for the synta ASN.1
library. Results cover parsing throughput, field-access latency, language binding
overhead, container format extraction, CA store workloads, full PKI pipeline timings,
and ASN.1 primitive encode/decode costs.

## Test Environment

- **Hardware:** Lenovo ThinkPad P1 Gen 5, 12th Gen Intel(R) Core(TM) i7-12800H, 64 GB RAM
- **Platform:** Linux 6.15.8-200.fc42.x86_64
- **Benchmark tool:** Criterion.rs 0.8 (Rust); `time.perf_counter` with warmup (Python)
- **Samples:** 100 per benchmark (20 for whole-store benchmarks); 3 s warmup, 5 s measurement
- **Build:** `--release` with full optimizations
- **Test vectors:** PyCA cryptography PKITS (traditional RSA/ECDSA), IETF LAMPS (ML-DSA, ML-KEM), Mozilla CA roots (NSS), Common CA Database (CCADB)
- **Run date:** 2026-03-08 (library comparison, CA stores, primitives); 2026-04-07 (pipeline benchmarks)

## Benchmark Suites

Several benchmark suites cover different aspects of performance:

- **Library comparison** (`synta-bench/benches/comparison.rs`) — synta vs six other X.509
  parsing implementations (three pure-Rust, three C-backed) on identical input, measuring
  both parse-only and parse+all-fields operation profiles.
- **Element vs Typed API** (`synta-bench/benches/comparison_typed.rs`) — three parsing modes
  within synta itself: O(1) lazy `Element` capture, full recursive `Element` traversal, and
  typed `Certificate` decoding via derive macros.
- **Bindings overhead** (`synta-bench/benches/bindings.rs`) — the additional cost of each
  of synta's language binding layers (Rust typed, Rust element, C FFI) on top of the shared
  `synta-certificate` backend.
- **CA store benchmarks** (`synta-bench/benches/mozilla_ca_certs.rs`,
  `synta-bench/benches/ccadb_certs.rs`) — synta vs NSS, rust-openssl, and ossl on the
  real-world certificate stores shipped in production operating systems.
- **PKCS#7 and PKCS#12** (`synta-bench/benches/pkcs_formats.rs`) — certificate extraction
  from PKCS#7 SignedData and PKCS#12 PFX containers, with Python vs `cryptography` comparison.
- **ASN.1 primitives** (`synta-bench/benches/encoding.rs`,
  `synta-bench/benches/derive_performance.rs`,
  `synta-bench/benches/constrained_integers.rs`) — tag/length parsing, integer and
  OctetString encode/decode, derive macro overhead, and constrained-integer native types.
- **MTC pipeline** (`mtcbench` binary, `synta-bench/benches/mtc_hash.rs`,
  `synta-bench/benches/mtc_parse.rs`, `synta-bench/benches/mtc_verify.rs`,
  `synta-bench/benches/mtc_build.rs`) — end-to-end Merkle Tree Certificate issuance,
  Merkle tree construction, inclusion proof generation, and SQLite persistence.
- **X.509 PKI pipeline** (`x509bench` binary) — end-to-end X.509 certificate issuance,
  CRL construction, OCSP response signing, and SQLite persistence.
- **Python benchmark** (`python/bench_certificate.py`) — synta's PyO3 binding vs
  `cryptography.x509`. Run separately: `cd synta-python && maturin develop --release && cd ..
  && python python/bench_certificate.py`.

## Library Notes

The `ossl` crate is part of the [Kryoptic](https://github.com/latchset/kryoptic) project
and provides partial OpenSSL bindings; where its API does not cover what certificate parsing
needs, the benchmark falls back to direct unsafe C FFI into the library. `rust-openssl` is
separate, using the `openssl` crate's safe Rust bindings.

## Benchmark Methodology

### Setup

- **Tool:** Criterion.rs 0.8 (Rust), `time.perf_counter` (Python)
- **Criterion samples:** 100 per benchmark, 20 for whole-store benchmarks
- **Warmup:** 3 s; measurement window: 5 s (adaptive for whole-store)
- **Build:** `--release` profile, full optimisations, no debug symbols
- **CPU isolation:** benchmarks run on an otherwise idle system; no explicit CPU pinning

### Test Certificates

- **Traditional:** PyCA cryptography PKITS (RSA-2048/ECDSA, 914–968 bytes)
- **Post-quantum:** IETF LAMPS ML-DSA reference certs (3,992–7,479 bytes)
- **CA store:** Mozilla NSS `certdata.txt` (180 root CAs); CCADB V4 all-certs download
  (9,898 root + intermediate CAs, multiple decade-spanning CSV endpoints); ML-DSA synthetic
  CA hierarchy generated by `tests/vectors/generate_mldsa_certs.py` (9,889 certs mirroring
  the CCADB hierarchy with ML-DSA-65/87 signatures, requires OpenSSL 3.4+)

### Measurement Scope

| Benchmark                          | What is timed                                              | What is excluded                              |
| ---------------------------------- | ---------------------------------------------------------- | --------------------------------------------- |
| Library comparison (parse-only)    | DER decoding + ASN.1 struct population                     | File I/O, PEM decode, signature verification  |
| Library comparison (parse+fields)  | Parse + all named field reads                              ||
| Element vs Typed (lazy)            | Outer SEQUENCE tag+length only                             | Child element decoding                        |
| Element vs Typed (eager)           | Full recursive decode of all elements                      | File I/O, PEM decode                          |
| Element vs Typed (typed)           | Full RFC 5280 typed decode                                 | File I/O, PEM decode                          |
| Bindings overhead                  | Per binding layer parse / parse+fields                     ||
| PKCS#7/12 (Rust)                   | Certificate extraction from container (DER in, `Vec<DER>` out) | File I/O, signature verification          |
| PKCS#7/12 (Python)                 | `pem_to_der()` / `pkcs12_certs_from_der()` call           | File I/O                                      |
| CA store (whole-store)             | Iterating + parsing all certs in dataset                   | Dataset loading (done once before loop)       |
| CA store (per-cert)                | Single-cert parse, bytes hot in L1/L2                      ||
| Python parse-only                  | `Certificate.from_der()` call                              | GIL amortised over loop                       |
| Python parse+fields                | `from_der()` + all field accesses, new cert per iteration  ||
| Python field access (warm)         | All getters on a pre-parsed cert; caches already populated | Parse cost, first-access decode               |

### Reproducing

```bash
# Library comparison (parse-only + parse+fields, traditional + ML-DSA)
BENCH_COMPARE_FEATURES=bench-compare ./contrib/ci/local-ci.sh bench-compare

# Element vs Typed API (no extra feature flag needed)
cargo bench -p synta-bench --bench comparison_typed

# Bindings overhead (rust_typed, rust_element, c_ffi)
./contrib/ci/local-ci.sh bench-bindings

# CA store benchmarks with C library comparisons (CCADB and Mozilla)
BENCH_CA_FEATURES=bench-nss,bench-ossl,bench-openssl \
  ./contrib/ci/local-ci.sh bench-ca-roots

# ML-DSA synthetic CA hierarchy (generate first if not present)
python3 tests/vectors/generate_mldsa_certs.py   # requires OpenSSL 3.4+
SYNTA_CERT_DB=mldsa BENCH_CA_FEATURES=bench-nss,bench-ossl,bench-openssl \
  ./contrib/ci/local-ci.sh bench-ca-roots

# Python benchmark (X.509 certificate parsing)
cd synta-python && maturin develop --release && cd ..
python python/bench_certificate.py             # parse-only, parse+fields
python python/bench_certificate.py --per-field # also per-field getter breakdown

# Python benchmark (PKCS#7 / PKCS#12 certificate extraction)
python python/bench_pkcs.py

# ASN.1 primitive benchmarks (no extra feature flag needed)
cargo bench -p synta-bench --bench encoding
cargo bench -p synta-bench --bench derive_performance
cargo bench -p synta-bench --bench constrained_integers

# PKCS#7 and PKCS#12 Rust benchmark (no extra feature flag needed)
cargo bench -p synta-bench --bench pkcs_formats

# MTC pipeline operational benchmark
cargo build --release -p synta-bench --features bench-mtc-sqlite --bin mtcbench
./target/release/mtcbench bench --sizes 1,2,4,8,16,32,64,128,256,512,1024 --algos sha256

# X.509 PKI pipeline operational benchmark
cargo build --release -p synta-bench --features bench-x509-sqlite --bin x509bench
./target/release/x509bench bench --sizes 1,2,4,8,16,32,64,128,256,512,1024 --ca-key-algo ecdsa-p256
```

Criterion writes HTML reports to `target/criterion/`. Use `--show-results` with
`local-ci.sh` to display a summary table after the run completes.

## Memory Usage

- **Stack per parse:** ~2 KB (traditional certs), ~4 KB (post-quantum)
- **Heap allocations (parse-only):** zero for Distinguished Names, OIDs, BIT STRINGs, and
  OCTET STRINGs — all stored as borrowed slices from the input buffer
- **Heap allocations (parse+fields):** two `String` allocations for `format_dn()` (issuer
  and subject), plus string-type copies for string attributes within each DN
- **L1 cache hit rate:** > 95% for certificate parsing; the hot-cache per-cert benchmark
  (487–520 ns) is within 5% of the whole-store average (482–519 ns per cert)

## See Also

- [Post-Quantum OIDs]../../POST_QUANTUM_OIDS.md — post-quantum cryptography OID reference
- [synta-bench]https://codeberg.org/abbra/synta/src/branch/main/synta-bench — benchmark suite source and README
- [python/bench_certificate.py]https://codeberg.org/abbra/synta/src/branch/main/python/bench_certificate.py — Python X.509 certificate parsing benchmark script
- [python/bench_pkcs.py]https://codeberg.org/abbra/synta/src/branch/main/python/bench_pkcs.py — Python PKCS#7/12 benchmark script
- [python/bench_x509.py]https://codeberg.org/abbra/synta/src/branch/main/python/bench_x509.py — Python benchmark port of the cryptography test_x509.py suite