Preparing
[libgcrypt.git] / cipher / ecc.c
1 /* ecc.c  -  Elliptic Curve Cryptography
2    Copyright (C) 2007, 2008 Free Software Foundation, Inc.
3
4    This file is part of Libgcrypt.
5   
6    Libgcrypt is free software; you can redistribute it and/or modify
7    it under the terms of the GNU Lesser General Public License as
8    published by the Free Software Foundation; either version 2.1 of
9    the License, or (at your option) any later version.
10   
11    Libgcrypt is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU Lesser General Public License for more details.
15   
16    You should have received a copy of the GNU Lesser General Public
17    License along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19    USA.  */
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
39 /* TODO:
40
41   - If we support point compression we need to decide how to compute
42     the keygrip - it should not change due to compression.
43
44   - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a
45     special case in mpi_powm or check whether mpi_mulm is faster.
46
47   - Decide whether we should hide the mpi_point_t definition.
48
49   - Support more than just ECDSA.
50 */
51
52
53 #include <config.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57
58 #include "g10lib.h"
59 #include "mpi.h"
60 #include "cipher.h"
61
62
63 /* Definition of a curve.  */
64 typedef struct
65 {
66   gcry_mpi_t p;   /* Prime specifying the field GF(p).  */
67   gcry_mpi_t a;   /* First coefficient of the Weierstrass equation.  */
68   gcry_mpi_t b;   /* Second coefficient of the Weierstrass equation.  */
69   mpi_point_t G;  /* Base point (generator).  */
70   gcry_mpi_t n;   /* Order of G.  */
71 } elliptic_curve_t; 
72
73
74 typedef struct
75 {
76   elliptic_curve_t E;
77   mpi_point_t Q;  /* Q = [d]G  */
78 } ECC_public_key;
79
80 typedef struct
81 {
82   elliptic_curve_t E;
83   mpi_point_t Q;
84   gcry_mpi_t d;
85 } ECC_secret_key;
86
87
88 /* This tables defines aliases for curve names.  */
89 static const struct
90 {
91   const char *name;  /* Our name.  */
92   const char *other; /* Other name. */
93 } curve_aliases[] = 
94   {
95     { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID  */
96     { "NIST P-192", "prime192v1" },          /* X9.62 name.  */
97     { "NIST P-192", "secp192r1"  },          /* SECP name.  */
98
99     { "NIST P-224", "secp224r1" },
100     { "NIST P-224", "1.3.132.0.33" },        /* SECP OID.  */
101
102     { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1.  */
103     { "NIST P-256", "prime256v1" },          
104     { "NIST P-256", "secp256r1"  },
105
106     { "NIST P-384", "secp384r1" },
107     { "NIST P-384", "1.3.132.0.34" },       
108
109     { "NIST P-521", "secp521r1" },
110     { "NIST P-521", "1.3.132.0.35" },
111
112     { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" },
113     { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" },
114     { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" },
115     { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7" },
116     { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" },
117     { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"},
118     { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"},
119
120     { NULL, NULL}
121   };
122
123
124
125 /* This static table defines all available curves.  */
126 static const struct
127 {
128   const char *desc;           /* Description of the curve.  */
129   unsigned int nbits;         /* Number of bits.  */
130   unsigned int fips:1;        /* True if this is a FIPS140-2 approved curve. */
131   const char  *p;             /* Order of the prime field.  */
132   const char *a, *b;          /* The coefficients. */
133   const char *n;              /* The order of the base point.  */
134   const char *g_x, *g_y;      /* Base point.  */
135 } domain_parms[] =
136   {
137     {
138       "NIST P-192", 192, 1,
139       "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
140       "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
141       "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
142       "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
143
144       "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
145       "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
146     },
147     {
148       "NIST P-224", 224, 1,
149       "0xffffffffffffffffffffffffffffffff000000000000000000000001",
150       "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
151       "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
152       "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
153
154       "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
155       "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"
156     },
157     {
158       "NIST P-256", 256, 1,
159       "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
160       "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
161       "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
162       "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
163
164       "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
165       "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
166     },
167     {
168       "NIST P-384", 384, 1,
169       "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
170       "ffffffff0000000000000000ffffffff",
171       "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
172       "ffffffff0000000000000000fffffffc",
173       "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
174       "c656398d8a2ed19d2a85c8edd3ec2aef",
175       "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
176       "581a0db248b0a77aecec196accc52973",
177
178       "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
179       "5502f25dbf55296c3a545e3872760ab7",
180       "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
181       "0a60b1ce1d7e819d7a431d7c90ea0e5f"
182     },
183     {
184       "NIST P-521", 521, 1,
185       "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
186       "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
187       "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
188       "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
189       "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
190       "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
191       "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
192       "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
193
194       "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
195       "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
196       "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
197       "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
198     },
199
200     { "brainpoolP160r1", 160, 0, 
201       "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f",
202       "0x340e7be2a280eb74e2be61bada745d97e8f7c300",
203       "0x1e589a8595423412134faa2dbdec95c8d8675e58",
204       "0xe95e4a5f737059dc60df5991d45029409e60fc09",
205       "0xbed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3",
206       "0x1667cb477a1a8ec338f94741669c976316da6321"
207     },
208
209     { "brainpoolP192r1", 192, 0, 
210       "0xc302f41d932a36cda7a3463093d18db78fce476de1a86297",
211       "0x6a91174076b1e0e19c39c031fe8685c1cae040e5c69a28ef",
212       "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9",
213       "0xc302f41d932a36cda7a3462f9e9e916b5be8f1029ac4acc1",
214       "0xc0a0647eaab6a48753b033c56cb0f0900a2f5c4853375fd6",
215       "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f"
216     },
217
218     { "brainpoolP224r1", 224, 0,
219       "0xd7c134aa264366862a18302575d1d787b09f075797da89f57ec8c0ff",
220       "0x68a5e62ca9ce6c1c299803a6c1530b514e182ad8b0042a59cad29f43",
221       "0x2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b",
222       "0xd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f",
223       "0x0d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d",
224       "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd"
225     },
226
227     { "brainpoolP256r1", 256, 0,
228       "0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377",
229       "0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9",
230       "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6",
231       "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7",
232       "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262",
233       "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997"
234     },
235
236     { "brainpoolP320r1", 320, 0,
237       "0xd35e472036bc4fb7e13c785ed201e065f98fcfa6f6f40def4f92b9ec7893ec28"
238       "fcd412b1f1b32e27",
239       "0x3ee30b568fbab0f883ccebd46d3f3bb8a2a73513f5eb79da66190eb085ffa9f4"
240       "92f375a97d860eb4",
241       "0x520883949dfdbc42d3ad198640688a6fe13f41349554b49acc31dccd88453981"
242       "6f5eb4ac8fb1f1a6",
243       "0xd35e472036bc4fb7e13c785ed201e065f98fcfa5b68f12a32d482ec7ee8658e9"
244       "8691555b44c59311",
245       "0x43bd7e9afb53d8b85289bcc48ee5bfe6f20137d10a087eb6e7871e2a10a599c7"
246       "10af8d0d39e20611",
247       "0x14fdd05545ec1cc8ab4093247f77275e0743ffed117182eaa9c77877aaac6ac7"
248       "d35245d1692e8ee1"
249     },
250
251     { "brainpoolP384r1", 384, 0,
252       "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123"
253       "acd3a729901d1a71874700133107ec53",
254       "0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f"
255       "8aa5814a503ad4eb04a8c7dd22ce2826",
256       "0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d5"
257       "7cb4390295dbc9943ab78696fa504c11",
258       "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7"
259       "cf3ab6af6b7fc3103b883202e9046565",
260       "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8"
261       "e826e03436d646aaef87b2e247d4af1e",
262       "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff9912928"
263       "0e4646217791811142820341263c5315"
264     },
265
266     { "brainpoolP512r1", 512, 0,
267       "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330871"
268       "7d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3",
269       "0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc"
270       "2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca",
271       "0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a7"
272       "2bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723",
273       "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870"
274       "553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069",
275       "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098e"
276       "ff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822",
277       "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111"
278       "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892"
279     },
280
281     { NULL, 0, 0, NULL, NULL, NULL, NULL }
282   };
283
284
285 /* Registered progress function and its callback value. */
286 static void (*progress_cb) (void *, const char*, int, int, int);
287 static void *progress_cb_data;
288
289
290 #define point_init(a)  _gcry_mpi_ec_point_init ((a))
291 #define point_free(a)  _gcry_mpi_ec_point_free ((a))
292
293
294 \f
295 /* Local prototypes. */
296 static gcry_mpi_t gen_k (gcry_mpi_t p, int security_level);
297 static void test_keys (ECC_secret_key * sk, unsigned int nbits);
298 static int check_secret_key (ECC_secret_key * sk);
299 static gpg_err_code_t sign (gcry_mpi_t input, ECC_secret_key *skey,
300                             gcry_mpi_t r, gcry_mpi_t s);
301 static gpg_err_code_t verify (gcry_mpi_t input, ECC_public_key *pkey,
302                               gcry_mpi_t r, gcry_mpi_t s);
303
304
305 static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base);
306
307
308
309 \f
310 void
311 _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
312                                             int, int, int),
313                                 void *cb_data)
314 {
315   progress_cb = cb;
316   progress_cb_data = cb_data;
317 }
318
319 /* static void */
320 /* progress (int c) */
321 /* { */
322 /*   if (progress_cb) */
323 /*     progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */
324 /* } */
325
326
327 \f
328
329 /* Set the value from S into D.  */
330 static void
331 point_set (mpi_point_t *d, mpi_point_t *s)
332 {
333   mpi_set (d->x, s->x);
334   mpi_set (d->y, s->y);
335   mpi_set (d->z, s->z);
336 }
337
338
339 /*
340  * Release a curve object.
341  */
342 static void
343 curve_free (elliptic_curve_t *E)
344 {
345   mpi_free (E->p); E->p = NULL;
346   mpi_free (E->a); E->a = NULL;
347   mpi_free (E->b);  E->b = NULL;
348   point_free (&E->G);
349   mpi_free (E->n);  E->n = NULL;
350 }
351
352
353 /*
354  * Return a copy of a curve object.
355  */
356 static elliptic_curve_t
357 curve_copy (elliptic_curve_t E)
358 {
359   elliptic_curve_t R;
360
361   R.p = mpi_copy (E.p);
362   R.a = mpi_copy (E.a);
363   R.b = mpi_copy (E.b);
364   point_init (&R.G);
365   point_set (&R.G, &E.G);
366   R.n = mpi_copy (E.n);
367
368   return R;
369 }
370
371
372
373 /* Helper to scan a hex string. */
374 static gcry_mpi_t
375 scanval (const char *string)
376 {
377   gpg_error_t err;
378   gcry_mpi_t val;
379
380   err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
381   if (err)
382     log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (err));
383   return val;
384 }
385
386
387
388 \f
389
390 /****************
391  * Solve the right side of the equation that defines a curve.
392  */
393 static gcry_mpi_t
394 gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base)
395 {
396   gcry_mpi_t three, x_3, axb, y;
397
398   three = mpi_alloc_set_ui (3);
399   x_3 = mpi_new (0);
400   axb = mpi_new (0);
401   y   = mpi_new (0);
402
403   mpi_powm (x_3, x, three, base->p);  
404   mpi_mulm (axb, base->a, x, base->p); 
405   mpi_addm (axb, axb, base->b, base->p);     
406   mpi_addm (y, x_3, axb, base->p);    
407
408   mpi_free (x_3);
409   mpi_free (axb);
410   mpi_free (three);
411   return y; /* The quadratic value of the coordinate if it exist. */
412 }
413
414
415
416
417
418 /* Generate a random secret scalar k with an order of p
419
420    At the beginning this was identical to the code is in elgamal.c.
421    Later imporved by mmr.   Further simplified by wk.  */
422 static gcry_mpi_t
423 gen_k (gcry_mpi_t p, int security_level)
424 {
425   gcry_mpi_t k;
426   unsigned int nbits;
427
428   nbits = mpi_get_nbits (p);
429   k = mpi_snew (nbits);
430   if (DBG_CIPHER)
431     log_debug ("choosing a random k of %u bits\n", nbits);
432
433   gcry_mpi_randomize (k, nbits, security_level);
434
435   mpi_mod (k, k, p);  /*  k = k mod p  */
436
437   return k;
438 }
439
440 /****************
441  * Generate the crypto system setup.
442  * As of now the fix NIST recommended values are used.
443  * The subgroup generator point is in another function: gen_big_point.
444  */
445 static gpg_err_code_t
446 generate_curve (unsigned int nbits, const char *name, 
447                 elliptic_curve_t *curve, unsigned int *r_nbits)
448 {
449   int idx, aliasno;
450
451   if (name)
452     {
453       /* First check nor native curves.  */
454       for (idx = 0; domain_parms[idx].desc; idx++)
455         if (!strcmp (name, domain_parms[idx].desc))
456           break;
457       /* If not found consult the alias table.  */
458       if (!domain_parms[idx].desc)
459         {
460           for (aliasno = 0; curve_aliases[aliasno].name; aliasno++)
461             if (!strcmp (name, curve_aliases[aliasno].other))
462               break;
463           if (curve_aliases[aliasno].name)
464             {
465               for (idx = 0; domain_parms[idx].desc; idx++)
466                 if (!strcmp (curve_aliases[aliasno].name,
467                              domain_parms[idx].desc))
468                   break;
469             }
470         }
471     }
472   else
473     {
474       for (idx = 0; domain_parms[idx].desc; idx++)
475         if (nbits == domain_parms[idx].nbits)
476           break;
477     }
478   if (!domain_parms[idx].desc)
479     return GPG_ERR_INV_VALUE;
480
481   /* In fips mode we only support NIST curves.  Note that it is
482      possible to bypass this check by specifying the curve parameters
483      directly.  */
484   if (fips_mode () && !domain_parms[idx].fips )
485     return GPG_ERR_NOT_SUPPORTED; 
486   
487
488   *r_nbits = domain_parms[idx].nbits;
489   curve->p = scanval (domain_parms[idx].p);
490   curve->a = scanval (domain_parms[idx].a);
491   curve->b = scanval (domain_parms[idx].b);
492   curve->n = scanval (domain_parms[idx].n);
493   curve->G.x = scanval (domain_parms[idx].g_x);
494   curve->G.y = scanval (domain_parms[idx].g_y);
495   curve->G.z = mpi_alloc_set_ui (1);
496
497   return 0;
498 }
499
500
501 /*
502  * First obtain the setup.  Over the finite field randomize an scalar
503  * secret value, and calculate the public point.
504  */
505 static gpg_err_code_t
506 generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
507               gcry_mpi_t g_x, gcry_mpi_t g_y,
508               gcry_mpi_t q_x, gcry_mpi_t q_y)
509 {
510   gpg_err_code_t err;
511   elliptic_curve_t E;
512   gcry_mpi_t d;
513   mpi_point_t Q;
514   mpi_ec_t ctx;
515
516   err = generate_curve (nbits, name, &E, &nbits);
517   if (err)
518     return err;
519
520   if (DBG_CIPHER)
521     {
522       log_mpidump ("ecc generation   p", E.p);
523       log_mpidump ("ecc generation   a", E.a);
524       log_mpidump ("ecc generation   b", E.b);
525       log_mpidump ("ecc generation   n", E.n);
526       log_mpidump ("ecc generation  Gx", E.G.x);
527       log_mpidump ("ecc generation  Gy", E.G.y);
528       log_mpidump ("ecc generation  Gz", E.G.z);
529     }
530
531   if (DBG_CIPHER)
532     log_debug ("choosing a random x of size %u\n", nbits);
533   d = gen_k (E.n, GCRY_VERY_STRONG_RANDOM); 
534
535   /* Compute Q.  */
536   point_init (&Q);
537   ctx = _gcry_mpi_ec_init (E.p, E.a);
538   _gcry_mpi_ec_mul_point (&Q, d, &E.G, ctx);
539
540   /* Copy the stuff to the key structures. */
541   sk->E.p = mpi_copy (E.p);
542   sk->E.a = mpi_copy (E.a);
543   sk->E.b = mpi_copy (E.b);
544   point_init (&sk->E.G);
545   point_set (&sk->E.G, &E.G);
546   sk->E.n = mpi_copy (E.n);
547   point_init (&sk->Q);
548   point_set (&sk->Q, &Q);
549   sk->d    = mpi_copy (d);
550   /* We also return copies of G and Q in affine coordinates if
551      requested.  */
552   if (g_x && g_y)
553     {
554       if (_gcry_mpi_ec_get_affine (g_x, g_y, &sk->E.G, ctx))
555         log_fatal ("ecc generate: Failed to get affine coordinates\n");
556     }
557   if (q_x && q_y)
558     {
559       if (_gcry_mpi_ec_get_affine (q_x, q_y, &sk->Q, ctx))
560         log_fatal ("ecc generate: Failed to get affine coordinates\n");
561     }
562   _gcry_mpi_ec_free (ctx);
563
564   point_free (&Q);
565   mpi_free (d);
566   curve_free (&E);
567
568   /* Now we can test our keys (this should never fail!). */
569   test_keys (sk, nbits - 64);
570
571   return 0;
572 }
573
574
575 /****************
576  * To verify correct skey it use a random information.
577  * First, encrypt and decrypt this dummy value,
578  * test if the information is recuperated.
579  * Second, test with the sign and verify functions.
580  */
581 static void
582 test_keys (ECC_secret_key *sk, unsigned int nbits)
583 {
584   ECC_public_key pk;
585   gcry_mpi_t test = mpi_new (nbits);
586   mpi_point_t R_;
587   gcry_mpi_t c = mpi_new (nbits);
588   gcry_mpi_t out = mpi_new (nbits);
589   gcry_mpi_t r = mpi_new (nbits);
590   gcry_mpi_t s = mpi_new (nbits);
591
592   if (DBG_CIPHER)
593     log_debug ("Testing key.\n");
594
595   point_init (&R_);
596
597   pk.E = curve_copy (sk->E);
598   point_init (&pk.Q);
599   point_set (&pk.Q, &sk->Q);
600
601   gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
602
603   if (sign (test, sk, r, s) )
604     log_fatal ("ECDSA operation: sign failed\n");
605
606   if (verify (test, &pk, r, s))
607     {
608       log_fatal ("ECDSA operation: sign, verify failed\n");
609     }
610
611   if (DBG_CIPHER)
612     log_debug ("ECDSA operation: sign, verify ok.\n");
613
614   point_free (&pk.Q);
615   curve_free (&pk.E);
616
617   point_free (&R_);
618   mpi_free (s);
619   mpi_free (r);
620   mpi_free (out);
621   mpi_free (c);
622   mpi_free (test);
623 }
624
625 /****************
626  * To check the validity of the value, recalculate the correspondence
627  * between the public value and the secret one.
628  */
629 static int
630 check_secret_key (ECC_secret_key * sk)
631 {
632   mpi_point_t Q;
633   gcry_mpi_t y_2, y2 = mpi_alloc (0);
634   mpi_ec_t ctx;
635
636   /* ?primarity test of 'p' */
637   /*  (...) //!! */
638   /* G in E(F_p) */
639   y_2 = gen_y_2 (sk->E.G.x, &sk->E);   /*  y^2=x^3+a*x+b */
640   mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p);      /*  y^2=y*y */
641   if (mpi_cmp (y_2, y2))
642     {
643       if (DBG_CIPHER)
644         log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
645       return (1);
646     }
647   /* G != PaI */
648   if (!mpi_cmp_ui (sk->E.G.z, 0))
649     {
650       if (DBG_CIPHER)
651         log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
652       return (1);
653     }
654
655   point_init (&Q);
656   ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a);
657   _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
658   if (mpi_cmp_ui (Q.z, 0))
659     {
660       if (DBG_CIPHER)
661         log_debug ("check_secret_key: E is not a curve of order n\n");
662       point_free (&Q);
663       _gcry_mpi_ec_free (ctx);
664       return 1;
665     }
666   /* pubkey cannot be PaI */
667   if (!mpi_cmp_ui (sk->Q.z, 0))
668     {
669       if (DBG_CIPHER)
670         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
671       _gcry_mpi_ec_free (ctx);
672       return (1);
673     }
674   /* pubkey = [d]G over E */
675   _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx);
676   if ((Q.x == sk->Q.x) && (Q.y == sk->Q.y) && (Q.z == sk->Q.z))
677     {
678       if (DBG_CIPHER)
679         log_debug
680           ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
681       _gcry_mpi_ec_free (ctx);
682       return (1);
683     }
684   _gcry_mpi_ec_free (ctx);
685   point_free (&Q);
686   return 0;
687 }
688
689
690 /*
691  * Return the signature struct (r,s) from the message hash.  The caller
692  * must have allocated R and S.
693  */
694 static gpg_err_code_t
695 sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s)
696 {
697   gpg_err_code_t err = 0;
698   gcry_mpi_t k, dr, sum, k_1, x;
699   mpi_point_t I;
700   mpi_ec_t ctx;
701
702   k = NULL;
703   dr = mpi_alloc (0);
704   sum = mpi_alloc (0);
705   k_1 = mpi_alloc (0);
706   x = mpi_alloc (0);
707   point_init (&I);
708
709   mpi_set_ui (s, 0);
710   mpi_set_ui (r, 0);
711
712   ctx = _gcry_mpi_ec_init (skey->E.p, skey->E.a);
713
714   while (!mpi_cmp_ui (s, 0)) /* s == 0 */
715     {
716       while (!mpi_cmp_ui (r, 0)) /* r == 0 */
717         {
718           /* Note, that we are guaranteed to enter this loop at least
719              once because r has been intialized to 0.  We can't use a
720              do_while because we want to keep the value of R even if S
721              has to be recomputed.  */
722           mpi_free (k);
723           k = gen_k (skey->E.n, GCRY_STRONG_RANDOM);
724           _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx); 
725           if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
726             {
727               if (DBG_CIPHER)
728                 log_debug ("ecc sign: Failed to get affine coordinates\n");
729               err = GPG_ERR_BAD_SIGNATURE;
730               goto leave;
731             }
732           mpi_mod (r, x, skey->E.n);  /* r = x mod n */
733         }
734       mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n  */
735       mpi_addm (sum, input, dr, skey->E.n); /* sum = hash + (d*r) mod n  */
736       mpi_invm (k_1, k, skey->E.n);         /* k_1 = k^(-1) mod n  */
737       mpi_mulm (s, k_1, sum, skey->E.n);    /* s = k^(-1)*(hash+(d*r)) mod n */
738     }
739
740  leave:
741   _gcry_mpi_ec_free (ctx);
742   point_free (&I);
743   mpi_free (x);
744   mpi_free (k_1);
745   mpi_free (sum);
746   mpi_free (dr);
747   mpi_free (k);
748
749   return err;
750 }
751
752 /*
753  * Check if R and S verifies INPUT.
754  */
755 static gpg_err_code_t
756 verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
757 {
758   gpg_err_code_t err = 0;
759   gcry_mpi_t h, h1, h2, x, y;
760   mpi_point_t Q, Q1, Q2;
761   mpi_ec_t ctx;
762
763   if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
764     return GPG_ERR_BAD_SIGNATURE; /* Assertion  0 < r < n  failed.  */
765   if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
766     return GPG_ERR_BAD_SIGNATURE; /* Assertion  0 < s < n  failed.  */
767
768   h  = mpi_alloc (0);
769   h1 = mpi_alloc (0);
770   h2 = mpi_alloc (0);
771   x = mpi_alloc (0);
772   y = mpi_alloc (0);
773   point_init (&Q);
774   point_init (&Q1);
775   point_init (&Q2);
776
777   ctx = _gcry_mpi_ec_init (pkey->E.p, pkey->E.a);
778
779   /* h  = s^(-1) (mod n) */
780   mpi_invm (h, s, pkey->E.n);
781 /*   log_mpidump ("   h", h); */
782   /* h1 = hash * s^(-1) (mod n) */
783   mpi_mulm (h1, input, h, pkey->E.n);
784 /*   log_mpidump ("  h1", h1); */
785   /* Q1 = [ hash * s^(-1) ]G  */
786   _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
787 /*   log_mpidump ("Q1.x", Q1.x); */
788 /*   log_mpidump ("Q1.y", Q1.y); */
789 /*   log_mpidump ("Q1.z", Q1.z); */
790   /* h2 = r * s^(-1) (mod n) */
791   mpi_mulm (h2, r, h, pkey->E.n);
792 /*   log_mpidump ("  h2", h2); */
793   /* Q2 = [ r * s^(-1) ]Q */
794   _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
795 /*   log_mpidump ("Q2.x", Q2.x); */
796 /*   log_mpidump ("Q2.y", Q2.y); */
797 /*   log_mpidump ("Q2.z", Q2.z); */
798   /* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
799   _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
800 /*   log_mpidump (" Q.x", Q.x); */
801 /*   log_mpidump (" Q.y", Q.y); */
802 /*   log_mpidump (" Q.z", Q.z); */
803
804   if (!mpi_cmp_ui (Q.z, 0))
805     {
806       if (DBG_CIPHER)
807           log_debug ("ecc verify: Rejected\n");
808       err = GPG_ERR_BAD_SIGNATURE;
809       goto leave;
810     }
811   if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
812     {
813       if (DBG_CIPHER)
814         log_debug ("ecc verify: Failed to get affine coordinates\n");
815       err = GPG_ERR_BAD_SIGNATURE;
816       goto leave;
817     }
818   mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
819   if (mpi_cmp (x, r))   /* x != r */
820     {
821       if (DBG_CIPHER)
822         {
823           log_mpidump ("   x", x);
824           log_mpidump ("   y", y);
825           log_mpidump ("   r", r);
826           log_mpidump ("   s", s);
827           log_debug ("ecc verify: Not verified\n");
828         }
829       err = GPG_ERR_BAD_SIGNATURE;
830       goto leave;
831     }
832   if (DBG_CIPHER)
833     log_debug ("ecc verify: Accepted\n");
834
835  leave:
836   _gcry_mpi_ec_free (ctx);
837   point_free (&Q2);
838   point_free (&Q1);
839   point_free (&Q);
840   mpi_free (y);
841   mpi_free (x);
842   mpi_free (h2);
843   mpi_free (h1);
844   mpi_free (h);
845   return err;
846 }
847
848
849
850 /*********************************************
851  **************  interface  ******************
852  *********************************************/
853 static gcry_mpi_t
854 ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p)
855 {
856   gpg_error_t err;
857   int pbytes = (mpi_get_nbits (p)+7)/8;
858   size_t n;
859   unsigned char *buf, *ptr;
860   gcry_mpi_t result;
861
862   buf = gcry_xmalloc ( 1 + 2*pbytes );
863   *buf = 04; /* Uncompressed point.  */
864   ptr = buf+1;
865   err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, x);
866   if (err)
867     log_fatal ("mpi_print failed: %s\n", gpg_strerror (err));
868   if (n < pbytes)
869     {
870       memmove (ptr+(pbytes-n), ptr, n);
871       memset (ptr, 0, (pbytes-n));
872     }
873   ptr += pbytes;
874   err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, y);
875   if (err)
876     log_fatal ("mpi_print failed: %s\n", gpg_strerror (err));
877   if (n < pbytes)
878     {
879       memmove (ptr+(pbytes-n), ptr, n);
880       memset (ptr, 0, (pbytes-n));
881     }
882   
883   err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, buf, 1+2*pbytes, NULL);
884   if (err)
885     log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err));
886   gcry_free (buf);
887
888   mpi_free (x);
889   mpi_free (y);
890
891   return result;
892 }
893
894 /* RESULT must have been initialized and is set on success to the
895    point given by VALUE.  */
896 static gcry_error_t
897 os2ec (mpi_point_t *result, gcry_mpi_t value)
898 {
899   gcry_error_t err;
900   size_t n;
901   unsigned char *buf;
902   gcry_mpi_t x, y;
903
904   n = (mpi_get_nbits (value)+7)/8;
905   buf = gcry_xmalloc (n);
906   err = gcry_mpi_print (GCRYMPI_FMT_USG, buf, n, &n, value);
907   if (err)
908     {
909       gcry_free (buf);
910       return err;
911     }
912   if (n < 1) 
913     {
914       gcry_free (buf);
915       return GPG_ERR_INV_OBJ;
916     }
917   if (*buf != 4)
918     {
919       gcry_free (buf);
920       return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression.  */
921     }
922   if ( ((n-1)%2) ) 
923     {
924       gcry_free (buf);
925       return GPG_ERR_INV_OBJ;
926     }
927   n = (n-1)/2;
928   err = gcry_mpi_scan (&x, GCRYMPI_FMT_USG, buf+1, n, NULL);
929   if (err)
930     {
931       gcry_free (buf);
932       return err;
933     }
934   err = gcry_mpi_scan (&y, GCRYMPI_FMT_USG, buf+1+n, n, NULL);
935   gcry_free (buf);
936   if (err)
937     {
938       mpi_free (x);
939       return err;
940     }
941
942   mpi_set (result->x, x);
943   mpi_set (result->y, y);
944   mpi_set_ui (result->z, 1);
945
946   mpi_free (x);
947   mpi_free (y);
948   
949   return 0;
950 }
951
952
953 /* Extended version of ecc_generate.  */
954 static gcry_err_code_t
955 ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
956                   const gcry_sexp_t genparms,
957                   gcry_mpi_t *skey, gcry_mpi_t **retfactors,
958                   gcry_sexp_t *r_extrainfo)
959 {
960   gpg_err_code_t ec;
961   ECC_secret_key sk;
962   gcry_mpi_t g_x, g_y, q_x, q_y;
963   char *curve_name = NULL;
964   gcry_sexp_t l1;
965
966   (void)algo;
967   (void)evalue;
968   (void)r_extrainfo;
969
970   if (genparms)
971     {
972       /* Parse the optional "curve" parameter. */
973       l1 = gcry_sexp_find_token (genparms, "curve", 0);
974       if (l1)
975         {
976           curve_name = _gcry_sexp_nth_string (l1, 1);
977           gcry_sexp_release (l1);
978           if (!curve_name)
979             return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
980         }
981     }
982
983   /* NBITS is required if no curve name has been given.  */
984   if (!nbits && !curve_name)
985     return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
986
987   g_x = mpi_new (0);
988   g_y = mpi_new (0);
989   q_x = mpi_new (0);
990   q_y = mpi_new (0);
991   ec = generate_key (&sk, nbits, curve_name, g_x, g_y, q_x, q_y);
992   gcry_free (curve_name);
993   if (ec)
994     return ec;
995
996   skey[0] = sk.E.p;
997   skey[1] = sk.E.a;
998   skey[2] = sk.E.b;
999   /* The function ec2os releases g_x and g_y.  */
1000   skey[3] = ec2os (g_x, g_y, sk.E.p);
1001   skey[4] = sk.E.n;
1002   /* The function ec2os releases g_x and g_y.  */
1003   skey[5] = ec2os (q_x, q_y, sk.E.p);
1004   skey[6] = sk.d;
1005
1006   point_free (&sk.E.G);
1007   point_free (&sk.Q);
1008
1009   /* Make an empty list of factors.  */
1010   *retfactors = gcry_calloc ( 1, sizeof **retfactors );
1011   if (!*retfactors)
1012     return gpg_err_code_from_syserror ();
1013
1014   return 0;
1015 }
1016
1017
1018 static gcry_err_code_t
1019 ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
1020               gcry_mpi_t *skey, gcry_mpi_t **retfactors)
1021 {
1022   (void)evalue;
1023   return ecc_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
1024 }
1025
1026
1027 /* Return the parameters of the curve NAME.  */
1028 static gcry_err_code_t
1029 ecc_get_param (const char *name, gcry_mpi_t *pkey)
1030 {
1031   gpg_err_code_t err;
1032   unsigned int nbits;
1033   elliptic_curve_t E;
1034   mpi_ec_t ctx;
1035   gcry_mpi_t g_x, g_y;
1036   
1037   err = generate_curve (0, name, &E, &nbits);
1038   if (err)
1039     return err;
1040
1041   g_x = mpi_new (0);
1042   g_y = mpi_new (0);
1043   ctx = _gcry_mpi_ec_init (E.p, E.a);
1044   if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx))
1045     log_fatal ("ecc get param: Failed to get affine coordinates\n");
1046   _gcry_mpi_ec_free (ctx);
1047   point_free (&E.G);
1048
1049   pkey[0] = E.p;
1050   pkey[1] = E.a;
1051   pkey[2] = E.b;
1052   pkey[3] = ec2os (g_x, g_y, E.p);
1053   pkey[4] = E.n;
1054   pkey[5] = NULL;
1055
1056   return 0;
1057 }
1058
1059
1060 static gcry_err_code_t
1061 ecc_check_secret_key (int algo, gcry_mpi_t *skey)
1062 {
1063   gpg_err_code_t err;
1064   ECC_secret_key sk;
1065
1066   (void)algo;
1067
1068   if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
1069       || !skey[6] || !skey[7] || !skey[8] || !skey[9] || !skey[10])
1070     return GPG_ERR_BAD_MPI;
1071
1072   sk.E.p = skey[0];
1073   sk.E.a = skey[1];
1074   sk.E.b = skey[2];
1075   point_init (&sk.E.G);
1076   err = os2ec (&sk.E.G, skey[3]);
1077   if (err)
1078     {
1079       point_free (&sk.E.G);
1080       return err;
1081     }
1082   sk.E.n = skey[4];
1083   point_init (&sk.Q);
1084   err = os2ec (&sk.Q, skey[5]);
1085   if (err)
1086     {
1087       point_free (&sk.E.G);
1088       point_free (&sk.Q);
1089       return err;
1090     }
1091
1092   sk.d = skey[6];
1093
1094   if (check_secret_key (&sk))
1095     {
1096       point_free (&sk.E.G);
1097       point_free (&sk.Q);
1098       return GPG_ERR_BAD_SECKEY;
1099     }
1100   point_free (&sk.E.G);
1101   point_free (&sk.Q);
1102   return 0;
1103 }
1104
1105
1106 static gcry_err_code_t
1107 ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
1108 {
1109   gpg_err_code_t err;
1110   ECC_secret_key sk;
1111
1112   (void)algo;
1113
1114   if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1115       || !skey[5] || !skey[6] )
1116     return GPG_ERR_BAD_MPI;
1117
1118   sk.E.p = skey[0];
1119   sk.E.a = skey[1];
1120   sk.E.b = skey[2];
1121   point_init (&sk.E.G);
1122   err = os2ec (&sk.E.G, skey[3]);
1123   if (err)
1124     {
1125       point_free (&sk.E.G);
1126       return err;
1127     }
1128   sk.E.n = skey[4];
1129   point_init (&sk.Q);
1130   err = os2ec (&sk.Q, skey[5]);
1131   if (err)
1132     {
1133       point_free (&sk.E.G);
1134       point_free (&sk.Q);
1135       return err;
1136     }
1137   sk.d = skey[6];
1138
1139   resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1140   resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1141   err = sign (data, &sk, resarr[0], resarr[1]);
1142   if (err)
1143     {
1144       mpi_free (resarr[0]);
1145       mpi_free (resarr[1]);
1146       resarr[0] = NULL; /* Mark array as released.  */
1147     }
1148   point_free (&sk.E.G);
1149   point_free (&sk.Q);
1150   return err;
1151 }
1152
1153 static gcry_err_code_t
1154 ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
1155             int (*cmp)(void *, gcry_mpi_t), void *opaquev)
1156 {
1157   gpg_err_code_t err;
1158   ECC_public_key pk;
1159
1160   (void)algo;
1161   (void)cmp;
1162   (void)opaquev;
1163
1164   if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2]
1165       || !pkey[3] || !pkey[4] || !pkey[5] )
1166     return GPG_ERR_BAD_MPI;
1167
1168   pk.E.p = pkey[0];
1169   pk.E.a = pkey[1];
1170   pk.E.b = pkey[2];
1171   point_init (&pk.E.G);
1172   err = os2ec (&pk.E.G, pkey[3]);
1173   if (err)
1174     {
1175       point_free (&pk.E.G);
1176       return err;
1177     }
1178   pk.E.n = pkey[4];
1179   point_init (&pk.Q);
1180   err = os2ec (&pk.Q, pkey[5]);
1181   if (err)
1182     {
1183       point_free (&pk.E.G);
1184       point_free (&pk.Q);
1185       return err;
1186     }
1187
1188   err = verify (hash, &pk, data[0], data[1]);
1189
1190   point_free (&pk.E.G);
1191   point_free (&pk.Q);
1192   return err;
1193 }
1194
1195
1196
1197 static unsigned int
1198 ecc_get_nbits (int algo, gcry_mpi_t *pkey)
1199 {
1200   (void)algo;
1201
1202   return mpi_get_nbits (pkey[0]);
1203 }
1204
1205
1206
1207 /* See rsa.c for a description of this function.  */
1208 static gpg_err_code_t
1209 compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
1210 {
1211   static const char names[] = "pabgnq";
1212   gpg_err_code_t ec = 0;
1213   gcry_sexp_t l1;
1214   gcry_mpi_t values[6];
1215   int idx;
1216
1217   /* Clear the values for easier error cleanup.  */
1218   for (idx=0; idx < 6; idx++)
1219     values[idx] = NULL;
1220     
1221   /* Fill values with all available parameters.  */
1222   for (idx=0; idx < 6; idx++)
1223     {
1224       l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
1225       if (l1)
1226         {
1227           values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1228           gcry_sexp_release (l1);
1229           if (!values[idx])
1230             {
1231               ec = GPG_ERR_INV_OBJ;
1232               goto leave;
1233             }
1234         }
1235     }
1236   
1237   /* Check whether a curve parameter is available and use that to fill
1238      in missing values.  */
1239   l1 = gcry_sexp_find_token (keyparam, "curve", 5);
1240   if (l1)
1241     {
1242       char *curve;
1243       gcry_mpi_t tmpvalues[6];
1244       
1245       for (idx = 0; idx < 6; idx++)
1246         tmpvalues[idx] = NULL;
1247
1248       curve = _gcry_sexp_nth_string (l1, 1);
1249       if (!curve)
1250         {
1251           ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
1252           goto leave;
1253         }
1254       ec = ecc_get_param (curve, tmpvalues);
1255       gcry_free (curve);
1256       if (ec)
1257         goto leave;
1258
1259       for (idx = 0; idx < 6; idx++)
1260         {
1261           if (!values[idx])
1262             values[idx] = tmpvalues[idx];
1263           else
1264             mpi_free (tmpvalues[idx]);
1265         }
1266     }
1267
1268   /* Check that all parameters are known and normalize all MPIs (that
1269      should not be required but we use an internal fucntion later and
1270      thus we better make 100% sure that they are normalized). */
1271   for (idx = 0; idx < 6; idx++)
1272     if (!values[idx])
1273       {
1274         ec = GPG_ERR_NO_OBJ;
1275         goto leave;
1276       }
1277     else
1278       _gcry_mpi_normalize (values[idx]);
1279       
1280   /* Hash them all.  */
1281   for (idx = 0; idx < 6; idx++)
1282     {
1283       char buf[30];
1284       unsigned char *rawmpi;
1285       unsigned int rawmpilen;
1286       
1287       rawmpi = _gcry_mpi_get_buffer (values[idx], &rawmpilen, NULL);
1288       if (!rawmpi)
1289         {
1290           ec = gpg_err_code_from_syserror ();
1291           goto leave;
1292         }
1293       snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
1294       gcry_md_write (md, buf, strlen (buf));
1295       gcry_md_write (md, rawmpi, rawmpilen);
1296       gcry_md_write (md, ")", 1);
1297       gcry_free (rawmpi);
1298     }
1299
1300  leave:
1301   for (idx = 0; idx < 6; idx++)
1302     _gcry_mpi_release (values[idx]);
1303   
1304   return ec;
1305 }
1306
1307
1308
1309
1310 \f
1311 /* 
1312      Self-test section.
1313  */
1314
1315
1316 static gpg_err_code_t
1317 selftests_ecdsa (selftest_report_func_t report)
1318 {
1319   const char *what;
1320   const char *errtxt;
1321   
1322   what = "low-level";
1323   errtxt = NULL; /*selftest ();*/
1324   if (errtxt)
1325     goto failed;
1326
1327   /* FIXME:  need more tests.  */
1328
1329   return 0; /* Succeeded. */
1330
1331  failed:
1332   if (report)
1333     report ("pubkey", GCRY_PK_ECDSA, what, errtxt);
1334   return GPG_ERR_SELFTEST_FAILED;
1335 }
1336
1337
1338 /* Run a full self-test for ALGO and return 0 on success.  */
1339 static gpg_err_code_t
1340 run_selftests (int algo, int extended, selftest_report_func_t report)
1341 {
1342   gpg_err_code_t ec;
1343
1344   (void)extended;
1345
1346   switch (algo)
1347     {
1348     case GCRY_PK_ECDSA:
1349       ec = selftests_ecdsa (report);
1350       break;
1351     default:
1352       ec = GPG_ERR_PUBKEY_ALGO;
1353       break;
1354         
1355     }
1356   return ec;
1357 }
1358
1359
1360
1361 \f
1362 static const char *ecdsa_names[] =
1363   {
1364     "ecdsa",
1365     "ecc",
1366     NULL,
1367   };
1368
1369 gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
1370   {
1371     "ECDSA", ecdsa_names,
1372     "pabgnq", "pabgnqd", "", "rs", "pabgnq",
1373     GCRY_PK_USAGE_SIGN,
1374     ecc_generate,
1375     ecc_check_secret_key,
1376     NULL,
1377     NULL,
1378     ecc_sign,
1379     ecc_verify,
1380     ecc_get_nbits
1381   };
1382
1383 pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa = 
1384   {
1385     run_selftests,
1386     ecc_generate_ext,
1387     compute_keygrip,
1388     ecc_get_param
1389   };
1390