Skip to content
Open
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
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ target_link_libraries(hurchalla_modular_arithmetic
target_link_libraries(hurchalla_modular_arithmetic
INTERFACE hurchalla_montgomery_arithmetic)


# Our use of if constexpr() requires C++ >= 2017
target_compile_features(hurchalla_modular_arithmetic INTERFACE cxx_std_17)

# TODO: The following may be overly simple, but works so far to install target
# include directories. It assumes that the build step from the subdirectories
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ typename MF::MontgomeryValue montgomery_pow_kary(const MF& mf, typename MF::Mont
using V = typename MF::MontgomeryValue;
using std::size_t;

constexpr size_t P = 4; // (1 << P) == the k in k-ary exponentiation
constexpr int P = 4; // (1 << P) == the k in k-ary exponentiation

// initialize the precalculation table for k-ary pow algorithm
static_assert(P > 0, "");
Expand All @@ -56,17 +56,17 @@ typename MF::MontgomeryValue montgomery_pow_kary(const MF& mf, typename MF::Mont
V table[TABLESIZE];
table[0] = mf.getUnityValue(); // montgomery one
table[1] = x;
if (TABLESIZE == 4) {
if constexpr (TABLESIZE == 4) {
table[2] = mf.square(x);
table[3] = mf.multiply(x, table[2]);
} else if (TABLESIZE == 8) {
} else if constexpr (TABLESIZE == 8) {
table[2] = mf.square(x);
table[3] = mf.multiply(x, table[2]);
table[4] = mf.square(table[2]);
table[5] = mf.multiply(table[2], table[3]);
table[6] = mf.square(table[3]);
table[7] = mf.multiply(table[3], table[4]);
} else if (TABLESIZE == 16) {
} else if constexpr (TABLESIZE == 16) {
table[2] = mf.square(x);
table[3] = mf.multiply(x, table[2]);
table[4] = mf.square(table[2]);
Expand All @@ -81,7 +81,7 @@ typename MF::MontgomeryValue montgomery_pow_kary(const MF& mf, typename MF::Mont
table[13] = mf.multiply(table[6], table[7]);
table[14] = mf.square(table[7]);
table[15] = mf.multiply(table[7], table[8]);
} else if (TABLESIZE == 32) {
} else if constexpr (TABLESIZE == 32) {
table[2] = mf.square(x);
table[3] = mf.multiply(x, table[2]);
table[4] = mf.square(table[2]);
Expand Down Expand Up @@ -140,15 +140,15 @@ typename MF::MontgomeryValue montgomery_pow_kary(const MF& mf, typename MF::Mont
// because we returned above if (n <= MASK), we can assert the following:
HPBC_ASSERT(numbits > P);

int shift = numbits - static_cast<int>(P);
int shift = numbits - P;
U tmp = n >> shift;
HPBC_ASSERT(tmp <= MASK);
// normally we'd use (tmp & MASK), but it's redundant with tmp <= MASK
size_t index = static_cast<size_t>(tmp);
V result = table[index];


while (shift >= static_cast<int>(P)) {
while (shift >= P) {
// HURCHALLA_REQUEST_UNROLL_LOOP
for (size_t i=0; i<P; ++i)
result = mf.square(result);
Expand All @@ -160,7 +160,7 @@ typename MF::MontgomeryValue montgomery_pow_kary(const MF& mf, typename MF::Mont
--shift;
}
#endif
shift -= static_cast<int>(P);
shift -= P;
// TODO: maybe optimize next line, since n may be > 64bit
tmp = n >> shift;
index = static_cast<size_t>(tmp) & MASK;
Expand Down Expand Up @@ -204,7 +204,7 @@ array_montgomery_pow_kary(const std::array<MF, ARRAY_SIZE>& mf,
using V = typename MF::MontgomeryValue;
using std::size_t;

constexpr size_t P = 4; // (1 << P) == the k in k-ary exponentiation
constexpr int P = 4; // (1 << P) == the k in k-ary exponentiation

// initialize the precalculation table for k-ary pow algorithm
static_assert(P > 0, "");
Expand Down Expand Up @@ -256,7 +256,7 @@ array_montgomery_pow_kary(const std::array<MF, ARRAY_SIZE>& mf,
// because we returned above if (n_max <= MASK), we can assert the following:
HPBC_ASSERT(numbits > P);

int shift = numbits - static_cast<int>(P);
int shift = numbits - P;
std::array<V, ARRAY_SIZE> result;
std::array<U, ARRAY_SIZE> tmp;
HURCHALLA_REQUEST_UNROLL_LOOP for (size_t j=0; j<ARRAY_SIZE; ++j) {
Expand All @@ -267,12 +267,12 @@ array_montgomery_pow_kary(const std::array<MF, ARRAY_SIZE>& mf,
}


while (shift >= static_cast<int>(P)) {
while (shift >= P) {
for (size_t i=0; i<P; ++i) {
HURCHALLA_REQUEST_UNROLL_LOOP for (size_t j=0; j<ARRAY_SIZE; ++j)
result[j] = mf[j].square(result[j]);
}
shift -= static_cast<int>(P);
shift -= P;
std::array<size_t, ARRAY_SIZE> index;
HURCHALLA_REQUEST_UNROLL_LOOP for (size_t j=0; j<ARRAY_SIZE; ++j) {
// TODO: maybe optimize next line, since n may be > 64bit
Expand Down Expand Up @@ -333,7 +333,7 @@ array_montgomery_pow_kary(const MF& mf,
using V = typename MF::MontgomeryValue;
using std::size_t;

constexpr size_t P = 4; // (1 << P) == the k in k-ary exponentiation
constexpr int P = 4; // (1 << P) == the k in k-ary exponentiation

// initialize the precalculation table for k-ary pow algorithm
static_assert(P > 0, "");
Expand Down Expand Up @@ -379,9 +379,9 @@ array_montgomery_pow_kary(const MF& mf,
int leading_zeros = count_leading_zeros(n_max);
int numbits = ut_numeric_limits<decltype(n_max)>::digits - leading_zeros;
// because we returned above if (n_max <= MASK), we can assert the following:
HPBC_ASSERT(numbits > static_cast<int>(P));
HPBC_ASSERT(numbits > P);

int shift = numbits - static_cast<int>(P);
int shift = numbits - P;
std::array<V, ARRAY_SIZE> result;
size_t tmp = static_cast<size_t>(n >> shift);
HPBC_ASSERT(tmp <= MASK);
Expand All @@ -391,21 +391,21 @@ array_montgomery_pow_kary(const MF& mf,
}


while (shift >= static_cast<int>(P)) {
while (shift >= P) {
for (size_t i=0; i<P; ++i) {
HURCHALLA_REQUEST_UNROLL_LOOP for (size_t j=0; j<ARRAY_SIZE; ++j)
result[j] = mf.square(result[j]);
}
#if 1
// sliding window optimization
// TODO: maybe optimize the shift in the next line, since n may be > 64bit
while (shift > static_cast<int>(P) && (static_cast<size_t>(n >> (shift-1)) & 1) == 0) {
while (shift > P && (static_cast<size_t>(n >> (shift-1)) & 1) == 0) {
HURCHALLA_REQUEST_UNROLL_LOOP for (size_t j=0; j<ARRAY_SIZE; ++j)
result[j] = mf.square(result[j]);
--shift;
}
#endif
shift -= static_cast<int>(P);
shift -= P;
// TODO: maybe optimize next line, since n may be > 64bit
size_t index = static_cast<size_t>(n >> shift) & MASK;
HURCHALLA_REQUEST_UNROLL_LOOP for (size_t j=0; j<ARRAY_SIZE; ++j) {
Expand All @@ -416,7 +416,7 @@ array_montgomery_pow_kary(const MF& mf,

if (shift == 0)
return result;
HPBC_ASSERT(0 < shift && shift < static_cast<int>(P));
HPBC_ASSERT(0 < shift && shift < P);

for (int i=0; i<shift; ++i) {
HURCHALLA_REQUEST_UNROLL_LOOP for (size_t j=0; j<ARRAY_SIZE; ++j)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ typename MF::MontgomeryValue montgomery_two_pow(const MF& mf, U n)
using C = typename MF::CanonicalValue;
using std::size_t;

constexpr size_t P = 5; // (1 << P) == the k in k-ary exponentiation
constexpr int P = 5; // (1 << P) == the k in k-ary exponentiation

// initialize the precalculation table for k-ary pow algorithm
static_assert(P > 0);
constexpr size_t TABLESIZE = 1 << P;
C table[TABLESIZE];
table[0] = mf.getUnityValue(); // montgomery one
for (int i=1; i<TABLESIZE; ++i)
for (size_t i=1; i<TABLESIZE; ++i)
table[i] = mf.add(table[i-1], table[i-1]);

constexpr size_t MASK = TABLESIZE - 1;
Expand All @@ -62,15 +62,15 @@ typename MF::MontgomeryValue montgomery_two_pow(const MF& mf, U n)
// because we returned above if (n <= MASK), we can assert the following:
HPBC_ASSERT(numbits > P);

int shift = numbits - static_cast<int>(P);
int shift = numbits - P;
U tmp = n >> shift;
HPBC_ASSERT(tmp <= MASK);
// normally we'd use (tmp & MASK), but it's redundant with tmp <= MASK
size_t index = static_cast<size_t>(tmp);
V result = table[index];


while (shift >= static_cast<int>(P)) {
while (shift >= P) {
// HURCHALLA_REQUEST_UNROLL_LOOP
for (int i=0; i<P; ++i)
result = mf.square(result);
Expand All @@ -82,7 +82,7 @@ typename MF::MontgomeryValue montgomery_two_pow(const MF& mf, U n)
--shift;
}
#endif
shift -= static_cast<int>(P);
shift -= P;
// TODO: maybe optimize next line, since n may be > 64bit
tmp = n >> shift;
index = static_cast<size_t>(tmp) & MASK;
Expand Down Expand Up @@ -116,15 +116,15 @@ array_montgomery_two_pow(const std::array<MF, ARRAY_SIZE>& mf, const std::array<
using C = typename MF::CanonicalValue;
using std::size_t;

constexpr size_t P = 5; // (1 << P) == the k in k-ary exponentiation
constexpr int P = 5; // (1 << P) == the k in k-ary exponentiation

// initialize the precalculation table for k-ary pow algorithm
static_assert(P > 0);
constexpr size_t TABLESIZE = 1 << P;
C table[TABLESIZE][ARRAY_SIZE];
HURCHALLA_REQUEST_UNROLL_LOOP for (int j=0; j<ARRAY_SIZE; ++j)
table[0][j] = mf[j].getUnityValue(); // montgomery one
for (int i=1; i<TABLESIZE; ++i) {
for (size_t i=1; i<TABLESIZE; ++i) {
HURCHALLA_REQUEST_UNROLL_LOOP for (int j=0; j<ARRAY_SIZE; ++j)
table[i][j] = mf[j].add(table[i-1][j], table[i-1][j]);
}
Expand Down Expand Up @@ -152,7 +152,7 @@ array_montgomery_two_pow(const std::array<MF, ARRAY_SIZE>& mf, const std::array<
// because we returned above if (n_max <= MASK), we can assert the following:
HPBC_ASSERT(numbits > P);

int shift = numbits - static_cast<int>(P);
int shift = numbits - P;
std::array<V, ARRAY_SIZE> result;
std::array<U, ARRAY_SIZE> tmp;
HURCHALLA_REQUEST_UNROLL_LOOP for (int j=0; j<ARRAY_SIZE; ++j) {
Expand All @@ -163,12 +163,12 @@ array_montgomery_two_pow(const std::array<MF, ARRAY_SIZE>& mf, const std::array<
}


while (shift >= static_cast<int>(P)) {
while (shift >= P) {
for (int i=0; i<P; ++i) {
HURCHALLA_REQUEST_UNROLL_LOOP for (int j=0; j<ARRAY_SIZE; ++j)
result[j] = mf[j].square(result[j]);
}
shift -= static_cast<int>(P);
shift -= P;
std::array<size_t, ARRAY_SIZE> index;
HURCHALLA_REQUEST_UNROLL_LOOP for (int j=0; j<ARRAY_SIZE; ++j) {
// TODO: maybe optimize next line, since n may be > 64bit
Expand Down