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