donna.h 7.9 KB

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