Bitcoin Forum
December 13, 2024, 09:29:15 PM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 [2] 3 »  All
  Print  
Author Topic: Bitcoin Off-The-Grid (BOTG): secure savings script v0.1.1  (Read 13267 times)
Rogue Star
Member
**
Offline Offline

Activity: 89
Merit: 10


View Profile
June 30, 2011, 03:13:22 AM
 #21

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!

you can donate to me for whatever reason at: 18xbnjDDXxgcvRzv5k2vmrKQHWDjYsBDCf
casascius
Mike Caldwell
VIP
Legendary
*
Offline Offline

Activity: 1386
Merit: 1140


The Casascius 1oz 10BTC Silver Round (w/ Gold B)


View Profile WWW
June 30, 2011, 03:15:44 AM
 #22

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.

Companies claiming they got hacked and lost your coins sounds like fraud so perfect it could be called fashionable.  I never believe them.  If I ever experience the misfortune of a real intrusion, I declare I have been honest about the way I have managed the keys in Casascius Coins.  I maintain no ability to recover or reproduce the keys, not even under limitless duress or total intrusion.  Remember that trusting strangers with your coins without any recourse is, as a matter of principle, not a best practice.  Don't keep coins online. Use paper or hardware wallets instead.
ben-abuya
Sr. Member
****
Offline Offline

Activity: 323
Merit: 250



View Profile WWW
June 30, 2011, 10:17:19 AM
 #23

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.

http://lamassubtc.com/
Lamassu Bitcoin Ventures
bitlotto (OP)
Hero Member
*****
Offline Offline

Activity: 672
Merit: 500


BitLotto - best odds + best payouts + cheat-proof


View Profile WWW
June 30, 2011, 12:31:23 PM
 #24

Just so people know, I've tested another 500 generated keys and they all worked too when imported!  Grin

*Next Draw Feb 1*  BitLotto: monthly raffle (0.25 BTC per ticket) Completely transparent and impossible to manipulate who wins. TOR
TOR2WEB
Donations to: 1JQdiQsjhV2uJ4Y8HFtdqteJsZhv835a8J are appreciated.
joan
Jr. Member
*
Offline Offline

Activity: 56
Merit: 1



View Profile
June 30, 2011, 02:55:32 PM
Last edit: June 30, 2011, 03:06:16 PM by joan
 #25

I have imported and redeemed successfully the following "vanity" privkey generated by casascius.
Code:
5HtNFUCKiNGPiECEoFGoDDaMNCoCKSuCKiNGSHiT3Viwnu6QQby
1Kv4AcDNkRjhAYvPo3w8RnDw8Jb6Pgq579
0.05 BTC
I Posted a related challenge for when the person makes a typo while writing the privkey down.
bcearl
Full Member
***
Offline Offline

Activity: 168
Merit: 103



View Profile
July 03, 2011, 05:54:28 PM
 #26

Looks like a good idea to me, I will take a closer look when I find some time.

Misspelling protects against dictionary attacks NOT
bitlotto (OP)
Hero Member
*****
Offline Offline

Activity: 672
Merit: 500


BitLotto - best odds + best payouts + cheat-proof


View Profile WWW
July 03, 2011, 06:15:37 PM
 #27

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.

*Next Draw Feb 1*  BitLotto: monthly raffle (0.25 BTC per ticket) Completely transparent and impossible to manipulate who wins. TOR
TOR2WEB
Donations to: 1JQdiQsjhV2uJ4Y8HFtdqteJsZhv835a8J are appreciated.
Ente
Legendary
*
Offline Offline

Activity: 2126
Merit: 1001



View Profile
August 05, 2011, 08:04:56 PM
 #28

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
Ente
Legendary
*
Offline Offline

Activity: 2126
Merit: 1001



View Profile
August 06, 2011, 04:32:55 PM
Last edit: August 06, 2011, 06:24:36 PM by Ente
 #29

..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
davout
Legendary
*
Offline Offline

Activity: 1372
Merit: 1008


1davout


View Profile WWW
August 17, 2011, 08:31:55 AM
 #30

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.

Red Emerald
Hero Member
*****
Offline Offline

Activity: 742
Merit: 500



View Profile WWW
September 26, 2011, 10:24:29 PM
Last edit: September 26, 2011, 10:47:34 PM by Red Emerald
 #31

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

grondilu
Legendary
*
Offline Offline

Activity: 1288
Merit: 1080


View Profile
November 02, 2011, 03:22:18 PM
 #32

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.

casascius
Mike Caldwell
VIP
Legendary
*
Offline Offline

Activity: 1386
Merit: 1140


The Casascius 1oz 10BTC Silver Round (w/ Gold B)


View Profile WWW
November 02, 2011, 03:42:43 PM
 #33

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.

Companies claiming they got hacked and lost your coins sounds like fraud so perfect it could be called fashionable.  I never believe them.  If I ever experience the misfortune of a real intrusion, I declare I have been honest about the way I have managed the keys in Casascius Coins.  I maintain no ability to recover or reproduce the keys, not even under limitless duress or total intrusion.  Remember that trusting strangers with your coins without any recourse is, as a matter of principle, not a best practice.  Don't keep coins online. Use paper or hardware wallets instead.
grondilu
Legendary
*
Offline Offline

Activity: 1288
Merit: 1080


View Profile
November 03, 2011, 09:59:54 AM
Last edit: November 23, 2011, 09:34:42 AM by grondilu
 #34

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)

btc_artist
Full Member
***
Offline Offline

Activity: 154
Merit: 102

Bitcoin!


View Profile WWW
November 18, 2011, 11:34:25 PM
 #35

Watching.

BTC: 1CDCLDBHbAzHyYUkk1wYHPYmrtDZNhk8zf
LTC: LMS7SqZJnqzxo76iDSEua33WCyYZdjaQoE
cjp
Full Member
***
Offline Offline

Activity: 210
Merit: 124



View Profile WWW
November 22, 2011, 07:53:23 PM
 #36

I like this. Thanks.

Donate to: 1KNgGhVJx4yKupWicMenyg6SLoS68nA6S8
http://cornwarecjp.github.io/amiko-pay/
grondilu
Legendary
*
Offline Offline

Activity: 1288
Merit: 1080


View Profile
June 08, 2012, 12:23:49 PM
 #37

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.

casascius
Mike Caldwell
VIP
Legendary
*
Offline Offline

Activity: 1386
Merit: 1140


The Casascius 1oz 10BTC Silver Round (w/ Gold B)


View Profile WWW
June 09, 2012, 05:20:41 AM
 #38

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.

Companies claiming they got hacked and lost your coins sounds like fraud so perfect it could be called fashionable.  I never believe them.  If I ever experience the misfortune of a real intrusion, I declare I have been honest about the way I have managed the keys in Casascius Coins.  I maintain no ability to recover or reproduce the keys, not even under limitless duress or total intrusion.  Remember that trusting strangers with your coins without any recourse is, as a matter of principle, not a best practice.  Don't keep coins online. Use paper or hardware wallets instead.
grondilu
Legendary
*
Offline Offline

Activity: 1288
Merit: 1080


View Profile
June 09, 2012, 09:37:16 AM
 #39

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??

bitcoindaddy
Hero Member
*****
Offline Offline

Activity: 481
Merit: 500


View Profile
August 15, 2012, 05:54:44 PM
 #40

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"
Pages: « 1 [2] 3 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!