pq-crystals/kyber

What are the requirements for the random number generator?

mnemocron opened this issue · 11 comments

With little cryptographic background I was wondering if there are special requirements for the random generator used in randombytes.c?

Does a pseudorandom number impair the algorithm's ability to be quantum secure?
The question came up because I recently ported this repo for the avr-32 microcontroller architecture where a pseudorandom number generator is used.

The rand() function computes a sequence of pseudo-random integers in the range of 0 to RAND_MAX (as defined by the header file <stdlib.h>).

I dug a bit deeper into the randombytes.c source file.
On a Linux system, randombytes() draws its randomness either from syscall(SYS_getrandom, out, outlen, 0) or directly from /dev/urandom.

From the Linux man page man7.org

By default, getrandom() draws entropy from the urandom source
(i.e., the same source as the /dev/urandom device)

From wikipedia

While /dev/urandom is still intended as a pseudorandom number generator suitable for most cryptographic purposes,
the authors of the corresponding man page note that, theoretically, there may exist an as-yet-unpublished attack
on the algorithm used by /dev/urandom


So per default on a PC the kyber draws pseudo-random numbers.
If I replace the source of the pseudo-random numbers with a different pseudo-random source, I should be fine, right?
Or are there "better" and "worse" PRNGs? Or does the kyber "hope" to never draw more than the 4096 available truly random bits in /dev/urandom?

the getrandom system call ensures that sufficient entropy is gathered before returning any output

Is this really the case? The way I understood "unlimited random" is that the device does not block when the entropy is drained. Instead it continues to output pseudo-random numbers.

Also, when is the AES256 implementation of randombytes used?
On a microcontroller platform I do not necessarily have the openssl libraries available.

On a microcontroller platform I do not necessarily have the openssl libraries available.

Microcontrollers, e.g., of smart cards, typically have some source of (possibly real) randomness available. Please check the manual of your embedded platform. But check carefully: As @cryptojedi pointed out, bad randomness is the source of truly spectacular crypto fails...

Ok, thank you all very much for the discussion. It was very insightful.

I have a suggestion for PQC in general from the embedded software standpoint:

The API of the algorithms themselves are straight forward per design. For example, the code in test_kex.c is enough to implement the key exchange without any documentation. So far so good.

But when it comes to the RNG it is not so clear anymore - and as @cryptojedi has pointed out, quite fatal if done wrong. It appears to me that with PQC the requirements for the RNG are even more important than with classical cryptography.
Therefore, as a developer who only wants apply a crypto algorithm I would appreciate a wiki / readme note or anything I can look at to get an idea of which important aspects I need to consider. As @baentsch correctly pointed out, MCUs sometimes have crypto specific peripherals which can come in handy here (or even an external QRNG chip on the board).

as a developer who only wants apply a crypto algorithm I would appreciate a wiki / readme note or anything I can look at to get an idea of which important aspects I need to consider.

For such developers, complete libraries that (are trying to :) care about such questions are being developed--or even abstracting them away into yet higher-abstraction libs/apps like OpenSSL. See for example liboqs.

See for example liboqs

Yes, I just see that you have a common source folder in liboqs.
Unfortunately, liboqs was not an option for my project because I am limited by the compiler to C99 standard.

Did I understand @cryptojedi correctly: The randombytes() function has to return only 32 bits of entropy - not the full KYBER_SYMBYTES*8?