コード例 #1
0
int main(int argc, char ** argv) {
	/* Generate 2 big random numbers (512 bits) */
	primitive_p = initialize("1011011");
	initialize_rand(SEED);
	BIGNUM *p = get_long_prime_number(RSA_KEY_LENGTH);
	printf("p=%s\n", BN_bn2hex(p));
	BIGNUM *q = get_long_prime_number(RSA_KEY_LENGTH);
	printf("q=%s\n", BN_bn2hex(q));
	/* Compute phi = (p-1)*(q-1) and n = p*q */
	BIGNUM *phi, *n;
	BN_CTX *tmp;
	tmp = BN_CTX_new();
	n = BN_new();
	phi = BN_new();
	BN_copy(n, p);
	BN_mul(n, n, q, tmp);
	printf("n=%s\n", BN_bn2dec(n));
	BN_sub_word(p, 1);
	printf("p-1=%s\n", BN_bn2dec(p));
	BN_sub_word(q, 1);
	printf("q-1=%s\n", BN_bn2dec(q));
	phi = BN_new();
	BN_init(tmp);
	BN_mul(phi, p, q, tmp);
	printf("(p-1)(q-1)=%s\n", BN_bn2dec(phi));
	/* Find the smallest integer coprime with phi */
	BIGNUM * e = BN_new();
	BIGNUM *gcd = BN_new();
	BN_add_word(e, 3);
	for ( ; ; BN_add_word(e, 2)) {
		tmp = BN_CTX_new();
		BN_gcd(gcd, e, phi, tmp);
		if (BN_is_one(gcd))
			break;
	}
	printf("e=%s\n", BN_bn2dec(e));
	/* Find d, the inverse of e in Z_phi */
	BIGNUM * d = BN_new();
	BIGNUM * i = BN_new();
	BIGNUM * rem = BN_new();
	BIGNUM * prod = BN_new();
	BN_add_word(i, 1);
	for ( ; ; BN_add_word(i, 1)) {
		BN_copy(prod, phi);
		tmp = BN_CTX_new();
		BN_mul(prod, prod, i, tmp);
		BN_add_word(prod, 1);
		BN_div(d, rem, prod, e, tmp);
		if (BN_is_zero(rem)) {
			break;
		}
	}
	printf("d=%s\n", BN_bn2dec(d));
	return 0;
}
コード例 #2
0
EVP_PKEY* CreateRsaKey(const_RsaDevice d)
{
  BN_CTX* ctx = IntegerGroup_GetCtx(RsaParams_GetGroup(d->params));
  // phi(n) = (p-1)(q-1)
  BIGNUM *phi_n, *pm, *qm;
  phi_n = BN_new();
  CHECK_CALL(phi_n);
  CHECK_CALL(pm = BN_dup(d->p));
  CHECK_CALL(qm = BN_dup(d->q));
  CHECK_CALL(BN_sub_word(pm, 1));
  CHECK_CALL(BN_sub_word(qm, 1));
  CHECK_CALL(BN_mul(phi_n, pm, qm, ctx));

  EVP_PKEY *evp = EVP_PKEY_new();
  RSA *rsa = RSA_new();
  CHECK_CALL(evp);
  CHECK_CALL(rsa);

  CHECK_CALL(rsa->n = BN_dup(d->n)); // public modulus
  CHECK_CALL(rsa->e = BN_new()); // public exponent
  BN_set_word(rsa->e, RsaEncryptionExponent);

  rsa->d = BN_new();              // private exponent
  CHECK_CALL(rsa->d);
  CHECK_CALL(BN_mod_inverse(rsa->d, rsa->e, phi_n, ctx));

  CHECK_CALL(rsa->p = BN_dup(d->p)); // secret prime factor
  CHECK_CALL(rsa->q = BN_dup(d->q)); // secret prime factor
  rsa->dmp1 = BN_new();           // d mod (p-1)
  CHECK_CALL(rsa->dmp1);
  CHECK_CALL(BN_mod(rsa->dmp1, rsa->d, pm, ctx));

  rsa->dmq1 = BN_new();           // d mod (q-1)
  CHECK_CALL(rsa->dmq1);
  CHECK_CALL(BN_mod(rsa->dmq1, rsa->d, qm, ctx));

  rsa->iqmp = BN_new();           // q^-1 mod p
  CHECK_CALL(rsa->iqmp);
  CHECK_CALL(BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx));

  CHECK_CALL(EVP_PKEY_set1_RSA(evp, rsa));
  ASSERT(RSA_check_key(rsa));

  BN_clear_free(phi_n);
  BN_clear_free(pm);
  BN_clear_free(qm);

  return evp;
}
コード例 #3
0
// Generate each party's random numbers. xa is in [0, q), xb is in [1, q).
static void genrand(JPakeUser * user, const JPakeParameters * params)
{
    BIGNUM *qm1;

    // xa in [0, q)
    user->xa = BN_new();
    BN_rand_range(user->xa, params->q);

    // q-1
    qm1 = BN_new();
    BN_copy(qm1, params->q);
    BN_sub_word(qm1, 1);

    // ... and xb in [0, q-1)
    user->xb = BN_new();
    BN_rand_range(user->xb, qm1);
    // [1, q)
    BN_add_word(user->xb, 1);

    // cleanup
    BN_free(qm1);

    // Show
    printf("x%d", user->p.base);
    showbn("", user->xa);
    printf("x%d", user->p.base + 1);
    showbn("", user->xb);
}
コード例 #4
0
ファイル: bn_word.c プロジェクト: easydmbox/oscam
int BN_add_word(BIGNUM *a, BN_ULONG w)
	{
	BN_ULONG l;
	int i;

	if (a->neg)
		{
		a->neg=0;
		i=BN_sub_word(a,w);
		if (!BN_is_zero(a))
			a->neg=!(a->neg);
		return(i);
		}
	w&=BN_MASK2;
	if (bn_wexpand(a,a->top+1) == NULL) return(0);
	i=0;
	for (;;)
		{
		l=(a->d[i]+(BN_ULONG)w)&BN_MASK2;
		a->d[i]=l;
		if (w > l)
			w=1;
		else
			break;
		i++;
		}
	if (i >= a->top)
		a->top++;
	return(1);
	}
コード例 #5
0
ファイル: check.c プロジェクト: 360ground/Meda.et
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) {
  int ok = 0;
  BIGNUM q;

  *ret = 0;
  BN_init(&q);
  if (!BN_set_word(&q, 1)) {
    goto err;
  }

  if (BN_cmp(pub_key, &q) <= 0) {
    *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
  }
  if (!BN_copy(&q, dh->p) ||
      !BN_sub_word(&q, 1)) {
    goto err;
  }
  if (BN_cmp(pub_key, &q) >= 0) {
    *ret |= DH_CHECK_PUBKEY_TOO_LARGE;
  }

  ok = 1;

err:
  BN_free(&q);
  return ok;
}
コード例 #6
0
ファイル: bn_word.c プロジェクト: RyunosukeOno/rayjack
int BN_add_word(BIGNUM *a, BN_ULONG w)
	{
	BN_ULONG l;
	int i;

	bn_check_top(a);
	w &= BN_MASK2;

	/* degenerate case: w is zero */
	if (!w) return 1;
	/* degenerate case: a is zero */
	if(BN_is_zero(a)) return BN_set_word(a, w);
	/* handle 'a' when negative */
	if (a->neg)
		{
		a->neg=0;
		i=BN_sub_word(a,w);
		if (!BN_is_zero(a))
			a->neg=!(a->neg);
		return(i);
		}
	for (i=0;w!=0 && i<a->top;i++)
		{
		a->d[i] = l = (a->d[i]+w)&BN_MASK2;
		w = (w>l)?1:0;
		}
	if (w && i==a->top)
		{
		if (bn_wexpand(a,a->top+1) == NULL) return 0;
		a->top++;
		a->d[i]=w;
		}
	bn_check_top(a);
	return(1);
	}
コード例 #7
0
ファイル: paillier.c プロジェクト: Talos-crypto/Talos-Android
int Lfast(BIGNUM *res, const BIGNUM *u, const BIGNUM *ninv, const BIGNUM *two_n, const BIGNUM *n) {
	BN_CTX *ctx = BN_CTX_new();
	BN_copy(res, u);
	BN_sub_word(res, 1);
	BN_mod_mul(res, res, ninv, two_n, ctx);
	BN_mod(res, res, n, ctx);
}
コード例 #8
0
ファイル: gost_sign.c プロジェクト: 274914765/C
int gost_do_verify (const unsigned char *dgst, int dgst_len, DSA_SIG * sig, DSA * dsa)
{
    BIGNUM *md, *tmp = NULL;

    BIGNUM *q2 = NULL;

    BIGNUM *u = NULL, *v = NULL, *z1 = NULL, *z2 = NULL;

    BIGNUM *tmp2 = NULL, *tmp3 = NULL;

    int ok;

    BN_CTX *ctx = BN_CTX_new ();

    BN_CTX_start (ctx);
    if (BN_cmp (sig->s, dsa->q) >= 1 || BN_cmp (sig->r, dsa->q) >= 1)
    {
        GOSTerr (GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
        return 0;
    }
    md = hashsum2bn (dgst);

    tmp = BN_CTX_get (ctx);
    v = BN_CTX_get (ctx);
    q2 = BN_CTX_get (ctx);
    z1 = BN_CTX_get (ctx);
    z2 = BN_CTX_get (ctx);
    tmp2 = BN_CTX_get (ctx);
    tmp3 = BN_CTX_get (ctx);
    u = BN_CTX_get (ctx);

    BN_mod (tmp, md, dsa->q, ctx);
    if (BN_is_zero (tmp))
    {
        BN_one (md);
    }
    BN_copy (q2, dsa->q);
    BN_sub_word (q2, 2);
    BN_mod_exp (v, md, q2, dsa->q, ctx);
    BN_mod_mul (z1, sig->s, v, dsa->q, ctx);
    BN_sub (tmp, dsa->q, sig->r);
    BN_mod_mul (z2, tmp, v, dsa->p, ctx);
    BN_mod_exp (tmp, dsa->g, z1, dsa->p, ctx);
    BN_mod_exp (tmp2, dsa->pub_key, z2, dsa->p, ctx);
    BN_mod_mul (tmp3, tmp, tmp2, dsa->p, ctx);
    BN_mod (u, tmp3, dsa->q, ctx);
    ok = BN_cmp (u, sig->r);

    BN_free (md);
    BN_CTX_end (ctx);
    BN_CTX_free (ctx);
    if (ok != 0)
    {
        GOSTerr (GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH);
    }
    return (ok == 0);
}
コード例 #9
0
ファイル: cryptoutils.cpp プロジェクト: Ahamtech/TB10
/**
  https://core.telegram.org/api/end-to-end says:
  "Both clients in a secret chat creation are to check that g, g_a and g_b are greater than one and smaller than p-1.
  Recommented checking that g_a and g_b are between 2^{2048-64} and p - 2^{2048-64} as well."
*/
qint32 CryptoUtils::checkCalculatedParams(const BIGNUM *gAOrB, const BIGNUM *g, const BIGNUM *p) {
    ASSERT(gAOrB);
    ASSERT(g);
    ASSERT(p);

    // 1) gAOrB and g greater than one and smaller than p-1
    BIGNUM one;
    BN_init(&one);
    Utils::ensure(BN_one(&one));

    BIGNUM *pMinusOne = BN_dup(p);
    Utils::ensure(BN_sub_word(pMinusOne, 1));

    // check params greater than one
    if (BN_cmp(gAOrB, &one) <= 0) return -1;
    if (BN_cmp(g, &one) <= 0) return -1;

    // check params <= p-1
    if (BN_cmp(gAOrB, pMinusOne) >= 0) return -1;
    if (BN_cmp(g, pMinusOne) >= 0) return -1;

    // 2) gAOrB between 2^{2048-64} and p - 2^{2048-64}
    quint64 expWord = 2048 - 64;
    BIGNUM exp;
    BN_init(&exp);
    Utils::ensure(BN_set_word(&exp, expWord));

    BIGNUM base;
    BN_init(&base);
    Utils::ensure(BN_set_word(&base, 2));

    // lowLimit = base ^ exp
    BIGNUM lowLimit;
    BN_init(&lowLimit);
    Utils::ensure(BN_exp(&lowLimit, &base, &exp, BN_ctx));

    // highLimit = p - lowLimit
    BIGNUM highLimit;
    BN_init(&highLimit);
    BN_sub(&highLimit, p, &lowLimit);

    if (BN_cmp(gAOrB, &lowLimit) < 0) return -1;
    if (BN_cmp(gAOrB, &highLimit) > 0) return -1;

    BN_free(&one);
    BN_free(pMinusOne);
    BN_free(&exp);
    BN_free(&lowLimit);
    BN_free(&highLimit);
    delete g;
    delete gAOrB;
    delete p;

    return 0;
}
コード例 #10
0
ファイル: key_gen.c プロジェクト: tan01/UDOO-PRNG
/*	
 *	prime_totient(p,q,totient)
 *	Euler totient function of n, under the assumption
 *	that n = pq and p and q are prime
 *	inputs: BIGNUM* p
 *		BIGNUM* q
 *	output: BIGNUM* totient
 *
 *	return value: 	0 if failure
 *			1 if success
 */
int prime_totient(BIGNUM* p, BIGNUM* q, BIGNUM* totient){
	BIGNUM one;
	BN_init(&one);
	BN_one(&one);

	BIGNUM* temp_p = BN_dup(p);
	BIGNUM* temp_q = BN_dup(q);

	BN_sub_word(temp_p, 1);
	BN_sub_word(temp_q, 1);

	BN_CTX* ctx = BN_CTX_new();

	BN_mul(totient, temp_p, temp_q, ctx);

	BN_free(temp_p);
	BN_free(temp_q);
	BN_CTX_free(ctx);

	return 1;
}
コード例 #11
0
ファイル: rsa_sp800_56b_test.c プロジェクト: Ana06/openssl
static int test_check_public_key(void)
{
    int ret = 0;
    BIGNUM *n = NULL, *e = NULL;
    RSA *key = NULL;

    ret = TEST_ptr(key = RSA_new())
          /* check NULL pointers fail */
          && TEST_false(rsa_sp800_56b_check_public(key))
          /* load public key */
          && TEST_ptr(e = bn_load_new(cav_e, sizeof(cav_e)))
          && TEST_ptr(n = bn_load_new(cav_n, sizeof(cav_n)))
          && TEST_true(RSA_set0_key(key, n, e, NULL));
    if (!ret) {
        BN_free(e);
        BN_free(n);
        goto end;
    }
    /* check public key is valid */
    ret = TEST_true(rsa_sp800_56b_check_public(key))
          /* check fail if n is even */
          && TEST_true(BN_add_word(n, 1))
          && TEST_false(rsa_sp800_56b_check_public(key))
          && TEST_true(BN_sub_word(n, 1))
          /* check fail if n is wrong number of bits */
          && TEST_true(BN_lshift1(n, n))
          && TEST_false(rsa_sp800_56b_check_public(key))
          && TEST_true(BN_rshift1(n, n))
          /* test odd exponent fails */
          && TEST_true(BN_add_word(e, 1))
          && TEST_false(rsa_sp800_56b_check_public(key))
          && TEST_true(BN_sub_word(e, 1))
          /* modulus fails composite check */
          && TEST_true(BN_add_word(n, 2))
          && TEST_false(rsa_sp800_56b_check_public(key));
end:
    RSA_free(key);
    return ret;
}
コード例 #12
0
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
{
    BIGNUM Ri,*R;

    BN_init(&Ri);
    R= &(mont->RR);					/* grab RR as a temp */
    BN_copy(&(mont->N),mod);			/* Set N */

    {
        BIGNUM tmod;
        BN_ULONG buf[2];

        mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
        if (!(BN_zero(R))) goto err;
        if (!(BN_set_bit(R,BN_BITS2))) goto err;	/* R */

        buf[0]=mod->d[0]; /* tmod = N mod word size */
        buf[1]=0;
        tmod.d=buf;
        tmod.top=1;
        tmod.dmax=2;
        tmod.neg=mod->neg;
        /* Ri = R^-1 mod N*/
        if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL)
            goto err;
        /* R*Ri */
        if (!(BN_lshift(&Ri,&Ri,BN_BITS2))) goto err;
        if (!BN_is_zero(&Ri))
        {
            if (!BN_sub_word(&Ri,1)) goto err;
        }
        else /* if N mod word size == 1 */
            /* Ri-- (mod word size) */
        {
            if (!BN_set_word(&Ri,BN_MASK2)) goto err;
        }
        /* Ni = (R*Ri-1)/N, keep only least significant word: */
        if (!(BN_div(&Ri,NULL,&Ri,&tmod,ctx))) goto err;
        mont->n0=Ri.d[0];
        BN_free(&Ri);
    }

    /* setup RR for conversions */
    if (!(BN_zero(&(mont->RR)))) goto err;
    if (!(BN_set_bit(&(mont->RR),mont->ri*2))) goto err;
    if (!(BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx))) goto err;

    return(1);
err:
    return(0);
}
コード例 #13
0
ファイル: factor.c プロジェクト: edgar-pek/PerspicuOS
/* pollard p-1, algorithm from Jim Gillogly, May 2000 */
static void
pollard_pminus1(BIGNUM *val)
{
	BIGNUM *base, *rbase, *num, *i, *x;

	base = BN_new();
	rbase = BN_new();
	num = BN_new();
	i = BN_new();
	x = BN_new();

	BN_set_word(rbase, 1);
newbase:
	if (!BN_add_word(rbase, 1))
		errx(1, "error in BN_add_word()");
	BN_set_word(i, 2);
	BN_copy(base, rbase);

	for (;;) {
		BN_mod_exp(base, base, i, val, ctx);
		if (BN_is_one(base))
			goto newbase;

		BN_copy(x, base);
		BN_sub_word(x, 1);
		if (!BN_gcd(x, x, val, ctx))
			errx(1, "error in BN_gcd()");

		if (!BN_is_one(x)) {
			if (BN_is_prime(x, PRIME_CHECKS, NULL, NULL,
			    NULL) == 1)
				pr_print(x);
			else
				pollard_pminus1(x);
			fflush(stdout);

			BN_div(num, NULL, val, x, ctx);
			if (BN_is_one(num))
				return;
			if (BN_is_prime(num, PRIME_CHECKS, NULL, NULL,
			    NULL) == 1) {
				pr_print(num);
				fflush(stdout);
				return;
			}
			BN_copy(val, num);
		}
		if (!BN_add_word(i, 1))
			errx(1, "error in BN_add_word()");
	}
}
コード例 #14
0
ファイル: check.c プロジェクト: alagoutte/proto-quic
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) {
  *ret = 0;

  BN_CTX *ctx = BN_CTX_new();
  if (ctx == NULL) {
    return 0;
  }
  BN_CTX_start(ctx);

  int ok = 0;

  /* Check |pub_key| is greater than 1. */
  BIGNUM *tmp = BN_CTX_get(ctx);
  if (tmp == NULL ||
      !BN_set_word(tmp, 1)) {
    goto err;
  }
  if (BN_cmp(pub_key, tmp) <= 0) {
    *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
  }

  /* Check |pub_key| is less than |dh->p| - 1. */
  if (!BN_copy(tmp, dh->p) ||
      !BN_sub_word(tmp, 1)) {
    goto err;
  }
  if (BN_cmp(pub_key, tmp) >= 0) {
    *ret |= DH_CHECK_PUBKEY_TOO_LARGE;
  }

  if (dh->q != NULL) {
    /* Check |pub_key|^|dh->q| is 1 mod |dh->p|. This is necessary for RFC 5114
     * groups which are not safe primes but pick a generator on a prime-order
     * subgroup of size |dh->q|. */
    if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx)) {
      goto err;
    }
    if (!BN_is_one(tmp)) {
      *ret |= DH_CHECK_PUBKEY_INVALID;
    }
  }

  ok = 1;

err:
  BN_CTX_end(ctx);
  BN_CTX_free(ctx);
  return ok;
}
コード例 #15
0
// http://stackoverflow.com/questions/356090/how-to-compute-the-nth-root-of-a-very-big-integer
static BIGNUM *nearest_cuberoot(BIGNUM *in)
{
    BN_CTX *ctx = BN_CTX_new();
    BN_CTX_start(ctx);

    BIGNUM *three = BN_CTX_get(ctx);
    BIGNUM *high = BN_CTX_get(ctx);
    BIGNUM *mid = BN_CTX_get(ctx);
    BIGNUM *low = BN_CTX_get(ctx);
    BIGNUM *tmp = BN_CTX_get(ctx);

    BN_set_word(three, 3);                                         // Create the constant 3
    BN_set_word(high, 1);                                          // high = 1

    do
    {
        BN_lshift1(high, high);                                    // high = high << 1 (high * 2)
        BN_exp(tmp, high, three, ctx);                             // tmp = high^3
    } while (BN_ucmp(tmp, in) <= -1);                              // while (tmp < in)

    BN_rshift1(low, high);                                         // low = high >> 1 (high / 2)

    while (BN_ucmp(low, high) <= -1)                               // while (low < high)
    {
        BN_add(tmp, low, high);                                    // tmp = low + high
        BN_rshift1(mid, tmp);                                      // mid = tmp >> 1 (tmp / 2)
        BN_exp(tmp, mid, three, ctx);                              // tmp = mid^3
        if (BN_ucmp(low, mid) <= -1 && BN_ucmp(tmp, in) <= -1)     // if (low < mid && tmp < in)
            BN_copy(low, mid);                                     // low = mid
        else if (BN_ucmp(high, mid) >= 1 && BN_ucmp(tmp, in) >= 1) // else if (high > mid && tmp > in)
            BN_copy(high, mid);                                    // high = mid
        else
        {
            // subtract 1 from mid because 1 will be added after the loop
            BN_sub_word(mid, 1);                                   // mid -= 1
            break;
        }
    }

    BN_add_word(mid, 1);                                           // mid += 1

    BIGNUM *result = BN_dup(mid);

    BN_CTX_end(ctx);
    BN_CTX_free(ctx);

    return result;
}
コード例 #16
0
ファイル: bn_word.c プロジェクト: yyyyyao/Slicer3-lib-mirrors
int BN_add_word(BIGNUM *a, BN_ULONG w)
  {
  BN_ULONG l;
  int i;

  bn_check_top(a);
  w &= BN_MASK2;

  /* degenerate case: w is zero */
  if (!w) return 1;
  /* degenerate case: a is zero */
  if(BN_is_zero(a)) return BN_set_word(a, w);
  /* handle 'a' when negative */
  if (a->neg)
    {
    a->neg=0;
    i=BN_sub_word(a,w);
    if (!BN_is_zero(a))
      a->neg=!(a->neg);
    return(i);
    }
  /* Only expand (and risk failing) if it's possibly necessary */
  if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) &&
      (bn_wexpand(a,a->top+1) == NULL))
    return(0);
  i=0;
  for (;;)
    {
    if (i >= a->top)
      l=w;
    else
      l=(a->d[i]+w)&BN_MASK2;
    a->d[i]=l;
    if (w > l)
      w=1;
    else
      break;
    i++;
    }
  if (i >= a->top)
    a->top++;
  bn_check_top(a);
  return(1);
  }
コード例 #17
0
BIGNUM *
DH_get_q(const DH *dh, BN_CTX *ctx)
{
    BIGNUM *q_new = NULL, *bn = NULL;
    int i;
    const BIGNUM *p, *q;

    check(dh, "Invalid arguments");

    DH_get0_pqg(dh, &p, &q, NULL);
    if (!q) {
        q_new = BN_new();
        bn = BN_dup(p);

        /* DH primes should be strong, based on a Sophie Germain prime q
         * p=(2*q)+1 or (p-1)/2=q */
        if (!q_new || !bn ||
                !BN_sub_word(bn, 1) ||
                !BN_rshift1(q_new, bn)) {
            goto err;
        }
    } else {
        q_new = BN_dup(q);
    }

    /* q should always be prime */
    i = BN_is_prime_ex(q_new, BN_prime_checks, ctx, NULL);
    if (i <= 0) {
       if (i == 0)
          log_err("Unable to get Sophie Germain prime");
       goto err;
    }

    return q_new;

err:
    if (bn)
        BN_clear_free(bn);
    if (q_new)
        BN_clear_free(q_new);

    return NULL;
}
コード例 #18
0
/* Generate each party's random numbers. xa is in [0, q), xb is in [1, q). */
static void genrand(JPAKE_CTX *ctx)
    {
    BIGNUM *qm1;

   /* xa in [0, q) */
    BN_rand_range(ctx->xa, ctx->p.q);

   /* q-1 */
    qm1 = BN_new();
    BN_copy(qm1, ctx->p.q);
    BN_sub_word(qm1, 1);

   /* ... and xb in [0, q-1) */
    BN_rand_range(ctx->xb, qm1);
   /* [1, q) */
    BN_add_word(ctx->xb, 1);

   /* cleanup */
    BN_free(qm1);
    }
コード例 #19
0
ファイル: dh_check.c プロジェクト: MiKTeX/miktex
int
DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
{
	BIGNUM *q = NULL;

	*ret = 0;
	q = BN_new();
	if (q == NULL)
		return 0;
	BN_set_word(q, 1);
	if (BN_cmp(pub_key, q) <= 0)
		*ret |= DH_CHECK_PUBKEY_TOO_SMALL;
	BN_copy(q, dh->p);
	BN_sub_word(q, 1);
	if (BN_cmp(pub_key, q) >= 0)
		*ret |= DH_CHECK_PUBKEY_TOO_LARGE;

	BN_free(q);
	return 1;
}
コード例 #20
0
ファイル: dh_check.c プロジェクト: RafaelRMachado/MinnowBoard
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
	{
	int ok=0;
	BIGNUM *q=NULL;

	*ret=0;
	q=BN_new();
	if (q == NULL) goto err;
	BN_set_word(q,1);
	if (BN_cmp(pub_key,q) <= 0)
		*ret|=DH_CHECK_PUBKEY_TOO_SMALL;
	BN_copy(q,dh->p);
	BN_sub_word(q,1);
	if (BN_cmp(pub_key,q) >= 0)
		*ret|=DH_CHECK_PUBKEY_TOO_LARGE;

	ok = 1;
err:
	if (q != NULL) BN_free(q);
	return(ok);
	}
コード例 #21
0
// For key generation
static int L(BIGNUM *res, const BIGNUM *u, const BIGNUM *n, BN_CTX *ctx)
{
    int ret = 1;

    BIGNUM *u_cp = BN_dup(u);
    if (!BN_sub_word(u_cp, 1))
        goto end;
    if (!BN_div(res, NULL, u_cp, n, ctx))
        goto end;

    ret = 0;
end:
    if (ret)
    {
        ERR_load_crypto_strings();
        fprintf(stderr, "Error calculating L: %s", ERR_error_string(ERR_get_error(), NULL));
    } 

    BN_free(u_cp);
    return ret;
}
コード例 #22
0
ファイル: add.c プロジェクト: aaqib123/angular_shoppingcart
int BN_add_word(BIGNUM *a, BN_ULONG w) {
  BN_ULONG l;
  int i;

  // degenerate case: w is zero
  if (!w) {
    return 1;
  }

  // degenerate case: a is zero
  if (BN_is_zero(a)) {
    return BN_set_word(a, w);
  }

  // handle 'a' when negative
  if (a->neg) {
    a->neg = 0;
    i = BN_sub_word(a, w);
    if (!BN_is_zero(a)) {
      a->neg = !(a->neg);
    }
    return i;
  }

  for (i = 0; w != 0 && i < a->width; i++) {
    a->d[i] = l = a->d[i] + w;
    w = (w > l) ? 1 : 0;
  }

  if (w && i == a->width) {
    if (!bn_wexpand(a, a->width + 1)) {
      return 0;
    }
    a->width++;
    a->d[i] = w;
  }

  return 1;
}
コード例 #23
0
BIGNUM *
DH_get_order(const DH *dh, BN_CTX *ctx)
{
    BIGNUM *order = NULL, *bn = NULL;
    const BIGNUM *p, *g;

    check(dh && ctx, "Invalid argument");

    BN_CTX_start(ctx);

    DH_get0_pqg(dh, &p, NULL, &g);

    /* suppose the order of g is q-1 */
    order = DH_get_q(dh, ctx);
    bn = BN_CTX_get(ctx);
    if (!bn || !order || !BN_sub_word(order, 1)
          || !BN_mod_exp(bn, g, order, p, ctx))
        goto err;

    if (BN_cmp(bn, BN_value_one()) != 0) {
        /* if bn != 1, then q-1 is not the order of g, but p-1 should be */
        if (!BN_sub(order, p, BN_value_one()) ||
              !BN_mod_exp(bn, g, order, p, ctx))
           goto err;
        check(BN_cmp(bn, BN_value_one()) == 0, "Unable to get order");
    }

    BN_CTX_end(ctx);

    return order;

err:
    if (order)
        BN_clear_free(order);
    BN_CTX_end(ctx);

    return NULL;
}
コード例 #24
0
ファイル: dh_check.c プロジェクト: 03050903/godot
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
{
    int ok = 0;
    BIGNUM *tmp = NULL;
    BN_CTX *ctx = NULL;

    *ret = 0;
    ctx = BN_CTX_new();
    if (ctx == NULL)
        goto err;
    BN_CTX_start(ctx);
    tmp = BN_CTX_get(ctx);
    if (tmp == NULL || !BN_set_word(tmp, 1))
        goto err;
    if (BN_cmp(pub_key, tmp) <= 0)
        *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
    if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1))
        goto err;
    if (BN_cmp(pub_key, tmp) >= 0)
        *ret |= DH_CHECK_PUBKEY_TOO_LARGE;

    if (dh->q != NULL) {
        /* Check pub_key^q == 1 mod p */
        if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx))
            goto err;
        if (!BN_is_one(tmp))
            *ret |= DH_CHECK_PUBKEY_INVALID;
    }

    ok = 1;
 err:
    if (ctx != NULL) {
        BN_CTX_end(ctx);
        BN_CTX_free(ctx);
    }
    return (ok);
}
コード例 #25
0
ファイル: bn_prime.c プロジェクト: xyzy/mips-openssl_0.9.7
int BN_is_prime_fasttest(const BIGNUM *a, int checks,
		void (*callback)(int,int,void *),
		BN_CTX *ctx_passed, void *cb_arg,
		int do_trial_division)
	{
	int i, j, ret = -1;
	int k;
	BN_CTX *ctx = NULL;
	BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
	BN_MONT_CTX *mont = NULL;
	const BIGNUM *A = NULL;

	if (BN_cmp(a, BN_value_one()) <= 0)
		return 0;
	
	if (checks == BN_prime_checks)
		checks = BN_prime_checks_for_size(BN_num_bits(a));

	/* first look for small factors */
	if (!BN_is_odd(a))
		return 0;
	if (do_trial_division)
		{
		for (i = 1; i < NUMPRIMES; i++)
			if (BN_mod_word(a, primes[i]) == 0) 
				return 0;
		if (callback != NULL) callback(1, -1, cb_arg);
		}

	if (ctx_passed != NULL)
		ctx = ctx_passed;
	else
		if ((ctx=BN_CTX_new()) == NULL)
			goto err;
	BN_CTX_start(ctx);

	/* A := abs(a) */
	if (a->neg)
		{
		BIGNUM *t;
		if ((t = BN_CTX_get(ctx)) == NULL) goto err;
		BN_copy(t, a);
		t->neg = 0;
		A = t;
		}
	else
		A = a;
	A1 = BN_CTX_get(ctx);
	A1_odd = BN_CTX_get(ctx);
	check = BN_CTX_get(ctx);
	if (check == NULL) goto err;

	/* compute A1 := A - 1 */
	if (!BN_copy(A1, A))
		goto err;
	if (!BN_sub_word(A1, 1))
		goto err;
	if (BN_is_zero(A1))
		{
		ret = 0;
		goto err;
		}

	/* write  A1  as  A1_odd * 2^k */
	k = 1;
	while (!BN_is_bit_set(A1, k))
		k++;
	if (!BN_rshift(A1_odd, A1, k))
		goto err;

	/* Montgomery setup for computations mod A */
	mont = BN_MONT_CTX_new();
	if (mont == NULL)
		goto err;
	if (!BN_MONT_CTX_set(mont, A, ctx))
		goto err;
	
	for (i = 0; i < checks; i++)
		{
		if (!BN_pseudo_rand_range(check, A1))
			goto err;
		if (!BN_add_word(check, 1))
			goto err;
		/* now 1 <= check < A */

		j = witness(check, A, A1, A1_odd, k, ctx, mont);
		if (j == -1) goto err;
		if (j)
			{
			ret=0;
			goto err;
			}
		if (callback != NULL) callback(1,i,cb_arg);
		}
	ret=1;
err:
	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		if (ctx_passed == NULL)
			BN_CTX_free(ctx);
		}
	if (mont != NULL)
		BN_MONT_CTX_free(mont);

	return(ret);
	}
コード例 #26
0
ファイル: bn_mont.c プロジェクト: mr-moai-2016/znk_project
int
BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
{
	int ret = 0;
	BIGNUM *Ri, *R;

	BN_CTX_start(ctx);
	if ((Ri = BN_CTX_get(ctx)) == NULL)
		goto err;
	R = &(mont->RR);				/* grab RR as a temp */
	if (!BN_copy(&(mont->N), mod))
		 goto err;				/* Set N */
	mont->N.neg = 0;

#ifdef MONT_WORD
	{
		BIGNUM tmod;
		BN_ULONG buf[2];

		BN_init(&tmod);
		tmod.d = buf;
		tmod.dmax = 2;
		tmod.neg = 0;

		mont->ri = (BN_num_bits(mod) +
		    (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;

#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
		/* Only certain BN_BITS2<=32 platforms actually make use of
		 * n0[1], and we could use the #else case (with a shorter R
		 * value) for the others.  However, currently only the assembler
		 * files do know which is which. */

		BN_zero(R);
		if (!(BN_set_bit(R, 2 * BN_BITS2)))
			goto err;

		tmod.top = 0;
		if ((buf[0] = mod->d[0]))
			tmod.top = 1;
		if ((buf[1] = mod->top > 1 ? mod->d[1] : 0))
			tmod.top = 2;

		if ((BN_mod_inverse_ct(Ri, R, &tmod, ctx)) == NULL)
			goto err;
		if (!BN_lshift(Ri, Ri, 2 * BN_BITS2))
			goto err; /* R*Ri */
		if (!BN_is_zero(Ri)) {
			if (!BN_sub_word(Ri, 1))
				goto err;
		}
		else /* if N mod word size == 1 */
		{
			if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL)
				goto err;
			/* Ri-- (mod double word size) */
			Ri->neg = 0;
			Ri->d[0] = BN_MASK2;
			Ri->d[1] = BN_MASK2;
			Ri->top = 2;
		}
		if (!BN_div_ct(Ri, NULL, Ri, &tmod, ctx))
			goto err;
		/* Ni = (R*Ri-1)/N,
		 * keep only couple of least significant words: */
		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
		mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
#else
		BN_zero(R);
		if (!(BN_set_bit(R, BN_BITS2)))
			goto err;	/* R */

		buf[0] = mod->d[0]; /* tmod = N mod word size */
		buf[1] = 0;
		tmod.top = buf[0] != 0 ? 1 : 0;
		/* Ri = R^-1 mod N*/
		if ((BN_mod_inverse_ct(Ri, R, &tmod, ctx)) == NULL)
			goto err;
		if (!BN_lshift(Ri, Ri, BN_BITS2))
			goto err; /* R*Ri */
		if (!BN_is_zero(Ri)) {
			if (!BN_sub_word(Ri, 1))
				goto err;
		}
		else /* if N mod word size == 1 */
		{
			if (!BN_set_word(Ri, BN_MASK2))
				goto err;  /* Ri-- (mod word size) */
		}
		if (!BN_div_ct(Ri, NULL, Ri, &tmod, ctx))
			goto err;
		/* Ni = (R*Ri-1)/N,
		 * keep only least significant word: */
		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
		mont->n0[1] = 0;
#endif
	}
#else /* !MONT_WORD */
	{ /* bignum version */
		mont->ri = BN_num_bits(&mont->N);
		BN_zero(R);
		if (!BN_set_bit(R, mont->ri))
			goto err;  /* R = 2^ri */
		/* Ri = R^-1 mod N*/
		if ((BN_mod_inverse_ct(Ri, R, &mont->N, ctx)) == NULL)
			goto err;
		if (!BN_lshift(Ri, Ri, mont->ri))
			goto err; /* R*Ri */
		if (!BN_sub_word(Ri, 1))
			goto err;
		/* Ni = (R*Ri-1) / N */
		if (!BN_div_ct(&(mont->Ni), NULL, Ri, &mont->N, ctx))
			goto err;
	}
#endif

	/* setup RR for conversions */
	BN_zero(&(mont->RR));
	if (!BN_set_bit(&(mont->RR), mont->ri*2))
		goto err;
	if (!BN_mod_ct(&(mont->RR), &(mont->RR), &(mont->N), ctx))
		goto err;

	ret = 1;

err:
	BN_CTX_end(ctx);
	return ret;
}
コード例 #27
0
BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 
/* Returns 'ret' such that
 *      ret^2 == a (mod p),
 * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course
 * in Algebraic Computational Number Theory", algorithm 1.5.1).
 * 'p' must be prime!
 */
	{
	BIGNUM *ret = in;
	int err = 1;
	int r;
	BIGNUM *A, *b, *q, *t, *x, *y;
	int e, i, j;
	
	if (!BN_is_odd(p) || BN_abs_is_word(p, 1))
		{
		if (BN_abs_is_word(p, 2))
			{
			if (ret == NULL)
				ret = BN_new();
			if (ret == NULL)
				goto end;
			if (!BN_set_word(ret, BN_is_bit_set(a, 0)))
				{
				if (ret != in)
					BN_free(ret);
				return NULL;
				}
			bn_check_top(ret);
			return ret;
			}

		BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
		return(NULL);
		}

	if (BN_is_zero(a) || BN_is_one(a))
		{
		if (ret == NULL)
			ret = BN_new();
		if (ret == NULL)
			goto end;
		if (!BN_set_word(ret, BN_is_one(a)))
			{
			if (ret != in)
				BN_free(ret);
			return NULL;
			}
		bn_check_top(ret);
		return ret;
		}

	BN_CTX_start(ctx);
	A = BN_CTX_get(ctx);
	b = BN_CTX_get(ctx);
	q = BN_CTX_get(ctx);
	t = BN_CTX_get(ctx);
	x = BN_CTX_get(ctx);
	y = BN_CTX_get(ctx);
	if (y == NULL) goto end;
	
	if (ret == NULL)
		ret = BN_new();
	if (ret == NULL) goto end;

	/* A = a mod p */
	if (!BN_nnmod(A, a, p, ctx)) goto end;

	/* now write  |p| - 1  as  2^e*q  where  q  is odd */
	e = 1;
	while (!BN_is_bit_set(p, e))
		e++;
	/* we'll set  q  later (if needed) */

	if (e == 1)
		{
		/* The easy case:  (|p|-1)/2  is odd, so 2 has an inverse
		 * modulo  (|p|-1)/2,  and square roots can be computed
		 * directly by modular exponentiation.
		 * We have
		 *     2 * (|p|+1)/4 == 1   (mod (|p|-1)/2),
		 * so we can use exponent  (|p|+1)/4,  i.e.  (|p|-3)/4 + 1.
		 */
		if (!BN_rshift(q, p, 2)) goto end;
		q->neg = 0;
		if (!BN_add_word(q, 1)) goto end;
		if (!BN_mod_exp(ret, A, q, p, ctx)) goto end;
		err = 0;
		goto vrfy;
		}
	
	if (e == 2)
		{
		/* |p| == 5  (mod 8)
		 *
		 * In this case  2  is always a non-square since
		 * Legendre(2,p) = (-1)^((p^2-1)/8)  for any odd prime.
		 * So if  a  really is a square, then  2*a  is a non-square.
		 * Thus for
		 *      b := (2*a)^((|p|-5)/8),
		 *      i := (2*a)*b^2
		 * we have
		 *     i^2 = (2*a)^((1 + (|p|-5)/4)*2)
		 *         = (2*a)^((p-1)/2)
		 *         = -1;
		 * so if we set
		 *      x := a*b*(i-1),
		 * then
		 *     x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
		 *         = a^2 * b^2 * (-2*i)
		 *         = a*(-i)*(2*a*b^2)
		 *         = a*(-i)*i
		 *         = a.
		 *
		 * (This is due to A.O.L. Atkin, 
		 * <URL: http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>,
		 * November 1992.)
		 */

		/* t := 2*a */
		if (!BN_mod_lshift1_quick(t, A, p)) goto end;

		/* b := (2*a)^((|p|-5)/8) */
		if (!BN_rshift(q, p, 3)) goto end;
		q->neg = 0;
		if (!BN_mod_exp(b, t, q, p, ctx)) goto end;

		/* y := b^2 */
		if (!BN_mod_sqr(y, b, p, ctx)) goto end;

		/* t := (2*a)*b^2 - 1*/
		if (!BN_mod_mul(t, t, y, p, ctx)) goto end;
		if (!BN_sub_word(t, 1)) goto end;

		/* x = a*b*t */
		if (!BN_mod_mul(x, A, b, p, ctx)) goto end;
		if (!BN_mod_mul(x, x, t, p, ctx)) goto end;

		if (!BN_copy(ret, x)) goto end;
		err = 0;
		goto vrfy;
		}
	
	/* e > 2, so we really have to use the Tonelli/Shanks algorithm.
	 * First, find some  y  that is not a square. */
	if (!BN_copy(q, p)) goto end; /* use 'q' as temp */
	q->neg = 0;
	i = 2;
	do
		{
		/* For efficiency, try small numbers first;
		 * if this fails, try random numbers.
		 */
		if (i < 22)
			{
			if (!BN_set_word(y, i)) goto end;
			}
		else
			{
			if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) goto end;
			if (BN_ucmp(y, p) >= 0)
				{
				if (!(p->neg ? BN_add : BN_sub)(y, y, p)) goto end;
				}
			/* now 0 <= y < |p| */
			if (BN_is_zero(y))
				if (!BN_set_word(y, i)) goto end;
			}
		
		r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
		if (r < -1) goto end;
		if (r == 0)
			{
			/* m divides p */
			BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
			goto end;
			}
		}
	while (r == 1 && ++i < 82);
	
	if (r != -1)
		{
		/* Many rounds and still no non-square -- this is more likely
		 * a bug than just bad luck.
		 * Even if  p  is not prime, we should have found some  y
		 * such that r == -1.
		 */
		BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS);
		goto end;
		}

	/* Here's our actual 'q': */
	if (!BN_rshift(q, q, e)) goto end;

	/* Now that we have some non-square, we can find an element
	 * of order  2^e  by computing its q'th power. */
	if (!BN_mod_exp(y, y, q, p, ctx)) goto end;
	if (BN_is_one(y))
		{
		BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
		goto end;
		}

	/* Now we know that (if  p  is indeed prime) there is an integer
	 * k,  0 <= k < 2^e,  such that
	 *
	 *      a^q * y^k == 1   (mod p).
	 *
	 * As  a^q  is a square and  y  is not,  k  must be even.
	 * q+1  is even, too, so there is an element
	 *
	 *     X := a^((q+1)/2) * y^(k/2),
	 *
	 * and it satisfies
	 *
	 *     X^2 = a^q * a     * y^k
	 *         = a,
	 *
	 * so it is the square root that we are looking for.
	 */
	
	/* t := (q-1)/2  (note that  q  is odd) */
	if (!BN_rshift1(t, q)) goto end;
	
	/* x := a^((q-1)/2) */
	if (BN_is_zero(t)) /* special case: p = 2^e + 1 */
		{
		if (!BN_nnmod(t, A, p, ctx)) goto end;
		if (BN_is_zero(t))
			{
			/* special case: a == 0  (mod p) */
			BN_zero(ret);
			err = 0;
			goto end;
			}
		else
			if (!BN_one(x)) goto end;
		}
	else
		{
		if (!BN_mod_exp(x, A, t, p, ctx)) goto end;
		if (BN_is_zero(x))
			{
			/* special case: a == 0  (mod p) */
			BN_zero(ret);
			err = 0;
			goto end;
			}
		}

	/* b := a*x^2  (= a^q) */
	if (!BN_mod_sqr(b, x, p, ctx)) goto end;
	if (!BN_mod_mul(b, b, A, p, ctx)) goto end;
	
	/* x := a*x    (= a^((q+1)/2)) */
	if (!BN_mod_mul(x, x, A, p, ctx)) goto end;

	while (1)
		{
		/* Now  b  is  a^q * y^k  for some even  k  (0 <= k < 2^E
		 * where  E  refers to the original value of  e,  which we
		 * don't keep in a variable),  and  x  is  a^((q+1)/2) * y^(k/2).
		 *
		 * We have  a*b = x^2,
		 *    y^2^(e-1) = -1,
		 *    b^2^(e-1) = 1.
		 */

		if (BN_is_one(b))
			{
			if (!BN_copy(ret, x)) goto end;
			err = 0;
			goto vrfy;
			}


		/* find smallest  i  such that  b^(2^i) = 1 */
		i = 1;
		if (!BN_mod_sqr(t, b, p, ctx)) goto end;
		while (!BN_is_one(t))
			{
			i++;
			if (i == e)
				{
				BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
				goto end;
				}
			if (!BN_mod_mul(t, t, t, p, ctx)) goto end;
			}
		

		/* t := y^2^(e - i - 1) */
		if (!BN_copy(t, y)) goto end;
		for (j = e - i - 1; j > 0; j--)
			{
			if (!BN_mod_sqr(t, t, p, ctx)) goto end;
			}
		if (!BN_mod_mul(y, t, t, p, ctx)) goto end;
		if (!BN_mod_mul(x, x, t, p, ctx)) goto end;
		if (!BN_mod_mul(b, b, y, p, ctx)) goto end;
		e = i;
		}

 vrfy:
	if (!err)
		{
		/* verify the result -- the input might have been not a square
		 * (test added in 0.9.8) */
		
		if (!BN_mod_sqr(x, ret, p, ctx))
			err = 1;
		
		if (!err && 0 != BN_cmp(x, A))
			{
			BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
			err = 1;
			}
		}

 end:
	if (err)
		{
		if (ret != NULL && ret != in)
			{
			BN_clear_free(ret);
			}
		ret = NULL;
		}
	BN_CTX_end(ctx);
	bn_check_top(ret);
	return ret;
	}
コード例 #28
0
ファイル: bn_x931p.c プロジェクト: Heratom/Firefly-project
int
BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, const BIGNUM *Xp,
    const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
    BN_GENCB *cb)
{
	int ret = 0;

	BIGNUM *t, *p1p2, *pm1;

	/* Only even e supported */
	if (!BN_is_odd(e))
		return 0;

	BN_CTX_start(ctx);
	if (p1 == NULL) {
		if ((p1 = BN_CTX_get(ctx)) == NULL)
			goto err;
	}
	if (p2 == NULL) {
		if ((p2 = BN_CTX_get(ctx)) == NULL)
			goto err;
	}

	if ((t = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((p1p2 = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((pm1 = BN_CTX_get(ctx)) == NULL)
		goto err;

	if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
		goto err;

	if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
		goto err;

	if (!BN_mul(p1p2, p1, p2, ctx))
		goto err;

	/* First set p to value of Rp */

	if (!BN_mod_inverse(p, p2, p1, ctx))
		goto err;

	if (!BN_mul(p, p, p2, ctx))
		goto err;

	if (!BN_mod_inverse(t, p1, p2, ctx))
		goto err;

	if (!BN_mul(t, t, p1, ctx))
		goto err;

	if (!BN_sub(p, p, t))
		goto err;

	if (p->neg && !BN_add(p, p, p1p2))
		goto err;

	/* p now equals Rp */

	if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
		goto err;

	if (!BN_add(p, p, Xp))
		goto err;

	/* p now equals Yp0 */

	for (;;) {
		int i = 1;
		BN_GENCB_call(cb, 0, i++);
		if (!BN_copy(pm1, p))
			goto err;
		if (!BN_sub_word(pm1, 1))
			goto err;
		if (!BN_gcd(t, pm1, e, ctx))
			goto err;
		if (BN_is_one(t)
		/* X9.31 specifies 8 MR and 1 Lucas test or any prime test
		 * offering similar or better guarantees 50 MR is considerably
		 * better.
		 */
		    && BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb))
			break;
		if (!BN_add(p, p, p1p2))
			goto err;
	}

	BN_GENCB_call(cb, 3, 0);

	ret = 1;

err:

	BN_CTX_end(ctx);

	return ret;
}
コード例 #29
0
int generateRandomKeys(paillierKeys *keys, int *key_len, BN_CTX *ctx)
{
    int ret = 1, final_key_l = 0;
    BIGNUM *p, *q, *tmp, *n, *n2, *g, *lamda, *mu;

    if (key_len != NULL && *key_len == 0)
    {
        *key_len = DEFAULT_KEY_LEN;
        final_key_l = *key_len;
    }
    else if (key_len != NULL)
    {
        final_key_l = *key_len;
    }
    else
    {
        final_key_l = DEFAULT_KEY_LEN;
    }

    if (final_key_l < 32)
    {
        fprintf(stderr, "Key lenght too short. Minimum lenght 32 bits");
        goto end;
    }

    BN_CTX_start(ctx);

    // Temp BIGNUMs
    p = BN_CTX_get(ctx);
    q = BN_CTX_get(ctx);
    tmp = BN_CTX_get(ctx);

    // Part of the keys BIGNUMs
    n = BN_new();
    n2 = BN_new();
    g = BN_new();
    lamda = BN_new();
    mu = BN_new();

    // 1. Choose two large prime numbers
    // This numbers have to hold gcd(pq, (p-1)(q-1)) = 1
    unsigned char buffer;
    do
    {
        if (!RAND_bytes(&buffer, sizeof(buffer)))
            goto end;
        srandom((int)buffer);

        if (!BN_generate_prime_ex(p, final_key_l / 2, 0, NULL, NULL, NULL))
            goto end;
        if (!BN_generate_prime_ex(q, final_key_l / 2, 0, NULL, NULL, NULL))
            goto end;

        // 2. Compute n = pq
        if (!BN_mul(n, p, q, ctx))
            goto end;

        // Test if primes are ok
        if (!BN_sub_word(p, 1))
            goto end;
        if (!BN_sub_word(q, 1))
            goto end;
        if (!BN_mul(tmp, p, q, ctx))
            goto end;

    }
    while (BN_cmp(p, q) == 0 || BN_gcd(tmp, tmp, n, ctx) != 1);

    // and lamda = lcm(p-1,q-1)
    if (!BN_lcm(lamda, p, q, ctx))
        goto end;

    if (!BN_mul(n2, n, n, ctx))
        goto end;
    do
    {
        // 3. Select a random integer g moz n2
        do
        {
            if (!BN_rand_range(g, n2))
                goto end;
        }
        while (BN_is_zero(g));

        // 4. Ensure n divides the order of g
        if (!BN_mod_exp(tmp, g, lamda, n2, ctx))
            goto end;
        if (L(tmp, tmp, n, ctx) != 0)
            goto end;

        BN_mod_inverse(mu, tmp, n, ctx);
    }
    while (mu == NULL);

    keys->pub.n = n;
    keys->pub.n2 = n2;
    keys->pub.g = g;

    keys->priv.n = BN_dup(n);
    keys->priv.n2 = BN_dup(n2);
    keys->priv.lamda = lamda;
    keys->priv.mu = mu;

    keys->n = BN_dup(n);
    keys->n2 = BN_dup(n2);

    ret = 0;
end:
    if (ret)
    {
        ERR_load_crypto_strings();
        fprintf(stderr, "Error generating keys: %s", ERR_error_string(ERR_get_error(), NULL));
    }

    BN_CTX_end(ctx);
    return ret;
}
コード例 #30
0
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
	{
	int ret = 0;
	BIGNUM *Ri,*R;

	BN_CTX_start(ctx);
	if((Ri = BN_CTX_get(ctx)) == NULL) goto err;
	R= &(mont->RR);					/* grab RR as a temp */
	if (!BN_copy(&(mont->N),mod)) goto err;		/* Set N */
	mont->N.neg = 0;

#ifdef MONT_WORD
		{
		BIGNUM tmod;
		BN_ULONG buf[2];

		mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
		BN_zero(R);
		if (!(BN_set_bit(R,BN_BITS2))) goto err;	/* R */

		buf[0]=mod->d[0]; /* tmod = N mod word size */
		buf[1]=0;
		tmod.d=buf;
		tmod.top = buf[0] != 0 ? 1 : 0;
		tmod.dmax=2;
		tmod.neg=0;
							/* Ri = R^-1 mod N*/
		if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
			goto err;
		if (!BN_lshift(Ri,Ri,BN_BITS2)) goto err; /* R*Ri */
		if (!BN_is_zero(Ri))
			{
			if (!BN_sub_word(Ri,1)) goto err;
			}
		else /* if N mod word size == 1 */
			{
			if (!BN_set_word(Ri,BN_MASK2)) goto err;  /* Ri-- (mod word size) */
			}
		if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
		/* Ni = (R*Ri-1)/N,
		 * keep only least significant word: */
		mont->n0 = (Ri->top > 0) ? Ri->d[0] : 0;
		}
#else /* !MONT_WORD */
		{ /* bignum version */
		mont->ri=BN_num_bits(&mont->N);
		BN_zero(R);
		if (!BN_set_bit(R,mont->ri)) goto err;  /* R = 2^ri */
		                                        /* Ri = R^-1 mod N*/
		if ((BN_mod_inverse(Ri,R,&mont->N,ctx)) == NULL)
			goto err;
		if (!BN_lshift(Ri,Ri,mont->ri)) goto err; /* R*Ri */
		if (!BN_sub_word(Ri,1)) goto err;
							/* Ni = (R*Ri-1) / N */
		if (!BN_div(&(mont->Ni),NULL,Ri,&mont->N,ctx)) goto err;
		}
#endif

	/* setup RR for conversions */
	BN_zero(&(mont->RR));
	if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err;
	if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err;

	ret = 1;
err:
	BN_CTX_end(ctx);
	return ret;
	}