-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Document cryptographically secure random number generation #8346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document cryptographically secure random number generation #8346
Conversation
- Mention which PRNG Godot internally uses.
| self-signed :ref:`class_X509Certificate`\ s. | ||
|
|
||
| The downside of :abbr:`CSPRNG (Cryptographically secure pseudorandom number generation)` | ||
| is that it's much slower than standard pseudorandom number generation. Its API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I generated 10 million random ints:
const COUNT = 10 * 1000 * 1000
func test_randi():
var arr: Array[int] = []
arr.resize(COUNT)
var t0 = Time.get_ticks_msec()
for i in range(COUNT):
arr[i] = randi()
var t1 = Time.get_ticks_msec()
prints("test_randi:", t1-t0, "ms")
return t1-t0
func test_random_bytes():
var arr: Array[int] = []
arr.resize(COUNT)
var t0 = Time.get_ticks_msec()
var crypto := Crypto.new()
var byte_array := crypto.generate_random_bytes(COUNT * 4)
for i in range(COUNT):
arr[i] = byte_array.decode_u32(i * 4)
var t1 = Time.get_ticks_msec()
prints("test_random_bytes:", t1-t0, "ms")
return t1-t0Result:
test_randi: 381 ms
test_random_bytes: 550 ms
So the crypto.generate_random_bytes() takes only about 50% more time. In my opinion that is not much slower, just slower. But is this something that could be dependent on operating system? Also, I'm pretty sure that the pseudo rng (randi()) always takes a constant time to generate a new random number, but how about the CSPRNG? If it does use operating system as a randomness source (does it?), generating even a single random byte might take non-constant time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
50% is a lot slower though generally speaking, so this is still a valid statement
It is also very hardware and OS dependent
|
The discussion on Reddit started from one user's goal to shuffle a deck of cards (52 card). It might be good to tell in the It would be nice if the documentation told even more specifically how the |
This does not follow, it depends on the period of the RNG, the seed is not related to that, all the length of the seed dictates is how many starting configurations you can have, the seed does not equal the state of the machine For example the classic Mersenne Twister has a nominal period of |
I understand that.
It doesn't matter how long the period is. It doesn't matter if you can get all the possible shuffles sometime in the future. You can't get all the possible shuffles in the first shuffle. |
What do you mean "the first shuffle"? Again this doesn't apply, because the seed doesn't control the period, the period is literally how much you can shuffle it Further to shuffle 20 elements you need no more than 20 numbers, so that doesn't apply either. The period is exactly what matters for this While it does matter that you can't seed it freely like that, it isn't relevant to this PR |
I have no idea how could I describe this more clearly. Start the app. Seed the rng. Generate 51 (or so) random numbers required to shuffle the deck. This is the first shuffle. In a perfect world every possible card combination should be possible. Even if the period would be infinite, that wouldn't help. Let's say we have a rng which can be seeded either with 0 or 1. Rng's period is infinite. When you generate the 51 random number for thr first deck shuffle, you have only those two seed options. Seed 0 produces some specific random numbers and seed 1 some others. Your game's first deck can have only two possible shuffles. Rng period doesn't matter at all. |
|
I am aware, though that's not how the issue was presented at first hence why I clarified those points But in any case it isn't relevant to this PR (as the CSPRNG isn't seeded this way, but uses entropy to seed), I'd suggest opening an issue to track this detail and discuss it Edit: Also the fact that the seed is limited like this does not mean you can't achieve more combinations, you can use many tricks to achieve more complexity, for example skipping ahead and discarding random data, though I don't know the period of the RNG used so can't guarantee it has a long enough period. But the fact that you only have a certain limited set of starting states doesn't mean that's just how many possible starts for randomness you have, for example shuffling from a seed of |
|
I'm going to merge this PR, the other discussion should probably be moved to an issue, if necessary. Thanks for contributing! |
…tion-csprng Document cryptographically secure random number generation
|
Cherry-picked to 4.1. |
Thanks to https://www.reddit.com/r/godot/comments/17hh09i/okay_nvm_im_starting_my_first_gdextension_for/k6p9axd/ for the suggestion 🙂