Expand description
§Post-quantum sealed boxes
DryocSealedBox encrypts a message to a recipient’s kem
public key so that only the holder of the matching secret key can read
it. Like DryocBox::seal, it is
anonymous: the sender needs no key pair, and the box does not identify the
sender. Unlike it, the key agreement uses X-Wing, the hybrid of ML-KEM-768
and X25519, so recorded boxes stay confidential even if a quantum computer
later breaks X25519.
Moving from DryocBox::seal takes two
changes: generate the recipient’s key pair with KeyPair from this
module (a kem key pair), and use DryocSealedBox in
place of DryocBox. The method names are the
same. Boxes are larger: 1136 bytes of overhead instead of 48.
§Format
The format is dryoc’s application profile of HPKE (RFC 9180),
which leaves the wire encoding to applications (section 10). The profile
is base mode, single-shot, with an empty info, empty associated data and
one fixed ciphersuite:
- KEM
0x647A, X-Wing, as defined by draft-connolly-cfrg-xwing-kem-11. The IANA registration cites -06; the draft’s test vectors are identical from -05 through -11. - KDF
0x0001, HKDF-SHA256. - AEAD
0x0003, ChaCha20-Poly1305.
A box is HPKE’s (enc, ct) output concatenated: enc (the 1120-byte
X-Wing ciphertext), then the AEAD ciphertext, then its 16-byte tag. The box
carries no suite identifier. Any HPKE implementation that supports this
ciphersuite can open it. The tests check the implementation against the
known-answer vector in draft-ietf-hpke-pq-05 Appendix A.5.
draft-ietf-hpke-hpke-04, the RFC 9180 revision in IESG review,
is backwards-compatible with RFC 9180 for this ciphersuite.
This byte format, written by DryocSealedBox::to_bytes (and to_vec)
and read by DryocSealedBox::from_bytes, is stable for the 2.x series. A
different ciphersuite or profile would be a new type, so existing boxes stay
readable.
With the serde feature,
serde::Deserialize and
serde::Serialize are implemented
for DryocSealedBox as a struct with the fields enc, tag and data,
in that order. That representation is separate from the byte format above;
use the byte format to exchange boxes with other HPKE implementations.
§Example
use dryoc::dryocsealedbox::*;
let recipient_keypair = StackKeyPair::generate();
let message = b"Now is the winter of our discontent.";
let sealed = DryocSealedBox::seal_to_vecbox(message, &recipient_keypair.public_key)
.expect("unable to seal");
// Serialize, send, and read the box back.
let bytes = sealed.to_vec();
let sealed = VecBox::from_bytes(&bytes).expect("unable to read box");
let decrypted = sealed
.open_to_vec(&recipient_keypair)
.expect("unable to open");
assert_eq!(message, decrypted.as_slice());Re-exports§
pub use crate::kem::xwing::KeyPair;pub use crate::kem::xwing::PublicKey;pub use crate::kem::xwing::SecretKey;pub use crate::kem::xwing::StackKeyPair;
Modules§
- protected
protected - Protected memory type aliases for
DryocSealedBox
Structs§
- Dryoc
Sealed Box - A post-quantum sealed box: an HPKE-encrypted message for one recipient.
Constants§
- SEALBYTES
- Bytes a sealed box adds to its message.
Type Aliases§
- Encapsulated
Key - Stack-allocated X-Wing ciphertext that carries the box’s key (HPKE’s
enc). - Mac
- Stack-allocated authentication tag.
- VecBox
alloc - Vec-based sealed box.