fractal-pqc 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/cli.mjs CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fractal-pqc",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Runnable reference for quantum-safe migration of a Bitcoin-style key: bind secp256k1/Taproot to ML-DSA-65 (FIPS-204), derive P2TR addresses, build+sign BIP-341 key-path spends (official-vector-verified), and broadcast on testnet. Real primitives, honest scope.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/mutations.mjs CHANGED
@@ -47,7 +47,7 @@
47
47
  * is load-bearing, never that no sentence is missing.
48
48
  */
49
49
 
50
- import { mkdtempSync, cpSync, writeFileSync, readFileSync, rmSync } from "node:fs";
50
+ import { mkdtempSync, cpSync, writeFileSync, readFileSync, rmSync, existsSync, symlinkSync } from "node:fs";
51
51
  import { tmpdir } from "node:os";
52
52
  import { join, dirname } from "node:path";
53
53
  import { fileURLToPath } from "node:url";
@@ -267,6 +267,36 @@ export const MUTATIONS = [
267
267
  },
268
268
  ];
269
269
 
270
+ /**
271
+ * Make the dependencies reachable from the throwaway copy.
272
+ *
273
+ * This used to be `cpSync(join(PKG, "node_modules"), …)`, which worked in a development
274
+ * checkout and threw ENOENT for EVERY user who installed from npm — because npm HOISTS
275
+ * dependencies to the top-level `node_modules`, so the package directory has none of its
276
+ * own. `claims --mutate` is one of the three commands we ask auditors to run, and it had
277
+ * never once worked outside this repository. It was caught by installing the published
278
+ * tarball into an empty directory and running it, which is the only test that would have.
279
+ *
280
+ * We now walk up from the package looking for the `node_modules` that actually holds our
281
+ * dependencies, and link it. Linking rather than copying is also the honest choice: the
282
+ * mutation runs against the SAME dependency bytes the caller has installed, not a copy we
283
+ * made.
284
+ */
285
+ function linkDependencies(work) {
286
+ let dir = PKG;
287
+ for (let i = 0; i < 8; i++) {
288
+ const candidate = join(dir, "node_modules");
289
+ if (existsSync(join(candidate, "@noble", "hashes"))) {
290
+ try { symlinkSync(candidate, join(work, "node_modules"), "dir"); return true; }
291
+ catch { try { cpSync(candidate, join(work, "node_modules"), { recursive: true, dereference: false }); return true; } catch { return false; } }
292
+ }
293
+ const up = dirname(dir);
294
+ if (up === dir) break;
295
+ dir = up;
296
+ }
297
+ return false;
298
+ }
299
+
270
300
  /**
271
301
  * Apply every mutation to a throwaway copy and check the named claims die.
272
302
  * Returns a matrix an auditor can read without trusting us.
@@ -279,7 +309,9 @@ export function runMutations({ claimIds } = {}) {
279
309
  cpSync(join(PKG, dir), join(work, dir), { recursive: true });
280
310
  }
281
311
  cpSync(join(PKG, "package.json"), join(work, "package.json"));
282
- cpSync(join(PKG, "node_modules"), join(work, "node_modules"), { recursive: true, dereference: false });
312
+ if (!linkDependencies(work)) {
313
+ throw new Error("could not locate the installed dependencies (@noble/*) to run mutations against");
314
+ }
283
315
 
284
316
  const ledger = () => {
285
317
  try {
@@ -368,7 +400,9 @@ export function runAttackAttribution() {
368
400
  try {
369
401
  for (const dir of ["src", "bin", "vectors"]) cpSync(join(PKG, dir), join(work, dir), { recursive: true });
370
402
  cpSync(join(PKG, "package.json"), join(work, "package.json"));
371
- cpSync(join(PKG, "node_modules"), join(work, "node_modules"), { recursive: true, dereference: false });
403
+ if (!linkDependencies(work)) {
404
+ throw new Error("could not locate the installed dependencies (@noble/*) to run mutations against");
405
+ }
372
406
 
373
407
  const reg = join(work, "src", "claims-registry.mjs");
374
408
  const regSrc = readFileSync(reg, "utf8");