@hicaru/chacharand.js
Version:
Pure JavaScript implementation of ChaCha8/12/20 random number generator
148 lines • 6.3 kB
TypeScript
/**
* A cryptographically secure random number generator that uses the ChaCha algorithm.
* Based on the Rust `rand_chacha` crate implementation.
*/
export declare class ChaChaRng {
private core;
private buffer;
private index;
private rounds;
private constructor();
/**
* Creates a new ChaChaRng instance from a 32-byte seed.
* Uses a default nonce (stream ID 0).
* @param seed The 32-byte seed.
* @param rounds The number of rounds (8, 12, or 20).
* @returns A new ChaChaRng instance.
*/
static fromSeed(seed: Uint8Array, rounds: 8 | 12 | 20): ChaChaRng;
/**
* Creates a new ChaChaRng instance from a 64-bit integer seed.
* Uses a simple seeding algorithm derived from PCG to initialize the 32-byte seed.
* @param state The initial 64-bit seed value (as bigint).
* @param rounds The number of rounds (8, 12, or 20).
* @returns A new ChaChaRng instance.
*/
static fromU64Seed(state: bigint, rounds: 8 | 12 | 20): ChaChaRng;
private static pcg32;
private refill;
/**
* Generates the next random u32 value.
* @returns A random unsigned 32-bit integer.
*/
nextU32(): number;
/**
* Generates the next random u8 value.
* @returns A random unsigned 8-bit integer.
*/
nextU8(): number;
/**
* Generates the next random u64 value (as bigint).
* @returns A random unsigned 64-bit integer (bigint).
*/
nextU64(): bigint;
/**
* Fills the given byte array with random bytes.
* @param bytes The Uint8Array to fill.
*/
fillBytes(bytes: Uint8Array): void;
/**
* Generates a random u64 (bigint) within the specified range.
* Matches the behavior of Rust's `rand::Rng::gen_range` for u64, using
* Canon's method (potentially biased, matching Rust's default).
* @param low The lower bound of the range (inclusive).
* @param high The upper bound of the range.
* @param inclusive If true, the range is [low, high]. If false, the range is [low, high). Defaults to false.
* @returns A random bigint within the specified range.
* @throws Error if the range is invalid (e.g., low > high).
*/
genRangeU64(low: bigint, high: bigint, inclusive?: boolean): bigint;
/**
* Alias for genRangeU64. Generates a random u64 (bigint) within the specified range.
* Matches the behavior of Rust's `rand::Rng::gen_range` for u64.
* @param low The lower bound of the range (inclusive).
* @param high The upper bound of the range.
* @param inclusive If true, the range is [low, high]. If false, the range is [low, high). Defaults to false.
* @returns A random bigint within the specified range.
* @throws Error if the range is invalid (e.g., low > high).
*/
gen_range_u64(low: bigint, high: bigint, inclusive?: boolean): bigint;
/**
* Generates a random u32 within the specified exclusive range [low, high).
* Uses rejection sampling for unbiased results.
* @param low The lower bound (inclusive).
* @param high The upper bound (exclusive).
* @returns A random number within the range.
* @throws Error if low >= high.
*/
genRangeU32(low: number, high: number): number;
/**
* Generates a random i32 within the specified exclusive range [low, high).
* @param low The lower bound (inclusive).
* @param high The upper bound (exclusive).
* @returns A random number within the range.
* @throws Error if low >= high.
*/
genRangeI32(low: number, high: number): number;
/**
* Generates a random i64 (bigint) within the specified exclusive range [low, high).
* @param low The lower bound (inclusive).
* @param high The upper bound (exclusive).
* @returns A random bigint within the range.
* @throws Error if low >= high.
*/
genRangeI64(low: bigint, high: bigint): bigint;
/**
* Generates a random f64 (number) within the specified exclusive range [low, high).
* Uses 53 bits of precision from the generator.
* @param low The lower bound (inclusive).
* @param high The upper bound (exclusive).
* @returns A random number within the range.
* @throws Error if low >= high or bounds are not finite.
*/
genRangeF64(low: number, high: number): number;
/**
* Gets the current position within the generator's output stream, measured in 32-bit words.
* This is a 68-bit value (combining the 64-bit block counter and 4-bit word index within a block).
* @returns The current absolute word position as a bigint.
*/
getWordPos(): bigint;
/**
* Sets the current position within the generator's output stream.
* The position is measured in 32-bit words from the beginning of the stream.
* This will refill the internal buffer.
* @param wordOffset The absolute word position to seek to (as bigint).
*/
setWordPos(wordOffset: bigint): void;
/**
* Sets the stream number (nonce). This allows generating multiple independent sequences
* from the same seed.
* Behavior matches Rust's rand_chacha: if the buffer is not fully consumed,
* the current position is preserved, but future generated blocks will use the new stream ID.
* @param stream The 64-bit stream ID (as bigint).
*/
setStream(stream: bigint): void;
/**
* Gets the current stream number (nonce).
* @returns The current 64-bit stream ID (as bigint).
*/
getStream(): bigint;
/**
* Gets the seed used to initialize the generator.
* @returns The 32-byte seed as a Uint8Array.
*/
getSeed(): Uint8Array;
/**
* Creates a clone of the current RNG state. The clone will produce the
* same sequence of numbers as the original from this point forward.
* @returns A new ChaChaRng instance with the same state.
*/
clone(): ChaChaRng;
}
/** Factory function for ChaCha8Rng. */
export declare const ChaCha8Rng: (seed: Uint8Array) => ChaChaRng;
/** Factory function for ChaCha12Rng. */
export declare const ChaCha12Rng: (seed: Uint8Array) => ChaChaRng;
/** Factory function for ChaCha20Rng. */
export declare const ChaCha20Rng: (seed: Uint8Array) => ChaChaRng;
//# sourceMappingURL=index.d.ts.map