Experimental support for ECDSA.
[libgcrypt.git] / cipher / ecc.c
1 /* ecc.c  -  ECElGamal Public Key encryption & ECDSA signature algorithm
2  * Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG 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 General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * 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
22 /* TODO wk
23
24   - Check whether we can LGPL the code.
25
26
27 */
28
29 /* This code is a based on the 
30  * Patch 0.1.6 for the gnupg 1.4.x branch
31  * as retrieved on 2007-03-21 from
32  * http://www.calcurco.cat/eccGnuPG/src/gnupg-1.4.6-ecc0.2.0beta1.diff.bz2
33  *
34  * Written by 
35  *  Sergi Blanch i Torne <d4372211 at alumnes.eup.udl.es>, 
36  *  Ramiro Moreno Chiral <ramiro at eup.udl.es>
37  * Maintainers
38  *  Sergi Blanch i Torne
39  *  Ramiro Moreno Chiral
40  *  Mikael Mylnikov (mmr)
41  */
42
43 /*
44  * This module are under development, it would not have to be used 
45  * in a production environments. It can have bugs!
46  * 
47  * Made work:
48  *  alex: found a bug over the passphrase.
49  *  mmr: signature bug found and solved (afine conversion).
50  *  mmr: found too many mistakes in the mathematical background transcription.
51  *  mmr: improve the mathematical performance.
52  *  mmr: solve ECElGamal IFP weakness.
53  *  more polite gen_k() and its calls.
54  *  mmr: extend the check_secret_key()
55  * In process:
56  *  gen_big_point(): Randomize the point generation.
57  *  improve te memory uses.
58  *  Separation between sign & encrypt keys to facility the subkeys creation.
59  *  read & reread the code in a bug search!
60  * To do:
61  *  2-isogeny: randomize the elliptic curves.
62  *  E(F_{2^m})
63  */
64
65 #include <config.h>
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <string.h>
69
70 #include "g10lib.h"
71 #include "mpi.h"
72 #include "cipher.h"
73
74 /* 
75     ECC over F_p; E(F_p)
76     T=(p,a,b,G,n,h)
77              p:    big odd number
78              a,b:  curve generators
79              G:    Subgroup generator point
80              n:    big int, in G order
81              h:    cofactor
82      y^2=x^3+ax+b --> (Y^2)Z=X^3+aX(Z^2)+b(Z^3)
83     
84     
85              Q=[d]G, 1<=d<=n-1
86 */
87
88
89 /* Point representation in projective coordinates. */
90 typedef struct
91 {
92   gcry_mpi_t x_;
93   gcry_mpi_t y_;
94   gcry_mpi_t z_;
95 } point_t;
96
97
98 /* Definition of a curve.  */
99 typedef struct
100 {
101   gcry_mpi_t p_;  /* Prime specifying the field GF(p).  */
102   gcry_mpi_t a_;  /* First coefficient of the Weierstrass equation.  */
103   gcry_mpi_t b_;  /* Second coefficient of teh Weierstrass equation.  */
104   point_t G;      /* Base point (generator).  */
105   gcry_mpi_t n_;  /* Order of G.  */
106   /*gcry_mpi_t h_; =1  fixme: We will need to change this value in 2-isogeny */
107 } elliptic_curve_t;             /* Fixme: doubtful name */
108
109
110 typedef struct
111 {
112   elliptic_curve_t E;
113   point_t Q;                    /* Q=[d]G */
114 } ECC_public_key;               /* Q */
115
116 typedef struct
117 {
118   elliptic_curve_t E;
119   point_t Q;                    /* Q=[d]G */
120   gcry_mpi_t d;
121 } ECC_secret_key;               /* d */
122
123
124 /* This static table defines all available curves.  */
125 static const struct
126 {
127   const char *desc;           /* Description of the curve.  */
128   unsigned int nbits;         /* Number of bits.  */
129   const char  *p, *a, *b, *n; /* Parameters.  */
130   const char *g_x, *g_y;      /* G_z is always 1.  */
131 } domain_parms[] = 
132   {
133     { 
134       "NIST P-192", 192,
135       "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
136       "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
137       "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
138       "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
139       
140       "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
141       "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
142     },
143     { 
144       "NIST P-224", 224,
145       "0xffffffffffffffffffffffffffffffff000000000000000000000001",
146       "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
147       "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
148       "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
149
150       "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
151       "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"
152     },
153     { 
154       "NIST P-256", 256,
155       "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
156       "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
157       "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
158       "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
159       
160       "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
161       "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
162     },
163     {
164       "NIST P-384", 384,
165       "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
166       "ffffffff0000000000000000ffffffff",
167       "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
168       "ffffffff0000000000000000fffffffc",  
169       "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
170       "c656398d8a2ed19d2a85c8edd3ec2aef",
171       "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
172       "581a0db248b0a77aecec196accc52973",
173
174       "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
175       "5502f25dbf55296c3a545e3872760ab7",
176       "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
177       "0a60b1ce1d7e819d7a431d7c90ea0e5f"
178     },
179     {
180       "NIST P-521", 521,
181       "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
182       "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
183       "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
184       "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
185       "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
186       "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
187       "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
188       "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
189
190       "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
191       "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
192       "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
193       "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
194     },
195     { NULL, 0, NULL, NULL, NULL, NULL }
196   };
197
198
199 /* Registered progress function and its callback value. */
200 static void (*progress_cb) (void *, const char*, int, int, int);
201 static void *progress_cb_data;
202
203
204
205 \f
206 /* Local prototypes. */
207 static gcry_mpi_t gen_k (gcry_mpi_t p, int secure);
208 static void test_keys (ECC_secret_key * sk, unsigned int nbits);
209 static int check_secret_key (ECC_secret_key * sk);
210 static void sign (gcry_mpi_t input, ECC_secret_key * skey, gcry_mpi_t * r, gcry_mpi_t * s);
211 static int verify (gcry_mpi_t input, ECC_public_key * pkey, gcry_mpi_t r, gcry_mpi_t s);
212
213
214 static int point_at_infinity (point_t query);
215
216 static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base);
217
218
219
220 \f
221 void
222 _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
223                                             int, int, int),
224                                 void *cb_data)
225 {
226   progress_cb = cb;
227   progress_cb_data = cb_data;
228 }
229
230 static void
231 progress (int c)
232 {
233   if (progress_cb)
234     progress_cb (progress_cb_data, "pk_dsa", c, 0, 0);
235   else
236     fputc (c, stderr);
237 }
238
239
240 \f
241 /*
242
243     O B J E C T   M A I N T E N A N C E
244
245  */
246
247 /* Intialize a point object, so that its elements may be sued directly
248    as MPI functions.  point_free is required for each initialzied
249    point. */
250 static void
251 point_init (point_t *P)
252 {
253   P->x_ = mpi_new (0);
254   P->y_ = mpi_new (0);
255   P->z_ = mpi_new (0);
256 }
257
258
259 /*
260  * Release a point object.
261  */
262 static void
263 point_free (point_t *P)
264 {
265   mpi_free (P->x_); P->x_ = NULL;
266   mpi_free (P->y_); P->y_ = NULL;
267   mpi_free (P->z_); P->z_ = NULL;
268 }
269
270
271 /*
272  * Return a copy of a point object.
273  */
274 static point_t
275 point_copy (point_t P)
276 {
277   point_t R;
278
279   R.x_ = mpi_copy (P.x_);
280   R.y_ = mpi_copy (P.y_);
281   R.z_ = mpi_copy (P.z_);
282
283   return R;
284 }
285
286
287 /*
288  * Release a curve object.
289  */
290 static void
291 curve_free (elliptic_curve_t *E)
292 {
293   mpi_free (E->p_); E->p_ = NULL;
294   mpi_free (E->a_); E->a_ = NULL;
295   mpi_free (E->b_);  E->b_ = NULL;
296   point_free (&E->G);
297   mpi_free (E->n_);  E->n_ = NULL;
298 }
299
300
301 /*
302  * Return a copy of a curve object.
303  */
304 static elliptic_curve_t
305 curve_copy (elliptic_curve_t E)
306 {
307   elliptic_curve_t R;
308
309   R.p_ = mpi_copy (E.p_);
310   R.a_ = mpi_copy (E.a_);
311   R.b_ = mpi_copy (E.b_);
312   R.G  = point_copy (E.G);
313   R.n_ = mpi_copy (E.n_);
314
315   return R;
316 }
317
318
319 \f
320 /*
321
322     A D D I T I O N A L   M P I   F U N C T I O N S
323
324  */
325
326
327 /****************
328  * Find, if it exist, the square root of one integer modulo a big prime.
329  * Return the square root or NULL if it is not found.
330  */
331 #if 0
332 static gcry_mpi_t
333 exist_square_root (gcry_mpi_t integer, gcry_mpi_t modulus)
334 {
335   unsigned long int i = 0;
336   gcry_mpi_t one, two, three, four, five, eight;
337   gcry_mpi_t k, r, z, k1;
338   gcry_mpi_t t1, t2, t3, t4;
339
340   one = mpi_alloc_set_ui (1);
341   two = mpi_alloc_set_ui (2);
342   three = mpi_alloc_set_ui (3);
343   four = mpi_alloc_set_ui (4);
344   five = mpi_alloc_set_ui (5);
345   eight = mpi_alloc_set_ui (8);
346   k = mpi_alloc (mpi_get_nlimbs (modulus));
347   r = mpi_alloc (mpi_get_nlimbs (modulus));
348   z = mpi_alloc (mpi_get_nlimbs (modulus));
349   k1 = mpi_alloc (mpi_get_nlimbs (modulus));
350   t1 = mpi_alloc (mpi_get_nlimbs (modulus));
351   t2 = mpi_alloc (mpi_get_nlimbs (modulus));
352   t3 = mpi_alloc (mpi_get_nlimbs (modulus));
353   t4 = mpi_alloc (mpi_get_nlimbs (modulus));
354
355   if (DBG_CIPHER)
356     log_mpidump ("?exist Square Root of ", integer);
357
358   mpi_fdiv_qr (k, r, modulus, four);
359   if (mpi_cmp (r, three))
360     {                           /* p=3 (mod 4) */
361       mpi_addm (k1, k, one, modulus);
362       mpi_powm (z, integer, k1, modulus);
363       if (DBG_CIPHER)
364         {
365           log_mpidump ("z=", z);
366         }
367       return z;                 /* value found */
368     }
369   mpi_fdiv_qr (k, r, modulus, eight);
370   if (mpi_cmp (r, five))
371     {                           /* p=5 (mod 8) */
372       mpi_mulm (t1, two, integer, modulus);
373       mpi_powm (t2, t1, k, modulus);
374       mpi_powm (t2, t2, two, modulus);
375       mpi_mulm (t2, t1, t2, modulus);
376       mpi_mulm (t3, integer, t1, modulus);
377       mpi_subm (t4, t2, one, modulus);
378       mpi_mulm (z, t3, t4, modulus);
379       if (DBG_CIPHER)
380         {
381           log_mpidump ("z=", z);
382         }
383       return z;                 /* value found */
384     }
385   if (mpi_cmp (r, one))
386     {                           /* p=1 (mod 8) */
387       while (i < 0xFF)
388         {                       /* while not find z after 256 iterations */
389           if (DBG_CIPHER)
390             log_debug ("Square root bucle.\n");
391           t1 = mpi_copy (integer);
392           t2 = gen_k (modulus, 0);
393           mpi_add_ui (t3, modulus, 1);  /* t3=p+1 */
394           mpi_rshift (t3, t3, 1);       /* t3=t3/2 */
395           lucas (t1, t2, t3, modulus, t4, t3);  /* t4=V_k */
396           mpi_rshift (z, t4, 1);        /* z=V/2 */
397           mpi_sub_ui (t3, modulus, 1);  /* t3=p-1 */
398           mpi_rshift (t4, t3, 2);       /* t4=t3/2 */
399           lucas (t1, t2, t4, modulus, t4, t1);  /* t1=Q_0 */
400           mpi_powm (t2, z, two, modulus);       /* t2=z^2 */
401           if (mpi_cmp (t1, integer))
402             {
403               if (DBG_CIPHER)
404                 {
405                   log_mpidump ("z=", z);
406                 }
407               return z;         /* value found */
408             }
409           if (t4 > mpi_alloc_set_ui (1) && t4 < t3)
410             {
411               if (DBG_CIPHER)
412                 log_debug ("Rejected.\n");
413               return (0);       /* NULL */
414             }
415           if (DBG_CIPHER)
416             log_debug ("Another loop.\n");
417         }
418     }
419   if (DBG_CIPHER)
420     log_debug ("iterations limit.\n");
421   return (0);                   /* because this algorithm not always finish. */
422 }
423 #endif /*0*/
424
425 /****************
426  * Formal definition:
427  * V_0 = 2; V_1 = p
428  * V_k = (p*V_(k-1)) - (q*V_(k-2))   for k >= 2
429  */
430 #if 0
431 static void
432 lucas (gcry_mpi_t n, gcry_mpi_t p_, gcry_mpi_t q_,
433        gcry_mpi_t k, gcry_mpi_t V_n, gcry_mpi_t Q_0)
434 {
435
436   gcry_mpi_t v0, v1, q0, q1;
437   gcry_mpi_t t1, t2;
438   unsigned int r, i;
439
440   v0 = mpi_alloc_set_ui (2);
441   v1 = mpi_copy (p_);
442   q0 = mpi_alloc_set_ui (1);
443   q1 = mpi_alloc_set_ui (1);
444   t1 = mpi_alloc_set_ui (0);
445   t2 = mpi_alloc_set_ui (0);
446
447   if (DBG_CIPHER)
448     {
449       log_debug ("Generating lucas sequence.\n");
450       log_mpidump ("k=", k);
451     }
452
453   r = mpi_get_nbits (k) - 1;
454   i = 0;
455   while (mpi_test_bit (k, i) != 1)
456     {                           /* search the first bit with value '1' */
457       i++;
458     }
459   while (i < r)
460     {
461       if (DBG_CIPHER)
462         {
463           log_debug ("Lucas sequence bucle.\n");
464           log_mpidump ("i=", mpi_alloc_set_ui (i));
465           log_mpidump ("r=", mpi_alloc_set_ui (r));
466         }
467       mpi_mulm (q0, q0, q1, n);
468       if (mpi_test_bit (k, i) == 1)
469         {
470           mpi_mulm (q1, q0, q_, n);
471           mpi_mul (t1, v0, v1);
472           mpi_mul (t2, p_, q0);
473           mpi_subm (v0, t1, t2, n);
474           mpi_powm (t1, v1, mpi_alloc_set_ui (2), n);
475           mpi_mul (t2, mpi_alloc_set_ui (2), q1);
476           mpi_subm (v1, t1, t2, n);
477         }
478       else
479         {
480           q1 = mpi_copy (q0);
481           mpi_mul (t1, v0, v1);
482           mpi_mul (t2, p_, q0);
483           mpi_subm (v1, t1, t2, n);
484           mpi_powm (t1, v0, mpi_alloc_set_ui (2), n);
485           mpi_mul (t2, mpi_alloc_set_ui (2), q0);
486           mpi_subm (v0, t1, t2, n);
487         }
488       i++;
489     }
490   V_n = mpi_copy (v0);
491   Q_0 = mpi_copy (q0);
492   if (DBG_CIPHER)
493     {
494       log_debug ("Lucas sequence generated.\n");
495       log_mpidump ("V_n=", V_n);
496       log_mpidump ("Q_0=", Q_0);
497     }
498 }
499 #endif /*0*/
500
501 \f
502 /* 
503
504    P O I N T   A N D   C U R V E   O P E R A T I O N S
505
506  */
507
508 /* fixme:
509  * The point at infinity is needed to make 
510  * a group structure to the elliptic curve.
511  * Know if one point is it, is needed so 
512  * much times in this code.
513  *
514  *  return true(1), false(0), or error(-1) for an invalid point
515  */
516 static int
517 point_at_infinity (point_t query)
518 {
519   if (!mpi_cmp_ui (query.z_, 0)) /* Z == 0 */
520     {
521       if ( /*mpi_cmp_ui(Query.x_,0) && */ mpi_cmp_ui (query.y_, 0))
522         {
523           /* X && Y != 0 & Z == 0 */
524           /* Fixme: The above condition is not asserted.  We may get
525              to here if X is 0 ! */
526           if (DBG_CIPHER)
527             log_debug ("True:It is a Point at Infinite.\n");
528           return 1;
529         }
530       if (DBG_CIPHER)
531         log_debug ("Error:It isn't an elliptic curve valid point.\n");
532       return -1;
533     }
534   return 0;  /* It is a valid curve point, but not the point at infinity.  */
535 }
536
537
538 /*
539  * Turn a projective coordinate to affine, return 0 (or 1 in error case).
540  * Returns 0 on success.
541  *
542  * Note, that Y is never used as we can do without it.
543  */
544 static int
545 point_affine (point_t *P, gcry_mpi_t x, gcry_mpi_t y, elliptic_curve_t *base)
546 {
547   gcry_mpi_t z1, z2, z3;
548
549   z1 = mpi_new (0);
550   z2 = mpi_new (0);
551   z3 = mpi_new (0);
552
553   if (point_at_infinity (*P))
554     {
555       if (DBG_CIPHER)
556         log_debug ("ecc point_affine: "
557                    "Point at Infinity does NOT exist in the affine plane!\n");
558       return 1;
559     }
560
561   mpi_invm (z1, P->z_, base->p_);       /*       z1 =Z^{-1} (mod p) */
562   mpi_mulm (z2, z1, z1, base->p_);      /*       z2 =Z^(-2) (mod p) */
563   mpi_mulm (z3, z2, z1, base->p_);      /*       z3 =Z^(-3) (mod p) */
564   mpi_mulm (x, P->x_, z2, base->p_);
565   mpi_mulm (y, P->y_, z3, base->p_);
566
567   mpi_free (z1);
568   mpi_free (z2);
569   mpi_free (z3);
570   return 0;
571 }
572
573
574 /*
575  * The point inversion over F_p is a simple modular inversion of the Y
576  * coordinate.
577  */
578 static void
579 invert_point (point_t *P, elliptic_curve_t *base)
580 {
581   mpi_subm (P->y_, base->p_, P->y_, base->p_);  /* y = p - y mod p */
582 }
583
584
585 /*
586  * Scalar multiplication of one point, with the integer fixed to 2.
587  *  R = 2P
588  */
589 static void
590 duplicate_point (point_t *R, point_t *P, elliptic_curve_t * base)
591 {
592   gcry_mpi_t one, two, three, four, eight;
593   gcry_mpi_t p, p_3, a;
594   gcry_mpi_t t1, t2, t3, t4, t5, t6, t7;
595   gcry_mpi_t aux;
596
597   one = mpi_alloc_set_ui (1);
598   two = mpi_alloc_set_ui (2);
599   three = mpi_alloc_set_ui (3);
600   four = mpi_alloc_set_ui (4);
601   eight = mpi_alloc_set_ui (8);
602   p = mpi_copy (base->p_);
603   p_3 = mpi_alloc (mpi_get_nlimbs (p));
604   mpi_sub_ui (p_3, p, 3);
605   a = mpi_copy (base->a_);
606   t1 = mpi_alloc (mpi_get_nlimbs (p));
607   t2 = mpi_alloc (mpi_get_nlimbs (p));
608   t3 = mpi_alloc (mpi_get_nlimbs (p));
609   t4 = mpi_alloc (mpi_get_nlimbs (p));
610   t5 = mpi_alloc (mpi_get_nlimbs (p));
611   t6 = mpi_alloc (mpi_get_nlimbs (p));
612   t7 = mpi_alloc (mpi_get_nlimbs (p));
613   aux = mpi_alloc (mpi_get_nlimbs (p));
614
615   t1 = mpi_copy (P->x_);        /* t1=x1 */
616   t2 = mpi_copy (P->y_);        /* t2=y1 */
617   t3 = mpi_copy (P->z_);        /* t3=z1 */
618
619   if (!mpi_cmp_ui (t2, 0) || !mpi_cmp_ui (t3, 0))
620     {                           /* t2==0 | t3==0 => [1:1:0] */
621       mpi_set_ui (R->x_, 1);
622       mpi_set_ui (R->y_, 1);
623       mpi_set_ui (R->z_, 0);
624     }
625   else
626     {
627       mpi_mod (a, a, p);        /* a mod p */
628       if (!mpi_cmp (a, p_3))
629         {                       /* a==p-3 */
630           mpi_powm (t4, t3, two, p);    /* t4=t3^2 mod p */
631           mpi_subm (t5, t1, t4, p);     /* t5=t1-t4 mod p */
632           mpi_addm (t4, t1, t4, p);     /* t4=t1+t4 mod p */
633           mpi_mulm (t5, t4, t5, p);     /* t5=t4*t5 mod p */
634           mpi_mulm (t4, three, t5, p);  /* t4=3*t5 mod p */
635         }
636       else
637         {
638           t4 = mpi_copy (a);    /* t4=a */
639           mpi_powm (t5, t3, two, p);    /* t5=t3^2 mod p */
640           mpi_powm (t5, t5, two, p);    /* t5=t5^2 mod p */
641           mpi_mulm (t5, t4, t5, p);     /* t5=t4*t5 mod p */
642           mpi_powm (t4, t1, two, p);    /* t4=t1^2 mod p */
643           mpi_mulm (t4, three, t4, p);  /* t4=3*t4 mod p */
644           mpi_addm (t4, t4, t5, p);     /* t4=t4+t5 mod p */
645         }
646       mpi_mulm (t3, t2, t3, p); /* t3=t2*t3 mod p */
647       mpi_mulm (t3, two, t3, p);        /* t3=2*t3 mod p  */
648       mpi_powm (aux, t2, two, p);       /* t2=t2^2 mod p */
649       t2 = mpi_copy (aux);
650       mpi_mulm (t5, t1, t2, p); /* t5=t1*t2 mod p */
651       mpi_mulm (t5, four, t5, p);       /* t5=4*t5 mod p */
652       mpi_powm (t1, t4, two, p);        /* t1=t4^2 mod p */
653       mpi_mulm (aux, two, t5, p);
654       mpi_subm (t1, t1, aux, p);        /* t1=t1-2*t5 mod p */
655       mpi_powm (aux, t2, two, p);       /* t2=t2^2 mod p */
656       t2 = mpi_copy (aux);
657       mpi_mulm (t2, eight, t2, p);      /* t2=8*t2 mod p */
658       mpi_subm (t5, t5, t1, p); /* t5=t5-t1 mod p */
659       mpi_mulm (t5, t4, t5, p); /* t5=t4*t5 mod p */
660       mpi_subm (t2, t5, t2, p); /* t2=t5-t2 mod p */
661
662       mpi_set (R->x_, t1);
663       mpi_set (R->y_, t2);
664       mpi_set (R->z_, t3);
665     }
666
667   mpi_free (aux);
668   mpi_free (t7);
669   mpi_free (t6);
670   mpi_free (t5);
671   mpi_free (t4);
672   mpi_free (t3);
673   mpi_free (t2);
674   mpi_free (t1);
675   mpi_free (p);
676   mpi_free (p_3);
677   mpi_free (a);
678   mpi_free (eight);
679   mpi_free (four);
680   mpi_free (three);
681   mpi_free (two);
682   mpi_free (one);
683 }
684
685
686 /*
687    Point addition is the group operation.
688
689    R = P0 + P1
690  */
691 static void
692 sum_points (point_t *R, point_t *P0, point_t *P1, elliptic_curve_t * base)
693 {
694   gcry_mpi_t one, two;
695   gcry_mpi_t p;
696   gcry_mpi_t t1, t2, t3, t4, t5, t6, t7;
697   unsigned int nbits;
698
699   one = mpi_alloc_set_ui (1);
700   two = mpi_alloc_set_ui (2);
701   p = mpi_copy (base->p_);
702   nbits = mpi_get_nbits (p);
703   t1 = mpi_new (nbits);
704   t2 = mpi_new (nbits);
705   t3 = mpi_new (nbits);
706   t4 = mpi_new (nbits);
707   t5 = mpi_new (nbits);
708   t6 = mpi_new (nbits);
709   t7 = mpi_new (nbits);
710
711   if ( (!mpi_cmp (P1->x_, P0->x_))
712        && (!mpi_cmp (P1->y_, P0->y_))
713        && (!mpi_cmp (P1->z_, P0->z_)) ) /* P1 == P0 */
714     {                           
715       duplicate_point (R, P0, base);
716     }
717   else if (point_at_infinity (*P0)) /* R == 0 && P1 == P1 */
718     {                           
719       /* (!mpi_cmp_ui(P0->y_,0) || !mpi_cmp_ui(P0->z_,0))*/
720       mpi_set (R->x_, P1->x_);
721       mpi_set (R->y_, P1->y_);
722       mpi_set (R->z_, P1->z_);
723     }
724   else if (point_at_infinity (*P1)) /* R == P0 && P0 == 0 */
725     {           
726       /* (!mpi_cmp_ui(P1->y_,0) || !mpi_cmp_ui(P1->z_,0)) */
727       mpi_set (R->x_, P0->x_);
728       mpi_set (R->y_, P0->y_);
729       mpi_set (R->z_, P0->z_);
730     }
731   else
732     {
733       t1 = mpi_copy (P0->x_);   /* t1=x0 */
734       t2 = mpi_copy (P0->y_);   /* t2=y0 */
735       t3 = mpi_copy (P0->z_);   /* t3=z0 */
736       t4 = mpi_copy (P1->x_);   /* t4=x1 */
737       t5 = mpi_copy (P1->y_);   /* t5=y2 */
738       if (mpi_cmp (P1->z_, one))  /* z1 != 1 */
739         {                       
740           /* fixme: Release old t6 or just set it. */
741           t6 = mpi_copy (P1->z_);       /* t6=z1 */
742           mpi_powm (t7, t6, two, p);    /* t7=t6^2 mod p */
743           mpi_mulm (t1, t1, t7, p);     /* t1=t1*t7 mod p */
744           mpi_mulm (t7, t6, t7, p);     /* t7=t6*t7 mod p */
745           mpi_mulm (t2, t2, t7, p);     /* t2=t2*t7 mod p */
746         }
747       mpi_powm (t7, t3, two, p);/* t7=t3^2 mod p */
748       mpi_mulm (t4, t4, t7, p); /* t4=t4*t7 mod p */
749       mpi_mulm (t7, t3, t7, p); /* t7=t3*t7 mod p */
750       mpi_mulm (t5, t5, t7, p); /* t5=t5*t7 mod p */
751       mpi_subm (t4, t1, t4, p); /* t4=t1-t4 mod p */
752       mpi_subm (t5, t2, t5, p); /* t5=t2-t5 mod p */
753
754       if (!mpi_cmp_ui (t4, 0)) /* t4==0 */
755         {                       
756           if (!mpi_cmp_ui (t5, 0))
757             {                   
758               /* return (0:0:0), it has a special mean. */
759               if (DBG_CIPHER)
760                 log_debug ("ecc sum_points: [0:0:0]!\n");
761               mpi_set_ui (R->x_, 0);
762               mpi_set_ui (R->y_, 0);
763               mpi_set_ui (R->z_, 0);
764             }
765           else
766             {           
767               if (DBG_CIPHER)
768                 log_debug ("ecc sum_points: [1:1:0]!\n");
769               mpi_set_ui (R->x_, 1);
770               mpi_set_ui (R->y_, 1);
771               mpi_set_ui (R->z_, 0);
772             }
773         }
774       else
775         {
776           mpi_mulm (t1, two, t1, p);
777           mpi_subm (t1, t1, t4, p);     /* t1=2*t1-t4 mod p */
778           mpi_mulm (t2, two, t2, p);
779           mpi_subm (t2, t2, t5, p);     /* t2=2*t2-t5 mod p */
780           if (mpi_cmp (P1->z_, one)) /* z1 != 1 */
781             {           
782               mpi_mulm (t3, t3, t6, p); /* t3=t3*t6 */
783             }
784           mpi_mulm (t3, t3, t4, p);     /* t3=t3*t4 mod p */
785           mpi_powm (t7, t4, two, p);    /* t7=t4^2 mod p */
786           mpi_mulm (t4, t4, t7, p);     /* t4=t4*t7 mod p */
787           mpi_mulm (t7, t1, t7, p);     /* t7=t1*t7 mod p */
788           mpi_powm (t1, t5, two, p);    /* t1=t5^2 mod p */
789           mpi_subm (t1, t1, t7, p);     /* t1=t1-t7 mod p */
790           mpi_mulm (t6, two, t1, p);
791           mpi_subm (t7, t7, t6, p);     /* t7=t7-2*t1 mod p */
792           mpi_mulm (t5, t5, t7, p);     /* t5=t5*t7 mod p */
793           mpi_mulm (t4, t2, t4, p);     /* t4=t2*t4 mod p */
794           mpi_subm (t2, t5, t4, p);     /* t2=t5-t4 mod p */
795           mpi_invm (t6, two, p);
796           mpi_mulm (t2, t2, t6, p);     /* t2 = t2/2 */
797
798           mpi_set (R->x_, t1);
799           mpi_set (R->y_, t2);
800           mpi_set (R->z_, t3);
801         }
802     }
803
804   mpi_free (t7);
805   mpi_free (t6);
806   mpi_free (t5);
807   mpi_free (t4);
808   mpi_free (t3);
809   mpi_free (t2);
810   mpi_free (t1);
811   mpi_free (p);
812   mpi_free (two);
813   mpi_free (one);
814 }
815
816 /****************
817  * The modular power used without EC, 
818  * is this function over EC.
819    return R = escalarP
820
821    ESCALAR = input
822    P       = input
823    BASE    = input
824    R       = output (caller must have intialized this point)
825
826  */
827 static void
828 escalar_mult (point_t *R, gcry_mpi_t escalar, point_t *P,
829               elliptic_curve_t *base)
830 {
831
832   gcry_mpi_t one, two, three;
833   gcry_mpi_t p;
834   gcry_mpi_t x1, y1, z1, z2, z3, k, h; 
835   gcry_mpi_t xx, yy, zz;
836   unsigned int i, loops;
837   point_t P1, P2, P1_;
838
839   if (DBG_CIPHER)
840     log_debug ("escalar_mult: begin\n");
841
842   one   = mpi_alloc_set_ui (1);
843   two   = mpi_alloc_set_ui (2);
844   three = mpi_alloc_set_ui (3);
845
846   p  = mpi_copy (base->p_);
847
848   x1 = mpi_alloc_like (P->x_);
849   y1 = mpi_alloc_like (P->y_);
850   /* z1 is not yet intialized.  */
851   z2 = mpi_alloc_like (P->z_);
852   z3 = mpi_alloc_like (P->z_);
853   /* k is not yet intialized.  */
854   h  = mpi_alloc_like (P->z_);
855
856
857   if (!mpi_cmp_ui (escalar, 0) || mpi_cmp_ui (P->z_, 0))
858     {                           /* n=0 | Z=0 => [1:1:0] */
859       mpi_set_ui (R->x_, 1);
860       mpi_set_ui (R->y_, 1);
861       mpi_set_ui (R->z_, 0);
862     }
863   xx = mpi_copy (P->x_);
864   zz = mpi_copy (P->z_);
865   z1 = mpi_copy (one);
866
867   if (mpi_is_neg (escalar))
868     {                           /* (-n)P=n(-P) */
869       escalar->sign = 0;        /* +n */
870       k = mpi_copy (escalar);
871       yy = mpi_copy (P->y_);    /* -P */
872       mpi_invm (yy, yy, p);
873     }
874   else
875     {
876       k = mpi_copy (escalar);
877       yy = mpi_copy (P->y_);
878     }
879   if (!mpi_cmp (zz, one))
880     {                           /* zz==1 */
881       x1 = mpi_copy (xx);
882       y1 = mpi_copy (yy);
883     }
884   else
885     {
886       mpi_mulm (z2, zz, zz, p); /* z^2 */
887       mpi_mulm (z3, zz, z2, p); /* z^3 */
888       mpi_invm (z2, z2, p);     /* 1/Z^2 */
889       mpi_mulm (x1, xx, z2, p); /* xx/z^2 */
890       mpi_invm (z3, z3, p);     /* 1/z^3 */
891       mpi_mulm (y1, yy, z3, p); /* yy/z^3 */
892     }
893   mpi_mul (h, three, k);        /* h=3k */
894   loops = mpi_get_nbits (h);
895   i = loops - 2;                /*  i = l-1 = loops-2 */
896   mpi_set (R->x_, xx);
897   mpi_set (R->y_, yy);
898   mpi_set (R->z_, zz);
899   P1.x_ = mpi_copy (x1);
900   P1.y_ = mpi_copy (y1);
901   P1.z_ = mpi_copy (z1);
902   while (i > 0)
903     {                           /*  A.10.9. step 11  i from l-1 downto 1 */
904       duplicate_point (R, R, base);
905       if (mpi_test_bit (h, i) == 1 && mpi_test_bit (k, i) == 0)
906         {                       /* h_i=1 & k_i=0 */
907           P2 = point_copy (*R);
908           sum_points (R, &P2, &P1, base); /* R=P2+P1 over the base elliptic curve */
909         }
910       if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1)
911         {                       /* h_i=0 & k_i=1 */
912           P2 = point_copy (*R);
913           P1_ = point_copy (P1);
914           invert_point (&P1_, base);
915           sum_points (R, &P2, &P1_, base); /* R=P2+P1_ over the base elliptic curve */
916         }
917       i--;
918     }
919
920   if (DBG_CIPHER)
921     log_debug ("escalar_mult: ready\n");
922
923   point_free (&P1);
924   point_free (&P2);
925   point_free (&P1_);
926   mpi_free (h);
927   mpi_free (k);
928   mpi_free (z3);
929   mpi_free (z2);
930   mpi_free (z1);
931   mpi_free (y1);
932   mpi_free (x1);
933   mpi_free (zz);
934   mpi_free (yy);
935   mpi_free (xx);
936   mpi_free (p);
937   mpi_free (three);
938   mpi_free (two);
939   mpi_free (one);
940 }
941
942
943 /****************
944  * Solve the right side of the equation that defines a curve.
945  */
946 static gcry_mpi_t
947 gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base)
948 {
949   gcry_mpi_t three;
950   gcry_mpi_t x_3, ax, axb, y;
951   gcry_mpi_t a, b, p;
952   unsigned int nbits;
953
954   three = mpi_alloc_set_ui (3);
955   a = mpi_copy (base->a_);
956   b = mpi_copy (base->b_);
957   p = mpi_copy (base->p_);
958   nbits = mpi_get_nbits (p);
959   x_3 = mpi_new (nbits);
960   ax  = mpi_new (nbits);
961   axb = mpi_new (nbits);
962   y   = mpi_new (nbits);
963
964   if (DBG_CIPHER)
965     log_debug ("ecc gen_y_2: Solving an elliptic equation.\n");
966
967   mpi_powm (x_3, x, three, p);  /* x_3=x^3 mod p */
968   mpi_mulm (ax, a, x, p);       /* ax=a*x mod p */
969   mpi_addm (axb, ax, b, p);     /* axb=ax+b mod p */
970   mpi_addm (y, x_3, axb, p);    /* y=x^3+ax+b mod p */
971
972   if (DBG_CIPHER)
973     log_debug ("ecc gen_y_2: Solved.\n");
974
975   return y; /* The quadratic value of the coordinate if it exist. */
976 }
977
978
979
980
981
982 \f
983 /*
984
985    E C C  C O R E  F U N C T I O N S
986  
987  */
988
989
990
991 /* Generate a random secret scalar k with an order of p
992
993    At the beginning this was identical to the code is in elgamal.c.
994    Later imporved by mmr.   Further simplified by wk.  */
995 static gcry_mpi_t
996 gen_k (gcry_mpi_t p, int secure)
997 {
998   gcry_mpi_t k;
999   unsigned int nbits;
1000
1001   nbits = mpi_get_nbits (p);
1002   k = (secure
1003        ? mpi_alloc_secure ( mpi_get_nlimbs (p) )
1004        : mpi_alloc ( mpi_get_nlimbs (p) ));
1005
1006   if (DBG_CIPHER)
1007     log_debug ("choosing a random k of %u bits\n", nbits);
1008   
1009   gcry_mpi_randomize (k, nbits, GCRY_STRONG_RANDOM);
1010
1011   mpi_mod (k, k, p);  /*  k = k mod p  */
1012
1013   if (DBG_CIPHER)
1014     progress ('\n');
1015
1016   return k;
1017 }
1018
1019
1020 /* Helper to scan a hex string. */
1021 static gcry_mpi_t
1022 scanval (const char *string)
1023 {
1024   gpg_error_t err;
1025   gcry_mpi_t val;
1026   
1027   err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
1028   if (err)
1029     log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (err));
1030   return val;
1031 }
1032
1033
1034 /****************
1035  * Generate the crypto system setup.
1036  * As of now the fix NIST recommended values are used.
1037  * The subgroup generator point is in another function: gen_big_point.
1038  */
1039 static gpg_err_code_t
1040 generate_curve (unsigned int nbits, elliptic_curve_t *curve)
1041 {
1042   int idx;
1043
1044   for (idx = 0; domain_parms[idx].desc; idx++)
1045     if (nbits == domain_parms[idx].nbits)
1046       break;
1047   if (!domain_parms[idx].desc)
1048     return GPG_ERR_INV_VALUE;
1049
1050   curve->p_ = scanval (domain_parms[idx].p);
1051   curve->a_ = scanval (domain_parms[idx].a);
1052   curve->b_ = scanval (domain_parms[idx].b);
1053   curve->n_ = scanval (domain_parms[idx].n);
1054   curve->G.x_ = scanval (domain_parms[idx].g_x);
1055   curve->G.y_ = scanval (domain_parms[idx].g_y);
1056   curve->G.z_ = mpi_alloc_set_ui (1);
1057
1058   /* Gx, Gy, Gz are planned to be generated by code like this:
1059      if ( gen_big_point (&curve->n_, curve, &curve->G, nbits) == -1)
1060       {
1061          log_fatal ("ECC operation: Point generation failed\n");
1062       }
1063
1064      A point of order 'n' is needed to generate a cyclic subgroup.
1065      Over this cyclic subgroup it's defined the ECDLP.  Now it use a
1066      fix values from NIST FIPS PUB 186-2.  Returns -1 if it isn't
1067      possible.
1068      static int
1069      gen_big_point (gcry_mpi_t * prime, elliptic_curve_t * base, point_t * G,
1070                     unsigned int nbits)
1071      {
1072          unsigned int i=0;
1073          gcry_mpi_t one;
1074          point_t Big, P;
1075     
1076          one = mpi_alloc_set_ui(1);
1077          G->x_ = mpi_alloc(mpi_get_nlimbs(*prime));
1078          G->y_ = mpi_alloc(mpi_get_nlimbs(*prime));
1079          G->z_ = mpi_alloc(mpi_get_nlimbs(*prime));
1080     
1081          if( DBG_CIPHER )log_debug("Generating a Big point.\n");
1082          do{
1083          do{
1084          *P = genPoint(*prime,*base);
1085          }while(PointAtInfinity(*P));//A random point in the curve that it's not PaI
1086          escalarMult(base.h,&P,&G,&base);//cofactor (1 o 2), could be improved
1087          }while(PointAtInfinity(G));
1088          if( DBG_CIPHER )log_debug("Big point generated.\n");
1089          if( DBG_CIPHER ){
1090          log_mpidump("Gx=",G->x_);log_mpidump("Gy=",G->y_);log_mpidump("Gz=",G->z_);
1091          }
1092      return 0;
1093      }
1094   */
1095
1096   if (DBG_CIPHER)
1097     {
1098       progress ('\n');
1099       log_mpidump ("ecc generation  p= ", curve->p_);
1100       log_mpidump ("ecc generation  a= ", curve->a_);
1101       log_mpidump ("ecc generation  b= ", curve->b_);
1102       log_mpidump ("ecc generation  n= ", curve->n_);
1103       log_mpidump ("ecc generation  Gx= ", curve->G.x_);
1104       log_mpidump ("ecc generation  Gy= ", curve->G.y_);
1105       log_mpidump ("ecc generation  Gz= ", curve->G.z_);
1106     }
1107   if (DBG_CIPHER)
1108     progress ('\n');
1109
1110   return 0;
1111 }
1112
1113
1114 /****************
1115  * First obtain the setup.  Over the finite field randomize an scalar
1116  * secret value, and calculate the public point.
1117  */
1118 static gpg_err_code_t
1119 generate_key (ECC_secret_key *sk, unsigned int nbits)
1120 {
1121   gpg_err_code_t err;
1122   elliptic_curve_t E;
1123   gcry_mpi_t d;
1124   point_t Q, G;
1125
1126   err = generate_curve (nbits, &E);
1127   if (err)
1128     return err;
1129
1130   d = mpi_snew (nbits);
1131   if (DBG_CIPHER)
1132     log_debug ("choosing a random x of size %u\n", nbits);
1133   d = gen_k (E.n_, 2);          /* generate_secret_prime(nbits); */
1134   G = point_copy (E.G);
1135
1136   /* Compute Q.  */
1137   point_init (&Q);
1138   escalar_mult (&Q, d, &E.G, &E);
1139
1140   /* Copy the stuff to the key structures. */
1141   sk->E.p_ = mpi_copy (E.p_);
1142   sk->E.a_ = mpi_copy (E.a_);
1143   sk->E.b_ = mpi_copy (E.b_);
1144   sk->E.G  = point_copy (E.G);
1145   sk->E.n_ = mpi_copy (E.n_);
1146   sk->Q    = point_copy (Q);
1147   sk->d    = mpi_copy (d);
1148
1149   /* Now we can test our keys (this should never fail!). */
1150   test_keys (sk, nbits - 64);
1151
1152   point_free (&Q);
1153   mpi_free (d);
1154   curve_free (&E);
1155
1156   return 0;
1157 }
1158
1159
1160 /****************
1161  * To verify correct skey it use a random information.
1162  * First, encrypt and decrypt this dummy value, 
1163  * test if the information is recuperated.
1164  * Second, test with the sign and verify functions.
1165  */
1166 static void
1167 test_keys (ECC_secret_key *sk, unsigned int nbits)
1168 {
1169   ECC_public_key pk;
1170   gcry_mpi_t test = mpi_new (nbits);
1171   point_t R_;
1172   gcry_mpi_t c = mpi_new (nbits);
1173   gcry_mpi_t out = mpi_new (nbits);
1174   gcry_mpi_t r = mpi_new (nbits);
1175   gcry_mpi_t s = mpi_new (nbits);
1176
1177   if (DBG_CIPHER)
1178     log_debug ("Testing key.\n");
1179
1180   point_init (&R_);
1181
1182   pk.E = curve_copy (sk->E);
1183   pk.Q = point_copy (sk->Q);
1184
1185   gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
1186
1187 #if 0  
1188   doEncrypt (test, &pk, &R_, c);
1189
1190   out = decrypt (out, sk, R_, c);
1191
1192   if (mpi_cmp (test, out))      /* test!=out */
1193     log_fatal ("ECELG operation: encrypt, decrypt failed\n");
1194   if (DBG_CIPHER)
1195     log_debug ("ECELG operation: encrypt, decrypt ok.\n");
1196 #endif
1197
1198   sign (test, sk, &r, &s);
1199
1200   if (!verify (test, &pk, r, s))
1201     {
1202       log_fatal ("ECDSA operation: sign, verify failed\n");
1203     }
1204
1205   if (DBG_CIPHER)
1206     log_debug ("ECDSA operation: sign, verify ok.\n");
1207
1208   point_free (&pk.Q);
1209   curve_free (&pk.E);
1210
1211   point_free (&R_);
1212   mpi_free (s);
1213   mpi_free (r);
1214   mpi_free (out);
1215   mpi_free (c);
1216   mpi_free (test);
1217 }
1218
1219 /****************
1220  * To check the validity of the value, recalculate the correspondence
1221  * between the public value and de secret one.
1222  */
1223 static int
1224 check_secret_key (ECC_secret_key * sk)
1225 {
1226   point_t Q;
1227   gcry_mpi_t y_2, y2 = mpi_alloc (0);
1228
1229   /* ?primarity test of 'p' */
1230   /*  (...) //!! */
1231   /* G in E(F_p) */
1232   y_2 = gen_y_2 (sk->E.G.x_, &sk->E);   /*  y^2=x^3+a*x+b */
1233   mpi_mulm (y2, sk->E.G.y_, sk->E.G.y_, sk->E.p_);      /*  y^2=y*y */
1234   if (mpi_cmp (y_2, y2))
1235     {
1236       if (DBG_CIPHER)
1237         log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
1238       return (1);
1239     }
1240   /* G != PaI */
1241   if (point_at_infinity (sk->E.G))
1242     {
1243       if (DBG_CIPHER)
1244         log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
1245       return (1);
1246     }
1247   /* ?primarity test of 'n' */
1248   /*  (...) //!! */
1249   /* ?(p-sqrt(p)) < n < (p+sqrt(p)) */
1250   /* ?n!=p */
1251   /* ?(n^k) mod p !=1 for k=1 to 31 (from GOST) or k=1 to 50 (from MIRACL) */
1252   /* Q=[n]G over E = PaI */
1253
1254   point_init (&Q);
1255   escalar_mult (&Q, sk->E.n_, &sk->E.G, &sk->E);
1256   if (!point_at_infinity (Q))
1257     {
1258       if (DBG_CIPHER)
1259         log_debug ("check_secret_key: E is not a curve of order n\n");
1260       point_free (&Q);
1261       return 1;
1262     }
1263   /* pubkey cannot be PaI */
1264   if (point_at_infinity (sk->Q))
1265     {
1266       if (DBG_CIPHER)
1267         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
1268       return (1);
1269     }
1270   /* pubkey = [d]G over E */
1271   escalar_mult (&Q, sk->d, &sk->E.G, &sk->E);
1272   if ((Q.x_ == sk->Q.x_) && (Q.y_ == sk->Q.y_) && (Q.z_ == sk->Q.z_))
1273     {
1274       if (DBG_CIPHER)
1275         log_debug
1276           ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
1277       return (1);
1278     }
1279   point_free (&Q);
1280   return 0;
1281 }
1282
1283
1284 #if 0
1285 /****************
1286  * Encrypt a number and obtain and struct (R,c)
1287  */
1288 static void
1289 doEncrypt (gcry_mpi_t input, ECC_public_key * pkey, point_t * R, gcry_mpi_t c)
1290 {
1291
1292   gcry_mpi_t k, p, x, y;
1293   point_t P, Q, G;
1294   elliptic_curve_t E;
1295
1296   k = mpi_alloc (0);
1297   p = mpi_copy (pkey->E.p_);
1298   x = mpi_alloc (0);
1299   y = mpi_alloc (0);
1300   Q = point_copy (pkey->Q);
1301   G = point_copy (pkey->E.G);
1302   E = curve_copy (pkey->E);
1303
1304   k = gen_k (p, 1);             /* 2nd parametre: how much security? */
1305   escalarMult (k, &Q, &P, &E);  /* P=[k]Q=[k]([d]G) */
1306   escalarMult (k, &G, R, &E);   /* R=[k]G */
1307   /* IFP weakness//mpi_mul(c,input,Q.x_);//c=input*Q_x */
1308   /* MMR Use affine conversion befor extract x-coordinate */
1309   if (point_affine (&P, x, y, &E))
1310     {                           /* Q cannot turn to affine coordinate */
1311       if (DBG_CIPHER)
1312         {
1313           log_debug ("Encrypting: Cannot turn to affine.\n");
1314         }
1315     }
1316   /* MMR According to the standard P1363 we can not use x-coordinate directly. */
1317   /*  It is necessary to add hash-operation later.  */
1318   /*  As the maximal length of a key for the symmetric cipher is 256 bit it is possible to take hash-function SHA256. */
1319   sha256_hashing (x, &x);
1320   aes256_encrypting (x, input, &c);
1321
1322   if (DBG_CIPHER)
1323     {
1324       log_debug ("doEncrypt: end.\n");
1325     }
1326 }
1327 #endif /*0*/
1328
1329 #if 0
1330 /****************
1331  * Undo the ciphertext
1332  */
1333 static gcry_mpi_t
1334 decrypt (gcry_mpi_t output, ECC_secret_key * skey, point_t R, gcry_mpi_t c)
1335 {
1336
1337   gcry_mpi_t p, inv, x, y;
1338   point_t P, Q;
1339   elliptic_curve_t E;
1340
1341   p = mpi_copy (skey->E.p_);
1342   inv = mpi_alloc (0);
1343   x = mpi_alloc (0);
1344   y = mpi_alloc (0);
1345   Q = point_copy (skey->Q);
1346   E = curve_copy (skey->E);
1347
1348   escalarMult (skey->d, &R, &P, &E);    /* P=[d]R */
1349   /* That is like: mpi_fdiv_q(output,c,Q.x_); */
1350   /* IFP weakness//mpi_invm(inv,Q.x_,p);//inv=Q{_x}^-1 (mod p) */
1351   /* IFP weakness//mpi_mulm(output,c,inv,p);//output=c*inv (mod p) */
1352   /* MMR Use affine conversion befor extract x-coordinate */
1353   if (point_affine (&P, x, y, &E))
1354     {                           /* Q cannot turn to affine coordinate */
1355       if (DBG_CIPHER)
1356         {
1357           log_debug ("Encrypting: Cannot turn to affine.\n");
1358         }
1359     }
1360   sha256_hashing (x, &x);
1361   aes256_decrypting (x, c, &output);
1362
1363   if (DBG_CIPHER)
1364     {
1365       log_debug ("decrypt: end.\n");
1366     }
1367   return (output);
1368 }
1369 #endif /*0*/
1370
1371 /****************
1372  * Return the signature struct (r,s) from the message hash.
1373  */
1374 static void
1375 sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t *r, gcry_mpi_t *s)
1376 {
1377   gcry_mpi_t k, i, dr, sum, k_1, x, y;
1378   point_t G, I;
1379   elliptic_curve_t E;
1380
1381   k = mpi_alloc (0);
1382   i = mpi_alloc (0);
1383   dr = mpi_alloc (0);
1384   sum = mpi_alloc (0);
1385   k_1 = mpi_alloc (0);
1386   x = mpi_alloc (0);
1387   y = mpi_alloc (0);
1388   G = point_copy (skey->E.G);
1389   E = curve_copy (skey->E);
1390   *r = mpi_alloc (0);
1391   *s = mpi_alloc (0);
1392
1393   point_init (&I);
1394
1395   while (!mpi_cmp_ui (*s, 0)) /* s == 0 */
1396     {                           
1397       while (!mpi_cmp_ui (*r, 0)) /* r == 0 */
1398         {                    
1399           k = gen_k (E.p_, 1);
1400           escalar_mult (&I, k, &G, &E); /* I = [k]G */
1401           if (point_affine (&I, x, y, &E))
1402             {
1403               if (DBG_CIPHER)
1404                 log_debug ("ecc sign: Cannot turn to affine. "
1405                            " Cannot complete sign.\n");
1406               /* FIXME: Shouldn't we return an error now? */
1407             }
1408           i = mpi_copy (x);       /* i = I_x     */
1409           mpi_mod (*r, i, E.n_);  /* r = i mod n */
1410           /* Fixme: release k, i and I? */
1411         }
1412       mpi_mulm (dr, skey->d, *r, E.n_); /* dr = d*r mod n */
1413       mpi_addm (sum, input, dr, E.n_);  /* sum = hash + (d*r) mod n */
1414       mpi_invm (k_1, k, E.n_);          /* k_1 = k^(-1) mod n */
1415       mpi_mulm (*s, k_1, sum, E.n_);    /* s = k^(-1)*(hash+(d*r)) mod n */
1416     }
1417   if (DBG_CIPHER)
1418     log_debug ("ess sign: end\n");
1419
1420   /* Fixme:  What about releasing G and E? */
1421   mpi_free (y);
1422   mpi_free (x);
1423   mpi_free (k_1);
1424   mpi_free (sum);
1425   mpi_free (dr);
1426   mpi_free (i);
1427   mpi_free (k);
1428 }
1429
1430 /****************
1431  * Check if the struct (r,s) is for the hash value that it have.
1432  * Returns: 0 = does not verify
1433  *          1 = verifies. 
1434  */
1435 static int
1436 verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
1437 {
1438   gcry_mpi_t r_, s_, h, h1, h2, i, x, y;
1439   point_t Q, Q1, Q2, G;
1440   elliptic_curve_t E;
1441
1442   /* Fixme: we need to release quite some values.  */
1443
1444   r_ = mpi_alloc (0);
1445   s_ = mpi_alloc (0);
1446   h = mpi_alloc (0);
1447   h1 = mpi_alloc (0);
1448   h2 = mpi_alloc (0);
1449   x = mpi_alloc (0);
1450   y = mpi_alloc (0);
1451   G = point_copy (pkey->E.G);
1452   E = curve_copy (pkey->E);
1453
1454   mpi_mod (r_, r, pkey->E.n_);  /* r = r mod E_n */
1455   mpi_mod (s_, s, pkey->E.n_);  /* s = s mod E_n */
1456
1457   /* Check that the input parameters are valid.  */
1458   if (mpi_cmp (r_, r) || mpi_cmp (s_, s)) /* r_ != r || s_ != s */
1459     {                           
1460       if (DBG_CIPHER)
1461         log_debug ("ecc verification: No valid values.\n");
1462       return 0;
1463     }
1464
1465   point_init (&Q);
1466   point_init (&Q1);
1467   point_init (&Q2);
1468
1469   mpi_invm (h, s, E.n_);                /* h  = s^(-1) (mod n) */
1470   mpi_mulm (h1, input, h, E.n_);        /* h1 = hash * s^(-1) (mod n) */
1471   escalar_mult (&Q1, h1, &G, &E);       /* Q1 = [ hash * s^(-1) ]G  */
1472   mpi_mulm (h2, r, h, E.n_);            /* h2 = r * s^(-1) (mod n) */
1473   escalar_mult (&Q2, h2, &pkey->Q, &E); /* Q2 = [ r * s^(-1) ]Q */
1474   sum_points (&Q, &Q1, &Q2, &E);/* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
1475
1476   if (point_at_infinity (Q))
1477     {
1478       if (DBG_CIPHER)
1479           log_debug ("ecc verification: Rejected.\n");
1480       return 0; /* Rejected.  */
1481     }
1482   if (point_affine (&Q, x, y, &E))
1483     {                   
1484       if (DBG_CIPHER)
1485         log_debug ("ecc verification: Cannot turn to affine. Rejected.\n");
1486       return 0; /* Rejected.  */
1487     }
1488
1489   i = mpi_copy (x);             /* Give the x_coordinate */
1490   mpi_mod (i, i, E.n_);         /* i = i mod E_n */
1491
1492   if (!mpi_cmp (i, r))  /* i==r => Return 0 (distance between them). */
1493     {                           
1494       if (DBG_CIPHER)
1495         log_debug ("ecc verification: Accepted.\n");
1496       return 1; /* Accepted.  */
1497     }
1498   if (DBG_CIPHER)
1499     log_debug ("ecc verification: Not verified.\n");
1500
1501   /* Fixme: release Q, Q1 and Q2.  */
1502
1503   return 0;
1504 }
1505
1506
1507 /****************
1508  * Generate a random point over an Elliptic curve is the first step to
1509  * find a random cyclic subgroup generator.
1510  *
1511  *        !! At this moment it isn't used !!  //!!
1512  */
1513 #if 0
1514 static point_t
1515 gen_point (gcry_mpi_t prime, elliptic_curve_t base)
1516 {
1517
1518   unsigned int i = 0;
1519   gcry_mpi_t x, y_2, y;
1520   gcry_mpi_t one, one_neg, bit;
1521   point_t P;
1522
1523   x = mpi_alloc (mpi_get_nlimbs (base.p_));
1524   y_2 = mpi_alloc (mpi_get_nlimbs (base.p_));
1525   y = mpi_alloc (mpi_get_nlimbs (base.p_));
1526   one = mpi_alloc_set_ui (1);
1527   one_neg = mpi_alloc (mpi_get_nlimbs (one));
1528   mpi_invm (one_neg, one, base.p_);
1529
1530   if (DBG_CIPHER)
1531     log_debug ("Generating a normal point.\n");
1532   do
1533     {
1534       x = gen_k (base.p_, 1);   /* generate_public_prime(mpi_get_nlimbs(base.n_)*BITS_PER_MPI_LIMB); */
1535       do
1536         {
1537           y_2 = gen_y_2 (x, &base);     /* x^3+ax+b (mod p) */
1538           mpi_add_ui (x, x, 1);
1539           i++;
1540         }
1541       while (!mpi_cmp_ui (y_2, 0) && i < 0xf);  /* Try to find a valid value until 16 iterations. */
1542       i = 0;
1543       y = existSquareRoot (y_2, base.p_);
1544     }
1545   while (!mpi_cmp_ui (y, 0));   /* Repeat until a valid coordinate is found. */
1546   bit = gen_bit ();             /* generate one bit */
1547   if (mpi_cmp_ui (bit, 1))
1548     {                           /* choose the y coordinate */
1549       mpi_invm (y, y, base.p_); /* mpi_powm(y, y, one_neg,base.p_); */
1550     }
1551   if (DBG_CIPHER)
1552     log_debug ("Normal point generated.\n");
1553
1554   P.x_ = mpi_copy (x);
1555   P.y_ = mpi_copy (y);
1556   P.z_ = mpi_copy (one);
1557
1558   mpi_free (bit);
1559   mpi_free (one_neg);
1560   mpi_free (one);
1561   mpi_free (y);
1562   mpi_free (y_2);
1563   mpi_free (x);
1564
1565   return (P);
1566 }
1567 #endif /*0*/
1568
1569 /****************
1570  * Boolean generator to choose between to coordinates.
1571  */
1572 #if 0
1573 static gcry_mpi_t
1574 gen_bit ()
1575 {
1576   gcry_mpi_t aux = mpi_alloc_set_ui (0);
1577
1578   /* FIXME: This is highly ineffective but the whole function is used
1579      only at one place. */
1580
1581   /* Get one random bit, with less security level, and translate it to
1582      an MPI. */
1583   mpi_set_buffer (aux, get_random_bits (1, 0, 1), 1, 0);        /* gen_k(...) */
1584
1585   return aux;                   /* b; */
1586 }
1587 #endif /*0*/
1588
1589
1590 \f
1591 #if 0
1592 /* Function to solve an IFP ECElGamal weakness: */
1593 /*  sha256_hashing() */
1594 /*  aes256_encrypting() */
1595 /*  aes356_decrypting() */
1596
1597 /****************
1598  * Compute 256 bit hash value from input MPI.
1599  * Use SHA256 Algorithm.
1600  */
1601 static void
1602 sha256_hashing (gcry_mpi_t input, gcry_mpi_t * output)
1603 {                               /*   */
1604
1605   int sign;
1606   byte *hash_inp_buf;
1607   byte hash_out_buf[32];
1608   MD_HANDLE hash = md_open (8, 1);      /* algo SHA256 in secure mode */
1609
1610   unsigned int nbytes;
1611
1612   hash_inp_buf = mpi_get_secure_buffer (input, &nbytes, &sign); /* convert gcry_mpi_t input to string */
1613
1614   md_write (hash, hash_inp_buf, nbytes);        /* hashing input string */
1615   wipememory (hash_inp_buf, sizeof hash_inp_buf);       /*  burn temp value  */
1616   xfree (hash_inp_buf);
1617
1618   md_digest (hash, 8, hash_out_buf, 32);
1619   mpi_set_buffer (*output, hash_out_buf, 32, 0);        /*  convert 256 bit digest to MPI */
1620
1621   wipememory (hash_out_buf, sizeof hash_out_buf);       /*  burn temp value  */
1622   md_close (hash);              /*  destroy and free hash state. */
1623
1624 }
1625
1626 /****************
1627  * Encrypt input MPI.
1628  * Use AES256 algorithm.
1629  */
1630
1631 static void
1632 aes256_encrypting (gcry_mpi_t key, gcry_mpi_t input, gcry_mpi_t * output)
1633 {                               /*   */
1634
1635   int sign;
1636   byte *key_buf;
1637   byte *cipher_buf;
1638
1639   unsigned int keylength;
1640   unsigned int nbytes;
1641
1642
1643   CIPHER_HANDLE cipher = cipher_open (9, CIPHER_MODE_CFB, 1);   /* algo AES256 CFB mode in secure memory */
1644   cipher_setiv (cipher, NULL, 0);       /*  Zero IV */
1645
1646   key_buf = mpi_get_secure_buffer (key, &keylength, &sign);     /* convert MPI key to string */
1647   cipher_setkey (cipher, key_buf, keylength);
1648   wipememory (key_buf, sizeof key_buf); /*  burn temp value  */
1649   xfree (key_buf);
1650
1651   cipher_buf = mpi_get_secure_buffer (input, &nbytes, &sign);   /* convert MPI input to string */
1652
1653   cipher_encrypt (cipher, cipher_buf + 1, cipher_buf + 1, nbytes - 1);  /*  */
1654   cipher_close (cipher);        /*  destroy and free cipher state. */
1655
1656   mpi_set_buffer (*output, cipher_buf, nbytes, 0);      /*  convert encrypted string to MPI */
1657   wipememory (cipher_buf, sizeof cipher_buf);   /*  burn temp value  */
1658   xfree (cipher_buf);
1659 }
1660
1661 /****************
1662  * Decrypt input MPI.
1663  * Use AES256 algorithm.
1664  */
1665
1666 static void
1667 aes256_decrypting (gcry_mpi_t key, gcry_mpi_t input, gcry_mpi_t * output)
1668 {                               /*   */
1669
1670   int sign;
1671   byte *key_buf;
1672   byte *cipher_buf;
1673
1674   unsigned int keylength;
1675   unsigned int nbytes;
1676
1677
1678   CIPHER_HANDLE cipher = cipher_open (9, CIPHER_MODE_CFB, 1);   /* algo AES256 CFB mode in secure memory */
1679   cipher_setiv (cipher, NULL, 0);       /*  Zero IV */
1680
1681   key_buf = mpi_get_secure_buffer (key, &keylength, &sign);     /* convert MPI input to string */
1682   cipher_setkey (cipher, key_buf, keylength);
1683   wipememory (key_buf, sizeof key_buf); /*  burn temp value  */
1684   xfree (key_buf);
1685
1686   cipher_buf = mpi_get_secure_buffer (input, &nbytes, &sign);   /* convert MPI input to string; */
1687
1688   cipher_decrypt (cipher, cipher_buf + 1, cipher_buf + 1, nbytes - 1);  /*  */
1689   cipher_close (cipher);        /*  destroy and free cipher state. */
1690
1691   mpi_set_buffer (*output, cipher_buf, nbytes, 0);      /*  convert encrypted string to MPI */
1692   wipememory (cipher_buf, sizeof cipher_buf);   /*  burn temp value  */
1693   xfree (cipher_buf);
1694 }
1695
1696 /* End of IFP ECElGamal weakness functions. */
1697 #endif /*0*/
1698
1699 /*********************************************
1700  **************  interface  ******************
1701  *********************************************/
1702
1703 static gcry_err_code_t
1704 ecc_generate (int algo, unsigned int nbits, unsigned long dummy,
1705               gcry_mpi_t *skey, gcry_mpi_t **retfactors)
1706 {
1707   gpg_err_code_t err;
1708   ECC_secret_key sk;
1709
1710   (void)algo;
1711
1712   /* Make an empty list of factors.  */
1713   *retfactors = gcry_calloc ( 1, sizeof **retfactors );
1714   if (!*retfactors)
1715     return gpg_err_code_from_syserror ();
1716
1717   err = generate_key (&sk, nbits);
1718   if (err)
1719     {
1720       gcry_free (*retfactors);
1721       *retfactors = NULL;
1722       return err;
1723     }
1724
1725   skey[0] = sk.E.p_;
1726   skey[1] = sk.E.a_;
1727   skey[2] = sk.E.b_;
1728   skey[3] = sk.E.G.x_;
1729   skey[4] = sk.E.G.y_;
1730   skey[5] = sk.E.G.z_;
1731   skey[6] = sk.E.n_;
1732   skey[7] = sk.Q.x_;
1733   skey[8] = sk.Q.y_;
1734   skey[9] = sk.Q.z_;
1735   skey[10] = sk.d;
1736
1737   if (DBG_CIPHER)
1738     {
1739       progress ('\n');
1740
1741       log_mpidump ("[ecc]  p= ", skey[0]);
1742       log_mpidump ("[ecc]  a= ", skey[1]);
1743       log_mpidump ("[ecc]  b= ", skey[2]);
1744       log_mpidump ("[ecc]  Gx= ", skey[3]);
1745       log_mpidump ("[ecc]  Gy= ", skey[4]);
1746       log_mpidump ("[ecc]  Gz= ", skey[5]);
1747       log_mpidump ("[ecc]  n= ", skey[6]);
1748       log_mpidump ("[ecc]  Qx= ", skey[7]);
1749       log_mpidump ("[ecc]  Qy= ", skey[8]);
1750       log_mpidump ("[ecc]  Qz= ", skey[9]);
1751       log_mpidump ("[ecc]  d= ", skey[10]);
1752     }
1753
1754   if (DBG_CIPHER)
1755     {
1756       log_debug ("ECC key Generated.\n");
1757     }
1758   return 0;
1759 }
1760
1761
1762 static gcry_err_code_t
1763 ecc_check_secret_key (int algo, gcry_mpi_t *skey)
1764 {
1765   ECC_secret_key sk;
1766
1767   (void)algo;
1768
1769   if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
1770       || !skey[6] || !skey[7] || !skey[8] || !skey[9] || !skey[10])
1771     return GPG_ERR_BAD_MPI;
1772
1773   if (DBG_CIPHER)
1774     {
1775       log_debug ("ECC check secret key.\n");
1776     }
1777   sk.E.p_ = skey[0];
1778   sk.E.a_ = skey[1];
1779   sk.E.b_ = skey[2];
1780   sk.E.G.x_ = skey[3];
1781   sk.E.G.y_ = skey[4];
1782   sk.E.G.z_ = skey[5];
1783   sk.E.n_ = skey[6];
1784   sk.Q.x_ = skey[7];
1785   sk.Q.y_ = skey[8];
1786   sk.Q.z_ = skey[9];
1787   sk.d = skey[10];
1788
1789   if (check_secret_key (&sk))
1790     {
1791       if (DBG_CIPHER)
1792         log_debug ("Bad check: Bad secret key.\n");
1793       return GPG_ERR_BAD_SECKEY;
1794     }
1795   return 0;
1796 }
1797
1798
1799 #if 0
1800 static int
1801 ecc_encrypt_FIXME (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey)
1802 {
1803   ECC_public_key pk;
1804   point R;
1805
1806   if (algo != PUBKEY_ALGO_ECC && algo != PUBKEY_ALGO_ECC_E)
1807     return G10ERR_PUBKEY_ALGO;
1808   if (!data || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4]
1809       || !pkey[5] || !pkey[6] || !pkey[7] || !pkey[8] || !pkey[9])
1810     return G10ERR_BAD_MPI;
1811
1812   if (DBG_CIPHER)
1813     {
1814       log_debug ("ECC encrypt.\n");
1815     }
1816   pk.E.p_ = pkey[0];
1817   pk.E.a_ = pkey[1];
1818   pk.E.b_ = pkey[2];
1819   pk.E.G.x_ = pkey[3];
1820   pk.E.G.y_ = pkey[4];
1821   pk.E.G.z_ = pkey[5];
1822   pk.E.n_ = pkey[6];
1823   pk.Q.x_ = pkey[7];
1824   pk.Q.y_ = pkey[8];
1825   pk.Q.z_ = pkey[9];
1826
1827   R.x_ = resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.Q.x_));
1828   R.y_ = resarr[1] = mpi_alloc (mpi_get_nlimbs (pk.Q.y_));
1829   R.z_ = resarr[2] = mpi_alloc (mpi_get_nlimbs (pk.Q.z_));
1830   resarr[3] = mpi_alloc (mpi_get_nlimbs (pk.E.p_));
1831
1832   doEncrypt (data, &pk, &R, resarr[3]);
1833
1834   resarr[0] = mpi_copy (R.x_);
1835   resarr[1] = mpi_copy (R.y_);
1836   resarr[2] = mpi_copy (R.z_);
1837   return 0;
1838 }
1839
1840 int
1841 ecc_decrypt_FIXME (int algo, gcry_mpi_t * result, gcry_mpi_t * data, gcry_mpi_t * skey)
1842 {
1843   ECC_secret_key sk;
1844   point R;
1845
1846   if (algo != PUBKEY_ALGO_ECC && algo != PUBKEY_ALGO_ECC_E)
1847     return G10ERR_PUBKEY_ALGO;
1848   if (!data[0] || !data[1] || !data[2] || !data[3] || !skey[0] || !skey[1]
1849       || !skey[2] || !skey[3] || !skey[4] || !skey[5] || !skey[6] || !skey[7]
1850       || !skey[8] || !skey[9] || !skey[10])
1851     return G10ERR_BAD_MPI;
1852
1853   if (DBG_CIPHER)
1854     {
1855       log_debug ("ECC decrypt.\n");
1856     }
1857   R.x_ = data[0];
1858   R.y_ = data[1];
1859   R.z_ = data[2];
1860   sk.E.p_ = skey[0];
1861   sk.E.a_ = skey[1];
1862   sk.E.b_ = skey[2];
1863   sk.E.G.x_ = skey[3];
1864   sk.E.G.y_ = skey[4];
1865   sk.E.G.z_ = skey[5];
1866   sk.E.n_ = skey[6];
1867   sk.Q.x_ = skey[7];
1868   sk.Q.y_ = skey[8];
1869   sk.Q.z_ = skey[9];
1870   sk.d = skey[10];
1871
1872   *result = mpi_alloc_secure (mpi_get_nlimbs (sk.E.p_));
1873   *result = decrypt (*result, &sk, R, data[3]);
1874   return 0;
1875 }
1876 #endif /*0*/
1877
1878 static gcry_err_code_t
1879 ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
1880 {
1881   ECC_secret_key sk;
1882
1883   (void)algo;
1884
1885   if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1886       || !skey[5] || !skey[6] || !skey[7] || !skey[8] || !skey[9]
1887       || !skey[10])
1888     return GPG_ERR_BAD_MPI;
1889
1890   sk.E.p_ = skey[0];
1891   sk.E.a_ = skey[1];
1892   sk.E.b_ = skey[2];
1893   sk.E.G.x_ = skey[3];
1894   sk.E.G.y_ = skey[4];
1895   sk.E.G.z_ = skey[5];
1896   sk.E.n_ = skey[6];
1897   sk.Q.x_ = skey[7];
1898   sk.Q.y_ = skey[8];
1899   sk.Q.z_ = skey[9];
1900   sk.d = skey[10];
1901
1902   resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.E.p_));
1903   resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.E.p_));
1904   sign (data, &sk, &resarr[0], &resarr[1]);
1905   return 0;
1906 }
1907
1908 static gcry_err_code_t
1909 ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
1910             int (*cmp)(void *, gcry_mpi_t), void *opaquev)
1911 {
1912   ECC_public_key pk;
1913
1914   (void)algo;
1915
1916   if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2]
1917       || !pkey[3] || !pkey[4] || !pkey[5] || !pkey[6] || !pkey[7] || !pkey[8]
1918       || !pkey[9])
1919     return GPG_ERR_BAD_MPI;
1920
1921   if (DBG_CIPHER)
1922     {
1923       log_debug ("ECC verify.\n");
1924     }
1925   pk.E.p_ = pkey[0];
1926   pk.E.a_ = pkey[1];
1927   pk.E.b_ = pkey[2];
1928   pk.E.G.x_ = pkey[3];
1929   pk.E.G.y_ = pkey[4];
1930   pk.E.G.z_ = pkey[5];
1931   pk.E.n_ = pkey[6];
1932   pk.Q.x_ = pkey[7];
1933   pk.Q.y_ = pkey[8];
1934   pk.Q.z_ = pkey[9];
1935
1936   if (!verify (hash, &pk, data[0], data[1]))
1937     return GPG_ERR_BAD_SIGNATURE;
1938   return 0;
1939 }
1940
1941
1942
1943 static unsigned int
1944 ecc_get_nbits (int algo, gcry_mpi_t *pkey)
1945 {
1946   (void)algo;
1947
1948   if (DBG_CIPHER)
1949     {
1950       log_debug ("ECC get nbits.\n");
1951     }
1952
1953   if (DBG_CIPHER)
1954     {
1955       progress ('\n');
1956
1957       log_mpidump ("[ecc]  p= ", pkey[0]);
1958       log_mpidump ("[ecc]  a= ", pkey[1]);
1959       log_mpidump ("[ecc]  b= ", pkey[2]);
1960       log_mpidump ("[ecc]  Gx= ", pkey[3]);
1961       log_mpidump ("[ecc]  Gy= ", pkey[4]);
1962       log_mpidump ("[ecc]  Gz= ", pkey[5]);
1963       log_mpidump ("[ecc]  n= ", pkey[6]);
1964       log_mpidump ("[ecc]  Qx= ", pkey[7]);
1965       log_mpidump ("[ecc]  Qy= ", pkey[8]);
1966       log_mpidump ("[ecc]  Qz= ", pkey[9]);
1967     }
1968
1969   return mpi_get_nbits (pkey[0]);
1970 }
1971
1972
1973 static const char *ecdsa_names[] =
1974   {
1975     "ecdsa",
1976     NULL,
1977   };
1978
1979 gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
1980   {
1981     "ECDSA", ecdsa_names, 
1982     "pabxyznXYZ", "pabxyznXYZd", "", "rs", "pabxyznXYZ",
1983     GCRY_PK_USAGE_SIGN,
1984     ecc_generate,
1985     ecc_check_secret_key,
1986     NULL,
1987     NULL,
1988     ecc_sign,
1989     ecc_verify,
1990     ecc_get_nbits
1991   };
1992
1993
1994