2 * Elliptic-curve crypto module for PuTTY
3 * Implements the three required curves, no optional curves
5 * NOTE: Only curves on prime field are handled by the maths functions
6 * in Weierstrass form using Jacobian co-ordinates.
8 * Montgomery form curves are supported for DH. (Curve25519)
10 * Edwards form curves are supported for DSA. (Ed25519)
16 * Elliptic curves in SSH are specified in RFC 5656:
17 * http://tools.ietf.org/html/rfc5656
19 * That specification delegates details of public key formatting and a
20 * lot of underlying mechanism to SEC 1:
21 * http://www.secg.org/sec1-v2.pdf
23 * Montgomery maths from:
24 * Handbook of elliptic and hyperelliptic curve cryptography, Chapter 13
25 * http://cs.ucsb.edu/~koc/ccs130h/2013/EllipticHyperelliptic-CohenFrey.pdf
27 * Curve25519 spec from libssh (with reference to other things in the
29 * https://git.libssh.org/users/aris/libssh.git/tree/doc/curve25519-sha256@libssh.org.txt
32 * http://ed25519.cr.yp.to/ed25519-20110926.pdf
40 /* ----------------------------------------------------------------------
41 * Elliptic curve definitions
44 static void initialise_wcurve(struct ec_curve *curve, int bits,
45 const unsigned char *p,
46 const unsigned char *a, const unsigned char *b,
47 const unsigned char *n, const unsigned char *Gx,
48 const unsigned char *Gy)
50 int length = bits / 8;
51 if (bits % 8) ++length;
53 curve->type = EC_WEIERSTRASS;
55 curve->fieldBits = bits;
56 curve->p = bignum_from_bytes(p, length);
58 /* Curve co-efficients */
59 curve->w.a = bignum_from_bytes(a, length);
60 curve->w.b = bignum_from_bytes(b, length);
62 /* Group order and generator */
63 curve->w.n = bignum_from_bytes(n, length);
64 curve->w.G.x = bignum_from_bytes(Gx, length);
65 curve->w.G.y = bignum_from_bytes(Gy, length);
66 curve->w.G.curve = curve;
67 curve->w.G.infinity = 0;
70 static void initialise_mcurve(struct ec_curve *curve, int bits,
71 const unsigned char *p,
72 const unsigned char *a, const unsigned char *b,
73 const unsigned char *Gx)
75 int length = bits / 8;
76 if (bits % 8) ++length;
78 curve->type = EC_MONTGOMERY;
80 curve->fieldBits = bits;
81 curve->p = bignum_from_bytes(p, length);
83 /* Curve co-efficients */
84 curve->m.a = bignum_from_bytes(a, length);
85 curve->m.b = bignum_from_bytes(b, length);
88 curve->m.G.x = bignum_from_bytes(Gx, length);
91 curve->m.G.curve = curve;
92 curve->m.G.infinity = 0;
95 static void initialise_ecurve(struct ec_curve *curve, int bits,
96 const unsigned char *p,
97 const unsigned char *l, const unsigned char *d,
98 const unsigned char *Bx, const unsigned char *By)
100 int length = bits / 8;
101 if (bits % 8) ++length;
103 curve->type = EC_EDWARDS;
105 curve->fieldBits = bits;
106 curve->p = bignum_from_bytes(p, length);
108 /* Curve co-efficients */
109 curve->e.l = bignum_from_bytes(l, length);
110 curve->e.d = bignum_from_bytes(d, length);
112 /* Group order and generator */
113 curve->e.B.x = bignum_from_bytes(Bx, length);
114 curve->e.B.y = bignum_from_bytes(By, length);
115 curve->e.B.curve = curve;
116 curve->e.B.infinity = 0;
119 static struct ec_curve *ec_p256(void)
121 static struct ec_curve curve = { 0 };
122 static unsigned char initialised = 0;
126 static const unsigned char p[] = {
127 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
130 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
132 static const unsigned char a[] = {
133 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
136 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc
138 static const unsigned char b[] = {
139 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
140 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
141 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
142 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b
144 static const unsigned char n[] = {
145 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
146 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
147 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84,
148 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51
150 static const unsigned char Gx[] = {
151 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
152 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
153 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
154 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96
156 static const unsigned char Gy[] = {
157 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b,
158 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
159 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
160 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5
163 initialise_wcurve(&curve, 256, p, a, b, n, Gx, Gy);
164 curve.textname = curve.name = "nistp256";
166 /* Now initialised, no need to do it again */
173 static struct ec_curve *ec_p384(void)
175 static struct ec_curve curve = { 0 };
176 static unsigned char initialised = 0;
180 static const unsigned char p[] = {
181 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
182 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
183 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
184 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
185 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
188 static const unsigned char a[] = {
189 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
190 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
191 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
192 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
193 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc
196 static const unsigned char b[] = {
197 0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4,
198 0x98, 0x8e, 0x05, 0x6b, 0xe3, 0xf8, 0x2d, 0x19,
199 0x18, 0x1d, 0x9c, 0x6e, 0xfe, 0x81, 0x41, 0x12,
200 0x03, 0x14, 0x08, 0x8f, 0x50, 0x13, 0x87, 0x5a,
201 0xc6, 0x56, 0x39, 0x8d, 0x8a, 0x2e, 0xd1, 0x9d,
202 0x2a, 0x85, 0xc8, 0xed, 0xd3, 0xec, 0x2a, 0xef
204 static const unsigned char n[] = {
205 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
206 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
207 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
208 0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf,
209 0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a,
210 0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73
212 static const unsigned char Gx[] = {
213 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37,
214 0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74,
215 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98,
216 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38,
217 0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c,
218 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7
220 static const unsigned char Gy[] = {
221 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f,
222 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29,
223 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
224 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0,
225 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d,
226 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f
229 initialise_wcurve(&curve, 384, p, a, b, n, Gx, Gy);
230 curve.textname = curve.name = "nistp384";
232 /* Now initialised, no need to do it again */
239 static struct ec_curve *ec_p521(void)
241 static struct ec_curve curve = { 0 };
242 static unsigned char initialised = 0;
246 static const unsigned char p[] = {
247 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
248 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
249 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
250 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
251 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
252 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
253 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
254 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
257 static const unsigned char a[] = {
258 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
259 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
260 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
261 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
262 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
263 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
264 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
265 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
268 static const unsigned char b[] = {
269 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c,
270 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
271 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
272 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
273 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
274 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
275 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
276 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
279 static const unsigned char n[] = {
280 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
281 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
282 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
283 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
284 0xff, 0xfa, 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f,
285 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09,
286 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c,
287 0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38,
290 static const unsigned char Gx[] = {
291 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04,
292 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
293 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
294 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
295 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
296 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
297 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
298 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
301 static const unsigned char Gy[] = {
302 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b,
303 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
304 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
305 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
306 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
307 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
308 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
309 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
313 initialise_wcurve(&curve, 521, p, a, b, n, Gx, Gy);
314 curve.textname = curve.name = "nistp521";
316 /* Now initialised, no need to do it again */
323 static struct ec_curve *ec_curve25519(void)
325 static struct ec_curve curve = { 0 };
326 static unsigned char initialised = 0;
330 static const unsigned char p[] = {
331 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
332 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
333 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
334 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed
336 static const unsigned char a[] = {
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x6d, 0x06
342 static const unsigned char b[] = {
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
348 static const unsigned char gx[32] = {
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09
355 initialise_mcurve(&curve, 256, p, a, b, gx);
356 /* This curve doesn't need a name, because it's never used in
357 * any format that embeds the curve name */
359 curve.textname = "Curve25519";
361 /* Now initialised, no need to do it again */
368 static struct ec_curve *ec_curve448(void)
370 static struct ec_curve curve = { 0 };
371 static unsigned char initialised = 0;
375 static const unsigned char p[56] = {
376 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
377 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
378 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
379 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
380 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
381 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
382 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
384 static const unsigned char a[56] = {
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x62, 0xa6,
393 static const unsigned char b[56] = {
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
402 static const unsigned char gx[56] = {
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
412 initialise_mcurve(&curve, 448, p, a, b, gx);
413 /* This curve doesn't need a name, because it's never used in
414 * any format that embeds the curve name */
416 curve.textname = "Curve448";
418 /* Now initialised, no need to do it again */
425 static struct ec_curve *ec_ed25519(void)
427 static struct ec_curve curve = { 0 };
428 static unsigned char initialised = 0;
432 static const unsigned char q[] = {
433 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
434 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
435 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
436 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed
438 static const unsigned char l[32] = {
439 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441 0x14, 0xde, 0xf9, 0xde, 0xa2, 0xf7, 0x9c, 0xd6,
442 0x58, 0x12, 0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed
444 static const unsigned char d[32] = {
445 0x52, 0x03, 0x6c, 0xee, 0x2b, 0x6f, 0xfe, 0x73,
446 0x8c, 0xc7, 0x40, 0x79, 0x77, 0x79, 0xe8, 0x98,
447 0x00, 0x70, 0x0a, 0x4d, 0x41, 0x41, 0xd8, 0xab,
448 0x75, 0xeb, 0x4d, 0xca, 0x13, 0x59, 0x78, 0xa3
450 static const unsigned char Bx[32] = {
451 0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe,
452 0xc0, 0xa4, 0xe2, 0x31, 0xfd, 0xd6, 0xdc, 0x5c,
453 0x69, 0x2c, 0xc7, 0x60, 0x95, 0x25, 0xa7, 0xb2,
454 0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a
456 static const unsigned char By[32] = {
457 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
458 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
459 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
460 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58
463 /* This curve doesn't need a name, because it's never used in
464 * any format that embeds the curve name */
467 initialise_ecurve(&curve, 256, q, l, d, Bx, By);
468 curve.textname = "Ed25519";
470 /* Now initialised, no need to do it again */
477 /* Return 1 if a is -3 % p, otherwise return 0
478 * This is used because there are some maths optimisations */
479 static int ec_aminus3(const struct ec_curve *curve)
484 if (curve->type != EC_WEIERSTRASS) {
488 _p = bignum_add_long(curve->w.a, 3);
490 ret = !bignum_cmp(curve->p, _p);
495 /* ----------------------------------------------------------------------
496 * Elliptic curve field maths
499 static Bignum ecf_add(const Bignum a, const Bignum b,
500 const struct ec_curve *curve)
502 Bignum a1, b1, ab, ret;
504 a1 = bigmod(a, curve->p);
505 b1 = bigmod(b, curve->p);
511 ret = bigmod(ab, curve->p);
517 static Bignum ecf_square(const Bignum a, const struct ec_curve *curve)
519 return modmul(a, a, curve->p);
522 static Bignum ecf_treble(const Bignum a, const struct ec_curve *curve)
527 tmp = bignum_lshift(a, 1);
529 /* Add itself (i.e. treble) */
530 ret = bigadd(tmp, a);
534 while (bignum_cmp(ret, curve->p) >= 0)
536 tmp = bigsub(ret, curve->p);
545 static Bignum ecf_double(const Bignum a, const struct ec_curve *curve)
547 Bignum ret = bignum_lshift(a, 1);
548 if (bignum_cmp(ret, curve->p) >= 0)
550 Bignum tmp = bigsub(ret, curve->p);
561 /* ----------------------------------------------------------------------
565 void ec_point_free(struct ec_point *point)
567 if (point == NULL) return;
569 if (point->x) freebn(point->x);
570 if (point->y) freebn(point->y);
571 if (point->z) freebn(point->z);
576 static struct ec_point *ec_point_new(const struct ec_curve *curve,
577 const Bignum x, const Bignum y, const Bignum z,
578 unsigned char infinity)
580 struct ec_point *point = snewn(1, struct ec_point);
581 point->curve = curve;
585 point->infinity = infinity ? 1 : 0;
589 static struct ec_point *ec_point_copy(const struct ec_point *a)
591 if (a == NULL) return NULL;
592 return ec_point_new(a->curve,
593 a->x ? copybn(a->x) : NULL,
594 a->y ? copybn(a->y) : NULL,
595 a->z ? copybn(a->z) : NULL,
599 static int ec_point_verify(const struct ec_point *a)
603 } else if (a->curve->type == EC_EDWARDS) {
604 /* Check y^2 - x^2 - 1 - d * x^2 * y^2 == 0 */
605 Bignum y2, x2, tmp, tmp2, tmp3;
608 y2 = ecf_square(a->y, a->curve);
609 x2 = ecf_square(a->x, a->curve);
610 tmp = modmul(a->curve->e.d, x2, a->curve->p);
611 tmp2 = modmul(tmp, y2, a->curve->p);
613 tmp = modsub(y2, x2, a->curve->p);
616 tmp3 = modsub(tmp, tmp2, a->curve->p);
619 ret = !bignum_cmp(tmp3, One);
622 } else if (a->curve->type == EC_WEIERSTRASS) {
623 /* Verify y^2 = x^3 + ax + b */
626 Bignum lhs = NULL, x3 = NULL, ax = NULL, x3ax = NULL, x3axm = NULL, x3axb = NULL, rhs = NULL;
628 Bignum Three = bignum_from_long(3);
630 lhs = modmul(a->y, a->y, a->curve->p);
632 /* This uses montgomery multiplication to optimise */
633 x3 = modpow(a->x, Three, a->curve->p);
635 ax = modmul(a->curve->w.a, a->x, a->curve->p);
636 x3ax = bigadd(x3, ax);
637 freebn(x3); x3 = NULL;
638 freebn(ax); ax = NULL;
639 x3axm = bigmod(x3ax, a->curve->p);
640 freebn(x3ax); x3ax = NULL;
641 x3axb = bigadd(x3axm, a->curve->w.b);
642 freebn(x3axm); x3axm = NULL;
643 rhs = bigmod(x3axb, a->curve->p);
646 ret = bignum_cmp(lhs, rhs) ? 0 : 1;
656 /* ----------------------------------------------------------------------
657 * Elliptic curve point maths
660 /* Returns 1 on success and 0 on memory error */
661 static int ecp_normalise(struct ec_point *a)
669 /* Point is at infinity - i.e. normalised */
673 if (a->curve->type == EC_WEIERSTRASS) {
674 /* In Jacobian Coordinates the triple (X, Y, Z) represents
675 the affine point (X / Z^2, Y / Z^3) */
677 Bignum Z2, Z2inv, Z3, Z3inv, tx, ty;
679 if (!a->x || !a->y) {
680 /* No point defined */
683 /* Already normalised */
687 Z2 = ecf_square(a->z, a->curve);
688 Z2inv = modinv(Z2, a->curve->p);
693 tx = modmul(a->x, Z2inv, a->curve->p);
696 Z3 = modmul(Z2, a->z, a->curve->p);
698 Z3inv = modinv(Z3, a->curve->p);
704 ty = modmul(a->y, Z3inv, a->curve->p);
714 } else if (a->curve->type == EC_MONTGOMERY) {
715 /* In Montgomery (X : Z) represents the x co-ord (X / Z, ?) */
720 /* No point defined */
723 /* Already normalised */
727 tmp = modinv(a->z, a->curve->p);
731 tmp2 = modmul(a->x, tmp, a->curve->p);
739 } else if (a->curve->type == EC_EDWARDS) {
740 /* Always normalised */
747 static struct ec_point *ecp_doublew(const struct ec_point *a, const int aminus3)
749 Bignum S, M, outx, outy, outz;
751 if (bignum_cmp(a->y, Zero) == 0)
754 return ec_point_new(a->curve, NULL, NULL, NULL, 1);
759 Bignum Y2, XY2, _2XY2;
761 Y2 = ecf_square(a->y, a->curve);
762 XY2 = modmul(a->x, Y2, a->curve->p);
765 _2XY2 = ecf_double(XY2, a->curve);
767 S = ecf_double(_2XY2, a->curve);
771 /* Faster calculation if a = -3 */
773 /* if a = -3, then M can also be calculated as M = 3*(X + Z^2)*(X - Z^2) */
774 Bignum Z2, XpZ2, XmZ2, second;
779 Z2 = ecf_square(a->z, a->curve);
782 XpZ2 = ecf_add(a->x, Z2, a->curve);
783 XmZ2 = modsub(a->x, Z2, a->curve->p);
786 second = modmul(XpZ2, XmZ2, a->curve->p);
790 M = ecf_treble(second, a->curve);
793 /* M = 3*X^2 + a*Z^4 */
794 Bignum _3X2, X2, aZ4;
797 aZ4 = copybn(a->curve->w.a);
801 Z2 = ecf_square(a->z, a->curve);
802 Z4 = ecf_square(Z2, a->curve);
804 aZ4 = modmul(a->curve->w.a, Z4, a->curve->p);
808 X2 = modmul(a->x, a->x, a->curve->p);
809 _3X2 = ecf_treble(X2, a->curve);
811 M = ecf_add(_3X2, aZ4, a->curve);
820 M2 = ecf_square(M, a->curve);
821 _2S = ecf_double(S, a->curve);
822 outx = modsub(M2, _2S, a->curve->p);
827 /* Y' = M*(S - X') - 8*Y^4 */
829 Bignum SX, MSX, Eight, Y2, Y4, _8Y4;
831 SX = modsub(S, outx, a->curve->p);
833 MSX = modmul(M, SX, a->curve->p);
836 Y2 = ecf_square(a->y, a->curve);
837 Y4 = ecf_square(Y2, a->curve);
839 Eight = bignum_from_long(8);
840 _8Y4 = modmul(Eight, Y4, a->curve->p);
843 outy = modsub(MSX, _8Y4, a->curve->p);
855 YZ = modmul(a->y, a->z, a->curve->p);
858 outz = ecf_double(YZ, a->curve);
862 return ec_point_new(a->curve, outx, outy, outz, 0);
865 static struct ec_point *ecp_doublem(const struct ec_point *a)
867 Bignum z, outx, outz, xpz, xmz;
874 /* 4xz = (x + z)^2 - (x - z)^2 */
878 tmp = ecf_add(a->x, z, a->curve);
879 xpz = ecf_square(tmp, a->curve);
882 tmp = modsub(a->x, z, a->curve->p);
883 xmz = ecf_square(tmp, a->curve);
887 /* outx = (x + z)^2 * (x - z)^2 */
888 outx = modmul(xpz, xmz, a->curve->p);
890 /* outz = 4xz * ((x - z)^2 + ((A + 2) / 4)*4xz) */
892 Bignum _4xz, tmp, tmp2, tmp3;
894 tmp = bignum_from_long(2);
895 tmp2 = ecf_add(a->curve->m.a, tmp, a->curve);
898 _4xz = modsub(xpz, xmz, a->curve->p);
900 tmp = modmul(tmp2, _4xz, a->curve->p);
903 tmp2 = bignum_from_long(4);
904 tmp3 = modinv(tmp2, a->curve->p);
913 tmp2 = modmul(tmp, tmp3, a->curve->p);
917 tmp = ecf_add(xmz, tmp2, a->curve);
920 outz = modmul(_4xz, tmp, a->curve->p);
925 return ec_point_new(a->curve, outx, NULL, outz, 0);
928 /* Forward declaration for Edwards curve doubling */
929 static struct ec_point *ecp_add(const struct ec_point *a,
930 const struct ec_point *b,
933 static struct ec_point *ecp_double(const struct ec_point *a, const int aminus3)
938 return ec_point_new(a->curve, NULL, NULL, NULL, 1);
941 if (a->curve->type == EC_EDWARDS)
943 return ecp_add(a, a, aminus3);
945 else if (a->curve->type == EC_WEIERSTRASS)
947 return ecp_doublew(a, aminus3);
951 return ecp_doublem(a);
955 static struct ec_point *ecp_addw(const struct ec_point *a,
956 const struct ec_point *b,
959 Bignum U1, U2, S1, S2, outx, outy, outz;
966 Z2 = ecf_square(b->z, a->curve);
967 U1 = modmul(a->x, Z2, a->curve->p);
968 Z3 = modmul(Z2, b->z, a->curve->p);
970 S1 = modmul(a->y, Z3, a->curve->p);
982 Z2 = ecf_square(a->z, b->curve);
983 U2 = modmul(b->x, Z2, b->curve->p);
984 Z3 = modmul(Z2, a->z, b->curve->p);
986 S2 = modmul(b->y, Z3, b->curve->p);
993 /* Check if multiplying by self */
994 if (bignum_cmp(U1, U2) == 0)
998 if (bignum_cmp(S1, S2) == 0)
1002 return ecp_double(a, aminus3);
1009 return ec_point_new(a->curve, NULL, NULL, NULL, 1);
1014 Bignum H, R, UH2, H3;
1017 H = modsub(U2, U1, a->curve->p);
1021 R = modsub(S2, S1, a->curve->p);
1024 /* X3 = R^2 - H^3 - 2*U1*H^2 */
1026 Bignum R2, H2, _2UH2, first;
1028 H2 = ecf_square(H, a->curve);
1029 UH2 = modmul(U1, H2, a->curve->p);
1031 H3 = modmul(H2, H, a->curve->p);
1033 R2 = ecf_square(R, a->curve);
1034 _2UH2 = ecf_double(UH2, a->curve);
1035 first = modsub(R2, H3, a->curve->p);
1037 outx = modsub(first, _2UH2, a->curve->p);
1042 /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
1044 Bignum RUH2mX, UH2mX, SH3;
1046 UH2mX = modsub(UH2, outx, a->curve->p);
1048 RUH2mX = modmul(R, UH2mX, a->curve->p);
1051 SH3 = modmul(S1, H3, a->curve->p);
1055 outy = modsub(RUH2mX, SH3, a->curve->p);
1064 ZZ = modmul(a->z, b->z, a->curve->p);
1065 outz = modmul(H, ZZ, a->curve->p);
1069 outz = modmul(H, a->z, a->curve->p);
1072 outz = modmul(H, b->z, a->curve->p);
1079 return ec_point_new(a->curve, outx, outy, outz, 0);
1082 static struct ec_point *ecp_addm(const struct ec_point *a,
1083 const struct ec_point *b,
1084 const struct ec_point *base)
1086 Bignum outx, outz, az, bz;
1097 /* a-b is maintained at 1 due to Montgomery ladder implementation */
1098 /* Xa+b = Za-b * ((Xa - Za)*(Xb + Zb) + (Xa + Za)*(Xb - Zb))^2 */
1099 /* Za+b = Xa-b * ((Xa - Za)*(Xb + Zb) - (Xa + Za)*(Xb - Zb))^2 */
1101 Bignum tmp, tmp2, tmp3, tmp4;
1103 /* (Xa + Za) * (Xb - Zb) */
1104 tmp = ecf_add(a->x, az, a->curve);
1105 tmp2 = modsub(b->x, bz, a->curve->p);
1106 tmp3 = modmul(tmp, tmp2, a->curve->p);
1110 /* (Xa - Za) * (Xb + Zb) */
1111 tmp = modsub(a->x, az, a->curve->p);
1112 tmp2 = ecf_add(b->x, bz, a->curve);
1113 tmp4 = modmul(tmp, tmp2, a->curve->p);
1117 tmp = ecf_add(tmp3, tmp4, a->curve);
1118 outx = ecf_square(tmp, a->curve);
1121 tmp = modsub(tmp3, tmp4, a->curve->p);
1124 tmp2 = ecf_square(tmp, a->curve);
1126 outz = modmul(base->x, tmp2, a->curve->p);
1130 return ec_point_new(a->curve, outx, NULL, outz, 0);
1133 static struct ec_point *ecp_adde(const struct ec_point *a,
1134 const struct ec_point *b)
1136 Bignum outx, outy, dmul;
1138 /* outx = (a->x * b->y + b->x * a->y) /
1139 * (1 + a->curve->e.d * a->x * b->x * a->y * b->y) */
1141 Bignum tmp, tmp2, tmp3, tmp4;
1143 tmp = modmul(a->x, b->y, a->curve->p);
1144 tmp2 = modmul(b->x, a->y, a->curve->p);
1145 tmp3 = ecf_add(tmp, tmp2, a->curve);
1147 tmp4 = modmul(tmp, tmp2, a->curve->p);
1150 dmul = modmul(a->curve->e.d, tmp4, a->curve->p);
1153 tmp = ecf_add(One, dmul, a->curve);
1154 tmp2 = modinv(tmp, a->curve->p);
1163 outx = modmul(tmp3, tmp2, a->curve->p);
1168 /* outy = (a->y * b->y + a->x * b->x) /
1169 * (1 - a->curve->e.d * a->x * b->x * a->y * b->y) */
1171 Bignum tmp, tmp2, tmp3, tmp4;
1173 tmp = modsub(One, dmul, a->curve->p);
1176 tmp2 = modinv(tmp, a->curve->p);
1184 tmp = modmul(a->y, b->y, a->curve->p);
1185 tmp3 = modmul(a->x, b->x, a->curve->p);
1186 tmp4 = ecf_add(tmp, tmp3, a->curve);
1190 outy = modmul(tmp4, tmp2, a->curve->p);
1195 return ec_point_new(a->curve, outx, outy, NULL, 0);
1198 static struct ec_point *ecp_add(const struct ec_point *a,
1199 const struct ec_point *b,
1202 if (a->curve != b->curve) {
1206 /* Check if multiplying by infinity */
1207 if (a->infinity) return ec_point_copy(b);
1208 if (b->infinity) return ec_point_copy(a);
1210 if (a->curve->type == EC_EDWARDS)
1212 return ecp_adde(a, b);
1215 if (a->curve->type == EC_WEIERSTRASS)
1217 return ecp_addw(a, b, aminus3);
1223 static struct ec_point *ecp_mul_(const struct ec_point *a, const Bignum b, int aminus3)
1225 struct ec_point *A, *ret;
1228 A = ec_point_copy(a);
1229 ret = ec_point_new(a->curve, NULL, NULL, NULL, 1);
1231 bits = bignum_bitcount(b);
1232 for (i = 0; i < bits; ++i)
1234 if (bignum_bit(b, i))
1236 struct ec_point *tmp = ecp_add(ret, A, aminus3);
1242 struct ec_point *tmp = ecp_double(A, aminus3);
1252 static struct ec_point *ecp_mulw(const struct ec_point *a, const Bignum b)
1254 struct ec_point *ret = ecp_mul_(a, b, ec_aminus3(a->curve));
1256 if (!ecp_normalise(ret)) {
1264 static struct ec_point *ecp_mule(const struct ec_point *a, const Bignum b)
1267 struct ec_point *ret;
1269 ret = ec_point_new(a->curve, NULL, NULL, NULL, 1);
1271 for (i = bignum_bitcount(b); i >= 0 && ret; --i)
1274 struct ec_point *tmp = ecp_double(ret, 0);
1278 if (ret && bignum_bit(b, i))
1280 struct ec_point *tmp = ecp_add(ret, a, 0);
1289 static struct ec_point *ecp_mulm(const struct ec_point *p, const Bignum n)
1291 struct ec_point *P1, *P2;
1294 /* P1 <- P and P2 <- [2]P */
1295 P2 = ecp_double(p, 0);
1296 P1 = ec_point_copy(p);
1298 /* for i = bits − 2 down to 0 */
1299 bits = bignum_bitcount(n);
1300 for (i = bits - 2; i >= 0; --i)
1302 if (!bignum_bit(n, i))
1305 struct ec_point *tmp = ecp_addm(P1, P2, p);
1310 tmp = ecp_double(P1, 0);
1317 struct ec_point *tmp = ecp_addm(P1, P2, p);
1322 tmp = ecp_double(P2, 0);
1330 if (!ecp_normalise(P1)) {
1338 /* Not static because it is used by sshecdsag.c to generate a new key */
1339 struct ec_point *ecp_mul(const struct ec_point *a, const Bignum b)
1341 if (a->curve->type == EC_WEIERSTRASS) {
1342 return ecp_mulw(a, b);
1343 } else if (a->curve->type == EC_EDWARDS) {
1344 return ecp_mule(a, b);
1346 return ecp_mulm(a, b);
1350 static struct ec_point *ecp_summul(const Bignum a, const Bignum b,
1351 const struct ec_point *point)
1353 struct ec_point *aG, *bP, *ret;
1356 if (point->curve->type != EC_WEIERSTRASS) {
1360 aminus3 = ec_aminus3(point->curve);
1362 aG = ecp_mul_(&point->curve->w.G, a, aminus3);
1363 if (!aG) return NULL;
1364 bP = ecp_mul_(point, b, aminus3);
1370 ret = ecp_add(aG, bP, aminus3);
1375 if (!ecp_normalise(ret)) {
1382 static Bignum *ecp_edx(const struct ec_curve *curve, const Bignum y)
1384 /* Get the x value on the given Edwards curve for a given y */
1387 /* xx = (y^2 - 1) / (d * y^2 + 1) */
1389 Bignum tmp, tmp2, tmp3;
1391 tmp = ecf_square(y, curve);
1392 tmp2 = modmul(curve->e.d, tmp, curve->p);
1393 tmp3 = ecf_add(tmp2, One, curve);
1395 tmp2 = modinv(tmp3, curve->p);
1402 tmp3 = modsub(tmp, One, curve->p);
1404 xx = modmul(tmp3, tmp2, curve->p);
1409 /* x = xx^((p + 3) / 8) */
1413 tmp = bignum_add_long(curve->p, 3);
1414 tmp2 = bignum_rshift(tmp, 3);
1416 x = modpow(xx, tmp2, curve->p);
1420 /* if x^2 - xx != 0 then x = x*(2^((p - 1) / 4)) */
1424 tmp = ecf_square(x, curve);
1425 tmp2 = modsub(tmp, xx, curve->p);
1428 if (bignum_cmp(tmp2, Zero)) {
1433 tmp = modsub(curve->p, One, curve->p);
1434 tmp2 = bignum_rshift(tmp, 2);
1436 tmp = bignum_from_long(2);
1437 tmp3 = modpow(tmp, tmp2, curve->p);
1441 tmp = modmul(x, tmp3, curve->p);
1450 /* if x % 2 != 0 then x = p - x */
1451 if (bignum_bit(x, 0)) {
1452 Bignum tmp = modsub(curve->p, x, curve->p);
1460 /* ----------------------------------------------------------------------
1461 * Public point from private
1464 struct ec_point *ec_public(const Bignum privateKey, const struct ec_curve *curve)
1466 if (curve->type == EC_WEIERSTRASS) {
1467 return ecp_mul(&curve->w.G, privateKey);
1468 } else if (curve->type == EC_EDWARDS) {
1469 /* hash = H(sk) (where hash creates 2 * fieldBits)
1471 * a = 2^(b-2) + SUM(2^i * h_i) for i = 2 -> b-2
1473 struct ec_point *ret;
1474 unsigned char hash[512/8];
1480 keylen = curve->fieldBits / 8;
1481 for (i = 0; i < keylen; ++i) {
1482 unsigned char b = bignum_byte(privateKey, i);
1483 SHA512_Bytes(&s, &b, 1);
1485 SHA512_Final(&s, hash);
1487 /* The second part is simply turning the hash into a Bignum,
1488 * however the 2^(b-2) bit *must* be set, and the bottom 3
1489 * bits *must* not be */
1490 hash[0] &= 0xf8; /* Unset bottom 3 bits (if set) */
1491 hash[31] &= 0x7f; /* Unset above (b-2) */
1492 hash[31] |= 0x40; /* Set 2^(b-2) */
1493 /* Chop off the top part and convert to int */
1494 a = bignum_from_bytes_le(hash, 32);
1496 ret = ecp_mul(&curve->e.B, a);
1504 /* ----------------------------------------------------------------------
1505 * Basic sign and verify routines
1508 static int _ecdsa_verify(const struct ec_point *publicKey,
1509 const unsigned char *data, const int dataLen,
1510 const Bignum r, const Bignum s)
1516 if (publicKey->curve->type != EC_WEIERSTRASS) {
1521 if (bignum_cmp(r, Zero) == 0 || bignum_cmp(r, publicKey->curve->w.n) >= 0
1522 || bignum_cmp(s, Zero) == 0 || bignum_cmp(s, publicKey->curve->w.n) >= 0)
1527 /* z = left most bitlen(curve->n) of data */
1528 z = bignum_from_bytes(data, dataLen);
1529 n_bits = bignum_bitcount(publicKey->curve->w.n);
1530 z_bits = bignum_bitcount(z);
1531 if (z_bits > n_bits)
1533 Bignum tmp = bignum_rshift(z, z_bits - n_bits);
1538 /* Ensure z in range of n */
1540 Bignum tmp = bigmod(z, publicKey->curve->w.n);
1545 /* Calculate signature */
1547 Bignum w, x, u1, u2;
1548 struct ec_point *tmp;
1550 w = modinv(s, publicKey->curve->w.n);
1555 u1 = modmul(z, w, publicKey->curve->w.n);
1556 u2 = modmul(r, w, publicKey->curve->w.n);
1559 tmp = ecp_summul(u1, u2, publicKey);
1567 x = bigmod(tmp->x, publicKey->curve->w.n);
1570 valid = (bignum_cmp(r, x) == 0) ? 1 : 0;
1579 static void _ecdsa_sign(const Bignum privateKey, const struct ec_curve *curve,
1580 const unsigned char *data, const int dataLen,
1581 Bignum *r, Bignum *s)
1583 unsigned char digest[20];
1586 struct ec_point *kG;
1591 if (curve->type != EC_WEIERSTRASS) {
1595 /* z = left most bitlen(curve->n) of data */
1596 z = bignum_from_bytes(data, dataLen);
1597 n_bits = bignum_bitcount(curve->w.n);
1598 z_bits = bignum_bitcount(z);
1599 if (z_bits > n_bits)
1602 tmp = bignum_rshift(z, z_bits - n_bits);
1607 /* Generate k between 1 and curve->n, using the same deterministic
1608 * k generation system we use for conventional DSA. */
1609 SHA_Simple(data, dataLen, digest);
1610 k = dss_gen_k("ECDSA deterministic k generator", curve->w.n, privateKey,
1611 digest, sizeof(digest));
1613 kG = ecp_mul(&curve->w.G, k);
1620 /* r = kG.x mod n */
1621 *r = bigmod(kG->x, curve->w.n);
1624 /* s = (z + r * priv)/k mod n */
1626 Bignum rPriv, zMod, first, firstMod, kInv;
1627 rPriv = modmul(*r, privateKey, curve->w.n);
1628 zMod = bigmod(z, curve->w.n);
1630 first = bigadd(rPriv, zMod);
1633 firstMod = bigmod(first, curve->w.n);
1635 kInv = modinv(k, curve->w.n);
1642 *s = modmul(firstMod, kInv, curve->w.n);
1648 /* ----------------------------------------------------------------------
1652 static void getstring(const char **data, int *datalen,
1653 const char **p, int *length)
1658 *length = toint(GET_32BIT(*data));
1663 if (*datalen < *length)
1667 *datalen -= *length;
1670 static Bignum getmp(const char **data, int *datalen)
1675 getstring(data, datalen, &p, &length);
1679 return NULL; /* negative mp */
1680 return bignum_from_bytes((unsigned char *)p, length);
1683 static Bignum getmp_le(const char **data, int *datalen)
1688 getstring(data, datalen, &p, &length);
1691 return bignum_from_bytes_le((const unsigned char *)p, length);
1694 static int decodepoint_ed(const char *p, int length, struct ec_point *point)
1696 /* Got some conversion to do, first read in the y co-ord */
1699 point->y = bignum_from_bytes_le((const unsigned char*)p, length);
1700 if ((unsigned)bignum_bitcount(point->y) > point->curve->fieldBits) {
1705 /* Read x bit and then reset it */
1706 negative = bignum_bit(point->y, point->curve->fieldBits - 1);
1707 bignum_set_bit(point->y, point->curve->fieldBits - 1, 0);
1708 bn_restore_invariant(point->y);
1710 /* Get the x from the y */
1711 point->x = ecp_edx(point->curve, point->y);
1718 Bignum tmp = modsub(point->curve->p, point->x, point->curve->p);
1723 /* Verify the point is on the curve */
1724 if (!ec_point_verify(point)) {
1735 static int decodepoint(const char *p, int length, struct ec_point *point)
1737 if (point->curve->type == EC_EDWARDS) {
1738 return decodepoint_ed(p, length, point);
1741 if (length < 1 || p[0] != 0x04) /* Only support uncompressed point */
1743 /* Skip compression flag */
1746 /* The two values must be equal length */
1747 if (length % 2 != 0) {
1753 length = length / 2;
1754 point->x = bignum_from_bytes((const unsigned char *)p, length);
1756 point->y = bignum_from_bytes((const unsigned char *)p, length);
1759 /* Verify the point is on the curve */
1760 if (!ec_point_verify(point)) {
1771 static int getmppoint(const char **data, int *datalen, struct ec_point *point)
1776 getstring(data, datalen, &p, &length);
1778 return decodepoint(p, length, point);
1781 /* ----------------------------------------------------------------------
1782 * Exposed ECDSA interface
1785 struct ecsign_extra {
1786 struct ec_curve *(*curve)(void);
1787 const struct ssh_hash *hash;
1789 /* These fields are used by the OpenSSH PEM format importer/exporter */
1790 const unsigned char *oid;
1794 static void ecdsa_freekey(void *key)
1796 struct ec_key *ec = (struct ec_key *) key;
1799 if (ec->publicKey.x)
1800 freebn(ec->publicKey.x);
1801 if (ec->publicKey.y)
1802 freebn(ec->publicKey.y);
1803 if (ec->publicKey.z)
1804 freebn(ec->publicKey.z);
1806 freebn(ec->privateKey);
1810 static void *ecdsa_newkey(const struct ssh_signkey *self,
1811 const char *data, int len)
1813 const struct ecsign_extra *extra =
1814 (const struct ecsign_extra *)self->extra;
1818 struct ec_curve *curve;
1820 getstring(&data, &len, &p, &slen);
1825 curve = extra->curve();
1826 assert(curve->type == EC_WEIERSTRASS || curve->type == EC_EDWARDS);
1828 /* Curve name is duplicated for Weierstrass form */
1829 if (curve->type == EC_WEIERSTRASS) {
1830 getstring(&data, &len, &p, &slen);
1831 if (!p) return NULL;
1832 if (!match_ssh_id(slen, p, curve->name)) return NULL;
1835 ec = snew(struct ec_key);
1838 ec->publicKey.curve = curve;
1839 ec->publicKey.infinity = 0;
1840 ec->publicKey.x = NULL;
1841 ec->publicKey.y = NULL;
1842 ec->publicKey.z = NULL;
1843 ec->privateKey = NULL;
1844 if (!getmppoint(&data, &len, &ec->publicKey)) {
1849 if (!ec->publicKey.x || !ec->publicKey.y ||
1850 bignum_cmp(ec->publicKey.x, curve->p) >= 0 ||
1851 bignum_cmp(ec->publicKey.y, curve->p) >= 0)
1860 static char *ecdsa_fmtkey(void *key)
1862 struct ec_key *ec = (struct ec_key *) key;
1864 int len, i, pos, nibbles;
1865 static const char hex[] = "0123456789abcdef";
1866 if (!ec->publicKey.x || !ec->publicKey.y || !ec->publicKey.curve)
1869 len = 4 + 2 + 1; /* 2 x "0x", punctuation, \0 */
1870 if (ec->publicKey.curve->name)
1871 len += strlen(ec->publicKey.curve->name); /* Curve name */
1872 len += 4 * (bignum_bitcount(ec->publicKey.x) + 15) / 16;
1873 len += 4 * (bignum_bitcount(ec->publicKey.y) + 15) / 16;
1874 p = snewn(len, char);
1877 if (ec->publicKey.curve->name)
1878 pos += sprintf(p + pos, "%s,", ec->publicKey.curve->name);
1879 pos += sprintf(p + pos, "0x");
1880 nibbles = (3 + bignum_bitcount(ec->publicKey.x)) / 4;
1883 for (i = nibbles; i--;) {
1885 hex[(bignum_byte(ec->publicKey.x, i / 2) >> (4 * (i % 2))) & 0xF];
1887 pos += sprintf(p + pos, ",0x");
1888 nibbles = (3 + bignum_bitcount(ec->publicKey.y)) / 4;
1891 for (i = nibbles; i--;) {
1893 hex[(bignum_byte(ec->publicKey.y, i / 2) >> (4 * (i % 2))) & 0xF];
1899 static unsigned char *ecdsa_public_blob(void *key, int *len)
1901 struct ec_key *ec = (struct ec_key *) key;
1902 int pointlen, bloblen, fullnamelen, namelen;
1904 unsigned char *blob, *p;
1906 fullnamelen = strlen(ec->signalg->name);
1908 if (ec->publicKey.curve->type == EC_EDWARDS) {
1909 /* Edwards compressed form "ssh-ed25519" point y[:-1] + x[0:1] */
1911 pointlen = ec->publicKey.curve->fieldBits / 8;
1913 /* Can't handle this in our loop */
1914 if (pointlen < 2) return NULL;
1916 bloblen = 4 + fullnamelen + 4 + pointlen;
1917 blob = snewn(bloblen, unsigned char);
1920 PUT_32BIT(p, fullnamelen);
1922 memcpy(p, ec->signalg->name, fullnamelen);
1924 PUT_32BIT(p, pointlen);
1927 /* Unset last bit of y and set first bit of x in its place */
1928 for (i = 0; i < pointlen - 1; ++i) {
1929 *p++ = bignum_byte(ec->publicKey.y, i);
1931 /* Unset last bit of y and set first bit of x in its place */
1932 *p = bignum_byte(ec->publicKey.y, i) & 0x7f;
1933 *p++ |= bignum_bit(ec->publicKey.x, 0) << 7;
1934 } else if (ec->publicKey.curve->type == EC_WEIERSTRASS) {
1935 assert(ec->publicKey.curve->name);
1936 namelen = strlen(ec->publicKey.curve->name);
1938 pointlen = (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8;
1941 * string "ecdsa-sha2-<name>", string "<name>", 0x04 point x, y.
1943 bloblen = 4 + fullnamelen + 4 + namelen + 4 + 1 + (pointlen * 2);
1944 blob = snewn(bloblen, unsigned char);
1947 PUT_32BIT(p, fullnamelen);
1949 memcpy(p, ec->signalg->name, fullnamelen);
1951 PUT_32BIT(p, namelen);
1953 memcpy(p, ec->publicKey.curve->name, namelen);
1955 PUT_32BIT(p, (2 * pointlen) + 1);
1958 for (i = pointlen; i--;) {
1959 *p++ = bignum_byte(ec->publicKey.x, i);
1961 for (i = pointlen; i--;) {
1962 *p++ = bignum_byte(ec->publicKey.y, i);
1968 assert(p == blob + bloblen);
1974 static unsigned char *ecdsa_private_blob(void *key, int *len)
1976 struct ec_key *ec = (struct ec_key *) key;
1977 int keylen, bloblen;
1979 unsigned char *blob, *p;
1981 if (!ec->privateKey) return NULL;
1983 if (ec->publicKey.curve->type == EC_EDWARDS) {
1985 keylen = (bignum_bitcount(ec->privateKey) + 7) / 8;
1988 keylen = (bignum_bitcount(ec->privateKey) + 8) / 8;
1992 * mpint privateKey. Total 4 + keylen.
1994 bloblen = 4 + keylen;
1995 blob = snewn(bloblen, unsigned char);
1998 PUT_32BIT(p, keylen);
2000 if (ec->publicKey.curve->type == EC_EDWARDS) {
2002 for (i = 0; i < keylen; ++i)
2003 *p++ = bignum_byte(ec->privateKey, i);
2005 for (i = keylen; i--;)
2006 *p++ = bignum_byte(ec->privateKey, i);
2009 assert(p == blob + bloblen);
2014 static void *ecdsa_createkey(const struct ssh_signkey *self,
2015 const unsigned char *pub_blob, int pub_len,
2016 const unsigned char *priv_blob, int priv_len)
2019 struct ec_point *publicKey;
2020 const char *pb = (const char *) priv_blob;
2022 ec = (struct ec_key*)ecdsa_newkey(self, (const char *) pub_blob, pub_len);
2027 if (ec->publicKey.curve->type != EC_WEIERSTRASS
2028 && ec->publicKey.curve->type != EC_EDWARDS) {
2033 if (ec->publicKey.curve->type == EC_EDWARDS) {
2034 ec->privateKey = getmp_le(&pb, &priv_len);
2036 ec->privateKey = getmp(&pb, &priv_len);
2038 if (!ec->privateKey) {
2043 /* Check that private key generates public key */
2044 publicKey = ec_public(ec->privateKey, ec->publicKey.curve);
2047 bignum_cmp(publicKey->x, ec->publicKey.x) ||
2048 bignum_cmp(publicKey->y, ec->publicKey.y))
2053 ec_point_free(publicKey);
2058 static void *ed25519_openssh_createkey(const struct ssh_signkey *self,
2059 const unsigned char **blob, int *len)
2062 struct ec_point *publicKey;
2066 getstring((const char**)blob, len, &p, &plen);
2072 ec = snew(struct ec_key);
2075 ec->publicKey.curve = ec_ed25519();
2076 ec->publicKey.infinity = 0;
2077 ec->privateKey = NULL;
2078 ec->publicKey.x = NULL;
2079 ec->publicKey.z = NULL;
2080 ec->publicKey.y = NULL;
2082 if (!decodepoint_ed(p, plen, &ec->publicKey))
2088 getstring((const char**)blob, len, &q, &qlen);
2094 ec->privateKey = bignum_from_bytes_le((const unsigned char *)q, 32);
2096 /* Check that private key generates public key */
2097 publicKey = ec_public(ec->privateKey, ec->publicKey.curve);
2100 bignum_cmp(publicKey->x, ec->publicKey.x) ||
2101 bignum_cmp(publicKey->y, ec->publicKey.y))
2106 ec_point_free(publicKey);
2108 /* The OpenSSH format for ed25519 private keys also for some
2109 * reason encodes an extra copy of the public key in the second
2110 * half of the secret-key string. Check that that's present and
2111 * correct as well, otherwise the key we think we've imported
2112 * won't behave identically to the way OpenSSH would have treated
2114 if (plen != 32 || 0 != memcmp(q + 32, p, 32)) {
2122 static int ed25519_openssh_fmtkey(void *key, unsigned char *blob, int len)
2124 struct ec_key *ec = (struct ec_key *) key;
2131 if (ec->publicKey.curve->type != EC_EDWARDS) {
2135 pointlen = (bignum_bitcount(ec->publicKey.y) + 7) / 8;
2136 keylen = (bignum_bitcount(ec->privateKey) + 7) / 8;
2137 bloblen = 4 + pointlen + 4 + keylen + pointlen;
2142 /* Encode the public point */
2143 PUT_32BIT(blob, pointlen);
2146 for (i = 0; i < pointlen - 1; ++i) {
2147 *blob++ = bignum_byte(ec->publicKey.y, i);
2149 /* Unset last bit of y and set first bit of x in its place */
2150 *blob = bignum_byte(ec->publicKey.y, i) & 0x7f;
2151 *blob++ |= bignum_bit(ec->publicKey.x, 0) << 7;
2153 PUT_32BIT(blob, keylen + pointlen);
2155 for (i = 0; i < keylen; ++i) {
2156 *blob++ = bignum_byte(ec->privateKey, i);
2158 /* Now encode an extra copy of the public point as the second half
2159 * of the private key string, as the OpenSSH format for some
2160 * reason requires */
2161 for (i = 0; i < pointlen - 1; ++i) {
2162 *blob++ = bignum_byte(ec->publicKey.y, i);
2164 /* Unset last bit of y and set first bit of x in its place */
2165 *blob = bignum_byte(ec->publicKey.y, i) & 0x7f;
2166 *blob++ |= bignum_bit(ec->publicKey.x, 0) << 7;
2171 static void *ecdsa_openssh_createkey(const struct ssh_signkey *self,
2172 const unsigned char **blob, int *len)
2174 const struct ecsign_extra *extra =
2175 (const struct ecsign_extra *)self->extra;
2176 const char **b = (const char **) blob;
2180 struct ec_curve *curve;
2181 struct ec_point *publicKey;
2183 getstring(b, len, &p, &slen);
2188 curve = extra->curve();
2189 assert(curve->type == EC_WEIERSTRASS);
2191 ec = snew(struct ec_key);
2194 ec->publicKey.curve = curve;
2195 ec->publicKey.infinity = 0;
2196 ec->publicKey.x = NULL;
2197 ec->publicKey.y = NULL;
2198 ec->publicKey.z = NULL;
2199 if (!getmppoint(b, len, &ec->publicKey)) {
2203 ec->privateKey = NULL;
2205 if (!ec->publicKey.x || !ec->publicKey.y ||
2206 bignum_cmp(ec->publicKey.x, curve->p) >= 0 ||
2207 bignum_cmp(ec->publicKey.y, curve->p) >= 0)
2213 ec->privateKey = getmp(b, len);
2214 if (ec->privateKey == NULL)
2220 /* Now check that the private key makes the public key */
2221 publicKey = ec_public(ec->privateKey, ec->publicKey.curve);
2228 if (bignum_cmp(ec->publicKey.x, publicKey->x) ||
2229 bignum_cmp(ec->publicKey.y, publicKey->y))
2231 /* Private key doesn't make the public key on the given curve */
2233 ec_point_free(publicKey);
2237 ec_point_free(publicKey);
2242 static int ecdsa_openssh_fmtkey(void *key, unsigned char *blob, int len)
2244 struct ec_key *ec = (struct ec_key *) key;
2251 if (ec->publicKey.curve->type != EC_WEIERSTRASS) {
2255 pointlen = (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8;
2256 namelen = strlen(ec->publicKey.curve->name);
2258 4 + namelen /* <LEN> nistpXXX */
2259 + 4 + 1 + (pointlen * 2) /* <LEN> 0x04 pX pY */
2260 + ssh2_bignum_length(ec->privateKey);
2267 PUT_32BIT(blob+bloblen, namelen);
2269 memcpy(blob+bloblen, ec->publicKey.curve->name, namelen);
2272 PUT_32BIT(blob+bloblen, 1 + (pointlen * 2));
2274 blob[bloblen++] = 0x04;
2275 for (i = pointlen; i--; )
2276 blob[bloblen++] = bignum_byte(ec->publicKey.x, i);
2277 for (i = pointlen; i--; )
2278 blob[bloblen++] = bignum_byte(ec->publicKey.y, i);
2280 pointlen = (bignum_bitcount(ec->privateKey) + 8) / 8;
2281 PUT_32BIT(blob+bloblen, pointlen);
2283 for (i = pointlen; i--; )
2284 blob[bloblen++] = bignum_byte(ec->privateKey, i);
2289 static int ecdsa_pubkey_bits(const struct ssh_signkey *self,
2290 const void *blob, int len)
2295 ec = (struct ec_key*)ecdsa_newkey(self, (const char *) blob, len);
2298 ret = ec->publicKey.curve->fieldBits;
2304 static int ecdsa_verifysig(void *key, const char *sig, int siglen,
2305 const char *data, int datalen)
2307 struct ec_key *ec = (struct ec_key *) key;
2308 const struct ecsign_extra *extra =
2309 (const struct ecsign_extra *)ec->signalg->extra;
2315 if (!ec->publicKey.x || !ec->publicKey.y || !ec->publicKey.curve)
2318 /* Check the signature starts with the algorithm name */
2319 getstring(&sig, &siglen, &p, &slen);
2323 if (!match_ssh_id(slen, p, ec->signalg->name)) {
2327 getstring(&sig, &siglen, &p, &slen);
2329 if (ec->publicKey.curve->type == EC_EDWARDS) {
2333 /* Check that the signature is two times the length of a point */
2334 if (slen != (ec->publicKey.curve->fieldBits / 8) * 2) {
2338 /* Check it's the 256 bit field so that SHA512 is the correct hash */
2339 if (ec->publicKey.curve->fieldBits != 256) {
2343 /* Get the signature */
2344 r = ec_point_new(ec->publicKey.curve, NULL, NULL, NULL, 0);
2348 if (!decodepoint(p, ec->publicKey.curve->fieldBits / 8, r)) {
2352 s = bignum_from_bytes_le((unsigned char*)p + (ec->publicKey.curve->fieldBits / 8),
2353 ec->publicKey.curve->fieldBits / 8);
2355 /* Get the hash of the encoded value of R + encoded value of pk + message */
2359 unsigned char digest[512 / 8];
2363 /* Add encoded r (no need to encode it again, it was in the signature) */
2364 SHA512_Bytes(&hs, p, ec->publicKey.curve->fieldBits / 8);
2366 /* Encode pk and add it */
2367 pointlen = ec->publicKey.curve->fieldBits / 8;
2368 for (i = 0; i < pointlen - 1; ++i) {
2369 b = bignum_byte(ec->publicKey.y, i);
2370 SHA512_Bytes(&hs, &b, 1);
2372 /* Unset last bit of y and set first bit of x in its place */
2373 b = bignum_byte(ec->publicKey.y, i) & 0x7f;
2374 b |= bignum_bit(ec->publicKey.x, 0) << 7;
2375 SHA512_Bytes(&hs, &b, 1);
2377 /* Add the message itself */
2378 SHA512_Bytes(&hs, data, datalen);
2381 SHA512_Final(&hs, digest);
2383 /* Convert to Bignum */
2384 h = bignum_from_bytes_le(digest, sizeof(digest));
2387 /* Verify sB == r + h*publicKey */
2389 struct ec_point *lhs, *rhs, *tmp;
2392 lhs = ecp_mul(&ec->publicKey.curve->e.B, s);
2400 /* rhs = r + h*publicKey */
2401 tmp = ecp_mul(&ec->publicKey, h);
2408 rhs = ecp_add(r, tmp, 0);
2416 /* Check the point is the same */
2417 ret = !bignum_cmp(lhs->x, rhs->x);
2419 ret = !bignum_cmp(lhs->y, rhs->y);
2429 unsigned char digest[512 / 8];
2432 r = getmp(&p, &slen);
2434 s = getmp(&p, &slen);
2440 digestLen = extra->hash->hlen;
2441 assert(digestLen <= sizeof(digest));
2442 hashctx = extra->hash->init();
2443 extra->hash->bytes(hashctx, data, datalen);
2444 extra->hash->final(hashctx, digest);
2446 /* Verify the signature */
2447 ret = _ecdsa_verify(&ec->publicKey, digest, digestLen, r, s);
2456 static unsigned char *ecdsa_sign(void *key, const char *data, int datalen,
2459 struct ec_key *ec = (struct ec_key *) key;
2460 const struct ecsign_extra *extra =
2461 (const struct ecsign_extra *)ec->signalg->extra;
2462 unsigned char digest[512 / 8];
2464 Bignum r = NULL, s = NULL;
2465 unsigned char *buf, *p;
2466 int rlen, slen, namelen;
2469 if (!ec->privateKey || !ec->publicKey.curve) {
2473 if (ec->publicKey.curve->type == EC_EDWARDS) {
2474 struct ec_point *rp;
2475 int pointlen = ec->publicKey.curve->fieldBits / 8;
2477 /* hash = H(sk) (where hash creates 2 * fieldBits)
2479 * a = 2^(b-2) + SUM(2^i * h_i) for i = 2 -> b-2
2480 * r = H(h[b/8:b/4] + m)
2482 * S = (r + H(encodepoint(R) + encodepoint(pk) + m) * a) % l */
2484 unsigned char hash[512/8];
2490 for (i = 0; i < pointlen; ++i) {
2491 unsigned char b = (unsigned char)bignum_byte(ec->privateKey, i);
2492 SHA512_Bytes(&hs, &b, 1);
2495 SHA512_Final(&hs, hash);
2497 /* The second part is simply turning the hash into a
2498 * Bignum, however the 2^(b-2) bit *must* be set, and the
2499 * bottom 3 bits *must* not be */
2500 hash[0] &= 0xf8; /* Unset bottom 3 bits (if set) */
2501 hash[31] &= 0x7f; /* Unset above (b-2) */
2502 hash[31] |= 0x40; /* Set 2^(b-2) */
2503 /* Chop off the top part and convert to int */
2504 a = bignum_from_bytes_le(hash, 32);
2508 hash+(ec->publicKey.curve->fieldBits / 8),
2509 (ec->publicKey.curve->fieldBits / 4)
2510 - (ec->publicKey.curve->fieldBits / 8));
2511 SHA512_Bytes(&hs, data, datalen);
2512 SHA512_Final(&hs, hash);
2514 r = bignum_from_bytes_le(hash, 512/8);
2515 rp = ecp_mul(&ec->publicKey.curve->e.B, r);
2522 /* Now calculate s */
2524 /* Encode the point R */
2525 for (i = 0; i < pointlen - 1; ++i) {
2526 b = bignum_byte(rp->y, i);
2527 SHA512_Bytes(&hs, &b, 1);
2529 /* Unset last bit of y and set first bit of x in its place */
2530 b = bignum_byte(rp->y, i) & 0x7f;
2531 b |= bignum_bit(rp->x, 0) << 7;
2532 SHA512_Bytes(&hs, &b, 1);
2534 /* Encode the point pk */
2535 for (i = 0; i < pointlen - 1; ++i) {
2536 b = bignum_byte(ec->publicKey.y, i);
2537 SHA512_Bytes(&hs, &b, 1);
2539 /* Unset last bit of y and set first bit of x in its place */
2540 b = bignum_byte(ec->publicKey.y, i) & 0x7f;
2541 b |= bignum_bit(ec->publicKey.x, 0) << 7;
2542 SHA512_Bytes(&hs, &b, 1);
2544 /* Add the message */
2545 SHA512_Bytes(&hs, data, datalen);
2546 SHA512_Final(&hs, hash);
2551 tmp = bignum_from_bytes_le(hash, 512/8);
2552 tmp2 = modmul(tmp, a, ec->publicKey.curve->e.l);
2555 tmp = bigadd(r, tmp2);
2558 s = bigmod(tmp, ec->publicKey.curve->e.l);
2563 /* Format the output */
2564 namelen = strlen(ec->signalg->name);
2565 *siglen = 4+namelen+4+((ec->publicKey.curve->fieldBits / 8)*2);
2566 buf = snewn(*siglen, unsigned char);
2568 PUT_32BIT(p, namelen);
2570 memcpy(p, ec->signalg->name, namelen);
2572 PUT_32BIT(p, ((ec->publicKey.curve->fieldBits / 8)*2));
2575 /* Encode the point */
2576 pointlen = ec->publicKey.curve->fieldBits / 8;
2577 for (i = 0; i < pointlen - 1; ++i) {
2578 *p++ = bignum_byte(rp->y, i);
2580 /* Unset last bit of y and set first bit of x in its place */
2581 *p = bignum_byte(rp->y, i) & 0x7f;
2582 *p++ |= bignum_bit(rp->x, 0) << 7;
2585 /* Encode the int */
2586 for (i = 0; i < pointlen; ++i) {
2587 *p++ = bignum_byte(s, i);
2593 digestLen = extra->hash->hlen;
2594 assert(digestLen <= sizeof(digest));
2595 hashctx = extra->hash->init();
2596 extra->hash->bytes(hashctx, data, datalen);
2597 extra->hash->final(hashctx, digest);
2599 /* Do the signature */
2600 _ecdsa_sign(ec->privateKey, ec->publicKey.curve, digest, digestLen, &r, &s);
2607 rlen = (bignum_bitcount(r) + 8) / 8;
2608 slen = (bignum_bitcount(s) + 8) / 8;
2610 namelen = strlen(ec->signalg->name);
2612 /* Format the output */
2613 *siglen = 8+namelen+rlen+slen+8;
2614 buf = snewn(*siglen, unsigned char);
2616 PUT_32BIT(p, namelen);
2618 memcpy(p, ec->signalg->name, namelen);
2620 PUT_32BIT(p, rlen + slen + 8);
2624 for (i = rlen; i--;)
2625 *p++ = bignum_byte(r, i);
2628 for (i = slen; i--;)
2629 *p++ = bignum_byte(s, i);
2638 const struct ecsign_extra sign_extra_ed25519 = {
2642 const struct ssh_signkey ssh_ecdsa_ed25519 = {
2649 ed25519_openssh_createkey,
2650 ed25519_openssh_fmtkey,
2651 2 /* point, private exponent */,
2657 &sign_extra_ed25519,
2660 /* OID: 1.2.840.10045.3.1.7 (ansiX9p256r1) */
2661 static const unsigned char nistp256_oid[] = {
2662 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
2664 const struct ecsign_extra sign_extra_nistp256 = {
2665 ec_p256, &ssh_sha256,
2666 nistp256_oid, lenof(nistp256_oid),
2668 const struct ssh_signkey ssh_ecdsa_nistp256 = {
2675 ecdsa_openssh_createkey,
2676 ecdsa_openssh_fmtkey,
2677 3 /* curve name, point, private exponent */,
2681 "ecdsa-sha2-nistp256",
2682 "ecdsa-sha2-nistp256",
2683 &sign_extra_nistp256,
2686 /* OID: 1.3.132.0.34 (secp384r1) */
2687 static const unsigned char nistp384_oid[] = {
2688 0x2b, 0x81, 0x04, 0x00, 0x22
2690 const struct ecsign_extra sign_extra_nistp384 = {
2691 ec_p384, &ssh_sha384,
2692 nistp384_oid, lenof(nistp384_oid),
2694 const struct ssh_signkey ssh_ecdsa_nistp384 = {
2701 ecdsa_openssh_createkey,
2702 ecdsa_openssh_fmtkey,
2703 3 /* curve name, point, private exponent */,
2707 "ecdsa-sha2-nistp384",
2708 "ecdsa-sha2-nistp384",
2709 &sign_extra_nistp384,
2712 /* OID: 1.3.132.0.35 (secp521r1) */
2713 static const unsigned char nistp521_oid[] = {
2714 0x2b, 0x81, 0x04, 0x00, 0x23
2716 const struct ecsign_extra sign_extra_nistp521 = {
2717 ec_p521, &ssh_sha512,
2718 nistp521_oid, lenof(nistp521_oid),
2720 const struct ssh_signkey ssh_ecdsa_nistp521 = {
2727 ecdsa_openssh_createkey,
2728 ecdsa_openssh_fmtkey,
2729 3 /* curve name, point, private exponent */,
2733 "ecdsa-sha2-nistp521",
2734 "ecdsa-sha2-nistp521",
2735 &sign_extra_nistp521,
2738 /* ----------------------------------------------------------------------
2739 * Exposed ECDH interface
2742 struct eckex_extra {
2743 struct ec_curve *(*curve)(void);
2744 int low_byte_mask, high_byte_top_bit;
2747 static Bignum ecdh_calculate(const Bignum private,
2748 const struct ec_point *public)
2752 p = ecp_mul(public, private);
2753 if (!p) return NULL;
2757 if (p->curve->type == EC_MONTGOMERY) {
2759 * Endianness-swap. The Curve25519 algorithm definition
2760 * assumes you were doing your computation in arrays of 32
2761 * little-endian bytes, and now specifies that you take your
2762 * final one of those and convert it into a bignum in
2763 * _network_ byte order, i.e. big-endian.
2765 * In particular, the spec says, you convert the _whole_ 32
2766 * bytes into a bignum. That is, on the rare occasions that
2767 * p->x has come out with the most significant 8 bits zero, we
2768 * have to imagine that being represented by a 32-byte string
2769 * with the last byte being zero, so that has to be converted
2770 * into an SSH-2 bignum with the _low_ byte zero, i.e. a
2774 int bytes = (p->curve->fieldBits+7) / 8;
2775 unsigned char *byteorder = snewn(bytes, unsigned char);
2776 for (i = 0; i < bytes; ++i) {
2777 byteorder[i] = bignum_byte(ret, i);
2780 ret = bignum_from_bytes(byteorder, bytes);
2781 smemclr(byteorder, bytes);
2789 const char *ssh_ecdhkex_curve_textname(const struct ssh_kex *kex)
2791 const struct eckex_extra *extra = (const struct eckex_extra *)kex->extra;
2792 struct ec_curve *curve = extra->curve();
2793 return curve->textname;
2796 void *ssh_ecdhkex_newkey(const struct ssh_kex *kex)
2798 const struct eckex_extra *extra = (const struct eckex_extra *)kex->extra;
2799 struct ec_curve *curve;
2801 struct ec_point *publicKey;
2803 curve = extra->curve();
2805 key = snew(struct ec_key);
2807 key->signalg = NULL;
2808 key->publicKey.curve = curve;
2810 if (curve->type == EC_MONTGOMERY) {
2811 int nbytes = (curve->fieldBits+7) / 8;
2812 unsigned char bytes[56] = {0};
2815 assert(nbytes <= lenof(bytes));
2817 for (i = 0; i < nbytes; ++i)
2819 bytes[i] = (unsigned char)random_byte();
2821 bytes[0] &= extra->low_byte_mask;
2822 bytes[nbytes-1] &= extra->high_byte_top_bit - 1;
2823 bytes[nbytes-1] |= extra->high_byte_top_bit;
2824 key->privateKey = bignum_from_bytes_le(bytes, nbytes);
2825 smemclr(bytes, nbytes);
2826 if (!key->privateKey) {
2830 publicKey = ecp_mul(&key->publicKey.curve->m.G, key->privateKey);
2832 freebn(key->privateKey);
2836 key->publicKey.x = publicKey->x;
2837 key->publicKey.y = publicKey->y;
2838 key->publicKey.z = NULL;
2841 key->privateKey = bignum_random_in_range(One, key->publicKey.curve->w.n);
2842 if (!key->privateKey) {
2846 publicKey = ecp_mul(&key->publicKey.curve->w.G, key->privateKey);
2848 freebn(key->privateKey);
2852 key->publicKey.x = publicKey->x;
2853 key->publicKey.y = publicKey->y;
2854 key->publicKey.z = NULL;
2860 char *ssh_ecdhkex_getpublic(void *key, int *len)
2862 struct ec_key *ec = (struct ec_key*)key;
2867 pointlen = (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8;
2869 if (ec->publicKey.curve->type == EC_WEIERSTRASS) {
2870 *len = 1 + pointlen * 2;
2874 point = (char*)snewn(*len, char);
2877 if (ec->publicKey.curve->type == EC_WEIERSTRASS) {
2879 for (i = pointlen; i--;) {
2880 *p++ = bignum_byte(ec->publicKey.x, i);
2882 for (i = pointlen; i--;) {
2883 *p++ = bignum_byte(ec->publicKey.y, i);
2886 for (i = 0; i < pointlen; ++i) {
2887 *p++ = bignum_byte(ec->publicKey.x, i);
2894 Bignum ssh_ecdhkex_getkey(void *key, char *remoteKey, int remoteKeyLen)
2896 struct ec_key *ec = (struct ec_key*) key;
2897 struct ec_point remote;
2900 if (ec->publicKey.curve->type == EC_WEIERSTRASS) {
2901 remote.curve = ec->publicKey.curve;
2902 remote.infinity = 0;
2903 if (!decodepoint(remoteKey, remoteKeyLen, &remote)) {
2907 /* Point length has to be the same length */
2908 if (remoteKeyLen != (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8) {
2912 remote.curve = ec->publicKey.curve;
2913 remote.infinity = 0;
2914 remote.x = bignum_from_bytes_le((unsigned char*)remoteKey, remoteKeyLen);
2919 ret = ecdh_calculate(ec->privateKey, &remote);
2920 if (remote.x) freebn(remote.x);
2921 if (remote.y) freebn(remote.y);
2925 void ssh_ecdhkex_freekey(void *key)
2930 static const struct eckex_extra kex_extra_curve25519 = {
2931 ec_curve25519, 0xF8, 0x40,
2933 static const struct ssh_kex ssh_ec_kex_curve25519 = {
2934 "curve25519-sha256@libssh.org", NULL, KEXTYPE_ECDH,
2935 &ssh_sha256, &kex_extra_curve25519,
2938 static const struct eckex_extra kex_extra_curve448 = {
2939 ec_curve448, 0xFC, 0x80,
2941 static const struct ssh_kex ssh_ec_kex_curve448 = {
2942 "curve448-sha512", NULL, KEXTYPE_ECDH,
2943 &ssh_sha512, &kex_extra_curve448,
2946 const struct eckex_extra kex_extra_nistp256 = { ec_p256 };
2947 static const struct ssh_kex ssh_ec_kex_nistp256 = {
2948 "ecdh-sha2-nistp256", NULL, KEXTYPE_ECDH,
2949 &ssh_sha256, &kex_extra_nistp256,
2952 const struct eckex_extra kex_extra_nistp384 = { ec_p384 };
2953 static const struct ssh_kex ssh_ec_kex_nistp384 = {
2954 "ecdh-sha2-nistp384", NULL, KEXTYPE_ECDH,
2955 &ssh_sha384, &kex_extra_nistp384,
2958 const struct eckex_extra kex_extra_nistp521 = { ec_p521 };
2959 static const struct ssh_kex ssh_ec_kex_nistp521 = {
2960 "ecdh-sha2-nistp521", NULL, KEXTYPE_ECDH,
2961 &ssh_sha512, &kex_extra_nistp521,
2964 static const struct ssh_kex *const ec_kex_list[] = {
2965 &ssh_ec_kex_curve448,
2966 &ssh_ec_kex_curve25519,
2967 &ssh_ec_kex_nistp256,
2968 &ssh_ec_kex_nistp384,
2969 &ssh_ec_kex_nistp521,
2972 const struct ssh_kexes ssh_ecdh_kex = {
2973 sizeof(ec_kex_list) / sizeof(*ec_kex_list),
2977 /* ----------------------------------------------------------------------
2978 * Helper functions for finding key algorithms and returning auxiliary
2982 const struct ssh_signkey *ec_alg_by_oid(int len, const void *oid,
2983 const struct ec_curve **curve)
2985 static const struct ssh_signkey *algs_with_oid[] = {
2986 &ssh_ecdsa_nistp256,
2987 &ssh_ecdsa_nistp384,
2988 &ssh_ecdsa_nistp521,
2992 for (i = 0; i < lenof(algs_with_oid); i++) {
2993 const struct ssh_signkey *alg = algs_with_oid[i];
2994 const struct ecsign_extra *extra =
2995 (const struct ecsign_extra *)alg->extra;
2996 if (len == extra->oidlen && !memcmp(oid, extra->oid, len)) {
2997 *curve = extra->curve();
3004 const unsigned char *ec_alg_oid(const struct ssh_signkey *alg,
3007 const struct ecsign_extra *extra = (const struct ecsign_extra *)alg->extra;
3008 *oidlen = extra->oidlen;
3012 const int ec_nist_curve_lengths[] = { 256, 384, 521 };
3013 const int n_ec_nist_curve_lengths = lenof(ec_nist_curve_lengths);
3015 const int ec_nist_alg_and_curve_by_bits(int bits,
3016 const struct ec_curve **curve,
3017 const struct ssh_signkey **alg)
3020 case 256: *alg = &ssh_ecdsa_nistp256; break;
3021 case 384: *alg = &ssh_ecdsa_nistp384; break;
3022 case 521: *alg = &ssh_ecdsa_nistp521; break;
3023 default: return FALSE;
3025 *curve = ((struct ecsign_extra *)(*alg)->extra)->curve();
3029 const int ec_ed_alg_and_curve_by_bits(int bits,
3030 const struct ec_curve **curve,
3031 const struct ssh_signkey **alg)
3034 case 256: *alg = &ssh_ecdsa_ed25519; break;
3035 default: return FALSE;
3037 *curve = ((struct ecsign_extra *)(*alg)->extra)->curve();