void GeneratePrimeTable()
{
    //nSievePercentage = (unsigned int)GetArg("-sievepercentage", nDefaultSievePercentage);
	nSievePercentage = globalconfs.coin.config.GetValue<uint>("sievepercentage");
    nSievePercentage = std::max(std::min(nSievePercentage, nMaxSievePercentage), nMinSievePercentage);

    //nSieveSize = (unsigned int)GetArg("-sievesize", nDefaultSieveSize);
	nSieveSize = globalconfs.coin.config.GetValue<uint>("sievesize");
    nSieveSize = std::max(std::min(nSieveSize, nMaxSieveSize), nMinSieveSize);

    printf("GeneratePrimeTable() : setting nSievePercentage = %u, nSieveSize = %u\n", nSievePercentage, nSieveSize);
    const unsigned nPrimeTableLimit = nSieveSize;
    vPrimes.clear();
    // Generate prime table using sieve of Eratosthenes
    std::vector<bool> vfComposite (nPrimeTableLimit, false);
    for (unsigned int nFactor = 2; nFactor * nFactor < nPrimeTableLimit; nFactor++)
    {
        if (vfComposite[nFactor])
            continue;
        for (unsigned int nComposite = nFactor * nFactor; nComposite < nPrimeTableLimit; nComposite += nFactor)
            vfComposite[nComposite] = true;
    }
    for (unsigned int n = 2; n < nPrimeTableLimit; n++)
        if (!vfComposite[n])
            vPrimes.push_back(n);
    printf("GeneratePrimeTable() : prime table [1, %d] generated with %lu primes", nPrimeTableLimit, vPrimes.size());
    //BOOST_FOREACH(unsigned int nPrime, vPrimes)
    //    printf(" %u", nPrime);
    printf("\n");
    
    const unsigned int nPrimes = vPrimes.size();
    vTwoInverses = std::vector<unsigned int> (nPrimes, 0);
    for (unsigned int nPrimeSeq = 1; nPrimeSeq < nPrimes; nPrimeSeq++)
    {
        vTwoInverses[nPrimeSeq] = int_invert(2, vPrimes[nPrimeSeq]);
    }
}
Beispiel #2
0
void riecoin_process(minerRiecoinBlock_t* block)
{
	uint32 searchBits = block->targetCompact;

	if( riecoin_sieve )
		memset(riecoin_sieve, 0x00, riecoin_sieveSize/8);
	else
	{
		riecoin_sieve = (uint8*)malloc(riecoin_sieveSize/8);
		memset(riecoin_sieve, 0x00, riecoin_sieveSize/8);
	}
	uint8* sieve = riecoin_sieve;

	// test data
	// getblock 16ee31c116b75d0299dc03cab2b6cbcb885aa29adf292b2697625bc9d28b2b64
	//debug_parseHexStringLE("c59ba5357285de73b878fed43039a37f85887c8960e66bcb6e86bdad565924bd", 64, block->merkleRoot);
	//block->version = 2;
	//debug_parseHexStringLE("c64673c670fb327c2e009b3b626d2def01d51ad4131a7a1040e9cef7bfa34838", 64, block->prevBlockHash);
	//block->nTime = 1392151955;
	//block->nBits = 0x02013000;
	//debug_parseHexStringLE("0000000000000000000000000000000000000000000000000000000070b67515", 64, block->nOffset);
	// generate PoW hash (version to nBits)
	uint8 powHash[32];
	sha256_ctx ctx;
	sha256_init(&ctx);
	sha256_update(&ctx, (uint8*)block, 80);
	sha256_final(&ctx, powHash);
	sha256_init(&ctx);
	sha256_update(&ctx, powHash, 32);
	sha256_final(&ctx, powHash);
	// generatePrimeBase
	uint32* powHashU32 = (uint32*)powHash;
	mpz_t z_target;
	mpz_t z_temp;
	mpz_init(z_temp);
	mpz_init_set_ui(z_target, 1);
	mpz_mul_2exp(z_target, z_target, zeroesBeforeHashInPrime);
	for(uint32 i=0; i<256; i++)
	{
		mpz_mul_2exp(z_target, z_target, 1);
		if( (powHashU32[i/32]>>(i))&1 )
			z_target->_mp_d[0]++;
	}
	unsigned int trailingZeros = searchBits - 1 - zeroesBeforeHashInPrime - 256;
	mpz_mul_2exp(z_target, z_target, trailingZeros);
	// find first offset where x%2310 = 97
	uint64 remainder2310 = mpz_tdiv_ui(z_target, 2310);
	remainder2310 = (2310-remainder2310)%2310;
	remainder2310 += 97;
	mpz_add_ui(z_temp, z_target, remainder2310);

	mpz_t z_temp2;
	mpz_init(z_temp2);
	mpz_t z_ft_r;
	mpz_init(z_ft_r);
	mpz_t z_ft_b;
	mpz_init_set_ui(z_ft_b, 2);
	mpz_t z_ft_n;
	mpz_init(z_ft_n);

	static uint32 primeTupleBias[6] = {0,4,6,10,12,16};
	for(uint32 i=5; i<riecoin_primeTestSize; i++)
	{
		for(uint32 f=0; f<6; f++)
		{
			uint32 p = riecoin_primeTestTable[i];
			uint32 remainder = mpz_tdiv_ui(z_temp, p);//;
			remainder += primeTupleBias[f];
			remainder %= p;
			uint32 index;
			// a+b*x=0 (mod p) => b*x=p-a => x = (p-a)*modinv(b)
			sint32 pa = (p<remainder)?(p-remainder+p):(p-remainder);
			sint32 b = 2310;
			index = (pa%p)*int_invert(b, p);
			index %= p;
			while(index < riecoin_sieveSize)
			{
				sieve[(index)>>3] |= (1<<((index)&7));
				index += p;
			}
		}
		
	}

	uint32 countCandidates = 0;
	uint32 countPrimes = 0;
	uint32 countPrimes2 = 0;
	// scan for candidates
	for(uint32 i=1; i<riecoin_sieveSize; i++)
	{
		if( sieve[(i)>>3] & (1<<((i)&7)) )
			continue;
		countCandidates++;
		// test the first 4 numbers for being prime (5th and 6th is checked server side)
		// we use fermat test as it is slightly faster for virtually the same accuracy
		// p1
		mpz_add_ui(z_temp, z_target, (uint64)remainder2310 + 2310ULL*(uint64)i);
		mpz_sub_ui(z_ft_n, z_temp, 1);
		mpz_powm(z_ft_r, z_ft_b, z_ft_n, z_temp);
		if (mpz_cmp_ui(z_ft_r, 1) != 0)
			continue;
		else
			countPrimes++;
		// p2
		mpz_add_ui(z_temp, z_temp, 4);
		mpz_sub_ui(z_ft_n, z_temp, 1);
		mpz_powm(z_ft_r, z_ft_b, z_ft_n, z_temp);
		if (mpz_cmp_ui(z_ft_r, 1) != 0)
			continue;
		else
			countPrimes2++;
		total2ChainCount++;
		// p3
		mpz_add_ui(z_temp, z_temp, 2);
		if( mpz_probab_prime_p(z_temp, 1) == 0 )
			continue;
		total3ChainCount++;
		// p4
		mpz_add_ui(z_temp, z_temp, 4);
		if( mpz_probab_prime_p(z_temp, 1) == 0 )
			continue;
		total4ChainCount++;
		// calculate offset
		mpz_add_ui(z_temp, z_target, (uint64)remainder2310 + 2310ULL*(uint64)i);
		mpz_sub(z_temp2, z_temp, z_target);
		// submit share
		uint8 nOffset[32];
		memset(nOffset, 0x00, 32);
#ifdef _WIN64
		for(uint32 d=0; d<min(32/8, z_temp2->_mp_size); d++)
		{
			*(uint64*)(nOffset+d*8) = z_temp2->_mp_d[d];
		}
#else
		for(uint32 d=0; d<min(32/4, z_temp2->_mp_size); d++)
		{
			*(uint32*)(nOffset+d*4) = z_temp2->_mp_d[d];
		}
#endif
		totalShareCount++;
		xptMiner_submitShare(block, nOffset);
	}
}