aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/curve25519/curve25519.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2014-12-27 17:50:57 +0000
committerlloyd <[email protected]>2014-12-27 17:50:57 +0000
commitd0daf875978848c3edf65c7b3683a21605f72e64 (patch)
tree46690afadfb5e9acb766468f7f7481bb1244049d /src/lib/pubkey/curve25519/curve25519.cpp
parent675c2e324268ebce7e2c665389ebd57d38083200 (diff)
Add Curve25519 based on curve25519-donna by Adam Langley.
This uses only the c64 version from curve25519-donna; on systems that don't have a native uint128_t type, a donna128 type stands in for just enough 128-bit operations to satisfy donna.cpp
Diffstat (limited to 'src/lib/pubkey/curve25519/curve25519.cpp')
-rw-r--r--src/lib/pubkey/curve25519/curve25519.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/lib/pubkey/curve25519/curve25519.cpp b/src/lib/pubkey/curve25519/curve25519.cpp
new file mode 100644
index 000000000..fe30e37d9
--- /dev/null
+++ b/src/lib/pubkey/curve25519/curve25519.cpp
@@ -0,0 +1,115 @@
+/*
+* Curve25519
+* (C) 2014 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/curve25519.h>
+#include <botan/ber_dec.h>
+#include <botan/der_enc.h>
+
+namespace Botan {
+
+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<byte> curve25519(const secure_vector<byte>& secret,
+ const byte pubval[32])
+ {
+ secure_vector<byte> out(32);
+ const int rc = curve25519_donna(&out[0], &secret[0], &pubval[0]);
+ BOTAN_ASSERT_EQUAL(rc, 0, "Return value of curve25519_donna is ok");
+ return out;
+ }
+
+secure_vector<byte> curve25519_basepoint(const secure_vector<byte>& secret)
+ {
+ const byte basepoint[32] = { 9 };
+ return curve25519(secret, basepoint);
+ }
+
+}
+
+AlgorithmIdentifier Curve25519_PublicKey::algorithm_identifier() const
+ {
+ return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_NULL_PARAM);
+ }
+
+bool Curve25519_PublicKey::check_key(RandomNumberGenerator&, bool) const
+ {
+ return true; // no tests possible?
+ }
+
+Curve25519_PublicKey::Curve25519_PublicKey(const AlgorithmIdentifier&,
+ const secure_vector<byte>& key_bits)
+ {
+ BER_Decoder(key_bits)
+ .start_cons(SEQUENCE)
+ .decode(m_public, OCTET_STRING)
+ .verify_end()
+ .end_cons();
+
+ size_check(m_public.size(), "public key");
+ }
+
+std::vector<byte> Curve25519_PublicKey::x509_subject_public_key() const
+ {
+ return DER_Encoder()
+ .start_cons(SEQUENCE)
+ .encode(m_public, OCTET_STRING)
+ .end_cons()
+ .get_contents_unlocked();
+ }
+
+Curve25519_PrivateKey::Curve25519_PrivateKey(RandomNumberGenerator& rng)
+ {
+ m_private = rng.random_vec(32);
+ m_public = curve25519_basepoint(m_private);
+ }
+
+Curve25519_PrivateKey::Curve25519_PrivateKey(const AlgorithmIdentifier&,
+ const secure_vector<byte>& key_bits,
+ RandomNumberGenerator& rng)
+ {
+ BER_Decoder(key_bits)
+ .start_cons(SEQUENCE)
+ .decode(m_public, OCTET_STRING)
+ .decode(m_private, OCTET_STRING)
+ .verify_end()
+ .end_cons();
+
+ size_check(m_public.size(), "public key");
+ size_check(m_private.size(), "private key");
+
+ load_check(rng);
+ }
+
+secure_vector<byte> Curve25519_PrivateKey::pkcs8_private_key() const
+ {
+ return DER_Encoder()
+ .start_cons(SEQUENCE)
+ .encode(m_public, OCTET_STRING)
+ .encode(m_private, OCTET_STRING)
+ .end_cons()
+ .get_contents();
+ }
+
+bool Curve25519_PrivateKey::check_key(RandomNumberGenerator&, bool) const
+ {
+ return curve25519_basepoint(m_private) == m_public;
+ }
+
+secure_vector<byte> Curve25519_PrivateKey::agree(const byte w[], size_t w_len) const
+ {
+ size_check(w_len, "public value");
+
+ return curve25519(m_private, w);
+ }
+
+}