pk: Add algo id GCRY_PK_ECC and deprecate ECDSA and ECDH.
[libgcrypt.git] / cipher / ecc.c
1 /* ecc.c  -  Elliptic Curve Cryptography
2  * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
3  * Copyright (C) 2013 g10 Code GmbH
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 /* This code is originally based on the Patch 0.1.6 for the gnupg
22    1.4.x branch as retrieved on 2007-03-21 from
23    http://www.calcurco.cat/eccGnuPG/src/gnupg-1.4.6-ecc0.2.0beta1.diff.bz2
24    The original authors are:
25      Written by
26       Sergi Blanch i Torne <d4372211 at alumnes.eup.udl.es>,
27       Ramiro Moreno Chiral <ramiro at eup.udl.es>
28      Maintainers
29       Sergi Blanch i Torne
30       Ramiro Moreno Chiral
31       Mikael Mylnikov (mmr)
32   For use in Libgcrypt the code has been heavily modified and cleaned
33   up. In fact there is not much left of the orginally code except for
34   some variable names and the text book implementaion of the sign and
35   verification algorithms.  The arithmetic functions have entirely
36   been rewritten and moved to mpi/ec.c.
37
38   ECDH encrypt and decrypt code written by Andrey Jivsov,
39 */
40
41
42 /* TODO:
43
44   - If we support point compression we need to uncompress before
45     computing the keygrip
46
47   - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a
48     special case in mpi_powm or check whether mpi_mulm is faster.
49
50 */
51
52
53 #include <config.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <errno.h>
58
59 #include "g10lib.h"
60 #include "mpi.h"
61 #include "cipher.h"
62 #include "context.h"
63 #include "ec-context.h"
64 #include "pubkey-internal.h"
65 #include "ecc-common.h"
66
67
68 /* Registered progress function and its callback value. */
69 static void (*progress_cb) (void *, const char*, int, int, int);
70 static void *progress_cb_data;
71
72
73 #define point_init(a)  _gcry_mpi_point_init ((a))
74 #define point_free(a)  _gcry_mpi_point_free_parts ((a))
75
76 \f
77 /* Local prototypes. */
78 static void test_keys (ECC_secret_key * sk, unsigned int nbits);
79 static int check_secret_key (ECC_secret_key * sk);
80 static gpg_err_code_t sign_ecdsa (gcry_mpi_t input, ECC_secret_key *skey,
81                                   gcry_mpi_t r, gcry_mpi_t s,
82                                   int flags, int hashalgo);
83 static gpg_err_code_t verify_ecdsa (gcry_mpi_t input, ECC_public_key *pkey,
84                                     gcry_mpi_t r, gcry_mpi_t s);
85
86 static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base);
87
88
89
90 \f
91 void
92 _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
93                                             int, int, int),
94                                 void *cb_data)
95 {
96   progress_cb = cb;
97   progress_cb_data = cb_data;
98 }
99
100 /* static void */
101 /* progress (int c) */
102 /* { */
103 /*   if (progress_cb) */
104 /*     progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */
105 /* } */
106
107
108 \f
109
110 /*
111  * Solve the right side of the Weierstrass equation.
112  */
113 static gcry_mpi_t
114 gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base)
115 {
116   gcry_mpi_t three, x_3, axb, y;
117
118   three = mpi_alloc_set_ui (3);
119   x_3 = mpi_new (0);
120   axb = mpi_new (0);
121   y   = mpi_new (0);
122
123   mpi_powm (x_3, x, three, base->p);
124   mpi_mulm (axb, base->a, x, base->p);
125   mpi_addm (axb, axb, base->b, base->p);
126   mpi_addm (y, x_3, axb, base->p);
127
128   mpi_free (x_3);
129   mpi_free (axb);
130   mpi_free (three);
131   return y; /* The quadratic value of the coordinate if it exist. */
132 }
133
134
135 /* Standard version of the key generation.  */
136 static gpg_err_code_t
137 nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
138                    gcry_random_level_t random_level, unsigned int nbits)
139 {
140   mpi_point_struct Q;
141
142   point_init (&Q);
143
144   /* Generate a secret.  */
145   sk->d = _gcry_dsa_gen_k (E->n, random_level);
146
147   /* Compute Q.  */
148   _gcry_mpi_ec_mul_point (&Q, sk->d, &E->G, ctx);
149
150   /* Copy the stuff to the key structures. */
151   sk->E.model = E->model;
152   sk->E.dialect = E->dialect;
153   sk->E.p = mpi_copy (E->p);
154   sk->E.a = mpi_copy (E->a);
155   sk->E.b = mpi_copy (E->b);
156   point_init (&sk->E.G);
157   point_set (&sk->E.G, &E->G);
158   sk->E.n = mpi_copy (E->n);
159   point_init (&sk->Q);
160
161   /* We want the Q=(x,y) be a "compliant key" in terms of the
162    * http://tools.ietf.org/html/draft-jivsov-ecc-compact, which simply
163    * means that we choose either Q=(x,y) or -Q=(x,p-y) such that we
164    * end up with the min(y,p-y) as the y coordinate.  Such a public
165    * key allows the most efficient compression: y can simply be
166    * dropped because we know that it's a minimum of the two
167    * possibilities without any loss of security.  */
168   {
169     gcry_mpi_t x, y, p_y;
170     const unsigned int pbits = mpi_get_nbits (E->p);
171
172     x = mpi_new (pbits);
173     y = mpi_new (pbits);
174     p_y = mpi_new (pbits);
175
176     if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
177       log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
178
179     mpi_sub (p_y, E->p, y);     /* p_y = p - y */
180
181     if (mpi_cmp (p_y, y) < 0)   /* p - y < p */
182       {
183         /* We need to end up with -Q; this assures that new Q's y is
184            the smallest one */
185         mpi_sub (sk->d, E->n, sk->d);   /* d = order - d */
186         gcry_mpi_point_snatch_set (&sk->Q, x, p_y, mpi_alloc_set_ui (1));
187
188       if (DBG_CIPHER)
189         log_debug ("ecgen converted Q to a compliant point\n");
190       }
191     else /* p - y >= p */
192       {
193         /* No change is needed exactly 50% of the time: just copy. */
194         point_set (&sk->Q, &Q);
195         if (DBG_CIPHER)
196           log_debug ("ecgen didn't need to convert Q to a compliant point\n");
197
198         mpi_free (p_y);
199         mpi_free (x);
200       }
201     mpi_free (y);
202   }
203
204   /* Now we can test our keys (this should never fail!).  */
205   test_keys (sk, nbits - 64);
206
207   return 0;
208 }
209
210
211 /*
212  * To verify correct skey it use a random information.
213  * First, encrypt and decrypt this dummy value,
214  * test if the information is recuperated.
215  * Second, test with the sign and verify functions.
216  */
217 static void
218 test_keys (ECC_secret_key *sk, unsigned int nbits)
219 {
220   ECC_public_key pk;
221   gcry_mpi_t test = mpi_new (nbits);
222   mpi_point_struct R_;
223   gcry_mpi_t c = mpi_new (nbits);
224   gcry_mpi_t out = mpi_new (nbits);
225   gcry_mpi_t r = mpi_new (nbits);
226   gcry_mpi_t s = mpi_new (nbits);
227
228   if (DBG_CIPHER)
229     log_debug ("Testing key.\n");
230
231   point_init (&R_);
232
233   pk.E = _gcry_ecc_curve_copy (sk->E);
234   point_init (&pk.Q);
235   point_set (&pk.Q, &sk->Q);
236
237   gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
238
239   if (sign_ecdsa (test, sk, r, s, 0, 0) )
240     log_fatal ("ECDSA operation: sign failed\n");
241
242   if (verify_ecdsa (test, &pk, r, s))
243     {
244       log_fatal ("ECDSA operation: sign, verify failed\n");
245     }
246
247   if (DBG_CIPHER)
248     log_debug ("ECDSA operation: sign, verify ok.\n");
249
250   point_free (&pk.Q);
251   _gcry_ecc_curve_free (&pk.E);
252
253   point_free (&R_);
254   mpi_free (s);
255   mpi_free (r);
256   mpi_free (out);
257   mpi_free (c);
258   mpi_free (test);
259 }
260
261
262 /*
263  * To check the validity of the value, recalculate the correspondence
264  * between the public value and the secret one.
265  */
266 static int
267 check_secret_key (ECC_secret_key * sk)
268 {
269   int rc = 1;
270   mpi_point_struct Q;
271   gcry_mpi_t y_2, y2;
272   gcry_mpi_t x1, x2;
273   mpi_ec_t ctx = NULL;
274
275   point_init (&Q);
276
277   /* ?primarity test of 'p' */
278   /*  (...) //!! */
279   /* G in E(F_p) */
280   y_2 = gen_y_2 (sk->E.G.x, &sk->E);   /*  y^2=x^3+a*x+b */
281   y2 = mpi_alloc (0);
282   x1 = mpi_alloc (0);
283   x2 = mpi_alloc (0);
284   mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p);      /*  y^2=y*y */
285   if (mpi_cmp (y_2, y2))
286     {
287       if (DBG_CIPHER)
288         log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
289       goto leave;
290     }
291   /* G != PaI */
292   if (!mpi_cmp_ui (sk->E.G.z, 0))
293     {
294       if (DBG_CIPHER)
295         log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
296       goto leave;
297     }
298
299   ctx = _gcry_mpi_ec_p_internal_new (sk->E.model, sk->E.dialect,
300                                      sk->E.p, sk->E.a, sk->E.b);
301
302   _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
303   if (mpi_cmp_ui (Q.z, 0))
304     {
305       if (DBG_CIPHER)
306         log_debug ("check_secret_key: E is not a curve of order n\n");
307       goto leave;
308     }
309   /* pubkey cannot be PaI */
310   if (!mpi_cmp_ui (sk->Q.z, 0))
311     {
312       if (DBG_CIPHER)
313         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
314       goto leave;
315     }
316   /* pubkey = [d]G over E */
317   _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx);
318
319   if (_gcry_mpi_ec_get_affine (x1, y_2, &Q, ctx))
320     {
321       if (DBG_CIPHER)
322         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
323       goto leave;
324     }
325
326   /* Fast path for loaded secret keys - Q is already in affine coordinates */
327   if (!mpi_cmp_ui (sk->Q.z, 1))
328     {
329       if (mpi_cmp (x1, sk->Q.x) || mpi_cmp (y_2, sk->Q.y))
330         {
331           if (DBG_CIPHER)
332             log_debug
333               ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
334           goto leave;
335         }
336     }
337   else
338     {
339       if (_gcry_mpi_ec_get_affine (x2, y2, &sk->Q, ctx))
340         {
341           if (DBG_CIPHER)
342             log_debug ("Bad check: Q can not be a Point at Infinity!\n");
343           goto leave;
344         }
345
346       if (mpi_cmp (x1, x2) || mpi_cmp (y_2, y2))
347         {
348           if (DBG_CIPHER)
349             log_debug
350               ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
351           goto leave;
352         }
353     }
354   rc = 0; /* Okay.  */
355
356  leave:
357   _gcry_mpi_ec_free (ctx);
358   mpi_free (x2);
359   mpi_free (x1);
360   mpi_free (y2);
361   mpi_free (y_2);
362   point_free (&Q);
363   return rc;
364 }
365
366
367 /* Compute an ECDSA signature.
368  * Return the signature struct (r,s) from the message hash.  The caller
369  * must have allocated R and S.
370  */
371 static gpg_err_code_t
372 sign_ecdsa (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s,
373             int flags, int hashalgo)
374 {
375   gpg_err_code_t err = 0;
376   int extraloops = 0;
377   gcry_mpi_t k, dr, sum, k_1, x;
378   mpi_point_struct I;
379   gcry_mpi_t hash;
380   const void *abuf;
381   unsigned int abits, qbits;
382   mpi_ec_t ctx;
383
384   if (DBG_CIPHER)
385     log_mpidump ("ecdsa sign hash  ", input );
386
387   qbits = mpi_get_nbits (skey->E.n);
388
389   /* Convert the INPUT into an MPI if needed.  */
390   if (mpi_is_opaque (input))
391     {
392       abuf = gcry_mpi_get_opaque (input, &abits);
393       err = gpg_err_code (gcry_mpi_scan (&hash, GCRYMPI_FMT_USG,
394                                          abuf, (abits+7)/8, NULL));
395       if (err)
396         return err;
397       if (abits > qbits)
398         gcry_mpi_rshift (hash, hash, abits - qbits);
399     }
400   else
401     hash = input;
402
403
404   k = NULL;
405   dr = mpi_alloc (0);
406   sum = mpi_alloc (0);
407   k_1 = mpi_alloc (0);
408   x = mpi_alloc (0);
409   point_init (&I);
410
411   mpi_set_ui (s, 0);
412   mpi_set_ui (r, 0);
413
414   ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
415                                      skey->E.p, skey->E.a, skey->E.b);
416
417   while (!mpi_cmp_ui (s, 0)) /* s == 0 */
418     {
419       while (!mpi_cmp_ui (r, 0)) /* r == 0 */
420         {
421           /* Note, that we are guaranteed to enter this loop at least
422              once because r has been intialized to 0.  We can't use a
423              do_while because we want to keep the value of R even if S
424              has to be recomputed.  */
425
426           mpi_free (k);
427           k = NULL;
428           if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
429             {
430               /* Use Pornin's method for deterministic DSA.  If this
431                  flag is set, it is expected that HASH is an opaque
432                  MPI with the to be signed hash.  That hash is also
433                  used as h1 from 3.2.a.  */
434               if (!mpi_is_opaque (input))
435                 {
436                   err = GPG_ERR_CONFLICT;
437                   goto leave;
438                 }
439
440               abuf = gcry_mpi_get_opaque (input, &abits);
441               err = _gcry_dsa_gen_rfc6979_k (&k, skey->E.n, skey->d,
442                                              abuf, (abits+7)/8,
443                                              hashalgo, extraloops);
444               if (err)
445                 goto leave;
446               extraloops++;
447             }
448           else
449             k = _gcry_dsa_gen_k (skey->E.n, GCRY_STRONG_RANDOM);
450
451           _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx);
452           if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
453             {
454               if (DBG_CIPHER)
455                 log_debug ("ecc sign: Failed to get affine coordinates\n");
456               err = GPG_ERR_BAD_SIGNATURE;
457               goto leave;
458             }
459           mpi_mod (r, x, skey->E.n);  /* r = x mod n */
460         }
461       mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n  */
462       mpi_addm (sum, hash, dr, skey->E.n);  /* sum = hash + (d*r) mod n  */
463       mpi_invm (k_1, k, skey->E.n);         /* k_1 = k^(-1) mod n  */
464       mpi_mulm (s, k_1, sum, skey->E.n);    /* s = k^(-1)*(hash+(d*r)) mod n */
465     }
466
467   if (DBG_CIPHER)
468     {
469       log_mpidump ("ecdsa sign result r ", r);
470       log_mpidump ("ecdsa sign result s ", s);
471     }
472
473  leave:
474   _gcry_mpi_ec_free (ctx);
475   point_free (&I);
476   mpi_free (x);
477   mpi_free (k_1);
478   mpi_free (sum);
479   mpi_free (dr);
480   mpi_free (k);
481
482   if (hash != input)
483     mpi_free (hash);
484
485   return err;
486 }
487
488
489 /* Verify an ECDSA signature.
490  * Check if R and S verifies INPUT.
491  */
492 static gpg_err_code_t
493 verify_ecdsa (gcry_mpi_t input, ECC_public_key *pkey,
494               gcry_mpi_t r, gcry_mpi_t s)
495 {
496   gpg_err_code_t err = 0;
497   gcry_mpi_t h, h1, h2, x;
498   mpi_point_struct Q, Q1, Q2;
499   mpi_ec_t ctx;
500
501   if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
502     return GPG_ERR_BAD_SIGNATURE; /* Assertion  0 < r < n  failed.  */
503   if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
504     return GPG_ERR_BAD_SIGNATURE; /* Assertion  0 < s < n  failed.  */
505
506   h  = mpi_alloc (0);
507   h1 = mpi_alloc (0);
508   h2 = mpi_alloc (0);
509   x = mpi_alloc (0);
510   point_init (&Q);
511   point_init (&Q1);
512   point_init (&Q2);
513
514   ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect,
515                                      pkey->E.p, pkey->E.a, pkey->E.b);
516
517   /* h  = s^(-1) (mod n) */
518   mpi_invm (h, s, pkey->E.n);
519   /* h1 = hash * s^(-1) (mod n) */
520   mpi_mulm (h1, input, h, pkey->E.n);
521   /* Q1 = [ hash * s^(-1) ]G  */
522   _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
523   /* h2 = r * s^(-1) (mod n) */
524   mpi_mulm (h2, r, h, pkey->E.n);
525   /* Q2 = [ r * s^(-1) ]Q */
526   _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
527   /* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
528   _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
529
530   if (!mpi_cmp_ui (Q.z, 0))
531     {
532       if (DBG_CIPHER)
533           log_debug ("ecc verify: Rejected\n");
534       err = GPG_ERR_BAD_SIGNATURE;
535       goto leave;
536     }
537   if (_gcry_mpi_ec_get_affine (x, NULL, &Q, ctx))
538     {
539       if (DBG_CIPHER)
540         log_debug ("ecc verify: Failed to get affine coordinates\n");
541       err = GPG_ERR_BAD_SIGNATURE;
542       goto leave;
543     }
544   mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
545   if (mpi_cmp (x, r))   /* x != r */
546     {
547       if (DBG_CIPHER)
548         {
549           log_mpidump ("     x", x);
550           log_mpidump ("     r", r);
551           log_mpidump ("     s", s);
552           log_debug ("ecc verify: Not verified\n");
553         }
554       err = GPG_ERR_BAD_SIGNATURE;
555       goto leave;
556     }
557   if (DBG_CIPHER)
558     log_debug ("ecc verify: Accepted\n");
559
560  leave:
561   _gcry_mpi_ec_free (ctx);
562   point_free (&Q2);
563   point_free (&Q1);
564   point_free (&Q);
565   mpi_free (x);
566   mpi_free (h2);
567   mpi_free (h1);
568   mpi_free (h);
569   return err;
570 }
571
572
573 \f
574 static void
575 reverse_buffer (unsigned char *buffer, unsigned int length)
576 {
577   unsigned int tmp, i;
578
579   for (i=0; i < length/2; i++)
580     {
581       tmp = buffer[i];
582       buffer[i] = buffer[length-1-i];
583       buffer[length-1-i] = tmp;
584     }
585 }
586
587
588 /* Encode MPI using the EdDSA scheme.  MINLEN specifies the required
589    length of the buffer in bytes.  On success 0 is returned an a
590    malloced buffer with the encoded point is stored at R_BUFFER; the
591    length of this buffer is stored at R_BUFLEN.  */
592 static gpg_err_code_t
593 eddsa_encodempi (gcry_mpi_t mpi, unsigned int minlen,
594                  unsigned char **r_buffer, unsigned int *r_buflen)
595 {
596   unsigned char *rawmpi;
597   unsigned int rawmpilen;
598
599   rawmpi = _gcry_mpi_get_buffer (mpi, minlen, &rawmpilen, NULL);
600   if (!rawmpi)
601     return gpg_err_code_from_syserror ();
602
603   *r_buffer = rawmpi;
604   *r_buflen = rawmpilen;
605   return 0;
606 }
607
608
609 /* Encode POINT using the EdDSA scheme.  X and Y are scratch variables
610    supplied by the caller and CTX is the usual context.  MINLEN is the
611    required length in bytes for the result. On success 0 is returned
612    an a malloced buffer with the encoded point is stored at R_BUFFER;
613    the length of this buffer is stored at R_BUFLEN.  */
614 static gpg_err_code_t
615 eddsa_encodepoint (mpi_point_t point, unsigned int minlen, mpi_ec_t ctx,
616                    gcry_mpi_t x, gcry_mpi_t y,
617                    unsigned char **r_buffer, unsigned int *r_buflen)
618 {
619   unsigned char *rawmpi;
620   unsigned int rawmpilen;
621
622   if (_gcry_mpi_ec_get_affine (x, y, point, ctx))
623     {
624       log_error ("eddsa_encodepoint: Failed to get affine coordinates\n");
625       return GPG_ERR_INTERNAL;
626     }
627   rawmpi = _gcry_mpi_get_buffer (y, minlen, &rawmpilen, NULL);
628   if (!rawmpi)
629     return gpg_err_code_from_syserror ();
630   if (mpi_test_bit (x, 0) && rawmpilen)
631     rawmpi[rawmpilen - 1] |= 0x80;  /* Set sign bit.  */
632
633   *r_buffer = rawmpi;
634   *r_buflen = rawmpilen;
635   return 0;
636 }
637
638
639 /* Decode the EdDSA style encoded PK and set it into RESULT.  LEN is
640    the expected length in bytes of the encoded key and CTX the usual
641    curve context.  If R_ENCPK is not NULL, the encoded PK is stored at
642    that address; this is a new copy to be release by the caller.  In
643    contrast to the supplied PK, this is not an MPI and thus guarnteed
644    to be properly padded.  R_ENCPKLEN received the length of that
645    encoded key.  */
646 static gpg_err_code_t
647 eddsa_decodepoint (gcry_mpi_t pk, unsigned int len, mpi_ec_t ctx,
648                    mpi_point_t result,
649                    unsigned char **r_encpk, unsigned int *r_encpklen)
650 {
651   unsigned char *rawmpi;
652   unsigned int rawmpilen;
653   gcry_mpi_t yy, t, x, p1, p2, p3;
654   int sign;
655
656   if (mpi_is_opaque (pk))
657     {
658       const void *buf;
659
660       buf = gcry_mpi_get_opaque (pk, &rawmpilen);
661       if (!buf)
662         return GPG_ERR_INV_OBJ;
663       rawmpilen = (rawmpilen + 7)/8;
664       rawmpi = gcry_malloc (rawmpilen? rawmpilen:1);
665       if (!rawmpi)
666         return gpg_err_code_from_syserror ();
667       memcpy (rawmpi, buf, rawmpilen);
668       reverse_buffer (rawmpi, rawmpilen);
669     }
670   else
671     {
672       rawmpi = _gcry_mpi_get_buffer (pk, len, &rawmpilen, NULL);
673       if (!rawmpi)
674         return gpg_err_code_from_syserror ();
675     }
676
677   if (rawmpilen)
678     {
679       sign = !!(rawmpi[0] & 0x80);
680       rawmpi[0] &= 0x7f;
681     }
682   else
683     sign = 0;
684   _gcry_mpi_set_buffer (result->y, rawmpi, rawmpilen, 0);
685   if (r_encpk)
686     {
687       /* Revert to little endian.  */
688       if (sign && rawmpilen)
689         rawmpi[0] |= 0x80;
690       reverse_buffer (rawmpi, rawmpilen);
691       *r_encpk = rawmpi;
692       if (r_encpklen)
693         *r_encpklen = rawmpilen;
694     }
695   else
696     gcry_free (rawmpi);
697
698   /* Now recover X.  */
699   /* t = (y^2-1) · ((b*y^2+1)^{p-2} mod p) */
700   x = mpi_new (0);
701   yy = mpi_new (0);
702   mpi_mul (yy, result->y, result->y);
703   t = mpi_copy (yy);
704   mpi_mul (t, t, ctx->b);
705   mpi_add_ui (t, t, 1);
706   p2 = mpi_copy (ctx->p);
707   mpi_sub_ui (p2, p2, 2);
708   mpi_powm (t, t, p2, ctx->p);
709
710   mpi_sub_ui (yy, yy, 1);
711   mpi_mul (t, yy, t);
712
713   /* x = t^{(p+3)/8} mod p */
714   p3 = mpi_copy (ctx->p);
715   mpi_add_ui (p3, p3, 3);
716   mpi_fdiv_q (p3, p3, mpi_const (MPI_C_EIGHT));
717   mpi_powm (x, t, p3, ctx->p);
718
719   /* (x^2 - t) % p != 0 ? x = (x*(2^{(p-1)/4} mod p)) % p */
720   mpi_mul (yy, x, x);
721   mpi_subm (yy, yy, t, ctx->p);
722   if (mpi_cmp_ui (yy, 0))
723     {
724       p1 = mpi_copy (ctx->p);
725       mpi_sub_ui (p1, p1, 1);
726       mpi_fdiv_q (p1, p1, mpi_const (MPI_C_FOUR));
727       mpi_powm (yy, mpi_const (MPI_C_TWO), p1, ctx->p);
728       mpi_mulm (x, x, yy, ctx->p);
729     }
730   else
731     p1 = NULL;
732
733   /* is_odd(x) ? x = p-x */
734   if (mpi_test_bit (x, 0))
735     mpi_sub (x, ctx->p, x);
736
737   /* lowbit(x) != highbit(input) ?  x = p-x */
738   if (mpi_test_bit (x, 0) != sign)
739     mpi_sub (x, ctx->p, x);
740
741   mpi_set (result->x, x);
742   mpi_set_ui (result->z, 1);
743
744   gcry_mpi_release (x);
745   gcry_mpi_release (yy);
746   gcry_mpi_release (t);
747   gcry_mpi_release (p3);
748   gcry_mpi_release (p2);
749   gcry_mpi_release (p1);
750
751   return 0;
752 }
753
754
755 /* Ed25519 version of the key generation.  */
756 static gpg_err_code_t
757 eddsa_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
758                     gcry_random_level_t random_level)
759 {
760   gpg_err_code_t rc;
761   int b = 256/8;             /* The only size we currently support.  */
762   gcry_mpi_t a, x, y;
763   mpi_point_struct Q;
764   char *dbuf;
765   size_t dlen;
766   gcry_buffer_t hvec[1];
767   unsigned char *hash_d = NULL;
768
769   point_init (&Q);
770   memset (hvec, 0, sizeof hvec);
771
772   a = mpi_snew (0);
773   x = mpi_new (0);
774   y = mpi_new (0);
775
776   /* Generate a secret.  */
777   hash_d = gcry_malloc_secure (2*b);
778   if (!hash_d)
779     {
780       rc = gpg_error_from_syserror ();
781       goto leave;
782     }
783   dlen = b;
784   dbuf = gcry_random_bytes_secure (dlen, random_level);
785
786   /* Compute the A value.  */
787   hvec[0].data = dbuf;
788   hvec[0].len = dlen;
789   rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, hash_d, hvec, 1);
790   if (rc)
791     goto leave;
792   sk->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8);
793   dbuf = NULL;
794   reverse_buffer (hash_d, 32);  /* Only the first half of the hash.  */
795   hash_d[0] = (hash_d[0] & 0x7f) | 0x40;
796   hash_d[31] &= 0xf8;
797   _gcry_mpi_set_buffer (a, hash_d, 32, 0);
798   gcry_free (hash_d); hash_d = NULL;
799   /* log_printmpi ("ecgen         a", a); */
800
801   /* Compute Q.  */
802   _gcry_mpi_ec_mul_point (&Q, a, &E->G, ctx);
803   if (DBG_CIPHER)
804     log_printpnt ("ecgen      pk", &Q, ctx);
805
806   /* Copy the stuff to the key structures. */
807   sk->E.model = E->model;
808   sk->E.dialect = E->dialect;
809   sk->E.p = mpi_copy (E->p);
810   sk->E.a = mpi_copy (E->a);
811   sk->E.b = mpi_copy (E->b);
812   point_init (&sk->E.G);
813   point_set (&sk->E.G, &E->G);
814   sk->E.n = mpi_copy (E->n);
815   point_init (&sk->Q);
816   point_set (&sk->Q, &Q);
817
818  leave:
819   gcry_mpi_release (a);
820   gcry_mpi_release (x);
821   gcry_mpi_release (y);
822   gcry_free (hash_d);
823   return rc;
824 }
825
826
827 /* Compute an EdDSA signature. See:
828  *   [ed25519] 23pp. (PDF) Daniel J. Bernstein, Niels Duif, Tanja
829  *   Lange, Peter Schwabe, Bo-Yin Yang. High-speed high-security
830  *   signatures.  Journal of Cryptographic Engineering 2 (2012), 77-89.
831  *   Document ID: a1a62a2f76d23f65d622484ddd09caf8.
832  *   URL: http://cr.yp.to/papers.html#ed25519. Date: 2011.09.26.
833  *
834  * Despite that this function requires the specification of a hash
835  * algorithm, we only support what has been specified by the paper.
836  * This may change in the future.  Note that we don't check the used
837  * curve; the user is responsible to use Ed25519.
838  *
839  * Return the signature struct (r,s) from the message hash.  The caller
840  * must have allocated R_R and S.
841  */
842 static gpg_err_code_t
843 sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey,
844             gcry_mpi_t r_r, gcry_mpi_t s, int hashalgo, gcry_mpi_t pk)
845 {
846   int rc;
847   mpi_ec_t ctx = NULL;
848   int b = 256/8;             /* The only size we currently support.  */
849   unsigned int tmp;
850   unsigned char hash_d[64];  /* Fixme: malloc in secure memory */
851   unsigned char digest[64];
852   gcry_buffer_t hvec[3];
853   const void *mbuf;
854   size_t mlen;
855   unsigned char *rawmpi = NULL;
856   unsigned int rawmpilen;
857   unsigned char *encpk = NULL; /* Encoded public key.  */
858   unsigned int encpklen;
859   mpi_point_struct I;          /* Intermediate value.  */
860   mpi_point_struct Q;          /* Public key.  */
861   gcry_mpi_t a, x, y, r;
862
863   memset (hvec, 0, sizeof hvec);
864
865   if (!mpi_is_opaque (input))
866     return GPG_ERR_INV_DATA;
867   if (hashalgo != GCRY_MD_SHA512)
868     return GPG_ERR_DIGEST_ALGO;
869
870   /* Initialize some helpers.  */
871   point_init (&I);
872   point_init (&Q);
873   a = mpi_snew (0);
874   x = mpi_new (0);
875   y = mpi_new (0);
876   r = mpi_new (0);
877   ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
878                                      skey->E.p, skey->E.a, skey->E.b);
879
880   /* Hash the secret key.  We clear DIGEST so we can use it to left
881      pad the key with zeroes for hashing.  */
882   rawmpi = _gcry_mpi_get_buffer (skey->d, 0, &rawmpilen, NULL);
883   if (!rawmpi)
884     {
885       rc = gpg_err_code_from_syserror ();
886       goto leave;
887     }
888   memset (digest, 0, b);
889   hvec[0].data = digest;
890   hvec[0].off = 0;
891   hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
892   hvec[1].data = rawmpi;
893   hvec[1].off = 0;
894   hvec[1].len = rawmpilen;
895   rc = _gcry_md_hash_buffers (hashalgo, 0, hash_d, hvec, 2);
896   gcry_free (rawmpi); rawmpi = NULL;
897   if (rc)
898     goto leave;
899
900   /* Compute the A value (this modifies hash_d).  */
901   reverse_buffer (hash_d, 32);  /* Only the first half of the hash.  */
902   hash_d[0] = (hash_d[0] & 0x7f) | 0x40;
903   hash_d[31] &= 0xf8;
904   _gcry_mpi_set_buffer (a, hash_d, 32, 0);
905   /* log_printmpi ("     a", a); */
906
907   /* Compute the public key if it has not been supplied as optional
908      parameter.  */
909   if (pk)
910     {
911       rc = eddsa_decodepoint (pk, b, ctx, &Q,  &encpk, &encpklen);
912       if (rc)
913         goto leave;
914       if (DBG_CIPHER)
915         log_printhex ("* e_pk", encpk, encpklen);
916       if (!_gcry_mpi_ec_curve_point (&Q, ctx))
917         {
918           rc = GPG_ERR_BROKEN_PUBKEY;
919           goto leave;
920         }
921     }
922   else
923     {
924       _gcry_mpi_ec_mul_point (&Q, a, &skey->E.G, ctx);
925       rc = eddsa_encodepoint (&Q, b, ctx, x, y, &encpk, &encpklen);
926       if (rc)
927         goto leave;
928       if (DBG_CIPHER)
929         log_printhex ("  e_pk", encpk, encpklen);
930     }
931
932   /* Compute R.  */
933   mbuf = gcry_mpi_get_opaque (input, &tmp);
934   mlen = (tmp +7)/8;
935   if (DBG_CIPHER)
936     log_printhex ("     m", mbuf, mlen);
937
938   hvec[0].data = hash_d;
939   hvec[0].off  = 32;
940   hvec[0].len  = 32;
941   hvec[1].data = (char*)mbuf;
942   hvec[1].len  = mlen;
943   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
944   if (rc)
945     goto leave;
946   reverse_buffer (digest, 64);
947   if (DBG_CIPHER)
948     log_printhex ("     r", digest, 64);
949   _gcry_mpi_set_buffer (r, digest, 64, 0);
950   _gcry_mpi_ec_mul_point (&I, r, &skey->E.G, ctx);
951   if (DBG_CIPHER)
952     log_printpnt ("   r", &I, ctx);
953
954   /* Convert R into affine coordinates and apply encoding.  */
955   rc = eddsa_encodepoint (&I, b, ctx, x, y, &rawmpi, &rawmpilen);
956   if (rc)
957     goto leave;
958   if (DBG_CIPHER)
959     log_printhex ("   e_r", rawmpi, rawmpilen);
960
961   /* S = r + a * H(encodepoint(R) + encodepoint(pk) + m) mod n  */
962   hvec[0].data = rawmpi;  /* (this is R) */
963   hvec[0].off  = 0;
964   hvec[0].len  = rawmpilen;
965   hvec[1].data = encpk;
966   hvec[1].off  = 0;
967   hvec[1].len  = encpklen;
968   hvec[2].data = (char*)mbuf;
969   hvec[2].off  = 0;
970   hvec[2].len  = mlen;
971   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
972   if (rc)
973     goto leave;
974
975   /* No more need for RAWMPI thus we now transfer it to R_R.  */
976   gcry_mpi_set_opaque (r_r, rawmpi, rawmpilen*8);
977   rawmpi = NULL;
978
979   reverse_buffer (digest, 64);
980   if (DBG_CIPHER)
981     log_printhex (" H(R+)", digest, 64);
982   _gcry_mpi_set_buffer (s, digest, 64, 0);
983   mpi_mulm (s, s, a, skey->E.n);
984   mpi_addm (s, s, r, skey->E.n);
985   rc = eddsa_encodempi (s, b, &rawmpi, &rawmpilen);
986   if (rc)
987     goto leave;
988   if (DBG_CIPHER)
989     log_printhex ("   e_s", rawmpi, rawmpilen);
990   gcry_mpi_set_opaque (s, rawmpi, rawmpilen*8);
991   rawmpi = NULL;
992
993   rc = 0;
994
995  leave:
996   gcry_mpi_release (a);
997   gcry_mpi_release (x);
998   gcry_mpi_release (y);
999   gcry_mpi_release (r);
1000   _gcry_mpi_ec_free (ctx);
1001   point_free (&I);
1002   point_free (&Q);
1003   gcry_free (encpk);
1004   gcry_free (rawmpi);
1005   return rc;
1006 }
1007
1008
1009 /* Verify an EdDSA signature.  See sign_eddsa for the reference.
1010  * Check if R_IN and S_IN verifies INPUT.  PKEY has the curve
1011  * parameters and PK is the EdDSA style encoded public key.
1012  */
1013 static gpg_err_code_t
1014 verify_eddsa (gcry_mpi_t input, ECC_public_key *pkey,
1015               gcry_mpi_t r_in, gcry_mpi_t s_in, int hashalgo, gcry_mpi_t pk)
1016 {
1017   int rc;
1018   mpi_ec_t ctx = NULL;
1019   int b = 256/8;               /* The only size we currently support.  */
1020   unsigned int tmp;
1021   mpi_point_struct Q;          /* Public key.  */
1022   unsigned char *encpk = NULL; /* Encoded public key.  */
1023   unsigned int encpklen;
1024   const void *mbuf, *rbuf;
1025   unsigned char *tbuf = NULL;
1026   size_t mlen, rlen;
1027   unsigned int tlen;
1028   unsigned char digest[64];
1029   gcry_buffer_t hvec[3];
1030   gcry_mpi_t h, s;
1031   mpi_point_struct Ia, Ib;
1032
1033   if (!mpi_is_opaque (input) || !mpi_is_opaque (r_in) || !mpi_is_opaque (s_in))
1034     return GPG_ERR_INV_DATA;
1035   if (hashalgo != GCRY_MD_SHA512)
1036     return GPG_ERR_DIGEST_ALGO;
1037
1038   point_init (&Q);
1039   point_init (&Ia);
1040   point_init (&Ib);
1041   h = mpi_new (0);
1042   s = mpi_new (0);
1043
1044   ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect,
1045                                      pkey->E.p, pkey->E.a, pkey->E.b);
1046
1047   /* Decode and check the public key.  */
1048   rc = eddsa_decodepoint (pk, b, ctx, &Q, &encpk, &encpklen);
1049   if (rc)
1050     goto leave;
1051   if (!_gcry_mpi_ec_curve_point (&Q, ctx))
1052     {
1053       rc = GPG_ERR_BROKEN_PUBKEY;
1054       goto leave;
1055     }
1056   if (DBG_CIPHER)
1057     log_printhex ("  e_pk", encpk, encpklen);
1058   if (encpklen != b)
1059     {
1060       rc = GPG_ERR_INV_LENGTH;
1061       goto leave;
1062     }
1063
1064   /* Convert the other input parameters.  */
1065   mbuf = gcry_mpi_get_opaque (input, &tmp);
1066   mlen = (tmp +7)/8;
1067   if (DBG_CIPHER)
1068     log_printhex ("     m", mbuf, mlen);
1069   rbuf = gcry_mpi_get_opaque (r_in, &tmp);
1070   rlen = (tmp +7)/8;
1071   if (DBG_CIPHER)
1072     log_printhex ("     r", rbuf, rlen);
1073   if (rlen != b)
1074     {
1075       rc = GPG_ERR_INV_LENGTH;
1076       goto leave;
1077     }
1078
1079   /* h = H(encodepoint(R) + encodepoint(pk) + m)  */
1080   hvec[0].data = (char*)rbuf;
1081   hvec[0].off  = 0;
1082   hvec[0].len  = rlen;
1083   hvec[1].data = encpk;
1084   hvec[1].off  = 0;
1085   hvec[1].len  = encpklen;
1086   hvec[2].data = (char*)mbuf;
1087   hvec[2].off  = 0;
1088   hvec[2].len  = mlen;
1089   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
1090   if (rc)
1091     goto leave;
1092   reverse_buffer (digest, 64);
1093   if (DBG_CIPHER)
1094     log_printhex (" H(R+)", digest, 64);
1095   _gcry_mpi_set_buffer (h, digest, 64, 0);
1096
1097   /* According to the paper the best way for verification is:
1098          encodepoint(sG - h·Q) = encodepoint(r)
1099      because we don't need to decode R. */
1100   {
1101     void *sbuf;
1102     unsigned int slen;
1103
1104     sbuf = _gcry_mpi_get_opaque_copy (s_in, &tmp);
1105     slen = (tmp +7)/8;
1106     reverse_buffer (sbuf, slen);
1107     if (DBG_CIPHER)
1108       log_printhex ("     s", sbuf, slen);
1109     _gcry_mpi_set_buffer (s, sbuf, slen, 0);
1110     gcry_free (sbuf);
1111     if (slen != b)
1112       {
1113         rc = GPG_ERR_INV_LENGTH;
1114         goto leave;
1115       }
1116   }
1117
1118   _gcry_mpi_ec_mul_point (&Ia, s, &pkey->E.G, ctx);
1119   _gcry_mpi_ec_mul_point (&Ib, h, &Q, ctx);
1120   _gcry_mpi_neg (Ib.x, Ib.x);
1121   _gcry_mpi_ec_add_points (&Ia, &Ia, &Ib, ctx);
1122   rc = eddsa_encodepoint (&Ia, b, ctx, s, h, &tbuf, &tlen);
1123   if (rc)
1124     goto leave;
1125   if (tlen != rlen || memcmp (tbuf, rbuf, tlen))
1126     {
1127       if (DBG_CIPHER)
1128         log_debug ("eddsa verify: Not verified\n");
1129       rc = GPG_ERR_BAD_SIGNATURE;
1130       goto leave;
1131     }
1132
1133   if (DBG_CIPHER)
1134     log_debug ("eddsa verify: Accepted\n");
1135   rc = 0;
1136
1137  leave:
1138   gcry_free (encpk);
1139   gcry_free (tbuf);
1140   _gcry_mpi_ec_free (ctx);
1141   gcry_mpi_release (s);
1142   gcry_mpi_release (h);
1143   point_free (&Ia);
1144   point_free (&Ib);
1145   point_free (&Q);
1146   return rc;
1147 }
1148
1149
1150 \f
1151 /*********************************************
1152  **************  interface  ******************
1153  *********************************************/
1154
1155 static gcry_err_code_t
1156 ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
1157               const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
1158 {
1159   gpg_err_code_t rc;
1160   elliptic_curve_t E;
1161   ECC_secret_key sk;
1162   gcry_mpi_t x = NULL;
1163   gcry_mpi_t y = NULL;
1164   char *curve_name = NULL;
1165   gcry_sexp_t l1;
1166   int transient_key = 0;
1167   gcry_random_level_t random_level;
1168   mpi_ec_t ctx = NULL;
1169   gcry_sexp_t curve_info = NULL;
1170   gcry_mpi_t base = NULL;
1171   gcry_mpi_t public = NULL;
1172   gcry_mpi_t secret = NULL;
1173
1174   (void)algo;
1175   (void)evalue;
1176
1177   memset (&E, 0, sizeof E);
1178   memset (&sk, 0, sizeof sk);
1179
1180   if (genparms)
1181     {
1182       /* Parse the optional "curve" parameter. */
1183       l1 = gcry_sexp_find_token (genparms, "curve", 0);
1184       if (l1)
1185         {
1186           curve_name = _gcry_sexp_nth_string (l1, 1);
1187           gcry_sexp_release (l1);
1188           if (!curve_name)
1189             return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
1190         }
1191
1192       /* Parse the optional transient-key flag.  */
1193       l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
1194       if (l1)
1195         {
1196           transient_key = 1;
1197           gcry_sexp_release (l1);
1198         }
1199     }
1200
1201   /* NBITS is required if no curve name has been given.  */
1202   if (!nbits && !curve_name)
1203     return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
1204
1205   rc = _gcry_ecc_fill_in_curve (nbits, curve_name, &E, &nbits);
1206   gcry_free (curve_name); curve_name = NULL;
1207   if (rc)
1208     goto leave;
1209
1210   if (DBG_CIPHER)
1211     {
1212       log_debug ("ecgen curve info: %s/%s\n",
1213                  _gcry_ecc_model2str (E.model),
1214                  _gcry_ecc_dialect2str (E.dialect));
1215       if (E.name)
1216         log_debug ("ecgen curve used: %s\n", E.name);
1217       log_printmpi ("ecgen curve   p", E.p);
1218       log_printmpi ("ecgen curve   a", E.a);
1219       log_printmpi ("ecgen curve   b", E.b);
1220       log_printmpi ("ecgen curve   n", E.n);
1221       log_printpnt ("ecgen curve G", &E.G, NULL);
1222     }
1223
1224   random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
1225   ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, E.p, E.a, E.b);
1226   x = mpi_new (0);
1227   y = mpi_new (0);
1228
1229   switch (E.dialect)
1230     {
1231     case ECC_DIALECT_STANDARD:
1232       rc = nist_generate_key (&sk, &E, ctx, random_level, nbits);
1233       break;
1234     case ECC_DIALECT_ED25519:
1235       rc = eddsa_generate_key (&sk, &E, ctx, random_level);
1236       break;
1237     default:
1238       rc = GPG_ERR_INTERNAL;
1239       break;
1240     }
1241   if (rc)
1242     goto leave;
1243
1244   /* Copy data to the result.  */
1245   if (_gcry_mpi_ec_get_affine (x, y, &sk.E.G, ctx))
1246     log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "G");
1247   base = _gcry_ecc_ec2os (x, y, sk.E.p);
1248   if (sk.E.dialect == ECC_DIALECT_ED25519)
1249     {
1250       unsigned char *encpk;
1251       unsigned int encpklen;
1252
1253       rc = eddsa_encodepoint (&sk.Q, 256/8, ctx, x, y, &encpk, &encpklen);
1254       if (rc)
1255         return rc;
1256       public = mpi_new (0);
1257       gcry_mpi_set_opaque (public, encpk, encpklen*8);
1258       encpk = NULL;
1259     }
1260   else
1261     {
1262       if (_gcry_mpi_ec_get_affine (x, y, &sk.Q, ctx))
1263         log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
1264       public = _gcry_ecc_ec2os (x, y, sk.E.p);
1265     }
1266   secret = sk.d; sk.d = NULL;
1267   if (E.name)
1268     {
1269       rc = gcry_sexp_build (&curve_info, NULL, "(curve %s)", E.name);
1270       if (rc)
1271         goto leave;
1272     }
1273
1274   rc = gcry_sexp_build (r_skey, NULL,
1275                         "(key-data"
1276                         " (public-key"
1277                         "  (ecc%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))"
1278                         " (private-key"
1279                         "  (ecc%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))"
1280                         " )",
1281                         curve_info,
1282                         sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public,
1283                         curve_info,
1284                         sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public, secret);
1285   if (rc)
1286     goto leave;
1287
1288   if (DBG_CIPHER)
1289     {
1290       log_printmpi ("ecgen result  p", sk.E.p);
1291       log_printmpi ("ecgen result  a", sk.E.a);
1292       log_printmpi ("ecgen result  b", sk.E.b);
1293       log_printmpi ("ecgen result  G", base);
1294       log_printmpi ("ecgen result  n", sk.E.n);
1295       log_printmpi ("ecgen result  Q", public);
1296       log_printmpi ("ecgen result  d", secret);
1297     }
1298
1299  leave:
1300   mpi_free (secret);
1301   mpi_free (public);
1302   mpi_free (base);
1303   {
1304     _gcry_ecc_curve_free (&sk.E);
1305     point_free (&sk.Q);
1306     mpi_free (sk.d);
1307   }
1308   _gcry_ecc_curve_free (&E);
1309   mpi_free (x);
1310   mpi_free (y);
1311   _gcry_mpi_ec_free (ctx);
1312   gcry_sexp_release (curve_info);
1313   return rc;
1314 }
1315
1316
1317 static gcry_err_code_t
1318 ecc_check_secret_key (int algo, gcry_mpi_t *skey)
1319 {
1320   gpg_err_code_t err;
1321   ECC_secret_key sk;
1322
1323   (void)algo;
1324
1325   /* FIXME:  This check looks a bit fishy:  Now long is the array?  */
1326   if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
1327       || !skey[6])
1328     return GPG_ERR_BAD_MPI;
1329
1330   sk.E.model = MPI_EC_WEIERSTRASS;
1331   sk.E.p = skey[0];
1332   sk.E.a = skey[1];
1333   sk.E.b = skey[2];
1334   point_init (&sk.E.G);
1335   err = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1336   if (err)
1337     {
1338       point_free (&sk.E.G);
1339       return err;
1340     }
1341   sk.E.n = skey[4];
1342   point_init (&sk.Q);
1343   err = _gcry_ecc_os2ec (&sk.Q, skey[5]);
1344   if (err)
1345     {
1346       point_free (&sk.E.G);
1347       point_free (&sk.Q);
1348       return err;
1349     }
1350
1351   {
1352     const unsigned char *buf;
1353     unsigned int n;
1354
1355     gcry_assert (mpi_is_opaque (skey[6]));
1356
1357     buf = gcry_mpi_get_opaque (skey[6], &n);
1358     if (!buf)
1359       err = GPG_ERR_INV_OBJ;
1360     else
1361       {
1362         n = (n + 7)/8;
1363         sk.d = NULL;
1364         err = gcry_mpi_scan (&sk.d, GCRYMPI_FMT_USG, buf, n, NULL);
1365         if (!err)
1366           {
1367             if (check_secret_key (&sk))
1368               err = GPG_ERR_BAD_SECKEY;
1369             gcry_mpi_release (sk.d);
1370             sk.d = NULL;
1371           }
1372       }
1373   }
1374
1375   point_free (&sk.E.G);
1376   point_free (&sk.Q);
1377   return err;
1378 }
1379
1380
1381 static gcry_err_code_t
1382 ecc_sign (int algo, gcry_sexp_t *r_result, gcry_mpi_t data, gcry_mpi_t *skey,
1383           int flags, int hashalgo)
1384 {
1385   gpg_err_code_t rc;
1386   ECC_secret_key sk;
1387   gcry_mpi_t r, s;
1388
1389   (void)algo;
1390
1391   if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1392       || !skey[6] )
1393     return GPG_ERR_BAD_MPI;
1394
1395   sk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
1396                 ? MPI_EC_TWISTEDEDWARDS
1397                 : MPI_EC_WEIERSTRASS);
1398   sk.E.p = skey[0];
1399   sk.E.a = skey[1];
1400   sk.E.b = skey[2];
1401   point_init (&sk.E.G);
1402   sk.Q.x = NULL;
1403   sk.Q.y = NULL;
1404   sk.Q.z = NULL;
1405   rc = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1406   if (rc)
1407     {
1408       point_free (&sk.E.G);
1409       return rc;
1410     }
1411   sk.E.n = skey[4];
1412
1413   r = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1414   s = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1415
1416   {
1417     const unsigned char *buf;
1418     unsigned int n;
1419
1420     gcry_assert (mpi_is_opaque (skey[6]));
1421
1422     buf = gcry_mpi_get_opaque (skey[6], &n);
1423     if (!buf)
1424       rc = GPG_ERR_INV_OBJ;
1425     else
1426       {
1427         n = (n + 7)/8;
1428         sk.d = NULL;
1429         rc = gcry_mpi_scan (&sk.d, GCRYMPI_FMT_USG, buf, n, NULL);
1430         if (!rc)
1431           {
1432             if ((flags & PUBKEY_FLAG_EDDSA))
1433               {
1434                 rc = sign_eddsa (data, &sk, r, s, hashalgo, skey[5]);
1435                 if (!rc)
1436                   rc = gcry_sexp_build (r_result, NULL,
1437                                         "(sig-val(eddsa(r%M)(s%M)))", r, s);
1438               }
1439             else
1440               {
1441                 rc = sign_ecdsa (data, &sk, r, s, flags, hashalgo);
1442                 if (!rc)
1443                   rc = gcry_sexp_build (r_result, NULL,
1444                                         "(sig-val(ecdsa(r%M)(s%M)))", r, s);
1445               }
1446             gcry_mpi_release (sk.d);
1447             sk.d = NULL;
1448           }
1449       }
1450   }
1451
1452   mpi_free (r);
1453   mpi_free (s);
1454   point_free (&sk.E.G);
1455   if (sk.Q.x)
1456     point_free (&sk.Q);
1457   return rc;
1458 }
1459
1460
1461 static gcry_err_code_t
1462 ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
1463             int (*cmp)(void *, gcry_mpi_t), void *opaquev,
1464             int flags, int hashalgo)
1465 {
1466   gpg_err_code_t err;
1467   ECC_public_key pk;
1468
1469   (void)algo;
1470   (void)cmp;
1471   (void)opaquev;
1472
1473   if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2]
1474       || !pkey[3] || !pkey[4] || !pkey[5] )
1475     return GPG_ERR_BAD_MPI;
1476
1477   pk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
1478                 ? MPI_EC_TWISTEDEDWARDS
1479                 : MPI_EC_WEIERSTRASS);
1480   pk.E.p = pkey[0];
1481   pk.E.a = pkey[1];
1482   pk.E.b = pkey[2];
1483   point_init (&pk.E.G);
1484   err = _gcry_ecc_os2ec (&pk.E.G, pkey[3]);
1485   if (err)
1486     {
1487       point_free (&pk.E.G);
1488       return err;
1489     }
1490   pk.E.n = pkey[4];
1491
1492   if ((flags & PUBKEY_FLAG_EDDSA))
1493     {
1494       pk.Q.x = NULL;
1495       pk.Q.y = NULL;
1496       pk.Q.z = NULL;
1497
1498       err = verify_eddsa (hash, &pk, data[0], data[1], hashalgo, pkey[5]);
1499     }
1500   else
1501     {
1502       point_init (&pk.Q);
1503       err = _gcry_ecc_os2ec (&pk.Q, pkey[5]);
1504       if (err)
1505         {
1506           point_free (&pk.E.G);
1507           point_free (&pk.Q);
1508           return err;
1509         }
1510
1511       if (mpi_is_opaque (hash))
1512         {
1513           const void *abuf;
1514           unsigned int abits, qbits;
1515           gcry_mpi_t a;
1516
1517           qbits = mpi_get_nbits (pk.E.n);
1518
1519           abuf = gcry_mpi_get_opaque (hash, &abits);
1520           err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, abuf, (abits+7)/8, NULL);
1521           if (!err)
1522             {
1523               if (abits > qbits)
1524                 gcry_mpi_rshift (a, a, abits - qbits);
1525
1526               err = verify_ecdsa (a, &pk, data[0], data[1]);
1527               gcry_mpi_release (a);
1528             }
1529         }
1530       else
1531         err = verify_ecdsa (hash, &pk, data[0], data[1]);
1532     }
1533
1534   point_free (&pk.E.G);
1535   point_free (&pk.Q);
1536   return err;
1537 }
1538
1539
1540 /* ecdh raw is classic 2-round DH protocol published in 1976.
1541  *
1542  * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
1543  *
1544  * As with any PK operation, encrypt version uses a public key and
1545  * decrypt -- private.
1546  *
1547  * Symbols used below:
1548  *     G - field generator point
1549  *     d - private long-term scalar
1550  *    dG - public long-term key
1551  *     k - ephemeral scalar
1552  *    kG - ephemeral public key
1553  *   dkG - shared secret
1554  *
1555  * ecc_encrypt_raw description:
1556  *   input:
1557  *     data[0] : private scalar (k)
1558  *   output: A new S-expression with the parameters:
1559  *     s : shared point (kdG)
1560  *     e : generated ephemeral public key (kG)
1561  *
1562  * ecc_decrypt_raw description:
1563  *   input:
1564  *     data[0] : a point kG (ephemeral public key)
1565  *   output:
1566  *     result[0] : shared point (kdG)
1567  */
1568 static gcry_err_code_t
1569 ecc_encrypt_raw (int algo, gcry_sexp_t *r_result, gcry_mpi_t k,
1570                  gcry_mpi_t *pkey, int flags)
1571 {
1572   gpg_err_code_t rc;
1573   ECC_public_key pk;
1574   mpi_ec_t ctx;
1575   gcry_mpi_t s, e;
1576
1577   (void)algo;
1578   (void)flags;
1579
1580   if (!k
1581       || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5])
1582     return GPG_ERR_BAD_MPI;
1583
1584   pk.E.model = MPI_EC_WEIERSTRASS;
1585   pk.E.p = pkey[0];
1586   pk.E.a = pkey[1];
1587   pk.E.b = pkey[2];
1588   point_init (&pk.E.G);
1589   rc = _gcry_ecc_os2ec (&pk.E.G, pkey[3]);
1590   if (rc)
1591     {
1592       point_free (&pk.E.G);
1593       return rc;
1594     }
1595   pk.E.n = pkey[4];
1596   point_init (&pk.Q);
1597   rc = _gcry_ecc_os2ec (&pk.Q, pkey[5]);
1598   if (rc)
1599     {
1600       point_free (&pk.E.G);
1601       point_free (&pk.Q);
1602       return rc;
1603     }
1604
1605   ctx = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect,
1606                                      pk.E.p, pk.E.a, pk.E.b);
1607   s = mpi_alloc (mpi_get_nlimbs (pk.E.p));
1608   e = mpi_alloc (mpi_get_nlimbs (pk.E.p));
1609
1610   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
1611   {
1612     mpi_point_struct R;  /* Result that we return.  */
1613     gcry_mpi_t x, y;
1614
1615     x = mpi_new (0);
1616     y = mpi_new (0);
1617
1618     point_init (&R);
1619
1620     /* R = kQ  <=>  R = kdG  */
1621     _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx);
1622
1623     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1624       log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
1625     s = _gcry_ecc_ec2os (x, y, pk.E.p);
1626
1627     /* R = kG */
1628     _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx);
1629
1630     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1631       log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
1632     e = _gcry_ecc_ec2os (x, y, pk.E.p);
1633
1634     mpi_free (x);
1635     mpi_free (y);
1636
1637     point_free (&R);
1638   }
1639
1640   _gcry_mpi_ec_free (ctx);
1641   point_free (&pk.E.G);
1642   point_free (&pk.Q);
1643
1644   rc = gcry_sexp_build (r_result, NULL, "(enc-val(ecdh(s%m)(e%m)))", s, e);
1645   mpi_free (s);
1646   mpi_free (e);
1647
1648   return rc;
1649 }
1650
1651 /*  input:
1652  *     data[0] : a point kG (ephemeral public key)
1653  *   output:
1654  *     resaddr[0] : shared point kdG
1655  *
1656  *  see ecc_encrypt_raw for details.
1657  */
1658 static gcry_err_code_t
1659 ecc_decrypt_raw (int algo, gcry_sexp_t *r_plain, gcry_mpi_t *data,
1660                  gcry_mpi_t *skey, int flags,
1661                  enum pk_encoding encoding, int hash_algo,
1662                  unsigned char *label, size_t labellen)
1663 {
1664   gpg_err_code_t rc;
1665   ECC_secret_key sk;
1666   mpi_point_struct R;   /* Result that we return.  */
1667   mpi_point_struct kG;
1668   mpi_ec_t ctx;
1669   gcry_mpi_t r;
1670
1671   (void)algo;
1672   (void)flags;
1673   (void)encoding;
1674   (void)hash_algo;
1675   (void)label;
1676   (void)labellen;
1677
1678   if (!data || !data[0]
1679       || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1680       || !skey[5] || !skey[6] )
1681     return GPG_ERR_BAD_MPI;
1682
1683   point_init (&kG);
1684   rc = _gcry_ecc_os2ec (&kG, data[0]);
1685   if (rc)
1686     {
1687       point_free (&kG);
1688       return rc;
1689     }
1690
1691   sk.E.model = MPI_EC_WEIERSTRASS;
1692   sk.E.p = skey[0];
1693   sk.E.a = skey[1];
1694   sk.E.b = skey[2];
1695   point_init (&sk.E.G);
1696   rc = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1697   if (rc)
1698     {
1699       point_free (&kG);
1700       point_free (&sk.E.G);
1701       return rc;
1702     }
1703   sk.E.n = skey[4];
1704   point_init (&sk.Q);
1705   rc = _gcry_ecc_os2ec (&sk.Q, skey[5]);
1706   if (rc)
1707     {
1708       point_free (&kG);
1709       point_free (&sk.E.G);
1710       point_free (&sk.Q);
1711       return rc;
1712     }
1713   sk.d = skey[6];
1714
1715   ctx = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect,
1716                                      sk.E.p, sk.E.a, sk.E.b);
1717
1718   /* R = dkG */
1719   point_init (&R);
1720   _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx);
1721
1722   point_free (&kG);
1723
1724   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so:  */
1725   {
1726     gcry_mpi_t x, y;
1727
1728     x = mpi_new (0);
1729     y = mpi_new (0);
1730
1731     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1732       log_fatal ("ecdh: Failed to get affine coordinates\n");
1733
1734     r = _gcry_ecc_ec2os (x, y, sk.E.p);
1735     if (!r)
1736       rc = gpg_err_code_from_syserror ();
1737     else
1738       rc = 0;
1739     mpi_free (x);
1740     mpi_free (y);
1741   }
1742
1743   point_free (&R);
1744   _gcry_mpi_ec_free (ctx);
1745   point_free (&kG);
1746   point_free (&sk.E.G);
1747   point_free (&sk.Q);
1748
1749   if (!rc)
1750     rc = gcry_sexp_build (r_plain, NULL, "(value %m)", r);
1751   mpi_free (r);
1752   return rc;
1753 }
1754
1755
1756 static unsigned int
1757 ecc_get_nbits (int algo, gcry_mpi_t *pkey)
1758 {
1759   (void)algo;
1760
1761   return mpi_get_nbits (pkey[0]);
1762 }
1763
1764
1765 /* See rsa.c for a description of this function.  */
1766 static gpg_err_code_t
1767 compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
1768 {
1769 #define N_COMPONENTS 6
1770   static const char names[N_COMPONENTS+1] = "pabgnq";
1771   gpg_err_code_t ec = 0;
1772   gcry_sexp_t l1;
1773   gcry_mpi_t values[N_COMPONENTS];
1774   int idx;
1775
1776   /* Clear the values for easier error cleanup.  */
1777   for (idx=0; idx < N_COMPONENTS; idx++)
1778     values[idx] = NULL;
1779
1780   /* Fill values with all provided parameters.  */
1781   for (idx=0; idx < N_COMPONENTS; idx++)
1782     {
1783       l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
1784       if (l1)
1785         {
1786           values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1787           gcry_sexp_release (l1);
1788           if (!values[idx])
1789             {
1790               ec = GPG_ERR_INV_OBJ;
1791               goto leave;
1792             }
1793         }
1794     }
1795
1796   /* Check whether a curve parameter is available and use that to fill
1797      in missing values.  */
1798   l1 = gcry_sexp_find_token (keyparam, "curve", 5);
1799   if (l1)
1800     {
1801       char *curve;
1802       gcry_mpi_t tmpvalues[N_COMPONENTS];
1803
1804       for (idx = 0; idx < N_COMPONENTS; idx++)
1805         tmpvalues[idx] = NULL;
1806
1807       curve = _gcry_sexp_nth_string (l1, 1);
1808       gcry_sexp_release (l1);
1809       if (!curve)
1810         {
1811           ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
1812           goto leave;
1813         }
1814       ec = _gcry_ecc_get_param (curve, tmpvalues);
1815       gcry_free (curve);
1816       if (ec)
1817         goto leave;
1818
1819       for (idx = 0; idx < N_COMPONENTS; idx++)
1820         {
1821           if (!values[idx])
1822             values[idx] = tmpvalues[idx];
1823           else
1824             mpi_free (tmpvalues[idx]);
1825         }
1826     }
1827
1828   /* Check that all parameters are known and normalize all MPIs (that
1829      should not be required but we use an internal function later and
1830      thus we better make 100% sure that they are normalized). */
1831   for (idx = 0; idx < N_COMPONENTS; idx++)
1832     if (!values[idx])
1833       {
1834         ec = GPG_ERR_NO_OBJ;
1835         goto leave;
1836       }
1837     else
1838       _gcry_mpi_normalize (values[idx]);
1839
1840   /* Hash them all.  */
1841   for (idx = 0; idx < N_COMPONENTS; idx++)
1842     {
1843       char buf[30];
1844       unsigned char *rawmpi;
1845       unsigned int rawmpilen;
1846
1847       rawmpi = _gcry_mpi_get_buffer (values[idx], 0, &rawmpilen, NULL);
1848       if (!rawmpi)
1849         {
1850           ec = gpg_err_code_from_syserror ();
1851           goto leave;
1852         }
1853       snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
1854       gcry_md_write (md, buf, strlen (buf));
1855       gcry_md_write (md, rawmpi, rawmpilen);
1856       gcry_md_write (md, ")", 1);
1857       gcry_free (rawmpi);
1858     }
1859
1860  leave:
1861   for (idx = 0; idx < N_COMPONENTS; idx++)
1862     _gcry_mpi_release (values[idx]);
1863
1864   return ec;
1865 #undef N_COMPONENTS
1866 }
1867
1868
1869 \f
1870 /*
1871    Low-level API helper functions.
1872  */
1873
1874 /* This is the wroker function for gcry_pubkey_get_sexp for ECC
1875    algorithms.  Note that the caller has already stored NULL at
1876    R_SEXP.  */
1877 gpg_err_code_t
1878 _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
1879 {
1880   gpg_err_code_t rc;
1881   gcry_mpi_t mpi_G = NULL;
1882   gcry_mpi_t mpi_Q = NULL;
1883
1884   if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n)
1885     return GPG_ERR_BAD_CRYPT_CTX;
1886
1887   if (mode == GCRY_PK_GET_SECKEY && !ec->d)
1888     return GPG_ERR_NO_SECKEY;
1889
1890   /* Compute the public point if it is missing.  */
1891   if (!ec->Q && ec->d)
1892     {
1893       ec->Q = gcry_mpi_point_new (0);
1894       _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec);
1895     }
1896
1897   /* Encode G and Q.  */
1898   mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec);
1899   if (!mpi_G)
1900     {
1901       rc = GPG_ERR_BROKEN_PUBKEY;
1902       goto leave;
1903     }
1904   if (!ec->Q)
1905     {
1906       rc = GPG_ERR_BAD_CRYPT_CTX;
1907       goto leave;
1908     }
1909   mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec);
1910   if (!mpi_Q)
1911     {
1912       rc = GPG_ERR_BROKEN_PUBKEY;
1913       goto leave;
1914     }
1915
1916   /* Fixme: We should return a curve name instead of the parameters if
1917      if know that they match a curve.  */
1918
1919   if (ec->d && (!mode || mode == GCRY_PK_GET_SECKEY))
1920     {
1921       /* Let's return a private key. */
1922       rc = gcry_sexp_build
1923         (r_sexp, NULL,
1924          "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))",
1925          ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q, ec->d);
1926     }
1927   else if (ec->Q)
1928     {
1929       /* Let's return a public key.  */
1930       rc = gcry_sexp_build
1931         (r_sexp, NULL,
1932          "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))",
1933          ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q);
1934     }
1935   else
1936     rc = GPG_ERR_BAD_CRYPT_CTX;
1937
1938  leave:
1939   mpi_free (mpi_Q);
1940   mpi_free (mpi_G);
1941   return rc;
1942 }
1943
1944
1945 \f
1946 /*
1947      Self-test section.
1948  */
1949
1950
1951 static gpg_err_code_t
1952 selftests_ecdsa (selftest_report_func_t report)
1953 {
1954   const char *what;
1955   const char *errtxt;
1956
1957   what = "low-level";
1958   errtxt = NULL; /*selftest ();*/
1959   if (errtxt)
1960     goto failed;
1961
1962   /* FIXME:  need more tests.  */
1963
1964   return 0; /* Succeeded. */
1965
1966  failed:
1967   if (report)
1968     report ("pubkey", GCRY_PK_ECC, what, errtxt);
1969   return GPG_ERR_SELFTEST_FAILED;
1970 }
1971
1972
1973 /* Run a full self-test for ALGO and return 0 on success.  */
1974 static gpg_err_code_t
1975 run_selftests (int algo, int extended, selftest_report_func_t report)
1976 {
1977   (void)extended;
1978
1979   if (algo != GCRY_PK_ECC)
1980     return GPG_ERR_PUBKEY_ALGO;
1981
1982   return selftests_ecdsa (report);
1983 }
1984
1985
1986
1987 \f
1988 static const char *ecc_names[] =
1989   {
1990     "ecc",
1991     "ecdsa",
1992     "ecdh",
1993     "eddsa",
1994     NULL,
1995   };
1996
1997 gcry_pk_spec_t _gcry_pubkey_spec_ecc =
1998   {
1999     GCRY_PK_ECC, { 0, 0 },
2000     (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
2001     "ECC", ecc_names,
2002     "pabgnq", "pabgnqd", "sw", "rs", "pabgnq",
2003     ecc_generate,
2004     ecc_check_secret_key,
2005     ecc_encrypt_raw,
2006     ecc_decrypt_raw,
2007     ecc_sign,
2008     ecc_verify,
2009     ecc_get_nbits,
2010     run_selftests,
2011     compute_keygrip,
2012     _gcry_ecc_get_param,
2013     _gcry_ecc_get_curve,
2014     _gcry_ecc_get_param_sexp
2015   };