Wyatt Hepler | f9fb90f | 2020-09-30 18:59:33 -0700 | [diff] [blame] | 1 | .. _module-pw_random: |
Armando Montanez | 47008e8 | 2020-08-04 11:04:45 -0700 | [diff] [blame] | 2 | |
| 3 | --------- |
| 4 | pw_random |
| 5 | --------- |
| 6 | Pigweed's ``pw_random`` module provides a generic interface for random number |
| 7 | generators, as well as some practical embedded-friendly implementations. While |
| 8 | this module does not provide drivers for hardware random number generators, it |
| 9 | acts as a user-friendly layer that can be used to abstract away such hardware. |
| 10 | |
| 11 | Embedded systems have the propensity to be more deterministic than your typical |
| 12 | PC. Sometimes this is a good thing. Other times, it's valuable to have some |
| 13 | random numbers that aren't predictable. In security contexts or areas where |
| 14 | things must be marked with a unique ID, this is especially important. Depending |
| 15 | on the project, true hardware random number generation peripherals may or may |
| 16 | not be available. Even if RNG hardware is present, it might not always be active |
| 17 | or accessible. ``pw_random`` provides libraries that make these situations |
| 18 | easier to manage. |
| 19 | |
| 20 | Using RandomGenerator |
| 21 | ===================== |
| 22 | There's two sides to a RandomGenerator; the input, and the output. The outputs |
| 23 | are relatively straightforward; ``GetInt()`` randomizes the passed integer |
| 24 | reference, and ``Get()`` dumps random values into a the passed span. The inputs |
| 25 | are in the form of the ``InjectEntropy*()`` functions. These functions are used |
| 26 | to "seed" the random generator. In some implementations, this can simply be |
| 27 | resetting the seed of a PRNG, while in others it might directly populate a |
| 28 | limited buffer of random data. In all cases, entropy injection is used to |
| 29 | improve the randomness of calls to ``Get*()``. |
| 30 | |
| 31 | It might not be easy to find sources of entropy in a system, but in general a |
| 32 | few bits of noise from ADCs or other highly variable inputs can be accumulated |
| 33 | in a RandomGenerator over time to improve randomness. Such an approach might |
| 34 | not be sufficient for security, but it could help for less strict uses. |
| 35 | |
| 36 | Algorithms |
| 37 | ========== |
| 38 | xorshift* |
| 39 | --------- |
| 40 | The ``xorshift*`` algorithm is a pseudo-random number generation algorithm. It's |
| 41 | very simple in principle; the state is represented as an integer that, with each |
| 42 | generation, performs exclusive OR operations on different left/right bit shifts |
| 43 | of itself. The "*" refers to a final multiplication that is applied to the |
| 44 | output value. |
| 45 | |
| 46 | Pigweed's implementation augments this with an ability to inject entropy to |
| 47 | reseed the generator throughout its lifetime. When entropy is injected, the |
| 48 | results of the generator are no longer completely deterministic based on the |
| 49 | original seed. |
| 50 | |
| 51 | Note that this generator is NOT cryptographically secure. |
| 52 | |
| 53 | For more information, see: |
| 54 | |
| 55 | * https://en.wikipedia.org/wiki/Xorshift |
| 56 | * https://www.jstatsoft.org/article/view/v008i14 |
| 57 | * http://vigna.di.unimi.it/ftp/papers/xorshift.pdf |
| 58 | |
| 59 | Future Work |
| 60 | =========== |
| 61 | A simple "entropy pool" implementation could buffer incoming entropy later use |
| 62 | instead of requiring an application to directly poll the hardware RNG peripheral |
| 63 | when the random data is needed. This would let a device collect entropy when |
| 64 | idling, improving the latency of potentially performance-sensitive areas where |
| 65 | random numbers are needed. |