Randomness serves a vital role in nearly every aspect of modern civilization. Voting systems, traffic management, and financial services all depend on randomness in some way. But by far, the most important and widely used aspect of randomness is within the field of cryptography.
WPA2 is the most widely used security protocol for connecting to Wifi networks. If a laptop wants to connect to a Wifi network, the Wifi access-point generates a large random number and sends it to the computer. At the same time, the laptop produces a large random number and sends it to the Wifi access point. Both devices use these numbers to perform a handshake and ensure that no one else can eavesdrop on their communications. If the random numbers were predictable, an attacker could trick either device into sending messages to themselves rather than the intended user. This scenario is just one use-case where good randomness is essential.
# Current randomness generators
There have been a collection of systems that have attempted to provide strong randomness, but they have all fallen short in one way or another.
The United States' National Institute of Standards and Technology (NIST)' has a project that aims to produce randomness by using quantum entanglement. While this is an excellent way to produce incredibly random numbers, there is no way for an end-user to verify that the numbers they are getting from NIST are random. Users have to trust that the system is providing genuinely random numbers.
Bitcoin is also able to produce random numbers. However, the cryptocurrency is fairly centralized, with power coming from a handful of mining pools.
Randhound is the most robust random number generator created so far. It claims to be scalable, bias-resistant, unpredictable, verifiable, and decentralized. However, tests have shown that it offers probabilistic guarantees, meaning that an attacker could have the system lean towards favorable numbers. Randhound is also hard to set up and takes a while to generate an output.
# Features of good randomness
There have been cases where attackers have rigged lotteries and elections by influencing the randomness of a system. To mitigate this exploitation, researchers have defined five points that a strong random-number-generator should be:
- Unpredictable: you can't predict the next number to come out of the generator.
- Publicly-verifiable: anyone can verify that a random number is a legitimately random number.
- Bias-resistant: you can't lead the generator one way or another.
- Decentralized: a set of independent parties produces random numbers.
- Always available: the system must always be able to provide random numbers.
The drand project aims to create a random number generator that has all five of these properties.
# How drand works
Here's a very simplified rundown of how drand works. For a deep-dive into the intricacies of drand, check out the project specifications.
The main challenge in generating good randomness is that no party involved in the randomness generation process should be able to predict or bias the final output. A drand network is not controlled by anyone of its members. There is no single point of failure, and none of the drand server operators can bias the randomness generated by the network.
A drand network is made up of a set number of nodes running the drand protocol. Before generating random numbers, they all agree on a threshold parameter. Each node creates a signature, and random numbers are created by each node broadcasting a part of their signature to the rest of the network. Each node waits and collects these signatures until it has enough signatures to match the threshold parameter, then this node can create the final signature. The final signature is a regular Boneh–Lynn–Shacham signature that can be verified against by the rest of the network. If that signature is correct, then the randomness is simply the hash of that signature.
This is an incredibly simplified outline of how drand works. Check out the project specifications for a more thorough look into how things work →
# Public randomness
Generating public randomness is the primary functionality of drand. Public randomness is generated collectively by drand nodes and made publicly available. The main challenge in generating good randomness is that no party involved in the randomness generation process should be able to predict or bias the final output. Additionally, the final result has to be verifiable by a third-party to make it actually useful for applications like lotteries, sharding, or parameter generation in security protocols.
A drand randomness beacon is composed of a distributed set of nodes and has two phases:
- Setup: Each node first generates a long-term public/private key pair. Then all of the public keys are written to a group file together with some further metadata required to operate the beacon. After this group file has been distributed, the nodes perform a distributed key generation (DKG) protocol to create the collective public key and one private key share per server. The participants NEVER see/use the actual (distributed) private key explicitly but instead utilize their respective private key shares for the generation of public randomness.
- Generation: After the setup, the nodes switch to the randomness generation mode. Any of the nodes can initiate a randomness generation round by broadcasting a message which all the other participants sign using a t-of-n threshold version of the Boneh-Lynn-Shacham (BLS) signature scheme and their respective private key shares. Once any node (or third-party observer) has gathered
tpartial signatures, it can reconstruct the full BLS signature (using Lagrange interpolation). The signature is then hashed using SHA-256 to ensure that there is no bias in the byte representation of the final output. This hash corresponds to the collective random value and can be verified against the collective public key.
# Private randomness
Private randomness generation is the secondary functionality of drand. Clients can request private randomness from some or all of the drand nodes which extract it locally from their entropy pools and send it back in encrypted form. This can be useful to gather randomness from different entropy sources, for example, in embedded devices.
In this mode, we assume that a client has a private/public key pair and encapsulates its public key towards the server's public key using the ECIES encryption scheme. After receiving a request, the drand node produces 32 random bytes locally (using Go's crypto/rand interface), encrypts them using the received public key, and sends it back to the client.
Note: Assuming that clients without good local entropy sources (such as embedded devices) use this process to gather high entropy randomness to bootstrap their local PRNGs, we emphasize that the initial client key pair has to be provided by a trusted source (such as the device manufacturer). Otherwise, we run into the chicken-and-egg problem of how to produce on the client's side a secure, ephemeral key pair for ECIES encryption without a good (local) source of randomness.