Pages:
Author

Topic: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1 - page 3. (Read 13277 times)

vip
Activity: 1386
Merit: 1140
The Casascius 1oz 10BTC Silver Round (w/ Gold B)
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!!"


member
Activity: 89
Merit: 10
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.
hero member
Activity: 672
Merit: 500
BitLotto - best odds + best payouts + cheat-proof
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  Embarrassed 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....
member
Activity: 89
Merit: 10
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.
hero member
Activity: 672
Merit: 500
BitLotto - best odds + best payouts + cheat-proof
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.
sr. member
Activity: 247
Merit: 250
Cosmic Cubist
Neato.  I like it.  Post your address and I'm sure someone will give you a small donation to test it.
hero member
Activity: 672
Merit: 500
BitLotto - best odds + best payouts + cheat-proof
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
Pages:
Jump to: