chiark / gitweb /
476d898969d5459ba3a010e2196da7afc52dcb27
[catacomb] / ec.h
1 /* -*-c-*-
2  *
3  * $Id: ec.h,v 1.4.4.2 2004/03/20 00:13:31 mdw Exp $
4  *
5  * Elliptic curve definitions
6  *
7  * (c) 2001 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  * 
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  * 
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Revision history --------------------------------------------------* 
31  *
32  * $Log: ec.h,v $
33  * Revision 1.4.4.2  2004/03/20 00:13:31  mdw
34  * Projective coordinates for prime curves
35  *
36  * Revision 1.4.4.1  2003/06/10 13:43:53  mdw
37  * Simple (non-projective) curves over prime fields now seem to work.
38  *
39  * Revision 1.4  2003/05/15 23:25:59  mdw
40  * Make elliptic curve stuff build.
41  *
42  * Revision 1.3  2002/01/13 13:48:44  mdw
43  * Further progress.
44  *
45  * Revision 1.2  2001/05/07 17:29:44  mdw
46  * Treat projective coordinates as an internal representation.  Various
47  * minor interface changes.
48  *
49  * Revision 1.1  2001/04/29 18:12:33  mdw
50  * Prototype version.
51  *
52  */
53
54 #ifndef CATACOMB_EC_H
55 #define CATACOMB_EC_H
56
57 #ifdef __cplusplus
58   extern "C" {
59 #endif
60
61 /*----- Header files ------------------------------------------------------*/
62
63 #include "field.h"
64 #include "mp.h"
65
66 /*----- Data structures ---------------------------------------------------*/
67
68 /* --- An elliptic curve representation --- */
69
70 typedef struct ec_curve {
71   const struct ec_ops *ops;             /* Curve operations */
72   field *f;                             /* Underlying field structure */
73 } ec_curve;
74
75 /* --- An elliptic curve point --- */
76
77 typedef struct ec {
78   mp *x, *y;                            /* Point coordinates */
79   mp *z;                                /* Common denominator (or null) */
80 } ec;
81
82 /* --- A factor for simultaneous multiplication --- */
83
84 typedef struct ec_mulfactor {
85   ec base;                              /* The point */
86   mp *exp;                              /* The exponent */
87 } ec_mulfactor;
88
89 /* --- Elliptic curve operations --- *
90  *
91  * All operations (apart from @destroy@ and @in@) are guaranteed to be
92  * performed on internal representations of points.  Moreover, the second
93  * argument to @add@ and @mul@ is guaranteed to be the output of @in@ or
94  * @fix@.
95  */
96
97 typedef struct ec_ops {
98   void (*destroy)(ec_curve */*c*/);
99   ec *(*in)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
100   ec *(*out)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
101   ec *(*fix)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
102   ec *(*find)(ec_curve */*c*/, ec */*d*/, mp */*x*/);
103   ec *(*neg)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
104   ec *(*add)(ec_curve */*c*/, ec */*d*/, const ec */*p*/, const ec */*q*/);
105   ec *(*sub)(ec_curve */*c*/, ec */*d*/, const ec */*p*/, const ec */*q*/);
106   ec *(*dbl)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
107   int (*check)(ec_curve */*c*/, const ec */*p*/);
108 } ec_ops;
109
110 #define EC_IN(c, d, p)          (c)->ops->in((c), (d), (p))
111 #define EC_OUT(c, d, p)         (c)->ops->out((c), (d), (p))
112 #define EC_FIX(c, d, p)         (c)->ops->fix((c), (d), (p))
113
114 #define EC_FIND(c, d, x)        (c)->ops->find((c), (d), (x))
115 #define EC_NEG(c, d, x)         (c)->ops->neg((c), (d), (x))
116 #define EC_ADD(c, d, p, q)      (c)->ops->add((c), (d), (p), (q))
117 #define EC_SUB(c, d, p, q)      (c)->ops->sub((c), (d), (p), (q))
118 #define EC_DBL(c, d, p)         (c)->ops->dbl((c), (d), (p))
119 #define EC_CHECK(c, p)          (c)->ops->check((c), (p))
120
121 /*----- Simple memory management things -----------------------------------*/
122
123 /* --- @ec_create@ --- *
124  *
125  * Arguments:   @ec *p@ = pointer to an elliptic-curve point
126  *
127  * Returns:     The argument @p@.
128  *
129  * Use:         Initializes a new point.  The initial value is the additive
130  *              identity (which is universal for all curves).
131  */
132
133 #define EC_INIT { MP_NEW, MP_NEW, MP_NEW }
134
135 #define EC_CREATE(p) do {                                               \
136   ec *_p = (p);                                                         \
137   _p->x = _p->y = _p->z = MP_NEW;                                       \
138 } while (0)
139
140 extern ec *ec_create(ec */*p*/);
141
142 /* --- @ec_destroy@ --- *
143  *
144  * Arguments:   @ec *p@ = pointer to an elliptic-curve point
145  *
146  * Returns:     ---
147  *
148  * Use:         Destroys a point, making it invalid.
149  */
150
151 #define EC_DESTROY(p) do {                                              \
152   ec *_p = (p);                                                         \
153   if (!EC_ATINF(_p)) {                                                  \
154     MP_DROP(_p->x);                                                     \
155     MP_DROP(_p->y);                                                     \
156     if (_p->z) MP_DROP(_p->z);                                          \
157   }                                                                     \
158 } while (0)
159
160 extern void ec_destroy(ec */*p*/);
161
162 /* --- @ec_atinf@ --- *
163  *
164  * Arguments:   @const ec *p@ = pointer to a point
165  *
166  * Returns:     Nonzero if %$p = O$% is the point at infinity, zero
167  *              otherwise.
168  */
169
170 #define EC_ATINF(p) ((p)->x == MP_NEW || (p)->x == MP_NEWSEC)
171
172 extern int ec_atinf(const ec */*p*/);
173
174 /* --- @ec_setinf@ --- *
175  *
176  * Arguments:   @ec *p@ = pointer to a point
177  *
178  * Returns:     The argument @p@.
179  *
180  * Use:         Sets the given point to be the point %$O$% at infinity.
181  */
182
183 #define EC_SETINF(p) do {                                               \
184   ec *_p = (p);                                                         \
185   if (!EC_ATINF(_p)) {                                                  \
186     MP_DROP(_p->x);                                                     \
187     MP_DROP(_p->y);                                                     \
188     if (_p->z) MP_DROP(_p->z);                                          \
189     _p->x = _p->y = _p->z = MP_NEW;                                     \
190     _p->y = MP_NEW;                                                     \
191     _p->z = MP_NEW;                                                     \
192   }                                                                     \
193 } while (0)
194
195 extern ec *ec_setinf(ec */*p*/);
196
197 /* --- @ec_copy@ --- *
198  *
199  * Arguments:   @ec *d@ = pointer to destination point
200  *              @const ec *p@ = pointer to source point
201  *
202  * Returns:     The destination @d@.
203  *
204  * Use:         Creates a copy of an elliptic curve point.
205  */
206
207 #define EC_COPY(d, p) do {                                              \
208   ec *_d = (d);                                                         \
209   const ec *_p = (p);                                                   \
210   if (d != p) {                                                         \
211     EC_DESTROY(d);                                                      \
212     if (EC_ATINF(p))                                                    \
213       _d->x = _d->y = _d->z = MP_NEW;                                   \
214     else {                                                              \
215       _d->x = MP_COPY(_p->x);                                           \
216       _d->y = MP_COPY(_p->y);                                           \
217       _d->z = _p->z ? MP_COPY(_p->z) : MP_NEW;                          \
218     }                                                                   \
219   }                                                                     \
220 } while (0)
221
222 extern ec *ec_copy(ec */*d*/, const ec */*p*/);
223
224 /*----- Interesting arithmetic --------------------------------------------*/
225
226 /* --- @ec_find@ --- *
227  *
228  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
229  *              @ec *d@ = pointer to the destination point
230  *              @mp *x@ = a possible x-coordinate
231  *
232  * Returns:     The destination if OK, or null if no point was found.
233  *
234  * Use:         Finds a point on an elliptic curve with a given
235  *              x-coordinate.  If there is no point with the given
236  *              %$x$%-coordinate, a null pointer is returned and the
237  *              destination is left invalid.
238  */
239
240 extern ec *ec_find(ec_curve */*c*/, ec */*d*/, mp */*x*/);
241
242 /* --- @ec_neg@ --- *
243  *
244  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
245  *              @ec *d@ = pointer to the destination point
246  *              @const ec *p@ = pointer to the operand point
247  *
248  * Returns:     The destination point.
249  *
250  * Use:         Computes the negation of the given point.
251  */
252
253 extern ec *ec_neg(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
254
255 /* --- @ec_add@ --- *
256  *
257  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
258  *              @ec *d@ = pointer to the destination point
259  *              @const ec *p, *q@ = pointers to the operand points
260  *
261  * Returns:     The destination @d@.
262  *
263  * Use:         Adds two points on an elliptic curve.
264  */
265
266 extern ec *ec_add(ec_curve */*c*/, ec */*d*/,
267                   const ec */*p*/, const ec */*q*/);
268
269 /* --- @ec_sub@ --- *
270  *
271  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
272  *              @ec *d@ = pointer to the destination point
273  *              @const ec *p, *q@ = pointers to the operand points
274  *
275  * Returns:     The destination @d@.
276  *
277  * Use:         Subtracts one point from another on an elliptic curve.
278  */
279
280 extern ec *ec_sub(ec_curve */*c*/, ec */*d*/,
281                   const ec */*p*/, const ec */*q*/);
282
283 /* --- @ec_dbl@ --- *
284  *
285  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
286  *              @ec *d@ = pointer to the destination point
287  *              @const ec *p@ = pointer to the operand point
288  *
289  * Returns:     The destination @d@.
290  *
291  * Use:         Doubles a point on an elliptic curve.
292  */
293
294 extern ec *ec_dbl(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
295
296 /* --- @ec_check@ --- *
297  *
298  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
299  *              @const ec *p@ = pointer to the point
300  *
301  * Returns:     Zero if OK, nonzero if this is an invalid point.
302  *
303  * Use:         Checks that a point is actually on an elliptic curve.
304  */
305
306 extern int ec_check(ec_curve */*c*/, const ec */*p*/);
307
308 /* --- @ec_mul@, @ec_imul@ --- *
309  *
310  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
311  *              @ec *d@ = pointer to the destination point
312  *              @const ec *p@ = pointer to the generator point
313  *              @mp *n@ = integer multiplier
314  *
315  * Returns:     The destination @d@.
316  *
317  * Use:         Multiplies a point by a scalar, returning %$n p$%.  The
318  *              @imul@ variant uses internal representations for argument
319  *              and result.
320  */
321
322 extern ec *ec_mul(ec_curve */*c*/, ec */*d*/, const ec */*p*/, mp */*n*/);
323 extern ec *ec_imul(ec_curve */*c*/, ec */*d*/, const ec */*p*/, mp */*n*/);
324
325 /* --- @ec_mmul@, @ec_immul@ --- *
326  *
327  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
328  *              @ec *d@ = pointer to the destination point
329  *              @const ec_mulfactor *f@ = pointer to vector of factors
330  *              @size_t n@ = number of factors
331  *
332  * Returns:     The destination @d@.
333  *
334  * Use:         Does simultaneous point multiplication.  The @immul@ variant
335  *              uses internal representations for arguments and result.
336  */
337
338 extern ec *ec_mmul(ec_curve */*c*/, ec */*d*/,
339                    const ec_mulfactor */*f*/, size_t /*n*/);
340 extern ec *ec_immul(ec_curve */*c*/, ec */*d*/,
341                     const ec_mulfactor */*f*/, size_t /*n*/);
342
343 /*----- Standard curve operations -----------------------------------------*/
344
345 /* --- @ec_idin@, @ec_idout@, @ec_idfix@ --- *
346  *
347  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
348  *              @ec *d@ = pointer to the destination
349  *              @const ec *p@ = pointer to a source point
350  *
351  * Returns:     The destination @d@.
352  *
353  * Use:         An identity operation if your curve has no internal
354  *              representation.  (The field internal representation is still
355  *              used.)
356  */
357
358 extern ec *ec_idin(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
359 extern ec *ec_idout(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
360 extern ec *ec_idfix(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
361
362 /* --- @ec_projin@, @ec_projout@, @ec_projfix@ --- *
363  *
364  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
365  *              @ec *d@ = pointer to the destination
366  *              @const ec *p@ = pointer to a source point
367  *
368  * Returns:     The destination @d@.
369  *
370  * Use:         Conversion functions if your curve operations use a
371  *              projective representation.
372  */
373
374 extern ec *ec_projin(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
375 extern ec *ec_projout(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
376 extern ec *ec_projfix(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
377
378 /* --- @ec_stdsub@ --- *
379  *
380  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
381  *              @ec *d@ = pointer to the destination
382  *              @const ec *p, *q@ = the operand points
383  *
384  * Returns:     The destination @d@.
385  *
386  * Use:         Standard point subtraction operation, in terms of negation
387  *              and addition.  This isn't as efficient as a ready-made
388  *              subtraction operator.
389  */
390
391 extern ec *ec_stdsub(ec_curve */*c*/, ec */*d*/,
392                      const ec */*p*/, const ec */*q*/);
393
394 /*----- Creating curves ---------------------------------------------------*/
395
396 /* --- @ec_destroycurve@ --- *
397  *
398  * Arguments:   @ec_curve *c@ = pointer to an ellptic curve
399  *
400  * Returns:     ---
401  *
402  * Use:         Destroys a description of an elliptic curve.
403  */
404
405 extern void ec_destroycurve(ec_curve */*c*/);
406
407 /* --- @ec_prime@, @ec_primeproj@ --- *
408  *
409  * Arguments:   @field *f@ = the underlying field for this elliptic curve
410  *              @mp *a, *b@ = the coefficients for this curve
411  *
412  * Returns:     A pointer to the curve.
413  *
414  * Use:         Creates a curve structure for an elliptic curve defined over
415  *              a prime field.  The @primeproj@ variant uses projective
416  *              coordinates, which can be a win.
417  */
418
419 extern ec_curve *ec_prime(field */*f*/, mp */*a*/, mp */*b*/);
420 extern ec_curve *ec_primeproj(field */*f*/, mp */*a*/, mp */*b*/);
421
422 /* --- @ec_bin@ --- *
423  *
424  * Arguments:   @field *f@ = the underlying field for this elliptic curve
425  *              @mp *a, *b@ = the coefficients for this curve
426  *
427  * Returns:     A pointer to the curve.
428  *
429  * Use:         Creates a curve structure for a non-supersingular elliptic
430  *              curve defined over a binary field.
431  */
432
433 extern ec_curve *ec_bin(field */*f*/, mp */*a*/, mp */*b*/);
434
435 /*----- That's all, folks -------------------------------------------------*/
436
437 #ifdef __cplusplus
438   }
439 #endif
440
441 #endif