9#ifndef BOTAN_LOAD_STORE_H_
10#define BOTAN_LOAD_STORE_H_
12#include <botan/types.h>
13#include <botan/internal/bswap.h>
14#include <botan/mem_ops.h>
17#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
18 #define BOTAN_ENDIAN_N2L(x) reverse_bytes(x)
19 #define BOTAN_ENDIAN_L2N(x) reverse_bytes(x)
20 #define BOTAN_ENDIAN_N2B(x) (x)
21 #define BOTAN_ENDIAN_B2N(x) (x)
23#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
24 #define BOTAN_ENDIAN_N2L(x) (x)
25 #define BOTAN_ENDIAN_L2N(x) (x)
26 #define BOTAN_ENDIAN_N2B(x) reverse_bytes(x)
27 #define BOTAN_ENDIAN_B2N(x) reverse_bytes(x)
39template<
typename T>
inline constexpr uint8_t
get_byte_var(
size_t byte_num,
T input)
41 return static_cast<uint8_t
>(
42 input >> (((~byte_num)&(
sizeof(
T)-1)) << 3)
51template<
size_t B,
typename T>
inline constexpr uint8_t
get_byte(
T input)
53 static_assert(B <
sizeof(
T),
"Valid byte offset");
55 const size_t shift = ((~B) & (
sizeof(
T) - 1)) << 3;
56 return static_cast<uint8_t
>((input >> shift) & 0xFF);
67 return static_cast<uint16_t
>((
static_cast<uint16_t
>(i0) << 8) | i1);
78inline constexpr uint32_t
make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
80 return ((
static_cast<uint32_t
>(i0) << 24) |
81 (
static_cast<uint32_t
>(i1) << 16) |
82 (
static_cast<uint32_t
>(i2) << 8) |
83 (
static_cast<uint32_t
>(i3)));
98inline constexpr uint64_t
make_uint64(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3,
99 uint8_t i4, uint8_t i5, uint8_t i6, uint8_t i7)
101 return ((
static_cast<uint64_t
>(i0) << 56) |
102 (
static_cast<uint64_t
>(i1) << 48) |
103 (
static_cast<uint64_t
>(i2) << 40) |
104 (
static_cast<uint64_t
>(i3) << 32) |
105 (
static_cast<uint64_t
>(i4) << 24) |
106 (
static_cast<uint64_t
>(i5) << 16) |
107 (
static_cast<uint64_t
>(i6) << 8) |
108 (
static_cast<uint64_t
>(i7)));
118inline constexpr T load_be(
const uint8_t in[],
size_t off)
120 in += off *
sizeof(
T);
122 for(
size_t i = 0; i !=
sizeof(
T); ++i)
123 out =
static_cast<T>((out << 8) | in[i]);
134inline constexpr T load_le(
const uint8_t in[],
size_t off)
136 in += off *
sizeof(
T);
138 for(
size_t i = 0; i !=
sizeof(
T); ++i)
139 out = (out << 8) | in[
sizeof(
T)-1-i];
152 in += off *
sizeof(uint16_t);
154#if defined(BOTAN_ENDIAN_N2B)
157 return BOTAN_ENDIAN_N2B(x);
172 in += off *
sizeof(uint16_t);
174#if defined(BOTAN_ENDIAN_N2L)
177 return BOTAN_ENDIAN_N2L(x);
192 in += off *
sizeof(uint32_t);
193#if defined(BOTAN_ENDIAN_N2B)
196 return BOTAN_ENDIAN_N2B(x);
211 in += off *
sizeof(uint32_t);
212#if defined(BOTAN_ENDIAN_N2L)
215 return BOTAN_ENDIAN_N2L(x);
230 in += off *
sizeof(uint64_t);
231#if defined(BOTAN_ENDIAN_N2B)
234 return BOTAN_ENDIAN_N2B(x);
237 in[4], in[5], in[6], in[7]);
250 in += off *
sizeof(uint64_t);
251#if defined(BOTAN_ENDIAN_N2L)
254 return BOTAN_ENDIAN_N2L(x);
257 in[3], in[2], in[1], in[0]);
268inline constexpr void load_le(
const uint8_t in[],
T& x0,
T& x1)
270 x0 = load_le<T>(in, 0);
271 x1 = load_le<T>(in, 1);
283inline constexpr void load_le(
const uint8_t in[],
284 T& x0,
T& x1,
T& x2,
T& x3)
286 x0 = load_le<T>(in, 0);
287 x1 = load_le<T>(in, 1);
288 x2 = load_le<T>(in, 2);
289 x3 = load_le<T>(in, 3);
305inline constexpr void load_le(
const uint8_t in[],
306 T& x0,
T& x1,
T& x2,
T& x3,
307 T& x4,
T& x5,
T& x6,
T& x7)
309 x0 = load_le<T>(in, 0);
310 x1 = load_le<T>(in, 1);
311 x2 = load_le<T>(in, 2);
312 x3 = load_le<T>(in, 3);
313 x4 = load_le<T>(in, 4);
314 x5 = load_le<T>(in, 5);
315 x6 = load_le<T>(in, 6);
316 x7 = load_le<T>(in, 7);
332#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
335#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
338 const size_t blocks = count - (count % 4);
339 const size_t left = count - blocks;
341 for(
size_t i = 0; i != blocks; i += 4)
344 for(
size_t i = 0; i != left; ++i)
347 for(
size_t i = 0; i != count; ++i)
348 out[i] = load_le<T>(in, i);
360inline constexpr void load_be(
const uint8_t in[],
T& x0,
T& x1)
362 x0 = load_be<T>(in, 0);
363 x1 = load_be<T>(in, 1);
375inline constexpr void load_be(
const uint8_t in[],
376 T& x0,
T& x1,
T& x2,
T& x3)
378 x0 = load_be<T>(in, 0);
379 x1 = load_be<T>(in, 1);
380 x2 = load_be<T>(in, 2);
381 x3 = load_be<T>(in, 3);
397inline constexpr void load_be(
const uint8_t in[],
398 T& x0,
T& x1,
T& x2,
T& x3,
399 T& x4,
T& x5,
T& x6,
T& x7)
401 x0 = load_be<T>(in, 0);
402 x1 = load_be<T>(in, 1);
403 x2 = load_be<T>(in, 2);
404 x3 = load_be<T>(in, 3);
405 x4 = load_be<T>(in, 4);
406 x5 = load_be<T>(in, 5);
407 x6 = load_be<T>(in, 6);
408 x7 = load_be<T>(in, 7);
424#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
427#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
429 const size_t blocks = count - (count % 4);
430 const size_t left = count - blocks;
432 for(
size_t i = 0; i != blocks; i += 4)
435 for(
size_t i = 0; i != left; ++i)
438 for(
size_t i = 0; i != count; ++i)
439 out[i] = load_be<T>(in, i);
449inline constexpr void store_be(uint16_t in, uint8_t out[2])
451#if defined(BOTAN_ENDIAN_N2B)
452 uint16_t o = BOTAN_ENDIAN_N2B(in);
455 out[0] = get_byte<0>(in);
456 out[1] = get_byte<1>(in);
465inline constexpr void store_le(uint16_t in, uint8_t out[2])
467#if defined(BOTAN_ENDIAN_N2L)
468 uint16_t o = BOTAN_ENDIAN_N2L(in);
471 out[0] = get_byte<1>(in);
472 out[1] = get_byte<0>(in);
481inline constexpr void store_be(uint32_t in, uint8_t out[4])
483#if defined(BOTAN_ENDIAN_B2N)
484 uint32_t o = BOTAN_ENDIAN_B2N(in);
487 out[0] = get_byte<0>(in);
488 out[1] = get_byte<1>(in);
489 out[2] = get_byte<2>(in);
490 out[3] = get_byte<3>(in);
499inline constexpr void store_le(uint32_t in, uint8_t out[4])
501#if defined(BOTAN_ENDIAN_L2N)
502 uint32_t o = BOTAN_ENDIAN_L2N(in);
505 out[0] = get_byte<3>(in);
506 out[1] = get_byte<2>(in);
507 out[2] = get_byte<1>(in);
508 out[3] = get_byte<0>(in);
517inline constexpr void store_be(uint64_t in, uint8_t out[8])
519#if defined(BOTAN_ENDIAN_B2N)
520 uint64_t o = BOTAN_ENDIAN_B2N(in);
523 out[0] = get_byte<0>(in);
524 out[1] = get_byte<1>(in);
525 out[2] = get_byte<2>(in);
526 out[3] = get_byte<3>(in);
527 out[4] = get_byte<4>(in);
528 out[5] = get_byte<5>(in);
529 out[6] = get_byte<6>(in);
530 out[7] = get_byte<7>(in);
539inline constexpr void store_le(uint64_t in, uint8_t out[8])
541#if defined(BOTAN_ENDIAN_L2N)
542 uint64_t o = BOTAN_ENDIAN_L2N(in);
545 out[0] = get_byte<7>(in);
546 out[1] = get_byte<6>(in);
547 out[2] = get_byte<5>(in);
548 out[3] = get_byte<4>(in);
549 out[4] = get_byte<3>(in);
550 out[5] = get_byte<2>(in);
551 out[6] = get_byte<1>(in);
552 out[7] = get_byte<0>(in);
630 T x4,
T x5,
T x6,
T x7)
656 T x4,
T x5,
T x6,
T x7)
671 while(out_bytes >=
sizeof(
T))
675 out_bytes -=
sizeof(
T);
679 for(
size_t i = 0; i != out_bytes; ++i)
683template<
typename T,
typename Alloc>
692 while(out_bytes >=
sizeof(
T))
696 out_bytes -=
sizeof(
T);
700 for(
size_t i = 0; i != out_bytes; ++i)
704template<
typename T,
typename Alloc>
constexpr uint32_t load_le< uint32_t >(const uint8_t in[], size_t off)
constexpr void store_le(uint16_t in, uint8_t out[2])
void copy_out_le(uint8_t out[], size_t out_bytes, const T in[])
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)
constexpr uint16_t load_le< uint16_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)
constexpr uint64_t load_be< uint64_t >(const uint8_t in[], size_t off)
constexpr uint8_t get_byte(T input)
constexpr void bswap_4(T x[4])
constexpr uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
constexpr T load_le(const uint8_t in[], size_t off)
constexpr uint32_t load_be< uint32_t >(const uint8_t in[], size_t off)
constexpr uint16_t reverse_bytes(uint16_t x)
constexpr uint16_t load_be< uint16_t >(const uint8_t in[], size_t off)
constexpr void store_be(uint16_t in, uint8_t out[2])
constexpr uint8_t get_byte_var(size_t byte_num, T input)
constexpr uint64_t load_le< uint64_t >(const uint8_t in[], size_t off)
constexpr void typecast_copy(T &out, const uint8_t in[])
void copy_out_be(uint8_t out[], size_t out_bytes, const T in[])
constexpr T load_be(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)
constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1)