Welcome to little lamb

Code » limb » master » tree

[master] / src / liblimb / poly1305.h / poly1305_blocks.c

/* This file is part of limb                           https://lila.oss/limb
 * Copyright (C) 2023 Olivier Brunel                          jjk@jjacky.com */
/* Based on poly1305-donna
 * Copyright (C) 2016 Andrew Moon */
/* SPDX-License-Identifier: GPL-2.0-only */
#include <string.h>
#include <limb/poly1305.h>
#include "poly1305.h"

void
poly1305_blocks(const u8 *msg, size_t mlen, struct poly1305_ctx *ctx)
{
    const u32 hibit = (ctx->final) ? 0 : (U32_C(1) << 24); /* 1 << 128 */
    u32 r0, r1, r2, r3, r4;
    u32 s1, s2, s3, s4;
    u32 a0, a1, a2, a3, a4;
    u64 d0, d1, d2, d3, d4;
    u32 c;

    r0 = ctx->r[0];
    r1 = ctx->r[1];
    r2 = ctx->r[2];
    r3 = ctx->r[3];
    r4 = ctx->r[4];

    s1 = r1 * 5;
    s2 = r2 * 5;
    s3 = r3 * 5;
    s4 = r4 * 5;

    a0 = ctx->a[0];
    a1 = ctx->a[1];
    a2 = ctx->a[2];
    a3 = ctx->a[3];
    a4 = ctx->a[4];

    while (mlen >= POLY1305_BLOCKSIZE) {
        /* a += msg[i] */
        a0 += (U32(msg +  0)     ) & 0x03ffffff;
        a1 += (U32(msg +  3) >> 2) & 0x03ffffff;
        a2 += (U32(msg +  6) >> 4) & 0x03ffffff;
        a3 += (U32(msg +  9) >> 6) & 0x03ffffff;
        a4 += (U32(msg + 12) >> 8) | hibit;

        /* a *= r */
        d0 = ((u64) a0 * r0) + ((u64) a1 * s4) + ((u64) a2 * s3) + ((u64) a3 * s2) + ((u64) a4 * s1);
        d1 = ((u64) a0 * r1) + ((u64) a1 * r0) + ((u64) a2 * s4) + ((u64) a3 * s3) + ((u64) a4 * s2);
        d2 = ((u64) a0 * r2) + ((u64) a1 * r1) + ((u64) a2 * r0) + ((u64) a3 * s4) + ((u64) a4 * s3);
        d3 = ((u64) a0 * r3) + ((u64) a1 * r2) + ((u64) a2 * r1) + ((u64) a3 * r0) + ((u64) a4 * s4);
        d4 = ((u64) a0 * r4) + ((u64) a1 * r3) + ((u64) a2 * r2) + ((u64) a3 * r1) + ((u64) a4 * r0);

        /* (partial) a %= p */
                      c = (u32) (d0 >> 26); a0 = (u32) d0 & 0x3ffffff;
        d1 += c;      c = (u32) (d1 >> 26); a1 = (u32) d1 & 0x3ffffff;
        d2 += c;      c = (u32) (d2 >> 26); a2 = (u32) d2 & 0x3ffffff;
        d3 += c;      c = (u32) (d3 >> 26); a3 = (u32) d3 & 0x3ffffff;
        d4 += c;      c = (u32) (d4 >> 26); a4 = (u32) d4 & 0x3ffffff;
        a0 += c * 5;  c = (u32) (a0 >> 26); a0 = (u32) a0 & 0x3ffffff;
        a1 += c;

        mlen -= POLY1305_BLOCKSIZE;
        msg += POLY1305_BLOCKSIZE;
    }

    ctx->a[0] = a0;
    ctx->a[1] = a1;
    ctx->a[2] = a2;
    ctx->a[3] = a3;
    ctx->a[4] = a4;
}