scrypt-jane-hash_skein512.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #define SCRYPT_HASH "Skein-512"
  2. #define SCRYPT_HASH_BLOCK_SIZE 64
  3. #define SCRYPT_HASH_DIGEST_SIZE 64
  4. typedef uint8_t scrypt_hash_digest[SCRYPT_HASH_DIGEST_SIZE];
  5. typedef struct scrypt_hash_state_t {
  6. uint64_t X[8], T[2];
  7. uint32_t leftover;
  8. uint8_t buffer[SCRYPT_HASH_BLOCK_SIZE];
  9. } scrypt_hash_state;
  10. #include <stdio.h>
  11. static void
  12. skein512_blocks(scrypt_hash_state *S, const uint8_t *in, size_t blocks, size_t add) {
  13. uint64_t X[8], key[8], Xt[9+18], T[3+1];
  14. size_t r;
  15. while (blocks--) {
  16. T[0] = S->T[0] + add;
  17. T[1] = S->T[1];
  18. T[2] = T[0] ^ T[1];
  19. key[0] = U8TO64_LE(in + 0); Xt[0] = S->X[0]; X[0] = key[0] + Xt[0];
  20. key[1] = U8TO64_LE(in + 8); Xt[1] = S->X[1]; X[1] = key[1] + Xt[1];
  21. key[2] = U8TO64_LE(in + 16); Xt[2] = S->X[2]; X[2] = key[2] + Xt[2];
  22. key[3] = U8TO64_LE(in + 24); Xt[3] = S->X[3]; X[3] = key[3] + Xt[3];
  23. key[4] = U8TO64_LE(in + 32); Xt[4] = S->X[4]; X[4] = key[4] + Xt[4];
  24. key[5] = U8TO64_LE(in + 40); Xt[5] = S->X[5]; X[5] = key[5] + Xt[5] + T[0];
  25. key[6] = U8TO64_LE(in + 48); Xt[6] = S->X[6]; X[6] = key[6] + Xt[6] + T[1];
  26. key[7] = U8TO64_LE(in + 56); Xt[7] = S->X[7]; X[7] = key[7] + Xt[7];
  27. Xt[8] = 0x1BD11BDAA9FC1A22ull ^ Xt[0] ^ Xt[1] ^ Xt[2] ^ Xt[3] ^ Xt[4] ^ Xt[5] ^ Xt[6] ^ Xt[7];
  28. in += SCRYPT_HASH_BLOCK_SIZE;
  29. for (r = 0; r < 18; r++)
  30. Xt[r + 9] = Xt[r + 0];
  31. for (r = 0; r < 18; r += 2) {
  32. X[0] += X[1]; X[1] = ROTL64(X[1], 46) ^ X[0];
  33. X[2] += X[3]; X[3] = ROTL64(X[3], 36) ^ X[2];
  34. X[4] += X[5]; X[5] = ROTL64(X[5], 19) ^ X[4];
  35. X[6] += X[7]; X[7] = ROTL64(X[7], 37) ^ X[6];
  36. X[2] += X[1]; X[1] = ROTL64(X[1], 33) ^ X[2];
  37. X[0] += X[3]; X[3] = ROTL64(X[3], 42) ^ X[0];
  38. X[6] += X[5]; X[5] = ROTL64(X[5], 14) ^ X[6];
  39. X[4] += X[7]; X[7] = ROTL64(X[7], 27) ^ X[4];
  40. X[4] += X[1]; X[1] = ROTL64(X[1], 17) ^ X[4];
  41. X[6] += X[3]; X[3] = ROTL64(X[3], 49) ^ X[6];
  42. X[0] += X[5]; X[5] = ROTL64(X[5], 36) ^ X[0];
  43. X[2] += X[7]; X[7] = ROTL64(X[7], 39) ^ X[2];
  44. X[6] += X[1]; X[1] = ROTL64(X[1], 44) ^ X[6];
  45. X[4] += X[3]; X[3] = ROTL64(X[3], 56) ^ X[4];
  46. X[2] += X[5]; X[5] = ROTL64(X[5], 54) ^ X[2];
  47. X[0] += X[7]; X[7] = ROTL64(X[7], 9) ^ X[0];
  48. X[0] += Xt[r + 1];
  49. X[1] += Xt[r + 2];
  50. X[2] += Xt[r + 3];
  51. X[3] += Xt[r + 4];
  52. X[4] += Xt[r + 5];
  53. X[5] += Xt[r + 6] + T[1];
  54. X[6] += Xt[r + 7] + T[2];
  55. X[7] += Xt[r + 8] + r + 1;
  56. T[3] = T[0];
  57. T[0] = T[1];
  58. T[1] = T[2];
  59. T[2] = T[3];
  60. X[0] += X[1]; X[1] = ROTL64(X[1], 39) ^ X[0];
  61. X[2] += X[3]; X[3] = ROTL64(X[3], 30) ^ X[2];
  62. X[4] += X[5]; X[5] = ROTL64(X[5], 34) ^ X[4];
  63. X[6] += X[7]; X[7] = ROTL64(X[7], 24) ^ X[6];
  64. X[2] += X[1]; X[1] = ROTL64(X[1], 13) ^ X[2];
  65. X[0] += X[3]; X[3] = ROTL64(X[3], 17) ^ X[0];
  66. X[6] += X[5]; X[5] = ROTL64(X[5], 10) ^ X[6];
  67. X[4] += X[7]; X[7] = ROTL64(X[7], 50) ^ X[4];
  68. X[4] += X[1]; X[1] = ROTL64(X[1], 25) ^ X[4];
  69. X[6] += X[3]; X[3] = ROTL64(X[3], 29) ^ X[6];
  70. X[0] += X[5]; X[5] = ROTL64(X[5], 39) ^ X[0];
  71. X[2] += X[7]; X[7] = ROTL64(X[7], 43) ^ X[2];
  72. X[6] += X[1]; X[1] = ROTL64(X[1], 8) ^ X[6];
  73. X[4] += X[3]; X[3] = ROTL64(X[3], 22) ^ X[4];
  74. X[2] += X[5]; X[5] = ROTL64(X[5], 56) ^ X[2];
  75. X[0] += X[7]; X[7] = ROTL64(X[7], 35) ^ X[0];
  76. X[0] += Xt[r + 2];
  77. X[1] += Xt[r + 3];
  78. X[2] += Xt[r + 4];
  79. X[3] += Xt[r + 5];
  80. X[4] += Xt[r + 6];
  81. X[5] += Xt[r + 7] + T[1];
  82. X[6] += Xt[r + 8] + T[2];
  83. X[7] += Xt[r + 9] + r + 2;
  84. T[3] = T[0];
  85. T[0] = T[1];
  86. T[1] = T[2];
  87. T[2] = T[3];
  88. }
  89. S->X[0] = key[0] ^ X[0];
  90. S->X[1] = key[1] ^ X[1];
  91. S->X[2] = key[2] ^ X[2];
  92. S->X[3] = key[3] ^ X[3];
  93. S->X[4] = key[4] ^ X[4];
  94. S->X[5] = key[5] ^ X[5];
  95. S->X[6] = key[6] ^ X[6];
  96. S->X[7] = key[7] ^ X[7];
  97. S->T[0] = T[0];
  98. S->T[1] = T[1] & ~0x4000000000000000ull;
  99. }
  100. }
  101. static void
  102. scrypt_hash_init(scrypt_hash_state *S) {
  103. S->X[0] = 0x4903ADFF749C51CEull;
  104. S->X[1] = 0x0D95DE399746DF03ull;
  105. S->X[2] = 0x8FD1934127C79BCEull;
  106. S->X[3] = 0x9A255629FF352CB1ull;
  107. S->X[4] = 0x5DB62599DF6CA7B0ull;
  108. S->X[5] = 0xEABE394CA9D5C3F4ull;
  109. S->X[6] = 0x991112C71A75B523ull;
  110. S->X[7] = 0xAE18A40B660FCC33ull;
  111. S->T[0] = 0x0000000000000000ull;
  112. S->T[1] = 0x7000000000000000ull;
  113. S->leftover = 0;
  114. }
  115. static void
  116. scrypt_hash_update(scrypt_hash_state *S, const uint8_t *in, size_t inlen) {
  117. size_t blocks, want;
  118. /* skein processes the final <=64 bytes raw, so we can only update if there are at least 64+1 bytes available */
  119. if ((S->leftover + inlen) > SCRYPT_HASH_BLOCK_SIZE) {
  120. /* handle the previous data, we know there is enough for at least one block */
  121. if (S->leftover) {
  122. want = (SCRYPT_HASH_BLOCK_SIZE - S->leftover);
  123. memcpy(S->buffer + S->leftover, in, want);
  124. in += want;
  125. inlen -= want;
  126. S->leftover = 0;
  127. skein512_blocks(S, S->buffer, 1, SCRYPT_HASH_BLOCK_SIZE);
  128. }
  129. /* handle the current data if there's more than one block */
  130. if (inlen > SCRYPT_HASH_BLOCK_SIZE) {
  131. blocks = ((inlen - 1) & ~(SCRYPT_HASH_BLOCK_SIZE - 1));
  132. skein512_blocks(S, in, blocks / SCRYPT_HASH_BLOCK_SIZE, SCRYPT_HASH_BLOCK_SIZE);
  133. inlen -= blocks;
  134. in += blocks;
  135. }
  136. }
  137. /* handle leftover data */
  138. memcpy(S->buffer + S->leftover, in, inlen);
  139. S->leftover += inlen;
  140. }
  141. static void
  142. scrypt_hash_finish(scrypt_hash_state *S, uint8_t *hash) {
  143. memset(S->buffer + S->leftover, 0, SCRYPT_HASH_BLOCK_SIZE - S->leftover);
  144. S->T[1] |= 0x8000000000000000ull;
  145. skein512_blocks(S, S->buffer, 1, S->leftover);
  146. memset(S->buffer, 0, SCRYPT_HASH_BLOCK_SIZE);
  147. S->T[0] = 0;
  148. S->T[1] = 0xff00000000000000ull;
  149. skein512_blocks(S, S->buffer, 1, 8);
  150. U64TO8_LE(&hash[ 0], S->X[0]);
  151. U64TO8_LE(&hash[ 8], S->X[1]);
  152. U64TO8_LE(&hash[16], S->X[2]);
  153. U64TO8_LE(&hash[24], S->X[3]);
  154. U64TO8_LE(&hash[32], S->X[4]);
  155. U64TO8_LE(&hash[40], S->X[5]);
  156. U64TO8_LE(&hash[48], S->X[6]);
  157. U64TO8_LE(&hash[56], S->X[7]);
  158. }
  159. static const uint8_t scrypt_test_hash_expected[SCRYPT_HASH_DIGEST_SIZE] = {
  160. 0x4d,0x52,0x29,0xff,0x10,0xbc,0xd2,0x62,0xd1,0x61,0x83,0xc8,0xe6,0xf0,0x83,0xc4,
  161. 0x9f,0xf5,0x6a,0x42,0x75,0x2a,0x26,0x4e,0xf0,0x28,0x72,0x28,0x47,0xe8,0x23,0xdf,
  162. 0x1e,0x64,0xf1,0x51,0x38,0x35,0x9d,0xc2,0x83,0xfc,0x35,0x4e,0xc0,0x52,0x5f,0x41,
  163. 0x6a,0x0b,0x7d,0xf5,0xce,0x98,0xde,0x6f,0x36,0xd8,0x51,0x15,0x78,0x78,0x93,0x67,
  164. };