xhpke library

HPKE cryptography wrappers and parametrization.

https://datatracker.ietf.org/doc/html/rfc9180

Messages are encrypted to a public key with X-Wing, a hybrid of ML-KEM-768 and X25519, and sealed with ChaCha20-Poly1305. Encryption and decryption use an application domain, prefixed with dark-bio-v1:, which both sides must agree on. The ciphertext also authenticates a second message that must be supplied separately.

A Sender and Receiver pair shares one encapsulated key across many messages, which must be opened in the order they were sealed. The domain is fixed when the pair is created.

import 'dart:convert';

import 'package:darkbio_crypto/xhpke.dart' as xhpke;

void example() {
  final secret = xhpke.SecretKey.generate();
  final domain = utf8.encode('example');
  final header = utf8.encode('header');

  final (encapKey, ciphertext) = secret.publicKey().seal(msgToSeal: utf8.encode('secret'), msgToAuth: header, domain: domain);
  final plaintext = secret.open(sessionKey: encapKey, msgToOpen: ciphertext, msgToAuth: header, domain: domain);
  assert(utf8.decode(plaintext) == 'secret');

  // Many messages under one encapsulated key, opened in the order sealed
  final (sender, senderKey) = secret.publicKey().newSender(domain: domain);
  final receiver = secret.newReceiver(encapKey: senderKey, domain: domain);
  final message = sender.seal(msgToSeal: utf8.encode('first'), msgToAuth: header);
  assert(utf8.decode(receiver.open(msgToOpen: message, msgToAuth: header)) == 'first');
}

Classes

Fingerprint
A 256-bit unique identifier for an xHPKE key.
PublicKey
An X-Wing public key for encrypting HPKE messages.
Receiver
A stateful HPKE receiver context for multi-message decryption.
SecretKey
An X-Wing private key for decrypting HPKE messages.
Sender
A stateful HPKE sender context for multi-message encryption.