Use auto-version machinery for building.
[u/mdw/catacomb] / prim.c
1 /* -*-c-*-
2 *
3 * $Id: prim.c,v 1.4 2004/04/08 01:36:15 mdw Exp $
4 *
5 * Finding primitive elements
6 *
7 * (c) 1999 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 /*----- Header files ------------------------------------------------------*/
31
32 #include "mp.h"
33 #include "mpint.h"
34 #include "mpmont.h"
35 #include "mprand.h"
36 #include "pgen.h"
37 #include "prim.h"
38
39 /*----- Main code ---------------------------------------------------------*/
40
41 /* --- @prim_test@ --- */
42
43 int prim_test(int rq, pgen_event *ev, void *p)
44 {
45 prim_ctx *c = p;
46 int rc = rq;
47
48 switch (rq) {
49 case PGEN_BEGIN:
50 return (PGEN_TRY);
51 case PGEN_TRY: {
52 mp *x;
53 rc = PGEN_FAIL;
54
55 if (!c->exp)
56 x = mp_copy(ev->m);
57 else {
58 x = mpmont_exp(&c->mm, MP_NEW, ev->m, c->exp);
59 if (MP_EQ(x, MP_ONE))
60 goto done;
61 }
62 if (c->n == 0)
63 goto ok;
64 else {
65 size_t n = c->n;
66 mp **f = c->f;
67 mp *y = MP_NEW;
68 while (n) {
69 y = mpmont_exp(&c->mm, y, x, *f);
70 if (MP_EQ(y, MP_ONE)) {
71 mp_drop(y);
72 goto done;
73 }
74 n--; f++;
75 }
76 mp_drop(y);
77 }
78 ok:
79 rc = PGEN_DONE;
80 mp_drop(ev->m);
81 ev->m = x;
82 break;
83 done:
84 mp_drop(x);
85 } break;
86 }
87
88 return (rc);
89 }
90
91 /* --- Trivial stepping functions -----------------------------------------*/
92
93 /* --- @prim_step@ --- */
94
95 int prim_step(int rq, pgen_event *ev, void *p)
96 {
97 unsigned *i = p;
98 switch (rq) {
99 case PGEN_BEGIN:
100 case PGEN_TRY:
101 if (*i >= NPRIME)
102 return PGEN_FAIL;
103 ev->m = mp_fromint(ev->m, primetab[(*i)++]);
104 return (PGEN_TRY);
105 }
106 return (0);
107 }
108
109 /*----- That's all, folks -------------------------------------------------*/