Bitcoin Forum

Bitcoin => Armory => Topic started by: RBell on April 21, 2015, 10:16:59 PM



Title: Inputting Your Own Entropy
Post by: RBell on April 21, 2015, 10:16:59 PM
Hi All,

I've read in quite a few places how to sort of be your own RNG, using dice or cards, to create a private key.  I have read a few different ways to do this with Armory and would like some clarification please on how to best do this.  I feel that cards would be the best way, because you don't have to worry about the weight of the dice being perfect.

Thank you for your input!

RB


Title: Re: Inputting Your Own Entropy
Post by: btchris on April 21, 2015, 11:40:25 PM
I've read in quite a few places how to sort of be your own RNG, using dice or cards, to create a private key.  I have read a few different ways to do this with Armory and would like some clarification please on how to best do this.  I feel that cards would be the best way, because you don't have to worry about the weight of the dice being perfect.

I also think cards are the easiest way, but they do have some pitfalls. See here for a good discussion on how to shuffle well enough to provide sufficient entropy: https://bitcointalk.org/index.php?topic=682842.0 (https://bitcointalk.org/index.php?topic=682842.0)


Title: Re: Inputting Your Own Entropy
Post by: RBell on April 22, 2015, 04:40:50 AM
I've read in quite a few places how to sort of be your own RNG, using dice or cards, to create a private key.  I have read a few different ways to do this with Armory and would like some clarification please on how to best do this.  I feel that cards would be the best way, because you don't have to worry about the weight of the dice being perfect.

I also think cards are the easiest way, but they do have some pitfalls. See here for a good discussion on how to shuffle well enough to provide sufficient entropy: https://bitcointalk.org/index.php?topic=682842.0 (https://bitcointalk.org/index.php?topic=682842.0)

That was a very interesting read, thank you!

Once I achieve the random shuffle, do you know how I go about getting the private key? And can this be used to generate a HD wallet, so I only need one backup?

Thanks!


Title: Re: Inputting Your Own Entropy
Post by: picobit on April 22, 2015, 07:17:42 AM
I've read in quite a few places how to sort of be your own RNG, using dice or cards, to create a private key.  I have read a few different ways to do this with Armory and would like some clarification please on how to best do this.  I feel that cards would be the best way, because you don't have to worry about the weight of the dice being perfect.

I also think cards are the easiest way, but they do have some pitfalls. See here for a good discussion on how to shuffle well enough to provide sufficient entropy: https://bitcointalk.org/index.php?topic=682842.0 (https://bitcointalk.org/index.php?topic=682842.0)

That was a very interesting read, thank you!

Once I achieve the random shuffle, do you know how I go about getting the private key? And can this be used to generate a HD wallet, so I only need one backup?

Thanks!

Shuffling 52 cards is equivalent to 225 bits of entropy, more than enough.  I added the three jokers, just since they were there.

I wrote down the sequence of cards, using one letter for each suit, the number for ace to 10, and JQK for the last three.  Any code will do.
In a terminal window on the secure offline machine I started the shasum -a 256 command and typed the sequence directly as input.
I then found the translation from hex to the Armory backup alphabet somewhere in the source code.  I also found the lines that did the checksum.  I made a small Python script that took the sha256 and converted it to Armory input.  Then I started Armory, cut-and-pasted the code into it, set a password, made a 2-of-3 paper backup, deleted the armory wallet again, restored from the paper backup, stored the paper backups in three safe places, and proceeded to use the wallet.

Hmm, I intended to paste the ten lines of code here - but I cannot find it.  That makes this post somewhat less useful. :(

As I remember it, I spend most of an afternoon looking at the source code to find the alphabet (easy to find) and the checksum calculation (not so easy to find) - and then writing the code was pretty fast.  But it is so long ago that I cannot reproduce it now.  Maybe somebody has posted such a code snippet somewhere.

WARNING:  It is of course possible to use the same procedure to generate brain wallets by sha256'ing a passphase.  That is a good way to lose bitcoins, either by using an insecure passphase (we are awful at generating entropy!) or by forgetting the passphase.  Not that the two are mutually exclusive  ;D


Title: Re: Inputting Your Own Entropy
Post by: btchris on April 22, 2015, 04:56:34 PM
Along the lines of what picobit was thinking, here's a Python script to do this.

It will ask you for a new wallet password, your entropy (e.g. "3s ad 9h tc 4d"....), and whether or not you'd like it to add additional OS-supplied entropy, and then it will ask Armory to create a wallet file (in its usual location).

It needs to run on a machine which already has Armory installed. If you choose not to add additional OS-supplied entropy, be certain you only run this on an offline/cold storage machine. Please close Armory before running it, and when you start Armory after running it the new wallet will be listed in the GUI.

Code:
import sys, os

# Try to add the Armory libraries to the path for various platforms
if sys.platform == "win32":
    progfiles_path = os.environ.get("ProgramFiles", r"C:\Program Files")  # default is for XP
    armory_path    = progfiles_path + r"\Armory"
    sys.path.extend((armory_path, armory_path + r"\library.zip"))
    # 64-bit Armory might install into the 32-bit directory; if this is 64-bit Python look in both
    import struct
    if struct.calcsize('P') * 8 == 64:  # calcsize('P') is a pointer's size in bytes
        assert not progfiles_path.endswith("(x86)"), "ProgramFiles doesn't end with '(x86)' on x64 Python"
        progfiles_path += " (x86)"
        armory_path     = progfiles_path + r"\Armory"
        sys.path.extend((armory_path, armory_path + r"\library.zip"))
elif sys.platform.startswith("linux"):
    sys.path.append("/usr/lib/armory")
elif sys.platform == "darwin":  # untested
    sys.path.append("/Applications/Armory.app/Contents/MacOS/py/usr/lib/armory")

from armoryengine import PyBtcWallet
from CppBlockUtils import SecureBinaryData
from hashlib import sha256
from getpass import getpass

# Hack to prevent Armory from overwriting an existing wallet file
def open_noclobber(name, mode='r'):
    if 'w' in mode:
        if os.path.exists(name):
            raise IOError("won't overwrite existing file '{}'".format(name))
    return open(name, mode)
PyBtcWallet.open = open_noclobber

password = getpass('Password>')
if not password:
    sys.exit('A password is required')
if getpass('Verify password>') != password:
    sys.exit("Passwords don't match")

cards = raw_input('Cards> ')
if len(cards.replace(' ', '')) < 50:  # 2 letters per card
    sys.exit('Requires a bare minimum of 25 cards')
entropy = sha256(cards).digest()

if raw_input('Also add additional OS-supplied entropy (Y/n)? ').lower().strip() == 'n':
    wallet = PyBtcWallet.PyBtcWallet().createNewWallet(plainRootKey=entropy, securePassphrase=password, doRegisterWithBDM=False)
else:
    wallet = PyBtcWallet.PyBtcWallet().createNewWallet(extraEntropy=SecureBinaryData(entropy), securePassphrase=password, doRegisterWithBDM=False)

print 'New wallet created with ID', wallet.uniqueIDB58

(consider it released under The MIT License (http://opensource.org/licenses/MIT))


Title: Re: Inputting Your Own Entropy
Post by: picobit on April 23, 2015, 07:41:48 AM
Along the lines of what picobit was thinking, here's a Python script to do this.
Wow!

Now I am glad I did not find my script - this is much easier to use, and more elegant.


Title: Re: Inputting Your Own Entropy
Post by: RBell on April 24, 2015, 03:25:06 AM
Along the lines of what picobit was thinking, here's a Python script to do this.
Wow!

Now I am glad I did not find my script - this is much easier to use, and more elegant.


Thank you both for your help!