Expunge revision histories in files.
[u/mdw/catacomb] / ec.h
CommitLineData
b0ab12e6 1/* -*-c-*-
2 *
b817bfc6 3 * $Id: ec.h,v 1.11 2004/04/08 01:36:15 mdw Exp $
b0ab12e6 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
b0ab12e6 30#ifndef CATACOMB_EC_H
31#define CATACOMB_EC_H
32
33#ifdef __cplusplus
34 extern "C" {
35#endif
36
37/*----- Header files ------------------------------------------------------*/
38
432c4e18 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
b0ab12e6 50
51/*----- Data structures ---------------------------------------------------*/
52
b085fd91 53/* --- An elliptic curve representation --- */
54
b0ab12e6 55typedef struct ec_curve {
56 const struct ec_ops *ops; /* Curve operations */
57 field *f; /* Underlying field structure */
432c4e18 58 mp *a, *b; /* Standard params (internal form) */
b0ab12e6 59} ec_curve;
60
b085fd91 61/* --- An elliptic curve point --- */
62
b0ab12e6 63typedef struct ec {
64 mp *x, *y; /* Point coordinates */
65 mp *z; /* Common denominator (or null) */
66} ec;
67
b085fd91 68/* --- A factor for simultaneous multiplication --- */
69
70typedef struct ec_mulfactor {
71 ec base; /* The point */
41cb1beb 72 mp *exp; /* The exponent */
b085fd91 73} ec_mulfactor;
74
8823192f 75/* --- Elliptic curve operations --- *
76 *
77 * All operations (apart from @destroy@ and @in@) are guaranteed to be
391faf42 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.)
8823192f 84 */
b085fd91 85
b0ab12e6 86typedef struct ec_ops {
87 void (*destroy)(ec_curve */*c*/);
34e4f738 88 int (*samep)(ec_curve */*c*/, ec_curve */*d*/);
41a324a7 89 ec *(*in)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
90 ec *(*out)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
8823192f 91 ec *(*fix)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
41a324a7 92 ec *(*find)(ec_curve */*c*/, ec */*d*/, mp */*x*/);
b085fd91 93 ec *(*neg)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
41a324a7 94 ec *(*add)(ec_curve */*c*/, ec */*d*/, const ec */*p*/, const ec */*q*/);
b085fd91 95 ec *(*sub)(ec_curve */*c*/, ec */*d*/, const ec */*p*/, const ec */*q*/);
41a324a7 96 ec *(*dbl)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
8823192f 97 int (*check)(ec_curve */*c*/, const ec */*p*/);
b0ab12e6 98} ec_ops;
99
34e4f738 100#define EC_SAMEP(c, d) (c)->ops->samep((c), (d))
41a324a7 101#define EC_IN(c, d, p) (c)->ops->in((c), (d), (p))
dbfee00a 102#define EC_OUT(c, d, p) (c)->ops->out((c), (d), (p))
8823192f 103#define EC_FIX(c, d, p) (c)->ops->fix((c), (d), (p))
41a324a7 104
b0ab12e6 105#define EC_FIND(c, d, x) (c)->ops->find((c), (d), (x))
b085fd91 106#define EC_NEG(c, d, x) (c)->ops->neg((c), (d), (x))
b0ab12e6 107#define EC_ADD(c, d, p, q) (c)->ops->add((c), (d), (p), (q))
b085fd91 108#define EC_SUB(c, d, p, q) (c)->ops->sub((c), (d), (p), (q))
b0ab12e6 109#define EC_DBL(c, d, p) (c)->ops->dbl((c), (d), (p))
8823192f 110#define EC_CHECK(c, p) (c)->ops->check((c), (p))
b0ab12e6 111
432c4e18 112/* --- Elliptic curve parameters --- */
113
114typedef 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
b0ab12e6 121/*----- Simple memory management things -----------------------------------*/
122
123/* --- @ec_create@ --- *
124 *
125 * Arguments: @ec *p@ = pointer to an elliptic-curve point
126 *
41a324a7 127 * Returns: The argument @p@.
b0ab12e6 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
41a324a7 140extern ec *ec_create(ec */*p*/);
b0ab12e6 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
160extern 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
172extern int ec_atinf(const ec */*p*/);
173
174/* --- @ec_setinf@ --- *
175 *
176 * Arguments: @ec *p@ = pointer to a point
177 *
41a324a7 178 * Returns: The argument @p@.
b0ab12e6 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
41a324a7 195extern ec *ec_setinf(ec */*p*/);
b0ab12e6 196
197/* --- @ec_copy@ --- *
198 *
199 * Arguments: @ec *d@ = pointer to destination point
200 * @const ec *p@ = pointer to source point
201 *
41a324a7 202 * Returns: The destination @d@.
b0ab12e6 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 { \
b085fd91 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; \
b0ab12e6 218 } \
219 } \
220} while (0)
221
41a324a7 222extern ec *ec_copy(ec */*d*/, const ec */*p*/);
b0ab12e6 223
bc985cef 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
238extern int ec_eq(const ec *p, const ec *q);
239
b0ab12e6 240/*----- Interesting arithmetic --------------------------------------------*/
241
34e4f738 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
253extern int ec_samep(ec_curve */*c*/, ec_curve */*d*/);
254
b0ab12e6 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 *
b085fd91 261 * Returns: The destination if OK, or null if no point was found.
b0ab12e6 262 *
b085fd91 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.
b0ab12e6 267 */
268
b085fd91 269extern ec *ec_find(ec_curve */*c*/, ec */*d*/, mp */*x*/);
270
bc985cef 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
282extern ec *ec_rand(ec_curve */*c*/, ec */*d*/, grand */*r*/);
283
b085fd91 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
295extern ec *ec_neg(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
b0ab12e6 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 *
41a324a7 303 * Returns: The destination @d@.
b0ab12e6 304 *
305 * Use: Adds two points on an elliptic curve.
306 */
307
41a324a7 308extern ec *ec_add(ec_curve */*c*/, ec */*d*/,
309 const ec */*p*/, const ec */*q*/);
b0ab12e6 310
b085fd91 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
322extern ec *ec_sub(ec_curve */*c*/, ec */*d*/,
323 const ec */*p*/, const ec */*q*/);
324
b0ab12e6 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 *
41a324a7 331 * Returns: The destination @d@.
b0ab12e6 332 *
333 * Use: Doubles a point on an elliptic curve.
334 */
335
41a324a7 336extern ec *ec_dbl(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
b0ab12e6 337
8823192f 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
348extern int ec_check(ec_curve */*c*/, const ec */*p*/);
349
b085fd91 350/* --- @ec_mul@, @ec_imul@ --- *
b0ab12e6 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 *
41a324a7 357 * Returns: The destination @d@.
b0ab12e6 358 *
b085fd91 359 * Use: Multiplies a point by a scalar, returning %$n p$%. The
360 * @imul@ variant uses internal representations for argument
361 * and result.
b0ab12e6 362 */
363
41a324a7 364extern ec *ec_mul(ec_curve */*c*/, ec */*d*/, const ec */*p*/, mp */*n*/);
b085fd91 365extern 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
380extern ec *ec_mmul(ec_curve */*c*/, ec */*d*/,
381 const ec_mulfactor */*f*/, size_t /*n*/);
382extern ec *ec_immul(ec_curve */*c*/, ec */*d*/,
383 const ec_mulfactor */*f*/, size_t /*n*/);
41a324a7 384
385/*----- Standard curve operations -----------------------------------------*/
386
34e4f738 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
396extern int ec_stdsamep(ec_curve */*c*/, ec_curve */*d*/);
397
8823192f 398/* --- @ec_idin@, @ec_idout@, @ec_idfix@ --- *
41a324a7 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
411extern ec *ec_idin(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
412extern ec *ec_idout(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
8823192f 413extern ec *ec_idfix(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
41a324a7 414
8823192f 415/* --- @ec_projin@, @ec_projout@, @ec_projfix@ --- *
41a324a7 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
427extern ec *ec_projin(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
428extern ec *ec_projout(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
8823192f 429extern ec *ec_projfix(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
b0ab12e6 430
b085fd91 431/* --- @ec_stdsub@ --- *
432 *
433 * Arguments: @ec_curve *c@ = pointer to an elliptic curve
434 * @ec *d@ = pointer to the destination
41cb1beb 435 * @const ec *p, *q@ = the operand points
b085fd91 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
41cb1beb 444extern ec *ec_stdsub(ec_curve */*c*/, ec */*d*/,
445 const ec */*p*/, const ec */*q*/);
b085fd91 446
b0ab12e6 447/*----- Creating curves ---------------------------------------------------*/
448
b085fd91 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
458extern void ec_destroycurve(ec_curve */*c*/);
459
460/* --- @ec_prime@, @ec_primeproj@ --- *
b0ab12e6 461 *
dbfee00a 462 * Arguments: @field *f@ = the underlying field for this elliptic curve
b0ab12e6 463 * @mp *a, *b@ = the coefficients for this curve
464 *
02d7884d 465 * Returns: A pointer to the curve, or null.
b0ab12e6 466 *
467 * Use: Creates a curve structure for an elliptic curve defined over
b085fd91 468 * a prime field. The @primeproj@ variant uses projective
469 * coordinates, which can be a win.
b0ab12e6 470 */
471
472extern ec_curve *ec_prime(field */*f*/, mp */*a*/, mp */*b*/);
b085fd91 473extern ec_curve *ec_primeproj(field */*f*/, mp */*a*/, mp */*b*/);
b0ab12e6 474
ceb3f0c0 475/* --- @ec_bin@, @ec_binproj@ --- *
b0ab12e6 476 *
477 * Arguments: @field *f@ = the underlying field for this elliptic curve
478 * @mp *a, *b@ = the coefficients for this curve
479 *
02d7884d 480 * Returns: A pointer to the curve, or null.
b0ab12e6 481 *
ceb3f0c0 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.
b0ab12e6 485 */
486
487extern ec_curve *ec_bin(field */*f*/, mp */*a*/, mp */*b*/);
ceb3f0c0 488extern ec_curve *ec_binproj(field */*f*/, mp */*a*/, mp */*b*/);
b0ab12e6 489
432c4e18 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
509extern 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
525extern 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
547extern 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
560extern const char *ec_getinfo(ec_info */*ei*/, const char */*p*/);
561
34e4f738 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
571extern int ec_sameinfop(ec_info */*ei*/, ec_info */*ej*/);
572
432c4e18 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
582extern 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
593extern const char *ec_checkinfo(const ec_info */*ei*/, grand */*gr*/);
594
b0ab12e6 595/*----- That's all, folks -------------------------------------------------*/
596
597#ifdef __cplusplus
598 }
599#endif
600
601#endif