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);
2454 const struct ssh_hash *hash;
2456 /* These fields are used by the OpenSSH PEM format importer/exporter */
2457 const unsigned char *oid;
2461 static void ecdsa_freekey(void *key)
2463 struct ec_key *ec = (struct ec_key *) key;
2466 if (ec->publicKey.x)
2467 freebn(ec->publicKey.x);
2468 if (ec->publicKey.y)
2469 freebn(ec->publicKey.y);
2470 if (ec->publicKey.z)
2471 freebn(ec->publicKey.z);
2473 freebn(ec->privateKey);
2477 static void *ecdsa_newkey(const struct ssh_signkey *self,
2478 const char *data, int len)
2480 const struct ecsign_extra *extra =
2481 (const struct ecsign_extra *)self->extra;
2485 struct ec_curve *curve;
2487 getstring(&data, &len, &p, &slen);
2492 curve = extra->curve();
2493 assert(curve->type == EC_WEIERSTRASS || curve->type == EC_EDWARDS);
2495 /* Curve name is duplicated for Weierstrass form */
2496 if (curve->type == EC_WEIERSTRASS) {
2497 getstring(&data, &len, &p, &slen);
2498 if (!match_ssh_id(slen, p, curve->name)) return NULL;
2501 ec = snew(struct ec_key);
2504 ec->publicKey.curve = curve;
2505 ec->publicKey.infinity = 0;
2506 ec->publicKey.x = NULL;
2507 ec->publicKey.y = NULL;
2508 ec->publicKey.z = NULL;
2509 if (!getmppoint(&data, &len, &ec->publicKey)) {
2513 ec->privateKey = NULL;
2515 if (!ec->publicKey.x || !ec->publicKey.y ||
2516 bignum_cmp(ec->publicKey.x, curve->p) >= 0 ||
2517 bignum_cmp(ec->publicKey.y, curve->p) >= 0)
2526 static char *ecdsa_fmtkey(void *key)
2528 struct ec_key *ec = (struct ec_key *) key;
2530 int len, i, pos, nibbles;
2531 static const char hex[] = "0123456789abcdef";
2532 if (!ec->publicKey.x || !ec->publicKey.y || !ec->publicKey.curve)
2535 len = 4 + 2 + 1; /* 2 x "0x", punctuation, \0 */
2536 if (ec->publicKey.curve->name)
2537 len += strlen(ec->publicKey.curve->name); /* Curve name */
2538 len += 4 * (bignum_bitcount(ec->publicKey.x) + 15) / 16;
2539 len += 4 * (bignum_bitcount(ec->publicKey.y) + 15) / 16;
2540 p = snewn(len, char);
2543 if (ec->publicKey.curve->name)
2544 pos += sprintf(p + pos, "%s,", ec->publicKey.curve->name);
2545 pos += sprintf(p + pos, "0x");
2546 nibbles = (3 + bignum_bitcount(ec->publicKey.x)) / 4;
2549 for (i = nibbles; i--;) {
2551 hex[(bignum_byte(ec->publicKey.x, i / 2) >> (4 * (i % 2))) & 0xF];
2553 pos += sprintf(p + pos, ",0x");
2554 nibbles = (3 + bignum_bitcount(ec->publicKey.y)) / 4;
2557 for (i = nibbles; i--;) {
2559 hex[(bignum_byte(ec->publicKey.y, i / 2) >> (4 * (i % 2))) & 0xF];
2565 static unsigned char *ecdsa_public_blob(void *key, int *len)
2567 struct ec_key *ec = (struct ec_key *) key;
2568 int pointlen, bloblen, fullnamelen, namelen;
2570 unsigned char *blob, *p;
2572 fullnamelen = strlen(ec->signalg->name);
2574 if (ec->publicKey.curve->type == EC_EDWARDS) {
2575 /* Edwards compressed form "ssh-ed25519" point y[:-1] + x[0:1] */
2577 pointlen = ec->publicKey.curve->fieldBits / 8;
2579 /* Can't handle this in our loop */
2580 if (pointlen < 2) return NULL;
2582 bloblen = 4 + fullnamelen + 4 + pointlen;
2583 blob = snewn(bloblen, unsigned char);
2584 if (!blob) return NULL;
2587 PUT_32BIT(p, fullnamelen);
2589 memcpy(p, ec->signalg->name, fullnamelen);
2591 PUT_32BIT(p, pointlen);
2594 /* Unset last bit of y and set first bit of x in its place */
2595 for (i = 0; i < pointlen - 1; ++i) {
2596 *p++ = bignum_byte(ec->publicKey.y, i);
2598 /* Unset last bit of y and set first bit of x in its place */
2599 *p = bignum_byte(ec->publicKey.y, i) & 0x7f;
2600 *p++ |= bignum_bit(ec->publicKey.x, 0) << 7;
2601 } else if (ec->publicKey.curve->type == EC_WEIERSTRASS) {
2602 assert(ec->publicKey.curve->name);
2603 namelen = strlen(ec->publicKey.curve->name);
2605 pointlen = (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8;
2608 * string "ecdsa-sha2-<name>", string "<name>", 0x04 point x, y.
2610 bloblen = 4 + fullnamelen + 4 + namelen + 4 + 1 + (pointlen * 2);
2611 blob = snewn(bloblen, unsigned char);
2614 PUT_32BIT(p, fullnamelen);
2616 memcpy(p, ec->signalg->name, fullnamelen);
2618 PUT_32BIT(p, namelen);
2620 memcpy(p, ec->publicKey.curve->name, namelen);
2622 PUT_32BIT(p, (2 * pointlen) + 1);
2625 for (i = pointlen; i--;) {
2626 *p++ = bignum_byte(ec->publicKey.x, i);
2628 for (i = pointlen; i--;) {
2629 *p++ = bignum_byte(ec->publicKey.y, i);
2635 assert(p == blob + bloblen);
2641 static unsigned char *ecdsa_private_blob(void *key, int *len)
2643 struct ec_key *ec = (struct ec_key *) key;
2644 int keylen, bloblen;
2646 unsigned char *blob, *p;
2648 if (!ec->privateKey) return NULL;
2650 if (ec->publicKey.curve->type == EC_EDWARDS) {
2652 keylen = (bignum_bitcount(ec->privateKey) + 7) / 8;
2655 keylen = (bignum_bitcount(ec->privateKey) + 8) / 8;
2659 * mpint privateKey. Total 4 + keylen.
2661 bloblen = 4 + keylen;
2662 blob = snewn(bloblen, unsigned char);
2665 PUT_32BIT(p, keylen);
2667 if (ec->publicKey.curve->type == EC_EDWARDS) {
2669 for (i = 0; i < keylen; ++i)
2670 *p++ = bignum_byte(ec->privateKey, i);
2672 for (i = keylen; i--;)
2673 *p++ = bignum_byte(ec->privateKey, i);
2676 assert(p == blob + bloblen);
2681 static void *ecdsa_createkey(const struct ssh_signkey *self,
2682 const unsigned char *pub_blob, int pub_len,
2683 const unsigned char *priv_blob, int priv_len)
2686 struct ec_point *publicKey;
2687 const char *pb = (const char *) priv_blob;
2689 ec = (struct ec_key*)ecdsa_newkey(self, (const char *) pub_blob, pub_len);
2694 if (ec->publicKey.curve->type != EC_WEIERSTRASS
2695 && ec->publicKey.curve->type != EC_EDWARDS) {
2700 if (ec->publicKey.curve->type == EC_EDWARDS) {
2701 ec->privateKey = getmp_le(&pb, &priv_len);
2703 ec->privateKey = getmp(&pb, &priv_len);
2705 if (!ec->privateKey) {
2710 /* Check that private key generates public key */
2711 publicKey = ec_public(ec->privateKey, ec->publicKey.curve);
2714 bignum_cmp(publicKey->x, ec->publicKey.x) ||
2715 bignum_cmp(publicKey->y, ec->publicKey.y))
2720 ec_point_free(publicKey);
2725 static void *ed25519_openssh_createkey(const struct ssh_signkey *self,
2726 const unsigned char **blob, int *len)
2729 struct ec_point *publicKey;
2733 getstring((const char**)blob, len, &p, &plen);
2739 ec = snew(struct ec_key);
2746 ec->publicKey.curve = ec_ed25519();
2747 ec->publicKey.infinity = 0;
2748 ec->privateKey = NULL;
2749 ec->publicKey.x = NULL;
2750 ec->publicKey.z = NULL;
2751 ec->publicKey.y = NULL;
2753 if (!decodepoint_ed(p, plen, &ec->publicKey))
2759 getstring((const char**)blob, len, &q, &qlen);
2765 ec->privateKey = bignum_from_bytes_le((const unsigned char *)q, 32);
2766 if (!ec->privateKey) {
2771 /* Check that private key generates public key */
2772 publicKey = ec_public(ec->privateKey, ec->publicKey.curve);
2775 bignum_cmp(publicKey->x, ec->publicKey.x) ||
2776 bignum_cmp(publicKey->y, ec->publicKey.y))
2781 ec_point_free(publicKey);
2783 /* The OpenSSH format for ed25519 private keys also for some
2784 * reason encodes an extra copy of the public key in the second
2785 * half of the secret-key string. Check that that's present and
2786 * correct as well, otherwise the key we think we've imported
2787 * won't behave identically to the way OpenSSH would have treated
2789 if (plen != 32 || 0 != memcmp(q + 32, p, 32)) {
2797 static int ed25519_openssh_fmtkey(void *key, unsigned char *blob, int len)
2799 struct ec_key *ec = (struct ec_key *) key;
2806 if (ec->publicKey.curve->type != EC_EDWARDS) {
2810 pointlen = (bignum_bitcount(ec->publicKey.y) + 7) / 8;
2811 keylen = (bignum_bitcount(ec->privateKey) + 7) / 8;
2812 bloblen = 4 + pointlen + 4 + keylen + pointlen;
2817 /* Encode the public point */
2818 PUT_32BIT(blob, pointlen);
2821 for (i = 0; i < pointlen - 1; ++i) {
2822 *blob++ = bignum_byte(ec->publicKey.y, i);
2824 /* Unset last bit of y and set first bit of x in its place */
2825 *blob = bignum_byte(ec->publicKey.y, i) & 0x7f;
2826 *blob++ |= bignum_bit(ec->publicKey.x, 0) << 7;
2828 PUT_32BIT(blob, keylen + pointlen);
2830 for (i = 0; i < keylen; ++i) {
2831 *blob++ = bignum_byte(ec->privateKey, i);
2833 /* Now encode an extra copy of the public point as the second half
2834 * of the private key string, as the OpenSSH format for some
2835 * reason requires */
2836 for (i = 0; i < pointlen - 1; ++i) {
2837 *blob++ = bignum_byte(ec->publicKey.y, i);
2839 /* Unset last bit of y and set first bit of x in its place */
2840 *blob = bignum_byte(ec->publicKey.y, i) & 0x7f;
2841 *blob++ |= bignum_bit(ec->publicKey.x, 0) << 7;
2846 static void *ecdsa_openssh_createkey(const struct ssh_signkey *self,
2847 const unsigned char **blob, int *len)
2849 const struct ecsign_extra *extra =
2850 (const struct ecsign_extra *)self->extra;
2851 const char **b = (const char **) blob;
2855 struct ec_curve *curve;
2856 struct ec_point *publicKey;
2858 getstring(b, len, &p, &slen);
2863 curve = extra->curve();
2864 assert(curve->type == EC_WEIERSTRASS);
2866 ec = snew(struct ec_key);
2869 ec->publicKey.curve = curve;
2870 ec->publicKey.infinity = 0;
2871 ec->publicKey.x = NULL;
2872 ec->publicKey.y = NULL;
2873 ec->publicKey.z = NULL;
2874 if (!getmppoint(b, len, &ec->publicKey)) {
2878 ec->privateKey = NULL;
2880 if (!ec->publicKey.x || !ec->publicKey.y ||
2881 bignum_cmp(ec->publicKey.x, curve->p) >= 0 ||
2882 bignum_cmp(ec->publicKey.y, curve->p) >= 0)
2888 ec->privateKey = getmp(b, len);
2889 if (ec->privateKey == NULL)
2895 /* Now check that the private key makes the public key */
2896 publicKey = ec_public(ec->privateKey, ec->publicKey.curve);
2903 if (bignum_cmp(ec->publicKey.x, publicKey->x) ||
2904 bignum_cmp(ec->publicKey.y, publicKey->y))
2906 /* Private key doesn't make the public key on the given curve */
2908 ec_point_free(publicKey);
2912 ec_point_free(publicKey);
2917 static int ecdsa_openssh_fmtkey(void *key, unsigned char *blob, int len)
2919 struct ec_key *ec = (struct ec_key *) key;
2926 if (ec->publicKey.curve->type != EC_WEIERSTRASS) {
2930 pointlen = (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8;
2931 namelen = strlen(ec->publicKey.curve->name);
2933 4 + namelen /* <LEN> nistpXXX */
2934 + 4 + 1 + (pointlen * 2) /* <LEN> 0x04 pX pY */
2935 + ssh2_bignum_length(ec->privateKey);
2942 PUT_32BIT(blob+bloblen, namelen);
2944 memcpy(blob+bloblen, ec->publicKey.curve->name, namelen);
2947 PUT_32BIT(blob+bloblen, 1 + (pointlen * 2));
2949 blob[bloblen++] = 0x04;
2950 for (i = pointlen; i--; )
2951 blob[bloblen++] = bignum_byte(ec->publicKey.x, i);
2952 for (i = pointlen; i--; )
2953 blob[bloblen++] = bignum_byte(ec->publicKey.y, i);
2955 pointlen = (bignum_bitcount(ec->privateKey) + 8) / 8;
2956 PUT_32BIT(blob+bloblen, pointlen);
2958 for (i = pointlen; i--; )
2959 blob[bloblen++] = bignum_byte(ec->privateKey, i);
2964 static int ecdsa_pubkey_bits(const struct ssh_signkey *self,
2965 const void *blob, int len)
2970 ec = (struct ec_key*)ecdsa_newkey(self, (const char *) blob, len);
2973 ret = ec->publicKey.curve->fieldBits;
2979 static int ecdsa_verifysig(void *key, const char *sig, int siglen,
2980 const char *data, int datalen)
2982 struct ec_key *ec = (struct ec_key *) key;
2983 const struct ecsign_extra *extra =
2984 (const struct ecsign_extra *)ec->signalg->extra;
2990 if (!ec->publicKey.x || !ec->publicKey.y || !ec->publicKey.curve)
2993 /* Check the signature starts with the algorithm name */
2994 getstring(&sig, &siglen, &p, &slen);
2998 if (!match_ssh_id(slen, p, ec->signalg->name)) {
3002 getstring(&sig, &siglen, &p, &slen);
3003 if (ec->publicKey.curve->type == EC_EDWARDS) {
3007 /* Check that the signature is two times the length of a point */
3008 if (slen != (ec->publicKey.curve->fieldBits / 8) * 2) {
3012 /* Check it's the 256 bit field so that SHA512 is the correct hash */
3013 if (ec->publicKey.curve->fieldBits != 256) {
3017 /* Get the signature */
3018 r = ec_point_new(ec->publicKey.curve, NULL, NULL, NULL, 0);
3022 if (!decodepoint(p, ec->publicKey.curve->fieldBits / 8, r)) {
3026 s = bignum_from_bytes_le((unsigned char*)p + (ec->publicKey.curve->fieldBits / 8),
3027 ec->publicKey.curve->fieldBits / 8);
3033 /* Get the hash of the encoded value of R + encoded value of pk + message */
3037 unsigned char digest[512 / 8];
3041 /* Add encoded r (no need to encode it again, it was in the signature) */
3042 SHA512_Bytes(&hs, p, ec->publicKey.curve->fieldBits / 8);
3044 /* Encode pk and add it */
3045 pointlen = ec->publicKey.curve->fieldBits / 8;
3046 for (i = 0; i < pointlen - 1; ++i) {
3047 b = bignum_byte(ec->publicKey.y, i);
3048 SHA512_Bytes(&hs, &b, 1);
3050 /* Unset last bit of y and set first bit of x in its place */
3051 b = bignum_byte(ec->publicKey.y, i) & 0x7f;
3052 b |= bignum_bit(ec->publicKey.x, 0) << 7;
3053 SHA512_Bytes(&hs, &b, 1);
3055 /* Add the message itself */
3056 SHA512_Bytes(&hs, data, datalen);
3059 SHA512_Final(&hs, digest);
3061 /* Convert to Bignum */
3062 h = bignum_from_bytes_le(digest, sizeof(digest));
3070 /* Verify sB == r + h*publicKey */
3072 struct ec_point *lhs, *rhs, *tmp;
3075 lhs = ecp_mul(&ec->publicKey.curve->e.B, s);
3083 /* rhs = r + h*publicKey */
3084 tmp = ecp_mul(&ec->publicKey, h);
3091 rhs = ecp_add(r, tmp, 0);
3099 /* Check the point is the same */
3100 ret = !bignum_cmp(lhs->x, rhs->x);
3102 ret = !bignum_cmp(lhs->y, rhs->y);
3112 unsigned char digest[512 / 8];
3115 r = getmp(&p, &slen);
3117 s = getmp(&p, &slen);
3123 digestLen = extra->hash->hlen;
3124 assert(digestLen <= sizeof(digest));
3125 hashctx = extra->hash->init();
3126 extra->hash->bytes(hashctx, data, datalen);
3127 extra->hash->final(hashctx, digest);
3129 /* Verify the signature */
3130 ret = _ecdsa_verify(&ec->publicKey, digest, digestLen, r, s);
3139 static unsigned char *ecdsa_sign(void *key, const char *data, int datalen,
3142 struct ec_key *ec = (struct ec_key *) key;
3143 const struct ecsign_extra *extra =
3144 (const struct ecsign_extra *)ec->signalg->extra;
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);
3302 digestLen = extra->hash->hlen;
3303 assert(digestLen <= sizeof(digest));
3304 hashctx = extra->hash->init();
3305 extra->hash->bytes(hashctx, data, datalen);
3306 extra->hash->final(hashctx, digest);
3308 /* Do the signature */
3309 _ecdsa_sign(ec->privateKey, ec->publicKey.curve, digest, digestLen, &r, &s);
3316 rlen = (bignum_bitcount(r) + 8) / 8;
3317 slen = (bignum_bitcount(s) + 8) / 8;
3319 namelen = strlen(ec->signalg->name);
3321 /* Format the output */
3322 *siglen = 8+namelen+rlen+slen+8;
3323 buf = snewn(*siglen, unsigned char);
3325 PUT_32BIT(p, namelen);
3327 memcpy(p, ec->signalg->name, namelen);
3329 PUT_32BIT(p, rlen + slen + 8);
3333 for (i = rlen; i--;)
3334 *p++ = bignum_byte(r, i);
3337 for (i = slen; i--;)
3338 *p++ = bignum_byte(s, i);
3347 const struct ecsign_extra sign_extra_ed25519 = {
3351 const struct ssh_signkey ssh_ecdsa_ed25519 = {
3358 ed25519_openssh_createkey,
3359 ed25519_openssh_fmtkey,
3360 2 /* point, private exponent */,
3366 &sign_extra_ed25519,
3369 /* OID: 1.2.840.10045.3.1.7 (ansiX9p256r1) */
3370 static const unsigned char nistp256_oid[] = {
3371 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
3373 const struct ecsign_extra sign_extra_nistp256 = {
3374 ec_p256, &ssh_sha256,
3375 nistp256_oid, lenof(nistp256_oid),
3377 const struct ssh_signkey ssh_ecdsa_nistp256 = {
3384 ecdsa_openssh_createkey,
3385 ecdsa_openssh_fmtkey,
3386 3 /* curve name, point, private exponent */,
3390 "ecdsa-sha2-nistp256",
3391 "ecdsa-sha2-nistp256",
3392 &sign_extra_nistp256,
3395 /* OID: 1.3.132.0.34 (secp384r1) */
3396 static const unsigned char nistp384_oid[] = {
3397 0x2b, 0x81, 0x04, 0x00, 0x22
3399 const struct ecsign_extra sign_extra_nistp384 = {
3400 ec_p384, &ssh_sha384,
3401 nistp384_oid, lenof(nistp384_oid),
3403 const struct ssh_signkey ssh_ecdsa_nistp384 = {
3410 ecdsa_openssh_createkey,
3411 ecdsa_openssh_fmtkey,
3412 3 /* curve name, point, private exponent */,
3416 "ecdsa-sha2-nistp384",
3417 "ecdsa-sha2-nistp384",
3418 &sign_extra_nistp384,
3421 /* OID: 1.3.132.0.35 (secp521r1) */
3422 static const unsigned char nistp521_oid[] = {
3423 0x2b, 0x81, 0x04, 0x00, 0x23
3425 const struct ecsign_extra sign_extra_nistp521 = {
3426 ec_p521, &ssh_sha512,
3427 nistp521_oid, lenof(nistp521_oid),
3429 const struct ssh_signkey ssh_ecdsa_nistp521 = {
3436 ecdsa_openssh_createkey,
3437 ecdsa_openssh_fmtkey,
3438 3 /* curve name, point, private exponent */,
3442 "ecdsa-sha2-nistp521",
3443 "ecdsa-sha2-nistp521",
3444 &sign_extra_nistp521,
3447 /* ----------------------------------------------------------------------
3448 * Exposed ECDH interface
3451 struct eckex_extra {
3452 struct ec_curve *(*curve)(void);
3455 static Bignum ecdh_calculate(const Bignum private,
3456 const struct ec_point *public)
3460 p = ecp_mul(public, private);
3461 if (!p) return NULL;
3465 if (p->curve->type == EC_MONTGOMERY) {
3466 /* Do conversion in network byte order */
3468 int bytes = (bignum_bitcount(ret)+7) / 8;
3469 unsigned char *byteorder = snewn(bytes, unsigned char);
3475 for (i = 0; i < bytes; ++i) {
3476 byteorder[i] = bignum_byte(ret, i);
3479 ret = bignum_from_bytes(byteorder, bytes);
3487 void *ssh_ecdhkex_newkey(const struct ssh_kex *kex)
3489 const struct eckex_extra *extra = (const struct eckex_extra *)kex->extra;
3490 struct ec_curve *curve;
3492 struct ec_point *publicKey;
3494 curve = extra->curve();
3496 key = snew(struct ec_key);
3501 key->signalg = NULL;
3502 key->publicKey.curve = curve;
3504 if (curve->type == EC_MONTGOMERY) {
3505 unsigned char bytes[32] = {0};
3508 for (i = 0; i < sizeof(bytes); ++i)
3510 bytes[i] = (unsigned char)random_byte();
3515 key->privateKey = bignum_from_bytes(bytes, sizeof(bytes));
3516 for (i = 0; i < sizeof(bytes); ++i)
3518 ((volatile char*)bytes)[i] = 0;
3520 if (!key->privateKey) {
3524 publicKey = ecp_mul(&key->publicKey.curve->m.G, key->privateKey);
3526 freebn(key->privateKey);
3530 key->publicKey.x = publicKey->x;
3531 key->publicKey.y = publicKey->y;
3532 key->publicKey.z = NULL;
3535 key->privateKey = bignum_random_in_range(One, key->publicKey.curve->w.n);
3536 if (!key->privateKey) {
3540 publicKey = ecp_mul(&key->publicKey.curve->w.G, key->privateKey);
3542 freebn(key->privateKey);
3546 key->publicKey.x = publicKey->x;
3547 key->publicKey.y = publicKey->y;
3548 key->publicKey.z = NULL;
3554 char *ssh_ecdhkex_getpublic(void *key, int *len)
3556 struct ec_key *ec = (struct ec_key*)key;
3561 pointlen = (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8;
3563 if (ec->publicKey.curve->type == EC_WEIERSTRASS) {
3564 *len = 1 + pointlen * 2;
3568 point = (char*)snewn(*len, char);
3574 if (ec->publicKey.curve->type == EC_WEIERSTRASS) {
3576 for (i = pointlen; i--;) {
3577 *p++ = bignum_byte(ec->publicKey.x, i);
3579 for (i = pointlen; i--;) {
3580 *p++ = bignum_byte(ec->publicKey.y, i);
3583 for (i = 0; i < pointlen; ++i) {
3584 *p++ = bignum_byte(ec->publicKey.x, i);
3591 Bignum ssh_ecdhkex_getkey(void *key, char *remoteKey, int remoteKeyLen)
3593 struct ec_key *ec = (struct ec_key*) key;
3594 struct ec_point remote;
3597 if (ec->publicKey.curve->type == EC_WEIERSTRASS) {
3598 remote.curve = ec->publicKey.curve;
3599 remote.infinity = 0;
3600 if (!decodepoint(remoteKey, remoteKeyLen, &remote)) {
3604 /* Point length has to be the same length */
3605 if (remoteKeyLen != (bignum_bitcount(ec->publicKey.curve->p) + 7) / 8) {
3609 remote.curve = ec->publicKey.curve;
3610 remote.infinity = 0;
3611 remote.x = bignum_from_bytes_le((unsigned char*)remoteKey, remoteKeyLen);
3616 ret = ecdh_calculate(ec->privateKey, &remote);
3617 if (remote.x) freebn(remote.x);
3618 if (remote.y) freebn(remote.y);
3622 void ssh_ecdhkex_freekey(void *key)
3627 static const struct eckex_extra kex_extra_curve25519 = { ec_curve25519 };
3628 static const struct ssh_kex ssh_ec_kex_curve25519 = {
3629 "curve25519-sha256@libssh.org", NULL, KEXTYPE_ECDH,
3630 &ssh_sha256, &kex_extra_curve25519,
3633 const struct eckex_extra kex_extra_nistp256 = { ec_p256 };
3634 static const struct ssh_kex ssh_ec_kex_nistp256 = {
3635 "ecdh-sha2-nistp256", NULL, KEXTYPE_ECDH,
3636 &ssh_sha256, &kex_extra_nistp256,
3639 const struct eckex_extra kex_extra_nistp384 = { ec_p384 };
3640 static const struct ssh_kex ssh_ec_kex_nistp384 = {
3641 "ecdh-sha2-nistp384", NULL, KEXTYPE_ECDH,
3642 &ssh_sha384, &kex_extra_nistp384,
3645 const struct eckex_extra kex_extra_nistp521 = { ec_p521 };
3646 static const struct ssh_kex ssh_ec_kex_nistp521 = {
3647 "ecdh-sha2-nistp521", NULL, KEXTYPE_ECDH,
3648 &ssh_sha512, &kex_extra_nistp521,
3651 static const struct ssh_kex *const ec_kex_list[] = {
3652 &ssh_ec_kex_curve25519,
3653 &ssh_ec_kex_nistp256,
3654 &ssh_ec_kex_nistp384,
3655 &ssh_ec_kex_nistp521,
3658 const struct ssh_kexes ssh_ecdh_kex = {
3659 sizeof(ec_kex_list) / sizeof(*ec_kex_list),
3663 /* ----------------------------------------------------------------------
3664 * Helper functions for finding key algorithms and returning auxiliary
3668 const struct ssh_signkey *ec_alg_by_oid(int len, const void *oid,
3669 const struct ec_curve **curve)
3671 static const struct ssh_signkey *algs_with_oid[] = {
3672 &ssh_ecdsa_nistp256,
3673 &ssh_ecdsa_nistp384,
3674 &ssh_ecdsa_nistp521,
3678 for (i = 0; i < lenof(algs_with_oid); i++) {
3679 const struct ssh_signkey *alg = algs_with_oid[i];
3680 const struct ecsign_extra *extra =
3681 (const struct ecsign_extra *)alg->extra;
3682 if (len == extra->oidlen && !memcmp(oid, extra->oid, len)) {
3683 *curve = extra->curve();
3690 const unsigned char *ec_alg_oid(const struct ssh_signkey *alg,
3693 const struct ecsign_extra *extra = (const struct ecsign_extra *)alg->extra;
3694 *oidlen = extra->oidlen;
3698 const int ec_nist_alg_and_curve_by_bits(int bits,
3699 const struct ec_curve **curve,
3700 const struct ssh_signkey **alg)
3703 case 256: *alg = &ssh_ecdsa_nistp256; break;
3704 case 384: *alg = &ssh_ecdsa_nistp384; break;
3705 case 521: *alg = &ssh_ecdsa_nistp521; break;
3706 default: return FALSE;
3708 *curve = ((struct ecsign_extra *)(*alg)->extra)->curve();
3712 const int ec_ed_alg_and_curve_by_bits(int bits,
3713 const struct ec_curve **curve,
3714 const struct ssh_signkey **alg)
3717 case 256: *alg = &ssh_ecdsa_ed25519; break;
3718 default: return FALSE;
3720 *curve = ((struct ecsign_extra *)(*alg)->extra)->curve();