Line data Source code
1 : /* t-mpi-point.c - Tests for mpi point functions
2 : * Copyright (C) 2013 g10 Code GmbH
3 : *
4 : * This file is part of Libgcrypt.
5 : *
6 : * Libgcrypt is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser General Public License as
8 : * published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * Libgcrypt is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #ifdef HAVE_CONFIG_H
21 : # include <config.h>
22 : #endif
23 : #include <stdio.h>
24 : #include <stdlib.h>
25 : #include <string.h>
26 : #include <assert.h>
27 : #include <stdarg.h>
28 :
29 : #define PGM "t-mpi-point"
30 : #include "t-common.h"
31 :
32 : static struct
33 : {
34 : const char *desc; /* Description of the curve. */
35 : const char *p; /* Order of the prime field. */
36 : const char *a, *b; /* The coefficients. */
37 : const char *n; /* The order of the base point. */
38 : const char *g_x, *g_y; /* Base point. */
39 : const char *h; /* Cofactor. */
40 : } test_curve[] =
41 : {
42 : {
43 : "NIST P-192",
44 : "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
45 : "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
46 : "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
47 : "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
48 :
49 : "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
50 : "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
51 : "0x01"
52 : },
53 : {
54 : "NIST P-224",
55 : "0xffffffffffffffffffffffffffffffff000000000000000000000001",
56 : "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
57 : "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
58 : "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
59 :
60 : "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
61 : "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
62 : "0x01"
63 : },
64 : {
65 : "NIST P-256",
66 : "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
67 : "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
68 : "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
69 : "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
70 :
71 : "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
72 : "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
73 : "0x01"
74 : },
75 : {
76 : "NIST P-384",
77 : "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
78 : "ffffffff0000000000000000ffffffff",
79 : "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
80 : "ffffffff0000000000000000fffffffc",
81 : "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
82 : "c656398d8a2ed19d2a85c8edd3ec2aef",
83 : "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
84 : "581a0db248b0a77aecec196accc52973",
85 :
86 : "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
87 : "5502f25dbf55296c3a545e3872760ab7",
88 : "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
89 : "0a60b1ce1d7e819d7a431d7c90ea0e5f",
90 : "0x01"
91 : },
92 : {
93 : "NIST P-521",
94 : "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
95 : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
96 : "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
97 : "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
98 : "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
99 : "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
100 : "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
101 : "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
102 :
103 : "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
104 : "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
105 : "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
106 : "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
107 : "0x01"
108 : },
109 : {
110 : "Ed25519",
111 : "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
112 : "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC",
113 : "0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3",
114 : "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
115 : "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A",
116 : "0x6666666666666666666666666666666666666666666666666666666666666658",
117 : "0x08"
118 : },
119 : { NULL, NULL, NULL, NULL, NULL, NULL }
120 : };
121 :
122 : /* A sample public key for NIST P-256. */
123 : static const char sample_p256_q[] =
124 : "04"
125 : "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E"
126 : "E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E";
127 : static const char sample_p256_q_x[] =
128 : "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E";
129 : static const char sample_p256_q_y[] =
130 : "00E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E";
131 :
132 :
133 : /* A sample public key for Ed25519. */
134 : static const char sample_ed25519_q[] =
135 : "04"
136 : "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce"
137 : "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7";
138 : static const char sample_ed25519_q_x[] =
139 : "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce";
140 : static const char sample_ed25519_q_y[] =
141 : "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7";
142 : static const char sample_ed25519_q_eddsa[] =
143 : "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a";
144 : static const char sample_ed25519_d[] =
145 : "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60";
146 :
147 :
148 : static void
149 0 : print_mpi_2 (const char *text, const char *text2, gcry_mpi_t a)
150 : {
151 : gcry_error_t err;
152 : char *buf;
153 0 : void *bufaddr = &buf;
154 :
155 0 : err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
156 0 : if (err)
157 0 : fprintf (stderr, "%s%s: [error printing number: %s]\n",
158 : text, text2? text2:"", gpg_strerror (err));
159 : else
160 : {
161 0 : fprintf (stderr, "%s%s: %s\n", text, text2? text2:"", buf);
162 0 : gcry_free (buf);
163 : }
164 0 : }
165 :
166 :
167 : static void
168 0 : print_mpi (const char *text, gcry_mpi_t a)
169 : {
170 0 : print_mpi_2 (text, NULL, a);
171 0 : }
172 :
173 :
174 : static void
175 0 : print_point (const char *text, gcry_mpi_point_t a)
176 : {
177 : gcry_mpi_t x, y, z;
178 :
179 0 : x = gcry_mpi_new (0);
180 0 : y = gcry_mpi_new (0);
181 0 : z = gcry_mpi_new (0);
182 0 : gcry_mpi_point_get (x, y, z, a);
183 0 : print_mpi_2 (text, ".x", x);
184 0 : print_mpi_2 (text, ".y", y);
185 0 : print_mpi_2 (text, ".z", z);
186 0 : gcry_mpi_release (x);
187 0 : gcry_mpi_release (y);
188 0 : gcry_mpi_release (z);
189 0 : }
190 :
191 :
192 : static void
193 0 : print_sexp (const char *prefix, gcry_sexp_t a)
194 : {
195 : char *buf;
196 : size_t size;
197 :
198 0 : if (prefix)
199 0 : fputs (prefix, stderr);
200 0 : size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
201 0 : buf = gcry_xmalloc (size);
202 :
203 0 : gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
204 0 : fprintf (stderr, "%.*s", (int)size, buf);
205 0 : gcry_free (buf);
206 0 : }
207 :
208 :
209 : static gcry_mpi_t
210 100 : hex2mpi (const char *string)
211 : {
212 : gpg_error_t err;
213 : gcry_mpi_t val;
214 :
215 100 : err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
216 100 : if (err)
217 0 : die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err));
218 100 : return val;
219 : }
220 :
221 :
222 : /* Convert STRING consisting of hex characters into its binary
223 : representation and return it as an allocated buffer. The valid
224 : length of the buffer is returned at R_LENGTH. The string is
225 : delimited by end of string. The function returns NULL on
226 : error. */
227 : static void *
228 2 : hex2buffer (const char *string, size_t *r_length)
229 : {
230 : const char *s;
231 : unsigned char *buffer;
232 : size_t length;
233 :
234 2 : buffer = xmalloc (strlen(string)/2+1);
235 2 : length = 0;
236 99 : for (s=string; *s; s +=2 )
237 : {
238 97 : if (!hexdigitp (s) || !hexdigitp (s+1))
239 0 : return NULL; /* Invalid hex digits. */
240 97 : ((unsigned char*)buffer)[length++] = xtoi_2 (s);
241 : }
242 2 : *r_length = length;
243 2 : return buffer;
244 : }
245 :
246 :
247 : static gcry_mpi_t
248 2 : hex2mpiopa (const char *string)
249 : {
250 : char *buffer;
251 : size_t buflen;
252 : gcry_mpi_t val;
253 :
254 2 : buffer = hex2buffer (string, &buflen);
255 2 : if (!buffer)
256 0 : die ("hex2mpiopa '%s' failed: parser error\n", string);
257 2 : val = gcry_mpi_set_opaque (NULL, buffer, buflen*8);
258 2 : if (!buffer)
259 0 : die ("hex2mpiopa '%s' failed: set_opaque error\n", string);
260 2 : return val;
261 : }
262 :
263 :
264 : /* Compare A to B, where B is given as a hex string. */
265 : static int
266 86 : cmp_mpihex (gcry_mpi_t a, const char *b)
267 : {
268 : gcry_mpi_t bval;
269 : int res;
270 :
271 86 : if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
272 1 : bval = hex2mpiopa (b);
273 : else
274 85 : bval = hex2mpi (b);
275 86 : res = gcry_mpi_cmp (a, bval);
276 86 : gcry_mpi_release (bval);
277 86 : return res;
278 : }
279 :
280 :
281 : /* Wrapper to emulate the libgcrypt internal EC context allocation
282 : function. */
283 : static gpg_error_t
284 4 : ec_p_new (gcry_ctx_t *r_ctx, gcry_mpi_t p, gcry_mpi_t a)
285 : {
286 : gpg_error_t err;
287 : gcry_sexp_t sexp;
288 :
289 4 : if (p && a)
290 2 : err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m)(a %m))", p, a);
291 2 : else if (p)
292 0 : err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m))", p);
293 2 : else if (a)
294 1 : err = gcry_sexp_build (&sexp, NULL, "(ecdsa (a %m))", a);
295 : else
296 1 : err = gcry_sexp_build (&sexp, NULL, "(ecdsa)");
297 4 : if (err)
298 0 : return err;
299 4 : err = gcry_mpi_ec_new (r_ctx, sexp, NULL);
300 4 : gcry_sexp_release (sexp);
301 4 : return err;
302 : }
303 :
304 :
305 :
306 : static void
307 1 : set_get_point (void)
308 : {
309 : gcry_mpi_point_t point;
310 : gcry_mpi_t x, y, z;
311 :
312 1 : wherestr = "set_get_point";
313 1 : info ("checking point setting functions\n");
314 :
315 1 : point = gcry_mpi_point_new (0);
316 1 : x = gcry_mpi_set_ui (NULL, 17);
317 1 : y = gcry_mpi_set_ui (NULL, 42);
318 1 : z = gcry_mpi_set_ui (NULL, 11371);
319 1 : gcry_mpi_point_get (x, y, z, point);
320 1 : if (gcry_mpi_cmp_ui (x, 0)
321 1 : || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0))
322 0 : fail ("new point not initialized to (0,0,0)\n");
323 1 : gcry_mpi_point_snatch_get (x, y, z, point);
324 1 : point = NULL;
325 1 : if (gcry_mpi_cmp_ui (x, 0)
326 1 : || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0))
327 0 : fail ("snatch_get failed\n");
328 1 : gcry_mpi_release (x);
329 1 : gcry_mpi_release (y);
330 1 : gcry_mpi_release (z);
331 :
332 1 : point = gcry_mpi_point_new (0);
333 1 : x = gcry_mpi_set_ui (NULL, 17);
334 1 : y = gcry_mpi_set_ui (NULL, 42);
335 1 : z = gcry_mpi_set_ui (NULL, 11371);
336 1 : gcry_mpi_point_set (point, x, y, z);
337 1 : gcry_mpi_set_ui (x, 23);
338 1 : gcry_mpi_set_ui (y, 24);
339 1 : gcry_mpi_set_ui (z, 25);
340 1 : gcry_mpi_point_get (x, y, z, point);
341 1 : if (gcry_mpi_cmp_ui (x, 17)
342 1 : || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371))
343 0 : fail ("point_set/point_get failed\n");
344 1 : gcry_mpi_point_snatch_set (point, x, y, z);
345 1 : x = gcry_mpi_new (0);
346 1 : y = gcry_mpi_new (0);
347 1 : z = gcry_mpi_new (0);
348 1 : gcry_mpi_point_get (x, y, z, point);
349 1 : if (gcry_mpi_cmp_ui (x, 17)
350 1 : || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371))
351 0 : fail ("point_snatch_set/point_get failed\n");
352 :
353 1 : gcry_mpi_point_release (point);
354 1 : gcry_mpi_release (x);
355 1 : gcry_mpi_release (y);
356 1 : gcry_mpi_release (z);
357 1 : }
358 :
359 :
360 : static void
361 1 : context_alloc (void)
362 : {
363 : gpg_error_t err;
364 : gcry_ctx_t ctx;
365 : gcry_mpi_t p, a;
366 :
367 1 : wherestr = "context_alloc";
368 1 : info ("checking context functions\n");
369 :
370 1 : p = gcry_mpi_set_ui (NULL, 1);
371 1 : a = gcry_mpi_set_ui (NULL, 1);
372 1 : err = ec_p_new (&ctx, p, a);
373 1 : if (err)
374 0 : die ("ec_p_new returned an error: %s\n", gpg_strerror (err));
375 1 : gcry_mpi_release (p);
376 1 : gcry_mpi_release (a);
377 1 : gcry_ctx_release (ctx);
378 :
379 1 : p = NULL;
380 1 : a = gcry_mpi_set_ui (NULL, 0);
381 :
382 1 : err = ec_p_new (&ctx, p, a);
383 1 : if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
384 0 : fail ("ec_p_new: bad parameter detection failed (1)\n");
385 :
386 1 : gcry_mpi_release (a);
387 1 : a = NULL;
388 1 : err = ec_p_new (&ctx, p, a);
389 1 : if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
390 0 : fail ("ec_p_new: bad parameter detection failed (2)\n");
391 :
392 1 : }
393 :
394 :
395 : static int
396 48 : get_and_cmp_mpi (const char *name, const char *mpistring, const char *desc,
397 : gcry_ctx_t ctx)
398 : {
399 : gcry_mpi_t mpi;
400 :
401 48 : mpi = gcry_mpi_ec_get_mpi (name, ctx, 1);
402 48 : if (!mpi)
403 : {
404 0 : fail ("error getting parameter '%s' of curve '%s'\n", name, desc);
405 0 : return 1;
406 : }
407 48 : if (debug)
408 0 : print_mpi (name, mpi);
409 48 : if (cmp_mpihex (mpi, mpistring))
410 : {
411 0 : fail ("parameter '%s' of curve '%s' does not match\n", name, desc);
412 0 : gcry_mpi_release (mpi);
413 0 : return 1;
414 : }
415 48 : gcry_mpi_release (mpi);
416 48 : return 0;
417 : }
418 :
419 :
420 : static int
421 8 : get_and_cmp_point (const char *name,
422 : const char *mpi_x_string, const char *mpi_y_string,
423 : const char *desc, gcry_ctx_t ctx)
424 : {
425 : gcry_mpi_point_t point;
426 : gcry_mpi_t x, y, z;
427 8 : int result = 0;
428 :
429 8 : point = gcry_mpi_ec_get_point (name, ctx, 1);
430 8 : if (!point)
431 : {
432 0 : fail ("error getting point parameter '%s' of curve '%s'\n", name, desc);
433 0 : return 1;
434 : }
435 8 : if (debug)
436 0 : print_point (name, point);
437 :
438 8 : x = gcry_mpi_new (0);
439 8 : y = gcry_mpi_new (0);
440 8 : z = gcry_mpi_new (0);
441 8 : gcry_mpi_point_snatch_get (x, y, z, point);
442 8 : if (cmp_mpihex (x, mpi_x_string))
443 : {
444 0 : fail ("x coordinate of '%s' of curve '%s' does not match\n", name, desc);
445 0 : result = 1;
446 : }
447 8 : if (cmp_mpihex (y, mpi_y_string))
448 : {
449 0 : fail ("y coordinate of '%s' of curve '%s' does not match\n", name, desc);
450 0 : result = 1;
451 : }
452 8 : if (cmp_mpihex (z, "01"))
453 : {
454 0 : fail ("z coordinate of '%s' of curve '%s' is not 1\n", name, desc);
455 0 : result = 1;
456 : }
457 8 : gcry_mpi_release (x);
458 8 : gcry_mpi_release (y);
459 8 : gcry_mpi_release (z);
460 8 : return result;
461 : }
462 :
463 :
464 : static void
465 1 : context_param (void)
466 : {
467 : gpg_error_t err;
468 : int idx;
469 1 : gcry_ctx_t ctx = NULL;
470 : gcry_mpi_t q, d;
471 : gcry_sexp_t keyparam;
472 :
473 1 : wherestr = "context_param";
474 :
475 1 : info ("checking standard curves\n");
476 7 : for (idx=0; test_curve[idx].desc; idx++)
477 : {
478 : /* P-192 and Ed25519 are not supported in fips mode */
479 6 : if (gcry_fips_mode_active())
480 : {
481 0 : if (!strcmp(test_curve[idx].desc, "NIST P-192")
482 0 : || !strcmp(test_curve[idx].desc, "Ed25519"))
483 : {
484 0 : info ("skipping %s in fips mode\n", test_curve[idx].desc );
485 0 : continue;
486 : }
487 : }
488 :
489 6 : gcry_ctx_release (ctx);
490 6 : err = gcry_mpi_ec_new (&ctx, NULL, test_curve[idx].desc);
491 6 : if (err)
492 : {
493 0 : fail ("can't create context for curve '%s': %s\n",
494 : test_curve[idx].desc, gpg_strerror (err));
495 0 : continue;
496 : }
497 6 : if (get_and_cmp_mpi ("p", test_curve[idx].p, test_curve[idx].desc, ctx))
498 0 : continue;
499 6 : if (get_and_cmp_mpi ("a", test_curve[idx].a, test_curve[idx].desc, ctx))
500 0 : continue;
501 6 : if (get_and_cmp_mpi ("b", test_curve[idx].b, test_curve[idx].desc, ctx))
502 0 : continue;
503 6 : if (get_and_cmp_mpi ("g.x",test_curve[idx].g_x, test_curve[idx].desc,ctx))
504 0 : continue;
505 6 : if (get_and_cmp_mpi ("g.y",test_curve[idx].g_y, test_curve[idx].desc,ctx))
506 0 : continue;
507 6 : if (get_and_cmp_mpi ("n", test_curve[idx].n, test_curve[idx].desc, ctx))
508 0 : continue;
509 6 : if (get_and_cmp_point ("g", test_curve[idx].g_x, test_curve[idx].g_y,
510 : test_curve[idx].desc, ctx))
511 0 : continue;
512 6 : if (get_and_cmp_mpi ("h", test_curve[idx].h, test_curve[idx].desc, ctx))
513 0 : continue;
514 :
515 : }
516 :
517 1 : info ("checking sample public key (nistp256)\n");
518 1 : q = hex2mpi (sample_p256_q);
519 1 : err = gcry_sexp_build (&keyparam, NULL,
520 : "(public-key(ecc(curve %s)(q %m)))",
521 : "NIST P-256", q);
522 1 : if (err)
523 0 : die ("gcry_sexp_build failed: %s\n", gpg_strerror (err));
524 1 : gcry_mpi_release (q);
525 :
526 : /* We can't call gcry_pk_testkey because it is only implemented for
527 : private keys. */
528 : /* err = gcry_pk_testkey (keyparam); */
529 : /* if (err) */
530 : /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */
531 : /* gpg_strerror (err)); */
532 :
533 1 : gcry_ctx_release (ctx);
534 1 : err = gcry_mpi_ec_new (&ctx, keyparam, NULL);
535 1 : if (err)
536 0 : fail ("gcry_mpi_ec_new failed for sample public key (nistp256): %s\n",
537 : gpg_strerror (err));
538 : else
539 : {
540 : gcry_sexp_t sexp;
541 :
542 1 : get_and_cmp_mpi ("q", sample_p256_q, "nistp256", ctx);
543 1 : get_and_cmp_point ("q", sample_p256_q_x, sample_p256_q_y, "nistp256",
544 : ctx);
545 :
546 : /* Delete Q. */
547 1 : err = gcry_mpi_ec_set_mpi ("q", NULL, ctx);
548 1 : if (err)
549 0 : fail ("clearing Q for nistp256 failed: %s\n", gpg_strerror (err));
550 1 : if (gcry_mpi_ec_get_mpi ("q", ctx, 0))
551 0 : fail ("clearing Q for nistp256 did not work\n");
552 :
553 : /* Set Q again. */
554 1 : q = hex2mpi (sample_p256_q);
555 1 : err = gcry_mpi_ec_set_mpi ("q", q, ctx);
556 1 : if (err)
557 0 : fail ("setting Q for nistp256 failed: %s\n", gpg_strerror (err));
558 1 : get_and_cmp_mpi ("q", sample_p256_q, "nistp256(2)", ctx);
559 1 : gcry_mpi_release (q);
560 :
561 : /* Get as s-expression. */
562 1 : err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
563 1 : if (err)
564 0 : fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err));
565 1 : else if (debug)
566 0 : print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp);
567 1 : gcry_sexp_release (sexp);
568 :
569 1 : err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx);
570 1 : if (err)
571 0 : fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n",
572 : gpg_strerror (err));
573 1 : else if (debug)
574 0 : print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp);
575 1 : gcry_sexp_release (sexp);
576 :
577 1 : err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx);
578 1 : if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
579 0 : fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n",
580 : gpg_strerror (err));
581 1 : gcry_sexp_release (sexp);
582 : }
583 :
584 : /* Skipping Ed25519 if in FIPS mode (it isn't supported) */
585 1 : if (gcry_fips_mode_active())
586 0 : goto cleanup;
587 :
588 1 : info ("checking sample public key (Ed25519)\n");
589 1 : q = hex2mpi (sample_ed25519_q);
590 1 : gcry_sexp_release (keyparam);
591 1 : err = gcry_sexp_build (&keyparam, NULL,
592 : "(public-key(ecc(curve %s)(flags eddsa)(q %m)))",
593 : "Ed25519", q);
594 1 : if (err)
595 0 : die ("gcry_sexp_build failed: %s\n", gpg_strerror (err));
596 1 : gcry_mpi_release (q);
597 :
598 : /* We can't call gcry_pk_testkey because it is only implemented for
599 : private keys. */
600 : /* err = gcry_pk_testkey (keyparam); */
601 : /* if (err) */
602 : /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */
603 : /* gpg_strerror (err)); */
604 :
605 1 : gcry_ctx_release (ctx);
606 1 : err = gcry_mpi_ec_new (&ctx, keyparam, NULL);
607 1 : if (err)
608 0 : fail ("gcry_mpi_ec_new failed for sample public key: %s\n",
609 : gpg_strerror (err));
610 : else
611 : {
612 : gcry_sexp_t sexp;
613 :
614 1 : get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519", ctx);
615 1 : get_and_cmp_point ("q", sample_ed25519_q_x, sample_ed25519_q_y,
616 : "Ed25519", ctx);
617 1 : get_and_cmp_mpi ("q@eddsa", sample_ed25519_q_eddsa, "Ed25519", ctx);
618 :
619 : /* Set d to see whether Q is correctly re-computed. */
620 1 : d = hex2mpi (sample_ed25519_d);
621 1 : err = gcry_mpi_ec_set_mpi ("d", d, ctx);
622 1 : if (err)
623 0 : fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err));
624 1 : gcry_mpi_release (d);
625 1 : get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(recompute Q)", ctx);
626 :
627 : /* Delete Q by setting d and then clearing d. The clearing is
628 : required so that we can check whether Q has been cleared and
629 : because further tests only expect a public key. */
630 1 : d = hex2mpi (sample_ed25519_d);
631 1 : err = gcry_mpi_ec_set_mpi ("d", d, ctx);
632 1 : if (err)
633 0 : fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err));
634 1 : gcry_mpi_release (d);
635 1 : err = gcry_mpi_ec_set_mpi ("d", NULL, ctx);
636 1 : if (err)
637 0 : fail ("setting d for Ed25519 failed(2): %s\n", gpg_strerror (err));
638 1 : if (gcry_mpi_ec_get_mpi ("q", ctx, 0))
639 0 : fail ("setting d for Ed25519 did not reset Q\n");
640 :
641 : /* Set Q again. We need to use an opaque MPI here because
642 : sample_ed25519_q is in uncompressed format which can only be
643 : auto-detected if passed opaque. */
644 1 : q = hex2mpiopa (sample_ed25519_q);
645 1 : err = gcry_mpi_ec_set_mpi ("q", q, ctx);
646 1 : if (err)
647 0 : fail ("setting Q for Ed25519 failed: %s\n", gpg_strerror (err));
648 1 : gcry_mpi_release (q);
649 1 : get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(2)", ctx);
650 :
651 : /* Get as s-expression. */
652 1 : err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
653 1 : if (err)
654 0 : fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err));
655 1 : else if (debug)
656 0 : print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp);
657 1 : gcry_sexp_release (sexp);
658 :
659 1 : err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx);
660 1 : if (err)
661 0 : fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n",
662 : gpg_strerror (err));
663 1 : else if (debug)
664 0 : print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp);
665 1 : gcry_sexp_release (sexp);
666 :
667 1 : err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx);
668 1 : if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
669 0 : fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n",
670 : gpg_strerror (err));
671 1 : gcry_sexp_release (sexp);
672 :
673 : }
674 :
675 : cleanup:
676 1 : gcry_ctx_release (ctx);
677 1 : gcry_sexp_release (keyparam);
678 1 : }
679 :
680 :
681 :
682 :
683 : /* Create a new point from (X,Y,Z) given as hex strings. */
684 : gcry_mpi_point_t
685 1 : make_point (const char *x, const char *y, const char *z)
686 : {
687 : gcry_mpi_point_t point;
688 :
689 1 : point = gcry_mpi_point_new (0);
690 1 : gcry_mpi_point_snatch_set (point, hex2mpi (x), hex2mpi (y), hex2mpi (z));
691 :
692 1 : return point;
693 : }
694 :
695 :
696 : /* This tests checks that the low-level EC API yields the same result
697 : as using the high level API. The values have been taken from a
698 : test run using the high level API. */
699 : static void
700 1 : basic_ec_math (void)
701 : {
702 : gpg_error_t err;
703 : gcry_ctx_t ctx;
704 : gcry_mpi_t P, A;
705 : gcry_mpi_point_t G, Q;
706 : gcry_mpi_t d;
707 : gcry_mpi_t x, y, z;
708 :
709 1 : wherestr = "basic_ec_math";
710 1 : info ("checking basic math functions for EC\n");
711 :
712 1 : P = hex2mpi ("0xfffffffffffffffffffffffffffffffeffffffffffffffff");
713 1 : A = hex2mpi ("0xfffffffffffffffffffffffffffffffefffffffffffffffc");
714 1 : G = make_point ("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
715 : "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
716 : "1");
717 1 : d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D");
718 1 : Q = gcry_mpi_point_new (0);
719 :
720 1 : err = ec_p_new (&ctx, P, A);
721 1 : if (err)
722 0 : die ("ec_p_new failed: %s\n", gpg_strerror (err));
723 :
724 1 : x = gcry_mpi_new (0);
725 1 : y = gcry_mpi_new (0);
726 1 : z = gcry_mpi_new (0);
727 :
728 : {
729 : /* A quick check that multiply by zero works. */
730 : gcry_mpi_t tmp;
731 :
732 1 : tmp = gcry_mpi_new (0);
733 1 : gcry_mpi_ec_mul (Q, tmp, G, ctx);
734 1 : gcry_mpi_release (tmp);
735 1 : gcry_mpi_point_get (x, y, z, Q);
736 1 : if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 0)
737 1 : || gcry_mpi_cmp_ui (z, 0))
738 0 : fail ("multiply a point by zero failed\n");
739 : }
740 :
741 1 : gcry_mpi_ec_mul (Q, d, G, ctx);
742 1 : gcry_mpi_point_get (x, y, z, Q);
743 1 : if (cmp_mpihex (x, "222D9EC717C89D047E0898C9185B033CD11C0A981EE6DC66")
744 1 : || cmp_mpihex (y, "605DE0A82D70D3E0F84A127D0739ED33D657DF0D054BFDE8")
745 1 : || cmp_mpihex (z, "00B06B519071BC536999AC8F2D3934B3C1FC9EACCD0A31F88F"))
746 0 : fail ("computed public key does not match\n");
747 1 : if (debug)
748 : {
749 0 : print_mpi ("Q.x", x);
750 0 : print_mpi ("Q.y", y);
751 0 : print_mpi ("Q.z", z);
752 : }
753 :
754 1 : if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
755 0 : fail ("failed to get affine coordinates\n");
756 1 : if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE")
757 1 : || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966"))
758 0 : fail ("computed affine coordinates of public key do not match\n");
759 1 : if (debug)
760 : {
761 0 : print_mpi ("q.x", x);
762 0 : print_mpi ("q.y", y);
763 : }
764 :
765 1 : gcry_mpi_release (z);
766 1 : gcry_mpi_release (y);
767 1 : gcry_mpi_release (x);
768 1 : gcry_mpi_point_release (Q);
769 1 : gcry_mpi_release (d);
770 1 : gcry_mpi_point_release (G);
771 1 : gcry_mpi_release (A);
772 1 : gcry_mpi_release (P);
773 1 : gcry_ctx_release (ctx);
774 1 : }
775 :
776 :
777 : /* This is the same as basic_ec_math but uses more advanced
778 : features. */
779 : static void
780 1 : basic_ec_math_simplified (void)
781 : {
782 : gpg_error_t err;
783 : gcry_ctx_t ctx;
784 : gcry_mpi_point_t G, Q;
785 : gcry_mpi_t d;
786 : gcry_mpi_t x, y, z;
787 : gcry_sexp_t sexp;
788 :
789 1 : wherestr = "basic_ec_math_simplified";
790 1 : info ("checking basic math functions for EC (variant)\n");
791 :
792 1 : d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D");
793 1 : Q = gcry_mpi_point_new (0);
794 :
795 1 : err = gcry_mpi_ec_new (&ctx, NULL, "NIST P-192");
796 1 : if (err)
797 0 : die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err));
798 1 : G = gcry_mpi_ec_get_point ("g", ctx, 1);
799 1 : if (!G)
800 0 : die ("gcry_mpi_ec_get_point(G) failed\n");
801 1 : gcry_mpi_ec_mul (Q, d, G, ctx);
802 :
803 1 : x = gcry_mpi_new (0);
804 1 : y = gcry_mpi_new (0);
805 1 : z = gcry_mpi_new (0);
806 1 : gcry_mpi_point_get (x, y, z, Q);
807 1 : if (cmp_mpihex (x, "222D9EC717C89D047E0898C9185B033CD11C0A981EE6DC66")
808 1 : || cmp_mpihex (y, "605DE0A82D70D3E0F84A127D0739ED33D657DF0D054BFDE8")
809 1 : || cmp_mpihex (z, "00B06B519071BC536999AC8F2D3934B3C1FC9EACCD0A31F88F"))
810 0 : fail ("computed public key does not match\n");
811 1 : if (debug)
812 : {
813 0 : print_mpi ("Q.x", x);
814 0 : print_mpi ("Q.y", y);
815 0 : print_mpi ("Q.z", z);
816 : }
817 :
818 1 : if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
819 0 : fail ("failed to get affine coordinates\n");
820 1 : if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE")
821 1 : || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966"))
822 0 : fail ("computed affine coordinates of public key do not match\n");
823 1 : if (debug)
824 : {
825 0 : print_mpi ("q.x", x);
826 0 : print_mpi ("q.y", y);
827 : }
828 :
829 1 : gcry_mpi_release (z);
830 1 : gcry_mpi_release (y);
831 1 : gcry_mpi_release (x);
832 :
833 : /* Let us also check whether we can update the context. */
834 1 : err = gcry_mpi_ec_set_point ("g", G, ctx);
835 1 : if (err)
836 0 : die ("gcry_mpi_ec_set_point(G) failed\n");
837 1 : err = gcry_mpi_ec_set_mpi ("d", d, ctx);
838 1 : if (err)
839 0 : die ("gcry_mpi_ec_set_mpi(d) failed\n");
840 :
841 : /* FIXME: Below we need to check that the returned S-expression is
842 : as requested. For now we use manual inspection using --debug. */
843 :
844 : /* Does get_sexp return the private key? */
845 1 : err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
846 1 : if (err)
847 0 : fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err));
848 1 : else if (debug)
849 0 : print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp);
850 1 : gcry_sexp_release (sexp);
851 :
852 : /* Does get_sexp return the public key if requested? */
853 1 : err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx);
854 1 : if (err)
855 0 : fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", gpg_strerror (err));
856 1 : else if (debug)
857 0 : print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp);
858 1 : gcry_sexp_release (sexp);
859 :
860 : /* Does get_sexp return the public key after d has been deleted? */
861 1 : err = gcry_mpi_ec_set_mpi ("d", NULL, ctx);
862 1 : if (err)
863 0 : die ("gcry_mpi_ec_set_mpi(d=NULL) failed\n");
864 1 : err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
865 1 : if (err)
866 0 : fail ("gcry_pubkey_get_sexp(0 w/o d) failed: %s\n", gpg_strerror (err));
867 1 : else if (debug)
868 0 : print_sexp ("Result of gcry_pubkey_get_sexp (0 w/o d):\n", sexp);
869 1 : gcry_sexp_release (sexp);
870 :
871 : /* Does get_sexp return an error after d has been deleted? */
872 1 : err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx);
873 1 : if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
874 0 : fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n",
875 : gpg_strerror (err));
876 1 : gcry_sexp_release (sexp);
877 :
878 : /* Does get_sexp return an error after d and Q have been deleted? */
879 1 : err = gcry_mpi_ec_set_point ("q", NULL, ctx);
880 1 : if (err)
881 0 : die ("gcry_mpi_ec_set_point(q=NULL) failed\n");
882 1 : err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
883 1 : if (gpg_err_code (err) != GPG_ERR_BAD_CRYPT_CTX)
884 0 : fail ("gcry_pubkey_get_sexp(0 w/o Q,d) returned wrong error: %s\n",
885 : gpg_strerror (err));
886 1 : gcry_sexp_release (sexp);
887 :
888 :
889 1 : gcry_mpi_point_release (Q);
890 1 : gcry_mpi_release (d);
891 1 : gcry_mpi_point_release (G);
892 1 : gcry_ctx_release (ctx);
893 1 : }
894 :
895 :
896 : /* Check the math used with Twisted Edwards curves. */
897 : static void
898 1 : twistededwards_math (void)
899 : {
900 : gpg_error_t err;
901 : gcry_ctx_t ctx;
902 : gcry_mpi_point_t G, Q;
903 : gcry_mpi_t k;
904 : gcry_mpi_t w, a, x, y, z, p, n, b, I;
905 :
906 1 : wherestr = "twistededwards_math";
907 1 : info ("checking basic Twisted Edwards math\n");
908 :
909 1 : err = gcry_mpi_ec_new (&ctx, NULL, "Ed25519");
910 1 : if (err)
911 0 : die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err));
912 :
913 1 : k = hex2mpi
914 : ("2D3501E723239632802454EE5DDC406EFB0BDF18486A5BDE9C0390A9C2984004"
915 : "F47252B628C953625B8DEB5DBCB8DA97AA43A1892D11FA83596F42E0D89CB1B6");
916 1 : G = gcry_mpi_ec_get_point ("g", ctx, 1);
917 1 : if (!G)
918 0 : die ("gcry_mpi_ec_get_point(G) failed\n");
919 1 : Q = gcry_mpi_point_new (0);
920 :
921 :
922 1 : w = gcry_mpi_new (0);
923 1 : a = gcry_mpi_new (0);
924 1 : x = gcry_mpi_new (0);
925 1 : y = gcry_mpi_new (0);
926 1 : z = gcry_mpi_new (0);
927 1 : I = gcry_mpi_new (0);
928 1 : p = gcry_mpi_ec_get_mpi ("p", ctx, 1);
929 1 : n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
930 1 : b = gcry_mpi_ec_get_mpi ("b", ctx, 1);
931 :
932 : /* Check: 2^{p-1} mod p == 1 */
933 1 : gcry_mpi_sub_ui (a, p, 1);
934 1 : gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, p);
935 1 : if (gcry_mpi_cmp_ui (w, 1))
936 0 : fail ("failed assertion: 2^{p-1} mod p == 1\n");
937 :
938 : /* Check: p % 4 == 1 */
939 1 : gcry_mpi_mod (w, p, GCRYMPI_CONST_FOUR);
940 1 : if (gcry_mpi_cmp_ui (w, 1))
941 0 : fail ("failed assertion: p %% 4 == 1\n");
942 :
943 : /* Check: 2^{n-1} mod n == 1 */
944 1 : gcry_mpi_sub_ui (a, n, 1);
945 1 : gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, n);
946 1 : if (gcry_mpi_cmp_ui (w, 1))
947 0 : fail ("failed assertion: 2^{n-1} mod n == 1\n");
948 :
949 : /* Check: b^{(p-1)/2} mod p == p-1 */
950 1 : gcry_mpi_sub_ui (a, p, 1);
951 1 : gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_TWO, -1);
952 1 : gcry_mpi_powm (w, b, x, p);
953 1 : gcry_mpi_abs (w);
954 1 : if (gcry_mpi_cmp (w, a))
955 0 : fail ("failed assertion: b^{(p-1)/2} mod p == p-1\n");
956 :
957 : /* I := 2^{(p-1)/4} mod p */
958 1 : gcry_mpi_sub_ui (a, p, 1);
959 1 : gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_FOUR, -1);
960 1 : gcry_mpi_powm (I, GCRYMPI_CONST_TWO, x, p);
961 :
962 : /* Check: I^2 mod p == p-1 */
963 1 : gcry_mpi_powm (w, I, GCRYMPI_CONST_TWO, p);
964 1 : if (gcry_mpi_cmp (w, a))
965 0 : fail ("failed assertion: I^2 mod p == p-1\n");
966 :
967 : /* Check: G is on the curve */
968 1 : if (!gcry_mpi_ec_curve_point (G, ctx))
969 0 : fail ("failed assertion: G is on the curve\n");
970 :
971 : /* Check: nG == (0,1) */
972 1 : gcry_mpi_ec_mul (Q, n, G, ctx);
973 1 : if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
974 0 : fail ("failed to get affine coordinates\n");
975 1 : if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 1))
976 0 : fail ("failed assertion: nG == (0,1)\n");
977 :
978 : /* Now two arbitrary point operations taken from the ed25519.py
979 : sample data. */
980 1 : gcry_mpi_release (a);
981 1 : a = hex2mpi
982 : ("4f71d012df3c371af3ea4dc38385ca5bb7272f90cb1b008b3ed601c76de1d496"
983 : "e30cbf625f0a756a678d8f256d5325595cccc83466f36db18f0178eb9925edd3");
984 1 : gcry_mpi_ec_mul (Q, a, G, ctx);
985 1 : if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
986 0 : fail ("failed to get affine coordinates\n");
987 1 : if (cmp_mpihex (x, ("157f7361c577aad36f67ed33e38dc7be"
988 : "00014fecc2165ca5cee9eee19fe4d2c1"))
989 1 : || cmp_mpihex (y, ("5a69dbeb232276b38f3f5016547bb2a2"
990 : "4025645f0b820e72b8cad4f0a909a092")))
991 : {
992 0 : fail ("sample point multiply failed:\n");
993 0 : print_mpi ("r", a);
994 0 : print_mpi ("Rx", x);
995 0 : print_mpi ("Ry", y);
996 : }
997 :
998 1 : gcry_mpi_release (a);
999 1 : a = hex2mpi
1000 : ("2d3501e723239632802454ee5ddc406efb0bdf18486a5bde9c0390a9c2984004"
1001 : "f47252b628c953625b8deb5dbcb8da97aa43a1892d11fa83596f42e0d89cb1b6");
1002 1 : gcry_mpi_ec_mul (Q, a, G, ctx);
1003 1 : if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
1004 0 : fail ("failed to get affine coordinates\n");
1005 1 : if (cmp_mpihex (x, ("6218e309d40065fcc338b3127f468371"
1006 : "82324bd01ce6f3cf81ab44e62959c82a"))
1007 1 : || cmp_mpihex (y, ("5501492265e073d874d9e5b81e7f8784"
1008 : "8a826e80cce2869072ac60c3004356e5")))
1009 : {
1010 0 : fail ("sample point multiply failed:\n");
1011 0 : print_mpi ("r", a);
1012 0 : print_mpi ("Rx", x);
1013 0 : print_mpi ("Ry", y);
1014 : }
1015 :
1016 :
1017 1 : gcry_mpi_release (I);
1018 1 : gcry_mpi_release (b);
1019 1 : gcry_mpi_release (n);
1020 1 : gcry_mpi_release (p);
1021 1 : gcry_mpi_release (w);
1022 1 : gcry_mpi_release (a);
1023 1 : gcry_mpi_release (x);
1024 1 : gcry_mpi_release (y);
1025 1 : gcry_mpi_release (z);
1026 1 : gcry_mpi_point_release (Q);
1027 1 : gcry_mpi_point_release (G);
1028 1 : gcry_mpi_release (k);
1029 1 : gcry_ctx_release (ctx);
1030 1 : }
1031 :
1032 :
1033 : int
1034 1 : main (int argc, char **argv)
1035 : {
1036 :
1037 1 : if (argc > 1 && !strcmp (argv[1], "--verbose"))
1038 0 : verbose = 1;
1039 1 : else if (argc > 1 && !strcmp (argv[1], "--debug"))
1040 0 : verbose = debug = 1;
1041 :
1042 1 : if (!gcry_check_version (GCRYPT_VERSION))
1043 0 : die ("version mismatch\n");
1044 :
1045 1 : xgcry_control (GCRYCTL_DISABLE_SECMEM, 0);
1046 1 : xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1047 1 : if (debug)
1048 0 : xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
1049 1 : xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
1050 :
1051 1 : set_get_point ();
1052 1 : context_alloc ();
1053 1 : context_param ();
1054 1 : basic_ec_math ();
1055 :
1056 : /* The tests are for P-192 and ed25519 which are not supported in
1057 : FIPS mode. */
1058 1 : if (!gcry_fips_mode_active())
1059 : {
1060 1 : basic_ec_math_simplified ();
1061 1 : twistededwards_math ();
1062 : }
1063 :
1064 1 : info ("All tests completed. Errors: %d\n", error_count);
1065 1 : return error_count ? 1 : 0;
1066 : }
|