nodejs-keccak256
affaan-m/everything-claude-code
Use Ethereum's Keccak-256, not Node's NIST SHA3, to prevent silent hashing bugs in selectors, signatures, and storage slots.
What is nodejs-keccak256?
This skill prevents a critical bug where Node.js's crypto.createHash('sha3-256') produces NIST SHA3 instead of Ethereum's Keccak-256, silently breaking function selectors, signatures, Merkle trees, and address derivation. Use it when building Ethereum-aware JavaScript or TypeScript code that hashes data.
- Demonstrates the difference between NIST SHA3 and Keccak-256 with concrete examples
- Provides correct Keccak-256 patterns using ethers v6, viem, and web3.js
- Shows how to compute Ethereum function selectors and event topics correctly
- Explains storage slot and address derivation from public keys using Keccak-256
- Includes audit commands to find unsafe sha3-256 usage in your codebase
How to install nodejs-keccak256
npx skills add https://github.com/affaan-m/everything-claude-code --skill nodejs-keccak256- Node.js environment with crypto module available
- One of: ethers v6, viem, or web3.js library installed for Keccak-256 functions
How to use nodejs-keccak256
- 1.Replace any crypto.createHash('sha3-256') calls with keccak256 from ethers, viem, or web3.js
- 2.For ethers v6: import keccak256 and toUtf8Bytes, then call keccak256(toUtf8Bytes(data))
- 3.For viem: import keccak256 and toBytes, then call keccak256(toBytes(data))
- 4.For web3.js: use web3.utils.keccak256(data) directly
- 5.Run the provided grep commands to audit your codebase for unsafe sha3-256 usage
Use cases
- Computing function selectors for contract interactions (e.g., transfer(address,uint256))
- Building EIP-712 signature helpers and Merkle tree implementations
- Deriving Ethereum addresses from public keys
- Computing storage slot keys for mapping lookups
- Validating or generating event topic hashes
- Ethereum/Web3 developers using Node.js or TypeScript
- Smart contract interaction library authors
- Anyone building signature or Merkle verification in JavaScript
- Code reviewers checking for cryptographic correctness in blockchain code
nodejs-keccak256 FAQ
Node.js implements the NIST-standardized SHA3 algorithm, which is different from the original Keccak-256 that Ethereum adopted before NIST standardization. They are incompatible and produce different hashes for the same input.
Function selectors, event topics, signatures, Merkle proofs, storage slot keys, and address derivation will all be incorrect. The bug is silent—no error is raised, but the hashes are wrong.
ethers v6, viem, and web3.js all provide correct Keccak-256 implementations. Choose based on your existing dependencies; ethers is widely used for general Ethereum work.
Use keccak256(toUtf8Bytes('functionName(type1,type2)')) from ethers, then take the first 4 bytes (0x prefix + 8 hex chars).
Yes, run: grep -rn "createHash.*sha3" --include="*.ts" --include="*.js" --exclude-dir=node_modules . to find unsafe usage.
Full instructions (SKILL.md)
Source of truth, from affaan-m/everything-claude-code.
name: nodejs-keccak256 description: Prevent Ethereum hashing bugs in JavaScript and TypeScript. Node's sha3-256 is NIST SHA3, not Ethereum Keccak-256, and silently breaks selectors, signatures, storage slots, and address derivation. metadata: origin: ECC direct-port adaptation version: "1.0.0"
Node.js Keccak-256
Ethereum uses Keccak-256, not the NIST-standardized SHA3 variant exposed by Node's crypto.createHash('sha3-256').
When to Use
- Computing Ethereum function selectors or event topics
- Building EIP-712, signature, Merkle, or storage-slot helpers in JS/TS
- Reviewing any code that hashes Ethereum data with Node crypto directly
How It Works
The two algorithms produce different outputs for the same input, and Node will not warn you.
import crypto from 'crypto';
import { keccak256, toUtf8Bytes } from 'ethers';
const data = 'hello';
const nistSha3 = crypto.createHash('sha3-256').update(data).digest('hex');
const keccak = keccak256(toUtf8Bytes(data)).slice(2);
console.log(nistSha3 === keccak); // false
Examples
ethers v6
import { keccak256, toUtf8Bytes, solidityPackedKeccak256, id } from 'ethers';
const hash = keccak256(new Uint8Array([0x01, 0x02]));
const hash2 = keccak256(toUtf8Bytes('hello'));
const topic = id('Transfer(address,address,uint256)');
const packed = solidityPackedKeccak256(
['address', 'uint256'],
['0x742d35Cc6634C0532925a3b8D4C9B569890FaC1c', 100n],
);
viem
import { keccak256, toBytes } from 'viem';
const hash = keccak256(toBytes('hello'));
web3.js
const hash = web3.utils.keccak256('hello');
const packed = web3.utils.soliditySha3(
{ type: 'address', value: '0x742d35Cc6634C0532925a3b8D4C9B569890FaC1c' },
{ type: 'uint256', value: '100' },
);
Common patterns
import { id, keccak256, AbiCoder } from 'ethers';
const selector = id('transfer(address,uint256)').slice(0, 10);
const typeHash = keccak256(toUtf8Bytes('Transfer(address from,address to,uint256 value)'));
function getMappingSlot(key: string, mappingSlot: number): string {
return keccak256(
AbiCoder.defaultAbiCoder().encode(['address', 'uint256'], [key, mappingSlot]),
);
}
Address from public key
import { keccak256 } from 'ethers';
function pubkeyToAddress(pubkeyBytes: Uint8Array): string {
const hash = keccak256(pubkeyBytes.slice(1));
return '0x' + hash.slice(-40);
}
Audit your codebase
grep -rn "createHash.*sha3" --include="*.ts" --include="*.js" --exclude-dir=node_modules .
grep -rn "keccak256" --include="*.ts" --include="*.js" . | grep -v node_modules
Rule
For Ethereum contexts, never use crypto.createHash('sha3-256'). Use Keccak-aware helpers from ethers, viem, web3, or another explicit Keccak implementation.
Related skills
More from affaan-m/everything-claude-code and the wider catalog.

security-review
Security checklist and patterns for authentication, input validation, secrets, and sensitive features.

golang-patterns
Idiomatic Go patterns, best practices, and conventions for building robust, efficient, and maintainable applications.

coding-standards
Baseline coding conventions for naming, readability, immutability, and quality across projects.

frontend-patterns
React and Next.js patterns for components, state management, performance, and modern frontend practices.

backend-patterns
REST/GraphQL API design, database optimization, and server-side patterns for Node.js, Express, and Next.js.

golang-testing
Go testing patterns: table-driven tests, subtests, benchmarks, fuzzing, and TDD methodology.