simple_output &simple_output::nl (void) { space_or_newline(); col += last_word.flush(fp); FPUTC('\n', fp); col = 0; return *this ; }
simple_output &simple_output::check_newline(int n) { if ((col + n + last_word.get_length() + 1 > max_line_length) && (newlines)) { FPUTC('\n', fp); col = last_word.flush(fp); } return *this; }
simple_output &simple_output::space_or_newline (void) { if ((col + last_word.get_length() + 1 > max_line_length) && (newlines)) { FPUTC('\n', fp); if (last_word.get_length() > 0) { col = last_word.flush(fp); } else { col = 0; } } else { if (last_word.get_length() != 0) { if (col > 0) { FPUTC(' ', fp); col++; } col += last_word.flush(fp); } } return *this; }
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; }
mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong, unsigned long * nTries) { mp_digit np; mp_err res; int i = 0; mp_int trial; mp_int q; mp_size num_tests; unsigned char *sieve; ARGCHK(start != 0, MP_BADARG); ARGCHK(nBits > 16, MP_RANGE); sieve = malloc(SIEVE_SIZE); ARGCHK(sieve != NULL, MP_MEM); MP_DIGITS(&trial) = 0; MP_DIGITS(&q) = 0; MP_CHECKOK( mp_init(&trial) ); MP_CHECKOK( mp_init(&q) ); /* values taken from table 4.4, HandBook of Applied Cryptography */ if (nBits >= 1300) { num_tests = 2; } else if (nBits >= 850) { num_tests = 3; } else if (nBits >= 650) { num_tests = 4; } else if (nBits >= 550) { num_tests = 5; } else if (nBits >= 450) { num_tests = 6; } else if (nBits >= 400) { num_tests = 7; } else if (nBits >= 350) { num_tests = 8; } else if (nBits >= 300) { num_tests = 9; } else if (nBits >= 250) { num_tests = 12; } else if (nBits >= 200) { num_tests = 15; } else if (nBits >= 150) { num_tests = 18; } else if (nBits >= 100) { num_tests = 27; } else num_tests = 50; if (strong) --nBits; MP_CHECKOK( mpl_set_bit(start, nBits - 1, 1) ); MP_CHECKOK( mpl_set_bit(start, 0, 1) ); for (i = mpl_significant_bits(start) - 1; i >= nBits; --i) { MP_CHECKOK( mpl_set_bit(start, i, 0) ); } /* start sieveing with prime value of 3. */ MP_CHECKOK(mpp_sieve(start, prime_tab + 1, prime_tab_size - 1, sieve, SIEVE_SIZE) ); #ifdef DEBUG_SIEVE res = 0; for (i = 0; i < SIEVE_SIZE; ++i) { if (!sieve[i]) ++res; } fprintf(stderr,"sieve found %d potential primes.\n", res); #define FPUTC(x,y) fputc(x,y) #else #define FPUTC(x,y) #endif res = MP_NO; for(i = 0; i < SIEVE_SIZE; ++i) { if (sieve[i]) /* this number is composite */ continue; MP_CHECKOK( mp_add_d(start, 2 * i, &trial) ); FPUTC('.', stderr); /* run a Fermat test */ res = mpp_fermat(&trial, 2); if (res != MP_OKAY) { if (res == MP_NO) continue; /* was composite */ goto CLEANUP; } FPUTC('+', stderr); /* If that passed, run some Miller-Rabin tests */ res = mpp_pprime(&trial, num_tests); if (res != MP_OKAY) { if (res == MP_NO) continue; /* was composite */ goto CLEANUP; } FPUTC('!', stderr); if (!strong) break; /* success !! */ /* At this point, we have strong evidence that our candidate is itself prime. If we want a strong prime, we need now to test q = 2p + 1 for primality... */ MP_CHECKOK( mp_mul_2(&trial, &q) ); MP_CHECKOK( mp_add_d(&q, 1, &q) ); /* Test q for small prime divisors ... */ np = prime_tab_size; res = mpp_divis_primes(&q, &np); if (res == MP_YES) { /* is composite */ mp_clear(&q); continue; } if (res != MP_NO) goto CLEANUP; /* And test with Fermat, as with its parent ... */ res = mpp_fermat(&q, 2); if (res != MP_YES) { mp_clear(&q); if (res == MP_NO) continue; /* was composite */ goto CLEANUP; } /* And test with Miller-Rabin, as with its parent ... */ res = mpp_pprime(&q, num_tests); if (res != MP_YES) { mp_clear(&q); if (res == MP_NO) continue; /* was composite */ goto CLEANUP; } /* If it passed, we've got a winner */ mp_exch(&q, &trial); mp_clear(&q); break; } /* end of loop through sieved values */ if (res == MP_YES) mp_exch(&trial, start); CLEANUP: mp_clear(&trial); mp_clear(&q); if (nTries) *nTries += i; if (sieve != NULL) { memset(sieve, 0, SIEVE_SIZE); free (sieve); } return res; }