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.
 
 
 
 
 

199 lines
5.9 KiB

  1. /*
  2. * Example Decaf cyrpto routines, C++ wrapper.
  3. * @warning These are merely examples, though they ought to be secure. But real
  4. * protocols will decide differently on magic numbers, formats, which items to
  5. * hash, etc.
  6. * @warning Experimental! The names, parameter orders etc are likely to change.
  7. */
  8. #include <decaf/decaf_$(gf_bits).hxx>
  9. #include <decaf/shake.hxx>
  10. #include <decaf/strobe.hxx>
  11. /** @cond internal */
  12. #if __cplusplus >= 201103L
  13. #define NOEXCEPT noexcept
  14. #else
  15. #define NOEXCEPT throw()
  16. #endif
  17. /** @endcond */
  18. namespace decaf {
  19. /** A public key for crypto over some Group */
  20. template <typename Group> class PublicKey;
  21. /** A private key for crypto over some Group */
  22. template <typename Group> class PrivateKey;
  23. /** A public key for crypto over $(name) */
  24. template<> class PublicKey<$(cxx_ns)>
  25. : public Serializable< PublicKey<$(cxx_ns)> > {
  26. private:
  27. /** @cond internal */
  28. typedef $(c_ns)_public_key_t Wrapped;
  29. Wrapped wrapped;
  30. template<class Group> friend class PrivateKey;
  31. /** @endcond */
  32. public:
  33. /** Underlying group */
  34. typedef $(cxx_ns) Group;
  35. /** Signature size. */
  36. static const size_t SIG_BYTES = sizeof($(c_ns)_signature_t);
  37. /** Serialization size. */
  38. static const size_t SER_BYTES = sizeof(Wrapped);
  39. /** Read a private key from a string*/
  40. inline explicit PublicKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT {
  41. memcpy(wrapped,b.data(),sizeof(wrapped));
  42. }
  43. /** Read a private key from a string*/
  44. inline explicit PublicKey(const PrivateKey<$(cxx_ns)> &b) NOEXCEPT;
  45. /** Create but don't initialize */
  46. inline explicit PublicKey(const NOINIT&) NOEXCEPT { }
  47. /** Serialize into a buffer. */
  48. inline void serialize_into(unsigned char *x) const NOEXCEPT {
  49. memcpy(x,wrapped,sizeof(wrapped));
  50. }
  51. /** Serialization size. */
  52. inline size_t serSize() const NOEXCEPT { return SER_BYTES; }
  53. /** Verify a message */
  54. inline void verify(
  55. const Block &message,
  56. const FixedBlock<SIG_BYTES> &sig
  57. ) const throw(CryptoException) {
  58. if (DECAF_SUCCESS != $(c_ns)_verify(sig.data(),wrapped,message.data(),message.size())) {
  59. throw(CryptoException());
  60. }
  61. }
  62. /** Verify a message */
  63. inline void verify(
  64. Strobe &context,
  65. const FixedBlock<SIG_BYTES> &sig
  66. ) const throw(CryptoException) {
  67. if (DECAF_SUCCESS != $(c_ns)_verify_strobe(context.wrapped,sig.data(),wrapped)) {
  68. throw(CryptoException());
  69. }
  70. }
  71. };
  72. /** A private key for crypto over $(name) */
  73. template<> class PrivateKey<$(cxx_ns)>
  74. : public Serializable< PrivateKey<$(cxx_ns)> > {
  75. private:
  76. /** @cond internal */
  77. typedef $(c_ns)_private_key_t Wrapped;
  78. Wrapped wrapped;
  79. template<class Group> friend class PublicKey;
  80. /** @endcond */
  81. public:
  82. /** Underlying group */
  83. typedef $(cxx_ns) Group;
  84. /** Signature size. */
  85. static const size_t SIG_BYTES = sizeof($(c_ns)_signature_t);
  86. /** Serialization size. */
  87. static const size_t SER_BYTES = sizeof(Wrapped);
  88. /** Compressed size. */
  89. static const size_t SYM_BYTES = $(C_NS)_SYMMETRIC_KEY_BYTES;
  90. /** Create but don't initialize */
  91. inline explicit PrivateKey(const NOINIT&) NOEXCEPT { }
  92. /** Read a private key from a string*/
  93. inline explicit PrivateKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT {
  94. memcpy(wrapped,b.data(),sizeof(wrapped));
  95. }
  96. /** Read a private key from a string*/
  97. inline explicit PrivateKey(const FixedBlock<SYM_BYTES> &b) NOEXCEPT {
  98. $(c_ns)_derive_private_key(wrapped, b.data());
  99. }
  100. /** Create at random */
  101. inline explicit PrivateKey(Rng &r) NOEXCEPT {
  102. FixedArrayBuffer<SYM_BYTES> tmp(r);
  103. $(c_ns)_derive_private_key(wrapped, tmp.data());
  104. }
  105. /** Secure destructor */
  106. inline ~PrivateKey() NOEXCEPT {
  107. $(c_ns)_destroy_private_key(wrapped);
  108. }
  109. /** Serialization size. */
  110. inline size_t serSize() const NOEXCEPT { return SER_BYTES; }
  111. /** Serialize into a buffer. */
  112. inline void serialize_into(unsigned char *x) const NOEXCEPT {
  113. memcpy(x,wrapped,sizeof(wrapped));
  114. }
  115. /** Compressed serialize. */
  116. inline SecureBuffer compress() const throw(std::bad_alloc) {
  117. SecureBuffer ret(sizeof(wrapped->sym));
  118. memcpy(ret.data(),wrapped->sym,sizeof(wrapped->sym));
  119. return ret;
  120. }
  121. /** Get the public key */
  122. inline PublicKey<$(cxx_ns)> pub() const NOEXCEPT {
  123. PublicKey<$(cxx_ns)> ret(*this); return ret;
  124. }
  125. /** Derive a shared secret */
  126. inline SecureBuffer sharedSecret(
  127. const PublicKey<$(cxx_ns)> &pub,
  128. size_t bytes,
  129. bool me_first
  130. ) const throw(CryptoException,std::bad_alloc) {
  131. SecureBuffer ret(bytes);
  132. if (DECAF_SUCCESS != $(c_ns)_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) {
  133. throw(CryptoException());
  134. }
  135. return ret;
  136. }
  137. /** Derive a shared secret */
  138. inline decaf_error_t __attribute__((warn_unused_result))
  139. sharedSecretNoexcept(
  140. Buffer ret,
  141. const PublicKey<$(cxx_ns)> &pub,
  142. bool me_first
  143. ) const NOEXCEPT {
  144. return $(c_ns)_shared_secret(ret.data(),ret.size(),wrapped,pub.wrapped,me_first);
  145. }
  146. /** Sign a message. */
  147. inline SecureBuffer sign(const Block &message) const {
  148. SecureBuffer sig(SIG_BYTES);
  149. $(c_ns)_sign(sig.data(), wrapped, message.data(), message.size());
  150. return sig;
  151. }
  152. /** Sign a message. */
  153. inline SecureBuffer verify(Strobe &context) const {
  154. SecureBuffer sig(SIG_BYTES);
  155. $(c_ns)_sign_strobe(context.wrapped, sig.data(), wrapped);
  156. return sig;
  157. }
  158. };
  159. /** @cond internal */
  160. PublicKey<$(cxx_ns)>::PublicKey(const PrivateKey<$(cxx_ns)> &b) NOEXCEPT {
  161. $(c_ns)_private_to_public(wrapped,b.wrapped);
  162. }
  163. /** @endcond */
  164. #undef NOEXCEPT
  165. } /* namespace decaf */