Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ml-kem: initial public preview release. #476

Merged
merged 1 commit into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ npm install @hpke/core

Following extensions can be installed in the same manner:

- `@hpke/core`
- `@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:

Expand Down Expand Up @@ -117,6 +117,7 @@ The hpke-js includes the following packages.
| @hpke/dhkem-x448 | [![npm](https://img.shields.io/npm/v/@hpke/dhkem-x448?color=%23EE3214)](https://www.npmjs.com/package/@hpke/dhkem-x448)<br/>[![JSR](https://jsr.io/badges/@hpke/dhkem-x448)](https://jsr.io/@hpke/dhkem-x448) | The HPKE module extension for DHKEM(X448, HKDF-SHA512).<br/>[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.<br/>[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`.<br/>[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)<br/>[![JSR](https://jsr.io/badges/@hpke/ml-kem)](https://jsr.io/@hpke/ml-kem) | **EXPERIMENTAL AND NOT STANDARDIZED**<br/>The HPKE module extension for [ML-KEM](https://datatracker.ietf.org/doc/draft-connolly-cfrg-hpke-mlkem/).<br/>[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)<br/>[![JSR](https://jsr.io/badges/@hpke/hybridkem-x-wing)](https://jsr.io/@hpke/hybridkem-x-wing) | **EXPERIMENTAL AND NOT STANDARDIZED**<br/>The HPKE module extension for [X-Wing: general-purpose hybrid post-quantum KEM](https://datatracker.ietf.org/doc/draft-connolly-cfrg-xwing-kem/).<br/>[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)<br/>[![JSR](https://jsr.io/badges/@hpke/hybridkem-x25519-kyber768)](https://jsr.io/@hpke/hybridkem-x25519-kyber768) | **EXPERIMENTAL AND NOT STANDARDIZED**<br/>The HPKE module extension for the hybrid post-quantum KEM currently named [X25519Kyber768Draft00](https://datatracker.ietf.org/doc/draft-westerbaan-cfrg-hpke-xyber768d00/).<br/>[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)<br/>[![JSR](https://jsr.io/badges/@hpke/dhkem-secp256k1)](https://jsr.io/@hpke/dhkem-secp256k1) | **EXPERIMENTAL AND NOT STANDARDIZED**<br/>The HPKE module extension for DHKEM(secp256k1, HKDF-SHA256).<br/>[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) |
Expand All @@ -138,6 +139,9 @@ The hpke-js includes the following packages.
| DHKEM (P-521, HKDF-SHA512) | ✅<br>hpke-js<br>@hpke/core | ✅<br>hpke-js<br>@hpke/core | | ✅<br>hpke-js<br>@hpke/core | ✅<br>hpke-js<br>@hpke/core |
| DHKEM (X25519, HKDF-SHA256) | ✅<br>hpke-js<br>@hpke/dhkem-x25519 | ✅<br>hpke-js<br>@hpke/dhkem-x25519 | ✅<br>hpke-js<br>@hpke/dhkem-x25519 | ✅<br>hpke-js<br>@hpke/dhkem-x25519 | ✅<br>hpke-js<br>@hpke/dhkem-x25519 |
| DHKEM (X448, HKDF-SHA512) | ✅<br>hpke-js<br>@hpke/dhkem-x448 | ✅<br>hpke-js<br>@hpke/dhkem-x448 | ✅<br>hpke-js<br>@hpke/dhkem-x448 | ✅<br>hpke-js<br>@hpke/dhkem-x448 | ✅<br>hpke-js<br>@hpke/dhkem-x448 |
| ML-KEM-512 | ✅<br>@hpke/ml-kem | ✅<br>@hpke/ml-kem | ✅<br>@hpke/ml-kem | ✅<br>@hpke/ml-kem | ✅<br>@hpke/ml-kem |
| ML-KEM-768 | ✅<br>@hpke/ml-kem | ✅<br>@hpke/ml-kem | ✅<br>@hpke/ml-kem | ✅<br>@hpke/ml-kem | ✅<br>@hpke/ml-kem |
| ML-KEM-1024 | ✅<br>@hpke/ml-kem | ✅<br>@hpke/ml-kem | ✅<br>@hpke/ml-kem | ✅<br>@hpke/ml-kem | ✅<br>@hpke/ml-kem |
| X-Wing | ✅<br>@hpke/hybridkem-x-wing | ✅<br>@hpke/hybridkem-x-wing | ✅<br>@hpke/hybridkem-x-wing | ✅<br>@hpke/hybridkem-x-wing | ✅<br>@hpke/hybridkem-x-wing |
| Hybrid KEM (X25519, Kyber768) | ✅<br>@hpke/hybridkem-x25519-kyber768 | ✅<br>@hpke/hybridkem-x25519-kyber768 | ✅<br>@hpke/hybridkem-x25519-kyber768 | ✅<br>@hpke/hybridkem-x25519-kyber768 | ✅<br>@hpke/hybridkem-x25519-kyber768 |
| DHKEM (secp256k1, HKDF-SHA256) | ✅<br>@hpke/dhkem-secp256k1 | ✅<br>@hpke/dhkem-secp256k1 | ✅<br>@hpke/dhkem-secp256k1 | ✅<br>@hpke/dhkem-secp256k1 | ✅<br>@hpke/dhkem-secp256k1 |
Expand Down
4 changes: 4 additions & 0 deletions packages/ml-kem/CHANGES.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
# Changes

Released 2024-11-10

- First public preview release.
25 changes: 13 additions & 12 deletions packages/ml-kem/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</div>

<div align="center">
A TypeScript <a href="https://datatracker.ietf.org/doc/html/rfc9180">Hybrid Public Key Encryption (HPKE)</a> module extension for <a href="https://datatracker.ietf.org/doc/draft-connolly-cfrg-xwing-kem/">X-Wing: general-purpose hybrid post-quantum KEM</a>.
A TypeScript <a href="https://datatracker.ietf.org/doc/html/rfc9180">Hybrid Public Key Encryption (HPKE)</a> module extension for <a href="https://datatracker.ietf.org/doc/draft-connolly-cfrg-hpke-mlkem/">ML-KEM for HPKE</a>.
</div>
<p></p>

Expand Down Expand Up @@ -34,23 +34,24 @@ async function doHpke() {
const jwkPub = {
kty: "AKP",
kid: "01",
alg: "X-Wing",
alg: "ML-KEM-768",
pub:
"4iNrNajCSzmxCqEyOpapGaLO2IQAYzp7BxMXE_wUsrWxnPw9pfoaksSfJVE-D9MNaxYRyauWNdcIZyekt9IdNCROZpac8Vs7KnhTKfYbCWsnfqA3ODR5prVW3nIx_kt_qcmsJMBpmgAYpSU0AbrPqQXKgWVz5WotLgZ-m3KHUzuhOpN97bMfpEus7UB2mSNhADSuMeYZoXAkUZmzxcOYZIWf4bTJcXoHwwSVvfuYoKACzPVsEobO9QQd7ePETPFr9WLHRIUYAms9i5lAaAq9OKFXX9J7WNoGO_rDLDnDCGk3TAXBrrGJi2swPMaL5FU0buCvaZY2IkoUjKKuoQRjERxwn2m2nHDOhTh0ZpjExgqa7wAwx5JM7sQqXTaBb1RerhMpNGCzrLN-oOE9cOSqeGhto5ioOXwI6vloghE_5Pe61NpAsFAeHHU-_nMFPIcBToZhwzCZr-i-3kFKWxqifYOSs-Ex6acMEFWHgkDK0PQNX-PN-FI26tl-KpdEg2OygIyq_VFs0lBSxcNiVDwlF-Ss0OYOwHFjAJtkJfwyJ3rO5xwkurU-2fKedMZqCjVklVmY12uWqai1DRY1pNemfrQt9WRNMwRXKTqAQvU8x6aSiPF-1Vgn6Cso6CZlqGoU-9lmReyoFywET4O8DYwLTIYmmFYxyoevgpBo8TWJY8szNmTKSCdjujs7sghXf5umrGLCX3ZZJ0O2S-UZMXcUy0ECy3svmiWytPBhXeMd7NnKVQJtbaC2URGxb-Uv7tikh-FERiptupNyj1ALb_xJ5RVWnvJf7Rev9SBQc2glNSWGD1i-O-YclkYEpqyBTmk1WWQCpSCkZws9KEMYhmWT0VpLsBw14-WH7gxn0ogNbyQH-3pwcSuDjeuWxde_K0S89gOMy-M_vPUaVKWE_pAIPJHHptQ9T7FfSMYML9ZuCoqtStZOXEK7iHfA6-wrXjh8ipiP3CO-ueFsh1d4HgoUmcYeE4wh8hbCnQdpeYccqmlCuvwJBUS-6ZtUsWy5qaNk1iRtn0LM5TxmtZxFyPmukpmnXRUYDDyVIVGpG3oQdyQp3Ey65vzGIvqAGMY0OfiQYwuZKNtrt_lDiuQGXtNNc9SG8_UvkPCAfciN_djHKOlU8aw1wGwADOQaBYJYDju1e2cpcokKxeeYjnhQZXEW8bV9CAmq7ewL7eGuFIFIMRxvfjFzRuUYn7jNY1uYb4wL3SdkHFhLd4s6kRqAvhyWkquOG7sSg5VzzOGd8YO0WDW7tVBS-fxmoWeO8qNt6nhBHmyNYFAbTmBZLRNpipQ7UJGF25EuLqEL4GFxI2syfHFxYJTJZKaLAzd_UToFvNmcHzRlg7sFKXehChKt_HWANOVhfaTBJ2WF5XdOHzuZeLCdDpxE07yGFRxDqtGFcScXNAIjrDgdIRUKBClOl7sTu9ohtaGCttqWnhmn_QcnN_qOiApTwkKOPQSbfSGXQFKW3bNhkSp7z0gnztYR0Men2hBN3kMiCVM59kph1bsQj_C_TXgMrlCfsiwlaRQZP_c0kEJYEjfVIoKIJO4739B_sD8flC0uoXn-ci8GzAPeW2mFntsG7_OJsn3OWYRFcCFiI1k9S6MtmrrIzQSQQO9lNA",
"PxuKXPWqDLFIz6x2ajCnggmjzpfLQnqegTJU4LapmuJTcLWDwnU1fOO01sYKr9oD6Zc04OmOulau74IekrjB20OUKnw3yZd9eZRv4EdN8nuc87EsqUuwZAHQkVBTC_gq38RiO9evl0JZhLjFP1GWnrwC2bQarOeVNuMoKvWt7bY2PUp727BqaeJMiSiI9nEAVbtkTbYLo7iEIEwDsHwqisoCSawp6td9XIeaeQoJuFClXvYUzHPPf3JyI7oNY1MpXACMmGqpIANJoKxQDjR-4XlaGoNpq2FRwnsTQcrOVoUu52xtPMuDMbI83osiSvmy3uQC2WBbv6hAGXZBnFerFoa9oJayjLZUzUpdt8MlmOAUkeIbjNVEl_YP4rwx14OSjjgr-_MzK3VM-WmxKqWPQ4tKVwZBKdRFYAmhcqWas7d8yEx2lEuZpTRFpSmsCmKtSQF0pHMkpdNLgaaCppwKjddfDek8IOQwJmwjsAxIafU8b9CFTtPK9FRJUrBe07Ow1so08PKX8umnwRh4BKN6Ehpq0qtQ2vR1qjol5smg1qKd72LL0pgFD1swfAU6XIg4tMM1fzN2ZTwzZvpv4QJdGWDHW6ZDJlwVeoTJFNVZ9UDGfsFYc5Sve9F4MNUInVBZBvqfdmqbk5CfW2YnzAWgshksv8InGwsi13oHzlUe2qZSLUArAAA3I8EVk2yX9UyIqlE0gqBVVMYo5pRI62oO9vNGNByAK9q5sDugryl9nouTi5yr76RnIkIaM4qHLZqIuIyfDuxGkyw2fMWLg1c9JgNqr1J25RWw8jBZtAyEj2OKzjcD7mwn2WaZDHcC7SOgzZukz2Fppmih8LtYawdmkuHCFXVP9nhL2RokjLkPAIo-ylmFLAV5ZpM6Goa24FsvrZGyi8YWSLBBp6wEargRK2rCy5APtcCYIdxLBxa1CeEi3JfG7XNC9vSftlVZcpw4R2O6LSu4z1auNvOyaZcKxUhBITskt5LJSfPHdecKyPfMU3Y_9jitxRE-xgB1waeSdspHPBE4MpVKviB76_DNBCbA4pczlHJWx3Vr-bUNghkaB_C6XVoVSwhm4pNHO0B2oemV-dCGpHLBGKwiwhaoOZIGYKMx7uGY31saFZUjnVeAzadfc8Z2WkauSqNAAZOd-tkvfhJKXyxiiyWd6VYLv0cMxpzGUtwpuTuoakmQ3OCvGkUkwZmmkmcMr3SNFmEv7tcR-IpQXVUqZECqBCJibxhfaSGoLvklCGAoroVi_HYQ4bFknvAJTZa1Bfu38RKJbvrA0ZKvRdkDrHmSu-m_MOJXfiRYHLxPc7GA0Epp9UCznhmkrjauxPIa3ndJZTkbyuvAr4actjYxMntCG-xnJmUbh1i_7nPFkSEtT_mB9mhMWLNZwtB_oeYB1sXL_clksxkJzKN__5YgT7VojZLKWoV1jPFg6bBu0YMgpLGwyOgZaudqb2IZctF6TWSn3wTFpMMzw7wayqs3cJFJo7jKCCqPvKEyaKGwIiMOLWMCcsuf8uZlWvFzJ_O5gHCV9YK-GL0_Tgu3I-ztabBYVimYZUjXIrA7W70Vesmd7hwKmqE",
key_ops: [],
};
const pk = await suite.kem.importKey("jwk", jwkPub, true);
// In addition to importing keys from external sources, you can also generate keys as follows:
// const rkp = await suite.kem.generateKeyPair();
// const rkp = await suite.kem.deriveKeyPair(random32bytesValue);
// const rkp = await suite.kem.deriveKeyPair(random64bytesValue);

const sender = await suite.createSenderContext({ recipientPublicKey: pk });

const jwkPriv = {
kty: "AKP",
kid: "01",
alg: "X-Wing",
priv: "f5wrpOiPgn1hYEVQdgWFPtc7gJP277yI6xpurPpm7yY",
alg: "ML-KEM-768",
priv:
"1pz8ZPhNTzPkxU4Wa3_5KDo5SYalObI5h6EPOdLZaJtt5i40ZaVcnHigfSZb6FQLPliwgBoSTQf_ErQ41SAuoA",
key_ops: ["deriveBits"],
};
const sk = await suite.kem.importKey("jwk", jwkPriv, false);
Expand Down Expand Up @@ -188,7 +189,7 @@ async function doHpke() {

const rkp = await suite.kem.generateKeyPair();

// Note that the `ct` (ciphertext) resulting from X-Wing Encapsulate() is set to `sender.enc`.
// Note that the `ct` (ciphertext) resulting from ML-KEM::Encaps() is set to `sender.enc`.
const sender = await suite.createSenderContext({
recipientPublicKey: rkp.publicKey,
});
Expand All @@ -198,7 +199,7 @@ async function doHpke() {

const recipient = await suite.createRecipientContext({
recipientKey: rkp.privateKey,
enc: sender.enc, // == `ct` (ciphertext) in the context of X-Wing
enc: sender.enc, // == `ct` (ciphertext) in the context of ML-KEM
});

// decrypt
Expand Down Expand Up @@ -231,7 +232,7 @@ async function doHpke() {

const rkp = await suite.kem.generateKeyPair();

// Note that the `ct` (ciphertext) resulting from X-Wing::Encapsulate() is set to `sender.enc`.
// Note that the `ct` (ciphertext) resulting from ML-KEM::Encaps() is set to `sender.enc`.
const sender = await suite.createSenderContext({
recipientPublicKey: rkp.publicKey,
});
Expand All @@ -241,7 +242,7 @@ async function doHpke() {

const recipient = await suite.createRecipientContext({
recipientKey: rkp.privateKey,
enc: sender.enc, // == `ct` (ciphertext) in the context of X-Wing
enc: sender.enc, // == `ct` (ciphertext) in the context of ML-KEM
});

// decrypt
Expand Down Expand Up @@ -282,7 +283,7 @@ try {

const rkp = await suite.kem.generateKeyPair();

// Note that the `ct` resulting from X-Wing::Encapsulate() is set to `sender.enc`.
// Note that the `ct` (ciphertext) resulting from ML-KEM::Encaps() is set to `sender.enc`.
const sender = await suite.createSenderContext({
recipientPublicKey: rkp.publicKey,
});
Expand All @@ -293,7 +294,7 @@ try {

const recipient = await suite.createRecipientContext({
recipientKey: rkp.privateKey, // rkp (CryptoKeyPair) is also acceptable.
enc: sender.enc, // == `ct` (ciphertext) in the context of X-Wing
enc: sender.enc, // == `ct` (ciphertext) in the context of ML-KEM
});

// decrypt
Expand Down
Loading