Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:56

0001 // donna.h - written and placed in public domain by Jeffrey Walton

0002 //           Crypto++ specific implementation wrapped around Andrew

0003 //           Moon's public domain curve25519-donna and ed25519-donna,

0004 //           https://github.com/floodyberry/curve25519-donna and

0005 //           https://github.com/floodyberry/ed25519-donna.

0006 
0007 // The curve25519 and ed25519 source files multiplex different repos and

0008 // architectures using namespaces. The repos are Andrew Moon's

0009 // curve25519-donna and ed25519-donna. The architectures are 32-bit, 64-bit

0010 // and SSE. For example, 32-bit x25519 uses symbols from Donna::X25519 and

0011 // Donna::Arch32.

0012 
0013 // If needed, see Moon's commit "Go back to ignoring 256th bit [sic]",

0014 // https://github.com/floodyberry/curve25519-donna/commit/57a683d18721a658

0015 
0016 /// \file donna.h

0017 /// \details Functions for curve25519 and ed25519 operations

0018 /// \details This header provides the entry points into Andrew Moon's

0019 ///   curve25519 and ed25519 curve functions. The Crypto++ classes x25519

0020 ///   and ed25519 use the functions. The functions are in the <tt>Donna</tt>

0021 ///   namespace and are curve25519_mult(), ed25519_publickey(),

0022 ///   ed25519_sign() and ed25519_sign_open().

0023 /// \details At the moment the hash function for signing is fixed at

0024 ///   SHA512.

0025 
0026 #ifndef CRYPTOPP_DONNA_H
0027 #define CRYPTOPP_DONNA_H
0028 
0029 #include "config.h"
0030 #include "cryptlib.h"
0031 #include "stdcpp.h"
0032 
0033 NAMESPACE_BEGIN(CryptoPP)
0034 NAMESPACE_BEGIN(Donna)
0035 
0036 //***************************** curve25519 *****************************//

0037 
0038 /// \brief Generate a public key

0039 /// \param publicKey byte array for the public key

0040 /// \param secretKey byte array with the private key

0041 /// \return 0 on success, non-0 otherwise

0042 /// \details curve25519_mult() generates a public key from an existing

0043 ///   secret key. Internally curve25519_mult() performs a scalar

0044 ///   multiplication using the base point and writes the result to

0045 ///   <tt>pubkey</tt>.

0046 int curve25519_mult(byte publicKey[32], const byte secretKey[32]);
0047 
0048 /// \brief Generate a shared key

0049 /// \param sharedKey byte array for the shared secret

0050 /// \param secretKey byte array with the private key

0051 /// \param othersKey byte array with the peer's public key

0052 /// \return 0 on success, non-0 otherwise

0053 /// \details curve25519_mult() generates a shared key from an existing

0054 ///   secret key and the other party's public key. Internally

0055 ///   curve25519_mult() performs a scalar multiplication using the two keys

0056 ///   and writes the result to <tt>sharedKey</tt>.

0057 int curve25519_mult(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]);
0058 
0059 //******************************* ed25519 *******************************//

0060 
0061 /// \brief Creates a public key from a secret key

0062 /// \param publicKey byte array for the public key

0063 /// \param secretKey byte array with the private key

0064 /// \return 0 on success, non-0 otherwise

0065 /// \details ed25519_publickey() generates a public key from a secret key.

0066 ///   Internally ed25519_publickey() performs a scalar multiplication

0067 ///   using the secret key and then writes the result to <tt>publicKey</tt>.

0068 int ed25519_publickey(byte publicKey[32], const byte secretKey[32]);
0069 
0070 /// \brief Creates a signature on a message

0071 /// \param message byte array with the message

0072 /// \param messageLength size of the message, in bytes

0073 /// \param publicKey byte array with the public key

0074 /// \param secretKey byte array with the private key

0075 /// \param signature byte array for the signature

0076 /// \return 0 on success, non-0 otherwise

0077 /// \details ed25519_sign() generates a signature on a message using

0078 ///   the public and private keys. The various buffers can be exact

0079 ///   sizes, and do not require extra space like when using the

0080 ///   NaCl library functions.

0081 /// \details At the moment the hash function for signing is fixed at

0082 ///   SHA512.

0083 int ed25519_sign(const byte* message, size_t messageLength, const byte secretKey[32], const byte publicKey[32], byte signature[64]);
0084 
0085 /// \brief Creates a signature on a message

0086 /// \param stream std::istream derived class

0087 /// \param publicKey byte array with the public key

0088 /// \param secretKey byte array with the private key

0089 /// \param signature byte array for the signature

0090 /// \return 0 on success, non-0 otherwise

0091 /// \details ed25519_sign() generates a signature on a message using

0092 ///   the public and private keys. The various buffers can be exact

0093 ///   sizes, and do not require extra space like when using the

0094 ///   NaCl library functions.

0095 /// \details This ed25519_sign() overload handles large streams. It

0096 ///   was added for signing and verifying files that are too large

0097 ///   for a memory allocation.

0098 /// \details At the moment the hash function for signing is fixed at

0099 ///   SHA512.

0100 int ed25519_sign(std::istream& stream, const byte secretKey[32], const byte publicKey[32], byte signature[64]);
0101 
0102 /// \brief Verifies a signature on a message

0103 /// \param message byte array with the message

0104 /// \param messageLength size of the message, in bytes

0105 /// \param publicKey byte array with the public key

0106 /// \param signature byte array with the signature

0107 /// \return 0 on success, non-0 otherwise

0108 /// \details ed25519_sign_open() verifies a signature on a message using

0109 ///   the public key. The various buffers can be exact sizes, and do not

0110 ///   require extra space like when using the NaCl library functions.

0111 /// \details At the moment the hash function for signing is fixed at

0112 ///   SHA512.

0113 int
0114 ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64]);
0115 
0116 /// \brief Verifies a signature on a message

0117 /// \param stream std::istream derived class

0118 /// \param publicKey byte array with the public key

0119 /// \param signature byte array with the signature

0120 /// \return 0 on success, non-0 otherwise

0121 /// \details ed25519_sign_open() verifies a signature on a message using

0122 ///   the public key. The various buffers can be exact sizes, and do not

0123 ///   require extra space like when using the NaCl library functions.

0124 /// \details This ed25519_sign_open() overload handles large streams. It

0125 ///   was added for signing and verifying files that are too large

0126 ///   for a memory allocation.

0127 /// \details At the moment the hash function for signing is fixed at

0128 ///   SHA512.

0129 int
0130 ed25519_sign_open(std::istream& stream, const byte publicKey[32], const byte signature[64]);
0131 
0132 //****************************** Internal ******************************//

0133 
0134 #ifndef CRYPTOPP_DOXYGEN_PROCESSING
0135 
0136 // CRYPTOPP_WORD128_AVAILABLE mostly depends upon GCC support for

0137 // __SIZEOF_INT128__. If __SIZEOF_INT128__ is not available then Moon

0138 // provides routines for MSC and GCC. It should cover most platforms,

0139 // but there are gaps like MS ARM64 and XLC. We tried to enable the

0140 // 64-bit path for SunCC from 12.5 but we got the dreaded compile

0141 // error "The operand ___LCM cannot be assigned to".

0142 
0143 #if defined(CRYPTOPP_WORD128_AVAILABLE) || \
0144    (defined(CRYPTOPP_MSC_VERSION) && defined(_M_X64))
0145 # define CRYPTOPP_CURVE25519_64BIT 1
0146 #else
0147 # define CRYPTOPP_CURVE25519_32BIT 1
0148 #endif
0149 
0150 // Benchmarking on a modern 64-bit Core i5-6400 @2.7 GHz shows SSE2 on Linux

0151 // is not profitable. Here are the numbers in milliseconds/operation:

0152 //

0153 //   * Langley, C++, 0.050

0154 //   * Moon, C++: 0.040

0155 //   * Moon, SSE2: 0.061

0156 //   * Moon, native: 0.045

0157 //

0158 // However, a modern 64-bit Core i5-3200 @2.5 GHz shows SSE2 is profitable

0159 // for MS compilers. Here are the numbers in milliseconds/operation:

0160 //

0161 //   * x86, no SSE2, 0.294

0162 //   * x86, SSE2, 0.097

0163 //   * x64, no SSE2, 0.081

0164 //   * x64, SSE2, 0.071

0165 
0166 #if defined(CRYPTOPP_MSC_VERSION) && (CRYPTOPP_SSE2_INTRIN_AVAILABLE)
0167 # define CRYPTOPP_CURVE25519_SSE2 1
0168 #endif
0169 
0170 #if (CRYPTOPP_CURVE25519_SSE2)
0171   extern int curve25519_mult_SSE2(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]);
0172 #endif
0173 
0174 #endif  // CRYPTOPP_DOXYGEN_PROCESSING

0175 
0176 NAMESPACE_END  // Donna

0177 NAMESPACE_END  // CryptoPP

0178 
0179 #endif  // CRYPTOPP_DONNA_H