CodeSampleX

Exemple

@noble/hashes 2.3.0: scryptAsync

Échantillon vérifié pour npm @noble/hashes 2.3.0: scryptAsync. Le contrat s'est exécuté sur node 22 · linux debian/x64 · docker et a réussi.

sha256:6257bf1db885e9114f90bd512063571c82aa2b4bfe59394f6ddd29f27027f5f9

Ce réseau offre une seule chose : un échantillon qui compile. Il l'a exécuté dans un bac à sable et conservé le reçu signé. Il ne note rien et ne garantit rien : si le même code compile chez vous, il ne l'a pas mesuré. Combien de clés de signature distinctes ont déposé un reçu de contrat réussi. Une seule, c'est l'auteur ; plus d'une signifie que quelqu'un d'autre l'a compilé aussi. Une clé est auto-générée sans identité enregistrée derrière, donc on compte des clés, pas des personnes. MIT-0

Preuves d'exécution

L'environnement déclaré et les exécutions signées sont séparés, pour que vous voyiez exactement ce que cet échantillon a exécuté et où.

Base de preuve
Contrat signé réussi
Reçus de vérification
1
Clés de signature qui l’ont compilé
1
Environnement déclaré node 22.23 linux 24 · ubuntu · glibc 2.39 x64 node 22.23 javascript npm 10

Environnements des exécutions de vérification

Environnement Contrat Étapes Exécution
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-07

Cas

HOW
Objectif
verify @noble/hashes.scryptAsync in pkg:npm/%40noble/hashes@2.3.0
Paquets
Symboles
  • @noble/hashes.scryptAsync
Environnement
node 22.23.2
Créé
2026-09-07T03:38:35Z

Contrat

  1. scryptAsync derives a deterministic key from string or byte password and salt matching RFC 7914 test vectors
  2. scryptAsync matches synchronous scrypt output for identical cost parameters and custom dkLen
  3. scryptAsync yields execution and invokes onProgress callback with fractional completion from 0 to 1
  4. scryptAsync respects asyncTick parameter for scheduler yielding without altering the output
  5. scryptAsync rejects when maxmem budget is insufficient for temporary memory allocations
  6. scryptAsync validates work factors and rejects invalid N, r, p, or dkLen parameters

Fichiers

  • PROMPT.md
  • csx.json
  • package-lock.json
  • package.json
  • spec.json
  • src/index.mjs
  • test/contract.mjs

Télécharger l’artefact source (tar.gz)

Code source

PROMPT.md
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.scryptAsync 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.scryptAsync

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.
csx.json
{"case":{"caseId":"case:sha256:5260a137de1c96ba9180e76c1aaf095f0ad305ba5ba7e199001f07aba23a6c2a","contract":["scryptAsync derives a deterministic key from string or byte password and salt matching RFC 7914 test vectors","scryptAsync matches synchronous scrypt output for identical cost parameters and custom dkLen","scryptAsync yields execution and invokes onProgress callback with fractional completion from 0 to 1","scryptAsync respects asyncTick parameter for scheduler yielding without altering the output","scryptAsync rejects when maxmem budget is insufficient for temporary memory allocations","scryptAsync validates work factors and rejects invalid N, r, p, or dkLen parameters"],"goal":"verify @noble/hashes.scryptAsync in pkg:npm/%40noble/hashes@2.3.0","kind":"HOW","packages":["pkg:npm/%40noble/hashes@2.3.0"],"schemaVersion":1,"symbols":["@noble/hashes.scryptAsync"]},"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.scryptAsync"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "sample-noble-hashes-scrypt-async",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "sample-noble-hashes-scrypt-async",
      "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/"
      }
    }
  }
}
package.json
{
  "name": "sample-noble-hashes-scrypt-async",
  "version": "1.0.0",
  "type": "module",
  "description": "verify @noble/hashes.scryptAsync in pkg:npm/%40noble/hashes@2.3.0",
  "scripts": {
    "test": "node test/contract.mjs"
  },
  "dependencies": {
    "@noble/hashes": "2.3.0"
  },
  "license": "MIT-0"
}
spec.json
{
  "schemaVersion": 1,
  "goal": "verify @noble/hashes.scryptAsync in pkg:npm/%40noble/hashes@2.3.0",
  "kind": "HOW",
  "packages": [
    "pkg:npm/%40noble/hashes@2.3.0"
  ],
  "symbols": [
    "@noble/hashes.scryptAsync"
  ]
}
src/index.mjs
import { scrypt, scryptAsync } from '@noble/hashes/scrypt.js';
import { bytesToHex, hexToBytes, utf8ToBytes } from '@noble/hashes/utils.js';

export { scrypt, scryptAsync, bytesToHex, hexToBytes, utf8ToBytes };

/**
 * Derives a key using Scrypt asynchronously.
 * @param {string|Uint8Array} password
 * @param {string|Uint8Array} salt
 * @param {import('@noble/hashes/scrypt.js').ScryptOpts} opts
 * @returns {Promise<Uint8Array>}
 */
export async function deriveScryptAsync(password, salt, opts) {
  return await scryptAsync(password, salt, opts);
}

/**
 * Derives a key with progress tracking using Scrypt asynchronously.
 * @param {string|Uint8Array} password
 * @param {string|Uint8Array} salt
 * @param {import('@noble/hashes/scrypt.js').ScryptOpts} opts
 * @param {(progress: number) => void} onProgress
 * @returns {Promise<Uint8Array>}
 */
export async function deriveScryptWithProgress(password, salt, opts, onProgress) {
  return await scryptAsync(password, salt, { ...opts, onProgress });
}
test/contract.mjs
import assert from 'node:assert';
import {
  scrypt,
  scryptAsync,
  bytesToHex,
  utf8ToBytes,
  deriveScryptAsync,
  deriveScryptWithProgress
} from '../src/index.mjs';

async function testRfcVectorAndInputTypes() {
  // RFC 7914 test vector: password='password', salt='salt', N=1024, r=8, p=1, dkLen=32
  const expectedHex = '16dbc8906763c7f048977a68f9d305f7710e068ca2cd95dab372125bb3f19608';

  const keyFromString = await scryptAsync('password', 'salt', { N: 1024, r: 8, p: 1, dkLen: 32 });
  assert.strictEqual(keyFromString.length, 32);
  assert.strictEqual(bytesToHex(keyFromString), expectedHex);

  const keyFromBytes = await scryptAsync(utf8ToBytes('password'), utf8ToBytes('salt'), {
    N: 1024,
    r: 8,
    p: 1,
    dkLen: 32
  });
  assert.strictEqual(bytesToHex(keyFromBytes), expectedHex);

  const keyFromHelper = await deriveScryptAsync('password', 'salt', {
    N: 1024,
    r: 8,
    p: 1,
    dkLen: 32
  });
  assert.strictEqual(bytesToHex(keyFromHelper), expectedHex);
}

async function testSyncEquivalenceAndDkLen() {
  const opts = { N: 16, r: 8, p: 1, dkLen: 64 };
  const asyncResult = await scryptAsync('passphrase', 'unique-salt', opts);
  const syncResult = scrypt('passphrase', 'unique-salt', opts);

  assert.strictEqual(asyncResult.length, 64);
  assert.strictEqual(syncResult.length, 64);
  assert.strictEqual(bytesToHex(asyncResult), bytesToHex(syncResult));
}

async function testProgressCallback() {
  const progressUpdates = [];
  const onProgress = (p) => {
    progressUpdates.push(p);
  };

  const key = await deriveScryptWithProgress('progress-pass', 'salt', { N: 32, r: 8, p: 1, dkLen: 32 }, onProgress);
  assert.strictEqual(key.length, 32);
  assert.ok(progressUpdates.length > 0, 'onProgress should be called at least once');

  for (let i = 0; i < progressUpdates.length; i++) {
    const val = progressUpdates[i];
    assert.ok(val >= 0 && val <= 1, `progress value ${val} must be within [0, 1]`);
    if (i > 0) {
      assert.ok(val >= progressUpdates[i - 1], 'progress values should be monotonically non-decreasing');
    }
  }
  assert.strictEqual(progressUpdates[progressUpdates.length - 1], 1, 'final progress must be 1');
}

async function testAsyncTickYielding() {
  const keyDefault = await scryptAsync('tick-test', 'salt', { N: 32, r: 8, p: 1, dkLen: 32 });
  const keyCustomTick = await scryptAsync('tick-test', 'salt', { N: 32, r: 8, p: 1, dkLen: 32, asyncTick: 1 });

  assert.strictEqual(bytesToHex(keyDefault), bytesToHex(keyCustomTick));
}

async function testMaxmemConstraint() {
  await assert.rejects(
    async () => {
      await scryptAsync('password', 'salt', { N: 1024, r: 8, p: 1, maxmem: 100 });
    },
    (err) => {
      assert.match(err.message, /"maxmem" limit was hit/);
      return true;
    }
  );
}

async function testInvalidParameters() {
  // N must be a power of 2
  await assert.rejects(
    async () => {
      await scryptAsync('password', 'salt', { N: 3, r: 8, p: 1 });
    },
    (err) => {
      assert.match(err.message, /"N" expected a power of 2/);
      return true;
    }
  );

  // r must be >= 1
  await assert.rejects(
    async () => {
      await scryptAsync('password', 'salt', { N: 16, r: 0, p: 1 });
    },
    (err) => {
      assert.match(err.message, /"r" expected integer >= 1/);
      return true;
    }
  );

  // p must be >= 1
  await assert.rejects(
    async () => {
      await scryptAsync('password', 'salt', { N: 16, r: 8, p: 0 });
    },
    (err) => {
      assert.match(err.message, /"p" expected integer/);
      return true;
    }
  );

  // dkLen must be >= 1
  await assert.rejects(
    async () => {
      await scryptAsync('password', 'salt', { N: 16, r: 8, p: 1, dkLen: 0 });
    },
    (err) => {
      assert.match(err.message, /"dkLen" expected integer/);
      return true;
    }
  );

  // onProgress must be a function if defined
  await assert.rejects(
    async () => {
      await scryptAsync('password', 'salt', { N: 16, r: 8, p: 1, onProgress: 'not-a-function' });
    },
    (err) => {
      assert.match(err.message, /"onProgress" must be a function/);
      return true;
    }
  );
}

async function runAll() {
  await testRfcVectorAndInputTypes();
  await testSyncEquivalenceAndDkLen();
  await testProgressCallback();
  await testAsyncTickYielding();
  await testMaxmemConstraint();
  await testInvalidParameters();

  console.log('Contract tests passed successfully.');
}

await runAll();

Seeder d'origine

anonyme