25 #include "utility/EndianUtil.h"
26 #include "utility/LimbUtil.h"
63 #define NUM_LIMBS_130BIT (NUM_LIMBS_128BIT + 1)
66 #if BIGNUMBER_LIMB_8BIT
67 #define lelimbtoh(x) (x)
68 #define htolelimb(x) (x)
69 #elif BIGNUMBER_LIMB_16BIT
70 #define lelimbtoh(x) (le16toh((x)))
71 #define htolelimb(x) (htole16((x)))
72 #elif BIGNUMBER_LIMB_32BIT
73 #define lelimbtoh(x) (le32toh((x)))
74 #define htolelimb(x) (htole32((x)))
76 #if defined(CRYPTO_LITTLE_ENDIAN)
77 #define littleToHost(r,size) do { ; } while (0)
79 #define littleToHost(r,size) \
81 for (uint8_t i = 0; i < (size); ++i) \
82 (r)[i] = lelimbtoh((r)[i]); \
113 uint8_t *r = (uint8_t *)state.r;
124 littleToHost(state.r, NUM_LIMBS_128BIT);
128 memset(state.h, 0,
sizeof(state.h));
145 const uint8_t *d = (
const uint8_t *)data;
147 uint8_t size = 16 - state.chunkSize;
150 memcpy(((uint8_t *)state.c) + state.chunkSize, d, size);
151 state.chunkSize += size;
154 if (state.chunkSize == 16) {
155 littleToHost(state.c, NUM_LIMBS_128BIT);
156 state.c[NUM_LIMBS_128BIT] = 1;
183 limb_t t[NUM_LIMBS_256BIT + 1];
186 if (state.chunkSize > 0) {
187 uint8_t *c = (uint8_t *)state.c;
188 c[state.chunkSize] = 1;
189 memset(c + state.chunkSize + 1, 0, 16 - state.chunkSize - 1);
190 littleToHost(state.c, NUM_LIMBS_128BIT);
191 state.c[NUM_LIMBS_128BIT] = 0;
200 carry = (dlimb_t)((state.h[NUM_LIMBS_128BIT] >> 2) +
201 (state.h[NUM_LIMBS_128BIT] & ~((limb_t)3)));
202 state.h[NUM_LIMBS_128BIT] &= 0x0003;
203 for (i = 0; i < NUM_LIMBS_128BIT; ++i) {
205 state.h[i] = (limb_t)carry;
208 state.h[i] += (limb_t)carry;
213 for (i = 0; i < NUM_LIMBS_130BIT; ++i) {
215 t[i] = (limb_t)carry;
225 limb_t mask = (~((t[NUM_LIMBS_128BIT] >> 2) & 1)) + 1;
226 limb_t nmask = ~mask;
227 for (i = 0; i < NUM_LIMBS_128BIT; ++i) {
228 state.h[i] = (state.h[i] & nmask) | (t[i] & mask);
232 memcpy(state.c, nonce, 16);
233 littleToHost(state.c, NUM_LIMBS_128BIT);
235 for (i = 0; i < NUM_LIMBS_128BIT; ++i) {
238 state.h[i] = htolelimb((limb_t)carry);
243 memcpy(token, state.h, len);
253 if (state.chunkSize != 0) {
254 memset(((uint8_t *)state.c) + state.chunkSize, 0, 16 - state.chunkSize);
255 littleToHost(state.c, NUM_LIMBS_128BIT);
256 state.c[NUM_LIMBS_128BIT] = 1;
273 void Poly1305::processChunk()
275 limb_t t[NUM_LIMBS_256BIT + 1];
283 for (i = 0; i < NUM_LIMBS_130BIT; ++i) {
286 state.h[i] = (limb_t)carry;
295 limb_t word = state.r[0];
296 for (i = 0; i < NUM_LIMBS_130BIT; ++i) {
297 carry += ((dlimb_t)(state.h[i])) * word;
298 t[i] = (limb_t)carry;
301 t[NUM_LIMBS_130BIT] = (limb_t)carry;
302 for (i = 1; i < NUM_LIMBS_128BIT; ++i) {
305 for (j = 0; j < NUM_LIMBS_130BIT; ++j) {
306 carry += ((dlimb_t)(state.h[j])) * word;
308 t[i + j] = (limb_t)carry;
311 t[i + NUM_LIMBS_130BIT] = (limb_t)carry;
317 carry = ((dlimb_t)(t[NUM_LIMBS_128BIT] >> 2)) +
318 (t[NUM_LIMBS_128BIT] & ~((limb_t)3));
319 t[NUM_LIMBS_128BIT] &= 0x0003;
320 for (i = 0; i < NUM_LIMBS_128BIT; ++i) {
329 word = t[i + NUM_LIMBS_130BIT];
330 carry += ((dlimb_t)word) << (LIMB_BITS - 2);
332 state.h[i] = (limb_t)carry;
336 state.h[i] = (limb_t)(carry + t[NUM_LIMBS_128BIT]);
void finalize(const void *nonce, void *token, size_t len)
Finalizes the authentication process and returns the token.
void reset(const void *key)
Resets the Poly1305 message authenticator for a new session.
void update(const void *data, size_t len)
Updates the message authenticator with more data.
void pad()
Pads the input stream with zero bytes to a multiple of 16.
~Poly1305()
Destroys this Poly1305 message authenticator after clearing all sensitive information.
Poly1305()
Constructs a new Poly1305 message authenticator.
void clear()
Clears the authenticator's state, removing all sensitive data.