Beispiel #1
0
static int
tfm_rsa_private_calculate(fp_int * in, fp_int * p,  fp_int * q,
			  fp_int * dmp1, fp_int * dmq1, fp_int * iqmp,
			  fp_int * out)
{
    fp_int vp, vq, u;

    fp_init_multi(&vp, &vq, &u, NULL);

    /* vq = c ^ (d mod (q - 1)) mod q */
    /* vp = c ^ (d mod (p - 1)) mod p */
    fp_mod(in, p, &u);
    fp_exptmod(&u, dmp1, p, &vp);
    fp_mod(in, q, &u);
    fp_exptmod(&u, dmq1, q, &vq);

    /* C2 = 1/q mod p  (iqmp) */
    /* u = (vp - vq)C2 mod p. */
    fp_sub(&vp, &vq, &u);
    if (fp_isneg(&u))
	fp_add(&u, p, &u);
    fp_mul(&u, iqmp, &u);
    fp_mod(&u, p, &u);

    /* c ^ d mod n = vq + u q */
    fp_mul(&u, q, &u);
    fp_add(&u, &vq, out);

    fp_zero_multi(&vp, &vq, &u, NULL);

    return 0;
}
/* d = a - b (mod c) */
int fp_submod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
{
  fp_int tmp;
  fp_zero(&tmp);
  fp_sub(a, b, &tmp);
  return fp_mod(&tmp, c, d);
}
Beispiel #3
0
/* c = (a, b) */
void fp_gcd(fp_int *a, fp_int *b, fp_int *c)
{
   fp_int u, v, r;

   /* either zero than gcd is the largest */
   if (fp_iszero (a) == 1 && fp_iszero (b) == 0) {
     fp_abs (b, c);
     return;
   }
   if (fp_iszero (a) == 0 && fp_iszero (b) == 1) {
     fp_abs (a, c);
     return;
   }

   /* optimized.  At this point if a == 0 then
    * b must equal zero too
    */
   if (fp_iszero (a) == 1) {
     fp_zero(c);
     return;
   }

   /* sort inputs */
   if (fp_cmp_mag(a, b) != FP_LT) {
      fp_init_copy(&u, a);
      fp_init_copy(&v, b);
   } else {
      fp_init_copy(&u, b);
      fp_init_copy(&v, a);
   }
 
   fp_zero(&r);
   while (fp_iszero(&v) == FP_NO) {
      fp_mod(&u, &v, &r);
      fp_copy(&v, &u);
      fp_copy(&r, &v);
   }
   fp_copy(&u, c);
}
Beispiel #4
0
static int
tfm_rsa_generate_key(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
{
    fp_int el, p, q, n, d, dmp1, dmq1, iqmp, t1, t2, t3;
    int counter, ret, bitsp;

    if (bits < 789)
	return -1;

    bitsp = (bits + 1) / 2;

    ret = -1;

    fp_init_multi(&el, &p, &q, &n, &n, &d, &dmp1, &dmq1, &iqmp, &t1, &t2, &t3, NULL);

    BN2mpz(&el, e);

    /* generate p and q so that p != q and bits(pq) ~ bits */
    counter = 0;
    do {
	BN_GENCB_call(cb, 2, counter++);
	CHECK(random_num(&p, bitsp), 0);
	CHECK(fp_find_prime(&p), FP_YES);

	fp_sub_d(&p, 1, &t1);
	fp_gcd(&t1, &el, &t2);
    } while(fp_cmp_d(&t2, 1) != 0);

    BN_GENCB_call(cb, 3, 0);

    counter = 0;
    do {
	BN_GENCB_call(cb, 2, counter++);
	CHECK(random_num(&q, bits - bitsp), 0);
	CHECK(fp_find_prime(&q), FP_YES);

	if (fp_cmp(&p, &q) == 0) /* don't let p and q be the same */
	    continue;

	fp_sub_d(&q, 1, &t1);
	fp_gcd(&t1, &el, &t2);
    } while(fp_cmp_d(&t2, 1) != 0);

    /* make p > q */
    if (fp_cmp(&p, &q) < 0) {
	fp_int c;
	fp_copy(&p, &c);
	fp_copy(&q, &p);
	fp_copy(&c, &q);
    }

    BN_GENCB_call(cb, 3, 1);

    /* calculate n,  		n = p * q */
    fp_mul(&p, &q, &n);

    /* calculate d, 		d = 1/e mod (p - 1)(q - 1) */
    fp_sub_d(&p, 1, &t1);
    fp_sub_d(&q, 1, &t2);
    fp_mul(&t1, &t2, &t3);
    fp_invmod(&el, &t3, &d);

    /* calculate dmp1		dmp1 = d mod (p-1) */
    fp_mod(&d, &t1, &dmp1);
    /* calculate dmq1		dmq1 = d mod (q-1) */
    fp_mod(&d, &t2, &dmq1);
    /* calculate iqmp 		iqmp = 1/q mod p */
    fp_invmod(&q, &p, &iqmp);

    /* fill in RSA key */

    rsa->e = mpz2BN(&el);
    rsa->p = mpz2BN(&p);
    rsa->q = mpz2BN(&q);
    rsa->n = mpz2BN(&n);
    rsa->d = mpz2BN(&d);
    rsa->dmp1 = mpz2BN(&dmp1);
    rsa->dmq1 = mpz2BN(&dmq1);
    rsa->iqmp = mpz2BN(&iqmp);

    ret = 1;

out:
    fp_zero_multi(&el, &p, &q, &n, &d, &dmp1,
		  &dmq1, &iqmp, &t1, &t2, &t3, NULL);

    return ret;
}
Beispiel #5
0
static int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c)
{
  fp_int  x, y, u, v, A, B, C, D;
  int     res;

  /* b cannot be negative */
  if (b->sign == FP_NEG || fp_iszero(b) == 1) {
    return FP_VAL;
  }

  /* init temps */
  fp_init(&x);    fp_init(&y);
  fp_init(&u);    fp_init(&v);
  fp_init(&A);    fp_init(&B);
  fp_init(&C);    fp_init(&D);

  /* x = a, y = b */
  if ((res = fp_mod(a, b, &x)) != FP_OKAY) {
      return res;
  }
  fp_copy(b, &y);

  /* 2. [modified] if x,y are both even then return an error! */
  if (fp_iseven (&x) == 1 && fp_iseven (&y) == 1) {
    return FP_VAL;
  }

  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
  fp_copy (&x, &u);
  fp_copy (&y, &v);
  fp_set (&A, 1);
  fp_set (&D, 1);

top:
  /* 4.  while u is even do */
  while (fp_iseven (&u) == 1) {
    /* 4.1 u = u/2 */
    fp_div_2 (&u, &u);

    /* 4.2 if A or B is odd then */
    if (fp_isodd (&A) == 1 || fp_isodd (&B) == 1) {
      /* A = (A+y)/2, B = (B-x)/2 */
      fp_add (&A, &y, &A);
      fp_sub (&B, &x, &B);
    }
    /* A = A/2, B = B/2 */
    fp_div_2 (&A, &A);
    fp_div_2 (&B, &B);
  }

  /* 5.  while v is even do */
  while (fp_iseven (&v) == 1) {
    /* 5.1 v = v/2 */
    fp_div_2 (&v, &v);

    /* 5.2 if C or D is odd then */
    if (fp_isodd (&C) == 1 || fp_isodd (&D) == 1) {
      /* C = (C+y)/2, D = (D-x)/2 */
      fp_add (&C, &y, &C);
      fp_sub (&D, &x, &D);
    }
    /* C = C/2, D = D/2 */
    fp_div_2 (&C, &C);
    fp_div_2 (&D, &D);
  }

  /* 6.  if u >= v then */
  if (fp_cmp (&u, &v) != FP_LT) {
    /* u = u - v, A = A - C, B = B - D */
    fp_sub (&u, &v, &u);
    fp_sub (&A, &C, &A);
    fp_sub (&B, &D, &B);
  } else {
    /* v - v - u, C = C - A, D = D - B */
    fp_sub (&v, &u, &v);
    fp_sub (&C, &A, &C);
    fp_sub (&D, &B, &D);
  }

  /* if not zero goto step 4 */
  if (fp_iszero (&u) == 0)
    goto top;

  /* now a = C, b = D, gcd == g*v */

  /* if v != 1 then there is no inverse */
  if (fp_cmp_d (&v, 1) != FP_EQ) {
    return FP_VAL;
  }

  /* if its too low */
  while (fp_cmp_d(&C, 0) == FP_LT) {
      fp_add(&C, b, &C);
  }
  
  /* too big */
  while (fp_cmp_mag(&C, b) != FP_LT) {
      fp_sub(&C, b, &C);
  }
  
  /* C is now the inverse */
  fp_copy(&C, c);
  return FP_OKAY;
}