diff --git a/ch04.asciidoc b/ch04.asciidoc index c131c102..d568ca1b 100644 --- a/ch04.asciidoc +++ b/ch04.asciidoc @@ -56,6 +56,7 @@ Do not try and design your own pseudo random number generator (PRNG). Use a cryp Below is a randomly generated private key shown in hexadecimal format (256 binary digits shown as 64 hexadecimal digits, each 4 bits): +.Randomly generated private key (k) ---- 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD ---- @@ -146,10 +147,28 @@ Starting with a private key in the form of a randomly generated number +k+, we m where +k+ is the private key, +G+ is a fixed point on the curve called the _generator point_, ((("generator point"))) and +K+ is the resulting public key, another point on the curve. Since the generator point is always the same, a private key k multiplied with G will always produce the same public key K. +Implementing the elliptic curve multiplication above, we take the private key generated previously and multiply it by G: + +.Multiply the private key k with the generator point G to find the public key K +---- +K = 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD * G +---- + + +.Public Key K defined as a point +K = (x,y)+ +---- +K = (x, y) +where, +x = 325D52E3B7...E5D378 +y = 7A3D41E670...CD90C2 +---- + To visualize multiplication of a point with an integer, we will use the simpler elliptic curve over the real numbers - remember, the math is the same. Our goal is to find the multiple kG of the generator point G. That is the same as adding G to itself, k times in a row. In elliptic curves, adding a point to itself is the equivalent of drawing a tangent line on the point and finding where it intersects the curve again, then reflecting that point on the x-axis. Starting with the generator point G, we take the tangent of the curve at G until it crosses the curve again at another point. This new point is -2G. Reflecting that point across the x-axis gives us 2G. If we take the tangent at 2G, it crosses the curve at -3G, which again we reflect on the x-axis to find 3G. Continuing this process, we can bounce around the curve finding the multiples of G, 2G, 3G, 4G etc. As you can see, a randomly selected large number k, when multiplied against the generator point G is like bouncing around the curve k times, until we land on the point kG which is the public key. This process is irreversible, meaning that it is infeasible to find the factor k (the secret k) in any way other than trying all multiples of G (1G, 2G, 3G etc) in a brute-force search for k. Since k can be an enormous number, that brute-force search would take an infeasible amount of computation and time. + + [[ecc_illustrated]] .Elliptic Curve Cryptography: Visualizing the multiplication of a point G by an integer k on an elliptic curve image::images/ecc_illustrated.png["ecc_illustrated"] @@ -188,8 +207,8 @@ image::images/PubKey_to_Bitcoin_Address.png["pubkey_to_address"] In order to represent long numbers in a compact way, using fewer symbols, many computer systems use mixed-alphanumeric representations with a base (or radix) higher than 10. For example, whereas the traditional decimal system uses the ten numerals 0 through 9, the hexadecimal system uses sixteen, with the letters A through F as the six additional symbols. A number represented in hexadecimal format is shorter than the equivalent decimal representation. Even more compact, Base-64 representation uses 26 lower case letters, 26 capital letters, 10 numerals and two more characters such as "\+" and "/" to transmit binary data over text-based media such as email. Base-64 is most commonly used to add binary attachments to email. Base-58 is a text-based binary-encoding format developed for use in bitcoin and used in many other crypto-currencies. It offers a balance between compact representation, readability and error detection and prevention. Base-58 is a subset of Base-64, using the upper and lower case letters and numbers but omitting some characters that are frequently mistaken for one another and can appear identical when displayed in certain fonts. Specifically, Base-58 is Base-64 without the 0 (number zero), O (capital o), l (lower L), I (capital i) and the symbols "\+" and "/". Or, more simply, it is a set of lower and capital letters and numbers without the four (0, O, l, I) mentioned above. [[base58alphabet]] +.Bitcoin's Base-58 Alphabet ---- -Bitcoin's Base-58 Alphabet: 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz ---- @@ -245,7 +264,7 @@ The private key we generated earlier can be represented as: [options="header"] |======= |Format | Private Key -| Hex | 1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd +| Hex | 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD | WIF | 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn | WIF-compressed | KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ |======= @@ -291,15 +310,15 @@ Here's the public key generated by the private key we created above, shown as th .Public Key K defined as a point +K = (x,y)+ ---- -x = 32 5D 52 E3 B7 ... E5 D3 78 -y = 7A 3D 41 E6 70 ... CD 90 C2 +x = 325D52E3B7...E5D378 +y = 7A3D41E670...CD90C2 ---- Here's the same public key shown as a 512-bit number (130 hex digits) with the prefix +04+ followed by +x+ and then +y+ coordinates, as +04 x y+: .Uncompressed Public Key K shown in hex (130 hex digits) as +04xy+ ---- -K = 04 32 5D 52 E3 B7 ... CD 90 C2 +K = 04325D52E3B7...CD90C2 ---- [[comp_pub]] @@ -319,7 +338,7 @@ Here's the same public key generated previously, shown as a +compressed public k .Compressed Public Key K shown in hex (66 hex digits) as +K = {02 or 03} x+ ---- -K = 02 32 5D 52 E3 B7 ... E5 D3 78 +K = 02325D52E3B7...E5D378 ---- The compressed public key, above, corresponds to the same private key, meaning that it is generated from the same private key. However it looks different from the uncompressed public key. More importantly, if we convert this compressed public key to a bitcoin address using the double-hash function (RIPEMD160(SHA256(K))) it will produce a _different_ bitcoin address. This can be confusing, because it means that a single private key can produce a public key expressed in two different formats (compressed and uncompressed) which produce two different bitcoin addresses. However, the private key is identical for both bitcoin addresses. @@ -343,9 +362,9 @@ Here's the same key, encoded in WIF and WIF-compressed formats [options="header"] |======= |Format | Private Key -| Hex | 1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd +| Hex | 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD | WIF | 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn -| Hex-compressed | 1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a526aedd_01_ +| Hex-compressed | 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD_01_ | WIF-compressed | KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ |=======