Botan  2.4.0
Crypto and TLS for C++11
ecdh.cpp
Go to the documentation of this file.
1 /*
2 * ECDH implemenation
3 * (C) 2007 Manuel Hartl, FlexSecure GmbH
4 * 2007 Falko Strenzke, FlexSecure GmbH
5 * 2008-2010 Jack Lloyd
6 *
7 * Botan is released under the Simplified BSD License (see license.txt)
8 */
9 
10 #include <botan/ecdh.h>
11 #include <botan/numthry.h>
12 #include <botan/internal/pk_ops_impl.h>
13 
14 #if defined(BOTAN_HAS_OPENSSL)
15  #include <botan/internal/openssl.h>
16 #endif
17 
18 namespace Botan {
19 
20 namespace {
21 
22 /**
23 * ECDH operation
24 */
25 class ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
26  {
27  public:
28 
29  ECDH_KA_Operation(const ECDH_PrivateKey& key, const std::string& kdf, RandomNumberGenerator& rng) :
30  PK_Ops::Key_Agreement_with_KDF(kdf),
31  m_curve(key.domain().get_curve()),
32  m_cofactor(key.domain().get_cofactor()),
33  m_order(key.domain().get_order()),
34  m_rng(rng)
35  {
36  m_l_times_priv = inverse_mod(m_cofactor, m_order) * key.private_value();
37  }
38 
39  secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
40  {
41  PointGFp point = OS2ECP(w, w_len, m_curve);
42  PointGFp S = m_cofactor * point;
43  Blinded_Point_Multiply blinder(S, m_order);
44  S = blinder.blinded_multiply(m_l_times_priv, m_rng);
45  BOTAN_ASSERT(S.on_the_curve(), "ECDH agreed value was on the curve");
46  return BigInt::encode_1363(S.get_affine_x(), m_curve.get_p().bytes());
47  }
48  private:
49  const CurveGFp& m_curve;
50  const BigInt& m_cofactor;
51  const BigInt& m_order;
52  BigInt m_l_times_priv;
53  RandomNumberGenerator& m_rng;
54 
55  };
56 
57 }
58 
59 std::unique_ptr<PK_Ops::Key_Agreement>
61  const std::string& params,
62  const std::string& provider) const
63  {
64 #if defined(BOTAN_HAS_OPENSSL)
65  if(provider == "openssl" || provider.empty())
66  {
67  try
68  {
69  return make_openssl_ecdh_ka_op(*this, params);
70  }
71  catch(Lookup_Error&)
72  {
73  if(provider == "openssl")
74  throw;
75  }
76  }
77 #endif
78 
79  if(provider == "base" || provider.empty())
80  return std::unique_ptr<PK_Ops::Key_Agreement>(new ECDH_KA_Operation(*this, params, rng));
81 
82  throw Provider_Not_Found(algo_name(), provider);
83  }
84 
85 
86 }
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:29
std::unique_ptr< PK_Ops::Key_Agreement > create_key_agreement_op(RandomNumberGenerator &rng, const std::string &params, const std::string &provider) const override
Definition: ecdh.cpp:60
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition: numthry.cpp:277
Definition: alg_id.cpp:13
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:82
PointGFp OS2ECP(const uint8_t data[], size_t data_len, const CurveGFp &curve)
Definition: point_gfp.cpp:543