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
28 * http://ed25519.cr.yp.to/ed25519-20110926.pdf
36 /* ----------------------------------------------------------------------
37 * Elliptic curve definitions
40 static int initialise_wcurve(struct ec_curve *curve, int bits, unsigned char *p,
41 unsigned char *a, unsigned char *b,
42 unsigned char *n, unsigned char *Gx,
45 int length = bits / 8;
46 if (bits % 8) ++length;
48 curve->type = EC_WEIERSTRASS;
50 curve->fieldBits = bits;
51 curve->p = bignum_from_bytes(p, length);
52 if (!curve->p) goto error;
54 /* Curve co-efficients */
55 curve->w.a = bignum_from_bytes(a, length);
56 if (!curve->w.a) goto error;
57 curve->w.b = bignum_from_bytes(b, length);
58 if (!curve->w.b) goto error;
60 /* Group order and generator */
61 curve->w.n = bignum_from_bytes(n, length);
62 if (!curve->w.n) goto error;
63 curve->w.G.x = bignum_from_bytes(Gx, length);
64 if (!curve->w.G.x) goto error;
65 curve->w.G.y = bignum_from_bytes(Gy, length);
66 if (!curve->w.G.y) goto error;
67 curve->w.G.curve = curve;
68 curve->w.G.infinity = 0;
72 if (curve->p) freebn(curve->p);
73 if (curve->w.a) freebn(curve->w.a);
74 if (curve->w.b) freebn(curve->w.b);
75 if (curve->w.n) freebn(curve->w.n);
76 if (curve->w.G.x) freebn(curve->w.G.x);
80 static int initialise_mcurve(struct ec_curve *curve, int bits, unsigned char *p,
81 unsigned char *a, unsigned char *b,
84 int length = bits / 8;
85 if (bits % 8) ++length;
87 curve->type = EC_MONTGOMERY;
89 curve->fieldBits = bits;
90 curve->p = bignum_from_bytes(p, length);
91 if (!curve->p) goto error;
93 /* Curve co-efficients */
94 curve->m.a = bignum_from_bytes(a, length);
95 if (!curve->m.a) goto error;
96 curve->m.b = bignum_from_bytes(b, length);
97 if (!curve->m.b) goto error;
100 curve->m.G.x = bignum_from_bytes(Gx, length);
101 if (!curve->m.G.x) goto error;
104 curve->m.G.curve = curve;
105 curve->m.G.infinity = 0;
109 if (curve->p) freebn(curve->p);
110 if (curve->m.a) freebn(curve->m.a);
111 if (curve->m.b) freebn(curve->m.b);
115 static int initialise_ecurve(struct ec_curve *curve, int bits, unsigned char *p,
116 unsigned char *l, unsigned char *d,
117 unsigned char *Bx, unsigned char *By)
119 int length = bits / 8;
120 if (bits % 8) ++length;
122 curve->type = EC_EDWARDS;
124 curve->fieldBits = bits;
125 curve->p = bignum_from_bytes(p, length);
126 if (!curve->p) goto error;
128 /* Curve co-efficients */
129 curve->e.l = bignum_from_bytes(l, length);
130 if (!curve->e.l) goto error;
131 curve->e.d = bignum_from_bytes(d, length);
132 if (!curve->e.d) goto error;
134 /* Group order and generator */
135 curve->e.B.x = bignum_from_bytes(Bx, length);
136 if (!curve->e.B.x) goto error;
137 curve->e.B.y = bignum_from_bytes(By, length);
138 if (!curve->e.B.y) goto error;
139 curve->e.B.curve = curve;
140 curve->e.B.infinity = 0;
144 if (curve->p) freebn(curve->p);
145 if (curve->e.l) freebn(curve->e.l);
146 if (curve->e.d) freebn(curve->e.d);
147 if (curve->e.B.x) freebn(curve->e.B.x);
151 static struct ec_curve *ec_p256(void)
153 static struct ec_curve curve = { 0 };
154 static unsigned char initialised = 0;
158 unsigned char p[] = {
159 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
162 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
164 unsigned char a[] = {
165 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
168 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc
170 unsigned char b[] = {
171 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
172 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
173 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
174 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b
176 unsigned char n[] = {
177 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
178 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
179 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84,
180 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51
182 unsigned char Gx[] = {
183 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
184 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
185 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
186 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96
188 unsigned char Gy[] = {
189 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b,
190 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
191 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
192 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5
195 if (!initialise_wcurve(&curve, 256, p, a, b, n, Gx, Gy)) {
199 curve.name = "nistp256";
201 /* Now initialised, no need to do it again */
208 static struct ec_curve *ec_p384(void)
210 static struct ec_curve curve = { 0 };
211 static unsigned char initialised = 0;
215 unsigned char p[] = {
216 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
217 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
218 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
219 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
220 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
221 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
223 unsigned char a[] = {
224 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
225 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
226 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
227 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
228 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
229 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc
231 unsigned char b[] = {
232 0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4,
233 0x98, 0x8e, 0x05, 0x6b, 0xe3, 0xf8, 0x2d, 0x19,
234 0x18, 0x1d, 0x9c, 0x6e, 0xfe, 0x81, 0x41, 0x12,
235 0x03, 0x14, 0x08, 0x8f, 0x50, 0x13, 0x87, 0x5a,
236 0xc6, 0x56, 0x39, 0x8d, 0x8a, 0x2e, 0xd1, 0x9d,
237 0x2a, 0x85, 0xc8, 0xed, 0xd3, 0xec, 0x2a, 0xef
239 unsigned char n[] = {
240 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
241 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
242 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
243 0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf,
244 0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a,
245 0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73
247 unsigned char Gx[] = {
248 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37,
249 0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74,
250 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98,
251 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38,
252 0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c,
253 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7
255 unsigned char Gy[] = {
256 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f,
257 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29,
258 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
259 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0,
260 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d,
261 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f
264 if (!initialise_wcurve(&curve, 384, p, a, b, n, Gx, Gy)) {
268 curve.name = "nistp384";
270 /* Now initialised, no need to do it again */
277 static struct ec_curve *ec_p521(void)
279 static struct ec_curve curve = { 0 };
280 static unsigned char initialised = 0;
284 unsigned char p[] = {
285 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
286 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
287 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
288 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
289 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
290 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
291 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
292 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
295 unsigned char a[] = {
296 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
297 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
298 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
299 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
300 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
301 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
302 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
303 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
306 unsigned char b[] = {
307 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c,
308 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
309 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
310 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
311 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
312 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
313 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
314 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
317 unsigned char n[] = {
318 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
319 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
320 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
321 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
322 0xff, 0xfa, 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f,
323 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09,
324 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c,
325 0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38,
328 unsigned char Gx[] = {
329 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04,
330 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
331 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
332 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
333 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
334 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
335 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
336 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
339 unsigned char Gy[] = {
340 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b,
341 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
342 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
343 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
344 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
345 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
346 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
347 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
351 if (!initialise_wcurve(&curve, 521, p, a, b, n, Gx, Gy)) {
355 curve.name = "nistp521";
357 /* Now initialised, no need to do it again */
364 static struct ec_curve *ec_curve25519(void)
366 static struct ec_curve curve = { 0 };
367 static unsigned char initialised = 0;
371 unsigned char p[] = {
372 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
373 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
374 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
375 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed
377 unsigned char a[] = {
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x6d, 0x06
383 unsigned char b[] = {
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x01
389 unsigned char gx[32] = {
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09
396 if (!initialise_mcurve(&curve, 256, p, a, b, gx)) {
400 /* This curve doesn't need a name, because it's never used in
401 * any format that embeds the curve name */
404 /* Now initialised, no need to do it again */
411 static struct ec_curve *ec_ed25519(void)
413 static struct ec_curve curve = { 0 };
414 static unsigned char initialised = 0;
418 unsigned char q[] = {
419 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
420 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
421 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
422 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed
424 unsigned char l[32] = {
425 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x14, 0xde, 0xf9, 0xde, 0xa2, 0xf7, 0x9c, 0xd6,
428 0x58, 0x12, 0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed
430 unsigned char d[32] = {
431 0x52, 0x03, 0x6c, 0xee, 0x2b, 0x6f, 0xfe, 0x73,
432 0x8c, 0xc7, 0x40, 0x79, 0x77, 0x79, 0xe8, 0x98,
433 0x00, 0x70, 0x0a, 0x4d, 0x41, 0x41, 0xd8, 0xab,
434 0x75, 0xeb, 0x4d, 0xca, 0x13, 0x59, 0x78, 0xa3
436 unsigned char Bx[32] = {
437 0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe,
438 0xc0, 0xa4, 0xe2, 0x31, 0xfd, 0xd6, 0xdc, 0x5c,
439 0x69, 0x2c, 0xc7, 0x60, 0x95, 0x25, 0xa7, 0xb2,
440 0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a
442 unsigned char By[32] = {
443 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
444 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
445 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
446 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58
449 /* This curve doesn't need a name, because it's never used in
450 * any format that embeds the curve name */
453 if (!initialise_ecurve(&curve, 256, q, l, d, Bx, By)) {
457 /* Now initialised, no need to do it again */
464 /* Return 1 if a is -3 % p, otherwise return 0
465 * This is used because there are some maths optimisations */
466 static int ec_aminus3(const struct ec_curve *curve)
471 if (curve->type != EC_WEIERSTRASS) {
475 _p = bignum_add_long(curve->w.a, 3);
478 ret = !bignum_cmp(curve->p, _p);
483 /* ----------------------------------------------------------------------
484 * Elliptic curve field maths
487 static Bignum ecf_add(const Bignum a, const Bignum b,
488 const struct ec_curve *curve)
490 Bignum a1, b1, ab, ret;
492 a1 = bigmod(a, curve->p);
493 if (!a1) return NULL;
494 b1 = bigmod(b, curve->p);
504 if (!ab) return NULL;
506 ret = bigmod(ab, curve->p);
512 static Bignum ecf_square(const Bignum a, const struct ec_curve *curve)
514 return modmul(a, a, curve->p);
517 static Bignum ecf_treble(const Bignum a, const struct ec_curve *curve)
522 tmp = bignum_lshift(a, 1);
523 if (!tmp) return NULL;
525 /* Add itself (i.e. treble) */
526 ret = bigadd(tmp, a);
530 while (ret != NULL && bignum_cmp(ret, curve->p) >= 0)
532 tmp = bigsub(ret, curve->p);
540 static Bignum ecf_double(const Bignum a, const struct ec_curve *curve)
542 Bignum ret = bignum_lshift(a, 1);
543 if (!ret) return NULL;
544 if (bignum_cmp(ret, curve->p) >= 0)
546 Bignum tmp = bigsub(ret, curve->p);
556 /* ----------------------------------------------------------------------
560 void ec_point_free(struct ec_point *point)
562 if (point == NULL) return;
564 if (point->x) freebn(point->x);
565 if (point->y) freebn(point->y);
566 if (point->z) freebn(point->z);
571 static struct ec_point *ec_point_new(const struct ec_curve *curve,
572 const Bignum x, const Bignum y, const Bignum z,
573 unsigned char infinity)
575 struct ec_point *point = snewn(1, struct ec_point);
576 point->curve = curve;
580 point->infinity = infinity ? 1 : 0;
584 static struct ec_point *ec_point_copy(const struct ec_point *a)
586 if (a == NULL) return NULL;
587 return ec_point_new(a->curve,
588 a->x ? copybn(a->x) : NULL,
589 a->y ? copybn(a->y) : NULL,
590 a->z ? copybn(a->z) : NULL,
594 static int ec_point_verify(const struct ec_point *a)
598 } else if (a->curve->type == EC_EDWARDS) {
599 /* Check y^2 - x^2 - 1 - d * x^2 * y^2 == 0 */
600 Bignum y2, x2, tmp, tmp2, tmp3;
603 y2 = ecf_square(a->y, a->curve);
607 x2 = ecf_square(a->x, a->curve);
612 tmp = modmul(a->curve->e.d, x2, a->curve->p);
618 tmp2 = modmul(tmp, y2, a->curve->p);
625 tmp = modsub(y2, x2, a->curve->p);
632 tmp3 = modsub(tmp, tmp2, a->curve->p);
638 ret = !bignum_cmp(tmp3, One);
641 } else if (a->curve->type == EC_WEIERSTRASS) {
642 /* Verify y^2 = x^3 + ax + b */
645 Bignum lhs = NULL, x3 = NULL, ax = NULL, x3ax = NULL, x3axm = NULL, x3axb = NULL, rhs = NULL;
647 Bignum Three = bignum_from_long(3);
648 if (!Three) return 0;
650 lhs = modmul(a->y, a->y, a->curve->p);
651 if (!lhs) goto error;
653 /* This uses montgomery multiplication to optimise */
654 x3 = modpow(a->x, Three, a->curve->p);
657 ax = modmul(a->curve->w.a, a->x, a->curve->p);
659 x3ax = bigadd(x3, ax);
660 if (!x3ax) goto error;
661 freebn(x3); x3 = NULL;
662 freebn(ax); ax = NULL;
663 x3axm = bigmod(x3ax, a->curve->p);
664 if (!x3axm) goto error;
665 freebn(x3ax); x3ax = NULL;
666 x3axb = bigadd(x3axm, a->curve->w.b);
667 if (!x3axb) goto error;
668 freebn(x3axm); x3axm = NULL;
669 rhs = bigmod(x3axb, a->curve->p);
670 if (!rhs) goto error;
673 ret = bignum_cmp(lhs, rhs) ? 0 : 1;
682 if (x3ax) freebn(x3ax);
683 if (x3axm) freebn(x3axm);
684 if (x3axb) freebn(x3axb);
685 if (lhs) freebn(lhs);
692 /* ----------------------------------------------------------------------
693 * Elliptic curve point maths
696 /* Returns 1 on success and 0 on memory error */
697 static int ecp_normalise(struct ec_point *a)
705 /* Point is at infinity - i.e. normalised */
709 if (a->curve->type == EC_WEIERSTRASS) {
710 /* In Jacobian Coordinates the triple (X, Y, Z) represents
711 the affine point (X / Z^2, Y / Z^3) */
713 Bignum Z2, Z2inv, Z3, Z3inv, tx, ty;
715 if (!a->x || !a->y) {
716 /* No point defined */
719 /* Already normalised */
723 Z2 = ecf_square(a->z, a->curve);
727 Z2inv = modinv(Z2, a->curve->p);
732 tx = modmul(a->x, Z2inv, a->curve->p);
739 Z3 = modmul(Z2, a->z, a->curve->p);
745 Z3inv = modinv(Z3, a->curve->p);
751 ty = modmul(a->y, Z3inv, a->curve->p);
765 } else if (a->curve->type == EC_MONTGOMERY) {
766 /* In Montgomery (X : Z) represents the x co-ord (X / Z, ?) */
771 /* No point defined */
774 /* Already normalised */
778 tmp = modinv(a->z, a->curve->p);
782 tmp2 = modmul(a->x, tmp, a->curve->p);
793 } else if (a->curve->type == EC_EDWARDS) {
794 /* Always normalised */
801 static struct ec_point *ecp_doublew(const struct ec_point *a, const int aminus3)
803 Bignum S, M, outx, outy, outz;
805 if (bignum_cmp(a->y, Zero) == 0)
808 return ec_point_new(a->curve, NULL, NULL, NULL, 1);
813 Bignum Y2, XY2, _2XY2;
815 Y2 = ecf_square(a->y, a->curve);
819 XY2 = modmul(a->x, Y2, a->curve->p);
825 _2XY2 = ecf_double(XY2, a->curve);
830 S = ecf_double(_2XY2, a->curve);
837 /* Faster calculation if a = -3 */
839 /* if a = -3, then M can also be calculated as M = 3*(X + Z^2)*(X - Z^2) */
840 Bignum Z2, XpZ2, XmZ2, second;
845 Z2 = ecf_square(a->z, a->curve);
852 XpZ2 = ecf_add(a->x, Z2, a->curve);
858 XmZ2 = modsub(a->x, Z2, a->curve->p);
866 second = modmul(XpZ2, XmZ2, a->curve->p);
874 M = ecf_treble(second, a->curve);
881 /* M = 3*X^2 + a*Z^4 */
882 Bignum _3X2, X2, aZ4;
885 aZ4 = copybn(a->curve->w.a);
889 Z2 = ecf_square(a->z, a->curve);
894 Z4 = ecf_square(Z2, a->curve);
900 aZ4 = modmul(a->curve->w.a, Z4, a->curve->p);
908 X2 = modmul(a->x, a->x, a->curve->p);
914 _3X2 = ecf_treble(X2, a->curve);
921 M = ecf_add(_3X2, aZ4, a->curve);
934 M2 = ecf_square(M, a->curve);
941 _2S = ecf_double(S, a->curve);
949 outx = modsub(M2, _2S, a->curve->p);
959 /* Y' = M*(S - X') - 8*Y^4 */
961 Bignum SX, MSX, Eight, Y2, Y4, _8Y4;
963 SX = modsub(S, outx, a->curve->p);
970 MSX = modmul(M, SX, a->curve->p);
977 Y2 = ecf_square(a->y, a->curve);
983 Y4 = ecf_square(Y2, a->curve);
990 Eight = bignum_from_long(8);
997 _8Y4 = modmul(Eight, Y4, a->curve->p);
1005 outy = modsub(MSX, _8Y4, a->curve->p);
1021 YZ = modmul(a->y, a->z, a->curve->p);
1029 outz = ecf_double(YZ, a->curve);
1038 return ec_point_new(a->curve, outx, outy, outz, 0);
1041 static struct ec_point *ecp_doublem(const struct ec_point *a)
1043 Bignum z, outx, outz, xpz, xmz;
1050 /* 4xz = (x + z)^2 - (x - z)^2 */
1054 tmp = ecf_add(a->x, z, a->curve);
1058 xpz = ecf_square(tmp, a->curve);
1064 tmp = modsub(a->x, z, a->curve->p);
1069 xmz = ecf_square(tmp, a->curve);
1077 /* outx = (x + z)^2 * (x - z)^2 */
1078 outx = modmul(xpz, xmz, a->curve->p);
1085 /* outz = 4xz * ((x - z)^2 + ((A + 2) / 4)*4xz) */
1087 Bignum _4xz, tmp, tmp2, tmp3;
1089 tmp = bignum_from_long(2);
1096 tmp2 = ecf_add(a->curve->m.a, tmp, a->curve);
1105 _4xz = modsub(xpz, xmz, a->curve->p);
1113 tmp = modmul(tmp2, _4xz, a->curve->p);
1122 tmp2 = bignum_from_long(4);
1130 tmp3 = modinv(tmp2, a->curve->p);
1139 tmp2 = modmul(tmp, tmp3, a->curve->p);
1149 tmp = ecf_add(xmz, tmp2, a->curve);
1157 outz = modmul(_4xz, tmp, a->curve->p);
1166 return ec_point_new(a->curve, outx, NULL, outz, 0);
1169 /* Forward declaration for Edwards curve doubling */
1170 static struct ec_point *ecp_add(const struct ec_point *a,
1171 const struct ec_point *b,
1174 static struct ec_point *ecp_double(const struct ec_point *a, const int aminus3)
1179 return ec_point_new(a->curve, NULL, NULL, NULL, 1);
1182 if (a->curve->type == EC_EDWARDS)
1184 return ecp_add(a, a, aminus3);
1186 else if (a->curve->type == EC_WEIERSTRASS)
1188 return ecp_doublew(a, aminus3);
1192 return ecp_doublem(a);
1196 static struct ec_point *ecp_addw(const struct ec_point *a,
1197 const struct ec_point *b,
1200 Bignum U1, U2, S1, S2, outx, outy, outz;
1207 Z2 = ecf_square(b->z, a->curve);
1211 U1 = modmul(a->x, Z2, a->curve->p);
1216 Z3 = modmul(Z2, b->z, a->curve->p);
1222 S1 = modmul(a->y, Z3, a->curve->p);
1245 Z2 = ecf_square(a->z, b->curve);
1251 U2 = modmul(b->x, Z2, b->curve->p);
1258 Z3 = modmul(Z2, a->z, b->curve->p);
1266 S2 = modmul(b->y, Z3, b->curve->p);
1290 /* Check if multiplying by self */
1291 if (bignum_cmp(U1, U2) == 0)
1295 if (bignum_cmp(S1, S2) == 0)
1299 return ecp_double(a, aminus3);
1306 return ec_point_new(a->curve, NULL, NULL, NULL, 1);
1311 Bignum H, R, UH2, H3;
1314 H = modsub(U2, U1, a->curve->p);
1324 R = modsub(S2, S1, a->curve->p);
1333 /* X3 = R^2 - H^3 - 2*U1*H^2 */
1335 Bignum R2, H2, _2UH2, first;
1337 H2 = ecf_square(H, a->curve);
1345 UH2 = modmul(U1, H2, a->curve->p);
1354 H3 = modmul(H2, H, a->curve->p);
1363 R2 = ecf_square(R, a->curve);
1372 _2UH2 = ecf_double(UH2, a->curve);
1382 first = modsub(R2, H3, a->curve->p);
1393 outx = modsub(first, _2UH2, a->curve->p);
1406 /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */
1408 Bignum RUH2mX, UH2mX, SH3;
1410 UH2mX = modsub(UH2, outx, a->curve->p);
1420 RUH2mX = modmul(R, UH2mX, a->curve->p);
1430 SH3 = modmul(S1, H3, a->curve->p);
1440 outy = modsub(RUH2mX, SH3, a->curve->p);
1454 ZZ = modmul(a->z, b->z, a->curve->p);
1461 outz = modmul(H, ZZ, a->curve->p);
1470 outz = modmul(H, a->z, a->curve->p);
1478 outz = modmul(H, b->z, a->curve->p);
1490 return ec_point_new(a->curve, outx, outy, outz, 0);
1493 static struct ec_point *ecp_addm(const struct ec_point *a,
1494 const struct ec_point *b,
1495 const struct ec_point *base)
1497 Bignum outx, outz, az, bz;
1508 /* a-b is maintained at 1 due to Montgomery ladder implementation */
1509 /* Xa+b = Za-b * ((Xa - Za)*(Xb + Zb) + (Xa + Za)*(Xb - Zb))^2 */
1510 /* Za+b = Xa-b * ((Xa - Za)*(Xb + Zb) - (Xa + Za)*(Xb - Zb))^2 */
1512 Bignum tmp, tmp2, tmp3, tmp4;
1514 /* (Xa + Za) * (Xb - Zb) */
1515 tmp = ecf_add(a->x, az, a->curve);
1519 tmp2 = modsub(b->x, bz, a->curve->p);
1524 tmp3 = modmul(tmp, tmp2, a->curve->p);
1531 /* (Xa - Za) * (Xb + Zb) */
1532 tmp = modsub(a->x, az, a->curve->p);
1537 tmp2 = ecf_add(b->x, bz, a->curve);
1543 tmp4 = modmul(tmp, tmp2, a->curve->p);
1551 tmp = ecf_add(tmp3, tmp4, a->curve);
1557 outx = ecf_square(tmp, a->curve);
1565 tmp = modsub(tmp3, tmp4, a->curve->p);
1572 tmp2 = ecf_square(tmp, a->curve);
1578 outz = modmul(base->x, tmp2, a->curve->p);
1586 return ec_point_new(a->curve, outx, NULL, outz, 0);
1589 static struct ec_point *ecp_adde(const struct ec_point *a,
1590 const struct ec_point *b)
1592 Bignum outx, outy, dmul;
1594 /* outx = (a->x * b->y + b->x * a->y) /
1595 * (1 + a->curve->e.d * a->x * b->x * a->y * b->y) */
1597 Bignum tmp, tmp2, tmp3, tmp4;
1599 tmp = modmul(a->x, b->y, a->curve->p);
1604 tmp2 = modmul(b->x, a->y, a->curve->p);
1610 tmp3 = ecf_add(tmp, tmp2, a->curve);
1618 tmp4 = modmul(tmp, tmp2, a->curve->p);
1626 dmul = modmul(a->curve->e.d, tmp4, a->curve->p);
1633 tmp = ecf_add(One, dmul, a->curve);
1640 tmp2 = modinv(tmp, a->curve->p);
1649 outx = modmul(tmp3, tmp2, a->curve->p);
1659 /* outy = (a->y * b->y + a->x * b->x) /
1660 * (1 - a->curve->e.d * a->x * b->x * a->y * b->y) */
1662 Bignum tmp, tmp2, tmp3, tmp4;
1664 tmp = modsub(One, dmul, a->curve->p);
1672 tmp2 = modinv(tmp, a->curve->p);
1680 tmp = modmul(a->y, b->y, a->curve->p);
1687 tmp3 = modmul(a->x, b->x, a->curve->p);
1695 tmp4 = ecf_add(tmp, tmp3, a->curve);
1705 outy = modmul(tmp4, tmp2, a->curve->p);
1715 return ec_point_new(a->curve, outx, outy, NULL, 0);
1718 static struct ec_point *ecp_add(const struct ec_point *a,
1719 const struct ec_point *b,
1722 if (a->curve != b->curve) {
1726 /* Check if multiplying by infinity */
1727 if (a->infinity) return ec_point_copy(b);
1728 if (b->infinity) return ec_point_copy(a);
1730 if (a->curve->type == EC_EDWARDS)
1732 return ecp_adde(a, b);
1735 if (a->curve->type == EC_WEIERSTRASS)
1737 return ecp_addw(a, b, aminus3);
1743 static struct ec_point *ecp_mul_(const struct ec_point *a, const Bignum b, int aminus3)
1745 struct ec_point *A, *ret;
1748 A = ec_point_copy(a);
1749 ret = ec_point_new(a->curve, NULL, NULL, NULL, 1);
1751 bits = bignum_bitcount(b);
1752 for (i = 0; ret != NULL && A != NULL && i < bits; ++i)
1754 if (bignum_bit(b, i))
1756 struct ec_point *tmp = ecp_add(ret, A, aminus3);
1762 struct ec_point *tmp = ecp_double(A, aminus3);
1778 static struct ec_point *ecp_mulw(const struct ec_point *a, const Bignum b)
1780 struct ec_point *ret = ecp_mul_(a, b, ec_aminus3(a->curve));
1782 if (!ecp_normalise(ret)) {
1790 static struct ec_point *ecp_mule(const struct ec_point *a, const Bignum b)
1793 struct ec_point *ret;
1795 ret = ec_point_new(a->curve, NULL, NULL, NULL, 1);
1797 for (i = bignum_bitcount(b); i >= 0 && ret; --i)
1800 struct ec_point *tmp = ecp_double(ret, 0);
1804 if (ret && bignum_bit(b, i))
1806 struct ec_point *tmp = ecp_add(ret, a, 0);
1815 static struct ec_point *ecp_mulm(const struct ec_point *p, const Bignum n)
1817 struct ec_point *P1, *P2;
1820 /* P1 <- P and P2 <- [2]P */
1821 P2 = ecp_double(p, 0);
1825 P1 = ec_point_copy(p);
1831 /* for i = bits − 2 down to 0 */
1832 bits = bignum_bitcount(n);
1833 for (i = bits - 2; P1 != NULL && P2 != NULL && i >= 0; --i)
1835 if (!bignum_bit(n, i))
1838 struct ec_point *tmp = ecp_addm(P1, P2, p);
1843 tmp = ecp_double(P1, 0);
1850 struct ec_point *tmp = ecp_addm(P1, P2, p);
1855 tmp = ecp_double(P2, 0);
1862 if (P1) ec_point_free(P1);
1868 if (!ecp_normalise(P1)) {
1876 /* Not static because it is used by sshecdsag.c to generate a new key */
1877 struct ec_point *ecp_mul(const struct ec_point *a, const Bignum b)
1879 if (a->curve->type == EC_WEIERSTRASS) {
1880 return ecp_mulw(a, b);
1881 } else if (a->curve->type == EC_EDWARDS) {
1882 return ecp_mule(a, b);
1884 return ecp_mulm(a, b);
1888 static struct ec_point *ecp_summul(const Bignum a, const Bignum b,
1889 const struct ec_point *point)
1891 struct ec_point *aG, *bP, *ret;
1894 if (point->curve->type != EC_WEIERSTRASS) {
1898 aminus3 = ec_aminus3(point->curve);
1900 aG = ecp_mul_(&point->curve->w.G, a, aminus3);
1901 if (!aG) return NULL;
1902 bP = ecp_mul_(point, b, aminus3);
1908 ret = ecp_add(aG, bP, aminus3);
1913 if (!ecp_normalise(ret)) {
1920 static Bignum *ecp_edx(const struct ec_curve *curve, const Bignum y)
1922 /* Get the x value on the given Edwards curve for a given y */
1925 /* xx = (y^2 - 1) / (d * y^2 + 1) */
1927 Bignum tmp, tmp2, tmp3;
1929 tmp = ecf_square(y, curve);
1933 tmp2 = modmul(curve->e.d, tmp, curve->p);
1938 tmp3 = ecf_add(tmp2, One, curve);
1944 tmp2 = modinv(tmp3, curve->p);
1951 tmp3 = modsub(tmp, One, curve->p);
1957 xx = modmul(tmp3, tmp2, curve->p);
1965 /* x = xx^((p + 3) / 8) */
1969 tmp = bignum_add_long(curve->p, 3);
1974 tmp2 = bignum_rshift(tmp, 3);
1980 x = modpow(xx, tmp2, curve->p);
1988 /* if x^2 - xx != 0 then x = x*(2^((p - 1) / 4)) */
1992 tmp = ecf_square(x, curve);
1998 tmp2 = modsub(tmp, xx, curve->p);
2005 if (bignum_cmp(tmp2, Zero)) {
2010 tmp = modsub(curve->p, One, curve->p);
2015 tmp2 = bignum_rshift(tmp, 2);
2021 tmp = bignum_from_long(2);
2027 tmp3 = modpow(tmp, tmp2, curve->p);
2035 tmp = modmul(x, tmp3, curve->p);
2047 /* if x % 2 != 0 then x = p - x */
2048 if (bignum_bit(x, 0)) {
2049 Bignum tmp = modsub(curve->p, x, curve->p);
2060 /* ----------------------------------------------------------------------
2061 * Public point from private
2064 struct ec_point *ec_public(const Bignum privateKey, const struct ec_curve *curve)
2066 if (curve->type == EC_WEIERSTRASS) {
2067 return ecp_mul(&curve->w.G, privateKey);
2068 } else if (curve->type == EC_EDWARDS) {
2069 /* hash = H(sk) (where hash creates 2 * fieldBits)
2071 * a = 2^(b-2) + SUM(2^i * h_i) for i = 2 -> b-2
2073 struct ec_point *ret;
2074 unsigned char hash[512/8];
2080 keylen = curve->fieldBits / 8;
2081 for (i = 0; i < keylen; ++i) {
2082 unsigned char b = bignum_byte(privateKey, i);
2083 SHA512_Bytes(&s, &b, 1);
2085 SHA512_Final(&s, hash);
2087 /* The second part is simply turning the hash into a Bignum,
2088 * however the 2^(b-2) bit *must* be set, and the bottom 3
2089 * bits *must* not be */
2090 hash[0] &= 0xf8; /* Unset bottom 3 bits (if set) */
2091 hash[31] &= 0x7f; /* Unset above (b-2) */
2092 hash[31] |= 0x40; /* Set 2^(b-2) */
2093 /* Chop off the top part and convert to int */
2094 a = bignum_from_bytes_le(hash, 32);
2099 ret = ecp_mul(&curve->e.B, a);
2107 /* ----------------------------------------------------------------------
2108 * Basic sign and verify routines
2111 static int _ecdsa_verify(const struct ec_point *publicKey,
2112 const unsigned char *data, const int dataLen,
2113 const Bignum r, const Bignum s)
2119 if (publicKey->curve->type != EC_WEIERSTRASS) {
2124 if (bignum_cmp(r, Zero) == 0 || bignum_cmp(r, publicKey->curve->w.n) >= 0
2125 || bignum_cmp(s, Zero) == 0 || bignum_cmp(s, publicKey->curve->w.n) >= 0)
2130 /* z = left most bitlen(curve->n) of data */
2131 z = bignum_from_bytes(data, dataLen);
2133 n_bits = bignum_bitcount(publicKey->curve->w.n);
2134 z_bits = bignum_bitcount(z);
2135 if (z_bits > n_bits)
2137 Bignum tmp = bignum_rshift(z, z_bits - n_bits);
2143 /* Ensure z in range of n */
2145 Bignum tmp = bigmod(z, publicKey->curve->w.n);
2151 /* Calculate signature */
2153 Bignum w, x, u1, u2;
2154 struct ec_point *tmp;
2156 w = modinv(s, publicKey->curve->w.n);
2161 u1 = modmul(z, w, publicKey->curve->w.n);
2167 u2 = modmul(r, w, publicKey->curve->w.n);
2175 tmp = ecp_summul(u1, u2, publicKey);
2183 x = bigmod(tmp->x, publicKey->curve->w.n);
2190 valid = (bignum_cmp(r, x) == 0) ? 1 : 0;
2199 static void _ecdsa_sign(const Bignum privateKey, const struct ec_curve *curve,
2200 const unsigned char *data, const int dataLen,
2201 Bignum *r, Bignum *s)
2203 unsigned char digest[20];
2206 struct ec_point *kG;
2211 if (curve->type != EC_WEIERSTRASS) {
2215 /* z = left most bitlen(curve->n) of data */
2216 z = bignum_from_bytes(data, dataLen);
2218 n_bits = bignum_bitcount(curve->w.n);
2219 z_bits = bignum_bitcount(z);
2220 if (z_bits > n_bits)
2223 tmp = bignum_rshift(z, z_bits - n_bits);
2229 /* Generate k between 1 and curve->n, using the same deterministic
2230 * k generation system we use for conventional DSA. */
2231 SHA_Simple(data, dataLen, digest);
2232 k = dss_gen_k("ECDSA deterministic k generator", curve->w.n, privateKey,
2233 digest, sizeof(digest));
2236 kG = ecp_mul(&curve->w.G, k);
2243 /* r = kG.x mod n */
2244 *r = bigmod(kG->x, curve->w.n);
2252 /* s = (z + r * priv)/k mod n */
2254 Bignum rPriv, zMod, first, firstMod, kInv;
2255 rPriv = modmul(*r, privateKey, curve->w.n);
2262 zMod = bigmod(z, curve->w.n);
2270 first = bigadd(rPriv, zMod);
2278 firstMod = bigmod(first, curve->w.n);
2285 kInv = modinv(k, curve->w.n);
2292 *s = modmul(firstMod, kInv, curve->w.n);
2302 /* ----------------------------------------------------------------------
2306 static void getstring(const char **data, int *datalen,
2307 const char **p, int *length)
2312 *length = toint(GET_32BIT(*data));
2317 if (*datalen < *length)
2321 *datalen -= *length;
2324 static Bignum getmp(const char **data, int *datalen)
2329 getstring(data, datalen, &p, &length);
2333 return NULL; /* negative mp */
2334 return bignum_from_bytes((unsigned char *)p, length);
2337 static Bignum getmp_le(const char **data, int *datalen)
2342 getstring(data, datalen, &p, &length);
2345 return bignum_from_bytes_le((const unsigned char *)p, length);
2348 static int decodepoint_ed(const char *p, int length, struct ec_point *point)
2350 /* Got some conversion to do, first read in the y co-ord */
2353 point->y = bignum_from_bytes_le((const unsigned char*)p, length);
2357 if ((unsigned)bignum_bitcount(point->y) > point->curve->fieldBits) {
2362 /* Read x bit and then reset it */
2363 negative = bignum_bit(point->y, point->curve->fieldBits - 1);
2364 bignum_set_bit(point->y, point->curve->fieldBits - 1, 0);
2366 /* Get the x from the y */
2367 point->x = ecp_edx(point->curve, point->y);
2374 Bignum tmp = modsub(point->curve->p, point->x, point->curve->p);
2384 /* Verify the point is on the curve */
2385 if (!ec_point_verify(point)) {
2396 static int decodepoint(const char *p, int length, struct ec_point *point)
2398 if (point->curve->type == EC_EDWARDS) {
2399 return decodepoint_ed(p, length, point);
2402 if (length < 1 || p[0] != 0x04) /* Only support uncompressed point */
2404 /* Skip compression flag */
2407 /* The two values must be equal length */
2408 if (length % 2 != 0) {
2414 length = length / 2;
2415 point->x = bignum_from_bytes((const unsigned char *)p, length);
2416 if (!point->x) return 0;
2418 point->y = bignum_from_bytes((const unsigned char *)p, length);
2426 /* Verify the point is on the curve */
2427 if (!ec_point_verify(point)) {
2438 static int getmppoint(const char **data, int *datalen, struct ec_point *point)
2443 getstring(data, datalen, &p, &length);
2445 return decodepoint(p, length, point);
2448 /* ----------------------------------------------------------------------
2449 * Exposed ECDSA interface
2452 struct ecsign_extra {
2453 struct ec_curve *(*curve)(void);
2455 /* These fields are used by the OpenSSH PEM format importer/exporter */
2456 const unsigned char *oid;
2460 static void ecdsa_freekey(void *key)
2462 struct ec_key *ec = (struct ec_key *) key;
2465 if (ec->publicKey.x)
2466 freebn(ec->publicKey.x);
2467 if (ec->publicKey.y)
2468 freebn(ec->publicKey.y);
2469 if (ec->publicKey.z)
2470 freebn(ec->publicKey.z);
2472 freebn(ec->privateKey);
2476 static void *ecdsa_newkey(const struct ssh_signkey *self,
2477 const char *data, int len)
2479 const struct ecsign_extra *extra =
2480 (const struct ecsign_extra *)self->extra;
2484 struct ec_curve *curve;
2486 getstring(&data, &len, &p, &slen);
2491 curve = extra->curve();
2492 assert(curve->type == EC_WEIERSTRASS || curve->type == EC_EDWARDS);
2494 /* Curve name is duplicated for Weierstrass form */
2495 if (curve->type == EC_WEIERSTRASS) {
2496 getstring(&data, &len, &p, &slen);
2497 if (!match_ssh_id(slen, p, curve->name)) return NULL;
2500 ec = snew(struct ec_key);
2503 ec->publicKey.curve = curve;
2504 ec->publicKey.infinity = 0;
2505 ec->publicKey.x = NULL;
2506 ec->publicKey.y = NULL;
2507 ec->publicKey.z = NULL;
2508 if (!getmppoint(&data, &len, &ec->publicKey)) {
2512 ec->privateKey = NULL;
2514 if (!ec->publicKey.x || !ec->publicKey.y ||
2515 bignum_cmp(ec->publicKey.x, curve->p) >= 0 ||
2516 bignum_cmp(ec->publicKey.y, curve->p) >= 0)
2525 static char *ecdsa_fmtkey(void *key)
2527 struct ec_key *ec = (struct ec_key *) key;
2529 int len, i, pos, nibbles;
2530 static const char hex[] = "0123456789abcdef";
2531 if (!ec->publicKey.x || !ec->publicKey.y || !ec->publicKey.curve)
2534 len = 4 + 2 + 1; /* 2 x "0x", punctuation, \0 */
2535 if (ec->publicKey.curve->name)
2536 len += strlen(ec->publicKey.curve->name); /* Curve name */
2537 len += 4 * (bignum_bitcount(ec->publicKey.x) + 15) / 16;
2538 len += 4 * (bignum_bitcount(ec->publicKey.y) + 15) / 16;
2539 p = snewn(len, char);
2542 if (ec->publicKey.curve->name)
2543 pos += sprintf(p + pos, "%s,", ec->publicKey.curve->name);
2544 pos += sprintf(p + pos, "0x");
2545 nibbles = (3 + bignum_bitcount(ec->publicKey.x)) / 4;
2548 for (i = nibbles; i--;) {
2550 hex[(bignum_byte(ec->publicKey.x, i / 2) >> (4 * (i % 2))) & 0xF];
2552 pos += sprintf(p + pos, ",0x");
2553 nibbles = (3 + bignum_bitcount(ec->publicKey.y)) / 4;
2556 for (i = nibbles; i--;) {
2558 hex[(bignum_byte(ec->publicKey.y, i / 2) >> (4 * (i % 2))) & 0xF];
2564 static unsigned char *ecdsa_public_blob(void *key, int *len)
2566 struct ec_key *ec = (struct ec_key *) key;
2567 int pointlen, bloblen, fullnamelen, namelen;
2569 unsigned char *blob, *p;
2571 fullnamelen = strlen(ec->signalg->name);
2573 if (ec->publicKey.curve->type == EC_EDWARDS) {
2574 /* Edwards compressed form "ssh-ed25519" point y[:-1] + x[0:1] */
2576 pointlen = ec->publicKey.curve->fieldBits / 8;
2578 /* Can't handle this in our loop */
2579 if (pointlen < 2) return NULL;
2581 bloblen = 4 + fullnamelen + 4 + pointlen;
2582 blob = snewn(bloblen, unsigned char);
2583 if (!blob) return NULL;
2586 PUT_32BIT(p, fullnamelen);
2588 memcpy(p, ec->signalg->name, fullnamelen);
2590 PUT_32BIT(p, pointlen);
2593 /* Unset last bit of y and set first bit of x in its place */
2594 for (i = 0; i < pointlen - 1; ++i) {
2595 *p++ = bignum_byte(ec->publicKey.y, i);
2597 /* Unset last bit of y and set first bit of x in its place */
2598 *p = bignum_byte(ec->publicKey.y, i) & 0x7f;
2599 *p++ |= bignum_bit(ec->publicKey.x, 0) << 7;
2600 } else if (ec->publicKey.curve->type == EC_WEIERSTRASS) {
2601 assert(ec->publicKey.curve->name);
2602 namelen = strlen(ec->publicKey.curve->name);
2604 pointlen = (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8;
2607 * string "ecdsa-sha2-<name>", string "<name>", 0x04 point x, y.
2609 bloblen = 4 + fullnamelen + 4 + namelen + 4 + 1 + (pointlen * 2);
2610 blob = snewn(bloblen, unsigned char);
2613 PUT_32BIT(p, fullnamelen);
2615 memcpy(p, ec->signalg->name, fullnamelen);
2617 PUT_32BIT(p, namelen);
2619 memcpy(p, ec->publicKey.curve->name, namelen);
2621 PUT_32BIT(p, (2 * pointlen) + 1);
2624 for (i = pointlen; i--;) {
2625 *p++ = bignum_byte(ec->publicKey.x, i);
2627 for (i = pointlen; i--;) {
2628 *p++ = bignum_byte(ec->publicKey.y, i);
2634 assert(p == blob + bloblen);
2640 static unsigned char *ecdsa_private_blob(void *key, int *len)
2642 struct ec_key *ec = (struct ec_key *) key;
2643 int keylen, bloblen;
2645 unsigned char *blob, *p;
2647 if (!ec->privateKey) return NULL;
2649 if (ec->publicKey.curve->type == EC_EDWARDS) {
2651 keylen = (bignum_bitcount(ec->privateKey) + 7) / 8;
2654 keylen = (bignum_bitcount(ec->privateKey) + 8) / 8;
2658 * mpint privateKey. Total 4 + keylen.
2660 bloblen = 4 + keylen;
2661 blob = snewn(bloblen, unsigned char);
2664 PUT_32BIT(p, keylen);
2666 if (ec->publicKey.curve->type == EC_EDWARDS) {
2668 for (i = 0; i < keylen; ++i)
2669 *p++ = bignum_byte(ec->privateKey, i);
2671 for (i = keylen; i--;)
2672 *p++ = bignum_byte(ec->privateKey, i);
2675 assert(p == blob + bloblen);
2680 static void *ecdsa_createkey(const struct ssh_signkey *self,
2681 const unsigned char *pub_blob, int pub_len,
2682 const unsigned char *priv_blob, int priv_len)
2685 struct ec_point *publicKey;
2686 const char *pb = (const char *) priv_blob;
2688 ec = (struct ec_key*)ecdsa_newkey(self, (const char *) pub_blob, pub_len);
2693 if (ec->publicKey.curve->type != EC_WEIERSTRASS
2694 && ec->publicKey.curve->type != EC_EDWARDS) {
2699 if (ec->publicKey.curve->type == EC_EDWARDS) {
2700 ec->privateKey = getmp_le(&pb, &priv_len);
2702 ec->privateKey = getmp(&pb, &priv_len);
2704 if (!ec->privateKey) {
2709 /* Check that private key generates public key */
2710 publicKey = ec_public(ec->privateKey, ec->publicKey.curve);
2713 bignum_cmp(publicKey->x, ec->publicKey.x) ||
2714 bignum_cmp(publicKey->y, ec->publicKey.y))
2719 ec_point_free(publicKey);
2724 static void *ed25519_openssh_createkey(const struct ssh_signkey *self,
2725 const unsigned char **blob, int *len)
2728 struct ec_point *publicKey;
2732 getstring((const char**)blob, len, &p, &plen);
2738 ec = snew(struct ec_key);
2745 ec->publicKey.curve = ec_ed25519();
2746 ec->publicKey.infinity = 0;
2747 ec->privateKey = NULL;
2748 ec->publicKey.x = NULL;
2749 ec->publicKey.z = NULL;
2750 ec->publicKey.y = NULL;
2752 if (!decodepoint_ed(p, plen, &ec->publicKey))
2758 getstring((const char**)blob, len, &q, &qlen);
2764 ec->privateKey = bignum_from_bytes_le((const unsigned char *)q, 32);
2765 if (!ec->privateKey) {
2770 /* Check that private key generates public key */
2771 publicKey = ec_public(ec->privateKey, ec->publicKey.curve);
2774 bignum_cmp(publicKey->x, ec->publicKey.x) ||
2775 bignum_cmp(publicKey->y, ec->publicKey.y))
2780 ec_point_free(publicKey);
2782 /* The OpenSSH format for ed25519 private keys also for some
2783 * reason encodes an extra copy of the public key in the second
2784 * half of the secret-key string. Check that that's present and
2785 * correct as well, otherwise the key we think we've imported
2786 * won't behave identically to the way OpenSSH would have treated
2788 if (plen != 32 || 0 != memcmp(q + 32, p, 32)) {
2796 static int ed25519_openssh_fmtkey(void *key, unsigned char *blob, int len)
2798 struct ec_key *ec = (struct ec_key *) key;
2805 if (ec->publicKey.curve->type != EC_EDWARDS) {
2809 pointlen = (bignum_bitcount(ec->publicKey.y) + 7) / 8;
2810 keylen = (bignum_bitcount(ec->privateKey) + 7) / 8;
2811 bloblen = 4 + pointlen + 4 + keylen + pointlen;
2816 /* Encode the public point */
2817 PUT_32BIT(blob, pointlen);
2820 for (i = 0; i < pointlen - 1; ++i) {
2821 *blob++ = bignum_byte(ec->publicKey.y, i);
2823 /* Unset last bit of y and set first bit of x in its place */
2824 *blob = bignum_byte(ec->publicKey.y, i) & 0x7f;
2825 *blob++ |= bignum_bit(ec->publicKey.x, 0) << 7;
2827 PUT_32BIT(blob, keylen + pointlen);
2829 for (i = 0; i < keylen; ++i) {
2830 *blob++ = bignum_byte(ec->privateKey, i);
2832 /* Now encode an extra copy of the public point as the second half
2833 * of the private key string, as the OpenSSH format for some
2834 * reason requires */
2835 for (i = 0; i < pointlen - 1; ++i) {
2836 *blob++ = bignum_byte(ec->publicKey.y, i);
2838 /* Unset last bit of y and set first bit of x in its place */
2839 *blob = bignum_byte(ec->publicKey.y, i) & 0x7f;
2840 *blob++ |= bignum_bit(ec->publicKey.x, 0) << 7;
2845 static void *ecdsa_openssh_createkey(const struct ssh_signkey *self,
2846 const unsigned char **blob, int *len)
2848 const struct ecsign_extra *extra =
2849 (const struct ecsign_extra *)self->extra;
2850 const char **b = (const char **) blob;
2854 struct ec_curve *curve;
2855 struct ec_point *publicKey;
2857 getstring(b, len, &p, &slen);
2862 curve = extra->curve();
2863 assert(curve->type == EC_WEIERSTRASS);
2865 ec = snew(struct ec_key);
2868 ec->publicKey.curve = curve;
2869 ec->publicKey.infinity = 0;
2870 ec->publicKey.x = NULL;
2871 ec->publicKey.y = NULL;
2872 ec->publicKey.z = NULL;
2873 if (!getmppoint(b, len, &ec->publicKey)) {
2877 ec->privateKey = NULL;
2879 if (!ec->publicKey.x || !ec->publicKey.y ||
2880 bignum_cmp(ec->publicKey.x, curve->p) >= 0 ||
2881 bignum_cmp(ec->publicKey.y, curve->p) >= 0)
2887 ec->privateKey = getmp(b, len);
2888 if (ec->privateKey == NULL)
2894 /* Now check that the private key makes the public key */
2895 publicKey = ec_public(ec->privateKey, ec->publicKey.curve);
2902 if (bignum_cmp(ec->publicKey.x, publicKey->x) ||
2903 bignum_cmp(ec->publicKey.y, publicKey->y))
2905 /* Private key doesn't make the public key on the given curve */
2907 ec_point_free(publicKey);
2911 ec_point_free(publicKey);
2916 static int ecdsa_openssh_fmtkey(void *key, unsigned char *blob, int len)
2918 struct ec_key *ec = (struct ec_key *) key;
2925 if (ec->publicKey.curve->type != EC_WEIERSTRASS) {
2929 pointlen = (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8;
2930 namelen = strlen(ec->publicKey.curve->name);
2932 4 + namelen /* <LEN> nistpXXX */
2933 + 4 + 1 + (pointlen * 2) /* <LEN> 0x04 pX pY */
2934 + ssh2_bignum_length(ec->privateKey);
2941 PUT_32BIT(blob+bloblen, namelen);
2943 memcpy(blob+bloblen, ec->publicKey.curve->name, namelen);
2946 PUT_32BIT(blob+bloblen, 1 + (pointlen * 2));
2948 blob[bloblen++] = 0x04;
2949 for (i = pointlen; i--; )
2950 blob[bloblen++] = bignum_byte(ec->publicKey.x, i);
2951 for (i = pointlen; i--; )
2952 blob[bloblen++] = bignum_byte(ec->publicKey.y, i);
2954 pointlen = (bignum_bitcount(ec->privateKey) + 8) / 8;
2955 PUT_32BIT(blob+bloblen, pointlen);
2957 for (i = pointlen; i--; )
2958 blob[bloblen++] = bignum_byte(ec->privateKey, i);
2963 static int ecdsa_pubkey_bits(const struct ssh_signkey *self,
2964 const void *blob, int len)
2969 ec = (struct ec_key*)ecdsa_newkey(self, (const char *) blob, len);
2972 ret = ec->publicKey.curve->fieldBits;
2978 static int ecdsa_verifysig(void *key, const char *sig, int siglen,
2979 const char *data, int datalen)
2981 struct ec_key *ec = (struct ec_key *) key;
2987 if (!ec->publicKey.x || !ec->publicKey.y || !ec->publicKey.curve)
2990 /* Check the signature starts with the algorithm name */
2991 getstring(&sig, &siglen, &p, &slen);
2995 if (!match_ssh_id(slen, p, ec->signalg->name)) {
2999 getstring(&sig, &siglen, &p, &slen);
3000 if (ec->publicKey.curve->type == EC_EDWARDS) {
3004 /* Check that the signature is two times the length of a point */
3005 if (slen != (ec->publicKey.curve->fieldBits / 8) * 2) {
3009 /* Check it's the 256 bit field so that SHA512 is the correct hash */
3010 if (ec->publicKey.curve->fieldBits != 256) {
3014 /* Get the signature */
3015 r = ec_point_new(ec->publicKey.curve, NULL, NULL, NULL, 0);
3019 if (!decodepoint(p, ec->publicKey.curve->fieldBits / 8, r)) {
3023 s = bignum_from_bytes_le((unsigned char*)p + (ec->publicKey.curve->fieldBits / 8),
3024 ec->publicKey.curve->fieldBits / 8);
3030 /* Get the hash of the encoded value of R + encoded value of pk + message */
3034 unsigned char digest[512 / 8];
3038 /* Add encoded r (no need to encode it again, it was in the signature) */
3039 SHA512_Bytes(&hs, p, ec->publicKey.curve->fieldBits / 8);
3041 /* Encode pk and add it */
3042 pointlen = ec->publicKey.curve->fieldBits / 8;
3043 for (i = 0; i < pointlen - 1; ++i) {
3044 b = bignum_byte(ec->publicKey.y, i);
3045 SHA512_Bytes(&hs, &b, 1);
3047 /* Unset last bit of y and set first bit of x in its place */
3048 b = bignum_byte(ec->publicKey.y, i) & 0x7f;
3049 b |= bignum_bit(ec->publicKey.x, 0) << 7;
3050 SHA512_Bytes(&hs, &b, 1);
3052 /* Add the message itself */
3053 SHA512_Bytes(&hs, data, datalen);
3056 SHA512_Final(&hs, digest);
3058 /* Convert to Bignum */
3059 h = bignum_from_bytes_le(digest, sizeof(digest));
3067 /* Verify sB == r + h*publicKey */
3069 struct ec_point *lhs, *rhs, *tmp;
3072 lhs = ecp_mul(&ec->publicKey.curve->e.B, s);
3080 /* rhs = r + h*publicKey */
3081 tmp = ecp_mul(&ec->publicKey, h);
3088 rhs = ecp_add(r, tmp, 0);
3096 /* Check the point is the same */
3097 ret = !bignum_cmp(lhs->x, rhs->x);
3099 ret = !bignum_cmp(lhs->y, rhs->y);
3109 unsigned char digest[512 / 8];
3111 r = getmp(&p, &slen);
3113 s = getmp(&p, &slen);
3119 /* Perform correct hash function depending on curve size */
3120 if (ec->publicKey.curve->fieldBits <= 256) {
3121 SHA256_Simple(data, datalen, digest);
3122 digestLen = 256 / 8;
3123 } else if (ec->publicKey.curve->fieldBits <= 384) {
3124 SHA384_Simple(data, datalen, digest);
3125 digestLen = 384 / 8;
3127 SHA512_Simple(data, datalen, digest);
3128 digestLen = 512 / 8;
3131 /* Verify the signature */
3132 ret = _ecdsa_verify(&ec->publicKey, digest, digestLen, r, s);
3141 static unsigned char *ecdsa_sign(void *key, const char *data, int datalen,
3144 struct ec_key *ec = (struct ec_key *) key;
3145 unsigned char digest[512 / 8];
3147 Bignum r = NULL, s = NULL;
3148 unsigned char *buf, *p;
3149 int rlen, slen, namelen;
3152 if (!ec->privateKey || !ec->publicKey.curve) {
3156 if (ec->publicKey.curve->type == EC_EDWARDS) {
3157 struct ec_point *rp;
3158 int pointlen = ec->publicKey.curve->fieldBits / 8;
3160 /* hash = H(sk) (where hash creates 2 * fieldBits)
3162 * a = 2^(b-2) + SUM(2^i * h_i) for i = 2 -> b-2
3163 * r = H(h[b/8:b/4] + m)
3165 * S = (r + H(encodepoint(R) + encodepoint(pk) + m) * a) % l */
3167 unsigned char hash[512/8];
3173 for (i = 0; i < pointlen; ++i) {
3174 unsigned char b = (unsigned char)bignum_byte(ec->privateKey, i);
3175 SHA512_Bytes(&hs, &b, 1);
3178 SHA512_Final(&hs, hash);
3180 /* The second part is simply turning the hash into a
3181 * Bignum, however the 2^(b-2) bit *must* be set, and the
3182 * bottom 3 bits *must* not be */
3183 hash[0] &= 0xf8; /* Unset bottom 3 bits (if set) */
3184 hash[31] &= 0x7f; /* Unset above (b-2) */
3185 hash[31] |= 0x40; /* Set 2^(b-2) */
3186 /* Chop off the top part and convert to int */
3187 a = bignum_from_bytes_le(hash, 32);
3194 hash+(ec->publicKey.curve->fieldBits / 8),
3195 (ec->publicKey.curve->fieldBits / 4)
3196 - (ec->publicKey.curve->fieldBits / 8));
3197 SHA512_Bytes(&hs, data, datalen);
3198 SHA512_Final(&hs, hash);
3200 r = bignum_from_bytes_le(hash, 512/8);
3205 rp = ecp_mul(&ec->publicKey.curve->e.B, r);
3212 /* Now calculate s */
3214 /* Encode the point R */
3215 for (i = 0; i < pointlen - 1; ++i) {
3216 b = bignum_byte(rp->y, i);
3217 SHA512_Bytes(&hs, &b, 1);
3219 /* Unset last bit of y and set first bit of x in its place */
3220 b = bignum_byte(rp->y, i) & 0x7f;
3221 b |= bignum_bit(rp->x, 0) << 7;
3222 SHA512_Bytes(&hs, &b, 1);
3224 /* Encode the point pk */
3225 for (i = 0; i < pointlen - 1; ++i) {
3226 b = bignum_byte(ec->publicKey.y, i);
3227 SHA512_Bytes(&hs, &b, 1);
3229 /* Unset last bit of y and set first bit of x in its place */
3230 b = bignum_byte(ec->publicKey.y, i) & 0x7f;
3231 b |= bignum_bit(ec->publicKey.x, 0) << 7;
3232 SHA512_Bytes(&hs, &b, 1);
3234 /* Add the message */
3235 SHA512_Bytes(&hs, data, datalen);
3236 SHA512_Final(&hs, hash);
3241 tmp = bignum_from_bytes_le(hash, 512/8);
3248 tmp2 = modmul(tmp, a, ec->publicKey.curve->e.l);
3256 tmp = bigadd(r, tmp2);
3263 s = bigmod(tmp, ec->publicKey.curve->e.l);
3272 /* Format the output */
3273 namelen = strlen(ec->signalg->name);
3274 *siglen = 4+namelen+4+((ec->publicKey.curve->fieldBits / 8)*2);
3275 buf = snewn(*siglen, unsigned char);
3277 PUT_32BIT(p, namelen);
3279 memcpy(p, ec->signalg->name, namelen);
3281 PUT_32BIT(p, ((ec->publicKey.curve->fieldBits / 8)*2));
3284 /* Encode the point */
3285 pointlen = ec->publicKey.curve->fieldBits / 8;
3286 for (i = 0; i < pointlen - 1; ++i) {
3287 *p++ = bignum_byte(rp->y, i);
3289 /* Unset last bit of y and set first bit of x in its place */
3290 *p = bignum_byte(rp->y, i) & 0x7f;
3291 *p++ |= bignum_bit(rp->x, 0) << 7;
3294 /* Encode the int */
3295 for (i = 0; i < pointlen; ++i) {
3296 *p++ = bignum_byte(s, i);
3300 /* Perform correct hash function depending on curve size */
3301 if (ec->publicKey.curve->fieldBits <= 256) {
3302 SHA256_Simple(data, datalen, digest);
3303 digestLen = 256 / 8;
3304 } else if (ec->publicKey.curve->fieldBits <= 384) {
3305 SHA384_Simple(data, datalen, digest);
3306 digestLen = 384 / 8;
3308 SHA512_Simple(data, datalen, digest);
3309 digestLen = 512 / 8;
3312 /* Do the signature */
3313 _ecdsa_sign(ec->privateKey, ec->publicKey.curve, digest, digestLen, &r, &s);
3320 rlen = (bignum_bitcount(r) + 8) / 8;
3321 slen = (bignum_bitcount(s) + 8) / 8;
3323 namelen = strlen(ec->signalg->name);
3325 /* Format the output */
3326 *siglen = 8+namelen+rlen+slen+8;
3327 buf = snewn(*siglen, unsigned char);
3329 PUT_32BIT(p, namelen);
3331 memcpy(p, ec->signalg->name, namelen);
3333 PUT_32BIT(p, rlen + slen + 8);
3337 for (i = rlen; i--;)
3338 *p++ = bignum_byte(r, i);
3341 for (i = slen; i--;)
3342 *p++ = bignum_byte(s, i);
3351 const struct ecsign_extra sign_extra_ed25519 = {
3355 const struct ssh_signkey ssh_ecdsa_ed25519 = {
3362 ed25519_openssh_createkey,
3363 ed25519_openssh_fmtkey,
3364 2 /* point, private exponent */,
3370 &sign_extra_ed25519,
3373 /* OID: 1.2.840.10045.3.1.7 (ansiX9p256r1) */
3374 static const unsigned char nistp256_oid[] = {
3375 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
3377 const struct ecsign_extra sign_extra_nistp256 = {
3379 nistp256_oid, lenof(nistp256_oid),
3381 const struct ssh_signkey ssh_ecdsa_nistp256 = {
3388 ecdsa_openssh_createkey,
3389 ecdsa_openssh_fmtkey,
3390 3 /* curve name, point, private exponent */,
3394 "ecdsa-sha2-nistp256",
3395 "ecdsa-sha2-nistp256",
3396 &sign_extra_nistp256,
3399 /* OID: 1.3.132.0.34 (secp384r1) */
3400 static const unsigned char nistp384_oid[] = {
3401 0x2b, 0x81, 0x04, 0x00, 0x22
3403 const struct ecsign_extra sign_extra_nistp384 = {
3405 nistp384_oid, lenof(nistp384_oid),
3407 const struct ssh_signkey ssh_ecdsa_nistp384 = {
3414 ecdsa_openssh_createkey,
3415 ecdsa_openssh_fmtkey,
3416 3 /* curve name, point, private exponent */,
3420 "ecdsa-sha2-nistp384",
3421 "ecdsa-sha2-nistp384",
3422 &sign_extra_nistp384,
3425 /* OID: 1.3.132.0.35 (secp521r1) */
3426 static const unsigned char nistp521_oid[] = {
3427 0x2b, 0x81, 0x04, 0x00, 0x23
3429 const struct ecsign_extra sign_extra_nistp521 = {
3431 nistp521_oid, lenof(nistp521_oid),
3433 const struct ssh_signkey ssh_ecdsa_nistp521 = {
3440 ecdsa_openssh_createkey,
3441 ecdsa_openssh_fmtkey,
3442 3 /* curve name, point, private exponent */,
3446 "ecdsa-sha2-nistp521",
3447 "ecdsa-sha2-nistp521",
3448 &sign_extra_nistp521,
3451 /* ----------------------------------------------------------------------
3452 * Exposed ECDH interface
3455 struct eckex_extra {
3456 struct ec_curve *(*curve)(void);
3459 static Bignum ecdh_calculate(const Bignum private,
3460 const struct ec_point *public)
3464 p = ecp_mul(public, private);
3465 if (!p) return NULL;
3469 if (p->curve->type == EC_MONTGOMERY) {
3470 /* Do conversion in network byte order */
3472 int bytes = (bignum_bitcount(ret)+7) / 8;
3473 unsigned char *byteorder = snewn(bytes, unsigned char);
3479 for (i = 0; i < bytes; ++i) {
3480 byteorder[i] = bignum_byte(ret, i);
3483 ret = bignum_from_bytes(byteorder, bytes);
3491 void *ssh_ecdhkex_newkey(const struct ssh_kex *kex)
3493 const struct eckex_extra *extra = (const struct eckex_extra *)kex->extra;
3494 struct ec_curve *curve;
3496 struct ec_point *publicKey;
3498 curve = extra->curve();
3500 key = snew(struct ec_key);
3505 key->signalg = NULL;
3506 key->publicKey.curve = curve;
3508 if (curve->type == EC_MONTGOMERY) {
3509 unsigned char bytes[32] = {0};
3512 for (i = 0; i < sizeof(bytes); ++i)
3514 bytes[i] = (unsigned char)random_byte();
3519 key->privateKey = bignum_from_bytes(bytes, sizeof(bytes));
3520 for (i = 0; i < sizeof(bytes); ++i)
3522 ((volatile char*)bytes)[i] = 0;
3524 if (!key->privateKey) {
3528 publicKey = ecp_mul(&key->publicKey.curve->m.G, key->privateKey);
3530 freebn(key->privateKey);
3534 key->publicKey.x = publicKey->x;
3535 key->publicKey.y = publicKey->y;
3536 key->publicKey.z = NULL;
3539 key->privateKey = bignum_random_in_range(One, key->publicKey.curve->w.n);
3540 if (!key->privateKey) {
3544 publicKey = ecp_mul(&key->publicKey.curve->w.G, key->privateKey);
3546 freebn(key->privateKey);
3550 key->publicKey.x = publicKey->x;
3551 key->publicKey.y = publicKey->y;
3552 key->publicKey.z = NULL;
3558 char *ssh_ecdhkex_getpublic(void *key, int *len)
3560 struct ec_key *ec = (struct ec_key*)key;
3565 pointlen = (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8;
3567 if (ec->publicKey.curve->type == EC_WEIERSTRASS) {
3568 *len = 1 + pointlen * 2;
3572 point = (char*)snewn(*len, char);
3578 if (ec->publicKey.curve->type == EC_WEIERSTRASS) {
3580 for (i = pointlen; i--;) {
3581 *p++ = bignum_byte(ec->publicKey.x, i);
3583 for (i = pointlen; i--;) {
3584 *p++ = bignum_byte(ec->publicKey.y, i);
3587 for (i = 0; i < pointlen; ++i) {
3588 *p++ = bignum_byte(ec->publicKey.x, i);
3595 Bignum ssh_ecdhkex_getkey(void *key, char *remoteKey, int remoteKeyLen)
3597 struct ec_key *ec = (struct ec_key*) key;
3598 struct ec_point remote;
3601 if (ec->publicKey.curve->type == EC_WEIERSTRASS) {
3602 remote.curve = ec->publicKey.curve;
3603 remote.infinity = 0;
3604 if (!decodepoint(remoteKey, remoteKeyLen, &remote)) {
3608 /* Point length has to be the same length */
3609 if (remoteKeyLen != (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8) {
3613 remote.curve = ec->publicKey.curve;
3614 remote.infinity = 0;
3615 remote.x = bignum_from_bytes_le((unsigned char*)remoteKey, remoteKeyLen);
3620 ret = ecdh_calculate(ec->privateKey, &remote);
3621 if (remote.x) freebn(remote.x);
3622 if (remote.y) freebn(remote.y);
3626 void ssh_ecdhkex_freekey(void *key)
3631 static const struct eckex_extra kex_extra_curve25519 = { ec_curve25519 };
3632 static const struct ssh_kex ssh_ec_kex_curve25519 = {
3633 "curve25519-sha256@libssh.org", NULL, KEXTYPE_ECDH,
3634 &ssh_sha256, &kex_extra_curve25519,
3637 const struct eckex_extra kex_extra_nistp256 = { ec_p256 };
3638 static const struct ssh_kex ssh_ec_kex_nistp256 = {
3639 "ecdh-sha2-nistp256", NULL, KEXTYPE_ECDH,
3640 &ssh_sha256, &kex_extra_nistp256,
3643 const struct eckex_extra kex_extra_nistp384 = { ec_p384 };
3644 static const struct ssh_kex ssh_ec_kex_nistp384 = {
3645 "ecdh-sha2-nistp384", NULL, KEXTYPE_ECDH,
3646 &ssh_sha384, &kex_extra_nistp384,
3649 const struct eckex_extra kex_extra_nistp521 = { ec_p521 };
3650 static const struct ssh_kex ssh_ec_kex_nistp521 = {
3651 "ecdh-sha2-nistp521", NULL, KEXTYPE_ECDH,
3652 &ssh_sha512, &kex_extra_nistp521,
3655 static const struct ssh_kex *const ec_kex_list[] = {
3656 &ssh_ec_kex_curve25519,
3657 &ssh_ec_kex_nistp256,
3658 &ssh_ec_kex_nistp384,
3659 &ssh_ec_kex_nistp521,
3662 const struct ssh_kexes ssh_ecdh_kex = {
3663 sizeof(ec_kex_list) / sizeof(*ec_kex_list),
3667 /* ----------------------------------------------------------------------
3668 * Helper functions for finding key algorithms and returning auxiliary
3672 const struct ssh_signkey *ec_alg_by_oid(int len, const void *oid,
3673 const struct ec_curve **curve)
3675 static const struct ssh_signkey *algs_with_oid[] = {
3676 &ssh_ecdsa_nistp256,
3677 &ssh_ecdsa_nistp384,
3678 &ssh_ecdsa_nistp521,
3682 for (i = 0; i < lenof(algs_with_oid); i++) {
3683 const struct ssh_signkey *alg = algs_with_oid[i];
3684 const struct ecsign_extra *extra =
3685 (const struct ecsign_extra *)alg->extra;
3686 if (len == extra->oidlen && !memcmp(oid, extra->oid, len)) {
3687 *curve = extra->curve();
3694 const unsigned char *ec_alg_oid(const struct ssh_signkey *alg,
3697 const struct ecsign_extra *extra = (const struct ecsign_extra *)alg->extra;
3698 *oidlen = extra->oidlen;
3702 const int ec_nist_alg_and_curve_by_bits(int bits,
3703 const struct ec_curve **curve,
3704 const struct ssh_signkey **alg)
3707 case 256: *alg = &ssh_ecdsa_nistp256; break;
3708 case 384: *alg = &ssh_ecdsa_nistp384; break;
3709 case 521: *alg = &ssh_ecdsa_nistp521; break;
3710 default: return FALSE;
3712 *curve = ((struct ecsign_extra *)(*alg)->extra)->curve();
3716 const int ec_ed_alg_and_curve_by_bits(int bits,
3717 const struct ec_curve **curve,
3718 const struct ssh_signkey **alg)
3721 case 256: *alg = &ssh_ecdsa_ed25519; break;
3722 default: return FALSE;
3724 *curve = ((struct ecsign_extra *)(*alg)->extra)->curve();