Pages:
Author

Topic: ANN: Python paper wallet generator with strong randomness - page 2. (Read 16939 times)

legendary
Activity: 1512
Merit: 1036
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.
legendary
Activity: 3682
Merit: 1580
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?
legendary
Activity: 1512
Merit: 1036
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!)
legendary
Activity: 1708
Merit: 1020
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.
legendary
Activity: 1512
Merit: 1036
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.
legendary
Activity: 1708
Merit: 1020
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
legendary
Activity: 1512
Merit: 1036
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...

full member
Activity: 476
Merit: 100
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?
legendary
Activity: 1708
Merit: 1020
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?
legendary
Activity: 1512
Merit: 1036
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!
legendary
Activity: 1960
Merit: 1062
One coin to rule them all
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.
sr. member
Activity: 288
Merit: 251
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)
sr. member
Activity: 288
Merit: 251
legendary
Activity: 3416
Merit: 1912
The Concierge of Crypto
Bitaddress running offline.
bitcoin-qt, running offline, importprivkey.

Delete securely after confirming the keys match.
legendary
Activity: 1960
Merit: 1062
One coin to rule them all
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.
legendary
Activity: 1960
Merit: 1062
One coin to rule them all
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?



 
legendary
Activity: 1960
Merit: 1062
One coin to rule them all
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
legendary
Activity: 3416
Merit: 1912
The Concierge of Crypto
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.
legendary
Activity: 1512
Merit: 1036
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.
hero member
Activity: 686
Merit: 504
always the student, never the master.
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

Pages:
Jump to: