11 #include <botan/poly1305.h>
12 #include <botan/loadstor.h>
13 #include <botan/mul128.h>
14 #include <botan/internal/donna128.h>
20 void poly1305_init(secure_vector<uint64_t>& X,
const uint8_t key[32])
26 X[0] = ( t0 ) & 0xffc0fffffff;
27 X[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff;
28 X[2] = ((t1 >> 24) ) & 0x00ffffffc0f;
40 void poly1305_blocks(secure_vector<uint64_t>& X,
const uint8_t *m,
size_t blocks,
bool is_final =
false)
42 #if !defined(BOTAN_TARGET_HAS_NATIVE_UINT128)
46 const uint64_t hibit = is_final ? 0 : (
static_cast<uint64_t
>(1) << 40);
48 const uint64_t r0 = X[0];
49 const uint64_t r1 = X[1];
50 const uint64_t r2 = X[2];
56 const uint64_t s1 = r1 * (5 << 2);
57 const uint64_t s2 = r2 * (5 << 2);
65 h0 += (( t0 ) & 0xfffffffffff);
66 h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff);
67 h2 += (((t1 >> 24) ) & 0x3ffffffffff) | hibit;
75 uint64_t c =
carry_shift(d0, 44); h0 = d0 & 0xfffffffffff;
76 d1 += c; c =
carry_shift(d1, 44); h1 = d1 & 0xfffffffffff;
77 d2 += c; c =
carry_shift(d2, 42); h2 = d2 & 0x3ffffffffff;
78 h0 += c * 5; c =
carry_shift(h0, 44); h0 = h0 & 0xfffffffffff;
89 void poly1305_finish(secure_vector<uint64_t>& X, uint8_t mac[16])
97 c = (h1 >> 44); h1 &= 0xfffffffffff;
98 h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff;
99 h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff;
100 h1 += c; c = (h1 >> 44); h1 &= 0xfffffffffff;
101 h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff;
102 h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff;
106 uint64_t g0 = h0 + 5; c = (g0 >> 44); g0 &= 0xfffffffffff;
107 uint64_t g1 = h1 + c; c = (g1 >> 44); g1 &= 0xfffffffffff;
108 uint64_t g2 = h2 + c - (
static_cast<uint64_t
>(1) << 42);
111 c = (g2 >> ((
sizeof(uint64_t) * 8) - 1)) - 1;
121 const uint64_t t0 = X[6];
122 const uint64_t t1 = X[7];
124 h0 += (( t0 ) & 0xfffffffffff) ; c = (h0 >> 44); h0 &= 0xfffffffffff;
125 h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c; c = (h1 >> 44); h1 &= 0xfffffffffff;
126 h2 += (((t1 >> 24) ) & 0x3ffffffffff) + c; h2 &= 0x3ffffffffff;
129 h0 = ((h0 ) | (h1 << 44));
130 h1 = ((h1 >> 20) | (h2 << 24));
147 void Poly1305::key_schedule(
const uint8_t key[],
size_t)
153 poly1305_init(m_poly, key);
156 void Poly1305::add_data(
const uint8_t input[],
size_t length)
164 if(m_buf_pos + length >= m_buf.size())
166 poly1305_blocks(m_poly, m_buf.data(), 1);
167 input += (m_buf.size() - m_buf_pos);
168 length -= (m_buf.size() - m_buf_pos);
173 const size_t full_blocks = length / m_buf.size();
174 const size_t remaining = length % m_buf.size();
177 poly1305_blocks(m_poly, input, full_blocks);
179 buffer_insert(m_buf, m_buf_pos, input + full_blocks * m_buf.size(), remaining);
180 m_buf_pos += remaining;
183 void Poly1305::final_result(uint8_t out[])
189 m_buf[m_buf_pos] = 1;
190 const size_t len = m_buf.size() - m_buf_pos - 1;
195 poly1305_blocks(m_poly, m_buf.data(), 1,
true);
198 poly1305_finish(m_poly, out);
void zap(std::vector< T, Alloc > &vec)
void clear_mem(T *ptr, size_t n)
uint64_t carry_shift(const donna128 &a, size_t shift)
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
uint64_t load_le< uint64_t >(const uint8_t in[], size_t off)
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
void store_le(uint16_t in, uint8_t out[2])