Find `safe' primes (i.e., %$p = 2q + 1$%).
[u/mdw/catacomb] / pgen-safe.c
CommitLineData
1c42b462 1/* -*-c-*-
2 *
3 * $Id: pgen-safe.c,v 1.1 1999/12/22 16:01:34 mdw Exp $
4 *
5 * Safe prime generation
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/*----- Revision history --------------------------------------------------*
31 *
32 * $Log: pgen-safe.c,v $
33 * Revision 1.1 1999/12/22 16:01:34 mdw
34 * Find `safe' primes (i.e., %$p = 2q + 1$%).
35 *
36 */
37
38/*----- Header files ------------------------------------------------------*/
39
40#include "mp.h"
41#include "mprand.h"
42#include "pgen.h"
43
44/*----- Main code ---------------------------------------------------------*/
45
46/* --- @pgen_safestep@ --- *
47 *
48 * Steps two numbers, %$q$% and %$p = 2q + 1$%, such that neither has any
49 * small factors. %$p$% is put in the event block.
50 */
51
52int pgen_safestep(int rq, pgen_event *ev, void *p)
53{
54 pgen_safestepctx *c = p;
55 int prc = PGEN_ABORT, qrc;
56
57 switch (rq) {
58 case PGEN_BEGIN: {
59 mp *p = mp_split(MP_COPY(ev->m));
60 mp *q;
61 p->v[0] |= 3;
62 q = mp_lsr(MP_NEW, p, 1);
63 qrc = pfilt_create(&c->q, q);
64 prc = pfilt_create(&c->p, p);
65 mp_drop(p);
66 mp_drop(q);
67 } goto step;
68 case PGEN_TRY:
69 again:
70 qrc = pfilt_step(&c->q, 2);
71 prc = pfilt_step(&c->p, 4);
72 step:
73 if (qrc == PGEN_FAIL || prc == PGEN_FAIL)
74 goto again;
75 mp_drop(ev->m);
76 ev->m = MP_COPY(c->p.m);
77 if (qrc == PGEN_TRY)
78 prc = PGEN_TRY;
79 break;
80 case PGEN_DONE:
81 pfilt_destroy(&c->q);
82 pfilt_destroy(&c->p);
83 break;
84 }
85 return (prc);
86}
87
88/* --- @pgen_safetest@ --- *
89 *
90 * Applies Rabin-Miller tests to %$p$% and %$q$%.
91 */
92
93int pgen_safetest(int rq, pgen_event *ev, void *p)
94{
95 pgen_safetestctx *c = p;
96 int rc = PGEN_ABORT;
97
98 switch (rq) {
99 case PGEN_BEGIN:
100 rabin_create(&c->q, c->c.q.m);
101 rabin_create(&c->p, c->c.p.m);
102 rc = PGEN_TRY;
103 break;
104 case PGEN_TRY: {
105 mp *m = mprand_range(MP_NEW, c->c.q.m, ev->r, 0);
106 rc = rabin_test(&c->p, m);
107 if (rc == PGEN_PASS)
108 rc = rabin_test(&c->q, m);
109 mp_drop(m);
110 } break;
111 case PGEN_DONE:
112 rabin_destroy(&c->q);
113 rabin_destroy(&c->p);
114 break;
115 }
116 return (rc);
117}
118
119/*----- That's all, folks -------------------------------------------------*/