Author

Topic: [PULL] 52-line patch supporting offline key generation (Read 3518 times)

sr. member
Activity: 416
Merit: 277
Here's a wallet ...

Using my amazing elliptic curve discrete logarithm calculating ability I deduce that the private key which generates the public key points
Code:
FF5443FCD00B8F3844569DCAA42662D90E0C8AFB1FE35804C320E5BB08EA6DAD        C3231767AA13B9DD6ABCB45A8CD0497490D5C2A78FF85EA61711394B3B08E5C9
in the above wallet is
Code:
44b1585492c83e83fd917783c1b74ec25e3e6b3ca8722cc41eabe05249a46288
which doesn't look noteworthy.

I'm not sure what all the rest of the wallet dump is but the first longer run of FFs looks like the modulus for the finite field and the second run is probably part of the group order.

Nothing to see here. Move along.

ByteCoin
legendary
Activity: 1072
Merit: 1189
Good idea.  Interestingly, the keys I tested with do not have the same structure as client-generated keys.  The new kind have a shorter private key length.  You might think they have fewer bits of entropy, but the client-generated keys (in DER/wallet form) have long strings of all 1's and other common subsequences.  I have not figured out why.

OpenSSL-encoded private keys have a lot of redundancy, they store the field and curve parameters, the secret parameter and the public key, some of which have several possible encodings (eg. compact public key or not).

What you should check is whether the public key - exported by OpenSSL - is identical to the public key bitcoin extracts after importing the OpenSSL-encoded private key.
hero member
Activity: 481
Merit: 529
OpenSSL creating private keys with low entropy would be surprising.

Could you (benjamindees and John Tobey) please post some unimportant private keys and point out the features you think are noteworthy?

Thanks in advance!

ByteCoin

Here's a wallet created with keypool=0, binary attached(upload folder is full), db_dump shown:
EDIT: broke up long lines
Code:
VERSION=3
format=bytevalue
database=main
type=btree
db_pagesize=4096
HEADER=END
 036b65794104ff5443fcd00b8f3844569dcaa42662d90e0c8afb1fe35804c320e5b\
b08ea6dadc3231767aa13b9dd6abcb45a8cd0497490d5c2a78ff85ea61711394b3b08e5c9
 fd170130820113020101042044b1585492c83e83fd917783c1b74ec25e3e6b3ca8722cc41\
eabe05249a46288a081a53081a2020101302c06072a8648ce3d0101022100fffffffffffffffffff\
ffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295\
ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd\
17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd\
25e8cd0364141020101a14403420004ff5443fcd00b8f3844569dcaa42662d90e0c8afb1fe3\
5804c320e5bb08ea6dadc3231767aa13b9dd6abcb45a8cd0497490d5c2a78ff85ea617113\
94b3b08e5c9
 046e616d6522313635486f51587a7863323678786b45434439356963544173635a573854\
6e674655
 0c596f75722041646472657373
 0776657273696f6e
 027d0000
 0a64656661756c746b6579
 4104ff5443fcd00b8f3844569dcaa42662d90e0c8afb1fe35804c320e5bb08ea6dadc323176\
7aa13b9dd6abcb45a8cd0497490d5c2a78ff85ea61711394b3b08e5c9
DATA=END

Note the long strings of 'ffff' apparently in the middle of the private key.  The public key starts with '04ff5443...' and is the last 65 bytes of both the database key and database value in the lines starting with "036b657941" and "fd17013082"
legendary
Activity: 1330
Merit: 1000
The issue is with the Bitcoin client, not OpenSSL.  Here is a client-generated key (with address) extracted using bc_key:

Code:
1HFCvpHXQXiixfsHwC4upUtqpUBisQ1gg4
-----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MIIBEwIBAQQgjnVgOESPkm6QN0RgdTvotkyHT3QyndddWuh9YU9C/YOggaUwgaIC
AQEwLAYHKoZIzj0BAQIhAP////////////////////////////////////7///wv
MAYEAQAEAQcEQQR5vmZ++dy7rFWgYpXOhwsHApv82y3OKNlZ8oFbFvgXmEg62ncm
o8RlXaT7/A4RCKj9F7RIpoVUGZxH0I/7ENS4AiEA/////////////////////rqu
3OavSKA7v9JejNA2QUECAQGhRANCAAQHbsYiY+9ss9XJcAhwYzO8msI9dFujnfcf
+QX1qdVMhnJwQ1pf714KrZfXExaJ8rHXJSV15xqD48HpGmzheBik
-----END EC PRIVATE KEY-----

Note the repetitive slashes and the fact that it's like 3x longer than necessary.

And here is an OpenSSL-generated key:

Code:
-----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIBni/G/mka5Lq+lwljTfwi76vLf+Pp/XIpLRALyfWAJIoAcGBSuBBAAK
oUQDQgAEYqfVWRS4/Uic7gaayYKLye313IDjSV56eXwk6NpwTB6e+9sHLYtJlhkW
fYLtnZ2DPN+xf1q9RLdHQNUm5DTm2g==
-----END EC PRIVATE KEY-----
sr. member
Activity: 416
Merit: 277
... the client-generated keys (in DER/wallet form) have long strings of all 1's and other common subsequences.  I have not figured out why.

I notice this also and it is troubling me.
OpenSSL creating private keys with low entropy would be surprising.

Could you (benjamindees and John Tobey) please post some unimportant private keys and point out the features you think are noteworthy?

Thanks in advance!

ByteCoin
hero member
Activity: 481
Merit: 529
Interestingly, the keys I tested with do not have the same structure as client-generated keys.  The new kind have a shorter private key length.  You might think they have fewer bits of entropy, but the client-generated keys (in DER/wallet form) have long strings of all 1's and other common subsequences.  I have not figured out why.

I notice this also and it is troubling me.

If I had massive wealth in BTC, I guess I would build OpenSSL from source and step through key generation to discover what is going on. Smiley
legendary
Activity: 1330
Merit: 1000
Interestingly, the keys I tested with do not have the same structure as client-generated keys.  The new kind have a shorter private key length.  You might think they have fewer bits of entropy, but the client-generated keys (in DER/wallet form) have long strings of all 1's and other common subsequences.  I have not figured out why.

I notice this also and it is troubling me.
hero member
Activity: 481
Merit: 529
Note: To be convenient, one (I) would write a little script to read one of these PEM files and print a Bitcoin address.  All key handling would be possible offline, and certainly in the absence of a block chain, until spend time.

Update: The script both creates the PEM file (using the openssl command) and prints the Bitcoin address: https://github.com/jtobey/bitcoin/raw/importkey/contrib/genkey.py
hero member
Activity: 481
Merit: 529
I have written a patch that allows extraction and insertion of bitcoin private keys in a custom base58-based format, only containing the secret parameters itself, without the field and curve parameters.
Is it on the pull list or otherwise available?
Yes, here: https://github.com/bitcoin/bitcoin/pull/220

Oh, that's you?  Thanks for the contributions!

I read your summary (hadn't got to the code yet) and the comments about "rpc.cpp too big" and "import to an account" and saw value in a patch that addresses those two issues and a more narrow use case.

Quote
Just checking upon import is fine. I suppose the easiest way would be extracting the private parameters, reconstructing the full private key from that, and check whether that results in a structure identical to the one imported. The pull request above contains code in CKey for doing those.

Good idea.  Interestingly, the keys I tested with do not have the same structure as client-generated keys.  The new kind have a shorter private key length.  You might think they have fewer bits of entropy, but the client-generated keys (in DER/wallet form) have long strings of all 1's and other common subsequences.  I have not figured out why.
legendary
Activity: 1072
Merit: 1189
I have written a patch that allows extraction and insertion of bitcoin private keys in a custom base58-based format, only containing the secret parameters itself, without the field and curve parameters.
Is it on the pull list or otherwise available?
Yes, here: https://github.com/bitcoin/bitcoin/pull/220

Quote
Import and export of DER-encoded keys would also be useful (I have code for export laying around somewhere) for certain purposes though. You should check whether the imported key is a real bitcoin key though, as the public keys and signatures over the network do net encode the field and curve parameters, and would be invalid if the corresponding private key doesn't match.
Good points, but I do not want to lose sight of my motivating use case.  For generating a key pair and receiving BTC outside of Bitcoin, obviously Bitcoin can not do the checking in advance.  I agree it should check when importing, though.  I'd appreciate hints at code that will do that.
Just checking upon import is fine. I suppose the easiest way would be extracting the private parameters, reconstructing the full private key from that, and check whether that results in a structure identical to the one imported. The pull request above contains code in CKey for doing those.
newbie
Activity: 42
Merit: 0
thanks for explanation/clarifying.
p.s.
still don't get BTC mechanics clearly, seems :[
i guess im too old. *cry*
hero member
Activity: 481
Merit: 529
I have written a patch that allows extraction and insertion of bitcoin private keys in a custom base58-based format, only containing the secret parameters itself, without the field and curve parameters.

Is it on the pull list or otherwise available?

Quote
Import and export of DER-encoded keys would also be useful (I have code for export laying around somewhere) for certain purposes though. You should check whether the imported key is a real bitcoin key though, as the public keys and signatures over the network do net encode the field and curve parameters, and would be invalid if the corresponding private key doesn't match.

Good points, but I do not want to lose sight of my motivating use case.  For generating a key pair and receiving BTC outside of Bitcoin, obviously Bitcoin can not do the checking in advance.  I agree it should check when importing, though.  I'd appreciate hints at code that will do that.
legendary
Activity: 1072
Merit: 1189
I have written a patch that allows extraction and insertion of bitcoin private keys in a custom base58-based format, only containing the secret parameters itself, without the field and curve parameters.

Import and export of DER-encoded keys would also be useful (I have code for export laying around somewhere) for certain purposes though. You should check whether the imported key is a real bitcoin key though, as the public keys and signatures over the network do net encode the field and curve parameters, and would be invalid if the corresponding private key doesn't match.
hero member
Activity: 481
Merit: 529
isn't "offline key generation" against basic BitCoin ideas ?

Not at all.  The most sensitive data in the system is the private key associated with a Bitcoin address.  That the current software requires private keys to be generated by a process that participates in the network and downloads blocks is a big design flaw.  (Early on, when BTC was under $0.01, it might have been justified in terms of simplicity and time-to-market.)

The network never needs to see private keys.  If you have a lot of BTC, you should keep your private keys well separated from the network and the threat of malware.  This patch will let you generate keys on an unconnected machine, perhaps booted from read-only media, and keep them away from the network until you are ready to spend their coins.

Even better would be a standalone transaction signer (and bitcoind importtx command) that would let you send, too, without putting your private key on a networked machine.  That is my next project, if I get around to it.
newbie
Activity: 42
Merit: 0
isn't "offline key generation" against basic BitCoin ideas ?
as well as pools in present state.
hero member
Activity: 481
Merit: 529
Yet another Feeping Creature, but it's tame, oh so tame...

https://github.com/bitcoin/bitcoin/pull/245

import key from PEM file

Motivation: Create keys on a secure system using only OpenSSL or similar software. Receive BTC, then when ready to spend them, use importkey in a running client.

importkey
Reads a PEM-encoded keypair from file and adds it to the wallet.
To create a keypair with OpenSSL, use:
openssl ecparam -name secp256k1 -out NEW_KEY.pem -genkey
Returns the key's bitcoin address.

$ bitcoind importkey ~/NEW_KEY.pem TestAcct
mt5M3Qa7fXsUV3bK6WtWTZEvXY2M1UPEgv

Bug: I'd like to safeguard against overwriting a key in the wallet with bogus data.
Bug: I don't understand what has to be mutexed.
Bug: Should do anything possible to make sure the imported key is valid.

Note: I did not implement the corresponding export function, because my use case does not require it.  I will be happy to implement it if this will improve the patch's chance of acceptance.

Note: To be convenient, one (I) would write a little script to read one of these PEM files and print a Bitcoin address.  All key handling would be possible offline, and certainly in the absence of a block chain, until spend time.  For my next trick, expect offline transaction signing and an importtx function.

Kind regards,
John
Jump to: