"secp256k1" - For 256-Bit ECC Keys

This section describes 'secp256k1' elliptic curve domain parameters for generating 256-Bit ECC Keys as specified by secg.org.

What Is "secp256k1"? "secp256k1" is a specific elliptic curve and associated domain parameters selected and recommended by SECG (Standards for Efficient Cryptography Group). See "SEC 2: Recommended Elliptic Curve Domain Parameters" at secg.org/sec2-v2.pdf.

The "p256k1" part of the "secp256k1" name indicates:

```p     Field type = Prime field
256   Key size = 256
k     Curve type = Koblitz curve
1     Sequence = 1
```

"secp256k1" domain parameters (p, a, b, G, n, h)

p: The modulo used to specify the reduced elliptic curve group:

```p = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1
= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
```

a: The first coefficient of the elliptic curve:

```a = 0x00
```

b: The second coefficient of the elliptic curve:

```b = 0x07
```

G: The generator (base point) of the subgroup:

```G =(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
```

n: The order of the subgroup:

```    0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
```

h: The cofactor of the subgroup:

```h = 1
```

Verify domain parameters with Python - G is on the curve.

```herong> python

>>> p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
>>> a = 0x00
>>> b = 0x07
>>> G =(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,

>>> G[1]**2 % p == (G[0]**3 + a*G[0] + b) % p
True
```

Generate a "secp256k1" key pair with OpenSSL

```herong> openssl ecparam -genkey -name secp256k1 \
-out secp256k1.pem -param_enc explicit

herong> openssl ec -in secp256k1.pem -noout -text

Private-Key: (256 bit)
priv:
4e:ac:29:11:6c:7c:f6:de:aa:31:a0:8a:80:37:c5:
ae:3d:72:46:8d:87:a8:48:7b:69:5b:d0:74:0a:f1:
7a:e5
pub:
04:9e:89:ef:e1:f6:76:6e:01:3d:aa:21:3a:6c:3a:
a8:98:20:8f:24:e2:23:e2:c8:88:b3:da:48:5c:9e:
16:82:5d:14:c0:60:c9:14:d5:5a:ef:7e:6c:33:30:
78:4e:de:0e:b0:00:4d:00:e3:23:12:61:e8:00:fa:
a8:47:0b:3c:6c
Field Type: prime-field
Prime:
00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:fe:ff:
ff:fc:2f
A:    0
B:    7 (0x7)
Generator (uncompressed):
04:79:be:66:7e:f9:dc:bb:ac:55:a0:62:95:ce:87:
0b:07:02:9b:fc:db:2d:ce:28:d9:59:f2:81:5b:16:
f8:17:98:48:3a:da:77:26:a3:c4:65:5d:a4:fb:fc:
0e:11:08:a8:fd:17:b4:48:a6:85:54:19:9c:47:d0:
8f:fb:10:d4:b8
Order:
00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
ff:fe:ba:ae:dc:e6:af:48:a0:3b:bf:d2:5e:8c:d0:
36:41:41
Cofactor:  1 (0x1)
```

The printed domain parameters (Prime, A, B, Generator, Order, Cofactor) match well with (p, a, b, G, n, h) specified by secg.org. Remember that OpenSSL prints "Generator" as 0x04<G.x><G.y>.

Exercise: Verify all "prime field" and "Koblitz curves": secp192k1, secp224k1, and secp256k1 specified by secg.org.