9#include <botan/internal/crc24.h>
11#include <botan/internal/loadstor.h>
26consteval std::array<uint32_t, 256> crc24_sarwate_table() noexcept {
27 std::array<uint32_t, 256> table = {};
28 for(
size_t i = 0; i != 256; ++i) {
29 uint32_t crc =
static_cast<uint32_t
>(i) << 16;
30 for(
size_t j = 0; j != 8; ++j) {
31 crc = ((crc << 1) & 0xFFFFFF) ^ ((crc & 0x800000) != 0 ? 0x864CFB : 0);
33 table[i] = ((crc & 0xFF) << 16) | (crc & 0xFF00) | (crc >> 16);
45consteval std::array<uint32_t, 256> crc24_slicing_table(
const std::array<uint32_t, 256>& prev,
46 const std::array<uint32_t, 256>& t0)
noexcept {
47 std::array<uint32_t, 256> table = {};
48 for(
size_t i = 0; i != 256; ++i) {
49 table[i] = (prev[i] >> 8) ^ t0[prev[i] & 0xFF];
54alignas(256)
constexpr auto CRC24_T0 = crc24_sarwate_table();
55alignas(256)
constexpr auto CRC24_T1 = crc24_slicing_table(CRC24_T0, CRC24_T0);
56alignas(256)
constexpr auto CRC24_T2 = crc24_slicing_table(CRC24_T1, CRC24_T0);
57alignas(256)
constexpr auto CRC24_T3 = crc24_slicing_table(CRC24_T2, CRC24_T0);
59inline uint32_t process8(uint32_t crc, uint8_t data) {
60 return (crc >> 8) ^ CRC24_T0[
get_byte<3>(crc) ^ data];
63inline uint32_t process32(uint32_t crc, uint32_t
word) {
64 const uint32_t sum = crc ^
word;
72 return std::make_unique<CRC24>(*
this);
85void CRC24::add_data(std::span<const uint8_t> input) {
89 static const uint8_t WA =
sizeof(size_t) - 1;
92 for(; !input.empty() && (
reinterpret_cast<uintptr_t
>(input.data()) & WA) > 0; input = input.last(input.size() - 1)) {
93 tmp = process8(tmp, input.front());
96 while(input.size() >= 16) {
99 tmp = process32(tmp, d[0]);
100 tmp = process32(tmp, d[1]);
101 tmp = process32(tmp, d[2]);
102 tmp = process32(tmp, d[3]);
104 input = input.last(input.size() - 16);
107 for(; !input.empty(); input = input.last(input.size() - 1)) {
108 tmp = process8(tmp, input.front());
117void CRC24::final_result(std::span<uint8_t> output) {
std::unique_ptr< HashFunction > copy_state() const override
constexpr uint8_t get_byte(T input)
constexpr auto load_le(ParamTs &&... params)
std::conditional_t< HasNative64BitRegisters, std::uint64_t, uint32_t > word
The native machine word, used as the limb type for multiprecision integers.