Rearrange the file tree.
[u/mdw/catacomb] / math / group-exp.c
1 /* -*-c-*-
2 *
3 * Exponentiation for abstract groups
4 *
5 * (c) 2004 Straylight/Edgeware
6 */
7
8 /*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of Catacomb.
11 *
12 * Catacomb is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Library General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 * Catacomb is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with Catacomb; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 * MA 02111-1307, USA.
26 */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include "group.h"
31 #include "group-exp.h"
32
33 /*----- Main code ---------------------------------------------------------*/
34
35 /* --- @group_stdexp@ --- *
36 *
37 * Arguments: @group *g@ = abstract group
38 * @ge *d@ = destination pointer
39 * @ge *x@ = base element
40 * @mp *n@ = exponent
41 *
42 * Returns: ---
43 *
44 * Use: Computes %$d = x^n$% efficiently.
45 */
46
47 void group_stdexp(group *gg, ge *d, ge *x, mp *n)
48 {
49 ge *t = G_CREATE(gg);
50
51 G_COPY(gg, t, x);
52 MP_SHRINK(n);
53 G_COPY(gg, d, gg->i);
54 if (n->f & MP_BURN)
55 G_BURN(gg, t);
56 if (MP_ZEROP(n))
57 ;
58 else {
59 if (MP_NEGP(n))
60 G_INV(gg, t, t);
61 if (MP_LEN(n) < EXP_THRESH)
62 EXP_SIMPLE(d, t, n);
63 else
64 EXP_WINDOW(d, t, n);
65 }
66 G_DESTROY(gg, t);
67 }
68
69 /* --- @group_stdmexp@ --- *
70 *
71 * Arguments: @group *g@ = abstract group
72 * @ge *d@ = destination pointer
73 * @const group_expfactor *f@ = vector of factors
74 * @size_t n@ = number of factors
75 *
76 * Returns: ---
77 *
78 * Use: Computes %$d = g_0^{x_0} g_1^{x_1} \ldots$% efficiently.
79 */
80
81 #undef EXP_WINSZ
82 #define EXP_WINSZ 3
83
84 void group_stdmexp(group *gg, ge *d, const group_expfactor *f, size_t n)
85 {
86 group_expfactor *ff = xmalloc(n * sizeof(group_expfactor));
87 size_t i;
88
89 for (i = 0; i < n; i++) {
90 ff[i].base = G_CREATE(gg);
91 MP_SHRINK(f[i].exp);
92 if (MP_NEGP(f[i].exp))
93 G_INV(gg, ff[i].base, f[i].base);
94 else
95 G_COPY(gg, ff[i].base, f[i].base);
96 if (f[i].exp->f & MP_BURN)
97 G_BURN(gg, ff[i].base);
98 ff[i].exp = f[i].exp;
99 }
100 G_COPY(gg, d, gg->i);
101 EXP_SIMUL(d, ff, n);
102 for (i = 0; i < n; i++)
103 G_DESTROY(gg, ff[i].base);
104 xfree(ff);
105 }
106
107 /*----- That's all, folks -------------------------------------------------*/