8 #include <botan/internal/gnump_engine.h>
9 #include <botan/internal/gmp_wrap.h>
13 #if defined(HAVE_MPZ_POWM_SEC)
15 #define mpz_powm mpz_powm_sec
18 #if defined(BOTAN_HAS_RSA)
19 #include <botan/rsa.h>
22 #if defined(BOTAN_HAS_DSA)
23 #include <botan/dsa.h>
26 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
34 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
35 class GMP_DH_KA_Operation :
public PK_Ops::Key_Agreement
38 GMP_DH_KA_Operation(
const DH_PrivateKey& dh) :
39 x(dh.get_x()), p(dh.group_p()) {}
41 SecureVector<byte> agree(
const byte w[],
size_t w_len)
44 mpz_powm(z.value, z.value, x.value, p.value);
53 #if defined(BOTAN_HAS_DSA)
55 class GMP_DSA_Signature_Operation :
public PK_Ops::Signature
58 GMP_DSA_Signature_Operation(
const DSA_PrivateKey& dsa) :
63 q_bits(dsa.group_q().bits()) {}
65 size_t message_parts()
const {
return 2; }
66 size_t message_part_size()
const {
return (q_bits + 7) / 8; }
67 size_t max_input_bits()
const {
return q_bits; }
69 SecureVector<byte> sign(
const byte msg[],
size_t msg_len,
70 RandomNumberGenerator&
rng);
72 const GMP_MPZ x, p, q, g;
77 GMP_DSA_Signature_Operation::sign(
const byte msg[],
size_t msg_len,
78 RandomNumberGenerator&
rng)
80 const size_t q_bytes = (q_bits + 7) / 8;
82 rng.add_entropy(msg, msg_len);
86 k_bn.randomize(rng, q_bits);
87 while(k_bn >= q.to_bigint());
89 GMP_MPZ i(msg, msg_len);
93 mpz_powm(r.value, g.value, k.value, p.value);
94 mpz_mod(r.value, r.value, q.value);
96 mpz_invert(k.value, k.value, q.value);
99 mpz_mul(s.value, x.value, r.value);
100 mpz_add(s.value, s.value, i.value);
101 mpz_mul(s.value, s.value, k.value);
102 mpz_mod(s.value, s.value, q.value);
104 if(mpz_cmp_ui(r.value, 0) == 0 || mpz_cmp_ui(s.value, 0) == 0)
105 throw Internal_Error(
"GMP_DSA_Op::sign: r or s was zero");
107 SecureVector<byte> output(2*q_bytes);
108 r.encode(output, q_bytes);
109 s.encode(output + q_bytes, q_bytes);
113 class GMP_DSA_Verification_Operation :
public PK_Ops::Verification
116 GMP_DSA_Verification_Operation(
const DSA_PublicKey& dsa) :
121 q_bits(dsa.group_q().bits()) {}
123 size_t message_parts()
const {
return 2; }
124 size_t message_part_size()
const {
return (q_bits + 7) / 8; }
125 size_t max_input_bits()
const {
return q_bits; }
127 bool with_recovery()
const {
return false; }
129 bool verify(
const byte msg[],
size_t msg_len,
130 const byte sig[],
size_t sig_len);
132 const GMP_MPZ y, p, q, g;
136 bool GMP_DSA_Verification_Operation::verify(
const byte msg[],
size_t msg_len,
137 const byte sig[],
size_t sig_len)
139 const size_t q_bytes = q.bytes();
141 if(sig_len != 2*q_bytes || msg_len > q_bytes)
144 GMP_MPZ
r(sig, q_bytes);
145 GMP_MPZ
s(sig + q_bytes, q_bytes);
146 GMP_MPZ i(msg, msg_len);
148 if(mpz_cmp_ui(r.value, 0) <= 0 || mpz_cmp(r.value, q.value) >= 0)
150 if(mpz_cmp_ui(s.value, 0) <= 0 || mpz_cmp(s.value, q.value) >= 0)
153 if(mpz_invert(s.value, s.value, q.value) == 0)
157 mpz_mul(si.value, s.value, i.value);
158 mpz_mod(si.value, si.value, q.value);
159 mpz_powm(si.value, g.value, si.value, p.value);
162 mpz_mul(sr.value, s.value, r.value);
163 mpz_mod(sr.value, sr.value, q.value);
164 mpz_powm(sr.value, y.value, sr.value, p.value);
166 mpz_mul(si.value, si.value, sr.value);
167 mpz_mod(si.value, si.value, p.value);
168 mpz_mod(si.value, si.value, q.value);
170 if(mpz_cmp(si.value, r.value) == 0)
177 #if defined(BOTAN_HAS_RSA)
179 class GMP_RSA_Private_Operation :
public PK_Ops::Signature,
180 public PK_Ops::Decryption
183 GMP_RSA_Private_Operation(
const RSA_PrivateKey& rsa) :
190 n_bits(rsa.get_n().bits())
193 size_t max_input_bits()
const {
return (n_bits - 1); }
195 SecureVector<byte> sign(
const byte msg[],
size_t msg_len,
196 RandomNumberGenerator&)
198 BigInt m(msg, msg_len);
199 BigInt x = private_op(m);
203 SecureVector<byte>
decrypt(
const byte msg[],
size_t msg_len)
205 BigInt m(msg, msg_len);
210 BigInt private_op(
const BigInt& m)
const;
212 GMP_MPZ
mod, p, q, d1, d2, c;
216 BigInt GMP_RSA_Private_Operation::private_op(
const BigInt& m)
const
218 GMP_MPZ j1, j2, h(m);
220 mpz_powm(j1.value, h.value, d1.value, p.value);
221 mpz_powm(j2.value, h.value, d2.value, q.value);
222 mpz_sub(h.value, j1.value, j2.value);
223 mpz_mul(h.value, h.value, c.value);
224 mpz_mod(h.value, h.value, p.value);
225 mpz_mul(h.value, h.value, q.value);
226 mpz_add(h.value, h.value, j2.value);
227 return h.to_bigint();
230 class GMP_RSA_Public_Operation :
public PK_Ops::Verification,
231 public PK_Ops::Encryption
234 GMP_RSA_Public_Operation(
const RSA_PublicKey& rsa) :
235 n(rsa.get_n()), e(rsa.get_e()),
mod(rsa.get_n())
238 size_t max_input_bits()
const {
return (
n.bits() - 1); }
239 bool with_recovery()
const {
return true; }
241 SecureVector<byte>
encrypt(
const byte msg[],
size_t msg_len,
242 RandomNumberGenerator&)
244 BigInt m(msg, msg_len);
248 SecureVector<byte> verify_mr(
const byte msg[],
size_t msg_len)
250 BigInt m(msg, msg_len);
255 BigInt public_op(
const BigInt& m)
const
261 mpz_powm(m_gmp.value, m_gmp.value, e.value,
mod.value);
262 return m_gmp.to_bigint();
266 const GMP_MPZ e,
mod;
273 PK_Ops::Key_Agreement*
276 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
277 if(
const DH_PrivateKey* dh = dynamic_cast<const DH_PrivateKey*>(&key))
278 return new GMP_DH_KA_Operation(*dh);
287 #if defined(BOTAN_HAS_RSA)
288 if(
const RSA_PrivateKey* s = dynamic_cast<const RSA_PrivateKey*>(&key))
289 return new GMP_RSA_Private_Operation(*s);
292 #if defined(BOTAN_HAS_DSA)
293 if(
const DSA_PrivateKey* s = dynamic_cast<const DSA_PrivateKey*>(&key))
294 return new GMP_DSA_Signature_Operation(*s);
303 #if defined(BOTAN_HAS_RSA)
304 if(
const RSA_PublicKey* s = dynamic_cast<const RSA_PublicKey*>(&key))
305 return new GMP_RSA_Public_Operation(*s);
308 #if defined(BOTAN_HAS_DSA)
309 if(
const DSA_PublicKey* s = dynamic_cast<const DSA_PublicKey*>(&key))
310 return new GMP_DSA_Verification_Operation(*s);
319 #if defined(BOTAN_HAS_RSA)
320 if(
const RSA_PublicKey* s = dynamic_cast<const RSA_PublicKey*>(&key))
321 return new GMP_RSA_Public_Operation(*s);
330 #if defined(BOTAN_HAS_RSA)
331 if(
const RSA_PrivateKey* s = dynamic_cast<const RSA_PrivateKey*>(&key))
332 return new GMP_RSA_Private_Operation(*s);
PK_Ops::Encryption * get_encryption_op(const Public_Key &key) const
std::invalid_argument Invalid_Argument
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
RandomNumberGenerator * rng
PK_Ops::Verification * get_verify_op(const Public_Key &key) const
PK_Ops::Signature * get_signature_op(const Private_Key &key) const
PK_Ops::Decryption * get_decryption_op(const Private_Key &key) const
static SecureVector< byte > encode_1363(const BigInt &n, size_t bytes)
PK_Ops::Key_Agreement * get_key_agreement_op(const Private_Key &key) const