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