int rand_prime(mp_int *N, long len, prng_state *prng, int wprng) { struct rng_data rng; int type, err; LTC_ARGCHK(N != NULL); /* allow sizes between 2 and 256 bytes for a prime size */ if (len < 16 || len > 4096) { return CRYPT_INVALID_PRIME_SIZE; } /* valid PRNG? Better be! */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } /* setup our callback data, then world domination! */ rng.prng = prng; rng.wprng = wprng; /* get type */ if (len < 0) { type = LTM_PRIME_BBS; len = -len; } else { type = 0; } type |= LTM_PRIME_2MSB_ON; /* New prime generation makes the code even more cryptoish-insane. Do you know what this means!!! -- Gir: Yeah, oh wait, er, no. */ return mpi_to_ltc_error(mp_prime_random_ex(N, mp_prime_rabin_miller_trials(len), len, type, rand_prime_helper, &rng)); }
static int rand_prime(mp_int *N, long len) { int type; /* get type */ if (len < 0) { type = LTM_PRIME_BBS; len = -len; } else { /* This seems to be what MS CSP's do: */ type = LTM_PRIME_2MSB_ON; /* Original LibTomCrypt: type = 0; */ } /* allow sizes between 2 and 256 bytes for a prime size */ if (len < 16 || len > 8192) { printf("Invalid prime size!\n"); return CRYPT_INVALID_PRIME_SIZE; } /* New prime generation makes the code even more cryptoish-insane. Do you know what this means!!! -- Gir: Yeah, oh wait, er, no. */ return mpi_to_ltc_error(mp_prime_random_ex(N, mp_prime_rabin_miller_trials(len), len, type, rand_prime_helper, NULL)); }
lnc_key_t *lnc_gen_key(const size_t size, int *status) { mp_int small_prime, random, mul, s, tmp; mp_int modulus, root, public_key, secret_key; int test_small, test_full; uint32_t smallsize = lnc_suggest_subgroup(size); int ret; lnc_key_t *out; if(size > UINT_MAX) { *status = LNC_ERR_OVER; return NULL; } test_small = mp_prime_rabin_miller_trials((int)smallsize); test_full = mp_prime_rabin_miller_trials((int)size); if((ret = mp_init_multi(&small_prime, &random, &mul, &s, &tmp, &modulus, &root, &secret_key, &public_key, NULL)) != MP_OKAY) { *status = LNC_ERR_LTM; return NULL; } /* * The modulus is created in the form p = q * r + 1. This aids * in finding g and guarantees a large prime factor (q) in the * order of the group. I the order of the group contains only * small prime factors, the key can be attacked easily. */ printf("libnetcrypt: Generating small prime (%d bits)...\n", smallsize); mp_prime_random_ex(&small_prime, test_small, smallsize, 0, lnc_fill_random, NULL); printf("libnetcrypt: Generating modulus... (%d bits)\n", size); do { do { mp_random(&random, size - smallsize); } while(mp_cmp_d(&random, 0) == MP_EQ); mp_mul(&small_prime, &random, &mul); mp_add1(&mul, &modulus); mp_prime_is_prime(&modulus, test_full, &ret); } while(!ret); /* Specified in FIPS 186-4 A.2.1 */ printf("libnetcrypt: Generating generator...\n"); do { mp_random(&s, size - smallsize); mp_exptmod(&s, &random, &modulus, &root); } while(mp_cmp_d(&root, 1) == MP_EQ); /* * We make sure a and g^a != 1 as these would make * determining the shared secret trivial. */ printf("libnetcrypt: Generating secret and public key...\n"); do { do { mp_random(&secret_key, size); } while((mp_cmp_d(&secret_key, 1) == MP_EQ) || (mp_cmp_mag(&secret_key, &modulus) != MP_LT)); mp_exptmod(&root, &secret_key, &modulus, &public_key); } while(mp_cmp_d(&public_key, 1) == MP_EQ); out = malloc(sizeof(lnc_key_t)); out->generator = root; out->modulus = modulus; out->secret_key = secret_key; out->public_key = public_key; printf("libnetcrypt: Done.\n"); mp_clear_multi(&small_prime, &random, &mul, &s, &tmp, NULL); *status = LNC_OK; return out; }