@mindpeeker/entropy 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.
- package/LICENSE +21 -0
- package/README.md +496 -0
- package/dist/errors.d.ts +14 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +13 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/bits.d.ts +9 -0
- package/dist/internal/bits.d.ts.map +1 -0
- package/dist/internal/bits.js +29 -0
- package/dist/internal/bits.js.map +1 -0
- package/dist/internal/byte-source.d.ts +16 -0
- package/dist/internal/byte-source.d.ts.map +1 -0
- package/dist/internal/byte-source.js +96 -0
- package/dist/internal/byte-source.js.map +1 -0
- package/dist/internal/bytes.d.ts +5 -0
- package/dist/internal/bytes.d.ts.map +1 -0
- package/dist/internal/bytes.js +56 -0
- package/dist/internal/bytes.js.map +1 -0
- package/dist/internal/composite.d.ts +15 -0
- package/dist/internal/composite.d.ts.map +1 -0
- package/dist/internal/composite.js +36 -0
- package/dist/internal/composite.js.map +1 -0
- package/dist/internal/condition.d.ts +38 -0
- package/dist/internal/condition.d.ts.map +1 -0
- package/dist/internal/condition.js +49 -0
- package/dist/internal/condition.js.map +1 -0
- package/dist/internal/encoding.d.ts +14 -0
- package/dist/internal/encoding.d.ts.map +1 -0
- package/dist/internal/encoding.js +91 -0
- package/dist/internal/encoding.js.map +1 -0
- package/dist/internal/health.d.ts +25 -0
- package/dist/internal/health.d.ts.map +1 -0
- package/dist/internal/health.js +84 -0
- package/dist/internal/health.js.map +1 -0
- package/dist/internal/http.d.ts +25 -0
- package/dist/internal/http.d.ts.map +1 -0
- package/dist/internal/http.js +76 -0
- package/dist/internal/http.js.map +1 -0
- package/dist/internal/nist-pulse.d.ts +31 -0
- package/dist/internal/nist-pulse.d.ts.map +1 -0
- package/dist/internal/nist-pulse.js +62 -0
- package/dist/internal/nist-pulse.js.map +1 -0
- package/dist/internal/provider.d.ts +19 -0
- package/dist/internal/provider.d.ts.map +1 -0
- package/dist/internal/provider.js +62 -0
- package/dist/internal/provider.js.map +1 -0
- package/dist/internal/rate-limit.d.ts +15 -0
- package/dist/internal/rate-limit.d.ts.map +1 -0
- package/dist/internal/rate-limit.js +47 -0
- package/dist/internal/rate-limit.js.map +1 -0
- package/dist/internal/sampled.d.ts +25 -0
- package/dist/internal/sampled.d.ts.map +1 -0
- package/dist/internal/sampled.js +49 -0
- package/dist/internal/sampled.js.map +1 -0
- package/dist/internal/stream.d.ts +29 -0
- package/dist/internal/stream.d.ts.map +1 -0
- package/dist/internal/stream.js +78 -0
- package/dist/internal/stream.js.map +1 -0
- package/dist/internal/validate.d.ts +5 -0
- package/dist/internal/validate.d.ts.map +1 -0
- package/dist/internal/validate.js +39 -0
- package/dist/internal/validate.js.map +1 -0
- package/dist/node/ffmpeg-frames.d.ts +27 -0
- package/dist/node/ffmpeg-frames.d.ts.map +1 -0
- package/dist/node/ffmpeg-frames.js +102 -0
- package/dist/node/ffmpeg-frames.js.map +1 -0
- package/dist/node/ffmpeg-samples.d.ts +21 -0
- package/dist/node/ffmpeg-samples.d.ts.map +1 -0
- package/dist/node/ffmpeg-samples.js +81 -0
- package/dist/node/ffmpeg-samples.js.map +1 -0
- package/dist/node/hwrng.d.ts +12 -0
- package/dist/node/hwrng.d.ts.map +1 -0
- package/dist/node/hwrng.js +43 -0
- package/dist/node/hwrng.js.map +1 -0
- package/dist/node/index.d.ts +9 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +7 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/rtl-sdr.d.ts +31 -0
- package/dist/node/rtl-sdr.d.ts.map +1 -0
- package/dist/node/rtl-sdr.js +63 -0
- package/dist/node/rtl-sdr.js.map +1 -0
- package/dist/node/serial-source.d.ts +22 -0
- package/dist/node/serial-source.d.ts.map +1 -0
- package/dist/node/serial-source.js +63 -0
- package/dist/node/serial-source.js.map +1 -0
- package/dist/providers/anu-legacy.d.ts +17 -0
- package/dist/providers/anu-legacy.d.ts.map +1 -0
- package/dist/providers/anu-legacy.js +56 -0
- package/dist/providers/anu-legacy.js.map +1 -0
- package/dist/providers/anu.d.ts +14 -0
- package/dist/providers/anu.d.ts.map +1 -0
- package/dist/providers/anu.js +42 -0
- package/dist/providers/anu.js.map +1 -0
- package/dist/providers/bitcoin.d.ts +14 -0
- package/dist/providers/bitcoin.d.ts.map +1 -0
- package/dist/providers/bitcoin.js +95 -0
- package/dist/providers/bitcoin.js.map +1 -0
- package/dist/providers/camera.d.ts +49 -0
- package/dist/providers/camera.d.ts.map +1 -0
- package/dist/providers/camera.js +123 -0
- package/dist/providers/camera.js.map +1 -0
- package/dist/providers/crypto.d.ts +8 -0
- package/dist/providers/crypto.d.ts.map +1 -0
- package/dist/providers/crypto.js +26 -0
- package/dist/providers/crypto.js.map +1 -0
- package/dist/providers/curby.d.ts +17 -0
- package/dist/providers/curby.d.ts.map +1 -0
- package/dist/providers/curby.js +113 -0
- package/dist/providers/curby.js.map +1 -0
- package/dist/providers/drand.d.ts +19 -0
- package/dist/providers/drand.d.ts.map +1 -0
- package/dist/providers/drand.js +87 -0
- package/dist/providers/drand.js.map +1 -0
- package/dist/providers/flow.d.ts +15 -0
- package/dist/providers/flow.d.ts.map +1 -0
- package/dist/providers/flow.js +82 -0
- package/dist/providers/flow.js.map +1 -0
- package/dist/providers/index.d.ts +56 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +32 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/inmetro.d.ts +17 -0
- package/dist/providers/inmetro.d.ts.map +1 -0
- package/dist/providers/inmetro.js +25 -0
- package/dist/providers/inmetro.js.map +1 -0
- package/dist/providers/jitter.d.ts +33 -0
- package/dist/providers/jitter.d.ts.map +1 -0
- package/dist/providers/jitter.js +81 -0
- package/dist/providers/jitter.js.map +1 -0
- package/dist/providers/lfdr.d.ts +11 -0
- package/dist/providers/lfdr.d.ts.map +1 -0
- package/dist/providers/lfdr.js +34 -0
- package/dist/providers/lfdr.js.map +1 -0
- package/dist/providers/microphone.d.ts +26 -0
- package/dist/providers/microphone.d.ts.map +1 -0
- package/dist/providers/microphone.js +120 -0
- package/dist/providers/microphone.js.map +1 -0
- package/dist/providers/nist-beacon.d.ts +11 -0
- package/dist/providers/nist-beacon.d.ts.map +1 -0
- package/dist/providers/nist-beacon.js +20 -0
- package/dist/providers/nist-beacon.js.map +1 -0
- package/dist/providers/nqsn.d.ts +11 -0
- package/dist/providers/nqsn.d.ts.map +1 -0
- package/dist/providers/nqsn.js +16 -0
- package/dist/providers/nqsn.js.map +1 -0
- package/dist/providers/outshift.d.ts +14 -0
- package/dist/providers/outshift.d.ts.map +1 -0
- package/dist/providers/outshift.js +52 -0
- package/dist/providers/outshift.js.map +1 -0
- package/dist/providers/padova.d.ts +12 -0
- package/dist/providers/padova.d.ts.map +1 -0
- package/dist/providers/padova.js +56 -0
- package/dist/providers/padova.js.map +1 -0
- package/dist/providers/qbck.d.ts +13 -0
- package/dist/providers/qbck.d.ts.map +1 -0
- package/dist/providers/qbck.js +62 -0
- package/dist/providers/qbck.js.map +1 -0
- package/dist/providers/qci.d.ts +14 -0
- package/dist/providers/qci.d.ts.map +1 -0
- package/dist/providers/qci.js +91 -0
- package/dist/providers/qci.js.map +1 -0
- package/dist/providers/qrandom.d.ts +12 -0
- package/dist/providers/qrandom.d.ts.map +1 -0
- package/dist/providers/qrandom.js +39 -0
- package/dist/providers/qrandom.js.map +1 -0
- package/dist/providers/randao.d.ts +14 -0
- package/dist/providers/randao.d.ts.map +1 -0
- package/dist/providers/randao.js +81 -0
- package/dist/providers/randao.js.map +1 -0
- package/dist/providers/random-org.d.ts +13 -0
- package/dist/providers/random-org.d.ts.map +1 -0
- package/dist/providers/random-org.js +89 -0
- package/dist/providers/random-org.js.map +1 -0
- package/dist/providers/sdr.d.ts +21 -0
- package/dist/providers/sdr.d.ts.map +1 -0
- package/dist/providers/sdr.js +63 -0
- package/dist/providers/sdr.js.map +1 -0
- package/dist/providers/sensor.d.ts +24 -0
- package/dist/providers/sensor.d.ts.map +1 -0
- package/dist/providers/sensor.js +119 -0
- package/dist/providers/sensor.js.map +1 -0
- package/dist/providers/serial.d.ts +35 -0
- package/dist/providers/serial.d.ts.map +1 -0
- package/dist/providers/serial.js +78 -0
- package/dist/providers/serial.js.map +1 -0
- package/dist/providers/solana.d.ts +13 -0
- package/dist/providers/solana.d.ts.map +1 -0
- package/dist/providers/solana.js +83 -0
- package/dist/providers/solana.js.map +1 -0
- package/dist/providers/superrand.d.ts +35 -0
- package/dist/providers/superrand.d.ts.map +1 -0
- package/dist/providers/superrand.js +215 -0
- package/dist/providers/superrand.js.map +1 -0
- package/dist/providers/tezos.d.ts +13 -0
- package/dist/providers/tezos.d.ts.map +1 -0
- package/dist/providers/tezos.js +92 -0
- package/dist/providers/tezos.js.map +1 -0
- package/dist/providers/uchile.d.ts +11 -0
- package/dist/providers/uchile.d.ts.map +1 -0
- package/dist/providers/uchile.js +22 -0
- package/dist/providers/uchile.js.map +1 -0
- package/dist/strategies/fallback.d.ts +12 -0
- package/dist/strategies/fallback.d.ts.map +1 -0
- package/dist/strategies/fallback.js +45 -0
- package/dist/strategies/fallback.js.map +1 -0
- package/dist/strategies/race.d.ts +7 -0
- package/dist/strategies/race.d.ts.map +1 -0
- package/dist/strategies/race.js +41 -0
- package/dist/strategies/race.js.map +1 -0
- package/dist/strategies/xor.d.ts +9 -0
- package/dist/strategies/xor.d.ts.map +1 -0
- package/dist/strategies/xor.js +56 -0
- package/dist/strategies/xor.js.map +1 -0
- package/dist/types.d.ts +36 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { EntropyProvider } from '../types.js';
|
|
2
|
+
export interface AnuOptions {
|
|
3
|
+
/** ANU Quantum Numbers API key (AWS Marketplace subscription). */
|
|
4
|
+
apiKey: string;
|
|
5
|
+
fetch?: typeof fetch;
|
|
6
|
+
/** Override for tests or a server-side proxy that hides the key. */
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* ANU Quantum Numbers (quantum-vacuum fluctuations), keyed API.
|
|
11
|
+
* https://quantumnumbers.anu.edu.au — up to 1024 numbers per request.
|
|
12
|
+
*/
|
|
13
|
+
export declare function anu(opts: AnuOptions): EntropyProvider;
|
|
14
|
+
//# sourceMappingURL=anu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anu.d.ts","sourceRoot":"","sources":["../../src/providers/anu.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAMrE,MAAM,WAAW,UAAU;IACzB,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAOD;;;GAGG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,eAAe,CA4BrD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { EntropyError } from '../errors.js';
|
|
2
|
+
import { concatBytes } from '../internal/bytes.js';
|
|
3
|
+
import { fetchJson } from '../internal/http.js';
|
|
4
|
+
import { defineProvider } from '../internal/provider.js';
|
|
5
|
+
import { byteArrayFrom } from '../internal/validate.js';
|
|
6
|
+
const INFO = Object.freeze({ name: 'anu', kind: 'qrng', privacy: 'private' });
|
|
7
|
+
const MAX_PER_REQUEST = 1024;
|
|
8
|
+
const DEFAULT_BASE_URL = 'https://api.quantumnumbers.anu.edu.au';
|
|
9
|
+
/**
|
|
10
|
+
* ANU Quantum Numbers (quantum-vacuum fluctuations), keyed API.
|
|
11
|
+
* https://quantumnumbers.anu.edu.au — up to 1024 numbers per request.
|
|
12
|
+
*/
|
|
13
|
+
export function anu(opts) {
|
|
14
|
+
if (!opts?.apiKey)
|
|
15
|
+
throw new TypeError('anu({ apiKey }) requires a non-empty apiKey');
|
|
16
|
+
const { apiKey, baseUrl = DEFAULT_BASE_URL, fetch: fetchImpl } = opts;
|
|
17
|
+
return defineProvider({
|
|
18
|
+
...INFO,
|
|
19
|
+
async getBytes(length, reqOpts) {
|
|
20
|
+
const chunks = [];
|
|
21
|
+
for (let remaining = length; remaining > 0;) {
|
|
22
|
+
const n = Math.min(MAX_PER_REQUEST, remaining);
|
|
23
|
+
const query = new URLSearchParams({ length: String(n), type: 'uint8' });
|
|
24
|
+
const res = await fetchJson(`${baseUrl}?${query}`, {
|
|
25
|
+
provider: INFO.name,
|
|
26
|
+
headers: { 'x-api-key': apiKey },
|
|
27
|
+
signal: reqOpts?.signal,
|
|
28
|
+
fetchImpl,
|
|
29
|
+
});
|
|
30
|
+
if (res?.success !== true) {
|
|
31
|
+
throw new EntropyError('bad_response', 'ANU QRNG returned an unsuccessful response', {
|
|
32
|
+
provider: INFO.name,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
chunks.push(byteArrayFrom(res.data, n, INFO.name));
|
|
36
|
+
remaining -= n;
|
|
37
|
+
}
|
|
38
|
+
return { bytes: concatBytes(chunks), sources: [INFO] };
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=anu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anu.js","sourceRoot":"","sources":["../../src/providers/anu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAGvD,MAAM,IAAI,GAAsB,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAA;AAChG,MAAM,eAAe,GAAG,IAAI,CAAA;AAC5B,MAAM,gBAAgB,GAAG,uCAAuC,CAAA;AAehE;;;GAGG;AACH,MAAM,UAAU,GAAG,CAAC,IAAgB;IAClC,IAAI,CAAC,IAAI,EAAE,MAAM;QAAE,MAAM,IAAI,SAAS,CAAC,6CAA6C,CAAC,CAAA;IACrF,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,gBAAgB,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAErE,OAAO,cAAc,CAAC;QACpB,GAAG,IAAI;QACP,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO;YAC5B,MAAM,MAAM,GAAiB,EAAE,CAAA;YAC/B,KAAK,IAAI,SAAS,GAAG,MAAM,EAAE,SAAS,GAAG,CAAC,GAAI,CAAC;gBAC7C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,SAAS,CAAC,CAAA;gBAC9C,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;gBACvE,MAAM,GAAG,GAAG,MAAM,SAAS,CAAc,GAAG,OAAO,IAAI,KAAK,EAAE,EAAE;oBAC9D,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE;oBAChC,MAAM,EAAE,OAAO,EAAE,MAAM;oBACvB,SAAS;iBACV,CAAC,CAAA;gBACF,IAAI,GAAG,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;oBAC1B,MAAM,IAAI,YAAY,CAAC,cAAc,EAAE,4CAA4C,EAAE;wBACnF,QAAQ,EAAE,IAAI,CAAC,IAAI;qBACpB,CAAC,CAAA;gBACJ,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;gBAClD,SAAS,IAAI,CAAC,CAAA;YAChB,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,CAAA;QACxD,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { EntropyProvider } from '../types.js';
|
|
2
|
+
export interface BitcoinBeaconOptions {
|
|
3
|
+
fetch?: typeof fetch;
|
|
4
|
+
baseUrls?: string[];
|
|
5
|
+
pollIntervalMs?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Bitcoin block hashes as a PUBLIC crypto-beacon. Proof-of-work makes bias
|
|
9
|
+
* expensive (six figures per bit — Bonneau et al., eprint 2015/1015) but not
|
|
10
|
+
* impossible: miners can discard unfavourable blocks. Slow cadence
|
|
11
|
+
* (~10 minutes). Audits and mixing only, never private entropy.
|
|
12
|
+
*/
|
|
13
|
+
export declare function bitcoinBeacon(opts?: BitcoinBeaconOptions): EntropyProvider;
|
|
14
|
+
//# sourceMappingURL=bitcoin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bitcoin.d.ts","sourceRoot":"","sources":["../../src/providers/bitcoin.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAYrE,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,GAAE,oBAAyB,GAAG,eAAe,CAuF9E"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { EntropyError } from '../errors.js';
|
|
2
|
+
import { concatBytes } from '../internal/bytes.js';
|
|
3
|
+
import { fetchJson, fetchText } from '../internal/http.js';
|
|
4
|
+
import { defineProvider } from '../internal/provider.js';
|
|
5
|
+
import { beaconStream } from '../internal/stream.js';
|
|
6
|
+
import { bytesFromHexField } from '../internal/validate.js';
|
|
7
|
+
const INFO = Object.freeze({
|
|
8
|
+
name: 'bitcoin',
|
|
9
|
+
kind: 'beacon',
|
|
10
|
+
privacy: 'public',
|
|
11
|
+
});
|
|
12
|
+
const HASH_BYTES = 32;
|
|
13
|
+
const DEFAULT_BASE_URLS = ['https://blockstream.info/api', 'https://mempool.space/api'];
|
|
14
|
+
// ~10-minute blocks; poll once a minute.
|
|
15
|
+
const DEFAULT_POLL_INTERVAL_MS = 60_000;
|
|
16
|
+
/**
|
|
17
|
+
* Bitcoin block hashes as a PUBLIC crypto-beacon. Proof-of-work makes bias
|
|
18
|
+
* expensive (six figures per bit — Bonneau et al., eprint 2015/1015) but not
|
|
19
|
+
* impossible: miners can discard unfavourable blocks. Slow cadence
|
|
20
|
+
* (~10 minutes). Audits and mixing only, never private entropy.
|
|
21
|
+
*/
|
|
22
|
+
export function bitcoinBeacon(opts = {}) {
|
|
23
|
+
const { baseUrls = DEFAULT_BASE_URLS, pollIntervalMs = DEFAULT_POLL_INTERVAL_MS, fetch: fetchImpl, } = opts;
|
|
24
|
+
async function withFailover(run) {
|
|
25
|
+
let lastError;
|
|
26
|
+
for (const base of baseUrls) {
|
|
27
|
+
try {
|
|
28
|
+
return await run(base);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (!(error instanceof EntropyError) || error.code === 'aborted')
|
|
32
|
+
throw error;
|
|
33
|
+
lastError = error; // try the next mirror
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
throw lastError;
|
|
37
|
+
}
|
|
38
|
+
function parseHash(hash) {
|
|
39
|
+
return bytesFromHexField(hash.trim(), HASH_BYTES, INFO.name);
|
|
40
|
+
}
|
|
41
|
+
async function fetchTip(signal) {
|
|
42
|
+
return withFailover(async (base) => {
|
|
43
|
+
const text = await fetchText(`${base}/blocks/tip/hash`, {
|
|
44
|
+
provider: INFO.name,
|
|
45
|
+
signal,
|
|
46
|
+
fetchImpl,
|
|
47
|
+
});
|
|
48
|
+
const hash = text.trim();
|
|
49
|
+
return { hash, bytes: parseHash(hash) };
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
async function fetchPreviousHash(hash, signal) {
|
|
53
|
+
return withFailover(async (base) => {
|
|
54
|
+
const res = await fetchJson(`${base}/block/${hash}`, {
|
|
55
|
+
provider: INFO.name,
|
|
56
|
+
signal,
|
|
57
|
+
fetchImpl,
|
|
58
|
+
});
|
|
59
|
+
if (typeof res?.previousblockhash !== 'string') {
|
|
60
|
+
throw new EntropyError('bad_response', 'missing previousblockhash', {
|
|
61
|
+
provider: INFO.name,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return res.previousblockhash;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return defineProvider({
|
|
68
|
+
...INFO,
|
|
69
|
+
defaultChunkBytes: HASH_BYTES,
|
|
70
|
+
async getBytes(length, reqOpts) {
|
|
71
|
+
const blocksNeeded = Math.ceil(length / HASH_BYTES);
|
|
72
|
+
const tip = await fetchTip(reqOpts?.signal);
|
|
73
|
+
const chunks = [tip.bytes];
|
|
74
|
+
let cursor = tip.hash;
|
|
75
|
+
for (let i = 1; i < blocksNeeded; i++) {
|
|
76
|
+
cursor = await fetchPreviousHash(cursor, reqOpts?.signal);
|
|
77
|
+
chunks.push(parseHash(cursor));
|
|
78
|
+
}
|
|
79
|
+
return { bytes: concatBytes(chunks).slice(0, length), sources: [INFO] };
|
|
80
|
+
},
|
|
81
|
+
stream(streamOpts = {}) {
|
|
82
|
+
let lastHash = '';
|
|
83
|
+
let seq = 0;
|
|
84
|
+
return beaconStream(async (signal) => {
|
|
85
|
+
const tip = await fetchTip(signal);
|
|
86
|
+
if (tip.hash !== lastHash) {
|
|
87
|
+
lastHash = tip.hash;
|
|
88
|
+
seq++;
|
|
89
|
+
}
|
|
90
|
+
return { id: seq, bytes: tip.bytes };
|
|
91
|
+
}, pollIntervalMs, HASH_BYTES, INFO.name, streamOpts);
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=bitcoin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bitcoin.js","sourceRoot":"","sources":["../../src/providers/bitcoin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ConditioningOptions } from '../internal/condition.js';
|
|
2
|
+
import type { EntropyProvider } from '../types.js';
|
|
3
|
+
export interface Frame {
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
/** RGBA (channels 4, e.g. canvas ImageData) or single-channel (1, e.g. rawvideo gray). */
|
|
7
|
+
data: Uint8ClampedArray | Uint8Array;
|
|
8
|
+
channels: 1 | 4;
|
|
9
|
+
}
|
|
10
|
+
export interface FrameSource {
|
|
11
|
+
/** A fresh frame iterable per session; stop capturing in the generator's finally. */
|
|
12
|
+
frames(signal?: AbortSignal): AsyncIterable<Frame>;
|
|
13
|
+
close?(): void | Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export interface CameraOptions extends ConditioningOptions {
|
|
16
|
+
/** Injected frames (Node, tests). Default: getUserMedia + canvas (browser only). */
|
|
17
|
+
source?: FrameSource;
|
|
18
|
+
/** getUserMedia video constraints. Default { width: 640, height: 480 }. */
|
|
19
|
+
constraints?: MediaTrackConstraints;
|
|
20
|
+
/** Pixel subsampling stride — breaks adjacent-pixel correlation. Default 4. */
|
|
21
|
+
stride?: number;
|
|
22
|
+
/** Frames discarded at session start while auto-exposure/AGC settles. Default 10. */
|
|
23
|
+
warmupFrames?: number;
|
|
24
|
+
/** Bit extraction: 'sign' (frame-diff sign, AetherOnePi-style, default) or 'lsb'. */
|
|
25
|
+
bits?: 'sign' | 'lsb';
|
|
26
|
+
/**
|
|
27
|
+
* Von Neumann debiasing over the bit stream before packing. Default TRUE:
|
|
28
|
+
* auto-exposure drift and mains-flicker make whole frames brighten or
|
|
29
|
+
* darken together, producing long identical-bit runs that rightly trip the
|
|
30
|
+
* health tests — debiasing drops those correlated runs. Disable for the
|
|
31
|
+
* unprocessed AetherOnePi-style bit stream.
|
|
32
|
+
*/
|
|
33
|
+
debias?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Frame-diff sign extraction: brighter pixel → 1, darker → 0, unchanged →
|
|
37
|
+
* no bit. Compares the green (or only) channel of every stride-th pixel.
|
|
38
|
+
*/
|
|
39
|
+
export declare function signBits(prev: Frame, cur: Frame, stride: number): number[];
|
|
40
|
+
/** Least-significant bit of every stride-th pixel's green (or only) channel. */
|
|
41
|
+
export declare function lsbBits(frame: Frame, stride: number): number[];
|
|
42
|
+
/**
|
|
43
|
+
* Camera sensor noise (photon shot noise in lit scenes, thermal noise with
|
|
44
|
+
* the lens covered). Raw mode emits the packed frame-diff sign bits — the
|
|
45
|
+
* honest unwhitened physical signal. Auto-exposure and ISP processing vary
|
|
46
|
+
* wildly between devices; the built-in health tests are the guard.
|
|
47
|
+
*/
|
|
48
|
+
export declare function cameraEntropy(opts?: CameraOptions): EntropyProvider;
|
|
49
|
+
//# sourceMappingURL=camera.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../../src/providers/camera.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAGnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,0FAA0F;IAC1F,IAAI,EAAE,iBAAiB,GAAG,UAAU,CAAA;IACpC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,qFAAqF;IACrF,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;IAClD,KAAK,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/B;AAED,MAAM,WAAW,aAAc,SAAQ,mBAAmB;IACxD,oFAAoF;IACpF,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,qBAAqB,CAAA;IACnC,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IACrB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAMD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAW1E;AAED,gFAAgF;AAChF,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAO9D;AAuCD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,eAAe,CAqDvE"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { packBits, vonNeumann } from '../internal/bits.js';
|
|
2
|
+
import { sleep } from '../internal/rate-limit.js';
|
|
3
|
+
import { sampledProvider } from '../internal/sampled.js';
|
|
4
|
+
function channelOffset(channels) {
|
|
5
|
+
return channels === 4 ? 1 : 0; // green channel for RGBA
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Frame-diff sign extraction: brighter pixel → 1, darker → 0, unchanged →
|
|
9
|
+
* no bit. Compares the green (or only) channel of every stride-th pixel.
|
|
10
|
+
*/
|
|
11
|
+
export function signBits(prev, cur, stride) {
|
|
12
|
+
const step = stride * cur.channels;
|
|
13
|
+
const length = Math.min(prev.data.length, cur.data.length);
|
|
14
|
+
const bits = [];
|
|
15
|
+
for (let i = channelOffset(cur.channels); i < length; i += step) {
|
|
16
|
+
const a = prev.data[i];
|
|
17
|
+
const b = cur.data[i];
|
|
18
|
+
if (b > a)
|
|
19
|
+
bits.push(1);
|
|
20
|
+
else if (b < a)
|
|
21
|
+
bits.push(0);
|
|
22
|
+
}
|
|
23
|
+
return bits;
|
|
24
|
+
}
|
|
25
|
+
/** Least-significant bit of every stride-th pixel's green (or only) channel. */
|
|
26
|
+
export function lsbBits(frame, stride) {
|
|
27
|
+
const step = stride * frame.channels;
|
|
28
|
+
const bits = [];
|
|
29
|
+
for (let i = channelOffset(frame.channels); i < frame.data.length; i += step) {
|
|
30
|
+
bits.push(frame.data[i] & 1);
|
|
31
|
+
}
|
|
32
|
+
return bits;
|
|
33
|
+
}
|
|
34
|
+
const FRAME_INTERVAL_MS = 100; // ~10 fps is plenty for entropy harvesting
|
|
35
|
+
function browserFrameSource(constraints) {
|
|
36
|
+
return {
|
|
37
|
+
async *frames(signal) {
|
|
38
|
+
const mediaDevices = globalThis.navigator?.mediaDevices;
|
|
39
|
+
if (typeof mediaDevices?.getUserMedia !== 'function') {
|
|
40
|
+
throw new TypeError('cameraEntropy: no camera in this runtime — pass a { source } (in Node: ffmpegFrameSource from @mindpeeker/entropy/node)');
|
|
41
|
+
}
|
|
42
|
+
const stream = await mediaDevices.getUserMedia({ video: constraints });
|
|
43
|
+
try {
|
|
44
|
+
const video = document.createElement('video');
|
|
45
|
+
video.srcObject = stream;
|
|
46
|
+
video.muted = true;
|
|
47
|
+
await video.play();
|
|
48
|
+
const width = video.videoWidth || 640;
|
|
49
|
+
const height = video.videoHeight || 480;
|
|
50
|
+
const canvas = document.createElement('canvas');
|
|
51
|
+
canvas.width = width;
|
|
52
|
+
canvas.height = height;
|
|
53
|
+
const context = canvas.getContext('2d', { willReadFrequently: true });
|
|
54
|
+
if (!context)
|
|
55
|
+
throw new TypeError('cameraEntropy: 2d canvas context unavailable');
|
|
56
|
+
while (true) {
|
|
57
|
+
context.drawImage(video, 0, 0);
|
|
58
|
+
const image = context.getImageData(0, 0, width, height);
|
|
59
|
+
yield { width, height, data: image.data, channels: 4 };
|
|
60
|
+
await sleep(FRAME_INTERVAL_MS, signal);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
for (const track of stream.getTracks())
|
|
65
|
+
track.stop();
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Camera sensor noise (photon shot noise in lit scenes, thermal noise with
|
|
72
|
+
* the lens covered). Raw mode emits the packed frame-diff sign bits — the
|
|
73
|
+
* honest unwhitened physical signal. Auto-exposure and ISP processing vary
|
|
74
|
+
* wildly between devices; the built-in health tests are the guard.
|
|
75
|
+
*/
|
|
76
|
+
export function cameraEntropy(opts = {}) {
|
|
77
|
+
const { constraints = { width: 640, height: 480 }, stride = 4, warmupFrames = 10, bits = 'sign', debias = true, } = opts;
|
|
78
|
+
const source = opts.source ?? browserFrameSource(constraints);
|
|
79
|
+
async function* open(signal) {
|
|
80
|
+
let previous = null;
|
|
81
|
+
let skipped = 0;
|
|
82
|
+
let leftover = [];
|
|
83
|
+
for await (const frame of source.frames(signal)) {
|
|
84
|
+
// cooperative abort: a frozen scene yields frames but never bytes, so
|
|
85
|
+
// this loop must observe the signal itself
|
|
86
|
+
if (signal?.aborted)
|
|
87
|
+
throw signal.reason ?? new DOMException('aborted', 'AbortError');
|
|
88
|
+
if (skipped < warmupFrames) {
|
|
89
|
+
skipped++;
|
|
90
|
+
previous = frame;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
let frameBits;
|
|
94
|
+
if (bits === 'sign') {
|
|
95
|
+
if (!previous) {
|
|
96
|
+
previous = frame;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
frameBits = signBits(previous, frame, stride);
|
|
100
|
+
previous = frame;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
frameBits = lsbBits(frame, stride);
|
|
104
|
+
}
|
|
105
|
+
if (debias)
|
|
106
|
+
frameBits = vonNeumann(frameBits);
|
|
107
|
+
const [bytes, rest] = packBits(leftover.concat(frameBits));
|
|
108
|
+
leftover = rest;
|
|
109
|
+
if (bytes.length > 0)
|
|
110
|
+
yield bytes;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return sampledProvider({
|
|
114
|
+
name: 'camera',
|
|
115
|
+
kind: 'trng',
|
|
116
|
+
privacy: 'private',
|
|
117
|
+
open,
|
|
118
|
+
defaultMinEntropyPerSample: 1,
|
|
119
|
+
defaultSafetyFactor: 8,
|
|
120
|
+
defaultTimeoutMs: 30_000, // permission prompt + AGC warmup
|
|
121
|
+
}, opts);
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=camera.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera.js","sourceRoot":"","sources":["../../src/providers/camera.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { EntropyProvider } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The runtime's cryptographic PRNG. Always available, never rate limited —
|
|
4
|
+
* the natural last link of any fallback chain and the standard private mixin
|
|
5
|
+
* for `xorMix` with public beacons.
|
|
6
|
+
*/
|
|
7
|
+
export declare function cryptoProvider(): EntropyProvider;
|
|
8
|
+
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/providers/crypto.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAWrE;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,eAAe,CAahD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { defineProvider } from '../internal/provider.js';
|
|
2
|
+
// crypto.getRandomValues throws QuotaExceededError above 65536 bytes per call.
|
|
3
|
+
const MAX_PER_CALL = 65_536;
|
|
4
|
+
const INFO = Object.freeze({
|
|
5
|
+
name: 'crypto',
|
|
6
|
+
kind: 'csprng',
|
|
7
|
+
privacy: 'private',
|
|
8
|
+
});
|
|
9
|
+
/**
|
|
10
|
+
* The runtime's cryptographic PRNG. Always available, never rate limited —
|
|
11
|
+
* the natural last link of any fallback chain and the standard private mixin
|
|
12
|
+
* for `xorMix` with public beacons.
|
|
13
|
+
*/
|
|
14
|
+
export function cryptoProvider() {
|
|
15
|
+
return defineProvider({
|
|
16
|
+
...INFO,
|
|
17
|
+
async getBytes(length) {
|
|
18
|
+
const bytes = new Uint8Array(length);
|
|
19
|
+
for (let offset = 0; offset < length; offset += MAX_PER_CALL) {
|
|
20
|
+
globalThis.crypto.getRandomValues(bytes.subarray(offset, Math.min(offset + MAX_PER_CALL, length)));
|
|
21
|
+
}
|
|
22
|
+
return { bytes, sources: [INFO] };
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/providers/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAGxD,+EAA+E;AAC/E,MAAM,YAAY,GAAG,MAAM,CAAA;AAE3B,MAAM,IAAI,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,SAAS;CACnB,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,cAAc,CAAC;QACpB,GAAG,IAAI;QACP,KAAK,CAAC,QAAQ,CAAC,MAAM;YACnB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAA;YACpC,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,YAAY,EAAE,CAAC;gBAC7D,UAAU,CAAC,MAAM,CAAC,eAAe,CAC/B,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,YAAY,EAAE,MAAM,CAAC,CAAC,CAChE,CAAA;YACH,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,CAAA;QACnC,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { EntropyProvider } from '../types.js';
|
|
2
|
+
export interface CurbyOptions {
|
|
3
|
+
fetch?: typeof fetch;
|
|
4
|
+
baseUrls?: string[];
|
|
5
|
+
/** Twine chain CID. Default: the CURBy-RNG chain. */
|
|
6
|
+
chainCid?: string;
|
|
7
|
+
pollIntervalMs?: number;
|
|
8
|
+
/** Reject pulses older than this — guards against a stalled spool. Default 180_000. */
|
|
9
|
+
maxStalenessMs?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* CURBy (CU Boulder + NIST) randomness beacon over the Twine protocol. The
|
|
13
|
+
* per-pulse randomness is defined as the block CID's multihash digest.
|
|
14
|
+
* PUBLIC randomness with a built-in freshness guard.
|
|
15
|
+
*/
|
|
16
|
+
export declare function curby(opts?: CurbyOptions): EntropyProvider;
|
|
17
|
+
//# sourceMappingURL=curby.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"curby.d.ts","sourceRoot":"","sources":["../../src/providers/curby.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAiBrE,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,uFAAuF;IACvF,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAOD;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,IAAI,GAAE,YAAiB,GAAG,eAAe,CA8G9D"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { EntropyError } from '../errors.js';
|
|
2
|
+
import { concatBytes } from '../internal/bytes.js';
|
|
3
|
+
import { cidDigest } from '../internal/encoding.js';
|
|
4
|
+
import { fetchJson } from '../internal/http.js';
|
|
5
|
+
import { defineProvider } from '../internal/provider.js';
|
|
6
|
+
import { beaconStream } from '../internal/stream.js';
|
|
7
|
+
const INFO = Object.freeze({
|
|
8
|
+
name: 'curby',
|
|
9
|
+
kind: 'beacon',
|
|
10
|
+
privacy: 'public',
|
|
11
|
+
});
|
|
12
|
+
const PULSE_BYTES = 32;
|
|
13
|
+
const DEFAULT_BASE_URLS = ['https://api.entwine.me', 'https://random.colorado.edu/api'];
|
|
14
|
+
// The CURBy-RNG chain (classical, 60 s cadence). The quantum CURBy-Q chain is
|
|
15
|
+
// deliberately NOT used: it has been stalled since 2025-08 (same round for
|
|
16
|
+
// months) while this chain keeps pulsing.
|
|
17
|
+
const CURBY_RNG_CHAIN_CID = 'bafyriqci6f3st2mg7gq733ho4zvvth32zpy2mtiylixwmhoz6d627eo3jfpmbxepe54u2zdvymonq5sp3armtm4rodxsynsirr5g3xsbd3q4s';
|
|
18
|
+
const DEFAULT_POLL_INTERVAL_MS = 60_000;
|
|
19
|
+
const DEFAULT_MAX_STALENESS_MS = 3 * 60_000;
|
|
20
|
+
/**
|
|
21
|
+
* CURBy (CU Boulder + NIST) randomness beacon over the Twine protocol. The
|
|
22
|
+
* per-pulse randomness is defined as the block CID's multihash digest.
|
|
23
|
+
* PUBLIC randomness with a built-in freshness guard.
|
|
24
|
+
*/
|
|
25
|
+
export function curby(opts = {}) {
|
|
26
|
+
const { baseUrls = DEFAULT_BASE_URLS, chainCid = CURBY_RNG_CHAIN_CID, pollIntervalMs = DEFAULT_POLL_INTERVAL_MS, maxStalenessMs = DEFAULT_MAX_STALENESS_MS, fetch: fetchImpl, } = opts;
|
|
27
|
+
function parseBlock(block) {
|
|
28
|
+
const rawCid = block?.cid;
|
|
29
|
+
const cidString = typeof rawCid === 'string' ? rawCid : rawCid?.['/'];
|
|
30
|
+
const index = block?.data?.content?.index;
|
|
31
|
+
const timestampRaw = block?.data?.content?.payload?.timestamp;
|
|
32
|
+
const timestamp = typeof timestampRaw === 'string' ? Date.parse(timestampRaw) : Number.NaN;
|
|
33
|
+
if (typeof cidString !== 'string' || !Number.isInteger(index) || Number.isNaN(timestamp)) {
|
|
34
|
+
throw new EntropyError('bad_response', 'malformed twine block', { provider: INFO.name });
|
|
35
|
+
}
|
|
36
|
+
let digest;
|
|
37
|
+
try {
|
|
38
|
+
digest = cidDigest(cidString);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
throw new EntropyError('bad_response', 'undecodable block CID', {
|
|
42
|
+
provider: INFO.name,
|
|
43
|
+
cause: error,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// The CURBy-RNG chain uses 64-byte (sha2-512) digests; other twine chains
|
|
47
|
+
// may differ, so accept any reasonable multihash digest size.
|
|
48
|
+
if (digest.length < 16) {
|
|
49
|
+
throw new EntropyError('bad_response', `digest too short (${digest.length} bytes)`, {
|
|
50
|
+
provider: INFO.name,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return { index: index, timestamp, bytes: digest };
|
|
54
|
+
}
|
|
55
|
+
async function fetchPulse(which, signal) {
|
|
56
|
+
let lastError;
|
|
57
|
+
for (const base of baseUrls) {
|
|
58
|
+
try {
|
|
59
|
+
const block = await fetchJson(`${base}/chains/${chainCid}/pulses/${which}`, {
|
|
60
|
+
provider: INFO.name,
|
|
61
|
+
signal,
|
|
62
|
+
fetchImpl,
|
|
63
|
+
});
|
|
64
|
+
return parseBlock(block);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
if (!(error instanceof EntropyError) || error.code === 'aborted')
|
|
68
|
+
throw error;
|
|
69
|
+
lastError = error; // try the next mirror
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
throw lastError;
|
|
73
|
+
}
|
|
74
|
+
async function fetchFreshLatest(signal) {
|
|
75
|
+
const pulse = await fetchPulse('latest', signal);
|
|
76
|
+
if (Date.now() - pulse.timestamp > maxStalenessMs) {
|
|
77
|
+
throw new EntropyError('bad_response', `chain stale — latest pulse is ${Math.round((Date.now() - pulse.timestamp) / 1000)}s old`, { provider: INFO.name });
|
|
78
|
+
}
|
|
79
|
+
return pulse;
|
|
80
|
+
}
|
|
81
|
+
return defineProvider({
|
|
82
|
+
...INFO,
|
|
83
|
+
defaultChunkBytes: PULSE_BYTES,
|
|
84
|
+
async getBytes(length, reqOpts) {
|
|
85
|
+
const latest = await fetchFreshLatest(reqOpts?.signal);
|
|
86
|
+
const chunks = [latest.bytes];
|
|
87
|
+
let collected = latest.bytes.length;
|
|
88
|
+
// Walk prior pulses until we have enough, adapting to the chain's actual
|
|
89
|
+
// digest size (learned from the latest block).
|
|
90
|
+
for (let i = 1; collected < length; i++) {
|
|
91
|
+
const index = latest.index - i;
|
|
92
|
+
if (index < 1) {
|
|
93
|
+
throw new EntropyError('insufficient_entropy', 'chain too short for request', {
|
|
94
|
+
provider: INFO.name,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// verify-live: latest is research-verified; by-index follows the
|
|
98
|
+
// documented twine pattern and is exercised by LIVE=1 runs
|
|
99
|
+
const prior = await fetchPulse(index, reqOpts?.signal);
|
|
100
|
+
chunks.push(prior.bytes);
|
|
101
|
+
collected += prior.bytes.length;
|
|
102
|
+
}
|
|
103
|
+
return { bytes: concatBytes(chunks).slice(0, length), sources: [INFO] };
|
|
104
|
+
},
|
|
105
|
+
stream(streamOpts = {}) {
|
|
106
|
+
return beaconStream(async (signal) => {
|
|
107
|
+
const pulse = await fetchFreshLatest(signal);
|
|
108
|
+
return { id: pulse.index, bytes: pulse.bytes };
|
|
109
|
+
}, pollIntervalMs, PULSE_BYTES, INFO.name, streamOpts);
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=curby.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"curby.js","sourceRoot":"","sources":["../../src/providers/curby.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { EntropyProvider } from '../types.js';
|
|
2
|
+
export interface DrandOptions {
|
|
3
|
+
fetch?: typeof fetch;
|
|
4
|
+
/** Mirrors tried in order per request. */
|
|
5
|
+
baseUrls?: string[];
|
|
6
|
+
/** Beacon id. Default 'quicknet' (3 s rounds, unchained). */
|
|
7
|
+
beacon?: string;
|
|
8
|
+
/** Stream poll cadence. Default 3000 (the quicknet round period). */
|
|
9
|
+
pollIntervalMs?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* drand / League of Entropy distributed randomness beacon (threshold BLS).
|
|
13
|
+
* PUBLIC randomness: everyone sees every round — never seed secrets from it
|
|
14
|
+
* alone; combine via `xorMix` with a private source for auditable secrets.
|
|
15
|
+
* Randomness is derived as SHA-256(signature), as specified for unchained
|
|
16
|
+
* beacons like quicknet.
|
|
17
|
+
*/
|
|
18
|
+
export declare function drand(opts?: DrandOptions): EntropyProvider;
|
|
19
|
+
//# sourceMappingURL=drand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drand.d.ts","sourceRoot":"","sources":["../../src/providers/drand.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAYrE,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAOD;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,IAAI,GAAE,YAAiB,GAAG,eAAe,CAgF9D"}
|