
Cracking random number generators (xoroshiro128+) - johndcook
https://lemire.me/blog/2017/08/22/cracking-random-number-generators-xoroshiro128/
======
pbnjay
Author's title should be "Cracking PSEUDO-random number generators" \- We
should all basically assume that any PRNG will be easily cracked like this and
not use them for anything important to security!

Always use a cryptographic RNG for important code!

~~~
tptacek
This shouldn't have been downvoted because it is exactly correct.

Cryptographic generators don't work like PCG and xoroshiro and Mersenne
Twister. They're generally built by taking a cryptographically secure cipher
or hash core, "keying" it with secret entropy, and running it in a streaming
configuration (like CTR mode).

A properly designed CSPRNG can only be "cracked" in a few specific scenarios:

1\. The primitive it's built on (or the streaming construction it's configured
in) is broken, in which case the news for cryptography as a field is
significantly bigger than the fact that an RNG has a flaw.

2\. An attacker has exploited a systems flaw to directly disclose the contents
of the memory the CSPRNG is operating out of, in which case you have bigger
problems than your CSPRNG.

3\. The secrets that key the generator have become predictable. This is in
practice the only way CSPRNGs get broken (unintentionally), and, in practice,
always means the CSPRNG wasn't initialized properly (the "cold start entropy
problem").

You should use the getrandom() system call, or read from /dev/urandom, to the
exclusion of all other mechanisms.

~~~
IanCal
I'd have called that a PRNG, because to me there were only two main
categories. Pseudo-random, where it's designed to be unpredictable, and
actually random where it is based on an external hardware source of true
random information.

A CSPRNG is surely a type of PRNG. Is that not right?

Their comment doesn't really seem correct to me. The title is "Cracking random
number generators (xoroshiro128+)" which seems pretty accurate to me. The
article definitely doesn't seem to say it's breaking anything other than a
very specific, flawed random number generator.

~~~
tptacek
I'd have added "Cryptographically secure" and not capitalized "pseudo", but
that's small-stakes stuff. The point he's making is the most important safety
point on this topic.

~~~
pbnjay
Duly noted!

I'm not in this field, but I know enough to know what not to do (most of the
time).

------
nolemurs
The article is a serious waste of time.

It can be summarized as "Non cryptographic PRNGs can be predicted! Look, I
cracked this one! I'm not going to tell you how I did it though."

There's no exposition describing non cryptographic PRNGs, nor any evidence
given for why they're not sound beyond the author's assertion that he cracked
one.

To be clear, non cryptographic PRNGs _are_ often predictable, and _shouldn 't_
be used if that's a problem, but if you're interested in learning more about
that, this article isn't going to help you much.

Skip the read.

------
TACIXAT
Hey, author of the SMT attack here. There is probably a clever way to go after
XorShift128+ as well, symbolic execution using an SMT solver is basically a
brute-force solution.

I'll have to give this challenge a shot later.

------
xoroshiro
As someone who first learned how to program by implementing PRNGs but never
really digging deeper into it, I found this post very interesting to read. I
do have an idea about some (small portion) of the things behind it, but I have
no background in cryptography.

Looking at the other posts, it seems like most PRNGs are fine for non-
cryptographic applications, but what are other ways to make PRNG's though?
Everything I've learned (mostly simple stuff; Linear Congruential, Midsquare,
etc.) seem to need to store a state to work, because otherwise, wouldn't you
just output the same thing over and over again? I know there's stuff like
/dev/random (though I'm unsure how that works), but that doesn't seem like a
good idea for getting a lot of numbers.

~~~
andrewla
Professor O'Neill (mentioned in the article) has written a PRNG [1]. The jury
is still out on how powerful it is in general. There continue to be fights
between what it means to be random for cryptographic purposes vs. numerical
analysis purposes.

That said, the PDF on that site that serves as a writeup for PCG contains a
nice discussion of the links between the size of the state held and the
strength of the algorithm, including a discussion of the state of the art for
crypto- and non-crypto- PRNGs.

[1] [http://www.pcg-random.org/](http://www.pcg-random.org/)

~~~
tptacek
There is in fact no real debate about what's required for an RNG to be
suitable for security purpose. The standard for security is cryptographic. To
design a new secure RNG, you effectively need to design a new cryptographic
primitive (most likely, a new native stream cipher).

There may indeed be some debate about the requirements for non-security
numerical analysis applications.

Most development platforms should be defaulting to secure random number
generators, and most developers should be reaching for secure random number
generators as their default choice. Neither PCG nor xorshiro128 are examples
of these.

~~~
fpgaminer
> Most development platforms should be defaulting to secure random number
> generators, and most developers should be reaching for secure random number
> generators as their default choice.

I was curious about this statement. So I did some research.

This page
([http://vigna.di.unimi.it/xorshift/](http://vigna.di.unimi.it/xorshift/))
indicates that xoroshiro128+ generates 64-bits in 0.81ns on a modern 3.6GHz
CPU.

If I'm reading this page correctly ([https://bench.cr.yp.to/results-
stream.html](https://bench.cr.yp.to/results-stream.html)) ChaCha20 gets about
0.8 cycles per byte these days on modern CPUs.

Running the math we get 9.88 GB/s for Xoroshiro128+ and 5.14 GB/s for ChaCha20
(assuming a 3.6GHz modern CPU for both).

Actually a _lot_ closer than I thought. It never occurred to me that a CSPRNG
could compete, performance wise, with a non-CS PRNG.

I'm sure there's variation here. Sometimes CSPRNGs will have re-keying cycles,
and probably most implementations aren't going to use the highly optimized
version we see in the benchmark. I'm not sure if the Xoroshiro128+ benchmark I
found used a version utilizing all the SIMD functionality of the CPU (like the
ChaCha20 benchmark does). I'm also not sure if Xoroshiro128+ is the fastest
PRNG or not.

But I have to say, if these numbers are accurate ... you're just plain right.
There's no reason to default to a non-CSPRNG. CSPRNG is a safer default, and
in the rare scenario that a developer needs more performance they can go seek
out a specific PRNG for their needs.

~~~
tptacek
I'm not even saying you should never use an LCG. Go ahead, if you're
absolutely sure you need it, in the very specific places that you actually
need it. But not only are CSPRNGs performance competitive on modern machines,
but most places that need RNGs aren't in the performance hot-spot anyways.

------
zb3
This problem can be solved using Z3:
[https://gist.github.com/zb3/c59cf596ce80c501db5ca16c31a1c3a7](https://gist.github.com/zb3/c59cf596ce80c501db5ca16c31a1c3a7)

I don't know whether autor used solver or some other magic method... Solutions
should be available to those who want to see them.

------
edflsafoiewq
Does anyone know how the constants in xoroshiro128+ were chosen?

------
aj7
Ha ha! By going to your predictions page I can crack you! Great post.

