Audited & minimal 0-dependency JS implementation of SHA, RIPEMD, BLAKE, HMAC, HKDF, PBKDF & Scrypt
SHA-3 is the latest NIST-standardized cryptographic hash function family, using the Keccak sponge construction. Unlike SHA-2, SHA-3 is based on a completely different internal structure, providing an alternative standard in case weaknesses are found in SHA-2. Keccak variants differ slightly from the official SHA-3 and are used in blockchain applications like Ethereum.
import {
sha3_224, sha3_256, sha3_384, sha3_512,
keccak_224, keccak_256, keccak_384, keccak_512,
shake128, shake256, shake128_32, shake256_64
} from '@noble/hashes/sha3.js';FIPS 202 standard SHA-3 hash functions with fixed output lengths.
/**
* Computes SHA3-224 hash of input data
* @param msg - Input data as Uint8Array
* @returns 28-byte hash digest
*/
function sha3_224(msg: Uint8Array): Uint8Array;
// Properties
sha3_224.outputLen: 28; // Output length in bytes
sha3_224.blockLen: 144; // Block length in bytes
// Create incremental hasher
function create(): Keccak;
/**
* Computes SHA3-256 hash of input data
* @param msg - Input data as Uint8Array
* @returns 32-byte hash digest
*/
function sha3_256(msg: Uint8Array): Uint8Array;
// Properties
sha3_256.outputLen: 32; // Output length in bytes
sha3_256.blockLen: 136; // Block length in bytes
// Create incremental hasher
function create(): Keccak;
/**
* Computes SHA3-384 hash of input data
* @param msg - Input data as Uint8Array
* @returns 48-byte hash digest
*/
function sha3_384(msg: Uint8Array): Uint8Array;
// Properties
sha3_384.outputLen: 48; // Output length in bytes
sha3_384.blockLen: 104; // Block length in bytes
// Create incremental hasher
function create(): Keccak;
/**
* Computes SHA3-512 hash of input data
* @param msg - Input data as Uint8Array
* @returns 64-byte hash digest
*/
function sha3_512(msg: Uint8Array): Uint8Array;
// Properties
sha3_512.outputLen: 64; // Output length in bytes
sha3_512.blockLen: 72; // Block length in bytes
// Create incremental hasher
function create(): Keccak;Usage:
import { sha3_256 } from '@noble/hashes/sha3.js';
import { bytesToHex } from '@noble/hashes/utils.js';
// Simple hash
const hash = sha3_256(Uint8Array.from([0xca, 0xfe]));
console.log(bytesToHex(hash)); // 32-byte hex string
// Incremental hashing
const hasher = sha3_256.create();
hasher.update(Uint8Array.from([0x10, 0x20]));
hasher.update(Uint8Array.from([0x30, 0x40]));
const result = hasher.digest();Original Keccak hash functions that differ from SHA-3 in the padding scheme. These are used in Ethereum and other blockchain applications.
/**
* Computes Keccak-224 hash of input data
* @param msg - Input data as Uint8Array
* @returns 28-byte hash digest
*/
function keccak_224(msg: Uint8Array): Uint8Array;
// Properties
keccak_224.outputLen: 28; // Output length in bytes
keccak_224.blockLen: 144; // Block length in bytes
// Create incremental hasher
function create(): Keccak;
/**
* Computes Keccak-256 hash of input data (Ethereum-compatible)
* @param msg - Input data as Uint8Array
* @returns 32-byte hash digest
*/
function keccak_256(msg: Uint8Array): Uint8Array;
// Properties
keccak_256.outputLen: 32; // Output length in bytes
keccak_256.blockLen: 136; // Block length in bytes
// Create incremental hasher
function create(): Keccak;
/**
* Computes Keccak-384 hash of input data
* @param msg - Input data as Uint8Array
* @returns 48-byte hash digest
*/
function keccak_384(msg: Uint8Array): Uint8Array;
// Properties
keccak_384.outputLen: 48; // Output length in bytes
keccak_384.blockLen: 104; // Block length in bytes
// Create incremental hasher
function create(): Keccak;
/**
* Computes Keccak-512 hash of input data
* @param msg - Input data as Uint8Array
* @returns 64-byte hash digest
*/
function keccak_512(msg: Uint8Array): Uint8Array;
// Properties
keccak_512.outputLen: 64; // Output length in bytes
keccak_512.blockLen: 72; // Block length in bytes
// Create incremental hasher
function create(): Keccak;Usage:
import { keccak_256 } from '@noble/hashes/sha3.js';
import { bytesToHex } from '@noble/hashes/utils.js';
// Ethereum address hashing
const address = Uint8Array.from([/* public key bytes */]);
const hash = keccak_256(address);
console.log(bytesToHex(hash.slice(-20))); // Last 20 bytes for Ethereum addressSHAKE functions provide variable-length output, allowing you to extract as many bytes as needed from a single hash computation.
/**
* SHAKE128 extendable output function
* @param msg - Input data as Uint8Array
* @param opts - Options with output length
* @param opts.dkLen - Desired output length in bytes (default: 32)
* @returns Hash digest of specified length
*/
function shake128(msg: Uint8Array, opts?: ShakeOpts): Uint8Array;
// Properties
shake128.outputLen: undefined; // Variable output length
shake128.blockLen: 168; // Block length in bytes
// Create incremental hasher
function create(opts?: ShakeOpts): Keccak;
/**
* SHAKE256 extendable output function
* @param msg - Input data as Uint8Array
* @param opts - Options with output length
* @param opts.dkLen - Desired output length in bytes (default: 64)
* @returns Hash digest of specified length
*/
function shake256(msg: Uint8Array, opts?: ShakeOpts): Uint8Array;
// Properties
shake256.outputLen: undefined; // Variable output length
shake256.blockLen: 136; // Block length in bytes
// Create incremental hasher
function create(opts?: ShakeOpts): Keccak;
/**
* SHAKE128 with default 32-byte output
* @param msg - Input data as Uint8Array
* @param opts - Options with output length
* @param opts.dkLen - Desired output length in bytes (default: 32)
* @returns 32-byte hash digest (or custom length if specified)
*/
function shake128_32(msg: Uint8Array, opts?: ShakeOpts): Uint8Array;
/**
* SHAKE256 with default 64-byte output
* @param msg - Input data as Uint8Array
* @param opts - Options with output length
* @param opts.dkLen - Desired output length in bytes (default: 64)
* @returns 64-byte hash digest (or custom length if specified)
*/
function shake256_64(msg: Uint8Array, opts?: ShakeOpts): Uint8Array;
/**
* Options for SHAKE functions
*/
interface ShakeOpts {
/** Desired output length in bytes */
dkLen?: number;
}Usage:
import { shake256 } from '@noble/hashes/sha3.js';
// Variable-length output
const hash64 = shake256(data, { dkLen: 64 });
const hash128 = shake256(data, { dkLen: 128 });
// Streaming XOF usage
const hasher = shake256.create();
hasher.update(chunk1);
hasher.update(chunk2);
// Extract multiple outputs
const output1 = hasher.xof(32); // Read 32 bytes
const output2 = hasher.xof(32); // Read another 32 bytes
const output3 = hasher.xof(64); // Read 64 more bytes
// Alternative: digest with specified length
const output = hasher.digest(); // Default length (64 bytes for shake256)All SHA-3 and Keccak functions return instances implementing the Keccak class interface:
class Keccak {
blockLen: number;
outputLen: number;
/**
* Updates hash with new data
* @param buf - Data to hash
* @returns this for chaining
*/
update(buf: Uint8Array): this;
/**
* Finalizes hash and returns digest
* @returns Hash digest as Uint8Array
*/
digest(): Uint8Array;
/**
* Finalizes hash and writes digest to provided buffer
* @param out - Output buffer (must be >= outputLen)
* @returns The output buffer
*/
digestInto(out: Uint8Array): Uint8Array;
/**
* Reads bytes from XOF (only for SHAKE functions)
* @param bytes - Number of bytes to read
* @returns Bytes from XOF stream
*/
xof(bytes: number): Uint8Array;
/**
* Reads bytes from XOF into provided buffer (only for SHAKE functions)
* @param out - Output buffer
* @returns The output buffer
*/
xofInto(out: Uint8Array): Uint8Array;
/**
* Destroys internal state (zeros memory)
*/
destroy(): void;
/**
* Creates independent copy of current hash state
* @returns Cloned hash instance
*/
clone(): Keccak;
}import { keccak_256 } from '@noble/hashes/sha3.js';
import { bytesToHex } from '@noble/hashes/utils.js';
function getEthereumAddress(publicKey: Uint8Array): string {
// Remove 0x04 prefix if present (uncompressed key)
const key = publicKey[0] === 0x04 ? publicKey.slice(1) : publicKey;
// Keccak-256 hash
const hash = keccak_256(key);
// Take last 20 bytes as address
const address = hash.slice(-20);
return '0x' + bytesToHex(address);
}import { shake256 } from '@noble/hashes/sha3.js';
function deriveKeys(masterSecret: Uint8Array, count: number, keyLen: number): Uint8Array[] {
const hasher = shake256.create();
hasher.update(masterSecret);
const keys: Uint8Array[] = [];
for (let i = 0; i < count; i++) {
keys.push(hasher.xof(keyLen));
}
return keys;
}
// Derive 5 keys of 32 bytes each from a master secret
const masterSecret = new Uint8Array(32).fill(0x42);
const keys = deriveKeys(masterSecret, 5, 32);import { sha3_256, keccak_256 } from '@noble/hashes/sha3.js';
import { bytesToHex } from '@noble/hashes/utils.js';
const data = Uint8Array.from([0x00, 0x01, 0x02]);
const sha3Hash = sha3_256(data);
const keccakHash = keccak_256(data);
console.log('SHA3-256: ', bytesToHex(sha3Hash));
console.log('Keccak-256:', bytesToHex(keccakHash));
// These will be different due to different padding schemesimport { sha3_256 } from '@noble/hashes/sha3.js';
// Create base hasher with common prefix
const baseHasher = sha3_256.create();
baseHasher.update(commonPrefix);
// Clone for different branches
const hasher1 = baseHasher.clone();
hasher1.update(branch1Data);
const hash1 = hasher1.digest();
const hasher2 = baseHasher.clone();
hasher2.update(branch2Data);
const hash2 = hasher2.digest();The Keccak family uses a sponge construction with:
The state is a 1600-bit (200-byte) array that undergoes the Keccak-f[1600] permutation.
Each Keccak variant has a security parameter called capacity (c):
Higher capacity = better security but slower performance.
The main difference is the padding scheme:
0x010x06This means sha3_256(data) ≠ keccak_256(data) for the same input.
Use SHA-3:
Use Keccak:
Use SHAKE: