Generates a keyed pseudo-random permutation of the integers [0, n) using a balanced Feistel network. More...
#include <MooseRandomPerturbation.h>
Public Member Functions | |
| MooseRandomPerturbation (uint64_t seed, unsigned int n, unsigned int rounds=8) | |
Construct a permutation of [0, n) keyed by seed. More... | |
| uint32_t | permute (uint32_t x) const |
Map x to its permuted index in [0, n). More... | |
| uint32_t | invert (uint32_t y) const |
| Recover the original index from a permuted value, i.e. More... | |
Private Member Functions | |
| uint32_t | permutePadded (uint32_t x) const |
| Apply one full pass of the balanced Feistel network over the padded domain [0, 2^(2*half_bits)). More... | |
| uint32_t | invertPadded (uint32_t y) const |
| Invert one full pass of the Feistel network by running rounds in reverse. More... | |
| uint32_t | roundFunction (uint32_t half, unsigned int round) const |
| Keyed round function F(half, round) used in each Feistel step. More... | |
Static Private Member Functions | |
| static unsigned int | ceilLog2 (uint32_t n) |
| Return the number of bits needed to represent values in [0, n-1], i.e. More... | |
| static uint32_t | mix32 (uint32_t x) |
| Bijective 32-bit avalanche hash (finalizer from Murmur3 / degski hash). More... | |
Private Attributes | |
| const uint32_t | _k0 |
| Lower 32 bits of the seed, used as the first subkey in the round function. More... | |
| const uint32_t | _k1 |
| Upper 32 bits of the seed, used as the second subkey in the round function. More... | |
| const unsigned int | _n |
| Size of the permutation domain [0, n) More... | |
| const unsigned int | _half_bits |
| Number of bits in each Feistel half-block: ceil((ceil(log2(n)) + 1) / 2) More... | |
| const uint32_t | _half_mask |
| Bitmask of width _half_bits, used to keep half-block arithmetic in range. More... | |
| const unsigned int | _rounds |
| Number of Feistel rounds to apply per permute/invert call. More... | |
Generates a keyed pseudo-random permutation of the integers [0, n) using a balanced Feistel network.
Given the same seed and n, the mapping is fully deterministic and bijective: every input in [0, n) maps to a unique output in [0, n). Different seeds produce statistically independent permutations.
Because n need not be a power of two, the Feistel network operates on a padded domain of size 2^(2*half_bits) >= n and uses cycle-walking: if the raw output falls outside [0, n) it is re-applied until a valid index is reached. This guarantees termination because the padded permutation is itself a bijection and n > 0 ensures at least one valid output exists.
The permutation is also invertible via invert(), which runs the Feistel rounds in reverse order.
Definition at line 31 of file MooseRandomPerturbation.h.
| MooseRandomPerturbation::MooseRandomPerturbation | ( | uint64_t | seed, |
| unsigned int | n, | ||
| unsigned int | rounds = 8 |
||
| ) |
Construct a permutation of [0, n) keyed by seed.
| seed | 64-bit seed; split into two 32-bit subkeys for the round function. |
| n | Size of the domain to permute; must be > 0. |
| rounds | Number of Feistel rounds. More rounds improve mixing at the cost of throughput; 8 is sufficient for sampling applications. |
Definition at line 12 of file MooseRandomPerturbation.C.
|
staticprivate |
Return the number of bits needed to represent values in [0, n-1], i.e.
ceil(log2(n)). Returns 0 for n == 1 (no bits needed to index a single element).
| n | Must be > 0. |
Definition at line 103 of file MooseRandomPerturbation.C.
| uint32_t MooseRandomPerturbation::invert | ( | uint32_t | y | ) | const |
Recover the original index from a permuted value, i.e.
invert(permute(x)) == x.
Runs the Feistel rounds in reverse order and cycle-walks back into [0, n).
| y | Permuted index; must satisfy y < n. |
Definition at line 39 of file MooseRandomPerturbation.C.
|
private |
Invert one full pass of the Feistel network by running rounds in reverse.
| y | Value in the padded domain produced by permutePadded. |
y. Definition at line 73 of file MooseRandomPerturbation.C.
Referenced by invert().
|
staticprivate |
Bijective 32-bit avalanche hash (finalizer from Murmur3 / degski hash).
Used inside the round function to achieve good bit diffusion.
| x | 32-bit input. |
Definition at line 118 of file MooseRandomPerturbation.C.
Referenced by roundFunction().
| uint32_t MooseRandomPerturbation::permute | ( | uint32_t | x | ) | const |
Map x to its permuted index in [0, n).
Applies the Feistel network to the padded domain and cycle-walks until the result falls within [0, n).
| x | Input index; must satisfy x < n. |
Definition at line 25 of file MooseRandomPerturbation.C.
|
private |
Apply one full pass of the balanced Feistel network over the padded domain [0, 2^(2*half_bits)).
The result may fall outside [0, n); the caller is responsible for cycle-walking.
| x | Input value in the padded domain. |
Definition at line 53 of file MooseRandomPerturbation.C.
Referenced by permute().
|
private |
Keyed round function F(half, round) used in each Feistel step.
Mixes the half-block with both subkeys and a round-dependent constant derived from the golden-ratio fractional bits (0x9e3779b9), then passes the result through a 32-bit avalanche hash (mix32).
| half | The half-block value (R in the forward direction). |
| round | Zero-based round index, used to vary the constant each round. |
_half_bits width. Definition at line 92 of file MooseRandomPerturbation.C.
Referenced by invertPadded(), and permutePadded().
|
private |
Number of bits in each Feistel half-block: ceil((ceil(log2(n)) + 1) / 2)
Definition at line 122 of file MooseRandomPerturbation.h.
Referenced by invertPadded(), and permutePadded().
|
private |
Bitmask of width _half_bits, used to keep half-block arithmetic in range.
Definition at line 124 of file MooseRandomPerturbation.h.
Referenced by invertPadded(), permutePadded(), and roundFunction().
|
private |
Lower 32 bits of the seed, used as the first subkey in the round function.
Definition at line 116 of file MooseRandomPerturbation.h.
Referenced by roundFunction().
|
private |
Upper 32 bits of the seed, used as the second subkey in the round function.
Definition at line 118 of file MooseRandomPerturbation.h.
Referenced by roundFunction().
|
private |
Size of the permutation domain [0, n)
Definition at line 120 of file MooseRandomPerturbation.h.
Referenced by invert(), MooseRandomPerturbation(), and permute().
|
private |
Number of Feistel rounds to apply per permute/invert call.
Definition at line 126 of file MooseRandomPerturbation.h.
Referenced by invertPadded(), MooseRandomPerturbation(), and permutePadded().
1.8.14