Blog literacki, portal erotyczny - seks i humor nie z tej ziemi
/*
Author: Pate Williams (c) 1997
The following program implements and tests the
Blum-Blum-Shub random bits generator. The test
suite is according to FIPS 140-1. See "Handbook
of Applied Cryptography" by Alfred J. Menezes
et al Section 5.4.4 pages 181 - 183 and 5.40
Algorithm page 186.
*/
#include
#include
#include
#include "lip.h"
#define BIT_STRING_LENGTH 20000l
#define MONOBIT_LO 9654l
#define MONOBIT_HI 10346l
#define POKER_LO 1.03
#define POKER_HI 57.4
void bbs_gen_key(long bit_length, verylong *zn, verylong *zx0)
/* generates the key and seed for the Blum-Blum-Shub
random bits generator */
{
long length = bit_length / 2;
verylong zp = 0, zq = 0, zs = 0;
zrstarts(time(NULL));
zrandomprime(- length, 5l, &zp, zrandomb);
zrandomprime(- length, 5l, &zq, zrandomb);
zmul(zp, zq, zn);
do zrandomb(*zn, &zs); while (zscompare(zs, 0l) == 0);
zmulmod(zs, zs, *zn, zx0);
zfree(&zp);
zfree(&zq);
zfree(&zs);
}
long bbs_next_bits(long number, verylong zn, verylong *zx)
/* gets number low order bits of x * x mod n */
{
long low_bits;
verylong zx0 = 0;
zcopy(*zx, &zx0);
zmulmod(zx0, zx0, zn, zx);
zlowbits(*zx, number, &zx0);
low_bits = zx0[1];
zfree(&zx0);
return low_bits;
}
int FIPS_140_1(char *bit_string)
/* Statistical tests for randomness returns - 3
if bit_string fails monobit test, - 2 if it
fails poker test, - 1 if it fails runs test,
0 if it fails the long run test 1 otherwise */
{
float X3, sum = 0.0;
long B[6]= {0}, G[6] = {0}, n[16] = {0};
long i, index, j, k, max_run = 0, n1 = 0;
long interval_lo[6] = {2267, 1079, 502, 223, 90, 90};
long interval_hi[6] = {2733, 1421, 748, 402, 223, 223};
/* monobit test */
for (i = 0; i < BIT_STRING_LENGTH; i++)
if (bit_string[i] == 1) n1++;
/* poker test */
i = 0;
k = BIT_STRING_LENGTH / 4;
for (j = 0; j < k; j++) {
index = 8 * bit_string[i + 3] + 4 * bit_string[i + 2]
+ 2 * bit_string[i + 1] + bit_string[i];
n[index]++;
i += 4;
}
for (i = 0; i < 16; i++) sum += n[i] * n[i];
X3 = 16.0 * sum / k - k;
/* runs test */
i = 0;
while (i < BIT_STRING_LENGTH) {
j = 0;
while (i < BIT_STRING_LENGTH && bit_string[i] == 1) i++, j++;
if (j <= 6) B[j - 1]++; else B[5]++;
if (j > max_run) max_run = j;
while (i < BIT_STRING_LENGTH && bit_string[i] == 0) i++;
}
i = 0;
while (i < BIT_STRING_LENGTH) {
j = 0;
while (i < BIT_STRING_LENGTH && bit_string[i] == 0) i++, j++;
if (j <= 6) G[j - 1]++; else G[5]++;
if (j > max_run) max_run = j;
while (i < BIT_STRING_LENGTH && bit_string[i] == 1) i++;
}
/* print out results of the tests */
printf("monobit statistic: %ld\n", n1);
printf("poker test statistic: %lf\n", X3);
printf("# blocks\tgaps\n");
for (i = 0; i < 6; i++)
printf("%ld %4ld\t\t%4ld\n", i + 1, B[i], G[i]);
printf("long runs statistic: %ld\n", max_run);
/* compute return value based on statistics */
if (n1 <= MONOBIT_LO || n1 >= MONOBIT_HI) return - 3;
if (X3 <= POKER_LO || X3 >= POKER_HI) return - 2;
for (i = 0; i < 6; i++) {
if (B[i] < interval_lo[i] || B[i] > interval_hi[i]) return - 1;
if (G[i] < interval_lo[i] || G[i] > interval_hi[i]) return - 1;
}
if (max_run >= 34) return 0;
return 1;
}
int main(void)
{
char bit_string[BIT_STRING_LENGTH];
long i;
verylong zn = 0, zx0 = 0;
/* fill the buffer to be tested */
bbs_gen_key(256l, &zn, &zx0);
for (i = 0; i < BIT_STRING_LENGTH; i++)
bit_string[i] = (char) bbs_next_bits(1l, zn, &zx0);
printf("value of FIPS_140_1 = %d\n", FIPS_140_1(bit_string));
zfree(&zn);
zfree(&zx0);
return 0;
}