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.
 
 
 
 
 

414 lines
12 KiB

  1. /**
  2. * @file decaf/ed448.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_ED448_HXX__
  15. #define __DECAF_ED448_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_448.hxx>
  25. #include <decaf/ed448.h>
  26. #include <decaf/shake.hxx>
  27. #include <decaf/sha512.hxx>
  28. /** @cond internal */
  29. #if __cplusplus >= 201103L
  30. #define NOEXCEPT noexcept
  31. #else
  32. #define 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 Ed448-Goldilocks */
  39. template<> struct EdDSA<Ed448Goldilocks> {
  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_448_NO_CONTEXT
  49. static inline const Block NO_CONTEXT() { return Block(ED448_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 SHAKE<256> {
  55. private:
  56. typedef SHAKE<256> 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_ed448_prehash_init((decaf_shake256_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() 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_ed448_sign_prehash (
  97. out.data(),
  98. ((const CRTP*)this)->priv_.data(),
  99. ((const CRTP*)this)->pub_.data(),
  100. (const decaf_ed448_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 /* TODO: this exn spec tickles a Clang bug?
  129. * throw(LengthException, std::bad_alloc)
  130. */ {
  131. if (context.size() > 255) {
  132. throw LengthException();
  133. }
  134. SecureBuffer out(CRTP::SIG_BYTES);
  135. decaf_ed448_sign (
  136. out.data(),
  137. ((const CRTP*)this)->priv_.data(),
  138. ((const CRTP*)this)->pub_.data(),
  139. message.data(),
  140. message.size(),
  141. 0,
  142. context.data(),
  143. context.size()
  144. );
  145. return out;
  146. }
  147. };
  148. class PrivateKeyBase
  149. : public Serializable<PrivateKeyBase>
  150. , public Signing<PrivateKeyBase,PURE>
  151. , public Signing<PrivateKeyBase,PREHASHED> {
  152. public:
  153. typedef class PublicKeyBase MyPublicKey;
  154. private:
  155. /** @cond internal */
  156. friend class PublicKeyBase;
  157. friend class Signing<PrivateKey,PURE>;
  158. friend class Signing<PrivateKey,PREHASHED>;
  159. /** @endcond */
  160. /** The pre-expansion form of the signing key. */
  161. FixedArrayBuffer<DECAF_EDDSA_448_PRIVATE_BYTES> priv_;
  162. /** The post-expansion public key. */
  163. FixedArrayBuffer<DECAF_EDDSA_448_PUBLIC_BYTES> pub_;
  164. public:
  165. /** Underlying group */
  166. typedef Ed448Goldilocks Group;
  167. /** Signature size. */
  168. static const size_t SIG_BYTES = DECAF_EDDSA_448_SIGNATURE_BYTES;
  169. /** Serialization size. */
  170. static const size_t SER_BYTES = DECAF_EDDSA_448_PRIVATE_BYTES;
  171. /** Create but don't initialize */
  172. inline explicit PrivateKeyBase(const NOINIT&) NOEXCEPT : priv_((NOINIT())), pub_((NOINIT())) { }
  173. /** Read a private key from a string */
  174. inline explicit PrivateKeyBase(const FixedBlock<SER_BYTES> &b) NOEXCEPT { *this = b; }
  175. /** Copy constructor */
  176. inline PrivateKeyBase(const PrivateKey &k) NOEXCEPT { *this = k; }
  177. /** Create at random */
  178. inline explicit PrivateKeyBase(Rng &r) NOEXCEPT : priv_(r) {
  179. decaf_ed448_derive_public_key(pub_.data(), priv_.data());
  180. }
  181. /** Assignment from string */
  182. inline PrivateKeyBase &operator=(const FixedBlock<SER_BYTES> &b) NOEXCEPT {
  183. memcpy(priv_.data(),b.data(),b.size());
  184. decaf_ed448_derive_public_key(pub_.data(), priv_.data());
  185. return *this;
  186. }
  187. /** Copy assignment */
  188. inline PrivateKeyBase &operator=(const PrivateKey &k) NOEXCEPT {
  189. memcpy(priv_.data(),k.priv_.data(), priv_.size());
  190. memcpy(pub_.data(),k.pub_.data(), pub_.size());
  191. return *this;
  192. }
  193. /** Serialization size. */
  194. inline size_t ser_size() const NOEXCEPT { return SER_BYTES; }
  195. /** Serialize into a buffer. */
  196. inline void serialize_into(unsigned char *x) const NOEXCEPT {
  197. memcpy(x,priv_.data(), priv_.size());
  198. }
  199. /** Return the corresponding public key */
  200. inline MyPublicKey pub() const NOEXCEPT {
  201. MyPublicKey pub(*this);
  202. return pub;
  203. }
  204. }; /* class PrivateKey */
  205. template<class CRTP> class Verification<CRTP,PURE> {
  206. public:
  207. /** Verify a signature, returning DECAF_FAILURE if verification fails */
  208. inline decaf_error_t WARN_UNUSED verify_noexcept (
  209. const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig,
  210. const Block &message,
  211. const Block &context = NO_CONTEXT()
  212. ) const /*NOEXCEPT*/ {
  213. if (context.size() > 255) {
  214. return DECAF_FAILURE;
  215. }
  216. return decaf_ed448_verify (
  217. sig.data(),
  218. ((const CRTP*)this)->pub_.data(),
  219. message.data(),
  220. message.size(),
  221. 0,
  222. context.data(),
  223. context.size()
  224. );
  225. }
  226. /** Verify a signature, throwing an exception if verification fails
  227. * @param [in] sig The signature.
  228. * @param [in] message The signed message.
  229. * @param [in] context A context for the signature; must be at most 255 bytes.
  230. *
  231. * @warning It is generally unsafe to use Ed25519 with both prehashed and non-prehashed messages.
  232. */
  233. inline void verify (
  234. const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig,
  235. const Block &message,
  236. const Block &context = NO_CONTEXT()
  237. ) const /*throw(LengthException,CryptoException)*/ {
  238. if (context.size() > 255) {
  239. throw LengthException();
  240. }
  241. if (DECAF_SUCCESS != verify_noexcept( sig, message, context )) {
  242. throw CryptoException();
  243. }
  244. }
  245. };
  246. template<class CRTP> class Verification<CRTP,PREHASHED> {
  247. public:
  248. /* Verify a prehash context. */
  249. inline decaf_error_t WARN_UNUSED verify_prehashed_noexcept (
  250. const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig,
  251. const Prehash &ph
  252. ) const /*NOEXCEPT*/ {
  253. return decaf_ed448_verify_prehash (
  254. sig.data(),
  255. ((const CRTP*)this)->pub_.data(),
  256. (const decaf_ed448_prehash_ctx_s*)ph.wrapped,
  257. ph.context_.data(),
  258. ph.context_.size()
  259. );
  260. }
  261. /* Verify a prehash context. */
  262. inline void verify_prehashed (
  263. const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig,
  264. const Prehash &ph
  265. ) const /*throw(CryptoException)*/ {
  266. if (DECAF_SUCCESS != decaf_ed448_verify_prehash (
  267. sig.data(),
  268. ((const CRTP*)this)->pub_.data(),
  269. (const decaf_ed448_prehash_ctx_s*)ph.wrapped,
  270. ph.context_.data(),
  271. ph.context_.size()
  272. )) {
  273. throw CryptoException();
  274. }
  275. }
  276. /* Verify a message using the prehasher */
  277. inline void verify_with_prehash (
  278. const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig,
  279. const Block &message,
  280. const Block &context = NO_CONTEXT()
  281. ) const /*throw(LengthException,CryptoException)*/ {
  282. Prehash ph(context);
  283. ph += message;
  284. verify_prehashed(sig,ph);
  285. }
  286. };
  287. class PublicKeyBase
  288. : public Serializable<PublicKeyBase>
  289. , public Verification<PublicKeyBase,PURE>
  290. , public Verification<PublicKeyBase,PREHASHED> {
  291. public:
  292. typedef class PrivateKeyBase MyPrivateKey;
  293. private:
  294. /** @cond internal */
  295. friend class PrivateKeyBase;
  296. friend class Verification<PublicKey,PURE>;
  297. friend class Verification<PublicKey,PREHASHED>;
  298. /** @endcond */
  299. private:
  300. /** The pre-expansion form of the signature */
  301. FixedArrayBuffer<DECAF_EDDSA_448_PUBLIC_BYTES> pub_;
  302. public:
  303. /* PERF FUTURE: Pre-cached decoding? Precomputed table?? */
  304. /** Underlying group */
  305. typedef Ed448Goldilocks Group;
  306. /** Signature size. */
  307. static const size_t SIG_BYTES = DECAF_EDDSA_448_SIGNATURE_BYTES;
  308. /** Serialization size. */
  309. static const size_t SER_BYTES = DECAF_EDDSA_448_PRIVATE_BYTES;
  310. /** Create but don't initialize */
  311. inline explicit PublicKeyBase(const NOINIT&) NOEXCEPT : pub_((NOINIT())) { }
  312. /** Read a private key from a string */
  313. inline explicit PublicKeyBase(const FixedBlock<SER_BYTES> &b) NOEXCEPT { *this = b; }
  314. /** Copy constructor */
  315. inline PublicKeyBase(const PublicKeyBase &k) NOEXCEPT { *this = k; }
  316. /** Copy constructor */
  317. inline explicit PublicKeyBase(const MyPrivateKey &k) NOEXCEPT { *this = k; }
  318. /** Assignment from string */
  319. inline PublicKey &operator=(const FixedBlock<SER_BYTES> &b) NOEXCEPT {
  320. memcpy(pub_.data(),b.data(),b.size());
  321. return *this;
  322. }
  323. /** Assignment from private key */
  324. inline PublicKey &operator=(const PublicKey &p) NOEXCEPT {
  325. return *this = p.pub_;
  326. }
  327. /** Assignment from private key */
  328. inline PublicKey &operator=(const MyPrivateKey &p) NOEXCEPT {
  329. return *this = p.pub_;
  330. }
  331. /** Serialization size. */
  332. inline size_t ser_size() const NOEXCEPT { return SER_BYTES; }
  333. /** Serialize into a buffer. */
  334. inline void serialize_into(unsigned char *x) const NOEXCEPT {
  335. memcpy(x,pub_.data(), pub_.size());
  336. }
  337. }; /* class PublicKey */
  338. }; /* template<> struct EdDSA<Ed448Goldilocks> */
  339. #undef NOEXCEPT
  340. } /* namespace decaf */
  341. #endif /* __DECAF_ED448_HXX__ */