9#ifndef BOTAN_LOAD_STORE_H_
10#define BOTAN_LOAD_STORE_H_
12#include <botan/types.h>
13#include <botan/bswap.h>
14#include <botan/mem_ops.h>
19#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
20 #define BOTAN_ENDIAN_N2L(x) reverse_bytes(x)
21 #define BOTAN_ENDIAN_L2N(x) reverse_bytes(x)
22 #define BOTAN_ENDIAN_N2B(x) (x)
23 #define BOTAN_ENDIAN_B2N(x) (x)
25#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
26 #define BOTAN_ENDIAN_N2L(x) (x)
27 #define BOTAN_ENDIAN_L2N(x) (x)
28 #define BOTAN_ENDIAN_N2B(x) reverse_bytes(x)
29 #define BOTAN_ENDIAN_B2N(x) reverse_bytes(x)
41template<
typename T>
inline constexpr uint8_t
get_byte(
size_t byte_num,
T input)
43 return static_cast<uint8_t
>(
44 input >> (((~byte_num)&(
sizeof(
T)-1)) << 3)
56 return static_cast<uint16_t
>((
static_cast<uint16_t
>(i0) << 8) | i1);
67inline constexpr uint32_t
make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
69 return ((
static_cast<uint32_t
>(i0) << 24) |
70 (
static_cast<uint32_t
>(i1) << 16) |
71 (
static_cast<uint32_t
>(i2) << 8) |
72 (
static_cast<uint32_t
>(i3)));
87inline constexpr uint64_t
make_uint64(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3,
88 uint8_t i4, uint8_t i5, uint8_t i6, uint8_t i7)
90 return ((
static_cast<uint64_t
>(i0) << 56) |
91 (
static_cast<uint64_t
>(i1) << 48) |
92 (
static_cast<uint64_t
>(i2) << 40) |
93 (
static_cast<uint64_t
>(i3) << 32) |
94 (
static_cast<uint64_t
>(i4) << 24) |
95 (
static_cast<uint64_t
>(i5) << 16) |
96 (
static_cast<uint64_t
>(i6) << 8) |
97 (
static_cast<uint64_t
>(i7)));
109 in += off *
sizeof(
T);
111 for(
size_t i = 0; i !=
sizeof(
T); ++i)
112 out =
static_cast<T>((out << 8) | in[i]);
125 in += off *
sizeof(
T);
127 for(
size_t i = 0; i !=
sizeof(
T); ++i)
128 out = (out << 8) | in[
sizeof(
T)-1-i];
141 in += off *
sizeof(uint16_t);
143#if defined(BOTAN_ENDIAN_N2B)
146 return BOTAN_ENDIAN_N2B(x);
161 in += off *
sizeof(uint16_t);
163#if defined(BOTAN_ENDIAN_N2L)
166 return BOTAN_ENDIAN_N2L(x);
181 in += off *
sizeof(uint32_t);
182#if defined(BOTAN_ENDIAN_N2B)
185 return BOTAN_ENDIAN_N2B(x);
200 in += off *
sizeof(uint32_t);
201#if defined(BOTAN_ENDIAN_N2L)
204 return BOTAN_ENDIAN_N2L(x);
219 in += off *
sizeof(uint64_t);
220#if defined(BOTAN_ENDIAN_N2B)
223 return BOTAN_ENDIAN_N2B(x);
226 in[4], in[5], in[6], in[7]);
239 in += off *
sizeof(uint64_t);
240#if defined(BOTAN_ENDIAN_N2L)
243 return BOTAN_ENDIAN_N2L(x);
246 in[3], in[2], in[1], in[0]);
259 x0 = load_le<T>(in, 0);
260 x1 = load_le<T>(in, 1);
273 T& x0,
T& x1,
T& x2,
T& x3)
275 x0 = load_le<T>(in, 0);
276 x1 = load_le<T>(in, 1);
277 x2 = load_le<T>(in, 2);
278 x3 = load_le<T>(in, 3);
295 T& x0,
T& x1,
T& x2,
T& x3,
296 T& x4,
T& x5,
T& x6,
T& x7)
298 x0 = load_le<T>(in, 0);
299 x1 = load_le<T>(in, 1);
300 x2 = load_le<T>(in, 2);
301 x3 = load_le<T>(in, 3);
302 x4 = load_le<T>(in, 4);
303 x5 = load_le<T>(in, 5);
304 x6 = load_le<T>(in, 6);
305 x7 = load_le<T>(in, 7);
321#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
324#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
327 const size_t blocks = count - (count % 4);
328 const size_t left = count - blocks;
330 for(
size_t i = 0; i != blocks; i += 4)
333 for(
size_t i = 0; i != left; ++i)
336 for(
size_t i = 0; i != count; ++i)
337 out[i] = load_le<T>(in, i);
351 x0 = load_be<T>(in, 0);
352 x1 = load_be<T>(in, 1);
365 T& x0,
T& x1,
T& x2,
T& x3)
367 x0 = load_be<T>(in, 0);
368 x1 = load_be<T>(in, 1);
369 x2 = load_be<T>(in, 2);
370 x3 = load_be<T>(in, 3);
387 T& x0,
T& x1,
T& x2,
T& x3,
388 T& x4,
T& x5,
T& x6,
T& x7)
390 x0 = load_be<T>(in, 0);
391 x1 = load_be<T>(in, 1);
392 x2 = load_be<T>(in, 2);
393 x3 = load_be<T>(in, 3);
394 x4 = load_be<T>(in, 4);
395 x5 = load_be<T>(in, 5);
396 x6 = load_be<T>(in, 6);
397 x7 = load_be<T>(in, 7);
413#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
416#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
418 const size_t blocks = count - (count % 4);
419 const size_t left = count - blocks;
421 for(
size_t i = 0; i != blocks; i += 4)
424 for(
size_t i = 0; i != left; ++i)
427 for(
size_t i = 0; i != count; ++i)
428 out[i] = load_be<T>(in, i);
440#if defined(BOTAN_ENDIAN_N2B)
441 uint16_t o = BOTAN_ENDIAN_N2B(in);
456#if defined(BOTAN_ENDIAN_N2L)
457 uint16_t o = BOTAN_ENDIAN_N2L(in);
472#if defined(BOTAN_ENDIAN_B2N)
473 uint32_t o = BOTAN_ENDIAN_B2N(in);
490#if defined(BOTAN_ENDIAN_L2N)
491 uint32_t o = BOTAN_ENDIAN_L2N(in);
508#if defined(BOTAN_ENDIAN_B2N)
509 uint64_t o = BOTAN_ENDIAN_B2N(in);
530#if defined(BOTAN_ENDIAN_L2N)
531 uint64_t o = BOTAN_ENDIAN_L2N(in);
619 T x4,
T x5,
T x6,
T x7)
645 T x4,
T x5,
T x6,
T x7)
660 while(out_bytes >=
sizeof(
T))
664 out_bytes -=
sizeof(
T);
668 for(
size_t i = 0; i != out_bytes; ++i)
672template<
typename T,
typename Alloc>
681 while(out_bytes >=
sizeof(
T))
685 out_bytes -=
sizeof(
T);
689 for(
size_t i = 0; i != out_bytes; ++i)
690 out[i] =
get_byte(
sizeof(
T) - 1 - (i % 8), in[0]);
693template<
typename T,
typename Alloc>
#define BOTAN_FUTURE_INTERNAL_HEADER(hdr)
void copy_out_le(uint8_t out[], size_t out_bytes, const T in[])
uint16_t reverse_bytes(uint16_t val)
constexpr uint64_t make_uint64(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4, uint8_t i5, uint8_t i6, uint8_t i7)
void store_be(uint16_t in, uint8_t out[2])
uint32_t load_le< uint32_t >(const uint8_t in[], size_t off)
void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector< T, Alloc > &in)
T load_be(const uint8_t in[], size_t off)
constexpr uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
T load_le(const uint8_t in[], size_t off)
uint32_t load_be< uint32_t >(const uint8_t in[], size_t off)
uint64_t load_be< uint64_t >(const uint8_t in[], size_t off)
void typecast_copy(uint8_t out[], T in[], size_t N)
uint16_t load_be< uint16_t >(const uint8_t in[], size_t off)
void store_le(uint16_t in, uint8_t out[2])
constexpr uint8_t get_byte(size_t byte_num, T input)
void copy_out_be(uint8_t out[], size_t out_bytes, const T in[])
uint16_t load_le< uint16_t >(const uint8_t in[], size_t off)
void copy_out_vec_be(uint8_t out[], size_t out_bytes, const std::vector< T, Alloc > &in)
uint64_t load_le< uint64_t >(const uint8_t in[], size_t off)
constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1)