示例#1
0
// Test Probable BiTwin Chain for: mpzOrigin
// Test the numbers in the optimal order for any given chain length
// Gives the correct length of a BiTwin chain even for short chains
static void ProbableBiTwinChainTestFast(const mpz_class& mpzOrigin, unsigned int& nProbableChainLength, CPrimalityTestParams& testParams)
{
    mpz_class& mpzOriginMinusOne = testParams.mpzOriginMinusOne;
    mpz_class& mpzOriginPlusOne = testParams.mpzOriginPlusOne;
    nProbableChainLength = 0;

    // Fermat test for origin-1 first
    mpzOriginMinusOne = mpzOrigin - 1;
    if (!FermatProbablePrimalityTestFast(mpzOriginMinusOne, nProbableChainLength, testParams, true))
        return;
    TargetIncrementLength(nProbableChainLength);

    // Fermat test for origin+1
    mpzOriginPlusOne = mpzOrigin + 1;
    if (!FermatProbablePrimalityTestFast(mpzOriginPlusOne, nProbableChainLength, testParams, true))
        return;
    TargetIncrementLength(nProbableChainLength);

    // Euler-Lagrange-Lifchitz test for the following numbers in chain
    for (unsigned int nChainSeq = 2; true; nChainSeq += 2)
    {
        mpzOriginMinusOne <<= 1;
        mpzOriginMinusOne++;
        bool fFastFail = nChainSeq < 4;
        if (!EulerLagrangeLifchitzPrimalityTestFast(mpzOriginMinusOne, true, nProbableChainLength, testParams, fFastFail))
            break;
        TargetIncrementLength(nProbableChainLength);

        mpzOriginPlusOne <<= 1;
        mpzOriginPlusOne--;
        if (!EulerLagrangeLifchitzPrimalityTestFast(mpzOriginPlusOne, false, nProbableChainLength, testParams, fFastFail))
            break;
        TargetIncrementLength(nProbableChainLength);
    }
}
示例#2
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 ProbableCunninghamChainTestFast(const mpz_class& n,
                                            bool fSophieGermain,
                                            bool fFermatTest,
                                            unsigned int& nProbableChainLength,
                                            CPrimalityTestParams& testParams)
{
  nProbableChainLength = 0;
  
  // Fermat test for n first
  if (!FermatProbablePrimalityTestFast(n, nProbableChainLength, testParams, true))
    return false;
  
  // Euler-Lagrange-Lifchitz test for the following numbers in chain
  mpz_class &N = testParams.N;
  N = n;
  while (true) {
    incrementChainLengthInBits(&nProbableChainLength);
    N <<= 1;
    N += (fSophieGermain? 1 : (-1));
    if (fFermatTest) {
      if (!FermatProbablePrimalityTestFast(N, nProbableChainLength, testParams))
        break;
    } else {
      if (!EulerLagrangeLifchitzPrimalityTestFast(N, fSophieGermain, nProbableChainLength, testParams))
        break;
    }
  }
  
  return (chainLengthFromBits(nProbableChainLength) >= 2);
}
// 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);
}
示例#4
0
bool ProbablePrimalityTestWithTrialDivisionFast(const mpz_class &candidate,
                                                unsigned trialDivisionLimit,
                                                const PrimeSource &primeSource,
                                                CPrimalityTestParams &testParams)
{
  for (unsigned i = 0; i < trialDivisionLimit; i++) {
    if (candidate % primeSource.prime(i) == 0)
      return false;
  }
  unsigned nLength = 0;
  return FermatProbablePrimalityTestFast(candidate, nLength, testParams, true);
}
示例#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, ...)
static void ProbableCunninghamChainTestFast(const mpz_class& n, bool fSophieGermain, unsigned int& nProbableChainLength, CPrimalityTestParams& testParams)
{
    nProbableChainLength = 0;

    // Fermat test for n first
    if (!FermatProbablePrimalityTestFast(n, nProbableChainLength, testParams, true))
        return;

    // Euler-Lagrange-Lifchitz test for the following numbers in chain
    mpz_class &N = testParams.mpzN;
    N = n;
    for (unsigned int nChainSeq = 1; true; nChainSeq++)
    {
        TargetIncrementLength(nProbableChainLength);
        N <<= 1;
        N += (fSophieGermain? 1 : (-1));
        bool fFastFail = nChainSeq < 4;
        if (!EulerLagrangeLifchitzPrimalityTestFast(N, fSophieGermain, nProbableChainLength, testParams, fFastFail))
            break;
    }
}