Botan
1.11.15
|
00001 /* 00002 * Diffie-Hellman 00003 * (C) 1999-2007 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/pk_utils.h> 00009 #include <botan/dh.h> 00010 #include <botan/workfactor.h> 00011 #include <botan/pow_mod.h> 00012 #include <botan/blinding.h> 00013 00014 namespace Botan { 00015 00016 /* 00017 * DH_PublicKey Constructor 00018 */ 00019 DH_PublicKey::DH_PublicKey(const DL_Group& grp, const BigInt& y1) 00020 { 00021 group = grp; 00022 y = y1; 00023 } 00024 00025 /* 00026 * Return the public value for key agreement 00027 */ 00028 std::vector<byte> DH_PublicKey::public_value() const 00029 { 00030 return unlock(BigInt::encode_1363(y, group_p().bytes())); 00031 } 00032 00033 /* 00034 * Create a DH private key 00035 */ 00036 DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng, 00037 const DL_Group& grp, 00038 const BigInt& x_arg) 00039 { 00040 group = grp; 00041 x = x_arg; 00042 00043 if(x == 0) 00044 { 00045 const BigInt& p = group_p(); 00046 x.randomize(rng, 2 * dl_work_factor(p.bits())); 00047 } 00048 00049 if(y == 0) 00050 y = power_mod(group_g(), x, group_p()); 00051 00052 if(x == 0) 00053 gen_check(rng); 00054 else 00055 load_check(rng); 00056 } 00057 00058 /* 00059 * Load a DH private key 00060 */ 00061 DH_PrivateKey::DH_PrivateKey(const AlgorithmIdentifier& alg_id, 00062 const secure_vector<byte>& key_bits, 00063 RandomNumberGenerator& rng) : 00064 DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_42) 00065 { 00066 if(y == 0) 00067 y = power_mod(group_g(), x, group_p()); 00068 00069 load_check(rng); 00070 } 00071 00072 /* 00073 * Return the public value for key agreement 00074 */ 00075 std::vector<byte> DH_PrivateKey::public_value() const 00076 { 00077 return DH_PublicKey::public_value(); 00078 } 00079 00080 namespace { 00081 00082 /** 00083 * DH operation 00084 */ 00085 class DH_KA_Operation : public PK_Ops::Key_Agreement 00086 { 00087 public: 00088 typedef DH_PrivateKey Key_Type; 00089 DH_KA_Operation(const DH_PrivateKey& key, const std::string&); 00090 00091 secure_vector<byte> agree(const byte w[], size_t w_len); 00092 private: 00093 const BigInt& m_p; 00094 00095 Fixed_Exponent_Power_Mod m_powermod_x_p; 00096 Blinder m_blinder; 00097 }; 00098 00099 DH_KA_Operation::DH_KA_Operation(const DH_PrivateKey& dh, const std::string&) : 00100 m_p(dh.group_p()), 00101 m_powermod_x_p(dh.get_x(), m_p), 00102 m_blinder(m_p, 00103 [](const BigInt& k) { return k; }, 00104 [this](const BigInt& k) { return m_powermod_x_p(inverse_mod(k, m_p)); }) 00105 { 00106 } 00107 00108 secure_vector<byte> DH_KA_Operation::agree(const byte w[], size_t w_len) 00109 { 00110 BigInt input = BigInt::decode(w, w_len); 00111 00112 if(input <= 1 || input >= m_p - 1) 00113 throw Invalid_Argument("DH agreement - invalid key provided"); 00114 00115 BigInt r = m_blinder.unblind(m_powermod_x_p(m_blinder.blind(input))); 00116 00117 return BigInt::encode_1363(r, m_p.bytes()); 00118 } 00119 00120 } 00121 00122 BOTAN_REGISTER_PK_KEY_AGREE_OP("DH", DH_KA_Operation); 00123 00124 }