packages feed

lol-0.0.1.0: src/Crypto/Lol/Cyclotomic/Tensor/CTensor/basic.c

#include "tensorTypes.h"
#ifdef CINTRIN
#include <immintrin.h>
#endif

#ifdef STATS
int mulCtr = 0;
struct timespec mulTime = {0,0};

int addCtr = 0;
struct timespec addTime = {0,0};
#endif

//a = zipWith (*) a b
void mulRq (hInt_t* a, hInt_t* b, hDim_t totm, hInt_t q) {
#ifdef STATS
    mulCtr++;
    struct timespec s1,t1;
    clock_gettime(CLOCK_REALTIME, &s1);
#endif
    for(int i = 0; i < totm; i++) {
        a[i] = (a[i]*b[i])%q;
    }
#ifdef STATS
    clock_gettime(CLOCK_REALTIME, &t1);
    mulTime = tsAdd(mulTime, tsSubtract(t1,s1));
#endif
}

void mulMq (hInt_t* a, const hInt_t* b, const hDim_t totm, const hByte_t logr, const hInt_t k, const hInt_t q) {
#ifdef STATS
    mulCtr++;
    struct timespec s1,t1;
    clock_gettime(CLOCK_REALTIME, &s1);
#endif
    hInt_t mask = (1<<logr)-1; // R-1

    for(int i = 0; i < totm; i++) {
        hInt_t x = a[i]*b[i];
        hInt_t s = k*(x & mask);
        hInt_t m = s & mask;
        a[i] = (x+m*q)>>logr;
    }

#ifdef STATS
    clock_gettime(CLOCK_REALTIME, &t1);
    mulTime = tsAdd(mulTime, tsSubtract(t1,s1));
#endif
}

void mulC (complex_t* a, complex_t* b, hDim_t totm) {
#ifdef STATS
    mulCtr++;
    struct timespec s1,t1;
    clock_gettime(CLOCK_REALTIME, &s1);
#endif
    for(int i = 0; i < totm; i++)
    {
        CMPLX_IMUL(a[i],b[i]);
    }
#ifdef STATS
    clock_gettime(CLOCK_REALTIME, &t1);
    mulTime = tsAdd(mulTime, tsSubtract(t1,s1));
#endif
}

//a = zipWith (+) a b
void addRq (hInt_t* a, const hInt_t* b, const hDim_t totm, const hInt_t q) {
#ifdef STATS
    addCtr++;
    struct timespec s1,t1;
    clock_gettime(CLOCK_REALTIME, &s1);
#endif
#ifdef CINTRIN
    __m128i qs = _mm_set1_epi64x(q);
    for(int i = 0; i < totm; i+=2) {
        __m128i xs = _mm_load_si128((const __m128i*)(a+i));
        __m128i ys = _mm_load_si128((const __m128i*)(b+i));
        __m128i zs = _mm_add_epi64(xs,ys);
        zs = _mm_rem_epi64(zs,qs);
        _mm_store_si128((__m128i*)(a+i),zs);
    }
#else
    for(int i = 0; i < totm; i++) {
        hInt_t temp = a[i]+b[i];
        if (temp >= q) a[i]=temp-q;
        else a[i] = temp;
    }
#endif
#ifdef STATS
    clock_gettime(CLOCK_REALTIME, &t1);
    addTime = tsAdd(addTime, tsSubtract(t1,s1));
#endif
}

void addMq (hInt_t* a, const hInt_t* b, const hDim_t totm, const hByte_t logr, const hInt_t k, const hInt_t q) {
#ifdef STATS
    addCtr++;
    struct timespec s1,t1;
    clock_gettime(CLOCK_REALTIME, &s1);
#endif
    hInt_t twoq = q<<1;
    for(int i = 0; i < totm; i++) {
        hInt_t temp = (a[i]+b[i]);
        if (temp >= twoq) a[i]=temp-twoq;
        else a[i] = temp;
    }

#ifdef STATS
    clock_gettime(CLOCK_REALTIME, &t1);
    addTime = tsAdd(addTime, tsSubtract(t1,s1));
#endif
}

//a = zipWith (+) a b
void addR (hInt_t* a, hInt_t* b, hDim_t totm) {
#ifdef STATS
    addCtr++;
    struct timespec s1,t1;
    clock_gettime(CLOCK_REALTIME, &s1);
#endif
    for(int i = 0; i < totm; i++)    {
        a[i] += b[i];
    }
#ifdef STATS
    clock_gettime(CLOCK_REALTIME, &t1);
    addTime = tsAdd(addTime, tsSubtract(t1,s1));
#endif
}

void addC (complex_t* a, complex_t* b, hDim_t totm) {
#ifdef STATS
    addCtr++;
    struct timespec s1,t1;
    clock_gettime(CLOCK_REALTIME, &s1);
#endif
    for(int i = 0; i < totm; i++)
    {
        CMPLX_IADD(a[i],b[i]);
    }
#ifdef STATS
    clock_gettime(CLOCK_REALTIME, &t1);
    addTime = tsAdd(addTime, tsSubtract(t1,s1));
#endif
}

void addD (double* a, double* b, hDim_t totm) {
#ifdef STATS
    addCtr++;
    struct timespec s1,t1;
    clock_gettime(CLOCK_REALTIME, &s1);
#endif
    for(int i = 0; i < totm; i++)
    {
        a[i]+=b[i];
    }
#ifdef STATS
    clock_gettime(CLOCK_REALTIME, &t1);
    addTime = tsAdd(addTime, tsSubtract(t1,s1));
#endif
}