New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@openforge-sh/liboqs

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@openforge-sh/liboqs

DEPRECATED - Use @oqs/liboqs-js instead. Post-quantum cryptography for Node.js and browsers via WebAssembly bindings to liboqs

latest
Source
npmnpm
Version
0.14.5
Version published
Maintainers
1
Created
Source

@openforge-sh/liboqs

DEPRECATED: This package has been adopted by the Open Quantum Safe project and is now maintained as @oqs/liboqs-js. This repository is archived and will no longer receive updates. Please migrate to the new package.

# Remove old package
npm uninstall @openforge-sh/liboqs

# Install new package
npm install @oqs/liboqs-js

The API is fully compatible. Update your imports:

- import { createMLKEM768 } from '@openforge-sh/liboqs';
+ import { createMLKEM768 } from '@oqs/liboqs-js';

License: MIT Node.js

A JavaScript/TypeScript wrapper for LibOQS, providing access to post-quantum cryptographic algorithms for key encapsulation mechanisms (KEM) and digital signatures.

Overview

This library provides WebAssembly bindings to LibOQS, part of the Open Quantum Safe project. It includes:

  • Individual WASM modules per algorithm for optimal bundle sizes
  • TypeScript definitions for complete type safety
  • Support for Node.js and browser environments
  • SIMD-optimized builds for maximum performance
  • Tree-shakable ES module exports to minimize bundle size
  • Automatic memory management and secure cleanup

Status

⚠️ Important Notice

This library is meant for research, prototyping, and experimentation. While the underlying LibOQS library is well-maintained by the Open Quantum Safe project, both projects carry important caveats:

  • Most post-quantum algorithms have not received the same level of scrutiny as traditional cryptography
  • Algorithm support may change rapidly as research advances
  • Some algorithms may prove insecure against classical or quantum computers
  • This library has not received a formal security audit

If you must use post-quantum cryptography in production environments, use hybrid approaches that combine post-quantum algorithms with traditional algorithms (e.g., ML-KEM with X25519, ML-DSA with Ed25519). This provides defense-in-depth during the transition period.

For production deployments, follow guidance from NIST's Post-Quantum Cryptography Standardization project.

NIST Standardized Algorithms

The algorithms implementing NIST FIPS standards are:

  • ML-KEM (FIPS 203, formerly Kyber): ML-KEM-512, ML-KEM-768, ML-KEM-1024
  • ML-DSA (FIPS 204, formerly Dilithium): ML-DSA-44, ML-DSA-65, ML-DSA-87
  • SLH-DSA (FIPS 205, formerly SPHINCS+): 12 variants (SHA2 and SHAKE, 128/192/256-bit security, f/s modes)

These algorithm names are stable and will be maintained. If NIST updates implementation details, this library will track those changes as closely as possible.

Available Algorithms

The library provides JavaScript wrappers for 97 algorithms including experimental and alternative post-quantum schemes:

Key Encapsulation Mechanisms (32 algorithms)
  • Kyber (legacy, use ML-KEM): Kyber512, Kyber768, Kyber1024
  • Classic McEliece: 10 variants (Classic-McEliece-348864 through Classic-McEliece-8192128f)
  • FrodoKEM: 6 variants (AES and SHAKE, 640/976/1344-bit)
  • HQC: HQC-128, HQC-192, HQC-256
  • NTRU: 6 variants (HPS and HRSS families)
  • NTRU Prime: sntrup761

Note: BIKE family is not supported due to WASM incompatibility (requires platform-specific optimizations).

Digital Signatures (65 algorithms)
  • Falcon: Falcon-512, Falcon-1024, Falcon-padded-512, Falcon-padded-1024
  • SLH-DSA (FIPS 205): 12 variants (SHA2 and SHAKE, 128/192/256-bit security, f/s modes)
  • CROSS: 18 variants (RSDP and RSDPG parameter sets with balanced/fast/small tradeoffs)
  • MAYO: MAYO-1, MAYO-2, MAYO-3, MAYO-5
  • SNOVA: 12 variants (various parameter sets)
  • UOV: 12 variants (Ip, Is, III, V with different optimization levels)

See algorithms.json for the complete algorithm registry, or the algorithms section. All 97 algorithms have WASM modules, JavaScript wrappers, TypeScript definitions, and test coverage.

Installation

Note: This package is deprecated. Install @oqs/liboqs-js instead.

# bun (recommended - fastest)
bun add @oqs/liboqs-js

# npm
npm install @oqs/liboqs-js

# pnpm
pnpm add @oqs/liboqs-js

# yarn
yarn add @oqs/liboqs-js

# deno (via npm: specifier - no install needed)
# See "Deno Usage" section below

Deno Usage

Fully Supported - Available through npm only due to package size limitations on JSR:

// Alternative: Import from npm
import { createMLKEM768 } from "npm:@oqs/liboqs-js";

const kem = await createMLKEM768();
const { publicKey, secretKey } = kem.generateKeyPair();
kem.destroy();

How it works: The library automatically detects the Deno runtime and loads optimized WASM modules built for deno compatibility (ENVIRONMENT='web' Emscripten build).

Recommended Setup - Create a deno.json for cleaner imports:

{
  "imports": {
    "liboqs": "npm:@oqs/liboqs-js@^0.15.0"
  }
}

Then import like:

import { createMLKEM768 } from "liboqs";

Using the CLI with Deno:

# Run CLI directly (JSR)
deno run --allow-read npm:@oqs/liboqs-js/cli kem keygen ml-kem-768

# Or from npm
deno run --allow-read npm:@oqs/liboqs-js/cli kem keygen ml-kem-768
# Or add to deno.json tasks:
{
  "tasks": {
    "liboqs": "deno run --allow-read npm:@oqs/liboqs-js/cli"
  }
}
# Then run:
deno task liboqs list --kem

Permissions:

# Library usage (cryptographic operations only)
deno run --allow-read your-script.ts

# CLI usage (may need write for output files)
deno run --allow-read --allow-write npm:@oqs/liboqs-js/cli kem keygen ml-kem-768 --output-dir ./keys

Deno automatically caches packages on first run - no separate install step needed.

Requirements

  • Node.js 22.0 or higher (for WASM SIMD support)
  • Package Managers: Bun 1.0+, npm 10+, pnpm 8+, yarn 4+ (for Node.js)
  • Deno 2.0+ (available only through npm)
  • Modern browsers with WebAssembly support (Chrome 91+, Firefox 89+, Edge 91+, Safari 16.4+ - Safari is untested)

Quick Start

Command Line Interface

The package includes a CLI for cryptographic operations without writing code:

# Generate ML-KEM-768 keypair
npx @oqs/liboqs-js kem keygen ml-kem-768 --output-dir ./keys

# Encapsulate to create shared secret
npx @oqs/liboqs-js kem encapsulate ml-kem-768 ./keys/public.key --format base64

# Sign a message
npx @oqs/liboqs-js sig sign ml-dsa-65 message.txt ./keys/secret.key -o signature.sig

# Verify signature
npx @oqs/liboqs-js sig verify ml-dsa-65 message.txt signature.sig ./keys/public.key

# List available algorithms
npx @oqs/liboqs-js list --kem

# Get algorithm info
npx @oqs/liboqs-js info ml-kem-768

Works with all package managers:

  • npx @oqs/liboqs-js (npm)
  • bunx @oqs/liboqs-js (bun)
  • pnpm dlx @oqs/liboqs-js (pnpm)
  • yarn dlx @oqs/liboqs-js (yarn)

For full CLI documentation, run:

npx @oqs/liboqs-js --help

Key Encapsulation (ML-KEM)

import { createMLKEM768 } from '@oqs/liboqs-js';

// Alice generates keypair
const alice = await createMLKEM768();
const { publicKey, secretKey } = alice.generateKeyPair();

// Bob encapsulates shared secret
const bob = await createMLKEM768();
const { ciphertext, sharedSecret } = bob.encapsulate(publicKey);

// Alice decapsulates
const aliceSecret = alice.decapsulate(ciphertext, secretKey);

// Verify shared secrets match
console.log('Secrets match:', Buffer.compare(sharedSecret, aliceSecret) === 0);

// Cleanup
alice.destroy();
bob.destroy();

Digital Signatures (ML-DSA)

import { createMLDSA65 } from '@oqs/liboqs-js';

const signer = await createMLDSA65();
const { publicKey, secretKey } = signer.generateKeyPair();

const message = new TextEncoder().encode('Hello, quantum world!');
const signature = signer.sign(message, secretKey);

const isValid = signer.verify(message, signature, publicKey);
console.log('Valid:', isValid); // true

signer.destroy();

Available Algorithms

These are the officially standardized post-quantum cryptographic algorithms approved by NIST for production use.

Key Encapsulation - ML-KEM (Module-Lattice-Based KEM)

AlgorithmSecurity LevelPublic KeySecret KeyCiphertextFactory Function
ML-KEM-512Level 1 (128-bit)800 B1,632 B768 BcreateMLKEM512()
ML-KEM-768Level 3 (192-bit)1,184 B2,400 B1,088 BcreateMLKEM768()
ML-KEM-1024Level 5 (256-bit)1,568 B3,168 B1,568 BcreateMLKEM1024()

Formerly known as: CRYSTALS-Kyber

Digital Signatures - ML-DSA (Module-Lattice-Based DSA)

AlgorithmSecurity LevelPublic KeySecret KeySignatureFactory Function
ML-DSA-44Level 2 (128-bit)1,312 B2,560 B~2,420 BcreateMLDSA44()
ML-DSA-65Level 3 (192-bit)1,952 B4,032 B~3,309 BcreateMLDSA65()
ML-DSA-87Level 5 (256-bit)2,592 B4,896 B~4,627 BcreateMLDSA87()

Formerly known as: CRYSTALS-Dilithium

Digital Signatures - SLH-DSA (Stateless Hash-Based DSA)

AlgorithmSecurity LevelPublic KeySecret KeySignatureFactory Function
SLH-DSA-SHA2-128fLevel 1 (128-bit)32 B64 B17,088 BcreateSLHDSASHA2128f()
SLH-DSA-SHA2-128sLevel 1 (128-bit)32 B64 B7,856 BcreateSLHDSASHA2128s()
SLH-DSA-SHA2-192fLevel 3 (192-bit)48 B96 B35,664 BcreateSLHDSASHA2192f()
SLH-DSA-SHA2-192sLevel 3 (192-bit)48 B96 B16,224 BcreateSLHDSASHA2192s()
SLH-DSA-SHA2-256fLevel 5 (256-bit)64 B128 B49,856 BcreateSLHDSASHA2256f()
SLH-DSA-SHA2-256sLevel 5 (256-bit)64 B128 B29,792 BcreateSLHDSASHA2256s()
SLH-DSA-SHAKE-128fLevel 1 (128-bit)32 B64 B17,088 BcreateSLHDSASHAKE128f()
SLH-DSA-SHAKE-128sLevel 1 (128-bit)32 B64 B7,856 BcreateSLHDSASHAKE128s()
SLH-DSA-SHAKE-192fLevel 3 (192-bit)48 B96 B35,664 BcreateSLHDSASHAKE192f()
SLH-DSA-SHAKE-192sLevel 3 (192-bit)48 B96 B16,224 BcreateSLHDSASHAKE192s()
SLH-DSA-SHAKE-256fLevel 5 (256-bit)64 B128 B49,856 BcreateSLHDSASHAKE256f()
SLH-DSA-SHAKE-256sLevel 5 (256-bit)64 B128 B29,792 BcreateSLHDSASHAKE256s()

Formerly known as: SPHINCS+ Variants: f = fast signing/slower verification, s = small signatures/slower signing

Additional Algorithms

Beyond the NIST-standardized algorithms, this library includes experimental and alternative post-quantum schemes for research purposes.

Legacy Kyber (Deprecated)

AlgorithmSecurity LevelPublic KeySecret KeyCiphertextFactory Function
Kyber512Level 1 (128-bit)800 B1,632 B768 BcreateKyber512()
Kyber768Level 3 (192-bit)1,184 B2,400 B1,088 BcreateKyber768()
Kyber1024Level 5 (256-bit)1,568 B3,168 B1,568 BcreateKyber1024()

Note: Use ML-KEM instead. Kyber is the pre-standardization version.

Key Encapsulation - Classic McEliece (10 variants)

AlgorithmSecurity LevelPublic KeySecret KeyCiphertextFactory Function
Classic-McEliece-348864Level 1 (128-bit)261,120 B6,492 B96 BcreateClassicMcEliece348864()
Classic-McEliece-348864fLevel 1 (128-bit)261,120 B6,492 B96 BcreateClassicMcEliece348864f()
Classic-McEliece-460896Level 3 (192-bit)524,160 B13,608 B156 BcreateClassicMcEliece460896()
Classic-McEliece-460896fLevel 3 (192-bit)524,160 B13,608 B156 BcreateClassicMcEliece460896f()
Classic-McEliece-6688128Level 5 (256-bit)1,044,992 B13,932 B208 BcreateClassicMcEliece6688128()
Classic-McEliece-6688128fLevel 5 (256-bit)1,044,992 B13,932 B208 BcreateClassicMcEliece6688128f()
Classic-McEliece-6960119Level 5 (256-bit)1,047,319 B13,948 B194 BcreateClassicMcEliece6960119()
Classic-McEliece-6960119fLevel 5 (256-bit)1,047,319 B13,948 B194 BcreateClassicMcEliece6960119f()
Classic-McEliece-8192128Level 5 (256-bit)1,357,824 B14,120 B208 BcreateClassicMcEliece8192128()
Classic-McEliece-8192128fLevel 5 (256-bit)1,357,824 B14,120 B208 BcreateClassicMcEliece8192128f()

Key Encapsulation - FrodoKEM (6 variants)

AlgorithmSecurity LevelPublic KeySecret KeyCiphertextFactory Function
FrodoKEM-640-AESLevel 1 (128-bit)9,616 B19,888 B9,720 BcreateFrodoKEM640AES()
FrodoKEM-640-SHAKELevel 1 (128-bit)9,616 B19,888 B9,720 BcreateFrodoKEM640SHAKE()
FrodoKEM-976-AESLevel 3 (192-bit)15,632 B31,296 B15,744 BcreateFrodoKEM976AES()
FrodoKEM-976-SHAKELevel 3 (192-bit)15,632 B31,296 B15,744 BcreateFrodoKEM976SHAKE()
FrodoKEM-1344-AESLevel 5 (256-bit)21,520 B43,088 B21,632 BcreateFrodoKEM1344AES()
FrodoKEM-1344-SHAKELevel 5 (256-bit)21,520 B43,088 B21,632 BcreateFrodoKEM1344SHAKE()

Key Encapsulation - HQC (3 variants)

AlgorithmSecurity LevelPublic KeySecret KeyCiphertextFactory Function
HQC-128Level 1 (128-bit)2,249 B2,305 B4,433 BcreateHQC128()
HQC-192Level 3 (192-bit)4,522 B4,586 B8,978 BcreateHQC192()
HQC-256Level 5 (256-bit)7,245 B7,317 B14,421 BcreateHQC256()

Key Encapsulation - NTRU (6 variants)

AlgorithmSecurity LevelPublic KeySecret KeyCiphertextFactory Function
NTRU-HPS-2048-509Level 1 (128-bit)699 B935 B699 BcreateNTRUHPS2048509()
NTRU-HPS-2048-677Level 3 (192-bit)930 B1,234 B930 BcreateNTRUHPS2048677()
NTRU-HPS-4096-821Level 5 (256-bit)1,230 B1,590 B1,230 BcreateNTRUHPS4096821()
NTRU-HPS-4096-1229Level 5 (256-bit)1,842 B2,366 B1,842 BcreateNTRUHPS40961229()
NTRU-HRSS-701Level 3 (192-bit)1,138 B1,450 B1,138 BcreateNTRUHRSS701()
NTRU-HRSS-1373Level 5 (256-bit)2,401 B2,983 B2,401 BcreateNTRUHRSS1373()

Key Encapsulation - NTRU Prime

AlgorithmSecurity LevelPublic KeySecret KeyCiphertextFactory Function
sntrup761Level 3 (192-bit)1,158 B1,763 B1,039 BcreateSntrup761()

Note: sntrup761 is included primarily for interoperability testing.

Digital Signatures - Falcon (4 variants)

AlgorithmSecurity LevelPublic KeySecret KeySignatureFactory Function
Falcon-512Level 1 (128-bit)897 B1,281 B~752 BcreateFalcon512()
Falcon-1024Level 5 (256-bit)1,793 B2,305 B~1,462 BcreateFalcon1024()
Falcon-padded-512Level 1 (128-bit)897 B1,281 B666 BcreateFalconPadded512()
Falcon-padded-1024Level 5 (256-bit)1,793 B2,305 B1,280 BcreateFalconPadded1024()

Digital Signatures - CROSS (18 variants)

AlgorithmSecurity LevelPublic KeySecret KeySignatureFactory Function
CROSS-rsdp-128-balancedLevel 1 (128-bit)77 B32 B13,152 BcreateCROSSRSDP128Balanced()
CROSS-rsdp-128-fastLevel 1 (128-bit)77 B32 B18,432 BcreateCROSSRSDP128Fast()
CROSS-rsdp-128-smallLevel 1 (128-bit)77 B32 B12,432 BcreateCROSSRSDP128Small()
CROSS-rsdp-192-balancedLevel 3 (192-bit)115 B48 B29,853 BcreateCROSSRSDP192Balanced()
CROSS-rsdp-192-fastLevel 3 (192-bit)115 B48 B41,406 BcreateCROSSRSDP192Fast()
CROSS-rsdp-192-smallLevel 3 (192-bit)115 B48 B28,391 BcreateCROSSRSDP192Small()
CROSS-rsdp-256-balancedLevel 5 (256-bit)153 B64 B53,527 BcreateCROSSRSDP256Balanced()
CROSS-rsdp-256-fastLevel 5 (256-bit)153 B64 B74,590 BcreateCROSSRSDP256Fast()
CROSS-rsdp-256-smallLevel 5 (256-bit)153 B64 B50,818 BcreateCROSSRSDP256Small()
CROSS-rsdpg-128-balancedLevel 1 (128-bit)54 B32 B9,120 BcreateCROSSRSDPG128Balanced()
CROSS-rsdpg-128-fastLevel 1 (128-bit)54 B32 B11,980 BcreateCROSSRSDPG128Fast()
CROSS-rsdpg-128-smallLevel 1 (128-bit)54 B32 B8,960 BcreateCROSSRSDPG128Small()
CROSS-rsdpg-192-balancedLevel 3 (192-bit)83 B48 B22,464 BcreateCROSSRSDPG192Balanced()
CROSS-rsdpg-192-fastLevel 3 (192-bit)83 B48 B26,772 BcreateCROSSRSDPG192Fast()
CROSS-rsdpg-192-smallLevel 3 (192-bit)83 B48 B20,452 BcreateCROSSRSDPG192Small()
CROSS-rsdpg-256-balancedLevel 5 (256-bit)106 B64 B40,100 BcreateCROSSRSDPG256Balanced()
CROSS-rsdpg-256-fastLevel 5 (256-bit)106 B64 B48,102 BcreateCROSSRSDPG256Fast()
CROSS-rsdpg-256-smallLevel 5 (256-bit)106 B64 B36,454 BcreateCROSSRSDPG256Small()

Digital Signatures - MAYO (4 variants)

AlgorithmSecurity LevelPublic KeySecret KeySignatureFactory Function
MAYO-1Level 1 (128-bit)1,420 B24 B454 BcreateMAYO1()
MAYO-2Level 1 (128-bit)4,912 B24 B186 BcreateMAYO2()
MAYO-3Level 3 (192-bit)2,986 B32 B681 BcreateMAYO3()
MAYO-5Level 5 (256-bit)5,554 B40 B964 BcreateMAYO5()

Digital Signatures - SNOVA (12 variants)

AlgorithmSecurity LevelPublic KeySecret KeySignatureFactory Function
SNOVA-24-5-4Level 1 (128-bit)1,016 B48 B248 BcreateSNOVA2454()
SNOVA-24-5-4-eskLevel 1 (128-bit)1,016 B36,848 B248 BcreateSNOVA2454ESK()
SNOVA-24-5-4-SHAKELevel 1 (128-bit)1,016 B48 B248 BcreateSNOVA2454SHAKE()
SNOVA-24-5-4-SHAKE-eskLevel 1 (128-bit)1,016 B36,848 B248 BcreateSNOVA2454SHAKEESK()
SNOVA-24-5-5Level 1 (128-bit)1,579 B48 B379 BcreateSNOVA2455()
SNOVA-25-8-3Level 1 (128-bit)2,320 B48 B165 BcreateSNOVA2583()
SNOVA-29-6-5Level 3 (192-bit)2,716 B48 B454 BcreateSNOVA2965()
SNOVA-37-17-2Level 3 (192-bit)9,842 B48 B124 BcreateSNOVA37172()
SNOVA-37-8-4Level 3 (192-bit)4,112 B48 B376 BcreateSNOVA3784()
SNOVA-49-11-3Level 5 (256-bit)6,006 B48 B286 BcreateSNOVA49113()
SNOVA-56-25-2Level 5 (256-bit)31,266 B48 B178 BcreateSNOVA56252()
SNOVA-60-10-4Level 5 (256-bit)8,016 B48 B576 BcreateSNOVA60104()

Digital Signatures - UOV (12 variants)

AlgorithmSecurity LevelPublic KeySecret KeySignatureFactory Function
OV-IpLevel 1 (128-bit)278,432 B237,896 B128 BcreateOVIp()
OV-Ip-pkcLevel 1 (128-bit)43,576 B237,896 B128 BcreateOVIpPKC()
OV-Ip-pkc-skcLevel 1 (128-bit)43,576 B32 B128 BcreateOVIpPKCSKC()
OV-IsLevel 1 (128-bit)412,160 B348,704 B96 BcreateOVIs()
OV-Is-pkcLevel 1 (128-bit)66,576 B348,704 B96 BcreateOVIsPKC()
OV-Is-pkc-skcLevel 1 (128-bit)66,576 B32 B96 BcreateOVIsPKCSKC()
OV-IIILevel 3 (192-bit)1,225,440 B1,044,320 B200 BcreateOVIII()
OV-III-pkcLevel 3 (192-bit)189,232 B1,044,320 B200 BcreateOVIIIPKC()
OV-III-pkc-skcLevel 3 (192-bit)189,232 B32 B200 BcreateOVIIIPKCSKC()
OV-VLevel 5 (256-bit)2,869,440 B2,436,704 B260 BcreateOVV()
OV-V-pkcLevel 5 (256-bit)446,992 B2,436,704 B260 BcreateOVVPKC()
OV-V-pkc-skcLevel 5 (256-bit)446,992 B32 B260 BcreateOVVPKCSKC()

Notes:

  • UOV variants with -pkc (public key compression) have smaller public keys
  • UOV variants with -skc (secret key compression) have smaller secret keys
  • -esk SNOVA variants use expanded secret keys for faster signing

Bundle Size Optimization

Each algorithm is compiled separately into individual WASM modules, so you only bundle what you use:

// Single algorithm (~80-160KB depending on algorithm complexity)
import { createMLKEM768 } from '@oqs/liboqs-js';
const kem = await createMLKEM768();

// Multiple algorithms - each adds its own WASM module
import { createMLKEM768, createMLDSA65 } from '@oqs/liboqs-js';
const kem = await createMLKEM768();
const sig = await createMLDSA65();

Tree-shaking ensures unused algorithms are never included in your bundle. Each algorithm's WASM is embedded in its module and loaded when you import the factory function.

Package Structure

Exports

// Main entry - all 97 algorithm factory functions, classes, and metadata
import { createMLKEM768, MLKEM768, ML_KEM_768_INFO } from '@oqs/liboqs-js';

// KEM-only exports (32 algorithms)
import {
  createMLKEM512,
  createClassicMcEliece348864,
  createFrodoKEM640AES
} from '@oqs/liboqs-js/kem';

// Signature-only exports (65 algorithms)
import {
  createMLDSA44,
  createFalcon512,
  createSphincsSha2128fSimple
} from '@oqs/liboqs-js/sig';

// Error classes only
import { LibOQSError, LibOQSInitError } from '@oqs/liboqs-js/errors';

File Structure

@oqs/liboqs-js/
├── src/
│   ├── algorithms/
│   │   ├── kem/
│   │   │   ├── ml-kem/           # ML-KEM (3 variants)
│   │   │   ├── kyber/            # Legacy Kyber (3 variants)
│   │   │   ├── classic-mceliece/ # Classic McEliece (10 variants)
│   │   │   ├── frodokem/         # FrodoKEM (6 variants)
│   │   │   ├── hqc/              # HQC (3 variants)
│   │   │   └── ntru/             # NTRU + sntrup761 (7 variants)
│   │   └── sig/
│   │       ├── ml-dsa/           # ML-DSA (3 variants)
│   │       ├── falcon/           # Falcon (4 variants)
│   │       ├── slh-dsa/          # SLH-DSA (12 variants)
│   │       ├── cross/            # CROSS (18 variants)
│   │       ├── mayo/             # MAYO (4 variants)
│   │       ├── snova/            # SNOVA (12 variants)
│   │       └── uov/              # UOV (12 variants)
│   ├── cli/
│   │   ├── commands/             # CLI command implementations
│   │   │   ├── info.js           # Algorithm information
│   │   │   ├── kem.js            # KEM operations (keygen, encaps, decaps)
│   │   │   ├── sig.js            # Signature operations (keygen, sign, verify)
│   │   │   └── list.js           # List available algorithms
│   │   ├── algorithms.js         # Algorithm registry
│   │   ├── index.js              # CLI entry point
│   │   ├── io.js                 # File I/O utilities
│   │   └── parser.js             # Command parser
│   ├── core/
│   │   ├── errors.js             # Error classes
│   │   └── validation.js         # Input validation utilities
│   ├── types/                    # TypeScript definitions
│   │   ├── algorithms.d.ts
│   │   ├── errors.d.ts
│   │   └── index.d.ts
│   ├── index.js                  # Main entry (all 97 algorithms)
│   ├── kem.js                    # KEM exports (32 algorithms)
│   └── sig.js                    # Signature exports (65 algorithms)
├── bin/
│   └── cli.js                    # CLI executable entry point
├── tests/
│   ├── kem.test.ts
│   ├── sig.test.ts
│   ├── cli.test.ts
│   └── deno/                     # Deno-specific tests
│       ├── kem.test.ts
│       ├── sig.test.ts
│       └── cli.test.ts
├── dist/                         # WASM modules (97 × 2 = 194 files, ~100-500KB each)
│   ├── ml-kem-512.min.js         # Node.js/Browser module
│   ├── ml-kem-512.deno.js        # Deno module
│   ├── falcon-512.min.js
│   ├── falcon-512.deno.js
│   └── ... (and 190 others)
├── algorithms.json               # Algorithm registry and metadata
└── build.sh                      # WASM build script

Architecture

The library is organized in layers:

  • WASM Modules: Emscripten-compiled LibOQS binaries (one per algorithm)
  • Low-level Bindings: Direct WASM function calls (_OQS_KEM_*, _OQS_SIG_*)
  • High-level Wrappers: User-friendly classes (MLKEM768, MLDSA65)
  • Public API: Factory functions and exports

Memory Management

IMPORTANT: Always call destroy() when finished with an algorithm instance. WASM memory is not garbage-collected by JavaScript.

Why This Matters

WebAssembly modules allocate native memory outside the JavaScript heap. When you create an algorithm instance, LibOQS allocates C structures that JavaScript's garbage collector cannot reclaim. Without calling destroy(), this memory leaks permanently.

Long-running applications (servers, single-page apps, daemons) that don't call destroy() will experience:

  • Increasing memory usage over time
  • Eventually: allocation failures or crashes when the 256MB WASM heap limit is reached

Short-lived scripts are less affected since the OS reclaims all memory when the process exits.

Best Practices

// Pattern 1: Simple cleanup
const kem = await createMLKEM768();
const { publicKey, secretKey } = kem.generateKeyPair();
kem.destroy();

// Pattern 2: Error-safe cleanup (recommended)
const kem = await createMLKEM768();
try {
  const { publicKey, secretKey } = kem.generateKeyPair();
  const { ciphertext, sharedSecret } = kem.encapsulate(publicKey);
  // ... use results ...
} finally {
  kem.destroy(); // Always runs, even if errors occur
}

// Pattern 3: Multiple operations
const sig = await createMLDSA65();
try {
  const { publicKey, secretKey } = sig.generateKeyPair();
  const message = new TextEncoder().encode('Hello!');
  const signature = sig.sign(message, secretKey);
  const isValid = sig.verify(message, signature, publicKey);
  return isValid;
} finally {
  sig.destroy();
}

Additional Notes

  • Secret keys, shared secrets, and signatures are handled via WASM memory
  • Keys and secrets are not automatically zeroed (limitation of JavaScript/WASM)
  • Each algorithm instance must be destroyed individually
  • After calling destroy(), the instance cannot be reused

Thread Safety

  • Individual algorithm instances are not thread-safe
  • For concurrent operations, create separate instances per worker/thread
  • WASM modules can be instantiated multiple times safely

Security Considerations

  • Use NIST Standardized Algorithms: ML-KEM, ML-DSA, and SLH-DSA are recommended for production
  • Hybrid Cryptography: We, as well as OQS, strongly recommend combining with traditional algorithms (X25519/Ed25519) during transition
  • Key Storage: Store secret keys securely, never in plain text or localStorage
  • Stay Updated: Monitor NIST guidance and update regularly
  • Audit Your Deployment: Consult cryptographic experts for production use
  • Random Number Generation: This library uses system entropy (Node.js crypto.randomBytes(), browser crypto.getRandomValues())

Reporting Security Issues

See SECURITY.md for our vulnerability disclosure policy. Issues specific to the LibOQS C library should be reported to the LibOQS project.

Building from Source

Prerequisites

  • Node.js 22+
  • Emscripten (latest stable release)
  • Git
  • CMake 3.20+
  • Python 3 (for Emscripten)
  • jq (for JSON parsing in build.sh)

Build Steps

# Clone repository
git clone https://github.com/open-quantum-safe/liboqs-js.git
cd liboqs-js

# Build all algorithms
./build.sh

# Build specific algorithm
./build.sh ml-kem-768

# Setup only (clone liboqs without building)
./build.sh --setup-only

# Clean build artifacts
./build.sh --clean

Build System

The build system is data-driven using algorithms.json:

{
  "kem": {
    "ml-kem": {
      "ML-KEM-768": {
        "slug": "ml-kem-768",
        "cmake_var": "ML_KEM_768",
        "security": 3,
        "standardized": true
      }
    }
  }
}

The build.sh script:

  • Parses algorithms.json with jq
  • Dynamically generates CMake flags to build single-algorithm WASM modules
  • Compiles with Emscripten optimizations (Closure compiler, WASM SIMD)
  • Outputs standalone .min.js files with embedded WASM

No build script changes needed to add new algorithms - just update the JSON registry.

Adding New Algorithms

Quick Start

# 1. Add algorithm metadata to algorithms.json
# 2. Create the algorithm wrapper file (see existing files for patterns)
# 3. Build WASM module
./build.sh <algorithm-slug>

# 4. Export from src/index.js, src/kem.js, or src/sig.js

Key Size Management

The fetch-key-sizes.js script extracts key sizes from existing algorithm files and updates algorithms.json:

node scripts/fetch-key-sizes.js
# Scans src/algorithms/**/*.js for keySize data
# Updates algorithms.json with found key sizes

This is useful when:

  • Updating key sizes after LibOQS version changes
  • Ensuring consistency across the codebase
  • Adding new algorithms

Steps

  • Add to algorithms.json: Include the algorithm metadata (slug, cmake_var, security level, key sizes)
  • Create wrapper file: Follow patterns in existing files under src/algorithms/kem/ or src/algorithms/sig/
  • Export in index files: Add to src/index.js, src/kem.js, or src/sig.js
  • Add tests: Follow patterns in tests/kem.test.ts or tests/sig.test.ts
  • Update TypeScript definitions: If needed, update src/types/algorithms.d.ts

All 97 algorithms maintain consistent APIs, documentation, and error handling patterns.

Testing

The library includes comprehensive test coverage using Vitest:

# Run all tests (1295+ tests across 97 algorithms)
bun test

# Or use your preferred package manager
npm test
pnpm test
yarn test

# Or with Deno:
deno test --allow-read --allow-write --allow-run --allow-env --no-check tests/deno/

Test coverage includes:

  • Algorithm correctness: All algorithms tested for basic functionality
  • Round-trip verification: KEM encapsulation/decapsulation, signature sign/verify
  • Key generation: Validates key sizes match specifications
  • Cross-environment: Node.js and browser (jsdom) compatibility
  • Error handling: Validates proper error messages and types
  • Memory safety: Ensures cleanup via destroy() methods
  • Edge cases: Empty messages, invalid signatures, destroyed instances

Contributing

Contributions are welcome! Please:

  • Tests must pass: Run bun run test (or npm run test) and deno test --allow-read --allow-write --allow-run --allow-env --no-check tests/deno/ before submitting
  • Follow existing code style: Use ESM, async/await, JSDoc comments
  • Document public APIs: Add comprehensive JSDoc for all exported functions and classes
  • Security first: Consider security implications, especially for cryptographic operations
  • Consistency matters: Follow established patterns in existing wrappers

For larger changes, open an issue first to discuss the approach.

Development Workflow

  • Fork the repository
  • Create a feature branch
  • Install dependencies: bun install (or npm install, pnpm install, etc.)
  • Make your changes (add tests if applicable)
  • Run tests: bun run test (or npm run test)
  • Build and test locally
  • Submit a pull request

Package Manager Notes

# Using bun (recommended/default for contributors)
bun install
bun run test
bun run build

# Using npm
npm install
npm run test
npm run build

# Using pnpm
pnpm install
pnpm runtest
pnpm run build

# Using yarn
yarn install
yarn run test
yarn run build

Contributions that add new algorithm wrappers, improve documentation, add tests, or enhance the build system are especially appreciated.

Documentation

Note: Documentation for this package will no longer be updated. See the new @oqs/liboqs-js repository for current documentation.

License

MIT License - see LICENSE.md for details.

Acknowledgments

Versioning

This library's version tracks the bundled LibOQS version:

  • @oqs/liboqs-js 0.15.x includes LibOQS 0.15.0

Disclaimer

This library provides access to cryptographic algorithms believed to be quantum-resistant based on current research. The field of post-quantum cryptography is evolving. Algorithm support may change as research advances. Always consult with cryptographic experts for production deployments and follow NIST recommendations.

The LibOQS project states: "WE DO NOT CURRENTLY RECOMMEND RELYING ON THIS LIBRARY IN A PRODUCTION ENVIRONMENT OR TO PROTECT ANY SENSITIVE DATA." This guidance applies to this JavaScript/WebAssembly wrapper as well.

Keywords

post-quantum

FAQs

Package last updated on 17 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts