ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
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.
 
 
 
 
 
 

206 lines
4.8 KiB

  1. // boost/uuid/sha1.hpp header file ----------------------------------------------//
  2. // Copyright 2007 Andy Tompkins.
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // Revision History
  7. // 29 May 2007 - Initial Revision
  8. // 25 Feb 2008 - moved to namespace boost::uuids::detail
  9. // This is a byte oriented implementation
  10. // Note: this implementation does not handle message longer than
  11. // 2^32 bytes.
  12. // Adopted from Boost by Artyom Beilis, 2010
  13. #ifndef CPPCMS_PRIVATE_SHA1_H
  14. #define CPPCMS_PRIVATE_SHA1_H
  15. #include <cstddef>
  16. namespace cppcms {
  17. namespace impl {
  18. namespace {
  19. struct tester {
  20. typedef char test_correct_sizes_for_sha1_type[ sizeof(unsigned int) == 4 ? 1 : -1 ];
  21. };
  22. }
  23. inline unsigned int left_rotate(unsigned int x, std::size_t n)
  24. {
  25. return (x<<n) ^ (x>> (32-n));
  26. }
  27. class sha1
  28. {
  29. public:
  30. typedef unsigned int(&digest_type)[5];
  31. public:
  32. sha1();
  33. void reset();
  34. void process_byte(unsigned char byte);
  35. void process_block(void const* bytes_begin, void const* bytes_end);
  36. void process_bytes(void const* buffer, std::size_t byte_count);
  37. void get_digest(digest_type digest);
  38. private:
  39. void process_block();
  40. private:
  41. unsigned int h_[5];
  42. unsigned char block_[64];
  43. std::size_t block_byte_index_;
  44. std::size_t byte_count_;
  45. };
  46. inline sha1::sha1()
  47. {
  48. reset();
  49. }
  50. inline void sha1::reset()
  51. {
  52. h_[0] = 0x67452301;
  53. h_[1] = 0xEFCDAB89;
  54. h_[2] = 0x98BADCFE;
  55. h_[3] = 0x10325476;
  56. h_[4] = 0xC3D2E1F0;
  57. block_byte_index_ = 0;
  58. byte_count_ = 0;
  59. }
  60. inline void sha1::process_byte(unsigned char byte)
  61. {
  62. block_[block_byte_index_++] = byte;
  63. ++byte_count_;
  64. if (block_byte_index_ == 64) {
  65. block_byte_index_ = 0;
  66. process_block();
  67. }
  68. }
  69. inline void sha1::process_block(void const* bytes_begin, void const* bytes_end)
  70. {
  71. unsigned char const* begin = static_cast<unsigned char const*>(bytes_begin);
  72. unsigned char const* end = static_cast<unsigned char const*>(bytes_end);
  73. for(; begin != end; ++begin) {
  74. process_byte(*begin);
  75. }
  76. }
  77. inline void sha1::process_bytes(void const* buffer, std::size_t byte_count)
  78. {
  79. unsigned char const* b = static_cast<unsigned char const*>(buffer);
  80. process_block(b, b+byte_count);
  81. }
  82. inline void sha1::process_block()
  83. {
  84. unsigned int w[80];
  85. for (std::size_t i=0; i<16; ++i) {
  86. w[i] = (block_[i*4 + 0] << 24);
  87. w[i] |= (block_[i*4 + 1] << 16);
  88. w[i] |= (block_[i*4 + 2] << 8);
  89. w[i] |= (block_[i*4 + 3]);
  90. }
  91. for (std::size_t i=16; i<80; ++i) {
  92. w[i] = left_rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1);
  93. }
  94. unsigned int a = h_[0];
  95. unsigned int b = h_[1];
  96. unsigned int c = h_[2];
  97. unsigned int d = h_[3];
  98. unsigned int e = h_[4];
  99. for (std::size_t i=0; i<80; ++i) {
  100. unsigned int f;
  101. unsigned int k;
  102. if (i<20) {
  103. f = (b & c) | (~b & d);
  104. k = 0x5A827999;
  105. } else if (i<40) {
  106. f = b ^ c ^ d;
  107. k = 0x6ED9EBA1;
  108. } else if (i<60) {
  109. f = (b & c) | (b & d) | (c & d);
  110. k = 0x8F1BBCDC;
  111. } else {
  112. f = b ^ c ^ d;
  113. k = 0xCA62C1D6;
  114. }
  115. unsigned temp = left_rotate(a, 5) + f + e + k + w[i];
  116. e = d;
  117. d = c;
  118. c = left_rotate(b, 30);
  119. b = a;
  120. a = temp;
  121. }
  122. h_[0] += a;
  123. h_[1] += b;
  124. h_[2] += c;
  125. h_[3] += d;
  126. h_[4] += e;
  127. }
  128. inline void sha1::get_digest(digest_type digest)
  129. {
  130. std::size_t bit_count = byte_count_*8;
  131. // append the bit '1' to the message
  132. process_byte(0x80);
  133. // append k bits '0', where k is the minimum number >= 0
  134. // such that the resulting message length is congruent to 56 (mod 64)
  135. // check if there is enough space for padding and bit_count
  136. if (block_byte_index_ > 56) {
  137. // finish this block
  138. while (block_byte_index_ != 0) {
  139. process_byte(0);
  140. }
  141. // one more block
  142. while (block_byte_index_ < 56) {
  143. process_byte(0);
  144. }
  145. } else {
  146. while (block_byte_index_ < 56) {
  147. process_byte(0);
  148. }
  149. }
  150. // append length of message (before pre-processing)
  151. // as a 64-bit big-endian integer
  152. process_byte(0);
  153. process_byte(0);
  154. process_byte(0);
  155. process_byte(0);
  156. process_byte( static_cast<unsigned char>((bit_count>>24) & 0xFF));
  157. process_byte( static_cast<unsigned char>((bit_count>>16) & 0xFF));
  158. process_byte( static_cast<unsigned char>((bit_count>>8 ) & 0xFF));
  159. process_byte( static_cast<unsigned char>((bit_count) & 0xFF));
  160. // get final digest
  161. digest[0] = h_[0];
  162. digest[1] = h_[1];
  163. digest[2] = h_[2];
  164. digest[3] = h_[3];
  165. digest[4] = h_[4];
  166. }
  167. }} // namespace cppcms::impl
  168. #endif