Complete API reference for @blockutil/kheavyhash.
Hashes input data using the KHeavyHash algorithm.
Signature:
function kheavyhash(input: Uint8Array | string): Uint8Array;Parameters:
input(Uint8Array | string): Input data to hash- If
Uint8Array: Must be exactly 80 bytes - If
string: Must be a hex string representing exactly 80 bytes (160 hex characters), with or without0xprefix
- If
Returns:
Uint8Array: The hash result (32 bytes)
Throws:
Error: If input is not exactly 80 bytes
Input Format:
The input must be exactly 80 bytes with the following structure:
| Bytes | Field | Size | Description |
|---|---|---|---|
| 0-31 | prePowHash |
32 bytes | Previous proof-of-work hash |
| 32-39 | timestamp |
8 bytes | Block timestamp (little-endian) |
| 40-71 | padding |
32 bytes | Must be all zeros |
| 72-79 | nonce |
8 bytes | Mining nonce (little-endian) |
Example:
import { kheavyhash, bytesToHex, hexToBytes } from '@blockutil/kheavyhash';
// From Uint8Array
const input = new Uint8Array(80);
// ... populate with data ...
const hash = kheavyhash(input);
console.log(bytesToHex(hash));
// From hex string
const hexInput =
'0ad86e9bef09726cdc75913e44ec96521391c7ceb2aae3c633f46a94bf4d2546' +
'3ed68b9501950000' + // timestamp (little-endian)
'0'.repeat(64) + // padding (32 bytes = 64 hex chars)
'39fd0630849571'; // nonce (little-endian)
const hash2 = kheavyhash(hexInput);
console.log(bytesToHex(hash2));Algorithm:
- Hash the input with
cSHAKE256(input, 256, '', 'ProofOfWorkHash')→powHash(32 bytes) - Extract
prePowHash(first 32 bytes of input) - Generate a 64×64 matrix of 4-bit values from
prePowHashusing xoshiro256++ - Apply matrix-vector multiplication to
powHash(HeavyHash transformation) - XOR the result with
powHashand hash again withcSHAKE256(res, 256, '', 'HeavyHash') - Return the final 32-byte hash
Compatibility:
This implementation is compatible with the Go reference implementation at:
Type guard to validate if input is valid for KHeavyHash.
Signature:
function validateInput(input: unknown): input is Uint8Array | string;Parameters:
input(unknown): Value to validate
Returns:
boolean:trueif input is valid,falseotherwise
Validation Rules:
- If
string: Must be a valid hex string (with or without0xprefix) representing exactly 80 bytes (160 hex characters) - If
Uint8Array: Must have exactly 80 bytes - Otherwise: Returns
false
Example:
import { validateInput, kheavyhash } from '@blockutil/kheavyhash';
const input = new Uint8Array(80);
if (validateInput(input)) {
const hash = kheavyhash(input);
}
// Or with hex string
const hexInput = '0'.repeat(160);
if (validateInput(hexInput)) {
const hash = kheavyhash(hexInput);
}Converts a hex string to Uint8Array.
Signature:
function hexToBytes(hex: string): Uint8Array;Parameters:
hex(string): Hex string (with or without0xprefix)
Returns:
Uint8Array: Byte representation of the hex string
Throws:
Error: If hex string contains invalid characters or has odd length
Example:
import { hexToBytes } from '@blockutil/kheavyhash';
const bytes = hexToBytes('0x0123abcd');
// or
const bytes2 = hexToBytes('0123abcd');Notes:
- Accepts both
'0x0123'and'0123'formats - Hex string must have even length (each byte = 2 hex characters)
- Case-insensitive (accepts both uppercase and lowercase)
Converts a Uint8Array to hex string.
Signature:
function bytesToHex(bytes: Uint8Array, prefix?: boolean): string;Parameters:
bytes(Uint8Array): Bytes to convertprefix(boolean, optional): Whether to prefix with0x(default:false)
Returns:
string: Hex string representation (lowercase)
Example:
import { bytesToHex } from '@blockutil/kheavyhash';
const bytes = new Uint8Array([0x01, 0x23, 0xab, 0xcd]);
const hex = bytesToHex(bytes); // "0123abcd"
const hexWithPrefix = bytesToHex(bytes, true); // "0x0123abcd"Notes:
- Output is always lowercase
- Each byte is represented as two hex characters
type KHeavyHashInput = Uint8Array | string;Uint8Array: Must be exactly 80 bytesstring: Must be a hex string representing exactly 80 bytes (160 hex characters)
type KHeavyHashOutput = Uint8Array; // Always 32 bytesAll functions that can fail will throw Error objects with descriptive messages.
Common Errors:
-
Invalid input length:
Error: KHeavyHash requires exactly 80 bytes, got 79
-
Invalid hex string:
Error: Invalid hex string
-
Odd-length hex string:
Error: Hex string must have even length
Best Practices:
import { kheavyhash, validateInput } from '@blockutil/kheavyhash';
try {
const input = new Uint8Array(80);
// ... populate input ...
if (validateInput(input)) {
const hash = kheavyhash(input);
// Use hash...
} else {
console.error('Invalid input');
}
} catch (error) {
if (error instanceof Error) {
console.error('Hash failed:', error.message);
}
}import { kheavyhash, bytesToHex, hexToBytes } from '@blockutil/kheavyhash';
// Construct 80-byte input
const prePowHash = hexToBytes('0ad86e9bef09726cdc75913e44ec96521391c7ceb2aae3c633f46a94bf4d2546');
const timestamp = new Uint8Array(8);
// Set timestamp as little-endian 64-bit integer
const view = new DataView(timestamp.buffer);
view.setBigUint64(0, BigInt(0x19568d36b3e), true); // true = little-endian
const padding = new Uint8Array(32); // Already zeros
const nonce = new Uint8Array(8);
view.setBigUint64(0, BigInt(0x571506849306fd39), true); // true = little-endian
// Combine into 80-byte input
const input = new Uint8Array(80);
input.set(prePowHash, 0);
input.set(timestamp, 32);
input.set(padding, 40);
input.set(nonce, 72);
// Hash
const hash = kheavyhash(input);
console.log(bytesToHex(hash));import { kheavyhash, bytesToHex } from '@blockutil/kheavyhash';
// All 80 bytes as hex string (160 hex characters)
const hexInput =
'0ad86e9bef09726cdc75913e44ec96521391c7ceb2aae3c633f46a94bf4d2546' +
'3ed68b9501950000' + // timestamp (little-endian)
'0'.repeat(64) + // padding (32 bytes)
'39fd0630849571'; // nonce (little-endian)
const hash = kheavyhash(hexInput);
console.log(bytesToHex(hash));import { kheavyhash, bytesToHex, hexToBytes } from '@blockutil/kheavyhash';
// Initial prePowHash
let prePowHash = hexToBytes('0ad86e9bef09726cdc75913e44ec96521391c7ceb2aae3c633f46a94bf4d2546');
const timestamp = 0x19568d36b3e; // Fixed timestamp
let nonce = 0;
// Mine for 1000 iterations
for (let i = 0; i < 1000; i++) {
// Construct input
const input = new Uint8Array(80);
input.set(prePowHash, 0);
// Set timestamp (little-endian)
const timestampBytes = new Uint8Array(8);
const view = new DataView(timestampBytes.buffer);
view.setBigUint64(0, BigInt(timestamp), true);
input.set(timestampBytes, 32);
// Padding (already zeros)
// input.set(new Uint8Array(32), 40); // Not needed, already zero
// Set nonce (little-endian)
const nonceBytes = new Uint8Array(8);
view.setBigUint64(0, BigInt(nonce), true);
input.set(nonceBytes, 72);
// Hash
const hash = kheavyhash(input);
// Use output as next prePowHash
prePowHash = hash;
// Increment nonce for next iteration
nonce++;
if (i % 100 === 0) {
console.log(`Iteration ${i}: ${bytesToHex(hash)}`);
}
}import { validateInput, kheavyhash } from '@blockutil/kheavyhash';
function safeHash(input: unknown): Uint8Array | null {
if (!validateInput(input)) {
console.error('Invalid input: must be 80-byte Uint8Array or 160-char hex string');
return null;
}
try {
return kheavyhash(input);
} catch (error) {
console.error('Hash failed:', error);
return null;
}
}
// Usage
const hash1 = safeHash(new Uint8Array(80)); // ✅ Valid
const hash2 = safeHash('0'.repeat(160)); // ✅ Valid
const hash3 = safeHash(new Uint8Array(79)); // ❌ Invalid (wrong length)
const hash4 = safeHash('invalid'); // ❌ Invalid (not hex)All functions are exported from the main module:
export { kheavyhash, validateInput, hexToBytes, bytesToHex };ESM Import:
import { kheavyhash, bytesToHex } from '@blockutil/kheavyhash';CommonJS Import:
const { kheavyhash, bytesToHex } = require('@blockutil/kheavyhash');- Matrix Generation: The Go reference regenerates matrices until full rank (64) is found, which can be slow. This implementation uses the first generated matrix for performance. All test vectors pass with this approach.
- Deterministic: The algorithm is fully deterministic - same input always produces same output.
- Performance: Typical hash time is < 10ms per hash on modern hardware.