Fact-checked by Grok 2 weeks ago

Permuted congruential generator

A permuted congruential generator (PCG) is a family of pseudorandom number generation algorithms that builds upon the linear congruential generator (LCG) framework by applying permutation functions to scramble the output, thereby enhancing statistical uniformity, period length, and resistance to prediction while maintaining computational efficiency. Developed by computer scientist Melissa E. O'Neill and first described in a 2014 technical report from Harvey Mudd College, PCGs address longstanding limitations in traditional RNGs by combining a simple LCG state transition with composable permutation primitives, such as xorshifts, multiplications, and rotations, to produce high-quality random sequences suitable for applications ranging from simulations to general-purpose computing. While offering improved predictability over plain LCGs, PCGs are not cryptographically secure. PCGs are characterized by their minimal state size—typically 64 or 128 bits—and exceptional performance, achieving output rates exceeding 40 gigabits per second on modern hardware while using compact code implementations of under 100 lines. Key variants, such as PCG-XSH-RS and PCG-RXS-M-XS, support output widths of 32 or 64 bits and full periods of $2^{64} or $2^{128}, with options for multiple independent streams (up to $2^{63} or more) via stream constants that ensure non-overlapping sequences. These generators excel in statistical testing, routinely passing the stringent BigCrush battery of TestU01 at effective dimensions as low as 36 bits, far surpassing many contemporaries like the Mersenne Twister in both quality and speed. The design of PCGs emphasizes practicality, with features like sequence jumping (advancing by arbitrary steps in constant time) and k-dimensional equidistribution for higher-order uniformity, making them ideal for parallel and distributed computing environments. By intentionally discarding output bits through permutations, PCGs obscure the internal state, providing strong unpredictability for non-cryptographic applications without the overhead of dedicated secure RNGs. Widely adopted in software ecosystems, including NumPy's PCG64 bit generator for Python and Rust's rand_pcg crate, PCGs have become a preferred choice for high-performance randomness in scientific computing, game development, and procedural content generation. Recent work as of 2025 has generalized PCG techniques beyond LCGs.

Background

Linear congruential generators

A linear congruential generator (LCG) is a type of pseudorandom number generator (PRNG) that produces a sequence of numbers through the iterative formula X_{n+1} = (a X_n + c) \mod m, where X_n is the current state (with X_0 as the initial seed), a is the multiplier, c is the increment, and m is the modulus, all of which are non-negative integers with m > 0. This algorithm was first proposed by D. H. Lehmer in 1949 as a method for generating random digits on early electronic computers, such as the ENIAC, and it became a foundational technique for pseudorandom number generation in scientific computing. LCGs gained widespread adoption in the mid-20th century, notably through implementations like IBM's RANDU in the 1960s and 1970s, which used parameters a = 65539, c = 0, and m = 2^{31} for simulations in physics and engineering. The period of an LCG—the length before the sequence repeats—depends critically on the choice of parameters and is at most m. To achieve the full period of m, the parameters must satisfy the Hull-Dobell theorem conditions: c and m must be coprime (i.e., \gcd(c, m) = 1); a - 1 must be divisible by every prime factor of m; and if $4dividesm, then $4 must divide a - 1. The output of an LCG is typically the fractional value U_n = X_n / m (yielding numbers in [0, 1)$) or the low-order bits of X_n$ for integer outputs, allowing adaptation for various applications like Monte Carlo simulations. A well-known example uses parameters from Numerical Recipes: m = 2^{32}, a = 1664525, and c = 1013904223, which satisfy the full-period conditions for efficient 32-bit computation. Permuted congruential generators build on this foundation by incorporating permutation steps to address certain statistical shortcomings of traditional LCGs.

Limitations of traditional LCGs

Traditional linear congruential generators (LCGs) exhibit poor statistical properties due to their inherent linear structure, which leads to visible lattice patterns in two- and three-dimensional scatter plots of generated points. These lattices arise because successive k-tuples of outputs lie on a limited number of parallel hyperplanes, violating the uniformity expected in multidimensional spaces. The spectral test, a key measure of LCG quality, quantifies this defect by evaluating the minimal distance between these hyperplanes; many LCGs, including well-chosen ones, fail this test in dimensions greater than two, resulting in detectable correlations that compromise their use in simulations. The least significant bits (LSBs) of LCG outputs suffer from particularly low entropy and periodicity issues, making them unsuitable for applications requiring high-quality randomness in lower bits. For an LCG with modulus m = 2^e, the lowest bit cycles with period 2, the lowest two bits with period 4, and in general, the lowest k bits have period dividing $2^k, far shorter than the full state period. This periodicity introduces strong correlations, especially when the increment c = 0 (multiplicative congruential generators), rendering the LSBs predictable and non-random. LCGs are highly predictable, as their internal state can be recovered from a small number of consecutive outputs by solving a system of linear equations modulo m, assuming the parameters are known or guessable. Even with partial output information, such as leading bits, cryptanalytic techniques can infer the full sequence efficiently, exposing vulnerabilities in security-sensitive applications. This predictability stems directly from the linear recurrence, allowing attackers to forecast future values after observing just a few prior ones. Despite supporting large state sizes, such as 64 bits, LCGs often demonstrate space inefficiency because poor parameter choices limit the effective period and mixing, reducing the usable entropy well below the theoretical maximum. A notorious historical example is the RANDU generator, with modulus m = 2^{31} and multiplier a = 65539, which produces points lying exactly on 15 parallel hyperplanes in three dimensions, leading to systematic errors in Monte Carlo simulations like those in nuclear physics. These flaws, including lattice artifacts and bit-level weaknesses, motivated innovations like permuted congruential generators to enhance randomness through nonlinear transformations.

Algorithm

Core state update

The core state update in a permuted congruential generator (PCG) advances the internal state using a linear congruential generator (LCG) recurrence. Specifically, the next state X_{n+1} is computed as X_{n+1} = (a \cdot X_n + c) \mod m, where a is the multiplier, c is the increment, and m is the modulus. A reversible permutation function is then applied to the updated state to generate the output, enhancing the statistical properties while retaining the efficiency of LCG-style modular arithmetic. This separation addresses shortcomings in traditional LCG outputs without modifying the state transition itself. The modulus m is typically selected as a power of 2, such as m = 2^{64}, to align with machine-word sizes on modern hardware, enabling fast implicit modulo operations via overflow. The parameters a and c are chosen similarly to those in LCGs but tuned to achieve the full period of m; for instance, a must be odd, and specific multiplier forms (e.g., of the form a = k \cdot 2^e + 1 with k odd) ensure maximal cycle length when c is odd and positive. The reversible permutation plays a crucial role by scrambling bits of the state for output generation, preserving the full period of the underlying LCG while eliminating linear artifacts that degrade statistical quality in plain LCGs. Mathematically, since the permutation is bijective, it maintains uniformity in the output derived from the state space traversal, but its non-linear mixing disrupts the predictable arithmetic progressions inherent to LCGs. This breaks the linearity in the generated sequence, leading to improved equidistribution of subsequences without introducing significant computational overhead beyond the efficient modular multiplication. In practice, the permutation is applied to the updated state to produce the final random value.

Permutation functions

In permuted congruential generators (PCGs), permutation functions are bijective mappings applied to the internal state to scramble the output of the underlying linear congruential generator (LCG), thereby mitigating its structural weaknesses while preserving the full period of the sequence. These functions operate on the state tuple, typically transforming the low-order component in a parameter-dependent manner, such as f^*(a, b) = (a, f_a(b)), where a selects the specific permutation from a family. Permutation functions in PCGs fall into two broad categories: additive operations, which include bit rotations and multiplications by odd constants, and more complex transformations akin to xorshift-style shifts. Bit rotations, for instance, cyclically shift bits left or right by a variable amount, while multiplications leverage modular arithmetic to redistribute bit patterns. Xorshift-style operations combine exclusive-OR with shifts, using state-derived parameters to introduce variability. These families are constructed such that high-order bits of the state determine the permutation parameter, ensuring the transformation depends on the evolving sequence itself. A key requirement for these permutations is their reversibility, as only invertible operations guarantee the generator maintains its full period, such as $2^{64} for a 64-bit state. For example, a left rotation by k bits is often self-inverse under certain conditions, allowing the state to be uniquely recovered, while multiplications by an odd constant M modulo $2^{64} are invertible via the modular inverse of M. This invertibility ensures that the output function forms a bijection on the relevant output space. Representative examples for a 64-bit state include a rotation by r bits, defined as (X \gg (64 - r)) \lor (X \ll r), where \gg and \ll denote right and left shifts, and \lor is bitwise OR; this operation preserves all bits while rearranging them. Another is multiplication by an odd constant M, computed as X \times M \mod 2^{64}, which effectively mixes bits across the state due to the odd multiplier's full rank in the bit matrix. For xorshift variants, a parameterized form might apply X \oplus (X \gg s) followed by a rotation, with s selected from the state. These permutations are integrated immediately after the LCG core update by applying them to the updated state to produce the output, while the unpermuted state advances to the next iteration. By applying the permutation for output, the generator disrupts the regular lattice structure inherent to LCGs in the visible sequence. The primary benefits of these permutation functions lie in their ability to destroy linear correlations present in traditional LCG outputs, such as low-entropy higher bits, leading to improved statistical quality across dimensions. For instance, random rotations or xorshifts elevate the effective randomness of upper bits, enabling PCG variants to pass rigorous test suites like TestU01's BigCrush even with reduced state sizes. This scrambling enhances equidistribution without sacrificing speed or space efficiency.

Variants

Output types and multiple streams

In permuted congruential generators (PCGs), output extraction involves applying a mixing function to the permuted state, typically in the form \text{output} = \mix(\permute(\state)), where \permute is a reversible permutation on the full state and \mix is an additional permutation applied to a subset of bits to produce the desired output size. This approach ensures that the output randomness exceeds that of the underlying linear congruential generator state alone, by scrambling bit dependencies. PCG variants support diverse output types to accommodate different applications, including full 32-bit or 64-bit integers from 64-bit or 128-bit states, respectively, as well as narrower formats like binary (1-bit) streams or quarter outputs (e.g., 16 bits from a 64-bit state). These options allow flexible bit stream generation, where binary outputs can be produced sequentially for applications requiring individual bits, while quarter outputs enable efficient partial extractions without full state mixing. Mixing techniques in PCGs vary to optimize randomness and performance, commonly employing xorshift operations (e.g., XORing the state with a right-shifted version of itself), multiplications to avalanche bits, or hash-like methods such as XSH (xor-shift high), which performs an xorshift followed by a right shift to isolate and extract upper bits. For instance, XSH variants use the high bits of the permuted state to determine shift amounts, ensuring even distribution across output ranges. A representative example is the PCG32 variant, which generates 32 random bits from a 64-bit state via a permutation combining xorshift, right shift, and rotation, effectively decorrelating the output from the internal state sequence. For full-period PCG variants, the output period equals the state period, such as $2^{64} for 64-bit generators, guaranteeing that every possible output sequence of the chosen length cycles through without repetition. PCGs support the production of multiple independent streams—up to $2^{b-1} streams from a b-bit state—each maintaining the full generator period, useful for parallel and distributed computing by providing non-overlapping sequences.

Specific implementations

The permuted congruential generator (PCG) family includes several specific variants tailored for different state sizes, output requirements, and performance needs, all designed by Melissa E. O'Neill in 2014. These implementations leverage the core LCG advancement combined with specialized permutation functions to produce outputs with desirable statistical properties and efficiency. The variants are implemented in languages like C and C++ under the Apache License 2.0, allowing broad adoption in software projects. One prominent variant is PCG-XSH-RS, which operates on a 64-bit state to generate 32-bit outputs. This implementation applies an "XSH" permutation—xor-shifting the high bits of the state into the low bits—followed by a "RS" random shift determined by the state's upper bits, providing effective mixing without excessive computational overhead. The multiplier parameter a is selected based on the local architecture or state size to optimize the LCG step, ensuring a full period of $2^{64}. This makes PCG-XSH-RS suitable for general-purpose simulations requiring balanced speed and output quality. For applications needing greater state space and enhanced diffusion, variants like PCG-XSL-RR use a 128-bit state to produce 64-bit outputs. The permutation involves xorshift and limited multiplication steps for efficient mixing across all bits. With a period of $2^{128}, it supports more complex scenarios like high-dimensional equidistribution, where the multiplier a is tuned for the extended state. Minimalist variants address constrained environments, such as embedded systems. PCG16 employs a 16-bit state for 16-bit outputs, using a simplified permutation to maintain core PCG benefits in limited memory, with a period of $2^{16}. Similarly, PCG8 uses an 8-bit state for 8-bit or smaller outputs, ideal for ultra-low-resource applications, achieving a period of $2^{8}. Both retain the family’s emphasis on efficient permutation without additional state overhead. To enable parallel or independent streams, PCG variants incorporate jump-ahead functionality, allowing efficient advancement of the state by arbitrary steps in O(\log k) time. This relies on the closed-form solution for LCG iteration: the state after k steps is computed as X_{n+k} = a^k X_n + c \frac{a^k - 1}{a - 1} \mod m, where exponentiation uses fast modular arithmetic. Such seekability supports creating multiple non-overlapping sequences from a single generator, crucial for parallel computing tasks.

Implementation

Pseudocode examples

The permuted congruential generator (PCG) family is implemented using a simple structure to maintain the internal state, consisting of a current state value and an increment (sequence constant) for the underlying linear congruential generator (LCG). The following pseudocode examples are drawn from the reference implementation and illustrate the core operations in a C-like syntax for clarity.

Basic PCG32 State Structure

The state is represented as a pair of 64-bit unsigned integers: one for the LCG state and one for the increment, enabling a full period of $2^{64} when properly chosen. The multiplier for the LCG step is fixed at 6364136223846793005 (a value ensuring good mixing properties).
struct pcg32_state {
    uint64_t state;  // Current LCG state
    uint64_t inc;    // Sequence constant (must be odd)
};

Initialization (Seeding)

Initialization mixes the provided seed values into the state to produce a valid starting point, ensuring reproducibility and avoiding poor initial sequences. The function calls the random step twice to further scramble the seed.
function pcg32_srandom(state: pcg32_state, initstate: uint64, initseq: uint64):
    state.state = 0
    state.inc = (initseq << 1) | 1  // Ensure inc is odd
    pcg32_random(state)             // Discard first value
    state.state += initstate
    pcg32_random(state)             // Discard second value

Core State Update and Output Generation (PCG-XSH-RR Variant)

The core generation advances the LCG state using multiplication and addition (modulo $2^{64} implicit in unsigned overflow), then applies a permutation via an output function. The PCG-XSH-RR variant uses an xorshift (XSH) followed by a random rotation (RR) on the high 32 bits of the state for the output, providing 32 bits of randomness. This variant balances speed and statistical quality.
function pcg32_random(state: pcg32_state) -> uint32:
    oldstate = state.state
    state.state = oldstate * 6364136223846793005 + state.inc  // LCG update
    xorshifted = ((oldstate >> 18) xor oldstate) >> 27
    rot = oldstate >> 59
    return (xorshifted >> rot) | (xorshifted << ((-rot) & 31))  // Rotate right
For the faster PCG-XSH-RS variant, the permutation uses a random shift instead of rotation: after the same LCG update, compute xorshifted = oldstate ^ (oldstate >> 22), then return (xorshifted >> (22 + (oldstate >> 61))) & 0xFFFFFFFF to produce the 32-bit output. This trades minor statistical quality for reduced operations.

Jump (Advance) Function

To skip ahead by a large number of steps (e.g., for parallel streams), the advance function uses logarithmic-time computation based on LCG closed-form advancement, avoiding linear iteration. It updates the state by \delta steps using repeated squaring of the multiplier, while keeping the increment fixed.
function pcg32_advance(state: pcg32_state, delta: uint64):
    multiplier = 6364136223846793005ULL
    acc_mult = 1ULL
    acc_plus = 0ULL
    cur_mult = multiplier
    cur_plus = state.inc
    tmp = delta
    while tmp > 0:
        if tmp & 1:
            acc_mult = acc_mult * cur_mult  // mod 2^64
            acc_plus = acc_plus * cur_mult + cur_plus  // mod 2^64
        cur_plus = (cur_mult + 1) * cur_plus  // mod 2^64
        cur_mult = cur_mult * cur_mult  // mod 2^64
        tmp >>= 1
    state.state = state.state * acc_mult + acc_plus  // mod 2^64
    // inc remains unchanged
    // Note: All operations modulo 2^64 using unsigned overflow

Optimization techniques

PCG implementations leverage hardware features of modern processors to achieve high performance in state updates. For 64-bit outputs, the core linear congruential step employs a single 128-bit multiplication to compute the new state modulo $2^{64}, exploiting the high throughput of wide-integer operations available on contemporary CPUs. In languages like C or C++, this is facilitated by compiler extensions such as GCC's __int128 type, which performs the multiplication efficiently without explicit modular reduction, as the high 64 bits of the product serve as the increment for the next state. To minimize execution overhead, PCG's permutation functions are designed to avoid conditional branches, relying instead on bitwise operations like shifts and XORs for output mixing. For instance, variants such as PCG-XSH-RR use a sequence of right shifts and XORs on the state to produce the permuted result, ensuring predictable execution paths and better instruction-level parallelism on superscalar processors. This branch-free approach is particularly effective in the output stage, where random rotations or selections are computed using arithmetic on the state bits themselves. The compact 64-bit state size of basic PCG variants contributes to cache efficiency, as the entire generator fits within a single register or cache line, reducing memory access latency during sequential calls. This small footprint is advantageous in performance-critical loops, where repeated invocations benefit from spatial and temporal locality without incurring cache misses. For parallel and SIMD applications, PCG supports jump-ahead functionality, allowing rapid advancement of the state by large increments in O(\log k) time using repeated squaring of the multiplier. This enables the creation of independent streams for multiple threads or SIMD lanes without shared state contention, facilitating scalable parallelism in simulations or Monte Carlo methods. Portability across platforms is maintained through fallback mechanisms for environments lacking native 128-bit arithmetic support. In such cases, PCG can decompose the multiplication into multiple 64-bit operations using algorithms like double-precision multiplication, ensuring consistent behavior while adapting to the host architecture's capabilities.

Properties

Statistical quality

The permuted congruential generator (PCG), introduced by Melissa E. O'Neill in 2014, was empirically designed to address the statistical shortcomings of traditional linear congruential generators (LCGs), particularly their tendencies toward structured patterns in output sequences. By applying permutation functions to the LCG state before output, PCG enhances randomness properties without relying on complex theoretical derivations, focusing instead on practical performance across empirical test suites. PCG variants consistently pass rigorous statistical test batteries, demonstrating high-quality randomness. For instance, the PCG-RS and PCG-RR implementations pass the comprehensive BigCrush suite from TestU01 with state sizes as small as 58 bits and 53 bits, respectively, providing substantial margin over failure thresholds. Similarly, PCG passes all 114 tests in the Dieharder suite, with p-values distributed uniformly and no failures observed, indicating robust randomness even under repeated testing. In comparisons, PCG exhibits superior performance to the Mersenne Twister in structural tests, such as TestU01's linear complexity test—where Mersenne Twister fails rapidly—and in lattice-related visualizations that reveal fewer dependencies. The full-period design of PCG's underlying LCG ensures equidistribution, providing uniform coverage across the entire state space and supporting k-dimensional equidistribution through period-extension techniques for multidimensional applications. Independence is further bolstered by the permutation step, which introduces low autocorrelation in output sequences, mitigating the serial correlations inherent in plain LCGs. Visual assessments, such as randograms (scatter plots of successive outputs modulo a power of 2), confirm PCG's quality: unlike LCGs, which display visible crystalline lattice patterns due to hyperplane alignments, PCG outputs appear as uniform noise with no discernible structure.

Performance metrics

The permuted congruential generator (PCG) family exhibits high computational efficiency, particularly in generating 32-bit outputs, achieving approximately 1-2 cycles per output on x86-64 architectures such as Intel Haswell processors. Specific variants like PCG-XSH-RS 64/32 demonstrate around 2.07 cycles per random number, translating to speeds of 0.61 ns per invocation and throughput exceeding 48 Gb/s when compiled with g++ -O2. This performance stems from the generator's reliance on a single multiplication, addition, and permutation operation per step, minimizing instruction count. PCG maintains minimal memory footprint, requiring only 8-16 bytes of state (64 or 128 bits, respectively) to store the internal linear congruential generator parameters, in contrast to more expansive designs like the Mersenne Twister's 2.5 KB. This compactness enables high throughput in resource-constrained environments, such as embedded systems, where a PCG-XSL-RR 64/32 variant outperforms alternatives by over 2x on ARM Cortex-A7 processors at 1 GHz. The design's simple arithmetic operations—primarily 64-bit multiplications and bit shifts—also contribute to low power consumption, making it suitable for battery-powered devices without specialized hardware acceleration. Since its introduction in 2014, PCG implementations have benefited from library-level optimizations, notably in pcg-cpp, which provides SIMD-accelerated variants and streamlined interfaces for modern C++ compilers, further enhancing speed on multi-core systems while preserving the core algorithm's efficiency. Benchmarks from the original work indicate PCG can generate outputs up to 4 times faster than Java's built-in Random class under comparable conditions.

Applications and Comparisons

Use cases

Permuted congruential generators (PCGs) are particularly well-suited for Monte Carlo simulations due to their high statistical quality, which ensures reliable sampling in probabilistic computations, and their support for reproducible results through easy seeding and multiple independent streams. In graphics applications, such as procedural terrain or texture generation in game engines, PCGs provide fast, high-quality randomness that avoids the performance bottlenecks of slower alternatives like the Mersenne Twister, enabling efficient real-time rendering and simulation workflows. In embedded systems, including IoT devices and microcontrollers, PCGs excel owing to their minimal memory footprint—often requiring just 128 bits of state—and compact code size, making them ideal for resource-constrained environments where traditional pseudorandom number generators (PRNGs) may impose excessive overhead. This space efficiency, combined with low-latency generation, supports applications like sensor data simulation and lightweight cryptographic primitives in battery-powered systems. PCGs have seen widespread adoption in general-purpose software libraries for non-cryptographic random number generation. In Python, the PCG64 variant has been integrated into NumPy since version 1.17 (released in 2018), serving as the default BitGenerator for array-based simulations and statistical analysis. Rust's rand ecosystem includes the rand_pcg crate, which implements several PCG variants for high-performance applications in systems programming. Similarly, C++ libraries leverage PCGs; for instance, Google's Abseil provides PCG-based engines in its random module for efficient, thread-safe randomness in large-scale software. In non-cryptographic contexts like video games and procedural content generation, PCGs are favored for their speed and ability to produce uncorrelated streams, which is crucial for generating diverse levels, items, or behaviors without predictability issues. Roguelike games, in particular, benefit from PCG32's 64-bit state and stream support, allowing deterministic yet varied procedural worlds across multiple playthroughs, outperforming bulkier PRNGs in performance-critical scenarios. Further adoption highlights PCGs' versatility: Intel's oneAPI Math Kernel Library (oneMKL) introduced a PCG Device API engine in recent releases, optimizing it for parallel computing in high-performance simulations on GPUs and accelerators. This integration underscores PCGs' role in balancing quality, speed, and efficiency across diverse computational domains.

Benchmarks against other PRNGs

The permuted congruential generator (PCG) family demonstrates significant advantages over traditional pseudorandom number generators (PRNGs) in benchmarks evaluating speed, state size, and statistical quality, particularly for non-cryptographic applications. These comparisons, drawn from extensive testing using suites like TestU01, highlight PCG's efficiency without sacrificing uniformity or equidistribution properties. Compared to the Mersenne Twister (MT19937), PCG variants achieve substantially higher throughput, often 2–5 times faster in generating 32-bit outputs, with rates exceeding 35 Gb/s versus MT's 13–27 Gb/s on optimized compilers like g++ and clang++. PCG also maintains a much smaller state size—typically 64 bits compared to MT's 2,503 bytes—reducing memory overhead while passing the stringent BigCrush battery of TestU01 at smaller internal state sizes (e.g., 58 bits for PCG-RS versus MT's failures in linear complexity tests after limited outputs). Modern statistical evaluations confirm PCG's superior quality, avoiding MT's known predictability issues after 624 outputs.
PRNG VariantSpeed (Gb/s, 32-bit output)State Size (bits)BigCrush Pass Threshold (bits)
PCG-XSH-RR 64/3235.67–65.866460
Mersenne Twister13.79–27.4820,032Fails linear complexity
XorShift* 64/3222.056440
PCG exhibits similar generation speeds to XorShift* variants but outperforms them in statistical robustness, passing BigCrush with greater headroom (24 bits at 64-bit state) and avoiding failures in multidimensional equidistribution tests that plague plain XorShift implementations at all sizes. For instance, while XorShift* requires at least 40 bits to pass BigCrush, PCG variants like PCG-XSH-RS succeed at 36 bits, demonstrating no poker or gap test failures observed in XorShift under suites like PractRand. Against linear congruential generators (LCGs), PCG offers vastly superior statistical quality with comparable speeds, as plain LCGs fail BigCrush below 88 bits due to poor mixing, whereas PCG's permutation step ensures passage at 49 bits or less while maintaining LCG-like efficiency (e.g., few instructions per output). For the cryptographic PRNG ChaCha20, PCG prioritizes non-cryptographic speed, achieving 3–5 times higher throughput in general-purpose benchmarks (e.g., >50 Gb/s versus ChaCha's ~10–15 Gb/s equivalents) at the cost of security guarantees, though both pass TestU01's BigCrush; ChaCha's larger state (104–1,104 bits) contrasts PCG's compactness, making PCG preferable for simulations over ChaCha's slower, backtracking-resistant design. Cycle length benchmarks from O'Neill's analyses show PCG's extensible periods (up to $2^{32830}) rivaling ChaCha's $2^{128} for practical use without cryptographic overhead.

Security Analysis

Predictability challenges

The permuted congruential generator (PCG) addresses predictability challenges inherent in simpler linear congruential generators (LCGs) by incorporating permutation functions that introduce non-linearity, thereby obscuring the underlying LCG state and complicating efforts to reverse-engineer the sequence from observed outputs. These permutations, applied as output functions on state tuples, require an adversary to invert multiple mixing steps—such as random rotations and XOR shifts—to access the linear core, significantly raising the computational barrier to prediction. PCG variants achieve a full period of 264 for their 64-bit LCG component (or larger in extended forms), traversing all possible states for a fixed stream increment within their 128-bit internal representation (64 bits for state and 64 for increment), which renders brute-force enumeration of the state space computationally infeasible for practical prediction attacks. This exhaustive cycle, combined with the generator's design, ensures that no shortcuts exist to traverse the state graph efficiently without knowledge of the internal parameters. Output mixing in PCG further enhances resistance by transforming the state through operations like XOR folding, which deliberately limits the leakage of low-order state bits into the output stream and disrupts patterns exploitable by lattice-based cryptanalytic methods. As a result, even partial observations of the output provide minimal information about the full state, forcing attackers to contend with a highly diffused representation. Theoretically, PCG's reversible permutation steps—such as invertible XOR and rotation operations—preserve the full information content of the state while scrambling it across multiple dimensions, effectively maximizing entropy utilization and thwarting attempts to correlate outputs with prior states. This scrambling elevates the generator's effective entropy beyond that of a plain LCG, making sequential prediction akin to decoding a permuted cipher without the key. Melissa O'Neill designed PCG with the explicit goal of providing statistical security for non-cryptographic applications, prioritizing resistance to casual prediction and algorithmic attacks over full cryptographic rigor, as evidenced by its performance in suites like TestU01 while maintaining low overhead. This focus ensures PCG remains suitable for simulations and games where predictability could compromise fairness or efficiency.

Seed recovery methods

Seed recovery for permuted congruential generators (PCG) primarily involves inversion attacks that reverse the output permutation and mixing functions to reconstruct internal states from observed outputs, often requiring guesses of partial state information. These attacks exploit the underlying linear congruential structure while accounting for the nonlinear permutation, making them feasible with a modest number of consecutive outputs but computationally intensive due to the need to enumerate candidate states. For instance, in variants with a known increment, an attacker can guess approximately 37 bits of the state and verify candidates by inverting the output function to recover the full state. Lattice reduction techniques, adapted from attacks on linear congruential generators (LCGs), further enable seed recovery by solving the closest vector problem (CVP) in low-dimensional lattices constructed from the observed outputs and the generator's parameters. For PCG, these lattices are typically 3-dimensional when the increment is known or 4-dimensional otherwise, allowing reconstruction of hidden parameters like the multiplier and increment after partial state recovery. The permutation step introduces additional difficulty, effectively multiplying the attack complexity by a factor of about $2^{32} compared to plain LCGs, as it scrambles low-order bits that would otherwise leak structural information. A specific example is the recovery attack on the PCG-XSH variant, which applies a permutation via bit shifts and multiplications followed by an output mixing function. Here, the method involves guessing partial state bits (e.g., 37 bits for known increments, up to around 55 for unknown) and solving multiple instances of the closest vector problem (CVP) using lattice reduction on partial states derived from 512 bytes (about 100 outputs) of generator output to find the exact internal state; this requires approximately $2^{57} operations for unknown increments, achievable in around 20,000 CPU hours on modern hardware. For cases with known increments, the complexity drops to $2^{37} operations, completable in about 23 core-minutes, demonstrating practicality under favorable conditions like exposed consecutive outputs. Limitations include the need for substantial output volume—192 bits for known increments and up to 4,096 bits for unknown—and the attacks' inapplicability to full 64-bit states without parameter leakage. Mitigations against these recovery methods emphasize using high-entropy seeds to increase the effective state space and avoiding the exposure of consecutive outputs, which reduces the information available for lattice-based reconstruction. These attacks, detailed in a 2020 analysis, remain the primary known vulnerabilities. As of 2025, no practical breaks for fully parameterized 64-bit PCG variants with unknown increments have emerged, as the required computational effort remains prohibitive for real-world adversaries despite theoretical vulnerabilities in simplified scenarios.

References

  1. [1]
    None
    Summary of each segment:
  2. [2]
    Permuted congruential generator (64-bit, PCG64) - NumPy
    Supports the method advance to advance the RNG an arbitrary number of steps. The state of the PCG-64 RNG is represented by 2 128-bit unsigned integers.
  3. [3]
    rand_pcg - Rust - Docs.rs
    The PCG random number generators. This is a native Rust implementation of a small selection of PCG generators. The primary goal of this crate is simple, ...
  4. [4]
    [PDF] THE ANNALS OF'THE COMPUTATION LABORATORY OF ...
    1949. XXI Tables of Generalized Exponential-Integral Functions. XXII Tables of the Function si: cP and of its First Eleven Derivatives. XXIII . (In preparation).
  5. [5]
    [PDF] Random-Number Generation
    ➢ The lth bit has a period at most 2l. ➢ In general, the high-order bits are more randomly distributed than the low-order bits. ⇒ Better ...
  6. [6]
    [PDF] Linear congruential generators do not produce random sequences
    ) Knuth (Vol. 2) contains an elaborate discussion of linear congruential generators. (LCG). The sequences produced by LCG's have been shown to satisfy ...
  7. [7]
    How to predict congruential generators - ScienceDirect.com
    In this paper we show how to predict a large class of pseudorandom number generators. We consider congruential generators which output a sequence of integers.
  8. [8]
    [PDF] A Family of Simple Fast Space-Efficient Statistically Good Algorithms ...
    This paper presents a new uniform pseudorandom number generation scheme that is both extremely practical and statistically good (easily passing L'Ecuyer and ...
  9. [9]
    Download the PCG Library
    ### Licensing Information for PCG Implementations
  10. [10]
    Download the PCG Library
    // *Really* minimal PCG32 code / (c) 2014 M.E. O'Neill / pcg-random.org // Licensed under Apache License 2.0 (NO WARRANTY, etc. see website) typedef struct ...<|control11|><|separator|>
  11. [11]
    Using the Minimal C Implementation | PCG, A Better Random ...
    You will also need to link your code with the pcg_basic.o. pcg32_srandom_r(rngptr, initstate, initseq). This function initializes (a.k.a. “seeds”) the random ...
  12. [12]
    DIEHARDER random number generator test results for PCG and MWC
    Jul 10, 2017 · Testing Maraglia's simple MWC random number generator with DIEHARDER, Robert G. Brown's extension of Marsaglia's DIEHARD test suite.
  13. [13]
  14. [14]
    GitHub - imneme/pcg-cpp: PCG — C++ Implementation
    **Summary of Performance Optimizations, Speed Improvements, or Benchmarks Since 2014 for pcg-cpp:**
  15. [15]
    Specific Problems with Other RNGs
    Mersenne Twister. This RNG is one of the most widely ... Fewer rounds result in poor statistical performance; ChaCha2 fails statistical tests badly, and ...Missing: lattice | Show results with:lattice
  16. [16]
    Testing non-cryptographic random number generators: my results
    Aug 22, 2017 · Though xorshift128+ has been widely adopted, it fails both big crush and practically random. The failure is rather decisive. Fortunately, Java' ...
  17. [17]
    Practical seed-recovery for the PCG Pseudo-Random Number ...
    Sep 28, 2020 · In this article, we present a practical algorithm that recovers all the hidden parameters and reconstructs the successive internal states of the generator.Missing: methods | Show results with:methods