Commit | Line | Data |
---|---|---|
2c52abe6 | 1 | /* -*-c-*- |
2c52abe6 | 2 | * |
3 | * Generate Blum integers | |
4 | * | |
5 | * (c) 1999 Straylight/Edgeware | |
6 | */ | |
7 | ||
45c0fd36 | 8 | /*----- Licensing notice --------------------------------------------------* |
2c52abe6 | 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. | |
45c0fd36 | 16 | * |
2c52abe6 | 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. | |
45c0fd36 | 21 | * |
2c52abe6 | 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 | ||
2c52abe6 | 28 | /*----- Header files ------------------------------------------------------*/ |
29 | ||
30 | #include <stdio.h> | |
31 | #include <stdlib.h> | |
32 | #include <string.h> | |
33 | ||
34 | #include "bbs.h" | |
2c52abe6 | 35 | #include "mp.h" |
36 | #include "mprand.h" | |
37 | #include "pgen.h" | |
052b36d0 | 38 | #include "strongprime.h" |
b04a7659 | 39 | |
2c52abe6 | 40 | /*----- Main code ---------------------------------------------------------*/ |
41 | ||
42 | /* --- @bbs_gen@ --- * | |
43 | * | |
a22bbdf6 | 44 | * Arguments: @bbs_priv *bp@ = pointer to parameter block |
052b36d0 | 45 | * @unsigned nbits@ = number of bits in the modulus |
46 | * @grand *r@ = pointer to random number source | |
47 | * @unsigned n@ = number of attempts to make | |
b04a7659 | 48 | * @pgen_proc *event@ = event handler function |
49 | * @void *ectx@ = argument for event handler | |
2c52abe6 | 50 | * |
b04a7659 | 51 | * Returns: If it worked OK, @PGEN_DONE@, otherwise @PGEN_ABORT@. |
2c52abe6 | 52 | * |
53 | * Use: Finds two prime numbers %$p'$% and %$q'$% such that both are | |
45c0fd36 | 54 | * congruent to %$3 \bmod 4$%, and $(p - 1)/2$% and |
2c52abe6 | 55 | * %$(q - 1)/2$% have no common factors. The product %$n = pq$% |
56 | * is eminently suitable for use as a modulus in a Blum-Blum- | |
57 | * Shub pseudorandom bit generator. | |
58 | */ | |
59 | ||
a22bbdf6 | 60 | int bbs_gen(bbs_priv *bp, unsigned nbits, grand *r, unsigned n, |
b04a7659 | 61 | pgen_proc *event, void *ectx) |
2c52abe6 | 62 | { |
052b36d0 | 63 | rabin rb; |
cda5fe55 MW |
64 | pfilt jp; |
65 | pgen_jumpctx j; | |
02b1cf93 | 66 | pgen_gcdstepctx g; |
052b36d0 | 67 | unsigned nb = nbits/2; |
3161ce63 | 68 | mp *x = MP_NEWSEC, *t = MP_NEW; |
2c52abe6 | 69 | |
b04a7659 | 70 | /* --- Generate @p@ --- */ |
2c52abe6 | 71 | |
cda5fe55 | 72 | if ((x = strongprime_setup("p", x, &jp, nb, r, n, event, ectx)) == 0) |
052b36d0 | 73 | goto fail_x; |
cda5fe55 | 74 | j.j = &jp; |
01f3ef93 | 75 | bp->p = pgen("p", MP_NEWSEC, x, event, ectx, n, pgen_jump, &j, |
052b36d0 | 76 | rabin_iters(nb), pgen_test, &rb); |
cda5fe55 | 77 | pfilt_destroy(&jp); |
285bf989 | 78 | if (!bp->p) goto fail_p; |
2c52abe6 | 79 | |
b04a7659 | 80 | /* --- Generate @q@ --- */ |
2c52abe6 | 81 | |
052b36d0 | 82 | nb = nbits - nb; |
83 | if ((x = strongprime_setup("q", x, &g.jp, nb, r, n, event, ectx)) == 0) | |
84 | goto fail_q; | |
02b1cf93 | 85 | if ((x->v[0] & 3) != 3) |
86 | x = mp_add(x, x, g.jp.m); | |
87 | pfilt_muladd(&g.jp, &g.jp, 2, 0); | |
b04a7659 | 88 | g.r = mp_lsr(MP_NEW, bp->p, 1); |
02b1cf93 | 89 | g.g = MP_NEW; |
90 | g.max = MP_ONE; | |
3161ce63 MW |
91 | t = mp_lsl(t, MP_ONE, nbits - 1); |
92 | mp_div(&t, 0, t, bp->p); | |
93 | if (MP_CMP(x, <, t)) x = mp_leastcongruent(x, t, x, g.jp.m); | |
01f3ef93 | 94 | bp->q = pgen("q", MP_NEWSEC, x, event, ectx, n, pgen_gcdstep, &g, |
052b36d0 | 95 | rabin_iters(nb), pgen_test, &rb); |
96 | pfilt_destroy(&g.jp); | |
97 | mp_drop(g.r); | |
02b1cf93 | 98 | mp_drop(g.g); |
3161ce63 | 99 | mp_drop(t); |
285bf989 | 100 | if (!bp->q) goto fail_q; |
2c52abe6 | 101 | |
b04a7659 | 102 | /* --- Compute @n@ --- */ |
2c52abe6 | 103 | |
b04a7659 | 104 | bp->n = mp_mul(MP_NEW, bp->p, bp->q); |
998e6c3d | 105 | if (mp_bits(bp->n) != nbits) goto fail_n; |
052b36d0 | 106 | mp_drop(x); |
b04a7659 | 107 | return (PGEN_DONE); |
2c52abe6 | 108 | |
b04a7659 | 109 | /* --- Tidy up if things went wrong --- */ |
2c52abe6 | 110 | |
998e6c3d MW |
111 | fail_n: |
112 | mp_drop(bp->n); | |
b04a7659 | 113 | fail_q: |
b04a7659 | 114 | mp_drop(bp->p); |
115 | fail_p: | |
052b36d0 | 116 | mp_drop(x); |
117 | fail_x: | |
b04a7659 | 118 | return (PGEN_ABORT); |
2c52abe6 | 119 | } |
120 | ||
121 | /*----- That's all, folks -------------------------------------------------*/ |