Bitcoin Forum
November 18, 2017, 08:38:55 AM *
News: Latest stable version of Bitcoin Core: 0.15.1  [Torrent].
 
   Home   Help Search Donate Login Register  
Pages: [1]
  Print  
Author Topic: How to get uncompressed public key from compressed one ?  (Read 2688 times)
Farghaly
Jr. Member
*
Offline Offline

Activity: 38


View Profile
June 08, 2014, 11:48:14 PM
 #1

Uncompressed public key is:
0x04 + x-coordinate + y-coordinate

Compressed public key is:
0x02 + x-coordinate if y is even
0x03 + x-coordinate if y is odd

How to use this equation to derive the uncompressed public key

y^2 mod p = (x^3 + 7) mod p

 

1510994335
Hero Member
*
Offline Offline

Posts: 1510994335

View Profile Personal Message (Offline)

Ignore
1510994335
Reply with quote  #2

1510994335
Report to moderator
A blockchain platform for effective freelancing
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
TimS
Sr. Member
****
Offline Offline

Activity: 247


View Profile WWW
June 09, 2014, 12:53:21 AM
 #2

From https://en.wikipedia.org/wiki/Quadratic_residue and http://mersennewiki.org/index.php/Modular_Square_Root, if

r^2 = a mod m where m = 3 mod 4 (as secp256k1's p does)
then
r = +-a^((m+1)/4) mod m

So:

y^2 mod p = (x^3 + 7) mod p
y mod p = +-(x^3 + 7)^((p+1)/4) mod p

So calculate (x^3 + 7)^((p+1)/4) mod p, and if the parity of the first answer you get is wrong, then take the negative of that answer (since we're working modulo an odd number, taking the negative will flip the even/odd parity).

Just for fun, here's some Python code that'll do the calculation in the blink of an eye, preset to work on the public key of (the random) private key 55255657523dd1c65a77d3cb53fcd050bf7fc2c11bb0bb6edabdbd41ea51f641

Code:
def pow_mod(x, y, z):
    "Calculate (x ** y) % z efficiently."
    number = 1
    while y:
        if y & 1:
            number = number * x % z
        y >>= 1
        x = x * x % z
    return number

p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
compressed_key = '0314fc03b8df87cd7b872996810db8458d61da8448e531569c8517b469a119d267'
y_parity = int(compressed_key[:2]) - 2
x = int(compressed_key[2:], 16)
a = (pow_mod(x, 3, p) + 7) % p
y = pow_mod(a, (p+1)//4, p)
if y % 2 != y_parity:
    y = -y % p
uncompressed_key = '04{:x}{:x}'.format(x, y)
print(uncompressed_key)
deepceleron
Legendary
*
Offline Offline

Activity: 1512



View Profile WWW
June 09, 2014, 06:07:36 PM
 #3

Be mindful that there is no practical reason to "convert" between uncompressed and compressed public keys. Each has their own Bitcoin address - you cannot spend funds sent to the uncompressed public key's address with the compressed public key.

ftc-c
Jr. Member
*
Offline Offline

Activity: 31


View Profile
May 09, 2015, 03:05:01 PM
 #4

Who can give a C++ implementation ?
fbueller
Sr. Member
****
Offline Offline

Activity: 412


View Profile
May 10, 2015, 01:01:24 AM
 #5

@ftc-c: Use libsecp256k1, AFAIK it has preprocessor stuff for C++ support, and it's easy enough to work through.

Bitwasp Developer.
samson
Legendary
*
Offline Offline

Activity: 1246


View Profile
May 10, 2015, 05:22:53 PM
 #6

The following link shows how to do it in C using the polarssl / mbedTLS library, you should be able to port this across a different crypto library so long as it has a proper 'bignum'/mpi implementation.

https://gist.github.com/flying-fury/6bc42c8bb60e5ea26631

The above example contains test data as well, from the comments '// Set y2 = X^3 + B' and '// Compute square root of y2' you can see where the important part is done.

I used the above to make a dll/so/dylib which does this useful conversion based on the above code.

What deepceleron said also applies, there are two distinct coin addresses which can be created from a single private key depending on whether the public key is 'compressed' or not.

The above conversion is still useful if you use ECC for things like verifying signatures.
CIYAM
Legendary
*
Offline Offline

Activity: 1862


Ian Knowles - CIYAM Lead Developer


View Profile WWW
May 10, 2015, 05:28:55 PM
 #7

Welcome to use the CIYAM code which includes parts of the Bitcoin code as well (but might be easier to follow in terms of the C++ classes as it doesn't involve any Boost stuff).

https://github.com/ciyam/ciyam/blob/master/src/crypto_keys.cpp

With CIYAM anyone can create 100% generated C++ web applications in literally minutes.

GPG Public Key | 1ciyam3htJit1feGa26p2wQ4aw6KFTejU
Blockchain Mechanic
Full Member
***
Offline Offline

Activity: 224

www.patreon.com/blockmechanic


View Profile WWW
January 09, 2017, 08:46:38 AM
 #8

Be mindful that there is no practical reason to "convert" between uncompressed and compressed public keys. Each has their own Bitcoin address - you cannot spend funds sent to the uncompressed public key's address with the compressed public key.

Hi

So I could use both addresses to receive funds so long as i have the one private key?


Equality vs Equity...
ranochigo
Legendary
*
Online Online

Activity: 1260

In the midst of an exam, will be very inactive.


View Profile WWW
January 09, 2017, 01:22:30 PM
 #9

Be mindful that there is no practical reason to "convert" between uncompressed and compressed public keys. Each has their own Bitcoin address - you cannot spend funds sent to the uncompressed public key's address with the compressed public key.

Hi

So I could use both addresses to receive funds so long as i have the one private key?


Yes. The compressed public key and the uncompressed ones have different public keys but they can be derived from the same private key. However, they may be different in the Wallet Import Format, private keys starting with 5 are compressed while the uncompressed ones starts from K or L.














 

 

█ 
█ 
█ 
█ 
█ 
█ 
█ 
█ 
█ 
█ 
█ 
BitBlender 

 













 















 












 
█ 
█ 
█ 
█ 
█ 
█ 
█ 
█ 
█ 
█ 
█ 
Pages: [1]
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!