int rand_prime(mp_int *N, long len, prng_state *prng, int wprng) { unsigned char buf[260]; int err, step, ormask; _ARGCHK(N != NULL); /* pass a negative size if you want a prime congruent to 3 mod 4 */ if (len < 0) { step = 4; ormask = 3; len = -len; } else { step = 2; ormask = 1; } /* allow sizes between 2 and 256 bytes for a prime size */ if (len < 2 || len > 256) { return CRYPT_INVALID_PRIME_SIZE; } /* valid PRNG? */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } /* read the prng */ if (prng_descriptor[wprng].read(buf+2, (unsigned long)len, prng) != (unsigned long)len) { return CRYPT_ERROR_READPRNG; } /* set sign byte to zero */ buf[0] = (unsigned char)0; /* Set the top byte to 0x01 which makes the number a len*8 bit number */ buf[1] = (unsigned char)0x01; /* set the LSB to the desired settings * (1 for any prime, 3 for primes congruent to 3 mod 4) */ buf[len+1] |= (unsigned char)ormask; /* read the number in */ if (mp_read_raw(N, buf, 2+len) != MP_OKAY) { return CRYPT_MEM; } /* add the step size to it while N is not prime */ if ((err = next_prime(N, step)) != CRYPT_OK) { return err; } #ifdef CLEAN_STACK zeromem(buf, sizeof(buf)); #endif return CRYPT_OK; }
void bbs_srand(unsigned char *data, int len) { if((bbs_init & SEED) == 0) { mp_init(&bbs_state); bbs_init |= SEED; } mp_read_raw(&bbs_state, (char *)data, len); } /* end bbs_srand() */
void rand_num2(mp_int *a) { int n, size; unsigned char buf[2048]; size = 10 + ((fgetc(rng)<<8) + fgetc(rng)) % 101; buf[0] = (fgetc(rng)&1)?1:0; fread(buf+1, 1, size, rng); while (buf[1] == 0) buf[1] = fgetc(rng); mp_read_raw(a, buf, 1+size); }
/* 1-256 bit numbers (to test things like exptmod) */ void rand_num2(mp_int *a) { int n, size; unsigned char buf[2048]; size = 1 + ((fgetc(rng)<<8) + fgetc(rng)) % (FP_MAX_SIZE/16 - DIGIT_BIT/2); buf[0] = (fgetc(rng)&1)?1:0; fread(buf+1, 1, size, rng); while (buf[1] == 0) buf[1] = fgetc(rng); mp_read_raw(a, buf, 1+size); }
void rand_num2(mp_int *a) { int size; unsigned char buf[2048]; size_t sz; size = 10 + ((getRandChar()<<8) + getRandChar()) % 101; buf[0] = (getRandChar()&1)?1:0; #ifdef LTM_MTEST_REAL_RAND sz = fread(buf+1, 1, size, rng); #else sz = 1; while (sz < (unsigned)size) { buf[sz] = getRandChar(); ++sz; } #endif if (sz != (unsigned)size) { fprintf(stderr, "\nWarning: fread failed\n\n"); } while (buf[1] == 0) buf[1] = getRandChar(); mp_read_raw(a, buf, 1+size); }
int main(int argc, char *argv[]) { unsigned char *raw; char *out; unsigned long nTries; int rawlen, bits, outlen, ngen, ix, jx; int g_strong = 0; mp_int testval; mp_err res; clock_t start, end; /* We'll just use the C library's rand() for now, although this won't be good enough for cryptographic purposes */ if((out = PR_GetEnvSecure("SEED")) == NULL) { srand((unsigned int)time(NULL)); } else { srand((unsigned int)atoi(out)); } if(argc < 2) { fprintf(stderr, "Usage: %s <bits> [<count> [strong]]\n", argv[0]); return 1; } if((bits = abs(atoi(argv[1]))) < CHAR_BIT) { fprintf(stderr, "%s: please request at least %d bits.\n", argv[0], CHAR_BIT); return 1; } /* If optional third argument is given, use that as the number of primes to generate; otherwise generate one prime only. */ if(argc < 3) { ngen = 1; } else { ngen = abs(atoi(argv[2])); } /* If fourth argument is given, and is the word "strong", we'll generate strong (Sophie Germain) primes. */ if(argc > 3 && strcmp(argv[3], "strong") == 0) g_strong = 1; /* testval - candidate being tested; nTries - number tried so far */ if ((res = mp_init(&testval)) != MP_OKAY) { fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); return 1; } if(g_strong) { printf("Requested %d strong prime value(s) of %d bits.\n", ngen, bits); } else { printf("Requested %d prime value(s) of %d bits.\n", ngen, bits); } rawlen = (bits / CHAR_BIT) + ((bits % CHAR_BIT) ? 1 : 0) + 1; if((raw = calloc(rawlen, sizeof(unsigned char))) == NULL) { fprintf(stderr, "%s: out of memory, sorry.\n", argv[0]); return 1; } /* This loop is one for each prime we need to generate */ for(jx = 0; jx < ngen; jx++) { raw[0] = 0; /* sign is positive */ /* Pack the initializer with random bytes */ for(ix = 1; ix < rawlen; ix++) raw[ix] = (rand() * rand()) & UCHAR_MAX; raw[1] |= 0x80; /* set high-order bit of test value */ raw[rawlen - 1] |= 1; /* set low-order bit of test value */ /* Make an mp_int out of the initializer */ mp_read_raw(&testval, (char *)raw, rawlen); /* Initialize candidate counter */ nTries = 0; start = clock(); /* time generation for this prime */ do { res = mpp_make_prime(&testval, bits, g_strong, &nTries); if (res != MP_NO) break; /* This code works whether digits are 16 or 32 bits */ res = mp_add_d(&testval, 32 * 1024, &testval); res = mp_add_d(&testval, 32 * 1024, &testval); FPUTC(',', stderr); } while (1); end = clock(); if (res != MP_YES) { break; } FPUTC('\n', stderr); puts("The following value is probably prime:"); outlen = mp_radix_size(&testval, 10); out = calloc(outlen, sizeof(unsigned char)); mp_toradix(&testval, (char *)out, 10); printf("10: %s\n", out); mp_toradix(&testval, (char *)out, 16); printf("16: %s\n\n", out); free(out); printf("Number of candidates tried: %lu\n", nTries); printf("This computation took %ld clock ticks (%.2f seconds)\n", (end - start), ((double)(end - start) / CLOCKS_PER_SEC)); FPUTC('\n', stderr); } /* end of loop to generate all requested primes */ if(res != MP_OKAY) fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); free(raw); mp_clear(&testval); return 0; }