Are you trying to use true randomness in your application, but don't want to use /dev/random
or random.org because they are "too mainstream" or "not edgy enough" for your project? Fear not! With blockrandom.py
, you can get entropy straight from unconfirmed bitcoin transactions! Now you can develop applications in style, safe with the knowledge that you have the hippest source of true randomness in town.
To install, just git clone
this repository and run python setup.py install
. For the lazy:
git clone https://github.com/billpmurphy/blockchain-random.git blockchain-random
cd blockchain-random
python setup.py install
After you've run the install script, you can use blockrandom
just like Python's standard library random
module.
>>> import blockrandom
>>> blockrandom.randbytes(5)
bytearray(b'\xff\xdcb\x9c\xee')
>>> blockrandom.randbool()
True
>>> blockrandom.randint(0, 100)
43
>>> blockrandom.random()
0.13928496837615967
>>> blockrandom.uniform(1.5, 2.5)
1.61923086643219
>>> blockrandom.choice(["a", "b", "c"])
"b"
>>> my_list = [1, 2, 3]
>>> blockrandom.shuffle(my_list) # mutating, in-place shuffle
>>> my_list
[2, 1, 3]
>>> blockrandom.shuffled([1, 2, 3]) # non-mutating shuffle
[3, 1, 2]
>>> blockrandom.sample(range(10), 5)
[0, 7, 8, 5, 4]
If you want a non-blocking random generator that will recycle previously collected entropy, similar to /dev/urandom
, you can use the following:
>>> blockrandom.u_randbytes(5)
bytearray(b'\xe5\x84Y\x87a')
>>> blockrandom.u_randbool()
False
>>> blockrandom.u_randint(0, 100)
22
>>> blockrandom.u_random()
0.24625146389007568
>>> blockrandom.u_uniform(1.5, 2.5)
1.980821943283081
>>> blockrandom.u_choice(["a", "b", "c"])
"c"
>>> my_list = [1, 2, 3]
>>> blockrandom.u_shuffle(my_list) # mutating, in-place shuffle
>>> my_list
[3, 2, 1]
>>> blockrandom.u_shuffled([1, 2, 3]) # non-mutating shuffle
[2, 3, 1]
>>> blockrandom.u_sample(range(10), 5)
[8, 1, 5, 3, 4]
Unconfirmed transaction hashes are queried from blockchain.info. If we need to recycle previous entropy, we use a 32-bit MurmurHash3 function.
How well does this work? Well, here's 1MB of truly random bytes from unconfirmed transactions:
Here is the same 1MB, after it was run through MurmurHash3 1000 times:
And is 1MB generated with MurmurHash3, with a few KB of entropy from transactions used as a seed:
As you can see, both the MurmurHash3'd entropy and the psuedorandomly generated byes are still well-distributed, which suggests that we can indeed use MurmurHash3 to create a decent PRNG.
For more details, check out the randomness_testing.py
file.