synta 0.1.6

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
# Classic vs Post-Quantum Crypto

ECDSA P-256 vs ML-DSA-65 across the full batch-size sweep (1–1024) on the
same machine. Both use the same algorithm for CA and subscriber keys.
ML-DSA-65 certificates are ~5.5 KB vs ~900 B for P-256.

`cert_gen` builds TBS once using the cached `sig_alg_der`, signs with
`sign_tbs_erased`, and assembles — the TBS DER (which embeds the ~2.5 KB
ML-DSA-65 SPKI) is encoded exactly once per certificate.

## cert_gen — certificate issuance (subscriber keygen + CA sign)

| Batch | P-256 ms | P-256 K/s | ML-DSA-65 ms | ML-DSA-65 K/s | Ratio |
|------:|---------:|----------:|-------------:|--------------:|------:|
|     1 |    0.600 |     1.7 K |        1.714 |         0.6 K |  2.9× |
|     2 |    0.255 |     7.8 K |        2.378 |         0.8 K |  9.3× |
|     4 |    0.204 |    19.6 K |        1.394 |         2.9 K |  6.8× |
|     8 |    0.313 |    25.6 K |        2.528 |         3.2 K |  8.1× |
|    16 |    0.306 |    52.2 K |        3.521 |         4.5 K | 11.5× |
|    32 |    0.459 |    69.8 K |        6.932 |         4.6 K | 15.1× |
|    64 |    0.532 |   120.3 K |       15.952 |         4.0 K | 30.0× |
|   128 |    0.752 |   170.1 K |       16.082 |         8.0 K | 21.4× |
|   256 |    3.704 |    69.1 K |       23.024 |        11.1 K |  6.2× |
|   512 |    4.510 |   113.5 K |       44.852 |        11.4 K |  9.9× |
|  1024 |    7.354 |   139.2 K |      107.927 |         9.5 K | 14.7× |

## cert_verify — certificate signature verification

| Batch | P-256 ms | P-256 K/s | ML-DSA-65 ms | ML-DSA-65 K/s | Ratio |
|------:|---------:|----------:|-------------:|--------------:|------:|
|     1 |    0.274 |     3.6 K |        0.317 |         3.2 K |  1.2× |
|     4 |    0.203 |    19.7 K |        0.278 |        14.4 K |  1.4× |
|    16 |    0.185 |    86.3 K |        0.331 |        48.4 K |  1.8× |
|    64 |    1.279 |    50.0 K |        1.941 |        33.0 K |  1.5× |
|   256 |    5.049 |    50.7 K |        3.764 |        68.0 K |  0.7× |
|  1024 |    8.004 |   127.9 K |       17.310 |        59.2 K |  2.2× |

## ocsp_sign — OCSP response signing (N parallel responses)

| Batch | P-256 ms | P-256 K/s | ML-DSA-65 ms | ML-DSA-65 K/s | Ratio |
|------:|---------:|----------:|-------------:|--------------:|------:|
|     1 |    0.032 |    31.4 K |        0.505 |         2.0 K | 15.9× |
|     4 |    0.165 |    24.2 K |        1.861 |         2.1 K | 11.3× |
|    16 |    0.227 |    70.6 K |        4.465 |         3.6 K | 19.7× |
|    64 |    0.241 |   265.1 K |       10.259 |         6.2 K | 42.5× |
|   256 |    1.109 |   230.9 K |       19.109 |        13.4 K | 17.2× |
|  1024 |    2.438 |   420.0 K |       77.121 |        13.3 K | 31.6× |

## ocsp_verify — OCSP response verification

| Batch | P-256 ms | P-256 K/s | ML-DSA-65 ms | ML-DSA-65 K/s | Ratio |
|------:|---------:|----------:|-------------:|--------------:|------:|
|     1 |    0.089 |    11.2 K |        0.138 |         7.2 K |  1.5× |
|     4 |    0.239 |    16.7 K |        0.280 |        14.3 K |  1.2× |
|    16 |    0.529 |    30.2 K |        0.398 |        40.2 K |  0.8× |
|    64 |    2.000 |    32.0 K |        2.011 |        31.8 K |  1.0× |
|   256 |    5.343 |    47.9 K |        4.496 |        56.9 K |  0.8× |
|  1024 |    8.881 |   115.3 K |       15.491 |        66.1 K |  1.7× |

## crl_sign — CRL signing (1 CRL per batch, N revoked serials)

| Batch | P-256 ms | P-256 K/s | ML-DSA-65 ms | ML-DSA-65 K/s | Ratio |
|------:|---------:|----------:|-------------:|--------------:|------:|
|     1 |    0.031 |    32.5 K |        0.261 |         3.8 K |  8.5× |
|     8 |    0.041 |    24.5 K |        0.261 |         3.8 K |  6.4× |
|    64 |    0.243 |     4.1 K |        0.754 |         1.3 K |  3.1× |
|   256 |    0.132 |     7.6 K |        1.622 |         0.6 K | 12.3× |
|  1024 |    0.439 |     2.3 K |        1.495 |         0.7 K |  3.4× |

## db_insert_certs / db_read_certs — SQLite I/O

| Batch | P-256 ins ms | ML-DSA ins ms | Ins ratio | P-256 rd ms | ML-DSA rd ms | Rd ratio |
|------:|-------------:|--------------:|----------:|------------:|-------------:|---------:|
|     1 |        0.043 |         0.045 |      1.1× |       0.030 |        0.030 |     1.0× |
|    16 |        0.086 |         0.195 |      2.3× |       0.037 |        0.075 |     2.0× |
|    64 |        0.637 |         1.356 |      2.1× |       0.225 |        0.622 |     2.8× |
|   256 |        1.012 |         4.658 |      4.6× |       0.615 |        0.478 |     0.8× |
|  1024 |        4.077 |        16.688 |      4.1× |       0.613 |        2.760 |     4.5× |

## Analysis

**Signing (cert_gen, ocsp_sign)** shows the largest asymmetry, with high
variability across batch sizes driven by Rayon scheduling:

- At **small batches (1–8)**, P-256 operations finish before the Rayon thread
  pool is fully loaded, so the ratio is relatively low (3–10×).
- At **medium batches (16–64)**, P-256 saturates the thread pool first and
  benefits from full parallelism while ML-DSA-65 is still ramping up —
  producing the highest ratios (15–42× for `ocsp_sign`, 11–30× for `cert_gen`).
- At **large batches (256–1024)**, ML-DSA-65 also saturates the pool, and the
  ratio settles in the 10–20× range for signing operations.

`cert_gen` ratios are lower than `ocsp_sign` ratios at the same batch size
because `cert_gen` bundles subscriber key generation (which is faster for
both algorithms) with CA signing, diluting the signing cost.

**Verification (cert_verify, ocsp_verify)** shows a fundamentally different
picture — ML-DSA-65 and P-256 are within 1–2× across all batch sizes:

- This reflects a core ML-DSA property: signing requires expensive lattice
  sampling (slow), while verification is a single NTT-based matrix-vector
  check (fast). ECDSA has more symmetric sign/verify costs.
- At batch=256 both `cert_verify` and `ocsp_verify` show ML-DSA-65 *faster*
  than P-256 (0.7–0.8× ratio) — Rayon scheduling noise at this batch size.

**DER payload size effect (db_insert_certs, db_read_certs):**

- Insert cost scales with DER size: ML-DSA-65 certs are ~6× larger (5.5 KB
  vs ~900 B), and the insert ratio grows from 1.1× at batch=1 to ~4.1–4.6×
  at batch=512–1024 as WAL write volume dominates.
- Read cost shows a similar but noisier pattern; at batch=256 ML-DSA-65 reads
  faster than P-256 (SQLite page-cache effect at this specific data size).

**CRL signing** ratios are noisy (only one signing operation per batch,
no Rayon parallelism): 3–12× depending on batch size. At large batches
(64–1024) the TBS DER encoding cost grows proportionally (more revoked serial
entries), gradually reducing the signing-time fraction for P-256 and narrowing
the ratio to 3–4×.