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

sha3.mddocs/

SHA-3, Keccak, and SHAKE

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.

Imports

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';

Capabilities

SHA-3 Hash Functions

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();

Keccak Hash Functions

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 address

SHAKE Extendable Output Functions (XOF)

SHAKE 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)

Keccak Class Interface

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;
}

Usage Examples

Ethereum Address Generation

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);
}

SHAKE for Key Derivation

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);

SHA-3 vs Keccak Comparison

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 schemes

Incremental Hashing with Clone

import { 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();

Technical Details

Keccak Sponge Construction

The Keccak family uses a sponge construction with:

  • Absorb phase: Input is XORed into state in blocks
  • Squeeze phase: Output is extracted from state

The state is a 1600-bit (200-byte) array that undergoes the Keccak-f[1600] permutation.

Capacity and Rate

Each Keccak variant has a security parameter called capacity (c):

  • Rate (r): Block size = 1600 - capacity
  • Capacity (c): Security parameter = 2 × output_length

Higher capacity = better security but slower performance.

Differences Between SHA-3 and Keccak

The main difference is the padding scheme:

  • Keccak: Uses padding 0x01
  • SHA-3: Uses padding 0x06

This means sha3_256(data) ≠ keccak_256(data) for the same input.

Performance Characteristics

  • SHA-3 is slower than SHA-2 but offers different security properties
  • Block size varies by variant (larger output = smaller blocks)
  • XOF functions have no performance penalty for reading additional bytes
  • Incremental hashing adds minimal overhead

Security Notes

  • All SHA-3 and Keccak variants are currently considered secure
  • SHA-3 was designed to be resistant to length extension attacks
  • Keccak won the SHA-3 competition in 2012
  • SHAKE provides variable-length output for flexible security levels
  • For quantum resistance: use SHAKE256 or SHA3-512 (256-bit post-quantum security)

When to Use Each

Use SHA-3:

  • When NIST compliance is required
  • As an alternative to SHA-2 for defense in depth
  • In post-quantum cryptographic systems

Use Keccak:

  • For Ethereum and blockchain compatibility
  • When you need the original Keccak algorithm
  • For legacy compatibility with pre-FIPS Keccak implementations

Use SHAKE:

  • When you need variable-length output
  • For key derivation with custom output sizes
  • When reading multiple keys from a single hash state
  • In protocols requiring extendable output

References

  • FIPS 202: SHA-3 Standard
  • Keccak Team Website: Original specifications
  • SHA-3 vs Keccak: Key differences explained

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