Nov. 21, 2013
1 of 28

• 1. Bitcoin Addresses How they are generated from public keys (a step-by-step guide) Ash Moran aviewfromafar.net ash@ashleymoran.net
• 2. Anatomy of an Address 1kqHKEYYC8CQPxyV53nCju4Lk2ufpQqA2 address  preﬁx Base58Check encoding of the cryptographic hash  of something  (indicated by the preﬁx)
• 4. What’s Base58? Represents numbers (eg decimal, base ten, numbers using the digits 0-9) using 58 characters Uses 1-9, most of A-Z and a-z, except: No letter capital i (I), lowercase L (l), O or 0 Like hexadecimal, but with more digits
• 5. What’s hexadecimal? Represents numbers (eg decimal, base ten, numbers using the digits 0-9) using 16 characters Uses 0-9, A-F A = 10, B = 11, etc
• 7. Hexadecimal example C6A = 2 + 6 * 161 + 10 * 160 = 12 * 16 12 * (256) + 6 * (16) + 10 * (1) = 3178
• 9. Base58 example 4iX = 2 + 41 * 581 + 30 * 580 = 3 * 58 3 * (3364) + 41 * (58) + 30 * (1) = 12500
• 11. Hashing A hash function takes a value in eg “This is my message” Returns a ﬁxed length number out eg 1129729371291755845 Generates a different number if the input changes even slightly “This it my message” => 3763820994290329705
• 12. Cryptographic hashing Like hashing but designed so it’s very very hard to ﬁgure out the message from the hash. hash_function(“This is my message”) => hash_value – EASY! hash_value => <?what was the message?> – HARD! Bitcoin uses SHA256 and RIPEMD-160 hash functions SHA256(“This is my message”) =>  3311b7c0bd91b6c73a38212de8ade31c51910f17480ad212ed2b9798a35b7747 SHA256(“This it my message”) => 26a9911800b6115eb7ee508f60a2fd6479d45155a8aef1b1a35eb3173a512063 RIPEMD160(“This is my message”) =>  bdb6824f7b28e7dd9b9d6b457142547064435937
• 13. Base58 version of a hash RIPEMD160(“This is my message”) =>  bdb6824f7b28e7dd9b9d6b457142547064435937 hex:   bdb6824f7b28e7dd9b9d6b457142547064435937   decimal: 1083069342955023797228115257453753838398332950839 Base58(1083069342955023797228115257453753838398332 950839) =>  3eJ7uPEgX8h56UJmTNmqwTvHs9H8
• 15. Public/private key signing Problem: Alice wants to send Bob a message and want anybody to be able to verify that the message came from her. She wants to make sure nobody can forge her signature on the message.
• 16. Elliptic Curve Cryptography See the excellent guide A (relatively easy to understand) primer on elliptic curve cryptography by Nick Sullivan
• 17. Elliptic Curve Cryptography Private key: a random 256-bit (32-byte) integer Public key: an (x, y) point on the curve, either: the number 4, followed by 256-bit x and y coordinates (old uncompressed 65-byte format)  [4, x, y] the number 2 or 3 followed by a 256-bit x coordinate (new compressed 33-byte format)  [2, x, y] or [3, x, y]
• 19. European Article Number Colgate Total 75 ml 4011200296908
• 20. Colgate Total 75ml EAN checksum Total of odd numbers = 25 27 + 25 = 52 Last digit of 52 = 2 4 0 1 1 2 0 0 2 9 6 9 0 8 Total of even numbers = 9  9 * 3 = 27 10 - 2 = 8 yay!
• 21. Step 5: Putting it together
• 22. Bitcoin pubkey address Take the pubkey with header byte, e.g. [4, x, y] Run it through the SHA256 hash function  pubkey_hash_step_1 = SHA256([4, x, y]) Run it through the RIPEMD160 hash function  pubkey_hash = RIPEMD160(pubkey_hash_step_1) Add a byte to the start to indicate which network it’s for (Bitcoin 00, Namecoin 34, Bitcoin testnet 6f)  plain_binary_address = [00, pubkey_hash] TBC…
• 23. Checksum generation Take the plain binary address, and run it through the SHA256 function twice:  plain_address_hash = SHA256(SHA256(plain_binary_address)) Take the ﬁrst four bytes of this hash as a checksum:  checksum = ﬁrst_4_bytes(plain_binary_address) Add the checksum onto the end to give the binary_address:  binary_address = [00, pubkey_hash, checksum] Base58 encode the result:  bitcoin_address = Base58(binary_address) Now we have the result, eg “16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM”
• 24. Demo! (source for live demo now on the next slide)
• 25. Example Ruby source require 'bitcoin' ! def hex_string_to_bytes(string) [string].pack("H*") end ! def bytes_to_hex_string(bytes) bytes.unpack("H*").first end ! # https://en.bitcoin.it/wiki/Technical_background_of_Bitcoin_addresses private_key_hex_string = "18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725" ! key = Bitcoin::Key.new(private_key_hex_string) pub_key_bytes = hex_string_to_bytes(key.pub_uncompressed) ! hash_step_1 = Digest::SHA256.digest(pub_key_bytes) hash160 = Digest::RMD160.digest(hash_step_1) hash160_hex_string = bytes_to_hex_string(hash160) ! versioned_hash160_hex_string = "00" + hash160_hex_string versioned_hash160 = hex_string_to_bytes(versioned_hash160_hex_string) ! checksum_hash_round_1 = Digest::SHA256.digest(versioned_hash160) checksum_hash_round_2 = Digest::SHA256.digest(checksum_hash_round_1) checksum = checksum_hash_round_2[0,4] ! binary_address = versioned_hash160 + checksum binary_address_hex_string = bytes_to_hex_string(binary_address) ! human_address = Bitcoin.encode_base58(binary_address_hex_string) p human_address https://gist.github.com/ashmoran/7582071
• 27. Other address types Bitcoin script addresses: 3xxx, e.g.:  3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX Bitcoin private key (uncompressed pubkey), 5xxx, e.g.:  5Htn3FzuH3b1X5VF2zLTsAQzBcyzkZNJsa2egXN8ZFJ TCqQm3Rq Bitcoin private key (compressed pubkey), [K/L]xxx, e.g.:  L1aW4aubDFB7yfras2S1mN3bqg9nwySY8nkoLmJebS LD5BWv3ENZ
• 28. Done!