void Cmod<type>::iFFT(zpx &x, const zzv& y)const { FHE_TIMER_START; zpBak bak; bak.save(); context.restore(); zp rt; long m = getM(); // convert input to zpx format, initializing only the coeffs i s.t. (i,m)=1 x.rep.SetLength(m); long i,j; for (i=j=0; i<m; i++) if (zMStar->inZmStar(i)) conv(x.rep[i], y[j++]); x.normalize(); conv(rt, rInv); // convert rInv to zp format BluesteinFFT(x, m, rt, *ipowers, ipowers_aux, *iRb, iRb_aux, *Ra); // call the FFT routine // reduce the result mod (Phi_m(X),q) and copy to the output polynomial x FHE_NTIMER_START("iFFT:division") rem(x, x, *phimx); // out %= (Phi_m(X),q) FHE_NTIMER_STOP("iFFT:division") // normalize zp mm_inv; conv(mm_inv, m_inv); x *= mm_inv; FHE_TIMER_STOP; }
void FFTHelper::FFT(const zz_pX& f, Vec<zz_p>& v) const { tmp = f; BluesteinFFT(tmp, m, root, powers, powers_aux, Rb, Rb_aux, Ra); v.SetLength(phim); for (long i = 0, j = 0; i < m; i++) if (coprime[i]) v[j++] = coeff(tmp, i); }
void Cmodulus::FFT(vec_long &y, const ZZX& x) const { FHE_TIMER_START; zz_pBak bak; bak.save(); context.restore(); zz_pX& tmp = Cmodulus::getScratch_zz_pX(); { FHE_NTIMER_START(FFT_remainder); conv(tmp,x); // convert input to zpx format } if (!ALT_CRT && zMStar->getPow2()) { // special case when m is a power of 2 long k = zMStar->getPow2(); long phim = (1L << (k-1)); long dx = deg(tmp); long p = zz_p::modulus(); const zz_p *powers_p = (*powers).rep.elts(); const mulmod_precon_t *powers_aux_p = powers_aux.elts(); y.SetLength(phim); long *yp = y.elts(); zz_p *tmp_p = tmp.rep.elts(); for (long i = 0; i <= dx; i++) yp[i] = MulModPrecon(rep(tmp_p[i]), rep(powers_p[i]), p, powers_aux_p[i]); for (long i = dx+1; i < phim; i++) yp[i] = 0; FFTFwd(yp, yp, k-1, *zz_pInfo->p_info); return; } zz_p rt; conv(rt, root); // convert root to zp format BluesteinFFT(tmp, getM(), rt, *powers, powers_aux, *Rb); // call the FFT routine // copy the result to the output vector y, keeping only the // entries corresponding to primitive roots of unity y.SetLength(zMStar->getPhiM()); long i,j; long m = getM(); for (i=j=0; i<m; i++) if (zMStar->inZmStar(i)) y[j++] = rep(coeff(tmp,i)); }
void FFTHelper::iFFT(zz_pX& f, const Vec<zz_p>& v, bool normalize) const { tmp.rep.SetLength(m); for (long i = 0, j = 0; i < m; i++) { if (coprime[i]) tmp.rep[i] = v[j++]; } tmp.normalize(); BluesteinFFT(tmp, m, iroot, ipowers, ipowers_aux, iRb, iRb_aux, Ra); rem(f, tmp, phimx); if (normalize) f *= m_inv; }
void Cmodulus::FFT_aux(vec_long &y, zz_pX& tmp) const { if (zMStar->getPow2()) { // special case when m is a power of 2 long k = zMStar->getPow2(); long phim = (1L << (k-1)); long dx = deg(tmp); long p = zz_p::modulus(); const zz_p *powers_p = (*powers).rep.elts(); const mulmod_precon_t *powers_aux_p = powers_aux.elts(); y.SetLength(phim); long *yp = y.elts(); zz_p *tmp_p = tmp.rep.elts(); for (long i = 0; i <= dx; i++) yp[i] = MulModPrecon(rep(tmp_p[i]), rep(powers_p[i]), p, powers_aux_p[i]); for (long i = dx+1; i < phim; i++) yp[i] = 0; #ifdef FHE_OPENCL AltFFTFwd(yp, yp, k-1, *altFFTInfo); #else FFTFwd(yp, yp, k-1, *zz_pInfo->p_info); #endif return; } zz_p rt; conv(rt, root); // convert root to zp format BluesteinFFT(tmp, getM(), rt, *powers, powers_aux, *Rb); // call the FFT routine // copy the result to the output vector y, keeping only the // entries corresponding to primitive roots of unity y.SetLength(zMStar->getPhiM()); long i,j; long m = getM(); for (i=j=0; i<m; i++) if (zMStar->inZmStar(i)) y[j++] = rep(coeff(tmp,i)); }
void Cmod<zz,zp,zpx,zzv,fftrep,zpContext>::FFT(zzv &y, const ZZX& x) const { context.restore(); zp rt; zpx in, out; conv(in,x); // convert input to zpx format conv(rt, root); // convert root to zp format BluesteinFFT(out, in, getM(), rt, *powers, *Rb); // call the FFT routine // copy the result to the output vector y, keeping only the // entries corresponding to primitive roots of unity y.SetLength(zmStar->phiM()); unsigned i,j; for (i=j=0; i<getM(); i++) if (zmStar->inZmStar(i)) y[j++] = rep(coeff(out,i)); }
void Cmod<type>::FFT(zzv &y, const ZZX& x) const { FHE_TIMER_START; zpBak bak; bak.save(); context.restore(); zp rt; zpx& tmp = getScratch(); conv(tmp,x); // convert input to zpx format conv(rt, root); // convert root to zp format BluesteinFFT(tmp, getM(), rt, *powers, powers_aux, *Rb, Rb_aux, *Ra); // call the FFT routine // copy the result to the output vector y, keeping only the // entries corresponding to primitive roots of unity y.SetLength(zMStar->getPhiM()); long i,j; long m = getM(); for (i=j=0; i<m; i++) if (zMStar->inZmStar(i)) y[j++] = rep(coeff(tmp,i)); FHE_TIMER_STOP; }
void Cmod<zz,zp,zpx,zzv,fftrep,zpContext>::iFFT(ZZX &x, const zzv& y) const { context.restore(); zp rt; zpx in, out, pwrs; // convert input to zpx format, initializing only the coeffs i s.t. (i,m)=1 in.SetMaxLength(getM()); unsigned i,j; for (i=j=0; i<getM(); i++) if (zmStar->inZmStar(i)) SetCoeff(in, i, y[j++]); in.normalize(); conv(rt, rInv); // convert rInv to zp format BluesteinFFT(out, in, getM(), rt, *ipowers, *iRb); // call the FFT routine out /= getM(); // normalization // reduce the result mod (Phi_m(X),q) and copy to the output polynomial x conv(in, zmStar->PhimX()); // convert Phi_m(X) to zpx format rem(out, out, in); // out %= (Phi_m(X),q) conv(x,out); // convert output to ZZX format }
void Cmodulus::iFFT(zz_pX &x, const vec_long& y)const { FHE_TIMER_START; zz_pBak bak; bak.save(); context.restore(); if (zMStar->getPow2()) { // special case when m is a power of 2 long k = zMStar->getPow2(); long phim = (1L << (k-1)); long p = zz_p::modulus(); const zz_p *ipowers_p = (*ipowers).rep.elts(); const mulmod_precon_t *ipowers_aux_p = ipowers_aux.elts(); const long *yp = y.elts(); vec_long& tmp = Cmodulus::getScratch_vec_long(); tmp.SetLength(phim); long *tmp_p = tmp.elts(); #ifdef FHE_OPENCL AltFFTRev1(tmp_p, yp, k-1, *altFFTInfo); #else FFTRev1(tmp_p, yp, k-1, *zz_pInfo->p_info); #endif x.rep.SetLength(phim); zz_p *xp = x.rep.elts(); for (long i = 0; i < phim; i++) xp[i].LoopHole() = MulModPrecon(tmp_p[i], rep(ipowers_p[i]), p, ipowers_aux_p[i]); x.normalize(); return; } zz_p rt; long m = getM(); // convert input to zpx format, initializing only the coeffs i s.t. (i,m)=1 x.rep.SetLength(m); long i,j; for (i=j=0; i<m; i++) if (zMStar->inZmStar(i)) x.rep[i].LoopHole() = y[j++]; // DIRT: y[j] already reduced x.normalize(); conv(rt, rInv); // convert rInv to zp format BluesteinFFT(x, m, rt, *ipowers, ipowers_aux, *iRb); // call the FFT routine // reduce the result mod (Phi_m(X),q) and copy to the output polynomial x { FHE_NTIMER_START(iFFT_division); rem(x, x, *phimx); // out %= (Phi_m(X),q) } // normalize zz_p mm_inv; conv(mm_inv, m_inv); x *= mm_inv; }