-1

pybitcointools (https://github.com/primal100/pybitcointools) generates a bitcoin private key using the following function (in main.py: https://github.com/primal100/pybitcointools/blob/master/cryptos/main.py):

import hashlib
def random_key():
    entropy = random_string(32) \
        + str(random.randrange(2**256)) \
        + str(int(time.time() * 1000000))
    return sha256(entropy)

in other places I saw a simpler implementation:

import os
os.urandom(32).hex()

I wonder which is more random, what is safer to use?

IamTheWalrus
  • 594
  • 5
  • 14
  • which do you think is better. you have exactly what the first one is there ( SHA256 with random range of numbers followed by time.time *1000000) the second one is done through the OS specifics. for windows its https://msdn.microsoft.com/en-us/library/windows/desktop/aa379942(v=vs.85).aspx – L_Church Mar 13 '18 at 14:34
  • @L_Church I'm not sure what you mean by "you have exactly what the first one is there" – IamTheWalrus Mar 13 '18 at 15:02
  • just research into what both of them do and what others say what the better is. the first one uses SHA256 encryption hash while the second one uses the OS method for cryptography. the method windows uses is what i linked (probably, google is your friend tl;dr) – L_Church Mar 13 '18 at 15:14
  • @L_Church I read that os.urandom() is supposed to be good enough for cryptography, as long the OS is doing a good job.. as we know in the case of Java.SecureRandom android implementation it failed in 2013. I also read (and understand) that hashing does not in fact improve randomness, so I am not clear why SHA256 is used at all. Despite my googling efforts I am still in the dark and will appreciate further insights. – IamTheWalrus Mar 13 '18 at 15:23
  • /dev/urandom is cryptographically secure enough for virtually anything, at least when Debian or Oracle or somebody hasn't introduced a bug. The rest looks like needless complexity designed to make laypeople think there is some randomness. There may or may not actually be. – Michael Hampton Mar 13 '18 at 18:20
  • The two methods are not comparable as the are designed for different purposes. Furthermore, you haven't indicated how random_string or random is initialized, nor is there any code at the link you provided. – President James K. Polk Mar 13 '18 at 20:49
  • @JamesKPolk Apologies, they have stopped supporting the package - I have now edited the question to include a link to a supported fork. – IamTheWalrus Mar 14 '18 at 03:29
  • @MichaelHampton is it possible to try to check it, with some degree of confidence? for example, to generate a large amount of random numbers and check the distribution? – IamTheWalrus Mar 14 '18 at 03:38

1 Answers1

2

os.urandom() uses system functions specifically designed for cryptographically secure random numbers, and is far superior to the other function you show. The first function looks pretty much like someone's "roll your own" version of a random string, and while he didn't completely screw it up, it's not nearly good enough for crypto use.

NEVER roll your own crypto!

Lee Daniel Crocker
  • 12,927
  • 3
  • 29
  • 55
  • _Never rolling your own crypto_ is worth emphasizing. This almost never ends well. – Michael Hampton Mar 14 '18 at 01:30
  • Thanks. And to followup on that, say I want to generate not one but 100 random numbers using os.urandom(). Does the randomness improve if I run it at different times, instead of using a loop? Perhaps the time intervals between calls to the function should be randomized as well? or do I try to mess with something that works? – IamTheWalrus Mar 14 '18 at 04:34
  • 1
    It shouldn't matter. Modern OSs implement this in hardware, so they are hard to screw up. – Lee Daniel Crocker Mar 14 '18 at 16:54