Expunge revision histories in files.
[u/mdw/catacomb] / ec.h
1 /* -*-c-*-
2 *
3 * $Id: ec.h,v 1.11 2004/04/08 01:36:15 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 #ifndef CATACOMB_EC_H
31 #define CATACOMB_EC_H
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 /*----- Header files ------------------------------------------------------*/
38
39 #ifndef CATACOMB_FIELD_H
40 # include "field.h"
41 #endif
42
43 #ifndef CATACOMB_MP_H
44 # include "mp.h"
45 #endif
46
47 #ifndef CATACOMB_QDPARSE_H
48 # include "qdparse.h"
49 #endif
50
51 /*----- Data structures ---------------------------------------------------*/
52
53 /* --- An elliptic curve representation --- */
54
55 typedef struct ec_curve {
56 const struct ec_ops *ops; /* Curve operations */
57 field *f; /* Underlying field structure */
58 mp *a, *b; /* Standard params (internal form) */
59 } ec_curve;
60
61 /* --- An elliptic curve point --- */
62
63 typedef struct ec {
64 mp *x, *y; /* Point coordinates */
65 mp *z; /* Common denominator (or null) */
66 } ec;
67
68 /* --- A factor for simultaneous multiplication --- */
69
70 typedef struct ec_mulfactor {
71 ec base; /* The point */
72 mp *exp; /* The exponent */
73 } ec_mulfactor;
74
75 /* --- Elliptic curve operations --- *
76 *
77 * All operations (apart from @destroy@ and @in@) are guaranteed to be
78 * performed on internal representations of points.
79 *
80 * (Historical note. We used to guarantee that the second to @add@ and @mul@
81 * was the output of @in@ or @fix@, but this canonification turned out to
82 * make the precomputation in @ec_exp@ too slow. Projective implementations
83 * must therefore cope with a pair of arbitrary points.)
84 */
85
86 typedef struct ec_ops {
87 void (*destroy)(ec_curve */*c*/);
88 int (*samep)(ec_curve */*c*/, ec_curve */*d*/);
89 ec *(*in)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
90 ec *(*out)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
91 ec *(*fix)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
92 ec *(*find)(ec_curve */*c*/, ec */*d*/, mp */*x*/);
93 ec *(*neg)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
94 ec *(*add)(ec_curve */*c*/, ec */*d*/, const ec */*p*/, const ec */*q*/);
95 ec *(*sub)(ec_curve */*c*/, ec */*d*/, const ec */*p*/, const ec */*q*/);
96 ec *(*dbl)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
97 int (*check)(ec_curve */*c*/, const ec */*p*/);
98 } ec_ops;
99
100 #define EC_SAMEP(c, d) (c)->ops->samep((c), (d))
101 #define EC_IN(c, d, p) (c)->ops->in((c), (d), (p))
102 #define EC_OUT(c, d, p) (c)->ops->out((c), (d), (p))
103 #define EC_FIX(c, d, p) (c)->ops->fix((c), (d), (p))
104
105 #define EC_FIND(c, d, x) (c)->ops->find((c), (d), (x))
106 #define EC_NEG(c, d, x) (c)->ops->neg((c), (d), (x))
107 #define EC_ADD(c, d, p, q) (c)->ops->add((c), (d), (p), (q))
108 #define EC_SUB(c, d, p, q) (c)->ops->sub((c), (d), (p), (q))
109 #define EC_DBL(c, d, p) (c)->ops->dbl((c), (d), (p))
110 #define EC_CHECK(c, p) (c)->ops->check((c), (p))
111
112 /* --- Elliptic curve parameters --- */
113
114 typedef struct ec_info {
115 ec_curve *c; /* The actual curve */
116 ec g; /* The common point */
117 mp *r; /* Order of %$g$% */
118 mp *h; /* Cofactor %$h = \#E/r$% */
119 } ec_info;
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 /* --- @ec_eq@ --- *
225 *
226 * Arguments: @const ec *p, *q@ = two points
227 *
228 * Returns: Nonzero if the points are equal. Compares external-format
229 * points.
230 */
231
232 #define EC_EQ(p, q) \
233 ((EC_ATINF(p) && EC_ATINF(q)) || \
234 (!EC_ATINF(p) && !EC_ATINF(q) && \
235 MP_EQ((p)->x, (q)->x) && \
236 MP_EQ((p)->y, (q)->y)))
237
238 extern int ec_eq(const ec *p, const ec *q);
239
240 /*----- Interesting arithmetic --------------------------------------------*/
241
242 /* --- @ec_samep@ --- *
243 *
244 * Arguments: @ec_curve *c, *d@ = two elliptic curves
245 *
246 * Returns: Nonzero if the curves are identical (not just isomorphic).
247 *
248 * Use: Checks for sameness of curves. This function does the full
249 * check, not just the curve-type-specific check done by the
250 * @sampep@ field operation.
251 */
252
253 extern int ec_samep(ec_curve */*c*/, ec_curve */*d*/);
254
255 /* --- @ec_find@ --- *
256 *
257 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
258 * @ec *d@ = pointer to the destination point
259 * @mp *x@ = a possible x-coordinate
260 *
261 * Returns: The destination if OK, or null if no point was found.
262 *
263 * Use: Finds a point on an elliptic curve with a given
264 * x-coordinate. If there is no point with the given
265 * %$x$%-coordinate, a null pointer is returned and the
266 * destination is left invalid.
267 */
268
269 extern ec *ec_find(ec_curve */*c*/, ec */*d*/, mp */*x*/);
270
271 /* --- @ec_rand@ --- *
272 *
273 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
274 * @ec *d@ = pointer to the destination point
275 * @grand *r@ = random number source
276 *
277 * Returns: The destination @d@.
278 *
279 * Use: Finds a random point on the given curve.
280 */
281
282 extern ec *ec_rand(ec_curve */*c*/, ec */*d*/, grand */*r*/);
283
284 /* --- @ec_neg@ --- *
285 *
286 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
287 * @ec *d@ = pointer to the destination point
288 * @const ec *p@ = pointer to the operand point
289 *
290 * Returns: The destination point.
291 *
292 * Use: Computes the negation of the given point.
293 */
294
295 extern ec *ec_neg(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
296
297 /* --- @ec_add@ --- *
298 *
299 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
300 * @ec *d@ = pointer to the destination point
301 * @const ec *p, *q@ = pointers to the operand points
302 *
303 * Returns: The destination @d@.
304 *
305 * Use: Adds two points on an elliptic curve.
306 */
307
308 extern ec *ec_add(ec_curve */*c*/, ec */*d*/,
309 const ec */*p*/, const ec */*q*/);
310
311 /* --- @ec_sub@ --- *
312 *
313 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
314 * @ec *d@ = pointer to the destination point
315 * @const ec *p, *q@ = pointers to the operand points
316 *
317 * Returns: The destination @d@.
318 *
319 * Use: Subtracts one point from another on an elliptic curve.
320 */
321
322 extern ec *ec_sub(ec_curve */*c*/, ec */*d*/,
323 const ec */*p*/, const ec */*q*/);
324
325 /* --- @ec_dbl@ --- *
326 *
327 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
328 * @ec *d@ = pointer to the destination point
329 * @const ec *p@ = pointer to the operand point
330 *
331 * Returns: The destination @d@.
332 *
333 * Use: Doubles a point on an elliptic curve.
334 */
335
336 extern ec *ec_dbl(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
337
338 /* --- @ec_check@ --- *
339 *
340 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
341 * @const ec *p@ = pointer to the point
342 *
343 * Returns: Zero if OK, nonzero if this is an invalid point.
344 *
345 * Use: Checks that a point is actually on an elliptic curve.
346 */
347
348 extern int ec_check(ec_curve */*c*/, const ec */*p*/);
349
350 /* --- @ec_mul@, @ec_imul@ --- *
351 *
352 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
353 * @ec *d@ = pointer to the destination point
354 * @const ec *p@ = pointer to the generator point
355 * @mp *n@ = integer multiplier
356 *
357 * Returns: The destination @d@.
358 *
359 * Use: Multiplies a point by a scalar, returning %$n p$%. The
360 * @imul@ variant uses internal representations for argument
361 * and result.
362 */
363
364 extern ec *ec_mul(ec_curve */*c*/, ec */*d*/, const ec */*p*/, mp */*n*/);
365 extern ec *ec_imul(ec_curve */*c*/, ec */*d*/, const ec */*p*/, mp */*n*/);
366
367 /* --- @ec_mmul@, @ec_immul@ --- *
368 *
369 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
370 * @ec *d@ = pointer to the destination point
371 * @const ec_mulfactor *f@ = pointer to vector of factors
372 * @size_t n@ = number of factors
373 *
374 * Returns: The destination @d@.
375 *
376 * Use: Does simultaneous point multiplication. The @immul@ variant
377 * uses internal representations for arguments and result.
378 */
379
380 extern ec *ec_mmul(ec_curve */*c*/, ec */*d*/,
381 const ec_mulfactor */*f*/, size_t /*n*/);
382 extern ec *ec_immul(ec_curve */*c*/, ec */*d*/,
383 const ec_mulfactor */*f*/, size_t /*n*/);
384
385 /*----- Standard curve operations -----------------------------------------*/
386
387 /* --- @ec_stdsamep@ --- *
388 *
389 * Arguments: @ec_curve *c, *d@ = two elliptic curves
390 *
391 * Returns: Nonzero if the curves are identical (not just isomorphic).
392 *
393 * Use: Simple sameness check on @a@ and @b@ curve members.
394 */
395
396 extern int ec_stdsamep(ec_curve */*c*/, ec_curve */*d*/);
397
398 /* --- @ec_idin@, @ec_idout@, @ec_idfix@ --- *
399 *
400 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
401 * @ec *d@ = pointer to the destination
402 * @const ec *p@ = pointer to a source point
403 *
404 * Returns: The destination @d@.
405 *
406 * Use: An identity operation if your curve has no internal
407 * representation. (The field internal representation is still
408 * used.)
409 */
410
411 extern ec *ec_idin(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
412 extern ec *ec_idout(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
413 extern ec *ec_idfix(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
414
415 /* --- @ec_projin@, @ec_projout@, @ec_projfix@ --- *
416 *
417 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
418 * @ec *d@ = pointer to the destination
419 * @const ec *p@ = pointer to a source point
420 *
421 * Returns: The destination @d@.
422 *
423 * Use: Conversion functions if your curve operations use a
424 * projective representation.
425 */
426
427 extern ec *ec_projin(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
428 extern ec *ec_projout(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
429 extern ec *ec_projfix(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
430
431 /* --- @ec_stdsub@ --- *
432 *
433 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
434 * @ec *d@ = pointer to the destination
435 * @const ec *p, *q@ = the operand points
436 *
437 * Returns: The destination @d@.
438 *
439 * Use: Standard point subtraction operation, in terms of negation
440 * and addition. This isn't as efficient as a ready-made
441 * subtraction operator.
442 */
443
444 extern ec *ec_stdsub(ec_curve */*c*/, ec */*d*/,
445 const ec */*p*/, const ec */*q*/);
446
447 /*----- Creating curves ---------------------------------------------------*/
448
449 /* --- @ec_destroycurve@ --- *
450 *
451 * Arguments: @ec_curve *c@ = pointer to an ellptic curve
452 *
453 * Returns: ---
454 *
455 * Use: Destroys a description of an elliptic curve.
456 */
457
458 extern void ec_destroycurve(ec_curve */*c*/);
459
460 /* --- @ec_prime@, @ec_primeproj@ --- *
461 *
462 * Arguments: @field *f@ = the underlying field for this elliptic curve
463 * @mp *a, *b@ = the coefficients for this curve
464 *
465 * Returns: A pointer to the curve, or null.
466 *
467 * Use: Creates a curve structure for an elliptic curve defined over
468 * a prime field. The @primeproj@ variant uses projective
469 * coordinates, which can be a win.
470 */
471
472 extern ec_curve *ec_prime(field */*f*/, mp */*a*/, mp */*b*/);
473 extern ec_curve *ec_primeproj(field */*f*/, mp */*a*/, mp */*b*/);
474
475 /* --- @ec_bin@, @ec_binproj@ --- *
476 *
477 * Arguments: @field *f@ = the underlying field for this elliptic curve
478 * @mp *a, *b@ = the coefficients for this curve
479 *
480 * Returns: A pointer to the curve, or null.
481 *
482 * Use: Creates a curve structure for an elliptic curve defined over
483 * a binary field. The @binproj@ variant uses projective
484 * coordinates, which can be a win.
485 */
486
487 extern ec_curve *ec_bin(field */*f*/, mp */*a*/, mp */*b*/);
488 extern ec_curve *ec_binproj(field */*f*/, mp */*a*/, mp */*b*/);
489
490 /*----- Curve parameter sets ----------------------------------------------*/
491
492 /* --- @ec_curveparse@ --- *
493 *
494 * Arguments: @qd_parse *qd@ = parser context
495 *
496 * Returns: Elliptic curve pointer if OK, or null.
497 *
498 * Use: Parses an elliptic curve description, which has the form
499 *
500 * * a field description
501 * * an optional `/'
502 * * `prime', `primeproj', `bin', or `binproj'
503 * * an optional `:'
504 * * the %$a$% parameter
505 * * an optional `,'
506 * * the %$b$% parameter
507 */
508
509 extern ec_curve *ec_curveparse(qd_parse */*qd*/);
510
511 /* --- @ec_ptparse@ --- *
512 *
513 * Arguments: @qd_parse *qd@ = parser context
514 * @ec *p@ = where to put the point
515 *
516 * Returns: The point address, or null.
517 *
518 * Use: Parses an elliptic curve point. This has the form
519 *
520 * * %$x$%-coordinate
521 * * optional `,'
522 * * %$y$%-coordinate
523 */
524
525 extern ec *ec_ptparse(qd_parse */*qd*/, ec */*p*/);
526
527 /* --- @ec_infoparse@ --- *
528 *
529 * Arguments: @qd_parse *qd@ = parser context
530 * @ec_info *ei@ = curve information block, currently
531 * uninitialized
532 *
533 * Returns: Zero on success, nonzero on failure.
534 *
535 * Use: Parses an elliptic curve information string, and stores the
536 * information in @ei@. This has the form
537 *
538 * * elliptic curve description
539 * * optional `/'
540 * * common point
541 * * optional `:'
542 * * group order
543 * * optional `*'
544 * * cofactor
545 */
546
547 extern int ec_infoparse(qd_parse */*qd*/, ec_info */*ei*/);
548
549 /* --- @ec_getinfo@ --- *
550 *
551 * Arguments: @ec_info *ei@ = where to write the information
552 * @const char *p@ = string describing a curve
553 *
554 * Returns: Null on success, or a pointer to an error message.
555 *
556 * Use: Parses out information about a curve. The string is either a
557 * standard curve name, or a curve info string.
558 */
559
560 extern const char *ec_getinfo(ec_info */*ei*/, const char */*p*/);
561
562 /* --- @ec_sameinfop@ --- *
563 *
564 * Arguments: @ec_info *ei, *ej@ = two elliptic curve parameter sets
565 *
566 * Returns: Nonzero if the curves are identical (not just isomorphic).
567 *
568 * Use: Checks for sameness of curve parameters.
569 */
570
571 extern int ec_sameinfop(ec_info */*ei*/, ec_info */*ej*/);
572
573 /* --- @ec_freeinfo@ --- *
574 *
575 * Arguments: @ec_info *ei@ = elliptic curve information block to free
576 *
577 * Returns: ---
578 *
579 * Use: Frees the information block.
580 */
581
582 extern void ec_freeinfo(ec_info */*ei*/);
583
584 /* --- @ec_checkinfo@ --- *
585 *
586 * Arguments: @const ec_info *ei@ = elliptic curve information block
587 *
588 * Returns: Null if OK, or pointer to error message.
589 *
590 * Use: Checks an elliptic curve according to the rules in SEC1.
591 */
592
593 extern const char *ec_checkinfo(const ec_info */*ei*/, grand */*gr*/);
594
595 /*----- That's all, folks -------------------------------------------------*/
596
597 #ifdef __cplusplus
598 }
599 #endif
600
601 #endif