Botan  1.11.15
src/lib/pubkey/dh/dh.cpp
Go to the documentation of this file.
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 }