ecc: Allow the use of an uncompressed public key.
[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 (X,Y) using the EdDSA scheme.  MINLEN is the required length
610    in bytes for the result.  On success 0 is returned and a malloced
611    buffer with the encoded point is stored at R_BUFFER; the length of
612    this buffer is stored at R_BUFLEN.  */
613 static gpg_err_code_t
614 eddsa_encode_x_y (gcry_mpi_t x, gcry_mpi_t y, unsigned int minlen,
615                   unsigned char **r_buffer, unsigned int *r_buflen)
616 {
617   unsigned char *rawmpi;
618   unsigned int rawmpilen;
619
620   rawmpi = _gcry_mpi_get_buffer (y, minlen, &rawmpilen, NULL);
621   if (!rawmpi)
622     return gpg_err_code_from_syserror ();
623   if (mpi_test_bit (x, 0) && rawmpilen)
624     rawmpi[rawmpilen - 1] |= 0x80;  /* Set sign bit.  */
625
626   *r_buffer = rawmpi;
627   *r_buflen = rawmpilen;
628   return 0;
629 }
630
631 /* Encode POINT using the EdDSA scheme.  X and Y are scratch variables
632    supplied by the caller and CTX is the usual context.  MINLEN is the
633    required length in bytes for the result. On success 0 is returned
634    and a malloced buffer with the encoded point is stored at R_BUFFER;
635    the length of this buffer is stored at R_BUFLEN.  */
636 static gpg_err_code_t
637 eddsa_encodepoint (mpi_point_t point, unsigned int minlen, mpi_ec_t ctx,
638                    gcry_mpi_t x, gcry_mpi_t y,
639                    unsigned char **r_buffer, unsigned int *r_buflen)
640 {
641   if (_gcry_mpi_ec_get_affine (x, y, point, ctx))
642     {
643       log_error ("eddsa_encodepoint: Failed to get affine coordinates\n");
644       return GPG_ERR_INTERNAL;
645     }
646   return eddsa_encode_x_y (x, y, minlen, r_buffer, r_buflen);
647 }
648
649
650 /* Decode the EdDSA style encoded PK and set it into RESULT.  LEN is
651    the expected length in bytes of the encoded key and CTX the usual
652    curve context.  If R_ENCPK is not NULL, the encoded PK is stored at
653    that address; this is a new copy to be released by the caller.  In
654    contrast to the supplied PK, this is not an MPI and thus guarnateed
655    to be properly padded.  R_ENCPKLEN received the length of that
656    encoded key.  */
657 static gpg_err_code_t
658 eddsa_decodepoint (gcry_mpi_t pk, unsigned int len, mpi_ec_t ctx,
659                    mpi_point_t result,
660                    unsigned char **r_encpk, unsigned int *r_encpklen)
661 {
662   gpg_err_code_t rc;
663   unsigned char *rawmpi;
664   unsigned int rawmpilen;
665   gcry_mpi_t yy, t, x, p1, p2, p3;
666   int sign;
667
668   if (mpi_is_opaque (pk))
669     {
670       const unsigned char *buf;
671
672       buf = gcry_mpi_get_opaque (pk, &rawmpilen);
673       if (!buf)
674         return GPG_ERR_INV_OBJ;
675       rawmpilen = (rawmpilen + 7)/8;
676
677       /* First check whether the public key has been given in standard
678          uncompressed format.  No need to recover x in this case.
679          Detection is easy: The size of the buffer will be odd and the
680          first byte be 0x04.  */
681       if (rawmpilen > 1 && buf[0] == 0x04 && (rawmpilen%2))
682         {
683           gcry_mpi_t y;
684
685           rc = gcry_mpi_scan (&x, GCRYMPI_FMT_STD,
686                               buf+1, (rawmpilen-1)/2, NULL);
687           if (rc)
688             return rc;
689           rc = gcry_mpi_scan (&y, GCRYMPI_FMT_STD,
690                               buf+1+(rawmpilen-1)/2, (rawmpilen-1)/2, NULL);
691           if (rc)
692             {
693               mpi_free (x);
694               return rc;
695             }
696
697           if (r_encpk)
698             {
699               rc = eddsa_encode_x_y (x, y, len, r_encpk, r_encpklen);
700               if (rc)
701                 {
702                   mpi_free (x);
703                   mpi_free (y);
704                   return rc;
705                 }
706             }
707           mpi_snatch (result->x, x);
708           mpi_snatch (result->y, y);
709           mpi_set_ui (result->z, 1);
710           return 0;
711         }
712
713       /* EdDSA compressed point.  */
714       rawmpi = gcry_malloc (rawmpilen? rawmpilen:1);
715       if (!rawmpi)
716         return gpg_err_code_from_syserror ();
717       memcpy (rawmpi, buf, rawmpilen);
718       reverse_buffer (rawmpi, rawmpilen);
719     }
720   else
721     {
722       /* Note: Without using an opaque MPI it is not reliable possible
723          to find out whether the public key has been given in
724          uncompressed format.  Thus we expect EdDSA format here.  */
725       rawmpi = _gcry_mpi_get_buffer (pk, len, &rawmpilen, NULL);
726       if (!rawmpi)
727         return gpg_err_code_from_syserror ();
728     }
729
730   if (rawmpilen)
731     {
732       sign = !!(rawmpi[0] & 0x80);
733       rawmpi[0] &= 0x7f;
734     }
735   else
736     sign = 0;
737   _gcry_mpi_set_buffer (result->y, rawmpi, rawmpilen, 0);
738   if (r_encpk)
739     {
740       /* Revert to little endian.  */
741       if (sign && rawmpilen)
742         rawmpi[0] |= 0x80;
743       reverse_buffer (rawmpi, rawmpilen);
744       *r_encpk = rawmpi;
745       if (r_encpklen)
746         *r_encpklen = rawmpilen;
747     }
748   else
749     gcry_free (rawmpi);
750
751   /* Now recover X.  */
752   /* t = (y^2-1) · ((b*y^2+1)^{p-2} mod p) */
753   x = mpi_new (0);
754   yy = mpi_new (0);
755   mpi_mul (yy, result->y, result->y);
756   t = mpi_copy (yy);
757   mpi_mul (t, t, ctx->b);
758   mpi_add_ui (t, t, 1);
759   p2 = mpi_copy (ctx->p);
760   mpi_sub_ui (p2, p2, 2);
761   mpi_powm (t, t, p2, ctx->p);
762
763   mpi_sub_ui (yy, yy, 1);
764   mpi_mul (t, yy, t);
765
766   /* x = t^{(p+3)/8} mod p */
767   p3 = mpi_copy (ctx->p);
768   mpi_add_ui (p3, p3, 3);
769   mpi_fdiv_q (p3, p3, mpi_const (MPI_C_EIGHT));
770   mpi_powm (x, t, p3, ctx->p);
771
772   /* (x^2 - t) % p != 0 ? x = (x*(2^{(p-1)/4} mod p)) % p */
773   mpi_mul (yy, x, x);
774   mpi_subm (yy, yy, t, ctx->p);
775   if (mpi_cmp_ui (yy, 0))
776     {
777       p1 = mpi_copy (ctx->p);
778       mpi_sub_ui (p1, p1, 1);
779       mpi_fdiv_q (p1, p1, mpi_const (MPI_C_FOUR));
780       mpi_powm (yy, mpi_const (MPI_C_TWO), p1, ctx->p);
781       mpi_mulm (x, x, yy, ctx->p);
782     }
783   else
784     p1 = NULL;
785
786   /* is_odd(x) ? x = p-x */
787   if (mpi_test_bit (x, 0))
788     mpi_sub (x, ctx->p, x);
789
790   /* lowbit(x) != highbit(input) ?  x = p-x */
791   if (mpi_test_bit (x, 0) != sign)
792     mpi_sub (x, ctx->p, x);
793
794   mpi_set (result->x, x);
795   mpi_set_ui (result->z, 1);
796
797   gcry_mpi_release (x);
798   gcry_mpi_release (yy);
799   gcry_mpi_release (t);
800   gcry_mpi_release (p3);
801   gcry_mpi_release (p2);
802   gcry_mpi_release (p1);
803
804   return 0;
805 }
806
807
808 /* Ed25519 version of the key generation.  */
809 static gpg_err_code_t
810 eddsa_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
811                     gcry_random_level_t random_level)
812 {
813   gpg_err_code_t rc;
814   int b = 256/8;             /* The only size we currently support.  */
815   gcry_mpi_t a, x, y;
816   mpi_point_struct Q;
817   char *dbuf;
818   size_t dlen;
819   gcry_buffer_t hvec[1];
820   unsigned char *hash_d = NULL;
821
822   point_init (&Q);
823   memset (hvec, 0, sizeof hvec);
824
825   a = mpi_snew (0);
826   x = mpi_new (0);
827   y = mpi_new (0);
828
829   /* Generate a secret.  */
830   hash_d = gcry_malloc_secure (2*b);
831   if (!hash_d)
832     {
833       rc = gpg_error_from_syserror ();
834       goto leave;
835     }
836   dlen = b;
837   dbuf = gcry_random_bytes_secure (dlen, random_level);
838
839   /* Compute the A value.  */
840   hvec[0].data = dbuf;
841   hvec[0].len = dlen;
842   rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, hash_d, hvec, 1);
843   if (rc)
844     goto leave;
845   sk->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8);
846   dbuf = NULL;
847   reverse_buffer (hash_d, 32);  /* Only the first half of the hash.  */
848   hash_d[0] = (hash_d[0] & 0x7f) | 0x40;
849   hash_d[31] &= 0xf8;
850   _gcry_mpi_set_buffer (a, hash_d, 32, 0);
851   gcry_free (hash_d); hash_d = NULL;
852   /* log_printmpi ("ecgen         a", a); */
853
854   /* Compute Q.  */
855   _gcry_mpi_ec_mul_point (&Q, a, &E->G, ctx);
856   if (DBG_CIPHER)
857     log_printpnt ("ecgen      pk", &Q, ctx);
858
859   /* Copy the stuff to the key structures. */
860   sk->E.model = E->model;
861   sk->E.dialect = E->dialect;
862   sk->E.p = mpi_copy (E->p);
863   sk->E.a = mpi_copy (E->a);
864   sk->E.b = mpi_copy (E->b);
865   point_init (&sk->E.G);
866   point_set (&sk->E.G, &E->G);
867   sk->E.n = mpi_copy (E->n);
868   point_init (&sk->Q);
869   point_set (&sk->Q, &Q);
870
871  leave:
872   gcry_mpi_release (a);
873   gcry_mpi_release (x);
874   gcry_mpi_release (y);
875   gcry_free (hash_d);
876   return rc;
877 }
878
879
880 /* Compute an EdDSA signature. See:
881  *   [ed25519] 23pp. (PDF) Daniel J. Bernstein, Niels Duif, Tanja
882  *   Lange, Peter Schwabe, Bo-Yin Yang. High-speed high-security
883  *   signatures.  Journal of Cryptographic Engineering 2 (2012), 77-89.
884  *   Document ID: a1a62a2f76d23f65d622484ddd09caf8.
885  *   URL: http://cr.yp.to/papers.html#ed25519. Date: 2011.09.26.
886  *
887  * Despite that this function requires the specification of a hash
888  * algorithm, we only support what has been specified by the paper.
889  * This may change in the future.  Note that we don't check the used
890  * curve; the user is responsible to use Ed25519.
891  *
892  * Return the signature struct (r,s) from the message hash.  The caller
893  * must have allocated R_R and S.
894  */
895 static gpg_err_code_t
896 sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey,
897             gcry_mpi_t r_r, gcry_mpi_t s, int hashalgo, gcry_mpi_t pk)
898 {
899   int rc;
900   mpi_ec_t ctx = NULL;
901   int b = 256/8;             /* The only size we currently support.  */
902   unsigned int tmp;
903   unsigned char hash_d[64];  /* Fixme: malloc in secure memory */
904   unsigned char digest[64];
905   gcry_buffer_t hvec[3];
906   const void *mbuf;
907   size_t mlen;
908   unsigned char *rawmpi = NULL;
909   unsigned int rawmpilen;
910   unsigned char *encpk = NULL; /* Encoded public key.  */
911   unsigned int encpklen;
912   mpi_point_struct I;          /* Intermediate value.  */
913   mpi_point_struct Q;          /* Public key.  */
914   gcry_mpi_t a, x, y, r;
915
916   memset (hvec, 0, sizeof hvec);
917
918   if (!mpi_is_opaque (input))
919     return GPG_ERR_INV_DATA;
920   if (hashalgo != GCRY_MD_SHA512)
921     return GPG_ERR_DIGEST_ALGO;
922
923   /* Initialize some helpers.  */
924   point_init (&I);
925   point_init (&Q);
926   a = mpi_snew (0);
927   x = mpi_new (0);
928   y = mpi_new (0);
929   r = mpi_new (0);
930   ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
931                                      skey->E.p, skey->E.a, skey->E.b);
932
933   /* Hash the secret key.  We clear DIGEST so we can use it to left
934      pad the key with zeroes for hashing.  */
935   rawmpi = _gcry_mpi_get_buffer (skey->d, 0, &rawmpilen, NULL);
936   if (!rawmpi)
937     {
938       rc = gpg_err_code_from_syserror ();
939       goto leave;
940     }
941   memset (digest, 0, b);
942   hvec[0].data = digest;
943   hvec[0].off = 0;
944   hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
945   hvec[1].data = rawmpi;
946   hvec[1].off = 0;
947   hvec[1].len = rawmpilen;
948   rc = _gcry_md_hash_buffers (hashalgo, 0, hash_d, hvec, 2);
949   gcry_free (rawmpi); rawmpi = NULL;
950   if (rc)
951     goto leave;
952
953   /* Compute the A value (this modifies hash_d).  */
954   reverse_buffer (hash_d, 32);  /* Only the first half of the hash.  */
955   hash_d[0] = (hash_d[0] & 0x7f) | 0x40;
956   hash_d[31] &= 0xf8;
957   _gcry_mpi_set_buffer (a, hash_d, 32, 0);
958   /* log_printmpi ("     a", a); */
959
960   /* Compute the public key if it has not been supplied as optional
961      parameter.  */
962   if (pk)
963     {
964       rc = eddsa_decodepoint (pk, b, ctx, &Q,  &encpk, &encpklen);
965       if (rc)
966         goto leave;
967       if (DBG_CIPHER)
968         log_printhex ("* e_pk", encpk, encpklen);
969       if (!_gcry_mpi_ec_curve_point (&Q, ctx))
970         {
971           rc = GPG_ERR_BROKEN_PUBKEY;
972           goto leave;
973         }
974     }
975   else
976     {
977       _gcry_mpi_ec_mul_point (&Q, a, &skey->E.G, ctx);
978       rc = eddsa_encodepoint (&Q, b, ctx, x, y, &encpk, &encpklen);
979       if (rc)
980         goto leave;
981       if (DBG_CIPHER)
982         log_printhex ("  e_pk", encpk, encpklen);
983     }
984
985   /* Compute R.  */
986   mbuf = gcry_mpi_get_opaque (input, &tmp);
987   mlen = (tmp +7)/8;
988   if (DBG_CIPHER)
989     log_printhex ("     m", mbuf, mlen);
990
991   hvec[0].data = hash_d;
992   hvec[0].off  = 32;
993   hvec[0].len  = 32;
994   hvec[1].data = (char*)mbuf;
995   hvec[1].len  = mlen;
996   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
997   if (rc)
998     goto leave;
999   reverse_buffer (digest, 64);
1000   if (DBG_CIPHER)
1001     log_printhex ("     r", digest, 64);
1002   _gcry_mpi_set_buffer (r, digest, 64, 0);
1003   _gcry_mpi_ec_mul_point (&I, r, &skey->E.G, ctx);
1004   if (DBG_CIPHER)
1005     log_printpnt ("   r", &I, ctx);
1006
1007   /* Convert R into affine coordinates and apply encoding.  */
1008   rc = eddsa_encodepoint (&I, b, ctx, x, y, &rawmpi, &rawmpilen);
1009   if (rc)
1010     goto leave;
1011   if (DBG_CIPHER)
1012     log_printhex ("   e_r", rawmpi, rawmpilen);
1013
1014   /* S = r + a * H(encodepoint(R) + encodepoint(pk) + m) mod n  */
1015   hvec[0].data = rawmpi;  /* (this is R) */
1016   hvec[0].off  = 0;
1017   hvec[0].len  = rawmpilen;
1018   hvec[1].data = encpk;
1019   hvec[1].off  = 0;
1020   hvec[1].len  = encpklen;
1021   hvec[2].data = (char*)mbuf;
1022   hvec[2].off  = 0;
1023   hvec[2].len  = mlen;
1024   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
1025   if (rc)
1026     goto leave;
1027
1028   /* No more need for RAWMPI thus we now transfer it to R_R.  */
1029   gcry_mpi_set_opaque (r_r, rawmpi, rawmpilen*8);
1030   rawmpi = NULL;
1031
1032   reverse_buffer (digest, 64);
1033   if (DBG_CIPHER)
1034     log_printhex (" H(R+)", digest, 64);
1035   _gcry_mpi_set_buffer (s, digest, 64, 0);
1036   mpi_mulm (s, s, a, skey->E.n);
1037   mpi_addm (s, s, r, skey->E.n);
1038   rc = eddsa_encodempi (s, b, &rawmpi, &rawmpilen);
1039   if (rc)
1040     goto leave;
1041   if (DBG_CIPHER)
1042     log_printhex ("   e_s", rawmpi, rawmpilen);
1043   gcry_mpi_set_opaque (s, rawmpi, rawmpilen*8);
1044   rawmpi = NULL;
1045
1046   rc = 0;
1047
1048  leave:
1049   gcry_mpi_release (a);
1050   gcry_mpi_release (x);
1051   gcry_mpi_release (y);
1052   gcry_mpi_release (r);
1053   _gcry_mpi_ec_free (ctx);
1054   point_free (&I);
1055   point_free (&Q);
1056   gcry_free (encpk);
1057   gcry_free (rawmpi);
1058   return rc;
1059 }
1060
1061
1062 /* Verify an EdDSA signature.  See sign_eddsa for the reference.
1063  * Check if R_IN and S_IN verifies INPUT.  PKEY has the curve
1064  * parameters and PK is the EdDSA style encoded public key.
1065  */
1066 static gpg_err_code_t
1067 verify_eddsa (gcry_mpi_t input, ECC_public_key *pkey,
1068               gcry_mpi_t r_in, gcry_mpi_t s_in, int hashalgo, gcry_mpi_t pk)
1069 {
1070   int rc;
1071   mpi_ec_t ctx = NULL;
1072   int b = 256/8;               /* The only size we currently support.  */
1073   unsigned int tmp;
1074   mpi_point_struct Q;          /* Public key.  */
1075   unsigned char *encpk = NULL; /* Encoded public key.  */
1076   unsigned int encpklen;
1077   const void *mbuf, *rbuf;
1078   unsigned char *tbuf = NULL;
1079   size_t mlen, rlen;
1080   unsigned int tlen;
1081   unsigned char digest[64];
1082   gcry_buffer_t hvec[3];
1083   gcry_mpi_t h, s;
1084   mpi_point_struct Ia, Ib;
1085
1086   if (!mpi_is_opaque (input) || !mpi_is_opaque (r_in) || !mpi_is_opaque (s_in))
1087     return GPG_ERR_INV_DATA;
1088   if (hashalgo != GCRY_MD_SHA512)
1089     return GPG_ERR_DIGEST_ALGO;
1090
1091   point_init (&Q);
1092   point_init (&Ia);
1093   point_init (&Ib);
1094   h = mpi_new (0);
1095   s = mpi_new (0);
1096
1097   ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect,
1098                                      pkey->E.p, pkey->E.a, pkey->E.b);
1099
1100   /* Decode and check the public key.  */
1101   rc = eddsa_decodepoint (pk, b, ctx, &Q, &encpk, &encpklen);
1102   if (rc)
1103     goto leave;
1104   if (!_gcry_mpi_ec_curve_point (&Q, ctx))
1105     {
1106       rc = GPG_ERR_BROKEN_PUBKEY;
1107       goto leave;
1108     }
1109   if (DBG_CIPHER)
1110     log_printhex ("  e_pk", encpk, encpklen);
1111   if (encpklen != b)
1112     {
1113       rc = GPG_ERR_INV_LENGTH;
1114       goto leave;
1115     }
1116
1117   /* Convert the other input parameters.  */
1118   mbuf = gcry_mpi_get_opaque (input, &tmp);
1119   mlen = (tmp +7)/8;
1120   if (DBG_CIPHER)
1121     log_printhex ("     m", mbuf, mlen);
1122   rbuf = gcry_mpi_get_opaque (r_in, &tmp);
1123   rlen = (tmp +7)/8;
1124   if (DBG_CIPHER)
1125     log_printhex ("     r", rbuf, rlen);
1126   if (rlen != b)
1127     {
1128       rc = GPG_ERR_INV_LENGTH;
1129       goto leave;
1130     }
1131
1132   /* h = H(encodepoint(R) + encodepoint(pk) + m)  */
1133   hvec[0].data = (char*)rbuf;
1134   hvec[0].off  = 0;
1135   hvec[0].len  = rlen;
1136   hvec[1].data = encpk;
1137   hvec[1].off  = 0;
1138   hvec[1].len  = encpklen;
1139   hvec[2].data = (char*)mbuf;
1140   hvec[2].off  = 0;
1141   hvec[2].len  = mlen;
1142   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
1143   if (rc)
1144     goto leave;
1145   reverse_buffer (digest, 64);
1146   if (DBG_CIPHER)
1147     log_printhex (" H(R+)", digest, 64);
1148   _gcry_mpi_set_buffer (h, digest, 64, 0);
1149
1150   /* According to the paper the best way for verification is:
1151          encodepoint(sG - h·Q) = encodepoint(r)
1152      because we don't need to decode R. */
1153   {
1154     void *sbuf;
1155     unsigned int slen;
1156
1157     sbuf = _gcry_mpi_get_opaque_copy (s_in, &tmp);
1158     slen = (tmp +7)/8;
1159     reverse_buffer (sbuf, slen);
1160     if (DBG_CIPHER)
1161       log_printhex ("     s", sbuf, slen);
1162     _gcry_mpi_set_buffer (s, sbuf, slen, 0);
1163     gcry_free (sbuf);
1164     if (slen != b)
1165       {
1166         rc = GPG_ERR_INV_LENGTH;
1167         goto leave;
1168       }
1169   }
1170
1171   _gcry_mpi_ec_mul_point (&Ia, s, &pkey->E.G, ctx);
1172   _gcry_mpi_ec_mul_point (&Ib, h, &Q, ctx);
1173   _gcry_mpi_neg (Ib.x, Ib.x);
1174   _gcry_mpi_ec_add_points (&Ia, &Ia, &Ib, ctx);
1175   rc = eddsa_encodepoint (&Ia, b, ctx, s, h, &tbuf, &tlen);
1176   if (rc)
1177     goto leave;
1178   if (tlen != rlen || memcmp (tbuf, rbuf, tlen))
1179     {
1180       if (DBG_CIPHER)
1181         log_debug ("eddsa verify: Not verified\n");
1182       rc = GPG_ERR_BAD_SIGNATURE;
1183       goto leave;
1184     }
1185
1186   if (DBG_CIPHER)
1187     log_debug ("eddsa verify: Accepted\n");
1188   rc = 0;
1189
1190  leave:
1191   gcry_free (encpk);
1192   gcry_free (tbuf);
1193   _gcry_mpi_ec_free (ctx);
1194   gcry_mpi_release (s);
1195   gcry_mpi_release (h);
1196   point_free (&Ia);
1197   point_free (&Ib);
1198   point_free (&Q);
1199   return rc;
1200 }
1201
1202
1203 \f
1204 /*********************************************
1205  **************  interface  ******************
1206  *********************************************/
1207
1208 static gcry_err_code_t
1209 ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
1210               const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
1211 {
1212   gpg_err_code_t rc;
1213   elliptic_curve_t E;
1214   ECC_secret_key sk;
1215   gcry_mpi_t x = NULL;
1216   gcry_mpi_t y = NULL;
1217   char *curve_name = NULL;
1218   gcry_sexp_t l1;
1219   int transient_key = 0;
1220   gcry_random_level_t random_level;
1221   mpi_ec_t ctx = NULL;
1222   gcry_sexp_t curve_info = NULL;
1223   gcry_mpi_t base = NULL;
1224   gcry_mpi_t public = NULL;
1225   gcry_mpi_t secret = NULL;
1226
1227   (void)algo;
1228   (void)evalue;
1229
1230   memset (&E, 0, sizeof E);
1231   memset (&sk, 0, sizeof sk);
1232
1233   if (genparms)
1234     {
1235       /* Parse the optional "curve" parameter. */
1236       l1 = gcry_sexp_find_token (genparms, "curve", 0);
1237       if (l1)
1238         {
1239           curve_name = _gcry_sexp_nth_string (l1, 1);
1240           gcry_sexp_release (l1);
1241           if (!curve_name)
1242             return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
1243         }
1244
1245       /* Parse the optional transient-key flag.  */
1246       l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
1247       if (l1)
1248         {
1249           transient_key = 1;
1250           gcry_sexp_release (l1);
1251         }
1252     }
1253
1254   /* NBITS is required if no curve name has been given.  */
1255   if (!nbits && !curve_name)
1256     return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
1257
1258   rc = _gcry_ecc_fill_in_curve (nbits, curve_name, &E, &nbits);
1259   gcry_free (curve_name); curve_name = NULL;
1260   if (rc)
1261     goto leave;
1262
1263   if (DBG_CIPHER)
1264     {
1265       log_debug ("ecgen curve info: %s/%s\n",
1266                  _gcry_ecc_model2str (E.model),
1267                  _gcry_ecc_dialect2str (E.dialect));
1268       if (E.name)
1269         log_debug ("ecgen curve used: %s\n", E.name);
1270       log_printmpi ("ecgen curve   p", E.p);
1271       log_printmpi ("ecgen curve   a", E.a);
1272       log_printmpi ("ecgen curve   b", E.b);
1273       log_printmpi ("ecgen curve   n", E.n);
1274       log_printpnt ("ecgen curve G", &E.G, NULL);
1275     }
1276
1277   random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
1278   ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, E.p, E.a, E.b);
1279   x = mpi_new (0);
1280   y = mpi_new (0);
1281
1282   switch (E.dialect)
1283     {
1284     case ECC_DIALECT_STANDARD:
1285       rc = nist_generate_key (&sk, &E, ctx, random_level, nbits);
1286       break;
1287     case ECC_DIALECT_ED25519:
1288       rc = eddsa_generate_key (&sk, &E, ctx, random_level);
1289       break;
1290     default:
1291       rc = GPG_ERR_INTERNAL;
1292       break;
1293     }
1294   if (rc)
1295     goto leave;
1296
1297   /* Copy data to the result.  */
1298   if (_gcry_mpi_ec_get_affine (x, y, &sk.E.G, ctx))
1299     log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "G");
1300   base = _gcry_ecc_ec2os (x, y, sk.E.p);
1301   if (sk.E.dialect == ECC_DIALECT_ED25519)
1302     {
1303       unsigned char *encpk;
1304       unsigned int encpklen;
1305
1306       rc = eddsa_encodepoint (&sk.Q, 256/8, ctx, x, y, &encpk, &encpklen);
1307       if (rc)
1308         return rc;
1309       public = mpi_new (0);
1310       gcry_mpi_set_opaque (public, encpk, encpklen*8);
1311       encpk = NULL;
1312     }
1313   else
1314     {
1315       if (_gcry_mpi_ec_get_affine (x, y, &sk.Q, ctx))
1316         log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
1317       public = _gcry_ecc_ec2os (x, y, sk.E.p);
1318     }
1319   secret = sk.d; sk.d = NULL;
1320   if (E.name)
1321     {
1322       rc = gcry_sexp_build (&curve_info, NULL, "(curve %s)", E.name);
1323       if (rc)
1324         goto leave;
1325     }
1326
1327   rc = gcry_sexp_build (r_skey, NULL,
1328                         "(key-data"
1329                         " (public-key"
1330                         "  (ecc%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))"
1331                         " (private-key"
1332                         "  (ecc%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))"
1333                         " )",
1334                         curve_info,
1335                         sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public,
1336                         curve_info,
1337                         sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public, secret);
1338   if (rc)
1339     goto leave;
1340
1341   if (DBG_CIPHER)
1342     {
1343       log_printmpi ("ecgen result  p", sk.E.p);
1344       log_printmpi ("ecgen result  a", sk.E.a);
1345       log_printmpi ("ecgen result  b", sk.E.b);
1346       log_printmpi ("ecgen result  G", base);
1347       log_printmpi ("ecgen result  n", sk.E.n);
1348       log_printmpi ("ecgen result  Q", public);
1349       log_printmpi ("ecgen result  d", secret);
1350     }
1351
1352  leave:
1353   mpi_free (secret);
1354   mpi_free (public);
1355   mpi_free (base);
1356   {
1357     _gcry_ecc_curve_free (&sk.E);
1358     point_free (&sk.Q);
1359     mpi_free (sk.d);
1360   }
1361   _gcry_ecc_curve_free (&E);
1362   mpi_free (x);
1363   mpi_free (y);
1364   _gcry_mpi_ec_free (ctx);
1365   gcry_sexp_release (curve_info);
1366   return rc;
1367 }
1368
1369
1370 static gcry_err_code_t
1371 ecc_check_secret_key (int algo, gcry_mpi_t *skey)
1372 {
1373   gpg_err_code_t err;
1374   ECC_secret_key sk;
1375
1376   (void)algo;
1377
1378   /* FIXME:  This check looks a bit fishy:  Now long is the array?  */
1379   if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
1380       || !skey[6])
1381     return GPG_ERR_BAD_MPI;
1382
1383   sk.E.model = MPI_EC_WEIERSTRASS;
1384   sk.E.p = skey[0];
1385   sk.E.a = skey[1];
1386   sk.E.b = skey[2];
1387   point_init (&sk.E.G);
1388   err = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1389   if (err)
1390     {
1391       point_free (&sk.E.G);
1392       return err;
1393     }
1394   sk.E.n = skey[4];
1395   point_init (&sk.Q);
1396   err = _gcry_ecc_os2ec (&sk.Q, skey[5]);
1397   if (err)
1398     {
1399       point_free (&sk.E.G);
1400       point_free (&sk.Q);
1401       return err;
1402     }
1403
1404   {
1405     const unsigned char *buf;
1406     unsigned int n;
1407
1408     gcry_assert (mpi_is_opaque (skey[6]));
1409
1410     buf = gcry_mpi_get_opaque (skey[6], &n);
1411     if (!buf)
1412       err = GPG_ERR_INV_OBJ;
1413     else
1414       {
1415         n = (n + 7)/8;
1416         sk.d = NULL;
1417         err = gcry_mpi_scan (&sk.d, GCRYMPI_FMT_USG, buf, n, NULL);
1418         if (!err)
1419           {
1420             if (check_secret_key (&sk))
1421               err = GPG_ERR_BAD_SECKEY;
1422             gcry_mpi_release (sk.d);
1423             sk.d = NULL;
1424           }
1425       }
1426   }
1427
1428   point_free (&sk.E.G);
1429   point_free (&sk.Q);
1430   return err;
1431 }
1432
1433
1434 static gcry_err_code_t
1435 ecc_sign (int algo, gcry_sexp_t *r_result, gcry_mpi_t data, gcry_mpi_t *skey,
1436           int flags, int hashalgo)
1437 {
1438   gpg_err_code_t rc;
1439   ECC_secret_key sk;
1440   gcry_mpi_t r, s;
1441
1442   (void)algo;
1443
1444   if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1445       || !skey[6] )
1446     return GPG_ERR_BAD_MPI;
1447
1448   sk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
1449                 ? MPI_EC_TWISTEDEDWARDS
1450                 : MPI_EC_WEIERSTRASS);
1451   sk.E.p = skey[0];
1452   sk.E.a = skey[1];
1453   sk.E.b = skey[2];
1454   point_init (&sk.E.G);
1455   sk.Q.x = NULL;
1456   sk.Q.y = NULL;
1457   sk.Q.z = NULL;
1458   rc = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1459   if (rc)
1460     {
1461       point_free (&sk.E.G);
1462       return rc;
1463     }
1464   sk.E.n = skey[4];
1465
1466   r = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1467   s = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1468
1469   {
1470     const unsigned char *buf;
1471     unsigned int n;
1472
1473     gcry_assert (mpi_is_opaque (skey[6]));
1474
1475     buf = gcry_mpi_get_opaque (skey[6], &n);
1476     if (!buf)
1477       rc = GPG_ERR_INV_OBJ;
1478     else
1479       {
1480         n = (n + 7)/8;
1481         sk.d = NULL;
1482         rc = gcry_mpi_scan (&sk.d, GCRYMPI_FMT_USG, buf, n, NULL);
1483         if (!rc)
1484           {
1485             if ((flags & PUBKEY_FLAG_EDDSA))
1486               {
1487                 rc = sign_eddsa (data, &sk, r, s, hashalgo, skey[5]);
1488                 if (!rc)
1489                   rc = gcry_sexp_build (r_result, NULL,
1490                                         "(sig-val(eddsa(r%M)(s%M)))", r, s);
1491               }
1492             else
1493               {
1494                 rc = sign_ecdsa (data, &sk, r, s, flags, hashalgo);
1495                 if (!rc)
1496                   rc = gcry_sexp_build (r_result, NULL,
1497                                         "(sig-val(ecdsa(r%M)(s%M)))", r, s);
1498               }
1499             gcry_mpi_release (sk.d);
1500             sk.d = NULL;
1501           }
1502       }
1503   }
1504
1505   mpi_free (r);
1506   mpi_free (s);
1507   point_free (&sk.E.G);
1508   if (sk.Q.x)
1509     point_free (&sk.Q);
1510   return rc;
1511 }
1512
1513
1514 static gcry_err_code_t
1515 ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
1516             int (*cmp)(void *, gcry_mpi_t), void *opaquev,
1517             int flags, int hashalgo)
1518 {
1519   gpg_err_code_t err;
1520   ECC_public_key pk;
1521
1522   (void)algo;
1523   (void)cmp;
1524   (void)opaquev;
1525
1526   if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2]
1527       || !pkey[3] || !pkey[4] || !pkey[5] )
1528     return GPG_ERR_BAD_MPI;
1529
1530   pk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
1531                 ? MPI_EC_TWISTEDEDWARDS
1532                 : MPI_EC_WEIERSTRASS);
1533   pk.E.p = pkey[0];
1534   pk.E.a = pkey[1];
1535   pk.E.b = pkey[2];
1536   point_init (&pk.E.G);
1537   err = _gcry_ecc_os2ec (&pk.E.G, pkey[3]);
1538   if (err)
1539     {
1540       point_free (&pk.E.G);
1541       return err;
1542     }
1543   pk.E.n = pkey[4];
1544
1545   if ((flags & PUBKEY_FLAG_EDDSA))
1546     {
1547       pk.Q.x = NULL;
1548       pk.Q.y = NULL;
1549       pk.Q.z = NULL;
1550
1551       err = verify_eddsa (hash, &pk, data[0], data[1], hashalgo, pkey[5]);
1552     }
1553   else
1554     {
1555       point_init (&pk.Q);
1556       err = _gcry_ecc_os2ec (&pk.Q, pkey[5]);
1557       if (err)
1558         {
1559           point_free (&pk.E.G);
1560           point_free (&pk.Q);
1561           return err;
1562         }
1563
1564       if (mpi_is_opaque (hash))
1565         {
1566           const void *abuf;
1567           unsigned int abits, qbits;
1568           gcry_mpi_t a;
1569
1570           qbits = mpi_get_nbits (pk.E.n);
1571
1572           abuf = gcry_mpi_get_opaque (hash, &abits);
1573           err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, abuf, (abits+7)/8, NULL);
1574           if (!err)
1575             {
1576               if (abits > qbits)
1577                 gcry_mpi_rshift (a, a, abits - qbits);
1578
1579               err = verify_ecdsa (a, &pk, data[0], data[1]);
1580               gcry_mpi_release (a);
1581             }
1582         }
1583       else
1584         err = verify_ecdsa (hash, &pk, data[0], data[1]);
1585     }
1586
1587   point_free (&pk.E.G);
1588   point_free (&pk.Q);
1589   return err;
1590 }
1591
1592
1593 /* ecdh raw is classic 2-round DH protocol published in 1976.
1594  *
1595  * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
1596  *
1597  * As with any PK operation, encrypt version uses a public key and
1598  * decrypt -- private.
1599  *
1600  * Symbols used below:
1601  *     G - field generator point
1602  *     d - private long-term scalar
1603  *    dG - public long-term key
1604  *     k - ephemeral scalar
1605  *    kG - ephemeral public key
1606  *   dkG - shared secret
1607  *
1608  * ecc_encrypt_raw description:
1609  *   input:
1610  *     data[0] : private scalar (k)
1611  *   output: A new S-expression with the parameters:
1612  *     s : shared point (kdG)
1613  *     e : generated ephemeral public key (kG)
1614  *
1615  * ecc_decrypt_raw description:
1616  *   input:
1617  *     data[0] : a point kG (ephemeral public key)
1618  *   output:
1619  *     result[0] : shared point (kdG)
1620  */
1621 static gcry_err_code_t
1622 ecc_encrypt_raw (int algo, gcry_sexp_t *r_result, gcry_mpi_t k,
1623                  gcry_mpi_t *pkey, int flags)
1624 {
1625   gpg_err_code_t rc;
1626   ECC_public_key pk;
1627   mpi_ec_t ctx;
1628   gcry_mpi_t s, e;
1629
1630   (void)algo;
1631   (void)flags;
1632
1633   if (!k
1634       || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5])
1635     return GPG_ERR_BAD_MPI;
1636
1637   pk.E.model = MPI_EC_WEIERSTRASS;
1638   pk.E.p = pkey[0];
1639   pk.E.a = pkey[1];
1640   pk.E.b = pkey[2];
1641   point_init (&pk.E.G);
1642   rc = _gcry_ecc_os2ec (&pk.E.G, pkey[3]);
1643   if (rc)
1644     {
1645       point_free (&pk.E.G);
1646       return rc;
1647     }
1648   pk.E.n = pkey[4];
1649   point_init (&pk.Q);
1650   rc = _gcry_ecc_os2ec (&pk.Q, pkey[5]);
1651   if (rc)
1652     {
1653       point_free (&pk.E.G);
1654       point_free (&pk.Q);
1655       return rc;
1656     }
1657
1658   ctx = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect,
1659                                      pk.E.p, pk.E.a, pk.E.b);
1660   s = mpi_alloc (mpi_get_nlimbs (pk.E.p));
1661   e = mpi_alloc (mpi_get_nlimbs (pk.E.p));
1662
1663   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
1664   {
1665     mpi_point_struct R;  /* Result that we return.  */
1666     gcry_mpi_t x, y;
1667
1668     x = mpi_new (0);
1669     y = mpi_new (0);
1670
1671     point_init (&R);
1672
1673     /* R = kQ  <=>  R = kdG  */
1674     _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx);
1675
1676     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1677       log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
1678     s = _gcry_ecc_ec2os (x, y, pk.E.p);
1679
1680     /* R = kG */
1681     _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx);
1682
1683     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1684       log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
1685     e = _gcry_ecc_ec2os (x, y, pk.E.p);
1686
1687     mpi_free (x);
1688     mpi_free (y);
1689
1690     point_free (&R);
1691   }
1692
1693   _gcry_mpi_ec_free (ctx);
1694   point_free (&pk.E.G);
1695   point_free (&pk.Q);
1696
1697   rc = gcry_sexp_build (r_result, NULL, "(enc-val(ecdh(s%m)(e%m)))", s, e);
1698   mpi_free (s);
1699   mpi_free (e);
1700
1701   return rc;
1702 }
1703
1704 /*  input:
1705  *     data[0] : a point kG (ephemeral public key)
1706  *   output:
1707  *     resaddr[0] : shared point kdG
1708  *
1709  *  see ecc_encrypt_raw for details.
1710  */
1711 static gcry_err_code_t
1712 ecc_decrypt_raw (int algo, gcry_sexp_t *r_plain, gcry_mpi_t *data,
1713                  gcry_mpi_t *skey, int flags,
1714                  enum pk_encoding encoding, int hash_algo,
1715                  unsigned char *label, size_t labellen)
1716 {
1717   gpg_err_code_t rc;
1718   ECC_secret_key sk;
1719   mpi_point_struct R;   /* Result that we return.  */
1720   mpi_point_struct kG;
1721   mpi_ec_t ctx;
1722   gcry_mpi_t r;
1723
1724   (void)algo;
1725   (void)flags;
1726   (void)encoding;
1727   (void)hash_algo;
1728   (void)label;
1729   (void)labellen;
1730
1731   if (!data || !data[0]
1732       || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1733       || !skey[5] || !skey[6] )
1734     return GPG_ERR_BAD_MPI;
1735
1736   point_init (&kG);
1737   rc = _gcry_ecc_os2ec (&kG, data[0]);
1738   if (rc)
1739     {
1740       point_free (&kG);
1741       return rc;
1742     }
1743
1744   sk.E.model = MPI_EC_WEIERSTRASS;
1745   sk.E.p = skey[0];
1746   sk.E.a = skey[1];
1747   sk.E.b = skey[2];
1748   point_init (&sk.E.G);
1749   rc = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1750   if (rc)
1751     {
1752       point_free (&kG);
1753       point_free (&sk.E.G);
1754       return rc;
1755     }
1756   sk.E.n = skey[4];
1757   point_init (&sk.Q);
1758   rc = _gcry_ecc_os2ec (&sk.Q, skey[5]);
1759   if (rc)
1760     {
1761       point_free (&kG);
1762       point_free (&sk.E.G);
1763       point_free (&sk.Q);
1764       return rc;
1765     }
1766   sk.d = skey[6];
1767
1768   ctx = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect,
1769                                      sk.E.p, sk.E.a, sk.E.b);
1770
1771   /* R = dkG */
1772   point_init (&R);
1773   _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx);
1774
1775   point_free (&kG);
1776
1777   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so:  */
1778   {
1779     gcry_mpi_t x, y;
1780
1781     x = mpi_new (0);
1782     y = mpi_new (0);
1783
1784     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1785       log_fatal ("ecdh: Failed to get affine coordinates\n");
1786
1787     r = _gcry_ecc_ec2os (x, y, sk.E.p);
1788     if (!r)
1789       rc = gpg_err_code_from_syserror ();
1790     else
1791       rc = 0;
1792     mpi_free (x);
1793     mpi_free (y);
1794   }
1795
1796   point_free (&R);
1797   _gcry_mpi_ec_free (ctx);
1798   point_free (&kG);
1799   point_free (&sk.E.G);
1800   point_free (&sk.Q);
1801
1802   if (!rc)
1803     rc = gcry_sexp_build (r_plain, NULL, "(value %m)", r);
1804   mpi_free (r);
1805   return rc;
1806 }
1807
1808
1809 static unsigned int
1810 ecc_get_nbits (int algo, gcry_mpi_t *pkey)
1811 {
1812   (void)algo;
1813
1814   return mpi_get_nbits (pkey[0]);
1815 }
1816
1817
1818 /* See rsa.c for a description of this function.  */
1819 static gpg_err_code_t
1820 compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
1821 {
1822 #define N_COMPONENTS 6
1823   static const char names[N_COMPONENTS+1] = "pabgnq";
1824   gpg_err_code_t ec = 0;
1825   gcry_sexp_t l1;
1826   gcry_mpi_t values[N_COMPONENTS];
1827   int idx;
1828
1829   /* Clear the values for easier error cleanup.  */
1830   for (idx=0; idx < N_COMPONENTS; idx++)
1831     values[idx] = NULL;
1832
1833   /* Fill values with all provided parameters.  */
1834   for (idx=0; idx < N_COMPONENTS; idx++)
1835     {
1836       l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
1837       if (l1)
1838         {
1839           values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1840           gcry_sexp_release (l1);
1841           if (!values[idx])
1842             {
1843               ec = GPG_ERR_INV_OBJ;
1844               goto leave;
1845             }
1846         }
1847     }
1848
1849   /* Check whether a curve parameter is available and use that to fill
1850      in missing values.  */
1851   l1 = gcry_sexp_find_token (keyparam, "curve", 5);
1852   if (l1)
1853     {
1854       char *curve;
1855       gcry_mpi_t tmpvalues[N_COMPONENTS];
1856
1857       for (idx = 0; idx < N_COMPONENTS; idx++)
1858         tmpvalues[idx] = NULL;
1859
1860       curve = _gcry_sexp_nth_string (l1, 1);
1861       gcry_sexp_release (l1);
1862       if (!curve)
1863         {
1864           ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
1865           goto leave;
1866         }
1867       ec = _gcry_ecc_get_param (curve, tmpvalues);
1868       gcry_free (curve);
1869       if (ec)
1870         goto leave;
1871
1872       for (idx = 0; idx < N_COMPONENTS; idx++)
1873         {
1874           if (!values[idx])
1875             values[idx] = tmpvalues[idx];
1876           else
1877             mpi_free (tmpvalues[idx]);
1878         }
1879     }
1880
1881   /* Check that all parameters are known and normalize all MPIs (that
1882      should not be required but we use an internal function later and
1883      thus we better make 100% sure that they are normalized). */
1884   for (idx = 0; idx < N_COMPONENTS; idx++)
1885     if (!values[idx])
1886       {
1887         ec = GPG_ERR_NO_OBJ;
1888         goto leave;
1889       }
1890     else
1891       _gcry_mpi_normalize (values[idx]);
1892
1893   /* Hash them all.  */
1894   for (idx = 0; idx < N_COMPONENTS; idx++)
1895     {
1896       char buf[30];
1897       unsigned char *rawmpi;
1898       unsigned int rawmpilen;
1899
1900       rawmpi = _gcry_mpi_get_buffer (values[idx], 0, &rawmpilen, NULL);
1901       if (!rawmpi)
1902         {
1903           ec = gpg_err_code_from_syserror ();
1904           goto leave;
1905         }
1906       snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
1907       gcry_md_write (md, buf, strlen (buf));
1908       gcry_md_write (md, rawmpi, rawmpilen);
1909       gcry_md_write (md, ")", 1);
1910       gcry_free (rawmpi);
1911     }
1912
1913  leave:
1914   for (idx = 0; idx < N_COMPONENTS; idx++)
1915     _gcry_mpi_release (values[idx]);
1916
1917   return ec;
1918 #undef N_COMPONENTS
1919 }
1920
1921
1922 \f
1923 /*
1924    Low-level API helper functions.
1925  */
1926
1927 /* This is the wroker function for gcry_pubkey_get_sexp for ECC
1928    algorithms.  Note that the caller has already stored NULL at
1929    R_SEXP.  */
1930 gpg_err_code_t
1931 _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
1932 {
1933   gpg_err_code_t rc;
1934   gcry_mpi_t mpi_G = NULL;
1935   gcry_mpi_t mpi_Q = NULL;
1936
1937   if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n)
1938     return GPG_ERR_BAD_CRYPT_CTX;
1939
1940   if (mode == GCRY_PK_GET_SECKEY && !ec->d)
1941     return GPG_ERR_NO_SECKEY;
1942
1943   /* Compute the public point if it is missing.  */
1944   if (!ec->Q && ec->d)
1945     {
1946       ec->Q = gcry_mpi_point_new (0);
1947       _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec);
1948     }
1949
1950   /* Encode G and Q.  */
1951   mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec);
1952   if (!mpi_G)
1953     {
1954       rc = GPG_ERR_BROKEN_PUBKEY;
1955       goto leave;
1956     }
1957   if (!ec->Q)
1958     {
1959       rc = GPG_ERR_BAD_CRYPT_CTX;
1960       goto leave;
1961     }
1962   mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec);
1963   if (!mpi_Q)
1964     {
1965       rc = GPG_ERR_BROKEN_PUBKEY;
1966       goto leave;
1967     }
1968
1969   /* Fixme: We should return a curve name instead of the parameters if
1970      if know that they match a curve.  */
1971
1972   if (ec->d && (!mode || mode == GCRY_PK_GET_SECKEY))
1973     {
1974       /* Let's return a private key. */
1975       rc = gcry_sexp_build
1976         (r_sexp, NULL,
1977          "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))",
1978          ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q, ec->d);
1979     }
1980   else if (ec->Q)
1981     {
1982       /* Let's return a public key.  */
1983       rc = gcry_sexp_build
1984         (r_sexp, NULL,
1985          "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))",
1986          ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q);
1987     }
1988   else
1989     rc = GPG_ERR_BAD_CRYPT_CTX;
1990
1991  leave:
1992   mpi_free (mpi_Q);
1993   mpi_free (mpi_G);
1994   return rc;
1995 }
1996
1997
1998 \f
1999 /*
2000      Self-test section.
2001  */
2002
2003
2004 static gpg_err_code_t
2005 selftests_ecdsa (selftest_report_func_t report)
2006 {
2007   const char *what;
2008   const char *errtxt;
2009
2010   what = "low-level";
2011   errtxt = NULL; /*selftest ();*/
2012   if (errtxt)
2013     goto failed;
2014
2015   /* FIXME:  need more tests.  */
2016
2017   return 0; /* Succeeded. */
2018
2019  failed:
2020   if (report)
2021     report ("pubkey", GCRY_PK_ECC, what, errtxt);
2022   return GPG_ERR_SELFTEST_FAILED;
2023 }
2024
2025
2026 /* Run a full self-test for ALGO and return 0 on success.  */
2027 static gpg_err_code_t
2028 run_selftests (int algo, int extended, selftest_report_func_t report)
2029 {
2030   (void)extended;
2031
2032   if (algo != GCRY_PK_ECC)
2033     return GPG_ERR_PUBKEY_ALGO;
2034
2035   return selftests_ecdsa (report);
2036 }
2037
2038
2039
2040 \f
2041 static const char *ecc_names[] =
2042   {
2043     "ecc",
2044     "ecdsa",
2045     "ecdh",
2046     "eddsa",
2047     NULL,
2048   };
2049
2050 gcry_pk_spec_t _gcry_pubkey_spec_ecc =
2051   {
2052     GCRY_PK_ECC, { 0, 0 },
2053     (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
2054     "ECC", ecc_names,
2055     "pabgnq", "pabgnqd", "sw", "rs", "pabgnq",
2056     ecc_generate,
2057     ecc_check_secret_key,
2058     ecc_encrypt_raw,
2059     ecc_decrypt_raw,
2060     ecc_sign,
2061     ecc_verify,
2062     ecc_get_nbits,
2063     run_selftests,
2064     compute_keygrip,
2065     _gcry_ecc_get_param,
2066     _gcry_ecc_get_curve,
2067     _gcry_ecc_get_param_sexp
2068   };