/* cpu and memory intensive function to transform a 80 byte buffer into a 32 byte output
   scratchpad size needs to be at least 63 + (128 * r * p) + (256 * r + 64) + (128 * r * N) bytes
   r = 1, p = 1, N = 1024
 */
uint256 scrypt_blockhash(const uint8_t* input)
{
    uint8_t scratchpad[SCRYPT_BUFFER_SIZE];
    uint32_t X[32];
    uint256 result = 0;

    uint32_t *V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));

    PKCS5_PBKDF2_HMAC((const char*)input, 80, input, 80, 1, EVP_sha256(), 128, (unsigned char *)X);

    uint16_t i, j, k;
    for (i = 0; i < 1024; i++) {
        memcpy(&V[i * 32], X, 128);
        xor_salsa8(&X[0], &X[16]);
        xor_salsa8(&X[16], &X[0]);
    }
    for (i = 0; i < 1024; i++) {
        j = 32 * (X[16] & 1023);
        for (k = 0; k < 32; k++)
            X[k] ^= V[j + k];
        xor_salsa8(&X[0], &X[16]);
        xor_salsa8(&X[16], &X[0]);
    }

    PKCS5_PBKDF2_HMAC((const char*)input, 80, (const unsigned char*)X, 128, 1, EVP_sha256(), 32, (unsigned char*)&result);

    return result;
}
예제 #2
0
void pluck_hash(uint32_t *hash, const uint32_t *data, uchar *hashbuffer, const int N)
{
	int size = N * 1024;
	sha256_hash(hashbuffer, (void*)data, BLOCK_HEADER_SIZE);
	memset(&hashbuffer[32], 0, 32);

	for(int i = 64; i < size - 32; i += 32)
	{
		uint32_t _ALIGN(64) randseed[16];
		uint32_t _ALIGN(64) randbuffer[16];
		uint32_t _ALIGN(64) joint[16];
		//i-4 because we use integers for all references against this, and we don't want to go 3 bytes over the defined area
		//we could use size here, but then it's probable to use 0 as the value in most cases
		int randmax = i - 4;

		//setup randbuffer to be an array of random indexes
		memcpy(randseed, &hashbuffer[i - 64], 64);

		if(i > 128) memcpy(randbuffer, &hashbuffer[i - 128], 64);
		//else memset(randbuffer, 0, 64);

		xor_salsa8((void*)randbuffer, (void*)randseed, i);
		memcpy(joint, &hashbuffer[i - 32], 32);

		//use the last hash value as the seed
		for (int j = 32; j < 64; j += 4)
		{
			//every other time, change to next random index
			//randmax - 32 as otherwise we go beyond memory that's already been written to
			uint32_t rand = randbuffer[(j - 32) >> 2] % (randmax - 32);
			joint[j >> 2] = *((uint32_t *)&hashbuffer[rand]);
		}

		sha256_hash512((uint32_t*) &hashbuffer[i], joint);

		//setup randbuffer to be an array of random indexes
		//use last hash value and previous hash value(post-mixing)
		memcpy(randseed, &hashbuffer[i - 32], 64);

		if(i > 128) memcpy(randbuffer, &hashbuffer[i - 128], 64);
		//else memset(randbuffer, 0, 64);

		xor_salsa8((void*)randbuffer, (void*)randseed, i);

		//use the last hash value as the seed
		for (int j = 0; j < 32; j += 2)
		{
			uint32_t rand = randbuffer[j >> 1] % randmax;
			*((uint32_t *)(hashbuffer + rand)) = *((uint32_t *)(hashbuffer + j + randmax));
		}
	}

	memcpy(hash, hashbuffer, 32);
}
예제 #3
0
void dfescrypt_cpu(uint32_t n, uint32_t *input, uint32_t *output, uint32_t *midstate) {
	uint32_t* X = (uint32_t*) malloc(sizeof(uint32_t)*32*n);
	uint32_t* tstates = (uint32_t*) malloc(sizeof(uint32_t)*8*n);
	uint32_t* ostates = (uint32_t*) malloc(sizeof(uint32_t)*8*n);
	uint32_t *V;
	uint32_t i, j, k;
	uint32_t iterations = HybridcoinMiner_Scrypt_Iterations;
	char scratchpad[SCRYPT_SCRATCHPAD_SIZE];
	V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));
	if(NULL == X || NULL == tstates || NULL == ostates){
		LOG_FATAL("unable to allocate buffer for Scrypt input!\n");
	}

#pragma omp parallel for
	for (int64_t i = 0; i < (int64_t)n; i++) {
		memcpy(&tstates[i*8], midstate, 32);
		SHA256_before(&tstates[i*8], &ostates[i*8], &input[20*i], &X[i*32]);
	}

	//SCRYPT CORE
	for (int64_t p = 0; p < (int64_t)n; p++) {
		uint32_t *Y = &X[p*32];
		for (i = 0; i < iterations; i++) {
			memcpy(&V[i * 32], Y, 128);
			xor_salsa8(&Y[0], &Y[16]);
			xor_salsa8(&Y[16], &Y[0]);
		}

		for (i = 0; i < iterations; i++) {
			j = 32 * (Y[16] & (iterations-1));

			for (k = 0; k < 32; k++)
				Y[k] ^= V[j + k];
			xor_salsa8(&Y[0], &Y[16]);
			xor_salsa8(&Y[16], &Y[0]);
		}
	}

#pragma omp parallel for
	for (int64_t i = 0; i < (int64_t)n; i++) {
		SHA256_after(&tstates[i*8], &ostates[i*8], &output[i*8], &X[i*32]);
	}

	free(X);
	free(tstates);
	free(ostates);
}
예제 #4
0
파일: scrypt.c 프로젝트: FrBillyD/cpuminer
static inline void scrypt_core(uint32_t *X, uint32_t *V, int N)
{
	uint32_t i, j, k;
	
	for (i = 0; i < N; i++) {
		memcpy(&V[i * 32], X, 128);
		xor_salsa8(&X[0], &X[16]);
		xor_salsa8(&X[16], &X[0]);
	}
	for (i = 0; i < N; i++) {
		j = 32 * (X[16] & (N - 1));
		for (k = 0; k < 32; k++)
			X[k] ^= V[j + k];
		xor_salsa8(&X[0], &X[16]);
		xor_salsa8(&X[16], &X[0]);
	}
}
예제 #5
0
static inline void scrypt_core(unsigned int *X, unsigned int *V)
{
    unsigned int i, j, k;

    for (i = 0; i < 1024; i++) {
        memcpy(&V[i * 32], X, 128);
        xor_salsa8(&X[0], &X[16]);
        xor_salsa8(&X[16], &X[0]);
    }
    for (i = 0; i < 1024; i++) {
        j = 32 * (X[16] & 1023);
        for (k = 0; k < 32; k++)
            X[k] ^= V[j + k];
        xor_salsa8(&X[0], &X[16]);
        xor_salsa8(&X[16], &X[0]);
    }
}