Add cyclic group abstraction, with test code. Separate off exponentation
[u/mdw/catacomb] / group-stdops.c
CommitLineData
34e4f738 1/* -*-c-*-
2 *
3 * $Id: group-stdops.c,v 1.1 2004/04/01 12:50:09 mdw Exp $
4 *
5 * Standard group operations
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-stdops.c,v $
33 * Revision 1.1 2004/04/01 12:50:09 mdw
34 * Add cyclic group abstraction, with test code. Separate off exponentation
35 * functions for better static linking. Fix a buttload of bugs on the way.
36 * Generally ensure that negative exponents do inversion correctly. Add
37 * table of standard prime-field subgroups. (Binary field subgroups are
38 * currently unimplemented but easy to add if anyone ever finds a good one.)
39 *
40 */
41
42/*----- Header files ------------------------------------------------------*/
43
44#include "group.h"
45#include "pgen.h"
46
47/*----- Handy functions ---------------------------------------------------*/
48
49/* --- @group_check@ --- *
50 *
51 * Arguments: @group *g@ = an abstract group
52 * @ge *x@ = a group element
53 *
54 * Returns: Zero on success, nonzero for failure.
55 *
56 * Use: Checks that @x@ is a valid group element. This may take a
57 * while, since it checks that %$x^h \ne 1$% and %$x^r = 1$%.
58 */
59
60int group_check(group *g, ge *x)
61{
62 ge *d = G_CREATE(g);
63 int rc;
64
65 G_EXP(g, d, x, g->h); rc = !G_IDENTP(g, d);
66 if (rc) { G_EXP(g, d, x, g->r); rc = G_IDENTP(g, d); }
67 G_DESTROY(g, d);
68 if (!rc) return (-1);
69 return (0);
70}
71
72/* --- @group_samep@ --- *
73 *
74 * Arguments: @group *g, *h@ = two abstract groups
75 *
76 * Returns: Nonzero if the groups are in fact identical (not just
77 * isomorphic).
78 *
79 * Use: Checks to see whether two groups are actually the same. This
80 * function does the full check: the group operatrion @samep@
81 * just does the group-specific details.
82 */
83
84int group_samep(group *g, group *h)
85{
86 return (g->ops == h->ops &&
87 MP_EQ(g->r, h->r) && MP_EQ(g->h, h->h) &&
88 G_EQ(g, g->i, h->i) && G_EQ(g, g->g, h->g) &&
89 G_SAMEP(g, h));
90}
91
92/*----- Standard implementations ------------------------------------------*/
93
94/* --- @group_stdidentp@ --- *
95 *
96 * Arguments: @group *g@ = abstract group
97 * @ge *x@ = group element
98 *
99 * Returns: Nonzero if %$x$% is the group identity.
100 */
101
102int group_stdidentp(group *g, ge *x) { return (G_EQ(g, x, g->i)); }
103
104/* --- @group_stdsqr@ --- *
105 *
106 * Arguments: @group *g@ = abstract group
107 * @ge *d@ = destination pointer
108 * @ge *x@ = group element
109 *
110 * Returns: ---
111 *
112 * Use: Computes %$d = x^2$% as %$d = x x$%.
113 */
114
115void group_stdsqr(group *g, ge *d, ge *x) { G_MUL(g, d, x, x); }
116
117/* --- @group_stddiv@ --- *
118 *
119 * Arguments: @group *g@ = abstract group
120 * @ge *d@ = destination pointer
121 * @ge *x@ = dividend
122 * @ge *y@ = divisor
123 *
124 * Returns: ---
125 *
126 * Use: Computes %$d = x/y$% as %$d = x y^{-1}$%.
127 */
128
129void group_stddiv(group *g, ge *d, ge *x, ge *y)
130{
131 G_INV(g, d, y);
132 G_MUL(g, d, x, d);
133}
134
135/* --- @group_stdtoec@ --- *
136 *
137 * Arguments: @group *g@ = abstract group
138 * @ec *d@ = destination point
139 * @ge *x@ = group element
140 *
141 * Returns: @-1@, indicating failure.
142 *
143 * Use: Fails to convert a group element to an elliptic curve point.
144 */
145
146int group_stdtoec(group *g, ec *d, ge *x) { return (-1); }
147
148/* --- @group_stdfromec@ --- *
149 *
150 * Arguments: @group *g@ = abstract group
151 * @ge *d@ = destination pointer
152 * @ec *p@ = elliptic curve point
153 *
154 * Returns: Zero for success, @-1@ on failure.
155 *
156 * Use: Converts %$p$% to a group element by converting its %$x$%-
157 * coordinate.
158 */
159
160int group_stdfromec(group *g, ge *d, ec *p)
161 { if (EC_ATINF(p)) return (-1); return (G_FROMINT(g, d, p->x)); }
162
163/* --- @group_stdcheck@ --- *
164 *
165 * Arguments: @group *g@ = abstract group
166 * @grand *gr@ = random number source.
167 *
168 * Returns: Null on success, or a pointer to an error message.
169 */
170
171const char *group_stdcheck(group *g, grand *gr)
172{
173 ge *t;
174 int rc;
175
176 if (!pgen_primep(g->r, gr)) return ("group order not prime");
177 t = G_CREATE(g); G_EXP(g, t, g->g, g->r);
178 rc = G_IDENTP(g, t); G_DESTROY(g, t);
179 if (!rc) return ("generator not in the group");
180 return (0);
181}
182
183/*----- That's all, folks -------------------------------------------------*/