synta 0.1.12

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

This page documents the performance comparison benchmark between **synta** and three widely-used
X.509 parsing libraries in the Rust ecosystem: **x509-parser**, **x509-cert** (RustCrypto), and
**cryptography-x509** (PyCA).

The comparison benchmark (`synta-bench/benches/comparison.rs`) tests all four libraries parsing
the same real-world X.509 certificates, providing an apples-to-apples performance comparison.

## What Is Compared

- **synta**: ASN.1 library with focus on performance and zero-copy parsing
- **x509-parser**: Established X.509 parser built on `nom`, widely used in Rust projects
- **x509-cert**: RustCrypto's pure Rust X.509 implementation using the `der` crate
- **cryptography-x509**: PyCA's X.509 implementation using the `asn1` crate

## Running the Comparison Benchmark

The comparison benchmark requires the `bench-compare` feature to activate its
external library dependencies (x509-parser, x509-cert, cryptography-x509, ossl,
pem, asn1). Without the feature flag, Cargo skips the benchmark to keep those
heavy dependencies out of regular builds and example linking.

```bash
cargo bench -p synta-bench --bench comparison --features bench-compare
```

For specific sub-benchmarks:

```bash
# Traditional certificates only
cargo bench -p synta-bench --bench comparison --features bench-compare -- synta_vs_x509_parser

# Post-quantum only
cargo bench -p synta-bench --bench comparison --features bench-compare -- post_quantum_comparison

# Scalability analysis only
cargo bench -p synta-bench --bench comparison --features bench-compare -- scalability

# Add NSS and rust-openssl for format and format_fields groups
cargo bench -p synta-bench --bench comparison --features bench-compare,bench-nss,bench-openssl
```

## What Makes synta Fast

### 1. Zero-Copy Parsing

- synta uses cursor-based decoder that avoids data copying
- Direct references to input buffer where possible
- Minimal allocations during parsing

### 2. SmallVec Optimization

- Integers up to 16 bytes stored on stack
- OIDs up to 8 components stored on stack
- Only allocates heap when necessary

### 3. Efficient Tag/Length Parsing

- Optimized tag parsing (~6–7 ns per tag)
- Single-pass length decoding
- No backtracking

### 4. Compile-Time Optimizations

- Derive macros generate optimal code
- No dynamic dispatch where avoidable
- Aggressive inlining of hot paths

## Library Profiles

### x509-parser

**Strengths:**
- Mature, battle-tested library
- Built on nom parser combinator framework
- Good error messages
- Well-documented

**Characteristics:**
- Parser combinator approach (nom)
- Focus on correctness and ease of use
- Widely used in production

### x509-cert (RustCrypto)

**Strengths:**
- Part of the RustCrypto ecosystem
- Pure Rust implementation
- Built on the `der` crate
- Modern, actively maintained

**Characteristics:**
- Low-level DER encoding/decoding approach
- Focus on correctness and security
- Growing adoption in crypto-focused projects

### cryptography-x509 (PyCA)

**Strengths:**
- Part of the PyCA cryptography project
- Widely used in Python ecosystem (via FFI)
- Built on the `asn1` crate
- Production-proven implementation

**Characteristics:**
- Uses custom `asn1` crate for parsing
- Designed for Python/Rust interop
- Focus on compatibility and correctness

## Fairness of Comparison

All four libraries:
- Parse complete X.509 certificates
- Validate structure and encoding
- Support standard certificate features
- Return parsed ASN.1 structures

The benchmark does **not** compare:
- Cryptographic verification (none of these libraries do this)
- Certificate validation logic (policy, chains, etc.)
- Memory usage
- Error message quality

The benchmark uses the same certificate files for all libraries, measures only
parsing time (not I/O), and uses Criterion.rs for fair measurement.

## Measured Performance (2026-03-12)

### Traditional Certificates — Parse Only

Average over 5 PyCA PKITS test certificates (914–968 bytes):

| Library | Parse Time | Throughput | Ranking |
|---------|-----------|------------|---------|
| **synta** | **0.43 µs** | **>2M/sec** | **1st** |
| cryptography-x509 | 1.45 µs | ~690K/sec | 2nd |
| x509-parser | 2.00 µs | ~500K/sec | 3rd |
| x509-cert | 3.17 µs | ~315K/sec | 4th |
| ossl | 16.9 µs | ~59K/sec | 5th |

### Traditional Certificates — Parse + All Fields

Accessing: serial, issuer DN, subject DN, signature OID, signature bytes, notBefore,
notAfter, public key OID, public key bytes, version.

| Library | Parse+Fields | Ranking |
|---------|-------------|---------|
| **synta** | **1.30 µs** | **1st** |
| cryptography-x509 | 1.47 µs | 2nd |
| x509-parser | 2.07 µs | 3rd |
| x509-cert | 3.34 µs | 4th |
| ossl | 16.8 µs | 5th |

synta's parse+fields uses `format_dn` (direct DER walk, no SequenceOf construction) and
`identify_*` (zero-allocation `&'static str` return).

### Traditional Certificates — Field-Level String Formatting

Parse + format issuer DN, subject DN, signature OID, not-before, not-after as strings.
Average over 5 PyCA PKITS test certificates (914–968 bytes):

| Library | Time | vs synta |
|---------|------|----------|
| **synta** | **~1.55 µs** | baseline |
| x509-parser | ~3.95 µs | ~2.5× slower |
| NSS | ~8.45 µs | ~5.5× slower |
| x509-cert | ~11.35 µs | ~7.3× slower |
| rust-openssl | ~18.20 µs | ~11.7× slower |

### Post-Quantum (ML-DSA) Certificates — Parse Only

| Certificate | Size | synta | cryptography-x509 | x509-parser | x509-cert | ossl |
|-------------|------|-------|-------------------|-------------|-----------|------|
| ML-DSA-44 | 3,992 B | **0.43 µs** | 1.25 µs | 1.66 µs | 2.71 µs | 15.40 µs |
| ML-DSA-65 | 5,521 B | **0.42 µs** | 1.27 µs | 1.67 µs | 2.75 µs | 17.33 µs |
| ML-DSA-87 | 7,479 B | **0.42 µs** | 1.25 µs | 1.68 µs | 2.80 µs | 18.69 µs |

synta's parse-only time is **size-independent** — the large ML-DSA signature BIT STRING is
captured as a zero-copy borrowed slice (`BitStringRef<'a>`) during parse.

### Post-Quantum (ML-DSA) Certificates — Parse + All Fields

| Certificate | Size | synta | cryptography-x509 | x509-parser | x509-cert | ossl |
|-------------|------|-------|-------------------|-------------|-----------|------|
| ML-DSA-44 | 3,992 B | **1.03 µs** | 1.28 µs | 1.69 µs | 2.91 µs | 16.14 µs |
| ML-DSA-65 | 5,521 B | **1.03 µs** | 1.26 µs | 1.79 µs | 2.94 µs | 17.36 µs |
| ML-DSA-87 | 7,479 B | **1.00 µs** | 1.25 µs | 1.73 µs | 2.93 µs | 18.89 µs |

### Post-Quantum (ML-DSA) Certificates — Field-Level String Formatting

| Library | ML-DSA-44 | ML-DSA-65 | ML-DSA-87 | vs synta (avg) |
|---------|-----------|-----------|-----------|----------------|
| **synta** | **1.32 µs** | **1.29 µs** | **1.31 µs** | baseline |
| x509-parser | 3.34 µs | 3.22 µs | 3.40 µs | ~2.5× slower |
| NSS | 7.62 µs | 7.80 µs | 7.75 µs | ~5.9× slower |
| x509-cert | 8.22 µs | 8.10 µs | 8.25 µs | ~6.3× slower |
| rust-openssl | 15.87 µs | 17.25 µs | 18.75 µs | ~13.5× slower |

synta is *faster on ML-DSA certs than on traditional certs* (~1.30 µs vs ~1.55 µs) because
`format_dn` and the timestamp Display traits process only the name and time bytes — they never
touch the large public key. All other libraries parse the full certificate first, so their
cost grows with cert size.

### Scalability (Parse Only)

Three representative certificate sizes from the PyCA PKITS corpus:

| Size | synta | x509-parser | x509-cert | cryptography-x509 | ossl |
|------|-------|-------------|-----------|-------------------|------|
| Small (914 B) | **0.45 µs** | 2.01 µs | 3.23 µs | 1.50 µs | 17.36 µs |
| Medium (933 B) | **0.45 µs** | 3.26 µs | 3.76 µs | 1.70 µs | 17.76 µs |
| Large (968 B) | **0.46 µs** | 2.96 µs | 3.93 µs | 1.63 µs | 17.59 µs |

synta is essentially flat (0.45–0.46 µs, +2% over a 6% size increase). x509-parser scales
with size (+47%) — nom parsers read content proportionally.

## Conclusion

synta leads in all measured categories:

**Parse-only:**
- synta (0.43 µs) is 3.4× faster than cryptography-x509, 4.7× faster than x509-parser
- `RawDer` lazy Names eliminate the dominant parse cost: issuer/subject stored as borrowed
  byte spans, no decode, no allocation
- synta's parse time is size-independent — 7 KB ML-DSA certs parse as fast as 900 B
  traditional certs

**Parse + all fields:**
- synta (1.30 µs traditional, 1.02 µs ML-DSA) leads by: `format_dn` direct DER walk,
  `identify_*` returning `&'static str` (zero allocation), and count_elements skip-only scan
  deferring element decode to access time

**Field-level string formatting:**
- synta (~1.55 µs traditional, ~1.30 µs ML-DSA) is 2.5–13.5× faster depending on competitor
- synta is *faster on ML-DSA certs* because `format_dn` and Display traits process only
  name/time bytes — they never touch the large public key

**When to choose synta:**
- **Parse-only throughput** (TLS chain checking, CT log scanning, bulk filtering): fastest by 3.4×
- **Parse + all fields**: 1st in both traditional and ML-DSA
- **Field formatting** (log identity fields, display cert details): 2.5–13.5× faster
- **Pure Rust** with no C dependencies: fastest in every category

All benchmark groups:
- `library_comparison` — parse-only, traditional certs
- `post_quantum_comparison` — parse-only, ML-DSA certs
- `library_comparison_fields` — parse+fields, traditional certs
- `post_quantum_comparison_fields` — parse+fields, ML-DSA certs
- `scalability` — parse-only, three size classes
- `library_comparison_format` — whole-cert text formatting, traditional certs
- `post_quantum_comparison_format` — whole-cert text formatting, ML-DSA certs
- `library_comparison_format_fields` — field-level string formatting, traditional certs
- `post_quantum_comparison_format_fields` — field-level string formatting, ML-DSA certs

Results are saved to `target/criterion/`.

> Note: Benchmark results may vary based on hardware and workload. Run your own benchmarks
> with your specific use case for the most accurate comparison.