or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

hmac.mdindex.mdripemd.mdsha-hashes.mdutilities.md
tile.json

hmac.mddocs/

HMAC

Hash-based Message Authentication Code (HMAC) is a mechanism for message authentication using cryptographic hash functions. HMAC provides both data integrity and authenticity verification using a shared secret key.

Capabilities

HMAC Constructor

Creates HMAC instances using any supported hash function with a secret key.

/**
 * Creates a new HMAC instance
 * @param hashFn - Hash function constructor (sha1, sha256, sha512, ripemd160, etc.)
 * @param key - Secret key for authentication (string, array, or Uint8Array) 
 * @param enc - Encoding for key input ('hex' or undefined for UTF-8)
 * @returns HMAC instance
 */
function hmac(hashFn: HashConstructor, key: any, enc?: 'hex'): HMACInstance;

interface HMACInstance {
  update(msg: any, enc?: 'hex'): this;
  digest(): number[];
  digest(enc: 'hex'): string;
  blockSize: number;  // Derived from hash function
  outSize: number;    // Derived from hash function
}

type HashConstructor = 
  | typeof sha1 
  | typeof sha224 
  | typeof sha256 
  | typeof sha384 
  | typeof sha512 
  | typeof ripemd160;

Usage Examples:

const hash = require('hash.js');

// HMAC-SHA256
const hmacSha256 = hash.hmac(hash.sha256, 'secret-key')
  .update('message to authenticate')
  .digest('hex');

// HMAC-SHA512  
const hmacSha512 = hash.hmac(hash.sha512, 'my-secret')
  .update('important data')
  .digest('hex');

// HMAC-RIPEMD160
const hmacRipemd = hash.hmac(hash.ripemd160, 'key')
  .update('data')
  .digest('hex');

HMAC with Different Key Formats

HMAC supports various key input formats including strings, hex-encoded keys, and binary data.

String Keys:

const hash = require('hash.js');

// UTF-8 string key
const hmac1 = hash.hmac(hash.sha256, 'my-secret-key')
  .update('message')
  .digest('hex');

// Long passphrase key
const hmac2 = hash.hmac(hash.sha256, 'this is a very long passphrase key')
  .update('message')
  .digest('hex');

Hex-Encoded Keys:

const hash = require('hash.js');

// Hex-encoded key
const hexKey = '00010203040506070809A0B0C0D0E0F101112131415161718191A1B1C1D1E1F';
const hmacHex = hash.hmac(hash.sha256, hexKey, 'hex')
  .update('message')
  .digest('hex');

Binary Keys:

const hash = require('hash.js');

// Byte array key
const binaryKey = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05];
const hmacBinary = hash.hmac(hash.sha256, binaryKey)
  .update('message')
  .digest('hex');

// Uint8Array key
const uint8Key = new Uint8Array([0x01, 0x02, 0x03, 0x04]);
const hmacUint8 = hash.hmac(hash.sha256, uint8Key)
  .update('message')
  .digest('hex');

HMAC with Incremental Updates

HMAC supports incremental message updates, allowing authentication of large or streaming data.

const hash = require('hash.js');

// Incremental HMAC computation
const hmac = hash.hmac(hash.sha256, 'secret-key');

hmac.update('first part of message');
hmac.update(' ');
hmac.update('second part of message');

const digest = hmac.digest('hex');

// Equivalent to single update
const singleUpdate = hash.hmac(hash.sha256, 'secret-key')
  .update('first part of message second part of message')
  .digest('hex');

console.log(digest === singleUpdate); // true

HMAC with Different Hash Functions

HMAC can be used with any supported hash function, providing different security levels and output sizes.

HMAC-SHA1 (160-bit output):

const hash = require('hash.js');

const hmacSha1 = hash.hmac(hash.sha1, 'key')
  .update('Sample message for keylen=blocklen')
  .digest('hex');

HMAC-SHA224 (224-bit output):

const hmacSha224 = hash.hmac(hash.sha224, 'key')
  .update('message')
  .digest('hex');

HMAC-SHA384 (384-bit output):

const hmacSha384 = hash.hmac(hash.sha384, 'key')
  .update('message')
  .digest('hex');

HMAC Properties

HMAC instances inherit properties from their underlying hash function:

const hash = require('hash.js');

// HMAC properties are derived from the hash function
const hmacSha256 = hash.hmac(hash.sha256, 'key');
console.log(hmacSha256.blockSize); // 64 (512 bits / 8)
console.log(hmacSha256.outSize);   // 32 (256 bits / 8)

const hmacSha512 = hash.hmac(hash.sha512, 'key');
console.log(hmacSha512.blockSize); // 128 (1024 bits / 8)
console.log(hmacSha512.outSize);   // 64 (512 bits / 8)

HMAC Test Vectors

Examples using standard HMAC test vectors:

const hash = require('hash.js');

// NIST test vector 1
const hmac1 = hash.hmac(
  hash.sha256,
  '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223242526272829A2B2C2D2E2F30313233343536373839A3B3C3D3E3F',
  'hex'
).update('Sample message for keylen=blocklen')
 .digest('hex');

// NIST test vector 2  
const hmac2 = hash.hmac(
  hash.sha256,
  '000102030405060708090A0B0C0D0E0F10111213141516171819A1B1C1D1E1F',
  'hex'
).update('Sample message for keylen<blocklen')
 .digest('hex');

Binary Output

HMAC can return results as byte arrays for binary processing:

const hash = require('hash.js');

// Get HMAC as byte array
const hmacBytes = hash.hmac(hash.sha256, 'secret')
  .update('message')
  .digest();

console.log(hmacBytes); // Array of bytes
console.log(hmacBytes.length); // 32 (for SHA-256)

// Convert to other formats
const base64 = Buffer.from(hmacBytes).toString('base64');
const hex = hmacBytes.map(b => b.toString(16).padStart(2, '0')).join('');

Key Length Considerations

HMAC handles keys of any length through the following process:

  • Short keys (< block size): Padded with zeros
  • Long keys (> block size): Hashed to fit block size
  • Optimal keys: Equal to hash function's block size
const hash = require('hash.js');

// Short key (will be padded)
const shortKey = hash.hmac(hash.sha256, 'short').update('msg').digest('hex');

// Long key (will be hashed first)
const longKey = 'a'.repeat(1000);
const longKeyHmac = hash.hmac(hash.sha256, longKey).update('msg').digest('hex');

// Optimal key length for SHA-256 is 64 bytes (512 bits)
const optimalKey = 'a'.repeat(64);
const optimalHmac = hash.hmac(hash.sha256, optimalKey).update('msg').digest('hex');