Advertisement
Guest User

Untitled

a guest
Jul 30th, 2010
909
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 37.52 KB | None | 0 0
  1. diff --git a/cryptopp/sha256.cpp b/cryptopp/sha256.cpp
  2. new file mode 100644
  3. index 0000000..15f8be1
  4. --- /dev/null
  5. +++ b/cryptopp/sha256.cpp
  6. @@ -0,0 +1,443 @@
  7. +#include <string.h>
  8. +#include <assert.h>
  9. +
  10. +#include <xmmintrin.h>
  11. +#include <stdint.h>
  12. +#include <stdio.h>
  13. +
  14. +#define NPAR 32
  15. +
  16. +static const unsigned int sha256_consts[] = {
  17. +   0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, /*  0 */
  18. +   0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  19. +   0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, /*  8 */
  20. +   0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  21. +   0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, /* 16 */
  22. +   0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  23. +   0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, /* 24 */
  24. +   0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  25. +   0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, /* 32 */
  26. +   0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  27. +   0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, /* 40 */
  28. +   0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  29. +   0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, /* 48 */
  30. +   0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  31. +   0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, /* 56 */
  32. +   0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
  33. +};
  34. +
  35. +
  36. +static inline __m128i Ch(const __m128i b, const __m128i c, const __m128i d) {
  37. +   return (b & c) ^ (~b & d);
  38. +}
  39. +
  40. +static inline __m128i Maj(const __m128i b, const __m128i c, const __m128i d) {
  41. +   return (b & c) ^ (b & d) ^ (c & d);
  42. +}
  43. +
  44. +static inline __m128i ROTR(__m128i x, const int n) {
  45. +   return _mm_srli_epi32(x, n) | _mm_slli_epi32(x, 32 - n);
  46. +}
  47. +
  48. +static inline __m128i SHR(__m128i x, const int n) {
  49. +   return _mm_srli_epi32(x, n);
  50. +}
  51. +
  52. +/* SHA256 Functions */
  53. +#define    BIGSIGMA0_256(x)    (ROTR((x), 2) ^ ROTR((x), 13) ^ ROTR((x), 22))
  54. +#define    BIGSIGMA1_256(x)    (ROTR((x), 6) ^ ROTR((x), 11) ^ ROTR((x), 25))
  55. +#define    SIGMA0_256(x)       (ROTR((x), 7) ^ ROTR((x), 18) ^ SHR((x), 3))
  56. +#define    SIGMA1_256(x)       (ROTR((x), 17) ^ ROTR((x), 19) ^ SHR((x), 10))
  57. +
  58. +static inline __m128i load_epi32(const unsigned int x0, const unsigned int x1, const unsigned int x2, const unsigned int x3) {
  59. +   return _mm_set_epi32(x0, x1, x2, x3);
  60. +}
  61. +
  62. +static inline unsigned int store32(const __m128i x, int i) {
  63. +   union { unsigned int ret[4]; __m128i x; } box;
  64. +   box.x = x;
  65. +   return box.ret[i];
  66. +}
  67. +
  68. +static inline void store_epi32(const __m128i x, unsigned int *x0, unsigned int *x1, unsigned int *x2, unsigned int *x3) {
  69. +   union { unsigned int ret[4]; __m128i x; } box;
  70. +   box.x = x;
  71. +   *x0 = box.ret[3]; *x1 = box.ret[2]; *x2 = box.ret[1]; *x3 = box.ret[0];
  72. +}
  73. +
  74. +static inline __m128i SHA256_CONST(const int i) {
  75. +   return _mm_set1_epi32(sha256_consts[i]);
  76. +}
  77. +
  78. +#define add4(x0, x1, x2, x3) _mm_add_epi32(_mm_add_epi32(_mm_add_epi32(x0, x1), x2), x3)
  79. +#define add5(x0, x1, x2, x3, x4) _mm_add_epi32(add4(x0, x1, x2, x3), x4)
  80. +
  81. +#define    SHA256ROUND(a, b, c, d, e, f, g, h, i, w)                       \
  82. +   T1 = add5(h, BIGSIGMA1_256(e), Ch(e, f, g), SHA256_CONST(i), w);    \
  83. +d = _mm_add_epi32(d, T1);                                           \
  84. +T2 = _mm_add_epi32(BIGSIGMA0_256(a), Maj(a, b, c));                 \
  85. +h = _mm_add_epi32(T1, T2);
  86. +
  87. +#define    SHA256ROUND_lastd(a, b, c, d, e, f, g, h, i, w)                       \
  88. +   T1 = add5(h, BIGSIGMA1_256(e), Ch(e, f, g), SHA256_CONST(i), w);    \
  89. +d = _mm_add_epi32(d, T1);                                          
  90. +//T2 = _mm_add_epi32(BIGSIGMA0_256(a), Maj(a, b, c));                
  91. +//h = _mm_add_epi32(T1, T2);
  92. +
  93. +#define    SHA256ROUND_last(a, b, c, d, e, f, g, h, i, w)                       \
  94. +   T1 = add5(h, BIGSIGMA1_256(e), Ch(e, f, g), SHA256_CONST(i), w);    \
  95. +T2 = _mm_add_epi32(BIGSIGMA0_256(a), Maj(a, b, c));                 \
  96. +h = _mm_add_epi32(T1, T2);
  97. +
  98. +static inline unsigned int swap(unsigned int value) {
  99. +   __asm__ ("bswap %0" : "=r" (value) : "0" (value));
  100. +   return value;
  101. +}
  102. +
  103. +static inline unsigned int SWAP32(const void *addr) {
  104. +   unsigned int value = (*((unsigned int *)(addr)));
  105. +   __asm__ ("bswap %0" : "=r" (value) : "0" (value));
  106. +   return value;
  107. +}
  108. +
  109. +static inline void dumpreg(__m128i x, char *msg) {
  110. +   union { unsigned int ret[4]; __m128i x; } box;
  111. +   box.x = x ;
  112. +   printf("%s %08x %08x %08x %08x\n", msg, box.ret[0], box.ret[1], box.ret[2], box.ret[3]);
  113. +}
  114. +
  115. +#if 1
  116. +#define dumpstate(i) printf("%s: %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", \
  117. +       __func__, store32(w0, i), store32(a, i), store32(b, i), store32(c, i), store32(d, i), store32(e, i), store32(f, i), store32(g, i), store32(h, i));
  118. +#else
  119. +#define dumpstate()
  120. +#endif
  121. +void Double_BlockSHA256(const void* pin, void* pad, const void *pre, unsigned int thash[8][NPAR], const void *init)
  122. +{
  123. +   unsigned int* In = (unsigned int*)pin;
  124. +   unsigned int* Pad = (unsigned int*)pad;
  125. +   unsigned int* hPre = (unsigned int*)pre;
  126. +   unsigned int* hInit = (unsigned int*)init;
  127. +   unsigned int i, j, k;
  128. +
  129. +   /* vectors used in calculation */
  130. +   __m128i w0, w1, w2, w3, w4, w5, w6, w7;
  131. +   __m128i w8, w9, w10, w11, w12, w13, w14, w15;
  132. +   __m128i T1, T2;
  133. +   __m128i a, b, c, d, e, f, g, h;
  134. +
  135. +   /* nonce offset for vector */
  136. +   __m128i offset = load_epi32(0x00000003, 0x00000002, 0x00000001, 0x00000000);
  137. +
  138. +
  139. +   for(k = 0; k<NPAR; k+=4) {
  140. +       w0 = load_epi32(In[0], In[0], In[0], In[0]);
  141. +       w1 = load_epi32(In[1], In[1], In[1], In[1]);
  142. +       w2 = load_epi32(In[2], In[2], In[2], In[2]);
  143. +       w3 = load_epi32(In[3], In[3], In[3], In[3]);
  144. +       w4 = load_epi32(In[4], In[4], In[4], In[4]);
  145. +       w5 = load_epi32(In[5], In[5], In[5], In[5]);
  146. +       w6 = load_epi32(In[6], In[6], In[6], In[6]);
  147. +       w7 = load_epi32(In[7], In[7], In[7], In[7]);
  148. +       w8 = load_epi32(In[8], In[8], In[8], In[8]);
  149. +       w9 = load_epi32(In[9], In[9], In[9], In[9]);
  150. +       w10 = load_epi32(In[10], In[10], In[10], In[10]);
  151. +       w11 = load_epi32(In[11], In[11], In[11], In[11]);
  152. +       w12 = load_epi32(In[12], In[12], In[12], In[12]);
  153. +       w13 = load_epi32(In[13], In[13], In[13], In[13]);
  154. +       w14 = load_epi32(In[14], In[14], In[14], In[14]);
  155. +       w15 = load_epi32(In[15], In[15], In[15], In[15]);
  156. +
  157. +       /* hack nonce into lowest byte of w3 */
  158. +       __m128i k_vec = load_epi32(k, k, k, k);
  159. +       w3 = _mm_add_epi32(w3, offset);
  160. +       w3 = _mm_add_epi32(w3, k_vec);
  161. +
  162. +       a = load_epi32(hPre[0], hPre[0], hPre[0], hPre[0]);
  163. +       b = load_epi32(hPre[1], hPre[1], hPre[1], hPre[1]);
  164. +       c = load_epi32(hPre[2], hPre[2], hPre[2], hPre[2]);
  165. +       d = load_epi32(hPre[3], hPre[3], hPre[3], hPre[3]);
  166. +       e = load_epi32(hPre[4], hPre[4], hPre[4], hPre[4]);
  167. +       f = load_epi32(hPre[5], hPre[5], hPre[5], hPre[5]);
  168. +       g = load_epi32(hPre[6], hPre[6], hPre[6], hPre[6]);
  169. +       h = load_epi32(hPre[7], hPre[7], hPre[7], hPre[7]);
  170. +
  171. +       SHA256ROUND(a, b, c, d, e, f, g, h, 0, w0);    
  172. +       SHA256ROUND(h, a, b, c, d, e, f, g, 1, w1);
  173. +       SHA256ROUND(g, h, a, b, c, d, e, f, 2, w2);
  174. +       SHA256ROUND(f, g, h, a, b, c, d, e, 3, w3);
  175. +       SHA256ROUND(e, f, g, h, a, b, c, d, 4, w4);
  176. +       SHA256ROUND(d, e, f, g, h, a, b, c, 5, w5);
  177. +       SHA256ROUND(c, d, e, f, g, h, a, b, 6, w6);
  178. +       SHA256ROUND(b, c, d, e, f, g, h, a, 7, w7);
  179. +       SHA256ROUND(a, b, c, d, e, f, g, h, 8, w8);
  180. +       SHA256ROUND(h, a, b, c, d, e, f, g, 9, w9);
  181. +       SHA256ROUND(g, h, a, b, c, d, e, f, 10, w10);
  182. +       SHA256ROUND(f, g, h, a, b, c, d, e, 11, w11);
  183. +       SHA256ROUND(e, f, g, h, a, b, c, d, 12, w12);
  184. +       SHA256ROUND(d, e, f, g, h, a, b, c, 13, w13);
  185. +       SHA256ROUND(c, d, e, f, g, h, a, b, 14, w14);
  186. +       SHA256ROUND(b, c, d, e, f, g, h, a, 15, w15);
  187. +
  188. +       w0 = add4(SIGMA1_256(w14), w9, SIGMA0_256(w1), w0);
  189. +       SHA256ROUND(a, b, c, d, e, f, g, h, 16, w0);
  190. +       w1 = add4(SIGMA1_256(w15), w10, SIGMA0_256(w2), w1);
  191. +       SHA256ROUND(h, a, b, c, d, e, f, g, 17, w1);
  192. +       w2 = add4(SIGMA1_256(w0), w11, SIGMA0_256(w3), w2);
  193. +       SHA256ROUND(g, h, a, b, c, d, e, f, 18, w2);
  194. +       w3 = add4(SIGMA1_256(w1), w12, SIGMA0_256(w4), w3);
  195. +       SHA256ROUND(f, g, h, a, b, c, d, e, 19, w3);
  196. +       w4 = add4(SIGMA1_256(w2), w13, SIGMA0_256(w5), w4);
  197. +       SHA256ROUND(e, f, g, h, a, b, c, d, 20, w4);
  198. +       w5 = add4(SIGMA1_256(w3), w14, SIGMA0_256(w6), w5);
  199. +       SHA256ROUND(d, e, f, g, h, a, b, c, 21, w5);
  200. +       w6 = add4(SIGMA1_256(w4), w15, SIGMA0_256(w7), w6);
  201. +       SHA256ROUND(c, d, e, f, g, h, a, b, 22, w6);
  202. +       w7 = add4(SIGMA1_256(w5), w0, SIGMA0_256(w8), w7);
  203. +       SHA256ROUND(b, c, d, e, f, g, h, a, 23, w7);
  204. +       w8 = add4(SIGMA1_256(w6), w1, SIGMA0_256(w9), w8);
  205. +       SHA256ROUND(a, b, c, d, e, f, g, h, 24, w8);
  206. +       w9 = add4(SIGMA1_256(w7), w2, SIGMA0_256(w10), w9);
  207. +       SHA256ROUND(h, a, b, c, d, e, f, g, 25, w9);
  208. +       w10 = add4(SIGMA1_256(w8), w3, SIGMA0_256(w11), w10);
  209. +       SHA256ROUND(g, h, a, b, c, d, e, f, 26, w10);
  210. +       w11 = add4(SIGMA1_256(w9), w4, SIGMA0_256(w12), w11);
  211. +       SHA256ROUND(f, g, h, a, b, c, d, e, 27, w11);
  212. +       w12 = add4(SIGMA1_256(w10), w5, SIGMA0_256(w13), w12);
  213. +       SHA256ROUND(e, f, g, h, a, b, c, d, 28, w12);
  214. +       w13 = add4(SIGMA1_256(w11), w6, SIGMA0_256(w14), w13);
  215. +       SHA256ROUND(d, e, f, g, h, a, b, c, 29, w13);
  216. +       w14 = add4(SIGMA1_256(w12), w7, SIGMA0_256(w15), w14);
  217. +       SHA256ROUND(c, d, e, f, g, h, a, b, 30, w14);
  218. +       w15 = add4(SIGMA1_256(w13), w8, SIGMA0_256(w0), w15);
  219. +       SHA256ROUND(b, c, d, e, f, g, h, a, 31, w15);
  220. +
  221. +       w0 = add4(SIGMA1_256(w14), w9, SIGMA0_256(w1), w0);
  222. +       SHA256ROUND(a, b, c, d, e, f, g, h, 32, w0);
  223. +       w1 = add4(SIGMA1_256(w15), w10, SIGMA0_256(w2), w1);
  224. +       SHA256ROUND(h, a, b, c, d, e, f, g, 33, w1);
  225. +       w2 = add4(SIGMA1_256(w0), w11, SIGMA0_256(w3), w2);
  226. +       SHA256ROUND(g, h, a, b, c, d, e, f, 34, w2);
  227. +       w3 = add4(SIGMA1_256(w1), w12, SIGMA0_256(w4), w3);
  228. +       SHA256ROUND(f, g, h, a, b, c, d, e, 35, w3);
  229. +       w4 = add4(SIGMA1_256(w2), w13, SIGMA0_256(w5), w4);
  230. +       SHA256ROUND(e, f, g, h, a, b, c, d, 36, w4);
  231. +       w5 = add4(SIGMA1_256(w3), w14, SIGMA0_256(w6), w5);
  232. +       SHA256ROUND(d, e, f, g, h, a, b, c, 37, w5);
  233. +       w6 = add4(SIGMA1_256(w4), w15, SIGMA0_256(w7), w6);
  234. +       SHA256ROUND(c, d, e, f, g, h, a, b, 38, w6);
  235. +       w7 = add4(SIGMA1_256(w5), w0, SIGMA0_256(w8), w7);
  236. +       SHA256ROUND(b, c, d, e, f, g, h, a, 39, w7);
  237. +       w8 = add4(SIGMA1_256(w6), w1, SIGMA0_256(w9), w8);
  238. +       SHA256ROUND(a, b, c, d, e, f, g, h, 40, w8);
  239. +       w9 = add4(SIGMA1_256(w7), w2, SIGMA0_256(w10), w9);
  240. +       SHA256ROUND(h, a, b, c, d, e, f, g, 41, w9);
  241. +       w10 = add4(SIGMA1_256(w8), w3, SIGMA0_256(w11), w10);
  242. +       SHA256ROUND(g, h, a, b, c, d, e, f, 42, w10);
  243. +       w11 = add4(SIGMA1_256(w9), w4, SIGMA0_256(w12), w11);
  244. +       SHA256ROUND(f, g, h, a, b, c, d, e, 43, w11);
  245. +       w12 = add4(SIGMA1_256(w10), w5, SIGMA0_256(w13), w12);
  246. +       SHA256ROUND(e, f, g, h, a, b, c, d, 44, w12);
  247. +       w13 = add4(SIGMA1_256(w11), w6, SIGMA0_256(w14), w13);
  248. +       SHA256ROUND(d, e, f, g, h, a, b, c, 45, w13);
  249. +       w14 = add4(SIGMA1_256(w12), w7, SIGMA0_256(w15), w14);
  250. +       SHA256ROUND(c, d, e, f, g, h, a, b, 46, w14);
  251. +       w15 = add4(SIGMA1_256(w13), w8, SIGMA0_256(w0), w15);
  252. +       SHA256ROUND(b, c, d, e, f, g, h, a, 47, w15);
  253. +
  254. +       w0 = add4(SIGMA1_256(w14), w9, SIGMA0_256(w1), w0);
  255. +       SHA256ROUND(a, b, c, d, e, f, g, h, 48, w0);
  256. +       w1 = add4(SIGMA1_256(w15), w10, SIGMA0_256(w2), w1);
  257. +       SHA256ROUND(h, a, b, c, d, e, f, g, 49, w1);
  258. +       w2 = add4(SIGMA1_256(w0), w11, SIGMA0_256(w3), w2);
  259. +       SHA256ROUND(g, h, a, b, c, d, e, f, 50, w2);
  260. +       w3 = add4(SIGMA1_256(w1), w12, SIGMA0_256(w4), w3);
  261. +       SHA256ROUND(f, g, h, a, b, c, d, e, 51, w3);
  262. +       w4 = add4(SIGMA1_256(w2), w13, SIGMA0_256(w5), w4);
  263. +       SHA256ROUND(e, f, g, h, a, b, c, d, 52, w4);
  264. +       w5 = add4(SIGMA1_256(w3), w14, SIGMA0_256(w6), w5);
  265. +       SHA256ROUND(d, e, f, g, h, a, b, c, 53, w5);
  266. +       w6 = add4(SIGMA1_256(w4), w15, SIGMA0_256(w7), w6);
  267. +       SHA256ROUND(c, d, e, f, g, h, a, b, 54, w6);
  268. +       w7 = add4(SIGMA1_256(w5), w0, SIGMA0_256(w8), w7);
  269. +       SHA256ROUND(b, c, d, e, f, g, h, a, 55, w7);
  270. +       w8 = add4(SIGMA1_256(w6), w1, SIGMA0_256(w9), w8);
  271. +       SHA256ROUND(a, b, c, d, e, f, g, h, 56, w8);
  272. +       w9 = add4(SIGMA1_256(w7), w2, SIGMA0_256(w10), w9);
  273. +       SHA256ROUND(h, a, b, c, d, e, f, g, 57, w9);
  274. +       w10 = add4(SIGMA1_256(w8), w3, SIGMA0_256(w11), w10);
  275. +       SHA256ROUND(g, h, a, b, c, d, e, f, 58, w10);
  276. +       w11 = add4(SIGMA1_256(w9), w4, SIGMA0_256(w12), w11);
  277. +       SHA256ROUND(f, g, h, a, b, c, d, e, 59, w11);
  278. +       w12 = add4(SIGMA1_256(w10), w5, SIGMA0_256(w13), w12);
  279. +       SHA256ROUND(e, f, g, h, a, b, c, d, 60, w12);
  280. +       w13 = add4(SIGMA1_256(w11), w6, SIGMA0_256(w14), w13);
  281. +       SHA256ROUND(d, e, f, g, h, a, b, c, 61, w13);
  282. +       w14 = add4(SIGMA1_256(w12), w7, SIGMA0_256(w15), w14);
  283. +       SHA256ROUND(c, d, e, f, g, h, a, b, 62, w14);
  284. +       w15 = add4(SIGMA1_256(w13), w8, SIGMA0_256(w0), w15);
  285. +       SHA256ROUND(b, c, d, e, f, g, h, a, 63, w15);
  286. +
  287. +#define store_load(x, i, dest) \
  288. +       w8 = load_epi32((hPre)[i], (hPre)[i], (hPre)[i], (hPre)[i]); \
  289. +       dest = _mm_add_epi32(w8, x);
  290. +
  291. +       store_load(a, 0, w0);
  292. +       store_load(b, 1, w1);
  293. +       store_load(c, 2, w2);
  294. +       store_load(d, 3, w3);
  295. +       store_load(e, 4, w4);
  296. +       store_load(f, 5, w5);
  297. +       store_load(g, 6, w6);
  298. +       store_load(h, 7, w7);
  299. +
  300. +       w8 = load_epi32(Pad[8], Pad[8], Pad[8], Pad[8]);
  301. +       w9 = load_epi32(Pad[9], Pad[9], Pad[9], Pad[9]);
  302. +       w10 = load_epi32(Pad[10], Pad[10], Pad[10], Pad[10]);
  303. +       w11 = load_epi32(Pad[11], Pad[11], Pad[11], Pad[11]);
  304. +       w12 = load_epi32(Pad[12], Pad[12], Pad[12], Pad[12]);
  305. +       w13 = load_epi32(Pad[13], Pad[13], Pad[13], Pad[13]);
  306. +       w14 = load_epi32(Pad[14], Pad[14], Pad[14], Pad[14]);
  307. +       w15 = load_epi32(Pad[15], Pad[15], Pad[15], Pad[15]);
  308. +
  309. +       a = load_epi32(hInit[0], hInit[0], hInit[0], hInit[0]);
  310. +       b = load_epi32(hInit[1], hInit[1], hInit[1], hInit[1]);
  311. +       c = load_epi32(hInit[2], hInit[2], hInit[2], hInit[2]);
  312. +       d = load_epi32(hInit[3], hInit[3], hInit[3], hInit[3]);
  313. +       e = load_epi32(hInit[4], hInit[4], hInit[4], hInit[4]);
  314. +       f = load_epi32(hInit[5], hInit[5], hInit[5], hInit[5]);
  315. +       g = load_epi32(hInit[6], hInit[6], hInit[6], hInit[6]);
  316. +       h = load_epi32(hInit[7], hInit[7], hInit[7], hInit[7]);
  317. +
  318. +       SHA256ROUND(a, b, c, d, e, f, g, h, 0, w0);    
  319. +       SHA256ROUND(h, a, b, c, d, e, f, g, 1, w1);
  320. +       SHA256ROUND(g, h, a, b, c, d, e, f, 2, w2);
  321. +       SHA256ROUND(f, g, h, a, b, c, d, e, 3, w3);
  322. +       SHA256ROUND(e, f, g, h, a, b, c, d, 4, w4);
  323. +       SHA256ROUND(d, e, f, g, h, a, b, c, 5, w5);
  324. +       SHA256ROUND(c, d, e, f, g, h, a, b, 6, w6);
  325. +       SHA256ROUND(b, c, d, e, f, g, h, a, 7, w7);
  326. +       SHA256ROUND(a, b, c, d, e, f, g, h, 8, w8);
  327. +       SHA256ROUND(h, a, b, c, d, e, f, g, 9, w9);
  328. +       SHA256ROUND(g, h, a, b, c, d, e, f, 10, w10);
  329. +       SHA256ROUND(f, g, h, a, b, c, d, e, 11, w11);
  330. +       SHA256ROUND(e, f, g, h, a, b, c, d, 12, w12);
  331. +       SHA256ROUND(d, e, f, g, h, a, b, c, 13, w13);
  332. +       SHA256ROUND(c, d, e, f, g, h, a, b, 14, w14);
  333. +       SHA256ROUND(b, c, d, e, f, g, h, a, 15, w15);
  334. +
  335. +       w0 = add4(SIGMA1_256(w14), w9, SIGMA0_256(w1), w0);
  336. +       SHA256ROUND(a, b, c, d, e, f, g, h, 16, w0);
  337. +       w1 = add4(SIGMA1_256(w15), w10, SIGMA0_256(w2), w1);
  338. +       SHA256ROUND(h, a, b, c, d, e, f, g, 17, w1);
  339. +       w2 = add4(SIGMA1_256(w0), w11, SIGMA0_256(w3), w2);
  340. +       SHA256ROUND(g, h, a, b, c, d, e, f, 18, w2);
  341. +       w3 = add4(SIGMA1_256(w1), w12, SIGMA0_256(w4), w3);
  342. +       SHA256ROUND(f, g, h, a, b, c, d, e, 19, w3);
  343. +       w4 = add4(SIGMA1_256(w2), w13, SIGMA0_256(w5), w4);
  344. +       SHA256ROUND(e, f, g, h, a, b, c, d, 20, w4);
  345. +       w5 = add4(SIGMA1_256(w3), w14, SIGMA0_256(w6), w5);
  346. +       SHA256ROUND(d, e, f, g, h, a, b, c, 21, w5);
  347. +       w6 = add4(SIGMA1_256(w4), w15, SIGMA0_256(w7), w6);
  348. +       SHA256ROUND(c, d, e, f, g, h, a, b, 22, w6);
  349. +       w7 = add4(SIGMA1_256(w5), w0, SIGMA0_256(w8), w7);
  350. +       SHA256ROUND(b, c, d, e, f, g, h, a, 23, w7);
  351. +       w8 = add4(SIGMA1_256(w6), w1, SIGMA0_256(w9), w8);
  352. +       SHA256ROUND(a, b, c, d, e, f, g, h, 24, w8);
  353. +       w9 = add4(SIGMA1_256(w7), w2, SIGMA0_256(w10), w9);
  354. +       SHA256ROUND(h, a, b, c, d, e, f, g, 25, w9);
  355. +       w10 = add4(SIGMA1_256(w8), w3, SIGMA0_256(w11), w10);
  356. +       SHA256ROUND(g, h, a, b, c, d, e, f, 26, w10);
  357. +       w11 = add4(SIGMA1_256(w9), w4, SIGMA0_256(w12), w11);
  358. +       SHA256ROUND(f, g, h, a, b, c, d, e, 27, w11);
  359. +       w12 = add4(SIGMA1_256(w10), w5, SIGMA0_256(w13), w12);
  360. +       SHA256ROUND(e, f, g, h, a, b, c, d, 28, w12);
  361. +       w13 = add4(SIGMA1_256(w11), w6, SIGMA0_256(w14), w13);
  362. +       SHA256ROUND(d, e, f, g, h, a, b, c, 29, w13);
  363. +       w14 = add4(SIGMA1_256(w12), w7, SIGMA0_256(w15), w14);
  364. +       SHA256ROUND(c, d, e, f, g, h, a, b, 30, w14);
  365. +       w15 = add4(SIGMA1_256(w13), w8, SIGMA0_256(w0), w15);
  366. +       SHA256ROUND(b, c, d, e, f, g, h, a, 31, w15);
  367. +
  368. +       w0 = add4(SIGMA1_256(w14), w9, SIGMA0_256(w1), w0);
  369. +       SHA256ROUND(a, b, c, d, e, f, g, h, 32, w0);
  370. +       w1 = add4(SIGMA1_256(w15), w10, SIGMA0_256(w2), w1);
  371. +       SHA256ROUND(h, a, b, c, d, e, f, g, 33, w1);
  372. +       w2 = add4(SIGMA1_256(w0), w11, SIGMA0_256(w3), w2);
  373. +       SHA256ROUND(g, h, a, b, c, d, e, f, 34, w2);
  374. +       w3 = add4(SIGMA1_256(w1), w12, SIGMA0_256(w4), w3);
  375. +       SHA256ROUND(f, g, h, a, b, c, d, e, 35, w3);
  376. +       w4 = add4(SIGMA1_256(w2), w13, SIGMA0_256(w5), w4);
  377. +       SHA256ROUND(e, f, g, h, a, b, c, d, 36, w4);
  378. +       w5 = add4(SIGMA1_256(w3), w14, SIGMA0_256(w6), w5);
  379. +       SHA256ROUND(d, e, f, g, h, a, b, c, 37, w5);
  380. +       w6 = add4(SIGMA1_256(w4), w15, SIGMA0_256(w7), w6);
  381. +       SHA256ROUND(c, d, e, f, g, h, a, b, 38, w6);
  382. +       w7 = add4(SIGMA1_256(w5), w0, SIGMA0_256(w8), w7);
  383. +       SHA256ROUND(b, c, d, e, f, g, h, a, 39, w7);
  384. +       w8 = add4(SIGMA1_256(w6), w1, SIGMA0_256(w9), w8);
  385. +       SHA256ROUND(a, b, c, d, e, f, g, h, 40, w8);
  386. +       w9 = add4(SIGMA1_256(w7), w2, SIGMA0_256(w10), w9);
  387. +       SHA256ROUND(h, a, b, c, d, e, f, g, 41, w9);
  388. +       w10 = add4(SIGMA1_256(w8), w3, SIGMA0_256(w11), w10);
  389. +       SHA256ROUND(g, h, a, b, c, d, e, f, 42, w10);
  390. +       w11 = add4(SIGMA1_256(w9), w4, SIGMA0_256(w12), w11);
  391. +       SHA256ROUND(f, g, h, a, b, c, d, e, 43, w11);
  392. +       w12 = add4(SIGMA1_256(w10), w5, SIGMA0_256(w13), w12);
  393. +       SHA256ROUND(e, f, g, h, a, b, c, d, 44, w12);
  394. +       w13 = add4(SIGMA1_256(w11), w6, SIGMA0_256(w14), w13);
  395. +       SHA256ROUND(d, e, f, g, h, a, b, c, 45, w13);
  396. +       w14 = add4(SIGMA1_256(w12), w7, SIGMA0_256(w15), w14);
  397. +       SHA256ROUND(c, d, e, f, g, h, a, b, 46, w14);
  398. +       w15 = add4(SIGMA1_256(w13), w8, SIGMA0_256(w0), w15);
  399. +       SHA256ROUND(b, c, d, e, f, g, h, a, 47, w15);
  400. +
  401. +       w0 = add4(SIGMA1_256(w14), w9, SIGMA0_256(w1), w0);
  402. +       SHA256ROUND(a, b, c, d, e, f, g, h, 48, w0);
  403. +       w1 = add4(SIGMA1_256(w15), w10, SIGMA0_256(w2), w1);
  404. +       SHA256ROUND(h, a, b, c, d, e, f, g, 49, w1);
  405. +       w2 = add4(SIGMA1_256(w0), w11, SIGMA0_256(w3), w2);
  406. +       SHA256ROUND(g, h, a, b, c, d, e, f, 50, w2);
  407. +       w3 = add4(SIGMA1_256(w1), w12, SIGMA0_256(w4), w3);
  408. +       SHA256ROUND(f, g, h, a, b, c, d, e, 51, w3);
  409. +       w4 = add4(SIGMA1_256(w2), w13, SIGMA0_256(w5), w4);
  410. +       SHA256ROUND(e, f, g, h, a, b, c, d, 52, w4);
  411. +       w5 = add4(SIGMA1_256(w3), w14, SIGMA0_256(w6), w5);
  412. +       SHA256ROUND(d, e, f, g, h, a, b, c, 53, w5);
  413. +       w6 = add4(SIGMA1_256(w4), w15, SIGMA0_256(w7), w6);
  414. +       SHA256ROUND(c, d, e, f, g, h, a, b, 54, w6);
  415. +       w7 = add4(SIGMA1_256(w5), w0, SIGMA0_256(w8), w7);
  416. +       SHA256ROUND(b, c, d, e, f, g, h, a, 55, w7);
  417. +       w8 = add4(SIGMA1_256(w6), w1, SIGMA0_256(w9), w8);
  418. +       SHA256ROUND(a, b, c, d, e, f, g, h, 56, w8);
  419. +       w9 = add4(SIGMA1_256(w7), w2, SIGMA0_256(w10), w9);
  420. +       SHA256ROUND(h, a, b, c, d, e, f, g, 57, w9);
  421. +       w10 = add4(SIGMA1_256(w8), w3, SIGMA0_256(w11), w10);
  422. +       SHA256ROUND(g, h, a, b, c, d, e, f, 58, w10);
  423. +       w11 = add4(SIGMA1_256(w9), w4, SIGMA0_256(w12), w11);
  424. +       SHA256ROUND(f, g, h, a, b, c, d, e, 59, w11);
  425. +       w12 = add4(SIGMA1_256(w10), w5, SIGMA0_256(w13), w12);
  426. +       SHA256ROUND(e, f, g, h, a, b, c, d, 60, w12);
  427. +       w13 = add4(SIGMA1_256(w11), w6, SIGMA0_256(w14), w13);
  428. +       SHA256ROUND(d, e, f, g, h, a, b, c, 61, w13);
  429. +       w14 = add4(SIGMA1_256(w12), w7, SIGMA0_256(w15), w14);
  430. +       SHA256ROUND(c, d, e, f, g, h, a, b, 62, w14);
  431. +       w15 = add4(SIGMA1_256(w13), w8, SIGMA0_256(w0), w15);
  432. +       SHA256ROUND(b, c, d, e, f, g, h, a, 63, w15);
  433. +
  434. +       /* store resulsts directly in thash */
  435. +#define store_2(x,i)  \
  436. +       w0 = load_epi32((hInit)[i], (hInit)[i], (hInit)[i], (hInit)[i]); \
  437. +       *(__m128i *)&(thash)[i][0+k] = _mm_add_epi32(w0, x);
  438. +
  439. +       store_2(a, 0);
  440. +       store_2(b, 1);
  441. +       store_2(c, 2);
  442. +       store_2(d, 3);
  443. +       store_2(e, 4);
  444. +       store_2(f, 5);
  445. +       store_2(g, 6);
  446. +       store_2(h, 7);
  447. +   }
  448. +
  449. +}
  450. diff --git a/main.cpp b/main.cpp
  451. index ddc359a..d30d642 100755
  452. --- a/main.cpp
  453. +++ b/main.cpp
  454. @@ -2555,8 +2555,10 @@ inline void SHA256Transform(void* pstate, void* pinput, const void* pinit)
  455.      CryptoPP::SHA256::Transform((CryptoPP::word32*)pstate, (CryptoPP::word32*)pinput);
  456.  }
  457.  
  458. +// !!!! NPAR must match NPAR in cryptopp/sha256.cpp !!!!
  459. +#define NPAR 32
  460.  
  461. -
  462. +extern void Double_BlockSHA256(const void* pin, void* pout, const void *pinit, unsigned int hash[8][NPAR], const void *init2);
  463.  
  464.  
  465.  void BitcoinMiner()
  466. @@ -2701,108 +2703,123 @@ void BitcoinMiner()
  467.          uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
  468.          uint256 hashbuf[2];
  469.          uint256& hash = *alignup<16>(hashbuf);
  470. +
  471. +        // Cache for NPAR hashes
  472. +        unsigned int thash[8][NPAR];
  473. +
  474. +        unsigned int j;
  475.          loop
  476.          {
  477. -            SHA256Transform(&tmp.hash1, (char*)&tmp.block + 64, &midstate);
  478. -            SHA256Transform(&hash, &tmp.hash1, pSHA256InitState);
  479. +          Double_BlockSHA256((char*)&tmp.block + 64, &tmp.hash1, &midstate, thash, pSHA256InitState);
  480.  
  481. -            if (((unsigned short*)&hash)[14] == 0)
  482. +          for(j = 0; j<NPAR; j++) {
  483. +            if (thash[7][j] == 0)
  484.              {
  485. -                // Byte swap the result after preliminary check
  486. -                for (int i = 0; i < sizeof(hash)/4; i++)
  487. -                    ((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]);
  488. -
  489. -                if (hash <= hashTarget)
  490. +              // Byte swap the result after preliminary check
  491. +              for (int i = 0; i < sizeof(hash)/4; i++)
  492. +                ((unsigned int*)&hash)[i] = ByteReverse((unsigned int)thash[i][j]);
  493. +
  494. +              if (hash <= hashTarget)
  495. +              {
  496. +                // Double_BlocSHA256 might only calculate parts of the hash.
  497. +                // We'll insert the nonce and get the real hash.
  498. +                //pblock->nNonce = ByteReverse(tmp.block.nNonce + j);
  499. +                //hash = pblock->GetHash();
  500. +
  501. +                pblock->nNonce = ByteReverse(tmp.block.nNonce + j);
  502. +                assert(hash == pblock->GetHash());
  503. +
  504. +                //// debug print
  505. +                printf("BitcoinMiner:\n");
  506. +                printf("proof-of-work found  \n  hash: %s  \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
  507. +                pblock->print();
  508. +                printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
  509. +                printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
  510. +
  511. +                SetThreadPriority(THREAD_PRIORITY_NORMAL);
  512. +                CRITICAL_BLOCK(cs_main)
  513.                  {
  514. -                    pblock->nNonce = ByteReverse(tmp.block.nNonce);
  515. -                    assert(hash == pblock->GetHash());
  516. -
  517. -                        //// debug print
  518. -                        printf("BitcoinMiner:\n");
  519. -                        printf("proof-of-work found  \n  hash: %s  \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
  520. -                        pblock->print();
  521. -                        printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
  522. -                        printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
  523. -
  524. -                    SetThreadPriority(THREAD_PRIORITY_NORMAL);
  525. -                    CRITICAL_BLOCK(cs_main)
  526. -                    {
  527. -                        if (pindexPrev == pindexBest)
  528. -                        {
  529. -                            // Save key
  530. -                            if (!AddKey(key))
  531. -                                return;
  532. -                            key.MakeNewKey();
  533. -
  534. -                            // Track how many getdata requests this block gets
  535. -                            CRITICAL_BLOCK(cs_mapRequestCount)
  536. -                                mapRequestCount[pblock->GetHash()] = 0;
  537. -
  538. -                            // Process this block the same as if we had received it from another node
  539. -                            if (!ProcessBlock(NULL, pblock.release()))
  540. -                                printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n");
  541. -                        }
  542. -                    }
  543. -                    SetThreadPriority(THREAD_PRIORITY_LOWEST);
  544. -
  545. -                    Sleep(500);
  546. -                    break;
  547. +                  if (pindexPrev == pindexBest)
  548. +                  {
  549. +                    // Save key
  550. +                    if (!AddKey(key))
  551. +                      return;
  552. +                    key.MakeNewKey();
  553. +
  554. +                    // Track how many getdata requests this block gets
  555. +                    CRITICAL_BLOCK(cs_mapRequestCount)
  556. +                      mapRequestCount[pblock->GetHash()] = 0;
  557. +
  558. +                    // Process this block the same as if we had received it from another node
  559. +                    if (!ProcessBlock(NULL, pblock.release()))
  560. +                      printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n");
  561. +
  562. +                  }
  563.                  }
  564. -            }
  565. +                SetThreadPriority(THREAD_PRIORITY_LOWEST);
  566.  
  567. -            // Update nTime every few seconds
  568. -            const unsigned int nMask = 0xffff;
  569. -            if ((++tmp.block.nNonce & nMask) == 0)
  570. +                Sleep(500);
  571. +                break;
  572. +              }
  573. +            }
  574. +          }
  575. +
  576. +          // Update nonce
  577. +          tmp.block.nNonce += NPAR;
  578. +
  579. +          // Update nTime every few seconds
  580. +          const unsigned int nMask = 0xffff;
  581. +          if ((tmp.block.nNonce & nMask) == 0)
  582. +          {
  583. +            // Meter hashes/sec
  584. +            static int64 nTimerStart;
  585. +            static int nHashCounter;
  586. +            if (nTimerStart == 0)
  587. +              nTimerStart = GetTimeMillis();
  588. +            else
  589. +              nHashCounter++;
  590. +            if (GetTimeMillis() - nTimerStart > 4000)
  591.              {
  592. -                // Meter hashes/sec
  593. -                static int64 nTimerStart;
  594. -                static int nHashCounter;
  595. -                if (nTimerStart == 0)
  596. -                    nTimerStart = GetTimeMillis();
  597. -                else
  598. -                    nHashCounter++;
  599. +              static CCriticalSection cs;
  600. +              CRITICAL_BLOCK(cs)
  601. +              {
  602.                  if (GetTimeMillis() - nTimerStart > 4000)
  603.                  {
  604. -                    static CCriticalSection cs;
  605. -                    CRITICAL_BLOCK(cs)
  606. -                    {
  607. -                        if (GetTimeMillis() - nTimerStart > 4000)
  608. -                        {
  609. -                            double dHashesPerSec = 1000.0 * (nMask+1) * nHashCounter / (GetTimeMillis() - nTimerStart);
  610. -                            nTimerStart = GetTimeMillis();
  611. -                            nHashCounter = 0;
  612. -                            string strStatus = strprintf("    %.0f khash/s", dHashesPerSec/1000.0);
  613. -                            UIThreadCall(bind(CalledSetStatusBar, strStatus, 0));
  614. -                            static int64 nLogTime;
  615. -                            if (GetTime() - nLogTime > 30 * 60)
  616. -                            {
  617. -                                nLogTime = GetTime();
  618. -                                printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
  619. -                                printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[3], dHashesPerSec/1000.0);
  620. -                            }
  621. -                        }
  622. -                    }
  623. +                  double dHashesPerSec = 1000.0 * (nMask+1) * nHashCounter / (GetTimeMillis() - nTimerStart);
  624. +                  nTimerStart = GetTimeMillis();
  625. +                  nHashCounter = 0;
  626. +                  string strStatus = strprintf("    %.0f khash/s", dHashesPerSec/1000.0);
  627. +                  UIThreadCall(bind(CalledSetStatusBar, strStatus, 0));
  628. +                  static int64 nLogTime;
  629. +                  if (GetTime() - nLogTime > 30 * 60)
  630. +                  {
  631. +                    nLogTime = GetTime();
  632. +                    printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
  633. +                    printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[3], dHashesPerSec/1000.0);
  634. +                  }
  635.                  }
  636. -
  637. -                // Check for stop or if block needs to be rebuilt
  638. -                if (fShutdown)
  639. -                    return;
  640. -                if (!fGenerateBitcoins)
  641. -                    return;
  642. -                if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
  643. -                    return;
  644. -                if (vNodes.empty())
  645. -                    break;
  646. -                if (tmp.block.nNonce == 0)
  647. -                    break;
  648. -                if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
  649. -                    break;
  650. -                if (pindexPrev != pindexBest)
  651. -                    break;
  652. -
  653. -                pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
  654. -                tmp.block.nTime = ByteReverse(pblock->nTime);
  655. +              }
  656.              }
  657. +
  658. +            // Check for stop or if block needs to be rebuilt
  659. +            if (fShutdown)
  660. +              return;
  661. +            if (!fGenerateBitcoins)
  662. +              return;
  663. +            if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
  664. +              return;
  665. +            if (vNodes.empty())
  666. +              break;
  667. +            if (tmp.block.nNonce == 0)
  668. +              break;
  669. +            if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
  670. +              break;
  671. +            if (pindexPrev != pindexBest)
  672. +              break;
  673. +
  674. +            pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
  675. +            tmp.block.nTime = ByteReverse(pblock->nTime);
  676. +          }
  677.          }
  678.      }
  679.  }
  680. diff --git a/makefile.unix b/makefile.unix
  681. index 597a0ea..8fb0aa6 100755
  682. --- a/makefile.unix
  683. +++ b/makefile.unix
  684. @@ -45,7 +45,8 @@ OBJS= \
  685.      obj/rpc.o \
  686.      obj/init.o \
  687.      cryptopp/obj/sha.o \
  688. -    cryptopp/obj/cpu.o
  689. +    cryptopp/obj/cpu.o \
  690. +       cryptopp/obj/sha256.o
  691.  
  692.  
  693.  all: bitcoin
  694. @@ -58,18 +59,20 @@ obj/%.o: %.cpp $(HEADERS) headers.h.gch
  695.     g++ -c $(CFLAGS) -DGUI -o $@ $<
  696.  
  697.  cryptopp/obj/%.o: cryptopp/%.cpp
  698. -   g++ -c $(CFLAGS) -O3 -DCRYPTOPP_DISABLE_SSE2 -o $@ $<
  699. +   g++ -c $(CFLAGS) -frename-registers -funroll-all-loops -fomit-frame-pointer  -march=native -msse2 -msse3  -ffast-math -O3 -o $@ $<
  700.  
  701.  bitcoin: $(OBJS) obj/ui.o obj/uibase.o
  702.     g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
  703.  
  704. -
  705.  obj/nogui/%.o: %.cpp $(HEADERS)
  706.     g++ -c $(CFLAGS) -o $@ $<
  707.  
  708.  bitcoind: $(OBJS:obj/%=obj/nogui/%)
  709.     g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
  710.  
  711. +test: cryptopp/obj/sha.o cryptopp/obj/sha256.o test.cpp
  712. +     g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
  713. +
  714.  
  715.  clean:
  716.     -rm -f obj/*.o
  717. diff --git a/test.cpp b/test.cpp
  718. new file mode 100755
  719. index 0000000..7cab332
  720. --- /dev/null
  721. +++ b/test.cpp
  722. @@ -0,0 +1,237 @@
  723. +// Copyright (c) 2009-2010 Satoshi Nakamoto
  724. +// Distributed under the MIT/X11 software license, see the accompanying
  725. +// file license.txt or http://www.opensource.org/licenses/mit-license.php.
  726. +#include <assert.h>
  727. +#include <openssl/ecdsa.h>
  728. +#include <openssl/evp.h>
  729. +#include <openssl/rand.h>
  730. +#include <openssl/sha.h>
  731. +#include <openssl/ripemd.h>
  732. +#include <db_cxx.h>
  733. +#include <stdio.h>
  734. +#include <stdlib.h>
  735. +#include <math.h>
  736. +#include <limits.h>
  737. +#include <float.h>
  738. +#include <assert.h>
  739. +#include <memory>
  740. +#include <iostream>
  741. +#include <sstream>
  742. +#include <string>
  743. +#include <vector>
  744. +#include <list>
  745. +#include <deque>
  746. +#include <map>
  747. +#include <set>
  748. +#include <algorithm>
  749. +#include <numeric>
  750. +#include <boost/foreach.hpp>
  751. +#include <boost/lexical_cast.hpp>
  752. +#include <boost/tuple/tuple.hpp>
  753. +#include <boost/fusion/container/vector.hpp>
  754. +#include <boost/tuple/tuple_comparison.hpp>
  755. +#include <boost/tuple/tuple_io.hpp>
  756. +#include <boost/array.hpp>
  757. +#include <boost/bind.hpp>
  758. +#include <boost/function.hpp>
  759. +#include <boost/filesystem.hpp>
  760. +#include <boost/filesystem/fstream.hpp>
  761. +#include <boost/algorithm/string.hpp>
  762. +#include <boost/interprocess/sync/interprocess_mutex.hpp>
  763. +#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
  764. +#include <boost/date_time/gregorian/gregorian_types.hpp>
  765. +#include <boost/date_time/posix_time/posix_time_types.hpp>
  766. +#include <sys/resource.h>
  767. +#include <sys/time.h>
  768. +using namespace std;
  769. +using namespace boost;
  770. +#include "cryptopp/sha.h"
  771. +#include "strlcpy.h"
  772. +#include "serialize.h"
  773. +#include "uint256.h"
  774. +#include "bignum.h"
  775. +
  776. +#undef printf
  777. +   template <size_t nBytes, typename T>
  778. +T* alignup(T* p)
  779. +{
  780. +   union
  781. +   {  
  782. +       T* ptr;
  783. +       size_t n;
  784. +   } u;
  785. +   u.ptr = p;
  786. +   u.n = (u.n + (nBytes-1)) & ~(nBytes-1);
  787. +   return u.ptr;
  788. +}
  789. +
  790. +int FormatHashBlocks(void* pbuffer, unsigned int len)
  791. +{
  792. +   unsigned char* pdata = (unsigned char*)pbuffer;
  793. +   unsigned int blocks = 1 + ((len + 8) / 64);
  794. +   unsigned char* pend = pdata + 64 * blocks;
  795. +   memset(pdata + len, 0, 64 * blocks - len);
  796. +   pdata[len] = 0x80;
  797. +   unsigned int bits = len * 8;
  798. +   pend[-1] = (bits >> 0) & 0xff;
  799. +   pend[-2] = (bits >> 8) & 0xff;
  800. +   pend[-3] = (bits >> 16) & 0xff;
  801. +   pend[-4] = (bits >> 24) & 0xff;
  802. +   return blocks;
  803. +}
  804. +
  805. +using CryptoPP::ByteReverse;
  806. +static int detectlittleendian = 1;
  807. +
  808. +#define NPAR 32
  809. +
  810. +extern void Double_BlockSHA256(const void* pin, void* pout, const void *pinit, unsigned int hash[8][NPAR], const void *init2);
  811. +
  812. +using CryptoPP::ByteReverse;
  813. +
  814. +static const unsigned int pSHA256InitState[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
  815. +
  816. +inline void SHA256Transform(void* pstate, void* pinput, const void* pinit)
  817. +{
  818. +   memcpy(pstate, pinit, 32);
  819. +   CryptoPP::SHA256::Transform((CryptoPP::word32*)pstate, (CryptoPP::word32*)pinput);
  820. +}
  821. +
  822. +void BitcoinTester(char *filename)
  823. +{
  824. +   printf("SHA256 test started\n");
  825. +
  826. +   struct tmpworkspace
  827. +   {
  828. +       struct unnamed2
  829. +       {
  830. +           int nVersion;
  831. +           uint256 hashPrevBlock;
  832. +           uint256 hashMerkleRoot;
  833. +           unsigned int nTime;
  834. +           unsigned int nBits;
  835. +           unsigned int nNonce;
  836. +       }
  837. +       block;
  838. +       unsigned char pchPadding0[64];
  839. +       uint256 hash1;
  840. +       unsigned char pchPadding1[64];
  841. +   };
  842. +   char tmpbuf[sizeof(tmpworkspace)+16];
  843. +   tmpworkspace& tmp = *(tmpworkspace*)alignup<16>(tmpbuf);
  844. +
  845. +
  846. +   char line[180];
  847. +   ifstream fin(filename);
  848. +   char *p;
  849. +   unsigned long int totalhashes= 0;
  850. +   unsigned long int found = 0;
  851. +   clock_t start, end;
  852. +   unsigned long int cpu_time_used;
  853. +   unsigned int tnonce;
  854. +   start = clock();
  855. +
  856. +   while( fin.getline(line, 180))
  857. +   {
  858. +       string in(line);
  859. +       //printf("%s\n", in.c_str());
  860. +       tmp.block.nVersion       = strtol(in.substr(0,8).c_str(), &p, 16);
  861. +       tmp.block.hashPrevBlock.SetHex(in.substr(8,64));
  862. +       tmp.block.hashMerkleRoot.SetHex(in.substr(64+8,64));
  863. +       tmp.block.nTime          = strtol(in.substr(128+8,8).c_str(), &p, 16);
  864. +       tmp.block.nBits          = strtol(in.substr(128+16,8).c_str(), &p, 16);
  865. +       tnonce = strtol(in.substr(128+24,8).c_str(), &p, 16);
  866. +       tmp.block.nNonce         = tnonce;
  867. +
  868. +       unsigned int nBlocks0 = FormatHashBlocks(&tmp.block, sizeof(tmp.block));
  869. +       unsigned int nBlocks1 = FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
  870. +
  871. +       // Byte swap all the input buffer
  872. +       for (int i = 0; i < sizeof(tmp)/4; i++)
  873. +           ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);
  874. +
  875. +       // Precalc the first half of the first hash, which stays constant
  876. +       uint256 midstatebuf[2];
  877. +       uint256& midstate = *alignup<16>(midstatebuf);
  878. +       SHA256Transform(&midstate, &tmp.block, pSHA256InitState);
  879. +
  880. +
  881. +       uint256 hashTarget = CBigNum().SetCompact(ByteReverse(tmp.block.nBits)).getuint256();
  882. +       //  printf("target %s\n", hashTarget.GetHex().c_str());
  883. +       uint256 hash;
  884. +       uint256 hashbuf[2];
  885. +       uint256& refhash = *alignup<16>(hashbuf);
  886. +
  887. +       unsigned int thash[8][NPAR];
  888. +       int done = 0;
  889. +       unsigned int i, j;
  890. +
  891. +       /* reference */
  892. +       SHA256Transform(&tmp.hash1, (char*)&tmp.block + 64, &midstate);
  893. +       SHA256Transform(&refhash, &tmp.hash1, pSHA256InitState);
  894. +       for (int i = 0; i < sizeof(refhash)/4; i++)
  895. +           ((unsigned int*)&refhash)[i] = ByteReverse(((unsigned int*)&refhash)[i]);
  896. +
  897. +       //printf("reference nonce %08x:\n%s\n\n", tnonce, refhash.GetHex().c_str());
  898. +
  899. +       tmp.block.nNonce = ByteReverse(tnonce) & 0xfffff000;
  900. +
  901. +
  902. +       for(;;)
  903. +       {
  904. +
  905. +           Double_BlockSHA256((char*)&tmp.block + 64, &tmp.hash1, &midstate, thash, pSHA256InitState);
  906. +
  907. +           for(i = 0; i<NPAR; i++) {
  908. +               /* fast hash checking */
  909. +               if(thash[7][i] == 0) {
  910. +           //      printf("found something... ");
  911. +
  912. +                   for(j = 0; j<8; j++) ((unsigned int *)&hash)[j] = ByteReverse((unsigned int)thash[j][i]);
  913. +               //  printf("%s\n", hash.GetHex().c_str());
  914. +
  915. +                   if (hash <= hashTarget)
  916. +                   {
  917. +                       found++;
  918. +                       if(tnonce == ByteReverse(tmp.block.nNonce + i) ) {
  919. +                           if(hash == refhash) {
  920. +                               printf("\r%lu", found);
  921. +                               totalhashes += NPAR;
  922. +                               done = 1;
  923. +                           } else {
  924. +                               printf("Hashes do not match!\n");
  925. +                           }
  926. +                       } else {
  927. +                           printf("nonce does not match. %08x != %08x\n", tnonce, ByteReverse(tmp.block.nNonce + i));
  928. +                       }
  929. +                       break;
  930. +                   }
  931. +               }
  932. +           }
  933. +           if(done) break;
  934. +
  935. +           tmp.block.nNonce+=NPAR;
  936. +           totalhashes += NPAR;
  937. +           if(tmp.block.nNonce == 0) {
  938. +               printf("ERROR: Hash not found for:\n%s\n", in.c_str());
  939. +               return;
  940. +           }
  941. +       }
  942. +   }
  943. +   printf("\n");
  944. +   end = clock();
  945. +   cpu_time_used += (unsigned int)(end - start);
  946. +   cpu_time_used /= ((CLOCKS_PER_SEC)/1000);
  947. +   printf("found solutions = %lu\n", found);
  948. +   printf("total hashes = %lu\n", totalhashes);
  949. +   printf("total time = %lu ms\n", cpu_time_used);
  950. +   printf("average speed: %lu khash/s\n", (totalhashes)/cpu_time_used);
  951. +}
  952. +
  953. +int main(int argc, char* argv[]) {
  954. +   if(argc == 2) {
  955. +       BitcoinTester(argv[1]);
  956. +   } else
  957. +       printf("Missing filename!\n");
  958. +   return 0;
  959. +}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement