ecc: Add Ed25519 key generation and prepare for optimizations.
[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 /* Extended version of ecc_generate.  */
1156 static gcry_err_code_t
1157 ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
1158                   const gcry_sexp_t genparms,
1159                   gcry_mpi_t *skey, gcry_mpi_t **retfactors,
1160                   gcry_sexp_t *r_extrainfo)
1161 {
1162   gpg_err_code_t rc;
1163   elliptic_curve_t E;
1164   ECC_secret_key sk;
1165   gcry_mpi_t x = NULL;
1166   gcry_mpi_t y = NULL;
1167   char *curve_name = NULL;
1168   gcry_sexp_t l1;
1169   int transient_key = 0;
1170   gcry_random_level_t random_level;
1171   mpi_ec_t ctx = NULL;
1172
1173   (void)algo;
1174   (void)evalue;
1175
1176   if (genparms)
1177     {
1178       /* Parse the optional "curve" parameter. */
1179       l1 = gcry_sexp_find_token (genparms, "curve", 0);
1180       if (l1)
1181         {
1182           curve_name = _gcry_sexp_nth_string (l1, 1);
1183           gcry_sexp_release (l1);
1184           if (!curve_name)
1185             return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
1186         }
1187
1188       /* Parse the optional transient-key flag.  */
1189       l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
1190       if (l1)
1191         {
1192           transient_key = 1;
1193           gcry_sexp_release (l1);
1194         }
1195     }
1196
1197   /* NBITS is required if no curve name has been given.  */
1198   if (!nbits && !curve_name)
1199     return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
1200
1201   rc = _gcry_ecc_fill_in_curve (nbits, curve_name, &E, &nbits);
1202   gcry_free (curve_name); curve_name = NULL;
1203   if (rc)
1204     goto leave;
1205
1206   if (DBG_CIPHER)
1207     {
1208       log_debug ("ecgen curve info: %s/%s\n",
1209                  _gcry_ecc_model2str (E.model),
1210                  _gcry_ecc_dialect2str (E.dialect));
1211       if (E.name)
1212         log_debug ("ecgen curve used: %s\n", E.name);
1213       log_printmpi ("ecgen curve   p", E.p);
1214       log_printmpi ("ecgen curve   a", E.a);
1215       log_printmpi ("ecgen curve   b", E.b);
1216       log_printmpi ("ecgen curve   n", E.n);
1217       log_printpnt ("ecgen curve G", &E.G, NULL);
1218     }
1219
1220   random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
1221   ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, E.p, E.a, E.b);
1222   x = mpi_new (0);
1223   y = mpi_new (0);
1224
1225   switch (E.dialect)
1226     {
1227     case ECC_DIALECT_STANDARD:
1228       rc = nist_generate_key (&sk, &E, ctx, random_level, nbits);
1229       break;
1230     case ECC_DIALECT_ED25519:
1231       rc = eddsa_generate_key (&sk, &E, ctx, random_level);
1232       break;
1233     default:
1234       rc = GPG_ERR_INTERNAL;
1235       break;
1236     }
1237   if (rc)
1238     goto leave;
1239
1240   /* Copy data to the result.  */
1241   if (_gcry_mpi_ec_get_affine (x, y, &sk.E.G, ctx))
1242     log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "G");
1243   skey[3] = _gcry_ecc_ec2os (x, y, sk.E.p);
1244   if (sk.E.dialect == ECC_DIALECT_ED25519)
1245     {
1246       unsigned char *encpk;
1247       unsigned int encpklen;
1248
1249       rc = eddsa_encodepoint (&sk.Q, 256/8, ctx, x, y, &encpk, &encpklen);
1250       if (rc)
1251         return rc;
1252       skey[5] = mpi_new (0);
1253       gcry_mpi_set_opaque (skey[5], encpk, encpklen*8);
1254       encpk = NULL;
1255       if (DBG_CIPHER)
1256         log_printmpi ("ecgen      e_pk", skey[5]);
1257     }
1258   else
1259     {
1260       if (_gcry_mpi_ec_get_affine (x, y, &sk.Q, ctx))
1261         log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
1262       skey[5] = _gcry_ecc_ec2os (x, y, sk.E.p);
1263     }
1264   skey[0] = sk.E.p; sk.E.p = NULL;
1265   skey[1] = sk.E.a; sk.E.a = NULL;
1266   skey[2] = sk.E.b; sk.E.b = NULL;
1267   skey[4] = sk.E.n; sk.E.n = NULL;
1268   skey[6] = sk.d; sk.d = NULL;
1269
1270   if (E.name)  /* Fixme: No error return checking.  */
1271     gcry_sexp_build (r_extrainfo, NULL, "(curve %s)", E.name);
1272
1273   /* Make an dummy list of factors.  */
1274   *retfactors = gcry_calloc ( 1, sizeof **retfactors );
1275   if (!*retfactors)
1276     {
1277       rc = gpg_err_code_from_syserror ();
1278       goto leave;
1279     }
1280
1281   if (DBG_CIPHER)
1282     {
1283       log_printmpi ("ecgen result  p", skey[0]);
1284       log_printmpi ("ecgen result  a", skey[1]);
1285       log_printmpi ("ecgen result  b", skey[2]);
1286       log_printmpi ("ecgen result  G", skey[3]);
1287       log_printmpi ("ecgen result  n", skey[4]);
1288       log_printmpi ("ecgen result  Q", skey[5]);
1289       log_printmpi ("ecgen result  d", skey[6]);
1290     }
1291   rc = 0;
1292
1293  leave:
1294   point_free (&sk.E.G);
1295   point_free (&sk.Q);
1296   _gcry_mpi_ec_free (ctx);
1297   _gcry_ecc_curve_free (&E);
1298   gcry_mpi_release (x);
1299   gcry_mpi_release (y);
1300   return rc;
1301 }
1302
1303
1304 static gcry_err_code_t
1305 ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
1306               gcry_mpi_t *skey, gcry_mpi_t **retfactors)
1307 {
1308   (void)evalue;
1309   return ecc_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
1310 }
1311
1312
1313 static gcry_err_code_t
1314 ecc_check_secret_key (int algo, gcry_mpi_t *skey)
1315 {
1316   gpg_err_code_t err;
1317   ECC_secret_key sk;
1318
1319   (void)algo;
1320
1321   /* FIXME:  This check looks a bit fishy:  Now long is the array?  */
1322   if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
1323       || !skey[6])
1324     return GPG_ERR_BAD_MPI;
1325
1326   sk.E.model = MPI_EC_WEIERSTRASS;
1327   sk.E.p = skey[0];
1328   sk.E.a = skey[1];
1329   sk.E.b = skey[2];
1330   point_init (&sk.E.G);
1331   err = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1332   if (err)
1333     {
1334       point_free (&sk.E.G);
1335       return err;
1336     }
1337   sk.E.n = skey[4];
1338   point_init (&sk.Q);
1339   err = _gcry_ecc_os2ec (&sk.Q, skey[5]);
1340   if (err)
1341     {
1342       point_free (&sk.E.G);
1343       point_free (&sk.Q);
1344       return err;
1345     }
1346
1347   {
1348     const unsigned char *buf;
1349     unsigned int n;
1350
1351     gcry_assert (mpi_is_opaque (skey[6]));
1352
1353     buf = gcry_mpi_get_opaque (skey[6], &n);
1354     if (!buf)
1355       err = GPG_ERR_INV_OBJ;
1356     else
1357       {
1358         n = (n + 7)/8;
1359         sk.d = NULL;
1360         err = gcry_mpi_scan (&sk.d, GCRYMPI_FMT_USG, buf, n, NULL);
1361         if (!err)
1362           {
1363             if (check_secret_key (&sk))
1364               err = GPG_ERR_BAD_SECKEY;
1365             gcry_mpi_release (sk.d);
1366             sk.d = NULL;
1367           }
1368       }
1369   }
1370
1371   point_free (&sk.E.G);
1372   point_free (&sk.Q);
1373   return err;
1374 }
1375
1376
1377 static gcry_err_code_t
1378 ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey,
1379           int flags, int hashalgo)
1380 {
1381   gpg_err_code_t err;
1382   ECC_secret_key sk;
1383
1384   (void)algo;
1385
1386   if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1387       || !skey[6] )
1388     return GPG_ERR_BAD_MPI;
1389
1390   sk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
1391                 ? MPI_EC_TWISTEDEDWARDS
1392                 : MPI_EC_WEIERSTRASS);
1393   sk.E.p = skey[0];
1394   sk.E.a = skey[1];
1395   sk.E.b = skey[2];
1396   point_init (&sk.E.G);
1397   sk.Q.x = NULL;
1398   sk.Q.y = NULL;
1399   sk.Q.z = NULL;
1400   err = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1401   if (err)
1402     {
1403       point_free (&sk.E.G);
1404       return err;
1405     }
1406   sk.E.n = skey[4];
1407
1408   resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1409   resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1410   {
1411     const unsigned char *buf;
1412     unsigned int n;
1413
1414     gcry_assert (mpi_is_opaque (skey[6]));
1415
1416     buf = gcry_mpi_get_opaque (skey[6], &n);
1417     if (!buf)
1418       err = GPG_ERR_INV_OBJ;
1419     else
1420       {
1421         n = (n + 7)/8;
1422         sk.d = NULL;
1423         err = gcry_mpi_scan (&sk.d, GCRYMPI_FMT_USG, buf, n, NULL);
1424         if (!err)
1425           {
1426             if ((flags & PUBKEY_FLAG_EDDSA))
1427               err = sign_eddsa (data, &sk, resarr[0], resarr[1],
1428                                 hashalgo, skey[5]);
1429             else
1430               err = sign_ecdsa (data, &sk, resarr[0], resarr[1],
1431                                 flags, hashalgo);
1432             gcry_mpi_release (sk.d);
1433             sk.d = NULL;
1434           }
1435       }
1436   }
1437   if (err)
1438     {
1439       mpi_free (resarr[0]);
1440       mpi_free (resarr[1]);
1441       resarr[0] = NULL; /* Mark array as released.  */
1442     }
1443   point_free (&sk.E.G);
1444   if (sk.Q.x)
1445     point_free (&sk.Q);
1446   return err;
1447 }
1448
1449
1450 static gcry_err_code_t
1451 ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
1452             int (*cmp)(void *, gcry_mpi_t), void *opaquev,
1453             int flags, int hashalgo)
1454 {
1455   gpg_err_code_t err;
1456   ECC_public_key pk;
1457
1458   (void)algo;
1459   (void)cmp;
1460   (void)opaquev;
1461
1462   if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2]
1463       || !pkey[3] || !pkey[4] || !pkey[5] )
1464     return GPG_ERR_BAD_MPI;
1465
1466   pk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
1467                 ? MPI_EC_TWISTEDEDWARDS
1468                 : MPI_EC_WEIERSTRASS);
1469   pk.E.p = pkey[0];
1470   pk.E.a = pkey[1];
1471   pk.E.b = pkey[2];
1472   point_init (&pk.E.G);
1473   err = _gcry_ecc_os2ec (&pk.E.G, pkey[3]);
1474   if (err)
1475     {
1476       point_free (&pk.E.G);
1477       return err;
1478     }
1479   pk.E.n = pkey[4];
1480
1481   if ((flags & PUBKEY_FLAG_EDDSA))
1482     {
1483       pk.Q.x = NULL;
1484       pk.Q.y = NULL;
1485       pk.Q.z = NULL;
1486
1487       err = verify_eddsa (hash, &pk, data[0], data[1], hashalgo, pkey[5]);
1488     }
1489   else
1490     {
1491       point_init (&pk.Q);
1492       err = _gcry_ecc_os2ec (&pk.Q, pkey[5]);
1493       if (err)
1494         {
1495           point_free (&pk.E.G);
1496           point_free (&pk.Q);
1497           return err;
1498         }
1499
1500       if (mpi_is_opaque (hash))
1501         {
1502           const void *abuf;
1503           unsigned int abits, qbits;
1504           gcry_mpi_t a;
1505
1506           qbits = mpi_get_nbits (pk.E.n);
1507
1508           abuf = gcry_mpi_get_opaque (hash, &abits);
1509           err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, abuf, (abits+7)/8, NULL);
1510           if (!err)
1511             {
1512               if (abits > qbits)
1513                 gcry_mpi_rshift (a, a, abits - qbits);
1514
1515               err = verify_ecdsa (a, &pk, data[0], data[1]);
1516               gcry_mpi_release (a);
1517             }
1518         }
1519       else
1520         err = verify_ecdsa (hash, &pk, data[0], data[1]);
1521     }
1522
1523   point_free (&pk.E.G);
1524   point_free (&pk.Q);
1525   return err;
1526 }
1527
1528
1529 /* ecdh raw is classic 2-round DH protocol published in 1976.
1530  *
1531  * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
1532  *
1533  * As with any PK operation, encrypt version uses a public key and
1534  * decrypt -- private.
1535  *
1536  * Symbols used below:
1537  *     G - field generator point
1538  *     d - private long-term scalar
1539  *    dG - public long-term key
1540  *     k - ephemeral scalar
1541  *    kG - ephemeral public key
1542  *   dkG - shared secret
1543  *
1544  * ecc_encrypt_raw description:
1545  *   input:
1546  *     data[0] : private scalar (k)
1547  *   output:
1548  *     result[0] : shared point (kdG)
1549  *     result[1] : generated ephemeral public key (kG)
1550  *
1551  * ecc_decrypt_raw description:
1552  *   input:
1553  *     data[0] : a point kG (ephemeral public key)
1554  *   output:
1555  *     result[0] : shared point (kdG)
1556  */
1557 static gcry_err_code_t
1558 ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k,
1559                  gcry_mpi_t *pkey, int flags)
1560 {
1561   ECC_public_key pk;
1562   mpi_ec_t ctx;
1563   gcry_mpi_t result[2];
1564   int err;
1565
1566   (void)algo;
1567   (void)flags;
1568
1569   if (!k
1570       || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5])
1571     return GPG_ERR_BAD_MPI;
1572
1573   pk.E.model = MPI_EC_WEIERSTRASS;
1574   pk.E.p = pkey[0];
1575   pk.E.a = pkey[1];
1576   pk.E.b = pkey[2];
1577   point_init (&pk.E.G);
1578   err = _gcry_ecc_os2ec (&pk.E.G, pkey[3]);
1579   if (err)
1580     {
1581       point_free (&pk.E.G);
1582       return err;
1583     }
1584   pk.E.n = pkey[4];
1585   point_init (&pk.Q);
1586   err = _gcry_ecc_os2ec (&pk.Q, pkey[5]);
1587   if (err)
1588     {
1589       point_free (&pk.E.G);
1590       point_free (&pk.Q);
1591       return err;
1592     }
1593
1594   ctx = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect,
1595                                      pk.E.p, pk.E.a, pk.E.b);
1596
1597   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
1598   {
1599     mpi_point_struct R;  /* Result that we return.  */
1600     gcry_mpi_t x, y;
1601
1602     x = mpi_new (0);
1603     y = mpi_new (0);
1604
1605     point_init (&R);
1606
1607     /* R = kQ  <=>  R = kdG  */
1608     _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx);
1609
1610     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1611       log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
1612
1613     result[0] = _gcry_ecc_ec2os (x, y, pk.E.p);
1614
1615     /* R = kG */
1616     _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx);
1617
1618     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1619       log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
1620
1621     result[1] = _gcry_ecc_ec2os (x, y, pk.E.p);
1622
1623     mpi_free (x);
1624     mpi_free (y);
1625
1626     point_free (&R);
1627   }
1628
1629   _gcry_mpi_ec_free (ctx);
1630   point_free (&pk.E.G);
1631   point_free (&pk.Q);
1632
1633   if (!result[0] || !result[1])
1634     {
1635       mpi_free (result[0]);
1636       mpi_free (result[1]);
1637       return GPG_ERR_ENOMEM;
1638     }
1639
1640   /* Success.  */
1641   resarr[0] = result[0];
1642   resarr[1] = result[1];
1643
1644   return 0;
1645 }
1646
1647 /*  input:
1648  *     data[0] : a point kG (ephemeral public key)
1649  *   output:
1650  *     resaddr[0] : shared point kdG
1651  *
1652  *  see ecc_encrypt_raw for details.
1653  */
1654 static gcry_err_code_t
1655 ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
1656                  gcry_mpi_t *skey, int flags)
1657 {
1658   ECC_secret_key sk;
1659   mpi_point_struct R;   /* Result that we return.  */
1660   mpi_point_struct kG;
1661   mpi_ec_t ctx;
1662   gcry_mpi_t r;
1663   int err;
1664
1665   (void)algo;
1666   (void)flags;
1667
1668   *result = NULL;
1669
1670   if (!data || !data[0]
1671       || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1672       || !skey[5] || !skey[6] )
1673     return GPG_ERR_BAD_MPI;
1674
1675   point_init (&kG);
1676   err = _gcry_ecc_os2ec (&kG, data[0]);
1677   if (err)
1678     {
1679       point_free (&kG);
1680       return err;
1681     }
1682
1683   sk.E.model = MPI_EC_WEIERSTRASS;
1684   sk.E.p = skey[0];
1685   sk.E.a = skey[1];
1686   sk.E.b = skey[2];
1687   point_init (&sk.E.G);
1688   err = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1689   if (err)
1690     {
1691       point_free (&kG);
1692       point_free (&sk.E.G);
1693       return err;
1694     }
1695   sk.E.n = skey[4];
1696   point_init (&sk.Q);
1697   err = _gcry_ecc_os2ec (&sk.Q, skey[5]);
1698   if (err)
1699     {
1700       point_free (&kG);
1701       point_free (&sk.E.G);
1702       point_free (&sk.Q);
1703       return err;
1704     }
1705   sk.d = skey[6];
1706
1707   ctx = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect,
1708                                      sk.E.p, sk.E.a, sk.E.b);
1709
1710   /* R = dkG */
1711   point_init (&R);
1712   _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx);
1713
1714   point_free (&kG);
1715
1716   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so:  */
1717   {
1718     gcry_mpi_t x, y;
1719
1720     x = mpi_new (0);
1721     y = mpi_new (0);
1722
1723     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1724       log_fatal ("ecdh: Failed to get affine coordinates\n");
1725
1726     r = _gcry_ecc_ec2os (x, y, sk.E.p);
1727     mpi_free (x);
1728     mpi_free (y);
1729   }
1730
1731   point_free (&R);
1732   _gcry_mpi_ec_free (ctx);
1733   point_free (&kG);
1734   point_free (&sk.E.G);
1735   point_free (&sk.Q);
1736
1737   if (!r)
1738     return GPG_ERR_ENOMEM;
1739
1740   /* Success.  */
1741
1742   *result = r;
1743
1744   return 0;
1745 }
1746
1747
1748 static unsigned int
1749 ecc_get_nbits (int algo, gcry_mpi_t *pkey)
1750 {
1751   (void)algo;
1752
1753   return mpi_get_nbits (pkey[0]);
1754 }
1755
1756
1757 /* See rsa.c for a description of this function.  */
1758 static gpg_err_code_t
1759 compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
1760 {
1761 #define N_COMPONENTS 6
1762   static const char names[N_COMPONENTS+1] = "pabgnq";
1763   gpg_err_code_t ec = 0;
1764   gcry_sexp_t l1;
1765   gcry_mpi_t values[N_COMPONENTS];
1766   int idx;
1767
1768   /* Clear the values for easier error cleanup.  */
1769   for (idx=0; idx < N_COMPONENTS; idx++)
1770     values[idx] = NULL;
1771
1772   /* Fill values with all provided parameters.  */
1773   for (idx=0; idx < N_COMPONENTS; idx++)
1774     {
1775       l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
1776       if (l1)
1777         {
1778           values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1779           gcry_sexp_release (l1);
1780           if (!values[idx])
1781             {
1782               ec = GPG_ERR_INV_OBJ;
1783               goto leave;
1784             }
1785         }
1786     }
1787
1788   /* Check whether a curve parameter is available and use that to fill
1789      in missing values.  */
1790   l1 = gcry_sexp_find_token (keyparam, "curve", 5);
1791   if (l1)
1792     {
1793       char *curve;
1794       gcry_mpi_t tmpvalues[N_COMPONENTS];
1795
1796       for (idx = 0; idx < N_COMPONENTS; idx++)
1797         tmpvalues[idx] = NULL;
1798
1799       curve = _gcry_sexp_nth_string (l1, 1);
1800       gcry_sexp_release (l1);
1801       if (!curve)
1802         {
1803           ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
1804           goto leave;
1805         }
1806       ec = _gcry_ecc_get_param (curve, tmpvalues);
1807       gcry_free (curve);
1808       if (ec)
1809         goto leave;
1810
1811       for (idx = 0; idx < N_COMPONENTS; idx++)
1812         {
1813           if (!values[idx])
1814             values[idx] = tmpvalues[idx];
1815           else
1816             mpi_free (tmpvalues[idx]);
1817         }
1818     }
1819
1820   /* Check that all parameters are known and normalize all MPIs (that
1821      should not be required but we use an internal function later and
1822      thus we better make 100% sure that they are normalized). */
1823   for (idx = 0; idx < N_COMPONENTS; idx++)
1824     if (!values[idx])
1825       {
1826         ec = GPG_ERR_NO_OBJ;
1827         goto leave;
1828       }
1829     else
1830       _gcry_mpi_normalize (values[idx]);
1831
1832   /* Hash them all.  */
1833   for (idx = 0; idx < N_COMPONENTS; idx++)
1834     {
1835       char buf[30];
1836       unsigned char *rawmpi;
1837       unsigned int rawmpilen;
1838
1839       rawmpi = _gcry_mpi_get_buffer (values[idx], 0, &rawmpilen, NULL);
1840       if (!rawmpi)
1841         {
1842           ec = gpg_err_code_from_syserror ();
1843           goto leave;
1844         }
1845       snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
1846       gcry_md_write (md, buf, strlen (buf));
1847       gcry_md_write (md, rawmpi, rawmpilen);
1848       gcry_md_write (md, ")", 1);
1849       gcry_free (rawmpi);
1850     }
1851
1852  leave:
1853   for (idx = 0; idx < N_COMPONENTS; idx++)
1854     _gcry_mpi_release (values[idx]);
1855
1856   return ec;
1857 #undef N_COMPONENTS
1858 }
1859
1860
1861 \f
1862 /*
1863    Low-level API helper functions.
1864  */
1865
1866 /* This is the wroker function for gcry_pubkey_get_sexp for ECC
1867    algorithms.  Note that the caller has already stored NULL at
1868    R_SEXP.  */
1869 gpg_err_code_t
1870 _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
1871 {
1872   gpg_err_code_t rc;
1873   gcry_mpi_t mpi_G = NULL;
1874   gcry_mpi_t mpi_Q = NULL;
1875
1876   if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n)
1877     return GPG_ERR_BAD_CRYPT_CTX;
1878
1879   if (mode == GCRY_PK_GET_SECKEY && !ec->d)
1880     return GPG_ERR_NO_SECKEY;
1881
1882   /* Compute the public point if it is missing.  */
1883   if (!ec->Q && ec->d)
1884     {
1885       ec->Q = gcry_mpi_point_new (0);
1886       _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec);
1887     }
1888
1889   /* Encode G and Q.  */
1890   mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec);
1891   if (!mpi_G)
1892     {
1893       rc = GPG_ERR_BROKEN_PUBKEY;
1894       goto leave;
1895     }
1896   if (!ec->Q)
1897     {
1898       rc = GPG_ERR_BAD_CRYPT_CTX;
1899       goto leave;
1900     }
1901   mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec);
1902   if (!mpi_Q)
1903     {
1904       rc = GPG_ERR_BROKEN_PUBKEY;
1905       goto leave;
1906     }
1907
1908   /* Fixme: We should return a curve name instead of the parameters if
1909      if know that they match a curve.  */
1910
1911   if (ec->d && (!mode || mode == GCRY_PK_GET_SECKEY))
1912     {
1913       /* Let's return a private key. */
1914       rc = gpg_err_code
1915         (gcry_sexp_build
1916          (r_sexp, NULL,
1917           "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))",
1918           ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q, ec->d));
1919     }
1920   else if (ec->Q)
1921     {
1922       /* Let's return a public key.  */
1923       rc = gpg_err_code
1924         (gcry_sexp_build
1925          (r_sexp, NULL,
1926           "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))",
1927           ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q));
1928     }
1929   else
1930     rc = GPG_ERR_BAD_CRYPT_CTX;
1931
1932  leave:
1933   mpi_free (mpi_Q);
1934   mpi_free (mpi_G);
1935   return rc;
1936 }
1937
1938
1939 \f
1940 /*
1941      Self-test section.
1942  */
1943
1944
1945 static gpg_err_code_t
1946 selftests_ecdsa (selftest_report_func_t report)
1947 {
1948   const char *what;
1949   const char *errtxt;
1950
1951   what = "low-level";
1952   errtxt = NULL; /*selftest ();*/
1953   if (errtxt)
1954     goto failed;
1955
1956   /* FIXME:  need more tests.  */
1957
1958   return 0; /* Succeeded. */
1959
1960  failed:
1961   if (report)
1962     report ("pubkey", GCRY_PK_ECDSA, what, errtxt);
1963   return GPG_ERR_SELFTEST_FAILED;
1964 }
1965
1966
1967 /* Run a full self-test for ALGO and return 0 on success.  */
1968 static gpg_err_code_t
1969 run_selftests (int algo, int extended, selftest_report_func_t report)
1970 {
1971   gpg_err_code_t ec;
1972
1973   (void)extended;
1974
1975   switch (algo)
1976     {
1977     case GCRY_PK_ECDSA:
1978       ec = selftests_ecdsa (report);
1979       break;
1980     default:
1981       ec = GPG_ERR_PUBKEY_ALGO;
1982       break;
1983
1984     }
1985   return ec;
1986 }
1987
1988
1989
1990 \f
1991 static const char *ecdsa_names[] =
1992   {
1993     "ecdsa",
1994     "ecc",
1995     NULL,
1996   };
1997 static const char *ecdh_names[] =
1998   {
1999     "ecdh",
2000     "ecc",
2001     NULL,
2002   };
2003
2004 gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
2005   {
2006     "ECDSA", ecdsa_names,
2007     "pabgnq", "pabgnqd", "", "rs", "pabgnq",
2008     GCRY_PK_USAGE_SIGN,
2009     ecc_generate,
2010     ecc_check_secret_key,
2011     NULL,
2012     NULL,
2013     ecc_sign,
2014     ecc_verify,
2015     ecc_get_nbits
2016   };
2017
2018 gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
2019   {
2020     "ECDH", ecdh_names,
2021     "pabgnq", "pabgnqd", "se", "", "pabgnq",
2022     GCRY_PK_USAGE_ENCR,
2023     ecc_generate,
2024     ecc_check_secret_key,
2025     ecc_encrypt_raw,
2026     ecc_decrypt_raw,
2027     NULL,
2028     NULL,
2029     ecc_get_nbits
2030   };
2031
2032
2033 pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa =
2034   {
2035     run_selftests,
2036     ecc_generate_ext,
2037     compute_keygrip,
2038     _gcry_ecc_get_param,
2039     _gcry_ecc_get_curve,
2040     _gcry_ecc_get_param_sexp
2041   };