Example #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;
      }
    }
  }
}
Example #2
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;
      }
    }
  }
}
Example #3
0
// Build a full permutation network
void PermNetwork::buildNetwork(const Permut& pi, const GeneratorTrees& trees)
{
  if (trees.numTrees()==0) { // the identity permutation, nothing to do
    layers.SetLength(0);
    return;
  }

  Vec<long> dims;
  trees.getCubeSubDims(dims);

  //  std::cerr << "pi =      "<<pi<<endl;
  //  std::cerr << "map2cube ="<<trees.mapToCube()<<endl;
  //  std::cerr << "map2array="<<trees.mapToArray()<<endl;

  // Compute the permutation on the cube, rho = map2cube o pi o map2array

  Permut rho;
  applyPermsToVec(rho, trees.mapToCube(), pi, trees.mapToArray());
  //  std::cerr << "rho =     "<<rho<<endl;


  // Break rho along the different dimensions
  CubeSignature sig(dims); // make a cube-signature object
  vector<ColPerm> perms;
  breakPermByDim(perms, rho, sig);

  //  for (long i=0; i<(long)perms.size(); i++) { // debugging printouts
  //    Permut tmp;
  //    perms[i].makeExplicit(tmp);
  //    std::cerr << " prems["<<i<<"]="<<tmp<<endl;
  //  }

  layers.SetLength(trees.numLayers()); // allocate space

  // Go over the different permutations and build the corresponding layers
  long dimIdx =0;
  long frntLyr=0, backLyr=layers.length();
  for (long g=0; g<trees.numTrees(); g++) { // go over all the generators/trees
    const OneGeneratorTree &T = trees[g];

    // In each tree, go over all the leaves
    for (long leaf=T.firstLeaf(); leaf>=0; leaf=T.nextLeaf(leaf)) {
      const SubDimension& leafData = T[leaf].getData();

      // This leaf determines layers frntLyer...frntLey+frst.length()-1, and
      // if it isn't the middle then also backLyr-scnd.length()...backLyr-1

      // handle the first Benes network
      setLayers4Leaf(/*1st-layer-index=*/frntLyr, 
		     /*permutation    =*/perms[dimIdx],
		     /*Benes levels   =*/leafData.frstBenes,
		     /*generator index=*/T.getAuxKey(),
		     /*(size,good,e)  =*/leafData,
		     /*hypercube renaming permutation=*/trees.mapToCube());
      frntLyr += leafData.frstBenes.length(); // how many layers were used
      dimIdx++;

      if (leafData.scndBenes.length()>0) { // Also a second Benes network
	long dimIdx2 = perms.size() -dimIdx; // dimIdx was incremented above
	backLyr -= leafData.scndBenes.length();
	setLayers4Leaf(/*1st-layer-index=*/backLyr, 
		       /*permutation    =*/perms[dimIdx2],
		       /*Benes levels   =*/leafData.scndBenes,
		       /*generator index=*/T.getAuxKey(),
		       /*(size,good,e)  =*/leafData,
		       /*hypercube renaming permutation=*/trees.mapToCube());
      }
    }
  }
}
Example #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();
  }
}