Skip to main content

Module dryocsealedbox

Module dryocsealedbox 

Source
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§

protectedprotected
Protected memory type aliases for DryocSealedBox

Structs§

DryocSealedBox
A post-quantum sealed box: an HPKE-encrypted message for one recipient.

Constants§

SEALBYTES
Bytes a sealed box adds to its message.

Type Aliases§

EncapsulatedKey
Stack-allocated X-Wing ciphertext that carries the box’s key (HPKE’s enc).
Mac
Stack-allocated authentication tag.
VecBoxalloc
Vec-based sealed box.