summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/lib/pubkey/curve25519/curve25519.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/lib/pubkey/curve25519/curve25519.cpp')
-rw-r--r--comm/third_party/botan/src/lib/pubkey/curve25519/curve25519.cpp143
1 files changed, 143 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/pubkey/curve25519/curve25519.cpp b/comm/third_party/botan/src/lib/pubkey/curve25519/curve25519.cpp
new file mode 100644
index 0000000000..515fdc5e68
--- /dev/null
+++ b/comm/third_party/botan/src/lib/pubkey/curve25519/curve25519.cpp
@@ -0,0 +1,143 @@
+/*
+* Curve25519
+* (C) 2014 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/curve25519.h>
+#include <botan/internal/pk_ops_impl.h>
+#include <botan/ber_dec.h>
+#include <botan/der_enc.h>
+#include <botan/rng.h>
+
+namespace Botan {
+
+void curve25519_basepoint(uint8_t mypublic[32], const uint8_t secret[32])
+ {
+ const uint8_t basepoint[32] = { 9 };
+ curve25519_donna(mypublic, secret, basepoint);
+ }
+
+namespace {
+
+void size_check(size_t size, const char* thing)
+ {
+ if(size != 32)
+ throw Decoding_Error("Invalid size " + std::to_string(size) + " for Curve25519 " + thing);
+ }
+
+secure_vector<uint8_t> curve25519(const secure_vector<uint8_t>& secret,
+ const uint8_t pubval[32])
+ {
+ secure_vector<uint8_t> out(32);
+ curve25519_donna(out.data(), secret.data(), pubval);
+ return out;
+ }
+
+}
+
+AlgorithmIdentifier Curve25519_PublicKey::algorithm_identifier() const
+ {
+ return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_EMPTY_PARAM);
+ }
+
+bool Curve25519_PublicKey::check_key(RandomNumberGenerator&, bool) const
+ {
+ return true; // no tests possible?
+ }
+
+Curve25519_PublicKey::Curve25519_PublicKey(const AlgorithmIdentifier&,
+ const std::vector<uint8_t>& key_bits)
+ {
+ m_public = key_bits;
+
+ size_check(m_public.size(), "public key");
+ }
+
+std::vector<uint8_t> Curve25519_PublicKey::public_key_bits() const
+ {
+ return m_public;
+ }
+
+Curve25519_PrivateKey::Curve25519_PrivateKey(const secure_vector<uint8_t>& secret_key)
+ {
+ if(secret_key.size() != 32)
+ throw Decoding_Error("Invalid size for Curve25519 private key");
+
+ m_public.resize(32);
+ m_private = secret_key;
+ curve25519_basepoint(m_public.data(), m_private.data());
+ }
+
+Curve25519_PrivateKey::Curve25519_PrivateKey(RandomNumberGenerator& rng)
+ {
+ m_private = rng.random_vec(32);
+ m_public.resize(32);
+ curve25519_basepoint(m_public.data(), m_private.data());
+ }
+
+Curve25519_PrivateKey::Curve25519_PrivateKey(const AlgorithmIdentifier&,
+ const secure_vector<uint8_t>& key_bits)
+ {
+ BER_Decoder(key_bits).decode(m_private, OCTET_STRING).discard_remaining();
+
+ size_check(m_private.size(), "private key");
+ m_public.resize(32);
+ curve25519_basepoint(m_public.data(), m_private.data());
+ }
+
+secure_vector<uint8_t> Curve25519_PrivateKey::private_key_bits() const
+ {
+ return DER_Encoder().encode(m_private, OCTET_STRING).get_contents();
+ }
+
+bool Curve25519_PrivateKey::check_key(RandomNumberGenerator&, bool) const
+ {
+ std::vector<uint8_t> public_point(32);
+ curve25519_basepoint(public_point.data(), m_private.data());
+ return public_point == m_public;
+ }
+
+secure_vector<uint8_t> Curve25519_PrivateKey::agree(const uint8_t w[], size_t w_len) const
+ {
+ size_check(w_len, "public value");
+ return curve25519(m_private, w);
+ }
+
+namespace {
+
+/**
+* Curve25519 operation
+*/
+class Curve25519_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
+ {
+ public:
+
+ Curve25519_KA_Operation(const Curve25519_PrivateKey& key, const std::string& kdf) :
+ PK_Ops::Key_Agreement_with_KDF(kdf),
+ m_key(key) {}
+
+ size_t agreed_value_size() const override { return 32; }
+
+ secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
+ {
+ return m_key.agree(w, w_len);
+ }
+ private:
+ const Curve25519_PrivateKey& m_key;
+ };
+
+}
+
+std::unique_ptr<PK_Ops::Key_Agreement>
+Curve25519_PrivateKey::create_key_agreement_op(RandomNumberGenerator& /*rng*/,
+ const std::string& params,
+ const std::string& provider) const
+ {
+ if(provider == "base" || provider.empty())
+ return std::unique_ptr<PK_Ops::Key_Agreement>(new Curve25519_KA_Operation(*this, params));
+ throw Provider_Not_Found(algo_name(), provider);
+ }
+
+}