qqq123 (OP)
Newbie
Offline
Activity: 11
Merit: 0
|
|
April 26, 2012, 04:52:46 AM |
|
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.
|
|
|
|
|
|
|
|
Every time a block is mined, a certain amount of BTC (called the
subsidy) is created out of thin air and given to the miner. The
subsidy halves every four years and will reach 0 in about 130 years.
|
|
|
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
|
|
|
|
|
qqq123 (OP)
Newbie
Offline
Activity: 11
Merit: 0
|
|
April 26, 2012, 01:44:10 PM |
|
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.
|
|
|
|
payb.tc
|
|
April 26, 2012, 01:51:30 PM |
|
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) define("ADDRESSVERSION","00"); //this is a hex byte function decodeHex($hex) { $hex=strtoupper($hex); $chars="0123456789ABCDEF"; $return="0"; for($i=0;$i<strlen($hex);$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<strlen($base58);$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<strlen($origbase58)&&$origbase58[$i]=="1";$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<strlen($orighex)&&substr($orighex,$i,2)=="00";$i+=2) { $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; }
|
|
|
|
qqq123 (OP)
Newbie
Offline
Activity: 11
Merit: 0
|
|
April 26, 2012, 02:06:57 PM |
|
That's from here, and I don't think it can be used to go from a private key to a public key.
|
|
|
|
|
|
payb.tc
|
|
April 27, 2012, 02:49:26 AM |
|
That's from here, and I don't think it can be used to go from a private key to a public key. * @author theymos (functionality) ah yeah, from before mike put it in a class.
|
|
|
|
qqq123 (OP)
Newbie
Offline
Activity: 11
Merit: 0
|
|
April 27, 2012, 07:09:55 PM Last edit: April 27, 2012, 07:25:58 PM by qqq123 |
|
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.
|
|
|
|
qqq123 (OP)
Newbie
Offline
Activity: 11
Merit: 0
|
|
April 28, 2012, 03:04:44 AM |
|
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) = 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...
|
|
|
|
|
|
bitdumper
Sr. Member
Offline
Activity: 266
Merit: 250
One world One currency, Bitcoin.
|
|
April 05, 2016, 04:20:02 AM |
|
|
|
|
|
|