chiark / gitweb /
Merge branch '2.4.x' into 2.5.x
[catacomb] / pub / bbs.h
1 /* -*-c-*-
2  *
3  * The Blum-Blum-Shub random bit generator
4  *
5  * (c) 1999 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 /*----- Notes on the BBS generator ----------------------------------------*
29  *
30  * The Blum-Blum-Shub generator takes the least significant bits from the
31  * sequence %$x_i = x_{i - 1}^2 \bmod n$%, where %$n = pq$% is the product of
32  * two primes %$p$% and %$q$%, each of which are congruent to %$3 \bmod 4$%.
33  * For maximum period of the generator, %$(p - 1)/2$% and %$(q - 1)/1$%
34  * should be coprime.  It is safe to use the least significant
35  * %$\log \log n$% bits of each step in the sequence -- an adversary must
36  * factor the modulus before being able to work forwards or backwards.  The
37  * output of the generator cannot be distinguished from a (uniform,
38  * independent) random sequence of bits using any polynomial-time test.  This
39  * is by far the strongest pseudorandom number generator provided in
40  * Catacomb, and by far the slowest too.  For normal use, the standard
41  * Catacomb @rand@ generator should be more than adequate.
42  */
43
44 #ifndef CATACOMB_BBS_H
45 #define CATACOMB_BBS_H
46
47 #ifdef __cplusplus
48   extern "C" {
49 #endif
50
51 /*----- Header files ------------------------------------------------------*/
52
53 #include <mLib/bits.h>
54
55 #ifndef CATACOMB_GRAND_H
56 #  include "grand.h"
57 #endif
58
59 #ifndef CATACOMB_KEY_H
60 #  include "key.h"
61 #endif
62
63 #ifndef CATACOMB_MP_H
64 #  include "mp.h"
65 #endif
66
67 #ifndef CATACOMB_MPBARRETT_H
68 #  include "mpbarrett.h"
69 #endif
70
71 #ifndef CATACOMB_PGEN_H
72 #  include "pgen.h"
73 #endif
74
75 /*----- Data structures ---------------------------------------------------*/
76
77 /* --- Basic generator state --- */
78
79 typedef struct bbs {
80   mpbarrett mb;                         /* Barrett reduction context */
81   mp *x;                                /* Current quadratic residue */
82   unsigned k;                           /* Number of bits from each step */
83   unsigned b;                           /* Number of bits in reservoir */
84   mpw r;                                /* Reservoir of output bits */
85 } bbs;
86
87 /* --- Parameters --- */
88
89 typedef struct bbs_pub {
90   mp *n;
91 } bbs_pub;
92
93 typedef struct bbs_priv {
94   mp *p, *q;                            /* Prime factors (3 mod 4) */
95   mp *n;                                /* Product @pq@ -- a Blum integer */
96 } bbs_priv;
97
98 /*----- Key fetching ------------------------------------------------------*/
99
100 extern const key_fetchdef bbs_pubfetch[];
101 #define BBS_PUBFETCHSZ 3
102
103 extern const key_fetchdef bbs_privfetch[];
104 #define BBS_PRIVFETCHSZ 7
105
106 /* --- @bbs_pubfree@, @bbs_privfree@ --- *
107  *
108  * Arguments:   @bbs_pub *bp@, @bbs_priv *bp@ = pointer to key block
109  *
110  * Returns:     ---
111  *
112  * Use:         Frees a BBS key block.
113  */
114
115 extern void bbs_pubfree(bbs_pub */*bp*/);
116 extern void bbs_privfree(bbs_priv */*bp*/);
117
118 /*----- The basic generator -----------------------------------------------*/
119
120 /* --- @bbs_create@ --- *
121  *
122  * Arguments:   @bbs *b@ = pointer to BBS generator state to initialize
123  *              @mp *m@ = modulus (must be a Blum integer)
124  *              @mp *x@ = initial seed for generator
125  *
126  * Returns:     ---
127  *
128  * Use:         Initializes a BBS generator.  The generator is stepped once
129  *              after initialization, as for @bbs_seed@.
130  */
131
132 extern void bbs_create(bbs */*b*/, mp */*m*/, mp */*x*/);
133
134 /* --- @bbs_destroy@ --- *
135  *
136  * Arguments:   @bbs *b@ = pointer to BBS generator state
137  *
138  * Returns:     ---
139  *
140  * Use:         Destroys a generator state when it's no longer wanted.
141  */
142
143 extern void bbs_destroy(bbs */*b*/);
144
145 /* --- @bbs_step@ --- *
146  *
147  * Arguments:   @bbs *b@ = pointer to BBS generator state
148  *
149  * Returns:     ---
150  *
151  * Use:         Steps the generator once.  This isn't too useful in client
152  *              code.
153  */
154
155 extern void bbs_step(bbs */*b*/);
156
157 /* --- @bbs_set@ --- *
158  *
159  * Arguments:   @bbs *b@ = pointer to BBS generator state
160  *              @mp *x@ = new residue to set
161  *
162  * Returns:     ---
163  *
164  * Use:         Sets a new quadratic residue.  The generator is stepped once.
165  */
166
167 extern void bbs_set(bbs */*b*/, mp */*x*/);
168
169 /* --- @bbs_seed@ --- *
170  *
171  * Arguments:   @bbs *b@ = pointer to BBS generator state
172  *              @mp *x@ = new seed to set
173  *
174  * Returns      ---
175  *
176  * Use:         Sets a new seed.  The generator is stepped until the residue
177  *              has clearly wrapped around.
178  */
179
180 extern void bbs_seed(bbs */*b*/, mp */*x*/);
181
182 /* --- @bbs_bits@ --- *
183  *
184  * Arguments:   @bbs *b@ = pointer to BBS generator state
185  *              @unsigned bits@ = number of bits wanted
186  *
187  * Returns:     Bits extracted from the BBS generator.
188  *
189  * Use:         Extracts a requested number of bits from the BBS generator.
190  */
191
192 extern uint32 bbs_bits(bbs */*b*/, unsigned /*bits*/);
193
194 /* --- @bbs_wrap@ --- *
195  *
196  * Arguments:   @bbs *b@ = pointer to BBS generator state
197  *
198  * Returns:     ---
199  *
200  * Use:         Steps the generator if any of the reservoir bits are used.
201  *              This can be used to `wrap up' after a Blum-Goldwasser
202  *              encryption, for example, producing the final value to be sent
203  *              along with the ciphertext.
204  *
205  *              If a generator is seeded, %$b$% bits are extracted, and then
206  *              @bbs_wrap@ is called, the generator will have been stepped
207  *              %$\lceil b/k \rceil$% times.
208  */
209
210 extern void bbs_wrap(bbs */*b*/);
211
212 /*----- Large forwards and backwards jumps --------------------------------*/
213
214 /* --- @bbs_{ff,rew}{,n}@ --- *
215  *
216  * Arguments:   @bbs *b@ = pointer to a BBS generator state
217  *              @const bbs_priv *bp@ = pointer to BBS modulus factors
218  *              @mp *n@, @unsigned long n@ = number of steps to make
219  *
220  * Returns:     ---
221  *
222  * Use:         `Fast-forwards' or rewinds a Blum-Blum-Shub generator by @n@
223  *              steps.  The @...n@ versions take an @unsigned long@ argument;
224  *              the non-@...n@ versions a multiprecision integer.  If @n@ is
225  *              negative then the generator is stepped in the reverse
226  *              direction.
227  */
228
229 extern void bbs_ff(bbs */*b*/, const bbs_priv */*bp*/, mp */*n*/);
230 extern void bbs_ffn(bbs */*b*/, const bbs_priv */*bp*/, unsigned long /*n*/);
231 extern void bbs_rew(bbs */*b*/, const bbs_priv */*bp*/, mp */*n*/);
232 extern void bbs_rewn(bbs */*b*/, const bbs_priv */*bp*/, unsigned long /*n*/);
233
234 /*----- Parameter generation ----------------------------------------------*/
235
236 /* --- @bbs_gen@ --- *
237  *
238  * Arguments:   @bbs_priv *bp@ = pointer to parameter block
239  *              @unsigned nbits@ = number of bits in the modulus
240  *              @grand *r@ = pointer to random number source
241  *              @unsigned n@ = number of attempts to make
242  *              @pgen_proc *event@ = event handler function
243  *              @void *ectx@ = argument for event handler
244  *
245  * Returns:     If it worked OK, @PGEN_DONE@, otherwise @PGEN_ABORT@.
246  *
247  * Use:         Finds two prime numbers %$p'$% and %$q'$% such that both are
248  *              congruent to %$3 \bmod 4$%, and  $(p - 1)/2$% and
249  *              %$(q - 1)/2$% have no common factors.  The product %$n = pq$%
250  *              is eminently suitable for use as a modulus in a Blum-Blum-
251  *              Shub pseudorandom bit generator.
252  */
253
254 extern int bbs_gen(bbs_priv */*bp*/, unsigned /*nbits*/, grand */*r*/,
255                    unsigned /*n*/, pgen_proc */*event*/, void */*ectx*/);
256
257 /*----- Generic random number generator interface -------------------------*/
258
259 /* --- @bbs_rand@ --- *
260  *
261  * Arguments:   @mp *m@ = modulus
262  *              @mp *x@ = initial seed
263  *
264  * Returns:     Pointer to a generic generator.
265  *
266  * Use:         Constructs a generic generator interface over a
267  *              Blum-Blum-Shub generator.
268  */
269
270 extern grand *bbs_rand(mp */*m*/, mp */*x*/);
271
272 /* --- Blum-Blum-Shub-specific misc op codes --- */
273
274 enum {
275   BBS_SET = GRAND_SPECIFIC('B'),        /* @mp *x@ */
276   BBS_STEP,                             /* @void@ */
277   BBS_STEPSZ,                           /* @void@ */
278   BBS_BITS,                             /* @unsigned bits, uint32 *w@ */
279   BBS_WRAP,                             /* @void@ */
280   BBS_FF,                               /* @bbs_priv *p, mp *n@ */
281   BBS_FFN,                              /* @bbs_priv *p, unsigned long n@ */
282   BBS_REW,                              /* @bbs_priv *p, mp *n@ */
283   BBS_REWN,                             /* @bbs_priv *p, unsigned long n@ */
284   BBS_MOD,                              /* @mp **n@ */
285   BBS_STATE                             /* @mp **x@ */
286 };
287
288 /*----- That's all, folks -------------------------------------------------*/
289
290 #ifdef __cplusplus
291   }
292 #endif
293
294 #endif