3 * Creating RSA signatures.
6 /* nettle, low-level cryptographics library
8 * Copyright (C) 2001, 2003 Niels Möller
10 * The nettle library is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or (at your
13 * option) any later version.
15 * The nettle library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with the nettle library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
35 rsa_private_key_init(struct rsa_private_key
*key
)
44 /* Not really necessary, but it seems cleaner to initialize all the
50 rsa_private_key_clear(struct rsa_private_key
*key
)
61 rsa_private_key_prepare(struct rsa_private_key
*key
)
65 /* The size of the product is the sum of the sizes of the factors,
66 * or sometimes one less. It's possible but tricky to compute the
67 * size without computing the full product. */
70 mpz_mul(n
, key
->p
, key
->q
);
72 key
->size
= _rsa_check_size(n
);
76 return (key
->size
> 0);
79 /* Computing an rsa root. */
81 rsa_compute_root(const struct rsa_private_key
*key
,
82 mpz_t x
, const mpz_t m
)
84 mpz_t xp
; /* modulo p */
85 mpz_t xq
; /* modulo q */
87 mpz_init(xp
); mpz_init(xq
);
89 /* Compute xq = m^d % q = (m%q)^b % q */
90 mpz_fdiv_r(xq
, m
, key
->q
);
91 mpz_powm(xq
, xq
, key
->b
, key
->q
);
93 /* Compute xp = m^d % p = (m%p)^a % p */
94 mpz_fdiv_r(xp
, m
, key
->p
);
95 mpz_powm(xp
, xp
, key
->a
, key
->p
);
97 /* Set xp' = (xp - xq) c % p. */
99 mpz_mul(xp
, xp
, key
->c
);
100 mpz_fdiv_r(xp
, xp
, key
->p
);
102 /* Finally, compute x = xq + q xp'
104 * To prove that this works, note that
110 * for some integers i, j and k. Now, for some integer l,
112 * xp' = (xp - xq) c + l p
113 * = (x + i p - (x + j q)) c + l p
114 * = (i p - j q) c + l p
115 * = (i c + l) p - j (c q)
116 * = (i c + l) p - j (1 + kp)
117 * = (i c + l - j k) p - j
119 * which shows that xp' = -j (mod p). We get
121 * xq + q xp' = x + j q + (i c + l - j k) p q - j q
122 * = x + (i c + l - j k) p q
126 * xq + q xp' = x (mod pq)
128 * We also get 0 <= xq + q xp' < p q, because
130 * 0 <= xq < q and 0 <= xp' < p.
132 mpz_mul(x
, key
->q
, xp
);
135 mpz_clear(xp
); mpz_clear(xq
);