Botan  1.11.15
src/lib/pubkey/curve25519/curve25519.cpp
Go to the documentation of this file.
00001 /*
00002 * Curve25519
00003 * (C) 2014 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/curve25519.h>
00010 #include <botan/ber_dec.h>
00011 #include <botan/der_enc.h>
00012 
00013 namespace Botan {
00014 
00015 namespace {
00016 
00017 void size_check(size_t size, const char* thing)
00018    {
00019    if(size != 32)
00020       throw Decoding_Error("Invalid size " + std::to_string(size) + " for Curve25519 " + thing);
00021    }
00022 
00023 secure_vector<byte> curve25519(const secure_vector<byte>& secret,
00024                                const byte pubval[32])
00025    {
00026    secure_vector<byte> out(32);
00027    const int rc = curve25519_donna(&out[0], &secret[0], &pubval[0]);
00028    BOTAN_ASSERT_EQUAL(rc, 0, "Return value of curve25519_donna is ok");
00029    return out;
00030    }
00031 
00032 secure_vector<byte> curve25519_basepoint(const secure_vector<byte>& secret)
00033    {
00034    const byte basepoint[32] = { 9 };
00035    return curve25519(secret, basepoint);
00036    }
00037 
00038 }
00039 
00040 AlgorithmIdentifier Curve25519_PublicKey::algorithm_identifier() const
00041    {
00042    return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_NULL_PARAM);
00043    }
00044 
00045 bool Curve25519_PublicKey::check_key(RandomNumberGenerator&, bool) const
00046    {
00047    return true; // no tests possible?
00048    }
00049 
00050 Curve25519_PublicKey::Curve25519_PublicKey(const AlgorithmIdentifier&,
00051                                            const secure_vector<byte>& key_bits)
00052    {
00053    BER_Decoder(key_bits)
00054       .start_cons(SEQUENCE)
00055       .decode(m_public, OCTET_STRING)
00056       .verify_end()
00057    .end_cons();
00058 
00059    size_check(m_public.size(), "public key");
00060    }
00061 
00062 std::vector<byte> Curve25519_PublicKey::x509_subject_public_key() const
00063    {
00064    return DER_Encoder()
00065       .start_cons(SEQUENCE)
00066         .encode(m_public, OCTET_STRING)
00067       .end_cons()
00068       .get_contents_unlocked();
00069    }
00070 
00071 Curve25519_PrivateKey::Curve25519_PrivateKey(RandomNumberGenerator& rng)
00072    {
00073    m_private = rng.random_vec(32);
00074    m_public = curve25519_basepoint(m_private);
00075    }
00076 
00077 Curve25519_PrivateKey::Curve25519_PrivateKey(const AlgorithmIdentifier&,
00078                                              const secure_vector<byte>& key_bits,
00079                                              RandomNumberGenerator& rng)
00080    {
00081    BER_Decoder(key_bits)
00082       .start_cons(SEQUENCE)
00083       .decode(m_public, OCTET_STRING)
00084       .decode(m_private, OCTET_STRING)
00085       .verify_end()
00086    .end_cons();
00087 
00088    size_check(m_public.size(), "public key");
00089    size_check(m_private.size(), "private key");
00090 
00091    load_check(rng);
00092    }
00093 
00094 secure_vector<byte> Curve25519_PrivateKey::pkcs8_private_key() const
00095    {
00096    return DER_Encoder()
00097       .start_cons(SEQUENCE)
00098         .encode(m_public, OCTET_STRING)
00099         .encode(m_private, OCTET_STRING)
00100       .end_cons()
00101       .get_contents();
00102    }
00103 
00104 bool Curve25519_PrivateKey::check_key(RandomNumberGenerator&, bool) const
00105    {
00106    return curve25519_basepoint(m_private) == m_public;
00107    }
00108 
00109 secure_vector<byte> Curve25519_PrivateKey::agree(const byte w[], size_t w_len) const
00110    {
00111    size_check(w_len, "public value");
00112    return curve25519(m_private, w);
00113    }
00114 
00115 namespace {
00116 
00117 /**
00118 * Curve25519 operation
00119 */
00120 class Curve25519_KA_Operation : public PK_Ops::Key_Agreement
00121    {
00122    public:
00123       typedef Curve25519_PrivateKey Key_Type;
00124 
00125       Curve25519_KA_Operation(const Curve25519_PrivateKey& key, const std::string&) :
00126          m_key(key) {}
00127 
00128       secure_vector<byte> agree(const byte w[], size_t w_len)
00129          {
00130          return m_key.agree(w, w_len);
00131          }
00132    private:
00133       const Curve25519_PrivateKey& m_key;
00134    };
00135 
00136 BOTAN_REGISTER_PK_KEY_AGREE_OP("Curve25519", Curve25519_KA_Operation);
00137 
00138 }
00139 
00140 
00141 }