Skip to content

Commit 8ef0dc0

Browse files
committed
improve montgomery two pow tests
1 parent 0a558ac commit 8ef0dc0

File tree

3 files changed

+12
-96
lines changed

3 files changed

+12
-96
lines changed

montgomery_arithmetic/include/hurchalla/montgomery_arithmetic/MontgomeryForm.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -334,11 +334,13 @@ class MontgomeryForm final {
334334
return ret;
335335
}
336336

337-
// Returns the Montgomery division of x by 2, which is a modular division.
338-
// The returned quotient times two is congruent to x. Division by two can
339-
// be defined as multiplication by the modular multiplicative inverse of 2,
340-
// which is always valid in Montgomery form because the inverse of 2 always
341-
// exists in Montgomery form (due to the Montgomery modulus being odd).
337+
// Returns the Montgomery modular division of x by 2.
338+
// The returned quotient times two is congruent to x.
339+
// Note: modular division is defined as multiplication by the modular
340+
// multiplicative inverse of the divisor; when halving, the divisor is 2.
341+
// Due to the requirement that a Montgomery modulus must always be odd, the
342+
// inverse of 2 always exists in Montgomery form, and thus halving is always
343+
// valid and well defined in Montgomery form.
342344
HURCHALLA_FORCE_INLINE
343345
MontgomeryValue halve(MontgomeryValue x) const
344346
{

montgomery_arithmetic/include/hurchalla/montgomery_arithmetic/detail/experimental/montgomery_two_pow/testbench.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ exit_on_failure () {
4343
#optimization_level=O3
4444
optimization_level=$2
4545

46-
#define_mont_type=-DDEF_MONT_TYPE=MontgomeryQuarter<U>
46+
#define_mont_type=-DDEF_MONT_TYPE=MontgomeryQuarter
4747
define_mont_type=-DDEF_MONT_TYPE=$3
4848
define_uint_type=-DDEF_UINT_TYPE=$4
4949

test/montgomery_arithmetic/test_montgomery_two_pow.cpp

Lines changed: 4 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
#include "hurchalla/modular_arithmetic/modular_pow.h"
4040
#include "hurchalla/montgomery_arithmetic/MontgomeryForm.h"
4141
#include "hurchalla/montgomery_arithmetic/montgomery_form_aliases.h"
42-
#include "hurchalla/montgomery_arithmetic/detail/impl_montgomery_two_pow.h"
42+
#include "hurchalla/montgomery_arithmetic/detail/platform_specific/montgomery_two_pow.h"
4343
#include "hurchalla/montgomery_arithmetic/detail/MontyTags.h"
4444
#include "hurchalla/util/traits/ut_numeric_limits.h"
4545
#include "hurchalla/util/traits/extensible_make_unsigned.h"
@@ -57,7 +57,7 @@ namespace {
5757

5858

5959
namespace hc = ::hurchalla;
60-
using two_pow = ::hurchalla::detail::impl_montgomery_two_pow;
60+
using two_pow = ::hurchalla::detail::montgomery_two_pow;
6161

6262

6363
// this utility function vector_to_stdarray() is adapted from
@@ -120,47 +120,10 @@ void test_two_pow_array(typename MF::IntegerType starting_modulus,
120120
}
121121

122122
std::array<V,ARRAY_SIZE> results;
123-
results = two_pow::call<MF,U,ARRAY_SIZE,0,28,false>(mfs, exponents);
123+
results = two_pow::call(mfs, exponents);
124124
for (std::size_t i=0; i<ARRAY_SIZE; ++i) {
125125
EXPECT_TRUE(mfs[i].convertOut(results[i]) == answers[i]);
126126
}
127-
results = two_pow::call<MF,U,ARRAY_SIZE,0,29,false>(mfs, exponents);
128-
for (std::size_t i=0; i<ARRAY_SIZE; ++i) {
129-
EXPECT_TRUE(mfs[i].convertOut(results[i]) == answers[i]);
130-
}
131-
results = two_pow::call<MF,U,ARRAY_SIZE,0,30,false>(mfs, exponents);
132-
for (std::size_t i=0; i<ARRAY_SIZE; ++i) {
133-
EXPECT_TRUE(mfs[i].convertOut(results[i]) == answers[i]);
134-
}
135-
results = two_pow::call<MF,U,ARRAY_SIZE,0,31,false>(mfs, exponents);
136-
for (std::size_t i=0; i<ARRAY_SIZE; ++i) {
137-
EXPECT_TRUE(mfs[i].convertOut(results[i]) == answers[i]);
138-
}
139-
140-
using MontyTag = typename MF::MontType::MontyTag;
141-
// We optimize testing to skip the next section of Squaring Value
142-
// tests when the monty type isn't MontgomeryFull. Other monty
143-
// types basically do nothing different with Squaring Values than
144-
// their normal operation - so we save testing time by not testing
145-
// them redundantly.
146-
if (std::is_same<MontyTag, hc::detail::TagMontyFullrange>::value) {
147-
results = two_pow::call<MF,U,ARRAY_SIZE,0,28,true>(mfs, exponents);
148-
for (std::size_t i=0; i<ARRAY_SIZE; ++i) {
149-
EXPECT_TRUE(mfs[i].convertOut(results[i]) == answers[i]);
150-
}
151-
results = two_pow::call<MF,U,ARRAY_SIZE,0,29,true>(mfs, exponents);
152-
for (std::size_t i=0; i<ARRAY_SIZE; ++i) {
153-
EXPECT_TRUE(mfs[i].convertOut(results[i]) == answers[i]);
154-
}
155-
results = two_pow::call<MF,U,ARRAY_SIZE,0,30,true>(mfs, exponents);
156-
for (std::size_t i=0; i<ARRAY_SIZE; ++i) {
157-
EXPECT_TRUE(mfs[i].convertOut(results[i]) == answers[i]);
158-
}
159-
results = two_pow::call<MF,U,ARRAY_SIZE,0,31,true>(mfs, exponents);
160-
for (std::size_t i=0; i<ARRAY_SIZE; ++i) {
161-
EXPECT_TRUE(mfs[i].convertOut(results[i]) == answers[i]);
162-
}
163-
}
164127
}
165128

166129

@@ -176,57 +139,8 @@ void test_two_pow(typename M::IntegerType modulus, U exponent)
176139
T answer = hc::modular_pow<T>(2, exponent, modulus);
177140

178141
T result;
179-
result = mf.convertOut(two_pow::call<M,U,true,0,22,false>(mf,exponent));
180-
EXPECT_TRUE(result == answer);
181-
result = mf.convertOut(two_pow::call<M,U,true,0,23,false>(mf,exponent));
142+
result = mf.convertOut(two_pow::call(mf,exponent));
182143
EXPECT_TRUE(result == answer);
183-
result = mf.convertOut(two_pow::call<M,U,true,0,24,false>(mf,exponent));
184-
EXPECT_TRUE(result == answer);
185-
result = mf.convertOut(two_pow::call<M,U,true,0,33,false>(mf,exponent));
186-
EXPECT_TRUE(result == answer);
187-
result = mf.convertOut(two_pow::call<M,U,true,0,34,false>(mf,exponent));
188-
EXPECT_TRUE(result == answer);
189-
190-
result = mf.convertOut(two_pow::call<M,U,false,0,22,false>(mf,exponent));
191-
EXPECT_TRUE(result == answer);
192-
result = mf.convertOut(two_pow::call<M,U,false,0,23,false>(mf,exponent));
193-
EXPECT_TRUE(result == answer);
194-
result = mf.convertOut(two_pow::call<M,U,false,0,24,false>(mf,exponent));
195-
EXPECT_TRUE(result == answer);
196-
result = mf.convertOut(two_pow::call<M,U,false,0,33,false>(mf,exponent));
197-
EXPECT_TRUE(result == answer);
198-
result = mf.convertOut(two_pow::call<M,U,false,0,34,false>(mf,exponent));
199-
EXPECT_TRUE(result == answer);
200-
201-
using MontyTag = typename M::MontType::MontyTag;
202-
// We optimize testing to skip the next section of Squaring Value
203-
// tests when the monty type isn't MontgomeryFull. Other monty
204-
// types basically do nothing different with Squaring Values than
205-
// their normal operation - so we save testing time by not testing
206-
// them redundantly.
207-
if (std::is_same<MontyTag, hc::detail::TagMontyFullrange>::value) {
208-
result = mf.convertOut(two_pow::call<M,U,true,0,22,true>(mf,exponent));
209-
EXPECT_TRUE(result == answer);
210-
result = mf.convertOut(two_pow::call<M,U,true,0,23,true>(mf,exponent));
211-
EXPECT_TRUE(result == answer);
212-
result = mf.convertOut(two_pow::call<M,U,true,0,24,true>(mf,exponent));
213-
EXPECT_TRUE(result == answer);
214-
result = mf.convertOut(two_pow::call<M,U,true,0,33,true>(mf,exponent));
215-
EXPECT_TRUE(result == answer);
216-
result = mf.convertOut(two_pow::call<M,U,true,0,34,true>(mf,exponent));
217-
EXPECT_TRUE(result == answer);
218-
219-
result = mf.convertOut(two_pow::call<M,U,false,0,22,true>(mf,exponent));
220-
EXPECT_TRUE(result == answer);
221-
result = mf.convertOut(two_pow::call<M,U,false,0,23,true>(mf,exponent));
222-
EXPECT_TRUE(result == answer);
223-
result = mf.convertOut(two_pow::call<M,U,false,0,24,true>(mf,exponent));
224-
EXPECT_TRUE(result == answer);
225-
result = mf.convertOut(two_pow::call<M,U,false,0,33,true>(mf,exponent));
226-
EXPECT_TRUE(result == answer);
227-
result = mf.convertOut(two_pow::call<M,U,false,0,34,true>(mf,exponent));
228-
EXPECT_TRUE(result == answer);
229-
}
230144

231145
// test the array version of two_pow with different array sizes
232146
test_two_pow_array<M,1>(modulus, exponent);

0 commit comments

Comments
 (0)