Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do i get compressed public keys? #2

Open
buzztiaan opened this issue Mar 29, 2015 · 12 comments
Open

How do i get compressed public keys? #2

buzztiaan opened this issue Mar 29, 2015 · 12 comments

Comments

@buzztiaan
Copy link

I am making a 'input 64 hexadecimal dice rolls and get two priv/pub keys' program, and was looking for some speedincrease.

Your library seems faster than my current code, but, i fail to be able to get the compressed keys from it.
Care to write a small example for that?

This gives me the uncompressed one ;

my $privkey = new EC::DSA::PrivateKey 1;
my $key = new Bitcoin::Key $privkey;

print $key;
print "\n";
print $key->address;
print "\n";

Was messing with EC::DSA::PublicKey::UnCompressed but doesnt seem to even be used to make an address?

@grondilu
Copy link
Owner

I've just looked at the code (which I haven't done for years btw) and apparently I wrote a "compress" method. So you should be able to do something like:

my $privkey->public_key->compress

and get the compressed version of the public key.

@buzztiaan
Copy link
Author

But don't I need it on the EC::DSA::PrivateKey?

The Bitcoin::Key doesnt have a public_key method, nor a compress ..
As far as I can see, only EC::DSA::PublicKey::UnCompressed has the compress method, but as far as i can see I can't use it's output to feed into Bitcoin::Key to get a priv/pubkey pair to use for the wallet?

@buzztiaan
Copy link
Author

oh, EC::DSA::PrivateKey -does- have public_key method which gets me the following result;

my $privkey = new EC::DSA::PrivateKey 1;

print $privkey->public_key->compress;
print "\n";

Output :

point is not on elliptic curve at EC.pm line 46.
in add at EC.pm line 59.

@grondilu
Copy link
Owner

I can't reproduce your error. The following works on my machine:

use EC::DSA qw(secp256k1);
say my $privkey = new EC::DSA::PrivateKey 1;
my $pubkey = bless $privkey->public_key, "EC::DSA::PublicKey::UnCompressed";
say $pubkey->compress;

As you can see I had to bless the public key manually in order to access the compress method, though. That should be automatic.

@buzztiaan
Copy link
Author

Ehr, maybe i am missing some step then O_o

use Bitcoin;
my $privkey = new EC::DSA::PrivateKey 1;
my $pubkey = $privkey->public_key;

print $pubkey;
print "\n";

my $pubkey = bless $privkey->public_key, "EC::DSA::PublicKey::UnCompressed";

print $pubkey -> compress;
print "\n";

This outputs:


x: 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
y: 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8


x: 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
y: 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8

@grondilu
Copy link
Owner

The only difference between a compressed public key and an uncompressed one is the "serialize" method, which is not used for pretty print (what you get when you print the object). This is maybe not the best, but apparently that's how I ended up implementing it.

If you want the compressed output to show up on the screen you have to call the serialize method and unpack it (because it's binary).

say unpack "H*", $compressed_public_key->serialize;

@buzztiaan
Copy link
Author

Then i still don't seem to be able to feed the compressed key into Bitcoin::Key :(

I think somehow i need to tell Bitcoin::Key to use the other serializer?

@grondilu
Copy link
Owner

Bitcoin::Key inherits from EC::DSA::PrivateKey. A private key is a secret exponent, and as such it is just a natural integer. There is no compression format for this. Only the public key can be compressed. So you feed Bitcoin::Key with an integer, you get the public key with the public_key method, then you bless it with EC::DSA::PublicKey::Compressed, and then you call the serialize method.

You can also explicitly call the serializer you want indeed:

say EC::DSA::PublicKey::Compressed::serialize($pubKey);

@buzztiaan
Copy link
Author

But then how do i turn that back into a Bitcoin::Key so i can create the WIF and address to feed into a wallet?

@buzztiaan
Copy link
Author

Or actually, feed to a QR printer ;)

@grondilu
Copy link
Owner

Trying making the address manually:

my $address =  new Bitcoin::Address bless $priv_key->public_key, "EC::DSA::PublicKey::Compressed";

I can't test this myself as I don't have all required modules anymore.

@buzztiaan
Copy link
Author

So,

my $privkey = new EC::DSA::PrivateKey 1;
my $address = new Bitcoin::Address bless $privkey->public_key, "EC::DSA::PublicKey::Compressed";

dies in a

point is not on elliptic curve at EC.pm line 46.
in add at EC.pm line 59.

And this creates -a- address, but the wrong one;

my $privkey = new EC::DSA::PrivateKey 1;

my $compkey = new Bitcoin::Key $privkey;
my $compkey = bless $compkey->public_key, "EC::DSA::PublicKey::Compressed";

my $address = new Bitcoin::Address bless $compkey, "EC::DSA::PublicKey::Compressed";

This outputs the address 12aJDuq56zPqWB31AHL38MUhNmr9xFNo3K but according to bitaddress , for secret exponent 0x1 it should be 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants