Welcome to little lamb

Code » limb » master » tree

[master] / src / liblimb / memxor.h / memxor.c

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

static void
xor8(void *dst_, const void *src_, size_t len)
{
    u8 *dst = dst_;
    const u8 *src = src_;

    while (len--) {
        *dst ^= *src;
        ++dst;
        ++src;
    }
}

static void
xor64(void *dst_, const void *src_, size_t len)
{
    u64 *dst = dst_;
    const u64 *src = src_;

    size_t n = len / sizeof(u64);
    len -= n * sizeof(u64);

    while (n >= 4) {
        dst[0] ^= src[0];
        dst[1] ^= src[1];
        dst[2] ^= src[2];
        dst[3] ^= src[3];
        dst += 4;
        src += 4;
        n -= 4;
    }

    while (n >= 1) {
        *dst ^= *src;
        ++dst;
        ++src;
        --n;
    }

    xor8(dst, src, len);
}

void
memxor(void *dst_, const void *src_, size_t len)
{
    u8 *dst = dst_;
    const u8 *src = src_;

    size_t off = ALIGN_OFFSET(dst);
    if (off) {
        off = sizeof(word_t) - off;
        if (off > len)
            off = len;
        xor8(dst, src, off);
        dst += off;
        src += off;
        len -= off;
    }

    off = ALIGN_OFFSET(src);
    if (off) {
        u8 buf[8092];
        size_t blen = sizeof(buf);

        while (len) {
            if (blen > len) blen = len;
            memcpy(buf, src, blen);
            xor64(dst, buf, blen);
            dst += blen;
            src += blen;
            len -= blen;
        }
    } else {
        xor64(dst, src, len);
    }
}