import { describe, it, expect } from 'vitest'; import { HASH_KEY, kirchenbauerSeed, isGreenToken, greenUniform, textsealR, keyFromString, ksemstampSeed, } from '../../src/lib/utils/hashing'; describe('kirchenbauerSeed', () => { it('matches the reference formula salt * prev mod 2^64-1', () => { expect(kirchenbauerSeed(1)).toBe(15485863n); expect(kirchenbauerSeed(1000)).toBe(15485863000n); const big = 2n ** 64n - 1n; expect(kirchenbauerSeed(123456)).toBe((HASH_KEY * 123456n) % big); }); }); describe('green partition', () => { it('is deterministic', () => { const seed = kirchenbauerSeed(777); for (let v = 0; v < 50; v++) { expect(isGreenToken(seed, v, 0.25)).toBe(isGreenToken(seed, v, 0.25)); } }); it('has approximately gamma green fraction over the vocab', () => { const seed = kirchenbauerSeed(42); const V = 50000; const gamma = 0.25; let green = 0; for (let v = 0; v < V; v++) if (isGreenToken(seed, v, gamma)) green++; const frac = green / V; // Binomial std ~ sqrt(g(1-g)/V) ~ 0.0019; allow 5 sigma expect(Math.abs(frac - gamma)).toBeLessThan(0.01); }); it('partitions differ across seeds (context-dependence)', () => { const s1 = kirchenbauerSeed(10); const s2 = kirchenbauerSeed(11); let diff = 0; for (let v = 0; v < 2000; v++) { if (isGreenToken(s1, v, 0.25) !== isGreenToken(s2, v, 0.25)) diff++; } expect(diff).toBeGreaterThan(200); }); it('greenUniform in [0,1)', () => { const seed = kirchenbauerSeed(5); for (let v = 0; v < 100; v++) { const u = greenUniform(seed, v); expect(u).toBeGreaterThanOrEqual(0); expect(u).toBeLessThan(1); } }); }); describe('textsealR', () => { const key = keyFromString('secret'); it('is deterministic per (key, context, token)', () => { expect(textsealR(key, [1, 2, 3], 42)).toBe(textsealR(key, [1, 2, 3], 42)); }); it('changes with context', () => { expect(textsealR(key, [1, 2, 3], 42)).not.toBe(textsealR(key, [1, 2, 4], 42)); }); it('changes with key', () => { const key2 = keyFromString('other'); expect(textsealR(key, [1, 2, 3], 42)).not.toBe(textsealR(key2, [1, 2, 3], 42)); }); it('is uniform-ish: mean near 0.5', () => { let sum = 0; const n = 20000; for (let v = 0; v < n; v++) sum += textsealR(key, [9, 8, 7], v); expect(Math.abs(sum / n - 0.5)).toBeLessThan(0.01); }); it('stays strictly inside (0,1)', () => { for (let v = 0; v < 1000; v++) { const r = textsealR(key, [], v); expect(r).toBeGreaterThan(0); expect(r).toBeLessThan(1); } }); }); describe('keyFromString / ksemstampSeed', () => { it('derives stable distinct keys', () => { expect(keyFromString('a')).toBe(keyFromString('a')); expect(keyFromString('a')).not.toBe(keyFromString('b')); }); it('ksemstamp seed differs per cluster and avoids zero for cluster 0', () => { expect(ksemstampSeed(0)).not.toBe(0n); expect(ksemstampSeed(0)).not.toBe(ksemstampSeed(1)); }); });