packages feed

lol-0.2.0.0: Crypto/Lol/Cyclotomic/Tensor/CTensor/random.c

#include <math.h>
#include <stdlib.h>
#include "tensorTypes.h"

// this function takes *inverse* RUs, so no negation is needed on the indexing
// I had been negating the ru-idx, but this was causing a *negative* mod, resulting in a hard-to-find bug
void primeD (double *y, hShort_t tupSize, hDim_t lts, hDim_t rts, hDim_t p, hDim_t rustride, complex_t* ruinv)
{
	if(p == 2)
  {
      return;
  }
  hDim_t blockOffset, modOffset, tensorOffset;
	double *tempSpace = (double*)malloc((p-1)*sizeof(double));
  hDim_t temp1 = rts*(p-1);
  for(blockOffset = 0; blockOffset < lts; blockOffset++)
  {
    hDim_t temp2 = blockOffset*temp1;
    for(modOffset = 0; modOffset < rts; modOffset++)
    {
      tensorOffset = temp2 + modOffset;
      hDim_t row, col;
      
      for(row = 0; row < p-1; row++)
      {
        double acc = 0;
        for(col = 1; col <= (p>>1); col++)
        {
          acc += 2 * ruinv[((row*col) % p)*rustride*tupSize].real * y[(tensorOffset+rts*(col-1))*tupSize];
        }
        for(col = (p>>1)+1; col <= p-1; col++)
        {
          acc += 2 * ruinv[((row*col) % p)*rustride*tupSize].imag * y[(tensorOffset+rts*(col-1))*tupSize];
        }
        tempSpace[row] = acc/sqrt(2);
      }
      
      for(row = 0; row < p-1; row++)
      {
        y[(tensorOffset+rts*row)*tupSize] = tempSpace[row];
      }
    }
  }
  free(tempSpace);
}

void ppD (void *y, hShort_t tupSize, hDim_t lts, hDim_t rts, PrimeExponent pe, void *ruinv, hInt_t* qs)
{
    hDim_t p = pe.prime;
    hDim_t e = pe.exponent;
#ifdef DEBUG_MODE
    ASSERT(e != 0);
#endif
    hDim_t mprime = ipow(p,e-1);
    for(int tupIdx = 0; tupIdx < tupSize; tupIdx++) {
      primeD (((double*)y)+tupIdx, tupSize, lts*mprime, rts, p, mprime, ((complex_t*)ruinv)+tupIdx);
    }
}

//the contents of y will be destroyed, but should be initialized in Haskell-land to independent Guassians over the reals
void tensorGaussianDec (hShort_t tupSize, double *y, hDim_t totm, PrimeExponent *peArr, hShort_t sizeOfPE, complex_t** ruinv)
{
  void** ruinvs = (void**)malloc(sizeOfPE*sizeof(void*));
  hShort_t i;
  for(i = 0; i < sizeOfPE; i++)
  {
      ruinvs[i] = (void*) (ruinv[i]);
  }
    
	tensorFuserCRT (y, tupSize, ppD, totm, peArr, sizeOfPE, ruinvs, (hInt_t*)0);
	
	free(ruinvs);
}