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.
 
 
 
 
 

153 lines
4.6 KiB

  1. /**
  2. * @file shake.hxx
  3. * @copyright
  4. * Based on CC0 code by David Leon Gil, 2015 \n
  5. * Copyright (c) 2015 Cryptography Research, Inc. \n
  6. * Released under the MIT License. See LICENSE.txt for license information.
  7. * @author Mike Hamburg
  8. * @brief SHA-3-n and SHAKE-n instances, C++ wrapper.
  9. * @warning EXPERIMENTAL! The names, parameter orders etc are likely to change.
  10. */
  11. #ifndef __SHAKE_HXX__
  12. #define __SHAKE_HXX__
  13. #include "shake.h"
  14. #include <string>
  15. #include <sys/types.h>
  16. /** @cond internal */
  17. #if __cplusplus >= 201103L
  18. #define NOEXCEPT noexcept
  19. #define EXPLICIT_CON explicit
  20. #define GET_DATA(str) ((const unsigned char *)&(str)[0])
  21. #else
  22. #define NOEXCEPT throw()
  23. #define EXPLICIT_CON
  24. #define GET_DATA(str) ((const unsigned char *)((str).data()))
  25. #endif
  26. /** @endcond */
  27. namespace decaf {
  28. /** A Keccak sponge internal class */
  29. class KeccakSponge {
  30. protected:
  31. /** The C-wrapper sponge state */
  32. keccak_sponge_t sp;
  33. /** Initialize from parameters */
  34. inline KeccakSponge(const struct kparams_s *params) NOEXCEPT { sponge_init(sp, params); }
  35. /** No initialization */
  36. inline KeccakSponge(const NOINIT &) NOEXCEPT { }
  37. public:
  38. /** Destructor zeroizes state */
  39. inline ~KeccakSponge() NOEXCEPT { sponge_destroy(sp); }
  40. };
  41. /**
  42. * Hash function derived from Keccak
  43. * @todo throw exceptions when hash is misused.
  44. */
  45. class KeccakHash : public KeccakSponge {
  46. protected:
  47. /** Initialize from parameters */
  48. inline KeccakHash(const kparams_s *params) NOEXCEPT : KeccakSponge(params) {}
  49. public:
  50. /** Add more data to running hash */
  51. inline void update(const uint8_t *__restrict__ in, size_t len) { sha3_update(sp,in,len); }
  52. /** Add more data to running hash, C++ version. */
  53. inline void update(const std::string &s) { sha3_update(sp,GET_DATA(s),s.size()); }
  54. /** Add more data, stream version. */
  55. inline KeccakHash &operator<<(const std::string &s) { update(s); return *this; }
  56. /** Same as <<. */
  57. inline KeccakHash &operator+=(const std::string &s) { return *this << s; }
  58. /**
  59. * @brief Output bytes from the sponge.
  60. * @todo make this throw exceptions.
  61. */
  62. inline void output(unsigned char *c, size_t len) {
  63. sha3_output(sp,c,len);
  64. }
  65. /** @brief Output bytes from the sponge. */
  66. inline std::string output(size_t len) {
  67. unsigned char *buffer = new unsigned char[len];
  68. sha3_output(sp,buffer,len);
  69. std::string out((char *)buffer, len);
  70. delete[] buffer;
  71. return out;
  72. }
  73. /** @brief Return the sponge's default output size. */
  74. inline size_t default_output_size() const NOEXCEPT {
  75. return sponge_default_output_bytes(sp);
  76. }
  77. /** Output the default number of bytes. */
  78. inline std::string output() {
  79. return output(default_output_size());
  80. }
  81. };
  82. /** Fixed-output-length SHA3 */
  83. template<int bits> class SHA3 : public KeccakSponge {
  84. private:
  85. /** Get the parameter template block for this hash */
  86. const struct kparams_s *get_params();
  87. public:
  88. /** Initializer */
  89. inline SHA3() NOEXCEPT : KeccakHash(get_params()) {}
  90. };
  91. /** Variable-output-length SHAKE */
  92. template<int bits>
  93. class SHAKE : public KeccakSponge {
  94. private:
  95. /** Get the parameter template block for this hash */
  96. const struct kparams_s *get_params();
  97. public:
  98. /** Initializer */
  99. inline SHAKE() NOEXCEPT : KeccakHash(get_params()) {}
  100. };
  101. /** @cond internal */
  102. template<> const struct kparams_s *SHAKE<128>::get_params() { return &SHAKE128_params_s; }
  103. template<> const struct kparams_s *SHAKE<256>::get_params() { return &SHAKE256_params_s; }
  104. template<> const struct kparams_s *SHA3<224>::get_params() { return &SHA3_224_params_s; }
  105. template<> const struct kparams_s *SHA3<256>::get_params() { return &SHA3_256_params_s; }
  106. template<> const struct kparams_s *SHA3<384>::get_params() { return &SHA3_384_params_s; }
  107. template<> const struct kparams_s *SHA3<512>::get_params() { return &SHA3_512_params_s; }
  108. /** @endcond */
  109. /** Sponge-based random-number generator */
  110. class SpongeRng : public KeccakSponge {
  111. public:
  112. /** Initialize, deterministically by default, from C buffer */
  113. inline SpongeRng( const uint8_t *in, size_t len, bool deterministic = true ) NOEXCEPT
  114. : KeccakSponge(NI) {
  115. spongerng_init_from_buffer(sp,in,len,deterministic);
  116. }
  117. /** Initialize, deterministically by default, from C++ string */
  118. inline SpongeRng( const std::string &in, bool deterministic = true ) NOEXCEPT
  119. : KeccakSponge(NI) {
  120. spongerng_init_from_buffer(sp,GET_DATA(in),in.size(),deterministic);
  121. }
  122. };
  123. } /* namespace decaf */
  124. #undef NOEXCEPT
  125. #undef EXPLICIT_CON
  126. #undef GET_DATA
  127. #endif /* __SHAKE_HXX__ */