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