Initial commit.
[BoarSSL] / Crypto / NIST.cs
1 /*
2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25 using System;
26
27 namespace Crypto {
28
29 /*
30 * This class contains static definitions for the NIST elliptic
31 * curves.
32 */
33
34 public class NIST {
35
36 // public static ECCurve P192;
37 // public static ECCurve P224;
38 public static ECCurve P256;
39 public static ECCurve P384;
40 public static ECCurve P521;
41
42 static NIST()
43 {
44 P256 = MakePrime(
45 "P-256",
46 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
47 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
48 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
49 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
50 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
51 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
52 "01");
53 P384 = MakePrime(
54 "P-384",
55 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
56 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
57 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
58 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
59 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
60 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
61 "01");
62 P521 = MakePrime(
63 "P-521",
64 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
65 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
66 "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
67 "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
68 "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
69 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
70 "01");
71 }
72
73 static ECCurvePrime MakePrime(string name, string smod,
74 string sa, string sb, string sgx, string sgy,
75 string sso, string scf)
76 {
77 return new ECCurvePrime(
78 name,
79 ToBytes(smod), ToBytes(sa), ToBytes(sb),
80 ToBytes(sgx), ToBytes(sgy),
81 ToBytes(sso), ToBytes(scf));
82 }
83
84 static byte[] ToBytes(string s)
85 {
86 int len = ToBytes(s, null);
87 byte[] dst = new byte[len];
88 ToBytes(s, dst);
89 return dst;
90 }
91
92 static int ToBytes(string str, byte[] dst)
93 {
94 int off = 0;
95 bool z = true;
96 int acc = 0;
97 foreach (char c in str) {
98 int d;
99 if (c >= '0' && c <= '9') {
100 d = c - '0';
101 } else if (c >= 'A' && c <= 'F') {
102 d = c - ('A' - 10);
103 } else if (c >= 'a' && c <= 'f') {
104 d = c - ('a' - 10);
105 } else if (c == ' ' || c == '\t' || c == ':') {
106 continue;
107 } else {
108 throw new ArgumentException(String.Format(
109 "not hex: U+{0:X4}", (int)c));
110 }
111 if (z) {
112 acc = d;
113 } else {
114 if (dst != null) {
115 dst[off] = (byte)((acc << 4) + d);
116 }
117 off ++;
118 }
119 z = !z;
120 }
121 if (!z) {
122 throw new ArgumentException("final half byte");
123 }
124 return off;
125 }
126 }
127
128 }