UNPKG

@scintilla-network/signatures

Version:

Enhanced signature and key exchange functions for blockchain and crypto applications, including post-quantum algorithms

111 lines (104 loc) 3.12 kB
/** * @typedef {import('../types.js').Bytes} Bytes */ /** * Check if value is a positive bigint * @param {unknown} n - Value to check * @returns {boolean} True if value is a positive bigint */ export function isPositiveBigInt(n) { return typeof n === 'bigint' && n >= 0n; } /** * Check if number is in range [min, max) * @param {bigint} n - Number to check * @param {bigint} min - Minimum value (inclusive) * @param {bigint} max - Maximum value (exclusive) * @returns {boolean} True if number is in range */ export function inRange(n, min, max) { return isPositiveBigInt(n) && isPositiveBigInt(min) && isPositiveBigInt(max) && min <= n && n < max; } /** * Assert that number is in range [min, max) * @param {string} name - Name of value for error message * @param {bigint} n - Number to check * @param {bigint} min - Minimum value (inclusive) * @param {bigint} max - Maximum value (exclusive) * @throws {Error} If number is not in range */ export function assertInRange(name, n, min, max) { if (!inRange(n, min, max)) { throw new Error(`${name} must be in range [${min}, ${max})`); } } /** * Calculate number of bits in a bigint * @param {bigint} n - Number to check * @returns {number} Number of bits * @throws {Error} If input is invalid */ export function bitLength(n) { if (!isPositiveBigInt(n)) { throw new Error('Input must be a positive bigint'); } let len = 0; while (n > 0n) { n >>= 1n; len++; } return len; } /** * Get bit at position * @param {bigint} n - Number to check * @param {number} pos - Bit position (0-based) * @returns {bigint} Bit value (0n or 1n) * @throws {Error} If inputs are invalid */ export function getBit(n, pos) { if (!isPositiveBigInt(n)) { throw new Error('First argument must be a positive bigint'); } if (typeof pos !== 'number' || pos < 0) { throw new Error('Position must be a non-negative number'); } return (n >> BigInt(pos)) & 1n; } /** * Set bit at position * @param {bigint} n - Number to modify * @param {number} pos - Bit position (0-based) * @param {boolean} value - Bit value * @returns {bigint} Modified number * @throws {Error} If inputs are invalid */ export function setBit(n, pos, value) { if (!isPositiveBigInt(n)) { throw new Error('First argument must be a positive bigint'); } if (typeof pos !== 'number' || pos < 0) { throw new Error('Position must be a non-negative number'); } if (typeof value !== 'boolean') { throw new Error('Value must be a boolean'); } const mask = 1n << BigInt(pos); if (value) { return n | mask; // Set bit using OR } else { return n & ~mask; // Clear bit using AND with inverted mask } } /** * Create bit mask of n bits * @param {number} n - Number of bits * @returns {bigint} Bit mask * @throws {Error} If input is invalid */ export function bitMask(n) { if (typeof n !== 'number' || n < 1) { throw new Error('Input must be a positive number'); } return (1n << BigInt(n)) - 1n; }