Пример
@noble/hashes 2.3.0: hmac
Проверенный пример — npm @noble/hashes 2.3.0: hmac. Контракт выполнен на node 22 · linux debian/x64 · docker и пройден: assert hmac computes one-shot…
sha256:d38e07ed915926e0227966d1fa4115a58aa63513d2c4a7cc57b580b69112caba
Эта сеть предлагает одно: образец, который собирается. Она запустила его в песочнице и сохранила подписанную квитанцию. Она ничего не оценивает и ничего не гарантирует — собирается ли тот же код у вас, она не измеряла.
Сколько различных ключей подписи подали пройденную квитанцию контракта. Один — только автор; больше одного — значит, кто-то ещё тоже собрал. Ключ создаётся сам и не имеет зарегистрированной личности, поэтому считаются ключи, а не люди.
MIT-0
Свидетельства выполнения
Заявленное окружение и подписанные запуски разделены, чтобы вы точно видели, что этот образец запускал и где.
- Основа свидетельства
- Подписанный контракт пройден
- Квитанции проверки
- 1
- Ключи подписи, собравшие его
- 1
Заявленная среда
node 22.23 linux 24 · ubuntu · glibc 2.39 x64 node 22.23 javascript npm 10
Среды запусков проверки
| Окружение | Контракт | Этапы | Запуск |
|---|---|---|---|
| node 22 · linux debian/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1node:22@sha256:8a34c4ab3ea2… |
2026-09-06 |
Кейс
HOW- Цель
- verify @noble/hashes.hmac in pkg:npm/%40noble/hashes@2.3.0
- Пакеты
- Символы
-
- @noble/hashes.hmac
- Окружение
- node 22.23.2
- Создан
- 2026-09-06T20:26:45Z
Контракт
- assert hmac computes one-shot authentication tag matching RFC 4231 test vectors for SHA-256 and SHA-512
- assert hmac.create initializes streaming instance exposing blockLen and outputLen properties
- assert hmac streaming instance update supports method chaining and matches one-shot computation
- assert hmac streaming instance clone forks intermediate state into independent authenticators
- assert hmac digestInto writes authentication tag directly into preallocated destination buffer
- assert hmac throws TypeError on non-byte keys or invalid hash functions
- assert hmac streaming methods throw on destroyed instance or undersized output buffer
Файлы
- PROMPT.md
- csx.json
- index.js
- package-lock.json
- package.json
- spec.json
- test/contract.mjs
Исходный код
Clean-room public code sample — generation instructions
Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.
A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.
Goal: verify @noble/hashes.hmac in pkg:npm/%40noble/hashes@2.3.0
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:npm/%40noble/hashes@2.3.0
Demonstrate these symbols/APIs:
- @noble/hashes.hmac
Rules:
- One focused purpose; the smallest project that proves the goal.
- Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
- Pin every dependency with a lockfile so resolution is reproducible.
- No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
- No personal names, emails, company names, or project identifiers of any kind.
- No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
- Keep it under 200 files and 256KB packed.
{"case":{"caseId":"case:sha256:3e566671ee67cb9d55d6eb1da504cf3e6d59a8c90bedd50f266cb1e993e71880","contract":["assert hmac computes one-shot authentication tag matching RFC 4231 test vectors for SHA-256 and SHA-512","assert hmac.create initializes streaming instance exposing blockLen and outputLen properties","assert hmac streaming instance update supports method chaining and matches one-shot computation","assert hmac streaming instance clone forks intermediate state into independent authenticators","assert hmac digestInto writes authentication tag directly into preallocated destination buffer","assert hmac throws TypeError on non-byte keys or invalid hash functions","assert hmac streaming methods throw on destroyed instance or undersized output buffer"],"goal":"verify @noble/hashes.hmac in pkg:npm/%40noble/hashes@2.3.0","kind":"HOW","packages":["pkg:npm/%40noble/hashes@2.3.0"],"schemaVersion":1,"symbols":["@noble/hashes.hmac"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","executionContext":"node","language":"javascript","libc":"glibc","libcVersion":"2.39","moduleSystem":"esm","os":"linux","osVersionBucket":"24","packageManager":"npm","packageManagerVersion":"10.9.8","runtime":"node","runtimeVersion":"22.23.2","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/%40noble/hashes@2.3.0"],"schemaVersion":1,"subject":"pkg:npm/%40noble/hashes@2.3.0","symbols":["@noble/hashes.hmac"],"verifierAdapter":"node-typescript@1"}
import { hmac, _HMAC } from '@noble/hashes/hmac.js';
import { sha256, sha512 } from '@noble/hashes/sha2.js';
import { bytesToHex, utf8ToBytes } from '@noble/hashes/utils.js';
/**
* Computes an HMAC authentication tag using the specified hash function.
* @param {import('@noble/hashes/utils.js').CHash} hash
* @param {Uint8Array} key
* @param {Uint8Array} message
* @returns {Uint8Array}
*/
export function computeHmac(hash, key, message) {
return hmac(hash, key, message);
}
/**
* Computes an HMAC digest and returns it as a lowercase hex string.
* @param {import('@noble/hashes/utils.js').CHash} hash
* @param {Uint8Array} key
* @param {Uint8Array} message
* @returns {string}
*/
export function computeHmacHex(hash, key, message) {
return bytesToHex(hmac(hash, key, message));
}
/**
* Creates an incremental HMAC streaming instance.
* @param {import('@noble/hashes/utils.js').CHash} hash
* @param {Uint8Array} key
* @returns {import('@noble/hashes/hmac.js')._HMAC<any>}
*/
export function createHmacStream(hash, key) {
return hmac.create(hash, key);
}
/**
* Computes an HMAC across an array of message chunks and returns lowercase hex.
* @param {import('@noble/hashes/utils.js').CHash} hash
* @param {Uint8Array} key
* @param {Uint8Array[]} chunks
* @returns {string}
*/
export function computeHmacChunksHex(hash, key, chunks) {
const stream = hmac.create(hash, key);
for (const chunk of chunks) {
stream.update(chunk);
}
return bytesToHex(stream.digest());
}
export { hmac, _HMAC, sha256, sha512, bytesToHex, utf8ToBytes };
{
"name": "sample-noble-hashes-hmac",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sample-noble-hashes-hmac",
"version": "1.0.0",
"license": "MIT-0",
"dependencies": {
"@noble/hashes": "2.3.0"
}
},
"node_modules/@noble/hashes": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.3.0.tgz",
"integrity": "sha512-oN+QwyX7VSHotibwubG3kpzbwKrfnyR6OOO+3Nk/53ADL7FmgHHz4TgrbaYKvvOw09u6QTx0oiH1cNCIOuN0CQ==",
"license": "MIT",
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
}
}
}
{
"name": "sample-noble-hashes-hmac",
"version": "1.0.0",
"description": "Clean-room verification sample for @noble/hashes.hmac in pkg:npm/%40noble/hashes@2.3.0",
"main": "index.js",
"type": "module",
"scripts": {
"test": "node test/contract.mjs"
},
"dependencies": {
"@noble/hashes": "2.3.0"
},
"license": "MIT-0"
}
{
"schemaVersion": 1,
"goal": "verify @noble/hashes.hmac in pkg:npm/%40noble/hashes@2.3.0",
"kind": "HOW",
"packages": [
"pkg:npm/%40noble/hashes@2.3.0"
],
"symbols": [
"@noble/hashes.hmac"
]
}
import assert from 'node:assert';
import {
hmac,
_HMAC,
sha256,
sha512,
computeHmac,
computeHmacHex,
createHmacStream,
computeHmacChunksHex,
bytesToHex,
utf8ToBytes,
} from '../index.js';
// 1. assert hmac computes one-shot authentication tag matching RFC 4231 test vectors for SHA-256 and SHA-512
const tc1Key = new Uint8Array(20).fill(0x0b);
const tc1Data = utf8ToBytes('Hi There');
const tc1Mac256 = computeHmac(sha256, tc1Key, tc1Data);
assert(tc1Mac256 instanceof Uint8Array, 'computeHmac returns Uint8Array');
assert.strictEqual(tc1Mac256.length, 32, 'HMAC-SHA256 produces 32-byte tag');
assert.strictEqual(
bytesToHex(tc1Mac256),
'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7',
'HMAC-SHA256 matches RFC 4231 TC1'
);
const tc2Key = utf8ToBytes('Jefe');
const tc2Data = utf8ToBytes('what do ya want for nothing?');
assert.strictEqual(
computeHmacHex(sha256, tc2Key, tc2Data),
'5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843',
'HMAC-SHA256 matches RFC 4231 TC2'
);
assert.strictEqual(
computeHmacHex(sha512, tc2Key, tc2Data),
'164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737',
'HMAC-SHA512 matches RFC 4231 TC2'
);
// 2. assert hmac.create initializes streaming instance exposing blockLen and outputLen properties
const stream256 = createHmacStream(sha256, tc2Key);
assert.strictEqual(stream256.blockLen, 64, 'HMAC-SHA256 blockLen is 64');
assert.strictEqual(stream256.outputLen, 32, 'HMAC-SHA256 outputLen is 32');
const stream512 = createHmacStream(sha512, tc2Key);
assert.strictEqual(stream512.blockLen, 128, 'HMAC-SHA512 blockLen is 128');
assert.strictEqual(stream512.outputLen, 64, 'HMAC-SHA512 outputLen is 64');
// 3. assert hmac streaming instance update supports method chaining and matches one-shot computation
const chainedStream = createHmacStream(sha256, tc2Key);
const chainedRet = chainedStream
.update(utf8ToBytes('what do '))
.update(utf8ToBytes('ya want '))
.update(utf8ToBytes('for nothing?'));
assert.strictEqual(chainedRet, chainedStream, 'update returns instance for fluent chaining');
const streamedTag = chainedStream.digest();
assert.strictEqual(
bytesToHex(streamedTag),
computeHmacHex(sha256, tc2Key, tc2Data),
'streaming digest matches one-shot HMAC'
);
const chunkedHex = computeHmacChunksHex(sha256, tc2Key, [
utf8ToBytes('what do '),
utf8ToBytes('ya want '),
utf8ToBytes('for nothing?'),
]);
assert.strictEqual(chunkedHex, computeHmacHex(sha256, tc2Key, tc2Data), 'chunked helper matches one-shot');
// 4. assert hmac streaming instance clone forks intermediate state into independent authenticators
const forkBase = createHmacStream(sha256, tc2Key);
forkBase.update(utf8ToBytes('prefix:'));
const branchAlpha = forkBase.clone();
const branchBeta = forkBase.clone();
branchAlpha.update(utf8ToBytes('route-alpha'));
branchBeta.update(utf8ToBytes('route-beta'));
const tagAlpha = bytesToHex(branchAlpha.digest());
const tagBeta = bytesToHex(branchBeta.digest());
assert.notStrictEqual(tagAlpha, tagBeta, 'Cloned branches produce distinct digests');
assert.strictEqual(
tagAlpha,
computeHmacHex(sha256, tc2Key, utf8ToBytes('prefix:route-alpha')),
'Branch Alpha matches independent computation'
);
assert.strictEqual(
tagBeta,
computeHmacHex(sha256, tc2Key, utf8ToBytes('prefix:route-beta')),
'Branch Beta matches independent computation'
);
// 5. assert hmac digestInto writes authentication tag directly into preallocated destination buffer
const destBuf = new Uint8Array(32);
const intoStream = createHmacStream(sha256, tc2Key);
intoStream.update(tc2Data);
intoStream.digestInto(destBuf);
assert.strictEqual(
bytesToHex(destBuf),
computeHmacHex(sha256, tc2Key, tc2Data),
'digestInto fills buffer accurately'
);
// 6. assert hmac throws TypeError on non-byte keys or invalid hash functions
assert.throws(() => {
hmac(sha256, 'string-key', tc2Data);
}, /expected Uint8Array/i, 'throws TypeError on string key');
assert.throws(() => {
hmac(() => {}, tc2Key, tc2Data);
}, /expected hash wrapped by utils.createHasher/i, 'throws TypeError on unwrapped hash function');
// 7. assert hmac streaming methods throw on destroyed instance or undersized output buffer
assert.throws(() => {
intoStream.update(utf8ToBytes('after destroy'));
}, /hash was destroyed/i, 'update throws after destruction');
assert.throws(() => {
intoStream.digest();
}, /hash was destroyed/i, 'digest throws after destruction');
const smallBuf = new Uint8Array(16);
const freshStream = createHmacStream(sha256, tc2Key);
assert.throws(() => {
freshStream.digestInto(smallBuf);
}, /expected length >= 32/i, 'digestInto throws RangeError on insufficient buffer length');
console.log('All @noble/hashes.hmac contract assertions passed.');
Исходный сидер
аноним