9#ifndef BOTAN_LOAD_STORE_H_
10#define BOTAN_LOAD_STORE_H_
12#include <botan/mem_ops.h>
13#include <botan/types.h>
14#include <botan/internal/bswap.h>
27 return static_cast<uint8_t
>(input >> (((~byte_num) & (
sizeof(
T) - 1)) << 3));
35template <
size_t B,
typename T>
37 requires(B <
sizeof(
T))
39 const size_t shift = ((~B) & (
sizeof(
T) - 1)) << 3;
40 return static_cast<uint8_t
>((input >> shift) & 0xFF);
49inline constexpr uint16_t
make_uint16(uint8_t i0, uint8_t i1) {
50 return static_cast<uint16_t
>((
static_cast<uint16_t
>(i0) << 8) | i1);
61inline constexpr uint32_t
make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3) {
62 return ((
static_cast<uint32_t
>(i0) << 24) | (
static_cast<uint32_t
>(i1) << 16) | (
static_cast<uint32_t
>(i2) << 8) |
63 (
static_cast<uint32_t
>(i3)));
79 uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4, uint8_t i5, uint8_t i6, uint8_t i7) {
80 return ((
static_cast<uint64_t
>(i0) << 56) | (
static_cast<uint64_t
>(i1) << 48) | (
static_cast<uint64_t
>(i2) << 40) |
81 (
static_cast<uint64_t
>(i3) << 32) | (
static_cast<uint64_t
>(i4) << 24) | (
static_cast<uint64_t
>(i5) << 16) |
82 (
static_cast<uint64_t
>(i6) << 8) | (
static_cast<uint64_t
>(i7)));
92inline constexpr T load_be(
const uint8_t in[],
size_t off) {
93 in += off *
sizeof(
T);
95 for(
size_t i = 0; i !=
sizeof(
T); ++i) {
96 out =
static_cast<T>((out << 8) | in[i]);
108inline constexpr T load_le(
const uint8_t in[],
size_t off) {
109 in += off *
sizeof(
T);
111 for(
size_t i = 0; i !=
sizeof(
T); ++i) {
112 out = (out << 8) | in[
sizeof(
T) - 1 - i];
125 in += off *
sizeof(uint16_t);
127#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
128 return typecast_copy<uint16_t>(in);
129#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
144 in += off *
sizeof(uint16_t);
146#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
148#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
149 return typecast_copy<uint16_t>(in);
163 in += off *
sizeof(uint32_t);
165#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
166 return typecast_copy<uint32_t>(in);
167#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
182 in += off *
sizeof(uint32_t);
184#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
186#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
187 return typecast_copy<uint32_t>(in);
201 in += off *
sizeof(uint64_t);
203#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
204 return typecast_copy<uint64_t>(in);
205#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
208 return make_uint64(in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7]);
220 in += off *
sizeof(uint64_t);
222#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
224#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
225 return typecast_copy<uint64_t>(in);
227 return make_uint64(in[7], in[6], in[5], in[4], in[3], in[2], in[1], in[0]);
238inline constexpr void load_le(
const uint8_t in[],
T& x0,
T& x1) {
239 x0 = load_le<T>(in, 0);
240 x1 = load_le<T>(in, 1);
252inline constexpr void load_le(
const uint8_t in[],
T& x0,
T& x1,
T& x2,
T& x3) {
253 x0 = load_le<T>(in, 0);
254 x1 = load_le<T>(in, 1);
255 x2 = load_le<T>(in, 2);
256 x3 = load_le<T>(in, 3);
272inline constexpr void load_le(
const uint8_t in[],
T& x0,
T& x1,
T& x2,
T& x3,
T& x4,
T& x5,
T& x6,
T& x7) {
273 x0 = load_le<T>(in, 0);
274 x1 = load_le<T>(in, 1);
275 x2 = load_le<T>(in, 2);
276 x3 = load_le<T>(in, 3);
277 x4 = load_le<T>(in, 4);
278 x5 = load_le<T>(in, 5);
279 x6 = load_le<T>(in, 6);
280 x7 = load_le<T>(in, 7);
290inline constexpr void load_le(
T out[],
const uint8_t in[],
size_t count) {
292#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
295#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
298 for(
size_t i = 0; i != count; ++i)
301 for(
size_t i = 0; i != count; ++i)
302 out[i] = load_le<T>(in, i);
314inline constexpr void load_be(
const uint8_t in[],
T& x0,
T& x1) {
315 x0 = load_be<T>(in, 0);
316 x1 = load_be<T>(in, 1);
328inline constexpr void load_be(
const uint8_t in[],
T& x0,
T& x1,
T& x2,
T& x3) {
329 x0 = load_be<T>(in, 0);
330 x1 = load_be<T>(in, 1);
331 x2 = load_be<T>(in, 2);
332 x3 = load_be<T>(in, 3);
348inline constexpr void load_be(
const uint8_t in[],
T& x0,
T& x1,
T& x2,
T& x3,
T& x4,
T& x5,
T& x6,
T& x7) {
349 x0 = load_be<T>(in, 0);
350 x1 = load_be<T>(in, 1);
351 x2 = load_be<T>(in, 2);
352 x3 = load_be<T>(in, 3);
353 x4 = load_be<T>(in, 4);
354 x5 = load_be<T>(in, 5);
355 x6 = load_be<T>(in, 6);
356 x7 = load_be<T>(in, 7);
366inline constexpr void load_be(
T out[],
const uint8_t in[],
size_t count) {
368#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
371#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
374 for(
size_t i = 0; i != count; ++i) {
378 for(
size_t i = 0; i != count; ++i)
379 out[i] = load_be<T>(in, i);
389inline constexpr void store_be(uint16_t in, uint8_t out[2]) {
390#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
392#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
395 out[0] = get_byte<0>(in);
396 out[1] = get_byte<1>(in);
405inline constexpr void store_le(uint16_t in, uint8_t out[2]) {
406#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
408#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
411 out[0] = get_byte<1>(in);
412 out[1] = get_byte<0>(in);
421inline constexpr void store_be(uint32_t in, uint8_t out[4]) {
422#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
424#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
427 out[0] = get_byte<0>(in);
428 out[1] = get_byte<1>(in);
429 out[2] = get_byte<2>(in);
430 out[3] = get_byte<3>(in);
439inline constexpr void store_le(uint32_t in, uint8_t out[4]) {
440#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
442#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
445 out[0] = get_byte<3>(in);
446 out[1] = get_byte<2>(in);
447 out[2] = get_byte<1>(in);
448 out[3] = get_byte<0>(in);
457inline constexpr void store_be(uint64_t in, uint8_t out[8]) {
458#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
460#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
463 out[0] = get_byte<0>(in);
464 out[1] = get_byte<1>(in);
465 out[2] = get_byte<2>(in);
466 out[3] = get_byte<3>(in);
467 out[4] = get_byte<4>(in);
468 out[5] = get_byte<5>(in);
469 out[6] = get_byte<6>(in);
470 out[7] = get_byte<7>(in);
479inline constexpr void store_le(uint64_t in, uint8_t out[8]) {
480#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
482#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
485 out[0] = get_byte<7>(in);
486 out[1] = get_byte<6>(in);
487 out[2] = get_byte<5>(in);
488 out[3] = get_byte<4>(in);
489 out[4] = get_byte<3>(in);
490 out[5] = get_byte<2>(in);
491 out[6] = get_byte<1>(in);
492 out[7] = get_byte<0>(in);
565inline constexpr void store_le(uint8_t out[],
T x0,
T x1,
T x2,
T x3,
T x4,
T x5,
T x6,
T x7) {
589inline constexpr void store_be(uint8_t out[],
T x0,
T x1,
T x2,
T x3,
T x4,
T x5,
T x6,
T x7) {
602 while(out_bytes >=
sizeof(
T)) {
605 out_bytes -=
sizeof(
T);
609 for(
size_t i = 0; i != out_bytes; ++i) {
614template <
typename T,
typename Alloc>
615void copy_out_vec_be(uint8_t out[],
size_t out_bytes,
const std::vector<T, Alloc>& in) {
621 while(out_bytes >=
sizeof(
T)) {
624 out_bytes -=
sizeof(
T);
628 for(
size_t i = 0; i != out_bytes; ++i) {
633template <
typename T,
typename Alloc>
634void copy_out_vec_le(uint8_t out[],
size_t out_bytes,
const std::vector<T, Alloc>& in) {
constexpr uint8_t get_byte(T input)
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 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)