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