Botan
1.11.15
|
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 }