@bcts/rand 1.0.0-alpha.21 → 1.0.0-alpha.23

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/dist/index.cjs CHANGED
@@ -1,5 +1,4 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
2
  //#region src/widening.ts
4
3
  /**
5
4
  * Performs wide multiplication for unsigned integers.
@@ -53,7 +52,6 @@ function wideMulU64(a, b) {
53
52
  const wide = (a & mask64) * (b & mask64);
54
53
  return [wide & mask64, wide >> 64n];
55
54
  }
56
-
57
55
  //#endregion
58
56
  //#region src/magnitude.ts
59
57
  /**
@@ -114,7 +112,6 @@ function fromMagnitude64(magnitude) {
114
112
  if ((maskedMag & signBit) !== 0n) return maskedMag - (1n << 64n);
115
113
  return maskedMag;
116
114
  }
117
-
118
115
  //#endregion
119
116
  //#region src/random-number-generator.ts
120
117
  /**
@@ -276,7 +273,6 @@ function rngRandomBool(rng) {
276
273
  function rngRandomU32(rng) {
277
274
  return rng.nextU32();
278
275
  }
279
-
280
276
  //#endregion
281
277
  //#region src/secure-random.ts
282
278
  /**
@@ -351,7 +347,6 @@ var SecureRandomNumberGenerator = class {
351
347
  fillRandomData(data);
352
348
  }
353
349
  };
354
-
355
350
  //#endregion
356
351
  //#region src/seeded-random.ts
357
352
  /**
@@ -484,7 +479,6 @@ function makeFakeRandomNumberGenerator() {
484
479
  function fakeRandomData(size) {
485
480
  return makeFakeRandomNumberGenerator().randomData(size);
486
481
  }
487
-
488
482
  //#endregion
489
483
  exports.SecureRandomNumberGenerator = SecureRandomNumberGenerator;
490
484
  exports.SeededRandomNumberGenerator = SeededRandomNumberGenerator;
@@ -514,4 +508,5 @@ exports.wideMulU16 = wideMulU16;
514
508
  exports.wideMulU32 = wideMulU32;
515
509
  exports.wideMulU64 = wideMulU64;
516
510
  exports.wideMulU8 = wideMulU8;
511
+
517
512
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/widening.ts","../src/magnitude.ts","../src/random-number-generator.ts","../src/secure-random.ts","../src/seeded-random.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// The below is so we don't have to use #![feature(bigint_helper_methods)]\n// Ported from bc-rand-rust/src/widening.rs\n\n/**\n * Wide multiplication result type - returns (low, high) parts.\n * For a multiplication of two N-bit values, the result is 2N bits\n * split into two N-bit parts.\n */\nexport type WideMulResult = [bigint, bigint];\n\n/**\n * Performs wide multiplication for unsigned integers.\n * Returns (low, high) parts of the full-width result.\n *\n * This is equivalent to Rust's widening_mul for unsigned types.\n */\nexport function wideMul(a: bigint, b: bigint, bits: number): WideMulResult {\n const mask = (1n << BigInt(bits)) - 1n;\n const wide = (a & mask) * (b & mask);\n const low = wide & mask;\n const high = wide >> BigInt(bits);\n return [low, high];\n}\n\n/**\n * Wide multiplication for 8-bit unsigned integers.\n * @param a - First 8-bit value\n * @param b - Second 8-bit value\n * @returns Tuple of (low 8 bits, high 8 bits)\n */\nexport function wideMulU8(a: number, b: number): [number, number] {\n const wide = (a & 0xff) * (b & 0xff);\n return [wide & 0xff, (wide >> 8) & 0xff];\n}\n\n/**\n * Wide multiplication for 16-bit unsigned integers.\n * @param a - First 16-bit value\n * @param b - Second 16-bit value\n * @returns Tuple of (low 16 bits, high 16 bits)\n */\nexport function wideMulU16(a: number, b: number): [number, number] {\n const wide = (a & 0xffff) * (b & 0xffff);\n return [wide & 0xffff, (wide >>> 16) & 0xffff];\n}\n\n/**\n * Wide multiplication for 32-bit unsigned integers.\n * @param a - First 32-bit value\n * @param b - Second 32-bit value\n * @returns Tuple of (low 32 bits, high 32 bits) as bigints\n */\nexport function wideMulU32(a: number, b: number): [bigint, bigint] {\n const aBig = BigInt(a >>> 0);\n const bBig = BigInt(b >>> 0);\n const wide = aBig * bBig;\n return [wide & 0xffffffffn, wide >> 32n];\n}\n\n/**\n * Wide multiplication for 64-bit unsigned integers.\n * @param a - First 64-bit value as bigint\n * @param b - Second 64-bit value as bigint\n * @returns Tuple of (low 64 bits, high 64 bits) as bigints\n */\nexport function wideMulU64(a: bigint, b: bigint): [bigint, bigint] {\n const mask64 = 0xffffffffffffffffn;\n const wide = (a & mask64) * (b & mask64);\n return [wide & mask64, wide >> 64n];\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/magnitude.rs\n\n/**\n * Converts a signed integer to its unsigned magnitude.\n * For positive numbers, returns the number unchanged.\n * For negative numbers, returns the absolute value (wrapping for MIN values).\n *\n * This matches Rust's wrapping_abs() behavior.\n */\nexport function toMagnitude(value: number, bits: 8 | 16 | 32): number {\n switch (bits) {\n case 8: {\n // i8 to u8: wrapping_abs\n const i8Value = (value << 24) >> 24; // Sign extend to i8\n return Math.abs(i8Value) & 0xff;\n }\n case 16: {\n // i16 to u16: wrapping_abs\n const i16Value = (value << 16) >> 16; // Sign extend to i16\n return Math.abs(i16Value) & 0xffff;\n }\n case 32: {\n // i32 to u32: wrapping_abs\n const i32Value = value | 0; // Force to i32\n // Handle MIN_VALUE specially (wrapping behavior)\n if (i32Value === -2147483648) {\n return 2147483648; // Returns as positive\n }\n return Math.abs(i32Value) >>> 0; // Convert to unsigned\n }\n }\n}\n\n/**\n * Converts a signed bigint to its unsigned magnitude for 64-bit values.\n */\nexport function toMagnitude64(value: bigint): bigint {\n const mask = 0xffffffffffffffffn;\n // Handle negative values\n if (value < 0n) {\n // Wrapping absolute value\n const absValue = -value;\n return absValue & mask;\n }\n return value & mask;\n}\n\n/**\n * Converts an unsigned magnitude back to a signed value.\n * Simply reinterprets the bits.\n */\nexport function fromMagnitude(magnitude: number, bits: 8 | 16 | 32): number {\n switch (bits) {\n case 8:\n return (magnitude << 24) >> 24; // Sign extend from u8 to i8\n case 16:\n return (magnitude << 16) >> 16; // Sign extend from u16 to i16\n case 32:\n return magnitude | 0; // Reinterpret as i32\n }\n}\n\n/**\n * Converts an unsigned 64-bit magnitude back to a signed bigint.\n */\nexport function fromMagnitude64(magnitude: bigint): bigint {\n const mask = 0xffffffffffffffffn;\n const signBit = 1n << 63n;\n const maskedMag = magnitude & mask;\n if ((maskedMag & signBit) !== 0n) {\n // Negative value - convert from two's complement\n return maskedMag - (1n << 64n);\n }\n return maskedMag;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/random_number_generator.rs\n\nimport { wideMulU32, wideMulU64 } from \"./widening.js\";\nimport {\n toMagnitude,\n toMagnitude64 as _toMagnitude64,\n fromMagnitude as _fromMagnitude,\n fromMagnitude64 as _fromMagnitude64,\n} from \"./magnitude.js\";\n\n/**\n * Interface for random number generators.\n * This is the TypeScript equivalent of Rust's RandomNumberGenerator trait\n * which extends RngCore + CryptoRng.\n *\n * This is compatible with the RandomNumberGenerator Swift protocol used\n * in MacOS and iOS, which is important for cross-platform testing.\n */\nexport interface RandomNumberGenerator {\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number;\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint;\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillBytes(dest: Uint8Array): void;\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n */\n randomData(size: number): Uint8Array;\n\n /**\n * Fills the given Uint8Array with random bytes.\n * Alias for fillBytes for compatibility.\n */\n fillRandomData(data: Uint8Array): void;\n}\n\n/**\n * Returns a Uint8Array of random bytes of the given size.\n */\nexport function rngRandomData(rng: RandomNumberGenerator, size: number): Uint8Array {\n const data = new Uint8Array(size);\n rng.fillRandomData(data);\n return data;\n}\n\n/**\n * Fills the given Uint8Array with random bytes.\n */\nexport function rngFillRandomData(rng: RandomNumberGenerator, data: Uint8Array): void {\n rng.fillRandomData(data);\n}\n\n/**\n * Returns a random value that is less than the given upper bound.\n *\n * Uses Lemire's \"nearly divisionless\" method for generating random\n * integers in an interval. For a detailed explanation, see:\n * https://arxiv.org/abs/1805.10941\n *\n * @param rng - The random number generator to use\n * @param upperBound - The upper bound for the randomly generated value. Must be non-zero.\n * @returns A random value in the range [0, upperBound). Every value in the range is equally likely.\n */\nexport function rngNextWithUpperBound(rng: RandomNumberGenerator, upperBound: bigint): bigint {\n if (upperBound === 0n) {\n throw new Error(\"upperBound must be non-zero\");\n }\n\n // We use Lemire's \"nearly divisionless\" method for generating random\n // integers in an interval. For a detailed explanation, see:\n // https://arxiv.org/abs/1805.10941\n\n const bitmask = 0xffffffffffffffffn; // u64 max\n let random = rng.nextU64() & bitmask;\n let m = wideMulU64(random, upperBound);\n\n if (m[0] < upperBound) {\n // t = (0 - upperBound) % upperBound\n const negUpperBound = (bitmask + 1n - upperBound) & bitmask;\n const t = negUpperBound % upperBound;\n while (m[0] < t) {\n random = rng.nextU64() & bitmask;\n m = wideMulU64(random, upperBound);\n }\n }\n\n return m[1];\n}\n\n/**\n * Returns a random 32-bit value that is less than the given upper bound.\n * This matches Rust's behavior when called with u32 type.\n *\n * Uses Lemire's \"nearly divisionless\" method with 32-bit arithmetic.\n *\n * @param rng - The random number generator to use\n * @param upperBound - The upper bound for the randomly generated value. Must be non-zero and fit in u32.\n * @returns A random u32 value in the range [0, upperBound).\n */\nexport function rngNextWithUpperBoundU32(rng: RandomNumberGenerator, upperBound: number): number {\n if (upperBound === 0) {\n throw new Error(\"upperBound must be non-zero\");\n }\n\n const upperBoundU32 = upperBound >>> 0;\n const bitmask = 0xffffffff;\n\n // Get random and mask to 32 bits (matches Rust behavior)\n let random = Number(rng.nextU64() & BigInt(bitmask));\n let m = wideMulU32(random, upperBoundU32);\n\n if (Number(m[0]) < upperBoundU32) {\n // t = (0 - upperBound) % upperBound (wrapping subtraction)\n const t = ((bitmask + 1 - upperBoundU32) >>> 0) % upperBoundU32;\n while (Number(m[0]) < t) {\n random = Number(rng.nextU64() & BigInt(bitmask));\n m = wideMulU32(random, upperBoundU32);\n }\n }\n\n return Number(m[1]);\n}\n\n/**\n * Returns a random value within the specified range [start, end) using 32-bit arithmetic.\n * This matches Rust's behavior when called with i32 types.\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive) as i32\n * @param end - The upper bound (exclusive) as i32\n * @returns A random i32 value within the bounds\n */\nexport function rngNextInRangeI32(rng: RandomNumberGenerator, start: number, end: number): number {\n if (start >= end) {\n throw new Error(\"start must be less than end\");\n }\n\n const startI32 = start | 0;\n const endI32 = end | 0;\n const delta = toMagnitude(endI32 - startI32, 32);\n\n if (delta === 0xffffffff) {\n return rng.nextU32() | 0;\n }\n\n const random = rngNextWithUpperBoundU32(rng, delta);\n return (startI32 + random) | 0;\n}\n\n/**\n * Returns a random value within the specified range [start, end).\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive)\n * @param end - The upper bound (exclusive)\n * @returns A random value within the bounds of the range\n */\nexport function rngNextInRange(rng: RandomNumberGenerator, start: bigint, end: bigint): bigint {\n if (start >= end) {\n throw new Error(\"start must be less than end\");\n }\n\n const delta = end - start;\n\n // If delta covers the entire range, just return a random value\n const maxU64 = 0xffffffffffffffffn;\n if (delta === maxU64) {\n return rng.nextU64();\n }\n\n const random = rngNextWithUpperBound(rng, delta);\n return start + random;\n}\n\n/**\n * Returns a random value within the specified closed range [start, end].\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive)\n * @param end - The upper bound (inclusive)\n * @returns A random value within the bounds of the range\n */\nexport function rngNextInClosedRange(\n rng: RandomNumberGenerator,\n start: bigint,\n end: bigint,\n): bigint {\n if (start > end) {\n throw new Error(\"start must be less than or equal to end\");\n }\n\n const delta = end - start;\n\n // If delta covers the entire range, just return a random value\n const maxU64 = 0xffffffffffffffffn;\n if (delta === maxU64) {\n return rng.nextU64();\n }\n\n const random = rngNextWithUpperBound(rng, delta + 1n);\n return start + random;\n}\n\n/**\n * Returns a random value within the specified closed range [start, end] for i32 values.\n * Convenience function that handles signed 32-bit integers.\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive) as i32\n * @param end - The upper bound (inclusive) as i32\n * @returns A random i32 value within the bounds of the range\n */\nexport function rngNextInClosedRangeI32(\n rng: RandomNumberGenerator,\n start: number,\n end: number,\n): number {\n if (start > end) {\n throw new Error(\"start must be less than or equal to end\");\n }\n\n // Convert to i32\n const startI32 = start | 0;\n const endI32 = end | 0;\n\n // Calculate delta as u32 magnitude\n const delta = toMagnitude(endI32 - startI32, 32);\n\n // If delta covers the entire u32 range, just return a random value\n if (delta === 0xffffffff) {\n return rng.nextU32() | 0;\n }\n\n const random = rngNextWithUpperBoundU32(rng, delta + 1);\n return (startI32 + random) | 0;\n}\n\n/**\n * Returns a fixed-size array of random bytes.\n *\n * @param rng - The random number generator to use\n * @param size - The size of the array to return\n * @returns A Uint8Array of the specified size filled with random bytes\n */\nexport function rngRandomArray(rng: RandomNumberGenerator, size: number): Uint8Array {\n const data = new Uint8Array(size);\n rng.fillRandomData(data);\n return data;\n}\n\n/**\n * Returns a random boolean value.\n *\n * @param rng - The random number generator to use\n * @returns A random boolean\n */\nexport function rngRandomBool(rng: RandomNumberGenerator): boolean {\n return (rng.nextU32() & 1) === 0;\n}\n\n/**\n * Returns a random 32-bit unsigned integer.\n *\n * @param rng - The random number generator to use\n * @returns A random u32 value\n */\nexport function rngRandomU32(rng: RandomNumberGenerator): number {\n return rng.nextU32();\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/secure_random.rs\n\nimport type { RandomNumberGenerator } from \"./random-number-generator.js\";\n\n/**\n * Detects the crypto API available in the current environment.\n * Works in both Node.js and browser environments.\n */\nfunction getCrypto(): Crypto {\n // Browser environment\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.crypto !== null &&\n globalThis.crypto !== undefined\n ) {\n return globalThis.crypto;\n }\n // Node.js environment - globalThis.crypto is also available in Node.js >= 15\n if (typeof globalThis.crypto !== \"undefined\") {\n return globalThis.crypto;\n }\n throw new Error(\"No crypto API available in this environment\");\n}\n\n/**\n * Generate a Uint8Array of cryptographically strong random bytes of the given size.\n */\nexport function randomData(size: number): Uint8Array {\n const data = new Uint8Array(size);\n fillRandomData(data);\n return data;\n}\n\n/**\n * Fill the given Uint8Array with cryptographically strong random bytes.\n */\nexport function fillRandomData(data: Uint8Array): void {\n const crypto = getCrypto();\n crypto.getRandomValues(data);\n}\n\n/**\n * Returns the next cryptographically strong random 64-bit unsigned integer.\n */\nexport function nextU64(): bigint {\n const data = new Uint8Array(8);\n fillRandomData(data);\n const view = new DataView(data.buffer);\n return view.getBigUint64(0, true); // little-endian\n}\n\n/**\n * A random number generator that can be used as a source of\n * cryptographically-strong randomness.\n *\n * Uses the Web Crypto API (crypto.getRandomValues) which is available\n * in both browsers and Node.js >= 15.\n */\nexport class SecureRandomNumberGenerator implements RandomNumberGenerator {\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number {\n const data = new Uint8Array(4);\n fillRandomData(data);\n const view = new DataView(data.buffer);\n return view.getUint32(0, true) >>> 0; // little-endian, unsigned\n }\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint {\n return nextU64();\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillBytes(dest: Uint8Array): void {\n fillRandomData(dest);\n }\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n */\n randomData(size: number): Uint8Array {\n return randomData(size);\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillRandomData(data: Uint8Array): void {\n fillRandomData(data);\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/seeded_random.rs\n\nimport type { RandomNumberGenerator } from \"./random-number-generator.js\";\n\n/**\n * Xoshiro256** state\n * Based on xoshiro256** 1.0 by David Blackman and Sebastiano Vigna\n * https://prng.di.unimi.it/\n */\ninterface Xoshiro256State {\n s0: bigint;\n s1: bigint;\n s2: bigint;\n s3: bigint;\n}\n\n/**\n * Rotate left for 64-bit bigint\n */\nfunction rotl(x: bigint, k: number): bigint {\n const mask = 0xffffffffffffffffn;\n return ((x << BigInt(k)) | (x >> BigInt(64 - k))) & mask;\n}\n\n/**\n * Xoshiro256** PRNG implementation\n * This is the same algorithm used by rand_xoshiro in Rust\n */\nfunction xoshiro256StarStar(state: Xoshiro256State): bigint {\n const mask = 0xffffffffffffffffn;\n\n // result = rotl(s1 * 5, 7) * 9\n const result = (rotl((state.s1 * 5n) & mask, 7) * 9n) & mask;\n\n // t = s1 << 17\n const t = (state.s1 << 17n) & mask;\n\n // Update state\n state.s2 ^= state.s0;\n state.s3 ^= state.s1;\n state.s1 ^= state.s2;\n state.s0 ^= state.s3;\n\n state.s2 ^= t;\n state.s3 = rotl(state.s3, 45);\n\n return result;\n}\n\n/**\n * A random number generator that can be used as a source of deterministic\n * pseudo-randomness for testing purposes.\n *\n * Uses the Xoshiro256** algorithm, which is the same algorithm used by\n * rand_xoshiro in Rust. This ensures cross-platform compatibility with\n * the Rust implementation.\n *\n * WARNING: This is NOT cryptographically secure and should only be used\n * for testing purposes.\n */\nexport class SeededRandomNumberGenerator implements RandomNumberGenerator {\n private readonly state: Xoshiro256State;\n\n /**\n * Creates a new seeded random number generator.\n *\n * The seed should be a 256-bit value, represented as an array of 4 64-bit\n * integers (as bigints). For the output distribution to look random, the seed\n * should not have any obvious patterns, like all zeroes or all ones.\n *\n * This is not cryptographically secure, and should only be used for\n * testing purposes.\n *\n * @param seed - Array of 4 64-bit unsigned integers as bigints\n */\n constructor(seed: [bigint, bigint, bigint, bigint]) {\n this.state = {\n s0: seed[0] & 0xffffffffffffffffn,\n s1: seed[1] & 0xffffffffffffffffn,\n s2: seed[2] & 0xffffffffffffffffn,\n s3: seed[3] & 0xffffffffffffffffn,\n };\n }\n\n /**\n * Creates a new seeded random number generator from a seed array.\n * Convenience method that accepts numbers and converts to bigints.\n *\n * @param seed - Array of 4 64-bit unsigned integers\n */\n static fromSeed(seed: [bigint, bigint, bigint, bigint]): SeededRandomNumberGenerator {\n return new SeededRandomNumberGenerator(seed);\n }\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint {\n return xoshiro256StarStar(this.state);\n }\n\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number {\n return Number(this.nextU64() & 0xffffffffn) >>> 0;\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n *\n * Note: This implementation matches the Rust behavior exactly -\n * it uses one nextU64() call per byte (taking only the low byte),\n * which matches the Swift version's behavior.\n */\n fillBytes(dest: Uint8Array): void {\n for (let i = 0; i < dest.length; i++) {\n dest[i] = Number(this.nextU64() & 0xffn);\n }\n }\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n *\n * This might not be the most efficient implementation,\n * but it works the same as the Swift version.\n */\n randomData(size: number): Uint8Array {\n const data = new Uint8Array(size);\n for (let i = 0; i < size; i++) {\n data[i] = Number(this.nextU64() & 0xffn);\n }\n return data;\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillRandomData(data: Uint8Array): void {\n this.fillBytes(data);\n }\n}\n\n/**\n * The standard test seed used across all Blockchain Commons implementations.\n */\nexport const TEST_SEED: [bigint, bigint, bigint, bigint] = [\n 17295166580085024720n,\n 422929670265678780n,\n 5577237070365765850n,\n 7953171132032326923n,\n];\n\n/**\n * Creates a seeded random number generator with a fixed seed.\n * This is useful for reproducible testing across different platforms.\n */\nexport function makeFakeRandomNumberGenerator(): SeededRandomNumberGenerator {\n return new SeededRandomNumberGenerator(TEST_SEED);\n}\n\n/**\n * Creates a Uint8Array of random data with a fixed seed.\n * This is useful for reproducible testing.\n *\n * @param size - The number of bytes to generate\n * @returns A Uint8Array of pseudo-random bytes\n */\nexport function fakeRandomData(size: number): Uint8Array {\n return makeFakeRandomNumberGenerator().randomData(size);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/widening.ts","../src/magnitude.ts","../src/random-number-generator.ts","../src/secure-random.ts","../src/seeded-random.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// The below is so we don't have to use #![feature(bigint_helper_methods)]\n// Ported from bc-rand-rust/src/widening.rs\n\n/**\n * Wide multiplication result type - returns (low, high) parts.\n * For a multiplication of two N-bit values, the result is 2N bits\n * split into two N-bit parts.\n */\nexport type WideMulResult = [bigint, bigint];\n\n/**\n * Performs wide multiplication for unsigned integers.\n * Returns (low, high) parts of the full-width result.\n *\n * This is equivalent to Rust's widening_mul for unsigned types.\n */\nexport function wideMul(a: bigint, b: bigint, bits: number): WideMulResult {\n const mask = (1n << BigInt(bits)) - 1n;\n const wide = (a & mask) * (b & mask);\n const low = wide & mask;\n const high = wide >> BigInt(bits);\n return [low, high];\n}\n\n/**\n * Wide multiplication for 8-bit unsigned integers.\n * @param a - First 8-bit value\n * @param b - Second 8-bit value\n * @returns Tuple of (low 8 bits, high 8 bits)\n */\nexport function wideMulU8(a: number, b: number): [number, number] {\n const wide = (a & 0xff) * (b & 0xff);\n return [wide & 0xff, (wide >> 8) & 0xff];\n}\n\n/**\n * Wide multiplication for 16-bit unsigned integers.\n * @param a - First 16-bit value\n * @param b - Second 16-bit value\n * @returns Tuple of (low 16 bits, high 16 bits)\n */\nexport function wideMulU16(a: number, b: number): [number, number] {\n const wide = (a & 0xffff) * (b & 0xffff);\n return [wide & 0xffff, (wide >>> 16) & 0xffff];\n}\n\n/**\n * Wide multiplication for 32-bit unsigned integers.\n * @param a - First 32-bit value\n * @param b - Second 32-bit value\n * @returns Tuple of (low 32 bits, high 32 bits) as bigints\n */\nexport function wideMulU32(a: number, b: number): [bigint, bigint] {\n const aBig = BigInt(a >>> 0);\n const bBig = BigInt(b >>> 0);\n const wide = aBig * bBig;\n return [wide & 0xffffffffn, wide >> 32n];\n}\n\n/**\n * Wide multiplication for 64-bit unsigned integers.\n * @param a - First 64-bit value as bigint\n * @param b - Second 64-bit value as bigint\n * @returns Tuple of (low 64 bits, high 64 bits) as bigints\n */\nexport function wideMulU64(a: bigint, b: bigint): [bigint, bigint] {\n const mask64 = 0xffffffffffffffffn;\n const wide = (a & mask64) * (b & mask64);\n return [wide & mask64, wide >> 64n];\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/magnitude.rs\n\n/**\n * Converts a signed integer to its unsigned magnitude.\n * For positive numbers, returns the number unchanged.\n * For negative numbers, returns the absolute value (wrapping for MIN values).\n *\n * This matches Rust's wrapping_abs() behavior.\n */\nexport function toMagnitude(value: number, bits: 8 | 16 | 32): number {\n switch (bits) {\n case 8: {\n // i8 to u8: wrapping_abs\n const i8Value = (value << 24) >> 24; // Sign extend to i8\n return Math.abs(i8Value) & 0xff;\n }\n case 16: {\n // i16 to u16: wrapping_abs\n const i16Value = (value << 16) >> 16; // Sign extend to i16\n return Math.abs(i16Value) & 0xffff;\n }\n case 32: {\n // i32 to u32: wrapping_abs\n const i32Value = value | 0; // Force to i32\n // Handle MIN_VALUE specially (wrapping behavior)\n if (i32Value === -2147483648) {\n return 2147483648; // Returns as positive\n }\n return Math.abs(i32Value) >>> 0; // Convert to unsigned\n }\n }\n}\n\n/**\n * Converts a signed bigint to its unsigned magnitude for 64-bit values.\n */\nexport function toMagnitude64(value: bigint): bigint {\n const mask = 0xffffffffffffffffn;\n // Handle negative values\n if (value < 0n) {\n // Wrapping absolute value\n const absValue = -value;\n return absValue & mask;\n }\n return value & mask;\n}\n\n/**\n * Converts an unsigned magnitude back to a signed value.\n * Simply reinterprets the bits.\n */\nexport function fromMagnitude(magnitude: number, bits: 8 | 16 | 32): number {\n switch (bits) {\n case 8:\n return (magnitude << 24) >> 24; // Sign extend from u8 to i8\n case 16:\n return (magnitude << 16) >> 16; // Sign extend from u16 to i16\n case 32:\n return magnitude | 0; // Reinterpret as i32\n }\n}\n\n/**\n * Converts an unsigned 64-bit magnitude back to a signed bigint.\n */\nexport function fromMagnitude64(magnitude: bigint): bigint {\n const mask = 0xffffffffffffffffn;\n const signBit = 1n << 63n;\n const maskedMag = magnitude & mask;\n if ((maskedMag & signBit) !== 0n) {\n // Negative value - convert from two's complement\n return maskedMag - (1n << 64n);\n }\n return maskedMag;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/random_number_generator.rs\n\nimport { wideMulU32, wideMulU64 } from \"./widening.js\";\nimport {\n toMagnitude,\n toMagnitude64 as _toMagnitude64,\n fromMagnitude as _fromMagnitude,\n fromMagnitude64 as _fromMagnitude64,\n} from \"./magnitude.js\";\n\n/**\n * Interface for random number generators.\n * This is the TypeScript equivalent of Rust's RandomNumberGenerator trait\n * which extends RngCore + CryptoRng.\n *\n * This is compatible with the RandomNumberGenerator Swift protocol used\n * in MacOS and iOS, which is important for cross-platform testing.\n */\nexport interface RandomNumberGenerator {\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number;\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint;\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillBytes(dest: Uint8Array): void;\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n */\n randomData(size: number): Uint8Array;\n\n /**\n * Fills the given Uint8Array with random bytes.\n * Alias for fillBytes for compatibility.\n */\n fillRandomData(data: Uint8Array): void;\n}\n\n/**\n * Returns a Uint8Array of random bytes of the given size.\n */\nexport function rngRandomData(rng: RandomNumberGenerator, size: number): Uint8Array {\n const data = new Uint8Array(size);\n rng.fillRandomData(data);\n return data;\n}\n\n/**\n * Fills the given Uint8Array with random bytes.\n */\nexport function rngFillRandomData(rng: RandomNumberGenerator, data: Uint8Array): void {\n rng.fillRandomData(data);\n}\n\n/**\n * Returns a random value that is less than the given upper bound.\n *\n * Uses Lemire's \"nearly divisionless\" method for generating random\n * integers in an interval. For a detailed explanation, see:\n * https://arxiv.org/abs/1805.10941\n *\n * @param rng - The random number generator to use\n * @param upperBound - The upper bound for the randomly generated value. Must be non-zero.\n * @returns A random value in the range [0, upperBound). Every value in the range is equally likely.\n */\nexport function rngNextWithUpperBound(rng: RandomNumberGenerator, upperBound: bigint): bigint {\n if (upperBound === 0n) {\n throw new Error(\"upperBound must be non-zero\");\n }\n\n // We use Lemire's \"nearly divisionless\" method for generating random\n // integers in an interval. For a detailed explanation, see:\n // https://arxiv.org/abs/1805.10941\n\n const bitmask = 0xffffffffffffffffn; // u64 max\n let random = rng.nextU64() & bitmask;\n let m = wideMulU64(random, upperBound);\n\n if (m[0] < upperBound) {\n // t = (0 - upperBound) % upperBound\n const negUpperBound = (bitmask + 1n - upperBound) & bitmask;\n const t = negUpperBound % upperBound;\n while (m[0] < t) {\n random = rng.nextU64() & bitmask;\n m = wideMulU64(random, upperBound);\n }\n }\n\n return m[1];\n}\n\n/**\n * Returns a random 32-bit value that is less than the given upper bound.\n * This matches Rust's behavior when called with u32 type.\n *\n * Uses Lemire's \"nearly divisionless\" method with 32-bit arithmetic.\n *\n * @param rng - The random number generator to use\n * @param upperBound - The upper bound for the randomly generated value. Must be non-zero and fit in u32.\n * @returns A random u32 value in the range [0, upperBound).\n */\nexport function rngNextWithUpperBoundU32(rng: RandomNumberGenerator, upperBound: number): number {\n if (upperBound === 0) {\n throw new Error(\"upperBound must be non-zero\");\n }\n\n const upperBoundU32 = upperBound >>> 0;\n const bitmask = 0xffffffff;\n\n // Get random and mask to 32 bits (matches Rust behavior)\n let random = Number(rng.nextU64() & BigInt(bitmask));\n let m = wideMulU32(random, upperBoundU32);\n\n if (Number(m[0]) < upperBoundU32) {\n // t = (0 - upperBound) % upperBound (wrapping subtraction)\n const t = ((bitmask + 1 - upperBoundU32) >>> 0) % upperBoundU32;\n while (Number(m[0]) < t) {\n random = Number(rng.nextU64() & BigInt(bitmask));\n m = wideMulU32(random, upperBoundU32);\n }\n }\n\n return Number(m[1]);\n}\n\n/**\n * Returns a random value within the specified range [start, end) using 32-bit arithmetic.\n * This matches Rust's behavior when called with i32 types.\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive) as i32\n * @param end - The upper bound (exclusive) as i32\n * @returns A random i32 value within the bounds\n */\nexport function rngNextInRangeI32(rng: RandomNumberGenerator, start: number, end: number): number {\n if (start >= end) {\n throw new Error(\"start must be less than end\");\n }\n\n const startI32 = start | 0;\n const endI32 = end | 0;\n const delta = toMagnitude(endI32 - startI32, 32);\n\n if (delta === 0xffffffff) {\n return rng.nextU32() | 0;\n }\n\n const random = rngNextWithUpperBoundU32(rng, delta);\n return (startI32 + random) | 0;\n}\n\n/**\n * Returns a random value within the specified range [start, end).\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive)\n * @param end - The upper bound (exclusive)\n * @returns A random value within the bounds of the range\n */\nexport function rngNextInRange(rng: RandomNumberGenerator, start: bigint, end: bigint): bigint {\n if (start >= end) {\n throw new Error(\"start must be less than end\");\n }\n\n const delta = end - start;\n\n // If delta covers the entire range, just return a random value\n const maxU64 = 0xffffffffffffffffn;\n if (delta === maxU64) {\n return rng.nextU64();\n }\n\n const random = rngNextWithUpperBound(rng, delta);\n return start + random;\n}\n\n/**\n * Returns a random value within the specified closed range [start, end].\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive)\n * @param end - The upper bound (inclusive)\n * @returns A random value within the bounds of the range\n */\nexport function rngNextInClosedRange(\n rng: RandomNumberGenerator,\n start: bigint,\n end: bigint,\n): bigint {\n if (start > end) {\n throw new Error(\"start must be less than or equal to end\");\n }\n\n const delta = end - start;\n\n // If delta covers the entire range, just return a random value\n const maxU64 = 0xffffffffffffffffn;\n if (delta === maxU64) {\n return rng.nextU64();\n }\n\n const random = rngNextWithUpperBound(rng, delta + 1n);\n return start + random;\n}\n\n/**\n * Returns a random value within the specified closed range [start, end] for i32 values.\n * Convenience function that handles signed 32-bit integers.\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive) as i32\n * @param end - The upper bound (inclusive) as i32\n * @returns A random i32 value within the bounds of the range\n */\nexport function rngNextInClosedRangeI32(\n rng: RandomNumberGenerator,\n start: number,\n end: number,\n): number {\n if (start > end) {\n throw new Error(\"start must be less than or equal to end\");\n }\n\n // Convert to i32\n const startI32 = start | 0;\n const endI32 = end | 0;\n\n // Calculate delta as u32 magnitude\n const delta = toMagnitude(endI32 - startI32, 32);\n\n // If delta covers the entire u32 range, just return a random value\n if (delta === 0xffffffff) {\n return rng.nextU32() | 0;\n }\n\n const random = rngNextWithUpperBoundU32(rng, delta + 1);\n return (startI32 + random) | 0;\n}\n\n/**\n * Returns a fixed-size array of random bytes.\n *\n * @param rng - The random number generator to use\n * @param size - The size of the array to return\n * @returns A Uint8Array of the specified size filled with random bytes\n */\nexport function rngRandomArray(rng: RandomNumberGenerator, size: number): Uint8Array {\n const data = new Uint8Array(size);\n rng.fillRandomData(data);\n return data;\n}\n\n/**\n * Returns a random boolean value.\n *\n * @param rng - The random number generator to use\n * @returns A random boolean\n */\nexport function rngRandomBool(rng: RandomNumberGenerator): boolean {\n return (rng.nextU32() & 1) === 0;\n}\n\n/**\n * Returns a random 32-bit unsigned integer.\n *\n * @param rng - The random number generator to use\n * @returns A random u32 value\n */\nexport function rngRandomU32(rng: RandomNumberGenerator): number {\n return rng.nextU32();\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/secure_random.rs\n\nimport type { RandomNumberGenerator } from \"./random-number-generator.js\";\n\n/**\n * Detects the crypto API available in the current environment.\n * Works in both Node.js and browser environments.\n */\nfunction getCrypto(): Crypto {\n // Browser environment\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.crypto !== null &&\n globalThis.crypto !== undefined\n ) {\n return globalThis.crypto;\n }\n // Node.js environment - globalThis.crypto is also available in Node.js >= 15\n if (typeof globalThis.crypto !== \"undefined\") {\n return globalThis.crypto;\n }\n throw new Error(\"No crypto API available in this environment\");\n}\n\n/**\n * Generate a Uint8Array of cryptographically strong random bytes of the given size.\n */\nexport function randomData(size: number): Uint8Array {\n const data = new Uint8Array(size);\n fillRandomData(data);\n return data;\n}\n\n/**\n * Fill the given Uint8Array with cryptographically strong random bytes.\n */\nexport function fillRandomData(data: Uint8Array): void {\n const crypto = getCrypto();\n crypto.getRandomValues(data as Uint8Array<ArrayBuffer>);\n}\n\n/**\n * Returns the next cryptographically strong random 64-bit unsigned integer.\n */\nexport function nextU64(): bigint {\n const data = new Uint8Array(8);\n fillRandomData(data);\n const view = new DataView(data.buffer);\n return view.getBigUint64(0, true); // little-endian\n}\n\n/**\n * A random number generator that can be used as a source of\n * cryptographically-strong randomness.\n *\n * Uses the Web Crypto API (crypto.getRandomValues) which is available\n * in both browsers and Node.js >= 15.\n */\nexport class SecureRandomNumberGenerator implements RandomNumberGenerator {\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number {\n const data = new Uint8Array(4);\n fillRandomData(data);\n const view = new DataView(data.buffer);\n return view.getUint32(0, true) >>> 0; // little-endian, unsigned\n }\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint {\n return nextU64();\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillBytes(dest: Uint8Array): void {\n fillRandomData(dest);\n }\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n */\n randomData(size: number): Uint8Array {\n return randomData(size);\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillRandomData(data: Uint8Array): void {\n fillRandomData(data);\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/seeded_random.rs\n\nimport type { RandomNumberGenerator } from \"./random-number-generator.js\";\n\n/**\n * Xoshiro256** state\n * Based on xoshiro256** 1.0 by David Blackman and Sebastiano Vigna\n * https://prng.di.unimi.it/\n */\ninterface Xoshiro256State {\n s0: bigint;\n s1: bigint;\n s2: bigint;\n s3: bigint;\n}\n\n/**\n * Rotate left for 64-bit bigint\n */\nfunction rotl(x: bigint, k: number): bigint {\n const mask = 0xffffffffffffffffn;\n return ((x << BigInt(k)) | (x >> BigInt(64 - k))) & mask;\n}\n\n/**\n * Xoshiro256** PRNG implementation\n * This is the same algorithm used by rand_xoshiro in Rust\n */\nfunction xoshiro256StarStar(state: Xoshiro256State): bigint {\n const mask = 0xffffffffffffffffn;\n\n // result = rotl(s1 * 5, 7) * 9\n const result = (rotl((state.s1 * 5n) & mask, 7) * 9n) & mask;\n\n // t = s1 << 17\n const t = (state.s1 << 17n) & mask;\n\n // Update state\n state.s2 ^= state.s0;\n state.s3 ^= state.s1;\n state.s1 ^= state.s2;\n state.s0 ^= state.s3;\n\n state.s2 ^= t;\n state.s3 = rotl(state.s3, 45);\n\n return result;\n}\n\n/**\n * A random number generator that can be used as a source of deterministic\n * pseudo-randomness for testing purposes.\n *\n * Uses the Xoshiro256** algorithm, which is the same algorithm used by\n * rand_xoshiro in Rust. This ensures cross-platform compatibility with\n * the Rust implementation.\n *\n * WARNING: This is NOT cryptographically secure and should only be used\n * for testing purposes.\n */\nexport class SeededRandomNumberGenerator implements RandomNumberGenerator {\n private readonly state: Xoshiro256State;\n\n /**\n * Creates a new seeded random number generator.\n *\n * The seed should be a 256-bit value, represented as an array of 4 64-bit\n * integers (as bigints). For the output distribution to look random, the seed\n * should not have any obvious patterns, like all zeroes or all ones.\n *\n * This is not cryptographically secure, and should only be used for\n * testing purposes.\n *\n * @param seed - Array of 4 64-bit unsigned integers as bigints\n */\n constructor(seed: [bigint, bigint, bigint, bigint]) {\n this.state = {\n s0: seed[0] & 0xffffffffffffffffn,\n s1: seed[1] & 0xffffffffffffffffn,\n s2: seed[2] & 0xffffffffffffffffn,\n s3: seed[3] & 0xffffffffffffffffn,\n };\n }\n\n /**\n * Creates a new seeded random number generator from a seed array.\n * Convenience method that accepts numbers and converts to bigints.\n *\n * @param seed - Array of 4 64-bit unsigned integers\n */\n static fromSeed(seed: [bigint, bigint, bigint, bigint]): SeededRandomNumberGenerator {\n return new SeededRandomNumberGenerator(seed);\n }\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint {\n return xoshiro256StarStar(this.state);\n }\n\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number {\n return Number(this.nextU64() & 0xffffffffn) >>> 0;\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n *\n * Note: This implementation matches the Rust behavior exactly -\n * it uses one nextU64() call per byte (taking only the low byte),\n * which matches the Swift version's behavior.\n */\n fillBytes(dest: Uint8Array): void {\n for (let i = 0; i < dest.length; i++) {\n dest[i] = Number(this.nextU64() & 0xffn);\n }\n }\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n *\n * This might not be the most efficient implementation,\n * but it works the same as the Swift version.\n */\n randomData(size: number): Uint8Array {\n const data = new Uint8Array(size);\n for (let i = 0; i < size; i++) {\n data[i] = Number(this.nextU64() & 0xffn);\n }\n return data;\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillRandomData(data: Uint8Array): void {\n this.fillBytes(data);\n }\n}\n\n/**\n * The standard test seed used across all Blockchain Commons implementations.\n */\nexport const TEST_SEED: [bigint, bigint, bigint, bigint] = [\n 17295166580085024720n,\n 422929670265678780n,\n 5577237070365765850n,\n 7953171132032326923n,\n];\n\n/**\n * Creates a seeded random number generator with a fixed seed.\n * This is useful for reproducible testing across different platforms.\n */\nexport function makeFakeRandomNumberGenerator(): SeededRandomNumberGenerator {\n return new SeededRandomNumberGenerator(TEST_SEED);\n}\n\n/**\n * Creates a Uint8Array of random data with a fixed seed.\n * This is useful for reproducible testing.\n *\n * @param size - The number of bytes to generate\n * @returns A Uint8Array of pseudo-random bytes\n */\nexport function fakeRandomData(size: number): Uint8Array {\n return makeFakeRandomNumberGenerator().randomData(size);\n}\n"],"mappings":";;;;;;;;AAsBA,SAAgB,QAAQ,GAAW,GAAW,MAA6B;CACzE,MAAM,QAAQ,MAAM,OAAO,KAAK,IAAI;CACpC,MAAM,QAAQ,IAAI,SAAS,IAAI;AAG/B,QAAO,CAFK,OAAO,MACN,QAAQ,OAAO,KAAK,CACf;;;;;;;;AASpB,SAAgB,UAAU,GAAW,GAA6B;CAChE,MAAM,QAAQ,IAAI,QAAS,IAAI;AAC/B,QAAO,CAAC,OAAO,KAAO,QAAQ,IAAK,IAAK;;;;;;;;AAS1C,SAAgB,WAAW,GAAW,GAA6B;CACjE,MAAM,QAAQ,IAAI,UAAW,IAAI;AACjC,QAAO,CAAC,OAAO,OAAS,SAAS,KAAM,MAAO;;;;;;;;AAShD,SAAgB,WAAW,GAAW,GAA6B;CAGjE,MAAM,OAFO,OAAO,MAAM,EAET,GADJ,OAAO,MAAM,EACF;AACxB,QAAO,CAAC,OAAO,aAAa,QAAQ,IAAI;;;;;;;;AAS1C,SAAgB,WAAW,GAAW,GAA6B;CACjE,MAAM,SAAS;CACf,MAAM,QAAQ,IAAI,WAAW,IAAI;AACjC,QAAO,CAAC,OAAO,QAAQ,QAAQ,IAAI;;;;;;;;;;;;;;;;AC3DrC,SAAgB,YAAY,OAAe,MAA2B;AACpE,SAAQ,MAAR;EACE,KAAK,GAAG;GAEN,MAAM,UAAW,SAAS,MAAO;AACjC,UAAO,KAAK,IAAI,QAAQ,GAAG;;EAE7B,KAAK,IAAI;GAEP,MAAM,WAAY,SAAS,MAAO;AAClC,UAAO,KAAK,IAAI,SAAS,GAAG;;EAE9B,KAAK,IAAI;GAEP,MAAM,WAAW,QAAQ;AAEzB,OAAI,aAAa,YACf,QAAO;AAET,UAAO,KAAK,IAAI,SAAS,KAAK;;;;;;;AAQpC,SAAgB,cAAc,OAAuB;CACnD,MAAM,OAAO;AAEb,KAAI,QAAQ,GAGV,QAAO,CADW,QACA;AAEpB,QAAO,QAAQ;;;;;;AAOjB,SAAgB,cAAc,WAAmB,MAA2B;AAC1E,SAAQ,MAAR;EACE,KAAK,EACH,QAAQ,aAAa,MAAO;EAC9B,KAAK,GACH,QAAQ,aAAa,MAAO;EAC9B,KAAK,GACH,QAAO,YAAY;;;;;;AAOzB,SAAgB,gBAAgB,WAA2B;CACzD,MAAM,OAAO;CACb,MAAM,UAAU,MAAM;CACtB,MAAM,YAAY,YAAY;AAC9B,MAAK,YAAY,aAAa,GAE5B,QAAO,aAAa,MAAM;AAE5B,QAAO;;;;;;;;;;;;ACxBT,SAAgB,cAAc,KAA4B,MAA0B;CAClF,MAAM,OAAO,IAAI,WAAW,KAAK;AACjC,KAAI,eAAe,KAAK;AACxB,QAAO;;;;;AAMT,SAAgB,kBAAkB,KAA4B,MAAwB;AACpF,KAAI,eAAe,KAAK;;;;;;;;;;;;;AAc1B,SAAgB,sBAAsB,KAA4B,YAA4B;AAC5F,KAAI,eAAe,GACjB,OAAM,IAAI,MAAM,8BAA8B;CAOhD,MAAM,UAAU;CAChB,IAAI,SAAS,IAAI,SAAS,GAAG;CAC7B,IAAI,IAAI,WAAW,QAAQ,WAAW;AAEtC,KAAI,EAAE,KAAK,YAAY;EAGrB,MAAM,KADiB,UAAU,KAAK,aAAc,WAC1B;AAC1B,SAAO,EAAE,KAAK,GAAG;AACf,YAAS,IAAI,SAAS,GAAG;AACzB,OAAI,WAAW,QAAQ,WAAW;;;AAItC,QAAO,EAAE;;;;;;;;;;;;AAaX,SAAgB,yBAAyB,KAA4B,YAA4B;AAC/F,KAAI,eAAe,EACjB,OAAM,IAAI,MAAM,8BAA8B;CAGhD,MAAM,gBAAgB,eAAe;CACrC,MAAM,UAAU;CAGhB,IAAI,SAAS,OAAO,IAAI,SAAS,GAAG,OAAO,QAAQ,CAAC;CACpD,IAAI,IAAI,WAAW,QAAQ,cAAc;AAEzC,KAAI,OAAO,EAAE,GAAG,GAAG,eAAe;EAEhC,MAAM,KAAM,UAAU,IAAI,kBAAmB,KAAK;AAClD,SAAO,OAAO,EAAE,GAAG,GAAG,GAAG;AACvB,YAAS,OAAO,IAAI,SAAS,GAAG,OAAO,QAAQ,CAAC;AAChD,OAAI,WAAW,QAAQ,cAAc;;;AAIzC,QAAO,OAAO,EAAE,GAAG;;;;;;;;;;;AAYrB,SAAgB,kBAAkB,KAA4B,OAAe,KAAqB;AAChG,KAAI,SAAS,IACX,OAAM,IAAI,MAAM,8BAA8B;CAGhD,MAAM,WAAW,QAAQ;CAEzB,MAAM,QAAQ,aADC,MAAM,KACc,UAAU,GAAG;AAEhD,KAAI,UAAU,WACZ,QAAO,IAAI,SAAS,GAAG;AAIzB,QAAQ,WADO,yBAAyB,KAAK,MACpB,GAAI;;;;;;;;;;AAW/B,SAAgB,eAAe,KAA4B,OAAe,KAAqB;AAC7F,KAAI,SAAS,IACX,OAAM,IAAI,MAAM,8BAA8B;CAGhD,MAAM,QAAQ,MAAM;AAIpB,KAAI,UAAU,sBACZ,QAAO,IAAI,SAAS;AAItB,QAAO,QADQ,sBAAsB,KAAK,MACrB;;;;;;;;;;AAWvB,SAAgB,qBACd,KACA,OACA,KACQ;AACR,KAAI,QAAQ,IACV,OAAM,IAAI,MAAM,0CAA0C;CAG5D,MAAM,QAAQ,MAAM;AAIpB,KAAI,UAAU,sBACZ,QAAO,IAAI,SAAS;AAItB,QAAO,QADQ,sBAAsB,KAAK,QAAQ,GAC7B;;;;;;;;;;;AAYvB,SAAgB,wBACd,KACA,OACA,KACQ;AACR,KAAI,QAAQ,IACV,OAAM,IAAI,MAAM,0CAA0C;CAI5D,MAAM,WAAW,QAAQ;CAIzB,MAAM,QAAQ,aAHC,MAAM,KAGc,UAAU,GAAG;AAGhD,KAAI,UAAU,WACZ,QAAO,IAAI,SAAS,GAAG;AAIzB,QAAQ,WADO,yBAAyB,KAAK,QAAQ,EAC5B,GAAI;;;;;;;;;AAU/B,SAAgB,eAAe,KAA4B,MAA0B;CACnF,MAAM,OAAO,IAAI,WAAW,KAAK;AACjC,KAAI,eAAe,KAAK;AACxB,QAAO;;;;;;;;AAST,SAAgB,cAAc,KAAqC;AACjE,SAAQ,IAAI,SAAS,GAAG,OAAO;;;;;;;;AASjC,SAAgB,aAAa,KAAoC;AAC/D,QAAO,IAAI,SAAS;;;;;;;;AC7QtB,SAAS,YAAoB;AAE3B,KACE,OAAO,eAAe,eACtB,WAAW,WAAW,QACtB,WAAW,WAAW,KAAA,EAEtB,QAAO,WAAW;AAGpB,KAAI,OAAO,WAAW,WAAW,YAC/B,QAAO,WAAW;AAEpB,OAAM,IAAI,MAAM,8CAA8C;;;;;AAMhE,SAAgB,WAAW,MAA0B;CACnD,MAAM,OAAO,IAAI,WAAW,KAAK;AACjC,gBAAe,KAAK;AACpB,QAAO;;;;;AAMT,SAAgB,eAAe,MAAwB;AACtC,YACT,CAAC,gBAAgB,KAAgC;;;;;AAMzD,SAAgB,UAAkB;CAChC,MAAM,OAAO,IAAI,WAAW,EAAE;AAC9B,gBAAe,KAAK;AAEpB,QAAO,IADU,SAAS,KAAK,OACpB,CAAC,aAAa,GAAG,KAAK;;;;;;;;;AAUnC,IAAa,8BAAb,MAA0E;;;;CAIxE,UAAkB;EAChB,MAAM,OAAO,IAAI,WAAW,EAAE;AAC9B,iBAAe,KAAK;AAEpB,SAAO,IADU,SAAS,KAAK,OACpB,CAAC,UAAU,GAAG,KAAK,KAAK;;;;;CAMrC,UAAkB;AAChB,SAAO,SAAS;;;;;CAMlB,UAAU,MAAwB;AAChC,iBAAe,KAAK;;;;;CAMtB,WAAW,MAA0B;AACnC,SAAO,WAAW,KAAK;;;;;CAMzB,eAAe,MAAwB;AACrC,iBAAe,KAAK;;;;;;;;AC3ExB,SAAS,KAAK,GAAW,GAAmB;AAE1C,SAAS,KAAK,OAAO,EAAE,GAAK,KAAK,OAAO,KAAK,EAAE,IAAK;;;;;;AAOtD,SAAS,mBAAmB,OAAgC;CAC1D,MAAM,OAAO;CAGb,MAAM,SAAU,KAAM,MAAM,KAAK,KAAM,MAAM,EAAE,GAAG,KAAM;CAGxD,MAAM,IAAK,MAAM,MAAM,MAAO;AAG9B,OAAM,MAAM,MAAM;AAClB,OAAM,MAAM,MAAM;AAClB,OAAM,MAAM,MAAM;AAClB,OAAM,MAAM,MAAM;AAElB,OAAM,MAAM;AACZ,OAAM,KAAK,KAAK,MAAM,IAAI,GAAG;AAE7B,QAAO;;;;;;;;;;;;;AAcT,IAAa,8BAAb,MAAa,4BAA6D;CACxE;;;;;;;;;;;;;CAcA,YAAY,MAAwC;AAClD,OAAK,QAAQ;GACX,IAAI,KAAK,KAAK;GACd,IAAI,KAAK,KAAK;GACd,IAAI,KAAK,KAAK;GACd,IAAI,KAAK,KAAK;GACf;;;;;;;;CASH,OAAO,SAAS,MAAqE;AACnF,SAAO,IAAI,4BAA4B,KAAK;;;;;CAM9C,UAAkB;AAChB,SAAO,mBAAmB,KAAK,MAAM;;;;;CAMvC,UAAkB;AAChB,SAAO,OAAO,KAAK,SAAS,GAAG,YAAY,KAAK;;;;;;;;;CAUlD,UAAU,MAAwB;AAChC,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,IAC/B,MAAK,KAAK,OAAO,KAAK,SAAS,GAAG,KAAM;;;;;;;;CAU5C,WAAW,MAA0B;EACnC,MAAM,OAAO,IAAI,WAAW,KAAK;AACjC,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,IACxB,MAAK,KAAK,OAAO,KAAK,SAAS,GAAG,KAAM;AAE1C,SAAO;;;;;CAMT,eAAe,MAAwB;AACrC,OAAK,UAAU,KAAK;;;;;;AAOxB,MAAa,YAA8C;CACzD;CACA;CACA;CACA;CACD;;;;;AAMD,SAAgB,gCAA6D;AAC3E,QAAO,IAAI,4BAA4B,UAAU;;;;;;;;;AAUnD,SAAgB,eAAe,MAA0B;AACvD,QAAO,+BAA+B,CAAC,WAAW,KAAK"}
@@ -1,9 +1,7 @@
1
1
  var bctsRand = (function(exports) {
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
-
5
- //#region src/widening.ts
6
- /**
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ //#region src/widening.ts
4
+ /**
7
5
  * Performs wide multiplication for unsigned integers.
8
6
  * Returns (low, high) parts of the full-width result.
9
7
  *
@@ -55,10 +53,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
55
53
  const wide = (a & mask64) * (b & mask64);
56
54
  return [wide & mask64, wide >> 64n];
57
55
  }
58
-
59
- //#endregion
60
- //#region src/magnitude.ts
61
- /**
56
+ //#endregion
57
+ //#region src/magnitude.ts
58
+ /**
62
59
  * Copyright © 2023-2026 Blockchain Commons, LLC
63
60
  * Copyright © 2025-2026 Parity Technologies
64
61
  *
@@ -116,10 +113,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
116
113
  if ((maskedMag & signBit) !== 0n) return maskedMag - (1n << 64n);
117
114
  return maskedMag;
118
115
  }
119
-
120
- //#endregion
121
- //#region src/random-number-generator.ts
122
- /**
116
+ //#endregion
117
+ //#region src/random-number-generator.ts
118
+ /**
123
119
  * Copyright © 2023-2026 Blockchain Commons, LLC
124
120
  * Copyright © 2025-2026 Parity Technologies
125
121
  *
@@ -278,10 +274,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
278
274
  function rngRandomU32(rng) {
279
275
  return rng.nextU32();
280
276
  }
281
-
282
- //#endregion
283
- //#region src/secure-random.ts
284
- /**
277
+ //#endregion
278
+ //#region src/secure-random.ts
279
+ /**
285
280
  * Detects the crypto API available in the current environment.
286
281
  * Works in both Node.js and browser environments.
287
282
  */
@@ -353,10 +348,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
353
348
  fillRandomData(data);
354
349
  }
355
350
  };
356
-
357
- //#endregion
358
- //#region src/seeded-random.ts
359
- /**
351
+ //#endregion
352
+ //#region src/seeded-random.ts
353
+ /**
360
354
  * Rotate left for 64-bit bigint
361
355
  */
362
356
  function rotl(x, k) {
@@ -486,36 +480,36 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
486
480
  function fakeRandomData(size) {
487
481
  return makeFakeRandomNumberGenerator().randomData(size);
488
482
  }
489
-
490
- //#endregion
491
- exports.SecureRandomNumberGenerator = SecureRandomNumberGenerator;
492
- exports.SeededRandomNumberGenerator = SeededRandomNumberGenerator;
493
- exports.TEST_SEED = TEST_SEED;
494
- exports.fakeRandomData = fakeRandomData;
495
- exports.fillRandomData = fillRandomData;
496
- exports.fromMagnitude = fromMagnitude;
497
- exports.fromMagnitude64 = fromMagnitude64;
498
- exports.makeFakeRandomNumberGenerator = makeFakeRandomNumberGenerator;
499
- exports.nextU64 = nextU64;
500
- exports.randomData = randomData;
501
- exports.rngFillRandomData = rngFillRandomData;
502
- exports.rngNextInClosedRange = rngNextInClosedRange;
503
- exports.rngNextInClosedRangeI32 = rngNextInClosedRangeI32;
504
- exports.rngNextInRange = rngNextInRange;
505
- exports.rngNextInRangeI32 = rngNextInRangeI32;
506
- exports.rngNextWithUpperBound = rngNextWithUpperBound;
507
- exports.rngNextWithUpperBoundU32 = rngNextWithUpperBoundU32;
508
- exports.rngRandomArray = rngRandomArray;
509
- exports.rngRandomBool = rngRandomBool;
510
- exports.rngRandomData = rngRandomData;
511
- exports.rngRandomU32 = rngRandomU32;
512
- exports.toMagnitude = toMagnitude;
513
- exports.toMagnitude64 = toMagnitude64;
514
- exports.wideMul = wideMul;
515
- exports.wideMulU16 = wideMulU16;
516
- exports.wideMulU32 = wideMulU32;
517
- exports.wideMulU64 = wideMulU64;
518
- exports.wideMulU8 = wideMulU8;
519
- return exports;
483
+ //#endregion
484
+ exports.SecureRandomNumberGenerator = SecureRandomNumberGenerator;
485
+ exports.SeededRandomNumberGenerator = SeededRandomNumberGenerator;
486
+ exports.TEST_SEED = TEST_SEED;
487
+ exports.fakeRandomData = fakeRandomData;
488
+ exports.fillRandomData = fillRandomData;
489
+ exports.fromMagnitude = fromMagnitude;
490
+ exports.fromMagnitude64 = fromMagnitude64;
491
+ exports.makeFakeRandomNumberGenerator = makeFakeRandomNumberGenerator;
492
+ exports.nextU64 = nextU64;
493
+ exports.randomData = randomData;
494
+ exports.rngFillRandomData = rngFillRandomData;
495
+ exports.rngNextInClosedRange = rngNextInClosedRange;
496
+ exports.rngNextInClosedRangeI32 = rngNextInClosedRangeI32;
497
+ exports.rngNextInRange = rngNextInRange;
498
+ exports.rngNextInRangeI32 = rngNextInRangeI32;
499
+ exports.rngNextWithUpperBound = rngNextWithUpperBound;
500
+ exports.rngNextWithUpperBoundU32 = rngNextWithUpperBoundU32;
501
+ exports.rngRandomArray = rngRandomArray;
502
+ exports.rngRandomBool = rngRandomBool;
503
+ exports.rngRandomData = rngRandomData;
504
+ exports.rngRandomU32 = rngRandomU32;
505
+ exports.toMagnitude = toMagnitude;
506
+ exports.toMagnitude64 = toMagnitude64;
507
+ exports.wideMul = wideMul;
508
+ exports.wideMulU16 = wideMulU16;
509
+ exports.wideMulU32 = wideMulU32;
510
+ exports.wideMulU64 = wideMulU64;
511
+ exports.wideMulU8 = wideMulU8;
512
+ return exports;
520
513
  })({});
514
+
521
515
  //# sourceMappingURL=index.iife.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.iife.js","names":[],"sources":["../src/widening.ts","../src/magnitude.ts","../src/random-number-generator.ts","../src/secure-random.ts","../src/seeded-random.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// The below is so we don't have to use #![feature(bigint_helper_methods)]\n// Ported from bc-rand-rust/src/widening.rs\n\n/**\n * Wide multiplication result type - returns (low, high) parts.\n * For a multiplication of two N-bit values, the result is 2N bits\n * split into two N-bit parts.\n */\nexport type WideMulResult = [bigint, bigint];\n\n/**\n * Performs wide multiplication for unsigned integers.\n * Returns (low, high) parts of the full-width result.\n *\n * This is equivalent to Rust's widening_mul for unsigned types.\n */\nexport function wideMul(a: bigint, b: bigint, bits: number): WideMulResult {\n const mask = (1n << BigInt(bits)) - 1n;\n const wide = (a & mask) * (b & mask);\n const low = wide & mask;\n const high = wide >> BigInt(bits);\n return [low, high];\n}\n\n/**\n * Wide multiplication for 8-bit unsigned integers.\n * @param a - First 8-bit value\n * @param b - Second 8-bit value\n * @returns Tuple of (low 8 bits, high 8 bits)\n */\nexport function wideMulU8(a: number, b: number): [number, number] {\n const wide = (a & 0xff) * (b & 0xff);\n return [wide & 0xff, (wide >> 8) & 0xff];\n}\n\n/**\n * Wide multiplication for 16-bit unsigned integers.\n * @param a - First 16-bit value\n * @param b - Second 16-bit value\n * @returns Tuple of (low 16 bits, high 16 bits)\n */\nexport function wideMulU16(a: number, b: number): [number, number] {\n const wide = (a & 0xffff) * (b & 0xffff);\n return [wide & 0xffff, (wide >>> 16) & 0xffff];\n}\n\n/**\n * Wide multiplication for 32-bit unsigned integers.\n * @param a - First 32-bit value\n * @param b - Second 32-bit value\n * @returns Tuple of (low 32 bits, high 32 bits) as bigints\n */\nexport function wideMulU32(a: number, b: number): [bigint, bigint] {\n const aBig = BigInt(a >>> 0);\n const bBig = BigInt(b >>> 0);\n const wide = aBig * bBig;\n return [wide & 0xffffffffn, wide >> 32n];\n}\n\n/**\n * Wide multiplication for 64-bit unsigned integers.\n * @param a - First 64-bit value as bigint\n * @param b - Second 64-bit value as bigint\n * @returns Tuple of (low 64 bits, high 64 bits) as bigints\n */\nexport function wideMulU64(a: bigint, b: bigint): [bigint, bigint] {\n const mask64 = 0xffffffffffffffffn;\n const wide = (a & mask64) * (b & mask64);\n return [wide & mask64, wide >> 64n];\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/magnitude.rs\n\n/**\n * Converts a signed integer to its unsigned magnitude.\n * For positive numbers, returns the number unchanged.\n * For negative numbers, returns the absolute value (wrapping for MIN values).\n *\n * This matches Rust's wrapping_abs() behavior.\n */\nexport function toMagnitude(value: number, bits: 8 | 16 | 32): number {\n switch (bits) {\n case 8: {\n // i8 to u8: wrapping_abs\n const i8Value = (value << 24) >> 24; // Sign extend to i8\n return Math.abs(i8Value) & 0xff;\n }\n case 16: {\n // i16 to u16: wrapping_abs\n const i16Value = (value << 16) >> 16; // Sign extend to i16\n return Math.abs(i16Value) & 0xffff;\n }\n case 32: {\n // i32 to u32: wrapping_abs\n const i32Value = value | 0; // Force to i32\n // Handle MIN_VALUE specially (wrapping behavior)\n if (i32Value === -2147483648) {\n return 2147483648; // Returns as positive\n }\n return Math.abs(i32Value) >>> 0; // Convert to unsigned\n }\n }\n}\n\n/**\n * Converts a signed bigint to its unsigned magnitude for 64-bit values.\n */\nexport function toMagnitude64(value: bigint): bigint {\n const mask = 0xffffffffffffffffn;\n // Handle negative values\n if (value < 0n) {\n // Wrapping absolute value\n const absValue = -value;\n return absValue & mask;\n }\n return value & mask;\n}\n\n/**\n * Converts an unsigned magnitude back to a signed value.\n * Simply reinterprets the bits.\n */\nexport function fromMagnitude(magnitude: number, bits: 8 | 16 | 32): number {\n switch (bits) {\n case 8:\n return (magnitude << 24) >> 24; // Sign extend from u8 to i8\n case 16:\n return (magnitude << 16) >> 16; // Sign extend from u16 to i16\n case 32:\n return magnitude | 0; // Reinterpret as i32\n }\n}\n\n/**\n * Converts an unsigned 64-bit magnitude back to a signed bigint.\n */\nexport function fromMagnitude64(magnitude: bigint): bigint {\n const mask = 0xffffffffffffffffn;\n const signBit = 1n << 63n;\n const maskedMag = magnitude & mask;\n if ((maskedMag & signBit) !== 0n) {\n // Negative value - convert from two's complement\n return maskedMag - (1n << 64n);\n }\n return maskedMag;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/random_number_generator.rs\n\nimport { wideMulU32, wideMulU64 } from \"./widening.js\";\nimport {\n toMagnitude,\n toMagnitude64 as _toMagnitude64,\n fromMagnitude as _fromMagnitude,\n fromMagnitude64 as _fromMagnitude64,\n} from \"./magnitude.js\";\n\n/**\n * Interface for random number generators.\n * This is the TypeScript equivalent of Rust's RandomNumberGenerator trait\n * which extends RngCore + CryptoRng.\n *\n * This is compatible with the RandomNumberGenerator Swift protocol used\n * in MacOS and iOS, which is important for cross-platform testing.\n */\nexport interface RandomNumberGenerator {\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number;\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint;\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillBytes(dest: Uint8Array): void;\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n */\n randomData(size: number): Uint8Array;\n\n /**\n * Fills the given Uint8Array with random bytes.\n * Alias for fillBytes for compatibility.\n */\n fillRandomData(data: Uint8Array): void;\n}\n\n/**\n * Returns a Uint8Array of random bytes of the given size.\n */\nexport function rngRandomData(rng: RandomNumberGenerator, size: number): Uint8Array {\n const data = new Uint8Array(size);\n rng.fillRandomData(data);\n return data;\n}\n\n/**\n * Fills the given Uint8Array with random bytes.\n */\nexport function rngFillRandomData(rng: RandomNumberGenerator, data: Uint8Array): void {\n rng.fillRandomData(data);\n}\n\n/**\n * Returns a random value that is less than the given upper bound.\n *\n * Uses Lemire's \"nearly divisionless\" method for generating random\n * integers in an interval. For a detailed explanation, see:\n * https://arxiv.org/abs/1805.10941\n *\n * @param rng - The random number generator to use\n * @param upperBound - The upper bound for the randomly generated value. Must be non-zero.\n * @returns A random value in the range [0, upperBound). Every value in the range is equally likely.\n */\nexport function rngNextWithUpperBound(rng: RandomNumberGenerator, upperBound: bigint): bigint {\n if (upperBound === 0n) {\n throw new Error(\"upperBound must be non-zero\");\n }\n\n // We use Lemire's \"nearly divisionless\" method for generating random\n // integers in an interval. For a detailed explanation, see:\n // https://arxiv.org/abs/1805.10941\n\n const bitmask = 0xffffffffffffffffn; // u64 max\n let random = rng.nextU64() & bitmask;\n let m = wideMulU64(random, upperBound);\n\n if (m[0] < upperBound) {\n // t = (0 - upperBound) % upperBound\n const negUpperBound = (bitmask + 1n - upperBound) & bitmask;\n const t = negUpperBound % upperBound;\n while (m[0] < t) {\n random = rng.nextU64() & bitmask;\n m = wideMulU64(random, upperBound);\n }\n }\n\n return m[1];\n}\n\n/**\n * Returns a random 32-bit value that is less than the given upper bound.\n * This matches Rust's behavior when called with u32 type.\n *\n * Uses Lemire's \"nearly divisionless\" method with 32-bit arithmetic.\n *\n * @param rng - The random number generator to use\n * @param upperBound - The upper bound for the randomly generated value. Must be non-zero and fit in u32.\n * @returns A random u32 value in the range [0, upperBound).\n */\nexport function rngNextWithUpperBoundU32(rng: RandomNumberGenerator, upperBound: number): number {\n if (upperBound === 0) {\n throw new Error(\"upperBound must be non-zero\");\n }\n\n const upperBoundU32 = upperBound >>> 0;\n const bitmask = 0xffffffff;\n\n // Get random and mask to 32 bits (matches Rust behavior)\n let random = Number(rng.nextU64() & BigInt(bitmask));\n let m = wideMulU32(random, upperBoundU32);\n\n if (Number(m[0]) < upperBoundU32) {\n // t = (0 - upperBound) % upperBound (wrapping subtraction)\n const t = ((bitmask + 1 - upperBoundU32) >>> 0) % upperBoundU32;\n while (Number(m[0]) < t) {\n random = Number(rng.nextU64() & BigInt(bitmask));\n m = wideMulU32(random, upperBoundU32);\n }\n }\n\n return Number(m[1]);\n}\n\n/**\n * Returns a random value within the specified range [start, end) using 32-bit arithmetic.\n * This matches Rust's behavior when called with i32 types.\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive) as i32\n * @param end - The upper bound (exclusive) as i32\n * @returns A random i32 value within the bounds\n */\nexport function rngNextInRangeI32(rng: RandomNumberGenerator, start: number, end: number): number {\n if (start >= end) {\n throw new Error(\"start must be less than end\");\n }\n\n const startI32 = start | 0;\n const endI32 = end | 0;\n const delta = toMagnitude(endI32 - startI32, 32);\n\n if (delta === 0xffffffff) {\n return rng.nextU32() | 0;\n }\n\n const random = rngNextWithUpperBoundU32(rng, delta);\n return (startI32 + random) | 0;\n}\n\n/**\n * Returns a random value within the specified range [start, end).\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive)\n * @param end - The upper bound (exclusive)\n * @returns A random value within the bounds of the range\n */\nexport function rngNextInRange(rng: RandomNumberGenerator, start: bigint, end: bigint): bigint {\n if (start >= end) {\n throw new Error(\"start must be less than end\");\n }\n\n const delta = end - start;\n\n // If delta covers the entire range, just return a random value\n const maxU64 = 0xffffffffffffffffn;\n if (delta === maxU64) {\n return rng.nextU64();\n }\n\n const random = rngNextWithUpperBound(rng, delta);\n return start + random;\n}\n\n/**\n * Returns a random value within the specified closed range [start, end].\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive)\n * @param end - The upper bound (inclusive)\n * @returns A random value within the bounds of the range\n */\nexport function rngNextInClosedRange(\n rng: RandomNumberGenerator,\n start: bigint,\n end: bigint,\n): bigint {\n if (start > end) {\n throw new Error(\"start must be less than or equal to end\");\n }\n\n const delta = end - start;\n\n // If delta covers the entire range, just return a random value\n const maxU64 = 0xffffffffffffffffn;\n if (delta === maxU64) {\n return rng.nextU64();\n }\n\n const random = rngNextWithUpperBound(rng, delta + 1n);\n return start + random;\n}\n\n/**\n * Returns a random value within the specified closed range [start, end] for i32 values.\n * Convenience function that handles signed 32-bit integers.\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive) as i32\n * @param end - The upper bound (inclusive) as i32\n * @returns A random i32 value within the bounds of the range\n */\nexport function rngNextInClosedRangeI32(\n rng: RandomNumberGenerator,\n start: number,\n end: number,\n): number {\n if (start > end) {\n throw new Error(\"start must be less than or equal to end\");\n }\n\n // Convert to i32\n const startI32 = start | 0;\n const endI32 = end | 0;\n\n // Calculate delta as u32 magnitude\n const delta = toMagnitude(endI32 - startI32, 32);\n\n // If delta covers the entire u32 range, just return a random value\n if (delta === 0xffffffff) {\n return rng.nextU32() | 0;\n }\n\n const random = rngNextWithUpperBoundU32(rng, delta + 1);\n return (startI32 + random) | 0;\n}\n\n/**\n * Returns a fixed-size array of random bytes.\n *\n * @param rng - The random number generator to use\n * @param size - The size of the array to return\n * @returns A Uint8Array of the specified size filled with random bytes\n */\nexport function rngRandomArray(rng: RandomNumberGenerator, size: number): Uint8Array {\n const data = new Uint8Array(size);\n rng.fillRandomData(data);\n return data;\n}\n\n/**\n * Returns a random boolean value.\n *\n * @param rng - The random number generator to use\n * @returns A random boolean\n */\nexport function rngRandomBool(rng: RandomNumberGenerator): boolean {\n return (rng.nextU32() & 1) === 0;\n}\n\n/**\n * Returns a random 32-bit unsigned integer.\n *\n * @param rng - The random number generator to use\n * @returns A random u32 value\n */\nexport function rngRandomU32(rng: RandomNumberGenerator): number {\n return rng.nextU32();\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/secure_random.rs\n\nimport type { RandomNumberGenerator } from \"./random-number-generator.js\";\n\n/**\n * Detects the crypto API available in the current environment.\n * Works in both Node.js and browser environments.\n */\nfunction getCrypto(): Crypto {\n // Browser environment\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.crypto !== null &&\n globalThis.crypto !== undefined\n ) {\n return globalThis.crypto;\n }\n // Node.js environment - globalThis.crypto is also available in Node.js >= 15\n if (typeof globalThis.crypto !== \"undefined\") {\n return globalThis.crypto;\n }\n throw new Error(\"No crypto API available in this environment\");\n}\n\n/**\n * Generate a Uint8Array of cryptographically strong random bytes of the given size.\n */\nexport function randomData(size: number): Uint8Array {\n const data = new Uint8Array(size);\n fillRandomData(data);\n return data;\n}\n\n/**\n * Fill the given Uint8Array with cryptographically strong random bytes.\n */\nexport function fillRandomData(data: Uint8Array): void {\n const crypto = getCrypto();\n crypto.getRandomValues(data);\n}\n\n/**\n * Returns the next cryptographically strong random 64-bit unsigned integer.\n */\nexport function nextU64(): bigint {\n const data = new Uint8Array(8);\n fillRandomData(data);\n const view = new DataView(data.buffer);\n return view.getBigUint64(0, true); // little-endian\n}\n\n/**\n * A random number generator that can be used as a source of\n * cryptographically-strong randomness.\n *\n * Uses the Web Crypto API (crypto.getRandomValues) which is available\n * in both browsers and Node.js >= 15.\n */\nexport class SecureRandomNumberGenerator implements RandomNumberGenerator {\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number {\n const data = new Uint8Array(4);\n fillRandomData(data);\n const view = new DataView(data.buffer);\n return view.getUint32(0, true) >>> 0; // little-endian, unsigned\n }\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint {\n return nextU64();\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillBytes(dest: Uint8Array): void {\n fillRandomData(dest);\n }\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n */\n randomData(size: number): Uint8Array {\n return randomData(size);\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillRandomData(data: Uint8Array): void {\n fillRandomData(data);\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/seeded_random.rs\n\nimport type { RandomNumberGenerator } from \"./random-number-generator.js\";\n\n/**\n * Xoshiro256** state\n * Based on xoshiro256** 1.0 by David Blackman and Sebastiano Vigna\n * https://prng.di.unimi.it/\n */\ninterface Xoshiro256State {\n s0: bigint;\n s1: bigint;\n s2: bigint;\n s3: bigint;\n}\n\n/**\n * Rotate left for 64-bit bigint\n */\nfunction rotl(x: bigint, k: number): bigint {\n const mask = 0xffffffffffffffffn;\n return ((x << BigInt(k)) | (x >> BigInt(64 - k))) & mask;\n}\n\n/**\n * Xoshiro256** PRNG implementation\n * This is the same algorithm used by rand_xoshiro in Rust\n */\nfunction xoshiro256StarStar(state: Xoshiro256State): bigint {\n const mask = 0xffffffffffffffffn;\n\n // result = rotl(s1 * 5, 7) * 9\n const result = (rotl((state.s1 * 5n) & mask, 7) * 9n) & mask;\n\n // t = s1 << 17\n const t = (state.s1 << 17n) & mask;\n\n // Update state\n state.s2 ^= state.s0;\n state.s3 ^= state.s1;\n state.s1 ^= state.s2;\n state.s0 ^= state.s3;\n\n state.s2 ^= t;\n state.s3 = rotl(state.s3, 45);\n\n return result;\n}\n\n/**\n * A random number generator that can be used as a source of deterministic\n * pseudo-randomness for testing purposes.\n *\n * Uses the Xoshiro256** algorithm, which is the same algorithm used by\n * rand_xoshiro in Rust. This ensures cross-platform compatibility with\n * the Rust implementation.\n *\n * WARNING: This is NOT cryptographically secure and should only be used\n * for testing purposes.\n */\nexport class SeededRandomNumberGenerator implements RandomNumberGenerator {\n private readonly state: Xoshiro256State;\n\n /**\n * Creates a new seeded random number generator.\n *\n * The seed should be a 256-bit value, represented as an array of 4 64-bit\n * integers (as bigints). For the output distribution to look random, the seed\n * should not have any obvious patterns, like all zeroes or all ones.\n *\n * This is not cryptographically secure, and should only be used for\n * testing purposes.\n *\n * @param seed - Array of 4 64-bit unsigned integers as bigints\n */\n constructor(seed: [bigint, bigint, bigint, bigint]) {\n this.state = {\n s0: seed[0] & 0xffffffffffffffffn,\n s1: seed[1] & 0xffffffffffffffffn,\n s2: seed[2] & 0xffffffffffffffffn,\n s3: seed[3] & 0xffffffffffffffffn,\n };\n }\n\n /**\n * Creates a new seeded random number generator from a seed array.\n * Convenience method that accepts numbers and converts to bigints.\n *\n * @param seed - Array of 4 64-bit unsigned integers\n */\n static fromSeed(seed: [bigint, bigint, bigint, bigint]): SeededRandomNumberGenerator {\n return new SeededRandomNumberGenerator(seed);\n }\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint {\n return xoshiro256StarStar(this.state);\n }\n\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number {\n return Number(this.nextU64() & 0xffffffffn) >>> 0;\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n *\n * Note: This implementation matches the Rust behavior exactly -\n * it uses one nextU64() call per byte (taking only the low byte),\n * which matches the Swift version's behavior.\n */\n fillBytes(dest: Uint8Array): void {\n for (let i = 0; i < dest.length; i++) {\n dest[i] = Number(this.nextU64() & 0xffn);\n }\n }\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n *\n * This might not be the most efficient implementation,\n * but it works the same as the Swift version.\n */\n randomData(size: number): Uint8Array {\n const data = new Uint8Array(size);\n for (let i = 0; i < size; i++) {\n data[i] = Number(this.nextU64() & 0xffn);\n }\n return data;\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillRandomData(data: Uint8Array): void {\n this.fillBytes(data);\n }\n}\n\n/**\n * The standard test seed used across all Blockchain Commons implementations.\n */\nexport const TEST_SEED: [bigint, bigint, bigint, bigint] = [\n 17295166580085024720n,\n 422929670265678780n,\n 5577237070365765850n,\n 7953171132032326923n,\n];\n\n/**\n * Creates a seeded random number generator with a fixed seed.\n * This is useful for reproducible testing across different platforms.\n */\nexport function makeFakeRandomNumberGenerator(): SeededRandomNumberGenerator {\n return new SeededRandomNumberGenerator(TEST_SEED);\n}\n\n/**\n * Creates a Uint8Array of random data with a fixed seed.\n * This is useful for reproducible testing.\n *\n * @param size - The number of bytes to generate\n * @returns A Uint8Array of pseudo-random bytes\n */\nexport function fakeRandomData(size: number): Uint8Array {\n return makeFakeRandomNumberGenerator().randomData(size);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.iife.js","names":[],"sources":["../src/widening.ts","../src/magnitude.ts","../src/random-number-generator.ts","../src/secure-random.ts","../src/seeded-random.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// The below is so we don't have to use #![feature(bigint_helper_methods)]\n// Ported from bc-rand-rust/src/widening.rs\n\n/**\n * Wide multiplication result type - returns (low, high) parts.\n * For a multiplication of two N-bit values, the result is 2N bits\n * split into two N-bit parts.\n */\nexport type WideMulResult = [bigint, bigint];\n\n/**\n * Performs wide multiplication for unsigned integers.\n * Returns (low, high) parts of the full-width result.\n *\n * This is equivalent to Rust's widening_mul for unsigned types.\n */\nexport function wideMul(a: bigint, b: bigint, bits: number): WideMulResult {\n const mask = (1n << BigInt(bits)) - 1n;\n const wide = (a & mask) * (b & mask);\n const low = wide & mask;\n const high = wide >> BigInt(bits);\n return [low, high];\n}\n\n/**\n * Wide multiplication for 8-bit unsigned integers.\n * @param a - First 8-bit value\n * @param b - Second 8-bit value\n * @returns Tuple of (low 8 bits, high 8 bits)\n */\nexport function wideMulU8(a: number, b: number): [number, number] {\n const wide = (a & 0xff) * (b & 0xff);\n return [wide & 0xff, (wide >> 8) & 0xff];\n}\n\n/**\n * Wide multiplication for 16-bit unsigned integers.\n * @param a - First 16-bit value\n * @param b - Second 16-bit value\n * @returns Tuple of (low 16 bits, high 16 bits)\n */\nexport function wideMulU16(a: number, b: number): [number, number] {\n const wide = (a & 0xffff) * (b & 0xffff);\n return [wide & 0xffff, (wide >>> 16) & 0xffff];\n}\n\n/**\n * Wide multiplication for 32-bit unsigned integers.\n * @param a - First 32-bit value\n * @param b - Second 32-bit value\n * @returns Tuple of (low 32 bits, high 32 bits) as bigints\n */\nexport function wideMulU32(a: number, b: number): [bigint, bigint] {\n const aBig = BigInt(a >>> 0);\n const bBig = BigInt(b >>> 0);\n const wide = aBig * bBig;\n return [wide & 0xffffffffn, wide >> 32n];\n}\n\n/**\n * Wide multiplication for 64-bit unsigned integers.\n * @param a - First 64-bit value as bigint\n * @param b - Second 64-bit value as bigint\n * @returns Tuple of (low 64 bits, high 64 bits) as bigints\n */\nexport function wideMulU64(a: bigint, b: bigint): [bigint, bigint] {\n const mask64 = 0xffffffffffffffffn;\n const wide = (a & mask64) * (b & mask64);\n return [wide & mask64, wide >> 64n];\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/magnitude.rs\n\n/**\n * Converts a signed integer to its unsigned magnitude.\n * For positive numbers, returns the number unchanged.\n * For negative numbers, returns the absolute value (wrapping for MIN values).\n *\n * This matches Rust's wrapping_abs() behavior.\n */\nexport function toMagnitude(value: number, bits: 8 | 16 | 32): number {\n switch (bits) {\n case 8: {\n // i8 to u8: wrapping_abs\n const i8Value = (value << 24) >> 24; // Sign extend to i8\n return Math.abs(i8Value) & 0xff;\n }\n case 16: {\n // i16 to u16: wrapping_abs\n const i16Value = (value << 16) >> 16; // Sign extend to i16\n return Math.abs(i16Value) & 0xffff;\n }\n case 32: {\n // i32 to u32: wrapping_abs\n const i32Value = value | 0; // Force to i32\n // Handle MIN_VALUE specially (wrapping behavior)\n if (i32Value === -2147483648) {\n return 2147483648; // Returns as positive\n }\n return Math.abs(i32Value) >>> 0; // Convert to unsigned\n }\n }\n}\n\n/**\n * Converts a signed bigint to its unsigned magnitude for 64-bit values.\n */\nexport function toMagnitude64(value: bigint): bigint {\n const mask = 0xffffffffffffffffn;\n // Handle negative values\n if (value < 0n) {\n // Wrapping absolute value\n const absValue = -value;\n return absValue & mask;\n }\n return value & mask;\n}\n\n/**\n * Converts an unsigned magnitude back to a signed value.\n * Simply reinterprets the bits.\n */\nexport function fromMagnitude(magnitude: number, bits: 8 | 16 | 32): number {\n switch (bits) {\n case 8:\n return (magnitude << 24) >> 24; // Sign extend from u8 to i8\n case 16:\n return (magnitude << 16) >> 16; // Sign extend from u16 to i16\n case 32:\n return magnitude | 0; // Reinterpret as i32\n }\n}\n\n/**\n * Converts an unsigned 64-bit magnitude back to a signed bigint.\n */\nexport function fromMagnitude64(magnitude: bigint): bigint {\n const mask = 0xffffffffffffffffn;\n const signBit = 1n << 63n;\n const maskedMag = magnitude & mask;\n if ((maskedMag & signBit) !== 0n) {\n // Negative value - convert from two's complement\n return maskedMag - (1n << 64n);\n }\n return maskedMag;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/random_number_generator.rs\n\nimport { wideMulU32, wideMulU64 } from \"./widening.js\";\nimport {\n toMagnitude,\n toMagnitude64 as _toMagnitude64,\n fromMagnitude as _fromMagnitude,\n fromMagnitude64 as _fromMagnitude64,\n} from \"./magnitude.js\";\n\n/**\n * Interface for random number generators.\n * This is the TypeScript equivalent of Rust's RandomNumberGenerator trait\n * which extends RngCore + CryptoRng.\n *\n * This is compatible with the RandomNumberGenerator Swift protocol used\n * in MacOS and iOS, which is important for cross-platform testing.\n */\nexport interface RandomNumberGenerator {\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number;\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint;\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillBytes(dest: Uint8Array): void;\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n */\n randomData(size: number): Uint8Array;\n\n /**\n * Fills the given Uint8Array with random bytes.\n * Alias for fillBytes for compatibility.\n */\n fillRandomData(data: Uint8Array): void;\n}\n\n/**\n * Returns a Uint8Array of random bytes of the given size.\n */\nexport function rngRandomData(rng: RandomNumberGenerator, size: number): Uint8Array {\n const data = new Uint8Array(size);\n rng.fillRandomData(data);\n return data;\n}\n\n/**\n * Fills the given Uint8Array with random bytes.\n */\nexport function rngFillRandomData(rng: RandomNumberGenerator, data: Uint8Array): void {\n rng.fillRandomData(data);\n}\n\n/**\n * Returns a random value that is less than the given upper bound.\n *\n * Uses Lemire's \"nearly divisionless\" method for generating random\n * integers in an interval. For a detailed explanation, see:\n * https://arxiv.org/abs/1805.10941\n *\n * @param rng - The random number generator to use\n * @param upperBound - The upper bound for the randomly generated value. Must be non-zero.\n * @returns A random value in the range [0, upperBound). Every value in the range is equally likely.\n */\nexport function rngNextWithUpperBound(rng: RandomNumberGenerator, upperBound: bigint): bigint {\n if (upperBound === 0n) {\n throw new Error(\"upperBound must be non-zero\");\n }\n\n // We use Lemire's \"nearly divisionless\" method for generating random\n // integers in an interval. For a detailed explanation, see:\n // https://arxiv.org/abs/1805.10941\n\n const bitmask = 0xffffffffffffffffn; // u64 max\n let random = rng.nextU64() & bitmask;\n let m = wideMulU64(random, upperBound);\n\n if (m[0] < upperBound) {\n // t = (0 - upperBound) % upperBound\n const negUpperBound = (bitmask + 1n - upperBound) & bitmask;\n const t = negUpperBound % upperBound;\n while (m[0] < t) {\n random = rng.nextU64() & bitmask;\n m = wideMulU64(random, upperBound);\n }\n }\n\n return m[1];\n}\n\n/**\n * Returns a random 32-bit value that is less than the given upper bound.\n * This matches Rust's behavior when called with u32 type.\n *\n * Uses Lemire's \"nearly divisionless\" method with 32-bit arithmetic.\n *\n * @param rng - The random number generator to use\n * @param upperBound - The upper bound for the randomly generated value. Must be non-zero and fit in u32.\n * @returns A random u32 value in the range [0, upperBound).\n */\nexport function rngNextWithUpperBoundU32(rng: RandomNumberGenerator, upperBound: number): number {\n if (upperBound === 0) {\n throw new Error(\"upperBound must be non-zero\");\n }\n\n const upperBoundU32 = upperBound >>> 0;\n const bitmask = 0xffffffff;\n\n // Get random and mask to 32 bits (matches Rust behavior)\n let random = Number(rng.nextU64() & BigInt(bitmask));\n let m = wideMulU32(random, upperBoundU32);\n\n if (Number(m[0]) < upperBoundU32) {\n // t = (0 - upperBound) % upperBound (wrapping subtraction)\n const t = ((bitmask + 1 - upperBoundU32) >>> 0) % upperBoundU32;\n while (Number(m[0]) < t) {\n random = Number(rng.nextU64() & BigInt(bitmask));\n m = wideMulU32(random, upperBoundU32);\n }\n }\n\n return Number(m[1]);\n}\n\n/**\n * Returns a random value within the specified range [start, end) using 32-bit arithmetic.\n * This matches Rust's behavior when called with i32 types.\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive) as i32\n * @param end - The upper bound (exclusive) as i32\n * @returns A random i32 value within the bounds\n */\nexport function rngNextInRangeI32(rng: RandomNumberGenerator, start: number, end: number): number {\n if (start >= end) {\n throw new Error(\"start must be less than end\");\n }\n\n const startI32 = start | 0;\n const endI32 = end | 0;\n const delta = toMagnitude(endI32 - startI32, 32);\n\n if (delta === 0xffffffff) {\n return rng.nextU32() | 0;\n }\n\n const random = rngNextWithUpperBoundU32(rng, delta);\n return (startI32 + random) | 0;\n}\n\n/**\n * Returns a random value within the specified range [start, end).\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive)\n * @param end - The upper bound (exclusive)\n * @returns A random value within the bounds of the range\n */\nexport function rngNextInRange(rng: RandomNumberGenerator, start: bigint, end: bigint): bigint {\n if (start >= end) {\n throw new Error(\"start must be less than end\");\n }\n\n const delta = end - start;\n\n // If delta covers the entire range, just return a random value\n const maxU64 = 0xffffffffffffffffn;\n if (delta === maxU64) {\n return rng.nextU64();\n }\n\n const random = rngNextWithUpperBound(rng, delta);\n return start + random;\n}\n\n/**\n * Returns a random value within the specified closed range [start, end].\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive)\n * @param end - The upper bound (inclusive)\n * @returns A random value within the bounds of the range\n */\nexport function rngNextInClosedRange(\n rng: RandomNumberGenerator,\n start: bigint,\n end: bigint,\n): bigint {\n if (start > end) {\n throw new Error(\"start must be less than or equal to end\");\n }\n\n const delta = end - start;\n\n // If delta covers the entire range, just return a random value\n const maxU64 = 0xffffffffffffffffn;\n if (delta === maxU64) {\n return rng.nextU64();\n }\n\n const random = rngNextWithUpperBound(rng, delta + 1n);\n return start + random;\n}\n\n/**\n * Returns a random value within the specified closed range [start, end] for i32 values.\n * Convenience function that handles signed 32-bit integers.\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive) as i32\n * @param end - The upper bound (inclusive) as i32\n * @returns A random i32 value within the bounds of the range\n */\nexport function rngNextInClosedRangeI32(\n rng: RandomNumberGenerator,\n start: number,\n end: number,\n): number {\n if (start > end) {\n throw new Error(\"start must be less than or equal to end\");\n }\n\n // Convert to i32\n const startI32 = start | 0;\n const endI32 = end | 0;\n\n // Calculate delta as u32 magnitude\n const delta = toMagnitude(endI32 - startI32, 32);\n\n // If delta covers the entire u32 range, just return a random value\n if (delta === 0xffffffff) {\n return rng.nextU32() | 0;\n }\n\n const random = rngNextWithUpperBoundU32(rng, delta + 1);\n return (startI32 + random) | 0;\n}\n\n/**\n * Returns a fixed-size array of random bytes.\n *\n * @param rng - The random number generator to use\n * @param size - The size of the array to return\n * @returns A Uint8Array of the specified size filled with random bytes\n */\nexport function rngRandomArray(rng: RandomNumberGenerator, size: number): Uint8Array {\n const data = new Uint8Array(size);\n rng.fillRandomData(data);\n return data;\n}\n\n/**\n * Returns a random boolean value.\n *\n * @param rng - The random number generator to use\n * @returns A random boolean\n */\nexport function rngRandomBool(rng: RandomNumberGenerator): boolean {\n return (rng.nextU32() & 1) === 0;\n}\n\n/**\n * Returns a random 32-bit unsigned integer.\n *\n * @param rng - The random number generator to use\n * @returns A random u32 value\n */\nexport function rngRandomU32(rng: RandomNumberGenerator): number {\n return rng.nextU32();\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/secure_random.rs\n\nimport type { RandomNumberGenerator } from \"./random-number-generator.js\";\n\n/**\n * Detects the crypto API available in the current environment.\n * Works in both Node.js and browser environments.\n */\nfunction getCrypto(): Crypto {\n // Browser environment\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.crypto !== null &&\n globalThis.crypto !== undefined\n ) {\n return globalThis.crypto;\n }\n // Node.js environment - globalThis.crypto is also available in Node.js >= 15\n if (typeof globalThis.crypto !== \"undefined\") {\n return globalThis.crypto;\n }\n throw new Error(\"No crypto API available in this environment\");\n}\n\n/**\n * Generate a Uint8Array of cryptographically strong random bytes of the given size.\n */\nexport function randomData(size: number): Uint8Array {\n const data = new Uint8Array(size);\n fillRandomData(data);\n return data;\n}\n\n/**\n * Fill the given Uint8Array with cryptographically strong random bytes.\n */\nexport function fillRandomData(data: Uint8Array): void {\n const crypto = getCrypto();\n crypto.getRandomValues(data as Uint8Array<ArrayBuffer>);\n}\n\n/**\n * Returns the next cryptographically strong random 64-bit unsigned integer.\n */\nexport function nextU64(): bigint {\n const data = new Uint8Array(8);\n fillRandomData(data);\n const view = new DataView(data.buffer);\n return view.getBigUint64(0, true); // little-endian\n}\n\n/**\n * A random number generator that can be used as a source of\n * cryptographically-strong randomness.\n *\n * Uses the Web Crypto API (crypto.getRandomValues) which is available\n * in both browsers and Node.js >= 15.\n */\nexport class SecureRandomNumberGenerator implements RandomNumberGenerator {\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number {\n const data = new Uint8Array(4);\n fillRandomData(data);\n const view = new DataView(data.buffer);\n return view.getUint32(0, true) >>> 0; // little-endian, unsigned\n }\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint {\n return nextU64();\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillBytes(dest: Uint8Array): void {\n fillRandomData(dest);\n }\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n */\n randomData(size: number): Uint8Array {\n return randomData(size);\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillRandomData(data: Uint8Array): void {\n fillRandomData(data);\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/seeded_random.rs\n\nimport type { RandomNumberGenerator } from \"./random-number-generator.js\";\n\n/**\n * Xoshiro256** state\n * Based on xoshiro256** 1.0 by David Blackman and Sebastiano Vigna\n * https://prng.di.unimi.it/\n */\ninterface Xoshiro256State {\n s0: bigint;\n s1: bigint;\n s2: bigint;\n s3: bigint;\n}\n\n/**\n * Rotate left for 64-bit bigint\n */\nfunction rotl(x: bigint, k: number): bigint {\n const mask = 0xffffffffffffffffn;\n return ((x << BigInt(k)) | (x >> BigInt(64 - k))) & mask;\n}\n\n/**\n * Xoshiro256** PRNG implementation\n * This is the same algorithm used by rand_xoshiro in Rust\n */\nfunction xoshiro256StarStar(state: Xoshiro256State): bigint {\n const mask = 0xffffffffffffffffn;\n\n // result = rotl(s1 * 5, 7) * 9\n const result = (rotl((state.s1 * 5n) & mask, 7) * 9n) & mask;\n\n // t = s1 << 17\n const t = (state.s1 << 17n) & mask;\n\n // Update state\n state.s2 ^= state.s0;\n state.s3 ^= state.s1;\n state.s1 ^= state.s2;\n state.s0 ^= state.s3;\n\n state.s2 ^= t;\n state.s3 = rotl(state.s3, 45);\n\n return result;\n}\n\n/**\n * A random number generator that can be used as a source of deterministic\n * pseudo-randomness for testing purposes.\n *\n * Uses the Xoshiro256** algorithm, which is the same algorithm used by\n * rand_xoshiro in Rust. This ensures cross-platform compatibility with\n * the Rust implementation.\n *\n * WARNING: This is NOT cryptographically secure and should only be used\n * for testing purposes.\n */\nexport class SeededRandomNumberGenerator implements RandomNumberGenerator {\n private readonly state: Xoshiro256State;\n\n /**\n * Creates a new seeded random number generator.\n *\n * The seed should be a 256-bit value, represented as an array of 4 64-bit\n * integers (as bigints). For the output distribution to look random, the seed\n * should not have any obvious patterns, like all zeroes or all ones.\n *\n * This is not cryptographically secure, and should only be used for\n * testing purposes.\n *\n * @param seed - Array of 4 64-bit unsigned integers as bigints\n */\n constructor(seed: [bigint, bigint, bigint, bigint]) {\n this.state = {\n s0: seed[0] & 0xffffffffffffffffn,\n s1: seed[1] & 0xffffffffffffffffn,\n s2: seed[2] & 0xffffffffffffffffn,\n s3: seed[3] & 0xffffffffffffffffn,\n };\n }\n\n /**\n * Creates a new seeded random number generator from a seed array.\n * Convenience method that accepts numbers and converts to bigints.\n *\n * @param seed - Array of 4 64-bit unsigned integers\n */\n static fromSeed(seed: [bigint, bigint, bigint, bigint]): SeededRandomNumberGenerator {\n return new SeededRandomNumberGenerator(seed);\n }\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint {\n return xoshiro256StarStar(this.state);\n }\n\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number {\n return Number(this.nextU64() & 0xffffffffn) >>> 0;\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n *\n * Note: This implementation matches the Rust behavior exactly -\n * it uses one nextU64() call per byte (taking only the low byte),\n * which matches the Swift version's behavior.\n */\n fillBytes(dest: Uint8Array): void {\n for (let i = 0; i < dest.length; i++) {\n dest[i] = Number(this.nextU64() & 0xffn);\n }\n }\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n *\n * This might not be the most efficient implementation,\n * but it works the same as the Swift version.\n */\n randomData(size: number): Uint8Array {\n const data = new Uint8Array(size);\n for (let i = 0; i < size; i++) {\n data[i] = Number(this.nextU64() & 0xffn);\n }\n return data;\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillRandomData(data: Uint8Array): void {\n this.fillBytes(data);\n }\n}\n\n/**\n * The standard test seed used across all Blockchain Commons implementations.\n */\nexport const TEST_SEED: [bigint, bigint, bigint, bigint] = [\n 17295166580085024720n,\n 422929670265678780n,\n 5577237070365765850n,\n 7953171132032326923n,\n];\n\n/**\n * Creates a seeded random number generator with a fixed seed.\n * This is useful for reproducible testing across different platforms.\n */\nexport function makeFakeRandomNumberGenerator(): SeededRandomNumberGenerator {\n return new SeededRandomNumberGenerator(TEST_SEED);\n}\n\n/**\n * Creates a Uint8Array of random data with a fixed seed.\n * This is useful for reproducible testing.\n *\n * @param size - The number of bytes to generate\n * @returns A Uint8Array of pseudo-random bytes\n */\nexport function fakeRandomData(size: number): Uint8Array {\n return makeFakeRandomNumberGenerator().randomData(size);\n}\n"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -51,7 +51,6 @@ function wideMulU64(a, b) {
51
51
  const wide = (a & mask64) * (b & mask64);
52
52
  return [wide & mask64, wide >> 64n];
53
53
  }
54
-
55
54
  //#endregion
56
55
  //#region src/magnitude.ts
57
56
  /**
@@ -112,7 +111,6 @@ function fromMagnitude64(magnitude) {
112
111
  if ((maskedMag & signBit) !== 0n) return maskedMag - (1n << 64n);
113
112
  return maskedMag;
114
113
  }
115
-
116
114
  //#endregion
117
115
  //#region src/random-number-generator.ts
118
116
  /**
@@ -274,7 +272,6 @@ function rngRandomBool(rng) {
274
272
  function rngRandomU32(rng) {
275
273
  return rng.nextU32();
276
274
  }
277
-
278
275
  //#endregion
279
276
  //#region src/secure-random.ts
280
277
  /**
@@ -349,7 +346,6 @@ var SecureRandomNumberGenerator = class {
349
346
  fillRandomData(data);
350
347
  }
351
348
  };
352
-
353
349
  //#endregion
354
350
  //#region src/seeded-random.ts
355
351
  /**
@@ -482,7 +478,7 @@ function makeFakeRandomNumberGenerator() {
482
478
  function fakeRandomData(size) {
483
479
  return makeFakeRandomNumberGenerator().randomData(size);
484
480
  }
485
-
486
481
  //#endregion
487
482
  export { SecureRandomNumberGenerator, SeededRandomNumberGenerator, TEST_SEED, fakeRandomData, fillRandomData, fromMagnitude, fromMagnitude64, makeFakeRandomNumberGenerator, nextU64, randomData, rngFillRandomData, rngNextInClosedRange, rngNextInClosedRangeI32, rngNextInRange, rngNextInRangeI32, rngNextWithUpperBound, rngNextWithUpperBoundU32, rngRandomArray, rngRandomBool, rngRandomData, rngRandomU32, toMagnitude, toMagnitude64, wideMul, wideMulU16, wideMulU32, wideMulU64, wideMulU8 };
483
+
488
484
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/widening.ts","../src/magnitude.ts","../src/random-number-generator.ts","../src/secure-random.ts","../src/seeded-random.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// The below is so we don't have to use #![feature(bigint_helper_methods)]\n// Ported from bc-rand-rust/src/widening.rs\n\n/**\n * Wide multiplication result type - returns (low, high) parts.\n * For a multiplication of two N-bit values, the result is 2N bits\n * split into two N-bit parts.\n */\nexport type WideMulResult = [bigint, bigint];\n\n/**\n * Performs wide multiplication for unsigned integers.\n * Returns (low, high) parts of the full-width result.\n *\n * This is equivalent to Rust's widening_mul for unsigned types.\n */\nexport function wideMul(a: bigint, b: bigint, bits: number): WideMulResult {\n const mask = (1n << BigInt(bits)) - 1n;\n const wide = (a & mask) * (b & mask);\n const low = wide & mask;\n const high = wide >> BigInt(bits);\n return [low, high];\n}\n\n/**\n * Wide multiplication for 8-bit unsigned integers.\n * @param a - First 8-bit value\n * @param b - Second 8-bit value\n * @returns Tuple of (low 8 bits, high 8 bits)\n */\nexport function wideMulU8(a: number, b: number): [number, number] {\n const wide = (a & 0xff) * (b & 0xff);\n return [wide & 0xff, (wide >> 8) & 0xff];\n}\n\n/**\n * Wide multiplication for 16-bit unsigned integers.\n * @param a - First 16-bit value\n * @param b - Second 16-bit value\n * @returns Tuple of (low 16 bits, high 16 bits)\n */\nexport function wideMulU16(a: number, b: number): [number, number] {\n const wide = (a & 0xffff) * (b & 0xffff);\n return [wide & 0xffff, (wide >>> 16) & 0xffff];\n}\n\n/**\n * Wide multiplication for 32-bit unsigned integers.\n * @param a - First 32-bit value\n * @param b - Second 32-bit value\n * @returns Tuple of (low 32 bits, high 32 bits) as bigints\n */\nexport function wideMulU32(a: number, b: number): [bigint, bigint] {\n const aBig = BigInt(a >>> 0);\n const bBig = BigInt(b >>> 0);\n const wide = aBig * bBig;\n return [wide & 0xffffffffn, wide >> 32n];\n}\n\n/**\n * Wide multiplication for 64-bit unsigned integers.\n * @param a - First 64-bit value as bigint\n * @param b - Second 64-bit value as bigint\n * @returns Tuple of (low 64 bits, high 64 bits) as bigints\n */\nexport function wideMulU64(a: bigint, b: bigint): [bigint, bigint] {\n const mask64 = 0xffffffffffffffffn;\n const wide = (a & mask64) * (b & mask64);\n return [wide & mask64, wide >> 64n];\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/magnitude.rs\n\n/**\n * Converts a signed integer to its unsigned magnitude.\n * For positive numbers, returns the number unchanged.\n * For negative numbers, returns the absolute value (wrapping for MIN values).\n *\n * This matches Rust's wrapping_abs() behavior.\n */\nexport function toMagnitude(value: number, bits: 8 | 16 | 32): number {\n switch (bits) {\n case 8: {\n // i8 to u8: wrapping_abs\n const i8Value = (value << 24) >> 24; // Sign extend to i8\n return Math.abs(i8Value) & 0xff;\n }\n case 16: {\n // i16 to u16: wrapping_abs\n const i16Value = (value << 16) >> 16; // Sign extend to i16\n return Math.abs(i16Value) & 0xffff;\n }\n case 32: {\n // i32 to u32: wrapping_abs\n const i32Value = value | 0; // Force to i32\n // Handle MIN_VALUE specially (wrapping behavior)\n if (i32Value === -2147483648) {\n return 2147483648; // Returns as positive\n }\n return Math.abs(i32Value) >>> 0; // Convert to unsigned\n }\n }\n}\n\n/**\n * Converts a signed bigint to its unsigned magnitude for 64-bit values.\n */\nexport function toMagnitude64(value: bigint): bigint {\n const mask = 0xffffffffffffffffn;\n // Handle negative values\n if (value < 0n) {\n // Wrapping absolute value\n const absValue = -value;\n return absValue & mask;\n }\n return value & mask;\n}\n\n/**\n * Converts an unsigned magnitude back to a signed value.\n * Simply reinterprets the bits.\n */\nexport function fromMagnitude(magnitude: number, bits: 8 | 16 | 32): number {\n switch (bits) {\n case 8:\n return (magnitude << 24) >> 24; // Sign extend from u8 to i8\n case 16:\n return (magnitude << 16) >> 16; // Sign extend from u16 to i16\n case 32:\n return magnitude | 0; // Reinterpret as i32\n }\n}\n\n/**\n * Converts an unsigned 64-bit magnitude back to a signed bigint.\n */\nexport function fromMagnitude64(magnitude: bigint): bigint {\n const mask = 0xffffffffffffffffn;\n const signBit = 1n << 63n;\n const maskedMag = magnitude & mask;\n if ((maskedMag & signBit) !== 0n) {\n // Negative value - convert from two's complement\n return maskedMag - (1n << 64n);\n }\n return maskedMag;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/random_number_generator.rs\n\nimport { wideMulU32, wideMulU64 } from \"./widening.js\";\nimport {\n toMagnitude,\n toMagnitude64 as _toMagnitude64,\n fromMagnitude as _fromMagnitude,\n fromMagnitude64 as _fromMagnitude64,\n} from \"./magnitude.js\";\n\n/**\n * Interface for random number generators.\n * This is the TypeScript equivalent of Rust's RandomNumberGenerator trait\n * which extends RngCore + CryptoRng.\n *\n * This is compatible with the RandomNumberGenerator Swift protocol used\n * in MacOS and iOS, which is important for cross-platform testing.\n */\nexport interface RandomNumberGenerator {\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number;\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint;\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillBytes(dest: Uint8Array): void;\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n */\n randomData(size: number): Uint8Array;\n\n /**\n * Fills the given Uint8Array with random bytes.\n * Alias for fillBytes for compatibility.\n */\n fillRandomData(data: Uint8Array): void;\n}\n\n/**\n * Returns a Uint8Array of random bytes of the given size.\n */\nexport function rngRandomData(rng: RandomNumberGenerator, size: number): Uint8Array {\n const data = new Uint8Array(size);\n rng.fillRandomData(data);\n return data;\n}\n\n/**\n * Fills the given Uint8Array with random bytes.\n */\nexport function rngFillRandomData(rng: RandomNumberGenerator, data: Uint8Array): void {\n rng.fillRandomData(data);\n}\n\n/**\n * Returns a random value that is less than the given upper bound.\n *\n * Uses Lemire's \"nearly divisionless\" method for generating random\n * integers in an interval. For a detailed explanation, see:\n * https://arxiv.org/abs/1805.10941\n *\n * @param rng - The random number generator to use\n * @param upperBound - The upper bound for the randomly generated value. Must be non-zero.\n * @returns A random value in the range [0, upperBound). Every value in the range is equally likely.\n */\nexport function rngNextWithUpperBound(rng: RandomNumberGenerator, upperBound: bigint): bigint {\n if (upperBound === 0n) {\n throw new Error(\"upperBound must be non-zero\");\n }\n\n // We use Lemire's \"nearly divisionless\" method for generating random\n // integers in an interval. For a detailed explanation, see:\n // https://arxiv.org/abs/1805.10941\n\n const bitmask = 0xffffffffffffffffn; // u64 max\n let random = rng.nextU64() & bitmask;\n let m = wideMulU64(random, upperBound);\n\n if (m[0] < upperBound) {\n // t = (0 - upperBound) % upperBound\n const negUpperBound = (bitmask + 1n - upperBound) & bitmask;\n const t = negUpperBound % upperBound;\n while (m[0] < t) {\n random = rng.nextU64() & bitmask;\n m = wideMulU64(random, upperBound);\n }\n }\n\n return m[1];\n}\n\n/**\n * Returns a random 32-bit value that is less than the given upper bound.\n * This matches Rust's behavior when called with u32 type.\n *\n * Uses Lemire's \"nearly divisionless\" method with 32-bit arithmetic.\n *\n * @param rng - The random number generator to use\n * @param upperBound - The upper bound for the randomly generated value. Must be non-zero and fit in u32.\n * @returns A random u32 value in the range [0, upperBound).\n */\nexport function rngNextWithUpperBoundU32(rng: RandomNumberGenerator, upperBound: number): number {\n if (upperBound === 0) {\n throw new Error(\"upperBound must be non-zero\");\n }\n\n const upperBoundU32 = upperBound >>> 0;\n const bitmask = 0xffffffff;\n\n // Get random and mask to 32 bits (matches Rust behavior)\n let random = Number(rng.nextU64() & BigInt(bitmask));\n let m = wideMulU32(random, upperBoundU32);\n\n if (Number(m[0]) < upperBoundU32) {\n // t = (0 - upperBound) % upperBound (wrapping subtraction)\n const t = ((bitmask + 1 - upperBoundU32) >>> 0) % upperBoundU32;\n while (Number(m[0]) < t) {\n random = Number(rng.nextU64() & BigInt(bitmask));\n m = wideMulU32(random, upperBoundU32);\n }\n }\n\n return Number(m[1]);\n}\n\n/**\n * Returns a random value within the specified range [start, end) using 32-bit arithmetic.\n * This matches Rust's behavior when called with i32 types.\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive) as i32\n * @param end - The upper bound (exclusive) as i32\n * @returns A random i32 value within the bounds\n */\nexport function rngNextInRangeI32(rng: RandomNumberGenerator, start: number, end: number): number {\n if (start >= end) {\n throw new Error(\"start must be less than end\");\n }\n\n const startI32 = start | 0;\n const endI32 = end | 0;\n const delta = toMagnitude(endI32 - startI32, 32);\n\n if (delta === 0xffffffff) {\n return rng.nextU32() | 0;\n }\n\n const random = rngNextWithUpperBoundU32(rng, delta);\n return (startI32 + random) | 0;\n}\n\n/**\n * Returns a random value within the specified range [start, end).\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive)\n * @param end - The upper bound (exclusive)\n * @returns A random value within the bounds of the range\n */\nexport function rngNextInRange(rng: RandomNumberGenerator, start: bigint, end: bigint): bigint {\n if (start >= end) {\n throw new Error(\"start must be less than end\");\n }\n\n const delta = end - start;\n\n // If delta covers the entire range, just return a random value\n const maxU64 = 0xffffffffffffffffn;\n if (delta === maxU64) {\n return rng.nextU64();\n }\n\n const random = rngNextWithUpperBound(rng, delta);\n return start + random;\n}\n\n/**\n * Returns a random value within the specified closed range [start, end].\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive)\n * @param end - The upper bound (inclusive)\n * @returns A random value within the bounds of the range\n */\nexport function rngNextInClosedRange(\n rng: RandomNumberGenerator,\n start: bigint,\n end: bigint,\n): bigint {\n if (start > end) {\n throw new Error(\"start must be less than or equal to end\");\n }\n\n const delta = end - start;\n\n // If delta covers the entire range, just return a random value\n const maxU64 = 0xffffffffffffffffn;\n if (delta === maxU64) {\n return rng.nextU64();\n }\n\n const random = rngNextWithUpperBound(rng, delta + 1n);\n return start + random;\n}\n\n/**\n * Returns a random value within the specified closed range [start, end] for i32 values.\n * Convenience function that handles signed 32-bit integers.\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive) as i32\n * @param end - The upper bound (inclusive) as i32\n * @returns A random i32 value within the bounds of the range\n */\nexport function rngNextInClosedRangeI32(\n rng: RandomNumberGenerator,\n start: number,\n end: number,\n): number {\n if (start > end) {\n throw new Error(\"start must be less than or equal to end\");\n }\n\n // Convert to i32\n const startI32 = start | 0;\n const endI32 = end | 0;\n\n // Calculate delta as u32 magnitude\n const delta = toMagnitude(endI32 - startI32, 32);\n\n // If delta covers the entire u32 range, just return a random value\n if (delta === 0xffffffff) {\n return rng.nextU32() | 0;\n }\n\n const random = rngNextWithUpperBoundU32(rng, delta + 1);\n return (startI32 + random) | 0;\n}\n\n/**\n * Returns a fixed-size array of random bytes.\n *\n * @param rng - The random number generator to use\n * @param size - The size of the array to return\n * @returns A Uint8Array of the specified size filled with random bytes\n */\nexport function rngRandomArray(rng: RandomNumberGenerator, size: number): Uint8Array {\n const data = new Uint8Array(size);\n rng.fillRandomData(data);\n return data;\n}\n\n/**\n * Returns a random boolean value.\n *\n * @param rng - The random number generator to use\n * @returns A random boolean\n */\nexport function rngRandomBool(rng: RandomNumberGenerator): boolean {\n return (rng.nextU32() & 1) === 0;\n}\n\n/**\n * Returns a random 32-bit unsigned integer.\n *\n * @param rng - The random number generator to use\n * @returns A random u32 value\n */\nexport function rngRandomU32(rng: RandomNumberGenerator): number {\n return rng.nextU32();\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/secure_random.rs\n\nimport type { RandomNumberGenerator } from \"./random-number-generator.js\";\n\n/**\n * Detects the crypto API available in the current environment.\n * Works in both Node.js and browser environments.\n */\nfunction getCrypto(): Crypto {\n // Browser environment\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.crypto !== null &&\n globalThis.crypto !== undefined\n ) {\n return globalThis.crypto;\n }\n // Node.js environment - globalThis.crypto is also available in Node.js >= 15\n if (typeof globalThis.crypto !== \"undefined\") {\n return globalThis.crypto;\n }\n throw new Error(\"No crypto API available in this environment\");\n}\n\n/**\n * Generate a Uint8Array of cryptographically strong random bytes of the given size.\n */\nexport function randomData(size: number): Uint8Array {\n const data = new Uint8Array(size);\n fillRandomData(data);\n return data;\n}\n\n/**\n * Fill the given Uint8Array with cryptographically strong random bytes.\n */\nexport function fillRandomData(data: Uint8Array): void {\n const crypto = getCrypto();\n crypto.getRandomValues(data);\n}\n\n/**\n * Returns the next cryptographically strong random 64-bit unsigned integer.\n */\nexport function nextU64(): bigint {\n const data = new Uint8Array(8);\n fillRandomData(data);\n const view = new DataView(data.buffer);\n return view.getBigUint64(0, true); // little-endian\n}\n\n/**\n * A random number generator that can be used as a source of\n * cryptographically-strong randomness.\n *\n * Uses the Web Crypto API (crypto.getRandomValues) which is available\n * in both browsers and Node.js >= 15.\n */\nexport class SecureRandomNumberGenerator implements RandomNumberGenerator {\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number {\n const data = new Uint8Array(4);\n fillRandomData(data);\n const view = new DataView(data.buffer);\n return view.getUint32(0, true) >>> 0; // little-endian, unsigned\n }\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint {\n return nextU64();\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillBytes(dest: Uint8Array): void {\n fillRandomData(dest);\n }\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n */\n randomData(size: number): Uint8Array {\n return randomData(size);\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillRandomData(data: Uint8Array): void {\n fillRandomData(data);\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/seeded_random.rs\n\nimport type { RandomNumberGenerator } from \"./random-number-generator.js\";\n\n/**\n * Xoshiro256** state\n * Based on xoshiro256** 1.0 by David Blackman and Sebastiano Vigna\n * https://prng.di.unimi.it/\n */\ninterface Xoshiro256State {\n s0: bigint;\n s1: bigint;\n s2: bigint;\n s3: bigint;\n}\n\n/**\n * Rotate left for 64-bit bigint\n */\nfunction rotl(x: bigint, k: number): bigint {\n const mask = 0xffffffffffffffffn;\n return ((x << BigInt(k)) | (x >> BigInt(64 - k))) & mask;\n}\n\n/**\n * Xoshiro256** PRNG implementation\n * This is the same algorithm used by rand_xoshiro in Rust\n */\nfunction xoshiro256StarStar(state: Xoshiro256State): bigint {\n const mask = 0xffffffffffffffffn;\n\n // result = rotl(s1 * 5, 7) * 9\n const result = (rotl((state.s1 * 5n) & mask, 7) * 9n) & mask;\n\n // t = s1 << 17\n const t = (state.s1 << 17n) & mask;\n\n // Update state\n state.s2 ^= state.s0;\n state.s3 ^= state.s1;\n state.s1 ^= state.s2;\n state.s0 ^= state.s3;\n\n state.s2 ^= t;\n state.s3 = rotl(state.s3, 45);\n\n return result;\n}\n\n/**\n * A random number generator that can be used as a source of deterministic\n * pseudo-randomness for testing purposes.\n *\n * Uses the Xoshiro256** algorithm, which is the same algorithm used by\n * rand_xoshiro in Rust. This ensures cross-platform compatibility with\n * the Rust implementation.\n *\n * WARNING: This is NOT cryptographically secure and should only be used\n * for testing purposes.\n */\nexport class SeededRandomNumberGenerator implements RandomNumberGenerator {\n private readonly state: Xoshiro256State;\n\n /**\n * Creates a new seeded random number generator.\n *\n * The seed should be a 256-bit value, represented as an array of 4 64-bit\n * integers (as bigints). For the output distribution to look random, the seed\n * should not have any obvious patterns, like all zeroes or all ones.\n *\n * This is not cryptographically secure, and should only be used for\n * testing purposes.\n *\n * @param seed - Array of 4 64-bit unsigned integers as bigints\n */\n constructor(seed: [bigint, bigint, bigint, bigint]) {\n this.state = {\n s0: seed[0] & 0xffffffffffffffffn,\n s1: seed[1] & 0xffffffffffffffffn,\n s2: seed[2] & 0xffffffffffffffffn,\n s3: seed[3] & 0xffffffffffffffffn,\n };\n }\n\n /**\n * Creates a new seeded random number generator from a seed array.\n * Convenience method that accepts numbers and converts to bigints.\n *\n * @param seed - Array of 4 64-bit unsigned integers\n */\n static fromSeed(seed: [bigint, bigint, bigint, bigint]): SeededRandomNumberGenerator {\n return new SeededRandomNumberGenerator(seed);\n }\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint {\n return xoshiro256StarStar(this.state);\n }\n\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number {\n return Number(this.nextU64() & 0xffffffffn) >>> 0;\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n *\n * Note: This implementation matches the Rust behavior exactly -\n * it uses one nextU64() call per byte (taking only the low byte),\n * which matches the Swift version's behavior.\n */\n fillBytes(dest: Uint8Array): void {\n for (let i = 0; i < dest.length; i++) {\n dest[i] = Number(this.nextU64() & 0xffn);\n }\n }\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n *\n * This might not be the most efficient implementation,\n * but it works the same as the Swift version.\n */\n randomData(size: number): Uint8Array {\n const data = new Uint8Array(size);\n for (let i = 0; i < size; i++) {\n data[i] = Number(this.nextU64() & 0xffn);\n }\n return data;\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillRandomData(data: Uint8Array): void {\n this.fillBytes(data);\n }\n}\n\n/**\n * The standard test seed used across all Blockchain Commons implementations.\n */\nexport const TEST_SEED: [bigint, bigint, bigint, bigint] = [\n 17295166580085024720n,\n 422929670265678780n,\n 5577237070365765850n,\n 7953171132032326923n,\n];\n\n/**\n * Creates a seeded random number generator with a fixed seed.\n * This is useful for reproducible testing across different platforms.\n */\nexport function makeFakeRandomNumberGenerator(): SeededRandomNumberGenerator {\n return new SeededRandomNumberGenerator(TEST_SEED);\n}\n\n/**\n * Creates a Uint8Array of random data with a fixed seed.\n * This is useful for reproducible testing.\n *\n * @param size - The number of bytes to generate\n * @returns A Uint8Array of pseudo-random bytes\n */\nexport function fakeRandomData(size: number): Uint8Array {\n return makeFakeRandomNumberGenerator().randomData(size);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/widening.ts","../src/magnitude.ts","../src/random-number-generator.ts","../src/secure-random.ts","../src/seeded-random.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// The below is so we don't have to use #![feature(bigint_helper_methods)]\n// Ported from bc-rand-rust/src/widening.rs\n\n/**\n * Wide multiplication result type - returns (low, high) parts.\n * For a multiplication of two N-bit values, the result is 2N bits\n * split into two N-bit parts.\n */\nexport type WideMulResult = [bigint, bigint];\n\n/**\n * Performs wide multiplication for unsigned integers.\n * Returns (low, high) parts of the full-width result.\n *\n * This is equivalent to Rust's widening_mul for unsigned types.\n */\nexport function wideMul(a: bigint, b: bigint, bits: number): WideMulResult {\n const mask = (1n << BigInt(bits)) - 1n;\n const wide = (a & mask) * (b & mask);\n const low = wide & mask;\n const high = wide >> BigInt(bits);\n return [low, high];\n}\n\n/**\n * Wide multiplication for 8-bit unsigned integers.\n * @param a - First 8-bit value\n * @param b - Second 8-bit value\n * @returns Tuple of (low 8 bits, high 8 bits)\n */\nexport function wideMulU8(a: number, b: number): [number, number] {\n const wide = (a & 0xff) * (b & 0xff);\n return [wide & 0xff, (wide >> 8) & 0xff];\n}\n\n/**\n * Wide multiplication for 16-bit unsigned integers.\n * @param a - First 16-bit value\n * @param b - Second 16-bit value\n * @returns Tuple of (low 16 bits, high 16 bits)\n */\nexport function wideMulU16(a: number, b: number): [number, number] {\n const wide = (a & 0xffff) * (b & 0xffff);\n return [wide & 0xffff, (wide >>> 16) & 0xffff];\n}\n\n/**\n * Wide multiplication for 32-bit unsigned integers.\n * @param a - First 32-bit value\n * @param b - Second 32-bit value\n * @returns Tuple of (low 32 bits, high 32 bits) as bigints\n */\nexport function wideMulU32(a: number, b: number): [bigint, bigint] {\n const aBig = BigInt(a >>> 0);\n const bBig = BigInt(b >>> 0);\n const wide = aBig * bBig;\n return [wide & 0xffffffffn, wide >> 32n];\n}\n\n/**\n * Wide multiplication for 64-bit unsigned integers.\n * @param a - First 64-bit value as bigint\n * @param b - Second 64-bit value as bigint\n * @returns Tuple of (low 64 bits, high 64 bits) as bigints\n */\nexport function wideMulU64(a: bigint, b: bigint): [bigint, bigint] {\n const mask64 = 0xffffffffffffffffn;\n const wide = (a & mask64) * (b & mask64);\n return [wide & mask64, wide >> 64n];\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/magnitude.rs\n\n/**\n * Converts a signed integer to its unsigned magnitude.\n * For positive numbers, returns the number unchanged.\n * For negative numbers, returns the absolute value (wrapping for MIN values).\n *\n * This matches Rust's wrapping_abs() behavior.\n */\nexport function toMagnitude(value: number, bits: 8 | 16 | 32): number {\n switch (bits) {\n case 8: {\n // i8 to u8: wrapping_abs\n const i8Value = (value << 24) >> 24; // Sign extend to i8\n return Math.abs(i8Value) & 0xff;\n }\n case 16: {\n // i16 to u16: wrapping_abs\n const i16Value = (value << 16) >> 16; // Sign extend to i16\n return Math.abs(i16Value) & 0xffff;\n }\n case 32: {\n // i32 to u32: wrapping_abs\n const i32Value = value | 0; // Force to i32\n // Handle MIN_VALUE specially (wrapping behavior)\n if (i32Value === -2147483648) {\n return 2147483648; // Returns as positive\n }\n return Math.abs(i32Value) >>> 0; // Convert to unsigned\n }\n }\n}\n\n/**\n * Converts a signed bigint to its unsigned magnitude for 64-bit values.\n */\nexport function toMagnitude64(value: bigint): bigint {\n const mask = 0xffffffffffffffffn;\n // Handle negative values\n if (value < 0n) {\n // Wrapping absolute value\n const absValue = -value;\n return absValue & mask;\n }\n return value & mask;\n}\n\n/**\n * Converts an unsigned magnitude back to a signed value.\n * Simply reinterprets the bits.\n */\nexport function fromMagnitude(magnitude: number, bits: 8 | 16 | 32): number {\n switch (bits) {\n case 8:\n return (magnitude << 24) >> 24; // Sign extend from u8 to i8\n case 16:\n return (magnitude << 16) >> 16; // Sign extend from u16 to i16\n case 32:\n return magnitude | 0; // Reinterpret as i32\n }\n}\n\n/**\n * Converts an unsigned 64-bit magnitude back to a signed bigint.\n */\nexport function fromMagnitude64(magnitude: bigint): bigint {\n const mask = 0xffffffffffffffffn;\n const signBit = 1n << 63n;\n const maskedMag = magnitude & mask;\n if ((maskedMag & signBit) !== 0n) {\n // Negative value - convert from two's complement\n return maskedMag - (1n << 64n);\n }\n return maskedMag;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/random_number_generator.rs\n\nimport { wideMulU32, wideMulU64 } from \"./widening.js\";\nimport {\n toMagnitude,\n toMagnitude64 as _toMagnitude64,\n fromMagnitude as _fromMagnitude,\n fromMagnitude64 as _fromMagnitude64,\n} from \"./magnitude.js\";\n\n/**\n * Interface for random number generators.\n * This is the TypeScript equivalent of Rust's RandomNumberGenerator trait\n * which extends RngCore + CryptoRng.\n *\n * This is compatible with the RandomNumberGenerator Swift protocol used\n * in MacOS and iOS, which is important for cross-platform testing.\n */\nexport interface RandomNumberGenerator {\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number;\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint;\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillBytes(dest: Uint8Array): void;\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n */\n randomData(size: number): Uint8Array;\n\n /**\n * Fills the given Uint8Array with random bytes.\n * Alias for fillBytes for compatibility.\n */\n fillRandomData(data: Uint8Array): void;\n}\n\n/**\n * Returns a Uint8Array of random bytes of the given size.\n */\nexport function rngRandomData(rng: RandomNumberGenerator, size: number): Uint8Array {\n const data = new Uint8Array(size);\n rng.fillRandomData(data);\n return data;\n}\n\n/**\n * Fills the given Uint8Array with random bytes.\n */\nexport function rngFillRandomData(rng: RandomNumberGenerator, data: Uint8Array): void {\n rng.fillRandomData(data);\n}\n\n/**\n * Returns a random value that is less than the given upper bound.\n *\n * Uses Lemire's \"nearly divisionless\" method for generating random\n * integers in an interval. For a detailed explanation, see:\n * https://arxiv.org/abs/1805.10941\n *\n * @param rng - The random number generator to use\n * @param upperBound - The upper bound for the randomly generated value. Must be non-zero.\n * @returns A random value in the range [0, upperBound). Every value in the range is equally likely.\n */\nexport function rngNextWithUpperBound(rng: RandomNumberGenerator, upperBound: bigint): bigint {\n if (upperBound === 0n) {\n throw new Error(\"upperBound must be non-zero\");\n }\n\n // We use Lemire's \"nearly divisionless\" method for generating random\n // integers in an interval. For a detailed explanation, see:\n // https://arxiv.org/abs/1805.10941\n\n const bitmask = 0xffffffffffffffffn; // u64 max\n let random = rng.nextU64() & bitmask;\n let m = wideMulU64(random, upperBound);\n\n if (m[0] < upperBound) {\n // t = (0 - upperBound) % upperBound\n const negUpperBound = (bitmask + 1n - upperBound) & bitmask;\n const t = negUpperBound % upperBound;\n while (m[0] < t) {\n random = rng.nextU64() & bitmask;\n m = wideMulU64(random, upperBound);\n }\n }\n\n return m[1];\n}\n\n/**\n * Returns a random 32-bit value that is less than the given upper bound.\n * This matches Rust's behavior when called with u32 type.\n *\n * Uses Lemire's \"nearly divisionless\" method with 32-bit arithmetic.\n *\n * @param rng - The random number generator to use\n * @param upperBound - The upper bound for the randomly generated value. Must be non-zero and fit in u32.\n * @returns A random u32 value in the range [0, upperBound).\n */\nexport function rngNextWithUpperBoundU32(rng: RandomNumberGenerator, upperBound: number): number {\n if (upperBound === 0) {\n throw new Error(\"upperBound must be non-zero\");\n }\n\n const upperBoundU32 = upperBound >>> 0;\n const bitmask = 0xffffffff;\n\n // Get random and mask to 32 bits (matches Rust behavior)\n let random = Number(rng.nextU64() & BigInt(bitmask));\n let m = wideMulU32(random, upperBoundU32);\n\n if (Number(m[0]) < upperBoundU32) {\n // t = (0 - upperBound) % upperBound (wrapping subtraction)\n const t = ((bitmask + 1 - upperBoundU32) >>> 0) % upperBoundU32;\n while (Number(m[0]) < t) {\n random = Number(rng.nextU64() & BigInt(bitmask));\n m = wideMulU32(random, upperBoundU32);\n }\n }\n\n return Number(m[1]);\n}\n\n/**\n * Returns a random value within the specified range [start, end) using 32-bit arithmetic.\n * This matches Rust's behavior when called with i32 types.\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive) as i32\n * @param end - The upper bound (exclusive) as i32\n * @returns A random i32 value within the bounds\n */\nexport function rngNextInRangeI32(rng: RandomNumberGenerator, start: number, end: number): number {\n if (start >= end) {\n throw new Error(\"start must be less than end\");\n }\n\n const startI32 = start | 0;\n const endI32 = end | 0;\n const delta = toMagnitude(endI32 - startI32, 32);\n\n if (delta === 0xffffffff) {\n return rng.nextU32() | 0;\n }\n\n const random = rngNextWithUpperBoundU32(rng, delta);\n return (startI32 + random) | 0;\n}\n\n/**\n * Returns a random value within the specified range [start, end).\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive)\n * @param end - The upper bound (exclusive)\n * @returns A random value within the bounds of the range\n */\nexport function rngNextInRange(rng: RandomNumberGenerator, start: bigint, end: bigint): bigint {\n if (start >= end) {\n throw new Error(\"start must be less than end\");\n }\n\n const delta = end - start;\n\n // If delta covers the entire range, just return a random value\n const maxU64 = 0xffffffffffffffffn;\n if (delta === maxU64) {\n return rng.nextU64();\n }\n\n const random = rngNextWithUpperBound(rng, delta);\n return start + random;\n}\n\n/**\n * Returns a random value within the specified closed range [start, end].\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive)\n * @param end - The upper bound (inclusive)\n * @returns A random value within the bounds of the range\n */\nexport function rngNextInClosedRange(\n rng: RandomNumberGenerator,\n start: bigint,\n end: bigint,\n): bigint {\n if (start > end) {\n throw new Error(\"start must be less than or equal to end\");\n }\n\n const delta = end - start;\n\n // If delta covers the entire range, just return a random value\n const maxU64 = 0xffffffffffffffffn;\n if (delta === maxU64) {\n return rng.nextU64();\n }\n\n const random = rngNextWithUpperBound(rng, delta + 1n);\n return start + random;\n}\n\n/**\n * Returns a random value within the specified closed range [start, end] for i32 values.\n * Convenience function that handles signed 32-bit integers.\n *\n * @param rng - The random number generator to use\n * @param start - The lower bound (inclusive) as i32\n * @param end - The upper bound (inclusive) as i32\n * @returns A random i32 value within the bounds of the range\n */\nexport function rngNextInClosedRangeI32(\n rng: RandomNumberGenerator,\n start: number,\n end: number,\n): number {\n if (start > end) {\n throw new Error(\"start must be less than or equal to end\");\n }\n\n // Convert to i32\n const startI32 = start | 0;\n const endI32 = end | 0;\n\n // Calculate delta as u32 magnitude\n const delta = toMagnitude(endI32 - startI32, 32);\n\n // If delta covers the entire u32 range, just return a random value\n if (delta === 0xffffffff) {\n return rng.nextU32() | 0;\n }\n\n const random = rngNextWithUpperBoundU32(rng, delta + 1);\n return (startI32 + random) | 0;\n}\n\n/**\n * Returns a fixed-size array of random bytes.\n *\n * @param rng - The random number generator to use\n * @param size - The size of the array to return\n * @returns A Uint8Array of the specified size filled with random bytes\n */\nexport function rngRandomArray(rng: RandomNumberGenerator, size: number): Uint8Array {\n const data = new Uint8Array(size);\n rng.fillRandomData(data);\n return data;\n}\n\n/**\n * Returns a random boolean value.\n *\n * @param rng - The random number generator to use\n * @returns A random boolean\n */\nexport function rngRandomBool(rng: RandomNumberGenerator): boolean {\n return (rng.nextU32() & 1) === 0;\n}\n\n/**\n * Returns a random 32-bit unsigned integer.\n *\n * @param rng - The random number generator to use\n * @returns A random u32 value\n */\nexport function rngRandomU32(rng: RandomNumberGenerator): number {\n return rng.nextU32();\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/secure_random.rs\n\nimport type { RandomNumberGenerator } from \"./random-number-generator.js\";\n\n/**\n * Detects the crypto API available in the current environment.\n * Works in both Node.js and browser environments.\n */\nfunction getCrypto(): Crypto {\n // Browser environment\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.crypto !== null &&\n globalThis.crypto !== undefined\n ) {\n return globalThis.crypto;\n }\n // Node.js environment - globalThis.crypto is also available in Node.js >= 15\n if (typeof globalThis.crypto !== \"undefined\") {\n return globalThis.crypto;\n }\n throw new Error(\"No crypto API available in this environment\");\n}\n\n/**\n * Generate a Uint8Array of cryptographically strong random bytes of the given size.\n */\nexport function randomData(size: number): Uint8Array {\n const data = new Uint8Array(size);\n fillRandomData(data);\n return data;\n}\n\n/**\n * Fill the given Uint8Array with cryptographically strong random bytes.\n */\nexport function fillRandomData(data: Uint8Array): void {\n const crypto = getCrypto();\n crypto.getRandomValues(data as Uint8Array<ArrayBuffer>);\n}\n\n/**\n * Returns the next cryptographically strong random 64-bit unsigned integer.\n */\nexport function nextU64(): bigint {\n const data = new Uint8Array(8);\n fillRandomData(data);\n const view = new DataView(data.buffer);\n return view.getBigUint64(0, true); // little-endian\n}\n\n/**\n * A random number generator that can be used as a source of\n * cryptographically-strong randomness.\n *\n * Uses the Web Crypto API (crypto.getRandomValues) which is available\n * in both browsers and Node.js >= 15.\n */\nexport class SecureRandomNumberGenerator implements RandomNumberGenerator {\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number {\n const data = new Uint8Array(4);\n fillRandomData(data);\n const view = new DataView(data.buffer);\n return view.getUint32(0, true) >>> 0; // little-endian, unsigned\n }\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint {\n return nextU64();\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillBytes(dest: Uint8Array): void {\n fillRandomData(dest);\n }\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n */\n randomData(size: number): Uint8Array {\n return randomData(size);\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillRandomData(data: Uint8Array): void {\n fillRandomData(data);\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-rand-rust/src/seeded_random.rs\n\nimport type { RandomNumberGenerator } from \"./random-number-generator.js\";\n\n/**\n * Xoshiro256** state\n * Based on xoshiro256** 1.0 by David Blackman and Sebastiano Vigna\n * https://prng.di.unimi.it/\n */\ninterface Xoshiro256State {\n s0: bigint;\n s1: bigint;\n s2: bigint;\n s3: bigint;\n}\n\n/**\n * Rotate left for 64-bit bigint\n */\nfunction rotl(x: bigint, k: number): bigint {\n const mask = 0xffffffffffffffffn;\n return ((x << BigInt(k)) | (x >> BigInt(64 - k))) & mask;\n}\n\n/**\n * Xoshiro256** PRNG implementation\n * This is the same algorithm used by rand_xoshiro in Rust\n */\nfunction xoshiro256StarStar(state: Xoshiro256State): bigint {\n const mask = 0xffffffffffffffffn;\n\n // result = rotl(s1 * 5, 7) * 9\n const result = (rotl((state.s1 * 5n) & mask, 7) * 9n) & mask;\n\n // t = s1 << 17\n const t = (state.s1 << 17n) & mask;\n\n // Update state\n state.s2 ^= state.s0;\n state.s3 ^= state.s1;\n state.s1 ^= state.s2;\n state.s0 ^= state.s3;\n\n state.s2 ^= t;\n state.s3 = rotl(state.s3, 45);\n\n return result;\n}\n\n/**\n * A random number generator that can be used as a source of deterministic\n * pseudo-randomness for testing purposes.\n *\n * Uses the Xoshiro256** algorithm, which is the same algorithm used by\n * rand_xoshiro in Rust. This ensures cross-platform compatibility with\n * the Rust implementation.\n *\n * WARNING: This is NOT cryptographically secure and should only be used\n * for testing purposes.\n */\nexport class SeededRandomNumberGenerator implements RandomNumberGenerator {\n private readonly state: Xoshiro256State;\n\n /**\n * Creates a new seeded random number generator.\n *\n * The seed should be a 256-bit value, represented as an array of 4 64-bit\n * integers (as bigints). For the output distribution to look random, the seed\n * should not have any obvious patterns, like all zeroes or all ones.\n *\n * This is not cryptographically secure, and should only be used for\n * testing purposes.\n *\n * @param seed - Array of 4 64-bit unsigned integers as bigints\n */\n constructor(seed: [bigint, bigint, bigint, bigint]) {\n this.state = {\n s0: seed[0] & 0xffffffffffffffffn,\n s1: seed[1] & 0xffffffffffffffffn,\n s2: seed[2] & 0xffffffffffffffffn,\n s3: seed[3] & 0xffffffffffffffffn,\n };\n }\n\n /**\n * Creates a new seeded random number generator from a seed array.\n * Convenience method that accepts numbers and converts to bigints.\n *\n * @param seed - Array of 4 64-bit unsigned integers\n */\n static fromSeed(seed: [bigint, bigint, bigint, bigint]): SeededRandomNumberGenerator {\n return new SeededRandomNumberGenerator(seed);\n }\n\n /**\n * Returns the next random 64-bit unsigned integer as a bigint.\n */\n nextU64(): bigint {\n return xoshiro256StarStar(this.state);\n }\n\n /**\n * Returns the next random 32-bit unsigned integer.\n */\n nextU32(): number {\n return Number(this.nextU64() & 0xffffffffn) >>> 0;\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n *\n * Note: This implementation matches the Rust behavior exactly -\n * it uses one nextU64() call per byte (taking only the low byte),\n * which matches the Swift version's behavior.\n */\n fillBytes(dest: Uint8Array): void {\n for (let i = 0; i < dest.length; i++) {\n dest[i] = Number(this.nextU64() & 0xffn);\n }\n }\n\n /**\n * Returns a Uint8Array of random bytes of the given size.\n *\n * This might not be the most efficient implementation,\n * but it works the same as the Swift version.\n */\n randomData(size: number): Uint8Array {\n const data = new Uint8Array(size);\n for (let i = 0; i < size; i++) {\n data[i] = Number(this.nextU64() & 0xffn);\n }\n return data;\n }\n\n /**\n * Fills the given Uint8Array with random bytes.\n */\n fillRandomData(data: Uint8Array): void {\n this.fillBytes(data);\n }\n}\n\n/**\n * The standard test seed used across all Blockchain Commons implementations.\n */\nexport const TEST_SEED: [bigint, bigint, bigint, bigint] = [\n 17295166580085024720n,\n 422929670265678780n,\n 5577237070365765850n,\n 7953171132032326923n,\n];\n\n/**\n * Creates a seeded random number generator with a fixed seed.\n * This is useful for reproducible testing across different platforms.\n */\nexport function makeFakeRandomNumberGenerator(): SeededRandomNumberGenerator {\n return new SeededRandomNumberGenerator(TEST_SEED);\n}\n\n/**\n * Creates a Uint8Array of random data with a fixed seed.\n * This is useful for reproducible testing.\n *\n * @param size - The number of bytes to generate\n * @returns A Uint8Array of pseudo-random bytes\n */\nexport function fakeRandomData(size: number): Uint8Array {\n return makeFakeRandomNumberGenerator().randomData(size);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bcts/rand",
3
- "version": "1.0.0-alpha.21",
3
+ "version": "1.0.0-alpha.23",
4
4
  "type": "module",
5
5
  "description": "Blockchain Commons Random Number Utilities for TypeScript",
6
6
  "license": "BSD-2-Clause-Patent",
@@ -57,12 +57,12 @@
57
57
  "@bcts/eslint": "^0.1.0",
58
58
  "@bcts/tsconfig": "^0.1.0",
59
59
  "@eslint/js": "^10.0.1",
60
- "@types/node": "^25.3.2",
61
- "eslint": "^10.0.2",
60
+ "@types/node": "^25.6.0",
61
+ "eslint": "^10.2.1",
62
62
  "ts-node": "^10.9.2",
63
- "tsdown": "^0.20.3",
64
- "typedoc": "^0.28.17",
65
- "typescript": "^5.9.3",
66
- "vitest": "^4.0.18"
63
+ "tsdown": "^0.21.0",
64
+ "typedoc": "^0.28.19",
65
+ "typescript": "^6.0.3",
66
+ "vitest": "^4.1.5"
67
67
  }
68
68
  }
@@ -42,7 +42,7 @@ export function randomData(size: number): Uint8Array {
42
42
  */
43
43
  export function fillRandomData(data: Uint8Array): void {
44
44
  const crypto = getCrypto();
45
- crypto.getRandomValues(data);
45
+ crypto.getRandomValues(data as Uint8Array<ArrayBuffer>);
46
46
  }
47
47
 
48
48
  /**