Author

Topic: Compressed vs. Uncompresed Private Keys (Read 10688 times)

sr. member
Activity: 412
Merit: 287
March 16, 2014, 07:18:36 AM
#18
so the compressed wif code represents the compressed private key, good to know.

Yes, even though the private key that is 'compressed' takes up more space than the other private key. Because it has an extra byte encoded.
hero member
Activity: 1014
Merit: 1055
March 15, 2014, 05:52:55 AM
#17
so the compressed wif code represents the compressed private key, good to know.
legendary
Activity: 3416
Merit: 1912
The Concierge of Crypto
March 31, 2013, 10:35:11 PM
#16
You can modify the experiment to use only private keys that nobody else knows. After the experiment, you can get back your funds. And you can send more coins so that you can avoid a transaction fee if you want to, like send 1.0 bitcoins and just wait 1 day.
hero member
Activity: 688
Merit: 500
ヽ( ㅇㅅㅇ)ノ ~!!
March 30, 2013, 09:18:24 AM
#15
thanks kjj, Blowfeld, that is all very enlightening.
newbie
Activity: 53
Merit: 0
March 29, 2013, 06:16:07 PM
#14
Assuming I have a private key written down in old "uncompressed" format, does it matter whether I send BTC to the compressed or uncompressed public address? Funds sent to either are still controllable by the single uncompressed private key?

Or must I be sure only to send funds to the "uncompressed" public address, otherwise I lose the funds?
First, let's be absolutely clear that nobody without the private key will have any idea the two addresses are connected to the same EC secret.  So, aside from the owner of the private key(s), they are as different as any other two distinct public addresses.

For the owner of the private key(s), they are (or should be) the same.  It is my contention that a wallet that doesn't recognize both public addresses is deficient.  [But I suspect most wallets are deficient, by my definition.]

As kjj explained, you haven't lost the funds.  But you may have to convert the private key from one form to another and then import the other form of private key to gain access to those funds.

Here's an experiment:  Send a tiny amount of coin to the uncompressed brain wallet for "correct mule battery horse", which I gave a few posts up.  Send a different tiny amount of coin to the compressed brain wallet for "correct mule battery horse", which is given above.  Add one private key at a time to your favorite wallet.  See which transaction(s) show up in your wallet.  Do not send more than you want to lose, because anybody who reads this thread may transfer the coins out of the brain wallet.

Once these transactions are in the blockchain, everyone who reads this thread could add one private key at a time to their favorite wallet and they can see for themselves which transactions appear in their wallet.
kjj
legendary
Activity: 1302
Merit: 1026
March 29, 2013, 03:27:59 PM
#13
Can somebody please confirm something for a slightly confused noob:

Assuming I have a private key written down in old "uncompressed" format, does it matter whether I send BTC to the compressed or uncompressed public address? Funds sent to either are still controllable by the single uncompressed private key?

Or must I be sure only to send funds to the "uncompressed" public address, otherwise I lose the funds?

You can take a WIF of either format, add or remove the compression flag, and re-encode back into a WIF.

The raw private key is just 256 bits of data, usually random.  For example:
Code:
19fdab0668a2586da7bea56410c814b83be86a956bb8565aea78651c174bfc04

That private key corresponds to a public key with these coordinates:

Code:
x: 82c3cb548fdfd632f622db534badc9dd6d68bf65cacc3297df4686ff8a8d83b2
y: df70ca968a53fc29e4163401eb953b49961b0539341b54748001c83c48f952d3

There are two ways of encoding that public key.  One way is
Code:
0482c3cb548fdfd632f622db534badc9dd6d68bf65cacc3297df4686ff8a8d83b2df70ca968a53fc29e4163401eb953b49961b0539341b54748001c83c48f952d3

The other is
Code:
0382c3cb548fdfd632f622db534badc9dd6d68bf65cacc3297df4686ff8a8d83b2

These two encodings have different hahes, so their addresses are 1Nt6XLmq8k8noafGGFdfwue74uJTFu9vQC and 13pRRXkGVC9mhUSiw6xkYkMi1EX91VvsBE.

If your program understands compressed keys, it should tell you something like:
Code:
Private Key: Kx6EWgKRJ2GZuXbrDquQPAE8MWZLLdsT4YYgQs4hdF7rRL4jGLHx
Bitcoin Address: 13pRRXkGVC9mhUSiw6xkYkMi1EX91VvsBE

If it doesn't understand compressed keys, it should say:
Code:
Private key: 5J1jV2CspMgKnS4N7zJJz8Xcej3Lngcu89WP53jXW4CXEGF9M3A
Bitcoin Address: 1Nt6XLmq8k8noafGGFdfwue74uJTFu9vQC

If you run those WIFs through a base58 decoder, you'll find:
8019fdab0668a2586da7bea56410c814b83be86a956bb8565aea78651c174bfc0401902f231b
8019fdab0668a2586da7bea56410c814b83be86a956bb8565aea78651c174bfc046ddddd0d


Green is the prefix byte for a WIF.  Red is the compression flag.  Blue is the check code.  Black is the actual private key.

So, the private key you have written down can be used for two different addresses, but it might take some doctoring to get it into a format that your wallet can import correctly if you are using an address that doesn't match the WIF encoding used.
hero member
Activity: 688
Merit: 500
ヽ( ㅇㅅㅇ)ノ ~!!
March 29, 2013, 01:10:58 PM
#12
Can somebody please confirm something for a slightly confused noob:

Assuming I have a private key written down in old "uncompressed" format, does it matter whether I send BTC to the compressed or uncompressed public address? Funds sent to either are still controllable by the single uncompressed private key?

Or must I be sure only to send funds to the "uncompressed" public address, otherwise I lose the funds?
newbie
Activity: 53
Merit: 0
March 28, 2013, 08:53:33 PM
#11
Brain wallets are by convention uncompressed. While I can now (with help of your answer) create a compressed key from a passphrase and import that into my wallet, I might have a hard time to reconstruct it later for another wallet when I don't have my scripts at hand.
The Web site at bitaddress.org (or the equivalent script you download to your own computer) can do the complete conversion for you.

1.  Under the BrainWallet tab, enter a phrase.  I will use "correct mule battery staple".
2.  The BrainWallet page generates an (uncompressed) bitcoin address of 1Aop6KxiZLccPPPjqmfZHYgnmCKuhiVq57, which we will ignore.
3.  The BrainWallet page generates a private key of 5JRks4Vf268r9cuCKiod2iFz1VcSpawX5m6T3PKSA1v7cRqfZZD, which we copy over to the WalletDetails tab.
4.  The WalletDetails page generates a compressed bitcoin address of 1JMsC6fCtYWkTjPPdDrYX3we2aBrewuEM3, which we can give to our payors.
5.  The WalletDetails page also generates a bitcoin private key, flagged as "compressed", of KyvGbxRUoofdw3TNydWn2Z78dBHSy2odn1d3wXWN2o3SAtccFNJL, which we can import into a wallet that supports the compressed keys.

You are now a good citizen.  As always, test your own generated BrainWallet (receiving and sending) on a very small amount of BTC, before you trust anything substantial to a BrainWallet or any other manually concocted wallet.
full member
Activity: 216
Merit: 100
March 27, 2013, 06:40:21 PM
#10
I wonder, why they didn't just pick a different first byte, like 0x81, or whatever makes a good base58-start.
There's little use for a wallet to import a compressed key when it doesn't yet know how to handle it correctly, and those that do know how to handle it, could easily check for a second prefix on import.
If the system processing the WIF doesn't understand compressed keys, it'll complain that it found 264 bits when it expected 256.  Or it should.  At any rate, it's been a while, the old software should be updated if it doesn't understand.

What I meant was, that "compatibility" with old software could hardly have been an argument for the decision to stick to 0x80 prefix. But then, what else was the reason for not just picking a different prefix-byte to indicate compressed keys?


Brain wallets & vanitygen
Unless you are computing EC multiply, SHA-256 and RIPEMD-160 with pen and paper, you are going to need tools either way.

Lol, I was rather thinking of those offline-able pages where you could enter a passphrase and have a priv-key and address (and QR of each) generated purely from Javascript.  I wanted to mention brainwallet.org, but noticed that that perfectly well gives choice over "compressed"/"uncompressed".  Still, blockchain.info also allows importing brainwallets, but doesn't yet seem to support the concept of "compressed brainwallets". (It can import K/L...-style priv-keys, but warns, that their mobile client isn't able to use these.)

Using uncompressed keys causes a modest, but real, bloat in the blockchain and should be avoided whenever possible.

If it were possible to place public keys (compressed or uncompressed) in a new "array" compartment of a transaction and access them per some new opcode with index from the scripts, then transactions that collect multiple coins from each address would benefit even more.

Instead of:
  47 30......... 21 02........
  47 30......... 21 02........
scripts could then use:
  47 30......... ba 00
  47 30......... ba 00
and the tx would have the "02........" string only once in that new compartment.
(ba isn't yet an opcode, so I'm using it for that new opcode, only for the sake of this post.)


The author of vanitygen has been ignoring requests on the forums for compressed key support for over a year now.  I still have no idea why, since it should have very close to zero impact on key generation speed.

Well, vanitygen is open source, so that wouldn't really be an insurmountable problem...
 
kjj
legendary
Activity: 1302
Merit: 1026
March 27, 2013, 05:02:16 PM
#9
I wonder, why they didn't just pick a different first byte, like 0x81, or whatever makes a good base58-start.
There's little use for a wallet to import a compressed key when it doesn't yet know how to handle it correctly, and those that do know how to handle it, could easily check for a second prefix on import.

If the system processing the WIF doesn't understand compressed keys, it'll complain that it found 264 bits when it expected 256.  Or it should.  At any rate, it's been a while, the old software should be updated if it doesn't understand.

Quote
You should pretty much always do compressed keys for new generation.  There is no reason to ever use uncompressed keys, at least none that I'm aware of.

Brain wallets are by convention uncompressed. While I can now (with help of your answer) create a compressed key from a passphrase and import that into my wallet, I might have a hard time to reconstruct it later for another wallet when I don't have my scripts at hand.

Also, vanitygen doesn't seem to search for vanity compressed keys (at least not the version I've got here).

Unless you are computing EC multiply, SHA-256 and RIPEMD-160 with pen and paper, you are going to need tools either way.

Using uncompressed keys causes a modest, but real, bloat in the blockchain and should be avoided whenever possible.  Uncompressed keys offer absolutely no advantages over compressed keys, require no more special knowledge to process*, and take no extra effort to create.

If there is some convention around using uncompressed keys for brain wallets, that convention needs to be die quickly, like a year ago.  May I suggest that the convention change to "create compressed, redeem both compressed and uncompressed"?  The private key is exactly the same in both cases, only the bitcoin address changes, and there are only two possible, so the redeeming system should have no problem checking both of them.

The author of vanitygen has been ignoring requests on the forums for compressed key support for over a year now.  I still have no idea why, since it should have very close to zero impact on key generation speed.

Well, I guess you have to remember "0x02=even, 0x03=odd" instead of remembering "0x04=magic", but that is close enough to nothing for me.
legendary
Activity: 1176
Merit: 1280
May Bitcoin be touched by his Noodly Appendage
March 27, 2013, 04:42:44 PM
#8
As a user, there is a reason to use uncompressed over compressed keys: the software you're using
If you use an old version of pywallet or vanitygen you have to deal with uncompressed keys

As a dev, yeah, no reason
full member
Activity: 216
Merit: 100
March 27, 2013, 04:37:27 PM
#7
So, to create the WIF, suitable for importing later, you take the 32 byte binary private key, prepend the 0x80 bytes, and append the 0x01 flag for compression, then run through base58encode and the output is the WIF.  For reference, to create an uncompressed WIF, just don't append the 0x01 before encoding.

Thanks, that was the missing bit.  I had read about "adding a flag" and such, but never so far understood it as literally slapping an extra 0x01-octet to the end of the string.  The reverse conversion then is of course trivial.

I wonder, why they didn't just pick a different first byte, like 0x81, or whatever makes a good base58-start.
There's little use for a wallet to import a compressed key when it doesn't yet know how to handle it correctly, and those that do know how to handle it, could easily check for a second prefix on import.

Quote
You should pretty much always do compressed keys for new generation.  There is no reason to ever use uncompressed keys, at least none that I'm aware of.

Brain wallets are by convention uncompressed. While I can now (with help of your answer) create a compressed key from a passphrase and import that into my wallet, I might have a hard time to reconstruct it later for another wallet when I don't have my scripts at hand.

Also, vanitygen doesn't seem to search for vanity compressed keys (at least not the version I've got here).
kjj
legendary
Activity: 1302
Merit: 1026
March 27, 2013, 12:28:43 PM
#6
So when you want to import a private key, the software has to know which of the public keys (with corresponding address) should be used. The solution is to add a flag bit to the base58 encoding of the private key, notifying the importer whether or not to use the compressed public keys. Typically, these get called compressed and uncompressed private keys - but it's really just a bit saying whether the corresponding public key is compressed or not.

Thanks for the explanation.  Being in progress of writing my own library for BTC-stuff,
I tried to "feed" it a compressed key (from my wallet) and an uncompressed key from
vanitygen, and I got a leading (hex)"80" octet for both. The number from the compressed
key was 8 bits longer, though.

Depending on the length (essentially the "ceil(log_2(N))" ) appears a bit fragile to me, for
the decision if the decoded priv-key is intended as a compressed or uncompressed key.
Is software expected to check for leading 5 or L/K on the base58 string, or did I miss
some sound discriminator within this larger N (maybe check it against the order of G
in secp256k1 ?)

If I intended to create a "compressed-key brain wallet", what do I have to do with the
sha²-output (before doing the chksum+base58 stuff) to get a priv-key that I could import
into a standard (sufficiently new) wallet?

Unfortunately, the bitcoin wiki-page about WEF-encoding priv-keys doesn't mention
compressed keys.

(hoping that you still have this thread monitored...)

The private key is always exactly 256 bits, or 32 bytes.  The exact same private key corresponds to two different public keys.  One is uncompressed in the form of (x,y), and the other is compressed in the form of (x,p).  The two forms have different representations, and thus different hashes, and thus different addresses.  The compression flag just tells the system which of the two possible addresses to use.

You should pretty much always do compressed keys for new generation.  There is no reason to ever use uncompressed keys, at least none that I'm aware of.

So, to create the WIF, suitable for importing later, you take the 32 byte binary private key, prepend the 0x80 bytes, and append the 0x01 flag for compression, then run through base58encode and the output is the WIF.  For reference, to create an uncompressed WIF, just don't append the 0x01 before encoding.

To create the matching address, calculate the public key as usual, but when you go to encode it, check the parity of Y.  If Y%2 is even, encode it as 0x02 + x.  If Y%2 is odd, encode it as 0x03 + x.  (Uncompressed, it would be 0x04 + x + y.)  Note that I'm using + to mean concatenation here.  Then the address is created as usual.

If you need to accept WIF as input, after the base58decode step, you'll always have 33 or 34 bytes.  If 33 bytes, it is uncompressed, and the private key is the 32 bytes after the 0x80 header.  If 34 bytes, it is compressed, the last byte must be 0x01, and the private key is everything between the 0x80 header and the 0x01 compression flag.  Once you have the private key and know whether the compression flag was present or not, you can calculate the public key and address as above.
full member
Activity: 216
Merit: 100
March 25, 2013, 06:46:21 AM
#5
So when you want to import a private key, the software has to know which of the public keys (with corresponding address) should be used. The solution is to add a flag bit to the base58 encoding of the private key, notifying the importer whether or not to use the compressed public keys. Typically, these get called compressed and uncompressed private keys - but it's really just a bit saying whether the corresponding public key is compressed or not.

Thanks for the explanation.  Being in progress of writing my own library for BTC-stuff,
I tried to "feed" it a compressed key (from my wallet) and an uncompressed key from
vanitygen, and I got a leading (hex)"80" octet for both. The number from the compressed
key was 8 bits longer, though.

Depending on the length (essentially the "ceil(log_2(N))" ) appears a bit fragile to me, for
the decision if the decoded priv-key is intended as a compressed or uncompressed key.
Is software expected to check for leading 5 or L/K on the base58 string, or did I miss
some sound discriminator within this larger N (maybe check it against the order of G
in secp256k1 ?)

If I intended to create a "compressed-key brain wallet", what do I have to do with the
sha²-output (before doing the chksum+base58 stuff) to get a priv-key that I could import
into a standard (sufficiently new) wallet?

Unfortunately, the bitcoin wiki-page about WEF-encoding priv-keys doesn't mention
compressed keys.

(hoping that you still have this thread monitored...)
legendary
Activity: 1708
Merit: 1010
December 07, 2012, 01:48:05 PM
#4
Well, I guess I was the one confused.
legendary
Activity: 1072
Merit: 1189
December 07, 2012, 01:45:48 PM
#3
From an EC point of view, you have one private key with one corresponding public key.

The problem is, public keys can be serialized in two ways - compressed (33 bytes) or uncompressed (65 bytes). One is slightly harder to deal with, but as storage space is more critical in Bitcoin, we prefer to use the compressed one. Thus, we now have one private key that corresponds to (from Bitcoin's point of view, as we deal with the serialized versions) two public keys. Each of these public keys has an address (as the hash is calculated from the serialized public key). So, 1 private key, 2 public keys, 2 addresses.

So when you want to import a private key, the software has to know which of the public keys (with corresponding address) should be used. The solution is to add a flag bit to the base58 encoding of the private key, notifying the importer whether or not to use the compressed public keys. Typically, these get called compressed and uncompressed private keys - but it's really just a bit saying whether the corresponding public key is compressed or not.

The only reason not to use a compressed public key is that not all software supports it (they were introduced in Bitcoind/Bitcoin-Qt 0.6 only).

@MoonShadow: EC public keys are actually not numbers but a pair of numbers (X and Y coordinate), and the Y coordinate can be calculated from the X coordinate. That is how "compression" works - it's just a somewhat less redundant encoding. Testnet is unrealted to this.
legendary
Activity: 1708
Merit: 1010
December 07, 2012, 01:38:20 PM
#2
One of us is confused.  The public and private keypairs are just really big numbers, and are not compressible.  The leading 5 on a bitcoin address denotes a private key expressed in bitcoin's own format, with a built in checksum.  I know not what the others represent, but could represent keys expressed raw, or keys expressed in the format for the testnet.
member
Activity: 87
Merit: 12
December 07, 2012, 01:33:11 PM
#1
I'd like to create some paper wallets for long-term offline storage.  I realize there are two types of private keys: uncompressed, which begin with a 5; and compressed, which begin with a K or L.  Bitaddress.org appears to generate the uncompressed pairs by default and bitcoind appears to generate the compressed by default.

Since I have a choice of how to generate these keys, are there reasons why I should use one over the other?
Jump to: