@azghr/debias
v0.1.0
Published
Debias a biased bitstream (e.g. from a hardware/quantum RNG) with the Von Neumann extractor and an optional XOR-fold whitener. Classical, zero deps. NOT a cryptographic RNG.
Maintainers
Readme
@azghr/debias
Debias a biased bitstream (e.g. from a hardware/quantum RNG) with the Von Neumann extractor and an optional XOR-fold whitener. Classical, zero deps. NOT a cryptographic RNG.
The problem
Hardware and quantum RNGs emit biased bitstreams. You must debias them before use, but the classic Von Neumann extractor is subtle to implement correctly. Standalone debiasing utilities are scarce and often untested on edge cases. This fills that gap for anyone consuming hardware/QRNG feeds in research, IoT, or novelty APIs.
Install
npm install @azghr/debias
# or
pnpm add @azghr/debias
# or
yarn add @azghr/debiasUse
import { vonNeumann, bias } from "@azghr/debias";
const biasedBits = new Uint8Array([1, 1, 1, 0, 0, 0, 1, 0]);
console.log(bias(biasedBits)); // 0.125 (biased)
const debiasedBits = vonNeumann(biasedBits);
console.log(bias(debiasedBits)); // 0.0 (unbiased)Real-world hardware QRNG processing
import { vonNeumann, bias, packBytes } from "@azghr/debias";
const qrngBits = generateFromHardwareQRNG(100000);
console.log("Raw bias:", bias(qrngBits)); // 0.201
const debiased = vonNeumann(qrngBits);
console.log("Debiased:", bias(debiased)); // 0.002
const packed = packBytes(debiased);
console.log("Size:", packed.length, "bytes"); // Efficient storageXOR-fold for problematic sources
import { xorFold } from "@azghr/debias";
// All equal pairs (Von Neumann produces nothing)
const problematic = new Uint8Array([0, 0, 1, 1, 0, 0, 1, 1]);
const whitened = xorFold(problematic, 4);
console.log(whitened); // [0, 0, 0, 0] - still processes dataAPI
vonNeumann(bits: Bits): Bits
Applies Von Neumann extractor: 01→0, 10→1, equal pairs discarded. Trailing odd bit ignored. Output length varies (≈ input * p(1-p)).
bits: Input bitstream (elements must be0or1)- Returns: Debias bitstream
- Throws:
InvalidBitif invalid input
xorFold(bits: Bits, blockSize?: number): Bits
XOR-folds by reshaping into blocks and XORing corresponding positions. Weaker than Von Neumann but handles problematic sources.
bits: Input bitstream (elements must be0or1)blockSize: Block size (default:2, must be ≥ 1)- Returns: Whitened bitstream
- Throws:
InvalidBitif invalid input,ErrorifblockSize < 1
bias(bits: Bits): number
Returns mean(bits) - 0.5 (estimates P(1) - 0.5). Returns 0 for empty input.
bits: Input bitstream (elements must be0or1)- Returns: Bias measurement
- Throws:
InvalidBitif invalid input
packBytes(bits: Bits): Uint8Array / unpackBytes(bytes: Uint8Array): Bits
MSB-first bit packing/unpacking. Non-multiple-of-8 inputs padded with zeros.
packBytes: Returns packed bytesunpackBytes: Returns 8 * bytes.length bits- Throws:
InvalidBitif invalid input (packBytes only)
InvalidBit extends Error
Thrown when bit value is invalid. Contains readonly index: number.
Security Notice
NOT FOR CRYPTOGRAPHIC USE — assumes independent bits. For crypto, use WebCrypto API or crypto.randomBytes().
Non-goals
This does NOT: generate random numbers, handle correlated sources (use Toeplitz/hashing), estimate entropy beyond bias, or replace CSPRNGs.
TypeScript note
Full TypeScript support included. Exported Bits type is Uint8Array (elements must be 0 or 1).
License
MIT
