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
//! Post-quantum hybrid key-exchange group recognition (issue #135).
//!
//! Modern browsers negotiate a *hybrid* key exchange that combines
//! a classical curve (X25519 / P-256) with a post-quantum KEM
//! (ML-KEM, formerly Kyber). The PQ public value is ~1.1 KiB, which
//! pushes the ClientHello past a single TCP segment / QUIC Initial —
//! the motivating case for ClientHello reassembly. Recognising the
//! group codepoint turns "the CH is suspiciously large" into a
//! first-class, named signal.
//!
//! # Example
//!
//! ```
//! use flowscope::tls::{is_pq_hybrid_group, pq_hybrid_group_name};
//!
//! // X25519MLKEM768 — the Chrome 131+ / Firefox default.
//! assert!(is_pq_hybrid_group(0x11ec));
//! assert_eq!(pq_hybrid_group_name(0x11ec), Some("X25519MLKEM768"));
//!
//! // Classical X25519 is not a PQ hybrid.
//! assert!(!is_pq_hybrid_group(0x001d));
//! assert_eq!(pq_hybrid_group_name(0x001d), None);
//! ```
/// `true` if `group` is a known post-quantum **hybrid**
/// key-exchange named group (IANA TLS Supported Groups).
///
/// Covers the deployed families as of 2026:
///
/// | Codepoint | Group | Notes |
/// |---|---|---|
/// | `0x11ec` | `X25519MLKEM768` | Chrome 131+ / Firefox default since late 2024 (final ML-KEM codepoint) |
/// | `0x11eb` | `SecP256r1MLKEM768` | P-256 hybrid |
/// | `0x11ed` | `SecP384r1MLKEM1024` | P-384 hybrid |
/// | `0x6399` | `X25519Kyber768Draft00` | pre-standard Chrome / Cloudflare rollout |
/// | `0x639a` | `SecP256r1Kyber768Draft00` | pre-standard P-256 hybrid |
/// | `0xfe30`–`0xfe3f` | OQS experimental hybrids | liboqs interop range |
///
/// Pure-PQ (non-hybrid) groups are intentionally excluded — no
/// browser ships them and their presence is a different signal.
/// Human-readable name for a known PQ hybrid group, or `None` if
/// `group` isn't a recognised PQ hybrid. Useful for logs / metric
/// labels.