@@ -59,13 +59,21 @@ void exhaustive_test_uint8_t()
59
59
{
60
60
for (std::uint8_t modulus=255 ; modulus>1 ; --modulus) {
61
61
for (std::uint8_t a=0 ; a<modulus; ++a) {
62
- std::uint8_t inv = hc::modular_multiplicative_inverse (a, modulus);
62
+ std::uint8_t g;
63
+ std::uint8_t inv = hc::modular_multiplicative_inverse (a, modulus,g);
64
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
63
65
if (inv == 0 )
64
- EXPECT_TRUE (1 < testmmi::gcd (a, modulus));
65
- else
66
+ EXPECT_TRUE (g > 1 );
67
+ else {
68
+ EXPECT_TRUE (g == 1 );
66
69
EXPECT_TRUE (static_cast <std::uint8_t >(1 ) ==
67
70
hc::modular_multiplication_prereduced_inputs (a, inv,
68
71
modulus));
72
+ }
73
+ if (g > 1 )
74
+ EXPECT_TRUE (inv == 0 );
75
+ else
76
+ EXPECT_TRUE (inv > 0 );
69
77
}
70
78
}
71
79
}
@@ -74,25 +82,34 @@ void exhaustive_test_uint8_t()
74
82
template <typename T>
75
83
void test_modulus (T modulus)
76
84
{
85
+ T g;
86
+
77
87
T a = 0 ;
78
88
EXPECT_TRUE (static_cast <T>(0 ) ==
79
- hc::modular_multiplicative_inverse (a, modulus));
89
+ hc::modular_multiplicative_inverse (a, modulus, g));
90
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
91
+
80
92
a = 1 ;
81
93
EXPECT_TRUE (static_cast <T>(1 ) ==
82
- hc::modular_multiplicative_inverse (a, modulus));
94
+ hc::modular_multiplicative_inverse (a, modulus, g));
95
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
96
+
83
97
a = modulus;
84
98
EXPECT_TRUE (static_cast <T>(0 ) ==
85
- hc::modular_multiplicative_inverse (a, modulus));
99
+ hc::modular_multiplicative_inverse (a, modulus, g));
100
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
86
101
87
102
T tmax = hc::ut_numeric_limits<T>::max ();
88
103
if (modulus < tmax) {
89
104
a = static_cast <T>(modulus + 1 );
90
105
EXPECT_TRUE (static_cast <T>(1 ) ==
91
- hc::modular_multiplicative_inverse (a, modulus));
106
+ hc::modular_multiplicative_inverse (a, modulus, g));
107
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
92
108
}
93
109
94
110
a = 2 ;
95
- T inverse = hc::modular_multiplicative_inverse (a, modulus);
111
+ T inverse = hc::modular_multiplicative_inverse (a, modulus, g);
112
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
96
113
if (inverse == 0 )
97
114
EXPECT_TRUE (1 < testmmi::gcd (a, modulus));
98
115
else
@@ -101,7 +118,8 @@ void test_modulus(T modulus)
101
118
static_cast <T>(a % modulus), inverse, modulus));
102
119
103
120
a = 3 ;
104
- inverse = hc::modular_multiplicative_inverse (a, modulus);
121
+ inverse = hc::modular_multiplicative_inverse (a, modulus, g);
122
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
105
123
if (inverse == 0 )
106
124
EXPECT_TRUE (1 < testmmi::gcd (a, modulus));
107
125
else
@@ -110,28 +128,32 @@ void test_modulus(T modulus)
110
128
static_cast <T>(a % modulus), inverse, modulus));
111
129
112
130
a = static_cast <T>(modulus - 1 );
113
- inverse = hc::modular_multiplicative_inverse (a, modulus);
131
+ inverse = hc::modular_multiplicative_inverse (a, modulus, g);
132
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
114
133
EXPECT_TRUE (static_cast <T>(1 ) ==
115
134
hc::modular_multiplication_prereduced_inputs (a, inverse, modulus));
116
135
117
136
a = static_cast <T>(modulus - 2 );
118
- inverse = hc::modular_multiplicative_inverse (a, modulus);
137
+ inverse = hc::modular_multiplicative_inverse (a, modulus, g);
138
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
119
139
if (inverse == 0 )
120
140
EXPECT_TRUE (1 < testmmi::gcd (a, modulus));
121
141
else
122
142
EXPECT_TRUE (static_cast <T>(1 ) ==
123
143
hc::modular_multiplication_prereduced_inputs (a, inverse, modulus));
124
144
125
145
a = static_cast <T>(modulus/2 );
126
- inverse = hc::modular_multiplicative_inverse (a, modulus);
146
+ inverse = hc::modular_multiplicative_inverse (a, modulus, g);
147
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
127
148
if (inverse == 0 )
128
149
EXPECT_TRUE (1 < testmmi::gcd (a, modulus));
129
150
else
130
151
EXPECT_TRUE (static_cast <T>(1 ) ==
131
152
hc::modular_multiplication_prereduced_inputs (a, inverse, modulus));
132
153
133
154
a++;
134
- inverse = hc::modular_multiplicative_inverse (a, modulus);
155
+ inverse = hc::modular_multiplicative_inverse (a, modulus, g);
156
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
135
157
if (inverse == 0 )
136
158
EXPECT_TRUE (1 < testmmi::gcd (a, modulus));
137
159
else
@@ -144,26 +166,52 @@ void test_modulus(T modulus)
144
166
template <typename T>
145
167
void test_modular_multiplicative_inverse ()
146
168
{
169
+ T g;
170
+
147
171
// test with a few basic examples first
148
172
T modulus = 13 ;
149
173
T a = 5 ;
150
174
EXPECT_TRUE (static_cast <T>(8 ) ==
151
175
hc::modular_multiplicative_inverse (a, modulus));
176
+ EXPECT_TRUE (static_cast <T>(8 ) ==
177
+ hc::modular_multiplicative_inverse (a, modulus, g));
178
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
179
+
152
180
a = 7 ;
153
181
EXPECT_TRUE (static_cast <T>(2 ) ==
154
182
hc::modular_multiplicative_inverse (a, modulus));
183
+ EXPECT_TRUE (static_cast <T>(2 ) ==
184
+ hc::modular_multiplicative_inverse (a, modulus, g));
185
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
186
+
155
187
a = 4 ;
156
188
EXPECT_TRUE (static_cast <T>(10 ) ==
157
189
hc::modular_multiplicative_inverse (a, modulus));
190
+ EXPECT_TRUE (static_cast <T>(10 ) ==
191
+ hc::modular_multiplicative_inverse (a, modulus, g));
192
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
193
+
158
194
a = 17 ;
159
195
EXPECT_TRUE (static_cast <T>(10 ) ==
160
196
hc::modular_multiplicative_inverse (a, modulus));
197
+ EXPECT_TRUE (static_cast <T>(10 ) ==
198
+ hc::modular_multiplicative_inverse (a, modulus, g));
199
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
200
+
161
201
a = 1 ;
162
202
EXPECT_TRUE (static_cast <T>(1 ) ==
163
203
hc::modular_multiplicative_inverse (a, modulus));
204
+ EXPECT_TRUE (static_cast <T>(1 ) ==
205
+ hc::modular_multiplicative_inverse (a, modulus, g));
206
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
207
+
164
208
a = 14 ;
165
209
EXPECT_TRUE (static_cast <T>(1 ) ==
166
210
hc::modular_multiplicative_inverse (a, modulus));
211
+ EXPECT_TRUE (static_cast <T>(1 ) ==
212
+ hc::modular_multiplicative_inverse (a, modulus, g));
213
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
214
+
167
215
168
216
169
217
// modular_multiplicative_inverse() indicates the inverse doesn't exist by
@@ -172,12 +220,24 @@ void test_modular_multiplicative_inverse()
172
220
modulus = 21 ; // a modulus of 21 shares the factor 3 with a.
173
221
EXPECT_TRUE (static_cast <T>(0 ) ==
174
222
hc::modular_multiplicative_inverse (a, modulus));
223
+ EXPECT_TRUE (static_cast <T>(0 ) ==
224
+ hc::modular_multiplicative_inverse (a, modulus, g));
225
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
226
+
175
227
a = 0 ;
176
228
EXPECT_TRUE (static_cast <T>(0 ) ==
177
229
hc::modular_multiplicative_inverse (a, modulus));
230
+ EXPECT_TRUE (static_cast <T>(0 ) ==
231
+ hc::modular_multiplicative_inverse (a, modulus, g));
232
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
233
+
178
234
a = 1 ;
179
235
EXPECT_TRUE (static_cast <T>(1 ) ==
180
236
hc::modular_multiplicative_inverse (a, modulus));
237
+ EXPECT_TRUE (static_cast <T>(1 ) ==
238
+ hc::modular_multiplicative_inverse (a, modulus, g));
239
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
240
+
181
241
182
242
a = 7 ;
183
243
modulus = 16 ;
@@ -204,12 +264,24 @@ void test_modular_multiplicative_inverse()
204
264
a = 0 ;
205
265
EXPECT_TRUE (static_cast <T>(0 ) ==
206
266
hc::modular_multiplicative_inverse (a, modulus));
267
+ EXPECT_TRUE (static_cast <T>(0 ) ==
268
+ hc::modular_multiplicative_inverse (a, modulus, g));
269
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
270
+
207
271
a = 1 ;
208
272
EXPECT_TRUE (static_cast <T>(1 ) ==
209
273
hc::modular_multiplicative_inverse (a, modulus));
274
+ EXPECT_TRUE (static_cast <T>(1 ) ==
275
+ hc::modular_multiplicative_inverse (a, modulus, g));
276
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
277
+
210
278
a = 5 ;
211
279
EXPECT_TRUE (static_cast <T>(1 ) ==
212
280
hc::modular_multiplicative_inverse (a, modulus));
281
+ EXPECT_TRUE (static_cast <T>(1 ) ==
282
+ hc::modular_multiplicative_inverse (a, modulus, g));
283
+ EXPECT_TRUE (g == testmmi::gcd (a, modulus));
284
+
213
285
214
286
modulus = hc::ut_numeric_limits<T>::max ();
215
287
test_modulus (modulus);
0 commit comments