Fill /dev/random via Bitcoin exchange value Announcing the arrival of Valued Associate #679:...

How do I find out the mythology and history of my Fortress?

Do jazz musicians improvise on the parent scale in addition to the chord-scales?

Do square wave exist?

Is it fair for a professor to grade us on the possession of past papers?

How do I make this wiring inside cabinet safer? (Pic)

If a VARCHAR(MAX) column is included in an index, is the entire value always stored in the index page(s)?

2001: A Space Odyssey's use of the song "Daisy Bell" (Bicycle Built for Two); life imitates art or vice-versa?

Using et al. for a last / senior author rather than for a first author

When the Haste spell ends on a creature, do attackers have advantage against that creature?

また usage in a dictionary

Wu formula for manifolds with boundary

Is there such thing as an Availability Group failover trigger?

Why do we bend a book to keep it straight?

Extracting terms with certain heads in a function

Is it common practice to audition new musicians one-on-one before rehearsing with the entire band?

Dating a Former Employee

Is it ethical to give a final exam after the professor has quit before teaching the remaining chapters of the course?

Why are the trig functions versine, haversine, exsecant, etc, rarely used in modern mathematics?

If my PI received research grants from a company to be able to pay my postdoc salary, did I have a potential conflict interest too?

Why aren't air breathing engines used as small first stages

How could we fake a moon landing now?

Generate an RGB colour grid

Amount of permutations on an NxNxN Rubik's Cube

Irreducible of finite Krull dimension implies quasi-compact?



Fill /dev/random via Bitcoin exchange value



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)Random value excluding both limitsRandom value generation for uncertainty analysisFilling random values in two sheets from a single sheet via Excel VBAScript for checking to leak via /dev/handsConvert bitcoin value based on exchange rate from JSON API





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







0












$begingroup$


I have written the following random numbers generator. I would like to know how safe this is and if it is suitable for use in computer engineering. For me, the result looks very random, but would like to have several opinions on it.



enter image description here



#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import fcntl
import struct
import logging
import json
import urllib
import time
from decimal import Decimal
import datetime
import hashlib

LOG_FILENAME = 'entro.py.log'
formatter = logging.Formatter('[%(asctime)s] %(levelno)s (%(process)d) %(module)s: %(message)s')
fh = logging.FileHandler(LOG_FILENAME)
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
logger = logging.getLogger('MyLogger')
logger.setLevel(logging.DEBUG)
logger.addHandler(fh)
debug = logger.debug
info = logger.info
warning = logger.warning
error = logger.error
critical = logger.critical


def add_entropy(rnd):
""" Add data to the entropy pool """
""" From https://github.com/netom/onetimepad/blob/master/rndaddentropy.py """
info('Add to entropy')
fd = os.open("/dev/random", os.O_WRONLY)
# struct rand_pool_info {
# int entropy_count;
# int buf_size;
# __u32 buf[0];
# };
fmt = 'ii%is' % len(rnd)
# Here we set 6*len(rnd) entropy bits (instead of 8 because tweet data does not have perfect randomness)
rand_pool_info = struct.pack(fmt, 6 * len(rnd), len(rnd), rnd)
fcntl.ioctl(fd, 1074287107, rand_pool_info)
os.close(fd)
info('added to entropy')

def get_JSON_ticker(url="https://blockchain.info/ticker"):
info("Load data from %s" % url)
response = urllib.urlopen(url)
Data = json.loads(response.read())
return Data

def main():
info('The tool to add Entropy to the system is started.')
start = datetime.datetime.now()
BTC_Exc_Data = get_JSON_ticker()
summe = 0
for currency in BTC_Exc_Data:
summe += float(BTC_Exc_Data[currency]["last"])
summe = Decimal(summe) * Decimal(time.time())
end = datetime.datetime.now()
diff = end - start
d = Decimal(summe)*Decimal(diff.microseconds)
Text = str(d)
Text = Text.replace("00", "").replace(".", "")
Text2 = hashlib.sha512(Text).hexdigest() + hashlib.sha256(Text).hexdigest() + hashlib.sha1(Text).hexdigest() + hashlib.sha224(Text).hexdigest() + hashlib.sha384(Text).hexdigest()
Text = str(diff.microseconds**diff.microseconds)
Text = hashlib.sha512(Text).hexdigest() + hashlib.sha256(Text).hexdigest() + hashlib.sha1(Text).hexdigest() + hashlib.sha224(Text).hexdigest() + hashlib.sha384(Text).hexdigest()
Text += Text2
debug("entropy string has a size of %s" % str(len(Text)))
add_entropy(Text)

info('The tool to add Entropy to the system has finished.')



if __name__ == '__main__':
main()









share|improve this question











$endgroup$



migrated from superuser.com 10 hours ago


This question came from our site for computer enthusiasts and power users.














  • 2




    $begingroup$
    There is a problem with your testing method: /dev/random never uses your input directly; it is mixed into the pool along with other entropy sources and eventually always goes through a PRNG to produce the actual output. So the output will appear random (and will likely be quite random) no matter what data you feed into it.
    $endgroup$
    – grawity
    14 hours ago










  • $begingroup$
    I have used the input of add_entropy(Text) as the source for the grafic. For my test I wrote the data into a file and converted it into the graphic. The code is the finished "product".
    $endgroup$
    – FrankStein
    14 hours ago






  • 2




    $begingroup$
    Then there is another problem with your testing method: cryptographic hash functions like SHA were designed to have output that appears as random as possible (uniformity), even in cases of the input not having much entropy at all.
    $endgroup$
    – grawity
    14 hours ago










  • $begingroup$
    But it could still be random? And at least it would make traceability and predictability more difficult?
    $endgroup$
    – FrankStein
    14 hours ago










  • $begingroup$
    "I would like to know how safe this is and if it is suitable for use in computer engineering." What's your threat model?
    $endgroup$
    – Mast
    8 hours ago


















0












$begingroup$


I have written the following random numbers generator. I would like to know how safe this is and if it is suitable for use in computer engineering. For me, the result looks very random, but would like to have several opinions on it.



enter image description here



#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import fcntl
import struct
import logging
import json
import urllib
import time
from decimal import Decimal
import datetime
import hashlib

LOG_FILENAME = 'entro.py.log'
formatter = logging.Formatter('[%(asctime)s] %(levelno)s (%(process)d) %(module)s: %(message)s')
fh = logging.FileHandler(LOG_FILENAME)
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
logger = logging.getLogger('MyLogger')
logger.setLevel(logging.DEBUG)
logger.addHandler(fh)
debug = logger.debug
info = logger.info
warning = logger.warning
error = logger.error
critical = logger.critical


def add_entropy(rnd):
""" Add data to the entropy pool """
""" From https://github.com/netom/onetimepad/blob/master/rndaddentropy.py """
info('Add to entropy')
fd = os.open("/dev/random", os.O_WRONLY)
# struct rand_pool_info {
# int entropy_count;
# int buf_size;
# __u32 buf[0];
# };
fmt = 'ii%is' % len(rnd)
# Here we set 6*len(rnd) entropy bits (instead of 8 because tweet data does not have perfect randomness)
rand_pool_info = struct.pack(fmt, 6 * len(rnd), len(rnd), rnd)
fcntl.ioctl(fd, 1074287107, rand_pool_info)
os.close(fd)
info('added to entropy')

def get_JSON_ticker(url="https://blockchain.info/ticker"):
info("Load data from %s" % url)
response = urllib.urlopen(url)
Data = json.loads(response.read())
return Data

def main():
info('The tool to add Entropy to the system is started.')
start = datetime.datetime.now()
BTC_Exc_Data = get_JSON_ticker()
summe = 0
for currency in BTC_Exc_Data:
summe += float(BTC_Exc_Data[currency]["last"])
summe = Decimal(summe) * Decimal(time.time())
end = datetime.datetime.now()
diff = end - start
d = Decimal(summe)*Decimal(diff.microseconds)
Text = str(d)
Text = Text.replace("00", "").replace(".", "")
Text2 = hashlib.sha512(Text).hexdigest() + hashlib.sha256(Text).hexdigest() + hashlib.sha1(Text).hexdigest() + hashlib.sha224(Text).hexdigest() + hashlib.sha384(Text).hexdigest()
Text = str(diff.microseconds**diff.microseconds)
Text = hashlib.sha512(Text).hexdigest() + hashlib.sha256(Text).hexdigest() + hashlib.sha1(Text).hexdigest() + hashlib.sha224(Text).hexdigest() + hashlib.sha384(Text).hexdigest()
Text += Text2
debug("entropy string has a size of %s" % str(len(Text)))
add_entropy(Text)

info('The tool to add Entropy to the system has finished.')



if __name__ == '__main__':
main()









share|improve this question











$endgroup$



migrated from superuser.com 10 hours ago


This question came from our site for computer enthusiasts and power users.














  • 2




    $begingroup$
    There is a problem with your testing method: /dev/random never uses your input directly; it is mixed into the pool along with other entropy sources and eventually always goes through a PRNG to produce the actual output. So the output will appear random (and will likely be quite random) no matter what data you feed into it.
    $endgroup$
    – grawity
    14 hours ago










  • $begingroup$
    I have used the input of add_entropy(Text) as the source for the grafic. For my test I wrote the data into a file and converted it into the graphic. The code is the finished "product".
    $endgroup$
    – FrankStein
    14 hours ago






  • 2




    $begingroup$
    Then there is another problem with your testing method: cryptographic hash functions like SHA were designed to have output that appears as random as possible (uniformity), even in cases of the input not having much entropy at all.
    $endgroup$
    – grawity
    14 hours ago










  • $begingroup$
    But it could still be random? And at least it would make traceability and predictability more difficult?
    $endgroup$
    – FrankStein
    14 hours ago










  • $begingroup$
    "I would like to know how safe this is and if it is suitable for use in computer engineering." What's your threat model?
    $endgroup$
    – Mast
    8 hours ago














0












0








0





$begingroup$


I have written the following random numbers generator. I would like to know how safe this is and if it is suitable for use in computer engineering. For me, the result looks very random, but would like to have several opinions on it.



enter image description here



#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import fcntl
import struct
import logging
import json
import urllib
import time
from decimal import Decimal
import datetime
import hashlib

LOG_FILENAME = 'entro.py.log'
formatter = logging.Formatter('[%(asctime)s] %(levelno)s (%(process)d) %(module)s: %(message)s')
fh = logging.FileHandler(LOG_FILENAME)
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
logger = logging.getLogger('MyLogger')
logger.setLevel(logging.DEBUG)
logger.addHandler(fh)
debug = logger.debug
info = logger.info
warning = logger.warning
error = logger.error
critical = logger.critical


def add_entropy(rnd):
""" Add data to the entropy pool """
""" From https://github.com/netom/onetimepad/blob/master/rndaddentropy.py """
info('Add to entropy')
fd = os.open("/dev/random", os.O_WRONLY)
# struct rand_pool_info {
# int entropy_count;
# int buf_size;
# __u32 buf[0];
# };
fmt = 'ii%is' % len(rnd)
# Here we set 6*len(rnd) entropy bits (instead of 8 because tweet data does not have perfect randomness)
rand_pool_info = struct.pack(fmt, 6 * len(rnd), len(rnd), rnd)
fcntl.ioctl(fd, 1074287107, rand_pool_info)
os.close(fd)
info('added to entropy')

def get_JSON_ticker(url="https://blockchain.info/ticker"):
info("Load data from %s" % url)
response = urllib.urlopen(url)
Data = json.loads(response.read())
return Data

def main():
info('The tool to add Entropy to the system is started.')
start = datetime.datetime.now()
BTC_Exc_Data = get_JSON_ticker()
summe = 0
for currency in BTC_Exc_Data:
summe += float(BTC_Exc_Data[currency]["last"])
summe = Decimal(summe) * Decimal(time.time())
end = datetime.datetime.now()
diff = end - start
d = Decimal(summe)*Decimal(diff.microseconds)
Text = str(d)
Text = Text.replace("00", "").replace(".", "")
Text2 = hashlib.sha512(Text).hexdigest() + hashlib.sha256(Text).hexdigest() + hashlib.sha1(Text).hexdigest() + hashlib.sha224(Text).hexdigest() + hashlib.sha384(Text).hexdigest()
Text = str(diff.microseconds**diff.microseconds)
Text = hashlib.sha512(Text).hexdigest() + hashlib.sha256(Text).hexdigest() + hashlib.sha1(Text).hexdigest() + hashlib.sha224(Text).hexdigest() + hashlib.sha384(Text).hexdigest()
Text += Text2
debug("entropy string has a size of %s" % str(len(Text)))
add_entropy(Text)

info('The tool to add Entropy to the system has finished.')



if __name__ == '__main__':
main()









share|improve this question











$endgroup$




I have written the following random numbers generator. I would like to know how safe this is and if it is suitable for use in computer engineering. For me, the result looks very random, but would like to have several opinions on it.



enter image description here



#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import fcntl
import struct
import logging
import json
import urllib
import time
from decimal import Decimal
import datetime
import hashlib

LOG_FILENAME = 'entro.py.log'
formatter = logging.Formatter('[%(asctime)s] %(levelno)s (%(process)d) %(module)s: %(message)s')
fh = logging.FileHandler(LOG_FILENAME)
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
logger = logging.getLogger('MyLogger')
logger.setLevel(logging.DEBUG)
logger.addHandler(fh)
debug = logger.debug
info = logger.info
warning = logger.warning
error = logger.error
critical = logger.critical


def add_entropy(rnd):
""" Add data to the entropy pool """
""" From https://github.com/netom/onetimepad/blob/master/rndaddentropy.py """
info('Add to entropy')
fd = os.open("/dev/random", os.O_WRONLY)
# struct rand_pool_info {
# int entropy_count;
# int buf_size;
# __u32 buf[0];
# };
fmt = 'ii%is' % len(rnd)
# Here we set 6*len(rnd) entropy bits (instead of 8 because tweet data does not have perfect randomness)
rand_pool_info = struct.pack(fmt, 6 * len(rnd), len(rnd), rnd)
fcntl.ioctl(fd, 1074287107, rand_pool_info)
os.close(fd)
info('added to entropy')

def get_JSON_ticker(url="https://blockchain.info/ticker"):
info("Load data from %s" % url)
response = urllib.urlopen(url)
Data = json.loads(response.read())
return Data

def main():
info('The tool to add Entropy to the system is started.')
start = datetime.datetime.now()
BTC_Exc_Data = get_JSON_ticker()
summe = 0
for currency in BTC_Exc_Data:
summe += float(BTC_Exc_Data[currency]["last"])
summe = Decimal(summe) * Decimal(time.time())
end = datetime.datetime.now()
diff = end - start
d = Decimal(summe)*Decimal(diff.microseconds)
Text = str(d)
Text = Text.replace("00", "").replace(".", "")
Text2 = hashlib.sha512(Text).hexdigest() + hashlib.sha256(Text).hexdigest() + hashlib.sha1(Text).hexdigest() + hashlib.sha224(Text).hexdigest() + hashlib.sha384(Text).hexdigest()
Text = str(diff.microseconds**diff.microseconds)
Text = hashlib.sha512(Text).hexdigest() + hashlib.sha256(Text).hexdigest() + hashlib.sha1(Text).hexdigest() + hashlib.sha224(Text).hexdigest() + hashlib.sha384(Text).hexdigest()
Text += Text2
debug("entropy string has a size of %s" % str(len(Text)))
add_entropy(Text)

info('The tool to add Entropy to the system has finished.')



if __name__ == '__main__':
main()






python json random linux cryptocurrency






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 8 hours ago









200_success

131k17157422




131k17157422










asked 14 hours ago







FrankStein











migrated from superuser.com 10 hours ago


This question came from our site for computer enthusiasts and power users.









migrated from superuser.com 10 hours ago


This question came from our site for computer enthusiasts and power users.










  • 2




    $begingroup$
    There is a problem with your testing method: /dev/random never uses your input directly; it is mixed into the pool along with other entropy sources and eventually always goes through a PRNG to produce the actual output. So the output will appear random (and will likely be quite random) no matter what data you feed into it.
    $endgroup$
    – grawity
    14 hours ago










  • $begingroup$
    I have used the input of add_entropy(Text) as the source for the grafic. For my test I wrote the data into a file and converted it into the graphic. The code is the finished "product".
    $endgroup$
    – FrankStein
    14 hours ago






  • 2




    $begingroup$
    Then there is another problem with your testing method: cryptographic hash functions like SHA were designed to have output that appears as random as possible (uniformity), even in cases of the input not having much entropy at all.
    $endgroup$
    – grawity
    14 hours ago










  • $begingroup$
    But it could still be random? And at least it would make traceability and predictability more difficult?
    $endgroup$
    – FrankStein
    14 hours ago










  • $begingroup$
    "I would like to know how safe this is and if it is suitable for use in computer engineering." What's your threat model?
    $endgroup$
    – Mast
    8 hours ago














  • 2




    $begingroup$
    There is a problem with your testing method: /dev/random never uses your input directly; it is mixed into the pool along with other entropy sources and eventually always goes through a PRNG to produce the actual output. So the output will appear random (and will likely be quite random) no matter what data you feed into it.
    $endgroup$
    – grawity
    14 hours ago










  • $begingroup$
    I have used the input of add_entropy(Text) as the source for the grafic. For my test I wrote the data into a file and converted it into the graphic. The code is the finished "product".
    $endgroup$
    – FrankStein
    14 hours ago






  • 2




    $begingroup$
    Then there is another problem with your testing method: cryptographic hash functions like SHA were designed to have output that appears as random as possible (uniformity), even in cases of the input not having much entropy at all.
    $endgroup$
    – grawity
    14 hours ago










  • $begingroup$
    But it could still be random? And at least it would make traceability and predictability more difficult?
    $endgroup$
    – FrankStein
    14 hours ago










  • $begingroup$
    "I would like to know how safe this is and if it is suitable for use in computer engineering." What's your threat model?
    $endgroup$
    – Mast
    8 hours ago








2




2




$begingroup$
There is a problem with your testing method: /dev/random never uses your input directly; it is mixed into the pool along with other entropy sources and eventually always goes through a PRNG to produce the actual output. So the output will appear random (and will likely be quite random) no matter what data you feed into it.
$endgroup$
– grawity
14 hours ago




$begingroup$
There is a problem with your testing method: /dev/random never uses your input directly; it is mixed into the pool along with other entropy sources and eventually always goes through a PRNG to produce the actual output. So the output will appear random (and will likely be quite random) no matter what data you feed into it.
$endgroup$
– grawity
14 hours ago












$begingroup$
I have used the input of add_entropy(Text) as the source for the grafic. For my test I wrote the data into a file and converted it into the graphic. The code is the finished "product".
$endgroup$
– FrankStein
14 hours ago




$begingroup$
I have used the input of add_entropy(Text) as the source for the grafic. For my test I wrote the data into a file and converted it into the graphic. The code is the finished "product".
$endgroup$
– FrankStein
14 hours ago




2




2




$begingroup$
Then there is another problem with your testing method: cryptographic hash functions like SHA were designed to have output that appears as random as possible (uniformity), even in cases of the input not having much entropy at all.
$endgroup$
– grawity
14 hours ago




$begingroup$
Then there is another problem with your testing method: cryptographic hash functions like SHA were designed to have output that appears as random as possible (uniformity), even in cases of the input not having much entropy at all.
$endgroup$
– grawity
14 hours ago












$begingroup$
But it could still be random? And at least it would make traceability and predictability more difficult?
$endgroup$
– FrankStein
14 hours ago




$begingroup$
But it could still be random? And at least it would make traceability and predictability more difficult?
$endgroup$
– FrankStein
14 hours ago












$begingroup$
"I would like to know how safe this is and if it is suitable for use in computer engineering." What's your threat model?
$endgroup$
– Mast
8 hours ago




$begingroup$
"I would like to know how safe this is and if it is suitable for use in computer engineering." What's your threat model?
$endgroup$
– Mast
8 hours ago










1 Answer
1






active

oldest

votes


















3












$begingroup$

There are a few things going on in your approach that need to be discussed, so let's look at each of those individually, and then see if we can come to a conclusion about your design.



Seeding /dev/random



There is certainly nothing wrong with reseeding /dev/random just as long as you understand the Linux CSPRNG architecture. When sending data to the kernel's CSPRNG, the data is mixed in the input pool with other data collected by the system. In fact, the kernel is mixing hardware events and interrupts into the input pool consistently, and this really only becomes a problem for embedded, low power, solid state devices where hardware interrupts are rare.



After data is added to the input pool, it is then mixed with all the other data in the input pool with a randomness extractor. The goal of this mixing is to take correlated, biased, and predictable data, and extract the raw entropy. Once extracted, that data is then encrypted with ChaCha20, if using Linux 4.8+, or SHA-1 otherwise (MD5 if you're using a really early 1.x or 2.x kernel).



Sending data from publicly accessible data, like Bitcoin transactions, into the CSPRNG to reseed it is fine, but don't get any false sense of security. You won't degrade the security margins of the generator, but you may not increase the security margins of the generator either. Ultimately, the goal of reseeding a CSPRNG is to prevent backtracking attacks, which you can't do with public data. So let's talk about that next.



Backtracking resistance



You're using SHA-512 as a randomness extractor, and that's perfectly fine, but as it stands in your implementation, it's not enough. SHA-512 is designed to take biased, correlated bits, and turn it into a fixed-length output of statistically unbiased, uncorrelated bits.



This is simple enough to demonstrate in the terminal:



$ dd if=/dev/zero bs=1 count=1000 2> /dev/random | sha512sum
ca3dff61bb23477aa6087b27508264a6f9126ee3a004f53cb8db942ed345f2f2d229b4b59c859220a1cf1913f34248e3803bab650e849a3d9a709edc09ae4a76 -


Here we fed 1,000 bytes of binary zeros into SHA-512, and got an output that is a hexadecimal representation of those unbiased bits. So, if SHA-512 is reseeded with unique, and secret seeds, then its output in indistinguishable from true random white noise, and it's data is also unpredictable.



But not predicting future data isn't enough for a CSPRNG. We also need to design it such that we cannot reproduce past states, thus predicting previously calculated keys or secrets. This is called forward secrecy or backtracking resistance.



To illustrate this is very simple terms, consider a simple counter i=0, 1, 2, 3, ..., n. We could hash this with SHA-512, and it would produce unique statistically uniform independent bits. But suppose an adversary is able to compromise the state of the generator, and after watching the state, knows you're just incrementing a counter. All the adversary needs to do at this point is decrement the counter, and they can calculate all prior RNG states. This generator is not backtracking resistant.



Using time has a similar problem. What prevents the adversary from calculating past times in microseconds, and generating past states? Sure, there will be some variability in accuracy, but if the adversary can monitor the state of the generator, then the adversary knows how long it takes each state to execute. This gives a window with a small epsilon of past states to calculate.



Because your RNG is reliant on time, it's not backtracking resistant, and as such, not cryptographically secure.



Public vs secret seeds



Finally, there is a time and place where seeding a generator with public data is perfectly acceptable, primarily for audits and transparent verification. That is what randomness beacons, such as the ones by NIST and CLCERT are doing. But the goal of these beacons/generators is to provide accountability for social decisions, such as elections, sampling, drug testing, and other things, where people picked as a result of the generator, can force an audit on the decision, and it can be strongly proven they were picked uniformly, and without bias.



Generally though, for RNGs, we want secret seeds, because we want the output of the generator to be unpredictable. If the seed is public, then all future output can be calculated in advance. If the seed is secret, then predicting future output should be as difficult as either breaking the algorithm, or forcing discovery of the seed.



This is why you don't want to use random.org, Bitcoin, tweets, atmospheric noise, RF spectrum, or any other publicly accessible sources for seeds to RNGs. Because if an adversary can either influence the source (RF jamming) or read the source (Bitcoin), then they can use that knowledge to predict the outcome of your RNG.



Also, financial exchanges do not exhibit random walks. So as an entropy input, they're not very good. This includes Bitcoin markets and transactions.



A suggestion for improvement



First and foremost, you should only ever use /dev/urandom when you need secure and safe random numbers. Userspace RNGs are loaded with footguns, a couple of which I outlined here. They're also almost completely unnecessary. It really is the only place as a developer you should be turning, when you need cryptographically secure randomness.



However, if you're hell-bent on shipping a userspace RNG, then as a suggestion to improve the quality of your generator, I would suggest you turn to fast key erasure as explained by Dr. Daniel J. Bernstein. Drop SHA-512 in favor of keyed AES-128 and forget about Bitcoin and timestamps, but instead use 128-bits of secret theoretic entropy (flip a coin 128 times, roll a d6 50 times, Argon2id a password, etc) as your seed.






share|improve this answer









$endgroup$














    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "196"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217625%2ffill-dev-random-via-bitcoin-exchange-value%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown
























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3












    $begingroup$

    There are a few things going on in your approach that need to be discussed, so let's look at each of those individually, and then see if we can come to a conclusion about your design.



    Seeding /dev/random



    There is certainly nothing wrong with reseeding /dev/random just as long as you understand the Linux CSPRNG architecture. When sending data to the kernel's CSPRNG, the data is mixed in the input pool with other data collected by the system. In fact, the kernel is mixing hardware events and interrupts into the input pool consistently, and this really only becomes a problem for embedded, low power, solid state devices where hardware interrupts are rare.



    After data is added to the input pool, it is then mixed with all the other data in the input pool with a randomness extractor. The goal of this mixing is to take correlated, biased, and predictable data, and extract the raw entropy. Once extracted, that data is then encrypted with ChaCha20, if using Linux 4.8+, or SHA-1 otherwise (MD5 if you're using a really early 1.x or 2.x kernel).



    Sending data from publicly accessible data, like Bitcoin transactions, into the CSPRNG to reseed it is fine, but don't get any false sense of security. You won't degrade the security margins of the generator, but you may not increase the security margins of the generator either. Ultimately, the goal of reseeding a CSPRNG is to prevent backtracking attacks, which you can't do with public data. So let's talk about that next.



    Backtracking resistance



    You're using SHA-512 as a randomness extractor, and that's perfectly fine, but as it stands in your implementation, it's not enough. SHA-512 is designed to take biased, correlated bits, and turn it into a fixed-length output of statistically unbiased, uncorrelated bits.



    This is simple enough to demonstrate in the terminal:



    $ dd if=/dev/zero bs=1 count=1000 2> /dev/random | sha512sum
    ca3dff61bb23477aa6087b27508264a6f9126ee3a004f53cb8db942ed345f2f2d229b4b59c859220a1cf1913f34248e3803bab650e849a3d9a709edc09ae4a76 -


    Here we fed 1,000 bytes of binary zeros into SHA-512, and got an output that is a hexadecimal representation of those unbiased bits. So, if SHA-512 is reseeded with unique, and secret seeds, then its output in indistinguishable from true random white noise, and it's data is also unpredictable.



    But not predicting future data isn't enough for a CSPRNG. We also need to design it such that we cannot reproduce past states, thus predicting previously calculated keys or secrets. This is called forward secrecy or backtracking resistance.



    To illustrate this is very simple terms, consider a simple counter i=0, 1, 2, 3, ..., n. We could hash this with SHA-512, and it would produce unique statistically uniform independent bits. But suppose an adversary is able to compromise the state of the generator, and after watching the state, knows you're just incrementing a counter. All the adversary needs to do at this point is decrement the counter, and they can calculate all prior RNG states. This generator is not backtracking resistant.



    Using time has a similar problem. What prevents the adversary from calculating past times in microseconds, and generating past states? Sure, there will be some variability in accuracy, but if the adversary can monitor the state of the generator, then the adversary knows how long it takes each state to execute. This gives a window with a small epsilon of past states to calculate.



    Because your RNG is reliant on time, it's not backtracking resistant, and as such, not cryptographically secure.



    Public vs secret seeds



    Finally, there is a time and place where seeding a generator with public data is perfectly acceptable, primarily for audits and transparent verification. That is what randomness beacons, such as the ones by NIST and CLCERT are doing. But the goal of these beacons/generators is to provide accountability for social decisions, such as elections, sampling, drug testing, and other things, where people picked as a result of the generator, can force an audit on the decision, and it can be strongly proven they were picked uniformly, and without bias.



    Generally though, for RNGs, we want secret seeds, because we want the output of the generator to be unpredictable. If the seed is public, then all future output can be calculated in advance. If the seed is secret, then predicting future output should be as difficult as either breaking the algorithm, or forcing discovery of the seed.



    This is why you don't want to use random.org, Bitcoin, tweets, atmospheric noise, RF spectrum, or any other publicly accessible sources for seeds to RNGs. Because if an adversary can either influence the source (RF jamming) or read the source (Bitcoin), then they can use that knowledge to predict the outcome of your RNG.



    Also, financial exchanges do not exhibit random walks. So as an entropy input, they're not very good. This includes Bitcoin markets and transactions.



    A suggestion for improvement



    First and foremost, you should only ever use /dev/urandom when you need secure and safe random numbers. Userspace RNGs are loaded with footguns, a couple of which I outlined here. They're also almost completely unnecessary. It really is the only place as a developer you should be turning, when you need cryptographically secure randomness.



    However, if you're hell-bent on shipping a userspace RNG, then as a suggestion to improve the quality of your generator, I would suggest you turn to fast key erasure as explained by Dr. Daniel J. Bernstein. Drop SHA-512 in favor of keyed AES-128 and forget about Bitcoin and timestamps, but instead use 128-bits of secret theoretic entropy (flip a coin 128 times, roll a d6 50 times, Argon2id a password, etc) as your seed.






    share|improve this answer









    $endgroup$


















      3












      $begingroup$

      There are a few things going on in your approach that need to be discussed, so let's look at each of those individually, and then see if we can come to a conclusion about your design.



      Seeding /dev/random



      There is certainly nothing wrong with reseeding /dev/random just as long as you understand the Linux CSPRNG architecture. When sending data to the kernel's CSPRNG, the data is mixed in the input pool with other data collected by the system. In fact, the kernel is mixing hardware events and interrupts into the input pool consistently, and this really only becomes a problem for embedded, low power, solid state devices where hardware interrupts are rare.



      After data is added to the input pool, it is then mixed with all the other data in the input pool with a randomness extractor. The goal of this mixing is to take correlated, biased, and predictable data, and extract the raw entropy. Once extracted, that data is then encrypted with ChaCha20, if using Linux 4.8+, or SHA-1 otherwise (MD5 if you're using a really early 1.x or 2.x kernel).



      Sending data from publicly accessible data, like Bitcoin transactions, into the CSPRNG to reseed it is fine, but don't get any false sense of security. You won't degrade the security margins of the generator, but you may not increase the security margins of the generator either. Ultimately, the goal of reseeding a CSPRNG is to prevent backtracking attacks, which you can't do with public data. So let's talk about that next.



      Backtracking resistance



      You're using SHA-512 as a randomness extractor, and that's perfectly fine, but as it stands in your implementation, it's not enough. SHA-512 is designed to take biased, correlated bits, and turn it into a fixed-length output of statistically unbiased, uncorrelated bits.



      This is simple enough to demonstrate in the terminal:



      $ dd if=/dev/zero bs=1 count=1000 2> /dev/random | sha512sum
      ca3dff61bb23477aa6087b27508264a6f9126ee3a004f53cb8db942ed345f2f2d229b4b59c859220a1cf1913f34248e3803bab650e849a3d9a709edc09ae4a76 -


      Here we fed 1,000 bytes of binary zeros into SHA-512, and got an output that is a hexadecimal representation of those unbiased bits. So, if SHA-512 is reseeded with unique, and secret seeds, then its output in indistinguishable from true random white noise, and it's data is also unpredictable.



      But not predicting future data isn't enough for a CSPRNG. We also need to design it such that we cannot reproduce past states, thus predicting previously calculated keys or secrets. This is called forward secrecy or backtracking resistance.



      To illustrate this is very simple terms, consider a simple counter i=0, 1, 2, 3, ..., n. We could hash this with SHA-512, and it would produce unique statistically uniform independent bits. But suppose an adversary is able to compromise the state of the generator, and after watching the state, knows you're just incrementing a counter. All the adversary needs to do at this point is decrement the counter, and they can calculate all prior RNG states. This generator is not backtracking resistant.



      Using time has a similar problem. What prevents the adversary from calculating past times in microseconds, and generating past states? Sure, there will be some variability in accuracy, but if the adversary can monitor the state of the generator, then the adversary knows how long it takes each state to execute. This gives a window with a small epsilon of past states to calculate.



      Because your RNG is reliant on time, it's not backtracking resistant, and as such, not cryptographically secure.



      Public vs secret seeds



      Finally, there is a time and place where seeding a generator with public data is perfectly acceptable, primarily for audits and transparent verification. That is what randomness beacons, such as the ones by NIST and CLCERT are doing. But the goal of these beacons/generators is to provide accountability for social decisions, such as elections, sampling, drug testing, and other things, where people picked as a result of the generator, can force an audit on the decision, and it can be strongly proven they were picked uniformly, and without bias.



      Generally though, for RNGs, we want secret seeds, because we want the output of the generator to be unpredictable. If the seed is public, then all future output can be calculated in advance. If the seed is secret, then predicting future output should be as difficult as either breaking the algorithm, or forcing discovery of the seed.



      This is why you don't want to use random.org, Bitcoin, tweets, atmospheric noise, RF spectrum, or any other publicly accessible sources for seeds to RNGs. Because if an adversary can either influence the source (RF jamming) or read the source (Bitcoin), then they can use that knowledge to predict the outcome of your RNG.



      Also, financial exchanges do not exhibit random walks. So as an entropy input, they're not very good. This includes Bitcoin markets and transactions.



      A suggestion for improvement



      First and foremost, you should only ever use /dev/urandom when you need secure and safe random numbers. Userspace RNGs are loaded with footguns, a couple of which I outlined here. They're also almost completely unnecessary. It really is the only place as a developer you should be turning, when you need cryptographically secure randomness.



      However, if you're hell-bent on shipping a userspace RNG, then as a suggestion to improve the quality of your generator, I would suggest you turn to fast key erasure as explained by Dr. Daniel J. Bernstein. Drop SHA-512 in favor of keyed AES-128 and forget about Bitcoin and timestamps, but instead use 128-bits of secret theoretic entropy (flip a coin 128 times, roll a d6 50 times, Argon2id a password, etc) as your seed.






      share|improve this answer









      $endgroup$
















        3












        3








        3





        $begingroup$

        There are a few things going on in your approach that need to be discussed, so let's look at each of those individually, and then see if we can come to a conclusion about your design.



        Seeding /dev/random



        There is certainly nothing wrong with reseeding /dev/random just as long as you understand the Linux CSPRNG architecture. When sending data to the kernel's CSPRNG, the data is mixed in the input pool with other data collected by the system. In fact, the kernel is mixing hardware events and interrupts into the input pool consistently, and this really only becomes a problem for embedded, low power, solid state devices where hardware interrupts are rare.



        After data is added to the input pool, it is then mixed with all the other data in the input pool with a randomness extractor. The goal of this mixing is to take correlated, biased, and predictable data, and extract the raw entropy. Once extracted, that data is then encrypted with ChaCha20, if using Linux 4.8+, or SHA-1 otherwise (MD5 if you're using a really early 1.x or 2.x kernel).



        Sending data from publicly accessible data, like Bitcoin transactions, into the CSPRNG to reseed it is fine, but don't get any false sense of security. You won't degrade the security margins of the generator, but you may not increase the security margins of the generator either. Ultimately, the goal of reseeding a CSPRNG is to prevent backtracking attacks, which you can't do with public data. So let's talk about that next.



        Backtracking resistance



        You're using SHA-512 as a randomness extractor, and that's perfectly fine, but as it stands in your implementation, it's not enough. SHA-512 is designed to take biased, correlated bits, and turn it into a fixed-length output of statistically unbiased, uncorrelated bits.



        This is simple enough to demonstrate in the terminal:



        $ dd if=/dev/zero bs=1 count=1000 2> /dev/random | sha512sum
        ca3dff61bb23477aa6087b27508264a6f9126ee3a004f53cb8db942ed345f2f2d229b4b59c859220a1cf1913f34248e3803bab650e849a3d9a709edc09ae4a76 -


        Here we fed 1,000 bytes of binary zeros into SHA-512, and got an output that is a hexadecimal representation of those unbiased bits. So, if SHA-512 is reseeded with unique, and secret seeds, then its output in indistinguishable from true random white noise, and it's data is also unpredictable.



        But not predicting future data isn't enough for a CSPRNG. We also need to design it such that we cannot reproduce past states, thus predicting previously calculated keys or secrets. This is called forward secrecy or backtracking resistance.



        To illustrate this is very simple terms, consider a simple counter i=0, 1, 2, 3, ..., n. We could hash this with SHA-512, and it would produce unique statistically uniform independent bits. But suppose an adversary is able to compromise the state of the generator, and after watching the state, knows you're just incrementing a counter. All the adversary needs to do at this point is decrement the counter, and they can calculate all prior RNG states. This generator is not backtracking resistant.



        Using time has a similar problem. What prevents the adversary from calculating past times in microseconds, and generating past states? Sure, there will be some variability in accuracy, but if the adversary can monitor the state of the generator, then the adversary knows how long it takes each state to execute. This gives a window with a small epsilon of past states to calculate.



        Because your RNG is reliant on time, it's not backtracking resistant, and as such, not cryptographically secure.



        Public vs secret seeds



        Finally, there is a time and place where seeding a generator with public data is perfectly acceptable, primarily for audits and transparent verification. That is what randomness beacons, such as the ones by NIST and CLCERT are doing. But the goal of these beacons/generators is to provide accountability for social decisions, such as elections, sampling, drug testing, and other things, where people picked as a result of the generator, can force an audit on the decision, and it can be strongly proven they were picked uniformly, and without bias.



        Generally though, for RNGs, we want secret seeds, because we want the output of the generator to be unpredictable. If the seed is public, then all future output can be calculated in advance. If the seed is secret, then predicting future output should be as difficult as either breaking the algorithm, or forcing discovery of the seed.



        This is why you don't want to use random.org, Bitcoin, tweets, atmospheric noise, RF spectrum, or any other publicly accessible sources for seeds to RNGs. Because if an adversary can either influence the source (RF jamming) or read the source (Bitcoin), then they can use that knowledge to predict the outcome of your RNG.



        Also, financial exchanges do not exhibit random walks. So as an entropy input, they're not very good. This includes Bitcoin markets and transactions.



        A suggestion for improvement



        First and foremost, you should only ever use /dev/urandom when you need secure and safe random numbers. Userspace RNGs are loaded with footguns, a couple of which I outlined here. They're also almost completely unnecessary. It really is the only place as a developer you should be turning, when you need cryptographically secure randomness.



        However, if you're hell-bent on shipping a userspace RNG, then as a suggestion to improve the quality of your generator, I would suggest you turn to fast key erasure as explained by Dr. Daniel J. Bernstein. Drop SHA-512 in favor of keyed AES-128 and forget about Bitcoin and timestamps, but instead use 128-bits of secret theoretic entropy (flip a coin 128 times, roll a d6 50 times, Argon2id a password, etc) as your seed.






        share|improve this answer









        $endgroup$



        There are a few things going on in your approach that need to be discussed, so let's look at each of those individually, and then see if we can come to a conclusion about your design.



        Seeding /dev/random



        There is certainly nothing wrong with reseeding /dev/random just as long as you understand the Linux CSPRNG architecture. When sending data to the kernel's CSPRNG, the data is mixed in the input pool with other data collected by the system. In fact, the kernel is mixing hardware events and interrupts into the input pool consistently, and this really only becomes a problem for embedded, low power, solid state devices where hardware interrupts are rare.



        After data is added to the input pool, it is then mixed with all the other data in the input pool with a randomness extractor. The goal of this mixing is to take correlated, biased, and predictable data, and extract the raw entropy. Once extracted, that data is then encrypted with ChaCha20, if using Linux 4.8+, or SHA-1 otherwise (MD5 if you're using a really early 1.x or 2.x kernel).



        Sending data from publicly accessible data, like Bitcoin transactions, into the CSPRNG to reseed it is fine, but don't get any false sense of security. You won't degrade the security margins of the generator, but you may not increase the security margins of the generator either. Ultimately, the goal of reseeding a CSPRNG is to prevent backtracking attacks, which you can't do with public data. So let's talk about that next.



        Backtracking resistance



        You're using SHA-512 as a randomness extractor, and that's perfectly fine, but as it stands in your implementation, it's not enough. SHA-512 is designed to take biased, correlated bits, and turn it into a fixed-length output of statistically unbiased, uncorrelated bits.



        This is simple enough to demonstrate in the terminal:



        $ dd if=/dev/zero bs=1 count=1000 2> /dev/random | sha512sum
        ca3dff61bb23477aa6087b27508264a6f9126ee3a004f53cb8db942ed345f2f2d229b4b59c859220a1cf1913f34248e3803bab650e849a3d9a709edc09ae4a76 -


        Here we fed 1,000 bytes of binary zeros into SHA-512, and got an output that is a hexadecimal representation of those unbiased bits. So, if SHA-512 is reseeded with unique, and secret seeds, then its output in indistinguishable from true random white noise, and it's data is also unpredictable.



        But not predicting future data isn't enough for a CSPRNG. We also need to design it such that we cannot reproduce past states, thus predicting previously calculated keys or secrets. This is called forward secrecy or backtracking resistance.



        To illustrate this is very simple terms, consider a simple counter i=0, 1, 2, 3, ..., n. We could hash this with SHA-512, and it would produce unique statistically uniform independent bits. But suppose an adversary is able to compromise the state of the generator, and after watching the state, knows you're just incrementing a counter. All the adversary needs to do at this point is decrement the counter, and they can calculate all prior RNG states. This generator is not backtracking resistant.



        Using time has a similar problem. What prevents the adversary from calculating past times in microseconds, and generating past states? Sure, there will be some variability in accuracy, but if the adversary can monitor the state of the generator, then the adversary knows how long it takes each state to execute. This gives a window with a small epsilon of past states to calculate.



        Because your RNG is reliant on time, it's not backtracking resistant, and as such, not cryptographically secure.



        Public vs secret seeds



        Finally, there is a time and place where seeding a generator with public data is perfectly acceptable, primarily for audits and transparent verification. That is what randomness beacons, such as the ones by NIST and CLCERT are doing. But the goal of these beacons/generators is to provide accountability for social decisions, such as elections, sampling, drug testing, and other things, where people picked as a result of the generator, can force an audit on the decision, and it can be strongly proven they were picked uniformly, and without bias.



        Generally though, for RNGs, we want secret seeds, because we want the output of the generator to be unpredictable. If the seed is public, then all future output can be calculated in advance. If the seed is secret, then predicting future output should be as difficult as either breaking the algorithm, or forcing discovery of the seed.



        This is why you don't want to use random.org, Bitcoin, tweets, atmospheric noise, RF spectrum, or any other publicly accessible sources for seeds to RNGs. Because if an adversary can either influence the source (RF jamming) or read the source (Bitcoin), then they can use that knowledge to predict the outcome of your RNG.



        Also, financial exchanges do not exhibit random walks. So as an entropy input, they're not very good. This includes Bitcoin markets and transactions.



        A suggestion for improvement



        First and foremost, you should only ever use /dev/urandom when you need secure and safe random numbers. Userspace RNGs are loaded with footguns, a couple of which I outlined here. They're also almost completely unnecessary. It really is the only place as a developer you should be turning, when you need cryptographically secure randomness.



        However, if you're hell-bent on shipping a userspace RNG, then as a suggestion to improve the quality of your generator, I would suggest you turn to fast key erasure as explained by Dr. Daniel J. Bernstein. Drop SHA-512 in favor of keyed AES-128 and forget about Bitcoin and timestamps, but instead use 128-bits of secret theoretic entropy (flip a coin 128 times, roll a d6 50 times, Argon2id a password, etc) as your seed.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 11 hours ago









        Aaron ToponceAaron Toponce

        1311




        1311






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217625%2ffill-dev-random-via-bitcoin-exchange-value%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Couldn't open a raw socket. Error: Permission denied (13) (nmap)Is it possible to run networking commands...

            VNC viewer RFB protocol error: bad desktop size 0x0I Cannot Type the Key 'd' (lowercase) in VNC Viewer...

            Why not use the yoke to control yaw, as well as pitch and roll? Announcing the arrival of...