🎲 A Distributed Randomness Beacon Daemon - Go implementation
Drand (pronounced "dee-rand") is a distributed randomness beacon daemon written in Golang.
Linked drand nodes collectively produce publicly verifiable, unbiased and unpredictable random values at fixed intervals using bilinear pairings and threshold cryptography.
Drand was first developed within the DEDIS organization, and as of December 2019, is now under the drand organization.
The need for digital randomness is paramount in multiple digital applications ([e]voting, lottery, cryptographic parameters, embedded devices bootstrapping randomness, blockchain systems etc) as well in non-digital such as statistical sampling (used for example to check results of an election), assigning court cases to random judges, random financial audits, etc. However, constructing a secure source of randomness is anything but easy: there are countless examples of attacks where the randomness generation was the culprit (static keys, non-uniform distribution, biased output, etc). drand aims to fix that gap by providing a Randomness-as-a-Service network (similar to NTP servers for time, or Certificate Authority servers for CAs verification), providing continuous source of randomness which is:
A drand network is operated by a group of organizations around the world that includes Cloudflare, EPFL, Kudelski Security, Protocol Labs, Celo, UCL, and UIUC. You can learn more by visiting the League of Entropy website, where you can also see the random values being generated by the network in real time.
Generating public randomness is the primary functionality of drand. Public randomness is generated collectively by drand nodes and 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 third-party verifiable 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:
Please go use the latest drand binary in the release page.
Drand can be installed via Golang or
Docker. By default, drand saves the configuration
files such as the long-term key pair, the group file, and the collective public
key in the directory $HOME/.drand/
.
The docker image can also be built manually by running docker build --build-arg version=$(git describe --tags) --build-arg gitCommit=$(git rev-parse HEAD) -t drandorg/go-drand:latest .
in the project root folder
Additional instructions for running a node or network using docker can be found in the docker directory
Make sure that you have a working Golang installation and that your GOPATH is set.
Then install drand via:
git clone https://github.com/drand/drand
cd drand
make install
The setup is explained in docker/README.md.
To run a local demo, you can simply run:
make demo
The script spins up a few drand local processes, performs resharing and other operations and will continue to print out new randomness every Xs (currently 6s). For more information, look at the demo README.
A drand beacon provides several public services to clients. A drand node
exposes its public services on a gRPC endpoint as well as a REST JSON endpoint,
on the same port. The latter is especially useful if one wishes to retrieve
randomness from a JavaScript application. Communication is protected through
TLS by default. If the contacted node is using a self-signed certificate, the
client can use the --tls-cert
flag to specify the server's certificate.
Consult full instructions at DEPLOYMENT
To get the latest public random value, run
drand get public --round <i> <group.toml>
where <group.toml>
is the group identity file of a drand node. You can
specify the round number when the public randomness has been generated. If not
specified, this command returns the most recent random beacon.
The JSON-formatted output produced by drand is of the following form:
{
"round": 367,
"signature": "b62dd642e939191af1f9e15bef0f0b0e9562a5f570a12a231864afe468377e2a6424a92ccfc34ef1471cbd58c37c6b020cf75ce9446d2aa1252a090250b2b1441f8a2a0d22208dcc09332eaa0143c4a508be13de63978dbed273e3b9813130d5",
"previous_signature": "afc545efb57f591dbdf833c339b3369f569566a93e49578db46b6586299422483b7a2d595814046e2847494b401650a0050981e716e531b6f4b620909c2bf1476fd82cf788a110becbc77e55746a7cccd47fb171e8ae2eea2a22fcc6a512486d",
"randomness": "d7aed3686bf2be657e6d38c20999831308ee6244b68c8825676db580e7e3bec6"
}
Here Signature
is the threshold BLS signature on the previous signature value
Previous
and the current round number. Randomness
is the hash of
Signature
, to be used as the random value for this round. The field Round
specifies the index of Randomness
in the sequence of all random values
produced by this drand instance. The message signed is therefore the
concatenation of the round number treated as a uint64
and the previous
signature. At the moment, we are only using BLS signatures on the bls12-381 curves
and the signature is made over G1.
(Note that this command expects access to a drand group member, this won't work with the current League of Entropy nodes, since they are not exposing their GRPC endpoints directly.)
This is the recommended way of using drand randomness, but don't forget to validate the beacons' signatures against the group public key.
One may want to get the distributed key or public randomness by issuing a GET to a HTTP endpoint instead of using a gRPC client. Here is a basic example on how to do so with curl.
To get the distributed key, you can use:
curl <address>/group
Similarly, to get the latest round of randomness from the drand beacon, you can use
curl <address>/public/latest
To facilitate the use of drand's randomness in JavaScript-based applications,
we provide drand-client
.
For more details on the procedure and instructions on how to use it, refer to the readme.
Here is a list of all documentation related to drand:
As well, here is a list of background readings w.r.t to the cryptography used in drand:
Note that drand was originally a DEDIS-owned project that is now spinning off on its own Github organization. For related previous work on public randomness, see DEDIS's academic paper Scalable Bias-Resistant Distributed Randomness.
Although being already functional, drand is still at an early development stage and there is a lot left to be done. The list of opened issues is a good place to start. On top of this, drand would benefit from higher-level enhancements such as the following:
Feel free to submit feature requests or, even better, pull requests ;)
If you want to contribute to Drand, head over to our Development documentation.
Thanks to @herumi for providing support on his optimized pairing-based cryptographic library used in the first version.
Thanks to Apostol Vassilev for its interest in drand and the extensive and helpful discussions on the drand design.
Thanks to @Bren2010 and @grittygrease for providing the native Golang bn256 implementation and for their help in the design of drand and future ideas.
Finally, a special note for Bryan Ford from the DEDIS lab for letting me work on this project and helping me grow it.
The drand project is dual-licensed under Apache 2.0 and MIT terms: