void Poly1305_Update(POLY1305 *ctx, const unsigned char *inp, size_t len)
{
#ifdef POLY1305_ASM
    poly1305_blocks_f poly1305_blocks_p = ctx->func.blocks;
#endif
    size_t rem, num;
    if ((num = ctx->num)) {
        rem = POLY1305_BLOCK_SIZE - num;
        if (len >= rem) {
            memcpy(ctx->data + num, inp, rem);
            poly1305_blocks(ctx->opaque, ctx->data, POLY1305_BLOCK_SIZE, 1);
            inp += rem;
            len -= rem;
        } else {
            memcpy(ctx->data + num, inp, len);
            ctx->num = num + len;
            return;
        }
    }
    rem = len % POLY1305_BLOCK_SIZE;
    len -= rem;
    if (len >= POLY1305_BLOCK_SIZE) {
        poly1305_blocks(ctx->opaque, inp, len, 1);
        inp += len;
    }
    if (rem)
        memcpy(ctx->data, inp, rem);
    ctx->num = rem;
}
['static void benchmark_poly1305()\n{\n# ifdef OPENSSL_CPUID_OBJ\n    POLY1305 poly1305;\n    unsigned char key[32];\n    unsigned char buf[8192];\n    uint32_t stopwatch;\n    unsigned int i;\n    memset (buf,0x55,sizeof(buf));\n    memset (key,0xAA,sizeof(key));\n    Poly1305_Init(&poly1305, key);\n    for (i=0;i<100000;i++)\n        Poly1305_Update(&poly1305,buf,sizeof(buf));\n    stopwatch = OPENSSL_rdtsc();\n    for (i=0;i<10000;i++)\n        Poly1305_Update(&poly1305,buf,sizeof(buf));\n    stopwatch = OPENSSL_rdtsc() - stopwatch;\n    printf("%g\\n",stopwatch/(double)(i*sizeof(buf)));\n    stopwatch = OPENSSL_rdtsc();\n    for (i=0;i<10000;i++) {\n        Poly1305_Init(&poly1305, key);\n        Poly1305_Update(&poly1305,buf,16);\n        Poly1305_Final(&poly1305,buf);\n    }\n    stopwatch = OPENSSL_rdtsc() - stopwatch;\n    printf("%g\\n",stopwatch/(double)(i));\n# else\n    fprintf(stderr,\n            "Benchmarking of poly1305 isn\'t available on this platform\\n");\n# endif\n}', 'void Poly1305_Update(POLY1305 *ctx, const unsigned char *inp, size_t len)\n{\n#ifdef POLY1305_ASM\n    poly1305_blocks_f poly1305_blocks_p = ctx->func.blocks;\n#endif\n    size_t rem, num;\n    if ((num = ctx->num)) {\n        rem = POLY1305_BLOCK_SIZE - num;\n        if (len >= rem) {\n            memcpy(ctx->data + num, inp, rem);\n            poly1305_blocks(ctx->opaque, ctx->data, POLY1305_BLOCK_SIZE, 1);\n            inp += rem;\n            len -= rem;\n        } else {\n            memcpy(ctx->data + num, inp, len);\n            ctx->num = num + len;\n            return;\n        }\n    }\n    rem = len % POLY1305_BLOCK_SIZE;\n    len -= rem;\n    if (len >= POLY1305_BLOCK_SIZE) {\n        poly1305_blocks(ctx->opaque, inp, len, 1);\n        inp += len;\n    }\n    if (rem)\n        memcpy(ctx->data, inp, rem);\n    ctx->num = rem;\n}']