Author

Topic: Private key to Public key (Read 18503 times)

sr. member
Activity: 266
Merit: 250
One world One currency, Bitcoin.
April 04, 2016, 11:20:02 PM
#13
If your backend is python
https://github.com/weex/addrgen

If it's php
https://github.com/RobKohr/PHP-Bitcoin-Address-Creator

If it's nodejs
Then
This is an old thread.
But just for people who land here and actually want to understand how to code the calculation from private to public key
See here:
http://procbits.com/2013/08/27/generating-a-bitcoin-address-with-javascript

newbie
Activity: 40
Merit: 0
April 04, 2016, 05:59:22 PM
#12
This is an old thread.
But just for people who land here and actually want to understand how to code the calculation from private to public key
See here:
http://procbits.com/2013/08/27/generating-a-bitcoin-address-with-javascript
full member
Activity: 202
Merit: 100
June 23, 2013, 06:12:53 PM
#11
Since this thread comes up on top when searching for priv key to pub key conversion, here is a link to a self-contained python file where you can see all the background mechanics.

https://bitcointalksearch.org/topic/solved-python-secp256k1-23241
newbie
Activity: 11
Merit: 0
April 27, 2012, 10:04:44 PM
#10
If anyone has any test problems I can run for point multiplication on the secp256k1 curve that would be great.  I think I have the implementation down, but the fact that everything is in hex is giving me fits.  I would love to be able to verify that the point multiplication works in decimal before moving on the tackling hex.

Doing the math by hand, I know that 2 * (4, 3) = (56, -419).
But doing large multiplications by hand is impossible.
For example, 100 * (4, 3) = Huh

And for actually doing the point multiplication required by bitcoin...

Let's say privatekey (in hex) = 059E2BF5E2C7A4098C164B29A91CF70508D2FD1A256A60656FD2593BDB980FAA
so privatekey in dec = 2541029483313867478679144795827841690699430215057902992954466247848698056618
Gx (in hex) = 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
so Gx in dec = 55066263022277343669578718895168534326250603453777594175500187360389116729240
Gy (in hex) = 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8
so Gy in dec = 32670510020758816978083085130507043184471273380659243275938904335757337482424

so, given that privatekey * (Gx, Gy) = publickey
the math is (in dec): 2541029483313867478679144795827841690699430215057902992954466247848698056618 * (55066263022277343669578718895168534326250603453777594175500187360389116729240, 32670510020758816978083085130507043184471273380659243275938904335757337482424).

Having a real hard time seeing if my function works with numbers that big...
newbie
Activity: 11
Merit: 0
April 27, 2012, 02:09:55 PM
#9
Thanks for the replies.  From what I've read I've gathered that:

PuK = G * PrK

where PuK is the public key, G is the set of (x, y) coordinates for the secp256k1 elliptic curve, which are, in hex, (x = 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798, y = 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8), PrK is the private key, and * stands for point multiplication.

I am, however, having trouble implementing point multiplication.  I've read the wiki article here, and understand that it's basically doubling and adding the point, but I can't quite wrap my head around the pseudocode they give.  Can anyone help with that?  I'm working in php, but anything would help really.

Thanks.
hero member
Activity: 812
Merit: 1000
April 26, 2012, 09:49:26 PM
#8
That's from here, and I don't think it can be used to go from a private key to a public key.

Quote
* @author theymos (functionality)

ah yeah, from before mike put it in a class.
legendary
Activity: 2506
Merit: 1010
April 26, 2012, 09:29:33 PM
#7
The website will be capable of dynamically creating a private key and the corresponding public key and Bitcoin address (much like bitaddress.org)

Doesn't explain the math behind it, but an example of it is in the Javascript from the HTML source here:
 - http://BitAddress.org

[Update: More info here?
 - https://bitcointalksearch.org/topic/speeding-up-signature-verification-3238
 - https://bitcointalksearch.org/topic/elliptic-curve-math-question-53177
 - https://bitcointalksearch.org/topic/question-about-address-generation-74136 ]
hero member
Activity: 742
Merit: 500
April 26, 2012, 12:56:04 PM
#6
So you want to know how the initial private and public key are created with ECDSA?  "Complex Math" is as far as I've gone into that one personally.

http://en.wikipedia.org/wiki/Elliptic_Curve_DSA
newbie
Activity: 11
Merit: 0
April 26, 2012, 09:06:57 AM
#5
That's from here, and I don't think it can be used to go from a private key to a public key.
hero member
Activity: 812
Merit: 1000
April 26, 2012, 08:51:30 AM
#4
if the private key is a hex string, try following the below functions.

(apologies to the author, i don't remember where i found this code)

Code:
define("ADDRESSVERSION","00"); //this is a hex byte
 
function decodeHex($hex)
{
        $hex=strtoupper($hex);
        $chars="0123456789ABCDEF";
        $return="0";
        for($i=0;$i        {
                $current=(string)strpos($chars,$hex[$i]);
                $return=(string)bcmul($return,"16",0);
                $return=(string)bcadd($return,$current,0);
        }
        return $return;
}
 
function encodeHex($dec)
{
        $chars="0123456789ABCDEF";
        $return="";
        while (bccomp($dec,0)==1)
        {
                $dv=(string)bcdiv($dec,"16",0);
                $rem=(integer)bcmod($dec,"16");
                $dec=$dv;
                $return=$return.$chars[$rem];
        }
        return strrev($return);
}
 
function decodeBase58($base58)
{
        $origbase58=$base58;
       
        $chars="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
        $return="0";
        for($i=0;$i        {
                $current=(string)strpos($chars,$base58[$i]);
                $return=(string)bcmul($return,"58",0);
                $return=(string)bcadd($return,$current,0);
        }
       
        $return=encodeHex($return);
       
        //leading zeros
        for($i=0;$i        {
                $return="00".$return;
        }
       
        if(strlen($return)%2!=0)
        {
                $return="0".$return;
        }
       
        return $return;
}
 
function encodeBase58($hex)
{
        if(strlen($hex)%2!=0)
        {
                die("encodeBase58: uneven number of hex characters");
        }
        $orighex=$hex;
       
        $chars="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
        $hex=decodeHex($hex);
        $return="";
        while (bccomp($hex,0)==1)
        {
                $dv=(string)bcdiv($hex,"58",0);
                $rem=(integer)bcmod($hex,"58");
                $hex=$dv;
                $return=$return.$chars[$rem];
        }
        $return=strrev($return);
       
        //leading zeros
        for($i=0;$i        {
                $return="1".$return;
        }
       
        return $return;
}
 
function hash160ToAddress($hash160,$addressversion=ADDRESSVERSION)
{
        $hash160=$addressversion.$hash160;
        $check=pack("H*" , $hash160);
        $check=hash("sha256",hash("sha256",$check,true));
        $check=substr($check,0,8);
        $hash160=strtoupper($hash160.$check);
        return encodeBase58($hash160);
}
 
function addressToHash160($addr)
{
        $addr=decodeBase58($addr);
        $addr=substr($addr,2,strlen($addr)-10);
        return $addr;
}
 
function checkAddress($addr,$addressversion=ADDRESSVERSION)
{
        $addr=decodeBase58($addr);
        if(strlen($addr)!=50)
        {
                return false;
        }
        $version=substr($addr,0,2);
        if(hexdec($version)>hexdec($addressversion))
        {
                return false;
        }
        $check=substr($addr,0,strlen($addr)-8);
        $check=pack("H*" , $check);
        $check=strtoupper(hash("sha256",hash("sha256",$check,true)));
        $check=substr($check,0,8);
        return $check==substr($addr,strlen($addr)-8);
}
 
function hash160($data)
{
        $data=pack("H*" , $data);
        return strtoupper(hash("ripemd160",hash("sha256",$data,true)));
}
 
function pubKeyToAddress($pubkey)
{
        return hash160ToAddress(hash160($pubkey));
}
 
function remove0x($string)
{
        if(substr($string,0,2)=="0x"||substr($string,0,2)=="0X")
        {
                $string=substr($string,2);
        }
        return $string;
}
newbie
Activity: 11
Merit: 0
April 26, 2012, 08:44:10 AM
#3
I've read that article more times than I can count.  It still doesn't explain the equation(s) used to go from the private key to the public key.  It just says "1) Have a private ECDSA key. 2) Take the public key generated with it (65 bytes, 1 byte 0x04, 32 bytes corresponding to X coordinate, 32 bytes corresponding to Y coordinate)."  I do not understand how that public key is generated, despite reading several articles on elliptic curve cryptography.
hero member
Activity: 742
Merit: 500
newbie
Activity: 11
Merit: 0
April 25, 2012, 11:52:46 PM
#1
Hello,

I am here looking for an understanding of the math behind converting a Bitcoin private key to a Bitcoin public key for a website I am creating.  The website will be capable of dynamically creating a private key and the corresponding public key and Bitcoin address (much like bitaddress.org).

If anyone can help with this understanding, I'd appreciate it.

Thanks.
Jump to: