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 Fp implementation.
17 /*! \file */
18 
19 #include <gtest/gtest.h>
20 
21 #include "epid/member/tiny/math/unittests/cmp-testhelper.h"
22 #include "epid/member/tiny/math/unittests/onetimepad.h"
23 
24 extern "C" {
25 #include "epid/member/tiny/math/fp.h"
26 #include "epid/member/tiny/math/mathtypes.h"
27 }
28 
29 namespace {
30 
31 ////////////////////////////////////////////////////////////////////////
32 // FpInField
33 
TEST(TinyFpTest,FpInFieldPasses)34 TEST(TinyFpTest, FpInFieldPasses) {
35   FpElem zero = {0};
36   FpElem p_minus_one = {{0xD10B500C, 0xF62D536C, 0x1299921A, 0x0CDC65FB,
37                          0xEE71A49E, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF}};
38   EXPECT_TRUE(FpInField(&zero));
39   EXPECT_TRUE(FpInField(&p_minus_one));
40 }
41 
TEST(TinyFpTest,FpInFieldFails)42 TEST(TinyFpTest, FpInFieldFails) {
43   FpElem p = {{0xD10B500D, 0xF62D536C, 0x1299921A, 0x0CDC65FB, 0xEE71A49E,
44                0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF}};
45   EXPECT_FALSE(FpInField(&p));
46 }
47 
48 ////////////////////////////////////////////////////////////////////////
49 // FpAdd
50 
TEST(TinyFpTest,FpAddWorks)51 TEST(TinyFpTest, FpAddWorks) {
52   FpElem result = {0}, expected = {0}, left = {0}, right = {0};
53   left.limbs.word[5] = 1;
54   right.limbs.word[5] = 2;
55   expected.limbs.word[5] = 3;
56   FpAdd(&result, &left, &right);
57   EXPECT_EQ(expected, result);
58 
59   FpElem p_minus_one = {0xD10B500C, 0xF62D536C, 0x1299921A, 0x0CDC65FB,
60                         0xEE71A49E, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF};
61   right = {2, 0, 0, 0, 0, 0, 0, 0};
62   expected = {1, 0, 0, 0, 0, 0, 0, 0};
63   FpAdd(&result, &p_minus_one, &right);
64   EXPECT_EQ(expected, result);
65 }
66 
67 ////////////////////////////////////////////////////////////////////////
68 // FpMul
69 
TEST(TinyFpTest,FpMultWorks)70 TEST(TinyFpTest, FpMultWorks) {
71   FpElem left = {0x22cfd6a2, 0x23e82f1e, 0xd50e1450, 0xe853e88c,
72                  0xafa65357, 0x4780716c, 0xffd94b0f, 0x5e643124};
73   FpElem right = {0x848cdb73, 0x6399829e, 0xcaa20cc0, 0x1b02bff6,
74                   0x2b477bd2, 0xf9d48534, 0xff7929a0, 0xd4745161};
75   FpElem expected = {0x3f172ebf, 0xf2219fce, 0x73591802, 0x7a7dbc7f,
76                      0xf82ed0df, 0xb8c0c56d, 0x3395ff68, 0x83d64983};
77   FpElem result = {0};
78   FpMul(&result, &left, &right);
79   EXPECT_EQ(expected, result);
80 }
81 
82 ////////////////////////////////////////////////////////////////////////
83 // FpSub
84 
TEST(TinyFpTest,FpSubWorks)85 TEST(TinyFpTest, FpSubWorks) {
86   FpElem result = {0}, expected = {0}, left = {0}, right = {0};
87   left.limbs.word[4] = 2;
88   right.limbs.word[4] = 1;
89   expected.limbs.word[4] = 1;
90   FpSub(&result, &left, &right);
91   EXPECT_EQ(expected, result);
92 
93   left = {1, 0, 0, 0, 0, 0, 0, 0};
94   right = {2, 0, 0, 0, 0, 0, 0, 0};
95   FpElem p_minus_one = {0xD10B500C, 0xF62D536C, 0x1299921A, 0x0CDC65FB,
96                         0xEE71A49E, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF};
97   FpSub(&result, &left, &right);
98   EXPECT_EQ(p_minus_one, result);
99 }
100 
101 ////////////////////////////////////////////////////////////////////////
102 // FpExp
TEST(TinyFpTest,FpExpWorks)103 TEST(TinyFpTest, FpExpWorks) {
104   FpElem result = {0}, expected = {0}, in = {0};
105   VeryLargeInt exp = {0xD10B500C, 0xF62D536C, 0x1299921A, 0x0CDC65FB,
106                       0xEE71A49E, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF};
107   in.limbs.word[0] = 1;
108   expected.limbs.word[0] = 1;
109   FpExp(&result, &in, &exp);
110   EXPECT_EQ(expected, result);
111 
112   exp = {4, 0, 0, 0, 0, 0, 0, 0};
113   in = {{0x0000007B, 0, 0, 0, 0, 0, 0, 0}};
114   expected = {{0x0DA48871, 0, 0, 0, 0, 0, 0, 0}};
115   FpExp(&result, &in, &exp);
116   EXPECT_EQ(expected, result);
117 }
118 
119 ////////////////////////////////////////////////////////////////////////
120 // FpNeg
TEST(TinyFpTest,FpNegWorks)121 TEST(TinyFpTest, FpNegWorks) {
122   FpElem const pairing_p = {{0xD10B500D, 0xF62D536C, 0x1299921A, 0x0CDC65FB,
123                              0xEE71A49E, 0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF}};
124   FpElem neg_value = {0};
125   FpElem one = {{1, 0, 0, 0, 0, 0, 0, 0}};
126   FpElem minus_one = pairing_p;
127   --minus_one.limbs.word[0];
128   FpNeg(&neg_value, &one);
129   EXPECT_EQ(minus_one, neg_value);
130 
131   FpElem value = {{0xD10B500C, 0xF62D536C, 0x1299921A, 0x0CDC65FB, 0xEE71A49E,
132                    0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF}};
133   FpNeg(&neg_value, &value);
134   FpNeg(&neg_value, &neg_value);
135   EXPECT_EQ(value, neg_value);
136 }
137 
138 ////////////////////////////////////////////////////////////////////////
139 // FpEq
140 
TEST(TinyFpTest,FpEqPasses)141 TEST(TinyFpTest, FpEqPasses) {
142   FpElem a = {{0xD10B500C, 0xF62D536C, 0x1299921A, 0x0CDC65FB, 0xEE71A49E,
143                0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF}};
144   FpElem c = {{0xD10B500C, 0xF62D536C, 0x1299921A, 0x0CDC65FB, 0xEE71A49E,
145                0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF}};
146   EXPECT_TRUE(FpEq(&a, &c));
147 }
148 
TEST(TinyFpTest,FpEqFails)149 TEST(TinyFpTest, FpEqFails) {
150   FpElem a = {{0xD10B500C, 0xF62D536C, 0x1299921A, 0x0CDC65FB, 0xEE71A49E,
151                0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF}};
152   FpElem b = {{0, 0, 0, 0, 0, 0, 1, 0}};
153   EXPECT_FALSE(FpEq(&a, &b));
154 }
155 
156 ////////////////////////////////////////////////////////////////////////
157 // FpInv
158 
TEST(TinyFpTest,FpInvWorks)159 TEST(TinyFpTest, FpInvWorks) {
160   FpElem a = {{0x22cfd6a2, 0x23e82f1e, 0xd50e1450, 0xe853e88c, 0xafa65357,
161                0x4780716c, 0xffd94b0f, 0x5e643124}};
162   FpElem expected = {{0xd97deaf7, 0xa6011d83, 0x3c381713, 0x92472e34,
163                       0x997861e8, 0xc1dfdc87, 0x157eb11b, 0xc9cd1238}};
164   FpElem result;
165   FpInv(&result, &a);
166   EXPECT_EQ(result, expected);
167 }
168 
169 ////////////////////////////////////////////////////////////////////////
170 // FpRand
171 
TEST(TinyFpTest,FpRandConsumes384BitsOfEntropy)172 TEST(TinyFpTest, FpRandConsumes384BitsOfEntropy) {
173   OneTimePad otp(64);
174   FpElem actual = {0};
175   EXPECT_TRUE(FpRand(&actual, OneTimePad::Generate, &otp));
176   EXPECT_EQ(384u, otp.BitsConsumed());
177 }
178 
TEST(TinyFpTest,FpRandWorks)179 TEST(TinyFpTest, FpRandWorks) {
180   OneTimePad otp({// slen bits
181                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183                   // p + 1
184                   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD, 0x46, 0xE5,
185                   0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9E, 0x0C, 0xDC, 0x65, 0xFB,
186                   0x12, 0x99, 0x92, 0x1A, 0xF6, 0x2D, 0x53, 0x6C, 0xD1, 0x0B,
187                   0x50, 0x0E});
188   FpElem expected = {{1, 0, 0, 0, 0, 0, 0, 0}};
189   FpElem actual = {0};
190   EXPECT_TRUE(FpRand(&actual, OneTimePad::Generate, &otp));
191   EXPECT_EQ(expected, actual);
192 }
193 
194 ////////////////////////////////////////////////////////////////////////
195 // FpRandNonzero
196 
TEST(TinyFpTest,FpRandNonzeroConsumes384BitsOfEntropy)197 TEST(TinyFpTest, FpRandNonzeroConsumes384BitsOfEntropy) {
198   OneTimePad otp(64);
199   FpElem actual = {0};
200   EXPECT_TRUE(FpRandNonzero(&actual, OneTimePad::Generate, &otp));
201   EXPECT_EQ(384u, otp.BitsConsumed());
202 }
203 
TEST(TinyFpTest,FpRandNonzeroWorks)204 TEST(TinyFpTest, FpRandNonzeroWorks) {
205   OneTimePad otp({// slen bits
206                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208                   // p - 1
209                   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD, 0x46, 0xE5,
210                   0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9E, 0x0C, 0xDC, 0x65, 0xFB,
211                   0x12, 0x99, 0x92, 0x1A, 0xF6, 0x2D, 0x53, 0x6C, 0xD1, 0x0B,
212                   0x50, 0x0C});
213   FpElem expected = {{1, 0, 0, 0, 0, 0, 0, 0}};
214   FpElem actual = {0};
215   EXPECT_TRUE(FpRandNonzero(&actual, OneTimePad::Generate, &otp));
216   EXPECT_EQ(expected, actual);
217 }
218 
219 ////////////////////////////////////////////////////////////////////////
220 // FpClear
221 
TEST(TinyFpTest,FpClearWorks)222 TEST(TinyFpTest, FpClearWorks) {
223   FpElem zero = {0};
224   FpElem a = {{0xD10B500C, 0xF62D536C, 0x1299921A, 0x0CDC65FB, 0xEE71A49E,
225                0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF}};
226   FpClear(&a);
227   EXPECT_EQ(zero, a);
228 }
229 
230 ////////////////////////////////////////////////////////////////////////
231 // FpSet
232 
TEST(TinyFpTest,FpSetWorks)233 TEST(TinyFpTest, FpSetWorks) {
234   uint32_t small = 0xffffffff;
235   FpElem expected = {{small, 0, 0, 0, 0, 0, 0, 0}};
236   FpElem result = {{0xD10B500C, 0xF62D536C, 0x1299921A, 0x0CDC65FB, 0xEE71A49E,
237                     0x46E5F25E, 0xFFFCF0CD, 0xFFFFFFFF}};
238   FpSet(&result, small);
239   EXPECT_EQ(expected, result);
240 }
241 
242 ////////////////////////////////////////////////////////////////////////
243 // FpFromHash
244 
TEST(TinyFpTest,FpFromHashWorks)245 TEST(TinyFpTest, FpFromHashWorks) {
246   FpElem p_mod_p;
247   FpElem zero = {0};
248   uint8_t p_str[32] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD,
249                        0x46, 0xE5, 0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9E,
250                        0x0C, 0xDC, 0x65, 0xFB, 0x12, 0x99, 0x92, 0x1A,
251                        0xF6, 0x2D, 0x53, 0x6C, 0xD1, 0x0B, 0x50, 0x0D};
252   FpFromHash(&p_mod_p, p_str, sizeof(p_str));
253   EXPECT_EQ(zero, p_mod_p);
254 
255   FpElem one = {{1, 0, 0, 0, 0, 0, 0, 0}};
256   uint8_t one_str[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
257                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
258   FpElem one_mod_p;
259   FpFromHash(&one_mod_p, one_str, sizeof(one_str));
260   EXPECT_EQ(one, one_mod_p);
261 }
262 
263 }  // namespace
264