Advertisement
Guest User

Untitled

a guest
Jul 29th, 2014
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.40 KB | None | 0 0
  1. /******************************
  2. doom.cu:
  3. *******************************/
  4. extern "C"
  5. {
  6.  
  7. #include "sph/sph_luffa.h"
  8.  
  9. #include "miner.h"
  10. }
  11.  
  12. // aus cpu-miner.c
  13. extern int device_map[8];
  14.  
  15. extern void doom_luffa512_cpu_init(int thr_id, int threads);
  16. extern void doom_luffa512_cpu_setBlock_80(int thr_id, void *pdata, uint32_t *ptarget);
  17. extern void doom_luffa512_cpu_hash_80(int thr_id, int threads, uint32_t startNounce, uint32_t *foundNonce, int order);
  18.  
  19. inline void doomhash(void *state, const void *input)
  20. {
  21.     // luffa512
  22.    
  23.     sph_luffa512_context ctx_luffa;
  24.    
  25.  
  26.     uint32_t hash[16];
  27.  
  28.     sph_luffa512_init(&ctx_luffa);
  29.     sph_luffa512 (&ctx_luffa, input, 80);
  30.     sph_luffa512_close(&ctx_luffa, (void*) hash);
  31.  
  32.     memcpy(state, hash, 32);
  33. }
  34.  
  35.  
  36. extern bool opt_benchmark;
  37.  
  38. extern "C" int scanhash_doom(int thr_id, uint32_t *pdata,
  39.     const uint32_t *ptarget, uint32_t max_nonce,
  40.     unsigned long *hashes_done)
  41. {
  42.     const uint32_t first_nonce = pdata[19];
  43.  
  44.     if (opt_benchmark)
  45.         ((uint32_t*)ptarget)[7] = 0x0000ff;
  46.  
  47.     const uint32_t Htarg = ptarget[7];
  48.  
  49.     const int throughput = 256*256*8*8;
  50.  
  51.     static bool init[8] = {0,0,0,0,0,0,0,0};
  52.     if (!init[thr_id])
  53.     {
  54.         cudaSetDevice(device_map[thr_id]);
  55.  
  56.         // Konstanten kopieren, Speicher belegen
  57.         doom_luffa512_cpu_init(thr_id, throughput);
  58.  
  59.         init[thr_id] = true;
  60.     }
  61.  
  62.     uint32_t endiandata[20];
  63.     for (int k=0; k < 20; k++)
  64.         be32enc(&endiandata[k], ((uint32_t*)pdata)[k]);
  65.  
  66.     doom_luffa512_cpu_setBlock_80(thr_id, (void*)endiandata, (uint32_t *)ptarget);
  67.  
  68.     do {
  69.         int order = 0;
  70.  
  71.         uint32_t foundNonce;
  72.  
  73.         // erstes luffa512 Hash mit CUDA
  74.         doom_luffa512_cpu_hash_80(thr_id, throughput, pdata[19], &foundNonce, order++);
  75.  
  76.         if  (foundNonce != 0xffffffff)
  77.         {
  78.             uint32_t vhash64[8];
  79.             be32enc(&endiandata[19], foundNonce);
  80.             doomhash(vhash64, endiandata);
  81.  
  82.             if( (vhash64[7]<=Htarg) && fulltest(vhash64, ptarget) ) {
  83.                
  84.                 pdata[19] = foundNonce;
  85.                 *hashes_done = foundNonce - first_nonce + 1;
  86.                 return 1;
  87.             } else {
  88.                 applog(LOG_INFO, "GPU #%d: result for nonce $%08X does not validate on CPU!", thr_id, foundNonce);
  89.             }
  90.         }
  91.  
  92.         pdata[19] += throughput;
  93.  
  94.     } while (pdata[19] < max_nonce && !work_restart[thr_id].restart);
  95.  
  96.     *hashes_done = pdata[19] - first_nonce + 1;
  97.     return 0;
  98. }
  99.  
  100. /******************************
  101. doom_luffa512.cu:
  102. *******************************/
  103.  
  104. // aus heavy.cu
  105. extern cudaError_t MyStreamSynchronize(cudaStream_t stream, int situation, int thr_id);
  106.  
  107. typedef unsigned char BitSequence;
  108.  
  109. typedef unsigned char uint8_t;
  110. typedef unsigned int uint32_t;
  111. typedef unsigned long long uint64_t;
  112.  
  113. static uint32_t *d_target[8];
  114. static uint32_t *d_resultNonce[8];
  115.  
  116. __constant__ uint64_t c_PaddedMessage80[16]; // padded message (80 bytes + padding)
  117. typedef struct {
  118.     uint32_t buffer[8]; /* Buffer to be hashed */
  119.     uint32_t chainv[40];   /* Chaining values */
  120. } hashState;
  121.  
  122. static __device__ uint64_t REPLACE_HIWORD(const uint64_t &x, const uint32_t &y) {
  123.     return (x & 0xFFFFFFFFULL) | (((uint64_t)y) << 32ULL);
  124. }
  125.  
  126. // Endian Drehung für 32 Bit Typen
  127.  
  128. static __device__ uint32_t cuda_swab32(uint32_t x)
  129. {
  130.     return __byte_perm(x, 0, 0x0123);
  131. }
  132.  
  133. static __device__ __forceinline__ uint32_t BYTES_SWAP32(uint32_t x)
  134. {
  135.     return __byte_perm(x, x, 0x0123);
  136. }
  137.  
  138. #define MULT2(a,j)\
  139.     tmp = a[7+(8*j)];\
  140.     a[7+(8*j)] = a[6+(8*j)];\
  141.     a[6+(8*j)] = a[5+(8*j)];\
  142.     a[5+(8*j)] = a[4+(8*j)];\
  143.     a[4+(8*j)] = a[3+(8*j)] ^ tmp;\
  144.     a[3+(8*j)] = a[2+(8*j)] ^ tmp;\
  145.     a[2+(8*j)] = a[1+(8*j)];\
  146.     a[1+(8*j)] = a[0+(8*j)] ^ tmp;\
  147.     a[0+(8*j)] = tmp;
  148.  
  149. #define TWEAK(a0,a1,a2,a3,j)\
  150.     a0 = (a0<<(j))|(a0>>(32-j));\
  151.     a1 = (a1<<(j))|(a1>>(32-j));\
  152.     a2 = (a2<<(j))|(a2>>(32-j));\
  153.     a3 = (a3<<(j))|(a3>>(32-j));
  154.  
  155. #define STEP(c0,c1)\
  156.     SUBCRUMB(chainv[0],chainv[1],chainv[2],chainv[3],tmp);\
  157.     SUBCRUMB(chainv[5],chainv[6],chainv[7],chainv[4],tmp);\
  158.     MIXWORD(chainv[0],chainv[4]);\
  159.     MIXWORD(chainv[1],chainv[5]);\
  160.     MIXWORD(chainv[2],chainv[6]);\
  161.     MIXWORD(chainv[3],chainv[7]);\
  162.     ADD_CONSTANT(chainv[0],chainv[4],c0,c1);
  163.  
  164. #define SUBCRUMB(a0,a1,a2,a3,a4)\
  165.     asm( \
  166.         "mov.b32    %4, %0;\n\t" \
  167.         "or.b32     %0, %0, %1;\n\t" \
  168.         "xor.b32    %2, %2, %3;\n\t" \
  169.         "not.b32    %1, %1;\n\t" \
  170.         "xor.b32    %0, %0, %3;\n\t" \
  171.         "and.b32    %3, %3, %4;\n\t" \
  172.         "xor.b32    %1, %1, %3;\n\t" \
  173.         "xor.b32    %3, %3, %2;\n\t" \
  174.         "and.b32    %2, %2, %0;\n\t" \
  175.         "not.b32    %0, %0;\n\t" \
  176.         "xor.b32    %2, %2, %1;\n\t" \
  177.         "or.b32     %1, %1, %3;\n\t" \
  178.         "xor.b32    %4, %4, %1;\n\t" \
  179.         "xor.b32    %3, %3, %2;\n\t" \
  180.         "and.b32    %2, %2, %1;\n\t" \
  181.         "xor.b32    %1, %1, %0;\n\t" \
  182.         "mov.b32    %0, %4;\n\t" \
  183.         :: "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4))
  184.  
  185. #define MIXWORD(a0,a4)\
  186.     a4 ^= a0;\
  187.     a0  = (a0<<2) | (a0>>(30));\
  188.     a0 ^= a4;\
  189.     a4  = (a4<<14) | (a4>>(18));\
  190.     a4 ^= a0;\
  191.     a0  = (a0<<10) | (a0>>(22));\
  192.     a0 ^= a4;\
  193.     a4  = (a4<<1) | (a4>>(31));
  194.  
  195. #define ADD_CONSTANT(a0,b0,c0,c1)\
  196.     a0 ^= c0;\
  197.     b0 ^= c1;
  198.  
  199. /* initial values of chaining variables */
  200. __constant__ uint32_t c_IV[40];
  201. const uint32_t h2_IV[40] = {
  202.     0x6d251e69,0x44b051e0,0x4eaa6fb4,0xdbf78465,
  203.     0x6e292011,0x90152df4,0xee058139,0xdef610bb,
  204.     0xc3b44b95,0xd9d2f256,0x70eee9a0,0xde099fa3,
  205.     0x5d9b0557,0x8fc944b3,0xcf1ccf0e,0x746cd581,
  206.     0xf7efc89d,0x5dba5781,0x04016ce5,0xad659c05,
  207.     0x0306194f,0x666d1836,0x24aa230a,0x8b264ae7,
  208.     0x858075d5,0x36d79cce,0xe571f7d7,0x204b1f67,
  209.     0x35870c6a,0x57e9e923,0x14bcb808,0x7cde72ce,
  210.     0x6c68e9be,0x5ec41e22,0xc825b7c7,0xaffb4363,
  211.     0xf5df3999,0x0fc688f1,0xb07224cc,0x03e86cea};
  212.  
  213. __constant__ uint32_t c_doom_CNS[80];
  214. uint32_t h2_doom_CNS[80] = {
  215.     0x303994a6,0xe0337818,0xc0e65299,0x441ba90d,
  216.     0x6cc33a12,0x7f34d442,0xdc56983e,0x9389217f,
  217.     0x1e00108f,0xe5a8bce6,0x7800423d,0x5274baf4,
  218.     0x8f5b7882,0x26889ba7,0x96e1db12,0x9a226e9d,
  219.     0xb6de10ed,0x01685f3d,0x70f47aae,0x05a17cf4,
  220.     0x0707a3d4,0xbd09caca,0x1c1e8f51,0xf4272b28,
  221.     0x707a3d45,0x144ae5cc,0xaeb28562,0xfaa7ae2b,
  222.     0xbaca1589,0x2e48f1c1,0x40a46f3e,0xb923c704,
  223.     0xfc20d9d2,0xe25e72c1,0x34552e25,0xe623bb72,
  224.     0x7ad8818f,0x5c58a4a4,0x8438764a,0x1e38e2e7,
  225.     0xbb6de032,0x78e38b9d,0xedb780c8,0x27586719,
  226.     0xd9847356,0x36eda57f,0xa2c78434,0x703aace7,
  227.     0xb213afa5,0xe028c9bf,0xc84ebe95,0x44756f91,
  228.     0x4e608a22,0x7e8fce32,0x56d858fe,0x956548be,
  229.     0x343b138f,0xfe191be2,0xd0ec4e3d,0x3cb226e5,
  230.     0x2ceb4882,0x5944a28e,0xb3ad2208,0xa1c4c355,
  231.     0xf0d2e9e3,0x5090d577,0xac11d7fa,0x2d1925ab,
  232.     0x1bcb66f2,0xb46496ac,0x6f2d9bc9,0xd1925ab0,
  233.     0x78602649,0x29131ab6,0x8edae952,0x0fc053c3,
  234.     0x3b6ba548,0x3f014f0c,0xedae9520,0xfc053c31};
  235.  
  236.  
  237. /***************************************************/
  238. __device__ __forceinline__ void rnd512(hashState *state)
  239. {
  240.     int i,j;
  241.     uint32_t t[40];
  242.     uint32_t chainv[8];
  243.     uint32_t tmp;
  244.  
  245. #pragma unroll 8
  246.     for(i=0;i<8;i++) {
  247.         t[i]=0;
  248. #pragma unroll 5
  249.         for(j=0;j<5;j++) {
  250.             t[i] ^= state->chainv[i+8*j];
  251.         }
  252.     }
  253.  
  254.     MULT2(t, 0);
  255.  
  256. #pragma unroll 5
  257.     for(j=0;j<5;j++) {
  258. #pragma unroll 8
  259.         for(i=0;i<8;i++) {
  260.             state->chainv[i+8*j] ^= t[i];
  261.         }
  262.     }
  263.  
  264. #pragma unroll 5
  265.     for(j=0;j<5;j++) {
  266. #pragma unroll 8
  267.         for(i=0;i<8;i++) {
  268.             t[i+8*j] = state->chainv[i+8*j];
  269.         }
  270.     }
  271.  
  272. #pragma unroll 5
  273.     for(j=0;j<5;j++) {
  274.         MULT2(state->chainv, j);
  275.     }
  276.  
  277. #pragma unroll 5
  278.     for(j=0;j<5;j++) {
  279. #pragma unroll 8
  280.         for(i=0;i<8;i++) {
  281.             state->chainv[8*j+i] ^= t[8*((j+1)%5)+i];
  282.         }
  283.     }
  284.  
  285. #pragma unroll 5
  286.     for(j=0;j<5;j++) {
  287. #pragma unroll 8
  288.         for(i=0;i<8;i++) {
  289.             t[i+8*j] = state->chainv[i+8*j];
  290.         }
  291.     }
  292.  
  293. #pragma unroll 5
  294.     for(j=0;j<5;j++) {
  295.         MULT2(state->chainv, j);
  296.     }
  297.  
  298. #pragma unroll 5
  299.     for(j=0;j<5;j++) {
  300. #pragma unroll 8
  301.         for(i=0;i<8;i++) {
  302.             state->chainv[8*j+i] ^= t[8*((j+4)%5)+i];
  303.         }
  304.     }
  305.  
  306. #pragma unroll 5
  307.     for(j=0;j<5;j++) {
  308. #pragma unroll 8
  309.         for(i=0;i<8;i++) {
  310.             state->chainv[i+8*j] ^= state->buffer[i];
  311.         }
  312.         MULT2(state->buffer, 0);
  313.     }
  314.  
  315. #pragma unroll 8
  316.     for(i=0;i<8;i++) {
  317.         chainv[i] = state->chainv[i];
  318.     }
  319.  
  320. #pragma unroll 8
  321.     for(i=0;i<8;i++) {
  322.         STEP(c_doom_CNS[(2*i)],c_doom_CNS[(2*i)+1]);
  323.     }
  324.  
  325. #pragma unroll 8
  326.     for(i=0;i<8;i++) {
  327.         state->chainv[i] = chainv[i];
  328.         chainv[i] = state->chainv[i+8];
  329.     }
  330.  
  331.     TWEAK(chainv[4],chainv[5],chainv[6],chainv[7],1);
  332.  
  333. #pragma unroll 8
  334.     for(i=0;i<8;i++) {
  335.         STEP(c_doom_CNS[(2*i)+16],c_doom_CNS[(2*i)+16+1]);
  336.     }
  337.  
  338. #pragma unroll 8
  339.     for(i=0;i<8;i++) {
  340.         state->chainv[i+8] = chainv[i];
  341.         chainv[i] = state->chainv[i+16];
  342.     }
  343.  
  344.     TWEAK(chainv[4],chainv[5],chainv[6],chainv[7],2);
  345.  
  346. #pragma unroll 8
  347.     for(i=0;i<8;i++) {
  348.         STEP(c_doom_CNS[(2*i)+32],c_doom_CNS[(2*i)+32+1]);
  349.     }
  350.  
  351. #pragma unroll 8
  352.     for(i=0;i<8;i++) {
  353.         state->chainv[i+16] = chainv[i];
  354.         chainv[i] = state->chainv[i+24];
  355.     }
  356.  
  357.     TWEAK(chainv[4],chainv[5],chainv[6],chainv[7],3);
  358.  
  359. #pragma unroll 8
  360.     for(i=0;i<8;i++) {
  361.         STEP(c_doom_CNS[(2*i)+48],c_doom_CNS[(2*i)+48+1]);
  362.     }
  363.  
  364. #pragma unroll 8
  365.     for(i=0;i<8;i++) {
  366.         state->chainv[i+24] = chainv[i];
  367.         chainv[i] = state->chainv[i+32];
  368.     }
  369.  
  370.     TWEAK(chainv[4],chainv[5],chainv[6],chainv[7],4);
  371.  
  372. #pragma unroll 8
  373.     for(i=0;i<8;i++) {
  374.         STEP(c_doom_CNS[(2*i)+64],c_doom_CNS[(2*i)+64+1]);
  375.     }
  376.  
  377. #pragma unroll 8
  378.     for(i=0;i<8;i++) {
  379.         state->chainv[i+32] = chainv[i];
  380.     }
  381. }
  382.  
  383.  
  384. __device__ __forceinline__ void Update512(hashState *state, const BitSequence *data)
  385. {
  386. #pragma unroll 8
  387.     for(int i=0;i<8;i++) state->buffer[i] = BYTES_SWAP32(((uint32_t*)data)[i]);
  388.     rnd512(state);
  389.  
  390. #pragma unroll 8
  391.     for(int i=0;i<8;i++) state->buffer[i] = BYTES_SWAP32(((uint32_t*)(data+32))[i]);
  392.     rnd512(state);
  393. #pragma unroll 4
  394.     for(int i=0;i<4;i++) state->buffer[i] = BYTES_SWAP32(((uint32_t*)(data+64))[i]);
  395. }
  396.  
  397.  
  398. /***************************************************/
  399. __device__ __forceinline__ void finalization512(hashState *state, uint32_t *b)
  400. {
  401.     int i,j;
  402.  
  403.     state->buffer[4] = 0x80000000;
  404. #pragma unroll 3
  405.     for(int i=5;i<8;i++) state->buffer[i] = 0;
  406.     rnd512(state);
  407.  
  408.     /*---- blank round with m=0 ----*/
  409. #pragma unroll 8
  410.     for(i=0;i<8;i++) state->buffer[i] =0;
  411.     rnd512(state);
  412.  
  413. #pragma unroll 8
  414.     for(i=0;i<8;i++) {
  415.         b[i] = 0;
  416. #pragma unroll 5
  417.         for(j=0;j<5;j++) {
  418.             b[i] ^= state->chainv[i+8*j];
  419.         }
  420.         b[i] = BYTES_SWAP32((b[i]));
  421.     }
  422.  
  423. #pragma unroll 8
  424.     for(i=0;i<8;i++) state->buffer[i]=0;
  425.     rnd512(state);
  426.  
  427. #pragma unroll 8
  428.     for(i=0;i<8;i++) {
  429.         b[8+i] = 0;
  430. #pragma unroll 5
  431.         for(j=0;j<5;j++) {
  432.             b[8+i] ^= state->chainv[i+8*j];
  433.         }
  434.         b[8+i] = BYTES_SWAP32((b[8+i]));
  435.     }
  436. }
  437.  
  438.  
  439. /***************************************************/
  440. // Die Hash-Funktion
  441. __global__ void doom_luffa512_gpu_hash_80(int threads, uint32_t startNounce, uint32_t *d_target, uint32_t *resNonce)
  442. {
  443.     int thread = (blockDim.x * blockIdx.x + threadIdx.x);
  444.     if (thread < threads)
  445.     {
  446.         uint32_t nounce = startNounce + thread;
  447.         uint32_t hash[16];
  448.         union {
  449.             uint64_t buf64[16];
  450.             uint32_t buf32[32];
  451.         } buff;
  452. #pragma unroll 16
  453.         for (int i=0; i < 16; ++i) buff.buf64[i] = c_PaddedMessage80[i];
  454.  
  455.         // die Nounce durch die thread-spezifische ersetzen
  456.         buff.buf64[9] = REPLACE_HIWORD(buff.buf64[9], cuda_swab32(nounce));
  457.  
  458.  
  459.         hashState state;
  460. #pragma unroll 40
  461.         for(int i=0;i<40;i++) state.chainv[i] = c_IV[i];
  462. #pragma unroll 8
  463.         for(int i=0;i<8;i++) state.buffer[i] = 0;
  464.         Update512(&state, (BitSequence*)buff.buf32);
  465.         finalization512(&state, (uint32_t*)hash);
  466.  
  467.         int position = -1;
  468.         bool rc = true;
  469.  
  470. #pragma unroll 8
  471.         for (int i = 7; i >= 0; i--) {
  472.             if (hash[i] > d_target[i]) {
  473.                 if(position < i) {
  474.                     position = i;
  475.                     rc = false;
  476.                 }
  477.              }
  478.              if (hash[i] < d_target[i]) {
  479.                 if(position < i) {
  480.                     position = i;
  481.                     rc = true;
  482.                 }
  483.              }
  484.         }
  485.  
  486.         if(rc == true)
  487.             if(resNonce[0] > nounce)
  488.                 resNonce[0] = nounce;
  489.     }
  490. }
  491. // Setup-Funktionen
  492. __host__ void doom_luffa512_cpu_init(int thr_id, int threads)
  493. {
  494.     cudaMalloc(&d_resultNonce[thr_id], sizeof(uint32_t));
  495.     cudaMalloc(&d_target[thr_id], 8 * sizeof(uint32_t));
  496.     cudaMemcpyToSymbol( c_IV, h2_IV, sizeof(h2_IV), 0, cudaMemcpyHostToDevice );
  497.     cudaMemcpyToSymbol( c_doom_CNS, h2_doom_CNS, sizeof(h2_doom_CNS), 0, cudaMemcpyHostToDevice );
  498. }
  499.  
  500. __host__ void doom_luffa512_cpu_hash_80(int thr_id, int threads, uint32_t startNounce, uint32_t *resnonce, int order)
  501. {
  502.     const int threadsperblock = 256;
  503.  
  504.     // berechne wie viele Thread Blocks wir brauchen
  505.     dim3 grid((threads + threadsperblock-1)/threadsperblock);
  506.     dim3 block(threadsperblock);
  507.  
  508.     // Größe des dynamischen Shared Memory Bereichs
  509.     size_t shared_size = 0;
  510.  
  511.     cudaMemset(d_resultNonce[thr_id], 0xFF, sizeof(uint32_t));
  512.  
  513.     doom_luffa512_gpu_hash_80<<<grid, block, shared_size>>>(threads, startNounce, d_target[thr_id], d_resultNonce[thr_id]);
  514.     MyStreamSynchronize(NULL, order, thr_id);
  515.  
  516.     cudaMemcpy(resnonce, d_resultNonce[thr_id], sizeof(uint32_t), cudaMemcpyDeviceToHost);
  517. }
  518.  
  519. __host__ void doom_luffa512_cpu_setBlock_80(int thr_id, void *pdata, uint32_t *ptarget)
  520. {
  521.     // Message mit Padding bereitstellen
  522.     // lediglich die korrekte Nonce ist noch ab Byte 76 einzusetzen.
  523.     unsigned char PaddedMessage[128];
  524.     memcpy(PaddedMessage, pdata, 80);
  525.     memset(PaddedMessage+80, 0, 48);
  526.     PaddedMessage[80] = 0x80;
  527.     PaddedMessage[111] = 1;
  528.     PaddedMessage[126] = 0x02;
  529.     PaddedMessage[127] = 0x80;
  530.  
  531.     // die Message zur Berechnung auf der GPU
  532.     cudaMemcpyToSymbol( c_PaddedMessage80, PaddedMessage, 16*sizeof(uint64_t), 0, cudaMemcpyHostToDevice);
  533.  
  534.     cudaMemcpy(d_target[thr_id], ptarget, 8*sizeof(uint32_t), cudaMemcpyHostToDevice);
  535. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement