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.
 
 
 
 
 

426 lines
13 KiB

  1. /**
  2. * @file decaf/ed255.hxx
  3. * @author Mike Hamburg
  4. *
  5. * @copyright
  6. * Copyright (c) 2015-2016 Cryptography Research, Inc. \n
  7. * Released under the MIT License. See LICENSE.txt for license information.
  8. *
  9. *
  10. *
  11. * @warning This file was automatically generated in Python.
  12. * Please do not edit it.
  13. */
  14. #ifndef __DECAF_ED255_HXX__
  15. #define __DECAF_ED255_HXX__ 1
  16. /*
  17. * Example Decaf cyrpto routines, C++ wrapper.
  18. * @warning These are merely examples, though they ought to be secure. But real
  19. * protocols will decide differently on magic numbers, formats, which items to
  20. * hash, etc.
  21. * @warning Experimental! The names, parameter orders etc are likely to change.
  22. */
  23. #include <decaf/eddsa.hxx>
  24. #include <decaf/point_255.hxx>
  25. #include <decaf/ed255.h>
  26. #include <decaf/shake.hxx>
  27. #include <decaf/sha512.hxx>
  28. /** @cond internal */
  29. #if __cplusplus >= 201103L
  30. #define DECAF_NOEXCEPT noexcept
  31. #else
  32. #define DECAF_NOEXCEPT throw()
  33. #endif
  34. /** @endcond */
  35. namespace decaf {
  36. /** A public key for crypto over some Group */
  37. template <typename Group> struct EdDSA;
  38. /** A public key for crypto over Iso-Ed25519 */
  39. template<> struct EdDSA<IsoEd25519> {
  40. /** @cond internal */
  41. template<class CRTP, Prehashed> class Signing;
  42. template<class CRTP, Prehashed> class Verification;
  43. class PublicKeyBase;
  44. class PrivateKeyBase;
  45. typedef class PrivateKeyBase PrivateKey, PrivateKeyPure, PrivateKeyPh;
  46. typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh;
  47. /** @endcond */
  48. #if DECAF_EDDSA_25519_SUPPORTS_CONTEXTLESS_SIGS
  49. static inline const Block NO_CONTEXT() { return Block(DECAF_ED25519_NO_CONTEXT,0); }
  50. #else
  51. static inline const Block NO_CONTEXT() { return Block(NULL,0); }
  52. #endif
  53. /** Prehash context for EdDSA. */
  54. class Prehash : public SHA512 {
  55. private:
  56. typedef SHA512 Super;
  57. SecureBuffer context_;
  58. template<class T, Prehashed Ph> friend class Signing;
  59. template<class T, Prehashed Ph> friend class Verification;
  60. void init() throw(LengthException) {
  61. Super::reset();
  62. if (context_.size() > 255) {
  63. throw LengthException();
  64. }
  65. decaf_ed25519_prehash_init((decaf_sha512_ctx_s *)wrapped);
  66. }
  67. public:
  68. /** Number of output bytes in prehash */
  69. static const size_t OUTPUT_BYTES = Super::DEFAULT_OUTPUT_BYTES;
  70. /** Create the prehash */
  71. Prehash(const Block &context = NO_CONTEXT()) throw(LengthException) {
  72. context_ = context;
  73. init();
  74. }
  75. /** Reset this hash */
  76. void reset() DECAF_NOEXCEPT { init(); }
  77. /** Output from this hash */
  78. SecureBuffer final() throw(std::bad_alloc) {
  79. SecureBuffer ret = Super::final(OUTPUT_BYTES);
  80. reset();
  81. return ret;
  82. }
  83. /** Output from this hash */
  84. void final(Buffer &b) throw(LengthException) {
  85. if (b.size() != OUTPUT_BYTES) throw LengthException();
  86. Super::final(b);
  87. reset();
  88. }
  89. };
  90. template<class CRTP, Prehashed ph> class Signing;
  91. template<class CRTP> class Signing<CRTP,PREHASHED> {
  92. public:
  93. /* Sign a prehash context, and reset the context */
  94. inline SecureBuffer sign_prehashed ( const Prehash &ph ) const /*throw(std::bad_alloc)*/ {
  95. SecureBuffer out(CRTP::SIG_BYTES);
  96. decaf_ed25519_sign_prehash (
  97. out.data(),
  98. ((const CRTP*)this)->priv_.data(),
  99. ((const CRTP*)this)->pub_.data(),
  100. (const decaf_ed25519_prehash_ctx_s*)ph.wrapped,
  101. ph.context_.data(),
  102. ph.context_.size()
  103. );
  104. return out;
  105. }
  106. /* Sign a message using the prehasher */
  107. inline SecureBuffer sign_with_prehash (
  108. const Block &message,
  109. const Block &context = NO_CONTEXT()
  110. ) const /*throw(LengthException,CryptoException)*/ {
  111. Prehash ph(context);
  112. ph += message;
  113. return sign_prehashed(ph);
  114. }
  115. };
  116. template<class CRTP> class Signing<CRTP,PURE> {
  117. public:
  118. /**
  119. * Sign a message.
  120. * @param [in] message The message to be signed.
  121. * @param [in] context A context for the signature; must be at most 255 bytes.
  122. *
  123. * @warning It is generally unsafe to use Ed25519 with both prehashed and non-prehashed messages.
  124. */
  125. inline SecureBuffer sign (
  126. const Block &message,
  127. const Block &context = NO_CONTEXT()
  128. ) const /* throw(LengthException, std::bad_alloc) */ {
  129. if (context.size() > 255) {
  130. throw LengthException();
  131. }
  132. SecureBuffer out(CRTP::SIG_BYTES);
  133. decaf_ed25519_sign (
  134. out.data(),
  135. ((const CRTP*)this)->priv_.data(),
  136. ((const CRTP*)this)->pub_.data(),
  137. message.data(),
  138. message.size(),
  139. 0,
  140. context.data(),
  141. context.size()
  142. );
  143. return out;
  144. }
  145. };
  146. class PrivateKeyBase
  147. : public Serializable<PrivateKeyBase>
  148. , public Signing<PrivateKeyBase,PURE>
  149. , public Signing<PrivateKeyBase,PREHASHED> {
  150. public:
  151. typedef class PublicKeyBase MyPublicKey;
  152. private:
  153. /** @cond internal */
  154. friend class PublicKeyBase;
  155. friend class Signing<PrivateKey,PURE>;
  156. friend class Signing<PrivateKey,PREHASHED>;
  157. /** @endcond */
  158. /** The pre-expansion form of the signing key. */
  159. FixedArrayBuffer<DECAF_EDDSA_25519_PRIVATE_BYTES> priv_;
  160. /** The post-expansion public key. */
  161. FixedArrayBuffer<DECAF_EDDSA_25519_PUBLIC_BYTES> pub_;
  162. public:
  163. /** Underlying group */
  164. typedef IsoEd25519 Group;
  165. /** Signature size. */
  166. static const size_t SIG_BYTES = DECAF_EDDSA_25519_SIGNATURE_BYTES;
  167. /** Serialization size. */
  168. static const size_t SER_BYTES = DECAF_EDDSA_25519_PRIVATE_BYTES;
  169. /** Create but don't initialize */
  170. inline explicit PrivateKeyBase(const NOINIT&) DECAF_NOEXCEPT : priv_((NOINIT())), pub_((NOINIT())) { }
  171. /** Read a private key from a string */
  172. inline explicit PrivateKeyBase(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT { *this = b; }
  173. /** Copy constructor */
  174. inline PrivateKeyBase(const PrivateKey &k) DECAF_NOEXCEPT { *this = k; }
  175. /** Create at random */
  176. inline explicit PrivateKeyBase(Rng &r) DECAF_NOEXCEPT : priv_(r) {
  177. decaf_ed25519_derive_public_key(pub_.data(), priv_.data());
  178. }
  179. /** Assignment from string */
  180. inline PrivateKeyBase &operator=(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT {
  181. memcpy(priv_.data(),b.data(),b.size());
  182. decaf_ed25519_derive_public_key(pub_.data(), priv_.data());
  183. return *this;
  184. }
  185. /** Copy assignment */
  186. inline PrivateKeyBase &operator=(const PrivateKey &k) DECAF_NOEXCEPT {
  187. memcpy(priv_.data(),k.priv_.data(), priv_.size());
  188. memcpy(pub_.data(),k.pub_.data(), pub_.size());
  189. return *this;
  190. }
  191. /** Serialization size. */
  192. inline size_t ser_size() const DECAF_NOEXCEPT { return SER_BYTES; }
  193. /** Serialize into a buffer. */
  194. inline void serialize_into(unsigned char *x) const DECAF_NOEXCEPT {
  195. memcpy(x,priv_.data(), priv_.size());
  196. }
  197. /** Convert to X format (to be used for key exchange) */
  198. inline SecureBuffer convert_to_x() const {
  199. SecureBuffer out(DECAF_X25519_PRIVATE_BYTES);
  200. decaf_ed25519_convert_private_key_to_x25519(out.data(), priv_.data());
  201. return out;
  202. }
  203. /** Return the corresponding public key */
  204. inline MyPublicKey pub() const DECAF_NOEXCEPT {
  205. MyPublicKey pub(*this);
  206. return pub;
  207. }
  208. }; /* class PrivateKey */
  209. template<class CRTP> class Verification<CRTP,PURE> {
  210. public:
  211. /** Verify a signature, returning DECAF_FAILURE if verification fails */
  212. inline decaf_error_t DECAF_WARN_UNUSED verify_noexcept (
  213. const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
  214. const Block &message,
  215. const Block &context = NO_CONTEXT()
  216. ) const /*DECAF_NOEXCEPT*/ {
  217. if (context.size() > 255) {
  218. return DECAF_FAILURE;
  219. }
  220. return decaf_ed25519_verify (
  221. sig.data(),
  222. ((const CRTP*)this)->pub_.data(),
  223. message.data(),
  224. message.size(),
  225. 0,
  226. context.data(),
  227. context.size()
  228. );
  229. }
  230. /** Verify a signature, throwing an exception if verification fails
  231. * @param [in] sig The signature.
  232. * @param [in] message The signed message.
  233. * @param [in] context A context for the signature; must be at most 255 bytes.
  234. *
  235. * @warning It is generally unsafe to use Ed25519 with both prehashed and non-prehashed messages.
  236. */
  237. inline void verify (
  238. const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
  239. const Block &message,
  240. const Block &context = NO_CONTEXT()
  241. ) const /*throw(LengthException,CryptoException)*/ {
  242. if (context.size() > 255) {
  243. throw LengthException();
  244. }
  245. if (DECAF_SUCCESS != verify_noexcept( sig, message, context )) {
  246. throw CryptoException();
  247. }
  248. }
  249. };
  250. template<class CRTP> class Verification<CRTP,PREHASHED> {
  251. public:
  252. /* Verify a prehash context. */
  253. inline decaf_error_t DECAF_WARN_UNUSED verify_prehashed_noexcept (
  254. const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
  255. const Prehash &ph
  256. ) const /*DECAF_NOEXCEPT*/ {
  257. return decaf_ed25519_verify_prehash (
  258. sig.data(),
  259. ((const CRTP*)this)->pub_.data(),
  260. (const decaf_ed25519_prehash_ctx_s*)ph.wrapped,
  261. ph.context_.data(),
  262. ph.context_.size()
  263. );
  264. }
  265. /* Verify a prehash context. */
  266. inline void verify_prehashed (
  267. const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
  268. const Prehash &ph
  269. ) const /*throw(CryptoException)*/ {
  270. if (DECAF_SUCCESS != decaf_ed25519_verify_prehash (
  271. sig.data(),
  272. ((const CRTP*)this)->pub_.data(),
  273. (const decaf_ed25519_prehash_ctx_s*)ph.wrapped,
  274. ph.context_.data(),
  275. ph.context_.size()
  276. )) {
  277. throw CryptoException();
  278. }
  279. }
  280. /* Verify a message using the prehasher */
  281. inline void verify_with_prehash (
  282. const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
  283. const Block &message,
  284. const Block &context = NO_CONTEXT()
  285. ) const /*throw(LengthException,CryptoException)*/ {
  286. Prehash ph(context);
  287. ph += message;
  288. verify_prehashed(sig,ph);
  289. }
  290. };
  291. class PublicKeyBase
  292. : public Serializable<PublicKeyBase>
  293. , public Verification<PublicKeyBase,PURE>
  294. , public Verification<PublicKeyBase,PREHASHED> {
  295. public:
  296. typedef class PrivateKeyBase MyPrivateKey;
  297. private:
  298. /** @cond internal */
  299. friend class PrivateKeyBase;
  300. friend class Verification<PublicKey,PURE>;
  301. friend class Verification<PublicKey,PREHASHED>;
  302. /** @endcond */
  303. private:
  304. /** The pre-expansion form of the signature */
  305. FixedArrayBuffer<DECAF_EDDSA_25519_PUBLIC_BYTES> pub_;
  306. public:
  307. /* PERF FUTURE: Pre-cached decoding? Precomputed table?? */
  308. /** Underlying group */
  309. typedef IsoEd25519 Group;
  310. /** Signature size. */
  311. static const size_t SIG_BYTES = DECAF_EDDSA_25519_SIGNATURE_BYTES;
  312. /** Serialization size. */
  313. static const size_t SER_BYTES = DECAF_EDDSA_25519_PRIVATE_BYTES;
  314. /** Create but don't initialize */
  315. inline explicit PublicKeyBase(const NOINIT&) DECAF_NOEXCEPT : pub_((NOINIT())) { }
  316. /** Read a private key from a string */
  317. inline explicit PublicKeyBase(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT { *this = b; }
  318. /** Copy constructor */
  319. inline PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT { *this = k; }
  320. /** Copy constructor */
  321. inline explicit PublicKeyBase(const MyPrivateKey &k) DECAF_NOEXCEPT { *this = k; }
  322. /** Assignment from string */
  323. inline PublicKey &operator=(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT {
  324. memcpy(pub_.data(),b.data(),b.size());
  325. return *this;
  326. }
  327. /** Assignment from private key */
  328. inline PublicKey &operator=(const PublicKey &p) DECAF_NOEXCEPT {
  329. return *this = p.pub_;
  330. }
  331. /** Assignment from private key */
  332. inline PublicKey &operator=(const MyPrivateKey &p) DECAF_NOEXCEPT {
  333. return *this = p.pub_;
  334. }
  335. /** Serialization size. */
  336. inline size_t ser_size() const DECAF_NOEXCEPT { return SER_BYTES; }
  337. /** Serialize into a buffer. */
  338. inline void serialize_into(unsigned char *x) const DECAF_NOEXCEPT {
  339. memcpy(x,pub_.data(), pub_.size());
  340. }
  341. /** Convert to X format (to be used for key exchange) */
  342. inline SecureBuffer convert_to_x() const {
  343. SecureBuffer out(DECAF_X25519_PRIVATE_BYTES);
  344. decaf_ed25519_convert_public_key_to_x25519(out.data(), pub_.data());
  345. return out;
  346. }
  347. }; /* class PublicKey */
  348. }; /* template<> struct EdDSA<IsoEd25519> */
  349. #undef DECAF_NOEXCEPT
  350. } /* namespace decaf */
  351. #endif /* __DECAF_ED255_HXX__ */