Bitcoin Forum

Bitcoin => Project Development => Topic started by: bitlotto on June 27, 2011, 05:33:16 AM



Title: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: bitlotto on June 27, 2011, 05:33:16 AM
Special thanks to 'grondilu' and 'unk' ! I pretty much merged their commands/scripts together to create this one! Donate to them if you want to show thanks!

This script is intended to be added to any live CD so that all a user has to do is type:

./botg.sh

A tiny little script that uses openssl to create a private key along with a matching Bitcoin address. When run off of a Live CD environment, a very safe location for storing BTC can be created. Running on a Live CD with no Internet ensures no virus or malware can get the private key. The script will create a private key and present it in two formats: Hex and Base58. Either format can be used to access the matching Bitcoin address and helps provide redundancy in case one is copied down wrong. After copying down the keys and the matching Bitcoin address the user is advised to reboot the computer. Keeping the key "off-the-grid" or off any computer means no viruses or computer security lapses will jeopardize your BTC. No backups or encryption is needed. Any money you send to the matching Bitcoin address will be safe. The only way to steal the BTC would be to steal the key directly off of where it is written down. Therefore, it's best to keep the paper somewhere safe where it can't get destroyed or stolen.

Other uses could be:
-pre-loaded cards/tickets that are redeemable
-sending BTC when you are not sure who is going to receive it such as geo cache locations
-scratch cards or draws that are done at parties where everyone gets tickets with unknown amounts
-give BTC to someone and you don't know their Bitcoin address

Script has been tested a lot. Personally I have created over 500 keys and then imported them into Bitcoin to see if they were valid. All worked perfectly!

I'll update this post as the script develops and suggestions/improvements are made.

BOTG v.0.1.1

Create file botg.sh and make executable.

Code:
#!/bin/bash 

base58=({1..9} {A..H} {J..N} {P..Z} {a..k} {m..z})
bitcoinregex="^[$(printf "%s" "${base58[@]}")]{34}$"

decodeBase58() {
    local s=$1
    for i in {0..57}
    do s="${s//${base58[i]}/ $i}"
    done
    dc <<< "16o0d${s// /+58*}+f"
}

encodeBase58() {
    # 58 = 0x3A
    bc <<<"ibase=16; n=${1^^}; while(n>0) { n%3A ; n/=3A }" |
    tac |
    while read n
    do echo -n ${base58[n]}
    done
}

checksum() {
    xxd -p -r <<<"$1" |
    openssl dgst -sha256 -binary |
    openssl dgst -sha256 -binary |
    xxd -p -c 80 |
    head -c 8
}

checkBitcoinAddress() {
    if [[ "$1" =~ $bitcoinregex ]]
    then
        h=$(decodeBase58 "$1")
        checksum "00${h::${#h}-8}" |
        grep -qi "^${h: -8}$"
    else return 2
    fi
}

hash160() {
    openssl dgst -sha256 -binary |
    openssl dgst -rmd160 -binary |
    xxd -p -c 80
}

hash160ToAddress() {
    printf "%34s\n" "$(encodeBase58 "00$1$(checksum "00$1")")" |
    sed "y/ /1/"
}

publicKeyToAddress() {
    hash160ToAddress $(
    openssl ec -pubin -pubout -outform DER |
    tail -c 65 |
    hash160
    )
}

hash256ToAddress() {
#printf "80$1$(checksum "80$1")"
    printf "%34s\n" "$(encodeBase58 "80$1$(checksum "80$1")")" |
    sed "y/ /1/"
}


privateKeyToWIF() {
    hash256ToAddress $(openssl ec -text -noout -in data.pem | head -5 | tail -3 | fmt -120 | sed 's/[: ]//g')
}

echo " "
echo "BITCOINS OFF-THE-GRID (BOTG) v0.1.1: One of the most secure savings you'll ever get!"
echo " "
echo "For BEST results:"
echo " "
echo "-run './botg' from a Live Linux CD"
echo "-run this script with the Internet turned off"
echo "-reboot computer when done"
echo "-never record the secret key on a computer"
echo "-safely hide the key on a peice of paper where it won't get stolen"
echo "eg. hiding the paper in your car or inside your TV means you'll "
echo "never be able to get your money if that thing is stolen."
echo "-if you are not hiding the key, lock it up in a safe or safety deposit box"
echo " "
echo "***BOTG's strength is that since the secret key is never stored on your computer"
echo "there is nothing for a virus, malware, or spyware to steal!***"
echo " "
echo "Type and/or move the mouse for about 5 minutes. This will help improve the"
echo "randomness of your key....."
echo "Pressing ENTER will continue the script!"

read random

openssl  ecparam -genkey -name secp256k1 | tee data.pem &>/dev/null

echo " "
echo " "
echo "The following is the secret key in hex format. Record it carefully."
echo "Record the whole line after a 'read EC key'"
echo " "

hexsize=$(openssl ec -text -noout -in data.pem | head -5 | tail -3 | fmt -120 | sed 's/[: ]//g' )

while [ ${#hexsize} -ne 64 ]
do
openssl  ecparam -genkey -name secp256k1 | tee data.pem &>/dev/null && hexsize=$(openssl ec -text -noout -in data.pem | head -5 | tail -3 | fmt -120 | sed 's/[: ]//g' )
done

openssl ec -text -noout -in data.pem | head -5 | tail -3 | fmt -120 | sed 's/[: ]//g'

echo "Hit ENTER to continue"
read random

echo " "
echo "The following is the secret key in base58. This is the most"
echo "common format to import your key. Make sure to copy it down"
echo "carefully. Either this or the hex code could be used but it's"
echo "best to record both for redundancy. These two codes are to "
echo "be kept secret on a peice of paper or written down"
echo "somewhere safe. Putting them on a computer will lesson"
echo "the security of these keys."
echo "The address should begin with '5'."
echo " "

privateKeyToWIF

echo "Hit ENTER to continue"
read random

echo " "
echo "The following is the Bitcoin address you can send your savings to."
echo "Record the address carefully. It is not critical you keep this address"
echo "secret. Only the two other codes must remain secret!"
echo "The line that begins with the number 1 is your Bitcoin address you send"
echo "the funds to."
echo " "

openssl ec -pubout < data.pem | publicKeyToAddress

openssl  ecparam -genkey -name secp256k1 | tee data.pem &>/dev/null && rm data.pem

echo " "
echo "Hit ENTER to exit"
read random
exit 0



This creates a file data.pem in RAM. DO NOT save anything onto disk. Reboot the computer. Do not use with a Live CD set up to automatically save stuff on the hard drive.

Changelog:
0.0.2 -add part to ensure that entropy is good enough on live cd, encode hex to base58 as well, add note about having key that begins with 00, remove all caps!
0.0.3 -remake key if it's not exactly 64
0.1.0 -improve operation, and make it pretty.
0.1.1 -add pause at end in case it's run in a gui so it doesn't close


Title: Re: Bitcoin Off-The-Grid (BOTG): script for very secure long term saving address
Post by: mpfrank on June 27, 2011, 05:37:53 AM
Neato.  I like it.  Post your address and I'm sure someone will give you a small donation to test it.


Title: Re: Bitcoin Off-The-Grid (BOTG): script for very secure long term saving address
Post by: bitlotto on June 27, 2011, 05:40:52 AM
Neato.  I like it.  Post your address and I'm sure someone will give you a small donation to test it.
I'd rather if someone wants to donate to the cause. Just run the script. Send some BTC to the address (tiny amount - it's not tested after all). Then post the bitcoin address and the hex and see how long till someone takes it.


Title: Re: Bitcoin Off-The-Grid (BOTG): script for very secure long term saving address
Post by: Rogue Star on June 27, 2011, 05:48:31 AM
if you ever need to test something, you should try learning about/using bitcoin in testnet mode. the testnet faucet is quite generous if you don't want to mine for them. transactions can take a long time to validate however.


Title: Re: Bitcoin Off-The-Grid (BOTG): script for very secure long term saving address
Post by: bitlotto on June 27, 2011, 05:51:36 AM
if you ever need to test something, you should try learning about/using bitcoin in testnet mode. the testnet faucet is quite generous if you don't want to mine for them. transactions can take a long time to validate however.
I know  :-[ It's just that I'm about to go to bed and thought people may want to take a look. I'll have to experiment with testnet. Hopefully some who already know how to use testnet are trying it out right now? Anyways, I figured I get it out sooner rather than later so some people can see it and look it over....


Title: Re: Bitcoin Off-The-Grid (BOTG): script for very secure long term saving address
Post by: Rogue Star on June 27, 2011, 05:54:23 AM
heh, i'm in the same boat. too late for me to review/test it out, might be helpful advice for people that don't want to use "real" BTC when they test it out.


Title: Re: Bitcoin Off-The-Grid (BOTG): script for very secure long term saving address
Post by: casascius on June 27, 2011, 06:26:13 AM
I made one test with this, and I was able to confirm that on my one test, the Bitcoin address given was a match for the private key given.  In other words, I imported the private key, and Bitcoin independently gave the same Bitcoin address that matched the one given by the script.

In order to import the private key, I had to modify the script to also give the private key in Wallet Import Format.  Here is my modified script.

NO WARRANTY WHATSOEVER, USE AT OWN RISK

EDIT: A known problem with my modification, is it doesn't deal with the leading 00 byte tacked on the front of the private key if the first byte >= 0x80.  (this extra 00 ostensibly is to ensure the number isn't interpreted as a negative number).  If that's there, the script generates a wallet import key code that doesn't start with a '5', and this is wrong.  I don't do bash scripting much, someone who knows more will need to fix it.  hash256toaddress needs to take only the last 64 characters of the input string.

Code:
#!/bin/bash 

base58=({1..9} {A..H} {J..N} {P..Z} {a..k} {m..z})
bitcoinregex="^[$(printf "%s" "${base58}")]{34}$"

decodeBase58() {
    local s=$1
    for i in {0..57}
    do s="${s//${base58}/ $i}"
    done
    dc <<< "16o0d${s// /+58*}+f"
}

encodeBase58() {
    # 58 = 0x3A
    bc <<<"ibase=16; n=${1^^}; while(n>0) { n%3A ; n/=3A }" |
    tac |
    while read n
    do echo -n ${base58[n]}
    done
}

checksum() {
    xxd -p -r <<<"$1" |
    openssl dgst -sha256 -binary |
    openssl dgst -sha256 -binary |
    xxd -p -c 80 |
    head -c 8
}

checkBitcoinAddress() {
    if [[ "$1" =~ $bitcoinregex ]]
    then
        h=$(decodeBase58 "$1")
        checksum "00${h::${#h}-8}" |
        grep -qi "^${h: -8}$"
    else return 2
    fi
}

hash160() {
    openssl dgst -sha256 -binary |
    openssl dgst -rmd160 -binary |
    xxd -p -c 80
}

hash160ToAddress() {
    printf "%34s\n" "$(encodeBase58 "00$1$(checksum "00$1")")" |
    sed "y/ /1/"
}

hash256ToAddress() {
#printf "80$1$(checksum "80$1")"
    printf "%34s\n" "$(encodeBase58 "80$1$(checksum "80$1")")" |
    sed "y/ /1/"
}

publicKeyToAddress() {
    hash160ToAddress $(
    openssl ec -pubin -pubout -outform DER |
    tail -c 65 |
    hash160
    )
}

privateKeyToWIF() {
    hash256ToAddress $(openssl ec -text -noout -in data.pem | head -5 | tail -3 | fmt -120 | sed 's/[: ]//g')
    
}

openssl  ecparam -genkey -name secp256k1 | tee data.pem &>/dev/null

sleep 3

echo " "
echo "BITCOINS OFF-THE-GRID (BOTG) : A VERY SECURE SAVINGS ACCOUNT!"
echo " "
echo "THE FOLLOWING WILL BE THE PRIVATE HEX KEY NEEDED TO ACCESS YOUR BITCOINS!"
echo "***RECORD THIS NUMBER CAREFULLY*** IT CONTAINS NUMBERS 0-9 AND LETTERS A-F."
echo "THIS WILL HELP SO YOU DON'T ACCIDENTALLY CONFUSE SIMILAR LOOKING DIGITS LATER ON!"
echo "KEEP THIS HEX KEY SAFE. HIDE IT AND/OR LOCK IT UP SOMEWHERE."
echo "IT IS THE ONLY WAY TO ACCESS THE BTC IN THE FUTURE. WHOEVER HAS THAT HEX KEY"
echo "CAN SPEND YOUR MONEY. RECORD THE WHOLE LINE AFTER 'read EC key' "
echo " "
echo "ONLY USE THIS HEX KEY AND ADDRESS IF THIS SCRIPT WAS RUN OFF OF A LIVE CD WITH"
echo "NO INTERNET CONNECTION. REBOOT COMPUTER WHEN DONE TO CLEAR RAM."
echo "DO NOT COPY THIS HEX KEY ANYWHERE ONTO A COMPUTER."
echo " "



openssl ec -text -noout -in data.pem | head -5 | tail -3 | fmt -120 | sed 's/[: ]//g'
privateKeyToWIF

sleep 2

echo " "
echo "THE FOLLOWING IS THE BITCOIN ADDRESS YOU CAN SEND YOUR SAVINGS TO."
echo "RECORD THE ADDRESS CAREFULLY. IT IS NOT CRITICAL YOU KEEP THIS ADDRESS"
echo "SECRET. THE HEX CODE AND THE WALLET-IMPORT-KEYCODE MUST REMAIN SECRET!"
echo "THE LINE THAT BEGINS WITH THE NUMBER 1 IS THE BITCOIN ADDRESS."
echo " "

openssl ec -pubout < data.pem | publicKeyToAddress


echo " "
echo "SPECIAL THANKS TO 'grondilu' AND 'unk' WHO MADE THIS SCRIPT POSSIBLE!!"




Title: Re: Bitcoin Off-The-Grid (BOTG): script for very secure long term saving address
Post by: Hal on June 27, 2011, 06:35:28 AM
How much entropy does a live cd have after booting?


Title: Re: Bitcoin Off-The-Grid (BOTG): script for very secure long term saving address
Post by: casascius on June 27, 2011, 06:37:15 AM
How much entropy does a live cd have after booting?

I guess the question really boils down to where does OpenSSL get its random numbers from.

EDIT: the answer looks like /dev/urandom.  And apparently, you can increase entropy by sending random data to /dev/random.  Maybe the user can be asked to mash on their keyboard, and that be sent to /dev/random.  Just going by what I read on Wikipedia, no guarantee to accuracy.


Title: Re: Bitcoin Off-The-Grid (BOTG): script for very secure long term saving address
Post by: casascius on June 27, 2011, 07:04:01 AM
One additional comment,

Having the person write down the private key in wallet import format provides a useful measure of protection against minor transcription errors. If user can't reimport their private key and the checksum fails, it is reasonably possible to make a utility brute force against simple transcription errors (wrong case, characters missing/transposed/etc.) until the checksum can be made to match.


 Better yet, maybe another script that allows user to type back in what they wrote down (with the original removed off screen so they MUST type from their copy) to make sure they wrote it right.


Title: Re: Bitcoin Off-The-Grid (BOTG): script for very secure long term saving address
Post by: bitlotto on June 27, 2011, 12:44:18 PM
Better yet, maybe another script that allows user to type back in what they wrote down (with the original removed off screen so they MUST type from their copy) to make sure they wrote it right.
That's a pretty good idea. Blank the screen and have the user write out what they wrote down. That way they can be sure they wrote it down correctly.


Title: Re: Bitcoin Off-The-Grid (BOTG): script for very secure long term saving address
Post by: bitlotto on June 27, 2011, 01:08:12 PM
How much entropy does a live cd have after booting?
Good point. I think I'll add something about typing stuff at random and/or moving the mouse around a bunch.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.0.2
Post by: bitlotto on June 28, 2011, 03:55:21 AM
Updated to 0.0.2
Some testing being done : https://forum.bitcoin.org/index.php?topic=23521.0

Any useful tips or changes to the script are appreciated!!  ;D


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.0.2
Post by: bitlotto on June 28, 2011, 12:54:56 PM
Quote
There's still a problem, in that any private key that legitimately starts with 0000 thru 007F will still get misprocessed, because it will be spit out as a 62-character string.

The criterion you need to look for is not whether the private key starts with 00, but rather, whether it is exactly 64 characters long.  This HAS to work 100% of the time; having it make people lose funds, even if rarely, is inviting disaster and liability.
Anyone now what a great fix would be? I'm off to work and won't have time to look at it for a while...


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.0.3
Post by: bitlotto on June 28, 2011, 10:10:11 PM
fixed script. Should always create 64 character long hexes. Will this always make right keys now?


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.0.3
Post by: casascius on June 28, 2011, 11:06:05 PM
fixed script. Should always create 64 character long hexes. Will this always make right keys now?

Fingers crossed, one would hope.

I did some playing with it - observed that it rerolls the dice a few times (when the length is not 64 I presume)... and I imported one Base58 key into a wallet with the import patch, and Bitcoin successfully derived the correct address for it.

The next suggestion I might offer would be to abbreviate the text, it seems overly verbose and a bit panicky, and also I'd remove the thanks to grondilu and unk (thanks guys...they've been thanked).  I would also be willing to bet that the Base58 key is what's most likely going to be imported by a user, rather than the hex key, and would update the text to reflect that (though I wouldn't remove the hex key altogether).  BitBills uses Base58, so does sipa's wallet import... and Base58 has a checksum and guards against typos, where hex does not.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.0.3
Post by: bitlotto on June 28, 2011, 11:42:37 PM
fixed script. Should always create 64 character long hexes. Will this always make right keys now?

Fingers crossed, one would hope.

I did some playing with it - observed that it rerolls the dice a few times (when the length is not 64 I presume)... and I imported one Base58 key into a wallet with the import patch, and Bitcoin successfully derived the correct address for it.

The next suggestion I might offer would be to abbreviate the text, it seems overly verbose and a bit panicky, and also I'd remove the thanks to grondilu and unk (thanks guys...they've been thanked).  I would also be willing to bet that the Base58 key is what's most likely going to be imported by a user, rather than the hex key, and would update the text to reflect that (though I wouldn't remove the hex key altogether).  BitBills uses Base58, so does sipa's wallet import... and Base58 has a checksum and guards against typos, where hex does not.
Thanks. Yes, the wording does have to be cleaned up. I was focusing first on the algorithms. Thanks for checking and helping me with this. I think once it's tested some people may want to use it as it provides a pretty high security place to put your BTC. Are you able to get those other transactions I did or did I make a bad key with the older script....


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.0.3
Post by: casascius on June 29, 2011, 12:03:25 AM
Thanks. Yes, the wording does have to be cleaned up. I was focusing first on the algorithms. Thanks for checking and helping me with this. I think once it's tested some people may want to use it as it provides a pretty high security place to put your BTC. Are you able to get those other transactions I did or did I make a bad key with the older script....

I didn't try to get the other ones... but regardless, if you just import the base58 version of the keys with sipa's import, and see that the matching Bitcoin address showed up in the wallet (since it is computed from the private key), and this could be repeated reliably without exception, I would guess it is overwhelmingly likely that it was correct without the need to do a confirming transaction.

Also I did some experimenting with openssl.  Yes, openssl will occasionally generate a 31-byte private key.  (it's, of course, a 32-byte private key that happens to start with 00, and the leading zero truncated).

It seems as though this behavior doesn't apply to the public key.  The public key as omitted by openssl seems to always start with 04, and no extra "sign" 00 appears if the key material starts with 0x80-0xFF, and nothing is omitted as "leading zeroes", even if the first byte of key material is 00 and the second is 00-7F.  I was able to generate a public key starting with "04 00 6b" (where 04 is the standard prefix).  So my guess is the public key is safe from weird exceptions.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: bitlotto on June 30, 2011, 01:17:34 AM
It looks like it's creating pretty good keys! I've personally created over 100 keys and they were all valid and correct when imported into Bitcoin!


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: casascius on June 30, 2011, 02:58:25 AM
5HtNFUCKiNGPiECEoFGoDDaMNCoCKSuCKiNGSHiT3Viwnu6QQby
1Kv4AcDNkRjhAYvPo3w8RnDw8Jb6Pgq579
0.05 BTC

5JokeHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHADmwBca
1HvUDLU1iTfoTCp7KQw6V3Rm9KtZ56NwPS
0.05 BTC

I made an app in Visual Studio that freely converts BTCAddress <--> Pubhash <-- PubKeyHex <-- PrivKeyHex <--> PrivKeyBase58... mainly to increase my understanding of how the algorithms work.

It can generate new addresses at random, and as you can guess, I added a silly feature that allows substitution of characters, where the app would automatically recompute the checksum so that it would be a valid key.

I may publish the source...it happens to be a handy tool.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: Rogue Star on June 30, 2011, 03:13:22 AM
is it possible to take this one step further and initiate an offline transaction? think:
1. generate transaction with offline wallet
2. load transaction to a clean medium (blank dvd, paper, whatever)
3. sneakernet to online computer
4. load transaction

if it's possible, i'd take the time to brush up on the language/source and learn how to do it!


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: casascius on June 30, 2011, 03:15:44 AM
is it possible to take this one step further and initiate an offline transaction? think:
1. generate transaction with offline wallet
2. load transaction to a clean medium (blank dvd, paper, whatever)
3. sneakernet to online computer
4. load transaction

if it's possible, i'd take the time to brush up on the language/source and learn how to do it!

As far as offline transactions go... I believe commands in bitcoind to do all of the following should be added:

1. GET AVAILABLE TRANSACTIONS: caller passes in a list of Bitcoin addresses (presumably of all the private keys it has, but without actually passing the private keys), bitcoind returns a list of all the available spendable transactions on those addresses, including transaction ID's and amounts...

this should be enough for a completely separate offline app to construct valid transactions, assuming it really has independent access to all the private keys involved.

2. FORWARD TRANSACTION TO NETWORK... caller passes in a base64-encoded (for example) raw transaction and bitcoind passes it along as though it had been received from any other peer.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: ben-abuya on June 30, 2011, 10:17:19 AM
is it possible to take this one step further and initiate an offline transaction? think:
1. generate transaction with offline wallet
2. load transaction to a clean medium (blank dvd, paper, whatever)
3. sneakernet to online computer
4. load transaction

if it's possible, i'd take the time to brush up on the language/source and learn how to do it!

As far as offline transactions go... I believe commands in bitcoind to do all of the following should be added:

1. GET AVAILABLE TRANSACTIONS: caller passes in a list of Bitcoin addresses (presumably of all the private keys it has, but without actually passing the private keys), bitcoind returns a list of all the available spendable transactions on those addresses, including transaction ID's and amounts...

this should be enough for a completely separate offline app to construct valid transactions, assuming it really has independent access to all the private keys involved.

2. FORWARD TRANSACTION TO NETWORK... caller passes in a base64-encoded (for example) raw transaction and bitcoind passes it along as though it had been received from any other peer.

Agreed. It shouldn't be too hard, but the whole transaction building and signing code is in a critical block, so it will take some care to break it out.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: bitlotto on June 30, 2011, 12:31:23 PM
Just so people know, I've tested another 500 generated keys and they all worked too when imported!  ;D


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: joan on June 30, 2011, 02:55:32 PM
I have imported and redeemed successfully the following "vanity" privkey generated by casascius.
Code:
5HtNFUCKiNGPiECEoFGoDDaMNCoCKSuCKiNGSHiT3Viwnu6QQby
1Kv4AcDNkRjhAYvPo3w8RnDw8Jb6Pgq579
0.05 BTC
I Posted a related challenge (http://forum.bitcoin.org/index.php?topic=24713.0) for when the person makes a typo while writing the privkey down.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: bcearl on July 03, 2011, 05:54:28 PM
Looks like a good idea to me, I will take a closer look when I find some time.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: bitlotto on July 03, 2011, 06:15:37 PM
Looks like a good idea to me, I will take a closer look when I find some time.
Thank you! You seem to have a bit of security knowledge. Like the OP says, I pretty much took the scripts posted throughout the forum and put them together! Thanks guys! I was on a mission to find the MOST secure method of storing BTC.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: Ente on August 05, 2011, 08:04:56 PM
Great work, thank you a lot! This will be very helpful for a lot of projects, I am sure!

Being a bash-script-noob and only a bit experienced with the inner parts of Bitcoin, I need a little help:
Which part of the botg script converts the HEX key into (sipa patch importable) base58?

My plan is to do this:

- Take a known plaintext string, like "Damnesia" (from another thread)

- Create the SHA256 hash from that string with "echo -n Damnesia | sha256sum", in this example its "58c00ef49f161ac94e40cde5106227e09a6dc1840cf601c877b48d9ccc7ebdbe"

- Take the relevant part of this BOTG script to convert the SHA256 Hex key to base58, should be "5JVNazqC4JucAHUeRLhcqrbGFAro2CySd2ptDaDnPe18G9tmuAs" here


I can do it in a script by using the blockexplorer's "converter", this here works by saving it as "mkprvkey.sh" for example and running it with "./mkprvkey.sh Damnesia"

Code:
STRING=$1
echo
echo String: $STRING
HEX=`echo -n $STRING | sha256sum | sed 's/.\{3\}$//'`
B58=`wget -qO- http://blockexplorer.com/q/hashtoaddress/$HEX/80`
echo PrvKey: $B58
echo

For obvious reasons there must be a better way to do this, without transferring my private key to an online service, and without having to be online to begin with..

Ultimately I want to create a wallet.dat from a handful of passphrases, as a worst-case backup in case my regular, encrypted backups of the wallet.dat get eaten by fire, lightningstorm and house searches ;-)

As I said, I am quite new to bash scripting, please bear with me!

Thank you,

Ente


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: Ente on August 06, 2011, 04:32:55 PM
..actually you can achieve what I try with jackjack's pywallet:
https://github.com/jackjack-jj/pywallet

Since I would use pywallet to import the base58 keys anyway, I can use it right away with the Hex keys as well.

If someone likes to point out which part of BOTG exactly does the conversion, I would like to see and understand!

Ente

edit:
found it somewhere:
the magic lines would be:

privkey=58c00ef49f161ac94e40cde5106227e09a6dc1840cf601c877b48d9ccc7ebdbe
encodeBase58 "80$privkey$(checksum "80$privkey")" && echo


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: davout on August 17, 2011, 08:31:55 AM
Check out the end of the original grondilu thread, I've shared a script that takes a PEM and spits out the private key encoded as a QR code for easy paper storage.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: Red Emerald on September 26, 2011, 10:24:29 PM
This is cool.

I played around with this on my mining rig and it worked great.

I tried testing the script on my Mac (Lion), but the "tac" command isn't installed.  This didn't really bother me since I don't want to run my "super secure wallet" on my main machine, so I setup a Fedora VM for my wallet to call home.

The problem is that Fedora's openssl does not have EC enabled (theres some sort of licensing problem with it).

I ended up making an xubuntu VM and that seems to play nice. Although it does say "read EC key" and "writing EC key" multiple times at each step which seems odd.

What way do you recommend importing these keys? I just updated my client to 0.4.1-beta. Is there a command line way of importing to the default client, or do we need to use a 3rd party one?

EDIT: Found https://bitcointalk.org/index.php?topic=8091.120


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: grondilu on November 02, 2011, 03:22:18 PM
Damned it, information about all this stuff seem quite dispatched every here and there.

I'd be interested in learning more about Casascius's formats (called "mini private key"  I think) and the "wallet import format".

Any entry in the wiki?  I can't contribute personnaly these days, but I'd be very happy if someone could centralize intel about those formats.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: casascius on November 02, 2011, 03:42:43 PM
Mine is really simple: I give a string, and sha256 of that string is the private key.

The string satisfies some trivial constraints to reject most typos without large loss of entropy.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.0.3
Post by: grondilu on November 03, 2011, 09:59:54 AM
Also I did some experimenting with openssl. Yes, openssl will occasionally generate a 31-byte private key. (it's, of course, a 32-byte private key that happens to start with 00, and the leading zero truncated).

There is indeed a problem when the key is below 8^31. Notice that in even more rare cases, it can also be below 2^30, 2^29, etc... Also, as you mentioned earlier, the key could have 33 bytes when the last byte is above 0x80.

It is quite a pain in the ass to deal with thoses cases and ensure that the key is 32 bytes long. Trial and error in bitlotto's code works, but it's kind of ugly.

I think a solution would be to use an arithmetic sum:  V*2^256 + K, where V is the version number and K is the private key.

Anyway, I rewrote my set of functions. I tried to suppress any unecessary dependancies (no more xxl, nor tac.) I use Perl to do binary packing, as Perl is installed on most unix plateform.

Here they are:


Code:
#!/bin/bash
# Satoshi Nakamoto's Base58 encoding
#
# requires dc, the unix desktop calculator (which should be included in the
# 'bc' package)

declare -a base58=({1..9} {A..H} {J..N} {P..Z} {a..k} {m..z})
unset dcr; for i in {0..57}; do dcr+="${i}s${base58[i]}"; done   # dc registers

decodeBase58() {
  dc -e "$dcr 16o0$(sed 's/./ 58*l&+/g' <<<$1)p" |
  while read l; do echo -n "$l"; done
}

encodeBase58() {
  dc -e "16i ${1^^} [3A ~r d0<x]dsxx +f" |
  while read n; do echo -n "${base58[n]}"; done
}

checksum() {
  perl -we "print pack 'H*', '$1'" |
  openssl dgst -sha256 -binary |
  openssl dgst -sha256 -binary |
  perl -we "print unpack 'H8', join '', <>"
}

checkBitcoinAddress() {
  if [[ "$1" =~ ^[$(IFS= ; echo "${base58[*]}")]+$ ]]
  then
# a bitcoin address should be 25 bytes long:
# - 20 bytes for the hash160 (16/8 = 2, right?);
# - 1 byte for the version number;
# - 4 bytes for the checksum.
# shorter addresses can only occur with standard 00 version number
# and should be zero padded
# Of course, in hex you must mutiply these numbers by 2
# to get the number of nybbles (hex digits)
h="$(printf "%50s" $(decodeBase58 "$1")| sed 's/ /0/g')"
    checksum "${h::${#h}-8}" |
    grep -qi "^${h: -8}$"
  else return 2
  fi
}

hash160() {
  openssl dgst -sha256 -binary |
  openssl dgst -rmd160 -binary |
  perl -we "print unpack 'H*', <>"
}

hashToAddress() {
  local version="${2:-00}" size="${3:-160}"
  local x="$(dc -e "${size}ss 16dio 2 ls^ ${version^^}* ${1^^}+p")"
  printf "%34s\n" "$(encodeBase58 "$x$(checksum "$x")")" |
  sed -r "s/ +/1/"
}

publicKeyToAddress() {
  hashToAddress "$(
  openssl ec -pubin -pubout -outform DER 2>&- |
  tail -c 65 |
  hash160
  )" "${1:-00}"
}

privateKeyToWIF() {
  hashToAddress "$(
  openssl ec -text -noout 2>&- |
  sed -n '3,5s/[: ]//gp' |
  while read l; do echo -n "$l"; done
  )" 80 256
}

WIFtoDER() {
  printf "%64s\n" "$(dc -e "16dio $(decodeBase58 $1) 100 4^ / 80 100 20^*-p")" |
  sed 's/ /0/g'
}

vanityAddress() {
  local addr priv
  while ! grep -qi "${1:-1}" <<< "$addr"
  do
priv="$(openssl ecparam -genkey -name secp256k1 2>&-)"
addr="$(openssl ec -pubout 2>&- <<<"$priv" | publicKeyToAddress)"
WIF="$(privateKeyToWIF <<<"$priv")"
  done
  echo "$addr, $WIF"
  echo "$priv"
}


PS. I forgot to mention that if you want to use some random typed data to seed the random number generator,
you can do something like:

Code:
read -p 'Type in some random characters:' random
openssl ecparam -genkey -name secp256k1 -rand <(echo $random)


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: btc_artist on November 18, 2011, 11:34:25 PM
Watching.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: cjp on November 22, 2011, 07:53:23 PM
I like this. Thanks.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: grondilu on June 08, 2012, 12:23:49 PM
I wrote a pure dc elliptic curve library:

Code:
I16iFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2Fsp
7sb0sa483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798lp*+sG
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141soilpsm
[[_1*lm1-*lm%q]Std0>tlm%Lts#]s%[_1*l%x]s_[+l%x]s+[*l%x]s*[-l%x]s-[Smdd
l%x-lm/rl%xLms#]s~[l%xsclmsd1su0sv0sr1st[q]SQ[lc0=Qldlcl~xlcsdscsqlrlq
lu*-ltlqlv*-lulvstsrsvsulXx]dSXxLXs#LQs#lrl%x]sI[lpSm[+q]S0d0=0lpl~xsy
dsxd*3*lal+x2ly*lIx*l%xdsld*2lx*l-xdlxrl-xlll*xlyl-xrlp*+Lms#L0s#]sD[lp
Sm[+q]S0[2;AlDxq]Sdd0=0rd0=0d2:Alp~1:A0:Ad2:Blp~1:B0:B2;A2;B=d[0q]Sx2;A
0;B1;Bl_xrlm*+=x0;A0;Bl-xlIxdsi1;A1;Bl-xl*xdsld*0;Al-x0;Bl-xd0;Arl-xll
l*x1;Al-xrlp*+L0s#Lds#Lxs#Lms#]sA[rs.0r[rl.lAxr]SP[q]sQ[d0!<Qd2%1=P2/l.
lDxs.lLx]dSLxs#LPs#LQs#]sM

I wrote this because it was fun, and because I wanted to rely on openssl as little as possible.

With this library you can do addition, doubling and multiplication with points on secp256k1.

For example, if you want to compute 10^100 times the subgroup generator, i.e. the bitcoin private key whose integer value is 10^100, you can type (assuming the above code is in a "ec.dc" file):

Code:
$ dc -f ec.dc -e '10 100^ lG lMx lm~f'

I'm planning to use this to do a few cool things, including a simple function for creating a vanity address from a public key.  This will allow people to create some for others without needing trust.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: casascius on June 09, 2012, 05:20:41 AM
Jeez, I can't believe the code is so small.

I wish I understood it better.  I would really like to offer a VeriFone-terminal program that generated Bitcoin addresses and spit out paper wallets.  My biggest barrier is the lack of desire to start chopping up OpenSSL and figuring out what to carve out to feed to its dinosaur compiler.

If I had a function that could just do:  privkey_to_bitcoin_address(char[32] privkey, char* bitcoinaddressbuffer) that had no external dependencies, I'd have this built in a heartbeat.  It's a 32 bit platform.

Then people could go on eBay and get the cheap old credit card machines (look at how much an Omni 3200 or a Vx510LE costs) and print paper wallets.  Flashing the terminal is easy, I have a VeriFone flashing server (self-made), just hook the terminal's dialup modem to an analog phone line and I'll give a phone number where you just point the terminal and it downloads the code and flashes it.

Such code would soon evolve into a hardware wallet that could show on-screen confirmation and communicate signed transactions to a host computer via rs232.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: grondilu on June 09, 2012, 09:37:16 AM
Jeez, I can't believe the code is so small.

I wish I understood it better.

Well, to be honnest I crunched it to show off.

Here is the more verbose version:
Code:
# Elliptic curve algebra and cryptography using dc
#
# Curve parameters are assumed to be stored in registers p, a, b.
# Subgroup generator is stored in register G with a base-p encoding.
# The order of the subgroup is in register o.

# secp256k1
I16i
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F sp
0000000000000000000000000000000000000000000000000000000000000007 sb
0000000000000000000000000000000000000000000000000000000000000000 sa

79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8 rlp*+ sG
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 so
i

# Most macros assume the modulus is in register 'm'.
# By default m is a copy of p.
lpsm

[ # a modulo that behaves well with negative numbers ( x -- y )
    [_1*lm1-*lm%q]St
    d0>t lm%
    Lts#
]s%

# negation
[_1*l%x]s_

# modular arithmetics ( x y -- z )
[+l%x]s+ [*l%x]s* [-l%x]s-
[Smddl%x-lm/rl%xLms#]s~ [rd0>_rlm|]s|

[ # modular inverse ( x -- y )
    l%xsc lmsd
    1su 0sv  0sr 1st
    [q]SQ
    [
        lc0=Q
ldlcl~x lc                   sd sc sq
lrlqlu*- ltlqlv*- lu lv    st sr sv su
lXx
    ]dSXx
    LXs#LQs#
    lr l%x
]sI

[ # doubling ( A -- B )
    lpSm
    [+q]S0 d0=0
    lpl~x
    sy dsx
    d*3* la l+x
    2ly* lIx
    * l%x dsl

    d* 2lx * l-x
    d lx r l-x ll l*x ly l-x
    rlp*+
    Lms# L0s#
]sD

[ # addition ( A B -- C )
    lpSm
    [+q]S0
    [2;A lDx q]Sd
    d0=0 rd0=0
    d2:A lp~ 1:A 0:A
    d2:B lp~ 1:B 0:B
    2;A 2;B =d
    [0q]Sx 2;A 0;B 1;B l_x rlm*+  =x
    0;A 0;B l-x lIx dsi
    1;A 1;B l-x l*x dsl
    d* 0;A l-x 0;B l-x d
    0;A r l-x ll l*x 1;A l-x
    rlp*+
    L0s# Lds# Lxs# Lms#
]sA

# multiplication ( A n -- B )
[
    rs.0r
    [r l. lAx r]SP
    [q]sQ
    [
        d0!<Q
d2%1=P
2/
l. lDx s.
lLx
    ]dSLx
    s# LPs# LQs#
]sM

Quote
I would really like to offer a VeriFone-terminal program that generated Bitcoin addresses and spit out paper wallets.  My biggest barrier is the lack of desire to start chopping up OpenSSL and figuring out what to carve out to feed to its dinosaur compiler.

If I had a function that could just do:  privkey_to_bitcoin_address(char[32] privkey, char* bitcoinaddressbuffer) that had no external dependencies, I'd have this built in a heartbeat.  It's a 32 bit platform.

This should not be too difficult.  Couldn't you just compile one statically??


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: bitcoindaddy on August 15, 2012, 05:54:44 PM
There are a couple of spelling mistakes in the script:

"peice of paper" should be "piece of paper"

and

"will lesson the security of these keys" should be "will lessen the security of these keys"


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: Scrat Acorns on December 18, 2012, 02:50:52 PM
I hope my post isn't considered a necro but this method needs more exposure and most importantly more scrutinization (is that even a word?) by people who know the internals of bitcoin.

There should always be a secure way to create addresses offline with readily available tools in a standard linux distro. Since the privkey is generated by a single openssl command, you know 100% that it hasn't been tampered with. As opposed to trusting a website and downloading a program from it.

Am I too paranoid?


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: casascius on December 18, 2012, 03:08:52 PM
There's lots of ways to generate bitcoin addresses and you just need to pick the one that works best for you.  If using this script gives you the right mix of comfort and convenience, then this is the method for you.

It will be nice when generating bitcoin addresses is a feature as standard as creating a new text file or subdirectory.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: Scrat Acorns on December 18, 2012, 03:23:17 PM
There's lots of ways to generate bitcoin addresses and you just need to pick the one that works best for you.  If using this script gives you the right mix of comfort and convenience, then this is the method for you.

It will be nice when generating bitcoin addresses is a feature as standard as creating a new text file or subdirectory.
I'm particularly worried by the "recreate key if hexsize != 64" deal. Won't that effectively reduce the keyspace? I know it won't be much but still.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: casascius on December 18, 2012, 03:35:51 PM
There's lots of ways to generate bitcoin addresses and you just need to pick the one that works best for you.  If using this script gives you the right mix of comfort and convenience, then this is the method for you.

It will be nice when generating bitcoin addresses is a feature as standard as creating a new text file or subdirectory.
I'm particularly worried by the "recreate key if hexsize != 64" deal. Won't that effectively reduce the keyspace? I know it won't be much but still.

By about one bit.  It's an ugly hack so the script doesn't have to deal with signed numbers or leading zeros but won't reduce your security in any practical sense.

Bitcoin addresses themselves are only 160 bits, so going from 256 to 255 bits of private key is no big deal.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: salfter on January 08, 2013, 07:03:26 PM
Looks like someone already necro'd this thread so I won't have to.  ;D

I stumbled across this thread while looking for something faster than pywallet to convert hexkeys to WIF privkeys and addresses... haven't quite gotten it running yet as it appears to depend on vim, which I don't usually have installed (vim provides xxd) just got it running after installing vim. It might be worth noting in the OP that it needs vim (and openssl, but I already had that) to run.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: Red Emerald on January 08, 2013, 08:18:34 PM
Looks like someone already necro'd this thread so I won't have to.  ;D

I stumbled across this thread while looking for something faster than pywallet to convert hexkeys to WIF privkeys and addresses... haven't quite gotten it running yet as it appears to depend on vim, which I don't usually have installed (vim provides xxd) just got it running after installing vim. It might be worth noting in the OP that it needs vim (and openssl, but I already had that) to run.
Why would this depend on vim?  I don't see vim called anywhere in the script.


Title: Re: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1
Post by: grondilu on January 08, 2013, 08:20:38 PM
Looks like someone already necro'd this thread so I won't have to.  ;D

I stumbled across this thread while looking for something faster than pywallet to convert hexkeys to WIF privkeys and addresses... haven't quite gotten it running yet as it appears to depend on vim, which I don't usually have installed (vim provides xxd) just got it running after installing vim. It might be worth noting in the OP that it needs vim (and openssl, but I already had that) to run.
Why would this depend on vim?  I don't see vim called anywhere in the script.

xxd is part of the Vim package.   To avoid this dependency you can use perl as mentioned earlier in this thread.

To spare you the hassle of looking for it:
Code:
checksum() {
    perl -we "print pack 'H*', '$1'" |
    openssl dgst -sha256 -binary |
    openssl dgst -sha256 -binary |
    perl -we "print unpack 'H8', join '', <>"
}