Bitcoin Forum
May 09, 2024, 02:41:27 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: 1 2 3 [All]
  Print  
Author Topic: ANN: Python paper wallet generator with strong randomness  (Read 16879 times)
deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
December 07, 2013, 04:10:46 PM
Last edit: December 04, 2017, 11:13:19 PM by deepceleron
Merited by ABCbits (7)
 #1

Preface

Bitcoin requires cryptographically strong random numbers behind its ECC math when generating addresses and creating transactions. Bad math = stolen bitcoins. Important address keys used for savings must also be kept secure, ideally kept off Internet-connected computers that may be hacked.  Bad procedures = stolen bitcoins.

What's A Paper Wallet?

"Paper wallet" is a term often used for what is better called a "cold storage address". You create a hard-copy of a new address and its private key, unconnected to your normal daily-use wallet, and write it down, print it, or even stamp it into a block of metal. Money can be sent to this address as long-term savings, and copies can be secured in safe-deposit boxes, with relatives, etc. To redeem funds, you later spend the entire balance after importing the private key into wallet software, and disuse the address.

Bitcoin Paper Wallet Address Creator - paperwal.py

Where do you get the address for your paper wallet? Taking one from your everyday Bitcoin wallet software defeats the security you desire, as the private key to spend the coins is saved not only to the wallet on the hard drive, but also potentially to hard drive swap space or temporary files. Naive Bitcoin software also may call poorly-implemented, faulty, or even backdoored OS crypto libraries, creating less-than ideal pseudo-random numbers.

To address this need, I made a paper wallet generator, a single script written for Python 2.7 and requiring no additional packages, that will let you type keypresses to create the entropy necessary to generate a strong address and private key pair. It can be run on a disconnected-from-the-Internet computer to safely create a single address for paper wallet use. It employs several techniques and entropy sources besides simply the characters you enter, discussed later in thread. The actual code you run is readable to allow audit and review (although it's a bit complex).

Usage

The address generator uses Python, an interpreted script language. Linux and Mac OS usually have the required Python 2.7 language interpreter pre-installed (Ubuntu 16.04, April 2016, is the first distro to switch the default interpreter to Python 3). Windows would require installation of 2.7.x from python.org - but you already can guess that Windows is not recommended.

With the Python interpreter installed, a double-click on the downloaded script or typing "paperwal" is generally enough to launch the generator. If not, you can specify the Python interpreter in the path with the command "python paperwal.py".

Some command-line options are available for more specialized use:

>paperwal.py -h
Usage: paperwal [options]

Options:
  -h, --help            show this help message and exit
  -e, --encrypted       create BIP38-encrypted privkey (takes a LONG time)
  -v, --validate        enable extensive system tests for entropy
  -s, --silent          disable most console output except address
  -l, --loop            restart instead of exit
  -p, --nopause         disable the pause before exiting
  -d, --doublecalc      calculate twice and test results
  -z JUST A HELPFUL HINT
                        try ctrl-tab to abort the program

  Warning:
    If you use this option, you should supply REAL randomly generated
    entropy.It is probably a good idea not to reuse a seed.

    -r ENTROPY, --entropy=ENTROPY
                        random seed instead of keypresses, 64+ characters



Generate Address On A Secure Platform

You can make your address hacker-proof - by never storing it on a computer. This is commonly done by rebooting your computer to the "clean environment" of a standard Linux live CD. You can even be paranoid and disconnect your hard drive.

Here is an example procedure using Alpine Linux, a small security-focused distro and live CD that starts to a shell prompt. We will use the Internet to install Python and download the script, but then you can disconnect the network cable:

logon: root (no password)
>setup-alpine (and press enter for just about every option, including no hard drive)
>apk add python

Download script from my site:

>wget http://we.lovebitco.in/paperwal.py

Generate addresses:

Now disconnect internet to be secure, verify the file hash, run the script, pound on the keyboard when prompted, and see the output:

>sha256sum paperwal.py
9a88d46ad2ea6d19cb3940dc396be9f7cbe29186150d57440d26005c628597ad *paperwal.py
  (update 2014-01-03 v1.2a)

>python paperwal.py
Press keys to generate secure address....  OK

Bitcoin Address:
 1Cz7oXpaYycVeAoX1LXqniYGTzazjA7Zm9
Private Key:
 KwuZP7E2Zq5WmzcvZyLTHMerZKmWtzYbnDaEUCg9BWJ5uUU8qwRe


Note: the generator only generates compressed addresses (used by Bitcoin-Qt since v0.6.0). The private key is in "Wallet Import Format"  Be sure your wallet-of-choice can import some test private keys.


Password-Protected Paper Wallet

Someone finding your paper wallet printout would be able to to spend your bitcoins. Bitcoin Improvement Proposal BIP0038 adds a password feature to protect the private key, making it impossible to spend without knowing or cracking the password. The encryption is purposefully made very hard to brute-force - it takes about ten minutes for the address generator to encrypt a key using plain Python. When using the generator's --encrypted option, the private key is not displayed unencrypted.

BIP38 private key encryption is a recent feature developed separately from Bitcoin Core; most wallets don't have a built-in decrypting feature. One way to decrypt is by downloading the http://bitaddress.org HTML page and using the javascript-based utilities in it offline to reveal the true private key.

This address generator allows you to type passphrases that other utilities might not process correctly, such as typing only spaces. Be sure you can decrypt private keys generated with your passphrase before using this feature.


Example use with encryption:



>paperwal.exe -e
 Enter your wallet passphrase (will not appear).....*
 Re-enter to verify your wallet passphrase.....*

 Show your passphrase before continuing? (y/n)
   Passphrase: (456456)
    (counter):  123456

Press keys to generate secure address....  OK

Calculating encrypted private key...
stage 1 of 8...
stage 2 of 8...
stage 3 of 8...
stage 4 of 8...
stage 5 of 8...
stage 6 of 8...
stage 7 of 8...
stage 8 of 8...


Press "Enter" to close


Other stuff

I'll leave you the headache to figure out printing from your live CD.

Download Links

http://we.lovebitco.in/paperwal.py  (35kB) Python 2.7 script, no other libraries needed
sha256: 9a88d46ad2ea6d19cb3940dc396be9f7cbe29186150d57440d26005c628597ad *paperwal.py
md5: 4d26d19b041f1f8f2ba29d1de537579f *paperwal.py

http://we.lovebitco.in/paperwal.exe (4MB) Windows exe created with py2exe, Python 2.7.6 32 bit
sha256: 31af7bec9aa68c8a32ce09de42f16cf58868c6d6a69a71c701ae52efba842076 *paperwal.exe
md5: e2e5d1d648ccc1cabebd745a160e5277 *paperwal.exe

(Windows users - don't use the binary exe for more than just demonstration; install Python for yourself: http://www.python.org/download/ - the script is reviewable, EXEs are not; don't blindly trust EXEs from the Internet with your bitcoins.)
No Gods or Kings. Only Bitcoin
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1715265687
Hero Member
*
Offline Offline

Posts: 1715265687

View Profile Personal Message (Offline)

Ignore
1715265687
Reply with quote  #2

1715265687
Report to moderator
1715265687
Hero Member
*
Offline Offline

Posts: 1715265687

View Profile Personal Message (Offline)

Ignore
1715265687
Reply with quote  #2

1715265687
Report to moderator
glitch003
Full Member
***
Offline Offline

Activity: 219
Merit: 101


View Profile
December 07, 2013, 06:26:02 PM
 #2

Hi deepceleron,

I’m the guy behind Piper.  This is a cool alternative to standard entropy collection, however, Piper uses a hardware random number generator which collects entropy from thermal gradients.  It does use a vanitygen binary, but that's because it supports setting your own address prefix and generating vanity keys.  But, the source for vanitygen is included and you can easily compile it yourself and compare the MD5 of the binary to the one used by the Piper software. 

RNGD runs on Piper and continuously feeds entropy into the /dev/random entropy pool from the hardware random number generator.  Vanitygen is called with parameters to tell it to use /dev/random instead of the default which is /dev/urandom.  Vanitygen is widely accepted in the bitcoin community as a good tool to generate safe keypairs and is used by hundreds of people everyday. 

So my point is, that the key generation method used by Piper is perfectly safe and the same solution widely used in the bitcoin community everyday.  I put a lot of thought into it and took community advice into account to make sure that the solution Piper uses is secure and safe.  I store my own coins with an unmodified Piper and I feel totally safe doing so.

That said, this is a really cool alternative to the standard entropy collection methods and if some community members can do a code audit on it and give it a thumbs up, I'm happy to include it on the base Piper SD card image or even eventually integrate it with the Piper GUI software.  I love giving people options, and this is a really cool one, especially for people who mistrust the OS random number generator.

Finally, I know you mentioned adding BIP0038 to this script.  Here's a python implementation of BIP0038 which should get you quite a bit closer to that goal.  I believe it could be added to your single file since it's only about 40 lines: https://github.com/zimage/python-bitcoinlib/blob/e9506aba6d53ad5bf760d67815d711a1c55b2557/bitcoin/bip38.py

That BIP0038 implementation has also been looked over by jgzarik in a pull request for the python-bitcoinlib and he doesn't seem to have any issues with it: https://github.com/jgarzik/python-bitcoinlib/pull/5

Thanks for making this really cool script.  I love creative ways of generating entropy!
deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
December 07, 2013, 07:35:52 PM
 #3

Hi deepceleron,

I’m the guy behind Piper.  This is a cool alternative to standard entropy collection, however, Piper uses a hardware random number generator which collects entropy from thermal gradients...

Finally, I know you mentioned adding BIP0038 to this script.  Here's a python implementation of BIP0038 which should get you quite a bit closer to that goal.  I believe it could be added to your single file since it's only about 40 lines: https://github.com/zimage/python-bitcoinlib/blob/e9506aba6d53ad5bf760d67815d711a1c55b2557/bitcoin/bip38.py
This is what I find untenable in the above code, not workable for a "run this script on your vanilla live CD":

import Crypto.Cipher.AES as AES
import scrypt

...
and the c behind them. A bounty got us a JavaScript native decoder, Python-drop-in-a-py libraries along the same lines would be awesome.

Thanks for your response. I called out the Piper because the source archive I found just has a vanitygen call; I don't have a device to dissect what you load them up with. When I examined deep into vanitygen previously, it was ultimately the OpenSSL build options that determined fips140 or OS entropy source, and such. The Pi has a HRNG, but it is low bit rate and it can't be examined for NSA bias insertion or such, but it is necessary with an unplugged environment-blind device. My script is really a response to the brainwallets and dice-rollers.

I wrote the methods imagining it being run on a device with broken deterministic random, and check for a working precision clock before letting the user proceed. I spent probably more time than needed examining the output range, bias, and reasoning behind every line of math, that even if urandom returns 0's and you skip the user input, you still get an unrepeatable 256 bit entropy key. Also so users can see inside the black box.

I get 512bit user entropy based on keypress times, with keypress values also used *8 (but not an integral component). I don't get the strict "time" between keypresses, there's a time->hash-driven variable length loop that runs after each keypress before time-poll to make CPU speed and system interrupts a factor, then I convolute the time. I seed the OS urandom with this user entropy and make a SHA256 hashed OS-based random key whitened with python's Mersenne Twister from oracle back to random bit depth. That's good enough, but then I re-seed the OS entropy pool every 1024 bits with time and user-based entropy plus hashes, then I XOR with a differently-obfuscated SHA2 of system random,  and then I XOR with processor-time based and clock based time sources stretched to put 512bits of noise in the hash. Repeat 100 times. The code is easier to read than the explanation.

To bad the piper doesn't have a button other than print, maybe I'd hack mine so the user keys Morse code on it until they are satisfied it's using their input too?
glitch003
Full Member
***
Offline Offline

Activity: 219
Merit: 101


View Profile
December 07, 2013, 08:05:35 PM
Last edit: December 07, 2013, 08:31:00 PM by glitch003
 #4

This is what I find untenable in the above code, not workable for a "run this script on your vanilla live CD":

import Crypto.Cipher.AES as AES
import scrypt

...
and the c behind them. A bounty got us a JavaScript native decoder, Python-drop-in-a-py libraries along the same lines would be awesome.

Oh good point, I overlooked that detail.  I understand your thoughts on this and fully agree.

Thanks for your response. I called out the Piper because the source archive I found just has a vanitygen call; I don't have a device to dissect what you load them up with. When I examined deep into vanitygen previously, it was ultimately the OpenSSL build options that determined fips140 or OS entropy source, and such. The Pi has a HRNG, but it is low bit rate and it can't be examined for NSA bias insertion or such, but it is necessary with an unplugged environment-blind device. My script is really a response to the brainwallets and dice-rollers.
I totally understand and I agree with the need for your script.  I just want to point out that I have indeed tested /dev/random being fed by the HRNG on Piper with all 26 of the "good" dieharder tests of randomness and it passed all of them.  So at least we can be confident that the randomness is statistically sound and we're not just blindly trusting it.



I wrote the methods imagining it being run on a device with broken deterministic random, and check for a working precision clock before letting the user proceed. I spent probably more time than needed examining the output range, bias, and reasoning behind every line of math, that even if urandom returns 0's and you skip the user input, you still get an unrepeatable 256 bit entropy key. Also so users can see inside the black box.


This makes perfect sense and having the ability to still generate secure keys on a device with a broken rng is an insanely cool idea.  

I get 512bit user entropy based on keypress times, with keypress values also used *8 (but not an integral component). I don't get the strict "time" between keypresses, there's a time->hash-driven variable length loop that runs after each keypress before time-poll to make CPU speed and system interrupts a factor, then I convolute the time. I seed the OS urandom with this user entropy and make a SHA256 hashed OS-based random key whitened with python's Mersenne Twister from oracle back to random bit depth. That's good enough, but then I re-seed the OS entropy pool every 1024 bits with time and user-based entropy plus hashes, then I XOR with a differently-obfuscated SHA2 of system random,  and then I XOR with processor-time based and clock based time sources stretched to put 512bits of noise in the hash. Repeat 100 times. The code is easier to read than the explanation.

Wow, it sounds like you put a lot of effort into making sure this is a rock solid implementation.  Thank you for taking the time to do this!

To bad the piper doesn't have a button other than print, maybe I'd hack mine so the user keys Morse code on it until they are satisfied it's using their input too?

The way the code on Piper is written (all python btw), you could easily hack it to support morse code on it until the user does something like holds the button down for 10 seconds to indicate that they are satisfied.  Piper does also have a bunch of spare GPIO pins so you could also add your own button(s), or repurpose the remember/forget switch to be used for the morse code input.  That would require a bit of soldering though.  

Finally, don't forget that Piper is running a full linux distro and also has an HDMI port and a USB port so a user could hook up a keyboard and use your unmodified script if they like.  I'm thinking about putting a button in the Piper GUI that essentially just launches your script, because combining all those forms of entropy with the whitening and everything is a really cool idea.


Edit: After looking over your code some more, it's clear that you put a ton of effort into this.  I donated ~$10 in BTC to your forum address to say thank you.
deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
December 10, 2013, 06:22:10 PM
Last edit: December 10, 2013, 06:39:43 PM by deepceleron
 #5

Updated to v1.1:
-removed all floating point math; floating point times are now retrieved as raw hex bits.
-simplified & robust time -> entropy functions
-interface cleanup
-partition library use into single methods needing them
-only OS random class is used, no python internal random
-no address calculation changes

(previous version at http://we.lovebitco.in/paperwal-v10.py)
Dabs
Legendary
*
Offline Offline

Activity: 3416
Merit: 1912


The Concierge of Crypto


View Profile
December 11, 2013, 06:15:17 AM
 #6

Got an .exe (for windows)? Or does that go against the philosophy? I liked your dice2key one.

whiskers75
Hero Member
*****
Offline Offline

Activity: 658
Merit: 502


Doesn't use these forums that often.


View Profile
December 11, 2013, 06:40:08 AM
 #7

Nice tool! I could mirror this on http://whiskers75.com if you like Wink

Got an .exe (for windows)? Or does that go against the philosophy? I liked your dice2key one.
The idea is that you don't use the most hackable OS in the world to make your keys ;P

Elastic.pw Elastic - The Decentralized Supercomputer
ELASTIC ANNOUNCEMENT THREAD | ELASTIC SLACK | ELASTIC FORUM
r3wt
Hero Member
*****
Offline Offline

Activity: 686
Merit: 504


always the student, never the master.


View Profile
December 11, 2013, 06:49:24 AM
 #8

Nice tool! I could mirror this on http://whiskers75.com if you like Wink

Got an .exe (for windows)? Or does that go against the philosophy? I liked your dice2key one.
The idea is that you don't use the most hackable OS in the world to make your keys ;P

speaking of being hacked..  Tongue

My negative trust rating is reflective of a personal vendetta by someone on default trust.
Dabs
Legendary
*
Offline Offline

Activity: 3416
Merit: 1912


The Concierge of Crypto


View Profile
December 11, 2013, 07:23:50 AM
 #9

It's offline. And, he can of course publish the SHA256 of the executable as well as GPG sign it.

whiskers75
Hero Member
*****
Offline Offline

Activity: 658
Merit: 502


Doesn't use these forums that often.


View Profile
December 11, 2013, 04:17:52 PM
 #10

Nice tool! I could mirror this on http://whiskers75.com if you like Wink

Got an .exe (for windows)? Or does that go against the philosophy? I liked your dice2key one.
The idea is that you don't use the most hackable OS in the world to make your keys ;P

speaking of being hacked..  Tongue
Yes? That was in October.

Elastic.pw Elastic - The Decentralized Supercomputer
ELASTIC ANNOUNCEMENT THREAD | ELASTIC SLACK | ELASTIC FORUM
deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
December 11, 2013, 09:55:42 PM
Last edit: December 20, 2013, 08:12:33 PM by deepceleron
 #11

It's offline. And, he can of course publish the SHA256 of the executable as well as GPG sign it.
Okay, for your (dis)pleasure...

http://we.lovebitco.in/paperwal.exe (2.0MB, AMD64 exe)
SHA256: 7b9dc3b92ae7c853f0313c1498af7d9bf7d7578b3843be952e0f6e5e3c35ff5b

New Windows exe, see first post.
r3wt
Hero Member
*****
Offline Offline

Activity: 686
Merit: 504


always the student, never the master.


View Profile
December 11, 2013, 10:01:19 PM
 #12

Merry Christmas deepceleron

Code:
Status: 0/unconfirmed, broadcast through 4 nodes
Date: 12/11/2013 16:00
To: 1DCeLERonUTsTERdpUNqxKTVMmnwU6reu5
Debit: -0.015 BTC
Transaction fee: -0.0001 BTC
Net amount: -0.0151 BTC
Transaction ID: d6562633d31abe762b1af2bce88821341f8e33b87cd2369d0078f3e8afc8f28e


My negative trust rating is reflective of a personal vendetta by someone on default trust.
deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
December 11, 2013, 10:30:19 PM
 #13

I just thought of another thing I might do in the category of "stupifyingly paranoid" - recalculate the public key and addresses several times, to check that calculation was not done incorrectly due to hardware failure or gamma ray bursts or such, and print the private key to screen both before and after calculations.
Dabs
Legendary
*
Offline Offline

Activity: 3416
Merit: 1912


The Concierge of Crypto


View Profile
December 12, 2013, 01:34:22 AM
 #14

It's offline. And, he can of course publish the SHA256 of the executable as well as GPG sign it.
Okay, for your (dis)pleasure...

http://we.lovebitco.in/paperwal.exe (2.0MB, AMD64 exe)
SHA256: 7b9dc3b92ae7c853f0313c1498af7d9bf7d7578b3843be952e0f6e5e3c35ff5b

Darn it. I'm on XP (32 bit.). dice2key works by the way.

I'ma just download python and run the script that way. (But if you make a 32 bit exe, I'll grab that too.)

Since this only makes one key at a time, it's a good idea to make several calculations and show the results. You could easily have it check a few hundred times, and if any one of them is different, some gamma ray hit at that time or something.

TookDk
Legendary
*
Offline Offline

Activity: 1960
Merit: 1062


One coin to rule them all


View Profile WWW
December 12, 2013, 11:26:25 AM
 #15

Updated to v1.1:
-removed all floating point math; floating point times are now retrieved as raw hex bits.
-simplified & robust time -> entropy functions
-interface cleanup
-partition library use into single methods needing them
-only OS random class is used, no python internal random
-no address calculation changes

(previous version at http://we.lovebitco.in/paperwal-v10.py)

The script works very nicely.
Thank you so much  Cheesy

Cryptography is one of the few things you can truly trust.
TookDk
Legendary
*
Offline Offline

Activity: 1960
Merit: 1062


One coin to rule them all


View Profile WWW
December 12, 2013, 12:12:56 PM
 #16

I could not get Electrum to import the private key.
I tried the same private key with blockchain online wallet, it worked beautifully.

What method you use/recommend to redeem your private key?



 

Cryptography is one of the few things you can truly trust.
TookDk
Legendary
*
Offline Offline

Activity: 1960
Merit: 1062


One coin to rule them all


View Profile WWW
December 12, 2013, 12:15:03 PM
 #17

Do anybody know if a parser script exist that can run offline, to check that the public adr. correspond to the private adr. ?

It would be nice to double check that the private key and public key match, before you transfer a lot of BTC.
Ofcause you can redeem your private key - but then has the key been exposed.

Cryptography is one of the few things you can truly trust.
Dabs
Legendary
*
Offline Offline

Activity: 3416
Merit: 1912


The Concierge of Crypto


View Profile
December 12, 2013, 01:14:40 PM
 #18

Bitaddress running offline.
bitcoin-qt, running offline, importprivkey.

Delete securely after confirming the keys match.

Jace
Sr. Member
****
Offline Offline

Activity: 288
Merit: 251


View Profile
December 12, 2013, 01:19:32 PM
 #19

Just posted this regarding strong randomness, I guess it's relevant here as well:

What is the best way to be absolutely sure my address is random|?
Has anyone ever thought about this issue?
Same here, I am extremely paranoia about this.

Almost 100% secure: just create them as brainwallets from very long random input strings. Obviously you don't need to remember these, they're meant for cold storage so they're not actual 'brainwallets'. They're just created in the same way as brainwallets, i.e. the private keys are hashes from strings. This rules out any dependency from random generators with possible weaknesses.

When I say 'very long random input strings', I mean garbage like this: (just typing a bunch of gibberish characters)
Code:
fY72^og(fU FO!MNxTL/rwA q2kd#plv0ni40X.e4 7n7*4nv5^3u 2_14h D!IQZD6k3L7n

For this particular example, the private key would be Sha256("fY72^og(fU FO!MNxTL/rwA q2kd#plv0ni40X.e4 7n7*4nv5^3u 2_14h D!IQZD6k3L7n") = eab9498f0c866509a2ff09fa40b556776f54b78f941f36cc69bdbf7832f45473, or expressed in more common Bitcoin format: 5KbfHWM9R2AKhoAtkcTDv6agnzJoPCHZkrEnSy8t8bnVTUHJnND and its corresponding address is 1FtUbMx47zhF3AUWTWCULQzDyRJgVDV23G.

Now, to compensate that last bit of paranoia (and just in case some day an entropy weakness is discovered in Sha256 or something), I took this one step further, and created the private keys for my 'big savings' addresses as three xorred hashes:
(1) Some generated (pseudo?)random private key (using bitcoind or bitaddress.org or whatever)
(2) The Sha256 hash of some long random garbage string
(3) The Sha3-256 hash of some different long random garbage string

So for example:
(1) = 5K2F4Ng3ZYx9s98yEj1ukm1boGEHrAt5rMxXy2cnRdMuQtgTVE7 = 9ed845749f418efc834f1b9b5fd0c1765e7ace2177153a59dc818d6ac5df6232
(2) = Sha256("wP7fB2-fo#90wZ7d 4p6.Z1Ug5r H!0tI6*gp7!zcn)V bw4!Qib") = 7220f93d3a8059d19a3a1be4a2e1c3294185ffcae61aece0d02d73d43f9840d2
(3) = Sha3-256("v5!0ZF%kv 2p0isI*yWJ dky3R7Q#en!4X6;UGS-v35r U#aw/5{61ca") = b6783aadb56f8228feb9673eaf15184417ecc3a1e854ed75bf26de1b126c1c26

Xorring these three gives 5a8086e410ae5505e7cc674152241a1b0813f24a795b3bccb38a20a5e82b3ec6 which results in 5JW9LPbpY1b8aLd8MHkZBCtSCbmA29oaHA1jmpf5dWAEntfYo58 / 13wCBWBnQ86kKHBztMm3j44wb53RYP8LuQ.

I'm quite convinced it doesn't get any more secure than this, in terms of private key 'randomness'.


Feel free to send your life savings to 1JhrfA12dBMUhcgh85wYan6HL2uLQdB6z9
Jace
Sr. Member
****
Offline Offline

Activity: 288
Merit: 251


View Profile
December 12, 2013, 01:33:08 PM
 #20

Do anybody know if a parser script exist that can run offline, to check that the public adr. correspond to the private adr. ?

It would be nice to double check that the private key and public key match, before you transfer a lot of BTC.
Ofcause you can redeem your private key - but then has the key been exposed.
Save a local copy of bitaddress.org? (it's just one HTML file with all necessary javascript included)

Feel free to send your life savings to 1JhrfA12dBMUhcgh85wYan6HL2uLQdB6z9
TookDk
Legendary
*
Offline Offline

Activity: 1960
Merit: 1062


One coin to rule them all


View Profile WWW
December 12, 2013, 02:02:03 PM
 #21

Do anybody know if a parser script exist that can run offline, to check that the public adr. correspond to the private adr. ?

It would be nice to double check that the private key and public key match, before you transfer a lot of BTC.
Ofcause you can redeem your private key - but then has the key been exposed.
Save a local copy of bitaddress.org? (it's just one HTML file with all necessary javascript included)

Thank you for reply's... (ofcause, doh).

OP: sorry I have messed up you thread, I guess my question about private key validation and retrieval was a bit of topic.
I can delete my posts about the private key validation if you like, just PM.

Cryptography is one of the few things you can truly trust.
deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
December 12, 2013, 02:14:10 PM
Last edit: January 09, 2014, 01:09:26 PM by deepceleron
 #22

I could not get Electrum to import the private key.
I tried the same private key with blockchain online wallet, it worked beautifully.

What method you use/recommend to redeem your private key?

Compressed addresses can reduce your fees by half, in addition to the reduction in blockchain size. I don't know if the status of Electrum has changed in a year, it seems not:
no, Electrum does not support compressed keys (except for verifying signed messages)
(Edit: it does, you just need to go to the correct screen in the current version.)
-

Darn it. I'm on XP (32 bit.)
Well, you have just been protected from yourself!:
http://en.wikipedia.org/wiki/CryptGenRandom

In practice though, a reduced strength OS crypto won't matter; just typing 32 unmemorized keypresses, which alone are combined with another long string, appended to itself eight times, and put through SHA512, is stronger than the first "brainwallet" (and that's just one line of the script, the same line which XORs that with the result of about 1917 other hashes. And that's just to generate 1/3rd of the entropy used by the random generator).

Install Python, it's no big thing, and a world will open up for you.
-

Merry Christmas deepceleron
Much thanks, this is not overlooked!
phelix
Legendary
*
Offline Offline

Activity: 1708
Merit: 1020



View Profile
December 13, 2013, 10:56:59 AM
 #23

Quote
I get 512bit user entropy based on keypress times, with keypress values also used *8 (but not an integral component). I don't get the strict "time" between keypresses, there's a time->hash-driven variable length loop that runs after each keypress before time-poll to make CPU speed and system interrupts a factor, then I convolute the time. I seed the OS urandom with this user entropy and make a SHA256 hashed OS-based random key whitened with python's Mersenne Twister from oracle back to random bit depth. That's good enough, but then I re-seed the OS entropy pool every 1024 bits with time and user-based entropy plus hashes, then I XOR with a differently-obfuscated SHA2 of system random,  and then I XOR with processor-time based and clock based time sources stretched to put 512bits of noise in the hash. Repeat 100 times. The code is easier to read than the explanation.
I think the code is too complicated to be easily verified. Why don't you concatenate the entered characters, some time (delta) string and urandom string together and sha256 the hole thing?
integrity42
Full Member
***
Offline Offline

Activity: 476
Merit: 100



View Profile WWW
December 13, 2013, 11:43:19 AM
 #24

Quote
I get 512bit user entropy based on keypress times, with keypress values also used *8 (but not an integral component). I don't get the strict "time" between keypresses, there's a time->hash-driven variable length loop that runs after each keypress before time-poll to make CPU speed and system interrupts a factor, then I convolute the time. I seed the OS urandom with this user entropy and make a SHA256 hashed OS-based random key whitened with python's Mersenne Twister from oracle back to random bit depth. That's good enough, but then I re-seed the OS entropy pool every 1024 bits with time and user-based entropy plus hashes, then I XOR with a differently-obfuscated SHA2 of system random,  and then I XOR with processor-time based and clock based time sources stretched to put 512bits of noise in the hash. Repeat 100 times. The code is easier to read than the explanation.
I think the code is too complicated to be easily verified. Why don't you concatenate the entered characters, some time (delta) string and urandom string together and sha256 the hole thing?

Yes thats probably enough entropy, and makes for easier to read code. Any thoughts on a simplified version?

deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
December 13, 2013, 04:05:54 PM
Last edit: December 04, 2017, 11:14:39 PM by deepceleron
 #25

Any thoughts on a simplified version?
My main goal was to fuzz all random sources way beyond reproducibility, with time being the primary source. Time is envisioned somewhat repeatable (think restart a no realtime-clock device with no entropy gathering and immediately run this) and has 32 bits, but less than 16 could be considered entropy-like. I already made a large simplification for the sake of readability, there's not much to remove that wouldn't defeat the goal. Remember, there are demonstrations of cryptanalysis of hardware RND bias by affecting heat generation through remotely running processes on a machine.

A white paper on the motivation and methods used may facilitate review without reading code. Here's a summary of
methods, in order they are used:

clockbase(): poll raw system timers twice,
clockrnd(): 512 bit entropy by random-length-loop of various hashings of clockbase(),
platform_check(): ensure repeating calls to clockrnd() never return same result,
keyboard_entropy(): accumulate XORs of clockrnd() before and after every keypress, XOR SHA512 of stretched presses,
random_key(): entropy by keyboard_entropy() + urandom state + time
    seed system random generator (urandom) with entropy
    privkey initial value by 256 bits urandom XOR sha256 of 512 bits urandom
    then random 64-128 loops of:
        XOR random 256 bit window of SHA512 of clockrnd()+clockrnd()+entropy
        XOR random 256 bit window of SHA512 of 512 bytes urandom
        XOR 256 more bits from 2nd urandom object
        reseed urandom with SHA512 of the first two XORs plus entropy

By the time we're done we've asked for the epoch time or processor time about 6000 between 43492-382796 times (or potentially millions on OSX), and done about that many hashes. Then we make a Bitcoin address from that garbage if it is a valid private key...

Or for users: bang on keys, get address.

In other news, I have gotten Python-only BIP38 passphrase encryption running from a single script. That's native AES, PBKDF2, SCrypt; at least Python includes SHA1 and 2.  It takes about nine minutes to produce the encrypted private key on one core of Core2Quad 2.8GHz...

phelix
Legendary
*
Offline Offline

Activity: 1708
Merit: 1020



View Profile
December 13, 2013, 05:44:46 PM
 #26

Code:
entropy = raw_input()
entropy += os.urandom(32) + str(random.randrange(2**256)) + str(int(time.time())**7)  # from Vitalik
entropyHash = hashlib.sha256(entropy).hexdigest()

Is this so much less safe than your version to justify 150 lines of code?

Don't get me wrong, I really like the general idea.  Smiley
deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
December 13, 2013, 06:00:35 PM
 #27

Code:
entropy = raw_input()
entropy += os.urandom(32) + str(random.randrange(2**256)) + str(int(time.time())**7)  # from Vitalik
entropyHash = hashlib.sha256(entropy).hexdigest()

Is this so much less safe than your version to justify 150 lines of code?

Don't get me wrong, I really like the general idea.  Smiley
That:
1. uses urandom, we don't know if it's good. Actually, we know it's not good.
2. uses the initial state of Mersenne Twister, likely deterministically related to the previous urandom
3. uses the current time, not unfathomable to gather what it's state might have been:
print time.time();print time.time()
1386957154.74
1386957154.78

4. uses SHA256, which is pretty darn strong as long as you don't let users put data through it. Created by the NSA.
phelix
Legendary
*
Offline Offline

Activity: 1708
Merit: 1020



View Profile
December 13, 2013, 07:27:18 PM
 #28

Code:
entropy = raw_input()
entropy += os.urandom(32) + str(random.randrange(2**256)) + str(int(time.time())**7)  # from Vitalik
entropyHash = hashlib.sha256(entropy).hexdigest()

Is this so much less safe than your version to justify 150 lines of code?

Don't get me wrong, I really like the general idea.  Smiley
That:
1. uses urandom, we don't know if it's good. Actually, we know it's not good.
2. uses the initial state of Mersenne Twister, likely deterministically related to the previous urandom
3. uses the current time, not unfathomable to gather what it's state might have been:
print time.time();print time.time()
1386957154.74
1386957154.78

Now that I look at it the use of time() and int() above seems rather bad. The clock() function you use is very interesting.

But if I let my dog play with the keyboard for a while to gather entropy it should not be a problem. Everything else is more like a salt then.

Quote
4. uses SHA256, which is pretty darn strong as long as you don't let users put data through it. Created by the NSA.
The idea is that if SHA256 will break then your Bitcoins will plummet anyway...


Anyway it's great that you do profound thinking about these issues that form the very basis of Bitcoin.
deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
December 14, 2013, 01:27:08 AM
Last edit: December 14, 2013, 05:39:25 AM by deepceleron
 #29

Big update. Much work. Encryption. Some Options. No changes to the random stuff or normal address generation.

There's bitcoins a few posts back if you want to steal them...(aand they're gone!)
Abdussamad
Legendary
*
Offline Offline

Activity: 3612
Merit: 1564



View Profile
December 14, 2013, 03:44:08 AM
 #30

Compressed addresses can reduce your fees by half, in addition to the reduction in blockchain size. I don't know if the status of Electrum has changed in a year, it seems not:

Electrum does support compressed keys now. Since 1.9 I think.

In other news, I have gotten Python-only BIP38 passphrase encryption running from a single script. That's native AES, PBKDF2, SCrypt; at least Python includes SHA1 and 2.  It takes about nine minutes to produce the encrypted private key on one core of Core2Quad 2.8GHz...

Why is this slower than the bitaddress implementation? Both python and javascript are interpreted languages so they should be equally fast, right?
deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
December 14, 2013, 05:37:10 AM
 #31

Why is this slower than the bitaddress implementation? Both python and javascript are interpreted languages so they should be equally fast, right?
Python can be much faster when it uses compiled libraries that are interfaces to c machine code behind some of the math; however I made the script with written-in-Python code, not especially optimized (if it's even possible), simply because I want to provide something as a single script for a live cd/offline wallet that doesn't require installation of obscure sources. The implementations of AES and SCrypt are, like a lot of Python, largely academic, since faster implementations will always be in native code. Just in time compilers like cpython and PyPi can accelerate things multiple times, just like Javascript JIT compilers in browsers, and have support for multithreaded greenlets, although the anti-GPU features of scrypt are just as much anti-Python features.

For the windows exe I could probably cheat and just give you fast libs.
Dabs
Legendary
*
Offline Offline

Activity: 3416
Merit: 1912


The Concierge of Crypto


View Profile
December 26, 2013, 02:24:26 AM
 #32

Okay, I like the fast libs.

Big update. Much work. Encryption. Some Options.

I was almost afraid you would say "very currency, much wow!" or something crazy like that. Seems to be the fashion the past two weeks.

TookDk
Legendary
*
Offline Offline

Activity: 1960
Merit: 1062


One coin to rule them all


View Profile WWW
December 26, 2013, 12:38:31 PM
 #33

Okay, I like the fast libs.

Big update. Much work. Encryption. Some Options.

I was almost afraid you would say "very currency, much wow!" or something crazy like that. Seems to be the fashion the past two weeks.

+1

"Such update. Much work. Much Encryption. Many Options. WOW"

Cheesy

Cryptography is one of the few things you can truly trust.
deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
July 16, 2014, 02:36:15 PM
 #34

Oops, I've had the wrong sha256sum in the first post since January, updated. I guess that shows how many people have actually tried this out...
TookDk
Legendary
*
Offline Offline

Activity: 1960
Merit: 1062


One coin to rule them all


View Profile WWW
July 16, 2014, 08:31:44 PM
 #35

Oops, I've had the wrong sha256sum in the first post since January, updated. I guess that shows how many people have actually tried this out...

I tried out your script, back in January, but never actually tested the keys generated with live coins.
I think this script is very useful, I hope to use it for something serious one day.

Cryptography is one of the few things you can truly trust.
Abdussamad
Legendary
*
Offline Offline

Activity: 3612
Merit: 1564



View Profile
July 17, 2014, 06:29:46 AM
 #36

At one point there were 2 sha256 hashes in the OP one of which was correct. Then a few months ago the correct one disappeared.

Dabs
Legendary
*
Offline Offline

Activity: 3416
Merit: 1912


The Concierge of Crypto


View Profile
October 08, 2014, 01:42:15 AM
 #37

What's the SHA256 for the Windows EXE?

deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
October 08, 2014, 04:36:38 AM
 #38

What's the SHA256 for the Windows EXE?
Verified my local compile vs what is on my site (still identical), and updated first post with sha256sum and md5sum info, thanks! (also just noticed the exe file properties still say version 1.1; this is from the py2exe script which I didn't update when compiling..)
Dabs
Legendary
*
Offline Offline

Activity: 3416
Merit: 1912


The Concierge of Crypto


View Profile
October 08, 2014, 04:43:19 AM
 #39

Thanks. I'm going to use it for some heavy duty BTC transactions. Smiley

r3c4ll
Member
**
Offline Offline

Activity: 100
Merit: 10


View Profile
October 08, 2014, 11:41:42 PM
 #40

Thanks for the script!

Dabs
Legendary
*
Offline Offline

Activity: 3416
Merit: 1912


The Concierge of Crypto


View Profile
October 16, 2014, 04:35:49 AM
 #41

BTW, got a version that makes hundreds or thousands of addresses? I want to make a giant non-deterministic wallet.

deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
October 16, 2014, 05:35:32 PM
 #42

BTW, got a version that makes hundreds or thousands of addresses? I want to make a giant non-deterministic wallet.

I specifically don't, because this would rely too much on the quality of the system random number generator PRNG instead of user-created entropy, which could conceivably link the addresses together and allow for cryptanalysis, especially with low system entropy available or intentionally flawed OS implementation. I could fashion something, but I would need to sweeten the random, maybe by throwing several rounds of scrypt hash XOR SHA hash XOR user entropy per urandom sourced key, with enhanced urandom reseeding while you keep pounding the keyboard.

I have also made this work with MinGW-compiled C scrypt code to make encrypted BIP38 wallets in less than a second vs 8 minutes. The all-in-Python script is written for easy verifiable LiveCD use; the Windows exe might as well be more utilitarian since it can't meet this challenge. However, I am having difficulty getting it packaged with py2exe, which seems to turn the pyd dependency into a pyo, and then the exe bytecode can't find the _scrypt code. Still have some more things to try.
Dabs
Legendary
*
Offline Offline

Activity: 3416
Merit: 1912


The Concierge of Crypto


View Profile
October 17, 2014, 01:54:09 AM
 #43

BTW, got a version that makes hundreds or thousands of addresses? I want to make a giant non-deterministic wallet.

I specifically don't, because this would rely too much on the quality of the system random number generator PRNG instead of user-created entropy, which could conceivably link the addresses together and allow for cryptanalysis, especially with low system entropy available or intentionally flawed OS implementation. I could fashion something, but I would need to sweeten the random, maybe by throwing several rounds of scrypt hash XOR SHA hash XOR user entropy per urandom sourced key, with enhanced urandom reseeding while you keep pounding the keyboard.

I have also made this work with MinGW-compiled C scrypt code to make encrypted BIP38 wallets in less than a second vs 8 minutes. The all-in-Python script is written for easy verifiable LiveCD use; the Windows exe might as well be more utilitarian since it can't meet this challenge. However, I am having difficulty getting it packaged with py2exe, which seems to turn the pyd dependency into a pyo, and then the exe bytecode can't find the _scrypt code. Still have some more things to try.

Okay, I like the 1 second BIP38 key. That would be really useful.

For random seeds, I could, for example, take a few hundred pictures with my SLR camera. That should provide enough entropy for a few thousand addresses. Or I could make a giant home video in mp4 format, going around pointing it at the sky and clouds or the trees swaying in the wind. Then I would of course securely erase any such jpegs and mp4s after.

There are also hardware RNGs, that plug into a USB port, and feed /dev/random

http://www.entropykey.co.uk/
https://www.tindie.com/products/ubldit/truerng-hardware-random-number-generator/

For about $50.

hanisnl
Member
**
Offline Offline

Activity: 119
Merit: 100

www.thecryptobot.com


View Profile WWW
October 21, 2014, 11:46:58 PM
 #44

hi there !

does your fine looking script run on python 3.x ?

https://thecryptobot.com - Buy GunBot Licenses and Services
deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
October 22, 2014, 01:39:50 AM
 #45

hi there !

does your fine looking script run on python 3.x ?

No. The first challenge will be functions that have had name changes. itertools izip used in the salsa mix function had a name change in Python 3. xrange is renamed to just range, but range() is not an generator in py2, etc. Better that Python 3 has a syntax error than Python 2 does the wrong thing.

I might change over to https://github.com/ricmoo/pyscrypt from http://hg.saddi.com/scrypt/ if I've got time to clean up and merge that code into one file (it is about 20% faster at encryption) and then see what other traps I find. Until the majority of LiveCDs don't run Python 2 as default this won't be a big concern.
deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
May 02, 2016, 03:24:12 PM
 #46

I updated the first post with a more verbose description. It should now be an answer you can provide to most "paper wallet...what?" questions.

No reason to change the two-year-old code. I anticipate changing hosting providers in the next month if anybody keeps track; this free and open-source code could also go up on a git/svn site, but taking contributions & trust is problematic, as well as hosting somewhere more vulnerable to hacking.
Dabs
Legendary
*
Offline Offline

Activity: 3416
Merit: 1912


The Concierge of Crypto


View Profile
May 02, 2016, 04:48:50 PM
Last edit: May 02, 2016, 05:48:48 PM by Dabs
 #47

If I can reproduce and recreate the steps to make a Windows executable, with the same version of py2exe, I should be able to have an identical paperwal.exe, with matching sha256 and md5 checksums. Or is the compiler not a deterministic builder?

Actually, as long as I can compare the majority of the binary result, it should be good. I've seen someone try the same thing with TrueCrypt with only the signature part that can't be matched, but the rest of the binary is very close to his own compiled version.

Quote
http://we.lovebitco.in/paperwal.exe (4MB) Windows exe created with py2exe, Python 2.7.6 32 bit
sha256: 31af7bec9aa68c8a32ce09de42f16cf58868c6d6a69a71c701ae52efba842076 *paperwal.exe
md5sum: e2e5d1d648ccc1cabebd745a160e5277 *paperwal.exe

*edit*

I just tried it, downloaded python 2.7.6 32 bit and py2exe-0.6.9.win32-py2.7.exe dated 2008-11-16

Then "compiled" it according to tutorials and came up with a 49 kb executable.

2016-05-02  01:37 PM            50,176 paperwal.exe

Obviously, the hashes are not going to match. Yours must be including everything or something, or you used a different version of py2exe.

But I should be able to trust my own executable since I did it myself, based on the paperwal.py which I already reviewed.

It's a lot smaller, but then I had to install python.

deepceleron (OP)
Legendary
*
Offline Offline

Activity: 1512
Merit: 1032



View Profile WWW
May 02, 2016, 08:25:39 PM
 #48

If I can reproduce and recreate the steps to make a Windows executable, with the same version of py2exe, I should be able to have an identical paperwal.exe,?
...
I just tried it, downloaded python 2.7.6 32 bit and py2exe-0.6.9.win32-py2.7.exe dated 2008-11-16
Then "compiled" it according to tutorials and came up with a 49 kb executable.

I've tried to replicate Python project py2exe binaries on other computers to make a reliable verification procedure and not had luck. For a start, you need the same setup.py file, and one character different (in the version string that shows up when you right click, for example) makes it not hash right.

Here's the setup.py I likely used to create the exe:
Code:
from distutils.core import setup
import py2exe, sys, os

sys.argv.append('py2exe')

setup(
    options = {'py2exe':
        {'optimize': 2,
         'bundle_files': 1,
         'compressed': True,
         },
    },
    console = ['paperwal.py'],
    zipfile = None,   
    version="1.1.0",
    description="Secure Address Generator",
    author="deepceleron",
)

Of course using different version of py2exe script byte-compiled on a different day with different windows libraries and modules graphed by the py2exe script with the moon in a different phase makes it different.

You did discover that the base py2exe options creates a small file reliant on the system's installed python modules. I had the same dependency problem with attempts using cython. The py2exe binary is partly ZIP file, you can extract the files to see the python interpreter and many other byte-compiled files included.
adelhmdt
Member
**
Offline Offline

Activity: 98
Merit: 10


View Profile
May 09, 2016, 02:19:05 PM
 #49

What's the SHA256 for the Windows EXE?
Dabs
Legendary
*
Offline Offline

Activity: 3416
Merit: 1912


The Concierge of Crypto


View Profile
May 09, 2016, 09:00:56 PM
 #50

What's the SHA256 for the Windows EXE?
It's there in the first post. If you compile your own version, it may be different.

huijaa
Newbie
*
Offline Offline

Activity: 7
Merit: 0


View Profile
August 12, 2017, 08:50:34 AM
 #51

Hi!

Very very greatfull program is it! Because paperwal.py is an open source, i can add new feature for printing on thermal-printer.

Code:
-t           --thermal-print           to print to thermal printer

Instead of outputting to screen, it will print a QR-code of public and private key.


I see a version of 1.2 at this moment, but i'll ask for newer version of paperwal.py ?

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!