board / client / test / helpers / det-random.mjs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
 * Deterministic `crypto.getRandomValues` for byte-exact sealing vectors.
 *
 * Sealer's IV epoch and AtRestCipher's per-encryption IV are random by design
 * (PROTOCOL.md §3 — there is no API that accepts a caller-supplied IV, so
 * nonce reuse is structurally impossible). That makes real sealing output
 * unreproducible, which would leave the vectors able to prove only
 * round-tripping.
 *
 * So the harness replaces ONLY `getRandomValues` with a seeded mulberry32
 * stream and leaves `crypto.subtle` untouched and real: every derivation,
 * AES-GCM tag and Ed25519 signature in the vectors is produced by the actual
 * WebCrypto implementation, while the IVs become a known sequence. Both the
 * TypeScript original and the ClojureScript port then emit byte-identical
 * ciphertext for the same input, so the vectors pin the ciphertext itself and
 * not merely "it decrypts".
 *
 * Cross-implementation round trips with REAL randomness are kept as well
 * (TS-sealed fixtures unsealed by the port); this only adds the stronger check.
 */
const real = globalThis.crypto;

let state = 0;

/** mulberry32 — the suite's usual small deterministic PRNG. */
function next() {
  state = (state + 0x6d2b79f5) | 0;
  let t = state;
  t = Math.imul(t ^ (t >>> 15), t | 1);
  t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
  return ((t ^ (t >>> 14)) >>> 0) & 0xff;
}

export function resetRandom(seed = 1) {
  state = seed | 0;
}

/** Install the stub. Idempotent; `crypto.subtle` stays the real one. */
export function installDetRandom() {
  if (globalThis.crypto?.__det) return;
  const stub = {
    __det: true,
    subtle: real.subtle,
    randomUUID: () => real.randomUUID(),
    getRandomValues(buf) {
      const b = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
      for (let i = 0; i < b.length; i++) b[i] = next();
      return buf;
    },
  };
  Object.defineProperty(globalThis, "crypto", { value: stub, configurable: true, writable: true });
}

/** Restore the platform crypto (for the real-randomness round-trip cases). */
export function restoreRandom() {
  Object.defineProperty(globalThis, "crypto", { value: real, configurable: true, writable: true });
}

export const hex = (u8) => [...u8].map((b) => b.toString(16).padStart(2, "0")).join("");

static mirror of HEAD · about · clone: git clone https://git.ardegazu.ro/board.git