Oops. Fix formatting. :-S
[u/mdw/catacomb] / group.h
CommitLineData
34e4f738 1/* -*-c-*-
2 *
02d7884d 3 * $Id: group.h,v 1.2 2004/04/03 03:32:05 mdw Exp $
34e4f738 4 *
5 * General cyclic group abstraction
6 *
7 * (c) 2004 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: group.h,v $
02d7884d 33 * Revision 1.2 2004/04/03 03:32:05 mdw
34 * General robustification.
35 *
34e4f738 36 * Revision 1.1 2004/04/01 12:50:09 mdw
37 * Add cyclic group abstraction, with test code. Separate off exponentation
38 * functions for better static linking. Fix a buttload of bugs on the way.
39 * Generally ensure that negative exponents do inversion correctly. Add
40 * table of standard prime-field subgroups. (Binary field subgroups are
41 * currently unimplemented but easy to add if anyone ever finds a good one.)
42 *
43 */
44
45#ifndef CATACOMB_GROUP_H
46#define CATACOMB_GROUP_H
47
48#ifdef __cplusplus
49 extern "C" {
50#endif
51
52/*----- Header files ------------------------------------------------------*/
53
54#include <mLib/dstr.h>
55
56#ifndef CATACOMB_BUF_H
57# include "buf.h"
58#endif
59
60#ifndef CATACOMB_DH_H
61# include "ec.h"
62#endif
63
64#ifndef CATACOMB_GRAND_H
65# include "grand.h"
66#endif
67
68#ifndef CATACOMB_MP_H
69# include "mp.h"
70#endif
71
72#ifndef CATACOMB_QDPARSE_H
73# include "qdparse.h"
74#endif
75
76/*----- Data structures ---------------------------------------------------*/
77
78#ifndef ge
79 typedef struct ge ge; /* Group element (abstract type) */
80#endif
81
02d7884d 82typedef struct group_ {
34e4f738 83 const struct group_ops *ops; /* Operations table */
84 size_t nbits; /* Size of an element in bits */
85 size_t noctets; /* Size of an element in octets */
86 ge *i; /* Identity element */
87 ge *g; /* Generator element */
88 mp *r; /* Order of the generator */
89 mp *h; /* Cofactor */
90} group;
91
92typedef struct group_expfactor {
93 ge *base; /* The base */
94 mp *exp; /* The exponent */
95} group_expfactor;
96
97typedef struct group_ops {
98 unsigned ty; /* Type of this group */
99
100 /* --- Memory management --- */
101
102 void (*destroygroup)(group */*g*/);
103 ge *(*create)(group */*g*/);
104 void (*copy)(group */*g*/, ge */*d*/, ge */*x*/);
105 void (*burn)(group */*g*/, ge */*x*/);
106 void (*destroy)(group */*g*/, ge */*e*/);
107
108 /* --- Comparisons --- */
109
110 int (*samep)(group */*g*/, group */*h*/);
111 int (*eq)(group */*g*/, ge */*x*/, ge */*y*/);
112 int (*identp)(group */*g*/, ge */*x*/);
113
114 /* --- Other stuff --- */
115
116 const char *(*check)(group */*g*/, grand */*gr*/);
117
118 /* --- Arithmetic --- */
119
120 void (*mul)(group */*g*/, ge */*d*/, ge */*x*/, ge */*y*/);
121 void (*sqr)(group */*g*/, ge */*d*/, ge */*x*/);
122 void (*inv)(group */*g*/, ge */*d*/, ge */*x*/);
123 void (*div)(group */*g*/, ge */*d*/, ge */*x*/, ge */*y*/);
124 void (*exp)(group */*g*/, ge */*d*/, ge */*x*/, mp */*n*/);
125 void (*mexp)(group */*g*/, ge */*d*/,
126 const group_expfactor */*f*/, size_t /*n*/);
127
128 /* --- Debugging --- */
129
130 int (*read)(group */*g*/, ge */*d*/,
131 const mptext_ops */*ops*/, void */*p*/);
132 int (*write)(group */*g*/, ge */*x*/,
133 const mptext_ops */*ops*/, void */*p*/);
134
135 /* --- Conversions --- */
136
137 mp *(*toint)(group */*g*/, mp */*d*/, ge */*x*/);
138 int (*fromint)(group */*g*/, ge */*d*/, mp */*x*/);
139 int (*toec)(group */*g*/, ec */*d*/, ge */*x*/);
140 int (*fromec)(group */*g*/, ge */*d*/, ec */*p*/);
141 int (*tobuf)(group */*h*/, buf */*b*/, ge */*x*/);
142 int (*frombuf)(group */*h*/, buf */*b*/, ge */*d*/);
143
144} group_ops;
145
146enum {
147 GTY_PRIME, /* Prime field subgroup */
148 GTY_BINARY, /* Binary feld subgroup */
149 GTY_EC /* Elliptic curve group */
150};
151
152#define G_DESTROYGROUP(g) (g)->ops->destroygroup((g))
153#define G_CREATE(g) (g)->ops->create((g))
154#define G_COPY(g, d, x) (g)->ops->copy((g), (d), (x))
155#define G_BURN(g, x) (g)->ops->burn((g), (x))
156#define G_DESTROY(g, x) (g)->ops->destroy((g), (x))
157
158#define G_SAMEP(g, h) (g)->ops->samep((g), (h))
159#define G_EQ(g, x, y) (g)->ops->eq((g), (x), (y))
160#define G_IDENTP(g, x) (g)->ops->identp((g), (x))
161
162#define G_CHECK(g, gr) (g)->ops->check((g), (gr))
163
164#define G_MUL(g, d, x, y) (g)->ops->mul((g), (d), (x), (y))
165#define G_SQR(g, d, x) (g)->ops->sqr((g), (d), (x))
166#define G_INV(g, d, x) (g)->ops->inv((g), (d), (x))
167#define G_DIV(g, d, x, y) (g)->ops->div((g), (d), (x), (y))
168#define G_EXP(g, d, x, n) (g)->ops->exp((g), (d), (x), (n))
169#define G_MEXP(g, d, f, n) (g)->ops->mexp((g), (d), (f), (n))
170
171#define G_READ(g, d, o, p) (g)->ops->read((g), (d), (o), (p))
172#define G_WRITE(g, x, o, p) (g)->ops->write((g), (x), (o), (p))
173
174#define G_TOINT(g, d, x) (g)->ops->toint((g), (d), (x))
175#define G_FROMINT(g, d, x) (g)->ops->fromint((g), (d), (x))
176#define G_TOEC(g, d, x) (g)->ops->toec((g), (d), (x))
177#define G_FROMEC(g, d, p) (g)->ops->fromec((g), (d), (p))
178#define G_TOBUF(g, b, x) (g)->ops->tobuf((g), (b), (x))
179#define G_FROMBUF(g, b, d) (g)->ops->frombuf((g), (b), (d))
180
181/*----- Handy functions ---------------------------------------------------*/
182
183/* --- @group_check@ --- *
184 *
185 * Arguments: @group *g@ = an abstract group
186 * @ge *x@ = a group element
187 *
188 * Returns: Zero on success, nonzero for failure.
189 *
190 * Use: Checks that @x@ is a valid group element. This may take a
191 * while, since it checks that %$x^h \ne 1$%.
192 */
193
194extern int group_check(group */*g*/, ge */*x*/);
195
196/* --- @group_samep@ --- *
197 *
198 * Arguments: @group *g, *h@ = two abstract groups
199 *
200 * Returns: Nonzero if the groups are in fact identical (not just
201 * isomorphic).
202 *
203 * Use: Checks to see whether two groups are actually the same. This
204 * function does the full check: the group operatrion @samep@
205 * just does the group-specific details.
206 */
207
208extern int group_samep(group */*g*/, group */*h*/);
209
210/*----- Textual I/O on group elements -------------------------------------*/
211
212extern int group_readstring(group */*g*/, ge */*d*/,
213 const char */*p*/, char **/*end*/);
214extern int group_writestring(group */*g*/, ge */*d*/,
215 char */*p*/, size_t /*sz*/);
216
217extern int group_readfile(group */*g*/, ge */*d*/, FILE */*fp*/);
218extern int group_writefile(group */*g*/, ge */*x*/, FILE */*fp*/);
219
220extern int group_readdstr(group */*g*/, ge */*d*/,
221 dstr */*dd*/, size_t */*off*/);
222extern int group_writedstr(group */*g*/, ge */*x*/, dstr */*d*/);
223
224/*----- Standard implementations ------------------------------------------*/
225
226/* --- @group_stdidentp@ --- *
227 *
228 * Arguments: @group *g@ = abstract group
229 * @ge *x@ = group element
230 *
231 * Returns: Nonzero if %$x$% is the group identity.
232 */
233
234extern int group_stdidentp(group */*g*/, ge */*x*/);
235
236/* --- @group_stdcheck@ --- *
237 *
238 * Arguments: @group *g@ = abstract group
239 * @grand *gr@ = random number source.
240 *
241 * Returns: Null on success, or a pointer to an error message.
242 */
243
244extern const char *group_stdcheck(group */*g*/, grand */*gr*/);
245
246/* --- @group_stdsqr@ --- *
247 *
248 * Arguments: @group *g@ = abstract group
249 * @ge *d@ = destination pointer
250 * @ge *x@ = group element
251 *
252 * Returns: ---
253 *
254 * Use: Computes %$d = x^2$% as %$d = x x$%.
255 */
256
257extern void group_stdsqr(group */*g*/, ge */*d*/, ge */*x*/);
258
259/* --- @group_stddiv@ --- *
260 *
261 * Arguments: @group *g@ = abstract group
262 * @ge *d@ = destination pointer
263 * @ge *x@ = dividend
264 * @ge *y@ = divisor
265 *
266 * Returns: ---
267 *
268 * Use: Computes %$d = x/y$% as %$d = x y^{-1}$%.
269 */
270
271extern void group_stddiv(group */*g*/, ge */*d*/, ge */*x*/, ge */*y*/);
272
273/* --- @group_stdexp@ --- *
274 *
275 * Arguments: @group *g@ = abstract group
276 * @ge *d@ = destination pointer
277 * @ge *x@ = base element
278 * @mp *n@ = exponent
279 *
280 * Returns: ---
281 *
282 * Use: Computes %$d = x^n$% efficiently.
283 */
284
285extern void group_stdexp(group */*g*/, ge */*d*/, ge */*x*/, mp */*n*/);
286
287/* --- @group_stdmexp@ --- *
288 *
289 * Arguments: @group *g@ = abstract group
290 * @ge *d@ = destination pointer
291 * @const group_expfactor *f@ = vector of factors
292 * @size_t n@ = number of factors
293 *
294 * Returns: ---
295 *
296 * Use: Computes %$d = g_0^{x_0} g_1^{x_1} \ldots$% efficiently.
297 */
298
299extern void group_stdmexp(group */*g*/, ge */*d*/,
300 const group_expfactor */*f*/, size_t /*n*/);
301
302/* --- @group_stdtoec@ --- *
303 *
304 * Arguments: @group *g@ = abstract group
305 * @ec *d@ = destination point
306 * @ge *x@ = group element
307 *
308 * Returns: @-1@, indicating failure.
309 *
310 * Use: Fails to convert a group element to an elliptic curve point.
311 */
312
313extern int group_stdtoec(group */*g*/, ec */*d*/, ge */*x*/);
314
315/* --- @group_stdfromec@ --- *
316 *
317 * Arguments: @group *g@ = abstract group
318 * @ge *d@ = destination pointer
319 * @ec *p@ = elliptic curve point
320 *
321 * Returns: Zero for success, @-1@ on failure.
322 *
323 * Use: Converts %$p$% to a group element by converting its %$x$%-
324 * coordinate.
325 */
326
327extern int group_stdfromec(group */*g*/, ge */*d*/, ec */*p*/);
328
329/*----- Prime field subgroups ---------------------------------------------*/
330
331typedef struct gprime_param {
332 mp *p, *q; /* Prime numbers %$p$% and %$q$% */
333 mp *g; /* Generates order-%$q$% subgroup */
334} gprime_param;
335
336/* --- @group_prime@ --- *
337 *
338 * Arguments: @const gprime_param *gp@ = group parameters
339 *
02d7884d 340 * Returns: A pointer to the group, or null.
34e4f738 341 *
342 * Use: Constructs an abstract group interface for a subgroup of a
343 * prime field. Group elements are @mp *@ pointers.
344 */
345
346group *group_prime(const gprime_param */*gp*/);
347
348/*----- Elliptic curve groups ---------------------------------------------*/
349
350/* --- @group_ec@ --- *
351 *
352 * Arguments: @const ec_info *ei@ = elliptic curve parameters
353 *
02d7884d 354 * Returns: A pointer to the group, or null.
34e4f738 355 *
356 * Use: Constructs an abstract group interface for an elliptic curve
357 * group. Group elements are @ec@ structures. The contents of
358 * the @ec_info@ structure becomes the property of the @group@
359 * object; you can (and should) free the structure itself, but
360 * calling @ec_freeinfo@ on it is not allowed.
361 */
362
363group *group_ec(const ec_info */*ei*/);
364
365/*----- General group initialization --------------------------------------*/
366
367/* --- @group_parse@ --- *
368 *
369 * Arguments: @qd_parse *qd@ = quick-and-dirty parser
370 *
371 * Returns: Group pointer, or null for failure.
372 *
373 * Use: Parses a group description and returns the group. This has
374 * the form `TYPE { SPEC }' where TYPE is `prime' or `ec', and
375 * SPEC is the appropriate kind of group specification of the
376 * given type.
377 */
378
379extern group *group_parse(qd_parse */*qd*/);
380
381/* --- @group_fromstring@ --- *
382 *
383 * Arguments: @const char *p@ = pointer to string to read
384 * @group **gg@ = where to put the group pointer
385 *
386 * Returns: Null if OK, or an error string.
387 *
388 * Use: Parses a group spec from a string, and returns the group.
389 */
390
391extern const char *group_fromstring(const char */*p*/, group **/*gg*/);
392
393/*----- That's all, folks -------------------------------------------------*/
394
395#ifdef __cplusplus
396 }
397#endif
398
399#endif