primeiter: New functions for iterating over small primes.
[u/mdw/catacomb] / prim.c
CommitLineData
fcdaa180 1/* -*-c-*-
2 *
b817bfc6 3 * $Id: prim.c,v 1.4 2004/04/08 01:36:15 mdw Exp $
fcdaa180 4 *
5 * Finding primitive elements
6 *
7 * (c) 1999 Straylight/Edgeware
8 */
9
45c0fd36 10/*----- Licensing notice --------------------------------------------------*
fcdaa180 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.
45c0fd36 18 *
fcdaa180 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.
45c0fd36 23 *
fcdaa180 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
fcdaa180 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
43int 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: {
6f80d39f 52 mp *x;
fcdaa180 53 rc = PGEN_FAIL;
54
6f80d39f 55 if (!c->exp)
45c0fd36 56 x = mp_copy(ev->m);
6f80d39f 57 else {
58 x = mpmont_exp(&c->mm, MP_NEW, ev->m, c->exp);
22bab86c 59 if (MP_EQ(x, MP_ONE))
6f80d39f 60 goto done;
61 }
62 if (c->n == 0)
45c0fd36 63 goto ok;
6f80d39f 64 else {
65 size_t n = c->n;
66 mp **f = c->f;
67 mp *y = MP_NEW;
fcdaa180 68 while (n) {
6f80d39f 69 y = mpmont_exp(&c->mm, y, x, *f);
22bab86c 70 if (MP_EQ(y, MP_ONE)) {
6f80d39f 71 mp_drop(y);
fcdaa180 72 goto done;
6f80d39f 73 }
fcdaa180 74 n--; f++;
75 }
6f80d39f 76 mp_drop(y);
fcdaa180 77 }
6f80d39f 78 ok:
fcdaa180 79 rc = PGEN_DONE;
6f80d39f 80 mp_drop(ev->m);
81 ev->m = x;
82 break;
fcdaa180 83 done:
84 mp_drop(x);
85 } break;
86 }
87
88 return (rc);
89}
90
91/* --- Trivial stepping functions -----------------------------------------*/
92
93/* --- @prim_step@ --- */
94
95int 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 -------------------------------------------------*/