AMD's random number generator can't generate a 0?

(board.flatassembler.net)

80 points | by BruceEel 2 hours ago

15 comments

  • 349ru3h4f03 16 minutes ago
    • peri-cl 9 minutes ago
      The OP says they discovered this on a Zen 2, which is not covered by that bulletin (?)
  • jstanley 51 minutes ago
    This is not the first RNG bug on Zen 2, I recall after I first got mine that some application or other would quit immediately at startup because rdrand always returned -1, i.e. all 1s. It was fixed with a microcode update.

    Do we now learn that they fixed "always generate all 1s" with "never generate all 0s"??

    EDIT: I've been unable to reproduce the problem on my CPU, FWIW. It's a Ryzen 5 3600.

    EDIT2: OK, update, I can reproduce it with rdrand16, rdrand32 is fine but rdrand16 can never generate all 0s. So my CPU does have this problem!

    • yk 44 minutes ago

          return 4 # Determined by fair dice roll.
    • JdeBP 9 minutes ago
    • RandomOnyx 21 minutes ago
      Does rdrand32 and then taking the lowest 16 bits of its result yield any zeroes?

      Basically I'm wondering if it's a bug in the version of the instruction that writes to a 16-bit reg, or a bug in the underlying RNG

      • jstanley 20 minutes ago
        Yes it does. rdrand32()%65535 was my first attempt, and generated zeroes at about the expected rate, that's why I initially erroneously thought my CPU did not have this problem.
        • RandomOnyx 19 minutes ago
          How about* rdrand32()%65536? Taking the remainder by 65535 doesn't take the lowest 16 bits after all

          *: missed a word the first time around

        • goalieca 15 minutes ago
          You should be using &0xFFFF for masking. Your mod is off by 1 too.
  • m_antis89 2 minutes ago
    0 is not a number, it's undefined
  • CodesInChaos 1 hour ago
    Embarrassing, but probably little practical impact, since these hardware random numbers are typically not used directly and instead seed a CSPRNG.
  • 20k 26 minutes ago
    I always wonder how hardware bugs like this happen with the sheer amount of hardware validation that's done. It'd be fascinating to know how it slipped through the cracks, though I know almost nothing about this side of the industry sadly
  • hnacobsxph 9 minutes ago
    Chased a similar bug in a KDF once and only caught it by histogramming the 16 bit draws, statistical suites never flagged it.
  • matja 56 minutes ago
    I'm getting 16-bit zeros on my Zen 3 chip (+1:3821, 0:3893, -1:3895), I will wait to get some statistically significant samples for the 32-bit values and update the forum thread. Maybe it was fixed after Zen 2?
  • throwawayffffas 24 minutes ago
    So what? The point is to be non predictable not to pick all the numbers in the range with exactly the same probability. Would it be a problem if it never generated 16542?
    • Hugsbox 2 minutes ago
      That may well be a problem, yes.
    • gnfargbl 9 minutes ago
      Consider an 8-bit RNG.

      By your argument, it would not be a problem if the RNG never generated 0. So, it must follow that it would also not be a problem if it never generated {1, 2, 3, ..., 253}.

      That means that our RNG now only generates the values 254 and 255. Which of the values is generated is unpredictable on any given call. However, 7 of the 8 output bits are now always fixed and so completely predictable. Can you imagine how an attacker could exploit that?

      Failing to generate only the number 0 is a weaker version of the same class of flaw.

    • swader999 7 minutes ago
      Betty from accounting will have words.
    • antiloper 16 minutes ago
      What are you talking about? The point is in fact to pick all the numbers in the range with exactly the same probability.

      See section 7.3.17 of the Intel SDM, and how NIST SP800-90A (which the SDM refers to) defines "random number".

  • dark-star 50 minutes ago
    Usually you do "rdrand % <some-number>" anyways, and in that case you will still get zeroes. True, your result might be skewed by 1/(maxint/some-number) but I guess that's not a big problem in practice
  • Plainharbor21 27 minutes ago
    [dead]
  • Ledgermellow 20 minutes ago
    [dead]
  • ExoticPearTree 57 minutes ago
    The probability of generating a zero is incredibly low if you use the normal distribution curve.

    So it is not necessarily that it doesn't generate zero, they did not run enough times to increase the probability of actually generating a zero.

    • blensor 51 minutes ago
      From what I can see they were trying to generate 16bit integers, so the probability is 1 in 65536 and they were running the test for 11 hours.

      You definitely would expect a roughly equal number of 0s as any other of those numbers since it's uniformly distributed. And definitely not 0

    • zygentoma 48 minutes ago
      This also seems to happen for 16 and 32 bit numbers, so you should be able to see zeros easily.

      They also write:

      > Running the same programs on an Intel processor, and the 0's are there with no problem.

    • matja 55 minutes ago
      Why would it be a normal distribution?
      • throawayonthe 32 minutes ago
        should be a discrete uniform distribution right?
  • ZiiS 1 hour ago
    It is just possible they decided crypto code that uses it was safer to skip zeros. (Whist mathematically it should be no more likely; it is vastly more likely someone will actually try that key).

    It is also possible that their code was generating too many zeros and the easiest fix was to discard them all.

    • jstanley 22 minutes ago
      Can you clarify what you mean by "it is vastly more likely someone will actually try that key"?

      I'm guessing you don't think there are people calling rdrand in a loop and throwing away the output with high probability except when it is 0, but I can't see how else you imagine people would be vastly more likely to use the output when it is 0?

    • dark-star 52 minutes ago
      this is not how crypto works