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));
}
Exemple #2
0
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));
}
Exemple #3
0
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;
}