ant-quic 0.26.2

QUIC transport protocol with advanced NAT traversal for P2P networks
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
# ant-quic

**Pure Post-Quantum QUIC** transport with NAT traversal for P2P networks. Every node is symmetric - can connect AND accept connections.

[![Documentation](https://docs.rs/ant-quic/badge.svg)](https://docs.rs/ant-quic/)
[![Crates.io](https://img.shields.io/crates/v/ant-quic.svg)](https://crates.io/crates/ant-quic)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE-MIT)
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE-APACHE)

[![CI Status](https://github.com/dirvine/ant-quic/actions/workflows/ci.yml/badge.svg)](https://github.com/dirvine/ant-quic/actions/workflows/ci.yml)
[![Security Audit](https://github.com/dirvine/ant-quic/actions/workflows/security.yml/badge.svg)](https://github.com/dirvine/ant-quic/actions/workflows/security.yml)

## Key Features

- **🔐 Pure Post-Quantum Cryptography (v0.2)** - ML-KEM-768 + ML-DSA-65 ONLY - no classical fallback
- **Symmetric P2P Nodes** - Every node is identical: connect, accept, coordinate
- **Automatic NAT Traversal** - Per [draft-seemann-quic-nat-traversal-02]docs/rfcs/draft-seemann-quic-nat-traversal-02.txt
- **External Address Discovery** - Per [draft-ietf-quic-address-discovery-00]docs/rfcs/draft-ietf-quic-address-discovery-00.txt
- **Default-On Local Discovery** - First-party scoped mDNS is built in and enabled by default on non-loopback endpoints
- **Router-Assisted Reachability** - UPnP IGD is part of the implemented connectivity stack as a best-effort local-router port-mapping assist layer (enabled by default, disable with `--no-port-mapping`)
- **Assist Capability Hints** - Nodes advertise relay/bootstrap/coordinator willingness by default; peers still decide whether to use them
- **Pure PQC Raw Public Keys** - ML-DSA-65 authentication per [our specification]docs/rfcs/ant-quic-pqc-authentication.md
- **Zero Configuration Required** - Sensible defaults, just create and connect
- **Powered by [saorsa-pqc]https://crates.io/crates/saorsa-pqc** - NIST FIPS 203/204 compliant implementations

## Quick Start

```rust
use ant_quic::{P2pEndpoint, P2pConfig};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Create a P2P endpoint - PQC is always on
    let config = P2pConfig::builder()
        .known_peer("peer.example.com:9000".parse()?)
        .build()?;

    let endpoint = P2pEndpoint::new(config).await?;
    println!("Peer ID: {:?}", endpoint.peer_id());

    // Seed connectivity and address discovery through the unified path
    endpoint.connect_known_peers().await?;

    // Your external address may become known after seeded peer observation
    if let Some(addr) = endpoint.external_addr() {
        println!("External address: {}", addr);
    }

    // Best-effort router port mapping contributes an additional candidate when available
    if let Some(mapped) = endpoint.port_mapping_addr() {
        println!("Router-mapped address: {}", mapped);
    }

    Ok(())
}
```

## Architecture

ant-quic uses a **symmetric P2P model** where every node has identical capabilities:

```
┌─────────────┐         ┌─────────────┐
│   Node A    │◄───────►│   Node B    │
│  (peer)     │   QUIC  │  (peer)     │
│             │   PQC   │             │
└─────────────┘         └─────────────┘
       │                       │
       │    OBSERVED_ADDRESS   │
       │◄──────────────────────┤
       │                       │
       ├──────────────────────►│
       │    ADD_ADDRESS        │
       └───────────────────────┘
```

### No Roles - All Nodes Are Equal

In v0.13.0, we removed all role distinctions:
- No `EndpointRole::Client/Server/Bootstrap`
- No `NatTraversalRole` enum
- **Any peer can coordinate** NAT traversal for other peers
- **Any peer can report** your external address via OBSERVED_ADDRESS frames

The term "known_peers" replaces "bootstrap_nodes" - they're just addresses to connect to first. In practice, seeded known peers and refreshed runtime peers provide the initial address-observation context.

**PeerId vs SocketAddr**: `PeerId` is the durable peer identity. `SocketAddr`
is only a routing/contact hint and may change across NAT rebinding,
reconnects, or path migration. Persist coordinator/bootstrap knowledge by
`PeerId`, then update the latest known `SocketAddr` as reachability changes.

**Measure, don't trust**: capability hints are treated as unverified signals.
Peers are selected based on observed reachability and success rates, not
self-asserted roles.

### Three-Layer Design

1. **Protocol Layer**: QUIC + NAT traversal extension frames
2. **Integration APIs**: `P2pEndpoint`, `P2pConfig`
3. **Applications**: Binary, examples

## Pure Post-Quantum Cryptography (v0.2)

**ant-quic v0.2 uses PURE post-quantum cryptography** - no classical algorithms, no hybrid modes, no fallback.

This is a greenfield network with no legacy compatibility requirements.

### Algorithms

| Algorithm | Standard | Purpose | Security Level | IANA Code |
|-----------|----------|---------|----------------|-----------|
| **ML-KEM-768** | FIPS 203 | Key Exchange | NIST Level 3 (192-bit) | 0x0201 |
| **ML-DSA-65** | FIPS 204 | Digital Signatures | NIST Level 3 (192-bit) | 0x0905 |

### Powered by saorsa-pqc

ant-quic uses [saorsa-pqc](https://crates.io/crates/saorsa-pqc) for all PQC operations:

- **NIST FIPS 203/204 compliant** implementations
- **AVX2/AVX-512/NEON** hardware acceleration
- **Constant-time operations** for side-channel resistance
- **Extensively tested** against NIST Known Answer Tests (KATs)

```rust
use ant_quic::crypto::pqc::PqcConfig;

let pqc = PqcConfig::builder()
    .ml_kem(true)               // ML-KEM-768 key exchange
    .ml_dsa(true)               // ML-DSA-65 signatures
    .memory_pool_size(10)       // Memory pool for crypto ops
    .handshake_timeout_multiplier(2.0)  // PQC handshakes are larger
    .build()?;
```

### Why Pure PQC (No Hybrid)?

- **Greenfield Network** - No legacy systems to maintain compatibility with
- **Maximum Security** - No weak classical algorithms in the chain
- **Simpler Implementation** - One cryptographic path, fewer edge cases
- **Future-Proof** - All connections quantum-resistant from day one
- **NIST Standardized** - ML-KEM and ML-DSA are FIPS 203/204 standards

### Identity Model

- **32-byte PeerId** - SHA-256 hash of ML-DSA-65 public key (compact identifier for durable peer identity)
- **SocketAddr is not identity** - addresses are ephemeral reachability hints and must be treated as mutable contact metadata
- **ML-DSA-65 Authentication** - All TLS handshake signatures use pure PQC
- **ML-KEM-768 Key Exchange** - All key agreement uses pure PQC

See [docs/guides/pqc-security.md](docs/guides/pqc-security.md) for security analysis.

## NAT Traversal

NAT traversal is built into the QUIC protocol via extension frames, not STUN/TURN.
In addition, the connectivity architecture now treats **UPnP IGD** as a
best-effort local-router assist layer on compatible home networks. This is
additive: it can improve inbound reachability and yield a better external
candidate address, but native QUIC address discovery, hole punching, and MASQUE
relay fallback remain the core connectivity path.

### Connectivity Stack

1. **Router assist (UPnP IGD)** — best-effort local gateway port mapping on compatible home routers
2. **Native QUIC NAT traversal** — OBSERVED_ADDRESS + ADD_ADDRESS + PUNCH_ME_NOW
3. **MASQUE relay fallback** — last-resort reachability when direct paths still fail

### How It Works

1. **Connect to one or more known/runtime peers**
2. **A connected peer may observe your external address** from incoming packets
3. **That peer can send an OBSERVED_ADDRESS frame** back to you
4. **You may learn a public address candidate** and use it for later coordination
5. **Direct P2P connection may then be established** through NAT

### Extension Frames

| Frame | Type ID | Purpose |
|-------|---------|---------|
| `ADD_ADDRESS` | 0x3d7e90 (IPv4), 0x3d7e91 (IPv6) | Advertise candidate addresses |
| `PUNCH_ME_NOW` | 0x3d7e92 (IPv4), 0x3d7e93 (IPv6) | Coordinate hole punching timing |
| `REMOVE_ADDRESS` | 0x3d7e94 | Remove stale address |
| `OBSERVED_ADDRESS` | 0x9f81a6 (IPv4), 0x9f81a7 (IPv6) | Report external address to peer |

### Transport Parameters

| Parameter | ID | Purpose |
|-----------|---|---------|
| NAT Traversal Capability | 0x3d7e9f0bca12fea6 | Negotiates NAT traversal support |
| RFC-Compliant Frames | 0x3d7e9f0bca12fea8 | Enables RFC frame format |
| Address Discovery | 0x9f81a176 | Configures address observation |

### NAT Type Support

| NAT Type | Success Rate | Notes |
|----------|--------------|-------|
| Full Cone | >95% | Direct connection |
| Restricted Cone | 80-90% | Coordinated punch |
| Port Restricted | 70-85% | Port-specific coordination |
| Symmetric | 60-80% | Prediction algorithms |
| CGNAT | 50-70% | Relay fallback may be needed |

See [docs/NAT_TRAVERSAL_GUIDE.md](docs/NAT_TRAVERSAL_GUIDE.md) for detailed information.

## Raw Public Key Identity (v0.2)

Each node has a single ML-DSA-65 key pair for both identity and authentication:

```rust
// ML-DSA-65 keypair - used for everything
let (ml_dsa_pub, ml_dsa_sec) = generate_ml_dsa_65_keypair();

// PeerId = SHA-256(ML-DSA-65 public key) = 32 bytes
// Compact identifier for addressing and peer tracking
let peer_id = derive_peer_id_from_public_key(&ml_dsa_pub);
```

This follows our [Pure PQC Authentication specification](docs/rfcs/ant-quic-pqc-authentication.md).

### v0.2 Changes

- **Pure PQC Identity**: Single ML-DSA-65 key pair, no classical keys
- **32-byte PeerId**: SHA-256 hash of ML-DSA-65 public key (1952 bytes → 32 bytes)
- **ML-DSA-65 Authentication**: ALL TLS handshake signatures use pure PQC
- **No Classical Keys**: Ed25519 completely removed, pure ML-DSA-65 only

### Trust Model

- **TOFU (Trust On First Use)**: First contact stores ML-DSA-65 public key fingerprint
- **Rotation**: New keys must be signed by old key (continuity)
- **Channel Binding**: TLS exporter signed with ML-DSA-65 (pure PQC)
- **NAT/Path Changes**: Token binding uses (PeerId || CID || nonce)

## Installation

### From Crates.io

```bash
cargo add ant-quic
```

### Pre-built Binaries

Download from [GitHub Releases](https://github.com/dirvine/ant-quic/releases):
- Linux: `ant-quic-linux-x86_64`, `ant-quic-linux-aarch64`
- Windows: `ant-quic-windows-x86_64.exe`
- macOS: `ant-quic-macos-x86_64`, `ant-quic-macos-aarch64`

### From Source

```bash
git clone https://github.com/dirvine/ant-quic
cd ant-quic
cargo build --release
```

## Binary Usage

```bash
# Run as a symmetric peer (auto-seeds from default known peers if none are provided)
ant-quic --listen 0.0.0.0:9000

# Provide explicit known peers for initial connectivity and address discovery
ant-quic --listen 0.0.0.0:9000 --known-peers 1.2.3.4:9000 --known-peers 5.6.7.8:9000

# Connect to a specific address through the unified outbound connectivity path
ant-quic --listen 0.0.0.0:9000 --connect 5.6.7.8:9001

# Disable best-effort router port mapping on demand
ant-quic --listen 0.0.0.0:9000 --no-port-mapping

# Show your external address (discovered via connected peers)
ant-quic --listen 0.0.0.0:9000
# Output: External address: YOUR.PUBLIC.IP:PORT
```

`--connect` does **not** force a "direct-only" attempt. It uses the canonical address-based connect entrypoint, so the endpoint still applies its normal routing/orchestration behavior such as connection reuse, direct dialing, and fallback handling when applicable. Richer peer-oriented discovery behavior comes from `connect_known_peers()` and `connect_peer()`.

### Default Known Peers

If no `--known-peers` are specified, ant-quic automatically seeds connectivity from the default Saorsa Labs known peers:
- `saorsa-1.saorsalabs.com:9000`
- `saorsa-2.saorsalabs.com:9000`

These are ordinary symmetric peers running the same ant-quic software as everyone else. They are useful starting points for initial discovery, but they are not special protocol roles.

### Peer Cache

ant-quic maintains a local cache of discovered peers to improve startup time and resilience. The cache is stored under the platform cache directory:

| Platform | Cache Directory |
|----------|-----------------|
| **macOS** | `~/Library/Caches/ant-quic/` |
| **Linux** | `~/.cache/ant-quic/` |
| **Windows** | `%LOCALAPPDATA%\\ant-quic\\` |

The runtime manages the exact cache filename and format within that directory.

The cache includes:
- Peer IDs and socket addresses
- Connection quality scores (RTT, success rate)
- NAT type hints for traversal optimization
- Last-seen timestamps for freshness

The cache is automatically managed - stale entries are pruned and high-quality peers are prioritized for reconnection.

## API Reference

### Primary Types

| Type | Purpose |
|------|---------|
| `P2pEndpoint` | Main entry point for P2P networking |
| `P2pConfig` | Configuration builder |
| `P2pEvent` | Events from the endpoint |
| `PeerId` | 32-byte peer identifier |
| `PqcConfig` | Post-quantum crypto tuning |
| `NatConfig` | NAT traversal tuning |

### P2pEndpoint Methods

```rust
impl P2pEndpoint {
    // Creation
    async fn new(config: P2pConfig) -> Result<Self>;

    // Identity
    fn peer_id(&self) -> PeerId;
    fn local_addr(&self) -> Option<SocketAddr>;
    fn external_addr(&self) -> Option<SocketAddr>;
    fn all_external_addrs(&self) -> Vec<SocketAddr>;
    fn port_mapping_active(&self) -> bool;
    fn port_mapping_addr(&self) -> Option<SocketAddr>;

    // Connections
    async fn connect_known_peers(&self) -> Result<usize>;
    async fn connect_addr(&self, addr: SocketAddr) -> Result<PeerConnection>;
    async fn connect_peer(&self, peer: PeerId) -> Result<PeerConnection>;
    async fn connected_peers(&self) -> Vec<PeerConnection>;
    async fn accept(&self) -> Option<PeerConnection>;

    // Events
    fn subscribe(&self) -> broadcast::Receiver<P2pEvent>;

    // Statistics
    async fn stats(&self) -> EndpointStats;
}
```

`connect_addr()` is the canonical address-based connect entrypoint. It goes through the endpoint's normal routing/orchestration path, including connection reuse, direct dialing, and fallback handling when applicable. Richer peer-oriented discovery and identity-driven behavior comes from `connect_known_peers()` and `connect_peer()`.

### P2pConfig Builder

```rust
let config = P2pConfig::builder()
    .bind_addr("0.0.0.0:9000".parse()?)  // Local address
    .known_peer(addr1)                    // Add known peer
    .known_peers(vec![addr2, addr3])      // Add multiple
    .max_connections(100)                 // Connection limit
    .pqc(pqc_config)                      // PQC tuning
    .nat(nat_config)                      // NAT tuning
    .mtu(MtuConfig::pqc_optimized())      // MTU for PQC
    .build()?;
```

See [docs/API_GUIDE.md](docs/API_GUIDE.md) for the complete API reference.

## RFC Compliance

ant-quic implements these specifications:

| Specification | Status | Notes |
|---------------|--------|-------|
| [RFC 9000]docs/rfcs/rfc9000.txt | Full | QUIC Transport Protocol |
| [RFC 9001]docs/rfcs/rfc9001.txt | Full | QUIC TLS |
| [Pure PQC Auth]docs/rfcs/ant-quic-pqc-authentication.md | Full | Raw Public Keys + Pure PQC (v0.2) |
| [draft-seemann-quic-nat-traversal-02]docs/rfcs/draft-seemann-quic-nat-traversal-02.txt | Full | NAT Traversal |
| [draft-ietf-quic-address-discovery-00]docs/rfcs/draft-ietf-quic-address-discovery-00.txt | Full | Address Discovery |
| [FIPS 203]docs/rfcs/fips-203-ml-kem.pdf | Full | ML-KEM (via saorsa-pqc) |
| [FIPS 204]docs/rfcs/fips-204-ml-dsa.pdf | Full | ML-DSA (via saorsa-pqc) |

See [docs/review.md](docs/review.md) for detailed RFC compliance analysis.

## Performance

### Connection Establishment

| Metric | Value |
|--------|-------|
| Handshake (PQC) | ~50ms typical |
| Address Discovery | <100ms |
| NAT Traversal | 200-500ms |
| PQC Overhead | ~8.7% |

### Data Transfer (localhost)

| Metric | Value |
|--------|-------|
| Send Throughput | 267 Mbps |
| Protocol Efficiency | 96.5% |
| Protocol Overhead | 3.5% |

### Scalability

| Connections | Memory | CPU |
|-------------|--------|-----|
| 100 | 56 KB | Minimal |
| 1,000 | 547 KB | Minimal |
| 5,000 | 2.7 MB | Linear |

## System Requirements

- **Rust**: 1.88.0+ (Edition 2024)
- **OS**: Linux 3.10+, Windows 10+, macOS 10.15+
- **Memory**: 64MB minimum, 256MB recommended
- **Network**: UDP traffic on chosen port

## Documentation

- [API Guide]docs/API_GUIDE.md - Complete API reference
- [Symmetric P2P]docs/SYMMETRIC_P2P.md - Architecture explanation
- [NAT Traversal Guide]docs/NAT_TRAVERSAL_GUIDE.md - NAT traversal details
- [PQC Configuration]docs/guides/pqc-configuration.md - PQC tuning
- [Architecture]docs/architecture/ARCHITECTURE.md - System design
- [Troubleshooting]docs/TROUBLESHOOTING.md - Common issues

## Examples

```bash
# Simple chat application
cargo run --example simple_chat -- --listen 0.0.0.0:9000

# Chat with peer discovery
cargo run --example chat_demo -- --known-peers peer.example.com:9000

# Statistics dashboard
cargo run --example dashboard_demo
```

## Testing

```bash
# Run all tests
cargo test

# Run with verbose output
cargo test -- --nocapture

# Specific test categories
cargo test nat_traversal
cargo test pqc
cargo test address_discovery

# Run benchmarks
cargo bench
```

## Contributing

Contributions welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md).

```bash
# Development setup
git clone https://github.com/dirvine/ant-quic
cd ant-quic
cargo fmt --all
cargo clippy --all-targets -- -D warnings
cargo test
```

## License

Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE)
- MIT license ([LICENSE-MIT]LICENSE-MIT)

at your option.

## Acknowledgments

- Built on [Quinn]https://github.com/quinn-rs/quinn QUIC implementation
- **Pure PQC powered by [saorsa-pqc]https://crates.io/crates/saorsa-pqc** - NIST FIPS 203/204 compliant ML-KEM and ML-DSA
- NAT traversal per [draft-seemann-quic-nat-traversal-02]https://datatracker.ietf.org/doc/draft-seemann-quic-nat-traversal/
- Developed for the [Autonomi]https://autonomi.com decentralized network

## Security

For security vulnerabilities, please email security@autonomi.com rather than filing a public issue.