Example #1
1
RSA *RSA_generate_key(int bits, unsigned long e_value,
	     void (*callback)(int,int,void *), void *cb_arg)
	{
	RSA *rsa=NULL;
	BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
	int bitsp,bitsq,ok= -1,n=0,i;
	BN_CTX *ctx=NULL,*ctx2=NULL;

	ctx=BN_CTX_new();
	if (ctx == NULL) goto err;
	ctx2=BN_CTX_new();
	if (ctx2 == NULL) goto err;
	BN_CTX_start(ctx);
	r0 = BN_CTX_get(ctx);
	r1 = BN_CTX_get(ctx);
	r2 = BN_CTX_get(ctx);
	r3 = BN_CTX_get(ctx);
	if (r3 == NULL) goto err;

	bitsp=(bits+1)/2;
	bitsq=bits-bitsp;
	rsa=RSA_new();
	if (rsa == NULL) goto err;

	/* set e */ 
	rsa->e=BN_new();
	if (rsa->e == NULL) goto err;

	/* The problem is when building with 8, 16, or 32 BN_ULONG,
	 * unsigned long can be larger */
	for (i=0; i<sizeof(unsigned long)*8; i++)
		{
		if (e_value & (1UL<<i))
			BN_set_bit(rsa->e,i);
		}

	/* generate p and q */
	for (;;)
		{
		rsa->p=BN_generate_prime(NULL,bitsp,0,NULL,NULL,callback,cb_arg);
		if (rsa->p == NULL) goto err;
		if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
		if (BN_is_one(r1)) break;
		if (callback != NULL) callback(2,n++,cb_arg);
		BN_free(rsa->p);
		}
	if (callback != NULL) callback(3,0,cb_arg);
	for (;;)
		{
		rsa->q=BN_generate_prime(NULL,bitsq,0,NULL,NULL,callback,cb_arg);
		if (rsa->q == NULL) goto err;
		if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
		if (BN_is_one(r1) && (BN_cmp(rsa->p,rsa->q) != 0))
			break;
		if (callback != NULL) callback(2,n++,cb_arg);
		BN_free(rsa->q);
		}
	if (callback != NULL) callback(3,1,cb_arg);
	if (BN_cmp(rsa->p,rsa->q) < 0)
		{
		tmp=rsa->p;
		rsa->p=rsa->q;
		rsa->q=tmp;
		}

	/* calculate n */
	rsa->n=BN_new();
	if (rsa->n == NULL) goto err;
	if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;

	/* calculate d */
	if (!BN_sub(r1,rsa->p,BN_value_one())) goto err;	/* p-1 */
	if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;	/* q-1 */
	if (!BN_mul(r0,r1,r2,ctx)) goto err;	/* (p-1)(q-1) */

/* should not be needed, since gcd(p-1,e) == 1 and gcd(q-1,e) == 1 */
/*	for (;;)
		{
		if (!BN_gcd(r3,r0,rsa->e,ctx)) goto err;
		if (BN_is_one(r3)) break;

		if (1)
			{
			if (!BN_add_word(rsa->e,2L)) goto err;
			continue;
			}
		RSAerr(RSA_F_RSA_GENERATE_KEY,RSA_R_BAD_E_VALUE);
		goto err;
		}
*/
	rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2);	/* d */
	if (rsa->d == NULL) goto err;

	/* calculate d mod (p-1) */
	rsa->dmp1=BN_new();
	if (rsa->dmp1 == NULL) goto err;
	if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) goto err;

	/* calculate d mod (q-1) */
	rsa->dmq1=BN_new();
	if (rsa->dmq1 == NULL) goto err;
	if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) goto err;

	/* calculate inverse of q mod p */
	rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2);
	if (rsa->iqmp == NULL) goto err;

	ok=1;
err:
	if (ok == -1)
		ok=0;
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	BN_CTX_free(ctx2);
	
	if (!ok)
		{
		if (rsa != NULL) RSA_free(rsa);
		return(NULL);
		}
	else
		return(rsa);
	}
Example #2
0
/*
 * call-seq:
 *    BN.generate_prime(bits, [, safe [, add [, rem]]]) => bn
 *
 * === Parameters
 * * +bits+ - integer
 * * +safe+ - boolean
 * * +add+ - BN
 * * +rem+ - BN
 */
static VALUE
ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
{
    BIGNUM *add = NULL, *rem = NULL, *result;
    int safe = 1, num;
    VALUE vnum, vsafe, vadd, vrem, obj;

    rb_scan_args(argc, argv, "13", &vnum, &vsafe, &vadd, &vrem);
	
    num = NUM2INT(vnum);

    if (vsafe == Qfalse) {
	safe = 0;
    }
    if (!NIL_P(vadd)) {
	add = GetBNPtr(vadd);
	rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem);
    }
    if (!(result = BN_new())) {
	ossl_raise(eBNError, NULL);
    }
    if (!BN_generate_prime(result, num, safe, add, rem, NULL, NULL)) {
	BN_free(result);
	ossl_raise(eBNError, NULL);
    }
    WrapBN(klass, obj, result);
    
    return obj;
}
Example #3
0
/**
 * Generate a prime number
 *
 * The internal CPRNG is seeded using the provided seed value.
 *
 * @param prime Pointer for storage of prime number
 * @param s Secret to share
 * @param bits Bit size of prime
 * @param rngSeed Seed value for CPRNG
 * @param rngSeedLength Length of Seed value for CPRNG
 *
 */
static int generatePrime(BIGNUM *prime, const BIGNUM *s, const int bits, unsigned char *rngSeed, const unsigned int rngSeedLength)
{
	int max_rounds = 1000;

	// Seed the RNG
	RAND_seed(rngSeed, rngSeedLength);

	// Clear the prime value
	BN_clear(prime);

	do {
		// Generate random prime
#if OPENSSL_VERSION_NUMBER  >= 0x00908000L /* last parm is BN_GENCB which is null in our case */
		BN_generate_prime_ex(prime, bits, 1, NULL, NULL, NULL);
#else
		BN_generate_prime(prime, bits, 1, NULL, NULL, NULL, NULL );
#endif

	} while ((BN_ucmp(prime, s) == -1) && (max_rounds-- > 0));	// If prime < s or not reached 1000 tries

	if (max_rounds > 0)
		return 0;
	else
		return -1; // We could not find a prime number
}
Example #4
0
void test_lehmer_thm(void)
{
  BIGNUM
    *v = BN_new(),
    *v2 = BN_new(),
    *h = BN_new(),
    *n = BN_new(),
    *p = BN_new(),
    *q = BN_new(),
    *g = BN_new();
  BN_CTX *ctx = BN_CTX_new();

  BN_dec2bn(&v, "2");
  BN_dec2bn(&p,
            "181857351165158586099319592412492032999818333818932850952491024"
            "131283899677766672100915923041329384157985577418702469610834914"
            "6296393743554494871840505599");
  BN_dec2bn(&q,
            "220481921324130321200060036818685031159071785249502660004347524"
            "831733577485433929892260897846567483448177204481081755191897197"
            "38283711758138566145322943999");
  BN_mul(n, p, q, ctx);
  /* p + 1 */
  BN_dec2bn(&h,
            "181857351165158586099319592412492032999818333818932850952491024"
            "131283899677766672100915923041329384157985577418702469610834914"
            "6296393743554494871840505600");
  lucas(v, h, n, ctx);
  BN_sub(v2, v, BN_value_two());
  BN_gcd(g, v2, n, ctx);
  assert(!BN_is_one(g));

  /* another test */
  BN_dec2bn(&v, "3");
  BN_dec2bn(&p,
            "181857351165158586099319592412492032999818333818932850952491024"
            "131283899677766672100915923041329384157985577418702469610834914"
            "62963937435544948718405055999");
  BN_generate_prime(q, 512, 1, NULL, NULL, NULL, NULL);
  BN_mul(n, p, q, ctx);

  BN_sub(h, p, BN_value_one());
  BN_mul(h, h, BN_value_two(), ctx);
  lucas(v, h, n, ctx);

  BN_mod_sub(v2, v, BN_value_two(), n, ctx);
  BN_gcd(g, v2, n, ctx);
  assert(!BN_is_one(g));
  assert(BN_cmp(g, n));

  BN_free(q);
  BN_free(p);
  BN_free(v);
  BN_free(v2);
  BN_free(h);

  BN_CTX_free(ctx);
}
Example #5
0
void DS::GenPrimeKeys(uint8_t* K, uint8_t* N)
{
    BIGNUM* bn_key = BN_new();
    init_rand();

    while (BN_num_bytes(bn_key) != 64) {
        BN_generate_prime(bn_key, 512, 1, 0, 0, 0, 0);
        putc('.', stdout);
        fflush(stdout);
    }
    BN_bn2bin(bn_key, reinterpret_cast<unsigned char*>(K));
    BN_set_word(bn_key, 0);
    while (BN_num_bytes(bn_key) != 64) {
        BN_generate_prime(bn_key, 512, 1, 0, 0, 0, 0);
        putc('.', stdout);
        fflush(stdout);
    }
    BN_bn2bin(bn_key, reinterpret_cast<unsigned char*>(N));

    BN_free(bn_key);
}
Example #6
0
/**
 * Generate a prime number
 *
 * The internal CPRNG is seeded using the provided seed value.
 * For the bit size of the generated prime the following condition holds:
 *
 * num_bits(prime) > max(2^r, num_bits(n + 1))
 *
 * r equals the number of bits needed to encode the secret.
 *
 * @param prime Pointer for storage of prime number
 * @param s Secret to share
 * @param n Maximum number of shares
 * @param rngSeed Seed value for CPRNG
 *
 */
static void generatePrime(BIGNUM *prime, const BIGNUM *s, const unsigned int n, char *rngSeed) {

	int bits = 0;

	// Seed the RNG
	RAND_seed(rngSeed, sizeof(rngSeed));

	// Determine minimum number of bits for prime >= max(2^r, n + 1)
	bits = BN_num_bits_word(n + 1) > BN_num_bits(s) ? (BN_num_bits_word(n + 1)) : (BN_num_bits(s));

	// Clear the prime value
	BN_clear(prime);

	// Generate random prime
	BN_generate_prime(prime, bits, 1, NULL, NULL, NULL, NULL );
}
Example #7
0
int main(int argc, char *argv[])
{
        char *prime;
        BIGNUM *num_tmp;
        long int num_bits = 0;
        
        if(argc >= 2 && argv[1]) 
                num_bits = atol(argv[1]);
        else
                num_bits = 1024;
        printf("Prime generator by (c) 2004 Paolo Ardoino < *****@*****.** >\n usage: ./genprimes [num_bits]\nGenerating %ld bits primes.\nWait…\n",num_bits);
        num_tmp = BN_new();
        for (;;) {
                BN_generate_prime(num_tmp,num_bits,1,NULL,NULL,status,NULL);
                prime = (char *)malloc(BN_num_bytes(num_tmp));
                prime = BN_bn2dec(num_tmp);
                print_prime(prime);
                free(prime);
        }
        BN_free(num_tmp);
}
Example #8
0
/* generates ElGamal key pair. returns 0 when generation went ok, and
 -1 if error occured. 'bits' is the number of bits in p; it should not
 be too low (at least 512 is recommended, 1024 is more realistic number.
 you can use precomputed p,g pairs; set bits to the ordinal of the
 precomputed combination (see table above). generator is either 2 or 5.
 public_key and secret_key will be malloc()ed and contain keys */
int eg_keypair (int bits, int generator, char **public_key, char **secret_key)
{
    BIGNUM       *p, *g, *t1, *t2, *key, *pbk;
    BN_CTX       *ctx2;
    BN_MONT_CTX  *mont;
    char         *buf1, *buf2, *buf3, *buf4, buf[8];
    int          rc;

    // create things needed for work
    ctx2 = BN_CTX_new ();         if (ctx2 == NULL) return -1;
    t1   = BN_new ();             if (t1 == NULL)   return -1;
    t2   = BN_new ();             if (t2 == NULL)   return -1;
    g    = BN_new ();             if (g == NULL)    return -1;
    key  = BN_new ();             if (key == NULL)  return -1;
    pbk  = BN_new ();             if (pbk == NULL)  return -1;
    mont = BN_MONT_CTX_new ();    if (mont == NULL) return -1;

    if (bits < 32)
    {
        if (bits > sizeof(precomp)/sizeof(precomp[0])-1) return -1;
        p = NULL;
        rc = BN_hex2bn (&p, precomp[bits].prime);
        if (rc == 0) return -1;
        // put generator into bignum
        BN_set_word (g, precomp[bits].generator);
    }
    else
    {
        // set values which will be used for checking when generating proper prime
        if (generator == 2)
        {
            BN_set_word (t1,24);
            BN_set_word (t2,11);
        }
        else if (generator == 5)
        {
            BN_set_word (t1,10);
            BN_set_word (t2,3);
            /* BN_set_word(t3,7); just have to miss
             * out on these ones :-( */
        }
        else
            goto err;
    
        // generate proper prime
        p = BN_generate_prime (NULL, bits, 1, t1, t2, NULL, NULL);
        if (p == NULL) goto err;

        // put generator into bignum
        BN_set_word (g, generator);
    }

    // create random private key
    if (!BN_rand (key, BN_num_bits (p)-1, 0, 0)) goto err;

    // create public part of the key
    BN_MONT_CTX_set (mont, p, ctx2);
    if (!BN_mod_exp_mont (pbk, g, key, p, ctx2, mont)) goto err;

    // p, g, key, pbk are ready. secret key: p,g:key, public key: p,g:pbk
    if (bits < 32)
    {
        snprintf1 (buf, sizeof(buf), "%d", bits);
        buf1 = strdup (buf);
    }
    else
    {
        buf1 = BN_bn2hex (p);
    }
    buf2 = BN_bn2hex (key);
    buf3 = BN_bn2hex (pbk);
    buf4 = BN_bn2hex (g);

    *secret_key = malloc (strlen(buf1) + strlen(buf2) + strlen(buf4) + 4);
    *public_key = malloc (strlen(buf1) + strlen(buf3) + strlen(buf4) + 4);

    strcpy (*secret_key, buf1);
    if (bits >= 32)
    {
        strcat (*secret_key, ",");
        strcat (*secret_key, buf4);
    }
    strcat (*secret_key, ":");
    strcat (*secret_key, buf2);
    
    strcpy (*public_key, buf1);
    if (bits >= 32)
    {
        strcat (*public_key, ",");
        strcat (*public_key, buf4);
    }
    strcat (*public_key, ":");
    strcat (*public_key, buf3);
    memset (buf2, 0, strlen (buf2));
    free (buf1); free (buf2); free (buf3);

    // cleanup
    BN_free (p);            BN_free (g);
    BN_clear_free (key);    BN_free (pbk);
    BN_CTX_free (ctx2);
    return 0;
    
err:
    return -1;
}
Example #9
0
int main() {
    clock_t begin, end;
    double time_spent;

    printf("====================================================================\n");
    BIGNUM *a, *b, *c, *d, *gen, *prime_mod;
    char *c_str;
    BN_CTX *ctx; /* used internally by the bignum lib */
    //DH *dhparms;
    int csize;

    ctx = BN_CTX_new();
    a = BN_new();
    b = BN_new();
    c = BN_new();
    d = BN_new();
    
    prime_mod = BN_new();    

    BN_set_word(a, 6);
    BN_set_word(b, 7);

    BN_mul(c, a, b, ctx);

    BN_generate_prime(prime_mod,1024,0,0,0,0,0);
    //char * primeMOD= "D3BAAE3CE4015583027B1D822109B874CDC6A805BEFEB3DA4B6AD9C3DC1D90B1CF04D70906A1897AF231A03041D6456E7113C573E038DE0EDCF7CAE1B237AC2328110681C83AE86CC5E3268B5808551575E066858684448336E32A9BBCDDAA248BC2685C94142E88C6A68B021941B1C60744E137122A20A7D2CB1641B01E0117";
    //BN_hex2bn(&prime_mod, primeMOD);
    c_str = BN_bn2hex(prime_mod); /* there's also a BN_d ec2bn() */
    csize = BN_num_bits(prime_mod);
    //printf("prime_mod = %s size = %d\n", c_str, csize);

    // BN_rand(c, 1024, 0, 0);
    // c_str = BN_bn2hex(c);  //there's also a BN_d ec2bn() 
    // csize = BN_num_bits(c);
    // printf("C = %s size = %d\n", c_str, csize);


    //char * BN_T= "DFB9E8DC1BA16AD6EB2ABE6C02E5A9C7B279EEB52DEEBFD550172FC59CAF08534DFEC64BDDE9BD1BE6F9FBDA376C917E615C1F639FE81B8A594812D3E64B3AE4D7BB3F735106845571E16C348CB5100B71B805B70D0CF293727FEAF48F3FFD2A88B09D14AD9D6E314E35BB72238DFAD2549FCF7554F3E1645B118AADACCA35FA";

    // BN_hex2bn(&d, BN_T);
    // c_str = BN_bn2hex(d); 
    // csize = BN_num_bits(d);
    // printf("D = %s size = %d\n", c_str, csize);

    // BN_sqr(c, d, ctx); // c = d^2
    // c_str = BN_bn2hex(c); 
    // csize = BN_num_bits(c);
    // printf("c sq = %s size = %d\n", c_str, csize);

    // BN_mod_add(b, b, c, prime_mod, ctx); //b = b+c mod p

    // BN_mod(d, c, prime_mod, ctx); // d = c mod p
    // c_str = BN_bn2hex(d); 
    // csize = BN_num_bits(d);
    // printf("c mod d = %s size = %d\n", c_str, csize);

    // BN_mod_exp(b, c, d, prime_mod, ctx); // b = c^d mod p
    // c_str = BN_bn2hex(b); 
    // csize = BN_num_bits(b);
    // printf("c exp d = %s size = %d\n", c_str, csize);





    int i, j, _ITERATION_NOR, _ITERATION_EXP;
    _ITERATION_NOR = 1000000;
    _ITERATION_EXP = 1000;
    time_t now;
    time(&now);

    struct tm* now_tm;
    now_tm = localtime(&now);

    char out[80];
    char fileNameT[80];
    strftime (out, 80, "%Y-%m-%d %H:%M:%S", now_tm);
    strftime (fileNameT, 80, "%Y.%m.%d.%H.%M.%S", now_tm);

    char filename[20];
    strcpy (filename,"Bignumber_");
    strcat (filename,fileNameT);
    strcat (filename,".txt");

    FILE *f = fopen(filename, "a+");
    //setbuf(f, NULL);
    if (f == NULL)
    {
        printf("Error opening file!\n");
        exit(1);
    }
    
    fprintf(f, "\nTested started on %s\n", out);
    fprintf(f, "Normal iteration = %d\n", _ITERATION_NOR);
    fprintf(f, "Exp    iteration = %d\n", _ITERATION_EXP);
    fprintf(f, "MOD    iteration = %d\n", _ITERATION_NOR*10);
    fprintf(f, "===================================\n");


for(j=0;j<100;j++){ 
    printf("Iteration\t#%d\n", j+1);
    fprintf(f, "Iteration #%d\n", j+1);
    fflush(f);
BN_rand(a, 1024, 0, 0);
BN_rand(d, 1024, 0, 0);

// d^2
begin = clock();
    for(i=0;i<_ITERATION_NOR;i++){
        BN_sqr(c, d, ctx);
    }
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Square %f\n", time_spent);
fprintf(f, "Square\t%f\n", time_spent);
fflush(f);

BN_rand(b, 1024, 0, 0);
BN_rand(c, 1024, 0, 0);
// b+c
begin = clock();
    for(i=0;i<_ITERATION_NOR;i++){
        BN_mod_add(b, b, c, prime_mod, ctx);
    }
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Addition %f\n", time_spent);
fprintf(f, "Addition\t%f\n", time_spent);
fflush(f);

BN_rand(b, 1024, 0, 0);
// b mod p
begin = clock();
    for(i=0;i<_ITERATION_NOR*10;i++){
        BN_mod(d, b, prime_mod, ctx);
    }
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Modulus %f\n", time_spent);
fprintf(f, "Modulus\t%f\n", time_spent);
fflush(f);

BN_rand(c, 1024, 0, 0);
BN_rand(d, 1024, 0, 0);
// c ^ d mod p
begin = clock();
    for(i=0;i<_ITERATION_EXP;i++){
        BN_mod_exp(b, c, d, prime_mod, ctx); // b = c^d mod p
    }
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("exponetial %f\n", time_spent);
fprintf(f, "exponetial\t%f\n", time_spent);
fflush(f);
}
    time(&now);
    now_tm = localtime(&now);
    strftime (out, 80, "%Y-%m-%d %H:%M:%S", now_tm);
    fprintf(f, "\nTested ended on %s\n", out);








    BN_CTX_free(ctx);
    printf("====================================================================\n");
    fclose(f);

    return 0;
}
Example #10
0
int test_sqrt(BIO *bp, BN_CTX *ctx)
	{
	BIGNUM *a,*p,*r;
	int i, j;
	int ret = 0;

	a = BN_new();
	p = BN_new();
	r = BN_new();
	if (a == NULL || p == NULL || r == NULL) goto err;
	
	for (i = 0; i < 16; i++)
		{
		if (i < 8)
			{
			unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
			
			if (!BN_set_word(p, primes[i])) goto err;
			}
		else
			{
			if (!BN_set_word(a, 32)) goto err;
			if (!BN_set_word(r, 2*i + 1)) goto err;
		
			if (!BN_generate_prime(p, 256, 0, a, r, genprime_cb, NULL)) goto err;
			putc('\n', stderr);
			}
		p->neg = rand_neg();

		for (j = 0; j < num2; j++)
			{
			/* construct 'a' such that it is a square modulo p,
			 * but in general not a proper square and not reduced modulo p */
			if (!BN_bntest_rand(r, 256, 0, 3)) goto err;
			if (!BN_nnmod(r, r, p, ctx)) goto err;
			if (!BN_mod_sqr(r, r, p, ctx)) goto err;
			if (!BN_bntest_rand(a, 256, 0, 3)) goto err;
			if (!BN_nnmod(a, a, p, ctx)) goto err;
			if (!BN_mod_sqr(a, a, p, ctx)) goto err;
			if (!BN_mul(a, a, r, ctx)) goto err;
			if (rand_neg())
				if (!BN_sub(a, a, p)) goto err;

			if (!BN_mod_sqrt(r, a, p, ctx)) goto err;
			if (!BN_mod_sqr(r, r, p, ctx)) goto err;

			if (!BN_nnmod(a, a, p, ctx)) goto err;

			if (BN_cmp(a, r) != 0)
				{
				fprintf(stderr, "BN_mod_sqrt failed: a = ");
				BN_print_fp(stderr, a);
				fprintf(stderr, ", r = ");
				BN_print_fp(stderr, r);
				fprintf(stderr, ", p = ");
				BN_print_fp(stderr, p);
				fprintf(stderr, "\n");
				goto err;
				}

			putc('.', stderr);
			fflush(stderr);
			}
		
		putc('\n', stderr);
		fflush(stderr);
		}
	ret = 1;
 err:
	if (a != NULL) BN_free(a);
	if (p != NULL) BN_free(p);
	if (r != NULL) BN_free(r);
	return ret;
	}
Example #11
0
int test_kron(BIO *bp, BN_CTX *ctx)
	{
	BIGNUM *a,*b,*r,*t;
	int i;
	int legendre, kronecker;
	int ret = 0;

	a = BN_new();
	b = BN_new();
	r = BN_new();
	t = BN_new();
	if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
	
	/* We test BN_kronecker(a, b, ctx) just for  b  odd (Jacobi symbol).
	 * In this case we know that if  b  is prime, then BN_kronecker(a, b, ctx)
	 * is congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol).
	 * So we generate a random prime  b  and compare these values
	 * for a number of random  a's.  (That is, we run the Solovay-Strassen
	 * primality test to confirm that  b  is prime, except that we
	 * don't want to test whether  b  is prime but whether BN_kronecker
	 * works.) */

	if (!BN_generate_prime(b, 512, 0, NULL, NULL, genprime_cb, NULL)) goto err;
	b->neg = rand_neg();
	putc('\n', stderr);

	for (i = 0; i < num0; i++)
		{
		if (!BN_bntest_rand(a, 512, 0, 0)) goto err;
		a->neg = rand_neg();

		/* t := (|b|-1)/2  (note that b is odd) */
		if (!BN_copy(t, b)) goto err;
		t->neg = 0;
		if (!BN_sub_word(t, 1)) goto err;
		if (!BN_rshift1(t, t)) goto err;
		/* r := a^t mod b */
		b->neg=0;
		
		if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err;
		b->neg=1;

		if (BN_is_word(r, 1))
			legendre = 1;
		else if (BN_is_zero(r))
			legendre = 0;
		else
			{
			if (!BN_add_word(r, 1)) goto err;
			if (0 != BN_ucmp(r, b))
				{
				fprintf(stderr, "Legendre symbol computation failed\n");
				goto err;
				}
			legendre = -1;
			}
		
		kronecker = BN_kronecker(a, b, ctx);
		if (kronecker < -1) goto err;
		/* we actually need BN_kronecker(a, |b|) */
		if (a->neg && b->neg)
			kronecker = -kronecker;
		
		if (legendre != kronecker)
			{
			fprintf(stderr, "legendre != kronecker; a = ");
			BN_print_fp(stderr, a);
			fprintf(stderr, ", b = ");
			BN_print_fp(stderr, b);
			fprintf(stderr, "\n");
			goto err;
			}

		putc('.', stderr);
		fflush(stderr);
		}

	putc('\n', stderr);
	fflush(stderr);
	ret = 1;
 err:
	if (a != NULL) BN_free(a);
	if (b != NULL) BN_free(b);
	if (r != NULL) BN_free(r);
	if (t != NULL) BN_free(t);
	return ret;
	}
Example #12
0
DH *DH_generate_parameters(int prime_len, int generator,
	     void (*callback)(int,int,void *), void *cb_arg)
	{
	BIGNUM *p=NULL,*t1,*t2;
	DH *ret=NULL;
	int g,ok= -1;
	BN_CTX *ctx=NULL;

	ret=DH_new();
	if (ret == NULL) goto err;
	ctx=BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	t1 = BN_CTX_get(ctx);
	t2 = BN_CTX_get(ctx);
	if (t1 == NULL || t2 == NULL) goto err;
	
	if (generator == DH_GENERATOR_2)
		{
		BN_set_word(t1,24);
		BN_set_word(t2,11);
		g=2;
		}
#ifdef undef  /* does not work for safe primes */
	else if (generator == DH_GENERATOR_3)
		{
		BN_set_word(t1,12);
		BN_set_word(t2,5);
		g=3;
		}
#endif
	else if (generator == DH_GENERATOR_5)
		{
		BN_set_word(t1,10);
		BN_set_word(t2,3);
		/* BN_set_word(t3,7); just have to miss
		 * out on these ones :-( */
		g=5;
		}
	else
		g=generator;
	
	p=BN_generate_prime(NULL,prime_len,1,t1,t2,callback,cb_arg);
	if (p == NULL) goto err;
	if (callback != NULL) callback(3,0,cb_arg);
	ret->p=p;
	ret->g=BN_new();
	if (!BN_set_word(ret->g,g)) goto err;
	ok=1;
err:
	if (ok == -1)
		{
		DHerr(DH_F_DH_GENERATE_PARAMETERS,ERR_R_BN_LIB);
		ok=0;
		}

	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	if (!ok && (ret != NULL))
		{
		DH_free(ret);
		ret=NULL;
		}
	return(ret);
	}
Example #13
0
int rsa_keypair (int bits, unsigned long e_value, char **public_key, char **secret_key)
{
    BIGNUM  *n=NULL, *e=NULL, *d=NULL, *p=NULL, *q=NULL;
    BIGNUM  *r0=NULL, *r1=NULL, *r2=NULL, *r3=NULL, *tmp;
    int     bitsp, bitsq, i;
    BN_CTX  *ctx=NULL, *ctx2=NULL;
    char    *buf1, *buf2, *buf3;

    ctx=BN_CTX_new();
    if (ctx == NULL) goto err;
    
    ctx2=BN_CTX_new();
    if (ctx2 == NULL) goto err;
    
    r0 = &(ctx->bn[0]);
    r1 = &(ctx->bn[1]);
    r2 = &(ctx->bn[2]);
    r3 = &(ctx->bn[3]);
    ctx->tos += 4;

    bitsp = (bits+1)/2;
    bitsq = bits-bitsp;
    
    /* set e */
    e = BN_new();
    if (e == NULL) goto err;

    /* The problem is when building with 8, 16, or 32 BN_ULONG,
     * unsigned long can be larger */
    for (i=0; i<sizeof(unsigned long)*8; i++)
    {
        if (e_value & (1<<i))
            BN_set_bit(e,i);
    }

    /* generate p and q */
    for (;;)
    {
        p = BN_generate_prime (NULL, bitsp, 1, NULL, NULL, NULL, NULL);
        if (p == NULL) goto err;
        if (!BN_sub (r2, p, BN_value_one())) goto err;
        if (!BN_gcd (r1, r2, e, ctx)) goto err;
        if (BN_is_one(r1)) break;
        BN_free(p);
    }
    
    for (;;)
    {
        q = BN_generate_prime (NULL, bitsq, 1, NULL, NULL, NULL, NULL);
        if (q == NULL) goto err;
        if (!BN_sub (r2, q, BN_value_one())) goto err;
        if (!BN_gcd (r1, r2, e, ctx)) goto err;
        if (BN_is_one (r1) && (BN_cmp (p, q) != 0)) break;
        BN_free(q);
    }
    
    if (BN_cmp (p, q) < 0) tmp = p, p = q, q = tmp;

    /* calculate n */
    n = BN_new();
    if (n == NULL) goto err;
    if (!BN_mul (n, p, q, ctx)) goto err;

    /* calculate d */
    if (!BN_sub (r1, p, BN_value_one())) goto err;	/* p-1 */
    if (!BN_sub (r2, q, BN_value_one())) goto err;	/* q-1 */
    if (!BN_mul (r0, r1, r2, ctx)) goto err;	/* (p-1)(q-1) */

    d = BN_mod_inverse (NULL, e, r0, ctx2);	/* d */
    if (d == NULL) goto err;

    BN_CTX_free(ctx);
    BN_CTX_free(ctx2);
    
    // n, d, e are ready. secret key: n:d, public key: n:e
    buf1 = BN_bn2hex (n);
    buf2 = BN_bn2hex (d);
    buf3 = BN_bn2hex (e);

    *secret_key = malloc (strlen(buf1) + strlen(buf2) + 2);
    *public_key = malloc (strlen(buf1) + strlen(buf3) + 2);
    
    strcpy (*secret_key, buf1); strcat (*secret_key, ":"); strcat (*secret_key, buf2);
    strcpy (*public_key, buf1); strcat (*public_key, ":"); strcat (*public_key, buf3);
    free (buf1); free (buf2); free (buf3);

    // cleanup
    BN_clear_free (n);    BN_clear_free (e);
    BN_clear_free (d);    BN_clear_free (p);
    BN_clear_free (q);

    return 0;
    
err:
    
    BN_CTX_free(ctx);
    BN_CTX_free(ctx2);
    return -1;
}
Example #14
0
/* Actually there is no reason to insist that 'generator' be a generator.
 * It's just as OK (and in some sense better) to use a generator of the
 * order-q subgroup.
 */
DH *DH_generate_parameters(int prime_len, int generator,
	     void (*callback)(int,int,void *), void *cb_arg)
	{
	BIGNUM *p=NULL,*t1,*t2;
	DH *ret=NULL;
	int g,ok= -1;
	BN_CTX *ctx=NULL;

	ret=DH_new();
	if (ret == NULL) goto err;
	ctx=BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	t1 = BN_CTX_get(ctx);
	t2 = BN_CTX_get(ctx);
	if (t1 == NULL || t2 == NULL) goto err;
	
	if (generator <= 1)
		{
		DHerr(DH_F_DH_GENERATE_PARAMETERS, DH_R_BAD_GENERATOR);
		goto err;
		}
	if (generator == DH_GENERATOR_2)
		{
		if (!BN_set_word(t1,24)) goto err;
		if (!BN_set_word(t2,11)) goto err;
		g=2;
		}
#if 0 /* does not work for safe primes */
	else if (generator == DH_GENERATOR_3)
		{
		if (!BN_set_word(t1,12)) goto err;
		if (!BN_set_word(t2,5)) goto err;
		g=3;
		}
#endif
	else if (generator == DH_GENERATOR_5)
		{
		if (!BN_set_word(t1,10)) goto err;
		if (!BN_set_word(t2,3)) goto err;
		/* BN_set_word(t3,7); just have to miss
		 * out on these ones :-( */
		g=5;
		}
	else
		{
		/* in the general case, don't worry if 'generator' is a
		 * generator or not: since we are using safe primes,
		 * it will generate either an order-q or an order-2q group,
		 * which both is OK */
		if (!BN_set_word(t1,2)) goto err;
		if (!BN_set_word(t2,1)) goto err;
		g=generator;
		}
	
	p=BN_generate_prime(NULL,prime_len,1,t1,t2,callback,cb_arg);
	if (p == NULL) goto err;
	if (callback != NULL) callback(3,0,cb_arg);
	ret->p=p;
	ret->g=BN_new();
	if (!BN_set_word(ret->g,g)) goto err;
	ok=1;
err:
	if (ok == -1)
		{
		DHerr(DH_F_DH_GENERATE_PARAMETERS,ERR_R_BN_LIB);
		ok=0;
		}

	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	if (!ok && (ret != NULL))
		{
		DH_free(ret);
		ret=NULL;
		}
	return(ret);
	}
void do_mul_exp(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx)
	{
	int i,k;
	double tm;
	long num;

	num=BASENUM;
	for (i=NUM_START; i<NUM_SIZES; i++)
		{
#ifdef C_PRIME
#  ifdef TEST_SQRT
		if (!BN_set_word(a, 64)) goto err;
		if (!BN_set_word(b, P_MOD_64)) goto err;
#    define ADD a
#    define REM b
#  else
#    define ADD NULL
#    define REM NULL
#  endif
		if (!BN_generate_prime(c,sizes[i],0,ADD,REM,genprime_cb,NULL)) goto err;
		putc('\n', stderr);
		fflush(stderr);
#endif

		for (k=0; k<num; k++)
			{
			if (k%50 == 0) /* Average over num/50 different choices of random numbers. */
				{
				if (!BN_pseudo_rand(a,sizes[i],1,0)) goto err;

				if (!BN_pseudo_rand(b,sizes[i],1,0)) goto err;

#ifndef C_PRIME
				if (!BN_pseudo_rand(c,sizes[i],1,1)) goto err;
#endif

#ifdef TEST_SQRT				
				if (!BN_mod_sqr(a,a,c,ctx)) goto err;
				if (!BN_mod_sqr(b,b,c,ctx)) goto err;
#else
				if (!BN_nnmod(a,a,c,ctx)) goto err;
				if (!BN_nnmod(b,b,c,ctx)) goto err;
#endif

				if (k == 0)
					Time_F(START);
				}

#if defined(TEST_EXP)
			if (!BN_mod_exp(r,a,b,c,ctx)) goto err;
#elif defined(TEST_MUL)
			{
			int i = 0;
			for (i = 0; i < 50; i++)
				if (!BN_mod_mul(r,a,b,c,ctx)) goto err;
			}
#elif defined(TEST_SQR)
			{
			int i = 0;
			for (i = 0; i < 50; i++)
				{
				if (!BN_mod_sqr(r,a,c,ctx)) goto err;
				if (!BN_mod_sqr(r,b,c,ctx)) goto err;
				}
			}
#elif defined(TEST_GCD)
			if (!BN_gcd(r,a,b,ctx)) goto err;
			if (!BN_gcd(r,b,c,ctx)) goto err;
			if (!BN_gcd(r,c,a,ctx)) goto err;
#elif defined(TEST_KRON)
			if (-2 == BN_kronecker(a,b,ctx)) goto err;
			if (-2 == BN_kronecker(b,c,ctx)) goto err;
			if (-2 == BN_kronecker(c,a,ctx)) goto err;
#elif defined(TEST_INV)
			if (!BN_mod_inverse(r,a,c,ctx)) goto err;
			if (!BN_mod_inverse(r,b,c,ctx)) goto err;
#else /* TEST_SQRT */
			if (!BN_mod_sqrt(r,a,c,ctx)) goto err;
			if (!BN_mod_sqrt(r,b,c,ctx)) goto err;
#endif
			}
		tm=Time_F(STOP);
		printf(
#if defined(TEST_EXP)
			"modexp %4d ^ %4d %% %4d"
#elif defined(TEST_MUL)
			"50*modmul %4d %4d %4d"
#elif defined(TEST_SQR)
			"100*modsqr %4d %4d %4d"
#elif defined(TEST_GCD)
			"3*gcd %4d %4d %4d"
#elif defined(TEST_KRON)
			"3*kronecker %4d %4d %4d"
#elif defined(TEST_INV)
			"2*inv %4d %4d mod %4d"
#else /* TEST_SQRT */
			"2*sqrt [prime == %d (mod 64)] %4d %4d mod %4d"
#endif
			" -> %8.3fms %5.1f (%ld)\n",
#ifdef TEST_SQRT
			P_MOD_64,
#endif
			sizes[i],sizes[i],sizes[i],tm*1000.0/num,tm*mul_c[i]/num, num);
		num/=7;
		if (num <= 0) num=1;
		}
	return;

 err:
	ERR_print_errors_fp(stderr);
	}