Example #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)
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);
}
Example #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)
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);
}
// 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);
}
// 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);
}