mlkem / crystals-kyber-js
An ML-KEM (NIST FIPS 203) and CRYSTALS-KYBER implementation written in TypeScript.
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:
This repository has the following packages:
package | registry | description |
---|
crystals-kyber-js | ![npm](https://img.shields.io/npm/v/crystals-kyber-js?color=%23EE3214) | 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 | ![npm](https://img.shields.io/npm/v/mlkem?color=%23EE3214) | 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 | ![JSR](https://jsr.io/badges/@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:
npm install mlkem
npm install crystals-kyber-js
Then, you can use it as follows:
import { MlKem768 } from "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);
return;
}
try {
doMlKem();
} catch (err: unknown) {
console.log("failed:", (err as Error).message);
}
Index
Installation
Node.js
npm install mlkem
yarn add mlkem
pnpm install mlkem
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
npm install mlkem
yarn add mlkem
pnpm install mlkem
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
npm install mlkem
yarn add mlkem
pnpm install mlkem
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.
<script type="module">
import { MlKem1024, MlKem512, MlKem768 } from "https://esm.sh/mlkem@<SEMVER>";
</script>
Usage
This section shows some typical usage examples.
Node.js
import { MlKem768 } from "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);
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);
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);
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.