Beispiel #1
0
int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
                         const BIGNUM *rem, BN_GENCB *cb) {
  BIGNUM *t;
  int found = 0;
  int i, j, c1 = 0;
  BN_CTX *ctx;
  int checks = BN_prime_checks_for_size(bits);

  if (bits < 2) {
    /* There are no prime numbers this small. */
    OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
    return 0;
  } else if (bits == 2 && safe) {
    /* The smallest safe prime (7) is three bits. */
    OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
    return 0;
  }

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto err;
  }
  BN_CTX_start(ctx);
  t = BN_CTX_get(ctx);
  if (!t) {
    goto err;
  }

loop:
  /* make a random number and set the top and bottom bits */
  if (add == NULL) {
    if (!probable_prime(ret, bits)) {
      goto err;
    }
  } else {
    if (safe) {
      if (!probable_prime_dh_safe(ret, bits, add, rem, ctx)) {
        goto err;
      }
    } else {
      if (!probable_prime_dh(ret, bits, add, rem, ctx)) {
        goto err;
      }
    }
  }

  if (!BN_GENCB_call(cb, BN_GENCB_GENERATED, c1++)) {
    /* aborted */
    goto err;
  }

  if (!safe) {
    i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
    if (i == -1) {
      goto err;
    } else if (i == 0) {
      goto loop;
    }
  } else {
    /* for "safe prime" generation, check that (p-1)/2 is prime. Since a prime
     * is odd, We just need to divide by 2 */
    if (!BN_rshift1(t, ret)) {
      goto err;
    }

    for (i = 0; i < checks; i++) {
      j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, NULL);
      if (j == -1) {
        goto err;
      } else if (j == 0) {
        goto loop;
      }

      j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, NULL);
      if (j == -1) {
        goto err;
      } else if (j == 0) {
        goto loop;
      }

      if (!BN_GENCB_call(cb, i, c1 - 1)) {
        goto err;
      }
      /* We have a safe prime test pass */
    }
  }

  /* we have a prime :-) */
  found = 1;

err:
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }

  return found;
}
Beispiel #2
0
BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
	const BIGNUM *add, const BIGNUM *rem,
	void (*callback)(int,int,void *), void *cb_arg)
	{
	BIGNUM *rnd=NULL;
	BIGNUM t;
	int found=0;
	int i,j,c1=0;
	BN_CTX *ctx;
	int checks = BN_prime_checks_for_size(bits);

	ctx=BN_CTX_new();
	if (ctx == NULL) goto err;
	if (ret == NULL)
		{
		if ((rnd=BN_new()) == NULL) goto err;
		}
	else
		rnd=ret;
	BN_init(&t);
loop: 
	/* make a random number and set the top and bottom bits */
	if (add == NULL)
		{
		if (!probable_prime(rnd,bits)) goto err;
		}
	else
		{
		if (safe)
			{
			if (!probable_prime_dh_safe(rnd,bits,add,rem,ctx))
				 goto err;
			}
		else
			{
			if (!probable_prime_dh(rnd,bits,add,rem,ctx))
				goto err;
			}
		}
	/* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */
	if (callback != NULL) callback(0,c1++,cb_arg);

	if (!safe)
		{
		i=BN_is_prime_fasttest(rnd,checks,callback,ctx,cb_arg,0);
		if (i == -1) goto err;
		if (i == 0) goto loop;
		}
	else
		{
		/* for "safe prime" generation,
		 * check that (p-1)/2 is prime.
		 * Since a prime is odd, We just
		 * need to divide by 2 */
		if (!BN_rshift1(&t,rnd)) goto err;

		for (i=0; i<checks; i++)
			{
			j=BN_is_prime_fasttest(rnd,1,callback,ctx,cb_arg,0);
			if (j == -1) goto err;
			if (j == 0) goto loop;

			j=BN_is_prime_fasttest(&t,1,callback,ctx,cb_arg,0);
			if (j == -1) goto err;
			if (j == 0) goto loop;

			if (callback != NULL) callback(2,c1-1,cb_arg);
			/* We have a safe prime test pass */
			}
		}
	/* we have a prime :-) */
	found = 1;
err:
	if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd);
	BN_free(&t);
	if (ctx != NULL) BN_CTX_free(ctx);
	return(found ? rnd : NULL);
	}
Beispiel #3
0
int
BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
    const BIGNUM *rem, BN_GENCB *cb)
{
	BIGNUM *t;
	int found = 0;
	int i, j, c1 = 0;
	BN_CTX *ctx;
	int checks = BN_prime_checks_for_size(bits);

	ctx = BN_CTX_new();
	if (ctx == NULL)
		goto err;
	BN_CTX_start(ctx);
	if ((t = BN_CTX_get(ctx)) == NULL)
		goto err;
loop:
	/* make a random number and set the top and bottom bits */
	if (add == NULL) {
		if (!probable_prime(ret, bits))
			goto err;
	} else {
		if (safe) {
			if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
				goto err;
		} else {
			if (!probable_prime_dh(ret, bits, add, rem, ctx))
				goto err;
		}
	}
	/* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
	if (!BN_GENCB_call(cb, 0, c1++))
		/* aborted */
		goto err;

	if (!safe) {
		i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
		if (i == -1)
			goto err;
		if (i == 0)
			goto loop;
	} else {
		/* for "safe prime" generation,
		 * check that (p-1)/2 is prime.
		 * Since a prime is odd, We just
		 * need to divide by 2 */
		if (!BN_rshift1(t, ret))
			goto err;

		for (i = 0; i < checks; i++) {
			j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb);
			if (j == -1)
				goto err;
			if (j == 0)
				goto loop;

			j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb);
			if (j == -1)
				goto err;
			if (j == 0)
				goto loop;

			if (!BN_GENCB_call(cb, 2, c1 - 1))
				goto err;
			/* We have a safe prime test pass */
		}
	}
	/* we have a prime :-) */
	found = 1;

err:
	if (ctx != NULL) {
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
	}
	bn_check_top(ret);
	return found;
}