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 de/serialize functionality.
17 /*! \file */
18 
19 #include "epid/member/tiny/math/serialize.h"
20 #include <stddef.h>
21 #include <stdint.h>
22 #include "epid/common/types.h"
23 #include "epid/member/tiny/math/mathtypes.h"
24 #include "epid/member/tiny/stdlib/endian.h"
25 #include "epid/member/tiny/stdlib/tiny_stdlib.h"
26 
27 #if !defined(UNOPTIMIZED_SERIALIZATION)
SwapNativeAndPortableLayout(void * dest,size_t dest_size,void const * src,size_t src_size)28 void SwapNativeAndPortableLayout(void* dest, size_t dest_size, void const* src,
29                                  size_t src_size) {
30   size_t i, j;
31 #if defined(DEBUG)
32   if (dest_size != src_size || 0 != src_size % 32) {
33     memset(dest, 0xff, dest_size);
34     return;
35   }
36 #else   // defined(DEBUG)
37   (void)dest_size;
38 #endif  // defined(DEBUG)
39   for (i = 0; i < src_size; i += 32) {
40     for (j = 0; j < 32 / 2; j += sizeof(uint32_t)) {
41       uint32_t tmp = htobe32(
42           *(uint32_t*)((uint8_t*)src + i + j));  // handle src==dest case
43       *(uint32_t*)((uint8_t*)dest + i + j) =
44           htobe32(*(uint32_t*)((uint8_t*)src + i + 32 - sizeof(uint32_t) - j));
45       *(uint32_t*)((uint8_t*)dest + i + 32 - sizeof(uint32_t) - j) = tmp;
46     }
47   }
48 }
49 #endif  // !defined(UNOPTIMIZED_SERIALIZATION)
50 
Uint32Serialize(OctStr32 * dest,uint32_t src)51 void* Uint32Serialize(OctStr32* dest, uint32_t src) {
52   int i;
53   for (i = 0; i < 4; i++)
54     dest->data[i] =
55         (char)((src >> (24 - 8 * i)) &
56                0x000000FF);  // get the ith byte of num, in little-endian order
57   return dest->data + 4;
58 }
59 
Uint32Deserialize(uint32_t * dest,OctStr32 const * src)60 void const* Uint32Deserialize(uint32_t* dest, OctStr32 const* src) {
61   int i;
62   *dest = 0;
63   for (i = 0; i < 4; i++) {
64     *dest <<= 8;
65     *dest |= (uint32_t)(*(&src->data[i]) & 0x000000FF);
66   }
67   return src->data + 4;
68 }
69 
VliSerialize(BigNumStr * dest,VeryLargeInt const * src)70 void* VliSerialize(BigNumStr* dest, VeryLargeInt const* src) {
71 #if defined(UNOPTIMIZED_SERIALIZATION)
72   int i;
73   for (i = NUM_ECC_DIGITS - 1; i >= 0; i--) {
74     dest = Uint32Serialize((OctStr32*)dest, src->word[i]);
75   }
76   return dest;
77 #else   // defined(UNOPTIMIZED_SERIALIZATION)
78   SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src));
79   return dest + 1;
80 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
81 }
82 
VliDeserialize(VeryLargeInt * dest,BigNumStr const * src)83 void const* VliDeserialize(VeryLargeInt* dest, BigNumStr const* src) {
84 #if defined(UNOPTIMIZED_SERIALIZATION)
85   int i;
86   for (i = NUM_ECC_DIGITS - 1; i >= 0; i--) {
87     src = Uint32Deserialize(dest->word + i, (OctStr32 const*)src);
88   }
89   return src;
90 #else   // defined(UNOPTIMIZED_SERIALIZATION)
91   SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src));
92   return src + 1;
93 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
94 }
95 
FqSerialize(FqElemStr * dest,FqElem const * src)96 void* FqSerialize(FqElemStr* dest, FqElem const* src) {
97 #if defined(UNOPTIMIZED_SERIALIZATION)
98   dest = VliSerialize((BigNumStr*)dest, &src->limbs);
99   return dest;
100 #else   // defined(UNOPTIMIZED_SERIALIZATION)
101   SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src));
102   return dest + 1;
103 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
104 }
105 
FqDeserialize(FqElem * dest,FqElemStr const * src)106 void const* FqDeserialize(FqElem* dest, FqElemStr const* src) {
107 #if defined(UNOPTIMIZED_SERIALIZATION)
108   src = VliDeserialize(&dest->limbs, (BigNumStr const*)src);
109   return src;
110 #else   // defined(UNOPTIMIZED_SERIALIZATION)
111   SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src));
112   return src + 1;
113 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
114 }
115 
116 #if defined(UNOPTIMIZED_SERIALIZATION)
Fq2Serialize(Fq2ElemStr * dest,Fq2Elem const * src)117 static void* Fq2Serialize(Fq2ElemStr* dest, Fq2Elem const* src) {
118   FqSerialize(&dest->a[0], &src->x0);
119   FqSerialize(&dest->a[1], &src->x1);
120   return dest + sizeof(*dest);
121 }
122 
Fq2Deserialize(Fq2Elem * dest,Fq2ElemStr const * src)123 static void const* Fq2Deserialize(Fq2Elem* dest, Fq2ElemStr const* src) {
124   FqDeserialize(&dest->x0, &src->a[0]);
125   FqDeserialize(&dest->x1, &src->a[1]);
126   return src + sizeof(*src);
127 }
128 
Fq6Serialize(Fq6ElemStr * dest,Fq6Elem const * src)129 static void* Fq6Serialize(Fq6ElemStr* dest, Fq6Elem const* src) {
130   Fq2Serialize(&dest->a[0], &src->y0);
131   Fq2Serialize(&dest->a[1], &src->y1);
132   Fq2Serialize(&dest->a[2], &src->y2);
133   return dest + sizeof(*dest);
134 }
135 
Fq6Deserialize(Fq6Elem * dest,Fq6ElemStr const * src)136 static void const* Fq6Deserialize(Fq6Elem* dest, Fq6ElemStr const* src) {
137   Fq2Deserialize(&dest->y0, &src->a[0]);
138   Fq2Deserialize(&dest->y1, &src->a[1]);
139   Fq2Deserialize(&dest->y2, &src->a[2]);
140   return src + sizeof(*src);
141 }
142 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
143 
Fq12Deserialize(Fq12Elem * dest,Fq12ElemStr const * src)144 void const* Fq12Deserialize(Fq12Elem* dest, Fq12ElemStr const* src) {
145 #if defined(UNOPTIMIZED_SERIALIZATION)
146   Fq6Deserialize(&dest->z0, &src->a[0]);
147   Fq6Deserialize(&dest->z1, &src->a[1]);
148   return src + sizeof(*src);
149 #else   // defined(UNOPTIMIZED_SERIALIZATION)
150   SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src));
151   return src + 1;
152 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
153 }
154 
Fq12Serialize(Fq12ElemStr * dest,Fq12Elem const * src)155 void* Fq12Serialize(Fq12ElemStr* dest, Fq12Elem const* src) {
156 #if defined(UNOPTIMIZED_SERIALIZATION)
157   Fq6Serialize(&dest->a[0], &src->z0);
158   Fq6Serialize(&dest->a[1], &src->z1);
159   return dest + sizeof(*dest);
160 #else   // defined(UNOPTIMIZED_SERIALIZATION)
161   SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src));
162   return dest + 1;
163 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
164 }
165 
FpSerialize(FpElemStr * dest,FpElem const * src)166 void* FpSerialize(FpElemStr* dest, FpElem const* src) {
167 #if defined(UNOPTIMIZED_SERIALIZATION)
168   dest = VliSerialize((BigNumStr*)dest, &src->limbs);
169   return dest;
170 #else   // defined(UNOPTIMIZED_SERIALIZATION)
171   SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src));
172   return dest + 1;
173 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
174 }
175 
FpDeserialize(FpElem * dest,FpElemStr const * src)176 void const* FpDeserialize(FpElem* dest, FpElemStr const* src) {
177 #if defined(UNOPTIMIZED_SERIALIZATION)
178   src = VliDeserialize(&dest->limbs, (BigNumStr const*)src);
179   return src;
180 #else   // defined(UNOPTIMIZED_SERIALIZATION)
181   SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src));
182   return src + 1;
183 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
184 }
185 
EFqSerialize(G1ElemStr * dest,EccPointFq const * src)186 void* EFqSerialize(G1ElemStr* dest, EccPointFq const* src) {
187 #if defined(UNOPTIMIZED_SERIALIZATION)
188   dest = FqSerialize((FqElemStr*)dest, &src->x);
189   dest = FqSerialize((FqElemStr*)dest, &src->y);
190   return dest;
191 #else   // defined(UNOPTIMIZED_SERIALIZATION)
192   SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src));
193   return dest + 1;
194 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
195 }
196 
EFqDeserialize(EccPointFq * dest,G1ElemStr const * src)197 void const* EFqDeserialize(EccPointFq* dest, G1ElemStr const* src) {
198 #if defined(UNOPTIMIZED_SERIALIZATION)
199   src = FqDeserialize(&dest->x, (FqElemStr const*)src);
200   src = FqDeserialize(&dest->y, (FqElemStr const*)src);
201   return src;
202 #else   // defined(UNOPTIMIZED_SERIALIZATION)
203   SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src));
204   return src + 1;
205 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
206 }
207 
EFq2Serialize(G2ElemStr * dest,EccPointFq2 const * src)208 void* EFq2Serialize(G2ElemStr* dest, EccPointFq2 const* src) {
209 #if defined(UNOPTIMIZED_SERIALIZATION)
210   dest = FqSerialize((FqElemStr*)dest, &src->x.x0);
211   dest = FqSerialize((FqElemStr*)dest, &src->x.x1);
212   dest = FqSerialize((FqElemStr*)dest, &src->y.x0);
213   dest = FqSerialize((FqElemStr*)dest, &src->y.x1);
214   return dest;
215 #else   // defined(UNOPTIMIZED_SERIALIZATION)
216   SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src));
217   return dest + 1;
218 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
219 }
220 
EFq2Deserialize(EccPointFq2 * dest,G2ElemStr const * src)221 void const* EFq2Deserialize(EccPointFq2* dest, G2ElemStr const* src) {
222 #if defined(UNOPTIMIZED_SERIALIZATION)
223   src = FqDeserialize(&dest->x.x0, (FqElemStr const*)src);
224   src = FqDeserialize(&dest->x.x1, (FqElemStr const*)src);
225   src = FqDeserialize(&dest->y.x0, (FqElemStr const*)src);
226   src = FqDeserialize(&dest->y.x1, (FqElemStr const*)src);
227   return src;
228 #else   // defined(UNOPTIMIZED_SERIALIZATION)
229   SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src));
230   return src + 1;
231 #endif  // defined(UNOPTIMIZED_SERIALIZATION)
232 }
233