diff options
-rw-r--r-- | src/lib/misc/srp6/srp6.cpp | 16 | ||||
-rw-r--r-- | src/lib/pubkey/dh/dh.cpp | 10 | ||||
-rw-r--r-- | src/lib/pubkey/dl_algo/dl_algo.h | 10 | ||||
-rw-r--r-- | src/lib/pubkey/dsa/dsa.cpp | 66 | ||||
-rw-r--r-- | src/lib/pubkey/elgamal/elgamal.cpp | 75 | ||||
-rw-r--r-- | src/lib/pubkey/rsa/rsa.cpp | 2 |
6 files changed, 93 insertions, 86 deletions
diff --git a/src/lib/misc/srp6/srp6.cpp b/src/lib/misc/srp6/srp6.cpp index e41c67c81..94a6fe4a4 100644 --- a/src/lib/misc/srp6/srp6.cpp +++ b/src/lib/misc/srp6/srp6.cpp @@ -86,24 +86,24 @@ srp6_client_agree(const std::string& identifier, const BigInt& g = group.get_g(); const BigInt& p = group.get_p(); - const size_t p_bytes = group.get_p().bytes(); + const size_t p_bytes = group.p_bytes(); if(B <= 0 || B >= p) throw Exception("Invalid SRP parameter from server"); - BigInt k = hash_seq(hash_id, p_bytes, p, g); + const BigInt k = hash_seq(hash_id, p_bytes, p, g); - BigInt a(rng, 256); + const BigInt a(rng, 256); - BigInt A = power_mod(g, a, p); + const BigInt A = group.power_g_p(a); - BigInt u = hash_seq(hash_id, p_bytes, A, B); + const BigInt u = hash_seq(hash_id, p_bytes, A, B); const BigInt x = compute_x(hash_id, identifier, password, salt); - BigInt S = power_mod((B - (k * power_mod(g, x, p))) % p, (a + (u * x)), p); + const BigInt S = power_mod((B - (k * power_mod(g, x, p))) % p, (a + (u * x)), p); - SymmetricKey Sk(BigInt::encode_1363(S, p_bytes)); + const SymmetricKey Sk(BigInt::encode_1363(S, p_bytes)); return std::make_pair(A, Sk); } @@ -137,7 +137,7 @@ BigInt SRP6_Server_Session::step1(const BigInt& v, const BigInt k = hash_seq(hash_id, m_p_bytes, p, g); - m_B = (v*k + power_mod(g, m_b, p)) % p; + m_B = group.mod_p(v*k + group.power_g_p(m_b));; return m_B; } diff --git a/src/lib/pubkey/dh/dh.cpp b/src/lib/pubkey/dh/dh.cpp index 2a7742738..b8b09ec3f 100644 --- a/src/lib/pubkey/dh/dh.cpp +++ b/src/lib/pubkey/dh/dh.cpp @@ -49,9 +49,9 @@ DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng, m_x = x_arg; } - if(m_y == 0) + if(m_y.is_zero()) { - m_y = power_mod(group_g(), m_x, group_p()); + m_y = m_group.power_g_p(m_x); } } @@ -62,8 +62,10 @@ DH_PrivateKey::DH_PrivateKey(const AlgorithmIdentifier& alg_id, const secure_vector<uint8_t>& key_bits) : DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_42) { - if(m_y == 0) - m_y = power_mod(group_g(), m_x, group_p()); + if(m_y.is_zero()) + { + m_y = m_group.power_g_p(m_x); + } } /* diff --git a/src/lib/pubkey/dl_algo/dl_algo.h b/src/lib/pubkey/dl_algo/dl_algo.h index 52b38a529..9364f4c5d 100644 --- a/src/lib/pubkey/dl_algo/dl_algo.h +++ b/src/lib/pubkey/dl_algo/dl_algo.h @@ -32,6 +32,12 @@ class BOTAN_PUBLIC_API(2,0) DL_Scheme_PublicKey : public virtual Public_Key const DL_Group& get_domain() const { return m_group; } /** + * Get the DL domain parameters of this key. + * @return DL domain parameters of this key + */ + const DL_Group& get_group() const { return m_group; } + + /** * Get the public value y with y = g^x mod p where x is the secret key. */ const BigInt& get_y() const { return m_y; } @@ -73,6 +79,10 @@ class BOTAN_PUBLIC_API(2,0) DL_Scheme_PublicKey : public virtual Public_Key const std::vector<uint8_t>& key_bits, DL_Group::Format group_format); + DL_Scheme_PublicKey(const DL_Group& group, const BigInt& y) : + m_y(y), m_group(group) + {} + DL_Scheme_PublicKey& operator=(const DL_Scheme_PublicKey& other) = default; protected: diff --git a/src/lib/pubkey/dsa/dsa.cpp b/src/lib/pubkey/dsa/dsa.cpp index 9a8418d46..7b4cbebfb 100644 --- a/src/lib/pubkey/dsa/dsa.cpp +++ b/src/lib/pubkey/dsa/dsa.cpp @@ -81,9 +81,8 @@ class DSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA public: DSA_Signature_Operation(const DSA_PrivateKey& dsa, const std::string& emsa) : PK_Ops::Signature_with_EMSA(emsa), - m_q(dsa.group_q()), + m_group(dsa.get_group()), m_x(dsa.get_x()), - m_powermod_g_p(dsa.group_g(), dsa.group_p()), m_mod_q(dsa.group_q()) { #if defined(BOTAN_HAS_RFC6979_GENERATOR) @@ -91,14 +90,13 @@ class DSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA #endif } - size_t max_input_bits() const override { return m_q.bits(); } + size_t max_input_bits() const override { return m_group.get_q().bits(); } secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len, RandomNumberGenerator& rng) override; private: - const BigInt& m_q; + const DL_Group m_group; const BigInt& m_x; - Fixed_Base_Power_Mod m_powermod_g_p; Modular_Reducer m_mod_q; #if defined(BOTAN_HAS_RFC6979_GENERATOR) std::string m_rfc6979_hash; @@ -109,36 +107,38 @@ secure_vector<uint8_t> DSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, RandomNumberGenerator& rng) { + const BigInt& q = m_group.get_q(); + BigInt i(msg, msg_len); - while(i >= m_q) - i -= m_q; + while(i >= q) + i -= q; #if defined(BOTAN_HAS_RFC6979_GENERATOR) BOTAN_UNUSED(rng); - const BigInt k = generate_rfc6979_nonce(m_x, m_q, i, m_rfc6979_hash); + const BigInt k = generate_rfc6979_nonce(m_x, q, i, m_rfc6979_hash); #else - const BigInt k = BigInt::random_integer(rng, 1, m_q); + const BigInt k = BigInt::random_integer(rng, 1, q); #endif #if defined(BOTAN_TARGET_OS_HAS_THREADS) auto future_r = std::async(std::launch::async, - [&]() { return m_mod_q.reduce(m_powermod_g_p(k)); }); + [&]() { return m_mod_q.reduce(m_group.power_g_p(k)); }); - BigInt s = inverse_mod(k, m_q); + BigInt s = inverse_mod(k, q); const BigInt r = future_r.get(); #else - BigInt s = inverse_mod(k, m_q); - const BigInt r = m_mod_q.reduce(m_powermod_g_p(k)); + BigInt s = inverse_mod(k, q); + const BigInt r = m_mod_q.reduce(m_group.power_g_p(k)); #endif s = m_mod_q.multiply(s, mul_add(m_x, r, i)); // With overwhelming probability, a bug rather than actual zero r/s - BOTAN_ASSERT(s != 0, "invalid s"); - BOTAN_ASSERT(r != 0, "invalid r"); + if(r.is_zero() || s.is_zero()) + throw Internal_Error("Computed zero r/s during DSA signature"); - return BigInt::encode_fixed_length_int_pair(r, s, m_q.bytes()); + return BigInt::encode_fixed_length_int_pair(r, s, q.bytes()); } /** @@ -150,52 +150,56 @@ class DSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA DSA_Verification_Operation(const DSA_PublicKey& dsa, const std::string& emsa) : PK_Ops::Verification_with_EMSA(emsa), - m_q(dsa.group_q()), m_y(dsa.get_y()), m_powermod_g_p{Fixed_Base_Power_Mod(dsa.group_g(), dsa.group_p())}, - m_powermod_y_p{Fixed_Base_Power_Mod(m_y, dsa.group_p())}, m_mod_p{Modular_Reducer(dsa.group_p())}, - m_mod_q{Modular_Reducer(dsa.group_q())} + m_group(dsa.get_group()), + m_y(dsa.get_y()), + m_powermod_y_p(m_y, dsa.group_p()), + m_mod_q(dsa.group_q()) {} - size_t max_input_bits() const override { return m_q.bits(); } + size_t max_input_bits() const override { return m_group.get_q().bits(); } bool with_recovery() const override { return false; } bool verify(const uint8_t msg[], size_t msg_len, const uint8_t sig[], size_t sig_len) override; private: - const BigInt& m_q; + const DL_Group m_group; const BigInt& m_y; - Fixed_Base_Power_Mod m_powermod_g_p, m_powermod_y_p; - Modular_Reducer m_mod_p, m_mod_q; + Fixed_Base_Power_Mod m_powermod_y_p; + Modular_Reducer m_mod_q; }; bool DSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len, const uint8_t sig[], size_t sig_len) { - if(sig_len != 2*m_q.bytes() || msg_len > m_q.bytes()) + const BigInt& q = m_group.get_q(); + const size_t q_bytes = q.bytes(); + + if(sig_len != 2*q_bytes || msg_len > q_bytes) return false; - BigInt r(sig, m_q.bytes()); - BigInt s(sig + m_q.bytes(), m_q.bytes()); + BigInt r(sig, q_bytes); + BigInt s(sig + q_bytes, q_bytes); BigInt i(msg, msg_len); - if(r <= 0 || r >= m_q || s <= 0 || s >= m_q) + if(r <= 0 || r >= q || s <= 0 || s >= q) return false; - s = inverse_mod(s, m_q); + s = inverse_mod(s, q); #if defined(BOTAN_TARGET_OS_HAS_THREADS) auto future_s_i = std::async(std::launch::async, - [&]() { return m_powermod_g_p(m_mod_q.multiply(s, i)); }); + [&]() { return m_group.power_g_p(m_mod_q.multiply(s, i)); }); BigInt s_r = m_powermod_y_p(m_mod_q.multiply(s, r)); BigInt s_i = future_s_i.get(); #else BigInt s_r = m_powermod_y_p(m_mod_q.multiply(s, r)); - BigInt s_i = m_powermod_g_p(m_mod_q.multiply(s, i)); + BigInt s_i = m_group.power_g_p(m_mod_q.multiply(s, i)); #endif - s = m_mod_p.multiply(s_i, s_r); + s = m_group.multiply_mod_p(s_i, s_r); return (m_mod_q.reduce(s) == r); } diff --git a/src/lib/pubkey/elgamal/elgamal.cpp b/src/lib/pubkey/elgamal/elgamal.cpp index a44f352f5..3a5d8b81e 100644 --- a/src/lib/pubkey/elgamal/elgamal.cpp +++ b/src/lib/pubkey/elgamal/elgamal.cpp @@ -1,6 +1,6 @@ /* * ElGamal -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2018 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -18,33 +18,34 @@ namespace Botan { /* * ElGamal_PublicKey Constructor */ -ElGamal_PublicKey::ElGamal_PublicKey(const DL_Group& grp, const BigInt& y1) +ElGamal_PublicKey::ElGamal_PublicKey(const DL_Group& group, const BigInt& y) : + DL_Scheme_PublicKey(group, y) { - m_group = grp; - m_y = y1; } /* * ElGamal_PrivateKey Constructor */ ElGamal_PrivateKey::ElGamal_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& grp, - const BigInt& x_arg) + const DL_Group& group, + const BigInt& x) { - m_group = grp; - m_x = x_arg; + m_x = x; + m_group = group; - if(m_x == 0) + if(m_x.is_zero()) + { m_x.randomize(rng, dl_exponent_size(group_p().bits())); + } - m_y = power_mod(group_g(), m_x, group_p()); + m_y = m_group.power_g_p(m_x); } ElGamal_PrivateKey::ElGamal_PrivateKey(const AlgorithmIdentifier& alg_id, const secure_vector<uint8_t>& key_bits) : DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_42) { - m_y = power_mod(group_g(), m_x, group_p()); + m_y = m_group.power_g_p(m_x); } /* @@ -71,7 +72,7 @@ class ElGamal_Encryption_Operation final : public PK_Ops::Encryption_with_EME { public: - size_t max_raw_input_bits() const override { return m_mod_p.get_modulus().bits() - 1; } + size_t max_raw_input_bits() const override { return m_group.p_bits() - 1; } ElGamal_Encryption_Operation(const ElGamal_PublicKey& key, const std::string& eme); @@ -79,41 +80,34 @@ class ElGamal_Encryption_Operation final : public PK_Ops::Encryption_with_EME RandomNumberGenerator& rng) override; private: - Fixed_Base_Power_Mod m_powermod_g_p, m_powermod_y_p; - Modular_Reducer m_mod_p; + const DL_Group m_group; + Fixed_Base_Power_Mod m_powermod_y_p; }; ElGamal_Encryption_Operation::ElGamal_Encryption_Operation(const ElGamal_PublicKey& key, const std::string& eme) : - PK_Ops::Encryption_with_EME(eme) + PK_Ops::Encryption_with_EME(eme), + m_group(key.get_group()), + m_powermod_y_p(key.get_y(), m_group.get_p()) { - const BigInt& p = key.group_p(); - - m_powermod_g_p = Fixed_Base_Power_Mod(key.group_g(), p); - m_powermod_y_p = Fixed_Base_Power_Mod(key.get_y(), p); - m_mod_p = Modular_Reducer(p); } secure_vector<uint8_t> ElGamal_Encryption_Operation::raw_encrypt(const uint8_t msg[], size_t msg_len, RandomNumberGenerator& rng) { - const BigInt& p = m_mod_p.get_modulus(); - BigInt m(msg, msg_len); - if(m >= p) + if(m >= m_group.get_p()) throw Invalid_Argument("ElGamal encryption: Input is too large"); - BigInt k(rng, dl_exponent_size(p.bits())); + const size_t k_bits = dl_exponent_size(m_group.p_bits()); + const BigInt k(rng, k_bits); - BigInt a = m_powermod_g_p(k); - BigInt b = m_mod_p.multiply(m, m_powermod_y_p(k)); + const BigInt a = m_group.power_g_p(k); + const BigInt b = m_group.multiply_mod_p(m, m_powermod_y_p(k)); - secure_vector<uint8_t> output(2*p.bytes()); - a.binary_encode(&output[p.bytes() - a.bytes()]); - b.binary_encode(&output[output.size() / 2 + (p.bytes() - b.bytes())]); - return output; + return BigInt::encode_fixed_length_int_pair(a, b, m_group.p_bytes()); } /** @@ -123,8 +117,7 @@ class ElGamal_Decryption_Operation final : public PK_Ops::Decryption_with_EME { public: - size_t max_raw_input_bits() const override - { return m_mod_p.get_modulus().bits() - 1; } + size_t max_raw_input_bits() const override { return m_group.p_bits() - 1; } ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key, const std::string& eme, @@ -132,8 +125,8 @@ class ElGamal_Decryption_Operation final : public PK_Ops::Decryption_with_EME secure_vector<uint8_t> raw_decrypt(const uint8_t msg[], size_t msg_len) override; private: + const DL_Group m_group; Fixed_Exponent_Power_Mod m_powermod_x_p; - Modular_Reducer m_mod_p; Blinder m_blinder; }; @@ -141,9 +134,9 @@ ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(const ElGamal_Private const std::string& eme, RandomNumberGenerator& rng) : PK_Ops::Decryption_with_EME(eme), - m_powermod_x_p(Fixed_Exponent_Power_Mod(key.get_x(), key.group_p())), - m_mod_p(Modular_Reducer(key.group_p())), - m_blinder(key.group_p(), + m_group(key.get_group()), + m_powermod_x_p(key.get_x(), m_group.get_p()), + m_blinder(m_group.get_p(), rng, [](const BigInt& k) { return k; }, [this](const BigInt& k) { return m_powermod_x_p(k); }) @@ -153,22 +146,20 @@ ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(const ElGamal_Private secure_vector<uint8_t> ElGamal_Decryption_Operation::raw_decrypt(const uint8_t msg[], size_t msg_len) { - const BigInt& p = m_mod_p.get_modulus(); - - const size_t p_bytes = p.bytes(); + const size_t p_bytes = m_group.p_bytes(); if(msg_len != 2 * p_bytes) throw Invalid_Argument("ElGamal decryption: Invalid message"); BigInt a(msg, p_bytes); - BigInt b(msg + p_bytes, p_bytes); + const BigInt b(msg + p_bytes, p_bytes); - if(a >= p || b >= p) + if(a >= m_group.get_p() || b >= m_group.get_p()) throw Invalid_Argument("ElGamal decryption: Invalid message"); a = m_blinder.blind(a); - BigInt r = m_mod_p.multiply(b, inverse_mod(m_powermod_x_p(a), p)); + const BigInt r = m_group.multiply_mod_p(m_group.inverse_mod_p(m_powermod_x_p(a)), b); return BigInt::encode_1363(m_blinder.unblind(r), p_bytes); } diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp index cfb1ae7ba..1ba4d6b25 100644 --- a/src/lib/pubkey/rsa/rsa.cpp +++ b/src/lib/pubkey/rsa/rsa.cpp @@ -219,7 +219,7 @@ class RSA_Private_Operation BigInt private_op(const BigInt& m) const { #if defined(BOTAN_TARGET_OS_HAS_THREADS) - auto future_j1 = std::async(std::launch::async, m_powermod_d1_p, m); + auto future_j1 = std::async(std::launch::async, std::ref(m_powermod_d1_p), m); BigInt j2 = m_powermod_d2_q(m); BigInt j1 = future_j1.get(); #else |