/*############################################################################ # Copyright 2017 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ############################################################################*/ /// Implementation of de/serialize functionality. /*! \file */ #include "epid/member/tiny/math/serialize.h" #include #include #include "epid/common/types.h" #include "epid/member/tiny/math/mathtypes.h" #include "epid/member/tiny/stdlib/endian.h" #include "epid/member/tiny/stdlib/tiny_stdlib.h" #if !defined(UNOPTIMIZED_SERIALIZATION) void SwapNativeAndPortableLayout(void* dest, size_t dest_size, void const* src, size_t src_size) { size_t i, j; #if defined(DEBUG) if (dest_size != src_size || 0 != src_size % 32) { memset(dest, 0xff, dest_size); return; } #else // defined(DEBUG) (void)dest_size; #endif // defined(DEBUG) for (i = 0; i < src_size; i += 32) { for (j = 0; j < 32 / 2; j += sizeof(uint32_t)) { uint32_t tmp = htobe32( *(uint32_t*)((uint8_t*)src + i + j)); // handle src==dest case *(uint32_t*)((uint8_t*)dest + i + j) = htobe32(*(uint32_t*)((uint8_t*)src + i + 32 - sizeof(uint32_t) - j)); *(uint32_t*)((uint8_t*)dest + i + 32 - sizeof(uint32_t) - j) = tmp; } } } #endif // !defined(UNOPTIMIZED_SERIALIZATION) void* Uint32Serialize(OctStr32* dest, uint32_t src) { int i; for (i = 0; i < 4; i++) dest->data[i] = (char)((src >> (24 - 8 * i)) & 0x000000FF); // get the ith byte of num, in little-endian order return dest->data + 4; } void const* Uint32Deserialize(uint32_t* dest, OctStr32 const* src) { int i; *dest = 0; for (i = 0; i < 4; i++) { *dest <<= 8; *dest |= (uint32_t)(*(&src->data[i]) & 0x000000FF); } return src->data + 4; } void* VliSerialize(BigNumStr* dest, VeryLargeInt const* src) { #if defined(UNOPTIMIZED_SERIALIZATION) int i; for (i = NUM_ECC_DIGITS - 1; i >= 0; i--) { dest = Uint32Serialize((OctStr32*)dest, src->word[i]); } return dest; #else // defined(UNOPTIMIZED_SERIALIZATION) SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src)); return dest + 1; #endif // defined(UNOPTIMIZED_SERIALIZATION) } void const* VliDeserialize(VeryLargeInt* dest, BigNumStr const* src) { #if defined(UNOPTIMIZED_SERIALIZATION) int i; for (i = NUM_ECC_DIGITS - 1; i >= 0; i--) { src = Uint32Deserialize(dest->word + i, (OctStr32 const*)src); } return src; #else // defined(UNOPTIMIZED_SERIALIZATION) SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src)); return src + 1; #endif // defined(UNOPTIMIZED_SERIALIZATION) } void* FqSerialize(FqElemStr* dest, FqElem const* src) { #if defined(UNOPTIMIZED_SERIALIZATION) dest = VliSerialize((BigNumStr*)dest, &src->limbs); return dest; #else // defined(UNOPTIMIZED_SERIALIZATION) SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src)); return dest + 1; #endif // defined(UNOPTIMIZED_SERIALIZATION) } void const* FqDeserialize(FqElem* dest, FqElemStr const* src) { #if defined(UNOPTIMIZED_SERIALIZATION) src = VliDeserialize(&dest->limbs, (BigNumStr const*)src); return src; #else // defined(UNOPTIMIZED_SERIALIZATION) SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src)); return src + 1; #endif // defined(UNOPTIMIZED_SERIALIZATION) } #if defined(UNOPTIMIZED_SERIALIZATION) static void* Fq2Serialize(Fq2ElemStr* dest, Fq2Elem const* src) { FqSerialize(&dest->a[0], &src->x0); FqSerialize(&dest->a[1], &src->x1); return dest + sizeof(*dest); } static void const* Fq2Deserialize(Fq2Elem* dest, Fq2ElemStr const* src) { FqDeserialize(&dest->x0, &src->a[0]); FqDeserialize(&dest->x1, &src->a[1]); return src + sizeof(*src); } static void* Fq6Serialize(Fq6ElemStr* dest, Fq6Elem const* src) { Fq2Serialize(&dest->a[0], &src->y0); Fq2Serialize(&dest->a[1], &src->y1); Fq2Serialize(&dest->a[2], &src->y2); return dest + sizeof(*dest); } static void const* Fq6Deserialize(Fq6Elem* dest, Fq6ElemStr const* src) { Fq2Deserialize(&dest->y0, &src->a[0]); Fq2Deserialize(&dest->y1, &src->a[1]); Fq2Deserialize(&dest->y2, &src->a[2]); return src + sizeof(*src); } #endif // defined(UNOPTIMIZED_SERIALIZATION) void const* Fq12Deserialize(Fq12Elem* dest, Fq12ElemStr const* src) { #if defined(UNOPTIMIZED_SERIALIZATION) Fq6Deserialize(&dest->z0, &src->a[0]); Fq6Deserialize(&dest->z1, &src->a[1]); return src + sizeof(*src); #else // defined(UNOPTIMIZED_SERIALIZATION) SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src)); return src + 1; #endif // defined(UNOPTIMIZED_SERIALIZATION) } void* Fq12Serialize(Fq12ElemStr* dest, Fq12Elem const* src) { #if defined(UNOPTIMIZED_SERIALIZATION) Fq6Serialize(&dest->a[0], &src->z0); Fq6Serialize(&dest->a[1], &src->z1); return dest + sizeof(*dest); #else // defined(UNOPTIMIZED_SERIALIZATION) SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src)); return dest + 1; #endif // defined(UNOPTIMIZED_SERIALIZATION) } void* FpSerialize(FpElemStr* dest, FpElem const* src) { #if defined(UNOPTIMIZED_SERIALIZATION) dest = VliSerialize((BigNumStr*)dest, &src->limbs); return dest; #else // defined(UNOPTIMIZED_SERIALIZATION) SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src)); return dest + 1; #endif // defined(UNOPTIMIZED_SERIALIZATION) } void const* FpDeserialize(FpElem* dest, FpElemStr const* src) { #if defined(UNOPTIMIZED_SERIALIZATION) src = VliDeserialize(&dest->limbs, (BigNumStr const*)src); return src; #else // defined(UNOPTIMIZED_SERIALIZATION) SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src)); return src + 1; #endif // defined(UNOPTIMIZED_SERIALIZATION) } void* EFqSerialize(G1ElemStr* dest, EccPointFq const* src) { #if defined(UNOPTIMIZED_SERIALIZATION) dest = FqSerialize((FqElemStr*)dest, &src->x); dest = FqSerialize((FqElemStr*)dest, &src->y); return dest; #else // defined(UNOPTIMIZED_SERIALIZATION) SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src)); return dest + 1; #endif // defined(UNOPTIMIZED_SERIALIZATION) } void const* EFqDeserialize(EccPointFq* dest, G1ElemStr const* src) { #if defined(UNOPTIMIZED_SERIALIZATION) src = FqDeserialize(&dest->x, (FqElemStr const*)src); src = FqDeserialize(&dest->y, (FqElemStr const*)src); return src; #else // defined(UNOPTIMIZED_SERIALIZATION) SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src)); return src + 1; #endif // defined(UNOPTIMIZED_SERIALIZATION) } void* EFq2Serialize(G2ElemStr* dest, EccPointFq2 const* src) { #if defined(UNOPTIMIZED_SERIALIZATION) dest = FqSerialize((FqElemStr*)dest, &src->x.x0); dest = FqSerialize((FqElemStr*)dest, &src->x.x1); dest = FqSerialize((FqElemStr*)dest, &src->y.x0); dest = FqSerialize((FqElemStr*)dest, &src->y.x1); return dest; #else // defined(UNOPTIMIZED_SERIALIZATION) SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src)); return dest + 1; #endif // defined(UNOPTIMIZED_SERIALIZATION) } void const* EFq2Deserialize(EccPointFq2* dest, G2ElemStr const* src) { #if defined(UNOPTIMIZED_SERIALIZATION) src = FqDeserialize(&dest->x.x0, (FqElemStr const*)src); src = FqDeserialize(&dest->x.x1, (FqElemStr const*)src); src = FqDeserialize(&dest->y.x0, (FqElemStr const*)src); src = FqDeserialize(&dest->y.x1, (FqElemStr const*)src); return src; #else // defined(UNOPTIMIZED_SERIALIZATION) SwapNativeAndPortableLayout(dest, sizeof(*dest), src, sizeof(*src)); return src + 1; #endif // defined(UNOPTIMIZED_SERIALIZATION) }