Esempio n. 1
0
// Test probable prime chain for: nOrigin
// Return value:
//   true - Probable prime chain found (one of nChainLength meeting target)
//   false - prime chain too short (none of nChainLength meeting target)
static
bool AllChainTest(mpz_t *bnPrimeChainOrigin, unsigned int nBits, bool fFermatTest, unsigned int *pnChainLengthCunningham1, unsigned int *pnChainLengthCunningham2, unsigned int *pnChainLengthBiTwin, unsigned int sievenumber)
{
	*pnChainLengthCunningham1 = 0;
	*pnChainLengthCunningham2 = 0;
	*pnChainLengthBiTwin = 0;
	
	mpz_t mp;
	mpz_init(mp);
	
	// Test for Cunningham Chain of first kind
	if (sievenumber&1)
	{
		mpz_sub_ui(mp, *bnPrimeChainOrigin, 1);
		CunnChainTest(&mp, true, fFermatTest, pnChainLengthCunningham1);
	}
	// Test for Cunningham Chain of second kind
	if (sievenumber&2)
	{
		mpz_add_ui(mp, *bnPrimeChainOrigin, 1);
		CunnChainTest(&mp, false, fFermatTest, pnChainLengthCunningham2);
	}
	
	mpz_clear(mp);
	// Figure out BiTwin Chain length
	// BiTwin Chain allows a single prime at the end for odd length chain
	*pnChainLengthBiTwin = (TargetGetLength(*pnChainLengthCunningham1) > TargetGetLength(*pnChainLengthCunningham2)) ? (*pnChainLengthCunningham2 + TargetFromInt(TargetGetLength(*pnChainLengthCunningham2)+1)) : (*pnChainLengthCunningham1 + TargetFromInt(TargetGetLength(*pnChainLengthCunningham1)));
	
	return (*pnChainLengthCunningham1 >= nBits || *pnChainLengthCunningham2 >= nBits || *pnChainLengthBiTwin >= nBits);
}
Esempio n. 2
0
// Test probable prime chain for: nOrigin
// Return value:
//   true - Probable prime chain found (one of nChainLength meeting target)
//   false - prime chain too short (none of nChainLength meeting target)
bool ProbablePrimeChainTestFast2(const mpz_class& mpzPrimeChainOrigin, CPrimalityTestParams& testParams, uint32 sieveFlags, uint32 multiplier)
{
	const unsigned int nBits = testParams.nBits;
	unsigned int& nChainLengthCunningham1 = testParams.nChainLengthCunningham1;
	unsigned int& nChainLengthCunningham2 = testParams.nChainLengthCunningham2;
	unsigned int& nChainLengthBiTwin = testParams.nChainLengthBiTwin;
	const bool fFermatTest = testParams.fFermatTest;
	mpz_class& mpzOriginMinusOne = testParams.mpzOriginMinusOne;
	mpz_class& mpzOriginPlusOne = testParams.mpzOriginPlusOne;
	nChainLengthCunningham1 = 0;
	nChainLengthCunningham2 = 0;
	nChainLengthBiTwin = 0;

	bool testCFirstKind = ((sieveFlags&SIEVE_FLAG_BT_COMPOSITE)!=0) || ((sieveFlags&SIEVE_FLAG_C2_COMPOSITE)!=0); // yes, C1 and C2 is switched
	bool testCSecondKind = ((sieveFlags&SIEVE_FLAG_BT_COMPOSITE)!=0) || ((sieveFlags&SIEVE_FLAG_C1_COMPOSITE)!=0);

	// Test for Cunningham Chain of first kind
	mpzOriginMinusOne = mpzPrimeChainOrigin - 1;
	if( testCFirstKind )
		ProbableCunninghamChainTestFast(mpzOriginMinusOne, true, fFermatTest, nChainLengthCunningham1, testParams);
	else
		nChainLengthCunningham1 = 0;
	// Test for Cunningham Chain of second kind
	mpzOriginPlusOne = mpzPrimeChainOrigin + 1;
	if( testCSecondKind )
		ProbableCunninghamChainTestFast(mpzOriginPlusOne, false, fFermatTest, nChainLengthCunningham2, testParams);
	else
		nChainLengthCunningham2 = 0;
	//// do we need to flag some bits as composite to avoid redundant chain checks?
	//uint32 redundancyCheckLength = min(nChainLengthCunningham1, nChainLengthCunningham2);
	//redundancyCheckLength >>= 24;
	//if( redundancyCheckLength >= 2 ) 
	//{
	//	printf(".");
	//	uint32 mask = 1<<(multiplier&7);
	//	uint32 maskIdx = multiplier>>3;
	//	for(uint32 r=0; r<redundancyCheckLength; r++)
	//	{
	//		uint8* maskC1 = cSieve->layerMaskC1+((cSieve->currentSieveLayerIdx+r)%cSieve->chainLength)*cSieve->maskBytes;
	//		uint8* maskC2 = cSieve->layerMaskC1+((cSieve->currentSieveLayerIdx+r)%cSieve->chainLength)*cSieve->maskBytes;
	//		maskC1[maskIdx] |= mask;
	//		maskC2[maskIdx] |= mask;
	//	}
	//}
	// verify if there is any chance to find a biTwin that worth calculation
	if (nChainLengthCunningham1 < 0x2000000 || nChainLengthCunningham2 < 0x2000000)
		return (nChainLengthCunningham1 >= nBits || nChainLengthCunningham2 >= nBits);
	// Figure out BiTwin Chain length
	// BiTwin Chain allows a single prime at the end for odd length chain
	nChainLengthBiTwin =
		(TargetGetLength(nChainLengthCunningham1) > TargetGetLength(nChainLengthCunningham2))?
		(nChainLengthCunningham2 + TargetFromInt(TargetGetLength(nChainLengthCunningham2)+1)) :
	(nChainLengthCunningham1 + TargetFromInt(TargetGetLength(nChainLengthCunningham1)));

	return (nChainLengthCunningham1 >= nBits || nChainLengthCunningham2 >= nBits || nChainLengthBiTwin >= nBits);
}
// Test Probable Cunningham Chain for: n
// fSophieGermain:
//   true - Test for Cunningham Chain of first kind (n, 2n+1, 4n+3, ...)
//   false - Test for Cunningham Chain of second kind (n, 2n-1, 4n-3, ...)
// Return value:
//   true - Probable Cunningham Chain found (length at least 2)
//   false - Not Cunningham Chain
static bool ProbableCunninghamChainTestFast(const mpz_class& n, bool fSophieGermain, bool fFermatTest, unsigned int& nProbableChainLength, CPrimalityTestParams& testParams, bool use_gpu_fermat_test)
{
    nProbableChainLength = 0;
    mpz_class &N = testParams.N;
    N = n;

	if (!use_gpu_fermat_test && !FermatProbablePrimalityTestFast(N, nProbableChainLength, testParams, true))
	{
		return false;
	}

    // Euler-Lagrange-Lifchitz test for the following numbers in chain
    while (true)
    {
        TargetIncrementLength(nProbableChainLength);
        N = N + N + (fSophieGermain? 1 : (-1));
        if (fFermatTest)
        {
            if (!FermatProbablePrimalityTestFast(N, nProbableChainLength, testParams, true))
                break;
        }
        else
        {
            if (!EulerLagrangeLifchitzPrimalityTestFast(N, fSophieGermain, nProbableChainLength, testParams, true))
                break;
        }
    }
    return (TargetGetLength(nProbableChainLength) >= 2);
}
std::string TargetToString(unsigned int nBits)
{
    //return strprintf("%02x.%06x", TargetGetLength(nBits), TargetGetFractional(nBits));
	stringstream ss;
	ss << std::hex << std::setw(2) << std::setfill('0') << TargetGetLength(nBits) << "." << std::setw(6) << std::setfill('0') << TargetGetFractional(nBits);
	return ss.str();
}
Esempio n. 5
0
// Test Probable Cunningham Chain for: n
// fSophieGermain:
//   true - Test for Cunningham Chain of first kind (n, 2n+1, 4n+3, ...)
//   false - Test for Cunningham Chain of second kind (n, 2n-1, 4n-3, ...)
// Return value:
//   true - Probable Cunningham Chain found (length at least 2)
//   false - Not Cunningham Chain
static
bool CunnChainTest(mpz_t *n, bool fSophieGermain, bool fFermatTest, unsigned int *pnProbableChainLength)
{
	*pnProbableChainLength = 0;
	mpz_t N;
	mpz_init_set(N, *n);
	
	// Fermat test for n first
	if (!PrimeTest(&N, pnProbableChainLength))
	{
		mpz_clear(N);
		return false;
	}

	// Euler-Lagrange-Lifchitz test for the following numbers in chain
	while (true)
	{
		TargetIncrementLength(pnProbableChainLength);
		mpz_add(N, N, N);
		if (fSophieGermain)
			mpz_add_ui(N, N, 1);
		else
			mpz_sub_ui(N, N, 1);
		//disabled, see SpecialPrimeTest() comments for further information
		/*if (fFermatTest)
		{
			if (!PrimeTest(&N, pnProbableChainLength))
				break;
		}
		else
		{
			if (!SpecialPrimeTest(&N, fSophieGermain, pnProbableChainLength))
				break;
		}*/
		if (!PrimeTest(&N, pnProbableChainLength))
			break;
	}
	mpz_clear(N);

#ifdef SUPERDEBUG
	printf("PCCT => %u (%u)\n", TargetGetLength(*pnProbableChainLength), *pnProbableChainLength);
#endif
	return (TargetGetLength(*pnProbableChainLength) >= 2);
}
Esempio n. 6
0
int PrimeWorker::HandleRequest(zmq_pollitem_t *item) {
	
	proto::Request& req = mRequest;
	zmsg_t* msg = ReceiveRequest(req, item->socket);
	if(!msg)
		return 0;
	
	//req.PrintDebugString();
	
	proto::Request::Type rtype = req.type();
	proto::Reply::ErrType etype = proto::Reply::NONE;
	
	proto::Reply& rep = mReply;
	rep.Clear();
	rep.set_type(rtype);
	rep.set_reqid(req.reqid());
	
	if(!proto::Request::Type_IsValid(rtype)){
		printf("ERROR: !proto::Request::Type_IsValid.\n");
		rtype = proto::Request::NONE;
		etype = proto::Reply::INVALID;
	}
	
	while(etype == proto::Reply::NONE) {
		
		int vstatus = CheckVersion(req.version());
		if(vstatus <= 0){
			rep.set_errstr("Your miner version is no longer supported. Please upgrade.");
			etype = proto::Reply::VERSION;
			break;
		}
		
		if(rtype == proto::Request::CONNECT){
			
			rep.mutable_sinfo()->CopyFrom(mServerInfo);
				
			if(vstatus == 1){
				etype = proto::Reply::VERSION;
				rep.set_errstr("Your miner version will no longer be supported in the near future. Please upgrade.");
			}
			
		}else if(rtype == proto::Request::GETWORK){
			
			if(!mCurrBlock.has_height()){
				etype = proto::Reply::HEIGHT;
				break;
			}
			
			if(req.height() != mCurrHeight){
				etype = proto::Reply::HEIGHT;
				break;
			}
			
			CBlock *pblock = &mBlockTemplate->block;
			IncrementExtraNonce(pblock, mIndexPrev, mExtraNonce);
			pblock->nTime = std::max(pblock->nTime, (unsigned int)GetAdjustedTime());
			
			mNonceMap[pblock->hashMerkleRoot] = mExtraNonce;
			
			proto::Work* work = rep.mutable_work();
			work->set_height(mCurrHeight);
			work->set_merkle(pblock->hashMerkleRoot.GetHex());
			work->set_time(pblock->nTime);
			work->set_bits(pblock->nBits);
			
		}else if(rtype == proto::Request::SHARE){
			
			if(!mCurrBlock.has_height()){
				etype = proto::Reply::STALE;
				break;
			}
			
			if(!req.has_share()){
				printf("ERROR: !req.has_share().\n");
				etype = proto::Reply::INVALID;
				break;
			}
			
			const proto::Share& share = req.share();
			
			if(share.height() != mCurrHeight){
				etype = proto::Reply::STALE;
				break;
			}
			
			if(share.length() < mCurrBlock.minshare()){
				printf("ERROR: share.length too short.\n");
				etype = proto::Reply::INVALID;
				break;
			}
			
			uint256 merkleRoot;
			merkleRoot.SetHex(share.merkle());
			
			unsigned extraNonce = mNonceMap[merkleRoot];
			if(!extraNonce){
				etype = proto::Reply::STALE;
				break;
			}
			
			unsigned nCandidateType = share.chaintype();
			if(nCandidateType > 2){
				printf("ERROR: share.chaintype invalid.\n");
				etype = proto::Reply::INVALID;
				break;
			}
			
			CBlock *pblock = &mBlockTemplate->block;
			extraNonce--;
			IncrementExtraNonce(pblock, mIndexPrev, extraNonce);
			pblock->nTime = share.time();
			pblock->nBits = share.bits();
			pblock->nNonce = share.nonce();
			
			uint256 headerHash = pblock->GetHeaderHash();
			{
				uint256 headerHashClient;
				headerHashClient.SetHex(share.hash());
				if(headerHashClient != headerHash){
					printf("ERROR: headerHashClient != headerHash.\n");
					etype = proto::Reply::INVALID;
					break;
				}
			}
			
			pblock->bnPrimeChainMultiplier.SetHex(share.multi());
			uint256 blockhash = pblock->GetHash();
			
			if(!mShares.insert(blockhash).second){
				etype = proto::Reply::DUPLICATE;
				break;
			}
			
			CBigNum bnChainOrigin = CBigNum(headerHash) * pblock->bnPrimeChainMultiplier;
			unsigned int nChainLength = 0;
			bool isblock = ProbablePrimeChainTestForMiner(bnChainOrigin, pblock->nBits, nCandidateType+1, nChainLength);
			
			nChainLength = TargetGetLength(nChainLength);
			if(nChainLength >= mCurrBlock.minshare()){
				
				if(isblock)
					isblock = CheckWork(pblock, *mWallet, mReserveKey);
				
				if(share.length() != nChainLength){
					printf("ERROR: share.length() != nChainLength.\n");
					etype = proto::Reply::INVALID;
				}
				
				mData.Clear();
				proto::Share* mshare = mData.mutable_share();
				mshare->CopyFrom(share);
				mshare->set_blockhash(blockhash.GetHex());
				mshare->set_length(nChainLength);
				mshare->set_isblock(isblock);
				
				if(isblock){
					mshare->set_genvalue(pblock->vtx[0].vout[0].nValue);
				}
				
				SendData(mData, mBackend);
				
				CBitcoinAddress address(share.addr());
				if(!address.IsValid()){
					printf("ERROR: invalid address for share: %s\n", share.addr().c_str());
					etype = proto::Reply::INVALID;
					std::string errstr = "Your payment address '";
					errstr.append(share.addr());
					errstr.append("' is INVALID!!!");
					rep.set_errstr(errstr);
					break;
				}
				
			}else{
				
				printf("ERROR: share.length too short after test: %d/%d\n", nChainLength, share.length());
				etype = proto::Reply::INVALID;
				break;
				
			}
			
		}else if(rtype == proto::Request::STATS){
			
			if(!req.has_stats()){
				printf("ERROR: !req.has_stats().\n");
				etype = proto::Reply::INVALID;
				break;
			}
			
			const proto::ClientStats& stats = req.stats();
			std::pair<std::string,uint64> key = std::make_pair(stats.addr(), stats.clientid() * stats.instanceid());
			
			std::map<std::pair<std::string,uint64>, proto::Data>::iterator iter = mStats.find(key);
			if(iter != mStats.end()){
				
				proto::ClientStats* s = mStats[key].mutable_clientstats();
				s->set_version(std::min(s->version(), stats.version()));
				s->set_cpd(s->cpd() + stats.cpd());
				s->set_errors(s->errors() + stats.errors());
				s->set_temp(std::max(s->temp(), stats.temp()));
				s->set_latency(std::max(s->latency(), stats.latency()));
				s->set_ngpus(s->ngpus() + stats.ngpus());
				/*if(s->name() != stats.name()){
					s->mutable_name()->append("+");
					s->mutable_name()->append(stats.name());
				}*/
				
			}else if(mStats.size() < 100000){
				mStats[key].mutable_clientstats()->CopyFrom(stats);
			}
			
		}
		
		break;
	}
	
	if(req.height() < mCurrHeight){
		rep.mutable_block()->CopyFrom(mCurrBlock);
	}
	
	mReqStats[std::make_pair(rtype,etype)]++;
	
	rep.set_error(etype);
	
	SendReply(rep, &msg, item->socket);
	
	zmsg_destroy(&msg);
	return 0;
	
}
Esempio n. 7
0
bool MinePrime(Reap_CPU_param* state, Work& tempwork)
{
	uchar* tempdata = &tempwork.data[0];
	uchar hash[32];
	mysha256(hash,tempdata,80);
	mysha256(hash,hash,32);
	
	//does this need byte flipping?
	uint bits = *(uint*)&tempdata[72];
	
	if (!(hash[31] & 0x80))
		return false; //hash is too small, abort

	Mpz_w hashnum;
	
	set_mpz_to_hash(&hashnum.n, hash);
	if (mpz_fdiv_ui(hashnum.n, 2*3) != 0)
		return false;
	
	bool found=false;

	
	//5431526412865007455
	mpz_t factor; mpz_init_set_str(factor, "5431526412865007455", 10);
	mpz_mul(hashnum.n,hashnum.n,factor);
	
	uint remainders[MAX_SIEVE_AMOUNT] = {};
	for(int i=0; i<MAX_SIEVE_AMOUNT; ++i)
	{
		remainders[i] = mpz_fdiv_ui(hashnum.n,Primes::v[i]);
	}
	
	mpz_t newhashnum; mpz_init(newhashnum);
	for(uint h=1; h<500; ++h)
	{
		mpz_add(newhashnum,newhashnum,hashnum.n);
		uint c1=0,c2=0,tw=0;

		uint sievenumber = 0;
		for(uint i=16; i<MAX_SIEVE_AMOUNT; ++i)
		{
			sievenumber |= Sieve::Get(i,remainders[i]*h%Primes::v[i])^3;
		}
		sievenumber ^= 3;
		//cout << sievenumber << endl;;
		if (sievenumber == 0)
			continue;
		
		//TODO: fix second parameter, it should be bits!
		AllChainTest(&newhashnum, 0, true, &c1, &c2, &tw, sievenumber);

		uint c1_i = TargetGetLength(c1);
		uint c2_i = TargetGetLength(c2);
		uint tw_i = TargetGetLength(tw);

		const int minlength=5;

		/*{
			if (c1_i >= minlength)
				cout << "First kind: " << c1_i << endl;
			if (c2_i >= minlength)
				cout << "Second kind: " << c2_i << endl;
			if (tw_i >= minlength)
				cout << "Twin kind: " << tw_i << endl;
		}*/
			
		
		++chainspersec[c1_i];
		++chainspersec[c2_i];
		++chainspersec[tw_i];
		++totalpersec;

		found = (c1_i >= minlength || c2_i >= minlength || tw_i >= minlength);
		if (found)
		{
			mpz_mul_ui(factor,factor,h);
			vector<uchar> auxdata = XPM_create_auxdata(&factor);
			Share share;
			
			CPU_Got_share(state,tempwork,auxdata);//tempdata,tempwork.target_share,current_server_id,tempwork.dataid,auxdata);
		}
	}

	return found;
}
Esempio n. 8
0
static void TargetDecrementLength(unsigned int& nBits)
{
    if (TargetGetLength(nBits) > nTargetMinLength)
        nBits -= (1 << nFractionalBits);
}
Esempio n. 9
0
std::string TargetToString(unsigned int nBits)
{
    char tmp[20];
	sprintf(tmp, "%02x.%06x", TargetGetLength(nBits), TargetGetFractional(nBits));
	return std::string(tmp);
}
Esempio n. 10
0
// Test probable prime chain for: nOrigin
// Return value:
//   true - Probable prime chain found (one of nChainLength meeting target)
//   false - prime chain too short (none of nChainLength meeting target)
bool ProbablePrimeChainTestFast2(const mpz_class& mpzPrimeChainOrigin, CPrimalityTestParams& testParams, uint32 sieveFlags, uint32 multiplier)
{
	const unsigned int nBits = testParams.nBits;
	unsigned int& nChainLengthCunningham1 = testParams.nChainLengthCunningham1;
	unsigned int& nChainLengthCunningham2 = testParams.nChainLengthCunningham2;
	unsigned int& nChainLengthBiTwin = testParams.nChainLengthBiTwin;
	const bool fFermatTest = testParams.fFermatTest;
	mpz_class& mpzOriginMinusOne = testParams.mpzOriginMinusOne;
	mpz_class& mpzOriginPlusOne = testParams.mpzOriginPlusOne;
	nChainLengthCunningham1 = 0;
	nChainLengthCunningham2 = 0;
	nChainLengthBiTwin = 0;

	//sieveFlags = 0; // note: enabling the sieve optimization seems to decrease the rate of shares (remove this line to enable this future for non-gpu mode)

	bool testCFirstKind = ((sieveFlags&SIEVE_FLAG_BT_COMPOSITE)==0) || ((sieveFlags&SIEVE_FLAG_C1_COMPOSITE)==0); // yes, C1 and C2 are switched
	bool testCSecondKind = ((sieveFlags&SIEVE_FLAG_BT_COMPOSITE)==0) || ((sieveFlags&SIEVE_FLAG_C2_COMPOSITE)==0);

	bool testCFirstFast = (sieveFlags&SIEVE_FLAG_C1_COMPOSITE)!=0; // should be !=0?
	bool testCSecondFast = (sieveFlags&SIEVE_FLAG_C2_COMPOSITE)!=0;

	mpzOriginMinusOne = mpzPrimeChainOrigin - 1; // first kind origin
	mpzOriginPlusOne = mpzPrimeChainOrigin + 1; // second kind origin

	// detailed test

	//if( testCFirstKind && testCFirstFast == true ) //(sieveFlags&SIEVE_FLAG_C1_COMPOSITE)==0 )
	//{
	//	for(uint32 i=0; i<5000; i++)
	//	{
	//		if( mpz_tdiv_ui(mpzOriginMinusOne.get_mpz_t(), vPrimes[i]) == 0 )
	//			__debugbreak();
	//	}
	//}
	//if( testCSecondKind && testCSecondFast == true )//(sieveFlags&SIEVE_FLAG_C2_COMPOSITE)==0 )
	//{
	//	for(uint32 i=0; i<5000; i++)
	//	{
	//		if( mpz_tdiv_ui(mpzOriginPlusOne.get_mpz_t(), vPrimes[i]) == 0 )
	//			__debugbreak();
	//	}
	//}


	//printf("%d\n", fFermatTest?1:0);

	// Test for Cunningham Chain of first kind
	if( testCFirstKind )
	{
		ProbableCunninghamChainTestFast(mpzOriginMinusOne, true, fFermatTest, nChainLengthCunningham1, testParams, testCFirstFast);
	
		//if( nChainLengthCunningham1 >= 0x04000000 )
		//{
		//	//__debugbreak();
		//	mpz_class mpz_r;
		//	mpz_class mpz_n1 = mpzPrimeChainOrigin - 1;
		//	mpz_class mpz_n2 = mpzPrimeChainOrigin*2 - 1;
		//	mpz_class mpz_n3 = mpzPrimeChainOrigin*4 - 1;
		//	mpz_class mpz_n4 = mpzPrimeChainOrigin*8 - 1;
		//	mpz_class mpz_e = mpz_n3 - 1;
		//	mpz_class mpz_m = mpz_n1 * mpz_n2 * mpz_n3 * mpz_n4;
		//	mpz_powm(mpz_r.get_mpz_t(), mpzTwo.get_mpz_t(), mpz_e.get_mpz_t(), mpz_m.get_mpz_t());

		//	bool isPrime = (mpz_r.get_mpz_t()->_mp_d[0]&0xFF)==0xFF;
		//	printf("%08X isPrime: %s	D: %016X\n", nChainLengthCunningham1, isPrime?"yes":"no", mpz_r.get_mpz_t()->_mp_d[0]);
		//	if( isPrime == false )
		//		__debugbreak();
		//	//__debugbreak();


		//}
	}
	else
		nChainLengthCunningham1 = 0;
	// Test for Cunningham Chain of second kind
	if( testCSecondKind )
		ProbableCunninghamChainTestFast(mpzOriginPlusOne, false, fFermatTest, nChainLengthCunningham2, testParams, testCSecondFast);
	else
		nChainLengthCunningham2 = 0;
	//// do we need to flag some bits as composite to avoid redundant chain checks?
	//uint32 redundancyCheckLength = min(nChainLengthCunningham1, nChainLengthCunningham2);
	//redundancyCheckLength >>= 24;
	//if( redundancyCheckLength >= 2 ) 
	//{
	//	printf(".");
	//	uint32 mask = 1<<(multiplier&7);
	//	uint32 maskIdx = multiplier>>3;
	//	for(uint32 r=0; r<redundancyCheckLength; r++)
	//	{
	//		uint8* maskC1 = cSieve->layerMaskC1+((cSieve->currentSieveLayerIdx+r)%cSieve->chainLength)*cSieve->maskBytes;
	//		uint8* maskC2 = cSieve->layerMaskC1+((cSieve->currentSieveLayerIdx+r)%cSieve->chainLength)*cSieve->maskBytes;
	//		maskC1[maskIdx] |= mask;
	//		maskC2[maskIdx] |= mask;
	//	}
	//}
	// verify if there is any chance to find a biTwin that worth calculation
	if (nChainLengthCunningham1 < 0x2000000 || nChainLengthCunningham2 < 0x2000000)
		return (nChainLengthCunningham1 >= nBits || nChainLengthCunningham2 >= nBits);
	// Figure out BiTwin Chain length
	// BiTwin Chain allows a single prime at the end for odd length chain
	nChainLengthBiTwin =
		(TargetGetLength(nChainLengthCunningham1) > TargetGetLength(nChainLengthCunningham2))?
		(nChainLengthCunningham2 + TargetFromInt(TargetGetLength(nChainLengthCunningham2)+1)) :
	(nChainLengthCunningham1 + TargetFromInt(TargetGetLength(nChainLengthCunningham1)));

	return (nChainLengthCunningham1 >= nBits || nChainLengthCunningham2 >= nBits || nChainLengthBiTwin >= nBits);
}
Esempio n. 11
0
// Mine probable prime chain of form: n = h * p# +/- 1
bool MineProbablePrimeChain(Reap_CPU_param* state, Work& tempwork, CSieveOfEratosthenes& psieve, mpz_class& mpzFixedMultiplier, bool& fNewBlock, unsigned int& nTriedMultiplier, unsigned int& nProbableChainLength, unsigned int& nTests, unsigned int& nPrimesHit, unsigned int& nChainsHit, mpz_class& mpzHash, unsigned int nPrimorialMultiplier)
{
    nProbableChainLength = 0;
    nPrimesHit = 0;
    nChainsHit = 0;
    //const unsigned int nBits = block.nBits;
	const unsigned int nBits = *(uint*)&tempwork.data[72];
	
	bool use_gpu_fermat_test = globalconfs.coin.config.GetValue<bool>("use_gpu_fermat_test");

    if (fNewBlock && psieve.inited)
    {
        // Must rebuild the sieve
		psieve.Deinit();
    }
    fNewBlock = false;

    int64 nStart; // microsecond timer
    if (!psieve.inited)
    {
        // Build sieve
        nStart = ticker()*1000;
		psieve.InitAndWeave(state, nSieveSize, nBits, mpzHash, mpzFixedMultiplier);
        if (globalconfs.coin.config.GetValue<bool>("debug"))
            printf("MineProbablePrimeChain() : new sieve (%lu/%u) ready in %uus\n", psieve.CandidateList.size(), nSieveSize, (unsigned int) (ticker()*1000 - nStart));
    }

    mpz_class mpzHashMultiplier = mpzHash * mpzFixedMultiplier;
    mpz_class mpzChainOrigin;

    // Determine the sequence number of the round primorial
    unsigned int nPrimorialSeq = 0;
    while (vPrimes[nPrimorialSeq + 1] <= nPrimorialMultiplier)
        nPrimorialSeq++;

    // Allocate GMP variables for primality tests
    CPrimalityTestParams testParams(nBits, nPrimorialSeq);
    nStart = ticker()*1000;

    // References to counters;
    unsigned int& nChainLengthCunningham1 = testParams.nChainLengthCunningham1;
    unsigned int& nChainLengthCunningham2 = testParams.nChainLengthCunningham2;
    unsigned int& nChainLengthBiTwin = testParams.nChainLengthBiTwin;
	
	//cout << "PSIEVIOSIE" << psieve.CandidateList.size() << endl;
	
	for(uint i=0; i<psieve.CandidateList.size(); ++i)
    {
		nTriedMultiplier = psieve.CandidateList[i]&0x3FFFFFFFU;
		uint sievenumber = psieve.CandidateList[i]>>30;
		if (sievenumber == 0)
			sievenumber=3;
		if (nTriedMultiplier == 0) //will crash otherwise
			continue;
		++nTests;
		if (tempwork.time != current_work.time)
		{
			//cout << "Tempwork.time != curnetopqi" << tempwork.time << " " << current_work.time << endl;
			break;
		}
        mpzChainOrigin = mpzHashMultiplier * (nTriedMultiplier&0x3FFFFFFFU);
        nChainLengthCunningham1 = 0;
        nChainLengthCunningham2 = 0;
        nChainLengthBiTwin = 0;
        if (ProbablePrimeChainTestFast(mpzChainOrigin, testParams, sievenumber, use_gpu_fermat_test))
        {
			mpz_t mpzPrimeChainMultiplier; mpz_init(mpzPrimeChainMultiplier);
			mpz_mul_ui(mpzPrimeChainMultiplier,mpzFixedMultiplier.get_mpz_t(),nTriedMultiplier);
			{
				//gmp_printf("Found chain! Mult: %Zx\n",mpzPrimeChainMultiplier);
				vector<uchar> auxdata = XPM_create_auxdata(&mpzPrimeChainMultiplier);
				CPU_Got_share(state,tempwork,auxdata);
			}
			mpz_clear(mpzPrimeChainMultiplier);

            nProbableChainLength = std::max(std::max(nChainLengthCunningham1, nChainLengthCunningham2), nChainLengthBiTwin);
            return true;
        }
        nProbableChainLength = std::max(std::max(nChainLengthCunningham1, nChainLengthCunningham2), nChainLengthBiTwin);
        if(TargetGetLength(nProbableChainLength) >= 1)
            nPrimesHit++;
        if(TargetGetLength(nProbableChainLength) >= nStatsChainLength)
            nChainsHit++;
    }

	// power tests completed for the sieve
	//if (fDebug && GetBoolArg("-printmining"))
		//printf("MineProbablePrimeChain() : %u tests (%u primes and %u %d-chains) in %uus\n", nTests, nPrimesHit, nChainsHit, nStatsChainLength, (unsigned int) (GetTimeMicros() - nStart));
	psieve.Deinit();
	fNewBlock = true; // notify caller to change nonce
	return false; // stop as new block arrived
}
Esempio n. 12
0
// Test probable prime chain for: nOrigin
// Return value:
//   true - Probable prime chain found (one of nChainLength meeting target)
//   false - prime chain too short (none of nChainLength meeting target)
static bool ProbablePrimeChainTestFast(const mpz_class& mpzPrimeChainOrigin, CPrimalityTestParams& testParams, uint sievenumber, bool use_gpu_fermat_test)
{
    const unsigned int nBits = testParams.nBits;
	const unsigned int nBits_masked = nBits&TARGET_LENGTH_MASK;
    unsigned int& nChainLengthCunningham1 = testParams.nChainLengthCunningham1;
    unsigned int& nChainLengthCunningham2 = testParams.nChainLengthCunningham2;
    unsigned int& nChainLengthBiTwin = testParams.nChainLengthBiTwin;
    const bool fFermatTest = testParams.fFermatTest;
    mpz_class& mpzOriginMinusOne = testParams.mpzOriginMinusOne;
    mpz_class& mpzOriginPlusOne = testParams.mpzOriginPlusOne;
    nChainLengthCunningham1 = 0;
    nChainLengthCunningham2 = 0;
    nChainLengthBiTwin = 0;
	
    // Test for Cunningham Chain of first kind
	if (sievenumber&1)
	{
		mpzOriginMinusOne = mpzPrimeChainOrigin - 1;
		ProbableCunninghamChainTestFast(mpzOriginMinusOne, true, fFermatTest, nChainLengthCunningham1, testParams, use_gpu_fermat_test);
		if ((nChainLengthCunningham1&TARGET_FRACTIONAL_MASK) == 0)
			nChainLengthCunningham1 |= TARGET_FRACTIONAL_MASK;
	}
    // Test for Cunningham Chain of second kind
	if (sievenumber&2)
	{
		mpzOriginPlusOne = mpzPrimeChainOrigin + 1;
		ProbableCunninghamChainTestFast(mpzOriginPlusOne, false, fFermatTest, nChainLengthCunningham2, testParams, use_gpu_fermat_test);
		if ((nChainLengthCunningham2&TARGET_FRACTIONAL_MASK) == 0)
			nChainLengthCunningham2 |= TARGET_FRACTIONAL_MASK;
	}
	// Figure out BiTwin Chain length
    // BiTwin Chain allows a single prime at the end for odd length chain
    nChainLengthBiTwin =
        (TargetGetLength(nChainLengthCunningham1) > TargetGetLength(nChainLengthCunningham2))?
            (nChainLengthCunningham2 + TargetFromInt(TargetGetLength(nChainLengthCunningham2)+1)) :
            (nChainLengthCunningham1 + TargetFromInt(TargetGetLength(nChainLengthCunningham1)));
			
	uint c1 = TargetGetLength(nChainLengthCunningham1);
	uint c2 = TargetGetLength(nChainLengthCunningham2);
	uint tw = TargetGetLength(nChainLengthBiTwin);
	
	if (c1 >= 6)
	{
		cout << "C1 " << nChainLengthCunningham1 << " --> " << TargetToString(nChainLengthCunningham1) << " found!" << endl;
	}
	if (c2 >= 6)
	{
		cout << "C2 " << nChainLengthCunningham2 << " --> " << TargetToString(nChainLengthCunningham2) << " found!" << endl;
	}
	if (tw >= 6)
	{
		cout << "TW " << nChainLengthBiTwin << " --> " << TargetToString(nChainLengthBiTwin) << " found!" << endl;
	}
	
	++chainspersec[c1];
	++chainspersec[c2];
	++chainspersec[tw];
	++totalpersec;
	
    return (nChainLengthCunningham1 >= nBits || nChainLengthCunningham2 >= nBits || nChainLengthBiTwin >= nBits);
}