This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4212. Make the round states in [rand.eng.philox] explicit

Section: 29.5.4.5 [rand.eng.philox] Status: New Submitter: Thomas Köppe Opened: 2025-02-12 Last modified: 2025-08-22

Priority: 3

View all other issues in [rand.eng.philox].

View all issues with New status.

Discussion:

The current wording that specifies the operation of the Philox random bit generator seems needlessly vague. We can add precision by defining a few more terms, instead of requiring the reader to fill in the blanks.

Concretely, the variable X' is only vaguely defined at the moment, and the definition of the "r-round network", "rounds", and how they fit together, is somewhat informal and imprecise. The statement that Philox "returns the sequence Y = X'" is needlessly ambiguous (what is X' here?).

I propose the change that I drafted at draft/pull/7152: Namely, spell out the meaning of the "rounds" and create a distinct name for every value in every round. This allows us to state the result precisely, and makes it clear how each round computes a new value from the values of the previous rounds.

It seems convenient to change the round counter q to be 1-based (and X(0) is an alias for the initial value, X), so that the final result is X(r).

[2025-06-13; Reflector poll]

Set priority to 3 after reflector poll.

Previous resolution [SUPERSEDED]:

This wording is relative to N5001.

  1. Modify 29.5.4.5 [rand.eng.philox] as indicated:

    -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+1
    if (i == n) {
      Y=Philox(K, X) // see below
      Z=Z+1         // this updates X
      i=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: That is, there are intermediate values X(0), X(1), …, X(r), where X(0):=X, and for each round q (with q=1,,r), X(q) is computed from X(q-1) as follows. The output sequence is X(r).

    1. (4.1) — 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)
      

      An intermediate state V(q) is obtained by permuting the previous output, Vj(q):=Xfn(j)(q-1), where j=0,,n1, and fn(j) is defined in Table 124.

    2. (4.2) — The following computations are applied to the elements of the V sequence: The next output X(q) is computed from the elements of the V(q) as follows. For k=0,,n/2-1,

      1. (4.2.?) — X2k+0(q) = mulhi(V2k(q),Mk,w) xor Kk(q) xor V2k+1(q), andX2k+0 = mulhi(V2k,Mk,w) xor keykq xor V2k+1

      2. (4.2.?) — X2k+1(q) = mullo(V2k(q),Mk,w),X2k+1 = mullo(V2k,Mk,w)

      where:

      1. (4.2.1) — mullo(a,b,w) is the low half of the modular multiplication of a and b: (ab)mod2w,

      2. (4.2.2) — mulhi(a,b,w) is the high half of the modular multiplication of a and b: ((ab)/2w),

      3. (4.2.3) — k=0,,n/21 is the index in the sequences, Kk(q) is the kth round key for round q, Kk(q):=(Kk+(q-1)Ck)mod2w,

      4. (4.2.4) — q=0,,r1 is the index of the round, Kk is the kth element of the key sequence K,

      5. (4.2.5) — keykq is the kth round key for round q, keykq:=(Kk+qCk)mod2w,

      6. (4.2.6) — Kk are the elements of the key sequence K,

      7. (4.2.7) — Mk is multipliers[k], and

      8. (4.2.8) — Ck is round_consts[k].

[2025-08-08; Matt Stephanson comments and makes wording improvements with Thomas Köppe]

  1. For what it's worth, I believe the new wording correctly describes the algorithm and does not make any substantive changes.

  2. As for the wording itself:

    1. Paragraphs 1, 2, and 3 still refer to the output sequence as Y, so I don't think it should be removed from the end of the first sentence in p4. On the contrary, to maintain the connection and parallel the "$X^{(0)} := X$" wording, I think the final sentence should also be "The output sequence is $X^{(r)} := Y$".

    2. I can't explain why, but my intuition is that, in bullet (4.2), "the elements of $V^{(q)}$" sounds better than "the elements of the $V^{(q)}$". The second "the" worked with the original wording "the V sequence", but "sequence" is omitted in the proposed resolution.

    3. The use of K for both the fixed key sequence and the round keys seems potentially confusing. Maybe R for "round key" is better?

After discussion with Thomas Köppe there was agreement that (a) should be applied with the modification that we should write it as definition of Y and not the other way around, that (b) should be applied as suggested, and that there was no real consensus for proposal (c).

Proposed resolution:

This wording is relative to N5014.

  1. Modify 29.5.4.5 [rand.eng.philox] as indicated:

    -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+1
    if (i == n) {
      Y=Philox(K, X) // see below
      Z=Z+1         // this updates X
      i=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: That is, there are intermediate values X(0), X(1), …, X(r), where X(0):=X, and for each round q (with q=1,,r), X(q) is computed from X(q-1) as follows. The output sequence is Y:=X(r).

    1. (4.1) — 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)
      

      An intermediate state V(q) is obtained by permuting the previous output, Vj(q):=Xfn(j)(q-1), where j=0,,n1, and fn(j) is defined in Table 129.

    2. (4.2) — The following computations are applied to the elements of the V sequence: The next output X(q) is computed from the elements of V(q) as follows. For k=0,,n/2-1,

      1. (4.2.?) — X2k+0(q) = mulhi(V2k(q),Mk,w) xor Kk(q) xor V2k+1(q), andX2k+0 = mulhi(V2k,Mk,w) xor keykq xor V2k+1

      2. (4.2.?) — X2k+1(q) = mullo(V2k(q),Mk,w),X2k+1 = mullo(V2k,Mk,w)

      where:

      1. (4.2.1) — mullo(a,b,w) is the low half of the modular multiplication of a and b: (ab)mod2w,

      2. (4.2.2) — mulhi(a,b,w) is the high half of the modular multiplication of a and b: ((ab)/2w),

      3. (4.2.3) — k=0,,n/21 is the index in the sequences, Kk(q) is the kth round key for round q, Kk(q):=(Kk+(q-1)Ck)mod2w,

      4. (4.2.4) — q=0,,r1 is the index of the round, Kk is the kth element of the key sequence K,

      5. (4.2.5) — keykq is the kth round key for round q, keykq:=(Kk+qCk)mod2w,

      6. (4.2.6) — Kk are the elements of the key sequence K,

      7. (4.2.7) — Mk is multipliers[k], and

      8. (4.2.8) — Ck is round_consts[k].