2
When creating a private key, how would I ensure that there is a mini private key equivalent, which could be substituted in place of the the full private key? What math would I have to use to create such a private key for bitcoins?
2
When creating a private key, how would I ensure that there is a mini private key equivalent, which could be substituted in place of the the full private key? What math would I have to use to create such a private key for bitcoins?
2
You can't create a minikey for a private key - you need to create a private key once you've created a minikey.
You need to ensure that the SHA256 of the mini key plus a question mark after it has a hash starting with 00.
Or, in Python:
sha256(candidate + "?")[0] == chr(0)
The following Python program will generate mini keys:
import hashlib
from binascii import hexlify as hx
import random
rand = random.SystemRandom()
B58_ALPHA = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
def sha256(s):
return hashlib.sha256(s).digest()
def gen_candidate():
candidate = "S"
for i in xrange(29):
candidate = candidate + rand.choice(B58_ALPHA)
return candidate
def test_candidate(candidate):
return sha256(candidate + "?")[0] == chr(0)
while True:
c = gen_candidate()
if test_candidate(c):
print c, hx(sha256(c))
2Pretty please use random.SystemRandom().choice() instead of random.choice(), even if it's just an example. We've been down the road of insecure RNGs before, and I'm sure you wouldn't want to contribute to that ;) – Christopher Gurnee – 2015-04-19T23:52:01.383
@ChristopherGurnee Good point. – Nick ODell – 2015-04-20T00:27:02.777
Yes, I have heard to use specific random generators before when making random numbers/strings that should be kept secret because if you use a well-known algorithm with few possibilities for the seed, your number could much more easily be guessed at. – Gemohn Herbile – 2015-04-20T12:37:14.800
For this particular example, for generating a single private key, it's actually OK to use random.choice() if a recent version of Python is used because the random module is well seeded from the OS's entropy source. For older versions of Python, or when generating many private keys at once (around 120 or more), using the base random module is very dangerous. It's always safer to just use SystemRandom() in crypto code. – Christopher Gurnee – 2015-04-20T15:00:09.917
@ChristopherGurnee
it's actually OK to use random.choice()That's actually not true. Even though the RNG is securely seeded, it uses the Wichmann-Hill algorithm to actually generate numbers. – Nick ODell – 2015-04-20T17:36:48.0301@NickODell It hasn't used WH for a few years now—it uses Mersenne Twister, specifically the 19937 variant. This isn't a CSPRNG either, and it's been shown that once you have 19937 bits of output (about 120 mini private keys' worth) you can predict all future output. Generating a small fraction of that is likely to be unpredictable assuming the seed contains enough entropy, although I don't think there's research on determining when (before gathering all 19937 bits) MT becomes feasibly predictable (which still makes it a bad idea I'll grant you!). – Christopher Gurnee – 2015-04-20T18:01:42.750
Shouldn't the loop be
– andebauchery – 2016-04-19T06:54:48.523for i in xrange(29):since well-formed minikeys are 30 Base58 characters starting with S?@andebauchery Thanks for the catch. Not sure what I was thinking. – Nick ODell – 2016-04-19T14:48:13.400