3 * $Id: group.h,v 1.2 2004/04/03 03:32:05 mdw Exp $
5 * General cyclic group abstraction
7 * (c) 2004 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
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.
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.
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,
30 /*----- Revision history --------------------------------------------------*
33 * Revision 1.2 2004/04/03 03:32:05 mdw
34 * General robustification.
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.)
45 #ifndef CATACOMB_GROUP_H
46 #define CATACOMB_GROUP_H
52 /*----- Header files ------------------------------------------------------*/
54 #include <mLib/dstr.h>
56 #ifndef CATACOMB_BUF_H
64 #ifndef CATACOMB_GRAND_H
72 #ifndef CATACOMB_QDPARSE_H
76 /*----- Data structures ---------------------------------------------------*/
79 typedef struct ge ge
; /* Group element (abstract type) */
82 typedef struct group_
{
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 */
92 typedef struct group_expfactor
{
93 ge
*base
; /* The base */
94 mp
*exp
; /* The exponent */
97 typedef struct group_ops
{
98 unsigned ty
; /* Type of this group */
100 /* --- Memory management --- */
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*/
);
108 /* --- Comparisons --- */
110 int (*samep
)(group */
*g*/
, group */
*h*/
);
111 int (*eq
)(group */
*g*/
, ge */
*x*/
, ge */
*y*/
);
112 int (*identp
)(group */
*g*/
, ge */
*x*/
);
114 /* --- Other stuff --- */
116 const char *(*check
)(group */
*g*/
, grand */
*gr*/
);
118 /* --- Arithmetic --- */
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*/);
128 /* --- Debugging --- */
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*/
);
135 /* --- Conversions --- */
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*/
);
147 GTY_PRIME
, /* Prime field subgroup */
148 GTY_BINARY
, /* Binary feld subgroup */
149 GTY_EC
/* Elliptic curve group */
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))
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))
162 #define G_CHECK(g, gr) (g)->ops->check((g), (gr))
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))
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))
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))
181 /*----- Handy functions ---------------------------------------------------*/
183 /* --- @group_check@ --- *
185 * Arguments: @group *g@ = an abstract group
186 * @ge *x@ = a group element
188 * Returns: Zero on success, nonzero for failure.
190 * Use: Checks that @x@ is a valid group element. This may take a
191 * while, since it checks that %$x^h \ne 1$%.
194 extern int group_check(group */
*g*/
, ge */
*x*/
);
196 /* --- @group_samep@ --- *
198 * Arguments: @group *g, *h@ = two abstract groups
200 * Returns: Nonzero if the groups are in fact identical (not just
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.
208 extern int group_samep(group */
*g*/
, group */
*h*/
);
210 /*----- Textual I/O on group elements -------------------------------------*/
212 extern int group_readstring(group */
*g*/
, ge */
*d*/
,
213 const char */
*p*/
, char **/
*end*/
);
214 extern int group_writestring(group */
*g*/
, ge */
*d*/
,
215 char */
*p*/
, size_t /*sz*/);
217 extern int group_readfile(group */
*g*/
, ge */
*d*/
, FILE */
*fp*/
);
218 extern int group_writefile(group */
*g*/
, ge */
*x*/
, FILE */
*fp*/
);
220 extern int group_readdstr(group */
*g*/
, ge */
*d*/
,
221 dstr */
*dd*/
, size_t */
*off*/
);
222 extern int group_writedstr(group */
*g*/
, ge */
*x*/
, dstr */
*d*/
);
224 /*----- Standard implementations ------------------------------------------*/
226 /* --- @group_stdidentp@ --- *
228 * Arguments: @group *g@ = abstract group
229 * @ge *x@ = group element
231 * Returns: Nonzero if %$x$% is the group identity.
234 extern int group_stdidentp(group */
*g*/
, ge */
*x*/
);
236 /* --- @group_stdcheck@ --- *
238 * Arguments: @group *g@ = abstract group
239 * @grand *gr@ = random number source.
241 * Returns: Null on success, or a pointer to an error message.
244 extern const char *group_stdcheck(group */
*g*/
, grand */
*gr*/
);
246 /* --- @group_stdsqr@ --- *
248 * Arguments: @group *g@ = abstract group
249 * @ge *d@ = destination pointer
250 * @ge *x@ = group element
254 * Use: Computes %$d = x^2$% as %$d = x x$%.
257 extern void group_stdsqr(group */
*g*/
, ge */
*d*/
, ge */
*x*/
);
259 /* --- @group_stddiv@ --- *
261 * Arguments: @group *g@ = abstract group
262 * @ge *d@ = destination pointer
268 * Use: Computes %$d = x/y$% as %$d = x y^{-1}$%.
271 extern void group_stddiv(group */
*g*/
, ge */
*d*/
, ge */
*x*/
, ge */
*y*/
);
273 /* --- @group_stdexp@ --- *
275 * Arguments: @group *g@ = abstract group
276 * @ge *d@ = destination pointer
277 * @ge *x@ = base element
282 * Use: Computes %$d = x^n$% efficiently.
285 extern void group_stdexp(group */
*g*/
, ge */
*d*/
, ge */
*x*/
, mp */
*n*/
);
287 /* --- @group_stdmexp@ --- *
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
296 * Use: Computes %$d = g_0^{x_0} g_1^{x_1} \ldots$% efficiently.
299 extern void group_stdmexp(group */
*g*/
, ge */
*d*/
,
300 const group_expfactor */
*f*/
, size_t /*n*/);
302 /* --- @group_stdtoec@ --- *
304 * Arguments: @group *g@ = abstract group
305 * @ec *d@ = destination point
306 * @ge *x@ = group element
308 * Returns: @-1@, indicating failure.
310 * Use: Fails to convert a group element to an elliptic curve point.
313 extern int group_stdtoec(group */
*g*/
, ec */
*d*/
, ge */
*x*/
);
315 /* --- @group_stdfromec@ --- *
317 * Arguments: @group *g@ = abstract group
318 * @ge *d@ = destination pointer
319 * @ec *p@ = elliptic curve point
321 * Returns: Zero for success, @-1@ on failure.
323 * Use: Converts %$p$% to a group element by converting its %$x$%-
327 extern int group_stdfromec(group */
*g*/
, ge */
*d*/
, ec */
*p*/
);
329 /*----- Prime field subgroups ---------------------------------------------*/
331 typedef struct gprime_param
{
332 mp
*p
, *q
; /* Prime numbers %$p$% and %$q$% */
333 mp
*g
; /* Generates order-%$q$% subgroup */
336 /* --- @group_prime@ --- *
338 * Arguments: @const gprime_param *gp@ = group parameters
340 * Returns: A pointer to the group, or null.
342 * Use: Constructs an abstract group interface for a subgroup of a
343 * prime field. Group elements are @mp *@ pointers.
346 group
*group_prime(const gprime_param */
*gp*/
);
348 /*----- Elliptic curve groups ---------------------------------------------*/
350 /* --- @group_ec@ --- *
352 * Arguments: @const ec_info *ei@ = elliptic curve parameters
354 * Returns: A pointer to the group, or null.
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.
363 group
*group_ec(const ec_info */
*ei*/
);
365 /*----- General group initialization --------------------------------------*/
367 /* --- @group_parse@ --- *
369 * Arguments: @qd_parse *qd@ = quick-and-dirty parser
371 * Returns: Group pointer, or null for failure.
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
379 extern group
*group_parse(qd_parse */
*qd*/
);
381 /* --- @group_fromstring@ --- *
383 * Arguments: @const char *p@ = pointer to string to read
384 * @group **gg@ = where to put the group pointer
386 * Returns: Null if OK, or an error string.
388 * Use: Parses a group spec from a string, and returns the group.
391 extern const char *group_fromstring(const char */
*p*/
, group
**/
*gg*/
);
393 /*----- That's all, folks -------------------------------------------------*/