30ANONYMOUS_NAMESPACE_BEGIN
32using namespace CryptoPP;
36 return ((a ^ ((a ^ b) | ((a - b) ^ b))) >> (
sizeof(a) * 8 - 1));
39void Poly1305_HashBlocks(
word32 h[5],
word32 r[4],
const byte *input,
size_t length,
word32 padbit)
43 word32 h0, h1, h2, h3, h4, c;
44 word64 d0, d1, d2, d3;
53 h0 = h[0]; h1 = h[1]; h2 = h[2];
59 h0 = (
word32)(d0 = (word64)h0 + GetWord<word32>(
false, LITTLE_ENDIAN_ORDER, input + 0));
60 h1 = (
word32)(d1 = (word64)h1 + (d0 >> 32) + GetWord<word32>(
false, LITTLE_ENDIAN_ORDER, input + 4));
61 h2 = (
word32)(d2 = (word64)h2 + (d1 >> 32) + GetWord<word32>(
false, LITTLE_ENDIAN_ORDER, input + 8));
62 h3 = (
word32)(d3 = (word64)h3 + (d2 >> 32) + GetWord<word32>(
false, LITTLE_ENDIAN_ORDER, input + 12));
63 h4 += (
word32)(d3 >> 32) + padbit;
66 d0 = ((word64)h0 * r0) +
70 d1 = ((word64)h0 * r1) +
75 d2 = ((word64)h0 * r2) +
80 d3 = ((word64)h0 * r3) +
89 h1 = (
word32)(d1 += d0 >> 32);
90 h2 = (
word32)(d2 += d1 >> 32);
91 h3 = (
word32)(d3 += d2 >> 32);
95 c = (h4 >> 2) + (h4 & ~3U);
98 h1 += (c = CONSTANT_TIME_CARRY(h0,c));
99 h2 += (c = CONSTANT_TIME_CARRY(h1,c));
100 h3 += (c = CONSTANT_TIME_CARRY(h2,c));
101 h4 += CONSTANT_TIME_CARRY(h3,c);
107 h[0] = h0; h[1] = h1; h[2] = h2;
108 h[3] = h3; h[4] = h4;
111void Poly1305_HashFinal(
word32 h[5],
word32 n[4],
byte *mac,
size_t size)
113 word32 h0, h1, h2, h3, h4;
114 word32 g0, g1, g2, g3, g4;
125 g0 = (
word32)(t = (word64)h0 + 5);
126 g1 = (
word32)(t = (word64)h1 + (t >> 32));
127 g2 = (
word32)(t = (word64)h2 + (t >> 32));
128 g3 = (
word32)(t = (word64)h3 + (t >> 32));
129 g4 = h4 + (
word32)(t >> 32);
132 mask = 0 - (g4 >> 2);
133 g0 &= mask; g1 &= mask;
134 g2 &= mask; g3 &= mask;
136 h0 = (h0 & mask) | g0; h1 = (h1 & mask) | g1;
137 h2 = (h2 & mask) | g2; h3 = (h3 & mask) | g3;
140 h0 = (
word32)(t = (word64)h0 + n[0]);
141 h1 = (
word32)(t = (word64)h1 + (t >> 32) + n[1]);
142 h2 = (
word32)(t = (word64)h2 + (t >> 32) + n[2]);
143 h3 = (
word32)(t = (word64)h3 + (t >> 32) + n[3]);
147 PutWord<word32>(
false, LITTLE_ENDIAN_ORDER, mac + 0, h0);
148 PutWord<word32>(
false, LITTLE_ENDIAN_ORDER, mac + 4, h1);
149 PutWord<word32>(
false, LITTLE_ENDIAN_ORDER, mac + 8, h2);
150 PutWord<word32>(
false, LITTLE_ENDIAN_ORDER, mac + 12, h3);
155 PutWord<word32>(
false, LITTLE_ENDIAN_ORDER, m + 0, h0);
156 PutWord<word32>(
false, LITTLE_ENDIAN_ORDER, m + 4, h1);
157 PutWord<word32>(
false, LITTLE_ENDIAN_ORDER, m + 8, h2);
158 PutWord<word32>(
false, LITTLE_ENDIAN_ORDER, m + 12, h3);
159 std::memcpy(mac, m, size);
163ANONYMOUS_NAMESPACE_END
165NAMESPACE_BEGIN(CryptoPP)
172 CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(padbit);
179 CRYPTOPP_UNUSED(mac); CRYPTOPP_UNUSED(length);
186 return m_cipher.AlgorithmProvider();
192 CRYPTOPP_ASSERT(key && length >= 32);
196 m_cipher.SetKey(key, length);
211 CRYPTOPP_ASSERT(t.
size() == m_nk.size());
221 CRYPTOPP_ASSERT((input && length) || !length);
224 size_t rem, num = m_idx;
227 rem = BLOCKSIZE - num;
231 memcpy_s(m_acc + num, BLOCKSIZE - num, input, rem);
232 Poly1305_HashBlocks(m_h, m_r, m_acc, BLOCKSIZE, 1);
233 input += rem; length -= rem;
238 memcpy_s(m_acc + num, BLOCKSIZE - num, input, length);
239 m_idx = num + length;
244 rem = length % BLOCKSIZE;
247 if (length >= BLOCKSIZE) {
248 Poly1305_HashBlocks(m_h, m_r, input, length, 1);
253 memcpy(m_acc, input, rem);
261 CRYPTOPP_ASSERT(mac);
262 CRYPTOPP_ASSERT(!m_used);
264 ThrowIfInvalidTruncatedSize(size);
270 while (num < BLOCKSIZE)
272 Poly1305_HashBlocks(m_h, m_r, m_acc, BLOCKSIZE, 0);
275 Poly1305_HashFinal(m_h, m_n, mac, size);
285 CRYPTOPP_ASSERT(nonceLength == -1 || nonceLength == (
int)BLOCKSIZE);
286 if (nonceLength == -1) { nonceLength = BLOCKSIZE; }
289 m_cipher.ProcessBlock(nonce, m_nk.begin());
309 m_h[0] = m_h[1] = m_h[2] = m_h[3] = m_h[4] = 0;
317 CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(length);
318 CRYPTOPP_ASSERT(key && length >= 32);
337 CRYPTOPP_ASSERT((input && length) || !length);
340 size_t rem, num = m_idx;
343 rem = BLOCKSIZE - num;
347 memcpy_s(m_acc + num, BLOCKSIZE - num, input, rem);
348 Poly1305_HashBlocks(m_h, m_r, m_acc, BLOCKSIZE, 1);
349 input += rem; length -= rem;
354 memcpy_s(m_acc + num, BLOCKSIZE - num, input, length);
355 m_idx = num + length;
360 rem = length % BLOCKSIZE;
363 if (length >= BLOCKSIZE) {
364 Poly1305_HashBlocks(m_h, m_r, input, length, 1);
369 memcpy(m_acc, input, rem);
376 CRYPTOPP_ASSERT(mac);
384 while (num < BLOCKSIZE)
386 Poly1305_HashBlocks(m_h, m_r, m_acc, BLOCKSIZE, 0);
389 Poly1305_HashFinal(m_h, m_n, mac, size);
396 m_h[0] = m_h[1] = m_h[2] = m_h[3] = m_h[4] = 0;
Class file for the AES cipher (Rijndael)
Used to pass byte array input as part of a NameValuePairs object.
const byte * begin() const
Pointer to the first byte in the memory block.
size_t size() const
Length of the memory block.
Fixed size stack-based SecBlock with 16-byte alignment.
Interface for retrieving values given their names.
bool GetValue(const char *name, T &value) const
Get a named value.
Poly1305 message authentication code base class.
void Update(const byte *input, size_t length)
Updates a hash with additional input.
void TruncatedFinal(byte *mac, size_t size)
Computes the hash of the current message.
void GetNextIV(RandomNumberGenerator &rng, byte *iv)
Retrieves a secure IV for the next message.
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms)
Sets the key for this object without performing parameter validation.
void Restart()
Restart the hash.
void Resynchronize(const byte *iv, int ivLength=-1)
Resynchronize with an IV.
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Poly1305 message authentication code.
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms)
Sets the key for this object without performing parameter validation.
void TruncatedFinal(byte *mac, size_t size)
Computes the hash of the current message.
void Update(const byte *input, size_t length)
Updates a hash with additional input.
void Restart()
Restart the hash.
Interface for random number generators.
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
unsigned int word32
32-bit unsigned datatype
Functions for CPU features and intrinsics.
Abstract base classes that provide a uniform interface to this library.
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
Bounds checking replacement for memcpy()
Classes for Poly1305 message authentication code.