1 // donna.h - written and placed in public domain by Jeffrey Walton 2 // Crypto++ specific implementation wrapped around Andrew 3 // Moon's public domain curve25519-donna and ed25519-donna, 4 // https://github.com/floodyberry/curve25519-donna and 5 // https://github.com/floodyberry/ed25519-donna. 6 7 // The curve25519 and ed25519 source files multiplex different repos and 8 // architectures using namespaces. The repos are Andrew Moon's 9 // curve25519-donna and ed25519-donna. The architectures are 32-bit, 64-bit 10 // and SSE. For example, 32-bit x25519 uses symbols from Donna::X25519 and 11 // Donna::Arch32. 12 13 // If needed, see Moon's commit "Go back to ignoring 256th bit [sic]", 14 // https://github.com/floodyberry/curve25519-donna/commit/57a683d18721a658 15 16 /// \file donna.h 17 /// \details Functions for curve25519 and ed25519 operations 18 /// \details This header provides the entry points into Andrew Moon's 19 /// curve25519 and ed25519 curve functions. The Crypto++ classes x25519 20 /// and ed25519 use the functions. The functions are in the <tt>Donna</tt> 21 /// namespace and are curve25519_mult(), ed25519_publickey(), 22 /// ed25519_sign() and ed25519_sign_open(). 23 /// \details At the moment the hash function for signing is fixed at 24 /// SHA512. 25 26 #ifndef CRYPTOPP_DONNA_H 27 #define CRYPTOPP_DONNA_H 28 29 #include "cryptlib.h" 30 #include "stdcpp.h" 31 32 NAMESPACE_BEGIN(CryptoPP) 33 NAMESPACE_BEGIN(Donna) 34 35 //***************************** curve25519 *****************************// 36 37 /// \brief Generate a public key 38 /// \param publicKey byte array for the public key 39 /// \param secretKey byte array with the private key 40 /// \return 0 on success, non-0 otherwise 41 /// \details curve25519_mult() generates a public key from an existing 42 /// secret key. Internally curve25519_mult() performs a scalar 43 /// multiplication using the base point and writes the result to 44 /// <tt>pubkey</tt>. 45 int curve25519_mult(byte publicKey[32], const byte secretKey[32]); 46 47 /// \brief Generate a shared key 48 /// \param sharedKey byte array for the shared secret 49 /// \param secretKey byte array with the private key 50 /// \param othersKey byte array with the peer's public key 51 /// \return 0 on success, non-0 otherwise 52 /// \details curve25519_mult() generates a shared key from an existing 53 /// secret key and the other party's public key. Internally 54 /// curve25519_mult() performs a scalar multiplication using the two keys 55 /// and writes the result to <tt>sharedKey</tt>. 56 int curve25519_mult(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]); 57 58 //******************************* ed25519 *******************************// 59 60 /// \brief Creates a public key from a secret key 61 /// \param publicKey byte array for the public key 62 /// \param secretKey byte array with the private key 63 /// \return 0 on success, non-0 otherwise 64 /// \details ed25519_publickey() generates a public key from a secret key. 65 /// Internally ed25519_publickey() performs a scalar multiplication 66 /// using the secret key and then writes the result to <tt>publicKey</tt>. 67 int ed25519_publickey(byte publicKey[32], const byte secretKey[32]); 68 69 /// \brief Creates a signature on a message 70 /// \param message byte array with the message 71 /// \param messageLength size of the message, in bytes 72 /// \param publicKey byte array with the public key 73 /// \param secretKey byte array with the private key 74 /// \param signature byte array for the signature 75 /// \return 0 on success, non-0 otherwise 76 /// \details ed25519_sign() generates a signature on a message using 77 /// the public and private keys. The various buffers can be exact 78 /// sizes, and do not require extra space like when using the 79 /// NaCl library functions. 80 /// \details At the moment the hash function for signing is fixed at 81 /// SHA512. 82 int ed25519_sign(const byte* message, size_t messageLength, const byte secretKey[32], const byte publicKey[32], byte signature[64]); 83 84 /// \brief Creates a signature on a message 85 /// \param stream std::istream derived class 86 /// \param publicKey byte array with the public key 87 /// \param secretKey byte array with the private key 88 /// \param signature byte array for the signature 89 /// \return 0 on success, non-0 otherwise 90 /// \details ed25519_sign() generates a signature on a message using 91 /// the public and private keys. The various buffers can be exact 92 /// sizes, and do not require extra space like when using the 93 /// NaCl library functions. 94 /// \details This ed25519_sign() overload handles large streams. It 95 /// was added for signing and verifying files that are too large 96 /// for a memory allocation. 97 /// \details At the moment the hash function for signing is fixed at 98 /// SHA512. 99 int ed25519_sign(std::istream& stream, const byte secretKey[32], const byte publicKey[32], byte signature[64]); 100 101 /// \brief Verifies a signature on a message 102 /// \param message byte array with the message 103 /// \param messageLength size of the message, in bytes 104 /// \param publicKey byte array with the public key 105 /// \param signature byte array with the signature 106 /// \return 0 on success, non-0 otherwise 107 /// \details ed25519_sign_open() verifies a signature on a message using 108 /// the public key. The various buffers can be exact sizes, and do not 109 /// require extra space like when using the NaCl library functions. 110 /// \details At the moment the hash function for signing is fixed at 111 /// SHA512. 112 int 113 ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64]); 114 115 /// \brief Verifies a signature on a message 116 /// \param stream std::istream derived class 117 /// \param publicKey byte array with the public key 118 /// \param signature byte array with the signature 119 /// \return 0 on success, non-0 otherwise 120 /// \details ed25519_sign_open() verifies a signature on a message using 121 /// the public key. The various buffers can be exact sizes, and do not 122 /// require extra space like when using the NaCl library functions. 123 /// \details This ed25519_sign_open() overload handles large streams. It 124 /// was added for signing and verifying files that are too large 125 /// for a memory allocation. 126 /// \details At the moment the hash function for signing is fixed at 127 /// SHA512. 128 int 129 ed25519_sign_open(std::istream& stream, const byte publicKey[32], const byte signature[64]); 130 131 //****************************** Internal ******************************// 132 133 #ifndef CRYPTOPP_DOXYGEN_PROCESSING 134 135 // CRYPTOPP_WORD128_AVAILABLE mostly depends upon GCC support for 136 // __SIZEOF_INT128__. If __SIZEOF_INT128__ is not available then Moon 137 // provides routines for MSC and GCC. It should cover most platforms, 138 // but there are gaps like MS ARM64 and XLC. We tried to enable the 139 // 64-bit path for SunCC from 12.5 but we got the dreaded compile 140 // error "The operand ___LCM cannot be assigned to". 141 142 #if defined(CRYPTOPP_WORD128_AVAILABLE) || \ 143 (defined(_MSC_VER) && defined(_M_X64)) 144 # define CRYPTOPP_CURVE25519_64BIT 1 145 #else 146 # define CRYPTOPP_CURVE25519_32BIT 1 147 #endif 148 149 // Benchmarking on a modern 64-bit Core i5-6400 @2.7 GHz shows SSE2 on Linux 150 // is not profitable. Here are the numbers in milliseconds/operation: 151 // 152 // * Langley, C++, 0.050 153 // * Moon, C++: 0.040 154 // * Moon, SSE2: 0.061 155 // * Moon, native: 0.045 156 // 157 // However, a modern 64-bit Core i5-3200 @2.5 GHz shows SSE2 is profitable 158 // for MS compilers. Here are the numbers in milliseconds/operation: 159 // 160 // * x86, no SSE2, 0.294 161 // * x86, SSE2, 0.097 162 // * x64, no SSE2, 0.081 163 // * x64, SSE2, 0.071 164 165 #if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) && defined(_MSC_VER) 166 # define CRYPTOPP_CURVE25519_SSE2 1 167 #endif 168 169 #if (CRYPTOPP_CURVE25519_SSE2) 170 extern int curve25519_mult_SSE2(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]); 171 #endif 172 173 #endif // CRYPTOPP_DOXYGEN_PROCESSING 174 175 NAMESPACE_END // Donna 176 NAMESPACE_END // CryptoPP 177 178 #endif // CRYPTOPP_DONNA_H 179