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