+ read_mpbin(&iqmp,b,length);
+ FREE(b);
+ /* Read q (the smaller of the two primes) */
+ length=(KEYFILE_GET(16)+7)/8;
+ if (length>RSA_MAX_MODBYTES) {
+ LDFATAL("implausibly long (%ld) q value\n",
+ length);
+ }
+ b=safe_malloc(length,"rsapriv_apply");
+ if (fread(b,length,1,f)!=1) {
+ LDFATAL_FILE("error reading q value\n");
+ }
+ read_mpbin(&st->q,b,length);
+ FREE(b);
+ /* Read p (the larger of the two primes) */
+ length=(KEYFILE_GET(16)+7)/8;
+ if (length>RSA_MAX_MODBYTES) {
+ LDFATAL("implausibly long (%ld) p value\n",
+ length);
+ }
+ b=safe_malloc(length,"rsapriv_apply");
+ if (fread(b,length,1,f)!=1) {
+ LDFATAL_FILE("error reading p value\n");
+ }
+ read_mpbin(&st->p,b,length);
+ FREE(b);
+
+ if (ferror(f)) {
+ fatal_perror("rsa-private (%s:%d): ferror",loc.file,loc.line);
+ }
+
+ /*
+ * Now verify the validity of the key, and set up the auxiliary
+ * values for fast CRT signing.
+ */
+ valid=False;
+ if (do_validity_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
+ * lambda(n) = lcm(p-1,q-1). The usual `textbook' condition,
+ * that d e == 1 (mod (p-1)(q-1)) is sufficient, but not
+ * actually necessary.
+ */
+ 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_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);