If we have an elliptic curve(defined by and ), a prime(), an basepoint and an order of this basepoint(), then we can choose a number(say ) and calculate .
is sometimes called private key and is sometimes called public key.
An example
The above example has only 27 possible private keys(). It’s not safe. We need a large , say
That’s the order of Bitcoin.
Bitcoin
1. Private key and public key
Parameters
a =0; b = 7; P = ;
x1 = 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
y1 = 483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
G = [x1,y1];
N = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
Tips: dealing with big numbers in JavaScript is tedious and the result of modular(%) may be negative in JavaScript while In Python it’s always positive.
In the real world, the private key still needs to be converted to Wallet Import Format(WIF). Also public key needs to be converted to address.
2. From private key to WIF
Suppose we’ve chosen a private key:
59748189462850000000000000000000000000000000000000000000000000000000000000000
2.1 Its hexdecimal form:
Private key(hex): PK0 = 841846de7afbe32ee7ded837872c6e0825db095275b8afed0000000000000000
2.2 Add “0x80” to the head of PK0:
PK1 = 80841846DE7AFBE32EE7DED837872C6E0825DB095275B8AFED0000000000000000
Here “0x” indicates this “80” is a hexdecimal number rather than a decimal number.
2.3 SHA-256(PK1):
PK2 = 185C164F93FA16C66019E15356AA2DE9674AD310B0D8A45747657F3079172815
2.4 SHA-256(PK2):
PK3 = 66FCA214401C8C61C5490FDD14D259877F21A86E9D1A26596E75F69770A678AB
2.5 Checksum(first 8 hexadecimal digits/4 bytes of PK3):
66FCA214
1 hexdecimal digit = 4 bits && 1 byte = 8 bits --> 2 hexdecimal digits = 1 byte -->
8 hexadecimal digits = 4 bytes
More info: Hexadecimal numeral system
2.6 Add Checksum to the tail of PK1:
PK4 = 80841846DE7AFBE32EE7DED837872C6E0825DB095275B8AFED000000000000000066FCA214
2.7 Base58 encoding of PK4:
WIF = 5JpTmRPSNsrt2EptGiR2pcJ7xZGQeCVvTRfpQr4XD4om8dsB8Ew
Base58 alphabet: “123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz”.
Compared to Base64, the following similar-looking letters are omitted: 0 (zero), O (capital o), I (capital i) and l (lower case L) as well as the non-alphanumeric characters + (plus) and / (slash).
3. From public key to address
Still, suppose we’ve chosen the private key:
59748189462850000000000000000000000000000000000000000000000000000000000000000
3.1 After Elliptic Curve Multiplication we get:
Public key(hex): UK0 = 3a56bd64573c28050bfe202c57e56b46c63744a253d1430e2b737876fa883b19,73c2f565444dc62151562993ff4b566c826010befb289fa2fc749293266066c0
3.2 Add “0x40” to the head of UK0:
UK1 = 043a56bd64573c28050bfe202c57e56b46c63744a253d1430e2b737876fa883b1973c2f565444dc62151562993ff4b566c826010befb289fa2fc749293266066c0
Again here “0x” indicates this “40” is a hexdecimal number rather than a decimal number. You may noticed two parts of UK0(value of horizontal axis and value of vertical axis) are put together.
3.3 SHA-256(UK1):
UK2 = c41dde43a4f6dd7aa0354150c784bbc8356cb8617ff685b6fc3f8287c826759f
3.4 RIPEMD-160(UK2):
UK3 = aa3dc7fda0e233b71a53938e7ae42bf5a583fc8c
3.5 Adding “0x00” to the head of UK3:
UK4 = 00aa3dc7fda0e233b71a53938e7ae42bf5a583fc8c
3.6 SHA-256(UK4):
UK5 = bef81c4a971778759545b3d3816765c437d5ab964df77e3e356ffc8b9a2d0af4
3.7 SHA-256(UK5):
UK6 = 6be6d3cfdb5464f3aca1777400be94dc500a8bb84a5cf25d968721c7a850d2cf
3.8 Checksum(first 8 hexadecimal digits/4 bytes of UK6):
6be6d3cf
3.9 Add Checksum to the tail of UK4:
UK7 = 00aa3dc7fda0e233b71a53938e7ae42bf5a583fc8c6be6d3cf
3.10 Base58 encoding of UK7:
Address = 1GX9tFDj3mBj7NBL6rDtqcnh1ZzPetqF9x
More info: ref1, ref2, ref3, ref4
4. Try it you self
5. Python gist
More info: freecodecamp, blocksmith, python-ecdsa, Python doc