aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pubkey')
-rw-r--r--src/lib/pubkey/ec_group/ec_group.cpp23
-rw-r--r--src/lib/pubkey/ec_group/ec_group.h11
-rw-r--r--src/lib/pubkey/ecdh/ecdh.cpp24
-rw-r--r--src/lib/pubkey/ecdsa/ecdsa.cpp6
-rw-r--r--src/lib/pubkey/ecgdsa/ecgdsa.cpp5
-rw-r--r--src/lib/pubkey/ecies/ecies.cpp18
-rw-r--r--src/lib/pubkey/eckcdsa/eckcdsa.cpp5
-rw-r--r--src/lib/pubkey/gost_3410/gost_3410.cpp5
-rw-r--r--src/lib/pubkey/sm2/sm2.cpp5
-rw-r--r--src/lib/pubkey/sm2/sm2_enc.cpp29
10 files changed, 87 insertions, 44 deletions
diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp
index 771bd4b0f..a41a59b66 100644
--- a/src/lib/pubkey/ec_group/ec_group.cpp
+++ b/src/lib/pubkey/ec_group/ec_group.cpp
@@ -17,6 +17,10 @@
#include <botan/mutex.h>
#include <vector>
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ #include <botan/system_rng.h>
+#endif
+
namespace Botan {
class EC_Group_Data final
@@ -36,10 +40,14 @@ class EC_Group_Data final
m_order(order),
m_cofactor(cofactor),
m_mod_order(order),
+ m_base_mult(m_base_point, 5),
m_oid(oid),
m_p_bits(p.bits()),
m_order_bits(order.bits())
{
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ m_base_mult.randomize(system_rng());
+#endif
}
bool match(const BigInt& p, const BigInt& a, const BigInt& b,
@@ -76,12 +84,20 @@ class EC_Group_Data final
return m_mod_order.multiply(x, y);
}
+ PointGFp blinded_base_point_multiply(const BigInt& k,
+ RandomNumberGenerator& rng,
+ std::vector<BigInt>& ws) const
+ {
+ return m_base_mult.mul(k, m_order, rng, ws);
+ }
+
private:
CurveGFp m_curve;
PointGFp m_base_point;
BigInt m_order;
BigInt m_cofactor;
Modular_Reducer m_mod_order;
+ PointGFp_Blinded_Multiplier m_base_mult;
OID m_oid;
size_t m_p_bits;
size_t m_order_bits;
@@ -429,6 +445,13 @@ PointGFp EC_Group::point_multiply(const BigInt& x, const PointGFp& pt, const Big
return multi_exponentiate(get_base_point(), x, pt, y);
}
+PointGFp EC_Group::blinded_base_point_multiply(const BigInt& k,
+ RandomNumberGenerator& rng,
+ std::vector<BigInt>& ws) const
+ {
+ return data().blinded_base_point_multiply(k, rng, ws);
+ }
+
PointGFp EC_Group::zero_point() const
{
return PointGFp(data().curve());
diff --git a/src/lib/pubkey/ec_group/ec_group.h b/src/lib/pubkey/ec_group/ec_group.h
index a60c71157..0e5f352f2 100644
--- a/src/lib/pubkey/ec_group/ec_group.h
+++ b/src/lib/pubkey/ec_group/ec_group.h
@@ -206,12 +206,21 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
PointGFp point(const BigInt& x, const BigInt& y) const;
/**
- * Multi exponentiate
+ * Multi exponentiate. Not constant time.
* @return base_point*x + pt*y
*/
PointGFp point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const;
/**
+ * Blinded point multiplication, attempts resistance to side channels
+ * @param k the scalar
+ * @param rng a random number generator
+ * @param ws a temp workspace
+ * @return base_point*k
+ */
+ PointGFp blinded_base_point_multiply(const BigInt& k, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const;
+
+ /**
* Return the zero (or infinite) point on this curve
*/
PointGFp zero_point() const;
diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp
index 1850696e1..4989fa0a5 100644
--- a/src/lib/pubkey/ecdh/ecdh.cpp
+++ b/src/lib/pubkey/ecdh/ecdh.cpp
@@ -28,26 +28,30 @@ class ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
ECDH_KA_Operation(const ECDH_PrivateKey& key, const std::string& kdf, RandomNumberGenerator& rng) :
PK_Ops::Key_Agreement_with_KDF(kdf),
- m_domain(key.domain()),
+ m_group(key.domain()),
m_rng(rng)
{
- m_l_times_priv = inverse_mod(m_domain.get_cofactor(), m_domain.get_order()) * key.private_value();
+ m_l_times_priv = inverse_mod(m_group.get_cofactor(), m_group.get_order()) * key.private_value();
}
secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
{
- PointGFp point = m_domain.OS2ECP(w, w_len);
- PointGFp S = m_domain.get_cofactor() * point;
- Blinded_Point_Multiply blinder(S, m_domain.get_order());
- S = blinder.blinded_multiply(m_l_times_priv, m_rng);
- BOTAN_ASSERT(S.on_the_curve(), "ECDH agreed value was on the curve");
- return BigInt::encode_1363(S.get_affine_x(), m_domain.get_p_bytes());
+ PointGFp input_point = m_group.get_cofactor() * m_group.OS2ECP(w, w_len);
+ input_point.randomize_repr(m_rng);
+
+ PointGFp_Blinded_Multiplier blinder(input_point, m_ws);
+
+ const PointGFp S = blinder.mul(m_l_times_priv, m_group.get_order(), m_rng, m_ws);
+
+ if(S.on_the_curve() == false)
+ throw Internal_Error("ECDH agreed value was not on the curve");
+ return BigInt::encode_1363(S.get_affine_x(), m_group.get_p_bytes());
}
private:
- const EC_Group& m_domain;
+ const EC_Group m_group;
BigInt m_l_times_priv;
RandomNumberGenerator& m_rng;
-
+ std::vector<BigInt> m_ws;
};
}
diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp
index 12ccd9608..57bc197c5 100644
--- a/src/lib/pubkey/ecdsa/ecdsa.cpp
+++ b/src/lib/pubkey/ecdsa/ecdsa.cpp
@@ -53,7 +53,6 @@ class ECDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA
const std::string& emsa) :
PK_Ops::Signature_with_EMSA(emsa),
m_group(ecdsa.domain()),
- m_base_point(m_group.get_base_point(), m_group.get_order()),
m_x(ecdsa.private_value())
{
#if defined(BOTAN_HAS_RFC6979_GENERATOR)
@@ -68,12 +67,13 @@ class ECDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA
private:
const EC_Group m_group;
- Blinded_Point_Multiply m_base_point;
const BigInt& m_x;
#if defined(BOTAN_HAS_RFC6979_GENERATOR)
std::string m_rfc6979_hash;
#endif
+
+ std::vector<BigInt> m_ws;
};
secure_vector<uint8_t>
@@ -89,7 +89,7 @@ ECDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len,
#endif
const BigInt k_inv = inverse_mod(k, m_group.get_order());
- const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng);
+ const PointGFp k_times_P = m_group.blinded_base_point_multiply(k, rng, m_ws);
const BigInt r = m_group.mod_order(k_times_P.get_affine_x());
const BigInt s = m_group.multiply_mod_order(k_inv, mul_add(m_x, r, m));
diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.cpp b/src/lib/pubkey/ecgdsa/ecgdsa.cpp
index f8e5744d9..6cbd3453b 100644
--- a/src/lib/pubkey/ecgdsa/ecgdsa.cpp
+++ b/src/lib/pubkey/ecgdsa/ecgdsa.cpp
@@ -38,7 +38,6 @@ class ECGDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA
const std::string& emsa) :
PK_Ops::Signature_with_EMSA(emsa),
m_group(ecgdsa.domain()),
- m_base_point(m_group.get_base_point(), m_group.get_order()),
m_x(ecgdsa.private_value())
{
}
@@ -50,8 +49,8 @@ class ECGDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA
private:
const EC_Group m_group;
- Blinded_Point_Multiply m_base_point;
const BigInt& m_x;
+ std::vector<BigInt> m_ws;
};
secure_vector<uint8_t>
@@ -62,7 +61,7 @@ ECGDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len,
BigInt k = BigInt::random_integer(rng, 1, m_group.get_order());
- const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng);
+ const PointGFp k_times_P = m_group.blinded_base_point_multiply(k, rng, m_ws);
const BigInt r = m_group.mod_order(k_times_P.get_affine_x());
const BigInt s = m_group.multiply_mod_order(m_x, mul_sub(k, r, m));
diff --git a/src/lib/pubkey/ecies/ecies.cpp b/src/lib/pubkey/ecies/ecies.cpp
index cd09b4c52..1120a850a 100644
--- a/src/lib/pubkey/ecies/ecies.cpp
+++ b/src/lib/pubkey/ecies/ecies.cpp
@@ -66,16 +66,24 @@ class ECIES_ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
{
- PointGFp point = m_key.domain().OS2ECP(w, w_len);
- Blinded_Point_Multiply blinder(point, m_key.domain().get_order());
- PointGFp S = blinder.blinded_multiply(m_key.private_value(), m_rng);
- BOTAN_ASSERT(S.on_the_curve(), "ECDH agreed value was on the curve");
- return BigInt::encode_1363(S.get_affine_x(), m_key.domain().get_p_bytes());
+ const EC_Group& group = m_key.domain();
+
+ PointGFp input_point = group.OS2ECP(w, w_len);
+ input_point.randomize_repr(m_rng);
+
+ PointGFp_Blinded_Multiplier blinder(input_point, m_ws);
+
+ const PointGFp S = blinder.mul(m_key.private_value(), group.get_order(), m_rng, m_ws);
+
+ if(S.on_the_curve() == false)
+ throw Internal_Error("ECDH agreed value was not on the curve");
+ return BigInt::encode_1363(S.get_affine_x(), group.get_p_bytes());
}
private:
ECIES_PrivateKey m_key;
RandomNumberGenerator& m_rng;
+ std::vector<BigInt> m_ws;
};
std::unique_ptr<PK_Ops::Key_Agreement>
diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.cpp b/src/lib/pubkey/eckcdsa/eckcdsa.cpp
index 743d5ab95..be721a6b6 100644
--- a/src/lib/pubkey/eckcdsa/eckcdsa.cpp
+++ b/src/lib/pubkey/eckcdsa/eckcdsa.cpp
@@ -45,7 +45,6 @@ class ECKCDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA
const std::string& emsa) :
PK_Ops::Signature_with_EMSA(emsa),
m_group(eckcdsa.domain()),
- m_base_point(m_group.get_base_point(), m_group.get_order()),
m_x(eckcdsa.private_value()),
m_prefix()
{
@@ -68,9 +67,9 @@ class ECKCDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA
private:
const EC_Group m_group;
- Blinded_Point_Multiply m_base_point;
const BigInt& m_x;
secure_vector<uint8_t> m_prefix;
+ std::vector<BigInt> m_ws;
};
secure_vector<uint8_t>
@@ -78,7 +77,7 @@ ECKCDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t,
RandomNumberGenerator& rng)
{
const BigInt k = BigInt::random_integer(rng, 1, m_group.get_order());
- const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng);
+ const PointGFp k_times_P = m_group.blinded_base_point_multiply(k, rng, m_ws);
const BigInt k_times_P_x = k_times_P.get_affine_x();
secure_vector<uint8_t> to_be_hashed(k_times_P_x.bytes());
diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp
index 760e667aa..79d3f204d 100644
--- a/src/lib/pubkey/gost_3410/gost_3410.cpp
+++ b/src/lib/pubkey/gost_3410/gost_3410.cpp
@@ -101,7 +101,6 @@ class GOST_3410_Signature_Operation final : public PK_Ops::Signature_with_EMSA
const std::string& emsa) :
PK_Ops::Signature_with_EMSA(emsa),
m_group(gost_3410.domain()),
- m_base_point(m_group.get_base_point(), m_group.get_order()),
m_x(gost_3410.private_value())
{}
@@ -112,8 +111,8 @@ class GOST_3410_Signature_Operation final : public PK_Ops::Signature_with_EMSA
private:
const EC_Group m_group;
- Blinded_Point_Multiply m_base_point;
const BigInt& m_x;
+ std::vector<BigInt> m_ws;
};
secure_vector<uint8_t>
@@ -133,7 +132,7 @@ GOST_3410_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len,
if(e == 0)
e = 1;
- const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng);
+ const PointGFp k_times_P = m_group.blinded_base_point_multiply(k, rng, m_ws);
BOTAN_ASSERT(k_times_P.on_the_curve(), "GOST 34.10 k*g is on the curve");
const BigInt r = m_group.mod_order(k_times_P.get_affine_x());
diff --git a/src/lib/pubkey/sm2/sm2.cpp b/src/lib/pubkey/sm2/sm2.cpp
index 2af888bbc..9ef30d9bf 100644
--- a/src/lib/pubkey/sm2/sm2.cpp
+++ b/src/lib/pubkey/sm2/sm2.cpp
@@ -83,7 +83,6 @@ class SM2_Signature_Operation final : public PK_Ops::Signature
const std::string& ident,
const std::string& hash) :
m_group(sm2.domain()),
- m_base_point(m_group.get_base_point(), m_group.get_order()),
m_x(sm2.private_value()),
m_da_inv(sm2.get_da_inv()),
m_hash(HashFunction::create_or_throw(hash))
@@ -102,12 +101,12 @@ class SM2_Signature_Operation final : public PK_Ops::Signature
private:
const EC_Group m_group;
- Blinded_Point_Multiply m_base_point;
const BigInt& m_x;
const BigInt& m_da_inv;
std::vector<uint8_t> m_za;
std::unique_ptr<HashFunction> m_hash;
+ std::vector<BigInt> m_ws;
};
secure_vector<uint8_t>
@@ -115,7 +114,7 @@ SM2_Signature_Operation::sign(RandomNumberGenerator& rng)
{
const BigInt k = BigInt::random_integer(rng, 1, m_group.get_order());
- const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng);
+ const PointGFp k_times_P = m_group.blinded_base_point_multiply(k, rng, m_ws);
const BigInt e = BigInt::decode(m_hash->final());
const BigInt r = m_group.mod_order(k_times_P.get_affine_x() + e);
diff --git a/src/lib/pubkey/sm2/sm2_enc.cpp b/src/lib/pubkey/sm2/sm2_enc.cpp
index 462c4b968..b0d773635 100644
--- a/src/lib/pubkey/sm2/sm2_enc.cpp
+++ b/src/lib/pubkey/sm2/sm2_enc.cpp
@@ -47,8 +47,7 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption
public:
SM2_Encryption_Operation(const SM2_Encryption_PublicKey& key, const std::string& kdf_hash) :
m_group(key.domain()),
- m_base_point(m_group.get_base_point(), m_group.get_order()),
- m_public_point(key.public_point(), m_group.get_order()),
+ m_mul_public_point(key.public_point()),
m_kdf_hash(kdf_hash)
{}
@@ -69,7 +68,7 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption
const BigInt k = BigInt::random_integer(rng, 1, m_group.get_order());
- const PointGFp C1 = m_base_point.blinded_multiply(k, rng);
+ const PointGFp C1 = m_group.blinded_base_point_multiply(k, rng, m_ws);
const BigInt x1 = C1.get_affine_x();
const BigInt y1 = C1.get_affine_y();
std::vector<uint8_t> x1_bytes(p_bytes);
@@ -77,7 +76,7 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption
BigInt::encode_1363(x1_bytes.data(), x1_bytes.size(), x1);
BigInt::encode_1363(y1_bytes.data(), y1_bytes.size(), y1);
- const PointGFp kPB = m_public_point.blinded_multiply(k, rng);
+ const PointGFp kPB = m_mul_public_point.mul(k, m_group.get_order(), rng, m_ws);
const BigInt x2 = kPB.get_affine_x();
const BigInt y2 = kPB.get_affine_y();
@@ -114,9 +113,9 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption
private:
const EC_Group m_group;
- Blinded_Point_Multiply m_base_point;
- Blinded_Point_Multiply m_public_point;
+ PointGFp_Blinded_Multiplier m_mul_public_point;
const std::string m_kdf_hash;
+ std::vector<BigInt> m_ws;
};
class SM2_Decryption_Operation final : public PK_Ops::Decryption
@@ -134,8 +133,9 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption
const uint8_t ciphertext[],
size_t ciphertext_len) override
{
- const BigInt& cofactor = m_key.domain().get_cofactor();
- const size_t p_bytes = m_key.domain().get_p_bytes();
+ const EC_Group& group = m_key.domain();
+ const BigInt& cofactor = group.get_cofactor();
+ const size_t p_bytes = group.get_p_bytes();
valid_mask = 0x00;
@@ -160,18 +160,20 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption
.end_cons()
.verify_end();
- const PointGFp C1 = m_key.domain().point(x1, y1);
+ PointGFp C1 = group.point(x1, y1);
if(!C1.on_the_curve())
return secure_vector<uint8_t>();
- Blinded_Point_Multiply C1_mul(C1, m_key.domain().get_order());
-
- if(cofactor > 1 && C1_mul.blinded_multiply(cofactor, m_rng).is_zero())
+ if(cofactor > 1 && (C1 * cofactor).is_zero())
{
return secure_vector<uint8_t>();
}
- const PointGFp dbC1 = C1_mul.blinded_multiply(m_key.private_value(), m_rng);
+ C1.randomize_repr(m_rng);
+
+ PointGFp_Blinded_Multiplier C1_mul(C1);
+
+ const PointGFp dbC1 = C1_mul.mul(m_key.private_value(), group.get_order(), m_rng, m_ws);
const BigInt x2 = dbC1.get_affine_x();
const BigInt y2 = dbC1.get_affine_y();
@@ -205,6 +207,7 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption
const SM2_Encryption_PrivateKey& m_key;
RandomNumberGenerator& m_rng;
const std::string m_kdf_hash;
+ std::vector<BigInt> m_ws;
};
}