CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-noble--hashes

Audited & minimal 0-dependency JS implementation of SHA, RIPEMD, BLAKE, HMAC, HKDF, PBKDF & Scrypt

Overview
Eval results
Files

index.mddocs/

@noble/hashes

@noble/hashes is an audited and minimal JavaScript cryptographic hashing library providing implementations of SHA, RIPEMD, BLAKE, HMAC, HKDF, PBKDF2, Scrypt, and Argon2. The library is designed with zero runtime dependencies, tree-shakeable architecture for minimal bundle sizes, and has been independently audited by Cure53. It offers both simple single-call APIs and streaming interfaces with incremental updates, supports multiple platforms and runtimes (Node.js, browsers, Deno, Bun), and emphasizes code quality through hand-optimized implementations without unrolled loops for easier verification.

Package Information

  • Package Name: @noble/hashes
  • Package Type: npm
  • Language: TypeScript (ESM-only)
  • Installation: npm install @noble/hashes or deno add jsr:@noble/hashes
  • Node.js Version: >= 20.19.0

Core Imports

All imports require the .js extension (ESM-only):

// SHA-2 family
import { sha256, sha384, sha512, sha224, sha512_224, sha512_256 } from '@noble/hashes/sha2.js';

// SHA-3 and Keccak family
import { sha3_256, sha3_512, keccak_256, shake128, shake256 } from '@noble/hashes/sha3.js';

// BLAKE family
import { blake3 } from '@noble/hashes/blake3.js';
import { blake2b, blake2s } from '@noble/hashes/blake2.js';

// MACs and KDFs
import { hmac } from '@noble/hashes/hmac.js';
import { hkdf } from '@noble/hashes/hkdf.js';
import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2.js';
import { scrypt, scryptAsync } from '@noble/hashes/scrypt.js';
import { argon2id } from '@noble/hashes/argon2.js';
import { eskdf } from '@noble/hashes/eskdf.js';

// Utilities
import { bytesToHex, hexToBytes, utf8ToBytes, randomBytes } from '@noble/hashes/utils.js';

Basic Usage

Simple Hashing

import { sha256 } from '@noble/hashes/sha2.js';
import { bytesToHex } from '@noble/hashes/utils.js';

const data = Uint8Array.from([0xca, 0xfe, 0x01, 0x23]);
const hash = sha256(data);
console.log(bytesToHex(hash));

Incremental Hashing

import { sha256 } from '@noble/hashes/sha2.js';

const hasher = sha256.create();
hasher.update(Uint8Array.from([0x10, 0x20]));
hasher.update(Uint8Array.from([0x30, 0x40]));
const hash = hasher.digest();

Key Derivation

import { pbkdf2 } from '@noble/hashes/pbkdf2.js';
import { sha256 } from '@noble/hashes/sha2.js';

const key = pbkdf2(sha256, 'password', 'salt', { c: 100000, dkLen: 32 });

Message Authentication

import { hmac } from '@noble/hashes/hmac.js';
import { sha256 } from '@noble/hashes/sha2.js';

const key = new Uint8Array(32).fill(1);
const message = new Uint8Array(32).fill(2);
const mac = hmac(sha256, key, message);

Architecture

@noble/hashes is built around several key design principles:

  • Zero Dependencies: No runtime dependencies for maximum security and auditability
  • Tree-Shakeable: Unused code is excluded from builds using ESM sub-imports
  • Streaming API: All hash functions support both single-call and incremental update patterns
  • Type Safety: Full TypeScript support with generic type preservation
  • Platform Agnostic: Works in Node.js, browsers, Deno, and Bun
  • Audited Security: Independent security audit by Cure53 (January 2022)

Common Hash Interface

All hash functions implement a consistent interface:

interface Hash<T> {
  blockLen: number;
  outputLen: number;
  update(buf: Uint8Array): this;
  digest(): Uint8Array;
  digestInto(buf: Uint8Array): void;
  destroy(): void;
  clone(): T;
}

type CHash<T extends Hash<T>, Opts = undefined> = {
  outputLen: number;
  blockLen: number;
  (msg: Uint8Array, opts?: Opts): Uint8Array;
  create(opts?: Opts): T;
}

Extendable Output Functions (XOF)

Some hash functions support XOF mode for variable-length output:

interface HashXOF<T extends Hash<T>> extends Hash<T> {
  xof(bytes: number): Uint8Array;
  xofInto(buf: Uint8Array): Uint8Array;
}

Capabilities

SHA-2 Family

Implements SHA-256, SHA-384, SHA-512 and their variants. Widely used standard hash functions suitable for most applications including digital signatures, data integrity verification, and blockchain operations.

function sha256(msg: Uint8Array): Uint8Array; // 32 bytes
function sha384(msg: Uint8Array): Uint8Array; // 48 bytes
function sha512(msg: Uint8Array): Uint8Array; // 64 bytes
function sha224(msg: Uint8Array): Uint8Array; // 28 bytes
function sha512_256(msg: Uint8Array): Uint8Array; // 32 bytes
function sha512_224(msg: Uint8Array): Uint8Array; // 28 bytes

Each function also exposes create() for incremental hashing, outputLen (output size), and blockLen (block size) properties.

SHA-2 Hashing

SHA-3 and Keccak

Implements FIPS SHA-3, original Keccak, and SHAKE XOF functions. SHA-3 is the latest NIST standard hash function. Keccak variants differ slightly from SHA-3 and are used in blockchain applications like Ethereum.

function sha3_256(msg: Uint8Array): Uint8Array; // 32 bytes
function sha3_512(msg: Uint8Array): Uint8Array; // 64 bytes
function keccak_256(msg: Uint8Array): Uint8Array; // 32 bytes (Ethereum)
function shake128(msg: Uint8Array, opts?: { dkLen?: number }): Uint8Array; // XOF
function shake256(msg: Uint8Array, opts?: { dkLen?: number }): Uint8Array; // XOF

SHA-3 and Keccak

SHA-3 Addons

Advanced SHA-3 variants including cSHAKE, KMAC, TurboSHAKE, KangarooTwelve, TupleHash, and ParallelHash from NIST SP 800-185 and IETF drafts.

function cshake128(msg: Uint8Array, opts?: { personalization?: Uint8Array; NISTfn?: string | Uint8Array; dkLen?: number }): Uint8Array;
function kmac128(key: Uint8Array, message: Uint8Array, opts?: { personalization?: Uint8Array; dkLen?: number }): Uint8Array;
function kt128(msg: Uint8Array, opts?: { personalization?: Uint8Array; dkLen?: number }): Uint8Array; // KangarooTwelve
function turboshake128(msg: Uint8Array, opts?: { D?: number; dkLen?: number }): Uint8Array;

SHA-3 Addons

BLAKE Family

BLAKE1, BLAKE2 (blake2b, blake2s), and BLAKE3 hash functions. BLAKE2 is faster than MD5, SHA-1, and SHA-2 while being as secure as SHA-3. BLAKE3 is even faster with additional features like tree hashing and XOF mode.

function blake2b(msg: Uint8Array, opts?: { dkLen?: number; key?: Uint8Array; salt?: Uint8Array; personalization?: Uint8Array }): Uint8Array;
function blake2s(msg: Uint8Array, opts?: { dkLen?: number; key?: Uint8Array; salt?: Uint8Array; personalization?: Uint8Array }): Uint8Array;
function blake3(msg: Uint8Array, opts?: { dkLen?: number; key?: Uint8Array; context?: Uint8Array }): Uint8Array;

BLAKE Hashing

Legacy Hash Functions

SHA-1, MD5, and RIPEMD-160 implementations. These are cryptographically weak and should not be used in new protocols. Included for compatibility with legacy systems only.

function sha1(msg: Uint8Array): Uint8Array; // 20 bytes - Weak, collisions possible
function md5(msg: Uint8Array): Uint8Array; // 16 bytes - Broken
function ripemd160(msg: Uint8Array): Uint8Array; // 20 bytes - Weak

Legacy Hashing

HMAC

Hash-based Message Authentication Code (HMAC) for message authentication. Works with any hash function from the library. Conforms to RFC 2104.

function hmac(hash: CHash, key: Uint8Array, message: Uint8Array): Uint8Array;

// Incremental usage
const mac = hmac.create(sha256, key);
mac.update(message1);
mac.update(message2);
const result = mac.digest();

HMAC

HKDF

HMAC-based Key Derivation Function for extracting and expanding key material. Conforms to RFC 5869.

function hkdf(hash: CHash, ikm: Uint8Array, salt?: Uint8Array, info?: Uint8Array, length: number): Uint8Array;
function extract(hash: CHash, ikm: Uint8Array, salt?: Uint8Array): Uint8Array;
function expand(hash: CHash, prk: Uint8Array, info?: Uint8Array, length?: number): Uint8Array;

HKDF

PBKDF2

Password-Based Key Derivation Function 2 for deriving keys from passwords. Supports both sync and async variants. Conforms to RFC 2898.

function pbkdf2(hash: CHash, password: string | Uint8Array, salt: string | Uint8Array, opts: { c: number; dkLen?: number }): Uint8Array;
function pbkdf2Async(hash: CHash, password: string | Uint8Array, salt: string | Uint8Array, opts: { c: number; dkLen?: number; asyncTick?: number }): Promise<Uint8Array>;

PBKDF2

Scrypt

Memory-hard key derivation function resistant to hardware brute-force attacks. Supports both sync and async variants with progress callbacks. Conforms to RFC 7914.

function scrypt(password: string | Uint8Array, salt: string | Uint8Array, opts: { N: number; r: number; p: number; dkLen?: number; maxmem?: number }): Uint8Array;
function scryptAsync(password: string | Uint8Array, salt: string | Uint8Array, opts: { N: number; r: number; p: number; dkLen?: number; maxmem?: number; asyncTick?: number; onProgress?: (progress: number) => void }): Promise<Uint8Array>;

Scrypt

Argon2

Modern password hashing function, winner of the Password Hashing Competition. Provides argon2d, argon2i, and argon2id variants. Conforms to RFC 9106. Note: JS implementation is slower than native code due to lack of efficient uint64 operations.

function argon2id(password: string | Uint8Array, salt: string | Uint8Array, opts: { t: number; m: number; p: number; dkLen?: number }): Uint8Array;
function argon2d(password: string | Uint8Array, salt: string | Uint8Array, opts: { t: number; m: number; p: number; dkLen?: number }): Uint8Array;
function argon2i(password: string | Uint8Array, salt: string | Uint8Array, opts: { t: number; m: number; p: number; dkLen?: number }): Uint8Array;

Argon2

ESKDF

Experimental key derivation function combining Scrypt and PBKDF2 for initial seed derivation, then using HKDF for efficient child key derivation. Designed for deriving multiple protocol-specific keys from a single master password.

async function eskdf(username: string, password: string): Promise<ESKDF>;
function deriveMainSeed(username: string, password: string): Uint8Array;
function scrypt(password: string, salt: string): Uint8Array;
function pbkdf2(password: string, salt: string): Uint8Array;

ESKDF

WebCrypto

Friendly wrapper over native WebCrypto API with noble-hashes compatible interface. All operations are async. Provides better performance when available but with less control than pure JS implementations.

async function sha256(msg: Uint8Array): Promise<Uint8Array>;
async function hmac(hash: WebHash, key: Uint8Array, message: Uint8Array): Promise<Uint8Array>;
async function hkdf(hash: WebHash, ikm: Uint8Array, salt?: Uint8Array, info?: Uint8Array, length: number): Promise<Uint8Array>;
async function pbkdf2(hash: WebHash, password: string | Uint8Array, salt: string | Uint8Array, opts: { c: number; dkLen?: number }): Promise<Uint8Array>;

WebCrypto

Utilities

Core utility functions for encoding/decoding, byte manipulation, validation, and cryptographic operations.

function bytesToHex(bytes: Uint8Array): string;
function hexToBytes(hex: string): Uint8Array;
function utf8ToBytes(str: string): Uint8Array;
function randomBytes(bytesLength?: number): Uint8Array;
function concatBytes(...arrays: Uint8Array[]): Uint8Array;
function isBytes(a: unknown): a is Uint8Array;

Utilities

Security Considerations

Audited Code

The library (v1.0.0) was independently audited by Cure53 in January 2022. Audit scope included everything except blake3, sha3-addons, sha1, and argon2. The audit was funded by Ethereum Foundation with help of Nomic Labs.

Constant-Time Operations

The library targets algorithmic constant time but JavaScript's JIT compiler and garbage collector make true constant-time operations difficult to achieve. For absolute security in timing-sensitive contexts, use low-level languages.

Supply Chain Security

  • Zero runtime dependencies
  • PGP-signed commits
  • Transparent builds on GitHub CI with attestations
  • Rare releases to reduce re-audit requirements

Random Number Generation

Uses built-in crypto.getRandomValues() which is considered cryptographically secure (CSPRNG).

Quantum Resistance

Hash output sizes should be doubled for quantum resistance: SHA-256 → SHA-512, SHA3-256 → SHA3-512, SHAKE128 → SHAKE256.

Important Notes

Input Format

All hash functions accept only Uint8Array inputs (v2.0+). To hash strings, use utf8ToBytes():

import { sha256 } from '@noble/hashes/sha2.js';
import { utf8ToBytes } from '@noble/hashes/utils.js';

const hash = sha256(utf8ToBytes('hello world'));

ESM-Only

Version 2.0+ is ESM-only. All imports must include the .js file extension.

Memory Cleanup

The library zeros out internal buffers after use. However, JavaScript provides no guarantees about memory security due to strings being immutable, async operations writing to memory, and lack of control over garbage collection.

Performance

Benchmarks on Apple M4 for 32-byte input:

  • sha256: 496ns/op
  • sha512: 1μs/op
  • sha3_256: 3μs/op
  • blake2b: 2μs/op
  • blake3: 1μs/op

For 1MB input:

  • sha256: 3ms/op
  • blake3: 13ms/op

KDF performance:

  • pbkdf2(sha256, c: 2^18): 197ms
  • scrypt(N: 2^18, r: 8, p: 1): 400ms

Install with Tessl CLI

npx tessl i tessl/npm-noble--hashes@2.0.0

docs

argon2.md

blake.md

eskdf.md

hkdf.md

hmac.md

index.md

legacy.md

pbkdf2.md

scrypt.md

sha2.md

sha3-addons.md

sha3.md

utils.md

webcrypto.md

tile.json