Crypt-Bear
view release on metacpan or search on metacpan
src/symcipher/poly1305_i15.c view on Meta::CPAN
/*
* Modulus: 2^130-5.
*/
static const uint16_t P1305[] = {
0x008A,
0x7FFB, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x03FF
};
/*
* -p mod 2^15.
*/
#define P0I 0x4CCD
/*
* R^2 mod p, for conversion to Montgomery representation (R = 2^135,
* since we use 9 words of 15 bits each, and 15*9 = 135).
*/
static const uint16_t R2[] = {
0x008A,
0x6400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
/*
* Perform the inner processing of blocks for Poly1305. The "r" array
* is in Montgomery representation, while the "a" array is not.
*/
static void
poly1305_inner(uint16_t *a, const uint16_t *r, const void *data, size_t len)
{
const unsigned char *buf;
buf = data;
while (len > 0) {
unsigned char tmp[16], rev[16];
uint16_t b[10];
uint32_t ctl;
int i;
/*
* If there is a partial block, right-pad it with zeros.
*/
if (len < 16) {
memset(tmp, 0, sizeof tmp);
memcpy(tmp, buf, len);
buf = tmp;
len = 16;
}
/*
* Decode next block and apply the "high bit". Since
* decoding is little-endian, we must byte-swap the buffer.
*/
for (i = 0; i < 16; i ++) {
rev[i] = buf[15 - i];
}
br_i15_decode_mod(b, rev, sizeof rev, P1305);
b[9] |= 0x0100;
/*
* Add the accumulator to the decoded block (modular
* addition).
*/
ctl = br_i15_add(b, a, 1);
ctl |= NOT(br_i15_sub(b, P1305, 0));
br_i15_sub(b, P1305, ctl);
/*
* Multiply by r, result is the new accumulator value.
*/
br_i15_montymul(a, b, r, P1305, P0I);
buf += 16;
len -= 16;
}
}
/*
* Byteswap a 16-byte value.
*/
static void
byteswap16(unsigned char *buf)
{
int i;
for (i = 0; i < 8; i ++) {
unsigned x;
x = buf[i];
buf[i] = buf[15 - i];
buf[15 - i] = x;
}
}
/* see bearssl_block.h */
void
br_poly1305_i15_run(const void *key, const void *iv,
void *data, size_t len, const void *aad, size_t aad_len,
void *tag, br_chacha20_run ichacha, int encrypt)
{
unsigned char pkey[32], foot[16];
uint16_t t[10], r[10], acc[10];
/*
* Compute the MAC key. The 'r' value is the first 16 bytes of
* pkey[].
*/
memset(pkey, 0, sizeof pkey);
ichacha(key, iv, 0, pkey, sizeof pkey);
/*
* If encrypting, ChaCha20 must run first, followed by Poly1305.
* When decrypting, the operations are reversed.
*/
if (encrypt) {
ichacha(key, iv, 1, data, len);
}
/*
* Run Poly1305. We must process the AAD, then ciphertext, then
* the footer (with the lengths). Note that the AAD and ciphertext
( run in 2.447 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )