You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
7.9 KiB
178 lines
7.9 KiB
// donna.h - written and placed in public domain by Jeffrey Walton |
|
// Crypto++ specific implementation wrapped around Andrew |
|
// Moon's public domain curve25519-donna and ed25519-donna, |
|
// https://github.com/floodyberry/curve25519-donna and |
|
// https://github.com/floodyberry/ed25519-donna. |
|
|
|
// The curve25519 and ed25519 source files multiplex different repos and |
|
// architectures using namespaces. The repos are Andrew Moon's |
|
// curve25519-donna and ed25519-donna. The architectures are 32-bit, 64-bit |
|
// and SSE. For example, 32-bit x25519 uses symbols from Donna::X25519 and |
|
// Donna::Arch32. |
|
|
|
// If needed, see Moon's commit "Go back to ignoring 256th bit [sic]", |
|
// https://github.com/floodyberry/curve25519-donna/commit/57a683d18721a658 |
|
|
|
/// \file donna.h |
|
/// \details Functions for curve25519 and ed25519 operations |
|
/// \details This header provides the entry points into Andrew Moon's |
|
/// curve25519 and ed25519 curve functions. The Crypto++ classes x25519 |
|
/// and ed25519 use the functions. The functions are in the <tt>Donna</tt> |
|
/// namespace and are curve25519_mult(), ed25519_publickey(), |
|
/// ed25519_sign() and ed25519_sign_open(). |
|
/// \details At the moment the hash function for signing is fixed at |
|
/// SHA512. |
|
|
|
#ifndef CRYPTOPP_DONNA_H |
|
#define CRYPTOPP_DONNA_H |
|
|
|
#include "cryptlib.h" |
|
#include "stdcpp.h" |
|
|
|
NAMESPACE_BEGIN(CryptoPP) |
|
NAMESPACE_BEGIN(Donna) |
|
|
|
//***************************** curve25519 *****************************// |
|
|
|
/// \brief Generate a public key |
|
/// \param publicKey byte array for the public key |
|
/// \param secretKey byte array with the private key |
|
/// \returns 0 on success, non-0 otherwise |
|
/// \details curve25519_mult() generates a public key from an existing |
|
/// secret key. Internally curve25519_mult() performs a scalar |
|
/// multiplication using the base point and writes the result to |
|
/// <tt>pubkey</tt>. |
|
int curve25519_mult(byte publicKey[32], const byte secretKey[32]); |
|
|
|
/// \brief Generate a shared key |
|
/// \param sharedKey byte array for the shared secret |
|
/// \param secretKey byte array with the private key |
|
/// \param othersKey byte array with the peer's public key |
|
/// \returns 0 on success, non-0 otherwise |
|
/// \details curve25519_mult() generates a shared key from an existing |
|
/// secret key and the other party's public key. Internally |
|
/// curve25519_mult() performs a scalar multiplication using the two keys |
|
/// and writes the result to <tt>sharedKey</tt>. |
|
int curve25519_mult(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]); |
|
|
|
//******************************* ed25519 *******************************// |
|
|
|
/// \brief Creates a public key from a secret key |
|
/// \param publicKey byte array for the public key |
|
/// \param secretKey byte array with the private key |
|
/// \returns 0 on success, non-0 otherwise |
|
/// \details ed25519_publickey() generates a public key from a secret key. |
|
/// Internally ed25519_publickey() performs a scalar multiplication |
|
/// using the secret key and then writes the result to <tt>publicKey</tt>. |
|
int ed25519_publickey(byte publicKey[32], const byte secretKey[32]); |
|
|
|
/// \brief Creates a signature on a message |
|
/// \param message byte array with the message |
|
/// \param messageLength size of the message, in bytes |
|
/// \param publicKey byte array with the public key |
|
/// \param secretKey byte array with the private key |
|
/// \param signature byte array for the signature |
|
/// \returns 0 on success, non-0 otherwise |
|
/// \details ed25519_sign() generates a signature on a message using |
|
/// the public and private keys. The various buffers can be exact |
|
/// sizes, and do not require extra space like when using the |
|
/// NaCl library functions. |
|
/// \details At the moment the hash function for signing is fixed at |
|
/// SHA512. |
|
int ed25519_sign(const byte* message, size_t messageLength, const byte secretKey[32], const byte publicKey[32], byte signature[64]); |
|
|
|
/// \brief Creates a signature on a message |
|
/// \param stream std::istream derived class |
|
/// \param publicKey byte array with the public key |
|
/// \param secretKey byte array with the private key |
|
/// \param signature byte array for the signature |
|
/// \returns 0 on success, non-0 otherwise |
|
/// \details ed25519_sign() generates a signature on a message using |
|
/// the public and private keys. The various buffers can be exact |
|
/// sizes, and do not require extra space like when using the |
|
/// NaCl library functions. |
|
/// \details This ed25519_sign() overload handles large streams. It |
|
/// was added for signing and verifying files that are too large |
|
/// for a memory allocation. |
|
/// \details At the moment the hash function for signing is fixed at |
|
/// SHA512. |
|
int ed25519_sign(std::istream& stream, const byte secretKey[32], const byte publicKey[32], byte signature[64]); |
|
|
|
/// \brief Verifies a signature on a message |
|
/// \param message byte array with the message |
|
/// \param messageLength size of the message, in bytes |
|
/// \param publicKey byte array with the public key |
|
/// \param signature byte array with the signature |
|
/// \returns 0 on success, non-0 otherwise |
|
/// \details ed25519_sign_open() verifies a signature on a message using |
|
/// the public key. The various buffers can be exact sizes, and do not |
|
/// require extra space like when using the NaCl library functions. |
|
/// \details At the moment the hash function for signing is fixed at |
|
/// SHA512. |
|
int |
|
ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64]); |
|
|
|
/// \brief Verifies a signature on a message |
|
/// \param stream std::istream derived class |
|
/// \param publicKey byte array with the public key |
|
/// \param signature byte array with the signature |
|
/// \returns 0 on success, non-0 otherwise |
|
/// \details ed25519_sign_open() verifies a signature on a message using |
|
/// the public key. The various buffers can be exact sizes, and do not |
|
/// require extra space like when using the NaCl library functions. |
|
/// \details This ed25519_sign_open() overload handles large streams. It |
|
/// was added for signing and verifying files that are too large |
|
/// for a memory allocation. |
|
/// \details At the moment the hash function for signing is fixed at |
|
/// SHA512. |
|
int |
|
ed25519_sign_open(std::istream& stream, const byte publicKey[32], const byte signature[64]); |
|
|
|
//****************************** Internal ******************************// |
|
|
|
#ifndef CRYPTOPP_DOXYGEN_PROCESSING |
|
|
|
// CRYPTOPP_WORD128_AVAILABLE mostly depends upon GCC support for |
|
// __SIZEOF_INT128__. If __SIZEOF_INT128__ is not available then Moon |
|
// provides routines for MSC and GCC. It should cover most platforms, |
|
// but there are gaps like MS ARM64 and XLC. We tried to enable the |
|
// 64-bit path for SunCC from 12.5 but we got the dreaded compile |
|
// error "The operand ___LCM cannot be assigned to". |
|
|
|
#if defined(CRYPTOPP_WORD128_AVAILABLE) || \ |
|
(defined(_MSC_VER) && defined(_M_X64)) |
|
# define CRYPTOPP_CURVE25519_64BIT 1 |
|
#else |
|
# define CRYPTOPP_CURVE25519_32BIT 1 |
|
#endif |
|
|
|
// Benchmarking on a modern 64-bit Core i5-6400 @2.7 GHz shows SSE2 on Linux |
|
// is not profitable. Here are the numbers in milliseconds/operation: |
|
// |
|
// * Langley, C++, 0.050 |
|
// * Moon, C++: 0.040 |
|
// * Moon, SSE2: 0.061 |
|
// * Moon, native: 0.045 |
|
// |
|
// However, a modern 64-bit Core i5-3200 @2.5 GHz shows SSE2 is profitable |
|
// for MS compilers. Here are the numbers in milliseconds/operation: |
|
// |
|
// * x86, no SSE2, 0.294 |
|
// * x86, SSE2, 0.097 |
|
// * x64, no SSE2, 0.081 |
|
// * x64, SSE2, 0.071 |
|
|
|
#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) && defined(_MSC_VER) |
|
# define CRYPTOPP_CURVE25519_SSE2 1 |
|
#endif |
|
|
|
#if (CRYPTOPP_CURVE25519_SSE2) |
|
extern int curve25519_mult_SSE2(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]); |
|
#endif |
|
|
|
#endif // CRYPTOPP_DOXYGEN_PROCESSING |
|
|
|
NAMESPACE_END // Donna |
|
NAMESPACE_END // CryptoPP |
|
|
|
#endif // CRYPTOPP_DONNA_H
|
|
|