crypto_hash.cc 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086
  1. /* Any copyright is dedicated to the Public Domain.
  2. * http://creativecommons.org/publicdomain/zero/1.0/ */
  3. // Written in 2014 by Nils Maier
  4. #include "crypto_hash.h"
  5. #include "crypto_endian.h"
  6. #include <cstring>
  7. #include <stdexcept>
  8. #include <unordered_map>
  9. // Compiler hints
  10. #if defined(__GNUG__)
  11. #define likely(x) __builtin_expect(!!(x), 1)
  12. #define unlikely(x) __builtin_expect(!!(x), 0)
  13. #else // ! __GNUG_
  14. #define likely(x) (x)
  15. #define unlikely(x) (x)
  16. #endif // ! __GNUG__
  17. // Basic operations
  18. static forceinline uint32_t rol(uint32_t x, uint32_t n)
  19. {
  20. return x << n | x >> (32 - n);
  21. }
  22. static forceinline uint32_t ror(uint32_t x, uint32_t n)
  23. {
  24. return x >> n | x << (32 - n);
  25. }
  26. static forceinline uint64_t ror(uint64_t x, uint64_t n)
  27. {
  28. return x >> n | x << (64 - n);
  29. }
  30. // SHA functions
  31. template <typename T> static forceinline T ch(T b, T c, T d)
  32. {
  33. return d ^ (b & (c ^ d));
  34. }
  35. template <typename T> static forceinline T maj(T b, T c, T d)
  36. {
  37. return (b & c) | (d & (b | c));
  38. }
  39. template <typename T> static forceinline T par(T b, T c, T d)
  40. {
  41. return b ^ c ^ d;
  42. }
  43. #ifdef __GNUG__
  44. #define __hash_maybe_memfence __asm__("" ::: "memory")
  45. #else // __GNUG__
  46. #define __hash_maybe_memfence
  47. #endif // __GNUG__
  48. // Template for the |::transform|s
  49. #define __hash_assign_words(endian) \
  50. word_t w00, w01, w02, w03, w04, w05, w06, w07, w08, w09, w10, w11, w12, w13, \
  51. w14, w15; \
  52. w15 = endian(buffer[15]), w14 = endian(buffer[14]); \
  53. w13 = endian(buffer[13]), w12 = endian(buffer[12]); \
  54. w11 = endian(buffer[11]), w10 = endian(buffer[10]); \
  55. w09 = endian(buffer[9]), w08 = endian(buffer[8]); \
  56. w07 = endian(buffer[7]), w06 = endian(buffer[6]); \
  57. w05 = endian(buffer[5]), w04 = endian(buffer[4]); \
  58. w03 = endian(buffer[3]), w02 = endian(buffer[2]); \
  59. w01 = endian(buffer[1]), w00 = endian(buffer[0])
  60. using namespace crypto;
  61. using namespace crypto::hash;
  62. // Our base implementation, doing most of the work, short of |transform|,
  63. // |digest| and initialization.
  64. template <typename word_, uint_fast8_t bsize, uint_fast8_t ssize>
  65. class AlgorithmImpl : public Algorithm {
  66. public:
  67. typedef word_ word_t;
  68. protected:
  69. template <uint_fast8_t size> union buffer_t {
  70. uint8_t bytes[size * sizeof(word_t)];
  71. word_t words[size];
  72. };
  73. uint_fast64_t count_;
  74. buffer_t<bsize> buffer_;
  75. buffer_t<ssize> state_;
  76. uint_fast8_t offset_;
  77. virtual void transform(const word_t* buffer) = 0;
  78. virtual std::string digest()
  79. {
  80. return std::string((const char*)state_.bytes, sizeof(state_.bytes));
  81. }
  82. public:
  83. AlgorithmImpl() {}
  84. virtual void update(const void* data, uint64_t len)
  85. {
  86. if (unlikely(!len)) {
  87. return;
  88. }
  89. auto bytes = reinterpret_cast<const uint8_t*>(data);
  90. count_ += len;
  91. // We have data buffered...
  92. if (unlikely(offset_)) {
  93. const uint32_t rem = sizeof(buffer_) - offset_;
  94. const uint32_t turn = (uint32_t)(len + ((rem - len) & (rem - len) >> 31));
  95. memcpy(buffer_.bytes + offset_, bytes, turn);
  96. len -= turn;
  97. bytes += turn;
  98. offset_ += turn;
  99. if (likely(offset_ == sizeof(buffer_))) {
  100. transform(buffer_.words);
  101. offset_ = 0;
  102. }
  103. }
  104. // |transform| as many blocks as possible.
  105. while (len >= sizeof(buffer_)) {
  106. // |offset_| has to be 0 at this point!
  107. // Which is guaranteed by the block above.
  108. transform(reinterpret_cast<const word_t*>(bytes));
  109. bytes += sizeof(buffer_);
  110. len -= sizeof(buffer_);
  111. }
  112. // Buffer remaining bytes, if any.
  113. if (unlikely(len)) {
  114. const uint32_t rem = sizeof(buffer_) - offset_;
  115. const uint32_t turn = (uint32_t)(len + ((rem - len) & (rem - len) >> 31));
  116. memcpy(buffer_.bytes + offset_, bytes, turn);
  117. offset_ += turn;
  118. }
  119. }
  120. virtual std::string finalize()
  121. {
  122. // Pad the message according to spec.
  123. const uint_fast16_t cutoff = sizeof(buffer_) - sizeof(word_t) * 2;
  124. buffer_.bytes[offset_] = 0x80;
  125. if (unlikely(++offset_ == sizeof(buffer_))) {
  126. transform(buffer_.words);
  127. memset(buffer_.bytes, 0x00, cutoff);
  128. }
  129. else if (offset_ > cutoff) {
  130. memset(buffer_.bytes + offset_, 0x00, sizeof(buffer_) - offset_);
  131. transform(buffer_.words);
  132. memset(buffer_.bytes, 0x00, cutoff);
  133. }
  134. else if (likely(offset_ != cutoff)) {
  135. memset(buffer_.bytes + offset_, 0x00, cutoff - offset_);
  136. }
  137. // Append length, multiplied by 8 (because bits!)
  138. const uint_fast64_t bits = __crypto_be(count_ << 3);
  139. if (sizeof(word_t) == 4) {
  140. #if LITTLE_ENDIAN == BYTE_ORDER
  141. buffer_.words[bsize - 2] = bits;
  142. buffer_.words[bsize - 1] = bits >> 32;
  143. #else // LITTLE_ENDIAN != BYTE_ORDER
  144. buffer_.words[bsize - 2] = bits >> 32;
  145. buffer_.words[bsize - 1] = bits;
  146. #endif // LITTLE_ENDIAN != BYTE_ORDER
  147. }
  148. else {
  149. buffer_.words[bsize - 2] = 0;
  150. buffer_.words[bsize - 1] = bits;
  151. }
  152. // Last transform:
  153. transform(buffer_.words);
  154. #if LITTLE_ENDIAN == BYTE_ORDER
  155. // On little endian, we still need to swap the bytes.
  156. for (auto i = 0; i < ssize; ++i) {
  157. state_.words[i] = __crypto_bswap(state_.words[i]);
  158. }
  159. #endif // LITTLE_ENDIAN == BYTE_ORDER
  160. auto rv = digest();
  161. reset();
  162. return rv;
  163. }
  164. virtual uint_fast16_t blocksize() const { return sizeof(buffer_); }
  165. };
  166. // Important! Other than the SHA family, MD5 is actually LE.
  167. class MD5 : public AlgorithmImpl<uint32_t, 16, 4> {
  168. private:
  169. static const word_t initvec[];
  170. protected:
  171. virtual void transform(const word_t* buffer)
  172. {
  173. __hash_assign_words(__crypto_le);
  174. __hash_maybe_memfence;
  175. word_t a, b, c, d;
  176. a = state_.words[0];
  177. b = state_.words[1];
  178. c = state_.words[2];
  179. d = state_.words[3];
  180. __hash_maybe_memfence;
  181. #define f1(x, y, z) (z ^ (x & (y ^ z)))
  182. #define f2(x, y, z) (y ^ (z & (x ^ y)))
  183. #define f3(x, y, z) (x ^ y ^ z)
  184. #define f4(x, y, z) (y ^ (x | ~z))
  185. #define r(f, a1, a2, a3, a4, w, k, n) \
  186. a1 += f(a2, a3, a4) + w + k; \
  187. a1 = rol(a1, n); \
  188. a1 += a2;
  189. // Yeah, unrolled loops.
  190. // This stuff is generated, but accidentally deleted the generator script.
  191. r(f1, a, b, c, d, w00, 0xd76aa478, 7);
  192. r(f1, d, a, b, c, w01, 0xe8c7b756, 12);
  193. r(f1, c, d, a, b, w02, 0x242070db, 17);
  194. r(f1, b, c, d, a, w03, 0xc1bdceee, 22);
  195. r(f1, a, b, c, d, w04, 0xf57c0faf, 7);
  196. r(f1, d, a, b, c, w05, 0x4787c62a, 12);
  197. r(f1, c, d, a, b, w06, 0xa8304613, 17);
  198. r(f1, b, c, d, a, w07, 0xfd469501, 22);
  199. r(f1, a, b, c, d, w08, 0x698098d8, 7);
  200. r(f1, d, a, b, c, w09, 0x8b44f7af, 12);
  201. r(f1, c, d, a, b, w10, 0xffff5bb1, 17);
  202. r(f1, b, c, d, a, w11, 0x895cd7be, 22);
  203. r(f1, a, b, c, d, w12, 0x6b901122, 7);
  204. r(f1, d, a, b, c, w13, 0xfd987193, 12);
  205. r(f1, c, d, a, b, w14, 0xa679438e, 17);
  206. r(f1, b, c, d, a, w15, 0x49b40821, 22);
  207. r(f2, a, b, c, d, w01, 0xf61e2562, 5);
  208. r(f2, d, a, b, c, w06, 0xc040b340, 9);
  209. r(f2, c, d, a, b, w11, 0x265e5a51, 14);
  210. r(f2, b, c, d, a, w00, 0xe9b6c7aa, 20);
  211. r(f2, a, b, c, d, w05, 0xd62f105d, 5);
  212. r(f2, d, a, b, c, w10, 0x02441453, 9);
  213. r(f2, c, d, a, b, w15, 0xd8a1e681, 14);
  214. r(f2, b, c, d, a, w04, 0xe7d3fbc8, 20);
  215. r(f2, a, b, c, d, w09, 0x21e1cde6, 5);
  216. r(f2, d, a, b, c, w14, 0xc33707d6, 9);
  217. r(f2, c, d, a, b, w03, 0xf4d50d87, 14);
  218. r(f2, b, c, d, a, w08, 0x455a14ed, 20);
  219. r(f2, a, b, c, d, w13, 0xa9e3e905, 5);
  220. r(f2, d, a, b, c, w02, 0xfcefa3f8, 9);
  221. r(f2, c, d, a, b, w07, 0x676f02d9, 14);
  222. r(f2, b, c, d, a, w12, 0x8d2a4c8a, 20);
  223. r(f3, a, b, c, d, w05, 0xfffa3942, 4);
  224. r(f3, d, a, b, c, w08, 0x8771f681, 11);
  225. r(f3, c, d, a, b, w11, 0x6d9d6122, 16);
  226. r(f3, b, c, d, a, w14, 0xfde5380c, 23);
  227. r(f3, a, b, c, d, w01, 0xa4beea44, 4);
  228. r(f3, d, a, b, c, w04, 0x4bdecfa9, 11);
  229. r(f3, c, d, a, b, w07, 0xf6bb4b60, 16);
  230. r(f3, b, c, d, a, w10, 0xbebfbc70, 23);
  231. r(f3, a, b, c, d, w13, 0x289b7ec6, 4);
  232. r(f3, d, a, b, c, w00, 0xeaa127fa, 11);
  233. r(f3, c, d, a, b, w03, 0xd4ef3085, 16);
  234. r(f3, b, c, d, a, w06, 0x04881d05, 23);
  235. r(f3, a, b, c, d, w09, 0xd9d4d039, 4);
  236. r(f3, d, a, b, c, w12, 0xe6db99e5, 11);
  237. r(f3, c, d, a, b, w15, 0x1fa27cf8, 16);
  238. r(f3, b, c, d, a, w02, 0xc4ac5665, 23);
  239. r(f4, a, b, c, d, w00, 0xf4292244, 6);
  240. r(f4, d, a, b, c, w07, 0x432aff97, 10);
  241. r(f4, c, d, a, b, w14, 0xab9423a7, 15);
  242. r(f4, b, c, d, a, w05, 0xfc93a039, 21);
  243. r(f4, a, b, c, d, w12, 0x655b59c3, 6);
  244. r(f4, d, a, b, c, w03, 0x8f0ccc92, 10);
  245. r(f4, c, d, a, b, w10, 0xffeff47d, 15);
  246. r(f4, b, c, d, a, w01, 0x85845dd1, 21);
  247. r(f4, a, b, c, d, w08, 0x6fa87e4f, 6);
  248. r(f4, d, a, b, c, w15, 0xfe2ce6e0, 10);
  249. r(f4, c, d, a, b, w06, 0xa3014314, 15);
  250. r(f4, b, c, d, a, w13, 0x4e0811a1, 21);
  251. r(f4, a, b, c, d, w04, 0xf7537e82, 6);
  252. r(f4, d, a, b, c, w11, 0xbd3af235, 10);
  253. r(f4, c, d, a, b, w02, 0x2ad7d2bb, 15);
  254. r(f4, b, c, d, a, w09, 0xeb86d391, 21);
  255. #undef r
  256. #undef f4
  257. #undef f3
  258. #undef f2
  259. #undef f1
  260. __hash_maybe_memfence;
  261. state_.words[0] += a;
  262. state_.words[1] += b;
  263. state_.words[2] += c;
  264. state_.words[3] += d;
  265. }
  266. public:
  267. MD5() { reset(); }
  268. virtual ~MD5() { reset(); }
  269. // Since this is LE, and I am lazy, copy-paste overwriting with BE -> LE.
  270. virtual std::string finalize()
  271. {
  272. // Pad
  273. buffer_.bytes[offset_] = 0x80;
  274. if (unlikely(++offset_ == 64)) {
  275. transform(buffer_.words);
  276. memset(buffer_.bytes, 0x00, 56);
  277. }
  278. else if (offset_ > 56) {
  279. memset(buffer_.bytes + offset_, 0x00, 64 - offset_);
  280. transform(buffer_.words);
  281. memset(buffer_.bytes, 0x00, 56);
  282. }
  283. else if (likely(offset_ != 56)) {
  284. memset(buffer_.bytes + offset_, 0x00, 56 - offset_);
  285. }
  286. // Append length, multiplied by 8 (because bits!)
  287. const uint_fast64_t bits = __crypto_le(count_ << 3);
  288. #if LITTLE_ENDIAN == BYTE_ORDER
  289. buffer_.words[14] = bits;
  290. buffer_.words[15] = bits >> 32;
  291. #else // LITTLE_ENDIAN != BYTE_ORDER
  292. buffer_.words[14] = bits >> 32;
  293. buffer_.words[15] = bits;
  294. #endif // LITTLE_ENDIAN != BYTE_ORDER
  295. transform(buffer_.words);
  296. #if BIG_ENDIAN == BYTE_ORDER
  297. state_.words[0] = __crypto_bswap(state_.words[0]);
  298. state_.words[1] = __crypto_bswap(state_.words[1]);
  299. state_.words[2] = __crypto_bswap(state_.words[2]);
  300. state_.words[3] = __crypto_bswap(state_.words[3]);
  301. #endif // LITTLE_ENDIAN == BYTE_ORDER
  302. auto rv = std::string((const char*)state_.bytes, sizeof(state_.bytes));
  303. reset();
  304. return rv;
  305. }
  306. virtual void reset()
  307. {
  308. memset(buffer_.bytes, 0, sizeof(buffer_));
  309. memcpy(state_.bytes, initvec, sizeof(state_));
  310. count_ = offset_ = 0;
  311. }
  312. virtual inline uint_fast16_t length() const { return 16; }
  313. };
  314. const MD5::word_t MD5::initvec[] = {0x67452301, 0xefcdab89, 0x98badcfe,
  315. 0x10325476};
  316. class SHA1 : public AlgorithmImpl<uint32_t, 16, 5> {
  317. private:
  318. static const word_t initvec[];
  319. protected:
  320. virtual void transform(const word_t* buffer)
  321. {
  322. __hash_assign_words(__crypto_be);
  323. __hash_maybe_memfence;
  324. word_t a, b, c, d, e;
  325. a = state_.words[0];
  326. b = state_.words[1];
  327. c = state_.words[2];
  328. d = state_.words[3];
  329. e = state_.words[4];
  330. __hash_maybe_memfence;
  331. #define c1 0x5a827999UL
  332. #define c2 0x6ed9eba1UL
  333. #define c3 0x8f1bbcdcUL
  334. #define c4 0xca62c1d6UL
  335. #define r(f, k, a1, a2, a3, a4, a5, w) \
  336. a1 = rol(a2, 5) + f(a3, a4, a5) + a1 + w + k; \
  337. a3 = rol(a3, 30);
  338. #define r1(a1, a2, a3, a4, a5, w) r(ch, c1, a1, a2, a3, a4, a5, w)
  339. #define r2(a1, a2, a3, a4, a5, w) r(par, c2, a1, a2, a3, a4, a5, w)
  340. #define r3(a1, a2, a3, a4, a5, w) r(maj, c3, a1, a2, a3, a4, a5, w)
  341. #define r4(a1, a2, a3, a4, a5, w) r(par, c4, a1, a2, a3, a4, a5, w)
  342. // Generated code. See sha1-transgen.py
  343. // Round 0
  344. r1(e, a, b, c, d, w00);
  345. r1(d, e, a, b, c, w01);
  346. r1(c, d, e, a, b, w02);
  347. r1(b, c, d, e, a, w03);
  348. r1(a, b, c, d, e, w04);
  349. r1(e, a, b, c, d, w05);
  350. r1(d, e, a, b, c, w06);
  351. r1(c, d, e, a, b, w07);
  352. r1(b, c, d, e, a, w08);
  353. r1(a, b, c, d, e, w09);
  354. // Round 10
  355. r1(e, a, b, c, d, w10);
  356. r1(d, e, a, b, c, w11);
  357. r1(c, d, e, a, b, w12);
  358. r1(b, c, d, e, a, w13);
  359. r1(a, b, c, d, e, w14);
  360. r1(e, a, b, c, d, w15);
  361. w00 = rol((w13 ^ w08 ^ w02 ^ w00), 1), r1(d, e, a, b, c, w00);
  362. w01 = rol((w14 ^ w09 ^ w03 ^ w01), 1), r1(c, d, e, a, b, w01);
  363. w02 = rol((w15 ^ w10 ^ w04 ^ w02), 1), r1(b, c, d, e, a, w02);
  364. w03 = rol((w00 ^ w11 ^ w05 ^ w03), 1), r1(a, b, c, d, e, w03);
  365. // Round 20
  366. w04 = rol((w01 ^ w12 ^ w06 ^ w04), 1), r2(e, a, b, c, d, w04);
  367. w05 = rol((w02 ^ w13 ^ w07 ^ w05), 1), r2(d, e, a, b, c, w05);
  368. w06 = rol((w03 ^ w14 ^ w08 ^ w06), 1), r2(c, d, e, a, b, w06);
  369. w07 = rol((w04 ^ w15 ^ w09 ^ w07), 1), r2(b, c, d, e, a, w07);
  370. w08 = rol((w05 ^ w00 ^ w10 ^ w08), 1), r2(a, b, c, d, e, w08);
  371. w09 = rol((w06 ^ w01 ^ w11 ^ w09), 1), r2(e, a, b, c, d, w09);
  372. w10 = rol((w07 ^ w02 ^ w12 ^ w10), 1), r2(d, e, a, b, c, w10);
  373. w11 = rol((w08 ^ w03 ^ w13 ^ w11), 1), r2(c, d, e, a, b, w11);
  374. w12 = rol((w09 ^ w04 ^ w14 ^ w12), 1), r2(b, c, d, e, a, w12);
  375. w13 = rol((w10 ^ w05 ^ w15 ^ w13), 1), r2(a, b, c, d, e, w13);
  376. // Round 30
  377. w14 = rol((w11 ^ w06 ^ w00 ^ w14), 1), r2(e, a, b, c, d, w14);
  378. w15 = rol((w12 ^ w07 ^ w01 ^ w15), 1), r2(d, e, a, b, c, w15);
  379. w00 = rol((w13 ^ w08 ^ w02 ^ w00), 1), r2(c, d, e, a, b, w00);
  380. w01 = rol((w14 ^ w09 ^ w03 ^ w01), 1), r2(b, c, d, e, a, w01);
  381. w02 = rol((w15 ^ w10 ^ w04 ^ w02), 1), r2(a, b, c, d, e, w02);
  382. w03 = rol((w00 ^ w11 ^ w05 ^ w03), 1), r2(e, a, b, c, d, w03);
  383. w04 = rol((w01 ^ w12 ^ w06 ^ w04), 1), r2(d, e, a, b, c, w04);
  384. w05 = rol((w02 ^ w13 ^ w07 ^ w05), 1), r2(c, d, e, a, b, w05);
  385. w06 = rol((w03 ^ w14 ^ w08 ^ w06), 1), r2(b, c, d, e, a, w06);
  386. w07 = rol((w04 ^ w15 ^ w09 ^ w07), 1), r2(a, b, c, d, e, w07);
  387. // Round 40
  388. w08 = rol((w05 ^ w00 ^ w10 ^ w08), 1), r3(e, a, b, c, d, w08);
  389. w09 = rol((w06 ^ w01 ^ w11 ^ w09), 1), r3(d, e, a, b, c, w09);
  390. w10 = rol((w07 ^ w02 ^ w12 ^ w10), 1), r3(c, d, e, a, b, w10);
  391. w11 = rol((w08 ^ w03 ^ w13 ^ w11), 1), r3(b, c, d, e, a, w11);
  392. w12 = rol((w09 ^ w04 ^ w14 ^ w12), 1), r3(a, b, c, d, e, w12);
  393. w13 = rol((w10 ^ w05 ^ w15 ^ w13), 1), r3(e, a, b, c, d, w13);
  394. w14 = rol((w11 ^ w06 ^ w00 ^ w14), 1), r3(d, e, a, b, c, w14);
  395. w15 = rol((w12 ^ w07 ^ w01 ^ w15), 1), r3(c, d, e, a, b, w15);
  396. w00 = rol((w13 ^ w08 ^ w02 ^ w00), 1), r3(b, c, d, e, a, w00);
  397. w01 = rol((w14 ^ w09 ^ w03 ^ w01), 1), r3(a, b, c, d, e, w01);
  398. // Round 50
  399. w02 = rol((w15 ^ w10 ^ w04 ^ w02), 1), r3(e, a, b, c, d, w02);
  400. w03 = rol((w00 ^ w11 ^ w05 ^ w03), 1), r3(d, e, a, b, c, w03);
  401. w04 = rol((w01 ^ w12 ^ w06 ^ w04), 1), r3(c, d, e, a, b, w04);
  402. w05 = rol((w02 ^ w13 ^ w07 ^ w05), 1), r3(b, c, d, e, a, w05);
  403. w06 = rol((w03 ^ w14 ^ w08 ^ w06), 1), r3(a, b, c, d, e, w06);
  404. w07 = rol((w04 ^ w15 ^ w09 ^ w07), 1), r3(e, a, b, c, d, w07);
  405. w08 = rol((w05 ^ w00 ^ w10 ^ w08), 1), r3(d, e, a, b, c, w08);
  406. w09 = rol((w06 ^ w01 ^ w11 ^ w09), 1), r3(c, d, e, a, b, w09);
  407. w10 = rol((w07 ^ w02 ^ w12 ^ w10), 1), r3(b, c, d, e, a, w10);
  408. w11 = rol((w08 ^ w03 ^ w13 ^ w11), 1), r3(a, b, c, d, e, w11);
  409. // Round 60
  410. w12 = rol((w09 ^ w04 ^ w14 ^ w12), 1), r4(e, a, b, c, d, w12);
  411. w13 = rol((w10 ^ w05 ^ w15 ^ w13), 1), r4(d, e, a, b, c, w13);
  412. w14 = rol((w11 ^ w06 ^ w00 ^ w14), 1), r4(c, d, e, a, b, w14);
  413. w15 = rol((w12 ^ w07 ^ w01 ^ w15), 1), r4(b, c, d, e, a, w15);
  414. w00 = rol((w13 ^ w08 ^ w02 ^ w00), 1), r4(a, b, c, d, e, w00);
  415. w01 = rol((w14 ^ w09 ^ w03 ^ w01), 1), r4(e, a, b, c, d, w01);
  416. w02 = rol((w15 ^ w10 ^ w04 ^ w02), 1), r4(d, e, a, b, c, w02);
  417. w03 = rol((w00 ^ w11 ^ w05 ^ w03), 1), r4(c, d, e, a, b, w03);
  418. w04 = rol((w01 ^ w12 ^ w06 ^ w04), 1), r4(b, c, d, e, a, w04);
  419. w05 = rol((w02 ^ w13 ^ w07 ^ w05), 1), r4(a, b, c, d, e, w05);
  420. // Round 70
  421. w06 = rol((w03 ^ w14 ^ w08 ^ w06), 1), r4(e, a, b, c, d, w06);
  422. w07 = rol((w04 ^ w15 ^ w09 ^ w07), 1), r4(d, e, a, b, c, w07);
  423. w08 = rol((w05 ^ w00 ^ w10 ^ w08), 1), r4(c, d, e, a, b, w08);
  424. w09 = rol((w06 ^ w01 ^ w11 ^ w09), 1), r4(b, c, d, e, a, w09);
  425. w10 = rol((w07 ^ w02 ^ w12 ^ w10), 1), r4(a, b, c, d, e, w10);
  426. w11 = rol((w08 ^ w03 ^ w13 ^ w11), 1), r4(e, a, b, c, d, w11);
  427. w12 = rol((w09 ^ w04 ^ w14 ^ w12), 1), r4(d, e, a, b, c, w12);
  428. w13 = rol((w10 ^ w05 ^ w15 ^ w13), 1), r4(c, d, e, a, b, w13);
  429. w14 = rol((w11 ^ w06 ^ w00 ^ w14), 1), r4(b, c, d, e, a, w14);
  430. w15 = rol((w12 ^ w07 ^ w01 ^ w15), 1), r4(a, b, c, d, e, w15);
  431. #undef r4
  432. #undef r3
  433. #undef r2
  434. #undef r1
  435. #undef r
  436. #undef c4
  437. #undef c3
  438. #undef c2
  439. #undef c1
  440. __hash_maybe_memfence;
  441. state_.words[0] += a;
  442. state_.words[1] += b;
  443. state_.words[2] += c;
  444. state_.words[3] += d;
  445. state_.words[4] += e;
  446. }
  447. public:
  448. SHA1() { reset(); }
  449. virtual ~SHA1() { reset(); }
  450. virtual void reset()
  451. {
  452. memset(buffer_.bytes, 0, sizeof(buffer_));
  453. memcpy(state_.bytes, initvec, sizeof(state_));
  454. count_ = offset_ = 0;
  455. }
  456. virtual inline uint_fast16_t length() const { return 20; }
  457. };
  458. const SHA1::word_t SHA1::initvec[] = {0x67452301, 0xefcdab89, 0x98badcfe,
  459. 0x10325476, 0xc3d2e1f0};
  460. class SHA256 : public AlgorithmImpl<uint32_t, 16, 8> {
  461. private:
  462. static const word_t initvec[];
  463. protected:
  464. virtual void transform(const word_t* buffer)
  465. {
  466. __hash_assign_words(__crypto_be);
  467. __hash_maybe_memfence;
  468. word_t a, b, c, d, e, f, g, h;
  469. word_t t;
  470. a = state_.words[0];
  471. b = state_.words[1];
  472. c = state_.words[2];
  473. d = state_.words[3];
  474. e = state_.words[4];
  475. f = state_.words[5];
  476. g = state_.words[6];
  477. h = state_.words[7];
  478. __hash_maybe_memfence;
  479. #define b0(w) (ror(w, 2) ^ ror(w, 13) ^ ror(w, 22))
  480. #define b1(w) (ror(w, 6) ^ ror(w, 11) ^ ror(w, 25))
  481. #define s0(w) (ror(w, 7) ^ ror(w, 18) ^ (w >> 3))
  482. #define s1(w) (ror(w, 17) ^ ror(w, 19) ^ (w >> 10))
  483. #define r(a1, a2, a3, a4, a5, a6, a7, a8, k, w) \
  484. a4 += t = a8 + b1(a5) + ch(a5, a6, a7) + k + w; \
  485. a8 = t + b0(a1) + maj(a1, a2, a3);
  486. // Generated code. See sha256-transgen.py
  487. // Round 0
  488. r(a, b, c, d, e, f, g, h, 0x428a2f98, w00);
  489. r(h, a, b, c, d, e, f, g, 0x71374491, w01);
  490. r(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w02);
  491. r(f, g, h, a, b, c, d, e, 0xe9b5dba5, w03);
  492. r(e, f, g, h, a, b, c, d, 0x3956c25b, w04);
  493. r(d, e, f, g, h, a, b, c, 0x59f111f1, w05);
  494. r(c, d, e, f, g, h, a, b, 0x923f82a4, w06);
  495. r(b, c, d, e, f, g, h, a, 0xab1c5ed5, w07);
  496. // Round 8
  497. r(a, b, c, d, e, f, g, h, 0xd807aa98, w08);
  498. r(h, a, b, c, d, e, f, g, 0x12835b01, w09);
  499. r(g, h, a, b, c, d, e, f, 0x243185be, w10);
  500. r(f, g, h, a, b, c, d, e, 0x550c7dc3, w11);
  501. r(e, f, g, h, a, b, c, d, 0x72be5d74, w12);
  502. r(d, e, f, g, h, a, b, c, 0x80deb1fe, w13);
  503. r(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14);
  504. r(b, c, d, e, f, g, h, a, 0xc19bf174, w15);
  505. // Round 16
  506. w00 = s1(w14) + w09 + s0(w01) + w00,
  507. r(a, b, c, d, e, f, g, h, 0xe49b69c1, w00);
  508. w01 = s1(w15) + w10 + s0(w02) + w01,
  509. r(h, a, b, c, d, e, f, g, 0xefbe4786, w01);
  510. w02 = s1(w00) + w11 + s0(w03) + w02,
  511. r(g, h, a, b, c, d, e, f, 0x0fc19dc6, w02);
  512. w03 = s1(w01) + w12 + s0(w04) + w03,
  513. r(f, g, h, a, b, c, d, e, 0x240ca1cc, w03);
  514. w04 = s1(w02) + w13 + s0(w05) + w04,
  515. r(e, f, g, h, a, b, c, d, 0x2de92c6f, w04);
  516. w05 = s1(w03) + w14 + s0(w06) + w05,
  517. r(d, e, f, g, h, a, b, c, 0x4a7484aa, w05);
  518. w06 = s1(w04) + w15 + s0(w07) + w06,
  519. r(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w06);
  520. w07 = s1(w05) + w00 + s0(w08) + w07,
  521. r(b, c, d, e, f, g, h, a, 0x76f988da, w07);
  522. // Round 24
  523. w08 = s1(w06) + w01 + s0(w09) + w08,
  524. r(a, b, c, d, e, f, g, h, 0x983e5152, w08);
  525. w09 = s1(w07) + w02 + s0(w10) + w09,
  526. r(h, a, b, c, d, e, f, g, 0xa831c66d, w09);
  527. w10 = s1(w08) + w03 + s0(w11) + w10,
  528. r(g, h, a, b, c, d, e, f, 0xb00327c8, w10);
  529. w11 = s1(w09) + w04 + s0(w12) + w11,
  530. r(f, g, h, a, b, c, d, e, 0xbf597fc7, w11);
  531. w12 = s1(w10) + w05 + s0(w13) + w12,
  532. r(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12);
  533. w13 = s1(w11) + w06 + s0(w14) + w13,
  534. r(d, e, f, g, h, a, b, c, 0xd5a79147, w13);
  535. w14 = s1(w12) + w07 + s0(w15) + w14,
  536. r(c, d, e, f, g, h, a, b, 0x06ca6351, w14);
  537. w15 = s1(w13) + w08 + s0(w00) + w15,
  538. r(b, c, d, e, f, g, h, a, 0x14292967, w15);
  539. // Round 32
  540. w00 = s1(w14) + w09 + s0(w01) + w00,
  541. r(a, b, c, d, e, f, g, h, 0x27b70a85, w00);
  542. w01 = s1(w15) + w10 + s0(w02) + w01,
  543. r(h, a, b, c, d, e, f, g, 0x2e1b2138, w01);
  544. w02 = s1(w00) + w11 + s0(w03) + w02,
  545. r(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w02);
  546. w03 = s1(w01) + w12 + s0(w04) + w03,
  547. r(f, g, h, a, b, c, d, e, 0x53380d13, w03);
  548. w04 = s1(w02) + w13 + s0(w05) + w04,
  549. r(e, f, g, h, a, b, c, d, 0x650a7354, w04);
  550. w05 = s1(w03) + w14 + s0(w06) + w05,
  551. r(d, e, f, g, h, a, b, c, 0x766a0abb, w05);
  552. w06 = s1(w04) + w15 + s0(w07) + w06,
  553. r(c, d, e, f, g, h, a, b, 0x81c2c92e, w06);
  554. w07 = s1(w05) + w00 + s0(w08) + w07,
  555. r(b, c, d, e, f, g, h, a, 0x92722c85, w07);
  556. // Round 40
  557. w08 = s1(w06) + w01 + s0(w09) + w08,
  558. r(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w08);
  559. w09 = s1(w07) + w02 + s0(w10) + w09,
  560. r(h, a, b, c, d, e, f, g, 0xa81a664b, w09);
  561. w10 = s1(w08) + w03 + s0(w11) + w10,
  562. r(g, h, a, b, c, d, e, f, 0xc24b8b70, w10);
  563. w11 = s1(w09) + w04 + s0(w12) + w11,
  564. r(f, g, h, a, b, c, d, e, 0xc76c51a3, w11);
  565. w12 = s1(w10) + w05 + s0(w13) + w12,
  566. r(e, f, g, h, a, b, c, d, 0xd192e819, w12);
  567. w13 = s1(w11) + w06 + s0(w14) + w13,
  568. r(d, e, f, g, h, a, b, c, 0xd6990624, w13);
  569. w14 = s1(w12) + w07 + s0(w15) + w14,
  570. r(c, d, e, f, g, h, a, b, 0xf40e3585, w14);
  571. w15 = s1(w13) + w08 + s0(w00) + w15,
  572. r(b, c, d, e, f, g, h, a, 0x106aa070, w15);
  573. // Round 48
  574. w00 = s1(w14) + w09 + s0(w01) + w00,
  575. r(a, b, c, d, e, f, g, h, 0x19a4c116, w00);
  576. w01 = s1(w15) + w10 + s0(w02) + w01,
  577. r(h, a, b, c, d, e, f, g, 0x1e376c08, w01);
  578. w02 = s1(w00) + w11 + s0(w03) + w02,
  579. r(g, h, a, b, c, d, e, f, 0x2748774c, w02);
  580. w03 = s1(w01) + w12 + s0(w04) + w03,
  581. r(f, g, h, a, b, c, d, e, 0x34b0bcb5, w03);
  582. w04 = s1(w02) + w13 + s0(w05) + w04,
  583. r(e, f, g, h, a, b, c, d, 0x391c0cb3, w04);
  584. w05 = s1(w03) + w14 + s0(w06) + w05,
  585. r(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w05);
  586. w06 = s1(w04) + w15 + s0(w07) + w06,
  587. r(c, d, e, f, g, h, a, b, 0x5b9cca4f, w06);
  588. w07 = s1(w05) + w00 + s0(w08) + w07,
  589. r(b, c, d, e, f, g, h, a, 0x682e6ff3, w07);
  590. // Round 56
  591. w08 = s1(w06) + w01 + s0(w09) + w08,
  592. r(a, b, c, d, e, f, g, h, 0x748f82ee, w08);
  593. w09 = s1(w07) + w02 + s0(w10) + w09,
  594. r(h, a, b, c, d, e, f, g, 0x78a5636f, w09);
  595. w10 = s1(w08) + w03 + s0(w11) + w10,
  596. r(g, h, a, b, c, d, e, f, 0x84c87814, w10);
  597. w11 = s1(w09) + w04 + s0(w12) + w11,
  598. r(f, g, h, a, b, c, d, e, 0x8cc70208, w11);
  599. w12 = s1(w10) + w05 + s0(w13) + w12,
  600. r(e, f, g, h, a, b, c, d, 0x90befffa, w12);
  601. w13 = s1(w11) + w06 + s0(w14) + w13,
  602. r(d, e, f, g, h, a, b, c, 0xa4506ceb, w13);
  603. w14 = s1(w12) + w07 + s0(w15) + w14,
  604. r(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14);
  605. w15 = s1(w13) + w08 + s0(w00) + w15,
  606. r(b, c, d, e, f, g, h, a, 0xc67178f2, w15);
  607. #undef b0
  608. #undef b1
  609. #undef s0
  610. #undef s1
  611. #undef r
  612. __hash_maybe_memfence;
  613. state_.words[0] += a;
  614. state_.words[1] += b;
  615. state_.words[2] += c;
  616. state_.words[3] += d;
  617. state_.words[4] += e;
  618. state_.words[5] += f;
  619. state_.words[6] += g;
  620. state_.words[7] += h;
  621. }
  622. public:
  623. SHA256() { reset(); }
  624. virtual ~SHA256() { reset(); }
  625. virtual void reset()
  626. {
  627. memset(buffer_.bytes, 0, sizeof(buffer_));
  628. memcpy(state_.bytes, initvec, sizeof(state_));
  629. count_ = offset_ = 0;
  630. }
  631. virtual inline uint_fast16_t length() const { return 32; }
  632. };
  633. const SHA256::word_t SHA256::initvec[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372,
  634. 0xa54ff53a, 0x510e527f, 0x9b05688c,
  635. 0x1f83d9ab, 0x5be0cd19};
  636. class SHA224 : public SHA256 {
  637. private:
  638. static const word_t initvec[];
  639. protected:
  640. virtual std::string digest()
  641. {
  642. return std::string((const char*)state_.bytes,
  643. sizeof(state_.bytes) - sizeof(word_t));
  644. }
  645. public:
  646. SHA224() { reset(); }
  647. virtual ~SHA224() { reset(); }
  648. virtual void reset()
  649. {
  650. memset(buffer_.bytes, 0, sizeof(buffer_));
  651. memcpy(state_.bytes, initvec, sizeof(state_));
  652. count_ = offset_ = 0;
  653. }
  654. virtual inline uint_fast16_t length() const { return 28; }
  655. };
  656. const SHA224::word_t SHA224::initvec[] = {0xc1059ed8, 0x367cd507, 0x3070dd17,
  657. 0xf70e5939, 0xffc00b31, 0x68581511,
  658. 0x64f98fa7, 0xbefa4fa4};
  659. class SHA512 : public AlgorithmImpl<uint64_t, 16, 8> {
  660. private:
  661. static const word_t initvec[];
  662. protected:
  663. virtual void transform(const word_t* buffer)
  664. {
  665. __hash_assign_words(__crypto_be);
  666. __hash_maybe_memfence;
  667. word_t a, b, c, d, e, f, g, h;
  668. word_t t;
  669. a = state_.words[0];
  670. b = state_.words[1];
  671. c = state_.words[2];
  672. d = state_.words[3];
  673. e = state_.words[4];
  674. f = state_.words[5];
  675. g = state_.words[6];
  676. h = state_.words[7];
  677. __hash_maybe_memfence;
  678. #define b0(w) (ror(w, 28) ^ ror(w, 34) ^ ror(w, 39))
  679. #define b1(w) (ror(w, 14) ^ ror(w, 18) ^ ror(w, 41))
  680. #define s0(w) (ror(w, 1) ^ ror(w, 8) ^ (w >> 7))
  681. #define s1(w) (ror(w, 19) ^ ror(w, 61) ^ (w >> 6))
  682. #define r(a1, a2, a3, a4, a5, a6, a7, a8, k, w) \
  683. a4 += t = a8 + b1(a5) + ch(a5, a6, a7) + k + w; \
  684. a8 = t + b0(a1) + maj(a1, a2, a3);
  685. // Generated code. See sha512-transgen.py
  686. // Round 0
  687. r(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22, w00);
  688. r(h, a, b, c, d, e, f, g, 0x7137449123ef65cd, w01);
  689. r(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2f, w02);
  690. r(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbc, w03);
  691. r(e, f, g, h, a, b, c, d, 0x3956c25bf348b538, w04);
  692. r(d, e, f, g, h, a, b, c, 0x59f111f1b605d019, w05);
  693. r(c, d, e, f, g, h, a, b, 0x923f82a4af194f9b, w06);
  694. r(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118, w07);
  695. // Round 8
  696. r(a, b, c, d, e, f, g, h, 0xd807aa98a3030242, w08);
  697. r(h, a, b, c, d, e, f, g, 0x12835b0145706fbe, w09);
  698. r(g, h, a, b, c, d, e, f, 0x243185be4ee4b28c, w10);
  699. r(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2, w11);
  700. r(e, f, g, h, a, b, c, d, 0x72be5d74f27b896f, w12);
  701. r(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1, w13);
  702. r(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235, w14);
  703. r(b, c, d, e, f, g, h, a, 0xc19bf174cf692694, w15);
  704. // Round 16
  705. w00 = s1(w14) + w09 + s0(w01) + w00;
  706. r(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2, w00);
  707. w01 = s1(w15) + w10 + s0(w02) + w01;
  708. r(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3, w01);
  709. w02 = s1(w00) + w11 + s0(w03) + w02;
  710. r(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5, w02);
  711. w03 = s1(w01) + w12 + s0(w04) + w03;
  712. r(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65, w03);
  713. w04 = s1(w02) + w13 + s0(w05) + w04;
  714. r(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275, w04);
  715. w05 = s1(w03) + w14 + s0(w06) + w05;
  716. r(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483, w05);
  717. w06 = s1(w04) + w15 + s0(w07) + w06;
  718. r(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4, w06);
  719. w07 = s1(w05) + w00 + s0(w08) + w07;
  720. r(b, c, d, e, f, g, h, a, 0x76f988da831153b5, w07);
  721. // Round 24
  722. w08 = s1(w06) + w01 + s0(w09) + w08;
  723. r(a, b, c, d, e, f, g, h, 0x983e5152ee66dfab, w08);
  724. w09 = s1(w07) + w02 + s0(w10) + w09;
  725. r(h, a, b, c, d, e, f, g, 0xa831c66d2db43210, w09);
  726. w10 = s1(w08) + w03 + s0(w11) + w10;
  727. r(g, h, a, b, c, d, e, f, 0xb00327c898fb213f, w10);
  728. w11 = s1(w09) + w04 + s0(w12) + w11;
  729. r(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4, w11);
  730. w12 = s1(w10) + w05 + s0(w13) + w12;
  731. r(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2, w12);
  732. w13 = s1(w11) + w06 + s0(w14) + w13;
  733. r(d, e, f, g, h, a, b, c, 0xd5a79147930aa725, w13);
  734. w14 = s1(w12) + w07 + s0(w15) + w14;
  735. r(c, d, e, f, g, h, a, b, 0x06ca6351e003826f, w14);
  736. w15 = s1(w13) + w08 + s0(w00) + w15;
  737. r(b, c, d, e, f, g, h, a, 0x142929670a0e6e70, w15);
  738. // Round 32
  739. w00 = s1(w14) + w09 + s0(w01) + w00;
  740. r(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffc, w00);
  741. w01 = s1(w15) + w10 + s0(w02) + w01;
  742. r(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926, w01);
  743. w02 = s1(w00) + w11 + s0(w03) + w02;
  744. r(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aed, w02);
  745. w03 = s1(w01) + w12 + s0(w04) + w03;
  746. r(f, g, h, a, b, c, d, e, 0x53380d139d95b3df, w03);
  747. w04 = s1(w02) + w13 + s0(w05) + w04;
  748. r(e, f, g, h, a, b, c, d, 0x650a73548baf63de, w04);
  749. w05 = s1(w03) + w14 + s0(w06) + w05;
  750. r(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8, w05);
  751. w06 = s1(w04) + w15 + s0(w07) + w06;
  752. r(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6, w06);
  753. w07 = s1(w05) + w00 + s0(w08) + w07;
  754. r(b, c, d, e, f, g, h, a, 0x92722c851482353b, w07);
  755. // Round 40
  756. w08 = s1(w06) + w01 + s0(w09) + w08;
  757. r(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364, w08);
  758. w09 = s1(w07) + w02 + s0(w10) + w09;
  759. r(h, a, b, c, d, e, f, g, 0xa81a664bbc423001, w09);
  760. w10 = s1(w08) + w03 + s0(w11) + w10;
  761. r(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791, w10);
  762. w11 = s1(w09) + w04 + s0(w12) + w11;
  763. r(f, g, h, a, b, c, d, e, 0xc76c51a30654be30, w11);
  764. w12 = s1(w10) + w05 + s0(w13) + w12;
  765. r(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218, w12);
  766. w13 = s1(w11) + w06 + s0(w14) + w13;
  767. r(d, e, f, g, h, a, b, c, 0xd69906245565a910, w13);
  768. w14 = s1(w12) + w07 + s0(w15) + w14;
  769. r(c, d, e, f, g, h, a, b, 0xf40e35855771202a, w14);
  770. w15 = s1(w13) + w08 + s0(w00) + w15;
  771. r(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8, w15);
  772. // Round 48
  773. w00 = s1(w14) + w09 + s0(w01) + w00;
  774. r(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8, w00);
  775. w01 = s1(w15) + w10 + s0(w02) + w01;
  776. r(h, a, b, c, d, e, f, g, 0x1e376c085141ab53, w01);
  777. w02 = s1(w00) + w11 + s0(w03) + w02;
  778. r(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99, w02);
  779. w03 = s1(w01) + w12 + s0(w04) + w03;
  780. r(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8, w03);
  781. w04 = s1(w02) + w13 + s0(w05) + w04;
  782. r(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63, w04);
  783. w05 = s1(w03) + w14 + s0(w06) + w05;
  784. r(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acb, w05);
  785. w06 = s1(w04) + w15 + s0(w07) + w06;
  786. r(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373, w06);
  787. w07 = s1(w05) + w00 + s0(w08) + w07;
  788. r(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3, w07);
  789. // Round 56
  790. w08 = s1(w06) + w01 + s0(w09) + w08;
  791. r(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fc, w08);
  792. w09 = s1(w07) + w02 + s0(w10) + w09;
  793. r(h, a, b, c, d, e, f, g, 0x78a5636f43172f60, w09);
  794. w10 = s1(w08) + w03 + s0(w11) + w10;
  795. r(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72, w10);
  796. w11 = s1(w09) + w04 + s0(w12) + w11;
  797. r(f, g, h, a, b, c, d, e, 0x8cc702081a6439ec, w11);
  798. w12 = s1(w10) + w05 + s0(w13) + w12;
  799. r(e, f, g, h, a, b, c, d, 0x90befffa23631e28, w12);
  800. w13 = s1(w11) + w06 + s0(w14) + w13;
  801. r(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9, w13);
  802. w14 = s1(w12) + w07 + s0(w15) + w14;
  803. r(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915, w14);
  804. w15 = s1(w13) + w08 + s0(w00) + w15;
  805. r(b, c, d, e, f, g, h, a, 0xc67178f2e372532b, w15);
  806. // Round 64
  807. w00 = s1(w14) + w09 + s0(w01) + w00;
  808. r(a, b, c, d, e, f, g, h, 0xca273eceea26619c, w00);
  809. w01 = s1(w15) + w10 + s0(w02) + w01;
  810. r(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207, w01);
  811. w02 = s1(w00) + w11 + s0(w03) + w02;
  812. r(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1e, w02);
  813. w03 = s1(w01) + w12 + s0(w04) + w03;
  814. r(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178, w03);
  815. w04 = s1(w02) + w13 + s0(w05) + w04;
  816. r(e, f, g, h, a, b, c, d, 0x06f067aa72176fba, w04);
  817. w05 = s1(w03) + w14 + s0(w06) + w05;
  818. r(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6, w05);
  819. w06 = s1(w04) + w15 + s0(w07) + w06;
  820. r(c, d, e, f, g, h, a, b, 0x113f9804bef90dae, w06);
  821. w07 = s1(w05) + w00 + s0(w08) + w07;
  822. r(b, c, d, e, f, g, h, a, 0x1b710b35131c471b, w07);
  823. // Round 72
  824. w08 = s1(w06) + w01 + s0(w09) + w08;
  825. r(a, b, c, d, e, f, g, h, 0x28db77f523047d84, w08);
  826. w09 = s1(w07) + w02 + s0(w10) + w09;
  827. r(h, a, b, c, d, e, f, g, 0x32caab7b40c72493, w09);
  828. w10 = s1(w08) + w03 + s0(w11) + w10;
  829. r(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebc, w10);
  830. w11 = s1(w09) + w04 + s0(w12) + w11;
  831. r(f, g, h, a, b, c, d, e, 0x431d67c49c100d4c, w11);
  832. w12 = s1(w10) + w05 + s0(w13) + w12;
  833. r(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6, w12);
  834. w13 = s1(w11) + w06 + s0(w14) + w13;
  835. r(d, e, f, g, h, a, b, c, 0x597f299cfc657e2a, w13);
  836. w14 = s1(w12) + w07 + s0(w15) + w14;
  837. r(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faec, w14);
  838. w15 = s1(w13) + w08 + s0(w00) + w15;
  839. r(b, c, d, e, f, g, h, a, 0x6c44198c4a475817, w15);
  840. #undef b0
  841. #undef b1
  842. #undef s0
  843. #undef s1
  844. #undef r
  845. __hash_maybe_memfence;
  846. state_.words[0] += a;
  847. state_.words[1] += b;
  848. state_.words[2] += c;
  849. state_.words[3] += d;
  850. state_.words[4] += e;
  851. state_.words[5] += f;
  852. state_.words[6] += g;
  853. state_.words[7] += h;
  854. }
  855. public:
  856. SHA512() { reset(); }
  857. virtual ~SHA512() { reset(); }
  858. virtual void reset()
  859. {
  860. memset(buffer_.bytes, 0, sizeof(buffer_));
  861. memcpy(state_.bytes, initvec, sizeof(state_));
  862. count_ = offset_ = 0;
  863. }
  864. virtual inline uint_fast16_t length() const { return 64; }
  865. };
  866. const SHA512::word_t SHA512::initvec[] = {
  867. 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b,
  868. 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
  869. 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
  870. };
  871. class SHA384 : public SHA512 {
  872. private:
  873. static const word_t initvec[];
  874. protected:
  875. virtual std::string digest()
  876. {
  877. return std::string((const char*)state_.bytes,
  878. sizeof(state_.bytes) - sizeof(word_t) * 2);
  879. }
  880. public:
  881. SHA384() { reset(); }
  882. virtual ~SHA384() { reset(); }
  883. virtual void reset()
  884. {
  885. memset(buffer_.bytes, 0, sizeof(buffer_));
  886. memcpy(state_.bytes, initvec, sizeof(state_));
  887. count_ = offset_ = 0;
  888. }
  889. virtual inline uint_fast16_t length() const { return 48; }
  890. };
  891. const SHA384::word_t SHA384::initvec[] = {
  892. 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17,
  893. 0x152fecd8f70e5939, 0x67332667ffc00b31, 0x8eb44a8768581511,
  894. 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4};
  895. namespace {
  896. // For |all|
  897. static const std::set<std::string> names{
  898. "md5", "sha", "sha1", "sha-1", "sha224", "sha-224",
  899. "sha256", "sha-256", "sha384", "sha-384", "sha512", "sha-512",
  900. };
  901. // For fast name |lookup|
  902. static const std::unordered_map<std::string, Algorithms> mapped{
  903. {"md5", algoMD5},
  904. {"sha", algoSHA1},
  905. {"sha1", algoSHA1},
  906. {"sha-1", algoSHA1},
  907. {"sha224", algoSHA224},
  908. {"sha-224", algoSHA224},
  909. {"sha256", algoSHA256},
  910. {"sha-256", algoSHA256},
  911. {"sha384", algoSHA384},
  912. {"sha-384", algoSHA384},
  913. {"sha512", algoSHA512},
  914. {"sha-512", algoSHA512},
  915. };
  916. static const auto mapped_end = mapped.end();
  917. } // namespace
  918. const std::set<std::string>& crypto::hash::all() { return names; }
  919. Algorithms crypto::hash::lookup(const std::string& name)
  920. {
  921. auto i = mapped.find(name);
  922. if (unlikely(i == mapped_end)) {
  923. return algoNone;
  924. }
  925. return i->second;
  926. }
  927. std::unique_ptr<Algorithm> crypto::hash::create(Algorithms algo)
  928. {
  929. switch (algo) {
  930. case algoMD5:
  931. return std::unique_ptr<MD5>(new MD5());
  932. case algoSHA1:
  933. return std::unique_ptr<SHA1>(new SHA1());
  934. case algoSHA224:
  935. return std::unique_ptr<SHA224>(new SHA224());
  936. case algoSHA256:
  937. return std::unique_ptr<SHA256>(new SHA256());
  938. case algoSHA384:
  939. return std::unique_ptr<SHA384>(new SHA384());
  940. case algoSHA512:
  941. return std::unique_ptr<SHA512>(new SHA512());
  942. default:
  943. throw std::domain_error("Invalid hash algorithm");
  944. }
  945. }