Exemplo n.º 1
0
// Compute the L-infinity distance between two vectors
double calcMaxDiff(const vector<cx_double>& v1, 
                   const vector<cx_double>& v2){

  if(lsize(v1)!=lsize(v2))
    NTL::Error("Vector sizes differ.\nFAILED\n");

  double maxDiff = 0.0;  
  for (long i=0; i<lsize(v1); i++) {
    double diffAbs = std::abs(v1[i]-v2[i]);
    if (diffAbs > maxDiff)
      maxDiff = diffAbs;
  }

  return maxDiff;
}
Exemplo n.º 2
0
void PAlgebraModDerived<type>::
buildLinPolyCoeffs(vector<RX>& C, const vector<RX>& L,
                   const MappingData<type>& mappingData) const
{
    REBak bak;
    bak.save();
    mappingData.contextForG.restore();

    long d = RE::degree();
    long p = zMStar.getP();

    assert(lsize(L) == d);

    vec_RE LL;
    LL.SetLength(d);

    for (long i = 0; i < d; i++)
        conv(LL[i], L[i]);

    vec_RE CC;
    ::buildLinPolyCoeffs(CC, LL, p, r);

    C.resize(d);
    for (long i = 0; i < d; i++)
        C[i] = rep(CC[i]);
}
Exemplo n.º 3
0
void PAlgebraModDerived<type>::embedInSlots(RX& H, const vector<RX>& alphas,
        const MappingData<type>& mappingData) const
{
    long nSlots = zMStar.getNSlots();
    assert(lsize(alphas) == nSlots);

    for (long i = 0; i < nSlots; i++) assert(deg(alphas[i]) < mappingData.degG);

    vector<RX> crt(nSlots); // alloate space for CRT components

    // The i'th CRT component is (H mod F_t) = alphas[i](maps[i]) mod F_t,
    // where with t=T[i].

    if (IsX(mappingData.G)) {
        // special case...no need for CompMod, which is
        // is not optimized for zero

        for (long i=0; i<nSlots; i++)   // crt[i] = alpha(maps[i]) mod Ft
            crt[i] = ConstTerm(alphas[i]);
    }
    else {
        // general case...

        for (long i=0; i<nSlots; i++)   // crt[i] = alpha(maps[i]) mod Ft
            CompMod(crt[i], alphas[i], mappingData.maps[i], factors[i]);
    }

    CRT_reconstruct(H,crt); // interpolate to get p
}
Exemplo n.º 4
0
/*---------------------------------------------------------------
|  lget_ln
|
|  get from list, listnode - return the nth list item, the
|  listnode is returned instead of the data, non-destructive
 ---------------------------------------------------------------*/
LNODEID
lget_ln ( LISTID lid, unsigned int n )
{
  int i;
  LIST * l;
  LISTNODE * ln;

  l = (LIST *)lid;

  CKLMAGIC(l);

  if ((n<1)||(n>lsize(l))) {
    return NULL;
  }

  ln = l->top;
  i = 1;
  while (i!=n) {
    CKMAGIC(ln);
    ln = ln->next;
    i++;
  }

  CKLMAGIC(l);
  return (LNODEID)ln;
}
Exemplo n.º 5
0
NTL_CLIENT

// Sample a degree-(n-1) poly, with only Hwt nonzero coefficients
void sampleHWt(zzX &poly, long n, long Hwt)
{
  if (n<=0) n=lsize(poly); if (n<=0) return;
  if (Hwt>=n) {
#ifdef DEBUG_PRINTOUT
    std::cerr << "Hwt="<<Hwt<<">=n="<<n<<", is this ok?\n";
#endif
    Hwt = n-1;
  }
  poly.SetLength(n); // allocate space
  for (long i=0; i<n; i++) poly[i] = 0;

  long i=0;
  while (i<Hwt) {  // continue until exactly Hwt nonzero coefficients
    long u = NTL::RandomBnd(n);  // The next coefficient to choose
    if (poly[u]==0) { // if we didn't choose it already
      long b = NTL::RandomBits_long(2)&2; // b random in {0,2}
      poly[u] = b-1;                      //   random in {-1,1}

      i++; // count another nonzero coefficient
    }
  }
}
Exemplo n.º 6
0
/*---------------------------------------------------------------
|  lget_n
|
|  get from list, index - return the nth list item, 
|  non-destructive
 ---------------------------------------------------------------*/
void * 
lget_n ( LISTID lid, unsigned int n )
{
  int i;
  LIST * l;
  LISTNODE * ln;

  l = (LIST *)lid;

  CKLMAGIC(l);

  if ((n<1)||(n>lsize(l))) {
    return NULL;
  }

  ln = l->top;
  i = 1;
  while (ln && (i!=n)) {
    CKMAGIC(ln);
    ln = ln->next;
    i++;
  }

  if (ln) {
    CKLMAGIC(l);
    return ln->data;
  }
  else {
    CKLMAGIC(l);
    return NULL;
  }
}
Exemplo n.º 7
0
// Sample a degree-(n-1) poly, with -1/0/+1 coefficients.
// Each coefficients is +-1 with probability prob/2 each,
// and 0 with probability 1-prob. By default, pr[nonzero]=1/2.
void sampleSmall(zzX &poly, long n, double prob)
{
  if (n<=0) n=lsize(poly); if (n<=0) return;
  assert(prob>3.05e-5 && prob<=1); // prob must be in [2^{-15},1/2]
  poly.SetLength(n);

  constexpr long bitSize=16;
  constexpr long hiMask = (1<<(bitSize-1)); // top bit = 2^15
  constexpr long loMask = hiMask-1;         // bottom 15 bits

  long threshold = round(hiMask*prob); // threshold/2^15 = Pr[nonzero]

  NTL_EXEC_RANGE(n, first, last)
  for (long i=first; i<last; i++) {
    long u = NTL::RandomBits_long(bitSize); // a random 16-bit number
    long uLo = u & loMask; // bottom 15 bits
    long uHi = u & hiMask; // top bit

    // with probability threshold/2^15, choose between +-1
    if (uLo<threshold) { // compare low 15 bits to threshold
      poly[i] = (uHi>>(bitSize-2))-1; // topBit*2 - 1 \in {+-1}
    }

    // with probability 1-prob, set to zero
    else poly[i] = 0;
Exemplo n.º 8
0
// A counterpart of tableLookup. The input is an encrypted table T[]
// and an array of encrypted bits I[], holding the binary representation
// of an index i into T.  This function increments by one the entry T[i].
void tableWriteIn(const CtPtrs& table, const CtPtrs& idx,
                  std::vector<zzX>* unpackSlotEncoding)
{
  FHE_TIMER_START;
  const Ctxt* ct = table.ptr2nonNull(); // find some non-null Ctxt
  long size = lsize(table);
  if (size==0) return;
  std::vector<Ctxt> products(size, Ctxt(ZeroCtxtLike, *ct));  
  CtPtrs_vectorCt pWrap(products); // A wrapper

  // Compute all products of ecnrypted bits =: b_i
  computeAllProducts(pWrap, idx, unpackSlotEncoding);

  // incrememnt each entry of T[i] by products[i]
  NTL_EXEC_RANGE(lsize(table), first, last)
  for(long i=first; i<last; i++)
    *table[i] += products[i];
  NTL_EXEC_RANGE_END
}
Exemplo n.º 9
0
// The input is a plaintext table T[] and an array of encrypted bits
// I[], holding the binary representation of an index i into T.
// The output is the encrypted value T[i].
void tableLookup(Ctxt& out, const vector<zzX>& table, const CtPtrs& idx,
                 std::vector<zzX>* unpackSlotEncoding)
{
  FHE_TIMER_START;
  out.clear();
  vector<Ctxt> products(lsize(table), out); // to hold subset products of idx
  CtPtrs_vectorCt pWrap(products); // A wrapper

  // Compute all products of ecnrypted bits =: b_i
  computeAllProducts(pWrap, idx, unpackSlotEncoding);

  // Compute the sum b_i * T[i]
  NTL_EXEC_RANGE(lsize(table), first, last)
  for(long i=first; i<last; i++)
    products[i].multByConstant(table[i]); // p[i] = p[i]*T[i]
  NTL_EXEC_RANGE_END
  for(long i=0; i<lsize(table); i++)
    out += products[i];
}
Exemplo n.º 10
0
// Apply different transformations to different slots. Cvec is a vector of
// length ea.size(), with each entry the output of ea.buildLinPolyCoeffs
void applyLinPolyMany(const EncryptedArray& ea, Ctxt& ctxt, 
                      const vector< vector<ZZX> >& Cvec)
{
  assert(&ea.getContext() == &ctxt.getContext());
  long d = ea.getDegree();
  long nslots = ea.size();

  assert(nslots == lsize(Cvec));
  for (long i = 0; i < nslots; i++)
    assert(d == lsize(Cvec[i]));

  vector<ZZX> encodedC(d);
  for (long j = 0; j < d; j++) {
    vector<ZZX> v(nslots);
    for (long i = 0; i < nslots; i++) v[i] = Cvec[i][j];
    ea.encode(encodedC[j], v);
  }

  applyLinPolyLL(ctxt, encodedC, ea.getDegree());
}
Exemplo n.º 11
0
/*------------------------------------------------------------
|  lcat
|
|  catenate - catenate l2 to l1, return pointer to l1.
 ------------------------------------------------------------*/
LISTID
lcat ( LISTID lid1, LISTID lid2 )
{
  CKLMAGIC(((LIST *)lid1));
  CKLMAGIC(((LIST *)lid2));
  while (lsize(lid2)) {
    ladd ( lid1, lrmv_n(lid2,1) );
  }

  CKLMAGIC(((LIST *)lid1));
  CKLMAGIC(((LIST *)lid2));

  return lid1;
}
Exemplo n.º 12
0
/* combine hunk lists a and b, while adjusting b for offset changes in a/
   this deletes a and b and returns the resultant list. */
static struct flist *combine(struct flist *a, struct flist *b)
{
	struct flist *c = NULL;
	struct frag *bh, *ct;
	int offset = 0, post;

	if (a && b)
		c = lalloc((lsize(a) + lsize(b)) * 2);

	if (c) {

		for (bh = b->head; bh != b->tail; bh++) {
			/* save old hunks */
			offset = gather(c, a, bh->start, offset);

			/* discard replaced hunks */
			post = discard(a, bh->end, offset);

			/* insert new hunk */
			ct = c->tail;
			ct->start = bh->start - offset;
			ct->end = bh->end - post;
			ct->len = bh->len;
			ct->data = bh->data;
			c->tail++;
			offset = post;
		}

		/* hold on to tail from a */
		memcpy(c->tail, a->head, sizeof(struct frag) * lsize(a));
		c->tail += lsize(a);
	}

	lfree(a);
	lfree(b);
	return c;
}
Exemplo n.º 13
0
// Compute the max relative difference between two vectors
double calcMaxRelDiff(const vector<cx_double>& v1,
                   const vector<cx_double>& v2)
{
    if(lsize(v1)!=lsize(v2))
        NTL::Error("Vector sizes differ.\nFAILED\n");

    // Compute the largest-magnitude value in the vector
    double maxAbs = 0.0;
    for (auto& x : v1) {
        if (std::abs(x) > maxAbs)
            maxAbs = std::abs(x);
    }
    if (maxAbs<1e-10)
        maxAbs = 1e-10;

    double maxDiff = 0.0;
    for (long i=0; i<lsize(v1); i++) {
        double relDiff = std::abs(v1[i]-v2[i]) / maxAbs;
        if (relDiff > maxDiff)
            maxDiff = relDiff;
    }

    return maxDiff;
}
Exemplo n.º 14
0
// For an n-size array, compute the 2^n products
//     products[j] = \prod_{i s.t. j_i=1} array[i]
//                   \times \prod_{i s.t. j_i=0}(a-array[i])
void computeAllProducts(/*Output*/CtPtrs& products,
                        /*Index*/const CtPtrs& array,
                       std::vector<zzX>* unpackSlotEncoding)
{
  FHE_TIMER_START;
  long nBits = array.size();
  if (lsize(products)>0) {
    long nBits2 = NTL::NumBits(lsize(products)-1); // ceil(log_2(size))
    if (nBits>nBits2)
      nBits=nBits2;    // ignore extra bits in 'array'
  }
  if (nBits<1) return; // do nothing
  assert(nBits <= 16); // Output cannot be bigger than 2^16

  if (lsize(products)==0) // try to set the output size
    products.resize(1L << nBits, &array);
  for (long i=0; i<lsize(products); i++)
    products[i]->clear();

  // Check that we have enough levels, try to bootstrap otherwise
  assert(array.ptr2nonNull() != nullptr);
  long bpl = array.ptr2nonNull()->getContext().BPL();
  if (findMinBitCapacity(array) < (NTL::NumBits(nBits)+1)*bpl) {
    const Ctxt* ct = array.ptr2nonNull(); // find some non-null Ctxt
    assert(unpackSlotEncoding!=nullptr);
    assert(ct!=nullptr);
    assert(ct->getPubKey().isBootstrappable());
    packedRecrypt(array, *unpackSlotEncoding,
                  *(ct->getContext().ea), /*belowLevel=*/nBits +3);
  }
  if (findMinBitCapacity(array) < (NTL::NumBits(nBits)+1)*bpl)
    throw std::logic_error("not enough levels for table lookup");

  // Call the recursive function that copmutes the products
  recursiveProducts(products, CtPtrs_slice(array,0,nBits));
}
Exemplo n.º 15
0
void applyLinPolyLL(Ctxt& ctxt, const vector<P>& encodedC, long d)
{
  assert(d == lsize(encodedC));

  ctxt.cleanUp();  // not sure, but this may be a good idea

  Ctxt tmp(ctxt);

  ctxt.multByConstant(encodedC[0]);
  for (long j = 1; j < d; j++) {
    Ctxt tmp1(tmp);
    tmp1.frobeniusAutomorph(j);
    tmp1.multByConstant(encodedC[j]);
    ctxt += tmp1;
  }
}
Exemplo n.º 16
0
void basicString::findLongestSpecificWord(const vector<string>& text,const string& notChar)
{
	auto iter = std::max_element(text.begin(), text.end(), [&](const string& lhs, const string& rhs) ->bool
	{
		string::size_type lsize(0), rsize(0);
		if (lhs.find_first_of(notChar) == string::npos)
			lsize = lhs.size();
		if (rhs.find_first_of(notChar) == string::npos)
			rsize = rhs.size();
		return lsize < rsize;
	});
	if (iter != text.end())
		std::cout << "Longest word without specific character is :" << *iter << std::endl;
	else
		std::cout << "input text is empty" << std::endl;
}
Exemplo n.º 17
0
// Returns in gens a generating set for Zm* /<p>, and in ords the
// order of these generators. Return value is the order of p in Zm*.
long findGenerators(vector<long>& gens, vector<long>& ords, long m, long p)
{
  gens.clear();
  ords.clear();
  // Compute the generators for (Z/mZ)^*
  vector<long> classes(m);
  vector<long> orders(m);

  for (long i=0; i<m; i++) { // initially each element in its own class
    if (GCD(i,m)!=1) classes[i] = 0; // i is not in (Z/mZ)^*
    else             classes[i] = i;
  }

  // Start building a representation of (Z/mZ)^*, first use the generator p
  conjClasses(classes,p % m,m);  // merge classes that have a factor of p

  // The order of p is the size of the equivalence class of 1
#if 0
  long ordP = std::count(classes.begin(), classes.end(), 1);
       // count(from,to,val) returns # of elements in (from,to) with value=val
#else
   long ordP = 0;
   for (long i = 0; i < lsize(classes); i++)
      if (classes[i] == 1) ordP++;
#endif

  // Compute orders in (Z/mZ)^*/<p> while comparing to (Z/mZ)^*
  while (true) {
    compOrder(orders,classes,true,m);
    // if the orders of i in Zm* /<p> and Zm* are not the same, then
    // order[i] contains the order in Zm* /<p> with negative sign

    long idx = argmax(orders, &gtAbsVal); // find the element with largest order
    long largest = orders[idx];

    if (abs(largest) == 1) break;   // Trivial group, we are done

    // store generator with same order as in (Z/mZ)^*
    gens.push_back(idx);
    ords.push_back(largest);
    conjClasses(classes,idx,m); // merge classes that have a factor of idx
  }
  return ordP;
}
Exemplo n.º 18
0
void PAlgebraModDerived<type>::embedInSlots(RX& H, const vector<RX>& alphas, 
                                         const MappingData<type>& mappingData) const
{
  if (isDryRun()) {
    H = RX::zero();
    return;
  }
  FHE_TIMER_START;

  long nSlots = zMStar.getNSlots();
  assert(lsize(alphas) == nSlots);

  for (long i = 0; i < nSlots; i++) assert(deg(alphas[i]) < mappingData.degG); 
 
  vector<RX> crt(nSlots); // alloate space for CRT components

  // The i'th CRT component is (H mod F_t) = alphas[i](maps[i]) mod F_t,
  // where with t=T[i].

  if (IsX(mappingData.G)) {
    // special case...no need for CompMod, which is
    // is not optimized for this case

    for (long i=0; i<nSlots; i++)   // crt[i] = alpha(maps[i]) mod Ft
      crt[i] = ConstTerm(alphas[i]);
  }
  else {
    // general case...still try to avoid CompMod when possible,
    // which is the common case for encoding masks

    for (long i=0; i<nSlots; i++) {   // crt[i] = alpha(maps[i]) mod Ft
      if (deg(alphas[i]) <= 0) 
        crt[i] = alphas[i];
      else
        CompMod(crt[i], alphas[i], mappingData.maps[i], factors[i]);
    }
  }

  CRT_reconstruct(H,crt); // interpolate to get p

  FHE_TIMER_STOP;
}
Exemplo n.º 19
0
// mod-switch up to add the primes in s \setminus primeSet, after this call we
// have s<=primeSet. s must contain either all special primes or none of them.
void Ctxt::modUpToSet(const IndexSet &s)
{
  //  FHE_TIMER_START;
  IndexSet setDiff = s/primeSet; // set minus (primes in s but not in primeSet)
  if (empty(setDiff)) return;    // nothing to do, no primes are added

  // scale up all the parts to use also the primes in setDiff
  double f = 0.0;
  for (long i=0; i<lsize(parts); i++) {
    // addPrimesAndScale returns the logarithm of the product of added primes,
    // all calls should return the same value = log(prod. of primes in setDiff)
    f = parts[i].addPrimesAndScale(setDiff);
  }

  // The variance estimate grows by a factor of exp(f)^2 = exp(2f)
  noiseVar *= xexp(2*f);

  primeSet.insert(setDiff); // add setDiff to primeSet
  assert(verifyPrimeSet()); // sanity-check: ensure primeSet is still valid
  //  FHE_TIMER_STOP;
}
Exemplo n.º 20
0
// A recursive function to compute, for an n-size array, the 2^n products
//     products[j] = \prod_{i s.t. j_i=1} array[i]
//                   \times \prod_{i s.t. j_i=0}(a-array[i])
// It is assume that 'products' size <= 2^n, else only 1st 2^n entries are set
static void
recursiveProducts(const CtPtrs& products, const CtPtrs_slice& array)
{
  long nBits = lsize(array);
  long N = lsize(products);
  if (nBits==0 || N==0) return; // nothing to do

  if (N > (1L << nBits)) N = (1L << nBits);
  else if (N < (1L << (nBits-1)))
    nBits = NTL::NumBits(N-1); // Ensure nBits <= ceil(log2(N))

  if (N<=2) { // edge condition
    *products[0] = *array[0];
    products[0]->negate();
    products[0]->addConstant(ZZ(1)); // out[0] = 1-in
    if (N>1)
      *products[1] = *array[0];    // out[1] = in
  }
  // optimization for n=2: a single multiplication instead of 4
  else if (N<=4) {
    *products[0] = *array[1];          // x1
    products[0]->multiplyBy(*array[0]);// x1 x0

    *products[1] = *array[0];          // x0
    *products[1] -= *products[0];      // x0 - x1 x0 = (1-x1)x0

    *products[2] = *array[1];          // x1
    *products[2] -= *products[0];      // x1 - x1 x0 = x1(1-x0)

    if (N>3)
      *products[3] = *products[0];     // x1 x0

    products[0]->addConstant(ZZ(1));  // 1 +x1 x0
    *products[0] -= *array[1];         // 1 +x1 x0 -x1
    *products[0] -= *array[0]   ;      // 1 +x1 x0 -x1 -x0 = (1-x1)(1-x0)
  }
  else { // split the array into two parts;
    // first part is highest pow(2) < n, second part is what is left

    long n1 = 1L << (NTL::NumBits(nBits)-1); // largest power of two <= n
    if (nBits<=n1) n1 = n1/2;                // largest power of two < n
    long k = 1L << n1;         // size of first part
    long l = 1L << (nBits-n1); // size of second part

    const Ctxt* ct = array.ptr2nonNull(); // find some non-null Ctxt
    std::vector<Ctxt> products1(k, Ctxt(ZeroCtxtLike, *ct));
    std::vector<Ctxt> products2(l, Ctxt(ZeroCtxtLike, *ct));

    // compute first part of the array
    recursiveProducts(CtPtrs_vectorCt(products1), CtPtrs_slice(array,0, n1));

    // recursive call on second part of array
    recursiveProducts(CtPtrs_vectorCt(products2), CtPtrs_slice(array,n1,nBits-n1));

    // multiplication to get all subset products
    NTL_EXEC_RANGE(lsize(products), first, last)
    for(long ii=first; ii<last; ii++) {
      long j = ii / k;
      long i = ii - j*k;
      *products[ii] = products1[i];
      products[ii]->multiplyBy(products2[j]);
    }
    NTL_EXEC_RANGE_END
  }
}
Exemplo n.º 21
0
int main(int argc, char *argv[]) 
{
  ArgMapping amap;
  amap.arg("noPrint", noPrint, "suppress printouts");

  long m=16;
  amap.arg("m", m, "cyclotomic index");
  amap.note("e.g., m=1024, m=2047");

  long r=8;
  amap.arg("r", r, "bit of precision");
  amap.parse(argc, argv);

  if (!noPrint) {
    vector<long> f;
    factorize(f,m);
    cout << "r="<<r<<", factoring "<<m<<" gives [";
    for (unsigned long i=0; i<f.size(); i++)
      cout << f[i] << " ";
    cout << "]\n";
  }

  FHEcontext context(m, /*p=*/-1, r);
  buildModChain(context, 5, 2);

  const EncryptedArrayCx& ea = context.ea->getCx();
  if (!noPrint)
    ea.getPAlgebra().printout();

#ifdef DEBUG_PRINTOUT
  vector<cx_double> vc1;
  ea.random(vc1);
  cout << "random complex vc1=";
  printVec(cout,vc1,8)<<endl;

  vector<double> vd;
  ea.random(vd);
  cout << "random real vd=";
  printVec(cout,vd,8)<<endl;
#endif

  vector<double> vl;
  ea.random(vl);
  vl[1] = -1; // ensure that this is not the zero vector
#ifdef DEBUG_PRINTOUT
  cout << "random int v=";
  printVec(cout,vl,8)<<endl;
#endif

  zzX poly;
  double factor = ea.encode(poly, vl, 1.0);
  if (!noPrint) {
    ZZX poly2;
    convert(poly2, poly);
    cout << "  encoded into a degree-"<<NTL::deg(poly2)<<" polynomial\n";
  }

  vector<double> vd2;
  ea.decode(vd2, poly, factor);
#ifdef DEBUG_PRINTOUT
  cout << "  decoded into vd2=";
  printVec(cout,vd2,8)<<endl;
#endif
  assert(lsize(vl)==lsize(vd2));

  double maxDiff = 0.0;
  for (long i=0; i<lsize(vl); i++) {
    double diffAbs = std::abs(vl[i]-vd2[i]);
    if (diffAbs > maxDiff)
      maxDiff = diffAbs;
  }
  cout << ((maxDiff>0.1)? "BAD?" : "GOOD?")
       << "  max |v-vd2|_{infty}="<<maxDiff
       << endl;
  return 0;
}
Exemplo n.º 22
0
void  TestIt(long p, long r, long c, long _k, long w,
             long L, Vec<long>& mvec, 
             Vec<long>& gens, Vec<long>& ords, long useCache)
{
  if (lsize(mvec)<1) { // use default values
    mvec.SetLength(3); gens.SetLength(3); ords.SetLength(3);
    mvec[0] = 7;    mvec[1] = 3;    mvec[2] = 221;
    gens[0] = 3979; gens[1] = 3095; gens[2] = 3760;
    ords[0] = 6;    ords[1] = 2;    ords[2] = -8;
  }
  if (!noPrint)
    cout << "*** TestIt"
       << (dry? " (dry run):" : ":")
       << " p=" << p
       << ", r=" << r
       << ", c=" << c
       << ", k=" << _k
       << ", w=" << w
       << ", L=" << L
       << ", mvec=" << mvec << ", "
       << ", useCache = " << useCache
       << endl;

  setTimersOn();
  setDryRun(false); // Need to get a "real context" to test ThinEvalMap

  // mvec is supposed to include the prime-power factorization of m
  long nfactors = mvec.length();
  for (long i = 0; i < nfactors; i++)
    for (long j = i+1; j < nfactors; j++)
      assert(GCD(mvec[i], mvec[j]) == 1);

  // multiply all the prime powers to get m itself
  long m = computeProd(mvec);
  assert(GCD(p, m) == 1);

  // build a context with these generators and orders
  vector<long> gens1, ords1;
  convert(gens1, gens);
  convert(ords1, ords);
  FHEcontext context(m, p, r, gens1, ords1);
  buildModChain(context, L, c);

  if (!noPrint) {
    context.zMStar.printout(); // print structure of Zm* /(p) to cout
    cout << endl;
  }
  long d = context.zMStar.getOrdP();
  long phim = context.zMStar.getPhiM();
  long nslots = phim/d;

  setDryRun(dry); // Now we can set the dry-run flag if desired

  FHESecKey secretKey(context);
  const FHEPubKey& publicKey = secretKey;
  secretKey.GenSecKey(w); // A Hamming-weight-w secret key
  addSome1DMatrices(secretKey); // compute key-switching matrices that we need
  addFrbMatrices(secretKey); // compute key-switching matrices that we need

  // GG defines the plaintext space Z_p[X]/GG(X)
  ZZX GG;
  GG = context.alMod.getFactorsOverZZ()[0];
  EncryptedArray ea(context, GG);

  zz_p::init(context.alMod.getPPowR());

  Vec<zz_p> val0(INIT_SIZE, nslots);
  for (auto& x: val0)
    random(x);

  vector<ZZX> val1;
  val1.resize(nslots);
  for (long i = 0; i < nslots; i++) {
    val1[i] = conv<ZZX>(conv<ZZ>(rep(val0[i])));
  }

  Ctxt ctxt(publicKey);
  ea.encrypt(ctxt, publicKey, val1);

  resetAllTimers();
  FHE_NTIMER_START(ALL);

  // Compute homomorphically the transformation that takes the
  // coefficients packed in the slots and produces the polynomial
  // corresponding to cube

  if (!noPrint) CheckCtxt(ctxt, "init");

  if (!noPrint) cout << "build ThinEvalMap\n";
  ThinEvalMap map(ea, /*minimal=*/false, mvec, 
    /*invert=*/false, /*build_cache=*/false); 
  // compute the transformation to apply

  if (!noPrint) cout << "apply ThinEvalMap\n";
  if (useCache) map.upgrade();
  map.apply(ctxt); // apply the transformation to ctxt
  if (!noPrint) CheckCtxt(ctxt, "ThinEvalMap");
  if (!noPrint) cout << "check results\n";

  if (!noPrint) cout << "build ThinEvalMap\n";
  ThinEvalMap imap(ea, /*minimal=*/false, mvec, 
    /*invert=*/true, /*build_cache=*/false); 
  // compute the transformation to apply
  if (!noPrint) cout << "apply ThinEvalMap\n";
  if (useCache) imap.upgrade();
  imap.apply(ctxt); // apply the transformation to ctxt
  if (!noPrint) {
    CheckCtxt(ctxt, "ThinEvalMap");
    cout << "check results\n";
  }

#if 1

  /* create dirty version of ctxt */
  Vec<zz_pX> dirty_val0;
  dirty_val0.SetLength(nslots);
  for (long i = 0; i < nslots; i++) {
    random(dirty_val0[i], d);
    SetCoeff(dirty_val0[i], 0, val0[i]);
  }
  
  vector<ZZX> dirty_val1;
  dirty_val1.resize(nslots);
  for (long i = 0; i < nslots; i++) {
    dirty_val1[i] = conv<ZZX>(dirty_val0[i]);
  }

  Ctxt dirty_ctxt(publicKey);
  ea.encrypt(dirty_ctxt, publicKey, dirty_val1);


  EvalMap dirty_map(ea, /*minimal=*/false, mvec, 
    /*invert=*/false, /*build_cache=*/false); 

  dirty_map.apply(dirty_ctxt);
  imap.apply(dirty_ctxt);
#endif


  vector<ZZX> val2;
  ea.decrypt(ctxt, secretKey, val2);

  if (val1 == val2)
    cout << "ThinEvalMap: GOOD\n";
  else
    cout << "ThinEvalMap: BAD\n";

#if 1
  vector<ZZX> dirty_val2;
  ea.decrypt(dirty_ctxt, secretKey, dirty_val2);

  if (val1 == dirty_val2)
    cout << "ThinEvalMap: GOOD\n";
  else
    cout << "ThinEvalMap: BAD\n";
#endif


  FHE_NTIMER_STOP(ALL);

  if (!noPrint) {
    cout << "\n*********\n";
    printAllTimers();
    cout << endl;
  }
}
Exemplo n.º 23
0
void testBasicArith(const FHEPubKey& publicKey,
                    const FHESecKey& secretKey,
                    const EncryptedArrayCx& ea, double epsilon)
{
  if (verbose)  cout << "Test Arithmetic ";
  // Test objects

  Ctxt c1(publicKey), c2(publicKey), c3(publicKey);
  
  vector<cx_double> vd;
  vector<cx_double> vd1, vd2, vd3;
  ea.random(vd1);
  ea.random(vd2);

  // test encoding of shorter vectors
  vd1.resize(vd1.size()-2);
  ea.encrypt(c1, publicKey, vd1, /*size=*/1.0);
  vd1.resize(vd1.size()+2, 0.0);

  ea.encrypt(c2, publicKey, vd2, /*size=*/1.0);

  // Test - Multiplication
  c1 *= c2;
  for (long i=0; i<lsize(vd1); i++) vd1[i] *= vd2[i];

  ZZX poly;
  ea.random(vd3);
  ea.encode(poly, vd3, /*size=*/1.0);
  c1.addConstant(poly); // vd1*vd2 + vd3
  for (long i=0; i<lsize(vd1); i++) vd1[i] += vd3[i];

  // Test encoding, encryption of a single number
  double xx = NTL::RandomLen_long(16)/double(1L<<16); // random in [0,1]
  ea.encryptOneNum(c2, publicKey, xx);
  c1 += c2;
  for (auto& x : vd1) x += xx;

  // Test - Multiply by a mask
  vector<long> mask(lsize(vd1), 1);
  for (long i=0; i*(i+1)<lsize(mask); i++) {
    mask[i*i] = 0;
    mask[i*(i+1)] = -1;
  }

  ea.encode(poly,mask, /*size=*/1.0);
  c1.multByConstant(poly); // mask*(vd1*vd2 + vd3)
  for (long i=0; i<lsize(vd1); i++) vd1[i] *= mask[i];

  // Test - Addition
  ea.random(vd3);
  ea.encrypt(c3, publicKey, vd3, /*size=*/1.0);
  c1 += c3;
  for (long i=0; i<lsize(vd1); i++) vd1[i] += vd3[i];

  c1.negate();
  c1.addConstant(to_ZZ(1));
  for (long i=0; i<lsize(vd1); i++) vd1[i] = 1.0 - vd1[i];

  // Diff between approxNums HE scheme and plaintext floating  
  ea.decrypt(c1, secretKey, vd);
#ifdef DEBUG_PRINTOUT
  printVec(cout<<"res=", vd, 10)<<endl;
  printVec(cout<<"vec=", vd1, 10)<<endl;
#endif
  if (verbose)
    cout << "(max |res-vec|_{infty}="<< calcMaxDiff(vd, vd1) << "): ";

  if (cx_equals(vd, vd1, conv<double>(epsilon*c1.getPtxtMag())))
    cout << "GOOD\n";
  else {
    cout << "BAD:\n";
    std::cout << "  max(vd)="<<largestCoeff(vd)
              << ", max(vd1)="<<largestCoeff(vd1)
              << ", maxDiff="<<calcMaxDiff(vd,vd1) << endl<<endl;
  }
}
Exemplo n.º 24
0
int main(int argc, char *argv[]) 
{

  argmap_t argmap;
  argmap["m"] = "0"; 
  argmap["p"] = "2";
  argmap["r"] = "1";

  if (!parseArgs(argc, argv, argmap)) usage();

  unsigned long m = atoi(argmap["m"]);

  if (!m) usage();

  unsigned long p = atoi(argmap["p"]);

  unsigned long r = atoi(argmap["r"]);

  cout << "m = " << m << ", p = " << p <<  ", r = " << r << endl;

  vector<long> f;
  factorize(f,m);
  cout << "factoring "<<m<<" gives [";
  for (unsigned long i=0; i<f.size(); i++)
    cout << f[i] << " ";
  cout << "]\n";

  PAlgebra al(m, p);
  al.printout();
  cout << "\n";

  PAlgebraMod almod(al, r);
  almod.genMaskTable();

  FHEcontext context(m, p, r);
  buildModChain(context, 5, 2);

  stringstream s1;
  writeContextBase(s1, context);
  s1 << context;

  string s2 = s1.str();

  cout << s2 << endl;

  stringstream s3(s2);

  unsigned long m1, p1, r1;
  readContextBase(s3, m1, p1, r1);

  FHEcontext c1(m1, p1, r1);
  s3 >> c1;

  if (context == c1)
    cout << "equal\n";
  else
    cout << "not equal\n";

  return 0;

#if 0


  PAlgebraModTwo al2(al);
  PAlgebraMod2r al2r(r,al2);

  if (false) {
    long nslots = al.NSlots();
    long ngens = al.numOfGens();

    for (long i = 0; i < nslots; i++) {
      const int* v = al.dLog(al.ith_rep(i));
      cout << i << " ";
      for (long j = 0; j < ngens; j++)
         cout << v[j] << " ";
      cout << "\n";
      
    }

    return 0;
  }

  //  GF2X::HexOutput = 1; // compact hexadecimal printout
  //  cout << "Phi_m(X) = " << al.PhimX()  << endl;
  //  vec_GF2X Fs = al2.Factors();
  //  cout << "Factors = " << Fs << endl;

  //  GF2X Q = Fs[0];
  //  for (long i=1; i<Fs.length(); i++) Q *= Fs[i];
  //  cout << "mult of factors = " << Q << endl;

  GF2X G;          // G is the AES polynomial, G(X)= X^8 +X^4 +X^3 +X +1
  SetCoeff(G,8); SetCoeff(G,4); SetCoeff(G,3); SetCoeff(G,1); SetCoeff(G,0);
  //  GF2X G; SetCoeff(G,4); SetCoeff(G,1); SetCoeff(G,0); // X^4 +X +1
  //  cout << "G = " << G << ", deg(G)=" << deg(G) << endl;

  vector<GF2X> maps;
  al2.mapToSlots(maps, G);
  //  cout << "maps = [";
  //  for (unsigned long i=0; i<maps.size(); i++)
  //    cout << maps[i] << " ";
  //  cout << "]\n";


  GF2X X; SetX(X); // The polynomial X
  GF2X ptxt;       // plaintext has X in all the slots
  cout << "embedding X in plaintext slots... ";
  al2.embedInAllSlots(ptxt, X, maps);
  cout << "done\n";
  //  cout << "ptxt = " << ptxt << endl;

  // Debugging printout: p modulo all the factors
  //  vector<GF2X> crt;
  //  al2.CRT_decompose(crt,ptxt);
  //  cout << "ptxt mod factors = [";
  //  for (unsigned long i=0; i<crt.size(); i++) cout << crt[i] << " ";
  //  cout << "]\n";

  // Decode the plaintext back to a vector of elements,
  // and check that they are all equal to X
  vector<GF2X> alphas;
  cout << "decoding plaintext slots... ";
  al2.decodePlaintext(alphas, ptxt, G, maps);
  cout << "done\n";
  //  cout << "alphas = [";
  //  for (unsigned long i=0; i<alphas.size(); i++)
  //    cout << alphas[i] << " ";
  //  cout << "]\n";

  cout << "comparing " << alphas.size() << " plaintext slots to X... ";
  for (unsigned long i=0; i<alphas.size(); i++) if (alphas[i] != X) {
      cout << "\n  alphas["<<i<<"] = "<<alphas[i]<<" != X\n\n";
      exit(0);
  }
  cout << "all tests completed successfully\n\n";

  // encode and decode random polynomials
  for (unsigned long i=0; i<alphas.size(); i++) 
    random(alphas[i], 8); // random degree-7 polynomial mod 2

  cout << "embedding random GF(2^8) elements in plaintext slots... ";
  al2.embedInSlots(ptxt, alphas, maps);
  cout << "done\n";

  // Compute p^2 mod Phi_m(X) and also p(X^2) mod Phi_m(X) and
  // verify that they both decode to a vector of X^2 in all the slots

  cout << "squaring and decoding plaintext slots... ";

  X *= X;                            // X^2
  //  GF2X ptxt2;
  //  SqrMod(ptxt2,ptxt,al2.PhimXMod());      // ptxt2 = ptxt^2 mod Phi_m(X)
  CompMod(ptxt, ptxt, X, al2.PhimXMod()); // ptxt = ptxt(X^2) mod Phi_m(X)

  //  // sanity chack: these should be the same mod 2 (but not mod 2^r)
  //  if (ptxt != ptxt2) cout << "ptxt^2 != ptxt(X^2) mod Phi_m(X)\n";

  vector<GF2X> betas;
  al2.decodePlaintext(betas, ptxt, G, maps);
  cout << "done\n";

  if (alphas.size() != betas.size()) Error("wrong number of slots decoded");

  cout << "comparing decoded plaintext slots... ";
  for (unsigned long i=0; i<alphas.size(); i++) {
    SqrMod(alphas[i],alphas[i],G); // should get alpha[i]^2 mod G
    if (alphas[i] != betas[i]) {
      cout << "\n  alphas["<<i<<"] = "<<alphas[i]
           <<" != " << "betas["<<i<<"] = " << betas[i] << "\n\n";
      exit(0);
    }
  }
  cout << "all tests completed successfully\n\n";
  // return 0;

  al2r.restoreContext();

  vector<zz_pX> maps1;
  zz_pX X1; SetX(X1);

  cerr << "HERE1\n";
  al2r.mapToSlots(maps1, X1);
  cerr << "HERE1a\n";

  vector<zz_pX> alphas1;
  alphas1.resize(maps.size());

  for (long i = 0; i < lsize(alphas1); i++)
    random(alphas1[i], 1);

  zz_pX ptxt1;

  cerr << "HERE2\n";
  al2r.embedInSlots(ptxt1, alphas1, maps1);

  cerr << "HERE3\n";
  vector<zz_pX> betas1;
  al2r.decodePlaintext(betas1, ptxt1, X1, maps1);

  assert(alphas1 == betas1);
  

  return 0;
#endif
}
Exemplo n.º 25
0
/*Edit file function-------------------------------------------------*/
void Editfile(list_ref list) {
  char stdinline[4096];
  int stdincount;
  for (stdincount = 0;; ++stdincount) {

    //print program basename
    printf("%s: ", Exec_Name); //change this before submitting

    //get string from file
    char *linepos = fgets(stdinline, sizeof (stdinline), stdin);

    //if EOF break and put EOF key
    if (linepos == NULL) {
      printf("^D\n");
      break;
    }
    //chomp newline
    char *nlinepos = strchr(stdinline, '\n');
    if (nlinepos != NULL) *nlinepos = '\0';

    //echo print to terminal
    if (want_echo) printf("%s", stdinline);

    //check for a line of all spaces
    bool space = SpaceCheck(stdinline);

    //check for badline



    //if a line of all spaces then go to next iteration
    if (space) {
      stdincount--;
      continue;

      //if not newline terminated or empty string then badline
    } else if (linepos == NULL || stdinline[0] == '\0') {
      Badline(Exec_Name, stdinline);

      //goodline so check for commands and lines
    } else {
      char *inputline; //used for commands that require an argument
      switch (stdinline[0]) {
        case '#':
          continue;
          break;
        case '$':
          Com$(list);
          break;
        case '*':
          viewlist(list);
          break;
        case '.':
          ComDot(list);
          break;
        case '0':
          Com0(list);
          break;
        case '<':
          ComL(list);
          break;
        case '>':
          ComR(list);
          break;
        case '@':
          debugdump_list(list);
          break;
        case 'a':
          ComA(list, inputline, stdinline);
          break;
        case 'd':
          if (lsize(list) > 0) delete_list(list);
          break;
        case 'i':
          ComI(list, inputline, stdinline);
          break;
        case 'r':
          break;
        case 'w':
          break;
        default:
          Badline(Exec_Name, stdinline);
          break;
      }
    }
  }
}