Esempio n. 1
0
void protoshares_process_8(minerProtosharesBlock_t* block)
{
	// generate mid hash using sha256 (header hash)
	uint8 midHash[32];
	sha256_ctx c256;
	sha256_init(&c256);
	sha256_update(&c256, (unsigned char*)block, 80);
	sha256_final(&c256, midHash);
	sha256_init(&c256);
	sha256_update(&c256, (unsigned char*)midHash, 32);
	sha256_final(&c256, midHash);
	// init collision map
	if( __collisionMap == NULL )
		__collisionMap = (uint32*)malloc(sizeof(uint32)*COLLISION_TABLE_SIZE);
	uint32* collisionIndices = __collisionMap;
	memset(collisionIndices, 0x00, sizeof(uint32)*COLLISION_TABLE_SIZE);
	// start search
	// uint8 midHash[64];
	uint8 tempHash[32+4];
	sha512_ctx c512;
	uint64 resultHashStorage[8*CACHED_HASHES];
	memcpy(tempHash+4, midHash, 32);
	for(uint32 n=0; n<MAX_MOMENTUM_NONCE; n += BIRTHDAYS_PER_HASH * CACHED_HASHES)
	{
		if( block->height != monitorCurrentBlockHeight )
			break;
		for(uint32 m=0; m<CACHED_HASHES; m++)
		{
			sha512_init(&c512);
			*(uint32*)tempHash = n+m*8;
			sha512_update_final(&c512, tempHash, 32+4, (unsigned char*)(resultHashStorage+8*m));
		}
		for(uint32 m=0; m<CACHED_HASHES; m++)
		{
			uint64* resultHash = resultHashStorage + 8*m;
			uint32 i = n + m*8;

			for(uint32 f=0; f<8; f++)
			{
				uint64 birthday = resultHash[f] >> (64ULL-SEARCH_SPACE_BITS);
				uint32 collisionKey = (uint32)((birthday>>18) & COLLISION_KEY_MASK);
				birthday %= COLLISION_TABLE_SIZE;
				if( collisionIndices[birthday] )
				{
					if( ((collisionIndices[birthday]&COLLISION_KEY_MASK) != collisionKey) || protoshares_revalidateCollision(block, midHash, collisionIndices[birthday]&~COLLISION_KEY_MASK, i+f) == false )
					{
						// invalid collision -> ignore
						
					}
				}
				collisionIndices[birthday] = i+f | collisionKey; // we have 6 bits available for validation
			}
		}
	}
}
void ProtoshareOpenCL::protoshare_process(minerProtosharesBlock_t* block)
{

#ifdef MEASURE_TIME
    uint32 overhead = getTimeMilliseconds();
#endif

    block->nonce = 0;
    uint32 target = *(uint32*)(block->targetShare + 28);
    // OpenCLDevice* device = OpenCLMain::getInstance().getDevice(device_num);

    uint32 midHash[8];
    // midHash = sha256(sha256(block))
    sha256_ctx c256;
    sha256_init(&c256);
    sha256_update(&c256, (unsigned char*)block, 80);
    sha256_final(&c256, (unsigned char*)midHash);

    sha256_init(&c256);
    sha256_update(&c256, (unsigned char*)midHash, 32);
    sha256_final(&c256, (unsigned char*)midHash);

    union { cl_ulong b64[16]; cl_uint b32[32]; } hash_state;
    hash_state.b32[0] = 0; // Reserved for nonce
    hash_state.b32[1] = midHash[0];
    hash_state.b32[2] = midHash[1];
    hash_state.b32[3] = midHash[2];
    hash_state.b32[4] = midHash[3];
    hash_state.b32[5] = midHash[4];
    hash_state.b32[6] = midHash[5];
    hash_state.b32[7] = midHash[6];
    hash_state.b32[8] = midHash[7];
    hash_state.b32[9] = 0x80; // High 1 bit to mark end of input

    // Swap the non-zero b64's except the first (so we can mix in the nonce later)
    for (uint8 i = 1; i < 5; ++i) { hash_state.b64[i] = SWAP64(hash_state.b64[i]); }


#ifdef MEASURE_TIME
    printf("Hashing...\n");
    uint32 begin = getTimeMilliseconds();
#endif


    // Calculate all hashes
    kernel_hash->resetArgs();

    kernel_hash->addScalarULong(hash_state.b64[0]);
    kernel_hash->addScalarULong(hash_state.b64[1]);
    kernel_hash->addScalarULong(hash_state.b64[2]);
    kernel_hash->addScalarULong(hash_state.b64[3]);
    kernel_hash->addScalarULong(hash_state.b64[4]);
    kernel_hash->addGlobalArg(hash_list);
    kernel_hash->addGlobalArg(index_list);

    q->enqueueWriteBuffer(mid_hash, hash_state.b32, 10 * sizeof(cl_uint));

    q->enqueueKernel1D(kernel_hash, MAX_MOMENTUM_NONCE / BIRTHDAYS_PER_HASH / vect_type, wgs);

#ifdef MEASURE_TIME
    q->finish();
    printf("Resetting...\n");
    uint32 hash_end = getTimeMilliseconds();
#endif

    // Reset index list and find collisions
    cl_uint result_qty = 0;
    cl_uint result_a[256];
    cl_uint result_b[256];

    kernel_reset->resetArgs();
    kernel_reset->addGlobalArg(hash_list);
    kernel_reset->addGlobalArg(index_list);
    kernel_reset->addGlobalArg(nonce_a);
    kernel_reset->addGlobalArg(nonce_b);
    kernel_reset->addGlobalArg(nonce_qty);

    q->enqueueWriteBuffer(nonce_qty, &result_qty, sizeof(cl_uint));

    q->enqueueKernel1D(kernel_reset, (1 << buckets_log2), wgs);

    q->enqueueReadBuffer(nonce_a,   result_a,    sizeof(cl_uint) * 256);
    q->enqueueReadBuffer(nonce_b,   result_b,    sizeof(cl_uint) * 256);
    q->enqueueReadBuffer(nonce_qty, &result_qty, sizeof(cl_uint));

    q->finish();

#ifdef MEASURE_TIME
    uint32 end = getTimeMilliseconds();
    uint32 warmup_skips = 3;

    if (totalTableCount > warmup_skips) { // Allow some warmup time
        totalOverhead   += (begin - overhead);
        totalHashTime   += (hash_end - begin);
        totalResetTime  += (end - hash_end);
    }

    printf("Found %2d collisions in %4d ms (Hash: %4d ms, Reset: %4d ms, Overhead: %4d)\n",
           result_qty * 2,
           (end - begin),
           (hash_end - begin),
           (end - hash_end),
           (begin - overhead));

    if (totalTableCount > 0 && totalTableCount % 10 == 0) {
        printf("\nAVG TIMES - Total: %4d, Hash: %4d, Reset: %4d, Overhead: %4d\n\n",
               (totalHashTime + totalResetTime) / (totalTableCount - warmup_skips),
               totalHashTime   / (totalTableCount - warmup_skips),
               totalResetTime  / (totalTableCount - warmup_skips),
               totalOverhead   / (totalTableCount - warmup_skips));
    }
#endif

    for (uint32 i = 0; i < result_qty; i++) {
        protoshares_revalidateCollision(block, (uint8 *)midHash, result_a[i], result_b[i]);
    }

    totalTableCount++;
}
void protoshares_process_512(minerProtosharesBlock_t* block, uint32** __collisionMap) {

	uint8 midHash[32];
	sha256_ctx c256;
	sha256_init(&c256);
	sha256_update(&c256, (unsigned char*)block, 80);
	sha256_final(&c256, midHash);
	sha256_init(&c256);
	sha256_update(&c256, (unsigned char*)midHash, 32);
	sha256_final(&c256, midHash);
	// init collision map
	if( *__collisionMap == NULL ) {
		*__collisionMap = (uint32*)malloc(sizeof(uint32)*COLLISION_TABLE_SIZE);
	}
	uint32* collisionIndices = *__collisionMap;
	memset(collisionIndices, 0x00, sizeof(uint32)*COLLISION_TABLE_SIZE);

	uint8 inHash[32+4];
	uint64 outHash[BIRTHDAYS_PER_HASH];
	sha512_ctx c512;
	memcpy(inHash+4, midHash, 32);

	// count full loop time
	uint32 firstTick = GetTickCount();

	//for (uint32 n = 0; n < MAX_MOMENTUM_NONCE; n+= BIRTHDAYS_PER_HASH) {
	uint32 n = 0;
	while (1) {
		if( block->height != monitorCurrentBlockHeight )
			break;
		if( n >= MAX_MOMENTUM_NONCE ) {
			//only normal exits count
			uint32 lastTick = GetTickCount();
			looptime += (lastTick - firstTick);
			numloops++;
			break;
		}

		inline_sha512_init(&c512);
		*(uint32*)inHash = n;
//		sha512_update_final(&c512, inHash, 36, (unsigned char*)(outHash));
		inline_sha512_update(&c512, inHash, 36);
		inline_sha512_final(&c512, (unsigned char*)(outHash));
		//inline_sha512(inHash, 36, (unsigned char*)(outHash));

		// unroll the loop
#ifndef UNROLL_LOOPS
		for(uint32 f=0; f<BIRTHDAYS_PER_HASH; f++)
		{
			uint32 birthdayB = outHash[f] >> (64ULL-SEARCH_SPACE_BITS);
			uint32 collisionKey = (uint32)((birthdayB>>18) & COLLISION_KEY_MASK);
			uint32 birthday = birthdayB & (COLLISION_TABLE_SIZE-1);
			if( collisionIndices[birthday] && ((collisionIndices[birthday]&COLLISION_KEY_MASK) == collisionKey))
			{
				protoshares_revalidateCollision(block, midHash, collisionIndices[birthday]&~COLLISION_KEY_MASK, n+f);
			} else {
				collisionIndices[birthday] = n+f | collisionKey; // we have 6 bits available for validation
			}
		}
#else
		{
			uint64 birthdayB = outHash[0] >> (64ULL-SEARCH_SPACE_BITS);
			uint32 collisionKey = (uint32)((birthdayB>>18) & COLLISION_KEY_MASK);
			uint64 birthday = birthdayB & (COLLISION_TABLE_SIZE-1);
			if( collisionIndices[birthday] && ((collisionIndices[birthday]&COLLISION_KEY_MASK) == collisionKey))
			{
				protoshares_revalidateCollision(block, midHash, collisionIndices[birthday]&~COLLISION_KEY_MASK, n);
			} else {
				collisionIndices[birthday] = n | collisionKey; // we have 6 bits available for validation
			}
		}
		{
			uint64 birthdayB = outHash[1] >> (64ULL-SEARCH_SPACE_BITS);
			uint32 collisionKey = (uint32)((birthdayB>>18) & COLLISION_KEY_MASK);
			uint64 birthday = birthdayB & (COLLISION_TABLE_SIZE-1);
			if( collisionIndices[birthday] && ((collisionIndices[birthday]&COLLISION_KEY_MASK) == collisionKey))
			{
				protoshares_revalidateCollision(block, midHash, collisionIndices[birthday]&~COLLISION_KEY_MASK, n+1);
			} else {
				collisionIndices[birthday] = n+1 | collisionKey; // we have 6 bits available for validation
			}
		}
		{
			uint64 birthdayB = outHash[2] >> (64ULL-SEARCH_SPACE_BITS);
			uint32 collisionKey = (uint32)((birthdayB>>18) & COLLISION_KEY_MASK);
			uint64 birthday = birthdayB & (COLLISION_TABLE_SIZE-1);
			if( collisionIndices[birthday] && ((collisionIndices[birthday]&COLLISION_KEY_MASK) == collisionKey))
			{
				protoshares_revalidateCollision(block, midHash, collisionIndices[birthday]&~COLLISION_KEY_MASK, n+2);
			} else {
				collisionIndices[birthday] = n+2 | collisionKey; // we have 6 bits available for validation
			}
		}
		{
			uint64 birthdayB = outHash[3] >> (64ULL-SEARCH_SPACE_BITS);
			uint32 collisionKey = (uint32)((birthdayB>>18) & COLLISION_KEY_MASK);
			uint64 birthday = birthdayB & (COLLISION_TABLE_SIZE-1);
			if( collisionIndices[birthday] && ((collisionIndices[birthday]&COLLISION_KEY_MASK) == collisionKey))
			{
				protoshares_revalidateCollision(block, midHash, collisionIndices[birthday]&~COLLISION_KEY_MASK, n+3);
			} else {
				collisionIndices[birthday] = n+3 | collisionKey; // we have 6 bits available for validation
			}
		}
		{
			uint64 birthdayB = outHash[4] >> (64ULL-SEARCH_SPACE_BITS);
			uint32 collisionKey = (uint32)((birthdayB>>18) & COLLISION_KEY_MASK);
			uint64 birthday = birthdayB & (COLLISION_TABLE_SIZE-1);
			if( collisionIndices[birthday] && ((collisionIndices[birthday]&COLLISION_KEY_MASK) == collisionKey))
			{
				protoshares_revalidateCollision(block, midHash, collisionIndices[birthday]&~COLLISION_KEY_MASK, n+4);
			} else {
				collisionIndices[birthday] = n+4 | collisionKey; // we have 6 bits available for validation
			}
		}
		{
			uint64 birthdayB = outHash[5] >> (64ULL-SEARCH_SPACE_BITS);
			uint32 collisionKey = (uint32)((birthdayB>>18) & COLLISION_KEY_MASK);
			uint64 birthday = birthdayB & (COLLISION_TABLE_SIZE-1);
			if( collisionIndices[birthday] && ((collisionIndices[birthday]&COLLISION_KEY_MASK) == collisionKey))
			{
				protoshares_revalidateCollision(block, midHash, collisionIndices[birthday]&~COLLISION_KEY_MASK, n+5);
			} else {
				collisionIndices[birthday] = n+5 | collisionKey; // we have 6 bits available for validation
			}
		}
		{
			uint64 birthdayB = outHash[6] >> (64ULL-SEARCH_SPACE_BITS);
			uint32 collisionKey = (uint32)((birthdayB>>18) & COLLISION_KEY_MASK);
			uint64 birthday = birthdayB & (COLLISION_TABLE_SIZE-1);
			if( collisionIndices[birthday] && ((collisionIndices[birthday]&COLLISION_KEY_MASK) == collisionKey))
			{
				protoshares_revalidateCollision(block, midHash, collisionIndices[birthday]&~COLLISION_KEY_MASK, n+6);
			} else {
				collisionIndices[birthday] = n+6 | collisionKey; // we have 6 bits available for validation
			}
		}
		{
			uint64 birthdayB = outHash[7] >> (64ULL-SEARCH_SPACE_BITS);
			uint32 collisionKey = (uint32)((birthdayB>>18) & COLLISION_KEY_MASK);
			uint64 birthday = birthdayB & (COLLISION_TABLE_SIZE-1);
			if( collisionIndices[birthday] && ((collisionIndices[birthday]&COLLISION_KEY_MASK) == collisionKey))
			{
				protoshares_revalidateCollision(block, midHash, collisionIndices[birthday]&~COLLISION_KEY_MASK, n+7);
			} else {
				collisionIndices[birthday] = n+7 | collisionKey; // we have 6 bits available for validation
			}
		}

#endif
		n+=BIRTHDAYS_PER_HASH;
	}
}