A TypeScript Hybrid Public Key Encryption (HPKE)
implementation build on top of Web Cryptography API.
This module works on web browsers, Node.js, Deno and various other JavaScript runtimes.
Documentation: jsr.io | pages (only for the latest ver.)
For Node.js, you can install @hpke/core
and other extensions via npm, yarn,
pnpm or jsr:
# Using npm:
npm install @hpke/core
yarn add @hpke/core
pnpm install @hpke/core
# Using jsr:
npx jsr add @hpke/core
yarn dlx jsr add @hpke/core
pnpm dlx jsr add @@hpke/core
npm install @hpke/core
Following extensions can be installed in the same manner:
@hpke/chacha20poly1305
@hpke/dhkem-x25519
@hpke/dhkem-x448
@hpke/dhkem-secp256k1
@hpke/hybridkem-x25519-kyber768
@hpke/hybridkem-x-wing
@hpke/ml-kem
Then, you can use it as follows:
import {
Aes128Gcm,
CipherSuite,
DhkemP256HkdfSha256,
HkdfSha256,
} from "@hpke/core";
async function doHpke() {
const suite = new CipherSuite({
kem: new DhkemP256HkdfSha256(),
kdf: new HkdfSha256(),
aead: new Aes128Gcm(),
});
// A recipient generates a key pair.
const rkp = await suite.kem.generateKeyPair();
// A sender encrypts a message with the recipient public key.
const sender = await suite.createSenderContext({
recipientPublicKey: rkp.publicKey,
});
const ct = await sender.seal(new TextEncoder().encode("Hello world!"));
// The recipient decrypts it.
const recipient = await suite.createRecipientContext({
recipientKey: rkp.privateKey,
enc: sender.enc,
});
const pt = await recipient.open(ct);
// Hello world!
console.log(new TextDecoder().decode(pt));
}
try {
doHpke();
} catch (e) {
console.log("failed:", e.message);
}
- Packages
- Supported Features
- Supported Environments
- Warnings and Restrictions
- Contributing
- References
The hpke-js includes the following packages.
name | registry | description |
---|---|---|
@hpke/core | The HPKE core module implemented using only Web Cryptography API. It does not support the X25519/X448-based KEMs and the ChaCha20/Poly1305 AEAD, but it has no external module dependencies. It's small in size and tree-shaking friendly. README / samples |
|
@hpke/chacha20poly1305 | The HPKE module extension for ChaCha20Poly1305 AEAD. README / samples |
|
@hpke/dhkem-x25519 | The HPKE module extension for DHKEM(X25519, HKDF-SHA256). README / samples |
|
@hpke/dhkem-x448 | The HPKE module extension for DHKEM(X448, HKDF-SHA512). README / samples |
|
hpke-js | The HPKE module supporting all of the ciphersuites defined in RFC9180, which consists of the above @hpke/{core, dhkem-x25519, dhkem-x448, chacha20poly1305} internally. README / samples |
|
@hpke/hpke-js | The JSR version of the above hpke-js .README / samples |
|
@hpke/ml-kem | EXPERIMENTAL AND NOT STANDARDIZED The HPKE module extension for ML-KEM. README / samples |
|
@hpke/hybridkem-x-wing | EXPERIMENTAL AND NOT STANDARDIZED The HPKE module extension for X-Wing: general-purpose hybrid post-quantum KEM. README / samples |
|
@hpke/hybridkem-x25519-kyber768 | EXPERIMENTAL AND NOT STANDARDIZED The HPKE module extension for the hybrid post-quantum KEM currently named X25519Kyber768Draft00. README / samples |
|
@hpke/dhkem-secp256k1 | EXPERIMENTAL AND NOT STANDARDIZED The HPKE module extension for DHKEM(secp256k1, HKDF-SHA256). README / samples |
Base | PSK | Auth | AuthPSK |
---|---|---|---|
✅ | ✅ | ✅ | ✅ |
KEMs | Browser | Node.js | Deno | Cloudflare Workers |
bun |
---|---|---|---|---|---|
DHKEM (P-256, HKDF-SHA256) | ✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
DHKEM (P-384, HKDF-SHA384) | ✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
DHKEM (P-521, HKDF-SHA512) | ✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
|
DHKEM (X25519, HKDF-SHA256) | ✅ hpke-js @hpke/dhkem-x25519 |
✅ hpke-js @hpke/dhkem-x25519 |
✅ hpke-js @hpke/dhkem-x25519 |
✅ hpke-js @hpke/dhkem-x25519 |
✅ hpke-js @hpke/dhkem-x25519 |
DHKEM (X448, HKDF-SHA512) | ✅ hpke-js @hpke/dhkem-x448 |
✅ hpke-js @hpke/dhkem-x448 |
✅ hpke-js @hpke/dhkem-x448 |
✅ hpke-js @hpke/dhkem-x448 |
✅ hpke-js @hpke/dhkem-x448 |
ML-KEM-512 | ✅ @hpke/ml-kem |
✅ @hpke/ml-kem |
✅ @hpke/ml-kem |
✅ @hpke/ml-kem |
✅ @hpke/ml-kem |
ML-KEM-768 | ✅ @hpke/ml-kem |
✅ @hpke/ml-kem |
✅ @hpke/ml-kem |
✅ @hpke/ml-kem |
✅ @hpke/ml-kem |
ML-KEM-1024 | ✅ @hpke/ml-kem |
✅ @hpke/ml-kem |
✅ @hpke/ml-kem |
✅ @hpke/ml-kem |
✅ @hpke/ml-kem |
X-Wing | ✅ @hpke/hybridkem-x-wing |
✅ @hpke/hybridkem-x-wing |
✅ @hpke/hybridkem-x-wing |
✅ @hpke/hybridkem-x-wing |
✅ @hpke/hybridkem-x-wing |
Hybrid KEM (X25519, Kyber768) | ✅ @hpke/hybridkem-x25519-kyber768 |
✅ @hpke/hybridkem-x25519-kyber768 |
✅ @hpke/hybridkem-x25519-kyber768 |
✅ @hpke/hybridkem-x25519-kyber768 |
✅ @hpke/hybridkem-x25519-kyber768 |
DHKEM (secp256k1, HKDF-SHA256) | ✅ @hpke/dhkem-secp256k1 |
✅ @hpke/dhkem-secp256k1 |
✅ @hpke/dhkem-secp256k1 |
✅ @hpke/dhkem-secp256k1 |
✅ @hpke/dhkem-secp256k1 |
KDFs | Browser | Node.js | Deno | Cloudflare Workers |
bun |
---|---|---|---|---|---|
HKDF-SHA256 | ✅ hpke-js @hpke/core(*1) |
✅ hpke-js @hpke/core(*1) |
✅ hpke-js @hpke/core(*1) |
✅ hpke-js @hpke/core(*1) |
✅ hpke-js @hpke/core(*1) |
HKDF-SHA384 | ✅ hpke-js @hpke/core(*1) |
✅ hpke-js @hpke/core(*1) |
✅ hpke-js @hpke/core(*1) |
✅ hpke-js @hpke/core(*1) |
✅ hpke-js @hpke/core(*1) |
HKDF-SHA512 | ✅ hpke-js @hpke/core(*1) |
✅ hpke-js @hpke/core(*1) |
✅ hpke-js @hpke/core(*1) |
✅ hpke-js @hpke/core(*1) |
✅ hpke-js @hpke/core(*1) |
- (*1) The HKDF functions built in
@hpke/core
can derive keys of the same length as the hash size. If you want to derive keys longer than the hash size, usehpke-js
.
AEADs | Browser | Node.js | Deno | Cloudflare Workers |
bun |
---|---|---|---|---|---|
AES-128-GCM | ✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
AES-256-GCM | ✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
ChaCha20 Poly1305 |
✅ hpke-js @hpke/chacha 20poly1305 |
✅ hpke-js @hpke/chacha 20poly1305 |
✅ hpke-js @hpke/chacha 20poly1305 |
✅ hpke-js @hpke/chacha 20poly1305 |
✅ hpke-js @hpke/chacha 20poly1305 |
Export Only | ✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
✅ hpke-js @hpke/core |
- Web Browser: Web Cryptography API
supported browsers
- Confirmed: Chrome, Firefox, Edge, Safari, Opera, Vivaldi, Brave
- Node.js: 16.x, 17.x, 18.x, 19.x, 20.x, 21.x, 22.x
- Deno: 1.x, 2.x
- Cloudflare Workers
- bun: 0.x (0.6.0-), 1.x
- Although this library has been passed the following test vectors, it has not been formally audited.
- The upper limit of the AEAD sequence number is further rounded to JavaScript's
MAX_SAFE_INTEGER (
2^53-1
).
We welcome all kind of contributions, filing issues, suggesting new features or sending PRs.