aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/misc/srp6/srp6.cpp16
-rw-r--r--src/lib/pubkey/dh/dh.cpp10
-rw-r--r--src/lib/pubkey/dl_algo/dl_algo.h10
-rw-r--r--src/lib/pubkey/dsa/dsa.cpp66
-rw-r--r--src/lib/pubkey/elgamal/elgamal.cpp75
-rw-r--r--src/lib/pubkey/rsa/rsa.cpp2
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