1 /*############################################################################
2 # Copyright 2017 Intel Corporation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 ############################################################################*/
16 /// Unit tests of large integer implementation.
17 /*! \file */
18
19 #include <gtest/gtest.h>
20 #include <limits.h> // for CHAR_BIT
21 #include <cstring>
22 #include <random>
23
24 #include "epid/member/tiny/math/unittests/cmp-testhelper.h"
25 #include "epid/member/tiny/math/unittests/onetimepad.h"
26
27 extern "C" {
28 #include "epid/member/tiny/math/mathtypes.h"
29 #include "epid/member/tiny/math/vli.h"
30 }
31
32 namespace {
33
34 ////////////////////////////////////////////////////////////////////////
35 // VliAdd
36
TEST(TinyVliTest,VliAddWorks)37 TEST(TinyVliTest, VliAddWorks) {
38 VeryLargeInt result = {0};
39 VeryLargeInt expected = {0};
40 VeryLargeInt left = {0};
41 VeryLargeInt right = {0};
42 left.word[0] = 1;
43 right.word[0] = 2;
44 expected.word[0] = 3;
45 VliAdd(&result, &left, &right);
46 EXPECT_EQ(expected, result);
47 }
TEST(TinyVliTest,VliAddCalculatesCarry)48 TEST(TinyVliTest, VliAddCalculatesCarry) {
49 VeryLargeInt left = {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
50 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}};
51 VeryLargeInt right = {{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}};
52 VeryLargeInt expected = {{0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}};
53 uint32_t expected_carry = 0x1;
54 uint32_t carry = 0;
55 VeryLargeInt result = {0};
56 carry = VliAdd(&result, &left, &right);
57 EXPECT_EQ(expected, result);
58 EXPECT_EQ(expected_carry, carry);
59 }
60 ////////////////////////////////////////////////////////////////////////
61 // VliMul
TEST(TinyVliTest,VliMultWorks)62 TEST(TinyVliTest, VliMultWorks) {
63 VeryLargeIntProduct result = {0};
64 VeryLargeIntProduct expected = {0};
65 VeryLargeInt left = {0}, right = {0};
66 left.word[0] = 2;
67 right.word[0] = 2;
68 expected.word[0] = 4;
69 VliMul(&result, &left, &right);
70 EXPECT_EQ(expected, result);
71 }
TEST(TinyVliTest,VliMultWorksWithOverflow)72 TEST(TinyVliTest, VliMultWorksWithOverflow) {
73 VeryLargeIntProduct result = {0};
74 VeryLargeIntProduct expected = {
75 {0xfffffffe, 0xfffffffd, 0xfffffffd, 0xfffffffd, 0xfffffffd, 0xfffffffd,
76 0xfffffffd, 0xfffffffd, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2}};
77 VeryLargeInt left = {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
78 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}};
79 VeryLargeInt right = {{0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2}};
80 VliMul(&result, &left, &right);
81 EXPECT_EQ(expected, result);
82 }
83
84 ////////////////////////////////////////////////////////////////////////
85 // VliRShift
TEST(TinyVliTest,VliRShiftWorks)86 TEST(TinyVliTest, VliRShiftWorks) {
87 VeryLargeInt result = {0}, expected = {0};
88 VeryLargeInt in = {0};
89 uint32_t shift = 1;
90 in.word[0] = 4;
91 expected.word[0] = 2;
92 VliRShift(&result, &in, shift);
93 EXPECT_EQ(expected, result);
94 }
TEST(TinyVliTest,VliRShiftWorksWithOverlap)95 TEST(TinyVliTest, VliRShiftWorksWithOverlap) {
96 VeryLargeInt result = {0}, expected = {0};
97 VeryLargeInt in = {0};
98 uint32_t shift = 4;
99 in.word[0] = 0x00000008;
100 in.word[1] = 0xffffffff;
101 expected.word[0] = 0xf0000000;
102 expected.word[1] = 0x0fffffff;
103 VliRShift(&result, &in, shift);
104 EXPECT_EQ(expected, result);
105 }
106
107 ////////////////////////////////////////////////////////////////////////
108 // VliSub
TEST(TinyVliTest,VliSubWorks)109 TEST(TinyVliTest, VliSubWorks) {
110 VeryLargeInt result = {0}, expected = {0};
111 VeryLargeInt left = {0}, right = {0};
112 uint32_t borrow = 0;
113 uint32_t expected_borrow = 0;
114 left.word[0] = 4;
115 right.word[0] = 2;
116 expected.word[0] = 2;
117 borrow = VliSub(&result, &left, &right);
118 EXPECT_EQ(expected, result);
119 EXPECT_EQ(expected_borrow, borrow);
120 }
TEST(TinyVliTest,VliSubWorksWithBorrow)121 TEST(TinyVliTest, VliSubWorksWithBorrow) {
122 VeryLargeInt result = {0};
123 VeryLargeInt expected = {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
124 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}};
125 VeryLargeInt left = {0}, right = {0};
126 uint32_t borrow = 0;
127 uint32_t expected_borrow = 1;
128 left.word[0] = 2;
129 right.word[0] = 3;
130 borrow = VliSub(&result, &left, &right);
131 EXPECT_EQ(expected, result);
132 EXPECT_EQ(expected_borrow, borrow);
133 }
134
135 ////////////////////////////////////////////////////////////////////////
136 // VliSet
137
TEST(TinyVliTest,VliSetWorks)138 TEST(TinyVliTest, VliSetWorks) {
139 VeryLargeInt result = {0};
140 VeryLargeInt in = {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
141 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}};
142 VliSet(&result, &in);
143 EXPECT_EQ(in, result);
144 }
145
146 ////////////////////////////////////////////////////////////////////////
147 // VliClear
148
TEST(TinyVliTest,VliClearWorks)149 TEST(TinyVliTest, VliClearWorks) {
150 VeryLargeInt expected = {0};
151 VeryLargeInt in_out = {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
152 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}};
153 VliClear(&in_out);
154 EXPECT_EQ(expected, in_out);
155 }
156
157 ////////////////////////////////////////////////////////////////////////
158 // VliIsZero
159
TEST(TinyVliTest,VliIsZeroAcceptsZero)160 TEST(TinyVliTest, VliIsZeroAcceptsZero) {
161 int is_zero = 0;
162 VeryLargeInt in_zero = {0};
163 is_zero = VliIsZero(&in_zero);
164 EXPECT_TRUE(is_zero);
165 }
TEST(TinyVliTest,VliIsZeroRejectsNonZero)166 TEST(TinyVliTest, VliIsZeroRejectsNonZero) {
167 int is_zero = 0;
168 VeryLargeInt in_nonzero = {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
169 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}};
170 is_zero = VliIsZero(&in_nonzero);
171 EXPECT_FALSE(is_zero);
172 }
173
174 ////////////////////////////////////////////////////////////////////////
175 // VliCondSet
176
TEST(TinyVliTest,VliCondSetWorksForTrue)177 TEST(TinyVliTest, VliCondSetWorksForTrue) {
178 VeryLargeInt result = {0};
179 VeryLargeInt true_val = {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
180 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}};
181 VeryLargeInt false_val = {{0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
182 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa}};
183 VliCondSet(&result, &true_val, &false_val, 1);
184 EXPECT_EQ(true_val, result);
185 }
TEST(TinyVliTest,VliCondSetWorksForFalse)186 TEST(TinyVliTest, VliCondSetWorksForFalse) {
187 VeryLargeInt result = {0};
188 VeryLargeInt true_val = {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
189 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}};
190 VeryLargeInt false_val = {{0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
191 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa}};
192 VliCondSet(&result, &true_val, &false_val, 0);
193 EXPECT_EQ(false_val, result);
194 }
195
196 ////////////////////////////////////////////////////////////////////////
197 // VliTestBit
198
TEST(TinyVliTest,VliTestBitWorks)199 TEST(TinyVliTest, VliTestBitWorks) {
200 VeryLargeInt in = {0};
201 uint32_t bit_set = 0;
202 in.word[0] = 4;
203 bit_set = VliTestBit(&in, 1);
204 EXPECT_EQ((uint32_t)0, bit_set);
205 bit_set = VliTestBit(&in, 2);
206 EXPECT_EQ((uint32_t)1, bit_set);
207 }
208
209 ////////////////////////////////////////////////////////////////////////
210 // VliRand
211
TEST(TinyVliTest,VliRandWorks)212 TEST(TinyVliTest, VliRandWorks) {
213 OneTimePad my_prng;
214 VeryLargeInt expected_rand_val1 = {{1, 0, 0, 0, 0, 0, 0, 0}};
215 my_prng.InitUint8({0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
216 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1});
217 VeryLargeInt rand_val1 = {0};
218 EXPECT_TRUE(VliRand(&rand_val1, &OneTimePad::Generate, &my_prng));
219 EXPECT_EQ(expected_rand_val1, rand_val1);
220 EXPECT_EQ(256u, my_prng.BitsConsumed());
221
222 VeryLargeInt expected_rand_val2 = {{0x1c6f5a0f, 0xeaa878b3, 0xc71dab6b,
223 0x1a101ad6, 0x1fe6394f, 0x1bec36ab,
224 0x07a3e97f, 0x36507914}};
225 VeryLargeInt rand_val2 = {0};
226 my_prng.InitUint32({0x14795036, 0x7fe9a307, 0xab36ec1b, 0x4f39e61f,
227 0xd61a101a, 0x6bab1dc7, 0xb378a8ea, 0x0f5a6f1c});
228 EXPECT_TRUE(VliRand(&rand_val2, &OneTimePad::Generate, &my_prng));
229 EXPECT_EQ(expected_rand_val2, rand_val2);
230 EXPECT_EQ(256u, my_prng.BitsConsumed());
231 }
232
233 ////////////////////////////////////////////////////////////////////////
234 // VliCmp
235
TEST(TinyVliTest,VliCmpWorksForLessThan)236 TEST(TinyVliTest, VliCmpWorksForLessThan) {
237 VeryLargeInt in_val1 = {0};
238 VeryLargeInt in_val2 = {0};
239 int res = 0;
240 in_val1.word[0] = 1;
241 in_val2.word[0] = 2;
242 res = VliCmp(&in_val1, &in_val2);
243 EXPECT_EQ(-1, res);
244 }
TEST(TinyVliTest,VliCmpWorksForEqual)245 TEST(TinyVliTest, VliCmpWorksForEqual) {
246 VeryLargeInt in_val1 = {0};
247 VeryLargeInt in_val2 = {0};
248 int res = 0;
249 in_val1.word[0] = 2;
250 in_val2.word[0] = 2;
251 res = VliCmp(&in_val1, &in_val2);
252 EXPECT_EQ(0, res);
253 }
TEST(TinyVliTest,VliCmpWorksGreaterThan)254 TEST(TinyVliTest, VliCmpWorksGreaterThan) {
255 VeryLargeInt in_val1 = {0};
256 VeryLargeInt in_val2 = {0};
257 int res = 0;
258 in_val1.word[0] = 1;
259 in_val2.word[0] = 2;
260 res = VliCmp(&in_val2, &in_val1);
261 EXPECT_EQ(1, res);
262 }
263
264 ////////////////////////////////////////////////////////////////////////
265 // VliModAdd
266
TEST(TinyVliTest,VliModAddWorks)267 TEST(TinyVliTest, VliModAddWorks) {
268 VeryLargeInt result = {0};
269 VeryLargeInt left = {0};
270 VeryLargeInt right = {0};
271 VeryLargeInt expected = {0};
272 VeryLargeInt mod = {0xAED33013, 0xD3292DDB, 0x12980A82, 0x0CDC65FB,
273 0xEE71A49F, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF};
274 left.word[0] = 0x9;
275 right.word[0] = 0x8;
276 expected.word[0] = 0x11;
277 VliModAdd(&result, &left, &right, &mod);
278 EXPECT_EQ(expected, result);
279 }
280
281 ////////////////////////////////////////////////////////////////////////
282 // VliModSub
283
TEST(TinyVliTest,VliModSubWorks)284 TEST(TinyVliTest, VliModSubWorks) {
285 VeryLargeInt result = {0};
286 VeryLargeInt left = {0};
287 VeryLargeInt right = {0};
288 VeryLargeInt expected = {0};
289 VeryLargeInt mod = {0xAED33013, 0xD3292DDB, 0x12980A82, 0x0CDC65FB,
290 0xEE71A49F, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF};
291 left.word[0] = 0x18;
292 right.word[0] = 0x12;
293 expected.word[0] = 0x6;
294 VliModSub(&result, &left, &right, &mod);
295 EXPECT_EQ(expected, result);
296 }
297
298 ////////////////////////////////////////////////////////////////////////
299 // VliModMul
300
TEST(TinyVliTest,VliModMultWorks)301 TEST(TinyVliTest, VliModMultWorks) {
302 VeryLargeInt result = {0};
303 VeryLargeInt left = {0};
304 VeryLargeInt right = {0};
305 VeryLargeInt expected = {0};
306 VeryLargeInt mod = {0xAED33013, 0xD3292DDB, 0x12980A82, 0x0CDC65FB,
307 0xEE71A49F, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF};
308 left.word[0] = 0x10;
309 right.word[0] = 0x2;
310 expected.word[0] = 0x20;
311 VliModMul(&result, &left, &right, &mod);
312 EXPECT_EQ(expected, result);
313 }
314
315 ////////////////////////////////////////////////////////////////////////
316 // VliModExp
317
TEST(TinyVliTest,VliModExpWorks)318 TEST(TinyVliTest, VliModExpWorks) {
319 VeryLargeInt result = {0};
320 VeryLargeInt base = {0};
321 VeryLargeInt exp = {0};
322 VeryLargeInt mod = {0xAED33013, 0xD3292DDB, 0x12980A82, 0x0CDC65FB,
323 0xEE71A49F, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF};
324 VeryLargeInt expected = {0};
325 base.word[0] = 0x4;
326 exp.word[0] = 0x2;
327 expected.word[0] = 0x10;
328 VliModExp(&result, &base, &exp, &mod);
329 EXPECT_EQ(expected, result);
330 }
331
332 ////////////////////////////////////////////////////////////////////////
333 // VliModInv
334
TEST(TinyVliTest,VliModInvWorks)335 TEST(TinyVliTest, VliModInvWorks) {
336 VeryLargeInt a = {0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1,
337 0xe3401760, 0x66eb7d52, 0x918d50a7, 0x12a65bd6};
338 VeryLargeInt q = {0xAED33013, 0xD3292DDB, 0x12980A82, 0x0CDC65FB,
339 0xEE71A49F, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF};
340 VeryLargeInt expected = {0x5a686df6, 0x56b6ab63, 0xdf907c6f, 0x44ad8d51,
341 0xa5513462, 0xc597ef78, 0x93711b39, 0x15171a1e};
342 VeryLargeInt result;
343 VliModInv(&result, &a, &q);
344 EXPECT_EQ(result, expected);
345 }
346
347 ////////////////////////////////////////////////////////////////////////
348 // VliModSquare
349
TEST(TinyVliTest,VliModSquareWorks)350 TEST(TinyVliTest, VliModSquareWorks) {
351 VeryLargeInt result = {0};
352 VeryLargeInt input = {0};
353 VeryLargeInt mod = {0xAED33013, 0xD3292DDB, 0x12980A82, 0x0CDC65FB,
354 0xEE71A49F, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF};
355 VeryLargeInt expected = {0};
356 input.word[0] = 0x4;
357 expected.word[0] = 0x10;
358 VliModSquare(&result, &input, &mod);
359 EXPECT_EQ(expected, result);
360 }
361
362 ////////////////////////////////////////////////////////////////////////
363 // VliModBarrett
364
TEST(TinyVliTest,VliModBarrettWorks)365 TEST(TinyVliTest, VliModBarrettWorks) {
366 VeryLargeInt result = {0};
367 VeryLargeIntProduct product = {0xAED33013, 0xD3292DDB, 0x12980A82, 0x0CDC65FB,
368 0xEE71A49F, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF,
369 0x0, 0x0, 0x0, 0x0,
370 0x0, 0x0, 0x0, 0x0};
371 VeryLargeInt mod = {0xAED33013, 0xD3292DDB, 0x12980A82, 0x0CDC65FB,
372 0xEE71A49F, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF};
373 VeryLargeInt expected = {0};
374 product.word[0] += 0xF;
375 expected.word[0] = 0xF;
376 VliModBarrett(&result, &product, &mod);
377 EXPECT_EQ(expected, result);
378 }
379 } // namespace
380