Beispiel #1
0
void testCube(Vec<GenDescriptor>& vec, long widthBound)
{
  GeneratorTrees trees;
  long cost = trees.buildOptimalTrees(vec, widthBound);
  if (!noPrint) {
    cout << "@TestCube: trees=" << trees << endl;
    cout << " cost =" << cost << endl;
  }
  Vec<long> dims;
  trees.getCubeDims(dims);
  CubeSignature sig(dims);

  for (long cnt=0; cnt<3; cnt++) {
    Permut pi;
    randomPerm(pi, trees.getSize());

    PermNetwork net;
    net.buildNetwork(pi, trees);

    HyperCube<long> cube1(sig), cube2(sig);
    for (long i=0; i<cube1.getSize(); i++) cube1[i] = i;
    HyperCube<long> cube3 = cube1;
    applyPermToVec(cube2.getData(), cube1.getData(), pi); // direct application
    net.applyToCube(cube3); // applying permutation netwrok
    if (cube2==cube3) cout << "GOOD\n";
    else {
      cout << "BAD\n";
      if (cube1.getSize()<100 && !noPrint) {
	cout << "in="<<cube1.getData() << endl;
	cout << "out1="<<cube2.getData()<<", out2="
	     << cube3.getData()<<endl<<endl;
      }
    }
  }
}
Beispiel #2
0
// Compute one or more layers corresponding to one network of one leaf
void PermNetwork::setLayers4Leaf(long lyrIdx, const ColPerm& p,
				 const Vec<long>& benesLvls, long gIdx,
				 const SubDimension& leafData, 
				 const Permut& map2cube)
{
#ifdef DEBUG_PRINTOUT
  std::cerr << "Layer "<<lyrIdx<<", column-permutation="<< p << endl;
#endif
  // Compute the shift amounts for all the layers in this network
  Vec<bool> isID;
  Vec<Permut> shifts;
  if (benesLvls.length()==1) {// Special case for a "trivial" 1-layer network
    shifts.SetLength(1);
    isID.SetLength(1);
    isID[0] = !p.getShiftAmounts(shifts[0]);
  }
  else  // The general case of a multi-layer Benes network
    p.getBenesShiftAmounts(shifts,isID,benesLvls);

  // Copy the shift amounts to the right place in the bigger network,
  // renaming the slots from a linear array to the hyper cube
  for (long i=0; i<benesLvls.length(); i++) {
    PermNetLayer& lyr = layers[lyrIdx+i];
    lyr.genIdx = gIdx;
    lyr.isID = isID[i];
    lyr.e = leafData.e;
    if (!lyr.isID) {
#ifdef DEBUG_PRINTOUT
      std::cerr << "layer "<<lyrIdx+i<<": "<<shifts[i]<<endl;
#endif
      if (leafData.good) // For good leaves, shift by -x is the same as size-x
	for (long k=0; k<shifts[i].length(); k++)
	  if (shifts[i][k]<0) shifts[i][k] += leafData.size;
      applyPermToVec(lyr.shifts, shifts[i], map2cube); // do the renaming
#ifdef DEBUG_PRINTOUT
      std::cerr << "       : "<<lyr.shifts<<endl;
#endif
    }
    //    else std::cerr << "layer "<<lyrIdx+i<<"= identity\n";
  }
}
Beispiel #3
0
void testCube(Vec<GenDescriptor>& vec, long widthBound)
{
  GeneratorTrees trees;
  long cost = trees.buildOptimalTrees(vec, widthBound);
  cout << "@TestCube: trees=" << trees << endl;
  cout << " cost =" << cost << endl;
  Vec<long> dims;
  trees.getCubeDims(dims);
  CubeSignature sig(dims);

  for (long cnt=0; cnt<3; cnt++) {
    Permut pi;
    randomPerm(pi, trees.getSize());
    //    if (pi.length()<100)  cout << "pi="<<pi<<endl;

    PermNetwork net;
    net.buildNetwork(pi, trees);
    //    if (pi.length()<100) {
    //      cout << "permutations network {[gIdx,e,isID,shifts]} = " << endl;
    //      cout << net << endl;
    //    }

    HyperCube<long> cube1(sig), cube2(sig);
    for (long i=0; i<cube1.getSize(); i++) cube1[i] = i;
    HyperCube<long> cube3 = cube1;
    applyPermToVec(cube2.getData(), cube1.getData(), pi); // direct application
    net.applyToCube(cube3); // applying permutation netwrok
    if (cube2==cube3) cout << "yay\n";
    else {
      cout << "blech\n";
      if (cube1.getSize()<100) {
	cout << "in="<<cube1.getData() << endl;
	cout << "out1="<<cube2.getData()<<", out2="
	     << cube3.getData()<<endl<<endl;
      }
    }
  }
}
Beispiel #4
0
void testCtxt(long m, long p, long widthBound, long L, long r)
{
  if (!noPrint)
    cout << "@testCtxt(m="<<m<<",p="<<p<<",depth="<<widthBound<< ",r="<<r<<")";

  FHEcontext context(m,p,r);
  EncryptedArray ea(context); // Use G(X)=X for this ea object

  // Some arbitrary initial plaintext array
  vector<long> in(ea.size());
  for (long i=0; i<ea.size(); i++) in[i] = i % p;

  // Setup generator-descriptors for the PAlgebra generators
  Vec<GenDescriptor> vec(INIT_SIZE, ea.dimension());
  for (long i=0; i<ea.dimension(); i++)
    vec[i] = GenDescriptor(/*order=*/ea.sizeOfDimension(i),
			   /*good=*/ ea.nativeDimension(i), /*genIdx=*/i);

  // Some default for the width-bound, if not provided
  if (widthBound<=0) widthBound = 1+log2((double)ea.size());

  // Get the generator-tree structures and the corresponding hypercube
  GeneratorTrees trees;
  long cost = trees.buildOptimalTrees(vec, widthBound);
  if (!noPrint) {
    context.zMStar.printout();
    cout << ": trees=" << trees << endl;
    cout << " cost =" << cost << endl;
  }
  //  Vec<long> dims;
  //  trees.getCubeDims(dims);
  //  CubeSignature sig(dims);

  // 1/2 prime per level should be more or less enough, here we use 1 per layer
  if (L<=0) L = (1+trees.numLayers())*context.BPL();
  buildModChain(context, /*nLevels=*/L, /*nDigits=*/3);
  if (!noPrint) cout << "**Using "<<L<<" and "
		     << context.ctxtPrimes.card() << " Ctxt-primes\n";

  // Generate a sk/pk pair
  FHESecKey secretKey(context);
  const FHEPubKey& publicKey = secretKey;
  secretKey.GenSecKey(); // A +-1/0 secret key
  Ctxt ctxt(publicKey);

  for (long cnt=0; cnt<3; cnt++) {
    resetAllTimers();
    // Choose a random permutation
    Permut pi;
    randomPerm(pi, trees.getSize());

    // Build a permutation network for pi
    PermNetwork net;
    net.buildNetwork(pi, trees);

    // make sure we have the key-switching matrices needed for this network
    addMatrices4Network(secretKey, net);

    // Apply the permutation pi to the plaintext
    vector<long> out1(ea.size());
    vector<long> out2(ea.size());
    applyPermToVec(out1, in, pi); // direct application

    // Encrypt plaintext array, then apply permutation network to ciphertext
    ea.encrypt(ctxt, publicKey, in);
    if (!noPrint)
      cout << "  ** applying permutation network to ciphertext... " << flush;
    double t = GetTime();
    net.applyToCtxt(ctxt, ea); // applying permutation netwrok
    t = GetTime() -t;
    if (!noPrint)
      cout << "done in " << t << " seconds" << endl;
    ea.decrypt(ctxt, secretKey, out2);

    if (out1==out2) cout << "GOOD\n";
    else {
      cout << "************ BAD\n";
    }
    // printAllTimers();
  }
}