michael@0: /* michael@0: * Blum, Blum & Shub PRNG using the MPI library michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "bbs_rand.h" michael@0: michael@0: #define SEED 1 michael@0: #define MODULUS 2 michael@0: michael@0: /* This modulus is the product of two randomly generated 512-bit michael@0: prime integers, each of which is congruent to 3 (mod 4). */ michael@0: static char *bbs_modulus = michael@0: "75A2A6E1D27393B86562B9CE7279A8403CB4258A637DAB5233465373E37837383EDC" michael@0: "332282B8575927BC4172CE8C147B4894050EE9D2BDEED355C121037270CA2570D127" michael@0: "7D2390CD1002263326635CC6B259148DE3A1A03201980A925E395E646A5E9164B0EC" michael@0: "28559EBA58C87447245ADD0651EDA507056A1129E3A3E16E903D64B437"; michael@0: michael@0: static int bbs_init = 0; /* flag set when library is initialized */ michael@0: static mp_int bbs_state; /* the current state of the generator */ michael@0: michael@0: /* Suggested size of random seed data */ michael@0: int bbs_seed_size = (sizeof(bbs_modulus) / 2); michael@0: michael@0: void bbs_srand(unsigned char *data, int len) michael@0: { michael@0: if((bbs_init & SEED) == 0) { michael@0: mp_init(&bbs_state); michael@0: bbs_init |= SEED; michael@0: } michael@0: michael@0: mp_read_raw(&bbs_state, (char *)data, len); michael@0: michael@0: } /* end bbs_srand() */ michael@0: michael@0: unsigned int bbs_rand(void) michael@0: { michael@0: static mp_int modulus; michael@0: unsigned int result = 0, ix; michael@0: michael@0: if((bbs_init & MODULUS) == 0) { michael@0: mp_init(&modulus); michael@0: mp_read_radix(&modulus, bbs_modulus, 16); michael@0: bbs_init |= MODULUS; michael@0: } michael@0: michael@0: for(ix = 0; ix < sizeof(unsigned int); ix++) { michael@0: mp_digit d; michael@0: michael@0: mp_sqrmod(&bbs_state, &modulus, &bbs_state); michael@0: d = DIGIT(&bbs_state, 0); michael@0: michael@0: result = (result << CHAR_BIT) | (d & UCHAR_MAX); michael@0: } michael@0: michael@0: return result; michael@0: michael@0: } /* end bbs_rand() */ michael@0: michael@0: /*------------------------------------------------------------------------*/ michael@0: /* HERE THERE BE DRAGONS */