• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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