From 2a873fd4e1d53c45898b27e1c953b551b2cf6023 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Tue, 7 Jul 2015 09:50:32 +0100 Subject: Add functions for creating and verifying ed25519 signatures --- include/olm/crypto.hh | 39 ++++++++++++++++++++++++++++++++++++++- src/crypto.cpp | 36 ++++++++++++++++++++++++++++++++++++ tests/test_crypto.cpp | 34 +++++++++++++++++++++++++++++++--- 3 files changed, 105 insertions(+), 4 deletions(-) diff --git a/include/olm/crypto.hh b/include/olm/crypto.hh index 7f8f069..b845bfe 100644 --- a/include/olm/crypto.hh +++ b/include/olm/crypto.hh @@ -33,6 +33,18 @@ struct Curve25519KeyPair : public Curve25519PublicKey { }; +struct Ed25519PublicKey { + static const int LENGTH = 32; + std::uint8_t public_key[32]; +}; + + +struct Ed25519KeyPair : public Ed25519PublicKey { + static const int LENGTH = 64; + std::uint8_t private_key[32]; +}; + + /** Generate a curve25519 key pair from 32 random bytes. */ void curve25519_generate_key( std::uint8_t const * random_32_bytes, @@ -61,7 +73,7 @@ void curve25519_sign( ); -/** Verify thei message using their public key. +/** Verify their message using their public key. * The signature input buffer must be 64 bytes long. * Returns true if the signature is valid. */ bool curve25519_verify( @@ -70,6 +82,31 @@ bool curve25519_verify( std::uint8_t const * signature ); +/** Generate a curve25519 key pair from 32 random bytes. */ +void ed25519_generate_key( + std::uint8_t const * random_32_bytes, + Ed25519KeyPair & key_pair +); + + +/** Signs the message using our private key. + * The output buffer must be at least 64 bytes long. */ +void ed25519_sign( + Ed25519KeyPair const & our_key, + std::uint8_t const * message, std::size_t message_length, + std::uint8_t * output +); + + +/** Verify their message using their public key. + * The signature input buffer must be 64 bytes long. + * Returns true if the signature is valid. */ +bool ed25519_verify( + Ed25519PublicKey const & their_key, + std::uint8_t const * message, std::size_t message_length, + std::uint8_t const * signature +); + struct Aes256Key { static const int LENGTH = 32; diff --git a/src/crypto.cpp b/src/crypto.cpp index db4bfa6..ed89d64 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -191,6 +191,42 @@ bool olm::curve25519_verify( ); } + +void olm::ed25519_generate_key( + std::uint8_t const * random_32_bytes, + olm::Ed25519KeyPair & key_pair +) { + std::memcpy(key_pair.private_key, random_32_bytes, 32); + ::ed25519_keypair(key_pair.private_key, key_pair.public_key); +} + + +void olm::ed25519_sign( + olm::Ed25519KeyPair const & our_key, + std::uint8_t const * message, std::size_t message_length, + std::uint8_t * output +) { + ::ed25519_sign( + output, + message, message_length, + our_key.public_key, our_key.private_key + ); +} + + +bool olm::ed25519_verify( + olm::Ed25519PublicKey const & their_key, + std::uint8_t const * message, std::size_t message_length, + std::uint8_t const * signature +) { + return 0 != ::ed25519_verify( + signature, + message, message_length, + their_key.public_key + ); +} + + std::size_t olm::aes_encrypt_cbc_length( std::size_t input_length ) { diff --git a/tests/test_crypto.cpp b/tests/test_crypto.cpp index b8ffbcd..b3ff593 100644 --- a/tests/test_crypto.cpp +++ b/tests/test_crypto.cpp @@ -83,8 +83,8 @@ assert_equals(expected_agreement, actual_agreement, 32); } /* Curve25529 Test Case 1 */ -{ /* Signature Test Cast 1 */ -TestCase test_case("Signature Test Case 1"); +{ /* Curve25519 Signature Test Case 1 */ +TestCase test_case("Curve25519 Signature Test Case 1"); std::uint8_t private_key[33] = "This key is a string of 32 bytes"; std::uint8_t message[] = "message"; @@ -110,7 +110,35 @@ result = olm::curve25519_verify( ); assert_equals(false, result); -} /* Signature Test Cast 1 */ +} /* Curve25519 Signature Test Case 1 */ + +{ +TestCase test_case("Ed25519 Signature Test Case 1"); +std::uint8_t private_key[33] = "This key is a string of 32 bytes"; + +std::uint8_t message[] = "Hello, World"; +std::size_t message_length = sizeof(message) - 1; + +olm::Ed25519KeyPair key_pair; +olm::ed25519_generate_key(private_key, key_pair); + +std::uint8_t signature[64]; +olm::ed25519_sign( + key_pair, message, message_length, signature +); + +bool result = olm::ed25519_verify( + key_pair, message, message_length, signature +); +assert_equals(true, result); + +message[0] = 'n'; +result = olm::ed25519_verify( + key_pair, message, message_length, signature +); +assert_equals(false, result); +} + { /* AES Test Case 1 */ -- cgit v1.2.3