@mindpeeker/negentropy 0.1.0

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.
Files changed (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +160 -0
  3. package/dist/errors.d.ts +12 -0
  4. package/dist/errors.d.ts.map +1 -0
  5. package/dist/errors.js +11 -0
  6. package/dist/errors.js.map +1 -0
  7. package/dist/estimators/entropy.d.ts +22 -0
  8. package/dist/estimators/entropy.d.ts.map +1 -0
  9. package/dist/estimators/entropy.js +78 -0
  10. package/dist/estimators/entropy.js.map +1 -0
  11. package/dist/estimators/frequency.d.ts +18 -0
  12. package/dist/estimators/frequency.d.ts.map +1 -0
  13. package/dist/estimators/frequency.js +57 -0
  14. package/dist/estimators/frequency.js.map +1 -0
  15. package/dist/estimators/negentropy.d.ts +62 -0
  16. package/dist/estimators/negentropy.d.ts.map +1 -0
  17. package/dist/estimators/negentropy.js +104 -0
  18. package/dist/estimators/negentropy.js.map +1 -0
  19. package/dist/estimators/pipeline.d.ts +25 -0
  20. package/dist/estimators/pipeline.d.ts.map +1 -0
  21. package/dist/estimators/pipeline.js +30 -0
  22. package/dist/estimators/pipeline.js.map +1 -0
  23. package/dist/estimators/vasicek.d.ts +18 -0
  24. package/dist/estimators/vasicek.d.ts.map +1 -0
  25. package/dist/estimators/vasicek.js +57 -0
  26. package/dist/estimators/vasicek.js.map +1 -0
  27. package/dist/estimators/windowed.d.ts +27 -0
  28. package/dist/estimators/windowed.d.ts.map +1 -0
  29. package/dist/estimators/windowed.js +66 -0
  30. package/dist/estimators/windowed.js.map +1 -0
  31. package/dist/experiment/batch.d.ts +15 -0
  32. package/dist/experiment/batch.d.ts.map +1 -0
  33. package/dist/experiment/batch.js +179 -0
  34. package/dist/experiment/batch.js.map +1 -0
  35. package/dist/experiment/composite.d.ts +12 -0
  36. package/dist/experiment/composite.d.ts.map +1 -0
  37. package/dist/experiment/composite.js +26 -0
  38. package/dist/experiment/composite.js.map +1 -0
  39. package/dist/experiment/registration.d.ts +20 -0
  40. package/dist/experiment/registration.d.ts.map +1 -0
  41. package/dist/experiment/registration.js +54 -0
  42. package/dist/experiment/registration.js.map +1 -0
  43. package/dist/experiment/session.d.ts +47 -0
  44. package/dist/experiment/session.d.ts.map +1 -0
  45. package/dist/experiment/session.js +245 -0
  46. package/dist/experiment/session.js.map +1 -0
  47. package/dist/experiment/types.d.ts +68 -0
  48. package/dist/experiment/types.d.ts.map +1 -0
  49. package/dist/experiment/types.js +2 -0
  50. package/dist/experiment/types.js.map +1 -0
  51. package/dist/extract/accounting.d.ts +52 -0
  52. package/dist/extract/accounting.d.ts.map +1 -0
  53. package/dist/extract/accounting.js +130 -0
  54. package/dist/extract/accounting.js.map +1 -0
  55. package/dist/extract/condition.d.ts +23 -0
  56. package/dist/extract/condition.d.ts.map +1 -0
  57. package/dist/extract/condition.js +50 -0
  58. package/dist/extract/condition.js.map +1 -0
  59. package/dist/extract/debias.d.ts +25 -0
  60. package/dist/extract/debias.d.ts.map +1 -0
  61. package/dist/extract/debias.js +80 -0
  62. package/dist/extract/debias.js.map +1 -0
  63. package/dist/extract/health.d.ts +44 -0
  64. package/dist/extract/health.d.ts.map +1 -0
  65. package/dist/extract/health.js +115 -0
  66. package/dist/extract/health.js.map +1 -0
  67. package/dist/extract/toeplitz.d.ts +19 -0
  68. package/dist/extract/toeplitz.d.ts.map +1 -0
  69. package/dist/extract/toeplitz.js +83 -0
  70. package/dist/extract/toeplitz.js.map +1 -0
  71. package/dist/index.d.ts +39 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +23 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/internal/bytes.d.ts +6 -0
  76. package/dist/internal/bytes.d.ts.map +1 -0
  77. package/dist/internal/bytes.js +36 -0
  78. package/dist/internal/bytes.js.map +1 -0
  79. package/dist/internal/kahan.d.ts +7 -0
  80. package/dist/internal/kahan.d.ts.map +1 -0
  81. package/dist/internal/kahan.js +15 -0
  82. package/dist/internal/kahan.js.map +1 -0
  83. package/dist/internal/prng.d.ts +7 -0
  84. package/dist/internal/prng.d.ts.map +1 -0
  85. package/dist/internal/prng.js +16 -0
  86. package/dist/internal/prng.js.map +1 -0
  87. package/dist/internal/special.d.ts +36 -0
  88. package/dist/internal/special.d.ts.map +1 -0
  89. package/dist/internal/special.js +258 -0
  90. package/dist/internal/special.js.map +1 -0
  91. package/dist/internal/welford.d.ts +13 -0
  92. package/dist/internal/welford.d.ts.map +1 -0
  93. package/dist/internal/welford.js +30 -0
  94. package/dist/internal/welford.js.map +1 -0
  95. package/dist/numerics.d.ts +32 -0
  96. package/dist/numerics.d.ts.map +1 -0
  97. package/dist/numerics.js +32 -0
  98. package/dist/numerics.js.map +1 -0
  99. package/dist/stats/calibration.d.ts +14 -0
  100. package/dist/stats/calibration.d.ts.map +1 -0
  101. package/dist/stats/calibration.js +41 -0
  102. package/dist/stats/calibration.js.map +1 -0
  103. package/dist/stats/cumdev.d.ts +15 -0
  104. package/dist/stats/cumdev.d.ts.map +1 -0
  105. package/dist/stats/cumdev.js +38 -0
  106. package/dist/stats/cumdev.js.map +1 -0
  107. package/dist/stats/network.d.ts +29 -0
  108. package/dist/stats/network.d.ts.map +1 -0
  109. package/dist/stats/network.js +119 -0
  110. package/dist/stats/network.js.map +1 -0
  111. package/dist/stats/pvalues.d.ts +11 -0
  112. package/dist/stats/pvalues.d.ts.map +1 -0
  113. package/dist/stats/pvalues.js +18 -0
  114. package/dist/stats/pvalues.js.map +1 -0
  115. package/dist/stats/trials.d.ts +34 -0
  116. package/dist/stats/trials.d.ts.map +1 -0
  117. package/dist/stats/trials.js +149 -0
  118. package/dist/stats/trials.js.map +1 -0
  119. package/dist/stats/zscores.d.ts +10 -0
  120. package/dist/stats/zscores.d.ts.map +1 -0
  121. package/dist/stats/zscores.js +26 -0
  122. package/dist/stats/zscores.js.map +1 -0
  123. package/dist/types.d.ts +61 -0
  124. package/dist/types.d.ts.map +1 -0
  125. package/dist/types.js +2 -0
  126. package/dist/types.js.map +1 -0
  127. package/package.json +46 -0
@@ -0,0 +1,245 @@
1
+ import { NegentropyError } from '../errors.js';
2
+ import { calibrate, theoreticalCalibration } from '../stats/calibration.js';
3
+ import { DEFAULT_BITS_PER_TRIAL, trialStream } from '../stats/trials.js';
4
+ import { stoufferZ } from '../stats/zscores.js';
5
+ import { analyzeTrials } from './batch.js';
6
+ const STEP_TIMEOUT = Symbol('step-timeout');
7
+ function stepDeadline(ms) {
8
+ let id;
9
+ const promise = new Promise((resolve) => {
10
+ id = setTimeout(() => resolve(STEP_TIMEOUT), ms);
11
+ });
12
+ return { promise, cancel: () => clearTimeout(id) };
13
+ }
14
+ /**
15
+ * Live experiment over N sources in lock-step rounds: each tick awaits one
16
+ * trial from every (still-active) source, so z vectors are step-aligned with
17
+ * bounded memory — one trial per source in flight. Lazy: no source I/O until
18
+ * the first tick is pulled. A stalled source stalls the round (that is the
19
+ * honest behavior for netvar, which needs simultaneity); under
20
+ * missing:'skip' the round proceeds with whoever answered and a source that
21
+ * ends is dropped from the roster.
22
+ */
23
+ export function session(opts) {
24
+ const { sources } = opts;
25
+ if (sources.length === 0) {
26
+ throw new NegentropyError('invalid_config', 'session needs at least one source');
27
+ }
28
+ const names = new Set(sources.map((s) => s.name));
29
+ if (names.size !== sources.length) {
30
+ throw new NegentropyError('invalid_config', 'source names must be unique');
31
+ }
32
+ const config = opts.registration ? opts.registration.config : opts;
33
+ const bitsPerTrial = config.trial?.bitsPerTrial ?? DEFAULT_BITS_PER_TRIAL;
34
+ const missing = config.missing ?? 'error';
35
+ const stepTimeoutMs = opts.stepTimeoutMs ?? 30_000;
36
+ const now = opts.now ?? (() => Date.now());
37
+ const events = config.events ?? [];
38
+ // recorded per-source trial data (post-calibration) + the tick timeline
39
+ const sums = sources.map(() => []);
40
+ const trialTimes = sources.map(() => []);
41
+ let calibrations = Array.isArray(config.calibration)
42
+ ? null // resolved in start() with validation
43
+ : config.calibration && typeof config.calibration === 'object'
44
+ ? null // burn-in — resolved live
45
+ : sources.map((s) => theoreticalCalibration(s.name, bitsPerTrial));
46
+ let stopped = false;
47
+ let generator = null;
48
+ const iterators = [];
49
+ const registrationHash = opts.registration?.hash;
50
+ let abortPromise = null;
51
+ if (opts.signal) {
52
+ const signal = opts.signal;
53
+ abortPromise = new Promise((_, reject) => {
54
+ signal.addEventListener('abort', () => reject(new NegentropyError('aborted', 'session aborted')), { once: true });
55
+ });
56
+ abortPromise.catch(() => { }); // guard: session may end before anyone awaits it
57
+ }
58
+ function resolveProvidedCalibrations() {
59
+ const provided = config.calibration;
60
+ return sources.map((s) => {
61
+ const cal = provided.find((c) => c.source === s.name && c.bitsPerTrial === bitsPerTrial);
62
+ if (!cal) {
63
+ throw new NegentropyError('calibration_required', `no calibration provided for ${s.name}@${bitsPerTrial} bits`, { source: s.name });
64
+ }
65
+ return cal;
66
+ });
67
+ }
68
+ async function pullOne(index) {
69
+ const deadline = stepDeadline(stepTimeoutMs);
70
+ try {
71
+ const raced = await Promise.race([
72
+ iterators[index].next(),
73
+ deadline.promise,
74
+ ...(abortPromise ? [abortPromise] : []),
75
+ ]);
76
+ if (raced === STEP_TIMEOUT) {
77
+ throw new NegentropyError('timeout', `no trial from ${sources[index]?.name} within ${stepTimeoutMs}ms`, {
78
+ source: sources[index]?.name,
79
+ });
80
+ }
81
+ if (raced.done) {
82
+ throw new NegentropyError('source_ended', `${sources[index]?.name} ended during calibration`, {
83
+ source: sources[index]?.name,
84
+ });
85
+ }
86
+ return raced.value;
87
+ }
88
+ finally {
89
+ deadline.cancel();
90
+ }
91
+ }
92
+ async function burnInCalibration(burn) {
93
+ if (!Number.isInteger(burn) || burn < 2) {
94
+ throw new NegentropyError('invalid_config', `calibration.trials must be an integer ≥ 2, got ${burn}`);
95
+ }
96
+ return Promise.all(sources.map(async (source, i) => {
97
+ const collected = new Float64Array(burn);
98
+ for (let t = 0; t < burn; t++)
99
+ collected[t] = (await pullOne(i)).sum;
100
+ return calibrate({ source: source.name, bitsPerTrial, sums: collected }, { minTrials: burn });
101
+ }));
102
+ }
103
+ async function* run() {
104
+ if (opts.signal?.aborted)
105
+ throw new NegentropyError('aborted', 'session aborted before start');
106
+ for (const source of sources) {
107
+ iterators.push(trialStream(source, {
108
+ ...config.trial,
109
+ signal: opts.signal,
110
+ ...(opts.now && { now: opts.now }),
111
+ }));
112
+ }
113
+ if (!calibrations) {
114
+ calibrations = Array.isArray(config.calibration)
115
+ ? resolveProvidedCalibrations()
116
+ : await burnInCalibration(config.calibration.trials);
117
+ }
118
+ const active = sources.map(() => true);
119
+ const pending = sources.map(() => null);
120
+ let step = 0;
121
+ let runningNetvar = 0;
122
+ let runningCumdev = 0;
123
+ try {
124
+ while (!stopped && active.some(Boolean)) {
125
+ for (let i = 0; i < sources.length; i++) {
126
+ if (active[i] && pending[i] === null) {
127
+ pending[i] = iterators[i].next();
128
+ }
129
+ }
130
+ const deadline = stepDeadline(stepTimeoutMs);
131
+ let outcomes;
132
+ try {
133
+ outcomes = await Promise.all(sources.map((_, i) => active[i] && pending[i]
134
+ ? Promise.race([
135
+ pending[i],
136
+ deadline.promise,
137
+ ...(abortPromise ? [abortPromise] : []),
138
+ ])
139
+ : Promise.resolve(null)));
140
+ }
141
+ finally {
142
+ deadline.cancel();
143
+ }
144
+ if (stopped)
145
+ break;
146
+ const zBySource = new Float64Array(sources.length).fill(Number.NaN);
147
+ const present = [];
148
+ const presentZ = [];
149
+ for (let i = 0; i < sources.length; i++) {
150
+ const outcome = outcomes[i];
151
+ if (outcome === null || outcome === undefined)
152
+ continue;
153
+ if (outcome === STEP_TIMEOUT) {
154
+ if (missing === 'error') {
155
+ throw new NegentropyError('timeout', `no trial from ${sources[i]?.name} within ${stepTimeoutMs}ms`, { source: sources[i]?.name });
156
+ }
157
+ continue; // pending promise carries into the next round
158
+ }
159
+ pending[i] = null;
160
+ if (outcome.done) {
161
+ if (missing === 'error') {
162
+ throw new NegentropyError('source_ended', `${sources[i]?.name} ended mid-session`, {
163
+ source: sources[i]?.name,
164
+ });
165
+ }
166
+ active[i] = false;
167
+ continue;
168
+ }
169
+ const trial = outcome.value;
170
+ const cal = calibrations[i];
171
+ const z = (trial.sum - cal.mean) / cal.sd;
172
+ zBySource[i] = z;
173
+ present.push(sources[i]?.name);
174
+ presentZ.push(z);
175
+ sums[i].push(trial.sum);
176
+ trialTimes[i].push(trial.at ?? now());
177
+ }
178
+ if (present.length === 0) {
179
+ if (!active.some(Boolean))
180
+ break;
181
+ continue; // everyone slow this round — keep waiting
182
+ }
183
+ const at = now();
184
+ const stouffer = stoufferZ(presentZ);
185
+ runningNetvar += stouffer * stouffer;
186
+ runningCumdev += stouffer * stouffer - 1;
187
+ const activeEvents = events
188
+ .filter((event) => windowContains(event, step, at))
189
+ .map((event) => event.id);
190
+ yield {
191
+ step,
192
+ at,
193
+ zBySource,
194
+ present,
195
+ stouffer,
196
+ netvar: runningNetvar,
197
+ cumdev: runningCumdev,
198
+ activeEvents,
199
+ };
200
+ step++;
201
+ }
202
+ }
203
+ finally {
204
+ for (const iterator of iterators)
205
+ void iterator.return(undefined).catch(() => { });
206
+ }
207
+ }
208
+ function windowContains(event, step, at) {
209
+ if (event.start instanceof Date && event.end instanceof Date) {
210
+ return at >= event.start.getTime() && at < event.end.getTime();
211
+ }
212
+ return (typeof event.start === 'number' &&
213
+ typeof event.end === 'number' &&
214
+ step >= event.start &&
215
+ step < event.end);
216
+ }
217
+ return {
218
+ [Symbol.asyncIterator]() {
219
+ generator ??= run();
220
+ return generator;
221
+ },
222
+ stop() {
223
+ stopped = true;
224
+ for (const iterator of iterators)
225
+ void iterator.return(undefined).catch(() => { });
226
+ if (!calibrations) {
227
+ throw new NegentropyError('insufficient_data', 'session stopped before live calibration completed');
228
+ }
229
+ const series = sources.map((source, i) => ({
230
+ source: source.name,
231
+ bitsPerTrial,
232
+ sums: Float64Array.from(sums[i]),
233
+ timestamps: Float64Array.from(trialTimes[i]),
234
+ }));
235
+ const result = analyzeTrials(series, {
236
+ trial: config.trial,
237
+ calibration: calibrations,
238
+ events,
239
+ missing: 'skip', // roster changes/misses make exact alignment impossible live
240
+ });
241
+ return registrationHash !== undefined ? { ...result, registration: registrationHash } : result;
242
+ },
243
+ };
244
+ }
245
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/experiment/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import type { Calibration, TrialConfig, TrialSeries } from '../types.js';
2
+ export type EventStatistic = 'netvar' | 'devvar' | 'correlation';
3
+ /**
4
+ * A pre-registered event window. Registering the statistic and window BEFORE
5
+ * looking at the data is what gives the resulting p-value its stated meaning
6
+ * — see `registerExperiment` and the pointwise-envelope caveat in cumdev.
7
+ */
8
+ export interface EventSpec {
9
+ id: string;
10
+ /** Hypothesis label, recorded verbatim in the result. */
11
+ label?: string;
12
+ statistic: EventStatistic;
13
+ /** Step index (number) or wall-clock Date (needs trial timestamps). Inclusive. */
14
+ start: number | Date;
15
+ /** Step index or Date. Exclusive. */
16
+ end: number | Date;
17
+ }
18
+ export interface ExperimentConfig {
19
+ trial?: TrialConfig;
20
+ /**
21
+ * 'theoretical' (default): Binomial(k, ½) normalization.
22
+ * Calibration[]: pre-fit calibrations, one per source.
23
+ * { trials: n }: burn the first n trials per source as a calibration
24
+ * window, disjoint from analysis by construction (recommend n ≥ 500).
25
+ * Event windows then index the post-calibration remainder.
26
+ */
27
+ calibration?: 'theoretical' | readonly Calibration[] | {
28
+ trials: number;
29
+ };
30
+ /** May be empty for pure live monitoring — the composite is then NaN. */
31
+ events?: readonly EventSpec[];
32
+ /**
33
+ * A source with no trial for a step: 'error' (default, fail-closed) or
34
+ * 'skip' — batch truncates to the shortest series; live combines over the
35
+ * sources that answered each round.
36
+ */
37
+ missing?: 'error' | 'skip';
38
+ }
39
+ export interface EventResult {
40
+ id: string;
41
+ label?: string;
42
+ statistic: EventStatistic;
43
+ value: number;
44
+ df: number;
45
+ pValue: number;
46
+ /** Normal-equivalent z of the one-sided pValue — the composite input. */
47
+ z: number;
48
+ steps: number;
49
+ /** cumsum(Z_s² − 1) inside the window — plot alongside significanceEnvelope(steps). */
50
+ cumulative: Float64Array;
51
+ sources: readonly string[];
52
+ }
53
+ export interface ExperimentComposite {
54
+ /** Stouffer across event z's. NaN when there were no events. */
55
+ z: number;
56
+ pValue: number;
57
+ events: number;
58
+ }
59
+ export interface ExperimentResult {
60
+ events: readonly EventResult[];
61
+ composite: ExperimentComposite;
62
+ calibration: readonly Calibration[];
63
+ /** Full archival trial data (post-calibration split) — reanalysis without re-running. */
64
+ series: readonly TrialSeries[];
65
+ /** SHA-256 hash of the pre-registered config, when one was used. */
66
+ registration?: string;
67
+ }
68
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/experiment/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAExE,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,GAAG,aAAa,CAAA;AAEhE;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,cAAc,CAAA;IACzB,kFAAkF;IAClF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,qCAAqC;IACrC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,aAAa,GAAG,SAAS,WAAW,EAAE,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACzE,yEAAyE;IACzE,MAAM,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;IAC7B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,cAAc,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,yEAAyE;IACzE,CAAC,EAAE,MAAM,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;IACb,uFAAuF;IACvF,UAAU,EAAE,YAAY,CAAA;IACxB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,CAAC,EAAE,MAAM,CAAA;IACT,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,SAAS,WAAW,EAAE,CAAA;IAC9B,SAAS,EAAE,mBAAmB,CAAA;IAC9B,WAAW,EAAE,SAAS,WAAW,EAAE,CAAA;IACnC,yFAAyF;IACzF,MAAM,EAAE,SAAS,WAAW,EAAE,CAAA;IAC9B,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/experiment/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ import type { ToeplitzExtractor } from './toeplitz.js';
2
+ /**
3
+ * Honest min-entropy bookkeeping through an extraction pipeline. Claims are
4
+ * conservative and only ever shrink relative to what the bytes could hold;
5
+ * every step records itself in the trace (mirroring EntropyResult.sources).
6
+ */
7
+ export interface EntropyClaim {
8
+ /** Total claimed min-entropy in bits. Invariant: 0 ≤ minEntropy ≤ 8·bytes. */
9
+ minEntropy: number;
10
+ /** Statistical distance from uniform accumulated by extraction steps (union bound). */
11
+ epsilon: number;
12
+ basis: 'declared' | 'measured' | 'derived';
13
+ /** Conditions the claim rests on (e.g. iid input bits, seed independence). */
14
+ assumptions: readonly string[];
15
+ }
16
+ export type PipelineOp = 'debias:von-neumann' | 'debias:peres' | 'condition:sha256' | 'condition:hmac' | 'extract:toeplitz';
17
+ export interface PipelineStep {
18
+ op: PipelineOp;
19
+ inBytes: number;
20
+ outBytes: number;
21
+ inMinEntropy: number;
22
+ outMinEntropy: number;
23
+ }
24
+ export interface AccountedBytes {
25
+ bytes: Uint8Array;
26
+ claim: EntropyClaim;
27
+ trace: readonly PipelineStep[];
28
+ }
29
+ /** SP 800-90B §3.1.5.1.2 vetted-conditioning output credit: min(h_in, 0.999·n_out). */
30
+ export declare function vettedOutputEntropy(inputMinEntropy: number, outputBits: number): number;
31
+ /** Start a pipeline: wrap raw bytes with a declared or measured per-byte claim. */
32
+ export declare function claimBytes(bytes: Uint8Array, minEntropyPerByte: number, basis?: 'declared' | 'measured'): AccountedBytes;
33
+ /**
34
+ * Debias the input's BITS (von Neumann or Peres). Output bits are exactly
35
+ * uniform under the iid-bits assumption, so the packed output gets full
36
+ * credit — there is no distributional slack parameter, hence the assumption
37
+ * tag rather than an epsilon. Trailing bits that don't fill a byte are
38
+ * dropped (and not credited).
39
+ */
40
+ export declare function debiasAccounted(input: AccountedBytes, method?: 'von-neumann' | 'peres'): AccountedBytes;
41
+ /** SP 800-90B vetted conditioning of the whole input into one 32-byte block. */
42
+ export declare function conditionAccounted(input: AccountedBytes, opts?: {
43
+ mode?: 'sha256' | 'hmac';
44
+ key?: Uint8Array;
45
+ }): Promise<AccountedBytes>;
46
+ /**
47
+ * Toeplitz extraction with leftover-hash-lemma enforcement: requires
48
+ * claim.minEntropy ≥ outputBits + 2·log₂(1/ε). Statistical distances add
49
+ * across composed extractions (union bound).
50
+ */
51
+ export declare function extractAccounted(input: AccountedBytes, extractor: ToeplitzExtractor, epsilon?: number): AccountedBytes;
52
+ //# sourceMappingURL=accounting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounting.d.ts","sourceRoot":"","sources":["../../src/extract/accounting.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEtD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAA;IAClB,uFAAuF;IACvF,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAA;IAC1C,8EAA8E;IAC9E,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CAC/B;AAED,MAAM,MAAM,UAAU,GAClB,oBAAoB,GACpB,cAAc,GACd,kBAAkB,GAClB,gBAAgB,GAChB,kBAAkB,CAAA;AAEtB,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,UAAU,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,UAAU,CAAA;IACjB,KAAK,EAAE,YAAY,CAAA;IACnB,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;CAC/B;AAED,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvF;AAED,mFAAmF;AACnF,wBAAgB,UAAU,CACxB,KAAK,EAAE,UAAU,EACjB,iBAAiB,EAAE,MAAM,EACzB,KAAK,GAAE,UAAU,GAAG,UAAuB,GAC1C,cAAc,CAiBhB;AAcD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,cAAc,EACrB,MAAM,GAAE,aAAa,GAAG,OAAiB,GACxC,cAAc,CAsBhB;AAED,gFAAgF;AAChF,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,cAAc,EACrB,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,UAAU,CAAA;CAAO,GACxD,OAAO,CAAC,cAAc,CAAC,CA2BzB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,SAAW,GACjB,cAAc,CAmChB"}
@@ -0,0 +1,130 @@
1
+ import { NegentropyError } from '../errors.js';
2
+ import { toBits } from '../internal/bytes.js';
3
+ import { hmacCondition, sha256Condition } from './condition.js';
4
+ import { peres, vonNeumann } from './debias.js';
5
+ /** SP 800-90B §3.1.5.1.2 vetted-conditioning output credit: min(h_in, 0.999·n_out). */
6
+ export function vettedOutputEntropy(inputMinEntropy, outputBits) {
7
+ return Math.min(inputMinEntropy, 0.999 * outputBits);
8
+ }
9
+ /** Start a pipeline: wrap raw bytes with a declared or measured per-byte claim. */
10
+ export function claimBytes(bytes, minEntropyPerByte, basis = 'declared') {
11
+ if (!(minEntropyPerByte > 0 && minEntropyPerByte <= 8)) {
12
+ throw new NegentropyError('invalid_config', `minEntropyPerByte must be in (0, 8], got ${minEntropyPerByte}`);
13
+ }
14
+ return {
15
+ bytes,
16
+ claim: {
17
+ minEntropy: bytes.length * minEntropyPerByte,
18
+ epsilon: 0,
19
+ basis,
20
+ assumptions: [`${basis} h_in = ${minEntropyPerByte} bits/byte`],
21
+ },
22
+ trace: [],
23
+ };
24
+ }
25
+ /** Pack 0/1 bits MSB-first into bytes; trailing bits (<8) are dropped. */
26
+ function packBits(bits) {
27
+ const byteCount = Math.floor(bits.length / 8);
28
+ const out = new Uint8Array(byteCount);
29
+ for (let i = 0; i < byteCount; i++) {
30
+ let value = 0;
31
+ for (let j = 0; j < 8; j++)
32
+ value = (value << 1) | (bits[i * 8 + j] & 1);
33
+ out[i] = value;
34
+ }
35
+ return out;
36
+ }
37
+ /**
38
+ * Debias the input's BITS (von Neumann or Peres). Output bits are exactly
39
+ * uniform under the iid-bits assumption, so the packed output gets full
40
+ * credit — there is no distributional slack parameter, hence the assumption
41
+ * tag rather than an epsilon. Trailing bits that don't fill a byte are
42
+ * dropped (and not credited).
43
+ */
44
+ export function debiasAccounted(input, method = 'peres') {
45
+ const bits = toBits(input.bytes);
46
+ const debiased = method === 'peres' ? peres(bits) : vonNeumann(bits);
47
+ const bytes = packBits(debiased);
48
+ const outMinEntropy = bytes.length * 8;
49
+ const step = {
50
+ op: method === 'peres' ? 'debias:peres' : 'debias:von-neumann',
51
+ inBytes: input.bytes.length,
52
+ outBytes: bytes.length,
53
+ inMinEntropy: input.claim.minEntropy,
54
+ outMinEntropy,
55
+ };
56
+ return {
57
+ bytes,
58
+ claim: {
59
+ minEntropy: outMinEntropy,
60
+ epsilon: input.claim.epsilon,
61
+ basis: 'derived',
62
+ assumptions: [...input.claim.assumptions, 'iid input bits (debiaser requirement)'],
63
+ },
64
+ trace: [...input.trace, step],
65
+ };
66
+ }
67
+ /** SP 800-90B vetted conditioning of the whole input into one 32-byte block. */
68
+ export async function conditionAccounted(input, opts = {}) {
69
+ const mode = opts.mode ?? 'sha256';
70
+ if (mode === 'hmac' && !opts.key) {
71
+ throw new NegentropyError('invalid_config', 'hmac conditioning requires a key');
72
+ }
73
+ const bytes = mode === 'hmac'
74
+ ? await hmacCondition(opts.key, input.bytes)
75
+ : await sha256Condition(input.bytes);
76
+ const outMinEntropy = vettedOutputEntropy(input.claim.minEntropy, bytes.length * 8);
77
+ const step = {
78
+ op: mode === 'hmac' ? 'condition:hmac' : 'condition:sha256',
79
+ inBytes: input.bytes.length,
80
+ outBytes: bytes.length,
81
+ inMinEntropy: input.claim.minEntropy,
82
+ outMinEntropy,
83
+ };
84
+ return {
85
+ bytes,
86
+ claim: {
87
+ minEntropy: outMinEntropy,
88
+ epsilon: input.claim.epsilon,
89
+ basis: 'derived',
90
+ assumptions: [...input.claim.assumptions, 'SP 800-90B vetted conditioning component'],
91
+ },
92
+ trace: [...input.trace, step],
93
+ };
94
+ }
95
+ /**
96
+ * Toeplitz extraction with leftover-hash-lemma enforcement: requires
97
+ * claim.minEntropy ≥ outputBits + 2·log₂(1/ε). Statistical distances add
98
+ * across composed extractions (union bound).
99
+ */
100
+ export function extractAccounted(input, extractor, epsilon = 2 ** -32) {
101
+ if (!(epsilon > 0 && epsilon < 1)) {
102
+ throw new NegentropyError('invalid_config', `epsilon must be in (0, 1), got ${epsilon}`);
103
+ }
104
+ if (extractor.inputBits !== input.bytes.length * 8) {
105
+ throw new NegentropyError('invalid_config', `extractor expects ${extractor.inputBits} input bits, accounted input has ${input.bytes.length * 8}`);
106
+ }
107
+ const required = extractor.outputBits + 2 * Math.log2(1 / epsilon);
108
+ if (input.claim.minEntropy < required) {
109
+ throw new NegentropyError('invalid_config', `leftover hash lemma violated: need ≥ ${required} bits of min-entropy for ${extractor.outputBits} output bits at ε=${epsilon}, have ${input.claim.minEntropy}`);
110
+ }
111
+ const bytes = extractor.extract(input.bytes);
112
+ const step = {
113
+ op: 'extract:toeplitz',
114
+ inBytes: input.bytes.length,
115
+ outBytes: bytes.length,
116
+ inMinEntropy: input.claim.minEntropy,
117
+ outMinEntropy: extractor.outputBits,
118
+ };
119
+ return {
120
+ bytes,
121
+ claim: {
122
+ minEntropy: extractor.outputBits,
123
+ epsilon: input.claim.epsilon + epsilon,
124
+ basis: 'derived',
125
+ assumptions: [...input.claim.assumptions, 'uniform seed independent of the input'],
126
+ },
127
+ trace: [...input.trace, step],
128
+ };
129
+ }
130
+ //# sourceMappingURL=accounting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounting.js","sourceRoot":"","sources":["../../src/extract/accounting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC/D,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAuC/C,uFAAuF;AACvF,MAAM,UAAU,mBAAmB,CAAC,eAAuB,EAAE,UAAkB;IAC7E,OAAO,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,GAAG,UAAU,CAAC,CAAA;AACtD,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,UAAU,CACxB,KAAiB,EACjB,iBAAyB,EACzB,QAAiC,UAAU;IAE3C,IAAI,CAAC,CAAC,iBAAiB,GAAG,CAAC,IAAI,iBAAiB,IAAI,CAAC,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,eAAe,CACvB,gBAAgB,EAChB,4CAA4C,iBAAiB,EAAE,CAChE,CAAA;IACH,CAAC;IACD,OAAO;QACL,KAAK;QACL,KAAK,EAAE;YACL,UAAU,EAAE,KAAK,CAAC,MAAM,GAAG,iBAAiB;YAC5C,OAAO,EAAE,CAAC;YACV,KAAK;YACL,WAAW,EAAE,CAAC,GAAG,KAAK,WAAW,iBAAiB,YAAY,CAAC;SAChE;QACD,KAAK,EAAE,EAAE;KACV,CAAA;AACH,CAAC;AAED,0EAA0E;AAC1E,SAAS,QAAQ,CAAC,IAAuB;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC7C,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAA;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAE,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAY,GAAG,CAAC,CAAC,CAAA;QACpF,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IAChB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAqB,EACrB,SAAkC,OAAO;IAEzC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAChC,MAAM,QAAQ,GAAG,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;IACpE,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAChC,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;IACtC,MAAM,IAAI,GAAiB;QACzB,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,oBAAoB;QAC9D,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;QAC3B,QAAQ,EAAE,KAAK,CAAC,MAAM;QACtB,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU;QACpC,aAAa;KACd,CAAA;IACD,OAAO;QACL,KAAK;QACL,KAAK,EAAE;YACL,UAAU,EAAE,aAAa;YACzB,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO;YAC5B,KAAK,EAAE,SAAS;YAChB,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,uCAAuC,CAAC;SACnF;QACD,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC;KAC9B,CAAA;AACH,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAqB,EACrB,OAAuD,EAAE;IAEzD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAA;IAClC,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACjC,MAAM,IAAI,eAAe,CAAC,gBAAgB,EAAE,kCAAkC,CAAC,CAAA;IACjF,CAAC;IACD,MAAM,KAAK,GACT,IAAI,KAAK,MAAM;QACb,CAAC,CAAC,MAAM,aAAa,CAAC,IAAI,CAAC,GAAiB,EAAE,KAAK,CAAC,KAAK,CAAC;QAC1D,CAAC,CAAC,MAAM,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACxC,MAAM,aAAa,GAAG,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACnF,MAAM,IAAI,GAAiB;QACzB,EAAE,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAAkB;QAC3D,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;QAC3B,QAAQ,EAAE,KAAK,CAAC,MAAM;QACtB,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU;QACpC,aAAa;KACd,CAAA;IACD,OAAO;QACL,KAAK;QACL,KAAK,EAAE;YACL,UAAU,EAAE,aAAa;YACzB,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO;YAC5B,KAAK,EAAE,SAAS;YAChB,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,0CAA0C,CAAC;SACtF;QACD,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC;KAC9B,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAqB,EACrB,SAA4B,EAC5B,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE;IAElB,IAAI,CAAC,CAAC,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,eAAe,CAAC,gBAAgB,EAAE,kCAAkC,OAAO,EAAE,CAAC,CAAA;IAC1F,CAAC;IACD,IAAI,SAAS,CAAC,SAAS,KAAK,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,eAAe,CACvB,gBAAgB,EAChB,qBAAqB,SAAS,CAAC,SAAS,oCAAoC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CACrG,CAAA;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,CAAA;IAClE,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,eAAe,CACvB,gBAAgB,EAChB,wCAAwC,QAAQ,4BAA4B,SAAS,CAAC,UAAU,qBAAqB,OAAO,UAAU,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,CAC/J,CAAA;IACH,CAAC;IACD,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC5C,MAAM,IAAI,GAAiB;QACzB,EAAE,EAAE,kBAAkB;QACtB,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;QAC3B,QAAQ,EAAE,KAAK,CAAC,MAAM;QACtB,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU;QACpC,aAAa,EAAE,SAAS,CAAC,UAAU;KACpC,CAAA;IACD,OAAO;QACL,KAAK;QACL,KAAK,EAAE;YACL,UAAU,EAAE,SAAS,CAAC,UAAU;YAChC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO;YACtC,KAAK,EAAE,SAAS;YAChB,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,uCAAuC,CAAC;SACnF;QACD,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC;KAC9B,CAAA;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ /** SHA-256 conditioning (SP 800-90B vetted component). 32 bytes out. */
2
+ export declare function sha256Condition(input: Uint8Array): Promise<Uint8Array>;
3
+ /** HMAC-SHA-256 conditioning (SP 800-90B vetted component). 32 bytes out. */
4
+ export declare function hmacCondition(key: Uint8Array, input: Uint8Array): Promise<Uint8Array>;
5
+ export interface ConditionStreamOptions {
6
+ /** Assessed min-entropy of the raw input, bits per byte (0 < h ≤ 8). */
7
+ minEntropyPerByte: number;
8
+ /** Pool safetyFactor × 256 credited bits per 32-byte output block. Default 2. */
9
+ safetyFactor?: number;
10
+ mode?: 'sha256' | 'hmac';
11
+ /** Required for 'hmac'. */
12
+ key?: Uint8Array;
13
+ signal?: AbortSignal;
14
+ }
15
+ /**
16
+ * Streaming conditioner: pools raw bytes until the credited min-entropy
17
+ * reaches safetyFactor × 256 bits, then emits one 32-byte conditioned block.
18
+ * Lazy and pull-based. A trailing under-filled pool is dropped, never
19
+ * emitted — no partial-credit output. Health testing is deliberately
20
+ * separate (`ContinuousHealth`) so raw analysis and conditioning compose.
21
+ */
22
+ export declare function conditionStream(raw: AsyncIterable<Uint8Array>, opts: ConditionStreamOptions): AsyncGenerator<Uint8Array>;
23
+ //# sourceMappingURL=condition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"condition.d.ts","sourceRoot":"","sources":["../../src/extract/condition.ts"],"names":[],"mappings":"AAGA,wEAAwE;AACxE,wBAAsB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAE5E;AAED,6EAA6E;AAC7E,wBAAsB,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAS3F;AAED,MAAM,WAAW,sBAAsB;IACrC,wEAAwE;IACxE,iBAAiB,EAAE,MAAM,CAAA;IACzB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;IACxB,2BAA2B;IAC3B,GAAG,CAAC,EAAE,UAAU,CAAA;IAChB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED;;;;;;GAMG;AACH,wBAAuB,eAAe,CACpC,GAAG,EAAE,aAAa,CAAC,UAAU,CAAC,EAC9B,IAAI,EAAE,sBAAsB,GAC3B,cAAc,CAAC,UAAU,CAAC,CAkC5B"}
@@ -0,0 +1,50 @@
1
+ import { NegentropyError } from '../errors.js';
2
+ import { concatBytes } from '../internal/bytes.js';
3
+ /** SHA-256 conditioning (SP 800-90B vetted component). 32 bytes out. */
4
+ export async function sha256Condition(input) {
5
+ return new Uint8Array(await crypto.subtle.digest('SHA-256', input));
6
+ }
7
+ /** HMAC-SHA-256 conditioning (SP 800-90B vetted component). 32 bytes out. */
8
+ export async function hmacCondition(key, input) {
9
+ const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
10
+ return new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, input));
11
+ }
12
+ /**
13
+ * Streaming conditioner: pools raw bytes until the credited min-entropy
14
+ * reaches safetyFactor × 256 bits, then emits one 32-byte conditioned block.
15
+ * Lazy and pull-based. A trailing under-filled pool is dropped, never
16
+ * emitted — no partial-credit output. Health testing is deliberately
17
+ * separate (`ContinuousHealth`) so raw analysis and conditioning compose.
18
+ */
19
+ export async function* conditionStream(raw, opts) {
20
+ const { minEntropyPerByte, mode = 'sha256', key, signal } = opts;
21
+ const safetyFactor = opts.safetyFactor ?? 2;
22
+ if (!(minEntropyPerByte > 0 && minEntropyPerByte <= 8)) {
23
+ throw new NegentropyError('invalid_config', `minEntropyPerByte must be in (0, 8], got ${minEntropyPerByte}`);
24
+ }
25
+ if (!(safetyFactor >= 1)) {
26
+ throw new NegentropyError('invalid_config', `safetyFactor must be ≥ 1, got ${safetyFactor}`);
27
+ }
28
+ if (mode === 'hmac' && !key) {
29
+ throw new NegentropyError('invalid_config', 'hmac conditioning requires a key');
30
+ }
31
+ const bytesPerBlock = Math.ceil((safetyFactor * 256) / minEntropyPerByte);
32
+ const digest = (block) => mode === 'hmac' ? hmacCondition(key, block) : sha256Condition(block);
33
+ let pool = [];
34
+ let pooled = 0;
35
+ for await (const chunk of raw) {
36
+ if (signal?.aborted)
37
+ throw new NegentropyError('aborted', 'condition stream aborted');
38
+ pool.push(chunk);
39
+ pooled += chunk.length;
40
+ while (pooled >= bytesPerBlock) {
41
+ const all = concatBytes(pool);
42
+ const block = all.slice(0, bytesPerBlock);
43
+ const rest = all.slice(bytesPerBlock);
44
+ pool = rest.length > 0 ? [rest] : [];
45
+ pooled = rest.length;
46
+ yield await digest(block);
47
+ }
48
+ }
49
+ }
50
+ //# sourceMappingURL=condition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"condition.js","sourceRoot":"","sources":["../../src/extract/condition.ts"],"names":[],"mappings":"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"}