{"id":15567328,"url":"https://github.com/dajiaji/crystals-kyber-js","last_synced_at":"2026-03-08T07:13:35.660Z","repository":{"id":192374052,"uuid":"686610212","full_name":"dajiaji/crystals-kyber-js","owner":"dajiaji","description":"An ML-KEM (NIST FIPS 203) and CRYSTALS-KYBER implementation written in TypeScript.","archived":false,"fork":false,"pushed_at":"2025-04-03T19:38:06.000Z","size":36077,"stargazers_count":37,"open_issues_count":2,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-04T15:05:55.342Z","etag":null,"topics":["cryptography","crystals-kyber","fips203","javascript","kem","kyber","ml-kem","mlkem","post-quantum","pqc","security","typescript"],"latest_commit_sha":null,"homepage":"https://dajiaji.github.io/crystals-kyber-js/docs/main","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dajiaji.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-03T11:28:01.000Z","updated_at":"2025-04-03T19:34:51.000Z","dependencies_parsed_at":"2023-11-25T14:28:59.177Z","dependency_job_id":"6b3387cb-cf89-499a-b1f2-3ccb0a39737b","html_url":"https://github.com/dajiaji/crystals-kyber-js","commit_stats":{"total_commits":177,"total_committers":2,"mean_commits":88.5,"dds":0.2655367231638418,"last_synced_commit":"6e14cd49c5823d7a4ca80cd2d12f7681ac0cfd77"},"previous_names":["dajiaji/crystals-kyber-js"],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dajiaji%2Fcrystals-kyber-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dajiaji%2Fcrystals-kyber-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dajiaji%2Fcrystals-kyber-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dajiaji%2Fcrystals-kyber-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dajiaji","download_url":"https://codeload.github.com/dajiaji/crystals-kyber-js/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247198448,"owners_count":20900079,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cryptography","crystals-kyber","fips203","javascript","kem","kyber","ml-kem","mlkem","post-quantum","pqc","security","typescript"],"created_at":"2024-10-02T17:10:44.556Z","updated_at":"2026-03-08T07:13:35.650Z","avatar_url":"https://github.com/dajiaji.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003emlkem / crystals-kyber-js\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n\u003ca href=\"https://jsr.io/@dajiaji/mlkem\"\u003e\u003cimg src=\"https://jsr.io/badges/@dajiaji/mlkem\" alt=\"JSR\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/mlkem\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/mlkem?color=%23EE3214\" alt=\"NPM\"/\u003e\u003c/a\u003e\n\u003cimg src=\"https://github.com/dajiaji/crystals-kyber-js/actions/workflows/ci_browsers.yml/badge.svg\" alt=\"Browser CI\" /\u003e\n\u003cimg src=\"https://github.com/dajiaji/crystals-kyber-js/actions/workflows/ci_node.yml/badge.svg\" alt=\"Node.js CI\" /\u003e\n\u003cimg src=\"https://github.com/dajiaji/crystals-kyber-js/actions/workflows/ci_deno.yml/badge.svg\" alt=\"Deno CI\" /\u003e\n\u003cimg src=\"https://github.com/dajiaji/crystals-kyber-js/actions/workflows/ci_cloudflare.yml/badge.svg\" alt=\"Cloudflare Workers CI\" /\u003e\n\u003cimg src=\"https://github.com/dajiaji/crystals-kyber-js/actions/workflows/ci_bun.yml/badge.svg\" alt=\"bun CI\" /\u003e\n\u003ca href=\"https://codecov.io/gh/dajiaji/crystals-kyber-js\"\u003e\n  \u003cimg src=\"https://codecov.io/gh/dajiaji/crystals-kyber-js/branch/main/graph/badge.svg?token=7I7JGKDDJ2\" alt=\"codecov\" /\u003e\n\u003c/a\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\nAn ML-KEM (NIST FIPS 203) and CRYSTALS-KYBER implementation written in TypeScript.\u003cbr\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[Documentation for main](https://dajiaji.github.io/crystals-kyber-js/docs/main/)\n\n\u003c/div\u003e\n\nThis module is based on\n[ntontutoveanu/crystals-kyber-javascript](https://github.com/antontutoveanu/crystals-kyber-javascript),\nbut includes the following improvements:\n\n- ✅ ML-KEM ([NIST FIPS 203](https://csrc.nist.gov/pubs/fips/203/final))\n  support.\n- ✅ Written in TypeScript.\n- ✅ Available on various JavaScript runtimes: Browsers, Node.js, Deno,\n  Cloudflare Workers, etc.\n- ✅ Deterministic key generation support.\n- ✅ Constant-time validation for ciphertext.\n- ✅ Better performance: The fastest pure TypeScript/JavaScript ML-KEM\n  implementation available — approximately 5x faster than the original\n  implementation. Run `deno bench` to see the benchmark results.\n- ✅ No dependencies on other libraries.\n- ✅ Tree-shaking friendly.\n- ✅ Fix [KyberSlash](https://kyberslash.cr.yp.to/index.html) vulnerability.\n- ✅ Passed all the tests published by:\n  - [post-quantum-cryptography/KAT/MLKEM](https://github.com/post-quantum-cryptography/KAT/tree/main/MLKEM)\n  - [C2SP/CCTV/ML-KEM](https://github.com/C2SP/CCTV/tree/main/ML-KEM)\n  - [pq-crystals/kyber](https://github.com/C2SP/CCTV/tree/main/ML-KEM) (10000\n    consecutive tests)\n\nThis repository has the following packages:\n\n| package           | registry                                                                                                                  | description                                                                                                                                                                                                                          |\n| ----------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| crystals-kyber-js | [![npm](https://img.shields.io/npm/v/crystals-kyber-js?color=%23EE3214)](https://www.npmjs.com/package/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`.         |\n| mlkem             | [![npm](https://img.shields.io/npm/v/mlkem?color=%23EE3214)](https://www.npmjs.com/package/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.                                                                  |\n| @dajiaji/mlkem    | [![JSR](https://jsr.io/badges/@dajiaji/mlkem)](https://jsr.io/@dajiaji/mlkem)                                             | Implements only ML-KEM (NIST FIPS 203). It is an ML-KEM package for [jsr.io](https://jsr.io/). The above `mlkem` is an npm package of `@dajiaji/mlkem`, which has been converted using [@deno/dnt](https://github.com/denoland/dnt). |\n\nFor Node.js, you can install `mlkem` or `crystals-kyber-js` via npm, yarn or\npnpm:\n\n```sh\n# RECOMMENTED using `mlkem`\nnpm install mlkem\n# `crystals-kyber-js` is still available for use, but it may become deprecated in the near future.\nnpm install crystals-kyber-js\n```\n\nThen, you can use it as follows:\n\n```ts\nimport { createMlKem768 } from \"mlkem\"; // or from \"crystals-kyber-js\"\n\nasync function doMlKem() {\n  // Create a pre-initialized instance (available since v2.7.0).\n  // createMlKem512 and createMlKem1024 are also available.\n  const recipient = await createMlKem768();\n\n  // A recipient generates a key pair.\n  const [pkR, skR] = recipient.generateKeyPair();\n  //// Deterministic key generation is also supported\n  // const seed = new Uint8Array(64);\n  // globalThis.crypto.getRandomValues(seed); // node \u003e= 19\n  // const [pkR, skR] = recipient.deriveKeyPair(seed);\n\n  // A sender generates a ciphertext and a shared secret with pkR.\n  const sender = await createMlKem768();\n  const [ct, ssS] = sender.encap(pkR);\n\n  // The recipient decapsulates the ciphertext and generates the same shared secret with skR.\n  const ssR = recipient.decap(ct, skR);\n\n  // ssS === ssR\n  return;\n}\n\ntry {\n  doMlKem();\n} catch (err: unknown) {\n  console.log(\"failed:\", (err as Error).message);\n}\n```\n\n## Index\n\n- [Installation](#installation)\n  - [Node.js](#nodejs)\n  - [Deno](#deno)\n  - [Cloudflare Workers](#cloudflare-workers)\n  - [Bun](#bun)\n  - [Web Browsers](#web-browsers)\n- [Usage](#usage)\n- [Contributing](#contributing)\n\n## Installation\n\n### Node.js\n\n```sh\n# Using npm:\nnpm install mlkem  # or crystals-kyber-js\nyarn add mlkem  # or crystals-kyber-js\npnpm install mlkem  # or crystals-kyber-js\n# Using jsr:\nnpx jsr add @dajiaji/mlkem\nyarn dlx jsr add @dajiaji/mlkem\npnpm dlx jsr add @dajiaji/mlkem\n```\n\n### Deno\n\nStarting from version 2.0.0, `@dajiaji/mlkem` is available from the\n[jsr.io](https://jsr.io). From this version onwards, please use JSR import\ninstead of HTTPS import in Deno.\n\n**JSR import (`\u003e=2.0.0`):**\n\nAdd `@dajiaji/mlkem` package using the commands below:\n\n```sh\ndeno add @dajiaji/mlkem\n```\n\nThen, you can use the module from code like this:\n\n```ts\nimport {\n  createMlKem1024,\n  createMlKem512,\n  createMlKem768,\n} from \"@dajiaji/mlkem\";\n```\n\n**HTTPS import (deprecated):**\n\n```ts\nimport {\n  Kyber1024,\n  Kyber512,\n  Kyber768,\n} from \"https://deno.land/x/crystals_kyber@\u003cSEMVER\u003e/mod.ts\";\n```\n\n### Cloudflare Workers\n\n```sh\n# Using npm:\nnpm install mlkem  # or crystals-kyber-js\nyarn add mlkem  # or crystals-kyber-js\npnpm install mlkem  # or crystals-kyber-js\n# Using jsr:\nnpx jsr add @dajiaji/mlkem\nyarn dlx jsr add @dajiaji/mlkem\npnpm dlx jsr add @dajiaji/mlkem\n```\n\n```ts\nimport {\n  createMlKem1024,\n  createMlKem512,\n  createMlKem768,\n} from \"@dajiaji/mlkem\";\n```\n\n### Bun\n\n```sh\n# Using npm:\nnpm install mlkem  # or crystals-kyber-js\nyarn add mlkem  # or crystals-kyber-js\npnpm install mlkem  # or crystals-kyber-js\n# Using jsr:\nbunx jsr add @dajiaji/bhttp\n```\n\n```ts\nimport {\n  createMlKem1024,\n  createMlKem512,\n  createMlKem768,\n} from \"@dajiaji/mlkem\";\n```\n\n### Web Browsers\n\nFollowings are how to use this module with typical CDNs. Other CDNs can be used\nas well.\n\n```html\n\u003c!-- use a specific version --\u003e\n\u003cscript type=\"module\"\u003e\n  // Using esm.sh:\n  import {\n    createMlKem1024,\n    createMlKem512,\n    createMlKem768,\n  } from \"https://esm.sh/mlkem@\u003cSEMVER\u003e\";\n  // Using unpkg.com:\n  // import { createMlKem768 } from \"https://unpkg.com/mlkem@SEMVER\";\n  // ...\n\u003c/script\u003e\n```\n\n## Usage\n\nThis section shows some typical usage examples.\n\n### Node.js\n\n```js\nimport { createMlKem768 } from \"mlkem\"; // Available since v2.7.0\n// const { createMlKem768 } = require(\"mlkem\");\n\nasync function doMlKem() {\n  const recipient = await createMlKem768();\n  const [pkR, skR] = recipient.generateKeyPair();\n\n  const sender = await createMlKem768();\n  const [ct, ssS] = sender.encap(pkR);\n\n  const ssR = recipient.decap(ct, skR);\n\n  // ssS === ssR\n  return;\n}\n\ntry {\n  doMlKem();\n} catch (err) {\n  console.log(\"failed: \", err.message);\n}\n```\n\n### Deno, Cloudflare Workers and Bun\n\n```ts\nimport { createMlKem512 } from \"@dajiaji/mlkem\"; // Available since v2.7.0\n\nasync function doMlKem() {\n  const recipient = await createMlKem512();\n  const [pkR, skR] = recipient.generateKeyPair();\n\n  const sender = await createMlKem512();\n  const [ct, ssS] = sender.encap(pkR);\n\n  const ssR = recipient.decap(ct, skR);\n\n  // ssS === ssR\n  return;\n}\n\ntry {\n  doMlKem();\n} catch (err: unknown) {\n  console.log(\"failed:\", (err as Error).message);\n}\n```\n\n### Browsers\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\u003c/head\u003e\n  \u003cbody\u003e\n    \u003cscript type=\"module\"\u003e\n      // createMlKem* available since v2.7.0\n      import { createMlKem1024 } from \"https://esm.sh/mlkem\";\n\n      globalThis.doMlKem = async () =\u003e {\n        try {\n          const recipient = await createMlKem1024();\n          const [pkR, skR] = recipient.generateKeyPair();\n\n          const sender = await createMlKem1024();\n          const [ct, ssS] = sender.encap(pkR);\n\n          const ssR = recipient.decap(ct, skR);\n\n          // ssS === ssR\n          return;\n        } catch (err) {\n          alert(\"failed: \", err.message);\n        }\n      };\n    \u003c/script\u003e\n    \u003cbutton type=\"button\" onclick=\"doMlKem()\"\u003edo ML-KEM\u003c/button\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n### Deprecated: Async API (`MlKem512`, `MlKem768`, `MlKem1024`)\n\nThe class-based async API (`new MlKem768()`) is deprecated and will be removed\nin a future release. Please migrate to the `createMlKem*` functions shown above.\n\n```ts\n// DEPRECATED - avoid using this pattern\nimport { MlKem768 } from \"mlkem\";\nconst recipient = new MlKem768();\nconst [pkR, skR] = await recipient.generateKeyPair();\nconst [ct, ssS] = await recipient.encap(pkR);\nconst ssR = await recipient.decap(ct, skR);\n\n// RECOMMENDED - use createMlKem* instead (available since v2.7.0)\nimport { createMlKem768 } from \"mlkem\";\nconst recipient = await createMlKem768();\nconst [pkR, skR] = recipient.generateKeyPair(); // sync\nconst [ct, ssS] = recipient.encap(pkR); // sync\nconst ssR = recipient.decap(ct, skR); // sync\n```\n\n## Contributing\n\nWe welcome all kind of contributions, filing issues, suggesting new features or\nsending PRs.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdajiaji%2Fcrystals-kyber-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdajiaji%2Fcrystals-kyber-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdajiaji%2Fcrystals-kyber-js/lists"}