The “bu” tool is obsolete, which makes this post not-so-useful. Look at this file instead.

The command line utility “bu” (for “Bitcoin utilities”) 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’s go through some examples.

The most basic form of a Bitcoin private key is simply an integer between 1 and 115792089237316195423570985008687907852837564279074904382605163141518161494336 ≅ 1.15e77 (inclusive). That’s it! This integer is a “secret exponent”, because generating the public key involves exponentiation, and there is no known way to go from the public key to the secret exponent.

Let’s take a look at the very first private key, also known as “1”.

$ bu 1 secret exponent: 1 hex: 1 WIF: KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn uncompressed: 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf public pair x: 55066263022277343669578718895168534326250603453777594175500187360389116729240 public pair y: 32670510020758816978083085130507043184471273380659243275938904335757337482424 x as hex: 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 y as hex: 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 y parity: even key pair as sec: 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 uncompressed: 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\ 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 hash160: 751e76e8199196d454941c45d1b3a323f1433bd6 uncompressed: 91b24bf9f5288532960ac687abb035127b1d28a5 Bitcoin address: 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH uncompressed: 1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm

You can see from blockchain.info that the addresses corresponding to this private key (1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH and 1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm) 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.

There is a bunch of information here. The secret exponent is displayed in decimal and in hex.

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".

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).

So encoding the WIF in this format really provides no additional (non-redundant) information beyond the secret exponent.

The public pair x and y correspond to the ECDSA (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

y*y = x*x*x + 7 (mod P) where P = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f

You can check this easily in Python:

$ python Python 3.3.0 (default, Mar 21 2013, 20:48:16) [GCC 4.2.1 Compatible Apple Clang 4.0 ((tags/Apple/clang-421.0.60))] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f >>> y = 32670510020758816978083085130507043184471273380659243275938904335757337482424 >>> x = 55066263022277343669578718895168534326250603453777594175500187360389116729240 >>> (x*x*x+7) % p 32748224938747404814623910738487752935528512903530129802856995983256684603122 >>> (y * y) % p 32748224938747404814623910738487752935528512903530129802856995983256684603122 >>> print "ta da!" ta da!

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.)

The SEC ("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.

The hash160 value is the ripemd160 hash of the sha256 hash of the bytestream of the sec version of the key.

$ python Python 2.7.2 (default, Oct 11 2012, 20:14:37) [GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import binascii, hashlib >>> sec = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" >>> binascii.hexlify(hashlib.new("ripemd", hashlib.sha256(binascii.unhexlify(sec)).digest()).digest()) '751e76e8199196d454941c45d1b3a323f1433bd6'

The Bitcoin address is the hashed base 58 representation of the hash160 value.

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!)

$ bu 55066263022277343669578718895168534326250603453777594175500187360389116729240,32670510020758816978083085130507043184471273380659243275938904335757337482424 public pair x: 55066263022277343669578718895168534326250603453777594175500187360389116729240 public pair y: 32670510020758816978083085130507043184471273380659243275938904335757337482424 x as hex: 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 y as hex: 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 even key pair as sec: 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 uncompressed: 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\ 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 hash160: 751e76e8199196d454941c45d1b3a323f1433bd6 uncompressed: 91b24bf9f5288532960ac687abb035127b1d28a5 Bitcoin address: 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH uncompressed: 1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm

The input is determined to be x & y coordinates.

$ bu 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH hash160: 751e76e8199196d454941c45d1b3a323f1433bd6 Bitcoin address: 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH

The input here is determined to be a Bitcoin address. The only thing that it can be converted to is a hash160.

Let's try one more example using the WIF from https://en.bitcoin.it/wiki/WIF :

$ bu 0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D secret exponent: 5500171714335001507730457227127633683517613019341760098818554179534751705629 hex: c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d WIF: KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617 uncompressed: 5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ public pair x: 94473386280621915394287615869907363252910868562986308188178980306950346138716 public pair y: 97844737324952875321726721826250953720280326724356638601167669885622888745738 x as hex: d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c y as hex: d85228a6fb29940e858e7e55842ae2bd115d1ed7cc0e82d934e929c97648cb0a y parity: even key pair as sec: 02d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c uncompressed: 04d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c\ d85228a6fb29940e858e7e55842ae2bd115d1ed7cc0e82d934e929c97648cb0a hash160: d9351dcbad5b8f3b8bfa2f2cdc85c28118ca9326 uncompressed: a65d1a239d4ec666643d350c7bb8fc44d2881128 Bitcoin address: 1LoVGDgRs9hTfTNJNuXKSpywcbdvwRXpmK uncompressed: 1GAehh7TsJAHuUAeKZcXf5CnwuGuGgyX2S

Pretty snazzy, eh?