- mpz_init(&sig);
- mpz_init(&plain);
- mpz_init(&check);
- read_mpbin(&plain,c,strlen(c));
- mpz_powm(&sig, &plain, &st->d, &st->n);
- mpz_powm(&check, &sig, &e, &st->n);
- if (mpz_cmp(&plain,&check)!=0) {
- cfgfatal(loc,"rsa-private","file \"%s\" does not contain a "
- "valid RSA key!\n",filename);
- }
- mpz_clear(&sig);
- mpz_clear(&plain);
- mpz_clear(&check);
+ /* Verify that p*q is equal to n. */
+ mpz_mul(&tmp, &st->p, &st->q);
+ if (mpz_cmp(&tmp, &st->n) != 0)
+ goto done_checks;
+
+ /*
+ * Verify that d*e is congruent to 1 mod (p-1), and mod
+ * (q-1). This is equivalent to it being congruent to 1 mod
+ * lcm(p-1,q-1), i.e. congruent to 1 mod phi(n). Note that
+ * phi(n) is _not_ simply (p-1)*(q-1).
+ */
+ mpz_mul(&tmp, &d, &e);
+ mpz_sub_ui(&tmp2, &st->p, 1);
+ mpz_mod(&tmp3, &tmp, &tmp2);
+ if (mpz_cmp_si(&tmp3, 1) != 0)
+ goto done_checks;
+ mpz_sub_ui(&tmp2, &st->q, 1);
+ mpz_mod(&tmp3, &tmp, &tmp2);
+ if (mpz_cmp_si(&tmp3, 1) != 0)
+ goto done_checks;
+
+ /* Verify that q*iqmp is congruent to 1 mod p. */
+ mpz_mul(&tmp, &st->q, &iqmp);
+ mpz_mod(&tmp2, &tmp, &st->p);
+ if (mpz_cmp_si(&tmp2, 1) != 0)
+ goto done_checks;
+ }
+ /* Now we know the key is valid (or we don't care). */
+ valid = True;
+
+ /*
+ * Now we compute auxiliary values dp, dq and w to allow us
+ * to use the CRT optimisation when signing.
+ *
+ * dp == d mod (p-1) so that a^dp == a^d mod p, for all a
+ * dq == d mod (q-1) similarly mod q
+ * w == iqmp * q so that w == 0 mod q, and w == 1 mod p
+ */
+ mpz_init(&st->dp);
+ mpz_init(&st->dq);
+ mpz_init(&st->w);
+ mpz_sub_ui(&tmp, &st->p, 1);
+ mpz_mod(&st->dp, &d, &tmp);
+ mpz_sub_ui(&tmp, &st->q, 1);
+ mpz_mod(&st->dq, &d, &tmp);
+ mpz_mul(&st->w, &iqmp, &st->q);
+
+done_checks:
+ if (!valid) {
+ cfgfatal(loc,"rsa-private","file \"%s\" does not contain a "
+ "valid RSA key!\n",filename);