Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
An ML-KEM (FIPS 203) implementation written in TypeScript for various JavaScript runtimes.
mlkem / crystals-kyber-js
This module is based on ntontutoveanu/crystals-kyber-javascript, but includes the following improvements:
- ✅ Written in TypeScript.
- ✅ Available on various JavaScript runtimes: Browsers, Node.js, Deno, Cloudflare Workers, etc.
- ✅ Deterministic key generation support.
- ✅ Constant-time validation for ciphertext.
- ✅ Better performance: 1.4 to 1.8 times faster than the original implementation.
- ✅ Tree-shaking friendly.
- ✅ Fix KyberSlash vulnerability.
- ✅ ML-KEM (NIST FIPS 203) support.
- ✅ Passed all the tests published by:
- post-quantum-cryptography/KAT/MLKEM
- C2SP/CCTV/ML-KEM
- pq-crystals/kyber (10000 consecutive tests)
This repository has the following packages:
package | registry | description |
---|---|---|
crystals-kyber-js | v1.x implements CRYSTALS-KYBER, and v2.x- implements ML-KEM (NIST FIPS 203). crystals-kyber-js may become deprecated in the near future. Instead, we recommend switching to the following mlkem or @dajiaji/mlkem . |
|
mlkem | Implements only ML-KEM (NIST FIPS 203). It is an alias for the above crystals-kyber-js starting from v2 onwards. We recommend using this package going forward. |
|
@dajiaji/mlkem | Implements only ML-KEM (NIST FIPS 203). It is an ML-KEM package for jsr.io. The above mlkem is an npm package of @dajiaji/mlkem , which has been converted using @deno/dnt. |
For Node.js, you can install mlkem
or crystals-kyber-js
via npm, yarn or
pnpm:
# RECOMMENTED using `mlkem` npm install mlkem # `crystals-kyber-js` is still available for use, but it may become deprecated in the near future. npm install crystals-kyber-js
Then, you can use it as follows:
import { MlKem768 } from "mlkem"; // or from "crystals-kyber-js" async function doMlKem() { // A recipient generates a key pair. const recipient = new MlKem768(); // MlKem512 and MlKem1024 are also available. const [pkR, skR] = await recipient.generateKeyPair(); //// Deterministic key generation is also supported // const seed = new Uint8Array(64); // globalThis.crypto.getRandomValues(seed); // node >= 19 // const [pkR, skR] = await recipient.deriveKeyPair(seed); // A sender generates a ciphertext and a shared secret with pkR. const sender = new MlKem768(); const [ct, ssS] = await sender.encap(pkR); // The recipient decapsulates the ciphertext and generates the same shared secret with skR. const ssR = await recipient.decap(ct, skR); // ssS === ssR return; } try { doMlKem(); } catch (err: unknown) { console.log("failed:", (err as Error).message); }
Index
Installation
Node.js
# Using npm: npm install mlkem # or crystals-kyber-js yarn add mlkem # or crystals-kyber-js pnpm install mlkem # or crystals-kyber-js # Using jsr: npx jsr add @dajiaji/mlkem yarn dlx jsr add @dajiaji/mlkem pnpm dlx jsr add @dajiaji/mlkem
Deno
Starting from version 2.0.0, @dajiaji/mlkem
is available from the
jsr.io. From this version onwards, please use JSR import
instead of HTTPS import in Deno.
JSR import (>=2.0.0
):
Add @dajiaji/mlkem
package using the commands below:
deno add @dajiaji/mlkem
Then, you can use the module from code like this:
import { MlKem1024, MlKem512, MlKem768 } from "@dajiaji/mlkem";
HTTPS import (deprecated):
import { Kyber1024, Kyber512, Kyber768, } from "https://deno.land/x/crystals_kyber@<SEMVER>/mod.ts";
Cloudflare Workers
# Using npm: npm install mlkem # or crystals-kyber-js yarn add mlkem # or crystals-kyber-js pnpm install mlkem # or crystals-kyber-js # Using jsr: npx jsr add @dajiaji/mlkem yarn dlx jsr add @dajiaji/mlkem pnpm dlx jsr add @dajiaji/mlkem
import { MlKem1024, MlKem512, MlKem768 } from "@dajiaji/mlkem";
Bun
# Using npm: npm install mlkem # or crystals-kyber-js yarn add mlkem # or crystals-kyber-js pnpm install mlkem # or crystals-kyber-js # Using jsr: bunx jsr add @dajiaji/bhttp
import { MlKem1024, MlKem512, MlKem768 } from "@dajiaji/mlkem";
Web Browsers
Followings are how to use this module with typical CDNs. Other CDNs can be used as well.
<!-- use a specific version --> <script type="module"> // Using esm.sh: import { MlKem1024, MlKem512, MlKem768, } from "https://esm.sh/mlkem@<SEMVER>"; // Using unpkg.com: // import { MlKem768 } from "https://unpkg.com/mlkem@SEMVER"; // ... </script>
Usage
This section shows some typical usage examples.
Node.js
import { MlKem768 } from "mlkem"; // const { MlKem768 } = require("mlkem"); async function doMlKem() { const recipient = new MlKem768(); const [pkR, skR] = await recipient.generateKeyPair(); const sender = new MlKem768(); const [ct, ssS] = await sender.encap(pkR); const ssR = await recipient.decap(ct, skR); // ssS === ssR return; } try { doMlKem(); } catch (err) { console.log("failed: ", err.message); }
Deno, Cloudflare Workers and Bun
import { MlKem512 } from "@dajiaji/mlkem"; async function doMlKem() { const recipient = new MlKem512(); const [pkR, skR] = await recipient.generateKeyPair(); const sender = new MlKem512(); const [ct, ssS] = await sender.encap(pkR); const ssR = await recipient.decap(ct, skR); // ssS === ssR return; } try { doMlKem(); } catch (err: unknown) { console.log("failed:", (err as Error).message); }
Browsers
<html> <head></head> <body> <script type="module"> import { MlKem1024 } from "https://esm.sh/mlkem"; globalThis.doMlKem = async () => { try { const recipient = new MlKem1024(); const [pkR, skR] = await recipient.generateKeyPair(); const sender = new MlKem1024(); const [ct, ssS] = await sender.encap(pkR); const ssR = await recipient.decap(ct, skR); // ssS === ssR return; } catch (err) { alert("failed: ", err.message); } }; </script> <button type="button" onclick="doMlKem()">do CRYSTALS-KYBER</button> </body> </html>
Contributing
We welcome all kind of contributions, filing issues, suggesting new features or sending PRs.
Add Package
deno add jsr:@dajiaji/mlkem
Import symbol
import * as mlkem from "@dajiaji/mlkem";
Import directly with a jsr specifier
import * as mlkem from "jsr:@dajiaji/mlkem";
Add Package
pnpm i jsr:@dajiaji/mlkem
pnpm dlx jsr add @dajiaji/mlkem
Import symbol
import * as mlkem from "@dajiaji/mlkem";
Add Package
yarn add jsr:@dajiaji/mlkem
yarn dlx jsr add @dajiaji/mlkem
Import symbol
import * as mlkem from "@dajiaji/mlkem";
Add Package
vlt install jsr:@dajiaji/mlkem
Import symbol
import * as mlkem from "@dajiaji/mlkem";
Add Package
npx jsr add @dajiaji/mlkem
Import symbol
import * as mlkem from "@dajiaji/mlkem";
Add Package
bunx jsr add @dajiaji/mlkem
Import symbol
import * as mlkem from "@dajiaji/mlkem";