{"id":371,"date":"2013-10-26T15:58:06","date_gmt":"2013-10-26T23:58:06","guid":{"rendered":"http:\/\/blog.richardkiss.com\/?p=371"},"modified":"2021-02-05T17:30:13","modified_gmt":"2021-02-06T01:30:13","slug":"messing-with-bitcoin-keys-and-addresses","status":"publish","type":"post","link":"https:\/\/blog.richardkiss.com\/?p=371","title":{"rendered":"Messing with Bitcoin Keys and Addresses"},"content":{"rendered":"<p><strong>The &#8220;bu&#8221; tool is obsolete, which makes this post not-so-useful. Look at <a href=\"https:\/\/github.com\/richardkiss\/pycoin\/blob\/master\/COMMAND-LINE-TOOLS.md\" title=\"https:\/\/github.com\/richardkiss\/pycoin\/blob\/master\/COMMAND-LINE-TOOLS.md\" target=\"_blank\" rel=\"noopener\">this file<\/a> instead.<\/strong><\/p>\n<p>The command line utility &#8220;bu&#8221; (for &#8220;Bitcoin utilities&#8221;) is included with my Python-based <a href=\"https:\/\/github.com\/richardkiss\/pycoin\">pycoin<\/a> library. This utility makes it easy to deal with Bitcoin private keys and addresses in their native and various intermediate formats. Let&#8217;s go through some examples.<\/p>\n<p>The most basic form of a Bitcoin private key is simply an integer between 1 and 115792089237316195423570985008687907852837564279074904382605163141518161494336 ? 1.15e77 (inclusive). That&#8217;s it! This integer is a &#8220;secret exponent&#8221;, because generating the public key involves exponentiation, and there is no known way to go from the public key to the secret exponent.<\/p>\n<p>Let&#8217;s take a look at the very first private key, also known as &#8220;1&#8221;.<\/p>\n<pre><code>\r\n$ bu 1\r\nsecret exponent: 1\r\n  hex:           1\r\nWIF:             KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn\r\n  uncompressed:  5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\r\npublic pair x:   55066263022277343669578718895168534326250603453777594175500187360389116729240\r\npublic pair y:   32670510020758816978083085130507043184471273380659243275938904335757337482424\r\n  x as hex:      79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\r\n  y as hex:      483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\r\ny parity:        even\r\nkey pair as sec: 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\r\n  uncompressed:  0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\\\r\n                   483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\r\nhash160:         751e76e8199196d454941c45d1b3a323f1433bd6\r\n  uncompressed:  91b24bf9f5288532960ac687abb035127b1d28a5\r\nBitcoin address: 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH\r\n  uncompressed:  1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm\r\n<\/pre>\n<p><\/code><\/p>\n<p>You can see from blockchain.info that the addresses corresponding to this private key (<a href=\"https:\/\/blockchain.info\/address\/1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH\">1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH<\/a> and <a href=\"https:\/\/blockchain.info\/address\/1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm\">1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm<\/a>) are used a lot in tests. Of course, neither has any funds in it (well, at least not at this time), since draining the funds is as simple as entering one of the WIF values above into a Bitcoin client.<\/p>\n<p>There is a bunch of information here. The secret exponent is displayed in decimal and in hex.<\/p>\n<p>The corresponding WIF (\"wallet import format\") key is displayed, both in compressed and uncompressed format; with this information, you can import the corresponding bitcoin address into your client. Note that the WIF simply contains the exponent encoded using \"hashed base 58\".<\/p>\n<p>The \"hashed base 58\" encoding is used to represent an integer with a checksum for validity. A 32-bit checksum is appended to the binary form of the integer, forming another integer. This integer is then represented in base 58 using the alphabet of all digits and all letters of the upper and lower case English alphabet except 0, o, O and l (presumably left out because of potential confusion).<\/p>\n<p>So encoding the WIF in this format really provides no additional (non-redundant) information beyond the secret exponent.<\/p>\n<p>The public pair x and y correspond to the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Elliptic_Curve_DSA\">ECDSA<\/a> (elliptical curve digital signature algorithm) public key that is used to verify digital signatures. Bitcoin clients use public keys to validate that transactions are signed by an entity that has knowledge of the corresponding secret exponent. The x, y value is on the elliptical curve used by bitcoin. In other words<\/p>\n<pre><code>y*y = x*x*x + 7 (mod P)\r\n\r\nwhere P = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f<\/code><\/pre>\n<p>You can check this easily in Python:<\/p>\n<pre><code>\r\n$ python\r\nPython 3.3.0 (default, Mar 21 2013, 20:48:16) \r\n[GCC 4.2.1 Compatible Apple Clang 4.0 ((tags\/Apple\/clang-421.0.60))] on darwin\r\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\r\n>>> p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\r\n>>> y = 32670510020758816978083085130507043184471273380659243275938904335757337482424\r\n>>> x = 55066263022277343669578718895168534326250603453777594175500187360389116729240\r\n>>> (x*x*x+7) % p\r\n32748224938747404814623910738487752935528512903530129802856995983256684603122\r\n>>> (y * y) % p\r\n32748224938747404814623910738487752935528512903530129802856995983256684603122\r\n>>> print \"ta da!\"\r\nta da!\r\n<\/code><\/pre>\n<p>For a given x value, you can rewrite as y = sqrt(x^3+7) (mod P). Since numbers have two square roots even in a finite field, there are two values y0 and y1 that satisfy this equation, where y1 = P - y0. Since P is odd, exactly one of y0 and y1 is even, and the other is odd. In other words, with x and knowledge of whether y is even or odd, we can figure out the value for y. (This is how compressed keys work... they include the value for x along with a boolean indicating even or odd rather than the full value for y.)<\/p>\n<p>The <a href=\"http:\/\/www.secg.org\/\">SEC<\/a> (\"Standards for Efficient Cryptography\") format provides an alternate way of encoding the public key. This is the internal format that Bitcoin uses in transaction signatures to encode public keys. There is an uncompressed format, which has a prefix of a single 04 byte, followed by the x and y coordinates, and a compressed format, which has a prefix of 02 or 03 depending upon whether the y coordinate is even or odd, followed by the x coordinate.<\/p>\n<p>The hash160 value is the ripemd160 hash of the sha256 hash of the bytestream of the sec version of the key.<\/p>\n<pre><code>\r\n$ python\r\nPython 2.7.2 (default, Oct 11 2012, 20:14:37) \r\n[GCC 4.2.1 Compatible Apple Clang 4.0 (tags\/Apple\/clang-418.0.60)] on darwin\r\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\r\n>>> import binascii, hashlib\r\n>>> sec = \"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\"\r\n>>> binascii.hexlify(hashlib.new(\"ripemd\", hashlib.sha256(binascii.unhexlify(sec)).digest()).digest()) \r\n'751e76e8199196d454941c45d1b3a323f1433bd6'\r\n<\/code><\/pre>\n<p>The Bitcoin address is the hashed base 58 representation of the hash160 value.<\/p>\n<p>The bu utility will accept input in nearly any format, automatically determining the input type, and display output of all values that can calculated. (Obviously if you enter a Bitcoin address, you won't get the corresponding WIF!)<\/p>\n<pre><code>\r\n$ bu 55066263022277343669578718895168534326250603453777594175500187360389116729240,32670510020758816978083085130507043184471273380659243275938904335757337482424\r\npublic pair x:   55066263022277343669578718895168534326250603453777594175500187360389116729240\r\npublic pair y:   32670510020758816978083085130507043184471273380659243275938904335757337482424\r\n  x as hex:      79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\r\n  y as hex:      483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\r\neven\r\nkey pair as sec: 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\r\n  uncompressed:  0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\\\r\n                   483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\r\nhash160:         751e76e8199196d454941c45d1b3a323f1433bd6\r\n  uncompressed:  91b24bf9f5288532960ac687abb035127b1d28a5\r\nBitcoin address: 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH\r\n  uncompressed:  1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm\r\n<\/code><\/pre>\n<p>The input is determined to be x & y coordinates.<\/p>\n<pre><code>\r\n$ bu 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH\r\nhash160:         751e76e8199196d454941c45d1b3a323f1433bd6\r\nBitcoin address: 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH\r\n<\/code><\/pre>\n<p>The input here is determined to be a Bitcoin address. The only thing that it can be converted to is a hash160. <\/p>\n<p>Let's try one more example using the WIF from <a href=\"https:\/\/en.bitcoin.it\/wiki\/WIF\">https:\/\/en.bitcoin.it\/wiki\/WIF<\/a> :<\/p>\n<pre><code>\r\n$ bu 0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D\r\nsecret exponent: 5500171714335001507730457227127633683517613019341760098818554179534751705629\r\n  hex:           c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d\r\nWIF:             KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617\r\n  uncompressed:  5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ\r\npublic pair x:   94473386280621915394287615869907363252910868562986308188178980306950346138716\r\npublic pair y:   97844737324952875321726721826250953720280326724356638601167669885622888745738\r\n  x as hex:      d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c\r\n  y as hex:      d85228a6fb29940e858e7e55842ae2bd115d1ed7cc0e82d934e929c97648cb0a\r\ny parity:        even\r\nkey pair as sec: 02d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c\r\n  uncompressed:  04d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c\\\r\n                   d85228a6fb29940e858e7e55842ae2bd115d1ed7cc0e82d934e929c97648cb0a\r\nhash160:         d9351dcbad5b8f3b8bfa2f2cdc85c28118ca9326\r\n  uncompressed:  a65d1a239d4ec666643d350c7bb8fc44d2881128\r\nBitcoin address: 1LoVGDgRs9hTfTNJNuXKSpywcbdvwRXpmK\r\n  uncompressed:  1GAehh7TsJAHuUAeKZcXf5CnwuGuGgyX2S\r\n<\/code><\/pre>\n<p>Pretty snazzy, eh?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The &#8220;bu&#8221; tool is obsolete, which makes this post not-so-useful. Look at this file instead. The command line utility &#8220;bu&#8221; (for &#8220;Bitcoin utilities&#8221;) is included with my Python-based pycoin library. This utility makes it easy to deal with Bitcoin private keys and addresses in their native and various intermediate formats. Let&#8217;s go through some examples. &hellip; <a href=\"https:\/\/blog.richardkiss.com\/?p=371\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Messing with Bitcoin Keys and Addresses<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-371","post","type-post","status-publish","format-standard","hentry","category-computers"],"_links":{"self":[{"href":"https:\/\/blog.richardkiss.com\/index.php?rest_route=\/wp\/v2\/posts\/371","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.richardkiss.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.richardkiss.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.richardkiss.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.richardkiss.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=371"}],"version-history":[{"count":21,"href":"https:\/\/blog.richardkiss.com\/index.php?rest_route=\/wp\/v2\/posts\/371\/revisions"}],"predecessor-version":[{"id":598,"href":"https:\/\/blog.richardkiss.com\/index.php?rest_route=\/wp\/v2\/posts\/371\/revisions\/598"}],"wp:attachment":[{"href":"https:\/\/blog.richardkiss.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=371"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.richardkiss.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=371"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.richardkiss.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=371"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}