Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions include/CppCore.Interface.C/cppcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,18 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// macro for large integer arithmetic function declarations
#define CPPCORE_UINT_DECLARATION(name) \
CPPCORE_EXPORT void name ## _shl (void* a, unsigned int b, void* r); \
CPPCORE_EXPORT void name ## _shr (void* a, unsigned int b, void* r); \
CPPCORE_EXPORT void name ## _add (void* a, void* b, void* r); \
CPPCORE_EXPORT void name ## _sub (void* a, void* b, void* r); \
CPPCORE_EXPORT void name ## _mul (void* a, void* b, void* r); \
CPPCORE_EXPORT void name ## _square(void* a, void* r); \
CPPCORE_EXPORT void name ## _divmod(void* a, void* b, void* q, void* r); \
CPPCORE_EXPORT void name ## _mulmod(void* a, void* b, void* m, void* r); \
CPPCORE_EXPORT void name ## _powmod(void* a, void* b, void* m, void* r); \
CPPCORE_EXPORT void name ## _gcd (void* a, void* b, void* r);
#define CPPCORE_UINT_DECLARATION(name) \
CPPCORE_EXPORT void name ## _shl (void* a, unsigned int b, void* r); \
CPPCORE_EXPORT void name ## _shr (void* a, unsigned int b, void* r); \
CPPCORE_EXPORT void name ## _add (void* a, void* b, void* r); \
CPPCORE_EXPORT void name ## _sub (void* a, void* b, void* r); \
CPPCORE_EXPORT void name ## _mul (void* a, void* b, void* r); \
CPPCORE_EXPORT void name ## _square (void* a, void* r); \
CPPCORE_EXPORT void name ## _divmod (void* a, void* b, void* q, void* r); \
CPPCORE_EXPORT void name ## _mulmod (void* a, void* b, void* m, void* r); \
CPPCORE_EXPORT void name ## _squaremod(void* a, void* m, void* r); \
CPPCORE_EXPORT void name ## _powmod (void* a, void* b, void* m, void* r); \
CPPCORE_EXPORT void name ## _gcd (void* a, void* b, void* r);

// macro for basex function declarations
#define CPPCORE_BASEX_DECLARATION(size) \
Expand Down
35 changes: 30 additions & 5 deletions include/CppCore.Test/Math/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -493,16 +493,41 @@ namespace CppCore { namespace Test { namespace Math

INLINE static bool usquare()
{
uint64_t a[4] = { 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL };
uint64_t r1[9] = { 0x0000000000000001ULL,0x0000000000000000ULL,0x0000000000000000ULL,0x0000000000000000ULL,
uint64_t a1[4] = { 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL };
uint64_t r1_1[9] = { 0x0000000000000001ULL,0x0000000000000000ULL,0x0000000000000000ULL,0x0000000000000000ULL,
0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
0x0000000000000000ULL };
uint64_t r2[9];
CppCore::usquare(a, r2);
if (!CppCore::equal(r1, r2))
uint64_t r1_2[9];
CppCore::usquare(a1, r1_2);
if (!CppCore::equal(r1_1, r1_2))
return false;

uint64_t a2 = 2;
uint64_t r2_1[2] = { 0x000000000004ULL, 0x0000000000000000ULL };
uint64_t r2_2[2];
CppCore::usquare(a2, r2_2);
if (!CppCore::equal(r2_1, r2_2))
return false;

uint64_t a3[2] = { 0x000000000002ULL, 0x0000000000000000ULL };
uint64_t r3_1 = 0x000000000004ULL;
uint64_t r3_2;
CppCore::usquare(a3, r3_2);
if (!CppCore::equal(r3_1, r3_2))
return false;

uint64_t a4 = 2;
uint64_t r4_1 = 4;
uint64_t r4_2;
CppCore::usquare(a4, r4_2);
if (!CppCore::equal(r4_1, r4_2))
return false;

return
usquare_template<1, 1>() &&
usquare_template<1, 2>() &&
usquare_template<1, 3>() &&
usquare_template<2, 1>() &&
usquare_template<4, 2>() &&
usquare_template<4, 4>() &&
usquare_template<4, 8>() &&
Expand Down
7 changes: 3 additions & 4 deletions include/CppCore/Math/Primes.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,7 @@ namespace CppCore
return true;
for (uint32_t i = 1U; i < s; i++)
{
//TODO: usquaremod
CppCore::umulmod(r, r, n, r, m);
CppCore::usquaremod(r, n, r, m);
if (r <= 1U) return false;
if (r == t) return true;
}
Expand Down Expand Up @@ -314,7 +313,7 @@ namespace CppCore
UINTX2 mem[2];
for (uint32_t i = 2U; i < ith; i++)
{
CppCore::umul(s, s, r);
CppCore::usquare(s, r);
CppCore::usub(r, (size_t)2U, r);
CppCore::umod(s, r, n, mem);
}
Expand Down Expand Up @@ -418,7 +417,7 @@ namespace CppCore

// perfect square root test
CppCore::isqrt(n, t);
CppCore::umul(t, t, d);
CppCore::usquare(t, d);
if (CppCore::equal(n, d))
return Primes::NotPrime;

Expand Down
96 changes: 91 additions & 5 deletions include/CppCore/Math/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -2951,7 +2951,10 @@ namespace CppCore
rp[i] = 0ULL;
// calculate one triangle
rp[0] = 0ULL;
CppCore::umul128(ap[0], ap[1], rp[1], k);
if (NA > 1 && NR > 1)
CppCore::umul128(ap[0], ap[1], rp[1], k);
else
k = 0ULL;
for (size_t j = 2; j < MIN(NA,NR); j++)
{
CppCore::umul128(ap[0], ap[j], tl, th);
Expand Down Expand Up @@ -3006,7 +3009,10 @@ namespace CppCore
rp[i] = 0U;
// calculate one triangle
rp[0] = 0U;
CppCore::umul64(ap[0], ap[1], rp[1], k);
if (NA > 1 && NR > 1)
CppCore::umul64(ap[0], ap[1], rp[1], k);
else
k = 0U;
for (size_t j = 2; j < MIN(NA,NR); j++)
{
CppCore::umul64(ap[0], ap[j], tl, th);
Expand Down Expand Up @@ -3980,6 +3986,87 @@ namespace CppCore
}
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SQUAREMOD
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/// <summary>
/// a*a mod m. For any sized integers that are multiples of 32-bit.
/// </summary>
template<typename UINT>
INLINE static void usquaremod(const UINT& a, const UINT& m, UINT& r, UINT p[3])
{
struct UINTX2 { UINT x[2]; };
CppCore::usquare<UINT, UINTX2>(a, *(UINTX2*)p);
CppCore::umod<UINTX2, UINT>(r, *(UINTX2*)p, m, (UINTX2*)p);
}

/// <summary>
/// a*a mod m. For any sized integers that are multiples of 32-bit.
/// </summary>
template<typename UINT>
INLINE static void usquaremod(const UINT& a, const UINT& m, UINT& r)
{
CPPCORE_ALIGN_OPTIM(UINT) p[3];
CppCore::usquaremod(a, m, r, p);
}

/// <summary>
/// Template Specialization for 16-Bit Unsigned.
/// </summary>
template<> INLINE void usquaremod(const uint16_t& a, const uint16_t& m, uint16_t& r, uint16_t p[3])
{
CppCore::umulmod16(a, a, m, r);
}

/// <summary>
/// Template Specialization for 16-Bit Unsigned.
/// </summary>
template<> INLINE void usquaremod(const uint16_t& a, const uint16_t& m, uint16_t& r)
{
CppCore::umulmod16(a, a, m, r);
}

/// <summary>
/// Template Specialization for 32-Bit Unsigned.
/// </summary>
template<> INLINE void usquaremod(const uint32_t& a, const uint32_t& m, uint32_t& r, uint32_t p[3])
{
CppCore::umulmod32(a, a, m, r);
}

/// <summary>
/// Template Specialization for 32-Bit Unsigned.
/// </summary>
template<> INLINE void usquaremod(const uint32_t& a, const uint32_t& m, uint32_t& r)
{
CppCore::umulmod32(a, a, m, r);
}

/// <summary>
/// Template Specialization for 64-Bit Unsigned.
/// </summary>
template<> INLINE void usquaremod(const uint64_t& a, const uint64_t& m, uint64_t& r, uint64_t p[3])
{
#if defined(CPPCORE_CPU_X64)
CppCore::umulmod64(a, a, m, r);
#else
CppCore::umulmod(a, a, m, r);
#endif
}

/// <summary>
/// Template Specialization for 64-Bit Unsigned.
/// </summary>
template<> INLINE void usquaremod(const uint64_t& a, const uint64_t& m, uint64_t& r)
{
#if defined(CPPCORE_CPU_X64)
CppCore::umulmod64(a, a, m, r);
#else
CppCore::umulmod(a, a, m, r);
#endif
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// POWMOD
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -4006,7 +4093,7 @@ namespace CppCore
{
if (CppCore::bittest(b, i))
CppCore::umulmod(r, a, m, r, t);
CppCore::umulmod(a, a, m, a, t); //TODO: usquaremod
CppCore::usquaremod(a, m, a, t);
}
}

Expand Down Expand Up @@ -4053,10 +4140,9 @@ namespace CppCore

// Process k bits at a time from left to right (MSB to LSB)
for (int pos = HIDX_K - K; pos >= 0; pos -= K) {

if (pos < HIDX_K - K)
for (size_t i = 0; i < K; i++)
CppCore::umulmod(r, r, m, r, t);
CppCore::usquaremod(r, m, r, t);
const uint32_t N = MIN(K, NUMBITS-pos);
const uint32_t CHUNK = CppCore::getbits32(b, pos, N);
CppCore::umulmod(r, powers[CHUNK], m, r, t);
Expand Down
23 changes: 12 additions & 11 deletions src/CppCore.Interface.C/cppcore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,18 @@ void cppcore_free (void* ptr) { CPPCORE_ALIGNED_FREE(ptr); }
#include <CppCore/Math/Util.h>
#include <CppCore/Block.h>

#define CPPCORE_UINT_IMPLEMENTATION(name, cname) \
void name ## _shl (void* a, unsigned int b, void* r) { CppCore::shl(*(cname*)r, *(cname*)a, b);} \
void name ## _shr (void* a, unsigned int b, void* r) { CppCore::shr(*(cname*)r, *(cname*)a, b);} \
void name ## _add (void* a, void* b, void* r) { CppCore::uadd(*(cname*)a, *(cname*)b, *(cname*)r);} \
void name ## _sub (void* a, void* b, void* r) { CppCore::usub(*(cname*)a, *(cname*)b, *(cname*)r);} \
void name ## _mul (void* a, void* b, void* r) { CppCore::umul(*(cname*)a, *(cname*)b, *(cname*)r);} \
void name ## _square(void* a, void* r) { CppCore::usquare(*(cname*)a, *(cname*)r);} \
void name ## _divmod(void* a, void* b, void* q, void* r){ CppCore::udivmod(*(cname*)q,*(cname*)r,*(cname*)a,*(cname*)b);}\
void name ## _mulmod(void* a, void* b, void* m, void* r){ CppCore::umulmod(*(cname*)a,*(cname*)b,*(cname*)m,*(cname*)r);}\
void name ## _powmod(void* a, void* b, void* m, void* r){ CppCore::upowmod(*(cname*)a,*(cname*)b,*(cname*)m,*(cname*)r);}\
void name ## _gcd (void* a, void* b, void* r) { CppCore::gcd(*(cname*)a, *(cname*)b, *(cname*)r);}
#define CPPCORE_UINT_IMPLEMENTATION(name, cname) \
void name ## _shl (void* a, unsigned int b, void* r) { CppCore::shl(*(cname*)r, *(cname*)a, b);} \
void name ## _shr (void* a, unsigned int b, void* r) { CppCore::shr(*(cname*)r, *(cname*)a, b);} \
void name ## _add (void* a, void* b, void* r) { CppCore::uadd(*(cname*)a, *(cname*)b, *(cname*)r);} \
void name ## _sub (void* a, void* b, void* r) { CppCore::usub(*(cname*)a, *(cname*)b, *(cname*)r);} \
void name ## _mul (void* a, void* b, void* r) { CppCore::umul(*(cname*)a, *(cname*)b, *(cname*)r);} \
void name ## _square (void* a, void* r) { CppCore::usquare(*(cname*)a, *(cname*)r);} \
void name ## _divmod (void* a, void* b, void* q, void* r){ CppCore::udivmod(*(cname*)q,*(cname*)r,*(cname*)a,*(cname*)b);}\
void name ## _mulmod (void* a, void* b, void* m, void* r){ CppCore::umulmod(*(cname*)a,*(cname*)b,*(cname*)m,*(cname*)r);}\
void name ## _squaremod(void* a, void* m, void* r) { CppCore::usquaremod(*(cname*)a,*(cname*)m,*(cname*)r);} \
void name ## _powmod (void* a, void* b, void* m, void* r){ CppCore::upowmod(*(cname*)a,*(cname*)b,*(cname*)m,*(cname*)r);}\
void name ## _gcd (void* a, void* b, void* r) { CppCore::gcd(*(cname*)a, *(cname*)b, *(cname*)r);}

CPPCORE_UINT_IMPLEMENTATION(cppcore_uint32, std::uint32_t)
CPPCORE_UINT_IMPLEMENTATION(cppcore_uint64, std::uint64_t)
Expand Down
Loading