#include "rivide/crypto/ghash.h"
void rivide_ghash_mult(uint8_t x[16], const uint8_t y[16]) {
uint8_t v[16];
uint8_t z[16] = {0};
int i, j;
for (i = 0; i < 16; i++) {
v[i] = y[i];
}
for (i = 0; i < 16; i++) {
for (j = 7; j >= 0; j--) {
uint8_t bit = (uint8_t)((x[i] >> j) & 1);
uint8_t mask_bit = (uint8_t)(0 - bit);
int k;
for (k = 0; k < 16; k++) {
z[k] ^= (uint8_t)(v[k] & mask_bit);
}
{
uint8_t carry = (uint8_t)(v[15] & 1);
uint8_t mask_carry = (uint8_t)(0 - carry);
for (k = 15; k > 0; k--) {
v[k] = (uint8_t)((v[k] >> 1) | ((v[k - 1] & 1) << 7));
}
v[0] = (uint8_t)((v[0] >> 1) ^ (mask_carry & 0xE1));
}
}
}
for (i = 0; i < 16; i++) {
x[i] = z[i];
}
}
void rivide_ghash_update(const uint8_t h[16], const uint8_t *data, size_t len, uint8_t tag[16]) {
size_t i, j;
uint8_t block[16];
while (len > 0) {
size_t chunk = (len >= 16) ? 16 : len;
for (i = 0; i < 16; i++) {
block[i] = 0;
}
for (i = 0; i < chunk; i++) {
block[i] = data[i];
}
for (j = 0; j < 16; j++) {
tag[j] ^= block[j];
}
rivide_ghash_mult(tag, h);
data += chunk;
len -= chunk;
}
}