This is an example of a bitcoin address: 14NWDXkQwcGN1Pd9fboL8npVynD5SfyJAE

**CONCEPT:- Elliptic Curves**

https://www.certicom.com/content/certicom/en/ecc-tutorial.html

Each address corresponds to a point on the **elliptic curve** secp256k1 (y^3=x^2+7 mod p) where prime p = 115792089237316195423570985008687907853269984665640564039457584007908834671663

The point for the above address as a decimal point on a graph:

(91519190036866233587583752863966343541024156557754641198598352460350806215674, 18110675123485594228049867696927871008716109164646265340106239137304742587157)

to check this is on the curve we can do:

>>> x=91519190036866233587583752863966343541024156557754641198598352460350806215674

>>> y=18110675123485594228049867696927871008716109164646265340106239137304742587157

>>> p=115792089237316195423570985008687907853269984665640564039457584007908834671663

>>> ((y2)%p)==((x3+7)%(p))

True

#### So how do we get from the *point* to the *address*?

**CONCEPT: HEX, ripemd150, sha256, base58**

First lets convert it to hexadecimal:

>>> x = 91519190036866233587583752863966343541024156557754641198598352460350806215674

>>> x2 = x.to_bytes(32, ‘big’).hex().encode()>>> y = 18110675123485594228049867696927871008716109164646265340106239137304742587157

>>> y2 = y.to_bytes(32, ‘big’).hex().encode()

>>> print(“(“,x2, “, “, y2, “)”)

( b’ca5606a1e820e7a2f6bb3ab090e8ade7b04a7e0b5909a68dda2744ae3b8ecbfa’ , b’280a47639c811134d648e8ee8096c33b41611be509ebca837fbda10baaa1eb15′ )

- Uncompressed SEC Format <0x04><x coordinate in 32 byte big endian hex><y coordinate in 32 byte big endian hex>

>>> r = “04ca5606a1e820e7a2f6bb3ab090e8ade7b04a7e0b5909a68dda2744ae3b8ecbfa280a47639c811134d648e8ee8096c33b41611be509ebca837fbda10baaa1eb15”

>>> rr = bytes.fromhex(r)

>>> rr

b”\x04\xcaV\x06\xa1\xe8\xe7\xa2\xf6\xbb\xb0\x90\xe8\xad\xe7\xb0J~\x0bY\t\xa6\x8d\xda’D\xae\x8e\xcb\xfa(\nGc\x9c\x81\x114\xd6H\xe8\xee\x80\x96\xc3;Aa\x1b\xe5\t\xeb\xca\x83\x7f\xbd\xa1\x0b\xaa\xa1\xeb\x15″

>>> rr.hex()

‘**04ca5606a1e820e7a2f6bb3ab090e8ade7b04a7e0b5909a68dda2744ae3b8ecbfa280a47639c811134d648e8ee8096c33b41611be509ebca837fbda10baaa1eb15**‘ - Compressed SEC format <0x02 or 0x03><x coordinate in 32 byte big endian hex>

For every value (x, y) on the Elliptic curve the value (x, p-y) is also on the curve so we can encode the y value as even or odd**03ca5606a1e820e7a2f6bb3ab090e8ade7b04a7e0b5909a68dda2744ae3b8ecbfa** - WIF Format this is described in this diagram –

i) take the uncompressed sec format address**04ca5606a1e820e7a2f6bb3ab090e8ade7b04a7e0b5909a68dda2744ae3b8ecbfa280a47639c811134d648e8ee8096c33b41611be509ebca837fbda10baaa1eb15**

ii) sha256 the long address, followed by ripemd160 -> 20 bytes

>>> hashlib.new(‘ripemd160’, hashlib.sha256(rr).digest()).digest().hex()**’24f98038e995ee03c4178bccaff1652223eba473**‘

iii) append 00 prefix byte to this -> 21 bytes

‘**0024f98038e995ee03c4178bccaff1652223eba473**‘

iv) sha256 these 21 bytes twice and output the first 4 bytes of the output -> 4 bytes

>>> rrr = “0024f98038e995ee03c4178bccaff1652223eba473”

>>> rrrr=bytes.fromhex(rrr)

>>> hashlib.sha256(hashlib.sha256(rrrr).digest()).digest().hex()**669e533b**3f7fd1b165e64c197717506453b927a39cf1751262c31f8fd3cbcd26

v) append these 4 bytes to the output of step iii) above**0024f98038e995ee03c4178bccaff1652223eba473669e533b**

vi) convert this to base58 encoding to get the address

>>> import base58

>>> rrrrr = “0024f98038e995ee03c4178bccaff1652223eba473669e533b”

>>> rrrrrr=bytes.fromhex(rrrrr)

>>> base58.b58encode(rrrr)**14NWDXkQwcGN1Pd9fboL8npVynD5SfyJAE**

#### How do we pick a point for our address?

**CONCEPT: Public Key Cryptography**

The point on the elliptic curve is the **public key** anyone can use to make payments to (for example p2pk transactions in early bitcoin). The above address works in the same way as the public key but it is easier to use and more secure* (for example p2pkh transactions that came a bit later in bitcoin)

To receive bitcoins you don’t select a the public key, instead you select the **private key** and generate a public key from the private key.

Once you have selected a private key (random integer between 1 and 2^256) you generate a public key through scalar multiplication of the private key with a specific point G (the generator point) on the elliptic curve as defined by secp256k1’s definition. This generates a new point (the public key) on the curve from which you create your address as above.

Given a public key, they only way to know the private key is to check every possible private key (number between 1 and 2^256), which takes an impossibly long time. This is what secures bitcoin (CONCEPT: Elliptic curve cryptography)

The most important requirement for a private key is that is is random over the whole set of possible keys. Then if someone does try to search the entire key space they will not be able to spend your bitcoins because it would just take too long.

G=(0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8)

**CONCEPT: Random numbers**

Random number generation is a bit tricky for computers and humans to do. The two main issues are that random number generators on computers are often deterministic (predictable given seed values), or contain hidden patterns.

**Good of private key generators are: **

1. bitaddress.org – this takes various sources of entropy such as time, screen size, and mouse position as you wiggle it around and generates a private key using that

2. openssl – uses /dev/urandom in unix or CryptGenRandom() on Windows. These use system events such as packet times, process id’s etc as entropy and are generally well tested as unpredictable

e.g. (there’s probably a better way to do this but it worked on windows so i transferred it to mac)

i) mac$ openssl ecparam -genkey -name secp256k1 -out /var/tmp/delete_me -outform PEM

ii) mac$ openssl ec -inform PEM -in /var/tmp/delete_me -text -out /var/tmp/delete_me2

read EC key

writing EC key

iii) Private-Key: (256 bit)

priv:

26:db:4e:0b:f4:fa:35:db:7b:16:37:5f:3a:bb:c4:

e9:f0:30:de:85:b0:7b:6f:a2:cd:7e:32:a7:02:a2:

c4:16

pub:

04:4e:66:89:9a:b2:05:6e:6e:4d:bc:60:2f:e4:e7:

c0:7a:9c:35:35:f0:c3:0d:f1:c9:b1:08:01:9d:8d:

5e:43:fc:03:22:21:0e:ba:f6:64:b3:f2:ce:7c:8e:

8b:6c:e2:d3:22:8e:d1:ec:1d:de:65:24:03:e3:77:

2d:9b:b3:3d:0a

ASN1 OID: secp256k1

—–BEGIN EC PRIVATE KEY—–

MHQCAQEEICbbTgv0+jXbexY3Xzq7xOnwMN6FsHtvos1+MqcCosQWoAcGBSuBBAAK

oUQDQgAETmaJmrIFbm5NvGAv5OfAepw1NfDDDfHJsQgBnY1eQ/wDIiEOuvZks/LO

fI6LbOLTIo7R7B3eZSQD43ctm7M9Cg==

—–END EC PRIVATE KEY—–

iv) the bit after priv: is the private key in hex, and the bit after pub: is the public key point on the graph. Notice that it starts with 04 as the prefix to show it is sec uncompressed format

**Some bad examples to generate private key (including the above public key address):**

1. Brain wallets – these take a string of text and hash it to create a private key.

For example the private key for the above address is the hash of “bitcoin is awesome” (sha256(“bitcoin is awesome”)=0x23d4a09295be678b21a5f1dceae1f634a69c1b41775f680ebf8165266471401b which is the private key)

2. Insecure random number generators – using the java class SecureRandom to generate random numbers for private keys https://www.theregister.co.uk/2013/08/12/android_bug_batters_bitcoin_wallets/

Further questions:

1. How many addresses are there?

2. How the blockchain works?

3. What are transactions?

4. How are bitcoins created?

5. Given a private key how do you generate public key/address?

**Resources**: https://www.amazon.co.uk/Programming-Bitcoin-Learn-Program-Scratch/dp/1492031496

https://www.certicom.com/content/certicom/en/ecc-tutorial.html

https://en.bitcoin.it/wiki/Secp256k1

https://en.bitcoin.it/w/images/en/9/9b/PubKeyToAddr.png

https://www.theregister.co.uk/2013/08/12/android_bug_batters_bitcoin_wallets/