/* invmod */ static int invmod(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return tfm_to_ltc_error(fp_invmod(a, b, c)); }
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; }