Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/dajiaji/hpke-js

A Hybrid Public Key Encryption (HPKE) module built on top of Web Cryptography API.
https://github.com/dajiaji/hpke-js

aead cryptography encryption hpke kdf kem kyber ml-kem post-quantum pqc rfc9180 security webcrypto x-wing

Last synced: 3 days ago
JSON representation

A Hybrid Public Key Encryption (HPKE) module built on top of Web Cryptography API.

Awesome Lists containing this project

README

        

hpke-js


JSR
Browser CI
Node.js CI
Deno CI
Cloudflare Workers CI
bun CI

codecov


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](https://jsr.io/@hpke/core/doc) |
[pages (only for the latest ver.)](https://dajiaji.github.io/hpke-js/core/docs/)

For Node.js, you can install `@hpke/core` and other extensions via npm, yarn,
pnpm or jsr:

```sh
# 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:

```js
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);
}
```

## Index

- [Packages](#packages)
- [Supported Features](#supported-features)
- [Supported Environments](#supported-environments)
- [Warnings and Restrictions](#warnings-and-restrictions)
- [Contributing](#contributing)
- [References](#references)

## Packages

The hpke-js includes the following packages.

| name | registry | description |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| @hpke/core | [![npm](https://img.shields.io/npm/v/@hpke/core?color=%23EE3214)](https://www.npmjs.com/package/@hpke/core)
[![JSR](https://jsr.io/badges/@hpke/core)](https://jsr.io/@hpke/core) | The HPKE core module implemented using only [Web Cryptography API](https://www.w3.org/TR/WebCryptoAPI/). 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](https://github.com/dajiaji/hpke-js/blob/main/packages/core/README.md) / [samples](https://github.com/dajiaji/hpke-js/tree/main/packages/core/samples) |
| @hpke/chacha20poly1305 | [![npm](https://img.shields.io/npm/v/@hpke/chacha20poly1305?color=%23EE3214)](https://www.npmjs.com/package/@hpke/chacha20poly1305)
[![JSR](https://jsr.io/badges/@hpke/chacha20poly1305)](https://jsr.io/@hpke/chacha20poly1305) | The HPKE module extension for ChaCha20Poly1305 AEAD.
[README](https://github.com/dajiaji/hpke-js/blob/main/packages/chacha20poly1305/README.md) / [samples](https://github.com/dajiaji/hpke-js/tree/main/packages/chacha20poly1305/samples) |
| @hpke/dhkem-x25519 | [![npm](https://img.shields.io/npm/v/@hpke/dhkem-x25519?color=%23EE3214)](https://www.npmjs.com/package/@hpke/dhkem-x25519)
[![JSR](https://jsr.io/badges/@hpke/dhkem-x25519)](https://jsr.io/@hpke/dhkem-x25519) | The HPKE module extension for DHKEM(X25519, HKDF-SHA256).
[README](https://github.com/dajiaji/hpke-js/blob/main/packages/dhkem-x25519/README.md) / [samples](https://github.com/dajiaji/hpke-js/tree/main/packages/dhkem-x25519/samples) |
| @hpke/dhkem-x448 | [![npm](https://img.shields.io/npm/v/@hpke/dhkem-x448?color=%23EE3214)](https://www.npmjs.com/package/@hpke/dhkem-x448)
[![JSR](https://jsr.io/badges/@hpke/dhkem-x448)](https://jsr.io/@hpke/dhkem-x448) | The HPKE module extension for DHKEM(X448, HKDF-SHA512).
[README](https://github.com/dajiaji/hpke-js/blob/main/packages/dhkem-x448/README.md) / [samples](https://github.com/dajiaji/hpke-js/tree/main/packages/dhkem-x448/samples) |
| hpke-js | [![npm](https://img.shields.io/npm/v/hpke-js?color=%23EE3214)](https://www.npmjs.com/package/hpke-js) | The HPKE module supporting all of the ciphersuites defined in [RFC9180](https://datatracker.ietf.org/doc/html/rfc9180), which consists of the above @hpke/{core, dhkem-x25519, dhkem-x448, chacha20poly1305} internally.
[README](https://github.com/dajiaji/hpke-js/tree/main/packages/hpke-js/README.md) / [samples](https://github.com/dajiaji/hpke-js/tree/main/packages/hpke-js/samples) |
| @hpke/hpke-js | [![JSR](https://jsr.io/badges/@hpke/hpke-js)](https://jsr.io/@hpke/hpke-js) | The JSR version of the above `hpke-js`.
[README](https://github.com/dajiaji/hpke-js/tree/main/packages/hpke-js/README.md) / [samples](https://github.com/dajiaji/hpke-js/tree/main/packages/hpke-js/samples) |
| @hpke/ml-kem | [![npm](https://img.shields.io/npm/v/@hpke/ml-kem?color=%23EE3214)](https://www.npmjs.com/package/@hpke/ml-kem)
[![JSR](https://jsr.io/badges/@hpke/ml-kem)](https://jsr.io/@hpke/ml-kem) | **EXPERIMENTAL AND NOT STANDARDIZED**
The HPKE module extension for [ML-KEM](https://datatracker.ietf.org/doc/draft-connolly-cfrg-hpke-mlkem/).
[README](https://github.com/dajiaji/hpke-js/blob/main/packages/ml-kem/README.md) / [samples](https://github.com/dajiaji/hpke-js/tree/main/packages/ml-kem/samples) |
| @hpke/hybridkem-x-wing | [![npm](https://img.shields.io/npm/v/@hpke/hybridkem-x-wing?color=%23EE3214)](https://www.npmjs.com/package/@hpke/hybridkem-x-wing)
[![JSR](https://jsr.io/badges/@hpke/hybridkem-x-wing)](https://jsr.io/@hpke/hybridkem-x-wing) | **EXPERIMENTAL AND NOT STANDARDIZED**
The HPKE module extension for [X-Wing: general-purpose hybrid post-quantum KEM](https://datatracker.ietf.org/doc/draft-connolly-cfrg-xwing-kem/).
[README](https://github.com/dajiaji/hpke-js/blob/main/packages/hybridkem-x-wing/README.md) / [samples](https://github.com/dajiaji/hpke-js/tree/main/packages/hybridkem-x-wing/samples) |
| @hpke/hybridkem-x25519-kyber768 | [![npm](https://img.shields.io/npm/v/@hpke/hybridkem-x25519-kyber768?color=%23EE3214)](https://www.npmjs.com/package/@hpke/hybridkem-x25519-kyber768)
[![JSR](https://jsr.io/badges/@hpke/hybridkem-x25519-kyber768)](https://jsr.io/@hpke/hybridkem-x25519-kyber768) | **EXPERIMENTAL AND NOT STANDARDIZED**
The HPKE module extension for the hybrid post-quantum KEM currently named [X25519Kyber768Draft00](https://datatracker.ietf.org/doc/draft-westerbaan-cfrg-hpke-xyber768d00/).
[README](https://github.com/dajiaji/hpke-js/blob/main/packages/hybridkem-x25519-kyber768/README.md) / [samples](https://github.com/dajiaji/hpke-js/tree/main/packages/hybridkem-x25519-kyber768/samples) |
| @hpke/dhkem-secp256k1 | [![npm](https://img.shields.io/npm/v/@hpke/dhkem-secp256k1?color=%23EE3214)](https://www.npmjs.com/package/@hpke/dhkem-secp256k1)
[![JSR](https://jsr.io/badges/@hpke/dhkem-secp256k1)](https://jsr.io/@hpke/dhkem-secp256k1) | **EXPERIMENTAL AND NOT STANDARDIZED**
The HPKE module extension for DHKEM(secp256k1, HKDF-SHA256).
[README](https://github.com/dajiaji/hpke-js/blob/main/packages/dhkem-secp256k1/README.md) / [samples](https://github.com/dajiaji/hpke-js/tree/main/packages/dhkem-secp256k1/samples) |

## Supported Features

### HPKE Modes

| Base | PSK | Auth | AuthPSK |
| ---- | --- | ---- | ------- |
| ✅ | ✅ | ✅ | ✅ |

### Key Encapsulation Machanisms (KEMs)

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

### Key Derivation Functions (KDFs)

| 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,
use `hpke-js`.

### Authenticated Encryption with Associated Data (AEAD) Functions

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

## Supported Environments

- **Web Browser**: [Web Cryptography API](https://www.w3.org/TR/WebCryptoAPI/)
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

## Warnings and Restrictions

- Although this library has been passed the following test vectors, it has not
been formally audited.
- [RFC9180 official test vectors provided on github.com/cfrg/draft-irtf-cfrg-hpke](https://github.com/cfrg/draft-irtf-cfrg-hpke/blob/5f503c564da00b0687b3de75f1dfbdfc4079ad31/test-vectors.json)
- [ECDH/X25519/X448 test vectors provided on Project Wycheproof](https://github.com/google/wycheproof)
- The upper limit of the AEAD sequence number is further rounded to JavaScript's
MAX\_SAFE\_INTEGER (`2^53-1`).

## Contributing

We welcome all kind of contributions, filing issues, suggesting new features or
sending PRs.

## References

- [RFC9180: Hybrid Public Key Encryption](https://datatracker.ietf.org/doc/html/rfc9180)
- [W3C/WICG: Secure Curves in the Web Cryptography API](https://wicg.github.io/webcrypto-secure-curves/)
- [X25519Kyber768Draft00 hybrid post-quantum KEM for HPKE](https://datatracker.ietf.org/doc/html/draft-westerbaan-cfrg-hpke-xyber768d00)
- [X-Wing: general-purpose hybrid post-quantum KEM](https://datatracker.ietf.org/doc/html/draft-connolly-cfrg-xwing-kem)