Skip to content

Commit

Permalink
Improve Primes.h further (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
cyberjunk authored Mar 7, 2024
1 parent 178b143 commit 2641dc4
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 100 deletions.
48 changes: 24 additions & 24 deletions include/CppCore.Test/Math/Primes.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,23 +157,23 @@ namespace CppCore { namespace Test { namespace Math
{
// test trivial cases
const bool t1 =
CppCore::Primes::isprime64(0ULL) == false &&
CppCore::Primes::isprime64(1ULL) == false &&
CppCore::Primes::isprime64(2ULL) == true &&
CppCore::Primes::isprime64(3ULL) == true;
CppCore::Primes::isprime64((uint64_t)0ULL) == false &&
CppCore::Primes::isprime64((uint64_t)1ULL) == false &&
CppCore::Primes::isprime64((uint64_t)2ULL) == true &&
CppCore::Primes::isprime64((uint64_t)3ULL) == true;
if (!t1)
return false;

// test precomputed 256 first odd primes
// test precomputed first odd primes
for (size_t i = 0; i < CppCore::Primes::NUMODDPRIMES; i++)
if (!CppCore::Primes::isprime64((uint64_t)CppCore::Primes::ODDPRIMES[i]))
return false;

// test some special primes
const bool t2 =
CppCore::Primes::isprime64(20771ULL) &&
CppCore::Primes::isprime64(40487ULL) &&
CppCore::Primes::isprime64(2481757ULL) &&
CppCore::Primes::isprime64((uint64_t)20771ULL) &&
CppCore::Primes::isprime64((uint64_t)40487ULL) &&
CppCore::Primes::isprime64((uint64_t)2481757ULL) &&
CppCore::Primes::isprime64((uint64_t)CppCore::Primes::MAX32S) &&
CppCore::Primes::isprime64((uint64_t)CppCore::Primes::MAX32U) &&
CppCore::Primes::isprime64((uint64_t)CppCore::Primes::MAX64S) &&
Expand All @@ -198,46 +198,46 @@ namespace CppCore { namespace Test { namespace Math
{
// test trivial cases
const bool t1 =
uint128_t(0ULL).isprime() == CppCore::Primes::Result::NotPrime &&
uint128_t(1ULL).isprime() == CppCore::Primes::Result::NotPrime &&
uint128_t(2ULL).isprime() == CppCore::Primes::Result::Prime &&
uint128_t(3ULL).isprime() == CppCore::Primes::Result::Prime;
CppCore::Primes::isprime(uint128_t(0ULL), false) == CppCore::Primes::Result::NotPrime &&
CppCore::Primes::isprime(uint128_t(1ULL), false) == CppCore::Primes::Result::NotPrime &&
CppCore::Primes::isprime(uint128_t(2ULL), false) == CppCore::Primes::Result::Prime &&
CppCore::Primes::isprime(uint128_t(3ULL), false) == CppCore::Primes::Result::Prime;
if (!t1)
return false;

// test precomputed 512 first odd primes
for (size_t i = 0; i < CppCore::Primes::NUMODDPRIMES; i++)
if (uint128_t((uint64_t)CppCore::Primes::ODDPRIMES[i]).isprime() != CppCore::Primes::Result::Prime)
if (CppCore::Primes::isprime(uint128_t((uint64_t)CppCore::Primes::ODDPRIMES[i]), false) != CppCore::Primes::Result::Prime)
return false;

// test some covered primes which are guaranteed to be true or false
const bool t2 =
uint128_t(20771ULL).isprime() == CppCore::Primes::Result::Prime &&
uint128_t(40487ULL).isprime() == CppCore::Primes::Result::Prime &&
uint128_t(2481757ULL).isprime() == CppCore::Primes::Result::Prime &&
uint128_t((uint64_t)CppCore::Primes::MAX32S).isprime() == CppCore::Primes::Result::Prime &&
uint128_t((uint64_t)CppCore::Primes::MAX32U).isprime() == CppCore::Primes::Result::Prime &&
uint128_t((uint64_t)CppCore::Primes::MAX64S).isprime() == CppCore::Primes::Result::Prime &&
uint128_t((uint64_t)CppCore::Primes::MAX64U).isprime() == CppCore::Primes::Result::Prime &&
uint128_t(CppCore::Primes::SMALL128).isprime() == CppCore::Primes::Result::Prime;
CppCore::Primes::isprime(uint128_t(20771ULL), false) == CppCore::Primes::Result::Prime &&
CppCore::Primes::isprime(uint128_t(40487ULL), false) == CppCore::Primes::Result::Prime &&
CppCore::Primes::isprime(uint128_t(2481757ULL), false) == CppCore::Primes::Result::Prime &&
CppCore::Primes::isprime(uint128_t((uint64_t)CppCore::Primes::MAX32S), false) == CppCore::Primes::Result::Prime &&
CppCore::Primes::isprime(uint128_t((uint64_t)CppCore::Primes::MAX32U), false) == CppCore::Primes::Result::Prime &&
CppCore::Primes::isprime(uint128_t((uint64_t)CppCore::Primes::MAX64S), false) == CppCore::Primes::Result::Prime &&
CppCore::Primes::isprime(uint128_t((uint64_t)CppCore::Primes::MAX64U), false) == CppCore::Primes::Result::Prime &&
CppCore::Primes::isprime(uint128_t(CppCore::Primes::SMALL128), false) == CppCore::Primes::Result::Prime;
if (!t2)
return false;

// test mersenne primes (any size gives true)
const bool t3 =
uint128_t(CppCore::Primes::MERSENNE128).isprime() == CppCore::Primes::Result::Prime;
CppCore::Primes::isprime(uint128_t(CppCore::Primes::MERSENNE128), false) == CppCore::Primes::Result::Prime;
if (!t3)
return false;

// test some uncovered high known primes
const bool t4 =
uint128_t(CppCore::Primes::LARGE128).isprime() == CppCore::Primes::Result::LikelyPrime;
CppCore::Primes::isprime(uint128_t(CppCore::Primes::LARGE128), false) == CppCore::Primes::Result::LikelyPrime;
if (!t4)
return false;

// test some uncovered perfect squares of high primes
const bool t5 =
(uint128_t(CppCore::Primes::MAX64U) * uint128_t(CppCore::Primes::MAX64U)).isprime() == CppCore::Primes::Result::NotPrime;
CppCore::Primes::isprime(uint128_t(CppCore::Primes::MAX64U) * uint128_t(CppCore::Primes::MAX64U), false) == CppCore::Primes::Result::NotPrime;
if (!t5)
return false;

Expand Down
11 changes: 6 additions & 5 deletions include/CppCore/Crypto/DH.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <CppCore/Root.h>
#include <CppCore/Math/BigInt.h>
#include <CppCore/Math/Primes.h>

namespace CppCore
{
Expand Down Expand Up @@ -40,7 +41,7 @@ namespace CppCore
}
INLINE void genprime(uint32_t certainty)
{
p.genprime(certainty);
CppCore::Primes::genprime(p, false, certainty);
}
INLINE void genpubkey()
{
Expand All @@ -67,7 +68,7 @@ namespace CppCore
INLINE void reset(const UINT& p, const UINT& g)
{
assert(CppCore::lzcnt(p) == 0);
assert(p.isprime(1));
assert(CppCore::Primes::isprime(p, false, 1));
assert(g < p);
CppCore::clone(this->p, p);
CppCore::clone(this->g, g);
Expand All @@ -83,7 +84,7 @@ namespace CppCore
Memory::singlecopy(&this->p, p);
Memory::singlecopy(&this->g, g);
assert(CppCore::lzcnt(this->p) == 0);
assert(this->p.isprime(1));
assert(CppCore::Primes::isprime(this->p, false, 1));
assert(this->g < this->p);
this->genrnd(v);
this->genpubkey();
Expand All @@ -95,7 +96,7 @@ namespace CppCore
/// </summary>
INLINE void reset(const UINT& p, const UINT& g, const UINT& v)
{
assert(p.isprime(1));
assert(CppCore::Primes::isprime(p, false, 1));
assert(g < p);
assert(v < p);
CppCore::clone(this->p, p);
Expand All @@ -112,7 +113,7 @@ namespace CppCore
Memory::singlecopy(&this->p, p);
Memory::singlecopy(&this->g, g);
Memory::singlecopy(&this->v, v);
assert(this->p.isprime(1));
assert(CppCore::Primes::isprime(this->p, false, 1));
assert(this->g < this->p);
assert(this->v < this->p);
this->genpubkey();
Expand Down
44 changes: 0 additions & 44 deletions include/CppCore/Math/BigInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include <CppCore/Root.h>
#include <CppCore/Memory.h>
#include <CppCore/Math/Util.h>
#include <CppCore/Math/Primes.h>
#include <CppCore/Encoding.h>
#include <CppCore/Random.h>

Expand Down Expand Up @@ -2378,49 +2377,6 @@ namespace CppCore
Random::Default prng;
thiss()->randomize(prng);
}

/////////////////////////////////////////////////////////////////////////////////////////////
// PRIMES
/////////////////////////////////////////////////////////////////////////////////////////////

/// <summary>
/// Test if this is a prime number.
/// </summary>
INLINE Primes::Result isprime(Primes::Memory<TC>& mem, uint32_t maxidx = Primes::DEFAULTMAXIDX) const
{
return Primes::isprime(*thiss(), mem, maxidx);
}

/// <summary>
/// Like other variant, but with temporary work memory on stack.
/// </summary>
INLINE Primes::Result isprime(uint32_t maxidx = Primes::DEFAULTMAXIDX) const
{
return Primes::isprime(*thiss(), maxidx);
}

/// <summary>
/// Turn into a strong probable prime
/// </summary>
template<typename PRNG>
INLINE void genprime(PRNG& prng, Primes::Memory<TC>& mem, uint32_t maxidx = Primes::DEFAULTMAXIDX)
{
do {
thiss()->randomize(prng);
d.i32[0] |= 0x00000001U;
d.i32[N32-1] |= 0x80000000U;
} while (Primes::isprime(*thiss(), mem, maxidx) == Primes::NotPrime);
}

/// <summary>
/// Turn into a strong probable prime
/// </summary>
INLINE void genprime(uint32_t maxidx = Primes::DEFAULTMAXIDX)
{
Primes::Memory<TC> mem;
Random::Default prng;
thiss()->genprime(prng, mem, maxidx);
}
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
Loading

0 comments on commit 2641dc4

Please sign in to comment.