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;
185 if (state.chunkSize > 0) {
186 uint8_t *c = (uint8_t *)state.c;
187 c[state.chunkSize] = 1;
188 memset(c + state.chunkSize + 1, 0, 16 - state.chunkSize - 1);
189 littleToHost(state.c, NUM_LIMBS_128BIT);
190 state.c[NUM_LIMBS_128BIT] = 0;
199 carry = (dlimb_t)((state.h[NUM_LIMBS_128BIT] >> 2) +
200 (state.h[NUM_LIMBS_128BIT] & ~((limb_t)3)));
201 state.h[NUM_LIMBS_128BIT] &= 0x0003;
202 for (i = 0; i < NUM_LIMBS_128BIT; ++i) {
204 state.h[i] = (limb_t)carry;
207 state.h[i] += (limb_t)carry;
212 for (i = 0; i < NUM_LIMBS_130BIT; ++i) {
214 state.t[i] = (limb_t)carry;
224 limb_t mask = (~((state.t[NUM_LIMBS_128BIT] >> 2) & 1)) + 1;
225 limb_t nmask = ~mask;
226 for (i = 0; i < NUM_LIMBS_128BIT; ++i) {
227 state.h[i] = (state.h[i] & nmask) | (state.t[i] & mask);
231 memcpy(state.c, nonce, 16);
232 littleToHost(state.c, NUM_LIMBS_128BIT);
234 for (i = 0; i < NUM_LIMBS_128BIT; ++i) {
237 state.h[i] = htolelimb((limb_t)carry);
242 memcpy(token, state.h, len);
252 if (state.chunkSize != 0) {
253 memset(((uint8_t *)state.c) + state.chunkSize, 0, 16 - state.chunkSize);
254 littleToHost(state.c, NUM_LIMBS_128BIT);
255 state.c[NUM_LIMBS_128BIT] = 1;
272 void Poly1305::processChunk()
280 for (i = 0; i < NUM_LIMBS_130BIT; ++i) {
283 state.h[i] = (limb_t)carry;
292 limb_t word = state.r[0];
293 for (i = 0; i < NUM_LIMBS_130BIT; ++i) {
294 carry += ((dlimb_t)(state.h[i])) * word;
295 state.t[i] = (limb_t)carry;
298 state.t[NUM_LIMBS_130BIT] = (limb_t)carry;
299 for (i = 1; i < NUM_LIMBS_128BIT; ++i) {
302 for (j = 0; j < NUM_LIMBS_130BIT; ++j) {
303 carry += ((dlimb_t)(state.h[j])) * word;
304 carry += state.t[i + j];
305 state.t[i + j] = (limb_t)carry;
308 state.t[i + NUM_LIMBS_130BIT] = (limb_t)carry;
314 carry = ((dlimb_t)(state.t[NUM_LIMBS_128BIT] >> 2)) +
315 (state.t[NUM_LIMBS_128BIT] & ~((limb_t)3));
316 state.t[NUM_LIMBS_128BIT] &= 0x0003;
317 for (i = 0; i < NUM_LIMBS_128BIT; ++i) {
326 word = state.t[i + NUM_LIMBS_130BIT];
327 carry += ((dlimb_t)word) << (LIMB_BITS - 2);
329 state.h[i] = (limb_t)carry;
333 state.h[i] = (limb_t)(carry + state.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.