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 /// Implementation of Fp math
17 /*! \file */
18
19 #include "epid/member/tiny/math/fp.h"
20
21 #include <limits.h> // for CHAR_BIT
22 #include "epid/member/tiny/math/mathtypes.h"
23 #include "epid/member/tiny/math/serialize.h"
24 #include "epid/member/tiny/math/vli.h"
25 #include "epid/member/tiny/stdlib/tiny_stdlib.h"
26
27 /// A security parameter. In this version of Intel(R) EPID SDK, slen = 128
28 #define EPID_SLEN 128
29 /// buffer size of random integer t in INT32
30 #define RAND_NUM_WORDS \
31 ((sizeof(FpElem) + EPID_SLEN / CHAR_BIT) / sizeof(uint32_t))
32
33 static VeryLargeInt const epid20_p = {{0xD10B500D, 0xF62D536C, 0x1299921A,
34 0x0CDC65FB, 0xEE71A49E, 0x46E5F25E,
35 0xFFFCF0CD, 0xFFFFFFFF}};
36 static FpElem const one = {{{1, 0, 0, 0, 0, 0, 0, 0}}};
37 static VeryLargeInt const p_minus_one = {{0xD10B500C, 0xF62D536C, 0x1299921A,
38 0x0CDC65FB, 0xEE71A49E, 0x46E5F25E,
39 0xFFFCF0CD, 0xFFFFFFFF}};
40
FpInField(FpElem const * in)41 int FpInField(FpElem const* in) { return (VliCmp(&in->limbs, &epid20_p) < 0); }
42
FpAdd(FpElem * result,FpElem const * left,FpElem const * right)43 void FpAdd(FpElem* result, FpElem const* left, FpElem const* right) {
44 VliModAdd(&result->limbs, &left->limbs, &right->limbs, &epid20_p);
45 }
46
FpMul(FpElem * result,FpElem const * left,FpElem const * right)47 void FpMul(FpElem* result, FpElem const* left, FpElem const* right) {
48 VliModMul(&result->limbs, &left->limbs, &right->limbs, &epid20_p);
49 }
50
FpSub(FpElem * result,FpElem const * left,FpElem const * right)51 void FpSub(FpElem* result, FpElem const* left, FpElem const* right) {
52 VliModSub(&result->limbs, &left->limbs, &right->limbs, &epid20_p);
53 }
54
FpExp(FpElem * result,FpElem const * base,VeryLargeInt const * exp)55 void FpExp(FpElem* result, FpElem const* base, VeryLargeInt const* exp) {
56 VliModExp(&result->limbs, &base->limbs, exp, &epid20_p);
57 }
58
FpNeg(FpElem * result,FpElem const * in)59 void FpNeg(FpElem* result, FpElem const* in) {
60 VliCondSet(&result->limbs, &epid20_p, &in->limbs, VliIsZero(&in->limbs));
61 VliSub(&result->limbs, &epid20_p, &result->limbs);
62 }
63
FpEq(FpElem const * left,FpElem const * right)64 int FpEq(FpElem const* left, FpElem const* right) {
65 return (VliCmp(&left->limbs, &right->limbs) == 0);
66 }
67
FpInv(FpElem * result,FpElem const * in)68 void FpInv(FpElem* result, FpElem const* in) {
69 VliModInv(&result->limbs, &in->limbs, &epid20_p);
70 }
71
FpRand(FpElem * result,BitSupplier rnd_func,void * rnd_param)72 int FpRand(FpElem* result, BitSupplier rnd_func, void* rnd_param) {
73 VeryLargeIntProduct deserialized_t = {{0}};
74 uint32_t t[RAND_NUM_WORDS] = {0};
75 OctStr32 const* src = (OctStr32 const*)t;
76
77 int i;
78 if (rnd_func(t, sizeof(FpElem) * CHAR_BIT + EPID_SLEN, rnd_param)) {
79 return 0;
80 }
81 for (i = RAND_NUM_WORDS - 1; i >= 0; i--) {
82 src = Uint32Deserialize(deserialized_t.word + i, src);
83 }
84 VliModBarrett(&result->limbs, &deserialized_t, &epid20_p);
85 return 1;
86 }
87
FpRandNonzero(FpElem * result,BitSupplier rnd_func,void * rnd_param)88 int FpRandNonzero(FpElem* result, BitSupplier rnd_func, void* rnd_param) {
89 VeryLargeIntProduct deserialized_t = {{0}};
90 uint32_t t[RAND_NUM_WORDS] = {0};
91 OctStr32 const* src = (OctStr32 const*)t;
92 int i;
93 if (rnd_func(t, sizeof(FpElem) * CHAR_BIT + EPID_SLEN, rnd_param)) {
94 return 0;
95 }
96 for (i = RAND_NUM_WORDS - 1; i >= 0; i--) {
97 src = Uint32Deserialize(deserialized_t.word + i, src);
98 }
99 VliModBarrett(&result->limbs, &deserialized_t, &p_minus_one);
100 // (t mod(p-1)) + 1 gives number in [1,p-1]
101 FpAdd(result, result, &one);
102 return 1;
103 }
104
FpClear(FpElem * result)105 void FpClear(FpElem* result) { VliClear(&result->limbs); }
106
FpSet(FpElem * result,uint32_t in)107 void FpSet(FpElem* result, uint32_t in) {
108 FpClear(result);
109 *(uint32_t*)(result->limbs.word) = in;
110 }
111
FpFromHash(FpElem * result,unsigned char const * hash,size_t len)112 void FpFromHash(FpElem* result, unsigned char const* hash, size_t len) {
113 size_t i;
114 VeryLargeIntProduct vli;
115 memset(&vli, 0, sizeof(vli));
116 for (i = 0; i < len; i++) {
117 ((uint8_t*)vli.word)[len - i - 1] = hash[i];
118 }
119 VliModBarrett(&result->limbs, &vli, &epid20_p);
120 }
121