11#include <botan/internal/poly1305.h>
13#include <botan/internal/ct_utils.h>
14#include <botan/internal/donna128.h>
15#include <botan/internal/loadstor.h>
16#include <botan/internal/mul128.h>
17#include <botan/internal/stl_util.h>
28 X[0] = (t0) & 0xffc0fffffff;
29 X[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff;
30 X[2] = ((t1 >> 24)) & 0x00ffffffc0f;
43#if !defined(BOTAN_TARGET_HAS_NATIVE_UINT128)
44 typedef donna128 uint128_t;
47 const uint64_t hibit = is_final ? 0 : (
static_cast<uint64_t
>(1) << 40);
49 const uint64_t r0 =
X[0];
50 const uint64_t r1 =
X[1];
51 const uint64_t r2 =
X[2];
53 const uint64_t M44 = 0xFFFFFFFFFFF;
54 const uint64_t M42 = 0x3FFFFFFFFFF;
56 uint64_t h0 =
X[3 + 0];
57 uint64_t h1 =
X[3 + 1];
58 uint64_t h2 =
X[3 + 2];
60 const uint64_t s1 = r1 * 20;
61 const uint64_t s2 = r2 * 20;
63 for(
size_t i = 0; i != blocks; ++i) {
68 h1 += (((t0 >> 44) | (t1 << 20)) & M44);
69 h2 += (((t1 >> 24)) & M42) | hibit;
71 const uint128_t d0 = uint128_t(h0) * r0 + uint128_t(h1) * s2 + uint128_t(h2) * s1;
74 const uint128_t d1 = uint128_t(h0) * r1 + uint128_t(h1) * r0 + uint128_t(h2) * s2 + c0;
77 const uint128_t d2 = uint128_t(h0) * r2 + uint128_t(h1) * r1 + uint128_t(h2) * r0 + c1;
97 const uint64_t M44 = 0xFFFFFFFFFFF;
98 const uint64_t M42 = 0x3FFFFFFFFFF;
101 uint64_t h0 =
X[3 + 0];
102 uint64_t h1 =
X[3 + 1];
103 uint64_t h2 =
X[3 + 2];
126 uint64_t g0 = h0 + 5;
129 uint64_t g1 = h1 + c;
132 uint64_t g2 = h2 + c - (
static_cast<uint64_t
>(1) << 42);
136 h0 = c_mask.select(g0, h0);
137 h1 = c_mask.select(g1, h1);
138 h2 = c_mask.select(g2, h2);
141 const uint64_t t0 =
X[6];
142 const uint64_t t1 =
X[7];
147 h1 += (((t0 >> 44) | (t1 << 20)) & M44) + c;
150 h2 += (((t1 >> 24)) & M42) + c;
154 h0 = ((h0) | (h1 << 44));
155 h1 = ((h1 >> 20) | (h2 << 24));
171 return m_poly.size() == 8;
174void Poly1305::key_schedule(std::span<const uint8_t> key) {
178 poly1305_init(m_poly, key.data());
181void Poly1305::add_data(std::span<const uint8_t> input) {
184 BufferSlicer in(input);
188 poly1305_blocks(m_poly, one_block->data(), 1);
193 if(full_blocks > 0) {
194 poly1305_blocks(m_poly, aligned_data.data(), full_blocks);
200void Poly1305::final_result(std::span<uint8_t> out) {
204 const uint8_t final_byte = 0x01;
205 m_buffer.
append({&final_byte, 1});
207 poly1305_blocks(m_poly, m_buffer.
consume().data(), 1,
true);
210 poly1305_finish(m_poly, out.data());
std::tuple< std::span< const uint8_t >, size_t > aligned_data_to_process(BufferSlicer &slicer) const
void append(std::span< const T > elements)
std::optional< std::span< const T > > handle_unaligned_data(BufferSlicer &slicer)
std::span< const T > consume()
void fill_up_with_zeros()
bool in_alignment() const
static constexpr Mask< T > expand(T v)
bool has_keying_material() const override
void assert_key_material_set() const
constexpr uint64_t carry_shift(const donna128 &a, size_t shift)
void zap(std::vector< T, Alloc > &vec)
constexpr auto store_le(ParamTs &&... params)
constexpr auto load_le(ParamTs &&... params)
std::vector< T, secure_allocator< T > > secure_vector
constexpr void clear_mem(T *ptr, size_t n)