"secp256r1" - For 256-Bit ECC Keys

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

What Is "secp256r1"? "secp256r1" 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 "secp256r1" elliptic curve is also recommended by NIST (National Institute of Standards and Technology) as "P-256", by ANSI (American National Standards Institute) as "prime256v1".

The "p256r1" part of the "secp256r1" name indicates:

```p     Field type = Prime field
256   Key size = 256
r     Curve type = Verifiably Random
1     Sequence = 1
```

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

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

```p = 2**224(2**32-1) + 2**192 + 2**96 - 1
= 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF
```

a: The first coefficient of the elliptic curve:

```a = p - 3
= 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC
```

b: The second coefficient of the elliptic curve:

```b = 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B
```

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

```G =(0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296,
0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5)
```

n: The order of the subgroup:

```n = 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551
```

h: The cofactor of the subgroup:

```h = 1
```

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

```herong> python

>>> p = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF
>>> a = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC
>>> b = 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B
>>> G =(0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296,
...    0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5)

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

Generate a "secp256r1" key pair with OpenSSL - "secp256r1" is also named as "prime256v1" in OpenSSL.

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

using curve name prime256v1 instead of secp256r1

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

Private-Key: (256 bit)
priv:
f5:02:fb:91:1d:74:6b:77:f4:43:8c:67:4e:1c:43:
65:0b:68:28:5d:fc:c0:58:3c:49:cd:6e:d8:8f:0f:
bb:58
pub:
04:f9:4c:20:d6:82:da:29:b7:e9:99:85:d8:db:a6:
ab:ea:90:51:d1:65:08:74:28:99:83:50:98:b1:11:
3d:3d:74:94:66:64:4c:47:b5:59:db:18:45:56:c1:
73:3c:33:e5:78:8a:e2:50:b8:fb:45:f2:9d:4c:f4:
8f:f7:52:c1:ed
Field Type: prime-field
Prime:
00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
ff:ff:ff
A:
00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
ff:ff:fc
B:
5a:c6:35:d8:aa:3a:93:e7:b3:eb:bd:55:76:98:86:
bc:65:1d:06:b0:cc:53:b0:f6:3b:ce:3c:3e:27:d2:
60:4b
Generator (uncompressed):
04:6b:17:d1:f2:e1:2c:42:47:f8:bc:e6:e5:63:a4:
40:f2:77:03:7d:81:2d:eb:33:a0:f4:a1:39:45:d8:
98:c2:96:4f:e3:42:e2:fe:1a:7f:9b:8e:e7:eb:4a:
7c:0f:9e:16:2b:ce:33:57:6b:31:5e:ce:cb:b6:40:
68:37:bf:51:f5
Order:
00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:
63:25:51
Cofactor:  1 (0x1)
Seed:
c4:9d:36:08:86:e7:04:93:6a:66:78:e1:13:9d:26:
b7:81:9f:7e:90
```

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>.

Notice that "secp256r1" is associated with a "Seed (S)". Its domain parameters are said to be verifiably at random from this seed: S = 0xC49D360886E704936A6678E1139D26B7819F7E90. secg.org specification says "These parameters are chosen from a seed using SHA-1 as specified in ANSI X9.62". I need to ready "ANSI X9.62" to find out how the seed is used.

Exercise: Verify all "prime field" and "verifiably at random" curves: secp192r1, secp224r1, secp256r1, secp384r1 and secp521r1 specified by secg.org.