XWingPureDartAlgo class final

X-Wing: general-purpose hybrid post-quantum/traditional KEM combining X25519 and ML-KEM-768. Registered at IANA HPKE KEM id 0x647A.

Which document to cite

The construction originates in draft-connolly-cfrg-xwing-kem, an Independent Submission that CFRG never adopted and that expires on 2026-09-03; cite it for history only. The identity that does not lapse is the IANA code point, plus the CFRG research-group document draft-irtf-cfrg-concrete-hybrid-kems section 4.2, which states that its MLKEM768-X25519 "is identical to the X-Wing construction" and retains the same combiner label for compatibility.

The IANA registry row still reads X-Wing (referencing draft-connolly-cfrg-xwing-kem-06). draft-ietf-hpke-pq requests the rename to MLKEM768-X25519, and that request has not been effected, so the code point should not be described as registered under the new name.

Conformance is checked against the IETF HPKE working group's published 0x647A vectors — see test/hpke_wg_kem_vectors.dart. Go's standard library vendors the same file, so crypto/hpke.MLKEM768X25519() is an independent oracle for these bytes.

Interop note for other implementations: Bouncy Castle has carried X-Wing since 1.78, but releases 1.78 to 1.80 feed the combiner label first rather than last and so derive a different shared secret from the same inputs. 1.81 is the floor. Since X-Wing rejects implicitly, getting this wrong surfaces as an opaque AEAD authentication failure rather than a key error.

  • secret (decapsulation) key: a 32-byte seed, expanded on use via SHAKE-256 into the ML-KEM-768 (d, z) and the X25519 secret key
  • public (encapsulation) key: pk_M || pk_X (1184 + 32 = 1216 bytes)
  • ciphertext: ct_M || ct_X (1088 + 32 = 1120 bytes), where ct_X is the encapsulator's ephemeral X25519 public key
  • shared secret: SHA3-256(ss_M || ss_X || ct_X || pk_X || XWingLabel), 32 bytes

IND-CCA security holds if EITHER component survives — X25519 carries the classical guarantee while ML-KEM-768 carries the post-quantum one (harvest-now-decrypt-later resistance).

Pure-Dart composition of MlKem768PureDartAlgo (pqcrypto) and the cryptography package's X25519. Stateless — safe to share the single instance.

Implemented types
Mixed-in types

Properties

hashCode int
The hash code for this object.
no setterinherited
kemSeedDescription String
How a wrong-length diagnostic names this backend's seed, e.g. an X-Wing seed or an ML-KEM-768 seed (d || z).
no setteroverride
kemSeedLength int
This backend's seed length in bytes. Feeds newSeed and keyPairFromSeed; not part of the caller-facing contract.
no setteroverride
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

decapsulate(Uint8List secretKey, Uint8List ciphertext) Future<Uint8List>
Recover the shared secret from ciphertext using secretKey.
override
encapsulate(Uint8List publicKey) Future<({Uint8List ciphertext, Uint8List sharedSecret})>
Encapsulate a fresh shared secret against publicKey.
override
encapsulateDerand(Uint8List publicKey, Uint8List eseed) Future<({Uint8List ciphertext, Uint8List sharedSecret})>
Derandomized encapsulation per the draft's EncapsulateDerand: eseed[0:32] is the ML-KEM-768 randomness m, eseed[32:64] the ephemeral X25519 secret. Exists to verify the draft's test vectors; production callers use encapsulate.
generateKeyPair([Uint8List? seed]) Future<({Uint8List publicKey, Uint8List secretKey})>
Generate an X-Wing key pair.
override
keyPairFromSeed(Uint8List seed) FutureOr<({Uint8List publicKey, Uint8List secretKey})>
Deterministically regenerate the key pair that seed produces.
inherited
keyPairFromValidatedSeed(Uint8List seed) Future<({Uint8List publicKey, Uint8List secretKey})>
For X-Wing this is the same call as generateKeyPair with a seed — the secret key IS the seed — but callers that do not name the backend go through keyPairFromSeed, because that identity does not hold for ML-KEM.
override
newSeed() Uint8List
A fresh seed drawn from a secure random source, of whatever length this backend's keyPairFromSeed takes.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited

Constants

ciphertextLength → const int
instance → const XWingPureDartAlgo
publicKeyLength → const int
seedLength → const int
sharedSecretLength → const int