chiark / gitweb /
47c01a9fdecc65db98f8a02b0f248d36cc1eb87a
[catacomb] / ec.c
1 /* -*-c-*-
2  *
3  * $Id: ec.c,v 1.4 2003/05/15 23:25:59 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.c,v $
33  * Revision 1.4  2003/05/15 23:25:59  mdw
34  * Make elliptic curve stuff build.
35  *
36  * Revision 1.3  2002/01/13 13:48:44  mdw
37  * Further progress.
38  *
39  * Revision 1.2  2001/05/07 17:29:44  mdw
40  * Treat projective coordinates as an internal representation.  Various
41  * minor interface changes.
42  *
43  * Revision 1.1  2001/04/29 18:12:33  mdw
44  * Prototype version.
45  *
46  */
47
48 /*----- Header files ------------------------------------------------------*/
49
50 #include "ec.h"
51 #include "ec-exp.h"
52
53 /*----- Trivial wrappers --------------------------------------------------*/
54
55 /* --- @ec_create@ --- *
56  *
57  * Arguments:   @ec *p@ = pointer to an elliptic-curve point
58  *
59  * Returns:     The argument @p@.
60  *
61  * Use:         Initializes a new point.  The initial value is the additive
62  *              identity (which is universal for all curves).
63  */
64
65 ec *ec_create(ec *p) { EC_CREATE(p); return (p); }
66
67 /* --- @ec_destroy@ --- *
68  *
69  * Arguments:   @ec *p@ = pointer to an elliptic-curve point
70  *
71  * Returns:     ---
72  *
73  * Use:         Destroys a point, making it invalid.
74  */
75
76 void ec_destroy(ec *p) { EC_DESTROY(p); }
77
78 /* --- @ec_atinf@ --- *
79  *
80  * Arguments:   @const ec *p@ = pointer to a point
81  *
82  * Returns:     Nonzero if %$p = O$% is the point at infinity, zero
83  *              otherwise.
84  */
85
86 int ec_atinf(const ec *p) { return (EC_ATINF(p)); }
87
88 /* --- @ec_setinf@ --- *
89  *
90  * Arguments:   @ec *p@ = pointer to a point
91  *
92  * Returns:     The argument @p@.
93  *
94  * Use:         Sets the given point to be the point %$O$% at infinity.
95  */
96
97 ec *ec_setinf(ec *p) { EC_SETINF(p); return (p); }
98
99 /* --- @ec_copy@ --- *
100  *
101  * Arguments:   @ec *d@ = pointer to destination point
102  *              @const ec *p@ = pointer to source point
103  *
104  * Returns:     The destination @d@.
105  *
106  * Use:         Creates a copy of an elliptic curve point.
107  */
108
109 ec *ec_copy(ec *d, const ec *p) { EC_COPY(d, p); return (d); }
110
111 /*----- Standard curve operations -----------------------------------------*/
112
113 /* --- @ec_idin@, @ec_idout@ --- *
114  *
115  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
116  *              @ec *d@ = pointer to the destination
117  *              @const ec *p@ = pointer to a source point
118  *
119  * Returns:     The destination @d@.
120  *
121  * Use:         An identity operation if your curve has no internal
122  *              representation.  (The field internal representation is still
123  *              used.)
124  */
125
126 ec *ec_idin(ec_curve *c, ec *d, const ec *p)
127 {
128   if (EC_ATINF(p))
129     EC_SETINF(d);
130   else {
131     field *f = c->f;
132     d->x = F_IN(f, d->x, p->x);
133     d->y = F_IN(f, d->y, p->y);
134     mp_drop(d->z); d->z = 0;
135   }
136   return (d);
137 }
138
139 ec *ec_idout(ec_curve *c, ec *d, const ec *p)
140 {
141   if (EC_ATINF(p))
142     EC_SETINF(d);
143   else {
144     field *f = c->f;
145     d->x = F_OUT(f, d->x, p->x);
146     d->y = F_OUT(f, d->y, p->y);
147     mp_drop(d->z); d->z = 0;
148   }
149   return (d);
150 }
151
152 /* --- @ec_projin@, @ec_projout@ --- *
153  *
154  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
155  *              @ec *d@ = pointer to the destination
156  *              @const ec *p@ = pointer to a source point
157  *
158  * Returns:     The destination @d@.
159  *
160  * Use:         Conversion functions if your curve operations use a
161  *              projective representation.
162  */
163
164 ec *ec_projin(ec_curve *c, ec *d, const ec *p)
165 {
166   if (EC_ATINF(p))
167     EC_SETINF(d);
168   else {
169     field *f = c->f;
170     d->x = F_IN(f, d->x, p->x);
171     d->y = F_IN(f, d->y, p->y);
172     mp_drop(d->z); d->z = MP_COPY(f->one);
173   }
174   return (d);
175 }
176
177 ec *ec_projout(ec_curve *c, ec *d, const ec *p)
178 {
179   if (EC_ATINF(p))
180     EC_SETINF(d);
181   else {
182     mp *x, *y, *z;
183     field *f = c->f;
184     z = F_INV(f, MP_NEW, p->z);
185     x = F_MUL(f, d->x, p->x, z);
186     y = F_MUL(f, d->y, p->y, z);
187     mp_drop(z);
188     mp_drop(d->z);
189     d->x = F_OUT(f, x, x);
190     d->y = F_OUT(f, y, y);
191     d->z = 0;
192   }
193   return (d);
194 }
195
196 /* --- @ec_stdsub@ --- *
197  *
198  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
199  *              @ec *d@ = pointer to the destination
200  *              @const ec *p, *q@ = the operand points
201  *
202  * Returns:     The destination @d@.
203  *
204  * Use:         Standard point subtraction operation, in terms of negation
205  *              and addition.  This isn't as efficient as a ready-made
206  *              subtraction operator.
207  */
208
209 ec *ec_stdsub(ec_curve *c, ec *d, const ec *p, const ec *q)
210 {
211   ec t = EC_INIT;
212   EC_NEG(c, &t, q);
213   EC_ADD(c, d, p, &t);
214   EC_DESTROY(&t);
215   return (d);
216 }
217
218 /*----- Creating curves ---------------------------------------------------*/
219
220 /* --- @ec_destroycurve@ --- *
221  *
222  * Arguments:   @ec_curve *c@ = pointer to an ellptic curve
223  *
224  * Returns:     ---
225  *
226  * Use:         Destroys a description of an elliptic curve.
227  */
228
229 void ec_destroycurve(ec_curve *c) { c->ops->destroy(c); }
230
231 /*----- Real arithmetic ---------------------------------------------------*/
232
233 /* --- @ec_find@ --- *
234  *
235  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
236  *              @ec *d@ = pointer to the destination point
237  *              @mp *x@ = a possible x-coordinate
238  *
239  * Returns:     Zero if OK, nonzero if there isn't a point there.
240  *
241  * Use:         Finds a point on an elliptic curve with a given x-coordinate.
242  */
243
244 ec *ec_find(ec_curve *c, ec *d, mp *x)
245 {
246   x = F_IN(c->f, MP_NEW, x);
247   if ((d = EC_FIND(c, d, x)) != 0)
248     EC_OUT(c, d, d);
249   mp_drop(x);
250   return (d);
251 }
252
253 /* --- @ec_add@ --- *
254  *
255  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
256  *              @ec *d@ = pointer to the destination point
257  *              @const ec *p, *q@ = pointers to the operand points
258  *
259  * Returns:     ---
260  *
261  * Use:         Adds two points on an elliptic curve.
262  */
263
264 ec *ec_add(ec_curve *c, ec *d, const ec *p, const ec *q)
265 {
266   ec pp = EC_INIT, qq = EC_INIT;
267   EC_IN(c, &pp, p);
268   EC_IN(c, &qq, q);
269   EC_ADD(c, d, &pp, &qq);
270   EC_OUT(c, d, d);
271   EC_DESTROY(&pp);
272   EC_DESTROY(&qq);
273   return (d);
274 }
275
276 /* --- @ec_dbl@ --- *
277  *
278  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
279  *              @ec *d@ = pointer to the destination point
280  *              @const ec *p@ = pointer to the operand point
281  *
282  * Returns:     ---
283  *
284  * Use:         Doubles a point on an elliptic curve.
285  */
286
287 ec *ec_dbl(ec_curve *c, ec *d, const ec *p)
288 {
289   EC_IN(c, d, p);
290   EC_DBL(c, d, d);
291   return (EC_OUT(c, d, d));
292 }
293
294 /* --- @ec_imul@, @ec_mul@ --- *
295  *
296  * Arguments:   @ec_curve *c@ = pointer to an elliptic curve
297  *              @ec *d@ = pointer to the destination point
298  *              @const ec *p@ = pointer to the generator point
299  *              @mp *n@ = integer multiplier
300  *
301  * Returns:     The destination @d@.
302  *
303  * Use:         Multiplies a point by a scalar, returning %$n p$%.  The
304  *              @imul@ variant uses internal representations for argument
305  *              and result.
306  */
307
308 ec *ec_imul(ec_curve *c, ec *d, const ec *p, mp *n)
309 {
310   ec t = EC_INIT;
311
312   EC_COPY(&t, p);
313   if (t.x && (n->f & MP_BURN))
314     t.x->f |= MP_BURN;
315   MP_SHRINK(n);
316   EC_SETINF(d);
317   if (MP_LEN(n) == 0)
318     ;
319   else if (MP_LEN(n) < EXP_THRESH)
320     EXP_SIMPLE(*d, t, n);
321   else
322     EXP_WINDOW(*d, t, n);
323   return (d);
324 }
325
326 ec *ec_mul(ec_curve *c, ec *d, const ec *p, mp *n)
327 {
328   EC_IN(c, d, p);
329   ec_imul(c, d, d, n);
330   return (EC_OUT(c, d, d));
331 }
332
333 /*----- That's all, folks -------------------------------------------------*/