canary-kit 0.9.0 → 0.10.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/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  [![TypeScript](https://img.shields.io/badge/TypeScript-native-blue)](https://www.typescriptlang.org/)
9
9
  [![Coverage](https://img.shields.io/badge/coverage-95%25-brightgreen)](vitest.config.ts)
10
10
 
11
- **[Interactive Demo](https://thecryptodonkey.github.io/canary-kit/)** · [Protocol Spec](CANARY.md) · [Nostr Binding](NIP-CANARY.md) · [Integration Guide](INTEGRATION.md)
11
+ **[Interactive Demo](https://canary.trotters.cc/)** · [Protocol Spec](CANARY.md) · [Nostr Binding](NIP-CANARY.md) · [Integration Guide](INTEGRATION.md)
12
12
 
13
13
  ## The Problem
14
14
 
package/dist/counter.d.ts CHANGED
@@ -1,37 +1,2 @@
1
- /** Default rotation interval: 7 days in seconds. */
2
- export declare const DEFAULT_ROTATION_INTERVAL = 604800;
3
- /**
4
- * Maximum allowed usage offset above the current time-based counter.
5
- * Implementations MUST reject counter updates where effective counter > time-based counter + MAX_COUNTER_OFFSET.
6
- * See CANARY spec §Counter Acceptance.
7
- */
8
- export declare const MAX_COUNTER_OFFSET = 100;
9
- /**
10
- * Derive the current counter from a unix timestamp and rotation interval.
11
- * Counter = floor(timestamp / interval).
12
- *
13
- * @param timestampSec - Unix timestamp in seconds (non-negative finite number).
14
- * @param rotationIntervalSec - Rotation interval in seconds (positive finite number, default: 604800 = 7 days).
15
- * @returns Integer counter value within uint32 range.
16
- * @throws {RangeError} If timestampSec is negative/non-finite, rotationIntervalSec is non-positive/non-finite, or counter exceeds uint32.
17
- */
18
- export declare function getCounter(timestampSec: number, rotationIntervalSec?: number): number;
19
- /**
20
- * Derive a counter from an event identifier (e.g. a task ID or Nostr event ID).
21
- * Uses SHA-256 truncated to 32 bits for a deterministic, uniformly distributed counter.
22
- * Per CANARY spec §Counter Schemes: event-based counters are deterministic from event ID.
23
- *
24
- * @param eventId - String identifier to derive the counter from (e.g. a Nostr event ID).
25
- * @returns Unsigned 32-bit integer derived from SHA-256 of the event ID.
26
- */
27
- export declare function counterFromEventId(eventId: string): number;
28
- /**
29
- * Serialise a counter to an 8-byte big-endian Uint8Array.
30
- * Same encoding as TOTP (RFC 6238).
31
- *
32
- * @param counter - Non-negative safe integer to serialise.
33
- * @returns 8-byte big-endian Uint8Array representation of the counter.
34
- * @throws {RangeError} If counter is negative, not an integer, or exceeds Number.MAX_SAFE_INTEGER.
35
- */
36
- export declare function counterToBytes(counter: number): Uint8Array;
1
+ export { getCounter, counterFromEventId, counterToBytes, DEFAULT_ROTATION_INTERVAL, MAX_COUNTER_OFFSET, } from 'spoken-token';
37
2
  //# sourceMappingURL=counter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"counter.d.ts","sourceRoot":"","sources":["../src/counter.ts"],"names":[],"mappings":"AAEA,oDAAoD;AACpD,eAAO,MAAM,yBAAyB,SAAU,CAAA;AAEhD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,MAAM,CAAA;AAErC;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,YAAY,EAAE,MAAM,EACpB,mBAAmB,GAAE,MAAkC,GACtD,MAAM,CAYR;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI1D;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAQ1D"}
1
+ {"version":3,"file":"counter.d.ts","sourceRoot":"","sources":["../src/counter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAAE,kBAAkB,EAAE,cAAc,EAC9C,yBAAyB,EAAE,kBAAkB,GAC9C,MAAM,cAAc,CAAA"}
package/dist/counter.js CHANGED
@@ -1,62 +1,2 @@
1
- import { sha256 } from './crypto.js';
2
- /** Default rotation interval: 7 days in seconds. */
3
- export const DEFAULT_ROTATION_INTERVAL = 604_800;
4
- /**
5
- * Maximum allowed usage offset above the current time-based counter.
6
- * Implementations MUST reject counter updates where effective counter > time-based counter + MAX_COUNTER_OFFSET.
7
- * See CANARY spec §Counter Acceptance.
8
- */
9
- export const MAX_COUNTER_OFFSET = 100;
10
- /**
11
- * Derive the current counter from a unix timestamp and rotation interval.
12
- * Counter = floor(timestamp / interval).
13
- *
14
- * @param timestampSec - Unix timestamp in seconds (non-negative finite number).
15
- * @param rotationIntervalSec - Rotation interval in seconds (positive finite number, default: 604800 = 7 days).
16
- * @returns Integer counter value within uint32 range.
17
- * @throws {RangeError} If timestampSec is negative/non-finite, rotationIntervalSec is non-positive/non-finite, or counter exceeds uint32.
18
- */
19
- export function getCounter(timestampSec, rotationIntervalSec = DEFAULT_ROTATION_INTERVAL) {
20
- if (!Number.isFinite(timestampSec) || timestampSec < 0) {
21
- throw new RangeError(`timestampSec must be a non-negative finite number, got ${timestampSec}`);
22
- }
23
- if (!Number.isFinite(rotationIntervalSec) || rotationIntervalSec <= 0) {
24
- throw new RangeError(`rotationIntervalSec must be a positive finite number, got ${rotationIntervalSec}`);
25
- }
26
- const result = Math.floor(timestampSec / rotationIntervalSec);
27
- if (result > 0xFFFFFFFF) {
28
- throw new RangeError(`Counter exceeds uint32 range (${result}). Use a larger rotation interval.`);
29
- }
30
- return result;
31
- }
32
- /**
33
- * Derive a counter from an event identifier (e.g. a task ID or Nostr event ID).
34
- * Uses SHA-256 truncated to 32 bits for a deterministic, uniformly distributed counter.
35
- * Per CANARY spec §Counter Schemes: event-based counters are deterministic from event ID.
36
- *
37
- * @param eventId - String identifier to derive the counter from (e.g. a Nostr event ID).
38
- * @returns Unsigned 32-bit integer derived from SHA-256 of the event ID.
39
- */
40
- export function counterFromEventId(eventId) {
41
- const hash = sha256(new TextEncoder().encode(eventId));
42
- // Read first 4 bytes as unsigned 32-bit big-endian integer
43
- return (hash[0] << 24 | hash[1] << 16 | hash[2] << 8 | hash[3]) >>> 0;
44
- }
45
- /**
46
- * Serialise a counter to an 8-byte big-endian Uint8Array.
47
- * Same encoding as TOTP (RFC 6238).
48
- *
49
- * @param counter - Non-negative safe integer to serialise.
50
- * @returns 8-byte big-endian Uint8Array representation of the counter.
51
- * @throws {RangeError} If counter is negative, not an integer, or exceeds Number.MAX_SAFE_INTEGER.
52
- */
53
- export function counterToBytes(counter) {
54
- if (!Number.isInteger(counter) || counter < 0 || counter > Number.MAX_SAFE_INTEGER) {
55
- throw new RangeError(`Counter must be a non-negative safe integer, got ${counter}`);
56
- }
57
- const buf = new Uint8Array(8);
58
- const view = new DataView(buf.buffer);
59
- view.setBigUint64(0, BigInt(counter), false); // false = big-endian
60
- return buf;
61
- }
1
+ export { getCounter, counterFromEventId, counterToBytes, DEFAULT_ROTATION_INTERVAL, MAX_COUNTER_OFFSET, } from 'spoken-token';
62
2
  //# sourceMappingURL=counter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"counter.js","sourceRoot":"","sources":["../src/counter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,oDAAoD;AACpD,MAAM,CAAC,MAAM,yBAAyB,GAAG,OAAO,CAAA;AAEhD;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;AAErC;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CACxB,YAAoB,EACpB,sBAA8B,yBAAyB;IAEvD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,UAAU,CAAC,0DAA0D,YAAY,EAAE,CAAC,CAAA;IAChG,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,mBAAmB,IAAI,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,UAAU,CAAC,6DAA6D,mBAAmB,EAAE,CAAC,CAAA;IAC1G,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,mBAAmB,CAAC,CAAA;IAC7D,IAAI,MAAM,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,IAAI,UAAU,CAAC,iCAAiC,MAAM,oCAAoC,CAAC,CAAA;IACnG,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAA;IACtD,2DAA2D;IAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;AACvE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC;QACnF,MAAM,IAAI,UAAU,CAAC,oDAAoD,OAAO,EAAE,CAAC,CAAA;IACrF,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;IAC7B,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACrC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAA,CAAC,qBAAqB;IAClE,OAAO,GAAG,CAAA;AACZ,CAAC"}
1
+ {"version":3,"file":"counter.js","sourceRoot":"","sources":["../src/counter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAAE,kBAAkB,EAAE,cAAc,EAC9C,yBAAyB,EAAE,kBAAkB,GAC9C,MAAM,cAAc,CAAA"}
package/dist/crypto.d.ts CHANGED
@@ -1,111 +1,2 @@
1
- /**
2
- * Universal synchronous crypto primitives — Node.js and browser compatible.
3
- *
4
- * SHA-256: FIPS 180-4
5
- * HMAC: RFC 2104
6
- *
7
- * Uses only Uint8Array and the global `crypto` object (Web Crypto API).
8
- * No async, no Web Crypto subtle API, no Buffer.
9
- */
10
- /**
11
- * Compute SHA-256 of `data`.
12
- * Implements FIPS 180-4 sections 5 (padding), 6.2 (hash computation).
13
- *
14
- * @param data - Input bytes to hash.
15
- * @returns 32-byte SHA-256 digest.
16
- */
17
- export declare function sha256(data: Uint8Array): Uint8Array;
18
- /**
19
- * Compute HMAC-SHA256(key, data) and return the raw 32-byte digest.
20
- *
21
- * RFC 2104:
22
- * H(K XOR opad, H(K XOR ipad, data))
23
- * ipad = 0x36 repeated, opad = 0x5c repeated.
24
- * Keys longer than the block size are hashed first.
25
- * Keys shorter than the block size are zero-padded on the right.
26
- *
27
- * @param key - HMAC key bytes (hashed if longer than 64 bytes, zero-padded if shorter).
28
- * @param data - Input data bytes.
29
- * @returns 32-byte HMAC-SHA256 digest.
30
- */
31
- export declare function hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array;
32
- /**
33
- * Generate a cryptographically secure 32-byte seed as a 64-character hex string.
34
- * Uses the global `crypto.getRandomValues` (Web Crypto API).
35
- *
36
- * @returns 64-character lowercase hex string (32 random bytes).
37
- */
38
- export declare function randomSeed(): string;
39
- /**
40
- * Convert a hex string to a Uint8Array. Replaces `Buffer.from(hex, 'hex')`.
41
- *
42
- * @param hex - Even-length hex string (case-insensitive).
43
- * @returns Decoded byte array.
44
- * @throws {Error} If hex has odd length.
45
- * @throws {TypeError} If hex contains invalid characters.
46
- */
47
- export declare function hexToBytes(hex: string): Uint8Array;
48
- /**
49
- * Convert a Uint8Array to a lowercase hex string. Replaces `buffer.toString('hex')`.
50
- *
51
- * @param bytes - Input byte array.
52
- * @returns Lowercase hex string (2 characters per byte).
53
- */
54
- export declare function bytesToHex(bytes: Uint8Array): string;
55
- /**
56
- * Read an unsigned 16-bit big-endian integer from `bytes` at `offset`.
57
- * Replaces `buffer.readUInt16BE(offset)`.
58
- *
59
- * @param bytes - Source byte array.
60
- * @param offset - Byte offset to read from.
61
- * @returns Unsigned 16-bit integer value.
62
- * @throws {RangeError} If offset is out of bounds.
63
- */
64
- export declare function readUint16BE(bytes: Uint8Array, offset: number): number;
65
- /**
66
- * Concatenate multiple Uint8Arrays into one.
67
- * Replaces `Buffer.concat([...])`.
68
- *
69
- * @param arrays - One or more Uint8Arrays to concatenate.
70
- * @returns A single Uint8Array containing all input bytes in order.
71
- */
72
- export declare function concatBytes(...arrays: Uint8Array[]): Uint8Array;
73
- /**
74
- * Encode a Uint8Array as a base64 string. Available in Node 16+ and all browsers.
75
- *
76
- * @param bytes - Input byte array.
77
- * @returns Base64-encoded string.
78
- */
79
- export declare function bytesToBase64(bytes: Uint8Array): string;
80
- /**
81
- * Decode a base64 string to a Uint8Array.
82
- *
83
- * @param base64 - Base64-encoded string.
84
- * @returns Decoded byte array.
85
- */
86
- export declare function base64ToBytes(base64: string): Uint8Array;
87
- /**
88
- * Best-effort constant-time comparison of two byte arrays.
89
- * Pads both arrays to equal length to avoid leaking length via timing.
90
- *
91
- * **Caveat:** JavaScript runtimes do not guarantee constant-time execution —
92
- * JIT compilation and speculative execution may introduce timing variation.
93
- * This is a defence-in-depth measure, not a cryptographic guarantee. For
94
- * high-assurance environments, pair with rate limiting and consider
95
- * platform-native constant-time primitives.
96
- *
97
- * @param a - First byte array.
98
- * @param b - Second byte array.
99
- * @returns `true` if arrays are equal in length and content, `false` otherwise.
100
- */
101
- export declare function timingSafeEqual(a: Uint8Array, b: Uint8Array): boolean;
102
- /**
103
- * Best-effort constant-time comparison of two strings (UTF-8 encoded, then byte-compared).
104
- * See {@link timingSafeEqual} caveats.
105
- *
106
- * @param a - First string.
107
- * @param b - Second string.
108
- * @returns `true` if strings are equal, `false` otherwise.
109
- */
110
- export declare function timingSafeStringEqual(a: string, b: string): boolean;
1
+ export { sha256, hmacSha256, randomSeed, hexToBytes, bytesToHex, readUint16BE, concatBytes, bytesToBase64, base64ToBytes, timingSafeEqual, timingSafeStringEqual, } from 'spoken-token';
111
2
  //# sourceMappingURL=crypto.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAqCH;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAiFnD;AAQD;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU,CA6BxE;AAMD;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAInC;AAMD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAWlD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGtE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,CAS/D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIvD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAKxD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAYrE;AAID;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAEnE"}
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AACA,OAAO,EACL,MAAM,EAAE,UAAU,EAAE,UAAU,EAC9B,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EACjD,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,qBAAqB,GACvC,MAAM,cAAc,CAAA"}
package/dist/crypto.js CHANGED
@@ -1,309 +1,3 @@
1
- /**
2
- * Universal synchronous crypto primitives Node.js and browser compatible.
3
- *
4
- * SHA-256: FIPS 180-4
5
- * HMAC: RFC 2104
6
- *
7
- * Uses only Uint8Array and the global `crypto` object (Web Crypto API).
8
- * No async, no Web Crypto subtle API, no Buffer.
9
- */
10
- // ---------------------------------------------------------------------------
11
- // SHA-256 — FIPS 180-4
12
- // ---------------------------------------------------------------------------
13
- /** Initial hash values H0–H7 (first 32 bits of fractional parts of sqrt of first 8 primes). */
14
- const H0 = [
15
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
16
- 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
17
- ];
18
- /** Round constants K[0..63] (first 32 bits of fractional parts of cbrt of first 64 primes). */
19
- const K = new Uint32Array([
20
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
21
- 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
22
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
23
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
24
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
25
- 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
26
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
27
- 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
28
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
29
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
30
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
31
- 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
32
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
33
- 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
34
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
35
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
36
- ]);
37
- /** Rotate-right a 32-bit integer by n bits. */
38
- function rotr32(x, n) {
39
- return ((x >>> n) | (x << (32 - n))) >>> 0;
40
- }
41
- /**
42
- * Compute SHA-256 of `data`.
43
- * Implements FIPS 180-4 sections 5 (padding), 6.2 (hash computation).
44
- *
45
- * @param data - Input bytes to hash.
46
- * @returns 32-byte SHA-256 digest.
47
- */
48
- export function sha256(data) {
49
- // --- Pre-processing: padding (FIPS 180-4 §5.1.1) ---
50
- const bitLen = data.length * 8;
51
- // Append 0x80, then zero bytes, then 8-byte big-endian bit-length.
52
- // Total padded length must be a multiple of 64 bytes (512 bits).
53
- // After the message and 0x80 byte we need at least 8 bytes for the length,
54
- // so we pad to the next multiple of 64 that satisfies this.
55
- const padded = new Uint8Array(Math.ceil((data.length + 9) / 64) * 64);
56
- padded.set(data);
57
- padded[data.length] = 0x80;
58
- // Write 64-bit big-endian bit length at the end.
59
- // bitLen fits in a 53-bit JS number so we can split safely.
60
- const view = new DataView(padded.buffer);
61
- view.setUint32(padded.length - 8, Math.floor(bitLen / 0x100000000), false);
62
- view.setUint32(padded.length - 4, bitLen >>> 0, false);
63
- // --- Processing blocks (FIPS 180-4 §6.2.2) ---
64
- // Working variables
65
- let [h0, h1, h2, h3, h4, h5, h6, h7] = H0;
66
- const W = new Uint32Array(64);
67
- for (let offset = 0; offset < padded.length; offset += 64) {
68
- // Prepare message schedule W[0..63]
69
- for (let t = 0; t < 16; t++) {
70
- W[t] = view.getUint32(offset + t * 4, false);
71
- }
72
- for (let t = 16; t < 64; t++) {
73
- const w15 = W[t - 15];
74
- const w2 = W[t - 2];
75
- const s0 = rotr32(w15, 7) ^ rotr32(w15, 18) ^ (w15 >>> 3);
76
- const s1 = rotr32(w2, 17) ^ rotr32(w2, 19) ^ (w2 >>> 10);
77
- W[t] = (W[t - 16] + s0 + W[t - 7] + s1) >>> 0;
78
- }
79
- // Initialise working variables
80
- let a = h0, b = h1, c = h2, d = h3;
81
- let e = h4, f = h5, g = h6, hh = h7;
82
- // 64 rounds
83
- for (let t = 0; t < 64; t++) {
84
- const S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);
85
- const ch = (e & f) ^ (~e & g);
86
- const tmp1 = (hh + S1 + ch + K[t] + W[t]) >>> 0;
87
- const S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);
88
- const maj = (a & b) ^ (a & c) ^ (b & c);
89
- const tmp2 = (S0 + maj) >>> 0;
90
- hh = g;
91
- g = f;
92
- f = e;
93
- e = (d + tmp1) >>> 0;
94
- d = c;
95
- c = b;
96
- b = a;
97
- a = (tmp1 + tmp2) >>> 0;
98
- }
99
- // Add the compressed chunk to the current hash value
100
- h0 = (h0 + a) >>> 0;
101
- h1 = (h1 + b) >>> 0;
102
- h2 = (h2 + c) >>> 0;
103
- h3 = (h3 + d) >>> 0;
104
- h4 = (h4 + e) >>> 0;
105
- h5 = (h5 + f) >>> 0;
106
- h6 = (h6 + g) >>> 0;
107
- h7 = (h7 + hh) >>> 0;
108
- }
109
- // Produce the final hash value (big-endian)
110
- const digest = new Uint8Array(32);
111
- const dv = new DataView(digest.buffer);
112
- dv.setUint32(0, h0, false);
113
- dv.setUint32(4, h1, false);
114
- dv.setUint32(8, h2, false);
115
- dv.setUint32(12, h3, false);
116
- dv.setUint32(16, h4, false);
117
- dv.setUint32(20, h5, false);
118
- dv.setUint32(24, h6, false);
119
- dv.setUint32(28, h7, false);
120
- return digest;
121
- }
122
- // ---------------------------------------------------------------------------
123
- // HMAC-SHA256 — RFC 2104
124
- // ---------------------------------------------------------------------------
125
- const BLOCK_SIZE = 64; // SHA-256 block size in bytes
126
- /**
127
- * Compute HMAC-SHA256(key, data) and return the raw 32-byte digest.
128
- *
129
- * RFC 2104:
130
- * H(K XOR opad, H(K XOR ipad, data))
131
- * ipad = 0x36 repeated, opad = 0x5c repeated.
132
- * Keys longer than the block size are hashed first.
133
- * Keys shorter than the block size are zero-padded on the right.
134
- *
135
- * @param key - HMAC key bytes (hashed if longer than 64 bytes, zero-padded if shorter).
136
- * @param data - Input data bytes.
137
- * @returns 32-byte HMAC-SHA256 digest.
138
- */
139
- export function hmacSha256(key, data) {
140
- // If the key is longer than the block size, hash it first.
141
- const normalised = key.length > BLOCK_SIZE ? sha256(key) : key;
142
- // Pad/extend to block size.
143
- const k = new Uint8Array(BLOCK_SIZE);
144
- k.set(normalised);
145
- // Build inner and outer padded keys.
146
- const ipad = new Uint8Array(BLOCK_SIZE);
147
- const opad = new Uint8Array(BLOCK_SIZE);
148
- for (let i = 0; i < BLOCK_SIZE; i++) {
149
- ipad[i] = k[i] ^ 0x36;
150
- opad[i] = k[i] ^ 0x5c;
151
- }
152
- // inner = sha256(ipad || data)
153
- const inner = sha256(concatBytes(ipad, data));
154
- // outer = sha256(opad || inner)
155
- const result = sha256(concatBytes(opad, inner));
156
- // Best-effort zeroing of key material and intermediate state
157
- k.fill(0);
158
- ipad.fill(0);
159
- opad.fill(0);
160
- inner.fill(0);
161
- return result;
162
- }
163
- // ---------------------------------------------------------------------------
164
- // Random seed
165
- // ---------------------------------------------------------------------------
166
- /**
167
- * Generate a cryptographically secure 32-byte seed as a 64-character hex string.
168
- * Uses the global `crypto.getRandomValues` (Web Crypto API).
169
- *
170
- * @returns 64-character lowercase hex string (32 random bytes).
171
- */
172
- export function randomSeed() {
173
- const bytes = new Uint8Array(32);
174
- crypto.getRandomValues(bytes);
175
- return bytesToHex(bytes);
176
- }
177
- // ---------------------------------------------------------------------------
178
- // Byte / hex utilities
179
- // ---------------------------------------------------------------------------
180
- /**
181
- * Convert a hex string to a Uint8Array. Replaces `Buffer.from(hex, 'hex')`.
182
- *
183
- * @param hex - Even-length hex string (case-insensitive).
184
- * @returns Decoded byte array.
185
- * @throws {Error} If hex has odd length.
186
- * @throws {TypeError} If hex contains invalid characters.
187
- */
188
- export function hexToBytes(hex) {
189
- if (hex.length % 2 !== 0) {
190
- throw new Error(`hexToBytes: odd-length hex string (${hex.length} chars)`);
191
- }
192
- const bytes = new Uint8Array(hex.length / 2);
193
- for (let i = 0; i < bytes.length; i++) {
194
- const pair = hex.slice(i * 2, i * 2 + 2);
195
- if (!/^[0-9a-fA-F]{2}$/.test(pair))
196
- throw new TypeError(`Invalid hex character at position ${i * 2}`);
197
- bytes[i] = parseInt(pair, 16);
198
- }
199
- return bytes;
200
- }
201
- /**
202
- * Convert a Uint8Array to a lowercase hex string. Replaces `buffer.toString('hex')`.
203
- *
204
- * @param bytes - Input byte array.
205
- * @returns Lowercase hex string (2 characters per byte).
206
- */
207
- export function bytesToHex(bytes) {
208
- let hex = '';
209
- for (let i = 0; i < bytes.length; i++) {
210
- hex += bytes[i].toString(16).padStart(2, '0');
211
- }
212
- return hex;
213
- }
214
- /**
215
- * Read an unsigned 16-bit big-endian integer from `bytes` at `offset`.
216
- * Replaces `buffer.readUInt16BE(offset)`.
217
- *
218
- * @param bytes - Source byte array.
219
- * @param offset - Byte offset to read from.
220
- * @returns Unsigned 16-bit integer value.
221
- * @throws {RangeError} If offset is out of bounds.
222
- */
223
- export function readUint16BE(bytes, offset) {
224
- if (offset < 0 || offset + 1 >= bytes.length)
225
- throw new RangeError(`readUint16BE: offset ${offset} out of bounds for length ${bytes.length}`);
226
- return ((bytes[offset] << 8) | bytes[offset + 1]) >>> 0;
227
- }
228
- /**
229
- * Concatenate multiple Uint8Arrays into one.
230
- * Replaces `Buffer.concat([...])`.
231
- *
232
- * @param arrays - One or more Uint8Arrays to concatenate.
233
- * @returns A single Uint8Array containing all input bytes in order.
234
- */
235
- export function concatBytes(...arrays) {
236
- const total = arrays.reduce((n, a) => n + a.length, 0);
237
- const out = new Uint8Array(total);
238
- let offset = 0;
239
- for (const arr of arrays) {
240
- out.set(arr, offset);
241
- offset += arr.length;
242
- }
243
- return out;
244
- }
245
- /**
246
- * Encode a Uint8Array as a base64 string. Available in Node 16+ and all browsers.
247
- *
248
- * @param bytes - Input byte array.
249
- * @returns Base64-encoded string.
250
- */
251
- export function bytesToBase64(bytes) {
252
- let binary = '';
253
- for (let i = 0; i < bytes.length; i++)
254
- binary += String.fromCharCode(bytes[i]);
255
- return btoa(binary);
256
- }
257
- /**
258
- * Decode a base64 string to a Uint8Array.
259
- *
260
- * @param base64 - Base64-encoded string.
261
- * @returns Decoded byte array.
262
- */
263
- export function base64ToBytes(base64) {
264
- const binary = atob(base64);
265
- const bytes = new Uint8Array(binary.length);
266
- for (let i = 0; i < binary.length; i++)
267
- bytes[i] = binary.charCodeAt(i);
268
- return bytes;
269
- }
270
- /**
271
- * Best-effort constant-time comparison of two byte arrays.
272
- * Pads both arrays to equal length to avoid leaking length via timing.
273
- *
274
- * **Caveat:** JavaScript runtimes do not guarantee constant-time execution —
275
- * JIT compilation and speculative execution may introduce timing variation.
276
- * This is a defence-in-depth measure, not a cryptographic guarantee. For
277
- * high-assurance environments, pair with rate limiting and consider
278
- * platform-native constant-time primitives.
279
- *
280
- * @param a - First byte array.
281
- * @param b - Second byte array.
282
- * @returns `true` if arrays are equal in length and content, `false` otherwise.
283
- */
284
- export function timingSafeEqual(a, b) {
285
- const len = Math.max(a.length, b.length);
286
- // Pre-allocate zero-padded copies to eliminate branch in the comparison loop
287
- const paddedA = new Uint8Array(len);
288
- const paddedB = new Uint8Array(len);
289
- paddedA.set(a);
290
- paddedB.set(b);
291
- let diff = a.length ^ b.length; // non-zero if lengths differ
292
- for (let i = 0; i < len; i++) {
293
- diff |= paddedA[i] ^ paddedB[i];
294
- }
295
- return diff === 0;
296
- }
297
- const stringEncoder = new TextEncoder();
298
- /**
299
- * Best-effort constant-time comparison of two strings (UTF-8 encoded, then byte-compared).
300
- * See {@link timingSafeEqual} caveats.
301
- *
302
- * @param a - First string.
303
- * @param b - Second string.
304
- * @returns `true` if strings are equal, `false` otherwise.
305
- */
306
- export function timingSafeStringEqual(a, b) {
307
- return timingSafeEqual(stringEncoder.encode(a), stringEncoder.encode(b));
308
- }
1
+ // Re-export from spoken-token for backwards compatibility
2
+ export { sha256, hmacSha256, randomSeed, hexToBytes, bytesToHex, readUint16BE, concatBytes, bytesToBase64, base64ToBytes, timingSafeEqual, timingSafeStringEqual, } from 'spoken-token';
309
3
  //# sourceMappingURL=crypto.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,OAAO,EACL,MAAM,EAAE,UAAU,EAAE,UAAU,EAC9B,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EACjD,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,qBAAqB,GACvC,MAAM,cAAc,CAAA"}
@@ -1,56 +1,2 @@
1
- /** Encoding options for token output. */
2
- export type TokenEncoding = {
3
- format: 'words';
4
- count?: number;
5
- wordlist?: readonly string[];
6
- } | {
7
- format: 'pin';
8
- digits?: number;
9
- } | {
10
- format: 'hex';
11
- length?: number;
12
- };
13
- /** Default encoding: single word from en-v1 wordlist. */
14
- export declare const DEFAULT_ENCODING: TokenEncoding;
15
- /**
16
- * Encode raw bytes as words using 11-bit indices into a wordlist.
17
- * Each word uses a consecutive 2-byte slice: readUint16BE(bytes, i*2) % wordlistSize.
18
- *
19
- * @param bytes - Raw bytes to encode (must have at least `count * 2` bytes).
20
- * @param count - Number of words to produce (integer 1–16, default: 1).
21
- * @param wordlist - Custom wordlist (must be exactly 2048 entries, default: en-v1).
22
- * @returns Array of lowercase word strings.
23
- * @throws {RangeError} If count is not an integer 1–16, wordlist is wrong size, or insufficient bytes.
24
- */
25
- export declare function encodeAsWords(bytes: Uint8Array, count?: number, wordlist?: readonly string[]): string[];
26
- /**
27
- * Encode raw bytes as a numeric PIN with leading zeros.
28
- * Uses the first ceil(digits * 0.415) bytes, interpreted as a big-endian
29
- * integer, reduced modulo 10^digits.
30
- *
31
- * @param bytes - Raw bytes to encode (must be non-empty).
32
- * @param digits - Number of PIN digits to produce (integer 1-10, default: 4).
33
- * @returns Zero-padded numeric string of the specified length.
34
- * @throws {RangeError} If digits is not an integer 1-10 or bytes is empty.
35
- */
36
- export declare function encodeAsPin(bytes: Uint8Array, digits?: number): string;
37
- /**
38
- * Encode raw bytes as a lowercase hex string.
39
- *
40
- * @param bytes - Raw bytes to encode.
41
- * @param length - Number of hex characters to produce (integer 1-64, default: 8).
42
- * @returns Lowercase hex string of the specified length.
43
- * @throws {RangeError} If length is not an integer 1-64 or insufficient bytes are provided.
44
- */
45
- export declare function encodeAsHex(bytes: Uint8Array, length?: number): string;
46
- /**
47
- * Encode raw bytes using the specified encoding format.
48
- * Returns a single string (words are space-joined).
49
- *
50
- * @param bytes - Raw bytes to encode.
51
- * @param encoding - Encoding format: words, pin, or hex (default: single word).
52
- * @returns Encoded token string (space-joined words, zero-padded PIN, or hex).
53
- * @throws {RangeError} If encoding parameters are out of range or bytes are insufficient.
54
- */
55
- export declare function encodeToken(bytes: Uint8Array, encoding?: TokenEncoding): string;
1
+ export { encodeAsWords, encodeAsPin, encodeAsHex, encodeToken, type TokenEncoding, DEFAULT_ENCODING, } from 'spoken-token';
56
2
  //# sourceMappingURL=encoding.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../src/encoding.ts"],"names":[],"mappings":"AAGA,yCAAyC;AACzC,MAAM,MAAM,aAAa,GACrB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GACjE;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtC,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,EAAE,aAA6C,CAAA;AAE5E;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,UAAU,EACjB,KAAK,GAAE,MAAU,EACjB,QAAQ,GAAE,SAAS,MAAM,EAAa,GACrC,MAAM,EAAE,CAUV;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,GAAE,MAAU,GAAG,MAAM,CAkBzE;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,GAAE,MAAU,GAAG,MAAM,CASzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,GAAE,aAAgC,GAAG,MAAM,CASjG"}
1
+ {"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../src/encoding.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EACpD,KAAK,aAAa,EAAE,gBAAgB,GACrC,MAAM,cAAc,CAAA"}