RFC 4086

Randomness Requirements for Security

๐Ÿ“… published June 2005, from ietf

Randomness Requirements for Security ๐ŸŽ€

  • RFC: 4086
  • Series: BCP 106 ๐Ÿ“
  • Category: Best Current Practice ๐Ÿ’…
  • Date: June 2005 ๐ŸŒธ
  • Authors: D. Eastlake, 3rd (Motorola Laboratories), J. Schiller (MIT), S. Crocker
  • Obsoletes: 1750 (RFC 1750)
  • Working group: Network Working Group

Status of This Memo ๐Ÿ“œ

This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements. Distribution of this memo is unlimited.

Copyright (C) The Internet Society (2005).

Abstract ๐Ÿ”ฎ

Okay so security systems are built on super strong cryptographic algorithms that totally foil pattern analysis attempts ๐Ÿ˜ค. But the security of these systems depends on generating secret quantities for passwords, cryptographic keys, and similar things. Using pseudo-random processes to make those secrets can result in pseudo-security, which is so not it ๐Ÿ™ˆ. A sophisticated attacker may find it easier to recreate the environment that produced the secret quantities and search the resulting small set of possibilities, instead of trying to locate the quantities somewhere in the whole potential number space.

Choosing random quantities to foil a resourceful and motivated adversary is surprisingly difficult ๐Ÿ’€. This document points out lots of pitfalls in using poor entropy sources or traditional pseudo-random number generation techniques to make those quantities. It recommends using truly random hardware techniques, and it shows that the existing hardware on many systems can be used for this purpose ๐Ÿฆ‹. It also gives suggestions to ameliorate the problem when a hardware solution isn't available, and it gives examples of how large such quantities need to be for some applications โœจ.

Table of Contents ๐Ÿ—‚๏ธ

   1. Introduction and Overview .......................................3
   2. General Requirements ............................................4
   3. Entropy Sources .................................................7
      3.1. Volume Required ............................................7
      3.2. Existing Hardware Can Be Used For Randomness ...............8
           3.2.1. Using Existing Sound/Video Input ....................8
           3.2.2. Using Existing Disk Drives ..........................8
      3.3. Ring Oscillator Sources ....................................9
      3.4. Problems with Clocks and Serial Numbers ...................10
      3.5. Timing and Value of External Events .......................11
      3.6. Non-hardware Sources of Randomness ........................12
   4. De-skewing .....................................................12
      4.1. Using Stream Parity to De-Skew ............................13
      4.2. Using Transition Mappings to De-Skew ......................14
      4.3. Using FFT to De-Skew ......................................15
      4.4. Using Compression to De-Skew ..............................15
   5. Mixing .........................................................16
      5.1. A Trivial Mixing Function .................................17
      5.2. Stronger Mixing Functions .................................18
      5.3. Using S-Boxes for Mixing ..................................19
      5.4. Diffie-Hellman as a Mixing Function .......................19
      5.5. Using a Mixing Function to Stretch Random Bits ............20
      5.6. Other Factors in Choosing a Mixing Function ...............20
   6. Pseudo-random Number Generators ................................21
      6.1. Some Bad Ideas ............................................21
           6.1.1. The Fallacy of Complex Manipulation ................21
           6.1.2. The Fallacy of Selection from a Large Database .....22
           6.1.3. Traditional Pseudo-random Sequences ................23
      6.2. Cryptographically Strong Sequences ........................24
           6.2.1. OFB and CTR Sequences ..............................25
           6.2.2. The Blum Blum Shub Sequence Generator ..............26
      6.3. Entropy Pool Techniques ...................................27
   7. Randomness Generation Examples and Standards ...................28
      7.1. Complete Randomness Generators ............................28
           7.1.1. US DoD Recommendations for Password Generation .....28
           7.1.2. The /dev/random Device .............................29
           7.1.3. Windows CryptGenRandom .............................30
      7.2. Generators Assuming a Source of Entropy ...................31
           7.2.1. X9.82 Pseudo-Random Number Generation ..............31
           7.2.2. X9.17 Key Generation ...............................33
           7.2.3. DSS Pseudo-random Number Generation ................34
   8. Examples of Randomness Required ................................34
      8.1. Password Generation .......................................35
      8.2. A Very High Security Cryptographic Key ....................36
   9. Conclusion .....................................................38
  10. Security Considerations ........................................38
  11. Acknowledgments ................................................39
  Appendix A: Changes from RFC 1750 ..................................40
  Informative References .............................................41

1. Introduction and Overview ๐Ÿฆ‹

Software cryptography is getting more and more popular, although it's got a long way to go before it's everywhere ๐ŸŒˆ. Systems like SSH, IPSEC, TLS, S/MIME, PGP, DNSSEC, and Kerberos are maturing and becoming part of the network landscape [SSH] [IPSEC] [TLS] [S/MIME] [MAIL_PGP*] [DNSSEC*]. For comparison, when the previous version of this document [RFC1750] came out in 1994, the only Internet cryptographic security specification in the IETF was the Privacy Enhanced Mail protocol [MAIL_PEM*]. Look how far we've come ๐Ÿฅนโœจ.

These systems give you substantial protection against snooping and spoofing ๐Ÿ›ก๏ธ. However, there's a potential flaw, and it's a big one ๐Ÿ˜ญ. At the heart of all cryptographic systems is the generation of secret, unguessable (i.e., random) numbers ๐ŸŽฒ.

The lack of generally available facilities for generating those random numbers (in other words, the lack of general availability of truly unpredictable sources) is an open wound in the design of cryptographic software ๐Ÿฉน. For the software developer who wants to build a key or password generation procedure that runs on a wide range of hardware, this is a very real problem ๐Ÿ’”.

Note that the requirement is for data that an adversary has a very low probability of guessing or determining ๐Ÿ‘€. This can easily fail if pseudo-random data is used that only passes traditional statistical tests for randomness, or if it's based on limited-range sources such as clocks โฐ. Sometimes these pseudo-random quantities can be guessed by an adversary searching through an embarrassingly small space of possibilities ๐Ÿ˜ฌ.

This Best Current Practice document describes techniques for producing random quantities that will hold up against attack ๐Ÿ’ช. It recommends that future systems include hardware random number generation, or provide access to existing hardware that can be used for this purpose ๐Ÿซถ. It suggests methods to use if that hardware isn't available, and it gives some estimates of how many random bits are needed for sample applications ๐Ÿงš.

2. General Requirements โœจ

okay bestie, let's talk about what randomness is actually FOR ๐Ÿ’… A super common example is picking a user password, usually just a simple character string. And obviously, if a password can be guessed, it's not giving security ๐Ÿ™ˆ For reusable passwords, people need to be able to remember them, so it can be a good idea to use pronounceable strings or phrases made of ordinary words. But that only changes the format of the password. It doesn't change the big requirement that the password be very hard to guess ๐Ÿ’œ

Lots of other requirements come from the crypto world ๐Ÿ” Cryptographic techniques can give you all kinds of services, including confidentiality and authentication. Those services run on quantities traditionally called "keys", which are unknown to an adversary and impossible for them to guess โœจ

TCP/IP even uses randomness for picking initial sequence numbers [RFC1948]. Iconic ๐Ÿฆ‹

Generally speaking, the examples above show two different kinds of random quantities you might want. For human-usable passwords, the only important thing is that they're unguessable. It doesn't matter if they're made of ASCII characters, so the top bit of every byte is zero, for example. But for fixed-length keys and things like that, you normally want quantities that look truly random, meaning their bits pass statistical randomness tests ๐ŸŒˆ

Next up, symmetric encryption, like one-time pads or an algorithm like the US Advanced Encryption Standard [AES]. Here, every party who wants to talk confidentially and/or with authentication has to know the same secret key ๐Ÿคซ With asymmetric or "public key" crypto, keys come in pairs. One key is private and has to stay secret with one party, and the other is public and can be published to the whole world. Figuring out the private key from the public key is computationally infeasible, and knowing the public key doesn't help an adversary at all [ASYMMETRIC]. For general references, check out [SCHNEIER, FERGUSON, KAUFMAN] ๐Ÿ“š

How much randomness you need also varies a LOT between crypto systems ๐Ÿ“ With pure RSA, you only need random quantities when you generate a brand new key pair. After that, you can sign any number of messages without needing more randomness. The public key Digital Signature Algorithm from the US National Institute of Standards and Technology (NIST) needs good random numbers for each signature [DSS]. And encrypting with a one-time pad (in principle the strongest encryption technique possible) needs randomness of equal volume to all the messages you process ๐Ÿ˜ญ General references again: [SCHNEIER, FERGUSON, KAUFMAN].

In most of these cases, an adversary can try to find the "secret" key by trial and error ๐Ÿ‘€ That's possible as long as the key is small enough compared to the message that the correct key can be uniquely identified. The chance of an adversary succeeding has to be made acceptably low, depending on the application. The size of the space the adversary has to search is tied to how much key "information" is present, in an information-theoretic sense [SHANNON]. That depends on how many different secret values are possible and how likely each one is, like this:

                              -----
                              \
        Bits of information =  \     - p   * log  ( p  )
                               /        i       2    i
                              /
                              -----

Here i counts from 1 to the number of possible secret values, and p sub i is the probability of the value numbered i. (Since p sub i is less than one, the log will be negative, so each term in the sum will be non-negative. Math is serving ๐Ÿงฎ)

If there are 2^n different values that are all equally likely, then n bits of information are present, and an adversary would have to try, on average, half of the values, or 2^(n-1), before guessing the secret. If the probabilities are unequal, there's less information, so the adversary will, on average, need fewer guesses. In particular, any values the adversary knows are impossible or very unlikely can be ignored at first, and they'll search the more probable values first ๐Ÿ•ต๏ธโ€โ™€๏ธ

Let's look at an example: a crypto system that uses 128-bit keys. If those keys are derived with a fixed pseudo-random number generator seeded with an 8-bit seed, then an adversary only needs to search through 256 keys (by running the generator with every possible seed), NOT 2^128 keys, even though it might look that way at first. Only 8 bits of "information" are in these 128-bit keys. Wild, right? ๐Ÿคฏ

Now, the analysis above is correct on average, but it can be misleading for crypto analysis, where the thing that really matters is the work factor for an adversary ๐Ÿ’… Say there's a pseudo-random number generator making 128-bit keys, like in the example above, but it generates zero half the time and a random pick from the remaining 2^128 - 1 values the rest of the time. The Shannon equation says there are 64 bits of information in one of these key values. But an adversary can just try the value zero and break the security of half the uses, albeit a random half ๐Ÿ’€ So for crypto purposes, it's also useful to look at other measures, like min-entropy, which is defined as:

        Min-entropy =  - log  ( maximum ( p  ) )
                                           i

Here i is as above. Using this equation, our new hypothetical distribution has 1 bit of min-entropy, versus 64 bits of classical Shannon entropy. Major difference, bestie ๐ŸŽ€

There's a whole spectrum of entropies, sometimes called Renyi entropy, specified by the parameter r. Here r = 1 is Shannon entropy, and r = infinity is min-entropy. When r = zero, it's just log (n), where n is the number of non-zero probabilities. Renyi entropy is a non-increasing function of r, so min-entropy is always the most conservative measure and usually the best one to use for crypto evaluation [LUBY] ๐ŸŒธ

Statistically tested randomness in the traditional sense is NOT the same as the unpredictability you need for security use ๐Ÿšจ

For example, using a widely available constant sequence, like the random table from the CRC Standard Mathematical Tables, is super weak against an adversary. If an adversary learns or guesses it, they can easily break all security, past and future, based on that sequence [CRC]. Another example: using AES with a constant key to encrypt successive integers like 1, 2, 3, ... will produce output with excellent statistical randomness properties, but it's still predictable ๐Ÿ™ƒ On the flip side, taking successive rolls of a six-sided die and encoding the values in ASCII would produce statistically poor output with a substantial unpredictable component. So passing or failing statistical tests doesn't tell you whether something is unpredictable or predictable. Main character energy for the stats, but not the whole story โœจ


3. Entropy Sources ๐Ÿฆ‹

Entropy sources tend to be very implementation dependent. Once you've gathered enough entropy, it can be used as the seed to produce the required amount of cryptographically strong pseudo-randomness, as described in Sections 6 and 7, after being de-skewed or mixed as necessary, as described in Sections 4 and 5 ๐Ÿ”ฅ

Is there any hope for true, strong, portable randomness in the future? There might be ๐Ÿ‘€ All that's needed is a physical source of unpredictable numbers.

Thermal noise (sometimes called Johnson noise in integrated circuits), or a radioactive decay source plus a fast, free-running oscillator, would do the trick directly [GIFFORD]. That's a trivial amount of hardware, and it could easily be a standard part of a computer's architecture. Most audio (or video) input devices are usable too [TURBID]. Furthermore, any system with a spinning disk or ring oscillator and a stable (crystal) time source or the like has an adequate source of randomness ([DAVIS] and Section 3.3). All that's needed is for computer vendors to widely agree that this small extra hardware, and the software to access it, is necessary and useful ๐Ÿ’–

ANSI X9 is currently developing a standard that includes a part devoted to entropy sources. See Part 2 of [X9.82] ๐Ÿงš

3.1. Volume Required

How much unpredictability is needed? Is it possible to quantify the requirement in terms of, say, number of random bits per second? ๐Ÿค”

The answer is: not very much! For AES, the key can be 128 bits, and, as we show in an example in Section 8, even the highest security system is unlikely to need strong keying material of much over 200 bits. If a series of keys is needed, they can be generated from a strong random seed (starting value) using a cryptographically strong sequence, as explained in Section 6.2. A few hundred random bits generated at start-up or once a day is enough if these techniques are used. Even if the random bits come in as slowly as one per second, and it's not possible to overlap the generation process, it should be tolerable in most high-security applications to wait 200 seconds occasionally โณ

These numbers are trivial to achieve ๐Ÿ’… A person could do it by repeatedly tossing a coin, and almost any hardware-based process is likely to be much faster.

3.2. Existing Hardware Can Be Used For Randomness

As described below, many computers come with hardware that can, with care, be used to generate truly random quantities ๐ŸŒˆ

3.2.1. Using Existing Sound/Video Input

Lots of computers are built with inputs that digitize some real-world analog source, like sound from a microphone or video from a camera. The "input" from a sound digitizer with no source plugged in, or from a camera with the lens cap on, is essentially thermal noise ๐ŸŽง If the system has enough gain to detect anything, that input can provide reasonably high quality random bits. This method is extremely dependent on the hardware implementation.

For example, on some UNIX-based systems, you can read from the /dev/audio device with nothing plugged into the microphone jack, or with the microphone picking up only low-level background noise. That data is essentially random noise. Still, it shouldn't be trusted without some checking, in case of hardware failure, and it will have to be de-skewed ๐Ÿ™ˆ

Combining this approach with compression to de-skew (see Section 4), you can generate a HUGE amount of medium-quality random data with the UNIX-style command line:

     cat /dev/audio | compress - >random-bits-file

A detailed examination of this type of randomness source appears in [TURBID] ๐Ÿซถ

3.2.2. Using Existing Disk Drives ๐Ÿ’ฟ

okay so disk drives have these tiny random wobbles in their rotational speed because of chaotic air turbulence [DAVIS, Jakobsson] ๐ŸŒช๏ธ if you add low-level disk seek-time instrumentation, you get a series of measurements that contain all that randomness โœจ the catch is the data is usually super correlated, so you need some serious processing, as described in Section 5.2 below ๐Ÿ™ˆ but here's the slay: experimentation a decade ago showed that, with that processing, even slow disk drives on the slower computers of that day could easily make 100 bits a minute or more of excellent random data ๐Ÿ’–

every bump in processor speed, which lets you time disk motion with better resolution or makes disk seeks happen faster, also boosts how many random bits this technique can make ๐Ÿš€ at the time of this paper and with modern hardware, a more typical rate would be in excess of 10,000 bits a second ๐Ÿคฏ this technique is literally used in random number generators included in many operating system libraries ๐Ÿซถ

Note: the inclusion of cache memories in disk controllers has little effect on this technique if very short seek times, which represent cache hits, are simply ignored. ๐Ÿ’…

3.3. Ring Oscillator Sources ๐ŸŒ€

okay bestie, if an integrated circuit is being designed or field-programmed, you can connect an odd number of gates in series to make a free-running ring oscillator ๐Ÿ”„ then you sample a point in the ring at a fixed frequency (like one set by a stable crystal oscillator), and you can extract some entropy from the variations in the free-running oscillator timing ๐Ÿฆ‹ to get more entropy per second, you can XOR sampled values from a few ring oscillators with relatively prime lengths ๐Ÿง  it's sometimes recommended to use an odd number of rings so that, even if the rings somehow become synchronously locked to each other, there will still be sampled bit transitions ๐Ÿ”ฅ another possible source to sample is the output of a noisy diode โšก

the sampled bits from these sources will have to be heavily de-skewed, just like disk rotation timings have to be (see Section 4) ๐Ÿซ  an engineering study would be needed to figure out how much entropy is actually being produced, depending on the particular design ๐Ÿ“‹ but honestly? these can be really good sources, and the cost is a trivial amount of hardware by modern standards ๐Ÿ’ธโœจ

as an example, IEEE 802.11i suggests the circuit below ๐Ÿ‘€ the design needs careful attention to isolating the rings from each other and from clocked circuits so you don't get undesired synchronization, etc., plus extensive post processing [IEEE_802.11i] ๐Ÿซถ

         |\     |\                |\
     +-->| >0-->| >0-- 19 total --| >0--+-------+
     |   |/     |/                |/    |       |
     |                                  |       |
     +----------------------------------+       V
                                             +-----+
         |\     |\                |\         |     | output
     +-->| >0-->| >0-- 23 total --| >0--+--->| XOR |------>
     |   |/     |/                |/    |    |     |
     |                                  |    +-----+
     +----------------------------------+      ^ ^
                                               | |
         |\     |\                |\           | |
     +-->| >0-->| >0-- 29 total --| >0--+------+ |
     |   |/     |/                |/    |        |
     |                                  |        |
     +----------------------------------+        |
                                                 |
         Other randomness, if available ---------+

3.4. Problems with Clocks and Serial Numbers โฐ

okay so computer clocks and similar operating system or hardware values provide significantly fewer real bits of unpredictability than you'd think from their specs ๐Ÿ˜ญ

tests have been done on clocks across numerous systems, and their behavior can vary widely and in unexpected ways ๐Ÿ™ƒ like, one version of an operating system on one set of hardware might give you microsecond resolution, while a different configuration of the "same" system always gives the same lower bits and only counts the upper bits at a much lower resolution ๐Ÿ’€ this means successive reads of the clock can produce identical values even when enough time has passed that the value "should" have changed based on the nominal clock resolution ๐Ÿฅด there are also cases where reading a clock a bunch can produce artificial sequential values, because of extra code that checks whether the clock is unchanged between two reads and bumps it up by one! ๐Ÿ˜ฑ designing portable application code to generate unpredictable numbers from system clocks is seriously hard, because the system designer doesn't always know the properties of the system clock ๐Ÿซ 

use of a hardware serial number (like an Ethernet MAC address) may also provide fewer bits of uniqueness than you'd guess ๐Ÿ‘€ these quantities are usually heavily structured, and subfields may have only a limited range of possible values, or the values may be easily guessable from the approximate date of manufacture or other data ๐Ÿ”

for example, a company that makes both computers and Ethernet adapters will, at least internally, probably use its own adapters, which really limits the range of built-in addresses ๐Ÿญ

so yeah, problems like these make producing code to generate unpredictable quantities difficult if the code needs to be ported across a variety of computer platforms and systems ๐ŸŒˆ


3.5. Timing and Value of External Events ๐ŸŽน

it's possible to measure the timing and content of mouse movement, key strokes, and similar user events ๐Ÿ–ฑ๏ธ this is a reasonable source of unguessable data, with some qualifications โœจ on some machines, input like key strokes is buffered, so even though the user's inter-keystroke timing may have sufficient variation and unpredictability, there might not be an easy way to access that variation ๐Ÿ˜ค another problem is that no standard method exists for sampling timing details ๐Ÿ™…โ€โ™€๏ธ which makes it hard to use this technique to build standard software meant for distribution to a large range of machines ๐Ÿ“ฆ

the amount of mouse movement and the actual key strokes are usually easier to access than timings, but they may yield less unpredictability because the user may provide highly repetitive input ๐Ÿ”

other external events, like network packet arrival times and lengths, can also be used, but only with great care ๐Ÿšจ the possibility of an adversary manipulating those network traffic measurements, and the lack of history at system start-up, must be carefully considered ๐Ÿ‘€ if this input is subject to manipulation, it must not be trusted as a source of entropy ๐Ÿ™…โ€โ™€๏ธ

in principle, almost any external sensor can be used, like raw radio reception or temperature sensing in appropriately equipped computers ๐ŸŒก๏ธ๐Ÿ“ก but in each case, you have to carefully consider how much this data is subject to adversarial manipulation and how much entropy it can actually provide ๐Ÿง

the above techniques are quite powerful against attackers that have no access to the quantities being measured ๐Ÿ’ช for example, these techniques would be powerful against offline attackers who had no access to one's environment and who were trying to crack one's random seed after the fact ๐Ÿ•ต๏ธโ€โ™€๏ธ in all cases, the more accurately you can measure the timing or value of an external sensor, the more rapidly you can generate bits โšก


3.6. Non-hardware Sources of Randomness ๐ŸŒธ

the best source of input entropy would be a hardware-based random source, like ring oscillators, disk drive timing, thermal noise, or radioactive decay ๐Ÿ† but if none of those is available, there are other possibilities ๐Ÿ™Œ these include system clocks, system or input/output buffers, user/system/hardware/network serial numbers or addresses and timing, and user input ๐ŸŽ€ unfortunately, each of these sources can produce very limited or predictable values under some circumstances ๐Ÿ˜ฉ

some of the sources above would be quite strong on multi-user systems, where each user is basically a source of randomness ๐Ÿ‘ฏโ€โ™€๏ธ but on a small single-user or embedded system, especially at start-up, it might be possible for an adversary to assemble a similar configuration ๐Ÿ•ณ๏ธ that could give the adversary mixing-process inputs that were correlated well enough to the originals to make an exhaustive search practical ๐Ÿ’€

using multiple random inputs with a strong mixing function is recommended, and it can overcome weakness in any particular input ๐Ÿง the timing and content of requested "random" user keystrokes can yield hundreds of random bits, but conservative assumptions need to be made ๐ŸŽฏ for example, one reasonably conservative assumption is that an inter-keystroke interval provides at most a few bits of randomness, but only when the interval is unique in the sequence of intervals up to that point ๐Ÿ”ข a similar assumption is that a key code provides a few bits of randomness, but only when the code is unique in the sequence ๐Ÿ”‘ so an interval or key code that duplicated a previous value is assumed to provide no additional randomness ๐Ÿ™…โ€โ™€๏ธ the results of mixing these timings with typed characters could be further combined with clock values and other inputs ๐Ÿซถ

this strategy may make portable code for producing good random numbers for security practical, even if some inputs are very weak on some target systems โœจ however, it may still fail against a high-grade attack on small, single-user, or embedded systems, especially if the adversary has ever been able to observe the generation process in the past ๐Ÿ˜ฌ a hardware-based random source is still preferable ๐Ÿ’–


4. De-skewing ๐ŸŒŠ

is there any specific requirement on the shape of the distribution of quantities gathered for the entropy to produce the random numbers? ๐Ÿค” the good news is that the distribution need not be uniform ๐ŸŽ‰ all that's needed to bound performance is a conservative estimate of how non-uniform it is ๐Ÿ“ simple techniques to de-skew a bit stream are given below, and stronger cryptographic techniques are described in Section 5.2 ๐Ÿ”

4.1. Using Stream Parity to De-Skew โœจ

okay so this one is a simple example, not a super practical one ๐Ÿ’…. Take a long enough string of bits and map it to "zero" or "one". The mapping won't come out perfectly uniform, but it can get as close as you want ๐Ÿซถ. The move here is to take the parity of the string. It's robust across every degree of skew up to the estimated maximum skew, and it's trivial to build in hardware ๐Ÿ”ฅ.

Here's the math for how many bits you need to sample ๐Ÿค“:

Say the ratio of ones to zeros is ( 0.5 + E ) to ( 0.5 - E ), where E is between 0 and 0.5 and measures the "eccentricity" of the distribution ๐Ÿงš. Now look at the parity function of N-bit samples. The chance the parity is one or zero is the sum of the odd or even terms in the binomial expansion of (p + q)^N, where p = 0.5 + E is the probability of a one and q = 0.5 - E is the probability of a zero ๐Ÿ’œ.

Those sums work out to:

                     N            N
    1/2 * ( ( p + q )  + ( p - q )  )

and

                     N            N
    1/2 * ( ( p + q )  - ( p - q )  )

(Which formula matches "parity is 1" depends on whether N is odd or even ๐Ÿ™ˆ.)

Since p + q = 1 and p - q = 2E, those reduce to:

                   N
    1/2 * [1 + (2E)  ]

and

                   N
    1/2 * [1 - (2E)  ]

Neither one is ever exactly 0.5 unless E is zero, but we can get them arbitrarily close ๐ŸŒธ. If we want the probabilities within some delta d of 0.5, e.g., then:

                        N
    ( 0.5 + ( 0.5 * (2E)  ) )  <  0.5 + d.

Solving for N gives N > log(2d)/log(2E). (Note that 2E is less than 1, so its log is negative. Dividing by a negative number flips the inequality. bestie, be careful with that one ๐Ÿ˜ญ.)

This table shows the length N of the string you have to sample for different skews, to get within 0.001 of a 50/50 distribution ๐Ÿ“:

            +---------+--------+-------+
            | Prob(1) |    E   |    N  |
            +---------+--------+-------+
            |   0.5   |  0.00  |    1  |
            |   0.6   |  0.10  |    4  |
            |   0.7   |  0.20  |    7  |
            |   0.8   |  0.30  |   13  |
            |   0.9   |  0.40  |   28  |
            |   0.95  |  0.45  |   59  |
            |   0.99  |  0.49  |  308  |
            +---------+--------+-------+

The last row is the iconic one ๐Ÿ‘‘. Even if the distribution is skewed 99% toward ones, the parity of a 308-sample string still lands within 0.001 of a 50/50 split. But, as we'll see in section 5.2, there are much stronger techniques that pull out more of the available entropy ๐Ÿ’–.


4.2. Using Transition Mappings to De-Skew ๐Ÿฆ‹

Another technique, originally due to von Neumann [VON_NEUMANN], is to read a bit stream as a sequence of non-overlapping pairs. You then throw away any 00 or 11 pairs, and read 01 as a 0 and 10 as a 1 ๐ŸŽ€. Assume the probability of a 1 is 0.5+E and the probability of a 0 is 0.5-E, where E is the eccentricity of the source from the previous section. Then the probability of each pair is:

     +------+-----------------------------------------+
     | pair |            probability                  |
     +------+-----------------------------------------+
     |  00  | (0.5 - E)^2          =  0.25 - E + E^2  |
     |  01  | (0.5 - E)*(0.5 + E)  =  0.25     - E^2  |
     |  10  | (0.5 + E)*(0.5 - E)  =  0.25     - E^2  |
     |  11  | (0.5 + E)^2          =  0.25 + E + E^2  |
     +------+-----------------------------------------+

This technique completely eliminates any bias ๐Ÿ’…, but it needs an indeterminate number of input bits for any particular number of output bits ๐Ÿ˜ญ. The probability of any given pair being discarded is 0.5 + 2E^2, so the expected number of input bits needed to produce X output bits is X/(0.25 - E^2).

This technique assumes the bits come from a stream where every bit has the same probability of being a 0 or a 1 as any other bit in the stream, and that the bits are uncorrelated, i.e., that they come from identical independent distributions. If alternate bits come from two correlated sources, for example, the analysis above breaks down ๐Ÿ™ˆ.

This technique also shows how a simple statistical analysis can mislead you if you aren't always on the lookout for patterns an adversary could exploit ๐Ÿ‘€. Suppose the algorithm were misread slightly, so that overlapping successive bit pairs were used instead of non-overlapping ones. The statistical analysis given would come out the same. But instead of an unbiased, uncorrelated series of random 1s and 0s, it would produce a totally predictable sequence of exactly alternating 1s and 0s ๐Ÿ’€.


4.3. Using FFT to De-Skew ๐ŸŒˆ

When real-world data has strongly correlated bits, it may still contain useful amounts of entropy โœจ. That entropy can be pulled out using various transforms, the most powerful of which are described in section 5.2 below.

Using the Fourier transform of the data, or its optimized variant the FFT, is interesting mainly for theoretical reasons ๐Ÿค“. It can be shown that this technique discards strong correlations. If enough data is processed and the remaining correlations decay, spectral lines that approach statistical independence and normally distributed randomness can be produced [BRILLINGER] ๐Ÿซถ.


4.4. Using Compression to De-Skew ๐Ÿงš

Reversible compression techniques also offer a crude way to de-skew a skewed bit stream ๐Ÿ’–. This follows directly from the definition of reversible compression and the formula in Section 2 for the amount of information in a sequence. Since the compression is reversible, the shorter output has to contain the same amount of information as the longer input did. By the Shannon information equation, this is only possible if, on average, the probabilities of the different shorter sequences are more uniformly distributed than the probabilities of the longer sequences were. So the shorter sequences end up de-skewed relative to the input ๐Ÿ”ฅ.

BUT (big but ๐Ÿ™ˆ), many compression techniques add a somewhat predictable preface to their output stream, may insert a similar sequence periodically, or otherwise introduce subtle patterns of their own. They should only be considered rough techniques compared to those in Section 5.2 ๐Ÿฅบ. At a minimum, the beginning of the compressed sequence should be skipped, and only later bits should be used for applications that need roughly-random bits.


5. Mixing ๐Ÿ’œ

What's the best overall strategy for getting unguessable random numbers when you don't have a strong, reliable hardware entropy source? ๐Ÿค” It's to get input from a number of uncorrelated sources and mix them with a strong mixing function. A good mixing function preserves the entropy in any of the sources, even if the other quantities being combined happen to be fixed or easily guessable (low entropy) ๐Ÿ‘‘. This approach may be advisable even with a good hardware source, because hardware can fail too ๐Ÿ˜ญ. But you have to weigh that against a possible increase in the chance of overall failure due to added software complexity.

Once you've used good sources, like some of those listed in Section 3, and mixed them the way this section describes, you have a strong seed โœจ. That seed can then be used to produce large amounts of cryptographically strong material, as described in Sections 6 and 7 ๐ŸŽ€.

A strong mixing function is one that combines inputs and produces an output where each output bit is a different complex non-linear function of all the input bits ๐Ÿฆ‹. On average, changing any input bit changes about half the output bits. But because the relationship is complex and non-linear, no particular output bit is guaranteed to change when any particular input bit changes ๐Ÿค“.

Now think about converting a stream of bits that is skewed toward 0 or 1, or has a somewhat predictable pattern, into a shorter stream that's more random, as discussed in Section 4 ๐Ÿ“. This is just another case where you want a strong mixing function: mix the input bits and produce a smaller number of output bits. The technique in Section 4.1, using the parity of a number of bits, is simply the result of XORing them successively. That's examined as a trivial mixing function, immediately below. Using stronger mixing functions to extract more randomness from a stream of skewed bits is examined in Section 5.2. See also [NASLUND] ๐ŸŒธ.

5.1. A Trivial Mixing Function ๐Ÿงš

For expository purposes, here's a trivial example for single-bit inputs using the Exclusive Or (XOR) function ๐Ÿ’…. This function is equivalent to addition without carry, as shown in the table below. It's a degenerate case in which the output bit always changes when either input bit changes. But despite its simplicity, it's a useful illustration ๐ŸŽ€.

          +-----------+-----------+----------+
          |  input 1  |  input 2  |  output  |
          +-----------+-----------+----------+
          |     0     |     0     |     0    |
          |     0     |     1     |     1    |
          |     1     |     0     |     1    |
          |     1     |     1     |     0    |
          +-----------+-----------+----------+

If inputs 1 and 2 are uncorrelated and combined this way, the output will be an even better (less skewed) random bit than either input ๐Ÿ™Œ. If we assume an "eccentricity" E as defined in Section 4.1 above, the output eccentricity relates to the input eccentricities like this:

     E       = 2 * E        * E
      output        input 1    input 2

Since E is never greater than 1/2, the eccentricity always improves, except when at least one input is a totally skewed constant ๐Ÿ”ฅ. The table below shows this, where the top and left side values are the two input eccentricities and the entries are the output eccentricity:

  +--------+--------+--------+--------+--------+--------+--------+
  |    E   |  0.00  |  0.10  |  0.20  |  0.30  |  0.40  |  0.50  |
  +--------+--------+--------+--------+--------+--------+--------+
  |  0.00  |  0.00  |  0.00  |  0.00  |  0.00  |  0.00  |  0.00  |
  |  0.10  |  0.00  |  0.02  |  0.04  |  0.06  |  0.08  |  0.10  |
  |  0.20  |  0.00  |  0.04  |  0.08  |  0.12  |  0.16  |  0.20  |
  |  0.30  |  0.00  |  0.06  |  0.12  |  0.18  |  0.24  |  0.30  |
  |  0.40  |  0.00  |  0.08  |  0.16  |  0.24  |  0.32  |  0.40  |
  |  0.50  |  0.00  |  0.10  |  0.20  |  0.30  |  0.40  |  0.50  |
  +--------+--------+--------+--------+--------+--------+--------+

BUT, and this is a big one ๐Ÿšจ, all of the calculations above assume the inputs are not correlated. Say the inputs were the parity of the number of minutes since midnight on two clocks that are accurate to a few seconds. Each one might look random if sampled at random intervals much longer than a minute ๐Ÿ•ฐ๏ธ. Yet if both were sampled and combined with XOR, the result would be zero most of the time ๐Ÿ’€.

5.2. Stronger Mixing Functions โœจ

Okay bestie, the US Government Advanced Encryption Standard [AES] is the queen of strong mixing functions for multiple bit quantities ๐Ÿ‘‘. It takes up to 384 bits of input (128 bits of "data" and 256 bits of "key") and spits out 128 bits of output, where every output bit depends on a complex non-linear function of all the input bits ๐Ÿซถ. Other encryption functions with this same vibe, like [DES], can also be used by treating all of their key and data input bits as stuff to mix ๐Ÿ’….

Another iconic family is the "message digest" or hashing functions, like the US Government Secure Hash Standards [SHA*] and the MD4, MD5 [MD4, MD5] series ๐ŸŒˆ. These take a practically unlimited amount of input and make a relatively short, fixed-length output that mixes all the input bits. The MD* series gives 128 bits of output, SHA-1 gives 160 bits, and other SHA functions give up to 512 bits โœจ.

Even though the message digest functions are built for variable amounts of input, AES and other encryption functions can also combine any number of inputs ๐Ÿงš. If 128 bits of output is enough, you can pack the inputs into a 128-bit data quantity and use successive AES "keys", padding with zeros if needed. Then the quantity gets successively encrypted by those "keys" using AES in Electronic Codebook Mode. Or, alternatively, the input could be packed into one 128-bit key and multiple data blocks, and a CBC-MAC could be calculated [MODES] ๐ŸŒธ.

More complex mixing should be used if more than 128 bits of output are needed and you want to use AES (but note that it is absolutely impossible to get more bits of "randomness" out than are put in ๐Ÿ™ˆ). For example, say the inputs are packed into three quantities, A, B, and C. You can use AES to encrypt A with B and then with C as keys to make the first part of the output, then encrypt B with C and then A for more output, and if necessary, encrypt C with A and then B for yet more. Still more output can be made by reversing the order of the keys above. The same can be done with the hash functions, hashing various subsets of the input data or different copies of the input data with different prefixes and/or suffixes to produce multiple outputs ๐Ÿ’œ.

For an example of using a strong mixing function, think about a string of 308 bits, each of which is biased 99% toward zero ๐Ÿ“. The parity technique in Section 4.1 reduces this to one bit, with only a 1/1000 deviance from being equally likely a zero or one. But, applying the equation for information given in Section 2, this 308-bit skewed sequence contains over 5 bits of information. So hashing it with SHA-1 and taking the bottom 5 bits of the result would yield 5 unbiased random bits, not the single bit you get from calculating the parity of the string ๐Ÿ˜ญ. Alternatively, for some applications, you could use the entire hash output to keep almost all of the 5+ bits of entropy in a 160-bit quantity ๐Ÿฆ‹.


5.3. Using S-Boxes for Mixing ๐ŸŽ€

Many modern block encryption functions, including DES and AES, include modules called S-Boxes (substitution boxes) ๐Ÿง . These produce a smaller number of outputs from a larger number of inputs through a complex non-linear mixing function, which has the effect of concentrating limited entropy from the inputs into the output.

S-Boxes sometimes incorporate bent Boolean functions (functions of an even number of bits producing one output bit with maximum non-linearity) ๐ŸŒŸ. Looking at the output for all input pairs differing in any particular bit position, exactly half the outputs are different. An S-Box in which each output bit is produced by a bent function, such that any linear combination of these functions is also a bent function, is called a "perfect S-Box" ๐Ÿ‘‘.

S-boxes and various repeated applications or cascades of such boxes can be used for mixing [SBOX1, SBOX2] ๐ŸŒธ.


5.4. Diffie-Hellman as a Mixing Function ๐Ÿ”

Diffie-Hellman exponential key exchange is a technique that yields a shared secret between two parties ๐Ÿ’–. It can be computationally infeasible for a third party to determine this secret, even if they can observe all the messages between the two communicating parties. This shared secret is a mixture of initial quantities generated by each of the parties [D-H] โœจ.

If these initial quantities are random and uncorrelated, then the shared secret combines their entropy but, of course, can not produce more randomness than the size of the shared secret generated ๐Ÿซง.

Although this is true if the Diffie-Hellman computation is performed privately, an adversary who can observe either of the public keys and knows the modulus being used need only search through the space of the other secret key in order to calculate the shared secret [D-H] ๐Ÿ™ˆ. So, conservatively, it would be best to consider public Diffie-Hellman to produce a quantity whose guessability corresponds to the worse of the two inputs. Because of this, and the fact that Diffie-Hellman is computationally intensive, its use as a mixing function is not recommended ๐Ÿ’€.


5.5. Using a Mixing Function to Stretch Random Bits ๐ŸŒˆ

Although it is not necessary for a mixing function to produce the same or fewer output bits than its inputs, mixing bits can not "stretch" the amount of random unpredictability present in the inputs ๐Ÿ˜ค. Thus, four inputs of 32 bits each, in which there are 12 bits worth of unpredictability (such as 4,096 equally probable values) in each input, can not produce more than 48 bits worth of unpredictable output. The output can be expanded to hundreds or thousands of bits by, for example, mixing with successive integers, but the clever adversary's search space is still 2^48 possibilities. Furthermore, mixing to fewer bits than are input will tend to strengthen the randomness of the output ๐Ÿ’….

The last table in Section 5.1 shows that mixing a random bit with a constant bit with Exclusive Or will produce a random bit. While this is true, it does not provide a way to "stretch" one random bit into more than one. If, for example, a random bit is mixed with a 0 and then with a 1, this produces a two-bit sequence, but it will always be either 01 or 10. Since there are only two possible values, there is still only the one bit of original randomness ๐Ÿซ .


5.6. Other Factors in Choosing a Mixing Function ๐Ÿง

For local use, AES has the advantages that it has been widely tested for flaws, is reasonably efficient in software, and is widely documented and implemented, with hardware and software implementations available all over the world, including open source code ๐ŸŒ. The SHA* family has had a little less study and tends to require more CPU cycles than AES, but there is no reason to believe they are flawed. Both SHA* and MD5 were derived from the earlier MD4 algorithm. They all have source code available [SHA*, MD4, MD5]. Some signs of weakness have been found in MD4 and MD5. In particular, MD4 has only three rounds, and there are several independent breaks of the first two or last two rounds. And some collisions have been found in MD5 output ๐Ÿ’€.

AES was selected by a robust, public, and international process. It and SHA* have been vouched for by the US National Security Agency (NSA) on the basis of criteria that mostly remain secret, as was DES. While this has been the cause of much speculation and doubt, investigation of DES over the years has indicated that NSA involvement in modifications to its design, which originated with IBM, was primarily to strengthen it. There has been no announcement of a concealed or special weakness being found in DES. It is likely that the NSA modifications to MD4 to produce the SHA algorithms similarly strengthened these algorithms, possibly against threats not yet known in the public cryptographic community ๐Ÿ•ต๏ธ

Where input lengths are unpredictable, hash algorithms are more convenient to use than block encryption algorithms, since they are generally designed to accept variable length inputs. Block encryption algorithms generally require an additional padding algorithm to accommodate inputs that are not an even multiple of the block size ๐Ÿงฉ.

As of the time of this document, the authors know of no patent claims to the basic AES, DES, SHA*, MD4, and MD5 algorithms other than patents for which an irrevocable royalty-free license has been granted to the world. There may, of course, be essential patents of which the authors are unaware, or patents on implementations or uses, or other relevant patents issued or to be issued ๐Ÿ“œ.


6. Pseudo-random Number Generators ๐ŸŽฒ

When a seed has sufficient entropy, from input as described in Section 3 and possibly de-skewed and mixed as described in Sections 4 and 5, one can algorithmically extend that seed to produce a large number of cryptographically-strong random quantities. Such algorithms are platform independent and can operate in the same fashion on any computer. For the algorithms to be secure, their input and internal workings must be protected from adversarial observation ๐Ÿ”’.

The design of such pseudo-random number generation algorithms, like the design of symmetric encryption algorithms, is not a task for amateurs ๐Ÿ™…. Section 6.1 below lists a number of bad ideas that failed algorithms have used. To learn what works, skip Section 6.1 and just read the remainder of this section and Section 7, which describes and references some standard pseudo random number generation algorithms. See Section 7 and Part 3 of [X9.82] ๐Ÿ“š.

6.1. Some Bad Ideas ๐Ÿšฉ

The subsections below describe a number of ideas that might seem reasonable but that lead to insecure pseudo-random number generation ๐Ÿ™ˆ.

6.1.1. The Fallacy of Complex Manipulation ๐Ÿง 

okay so one trap that looks super unpredictable but isn't ๐Ÿ’€ is taking a really complicated algorithm (or a great old-school pseudo-random generator with nice statistics) and using the system clock as the seed to make a cryptographic key. If an attacker roughly knows when the generator started, they only have a small pile of possible seeds to test, because they can guess what the clock was likely showing. You can generate tons of bits, but the search space the attacker has to check could still be tiny ๐Ÿ˜ญ

So, bestie, very strong or complicated mixing won't save you if the attacker can figure out what the mixing is and the starting seed doesn't have enough entropy. They can usually work through the limited set of outputs from the limited set of seeds and break your security anyway ๐Ÿ™ˆ

Another big mistake is assuming a super complex PRNG algorithm will give you strong random numbers when nobody has any theory behind it or has analyzed it. There's a iconic example of this near the start of Chapter 3 in [KNUTH], where the author describes a complex algorithm. The idea was that the machine language program would be so tangled that someone reading the code with no comments wouldn't have a clue what it was doing. Unfortunately, when people actually used it, it quickly collapsed into a single repeated value in one case and a small cycle of values in another case ๐Ÿ’…

And here's the plot twist: complex manipulation doesn't help if you only have a limited range of seeds, and blindly picked complex manipulation can actually destroy the entropy in a good seed! ๐Ÿ˜ฑ๐ŸŒ€

6.1.2. The Fallacy of Selection from a Large Database ๐Ÿ“š

Another move that gives off strong "unpredictable" vibes but isn't really it is randomly picking a chunk out of a big database and assuming its strength depends on how many total bits the database holds. For example, typical USENET servers process many megabytes of information per day [USENET_1, USENET_2]. Say you grab 32 bytes from a random starting point in that data. That does NOT give you 32*8 = 256 bits of unguessability, sis ๐Ÿ™…โ€โ™€๏ธ Even if most of the data is human language with only 2 or 3 bits of information per byte, you still don't get 32*2 = 64 bits. If the attacker has the same Usenet database, the only unguessability left is the starting point, which is perhaps a little over a couple of dozen bits ๐Ÿซ 

The same logic applies to picking sequences off a publicly available CD/DVD recording or any other big public database. If the attacker can access the same database, this "select from a large volume of data" step barely helps ๐Ÿ˜ค It can help if the selection comes from data the attacker can't see, like system buffers on an active multi-user system ๐Ÿฆ‹

6.1.3. Traditional Pseudo-random Sequences ๐Ÿงš

This part is about the old-school sources of deterministic or "pseudo-random" numbers. They usually start from a "seed" value and use simple numeric or logical operations to churn out a sequence. Heads up: none of the techniques in this section are suitable for cryptographic use ๐Ÿšซ They're here for general info only, bestie.

[KNUTH] has a classic explanation of pseudo-random numbers. The applications he covers are simulations of natural phenomena, sampling, numerical analysis, testing computer programs, decision making, and games. None of those have the same characteristics as the security stuff we're talking about. Only the last two could involve an adversary hunting for the random quantity ๐Ÿ‘€ But even then, the adversary usually gets only one shot at a guessed value. When you're guessing passwords or trying to break an encryption scheme, the adversary normally gets many, maybe unlimited, chances to guess right. Sometimes they can even store the message and attack it over and over. And adversaries are also assumed to be aided by a computer ๐Ÿค–๐Ÿ’ป

For testing whether numbers are "random," Knuth suggests a bunch of measures, both statistical and spectral. These check things like autocorrelation between different parts of a "random" sequence or how its values are distributed. But here's the tea โ˜• a constant stored random sequence, like the "random" sequence printed in the CRC Standard Mathematical Tables [CRC], could pass those tests too. Even though that sequence passes every test Knuth suggests, it's totally unsuitable for cryptographic use, because adversaries have to be assumed to have copies of all commonly published "random" sequences and to be able to spot the source and predict future values ๐Ÿ’€๐Ÿซ 

A typical pseudo-random number generation technique is the linear congruence PRNG. It uses modular arithmetic, where the value numbered N+1 is calculated from the value numbered N by:

     V    = ( V  * a + b )(Mod c)
      N+1      N

This technique is closely related to linear shift register PRNGs, which are well understood cryptographically [SHIFT*]. In these generators, bits get shifted in at one end of a shift register as the Exclusive Or (binary sum without carry) of bits from selected fixed taps. For example, check this out:

   +----+     +----+     +----+                      +----+
   | B  | <-- | B  | <-- | B  | <--  . . . . . . <-- | B  | <-+
   |  0 |     |  1 |     |  2 |                      |  n |   |
   +----+     +----+     +----+                      +----+   |
     |                     |            |                     |
     |                     |            V                  +-----+
     |                     V            +----------------> |     |
     V                     +-----------------------------> | XOR |
     +---------------------------------------------------> |     |
                                                           +-----+

    V    = ( ( V  * 2 ) + B  XOR  B ... )(Mod 2^n)
     N+1         N         0       2

The quality of these traditional PRNG algorithms is judged by statistical tests on the sequences they make. Carefully chosen values of a, b, c, and initial V, or a carefully placed shift register tap in the simple process above, can produce excellent statistics โœจ

These sequences might be fine for simulations (Monte Carlo experiments), as long as the sequence is orthogonal to the structure of the space being explored. Even then, subtle patterns can cause trouble ๐Ÿ™ƒ But they are clearly bad news for security applications ๐Ÿšจ They're fully predictable if the initial state is known. Depending on the form of the PRNG, the sequence might be figured out from just a short peek at it [SCHNEIER, STERN]. For example, with the generators above, you can work out V(n+1) if you know V(n). It's actually been shown that with these techniques, even if only one bit of each pseudo-random value is released, the seed can be determined from short sequences ๐Ÿ˜ฑ

And it doesn't stop there: not only have linear congruent generators been broken, but techniques are now known for breaking all polynomial congruent generators [KRAWCZYK]. Yikes ๐Ÿ’”

6.2. Cryptographically Strong Sequences ๐Ÿ”

Sometimes you need a whole series of random quantities, and an adversary might learn some of the values in it. In general, adversaries should not be able to predict other values from the ones they already know ๐Ÿ‘€

The correct technique is to start with a strong random seed, take cryptographically strong steps from that seed [FERGUSON, SCHNEIER], and never reveal the complete state of the generator in the sequence elements ๐Ÿซถ If each value can be calculated in a fixed way from the previous value, then once any value is compromised, every future value can be determined. That would be the case, for instance, if each value were a constant function of the previously used values, even if the function were a super strong, non-invertible message digest function. So the vibe is: no predictable chains! ๐Ÿ”—๐Ÿšซ

(Side note, but it's a good one ๐Ÿ’œ If a technique for generating a sequence of key values is fast enough, it can trivially be used as the basis for a confidentiality system. If two parties use the same sequence generation technique and start with the same seed material, they'll generate identical sequences. These could be XOR'ed with the data being sent to encrypt it, and XOR'ed with the received data to decrypt it, thanks to the reversible properties of the XOR operation. This is commonly called a simple stream cipher ๐ŸŽ€)

6.2.1. OFB and CTR Sequences โœจ

okay so the first way to cook up a strong sequence is to grab a seed, hash it together with successive integers (or something similar), and then mask the results so the adversary can't see too much of the generator's state ๐Ÿ”๐Ÿ’–

you could also use an "encryption" algorithm with a random key and seed value to encrypt successive integers, which is basically counter (CTR) mode encryption ๐ŸŽ€ or you can feed all of the encryption output back in as the input for the next round. that's a specific flavor called output feedback mode (OFB) [MODES] ๐Ÿฆ‹

here's one where shifting and masking combine part of the output feedback with part of the old input. bestie, this kind of partial feedback should be avoided, and I'll explain why below ๐Ÿ’…

         +---------------+
         |       V       |
         |  |     n      |--+
         +--+------------+  |
               |            |     +---------+
          shift|            +---> |         |      +-----+
            +--+                  | Encrypt | <--- | Key |
            |           +-------- |         |      +-----+
            |           |         +---------+
            V           V
         +------------+--+
         |      V     |  |
         |       n+1     |
         +---------------+

ngl this looks similar to the shift register technique from Section 6.1.3 ๐ŸŒธ if the shift is one, that's exactly what's happening. the big difference is that the feedback comes from a complex non-linear function of all the bits, not a simple linear or polynomial mix of output from a few bit position taps. ๐Ÿงš

Donald W. Davies showed that this shifted partial output feedback significantly weakens an algorithm compared to feeding back all of the output bits as input ๐Ÿ˜ญ for DES specifically, repeatedly encrypting a full 64-bit quantity gives an expected repeat in about 2^63 iterations. but feeding back anything less than 64 (and more than 0) bits gives an expected repeat somewhere between 2^31 and 2^32 iterations! that's giving "not enough" ๐Ÿ’€

predicting values of a sequence from others, when it was generated with these techniques, is equivalent to breaking the cryptosystem, or to inverting the "non-invertible" hashing with only partial information available. the less info revealed in each iteration, the harder it is for an adversary to predict the sequence ๐Ÿ”ฅ so it's best to use only one bit from each value. and it's been shown that in some cases this makes it impossible to break a system, even when the cryptographic system is invertible and could be broken if all of each generated value were revealed. iconic ๐Ÿ‘‘


6.2.2. The Blum Blum Shub Sequence Generator ๐Ÿง 

currently, the generator with the strongest public proof of strength is the Blum Blum Shub generator, named after its inventors [BBS] ๐Ÿ’œ it's also very simple, and it's based on quadratic residues. its only downside is that it's computationally intensive compared to the traditional techniques in Section 6.1.3. that's not a huge deal if you're using it for moderately-infrequent stuff, like generating session keys ๐Ÿ—๏ธ

here's the recipe. choose two large prime numbers (say, p and q) that each give a remainder of 3 when divided by 4. let n = p * q. then pick a random number, x, that is relatively prime to n. the initial seed for the generator and the method for calculating later values are:

              2
   s    =  ( x  )(Mod n)
    0

              2
   s    = ( s   )(Mod n)
    i+1      i

bestie, be careful to use only a few bits from the bottom of each s ๐Ÿซถ it's always safe to use only the lowest-order bit. if you use no more than the low-order bits given by:

   log  ( log  ( s  ) )
      2      2    i

then predicting any additional bits from a sequence generated this way is provably as hard as factoring n. and as long as the initial x is secret, n can be made public if you want ๐ŸŒˆ

an interesting characteristic of this generator is that any of the s values can be calculated directly ๐Ÿคฏ in particular:

            ( (2^i) (Mod ((p-1)*(q-1)) ) )
   s  = ( s                                )(Mod n)
    i      0

so in apps where lots of keys are generated this way, you don't have to save them all. each key can be effectively indexed and recovered from that small index plus the initial s and n. main character energy โœจ


6.3. Entropy Pool Techniques ๐ŸŒŠ

many modern pseudo-random number sources, like the ones in Sections 7.1.2 and 7.1.3, use the technique of keeping a "pool" of bits. you get operations for strongly mixing input with some randomness into the pool, and for extracting pseudo-random bits back out ๐Ÿ“ here's the picture:

          +--------+    +------+    +---------+
      --->| Mix In |--->| POOL |--->| Extract |--->
          |  Bits  |    |      |    |   Bits  |
          +--------+    +------+    +---------+
                            ^           V
                            |           |
                            +-----------+

the bits going into the pool can come from any of the hardware, environmental, or user input sources we talked about above ๐ŸŽ€ it's also common to save the pool's state on system shutdown and restore it on startup, when stable storage is available.

โš ๏ธ bestie, make sure enough entropy has actually been added to the pool to support the output uses you want. see [RSA_BULL1] for similar suggestions ๐Ÿ’€

7. Randomness Generation Examples and Standards ๐ŸŽ€

several public standards and widely deployed examples now exist for generating keys or other cryptographically random quantities ๐Ÿ’… some of them, in Section 7.1, include an entropy source. others, described in Section 7.2, provide the pseudo-random number strong-sequence generator but assume you'll input a random seed or input from an entropy source ๐Ÿซถ


7.1. Complete Randomness Generators ๐Ÿ”ฅ

three standards are described below. the two older ones use DES, with its 64-bit block and key size limit, but any equally strong or stronger mixing function could be swapped in [DES] ๐Ÿฆ‹ the third is a more modern, stronger standard based on SHA-1 [SHA*]. and lastly, the widely deployed modern UNIX and Windows random number generators get their moment too ๐Ÿ‘‘


7.1.1. US DoD Recommendations for Password Generation ๐Ÿ”

the United States Department of Defense has specific recommendations for password generation [DoD] ๐Ÿ’– it suggests using the US Data Encryption Standard [DES] in Output Feedback Mode [MODES], like this:

      Use an initialization vector determined from
           the system clock,
           system ID,
           user ID, and
           date and time;
      use a key determined from
           system interrupt registers,
           system status registers, and
           system counters; and,
      as plain text, use an external randomly generated 64-bit
      quantity such as the ASCII bytes for 8 characters typed
      in by a system administrator.

the password is then calculated from the 64-bit "cipher text" that DES produces in 64-bit Output Feedback Mode ๐Ÿ“ as many bits as needed can be taken from those 64 and expanded into a pronounceable word, phrase, or other format if a human has to remember the password ๐ŸŒธ


7.1.2. The /dev/random Device ๐ŸŽฒ

several versions of the UNIX operating system provide a kernel-resident random number generator ๐Ÿ’œ some of these generators use events the Kernel captures during normal system operation.

for example, on some versions of Linux, the generator is a random pool of 512 bytes, represented as 128 words of 4 bytes each ๐Ÿงš when an event happens, like a disk drive interrupt, the time of the event is XOR'ed into the pool, and the pool is stirred via a primitive polynomial of degree 128. the pool is treated as a ring buffer, with new data XOR'ed (after stirring with the polynomial) across the entire pool. it's giving very carefully engineered vibes โœจ

every call that adds entropy to the pool estimates how much likely true entropy the input contains ๐Ÿค“ the pool itself has an accumulator that estimates the total entropy across the whole pool.

input events come from several sources, listed below. unfortunately, for server machines without human operators, the first and third aren't available, so entropy may be added slowly in that case ๐Ÿ˜ญ

  1. Keyboard interrupts. The time of the interrupt and the scan code are added to the pool. This in effect adds entropy from the human operator by measuring inter-keystroke arrival times. ๐Ÿ’…
  2. Disk completion and other interrupts. A system being used by a person will likely have a hard-to-predict pattern of disk accesses. (But not all disk drivers support capturing this timing information with sufficient accuracy to be useful.) ๐Ÿ™ˆ
  3. Mouse motion. The timing and mouse position are added in. ๐Ÿ–ฑ๏ธ

when random bytes are required, the pool is hashed with SHA-1 [SHA*] to yield the returned bytes of randomness ๐Ÿ”ฅ if more bytes are needed than SHA-1's output (20 bytes), the hashed output is stirred back into the pool and a new hash is performed to get the next 20 bytes. as bytes are removed from the pool, the entropy estimate is decremented to match ๐Ÿซง

to make sure the pool is reasonably random at startup, the standard startup and shutdown scripts save the pool to a disk file at shutdown and read that file back in at startup ๐ŸŒˆ

there are two user-exported interfaces ๐Ÿ‘‘ /dev/random returns bytes from the pool, but blocks when the estimated entropy drops to zero. as entropy gets added to the pool from events, more data becomes available from /dev/random. random data from such a /dev/random device is suitable for generating long-term keys, if enough random bits are in the pool or get added in a reasonable amount of time ๐Ÿ”

/dev/urandom works like /dev/random, except it provides data even when the pool's entropy estimate drops to zero ๐Ÿฆ‹ this may be adequate for session keys, or for other key generation tasks where blocking to wait for more random bits isn't acceptable. the risk of taking data even when the pool's entropy estimate is small is that past output may be computable from current output, provided an attacker can reverse SHA-1. since SHA-1 is designed to be non-invertible, this is considered a reasonable risk ๐Ÿง 

to get random numbers under Linux, Solaris, or other UNIX systems equipped with code like this, all an application has to do is open either /dev/random or /dev/urandom and read the number of bytes it wants ๐ŸŽ€

(The Linux Random device was written by Theodore Ts'o. It was based loosely on the random number generator in PGP 2.X and PGP 3.0 (aka PGP 5.0).) ๐Ÿ’–

7.1.3. Windows CryptGenRandom ๐ŸชŸโœจ

okay bestie, Microsoft's go-to advice for the super widely used Windows OS is to use the CryptGenRandom pseudo-random number generation call with the CryptAPI cryptographic service provider ๐Ÿ’ป. You hand it a handle to a cryptographic service provider library, a pointer to a buffer where you can drop in your own entropy, and the buffer where the random stuff comes back, plus how many octets of randomness you want ๐ŸŽ€.

Behind the scenes, the Windows CryptAPI provider keeps a seed state variable for every user ๐ŸŒธ. Whenever CryptGenRandom gets called, that seed gets mixed with whatever randomness you passed in and a bunch of system and user data: process ID, thread ID, system clock, system time, system counter, memory status, free disk clusters, and a hashed user environment block ๐Ÿงš. All of that gets fed into SHA-1, and the output seeds an RC4 key stream ๐Ÿ”ฅ. That key stream is what actually produces your requested pseudo-random data, and it also updates the user's seed state variable for next time ๐Ÿ’œ.

Windows ".NET" users will probably find the RNGCryptoServiceProvider.GetBytes method interface way easier to use ๐Ÿ™Œ.

For more info, check out [WSC] ๐Ÿ“š.


7.2. Generators Assuming a Source of Entropy ๐ŸŒˆ

The three pseudo-random number generators in the next three sections all assume you're giving them a seed value with enough entropy ๐Ÿ”‹. From that seed, they generate a strong sequence (see Section 6.2) ๐Ÿ’ช.

7.2.1. X9.82 Pseudo-Random Number Generation ๐ŸŽฒ

The ANSI X9F1 committee is basically in the final stretch of making a standard for random number generation ๐Ÿ. It covers both true randomness generators and pseudo-random number generators, and it includes a bunch of PRNGs built on hash functions. One of them will probably be based on HMAC SHA hash constructs [RFC2104] ๐Ÿ“. The draft version of that generator is described below, minus a number of optional features [X9.82] ๐Ÿซถ.

In the subsections below, I'm just calling the HMAC hash construct "HMAC," but obviously you have to pick a particular standard SHA function when you actually use it ๐Ÿ’…. Generally speaking, if you want the strength of your pseudo-random values to be N bits, the SHA function you choose has to produce N or more bits of output, and you'll need a source of at least N bits of input entropy ๐Ÿ˜ญ. The same hash function has to be used all the way through one instantiation of this generator ๐Ÿ”’.

7.2.1.1. Notation ๐Ÿ“

In the following sections, we use this notation:

  • hash_length is the output size of the underlying hash function in use.
  • input_entropy is the input bit string that provides entropy to the generator.
  • K is a bit string of size hash_length that's part of the generator's state, and it gets updated at least once every time random bits are generated.
  • V is a bit string of size hash_length that's also part of the state. It gets updated each time hash_length bits of output are generated.
  • "|" represents concatenation.

7.2.1.2. Initializing the Generator ๐ŸŒฑ

Set V to all zero bytes, except the low-order bit of each byte is set to one.

Set K to all zero bytes, then set:

      K = HMAC ( K, V | 0x00 | input_entropy )

      V = HMAC ( K, V )

      K = HMAC ( K, V | 0x01 | input_entropy )

      V = HMAC ( K, V )

Note: All SHA algorithms produce an integral number of bytes, so the lengths of K and V will be integral numbers of bytes ๐Ÿง .

7.2.1.3. Generating Random Bits ๐ŸŽฐ

When you need output, just set:

      V = HMAC ( K, V )

and use the leading bits from V. If you need more bits than the length of V, set "temp" to a null bit string and then repeatedly do:

      V = HMAC ( K, V )
      temp = temp | V

stopping as soon as temp is equal to or longer than the number of random bits you asked for. Then use the requested number of leading bits from temp โœจ. The definition of the algorithm prohibits requesting more than 2^35 bits ๐Ÿšซ.

After you've extracted and saved your pseudo-random output bits like we just did, you MUST also perform two more HMACs before returning, like this:

      K = HMAC ( K, V | 0x00 )
      V = HMAC ( K, V )

7.2.2. X9.17 Key Generation ๐Ÿ”‘

The American National Standards Institute has specified the following method for generating a sequence of keys [X9.17] ๐Ÿ›๏ธ.

  • s0 is the initial 64 bit seed.
  • gn is the sequence of generated 64-bit key quantities.
  • k is a random key reserved for generating this key sequence.
  • t is the time at which a key is generated, to as fine a resolution as is available (up to 64 bits) โฐ.
  • DES ( K, Q ) is the DES encryption of quantity Q with key K.

Then:

      gn   = DES ( k, DES ( k, t ) XOR sn )

      sn+1 = DES ( k, DES ( k, t ) XOR gn )

If gn is going to be used as a DES key, then every eighth bit SHOULD be adjusted for parity for that use ๐Ÿ”. But the entire 64 bit unmodified gn should be used when calculating the next sn+1 ๐Ÿซถ.

7.2.3. DSS Pseudo-random Number Generation ๐Ÿงฎ

Appendix 3 of the NIST Digital Signature Standard [DSS] gives you a way to produce a sequence of pseudo-random 160 bit quantities for stuff like private keys ๐Ÿ—๏ธ. Change Notice 1 [DSS_CN1] then modified it into this algorithm for general-purpose pseudo-random numbers:

      t = 0x 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0

      XKEY0 = initial seed

      For j = 0 to ...

          XVAL = ( XKEYj + optional user input ) (Mod 2^512)

          Xj = G( t, XVAL )

          XKEYj+1 = ( 1 + XKEYj + Xj ) (Mod 2^512)

The X quantities produced this way are the pseudo-random sequence of 160-bit values ๐ŸŒŸ. There are two functions you can use for "G" above. Each one produces a 160-bit value and takes two arguments: a 160-bit value and a 512 bit value ๐Ÿค“.

The first one is based on SHA-1. It works by setting the 5 linking variables (denoted H with subscripts in the SHA-1 specification) to the first argument divided into fifths. Then steps (a) through (e) of section 7 of the NIST SHA-1 specification run over the second argument as if it were a 512-bit data block. The values of the linking variables after those steps get concatenated to produce the output of G [SHA*] ๐Ÿ’ซ.

As an alternative, NIST also defined an alternate G function based on multiple applications of the DES encryption function [DSS] ๐Ÿ”.


8. Examples of Randomness Required ๐ŸŽฏ

Here are two examples doing rough calculations of the randomness you need for security ๐Ÿง. The first one is for moderate security passwords, and the second assumes you need a super high-security cryptographic key ๐Ÿ‘‘.

Also, [ORMAN] and [RSA_BULL13] give info on the public key lengths that SHOULD be used for exchanging symmetric keys ๐Ÿ”‘๐Ÿ’•.

8.1. Password Generation ๐Ÿ”

Let's assume user passwords change once a year, and you want the probability that an adversary could guess the password for a particular account to be less than one in a thousand ๐Ÿ˜ค. Also assume that sending a password to the system is the only way to try one. The crucial question is then how often an adversary can try possibilities ๐Ÿค”. Let's say delays have been added to the system so an adversary can make at most one password try every six seconds โณ. That's 600 per hour, or about 15,000 per day, or about 5,000,000 tries in a year ๐Ÿ“ˆ. With any sort of monitoring, it's unlikely someone could actually keep trying nonstop for a whole year ๐Ÿ‘€. Even if log files only get checked monthly, 500,000 tries is more realistic before the attack gets noticed and people change their passwords and make it harder to keep guessing ๐Ÿšจ.

To have a one-in-a-thousand chance of guessing the password in 500,000 tries, you need a universe of at least 500,000,000 passwords, or about 2^29 ๐Ÿงฎ. So, 29 bits of randomness are needed ๐Ÿ’–. This can probably be achieved by using the US DoD-recommended inputs for password generation, since it has 8 inputs that probably average over 5 bits of randomness each (see section 7.1) ๐ŸŽ€. Using a list of 1,000 words, the password could be a three-word phrase (1,000,000,000 possibilities) ๐Ÿ“. By using case-insensitive letters and digits, six characters would be enough ((26+10)^6 = 2,176,782,336 possibilities) ๐ŸŒธ.

For a higher-security password, you need more bits. To cut the probability by 1,000, you have to increase the universe of passwords by that same factor, which adds about 10 bits ๐Ÿ“Š. So, to have only a one in a million chance of a password being guessed under the scenario above, you'd need 39 bits of randomness and a password that's a four-word phrase from a 1,000 word list, or eight letters/digits ๐Ÿซถ. To go down to a one-in-10^9 chance, you need 49 bits of randomness, which means a five-word phrase or a ten-letter/digit password ๐Ÿš€.

In a real system, of course, there are other factors ๐Ÿ™ˆ. For example, the larger and harder to remember passwords are, the more likely users will need to write them down, which adds extra risk of compromise ๐Ÿ“โš ๏ธ.

8.2. A Very High Security Cryptographic Key ๐Ÿ—๏ธ๐Ÿ’Ž

Let's assume a very high security key is needed for symmetric encryption/decryption between two parties ๐Ÿ›ก๏ธ. Also assume an adversary can observe communications and knows the algorithm being used ๐Ÿ‘€. Within the field of random possibilities, the adversary can try key values hoping to find the one in use ๐Ÿ•ต๏ธโ€โ™€๏ธ. Finally, assume brute force trial of keys is the best the adversary can do ๐Ÿ’€.

8.2.1. Effort per Key Trial ๐Ÿ’–

Okay so, how much effort does it take to try each key? ๐Ÿค” For super high-security stuff, bestie, you have to assume a low amount of effort. Even if trying one key would clearly take tens of thousands of computer cycles or more, there might be some pattern that lets huge blocks of key values get tested with way less effort per key. ๐Ÿ˜ณ So it's probably safest to assume no more than a couple of hundred cycles per key. (There's no clear lower bound on this, because computers work on a bunch of bits in parallel, and a sloppy encryption algorithm could let many keys, or even groups of keys, get tested in parallel. ๐Ÿ™ˆ But we still need to pick a number, and we can hope a reasonably strong algorithm got chosen for our hypothetical high-security task. ๐Ÿคž)

If the adversary can get their hands on a highly parallel processor or a big network of work stations, 10^11 cycles per second is probably a minimum assumption today. โšก Looking a few years ahead, there should be at least an order of magnitude improvement. So it's reasonable to assume that 10^10 keys could be checked per second, or 3.6*10^12 per hour, or 6*10^14 per week, or 2.4*10^15 per month. ๐Ÿ˜ฑ This means you need a minimum of 63 bits of randomness in keys so they can't be found in a month. But even then, a few years from now, a super determined and resourceful adversary could break the key in 2 weeks. ๐Ÿ’€ On average, they only need to try half the keys.

These questions get covered in detail in "Minimal Key Lengths for Symmetric Ciphers to Provide Adequate Commercial Security: A Report by an Ad Hoc Group of Cryptographers and Computer Scientists" [KeyStudy], which was sponsored by the Business Software Alliance. ๐Ÿ“š It concluded that a reasonable key length in 1995 for very high security is in the range of 75 to 90 bits. Since the cost of cryptography doesn't vary much with the key size, it recommends 90 bits. โœจ To update these recommendations, just add 2/3 of a bit per year for Moore's law [MOORE]. That translates to this: in the year 2004, a reasonable key length is in the 81- to 96-bit range. ๐Ÿฆ‹ And honestly? Today it's getting more and more common to use keys longer than 96 bits, like 128-bit (or longer) keys with AES, and keys with effective lengths of 112-bits with triple-DES. ๐Ÿ”ฅ

8.2.2. Meet-in-the-Middle Attacks ๐Ÿ•ต๏ธโ€โ™€๏ธ

Okay, so if chosen or known plain text and the resulting encrypted text are available, a "meet-in-the-middle" attack is possible if the structure of the encryption algorithm allows it. ๐Ÿ‘€ (In a known plain text attack, the adversary knows all or part of the messages being encrypted, possibly some standard header or trailer fields. In a chosen plain text attack, the adversary can force some chosen plain text to be encrypted, possibly by "leaking" an exciting text that the adversary sends over an encrypted channel because the text is so interesting. ๐Ÿ˜ญ)

Here's an oversimplified explanation of the meet-in-the-middle attack: the adversary can half-encrypt the known or chosen plain text with all possible first half-keys, sort the output, and then half-decrypt the encoded text with all the second half-keys. ๐Ÿงฉ If a match is found, the full key can be assembled from the halves and used to decrypt other parts of the message or other messages. At its best, this kind of attack can halve the exponent of the work required by the adversary, while adding a very large but roughly constant factor of effort. So if this attack can be mounted, a doubling of the amount of randomness in the very strong key to a minimum of 192 bits (96*2) is required for the year 2004, based on the [KeyStudy] analysis. ๐Ÿ”

This amount of randomness is well beyond the limit of the randomness in the inputs recommended by the US DoD for password generation. It could require user-typing timing, hardware random number generation, or other sources of randomness. โŒจ๏ธ๐ŸŽฒ

The meet-in-the-middle attack assumes that the cryptographic algorithm can be decomposed in this way. Hopefully no modern algorithm has this weakness, but there may be cases where we aren't sure of that, or even of what algorithm a key will be used with. ๐Ÿฅบ Even if a basic algorithm isn't subject to a meet-in-the-middle attack, trying to make a stronger algorithm by applying the basic algorithm twice (or two different algorithms sequentially) with different keys will gain less added security than you'd expect. ๐Ÿ“‰ Such a composite algorithm would be subject to a meet-in-the-middle attack. ๐Ÿ™ƒ

Enormous resources may be required to mount a meet-in-the-middle attack, but they're probably within the range of the national security services of a major nation. Essentially all nations spy on other nations' traffic. ๐Ÿ‘๏ธ Tea, but make it geopolitical. โ˜•

8.2.3. Other Considerations ๐Ÿง

[KeyStudy] also considers the possibilities of special-purpose code-breaking hardware, and having an adequate safety margin. ๐Ÿ› ๏ธ

Note that key length calculations like the ones above are controversial, and they depend on various assumptions about the cryptographic algorithms in use. ๐Ÿค“ In some cases, a professional with deep knowledge of algorithm-breaking techniques, and of the strength of the algorithm in use, could be satisfied with less than half of the 192 bit key size derived above.

For further examples of conservative design principles, see [FERGUSON]. ๐Ÿ“–


9. Conclusion ๐ŸŽ€

Generating unguessable "random" secret quantities for security use is an essential but difficult task. ๐Ÿ˜ค

Hardware techniques for producing the needed entropy would be relatively simple. In particular, the volume and quality wouldn't need to be high, and existing computer hardware, like audio input or disk drives, can be used. ๐ŸŽง๐Ÿ’พ

Widely-available computational techniques can process low-quality random quantities from multiple sources, or a larger quantity of that low-quality input from one source, to produce a smaller quantity of higher-quality keying material. โœจ If there's no hardware source of randomness, a variety of user and software sources can frequently, with care, be used instead. However, most modern systems already have hardware, like disk drives or audio input, that could be used to produce high-quality randomness. ๐ŸŒˆ

Once a sufficient quantity of high-quality seed key material (a couple of hundred bits) is available, computational techniques are available to produce cryptographically-strong sequences of computationally-unpredictable quantities from this seed material. ๐Ÿ”‘๐Ÿ’–

10. Security Considerations ๐Ÿšจ

This is serious, bestie. The entirety of this document concerns techniques and recommendations for generating unguessable "random" quantities for use as passwords, cryptographic keys, initialization vectors, sequence numbers, and similar security applications. If you get the randomness wrong, everything built on top of it is cooked. ๐Ÿ’€๐Ÿ”ฅ

11. Acknowledgements ๐Ÿซถ

Special thanks to Paul Hoffman and John Kelsey for their extensive comments, and to Peter Gutmann, who has permitted the incorporation of material from his paper "Software Generation of Practically Strong Random Numbers". ๐Ÿ’œ

The following people (in alphabetic order) have contributed substantially to this document:

Steve Bellovin, Daniel Brown, Don Davis, Peter Gutmann, Tony Hansen, Sandy Harris, Paul Hoffman, Scott Hollenback, Russ Housley, Christian Huitema, John Kelsey, Mats Naslund, and Damir Rajnovic. ๐Ÿ‘‘

The following people (in alphabetic order) contributed to RFC 1750, the predecessor of this document:

David M. Balenson, Don T. Davis, Carl Ellison, Marc Horowitz, Christian Huitema, Charlie Kaufman, Steve Kent, Hal Murray, Neil Haller, Richard Pitkin, Tim Redmond, and Doug Tygar. ๐ŸŒธ

Appendix A: Changes from RFC 1750 ๐Ÿฆ‹

  1. Additional acknowledgements have been added. ๐Ÿ™Œ
  2. Insertion of section 5.3 on mixing with S-boxes.
  3. Addition of section 3.3 on Ring Oscillator randomness sources.
  4. Addition of AES and the members of the SHA series producing more than 160 bits. Use of AES has been emphasized and the use of DES de-emphasized.
  5. Addition of section 6.3 on entropy pool techniques.
  6. Addition of section 7.2.3 on the pseudo-random number generation techniques given in FIPS 186-2 (with Change Notice 1), 7.2.1 on those given in X9.82, section 7.1.2 on the random number generation techniques of the /dev/random device in Linux and other UNIX systems, and section 7.1.3 on random number generation techniques in the Windows operating system.
  7. Addition of references to the "Minimal Key Lengths for Symmetric Ciphers to Provide Adequate Commercial Security" study published in January 1996 [KeyStudy] and to [RFC1948].
  8. Added caveats to using Diffie-Hellman as a mixing function and, because of those caveats and its computationally intensive nature, recommend against its use. ๐Ÿ™…โ€โ™€๏ธ
  9. Addition of references to the X9.82 effort and the [TURBID] and [NASLUND] papers.
  10. Addition of discussion of min-entropy and Renyi entropy and references to the [LUBY] book.
  11. Major restructuring, minor wording changes, and a variety of reference updates. ๐Ÿ”„

Informative References ๐Ÿ“š

[AES] "Specification of the Advanced Encryption Standard (AES)", United States of America, US National Institute of Standards and Technology, FIPS 197, November 2001.

[ASYMMETRIC] Simmons, G., Ed., "Secure Communications and Asymmetric Cryptosystems", AAAS Selected Symposium 69, ISBN 0-86531-338-5, Westview Press, 1982.

[BBS] Blum, L., Blum, M., and M. Shub, "A Simple Unpredictable Pseudo-Random Number Generator", SIAM Journal on Computing, v. 15, n. 2, 1986.

[BRILLINGER] Brillinger, D., "Time Series: Data Analysis and Theory", Holden-Day, 1981.

[CRC] "C.R.C. Standard Mathematical Tables", Chemical Rubber Publishing Company.

[DAVIS] Davis, D., Ihaka, R., and P. Fenstermacher, "Cryptographic Randomness from Air Turbulence in Disk Drives", Advances in Cryptology - Crypto '94, Springer-Verlag Lecture Notes in Computer Science #839, 1984.

[DES] "Data Encryption Standard", US National Institute of Standards and Technology, FIPS 46-3, October 1999. Also, "Data Encryption Algorithm", American National Standards Institute, ANSI X3.92-1981. See also FIPS 112, "Password Usage", which includes FORTRAN code for performing DES.

[D-H] Rescorla, E., "Diffie-Hellman Key Agreement Method", RFC 2631, June 1999.

[DNSSEC1] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, "DNS Security Introduction and Requirements", RFC 4033, March 2005.

[DNSSEC2] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, "Resource Records for the DNS Security Extensions", RFC 4034, March 2005.

[DNSSEC3] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, "Protocol Modifications for the DNS Security Extensions", RFC 4035, March 2005.

[DoD] "Password Management Guideline", United States of America, Department of Defense, Computer Security Center, CSC-STD-002-85, April 1885.

(See also "Password Usage", FIPS 112, which incorporates CSC-STD-002-85 as one of its appendices. FIPS 112 is currently available at: http://www.idl.nist.gov/fipspubs/fip112.htm.) ๐Ÿ“šโœจ

  • [DSS] "Digital Signature Standard (DSS)", US National Institute of Technology and Standards, FIPS 186-2, January 2000. ๐Ÿ’–
  • [DSS_CN1] "Digital Signature Standard Change Notice 1", US National Institute of Standards and Technology, FIPS 186-2 Change Notice 1, 5, October 2001. ๐ŸŽ€
  • [FERGUSON] Ferguson, N. and B. Schneier, "Practical Cryptography", Wiley Publishing Inc., ISBN 047122894X, April 2003. ๐Ÿฆ‹
  • [GIFFORD] Gifford, D., "Natural Random Number", MIT/LCS/TM-371, September 1988. ๐ŸŒธ
  • [IEEE_802.11i] "Amendment to Standard for Telecommunications and Information Exchange Between Systems - LAN/MAN Specific Requirements - Part 11: Wireless Medium Access Control (MAC) and physical layer (PHY) specifications: Medium Access Control (MAC) Security Enhancements", IEEE, January 2004. ๐Ÿ“ก
  • [IPSEC] Kent, S. and R. Atkinson, "Security Architecture for the Internet Protocol", RFC 2401, November 1998. ๐Ÿ”
  • [Jakobsson] Jakobsson, M., Shriver, E., Hillyer, B., and A. Juels, "A practical secure random bit generator", Proceedings of the Fifth ACM Conference on Computer and Communications Security, 1998. ๐Ÿงš
  • [KAUFMAN] Kaufman, C., Perlman, R., and M. Speciner, "Network Security: Private Communication in a Public World", Prentis Hall PTR, ISBN 0-13-046019-2, 2nd Edition 2002. ๐Ÿ“–
  • [KeyStudy] Blaze, M., Diffie, W., Riverst, R., Schneier, B. Shimomura, T., Thompson, E., and M. Weiner, "Minimal Key Lengths for Symmetric Ciphers to Provide Adequate Commercial Security: A Report by an Ad Hoc Group of Cryptographers and Computer Scientists", January 1996. Currently available at: http://www.crypto.com/papers/keylength.txt and http://www.securitydocs.com/library/441. ๐Ÿ”‘
  • [KNUTH] Knuth, D., "The Art of Computer Programming", Volume 2: Seminumerical Algorithms, Chapter 3: Random Numbers, Addison-Wesley Publishing Company, 3rd Edition, November 1997. ๐Ÿ‘‘
  • [KRAWCZYK] Krawczyk, H., "How to Predict Congruential Generators", Journal of Algorithms, V. 13, N. 4, December 1992. ๐Ÿ”ฎ
  • [LUBY] Luby, M., "Pseudorandomness and Cryptographic Applications", Princeton University Press, ISBN 0691025460, 8 January 1996. ๐ŸŒˆ
  • [MAIL_PEM1] Linn, J., "Privacy Enhancement for Internet Electronic Mail: Part I: Message Encryption and Authentication Procedures", RFC 1421, February 1993. ๐Ÿ’Œ
  • [MAIL_PEM2] Kent, S., "Privacy Enhancement for Internet Electronic Mail: Part II: Certificate-Based Key Management", RFC 1422, February 1993. ๐Ÿ’Œ
  • [MAIL_PEM3] Balenson, D., "Privacy Enhancement for Internet Electronic Mail: Part III: Algorithms, Modes, and Identifiers", RFC 1423, February 1993. ๐Ÿ’Œ
  • [MAIL_PEM4] Kaliski, B., "Privacy Enhancement for Internet Electronic Mail: Part IV: Key Certification and Related Services", RFC 1424, February 1993. ๐Ÿ’Œ
  • [MAIL_PGP1] Callas, J., Donnerhacke, L., Finney, H., and R. Thayer, "OpenPGP Message Format", RFC 2440, November 1998. ๐Ÿซถ
  • [MAIL_PGP2] Elkins, M., Del Torto, D., Levien, R., and T. Roessler, "MIME Security with OpenPGP", RFC 3156, August 2001. ๐Ÿซถ
  • [S/MIME] RFCs 2632 through 2634:
    • Ramsdell, B., "S/MIME Version 3 Certificate Handling", RFC 2632, June 1999. ๐Ÿ“ฌ
    • Ramsdell, B., "S/MIME Version 3 Message Specification", RFC 2633, June 1999. ๐Ÿ“ฌ
    • Hoffman, P., "Enhanced Security Services for S/MIME", RFC 2634, June 1999. ๐Ÿ“ฌ
  • [MD4] Rivest, R., "The MD4 Message-Digest Algorithm", RFC 1320, April 1992. ๐Ÿ“
  • [MD5] Rivest, R., "The MD5 Message-Digest Algorithm ", RFC 1321, April 1992. ๐Ÿ“
  • [MODES] "DES Modes of Operation", US National Institute of Standards and Technology, FIPS 81, December 1980. Also: "Data Encryption Algorithm - Modes of Operation", American National Standards Institute, ANSI X3.106-1983. ๐Ÿง
  • [MOORE] Moore's Law: the exponential increase in the logic density of silicon circuits. Originally formulated by Gordon Moore in 1964 as a doubling every year starting in 1962, in the late 1970s the rate fell to a doubling every 18 months and has remained there through the date of this document. See "The New Hacker's Dictionary", Third Edition, MIT Press, ISBN 0-262-18178-9, Eric S. Raymond, 1996. ๐Ÿ“ˆ
  • [NASLUND] Naslund, M. and A. Russell, "Extraction of Optimally Unbiased Bits from a Biased Source", IEEE Transactions on Information Theory. 46(3), May 2000. ๐ŸŽฒ
  • [ORMAN] Orman, H. and P. Hoffman, "Determining Strengths For Public Keys Used For Exchanging Symmetric Keys", BCP 86, RFC 3766, April 2004. ๐Ÿ’ช
  • [RFC1750] Eastlake 3rd, D., Crocker, S., and J. Schiller, "Randomness Recommendations for Security", RFC 1750, December 1994. ๐ŸŒŸ
  • [RFC1948] Bellovin, S., "Defending Against Sequence Number Attacks", RFC 1948, May 1996. ๐Ÿ›ก๏ธ
  • [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-Hashing for Message Authentication", RFC 2104, February 1997. ๐Ÿ”
  • [RSA_BULL1] "Suggestions for Random Number Generation in Software", RSA Laboratories Bulletin #1, January 1996. ๐Ÿš
  • [RSA_BULL13] Silverman, R., "A Cost-Based Security Analysis of Symmetric and Asymmetric Key Lengths", RSA Laboratories Bulletin #13, April 2000 (revised November 2001). ๐Ÿ’ฐ
  • [SBOX1] Mister, S. and C. Adams, "Practical S-box Design", Selected Areas in Cryptography, 1996. ๐Ÿงฉ
  • [SBOX2] Nyberg, K., "Perfect Non-linear S-boxes", Advances in Cryptography, Eurocrypt '91 Proceedings, Springer-Verland, 1991. ๐Ÿงฉ
  • [SCHNEIER] Schneier, B., "Applied Cryptography: Protocols, Algorithms, and Source Code in C", 2nd Edition, John Wiley & Sons, 1996. ๐Ÿ“•
  • [SHANNON] Shannon, C., "The Mathematical Theory of Communication", University of Illinois Press, 1963. Originally from: Bell System Technical Journal, July and October, 1948. ๐Ÿ“ก
  • [SHIFT1] Golub, S., "Shift Register Sequences", Aegean Park Press, Revised Edition, 1982. ๐ŸŒ€
  • [SHIFT2] Barker, W., "Cryptanalysis of Shift-Register Generated Stream Cypher Systems", Aegean Park Press, 1984. ๐ŸŒ€
  • [SHA] "Secure Hash Standard", US National Institute of Science and Technology, FIPS 180-2, 1 August 2002. ๐Ÿงพ
  • [SHA_RFC] Eastlake 3rd, D. and P. Jones, "US Secure Hash Algorithm 1 (SHA1)", RFC 3174, September 2001. ๐Ÿงพ
  • [SSH] Products of the SECSH Working Group, Works in Progress, 2005. ๐Ÿš
  • [STERN] Stern, J., "Secret Linear Congruential Generators are not Cryptographically Secure", Proc. IEEE STOC, 1987. ๐Ÿ•ต๏ธ
  • [TLS] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", RFC 2246, January 1999. ๐Ÿ”’
  • [TURBID] Denker, J., "High Entropy Symbol Generator", <http://www.av8n.com/turbid/paper/turbid.htm>, 2003. โญ
  • [USENET_1] Kantor, B. and P. Lapsley, "Network News Transfer Protocol", RFC 977, February 1986. ๐Ÿ“ฐ
  • [USENET_2] Barber, S., "Common NNTP Extensions", RFC 2980, October 2000. ๐Ÿ“ฐ
  • [VON_NEUMANN] Von Nuemann, J., "Various techniques used in connection with random digits", Von Neumann's Collected Works, Vol. 5, Pergamon Press, 1963. ๐ŸŽฐ
  • [WSC] Howard, M. and D. LeBlanc, "Writing Secure Code, Second Edition", Microsoft Press, ISBN 0735617228, December 2002. ๐Ÿ’ป
  • [X9.17] "American National Standard for Financial Institution Key Management (Wholesale)", American Bankers Association, 1985. ๐Ÿฆ
  • [X9.82] "Random Number Generation", American National Standards Institute, ANSI X9F1, Work in Progress.
    • Part 1 - Overview and General Principles.
    • Part 2 - Non-Deterministic Random Bit Generators
    • Part 3 - Deterministic Random Bit Generators

Authors' Addresses ๐ŸŒท

   Donald E. Eastlake 3rd
   Motorola Laboratories
   155 Beaver Street
   Milford, MA 01757 USA

   Phone: +1 508-786-7554 (w)
          +1 508-634-2066 (h)
   EMail: Donald.Eastlake@motorola.com


   Jeffrey I. Schiller
   MIT, Room E40-311
   77 Massachusetts Avenue
   Cambridge, MA 02139-4307 USA

   Phone: +1 617-253-0161
   EMail: jis@mit.edu


   Steve Crocker

   EMail: steve@stevecrocker.com

Copyright (C) The Internet Society (2005).

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ๐Ÿซง

Intellectual Property โœจ

okay bestie, the IETF is basically saying "we're not picking a side on who owns what" ๐Ÿ™ƒ They take no position on whether any Intellectual Property Rights or other rights that someone might claim over the tech in this document are valid, or how far those rights reach. They also don't say whether a license is available to use them. And they haven't gone digging for any of those rights on their own ๐Ÿ•ต๏ธโ€โ™€๏ธ For the rules on rights in RFC documents, check out BCP 78 and BCP 79 ๐ŸŽ€

Copies of IPR disclosures sent to the IETF Secretariat are in the IETF's online IPR repository at http://www.ietf.org/ipr ๐ŸŒธ You can also find any assurances of licenses that have been made available there. And if someone tried to get a general license or permission for implementers or users of this spec to use proprietary rights, the result of that attempt lives there too ๐Ÿ“‚

The IETF also invites anyone who's interested to flag any copyrights, patents, patent applications, or other proprietary rights that might cover technology needed to implement this standard. Send that info to ietf-ipr@ietf.org ๐Ÿ’Œ Basically, if you spot something, tell them! ๐Ÿซถ

Acknowledgement

Funding for the RFC Editor function is currently provided by the Internet Society. ๐Ÿ’œ Big thank-you energy to them for keeping the RFC Editor running ๐Ÿ‘‘

๐Ÿ“ฆ where this page comes from