Contents:
numpy
The Quantum Dice Entropy as a Service facility is intended for demonstrating the use of quantum randomness, particularly in two situations
You will need:
Please note that the demo server imposes limits on the rate at which it will supply random bits. This is typically around 1Mb/s.
The python demo is the simplest to run as it does not require anything to be built. Unpack the software into a convenient directory. In that directory you now have:
The qdremdemo program fetches and prints out various forms of randomness: raw bytes, integers, uniformly
distributed floating point numbers, and normally distributed floating point numbers.
python3 qdremdemo.py 20.100.202.187 33399 demosrv-cert.pem cli-cert.pem cli-key.pemand it should print something like this:
256 random bytes: b'"s|\xc0\x98\xcf\xae\x0e\x8b\xb2VZ\x9epb\x89\x94\xc4L\x88\xb
4\x87q\x9e\xd6:\xd6\xef\xa2\xafo\xf7\x9e\x847\x92*\x842\xf0\x7f\xfa_\x89\xe0\x1
4\xe2\xe8\xef\xbf\xde\x94\xd1\xfc\xee\xf1\x8c\xfe\x06\x00I4\x8e!\x06D\xb3=|p\x0
7\xda\xf4p\x7f\xcec\x05\x9276\xf9\x1c\'\xd2\xe8\x99\xaf\xb8\x1c\x89\xd9\x8e3\xa
3\xff^\x7f.~B@\xc2O\x80\x88\xaf\xb8%\x1c#k$\x1c\xb8t\xa9e\x11\x10;\x0fL\xdc\x9b
\xaa\x88\xa4*\xcbp\xd0X\x12\x8d\x8a\x1e\xc0\xba\xd5\x1e5\x1e\xb8\x8a\x06\xe2HW\
xd8\xcf\x01\xb2\xb1\x13\xa0?\xbd\xb9\xba\x10\x86\x14\x82\xe6\xc1->\\\xb9\xe3\xa
2\x0b\xe9!\xab\x98I\xf0\x01\xbc\x01"3f\xac\xa8-\xb5\xf6\xed]\xb2\xb1"\xfe\xfe\x
e8\xb5\xe3Q;9\xf8\t\x9b\xca$\x97\x9f\xf3\xec\xb6\x9f\xf56\x19\xb1u\xber\xe1\xec
\x1f\\\xdb(\x97\xc5%\xf2<b01\xf4&{I\xe1\xb8+]\xb5\x95o\xe1[2\x19 \x02\xb7\x80G\
x8c'
Random 32-bit integers:
7536378
1856549
6399506
8269273
5024114
791705
5318393
2693547
Random floating point numbers from uniform distribution [0.0, 1.0):
0.2247355259061654
0.2981547999074439
0.23002471487530218
0.15749698067082712
0.009459903074000367
0.8291698869058668
0.1367646699608786
0.22908912270217624
Random floating point numbers from normal distribution mean=42, standard deviation=5:
35.23340522476584
46.930543271537225
42.257069766022894
35.354253981998625
41.3176988941606
45.183924496995424
44.739646992171515
42.407759769057996
Certified random data:
c2 95 92 0e fa d4 5c from 120 bits, with 66.8671875 bits of entropy
e8 78 3e 7f bd db fb from 120 bits, with 66.84375 bits of entropy
a3 fd bf 61 9b 55 e7 from 120 bits, with 66.8515625 bits of entropy
04 52 51 5d b0 0e 7a from 120 bits, with 66.8515625 bits of entropy
69 e0 f3 11 59 a5 54 from 120 bits, with 66.859375 bits of entropy
02 27 5e 1f 63 1d be from 120 bits, with 66.875 bits of entropy
a9 58 da 63 01 b9 14 from 120 bits, with 66.8671875 bits of entropy
25 af 05 8b 6f 03 b7 from 120 bits, with 66.8515625 bits of entropy
Certified random data is provided in blocks which contain 64 bits of randomness each. Each block was generated from unconditioned data, the size of which is shown. The estimated entropy content of that unconditioned data is also shown. While the entropy is shown as being greater than 64, obviously the actual conditioned data cannot fit more than 64 bits of entropy into 64 bits of data. The entropy estimate is larger because the conditioning guarantees to provide at least (and therefore exactly) 64 bits of entropy in the 64 random bits. If there a fault arises in the entropy source, the reported number of bits will be less than 64 (in fact, almost certainly 0) which shows the randomness should be discarded. In contrast, fetching uncertified random bits during a fault condition will block until the fault is corrected - it will never return data which has an entropy estimate less than its size.
Unpack the software into a convenient directory. In that directory run:
makeyou should find that in the
BUILT subdirectory you now have:
The qdremdemo program fetches 100KB of random data. Try it out like this:
qdremdemo 20.100.202.187 33399 demosrv-cert.pem cli-cert.pem cli-key.pem >qd.rndand you should find that the file
qd.rnd now contains 1024000 bytes of random data.
The qdremdemo_ce demonstrates the certification and entropy values accompanying randomness. Run it like this:
qdremdemo_ce 20.100.202.187 33399 demosrv-cert.pem cli-cert.pem cli-key.pemand it will fetch blocks of randomness and print their contents. Each line looks like this:
144 72.953125 8d 49 1b b0 e7 c6 81 cfwhere the first number is the number of unconditioned bits that were used in producing this block, the second is the estimate of the amount of entropy in those bits, and the eight hex values are the 64 bits of randomness in this block. In unusual circumstances, if the randomness generator is unable to generate sufficient entropy in a reasonable time, the value for entropy is less than 64 and this block should not be used. When you get a stream of random data without metadata (as with the other demo programs) the stream does not contain any data from blocks like these, so may be delayed arbitrarily.
The qdremdemo_norm demonstrates generation of random values according to a specific probability distribution
using the standard C++ distributions. Try it like this:
qdremdemo_norm 20.100.202.187 33399 demosrv-cert.pem cli-cert.pem cli-key.pemand you should find it prints out 42 values from a Gaussian normal distribution which has mean of 42 and standard deviation of 5.
Unpack the software into a convenient directory. In that directory you now have:
The qdnumpydemo program uses the Quantum Dice randomness server as a randomness generator for numpy.
Note that it uses the python module randomgen which is you
most likely need to install but which is not currently included in the
standard Debian distribution (and hence derivatives such as Ubuntu),
so the usual command of apt install python3-randomgen will not find and install
it. You will need to install using pip install
randomgen. Typically this would be done into a virtual environment:
$ python3 -m venv qdrand-env $ source qdrand-env/bin/activate (qdrand-env) $ pip install randomgen (qdrand-env) $ python3 qdnumpydemo.py 20.100.202.187 33399 demosrv-cert.pem cli-cert.pem cli-key.pemTo run the demo use:
python3 qdnumpydemo.py 20.100.202.187 33399 demosrv-cert.pem cli-cert.pem cli-key.pemand it should print something like this:
Randint_64: 3028800426629873715 5 values from QDRandom via UserBitGenerator: [ 2566153804708623171 367241064909403286 14845878088422313213 10689817887016309455 642781941046069738] normal distribution: [41.49551784 40.14690052 35.98635924 38.85922673 35.93685133 41.79434128 42.73581742] uniform distribution: [31.17760795 22.83976742 6.13916706 25.79482315 9.61263327 23.01004319 29.38847962] binomial: [2 4 3 5 6 6 3]
Use qdremdemo_ce.c as a starting point. You need to include qdremrand.h and initialise the
connection to the EaaS server with:
QDREMRAND qdr;
qdremrand(&qdr);
if (qdremrand_connect(&qdr, rem_host, rem_port, peer_cert, my_cert, my_key)) {
fprintf(stderr, "Cannot connect to QD remote randomness\n");
return 1;
}
then if you want metadata with your randomness, fetch it like this:
struct qdrandom randbuf[16];
ssize_t got = qdremrand_getrand_ce(&qdr, randbuf, ARRAY_SIZE(randbuf));
if (got == -1) {
fprintf(stderr, "qdremrand_getrand_ce() failed\nCannot get random data\n");
return 1;
}
or for just a stream of randomness, fetch it like this:
unsigned char rands[16000];
ssize_t got = qdremrand_getrand(&qdr, rands, sizeof(rands));
if (got == -1) {
fprintf(stderr, "qdremrand_getrand() failed\nCannot get random data\n");
return 1;
}
You can use the demo programs to see how you can use the randomness in your own code. In qdremdemo.cpp it
initialises the connection to the EaaS server with:
Qdremrand qdr;
if (qdr.connect(rem_host, rem_port, peer_cert, my_cert, my_key)) {
std::cerr << "Cannot connect to QD remote randomness\n";
return 1;
}
and gets blocks of random bytes with:
unsigned char randbuf[64000];
ssize_t got = qdr.getrand(randbuf, sizeof(randbuf));
if (got == -1) {
fprintf(stderr, "getrand() failed\nCannot get random data\n");
...
while qdremdemo_norm.cpp sets up a distribution with:
Qdremrand qdr;
if (qdr.connect(rem_host, rem_port, peer_cert, my_cert, my_key)) {
std::cerr << "Cannot connect to QD remote randomness\n";
return 1;
}
Filerand<uint_fast32_t> qd_gen(&qdr);
std::normal_distribution norm(42.0, 5.0);
and then fetches and prints each value with:
std::cout << norm(qd_gen) << "\n";
You can get all the standard C++ randomness distributions this way.
The qdremrand.py file is the python module that you can import in your own code to access the server.
For python's standard builtin randomness functions, use it like this:
import qdremrand ... qrn = qdremrand.QDRemRand(host, int(port), srvcert, clicert, clikey)
and you can get all the standard randomness functionality from qrn.
numpy
For use with numpy, instead of using:
npg = numpy.random.default_rng()use
from randomgen import UserBitGenerator import numpy import qdremrand ... qdr = qdremrand.QDRemRand(host, int(port), srvcert, clicert, clikey) qd_ubg = UserBitGenerator(qdr.randint_64, 64, next_32=qdr.randint_32) npg = numpy.random.Generator(qd_ubg)and you can use
npg as usual. One big difference is that parallelism is much simpler. You can create
multiple connections to the Quantum Dice server and use them in parallel with no need to worry about using different
seeds or skipping ahead to avoid duplicate random numbers.
The simplest way to add randomness to the Linux /dev/random pool is to fetch randomness into a file, qd.rnd (as done in the
example of using qdremdemo above) and copy it in:
cat qd.rnd >/dev/randomhowever, this does not update the pool's estimate of its entropy. That can only be done with an
ioctl(), and
there is a handy utility provided in the demo package to do this. To use it, after you have built the C/C++ demo programs, run:
BUILT/linuxaddrand -s 1 <qd.rndThe
-s option is the safety factor which indicates how much entropy is in the data being written. For
example, if you think that your data is 30% random, you specify -s 0.3 but for Quantum Dice randomness, since
it is derived from truly random quantum processes and carefully conditioned, it should be pure randomness, so specify
-s 1 . If you omit this option, it defaults to 0 so the effect is the same as merely writing the
data to /dev/random. Note that this utility is supplied as a separate program for security. Updating the
pool entropy estimate is a privileged operation, so it will have to be
run as root, but fetching data from the EaaS server does not
require any special privilege, so should not be done by root.