diff options
-rw-r--r-- | src/lib/pubkey/ec_group/ec_group.cpp | 3 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/point_gfp.cpp | 60 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/point_mul.cpp | 81 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/point_mul.h | 16 | ||||
-rw-r--r-- | src/lib/pubkey/ecdsa/ecdsa.cpp | 7 |
5 files changed, 103 insertions, 64 deletions
diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp index 50a4d85c7..ed1a75b48 100644 --- a/src/lib/pubkey/ec_group/ec_group.cpp +++ b/src/lib/pubkey/ec_group/ec_group.cpp @@ -473,7 +473,8 @@ PointGFp EC_Group::point(const BigInt& x, const BigInt& y) const PointGFp EC_Group::point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const { - return multi_exponentiate(get_base_point(), x, pt, y); + PointGFp_Multi_Point_Precompute xy_mul(get_base_point(), pt); + return xy_mul.multi_exp(x, y); } PointGFp EC_Group::blinded_base_point_multiply(const BigInt& k, diff --git a/src/lib/pubkey/ec_group/point_gfp.cpp b/src/lib/pubkey/ec_group/point_gfp.cpp index 51cb7d153..48ae91f3c 100644 --- a/src/lib/pubkey/ec_group/point_gfp.cpp +++ b/src/lib/pubkey/ec_group/point_gfp.cpp @@ -361,66 +361,6 @@ PointGFp& PointGFp::operator*=(const BigInt& scalar) return *this; } -PointGFp multi_exponentiate(const PointGFp& x, const BigInt& z1, - const PointGFp& y, const BigInt& z2) - { - const size_t z_bits = round_up(std::max(z1.bits(), z2.bits()), 2); - - std::vector<BigInt> ws(PointGFp::WORKSPACE_SIZE); - - PointGFp x2 = x; - x2.mult2(ws); - - const PointGFp x3(x2.plus(x, ws)); - - PointGFp y2 = y; - y2.mult2(ws); - - const PointGFp y3(y2.plus(y, ws)); - - const PointGFp M[16] = { - x.zero(), // 0000 - x, // 0001 - x2, // 0010 - x3, // 0011 - y, // 0100 - y.plus(x, ws), // 0101 - y.plus(x2, ws), // 0110 - y.plus(x3, ws), // 0111 - y2, // 1000 - y2.plus(x, ws), // 1001 - y2.plus(x2, ws), // 1010 - y2.plus(x3, ws), // 1011 - y3, // 1100 - y3.plus(x, ws), // 1101 - y3.plus(x2, ws), // 1110 - y3.plus(x3, ws), // 1111 - }; - - PointGFp H = x.zero(); - - for(size_t i = 0; i != z_bits; i += 2) - { - if(i > 0) - { - H.mult2(ws); - H.mult2(ws); - } - - const uint8_t z1_b = z1.get_substring(z_bits - i - 2, 2); - const uint8_t z2_b = z2.get_substring(z_bits - i - 2, 2); - - const uint8_t z12 = (4*z2_b) + z1_b; - - H.add(M[z12], ws); - } - - if(z1.is_negative() != z2.is_negative()) - H.negate(); - - return H; - } - PointGFp operator*(const BigInt& scalar, const PointGFp& point) { BOTAN_DEBUG_ASSERT(point.on_the_curve()); diff --git a/src/lib/pubkey/ec_group/point_mul.cpp b/src/lib/pubkey/ec_group/point_mul.cpp index 7acb60b6a..adddaaa37 100644 --- a/src/lib/pubkey/ec_group/point_mul.cpp +++ b/src/lib/pubkey/ec_group/point_mul.cpp @@ -10,6 +10,13 @@ namespace Botan { +PointGFp multi_exponentiate(const PointGFp& x, const BigInt& z1, + const PointGFp& y, const BigInt& z2) + { + PointGFp_Multi_Point_Precompute xy_mul(x, y); + return xy_mul.multi_exp(z1, z2); + } + Blinded_Point_Multiply::Blinded_Point_Multiply(const PointGFp& base, const BigInt& order, size_t h) : @@ -178,4 +185,78 @@ PointGFp PointGFp_Var_Point_Precompute::mul(const BigInt& k, return R; } + +PointGFp_Multi_Point_Precompute::PointGFp_Multi_Point_Precompute(const PointGFp& x, + const PointGFp& y) + { + std::vector<BigInt> ws(PointGFp::WORKSPACE_SIZE); + + PointGFp x2 = x; + x2.mult2(ws); + + const PointGFp x3(x2.plus(x, ws)); + + PointGFp y2 = y; + y2.mult2(ws); + + const PointGFp y3(y2.plus(y, ws)); + + m_M.reserve(15); + + m_M.push_back(x); + m_M.push_back(x2); + m_M.push_back(x3); + + m_M.push_back(y); + m_M.push_back(y.plus(x, ws)); + m_M.push_back(y.plus(x2, ws)); + m_M.push_back(y.plus(x3, ws)); + + m_M.push_back(y2); + m_M.push_back(y2.plus(x, ws)); + m_M.push_back(y2.plus(x2, ws)); + m_M.push_back(y2.plus(x3, ws)); + + m_M.push_back(y3); + m_M.push_back(y3.plus(x, ws)); + m_M.push_back(y3.plus(x2, ws)); + m_M.push_back(y3.plus(x3, ws)); + + PointGFp::force_all_affine(m_M, ws[0].get_word_vector()); + } + +PointGFp PointGFp_Multi_Point_Precompute::multi_exp(const BigInt& z1, + const BigInt& z2) const + { + std::vector<BigInt> ws(PointGFp::WORKSPACE_SIZE); + + const size_t z_bits = round_up(std::max(z1.bits(), z2.bits()), 2); + + PointGFp H = m_M[0].zero(); + + for(size_t i = 0; i != z_bits; i += 2) + { + if(i > 0) + { + H.mult2(ws); + H.mult2(ws); + } + + const uint8_t z1_b = z1.get_substring(z_bits - i - 2, 2); + const uint8_t z2_b = z2.get_substring(z_bits - i - 2, 2); + + const uint8_t z12 = (4*z2_b) + z1_b; + + if(z12) + { + H.add_affine(m_M[z12-1], ws); + } + } + + if(z1.is_negative() != z2.is_negative()) + H.negate(); + + return H; + } + } diff --git a/src/lib/pubkey/ec_group/point_mul.h b/src/lib/pubkey/ec_group/point_mul.h index 97fd326a2..9a19f90d4 100644 --- a/src/lib/pubkey/ec_group/point_mul.h +++ b/src/lib/pubkey/ec_group/point_mul.h @@ -42,6 +42,22 @@ class PointGFp_Var_Point_Precompute std::vector<PointGFp> m_U; }; +class PointGFp_Multi_Point_Precompute + { + public: + PointGFp_Multi_Point_Precompute(const PointGFp& g1, + const PointGFp& g2); + + /* + * Return (g1*k1 + g2*k2) + * Not constant time, intended to use with public inputs + */ + PointGFp multi_exp(const BigInt& k1, + const BigInt& k2) const; + private: + std::vector<PointGFp> m_M; + }; + } #endif diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp index a2877f7fc..6ff02e8c9 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.cpp +++ b/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -10,6 +10,7 @@ #include <botan/ecdsa.h> #include <botan/internal/pk_ops_impl.h> +#include <botan/internal/point_mul.h> #include <botan/keypair.h> #include <botan/reducer.h> #include <botan/emsa.h> @@ -112,7 +113,7 @@ class ECDSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA const std::string& emsa) : PK_Ops::Verification_with_EMSA(emsa), m_group(ecdsa.domain()), - m_public_point(ecdsa.public_point()) + m_gy_mul(m_group.get_base_point(), ecdsa.public_point()) { } @@ -124,7 +125,7 @@ class ECDSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA const uint8_t sig[], size_t sig_len) override; private: const EC_Group m_group; - const PointGFp& m_public_point; + const PointGFp_Multi_Point_Precompute m_gy_mul; }; bool ECDSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len, @@ -145,7 +146,7 @@ bool ECDSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len, const BigInt u1 = m_group.multiply_mod_order(e, w); const BigInt u2 = m_group.multiply_mod_order(r, w); - const PointGFp R = m_group.point_multiply(u1, m_public_point, u2); + const PointGFp R = m_gy_mul.multi_exp(u1, u2); if(R.is_zero()) return false; |