Files
2025-10-25 03:02:53 +03:00

8.0 KiB
Raw Permalink Blame History

[rand.eng.philox]

29 Numerics library [numerics]

29.5 Random number generation [rand]

29.5.4 Random number engine class templates [rand.eng]

29.5.4.5 Class template philox_engine [rand.eng.philox]

1

#

A philox_engine random number engine produces unsigned integer random numbers in the interval [0, m), where m=2w and the template parameter w defines the range of the produced numbers.

The state of a philox_engine object consists of a sequence X of n unsigned integer values of width w, a sequence K of n/2 values of result_type, a sequence Y of n values of result_type, and a scalar i, where

X is the interpretation of the unsigned integer counter valueZ:=∑ˆ’1j=0Xjâ‹2wj of nâ‹w bits,

K are keys, which are generated once from the seed (see constructors below) and remain constant unless the seed function ([rand.req.eng]) is invoked,

Y stores a batch of output values, and

i is an index for an element of the sequence Y.

2

#

The generation algorithm returns Yi, the value stored in the ith element of Y after applying the transition algorithm.

3

#

The state transition is performed as if by the following algorithm:i = i + 1if (i == n) {Y = Philox(K, X) // see belowZ = Z + 1i = 0}

4

#

The Philox function maps the length-n/2 sequence K and the length-n sequence X into a length-n output sequence Y.

Philox applies an r-round substitution-permutation network to the values in X.

A single round of the generation algorithm performs the following steps:

The output sequence X′ of the previous round (X in case of the first round) is permuted to obtain the intermediate state V:Vj=X′fn(j) where j=0,…,n−1 andfn(j) is defined in Table 129. Table 129 — Values for the word permutation fn(j) [tab:rand.eng.philox.f]

🔗
fn(j)
j
🔗 0 1 2 3
🔗
n
2 0 1
🔗
4 2 1 0 3
🔗

[Note 1: For n=2 the sequence is not permuted. — end note]

The following computations are applied to the elements of the V sequence:X2k+0=mulhi(V2k,Mk,w)xorkeyqkxorV2k+1X2k+1=mullo(V2k,Mk,w) where:

mullo(a, b, w) is the low half of the modular multiplication of a and b: (aâ‹b)mod2w,

mulhi(a, b, w) is the high half of the modular multiplication of a and b: (⌊(aâ‹b)/2w⌋),

k=0,…,n/2−1 is the index in the sequences,

q=0,…,r−1 is the index of the round,

keyqk is the kth round key for round q, keyqk:=(Kk+qâ‹Ck)mod2w,

Kk are the elements of the key sequence K,

Mk is multipliers[k], and

Ck is round_consts[k].

5

#

After r applications of the single-round function,Philox returns the sequence Y=X′.

🔗

namespace std {template<class UIntType, size_t w, size_t n, size_t r, UIntType... consts>class philox_engine {static constexpr size_t array-size = n / 2; // exposition onlypublic:// typesusing result_type = UIntType; // engine characteristicsstatic constexpr size_t word_size = w; static constexpr size_t word_count = n; static constexpr size_t round_count = r; static constexpr array<result_type, array-size> multipliers; static constexpr array<result_type, array-size> round_consts; static constexpr result_type min() { return 0; }static constexpr result_type max() { return m - 1; }static constexpr result_type default_seed = 20111115u; // constructors and seeding functions philox_engine() : philox_engine(default_seed) {}explicit philox_engine(result_type value); template explicit philox_engine(Sseq& q); void seed(result_type value = default_seed); template void seed(Sseq& q); void set_counter(const array<result_type, n>& counter); // equality operatorsfriend bool operator==(const philox_engine& x, const philox_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // inserters and extractorstemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, const philox_engine& x); // hostedtemplate<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, philox_engine& x); // hosted};}

6

#

Mandates:

sizeof...(consts) == n is true, and

n == 2 || n == 4 is true, and

0 < r is true, and

0 < w && w <= numeric_limits::digits is true.

7

#

The template parameter pack consts represents the Mk and Ck constants which are grouped as follows:[M0,C0,M1,C1,M2,C2,…,Mn/2−1,Cn/2−1].

8

#

The textual representation consists of the values ofK0,…,Kn/2−1,X0,…,Xn−1,i, in that order.

[Note 2:

The stream extraction operator can reconstruct Y from K and X, as needed.

— end note]

🔗

explicit philox_engine(result_type value);

9

#

Effects: Sets the K0 element of sequence K to valuemod2w.

All elements of sequences X and K (except K0) are set to 0.

The value of i is set to n−1.

🔗

template<class Sseq> explicit philox_engine(Sseq& q);

10

#

Effects: With p=⌈w/32⌉ and an array (or equivalent) a of length (n/2)â‹p, invokes q.generate(a + 0, a + n / 2 * p) and then iteratively for k=0,…,n/2−1, sets Kk to(∑ˆ’1j=0akp+jâ‹232j)mod2w.

All elements of sequence X are set to 0.

The value of i is set to n−1.

🔗

void set_counter(const array<result_type, n>& c);

11

#

Effects: For j=0,…,n−1 sets Xj to Cn−ˆ’jmod2w.

The value of i is set to n−1.

[Note 3:

The counter is the value Z introduced at the beginning of this subclause.

— end note]