Beispiel #1
0
DoubleCRT& DoubleCRT::Op(const DoubleCRT &other, Fun fun,
			 bool matchIndexSets)
{
  if (dryRun) return *this;

  if (&context != &other.context)
    Error("DoubleCRT::Op: incompatible objects");

  // Match the index sets, if needed
  if (matchIndexSets && !(map.getIndexSet() >= other.map.getIndexSet()))
    addPrimes(other.map.getIndexSet() / map.getIndexSet()); // This is expensive

  // If you need to mod-up the other, do it on a temporary scratch copy
  DoubleCRT tmp(context, IndexSet()); 
  const IndexMap<vec_long>* other_map = &other.map;
  if (!(map.getIndexSet() <= other.map.getIndexSet())){ // Even more expensive
    tmp = other;
    tmp.addPrimes(map.getIndexSet() / other.map.getIndexSet());
    other_map = &tmp.map;
  }

  const IndexSet& s = map.getIndexSet();
  long phim = context.zMStar.getPhiM();

  // add/sub/mul the data, element by element, modulo the respective primes
  for (long i = s.first(); i <= s.last(); i = s.next(i)) {
    long pi = context.ithPrime(i);
    vec_long& row = map[i];
    const vec_long& other_row = (*other_map)[i];
    
    for (long j = 0; j < phim; j++)
      row[j] = fun.apply(row[j], other_row[j], pi);
  }
  return *this;
}
Beispiel #2
0
// Uses the "active context", run-time error if it is NULL
SingleCRT::SingleCRT(): context(*activeContext)
{
  IndexSet s = IndexSet(0, context.numPrimes()-1);
  // FIXME: maybe the default index set should be determined by context?

  map.insert(s);
  // default constructor for ZZX creates the zero polynomial
}
Beispiel #3
0
// Uses the "active context", run-time error if it is NULL
SingleCRT::SingleCRT(const ZZX&poly)
: context(*activeContext)
{
  IndexSet s = IndexSet(0, context.numPrimes()-1);
  // FIXME: maybe the default index set should be determined by context?

  map.insert(s);
  *this = poly;           // convert polynomial to singleCRT representation
}
Beispiel #4
0
void IRRewriter::visit(const Length *op) {
  if (op->indexSet.getKind() == IndexSet::Set) {
    Expr set = rewrite(op->indexSet.getSet());
    if (set == op->indexSet.getSet()) {
      expr = op;
    }
    else {
      expr = Length::make(IndexSet(set));
    }
  } else {
    expr = op;
  }
}
Beispiel #5
0
// Find the IndexSet such that modDown to that set of primes makes the
// additive term due to rounding into the dominant noise term 
void Ctxt::findBaseSet(IndexSet& s) const
{
  if (getNoiseVar()<=0.0) { // an empty ciphertext
    s = context.ctxtPrimes;
    return;
  }

  assert(verifyPrimeSet());
  bool halfSize = context.containsSmallPrime();
  double addedNoise = log(modSwitchAddedNoiseVar())/2;
  double curNoise = log(getNoiseVar())/2;
  double firstNoise = context.logOfPrime(0);

  // remove special primes, if they are included in this->primeSet
  s = getPrimeSet();
  if (!s.disjointFrom(context.specialPrimes)) { 
    // scale down noise
    curNoise -= context.logOfProduct(context.specialPrimes);
    s.remove(context.specialPrimes);
  }

  if (curNoise<=2*addedNoise) return; // no need to mod down

  // if the first prime in half size, begin by removing it
  if (halfSize && s.contains(0)) {
    curNoise -= firstNoise;
    s.remove(0);
  }

  // while noise is larger than added term, scale down by the next prime
  while (curNoise>addedNoise && card(s)>1) {
    curNoise -= context.logOfPrime(s.last());
    s.remove(s.last());
  }

  if (halfSize) {
    // If noise is still too big, drop last big prime and insert half-size prime
    if (curNoise>addedNoise) {
      curNoise = firstNoise;
      s = IndexSet(0);
    } 
    // Otherwise check if you can add back the half-size prime
    else if (curNoise+firstNoise <= addedNoise) {
      curNoise += firstNoise;
      s.insert(0);
    }
  }

  if (curNoise>addedNoise && log_of_ratio()>-0.5)
    cerr << "Ctxt::findBaseSet warning: already at lowest level\n";
}
Beispiel #6
0
// Modulus-switching down
void Ctxt::modDownToLevel(long lvl)
{
  long currentLvl;
  IndexSet targetSet;
  IndexSet currentSet = primeSet & context.ctxtPrimes;
  if (context.containsSmallPrime()) {
    currentLvl = 2*card(currentSet);
    if (currentSet.contains(0))
      currentLvl--;  // first prime is half the size

    if (lvl & 1) {   // odd level, includes the half-size prime
      targetSet = IndexSet(0,(lvl-1)/2);
    } else {
      targetSet = IndexSet(1,lvl/2);
    }
  }
  else {
    currentLvl = card(currentSet);
    targetSet = IndexSet(0,lvl-1);    // one prime per level
  }

  // If target is not below the current level, nothing to do
  if (lvl >= currentLvl && currentSet==primeSet) return;

  if (lvl >= currentLvl) { // just remove the special primes
    targetSet = currentSet;
  }

  // sanity-check: interval does not contain special primes
  assert(targetSet.disjointFrom(context.specialPrimes));

  // may need to mod-UP to include the smallest prime
  if (targetSet.contains(0) && !currentSet.contains(0))
    modUpToSet(targetSet); // adds the primes in targetSet / primeSet

  modDownToSet(targetSet); // removes the primes in primeSet / targetSet
}
Beispiel #7
0
DoubleCRT::DoubleCRT(const ZZX& poly)
: context(*activeContext), map(new DoubleCRTHelper(*activeContext))
{
  IndexSet s = IndexSet(0, context.numPrimes()-1);
  // FIXME: maybe the default index set should be determined by context?

  map.insert(s);
  if (dryRun) return;

  // convert the integer polynomial to FFT representation modulo the primes
  for (long i = s.first(); i <= s.last(); i = s.next(i)) {
    const Cmodulus &pi = context.ithModulus(i);
    pi.FFT(map[i], poly); // reduce mod pi and store FFT image
  }
}
Beispiel #8
0
DoubleCRT::DoubleCRT(const FHEcontext &_context)
: context(_context), map(new DoubleCRTHelper(_context))
{
  IndexSet s = IndexSet(0, context.numPrimes()-1);
  // FIXME: maybe the default index set should be determined by context?

  map.insert(s);
  if (dryRun) return;

  long phim = context.zMStar.getPhiM();

  for (long i = s.first(); i <= s.last(); i = s.next(i)) {
    vec_long& row = map[i];
    for (long j = 0; j < phim; j++) row[j] = 0;
  }
}
Beispiel #9
0
//FIXME: both the reduction from powerful to the individual primes and
//  the CRT back to poly can be made more efficient
void PowerfulDCRT::powerfulToZZX(ZZX& poly, const Vec<ZZ>& powerful,
				 IndexSet set) const
{
  zz_pBak bak; bak.save(); // backup NTL's current modulus

  if (empty(set)) set = IndexSet(0, pConvVec.length()-1);

  clear(poly);
  //  poly.SetLength(powerful.length());
  ZZ product = conv<ZZ>(1L);
  for (long i = set.first(); i <= set.last(); i = set.next(i)) {
    pConvVec[i].restoreModulus();
    //    long newPrime = zz_p::modulus();

    HyperCube<zz_p> oneRowPwrfl(indexes.shortSig);
    conv(oneRowPwrfl.getData(), powerful); // reduce and convert to Vec<zz_p>

    zz_pX oneRowPoly;
    pConvVec[i].powerfulToPoly(oneRowPoly, oneRowPwrfl);
    CRT(poly, product, oneRowPoly);                   // NTL :-)
  }
  poly.normalize();
}
Beispiel #10
0
// If the IndexSet is omitted, default to all the primes in the chain
void PowerfulDCRT::ZZXtoPowerful(Vec<ZZ>& out, const ZZX& poly,
				 IndexSet set) const
{
  if (empty(set))
    set = IndexSet(0, pConvVec.length()-1);

  zz_pBak bak; bak.save(); // backup NTL's current modulus

  ZZ product = conv<ZZ>(1L);
  for (long i = set.first(); i <= set.last(); i = set.next(i)) {
    pConvVec[i].restoreModulus();
    long newPrime = zz_p::modulus();
    zz_pX oneRowPoly;
    conv(oneRowPoly, poly);  // reduce mod p and convert to zz_pX

    HyperCube<zz_p> oneRowPwrfl(indexes.shortSig);
    pConvVec[i].polyToPowerful(oneRowPwrfl, oneRowPoly);
    if (i == set.first()) // just copy
      conv(out, oneRowPwrfl.getData());
    else                  // CRT
      intVecCRT(out, product, oneRowPwrfl.getData(), newPrime); // in NumbTh
    product *= newPrime;
  }
}
#include "ExtraKnuckles.h"

const IndexSet pinkyIndices  = IndexSet() /IndexRange(21,41);
const IndexSet ringIndices   = IndexSet() /IndexRange(42,62);
const IndexSet middleIndices = IndexSet() /IndexRange(63,83);
const IndexSet indexIndices  = IndexSet() /IndexRange(84,104);

const IndexSet baseIndices = IndexSet() /IndexRange(0,5);
const IndexSet knuckleIndices = IndexSet() /IndexRange(3,11);
const IndexSet tipIndices = IndexSet() /IndexRange(9,20);

const IndexSet lowerGapIndices = IndexSet() /IndexRange(0,5);
const IndexSet upperGapIndices = IndexSet() /IndexRange(9,14);

const IndexSet blendIndices = IndexSet() /IndexRange(0,5);

const IndexSet allFingerIndices = IndexSet()
/IndexRange(21,41)
/IndexRange(42,62)
/IndexRange(63,83)
/IndexRange(84,104);

string ExtraKnuckles::getName() const {
    return "ExtraKnuckles";
}

void ExtraKnuckles::initialize(){
    ExtraKnuckles::initializeGui();
    this->gui->autoSizeToFitWidgets();
    
	final.load("models/mesh_ExtraKnuckles_final.ply");
Beispiel #12
0
int main(int argc, char *argv[]) 
{
  if (argc<2) {
    cout << "\nUsage: " << argv[0] << " L [c=2 w=64 k=80 d=1]" << endl;
    cout << "  L is the number of levels\n";
    cout << "  optional c is number of columns in the key-switching matrices (default=2)\n";
    cout << "  optional w is Hamming weight of the secret key (default=64)\n";
    cout << "  optional k is the security parameter (default=80)\n";
    cout << "  optional d specifies GF(2^d) arithmetic (default=1, must be <=16)\n";
    //    cout << "  k is the security parameter\n";
    //    cout << "  m determines the ring mod Phi_m(X)" << endl;
    cout << endl;
    exit(0);
  }
  cout.unsetf(ios::floatfield);
  cout.precision(4);

  long L = atoi(argv[1]);
  long c = 2;
  long w = 64;
  long k = 80;
  long d = 1;
  if (argc>2) c = atoi(argv[2]);
  if (argc>3) w = atoi(argv[3]);
  if (argc>4) k = atoi(argv[4]);
  if (argc>5) d = atoi(argv[5]);

  if (d>16) Error("d cannot be larger than 16\n");

  cout << "\nTesting FHE with parameters L="<<L
       << ", c="<<c<<", w="<<w<<", k="<<k<<", d="<<d<< endl;

  // get a lower-bound on the parameter N=phi(m):
  // 1. Empirically, we use ~20-bit small primes in the modulus chain (the main
  //    constraints is that 2m must divide p-1 for every prime p). The first
  //    prime is larger, a 40-bit prime. (If this is a 32-bit machine then we
  //    use two 20-bit primes instead.)
  // 2. With L levels, the largest modulus for "fresh ciphertexts" has size
  //          q0 ~ p0 * p^{L} ~ 2^{40+20L}
  // 3. We break each ciphertext into upto c digits, do each digit is as large
  //    as    D=2^{(40+20L)/c}
  // 4. The added noise variance term from the key-switching operation is
  //    c*N*sigma^2*D^2, and this must be mod-switched down to w*N (so it is
  //    on part with the added noise from modulus-switching). Hence the ratio
  //    P that we use for mod-switching must satisfy c*N*sigma^2*D^2/P^2<w*N,
  //    or    P > sqrt(c/w) * sigma * 2^{(40+20L)/c}
  // 5. With this extra P factor, the key-switching matrices are defined
  //    relative to a modulus of size
  //          Q0 = q0*P ~ sqrt{c/w} sigma 2^{(40+20L)(1+1/c)}
  // 6. To get k-bit security we need N>log(Q0/sigma)(k+110)/7.2, i.e. roughly
  //          N > (40+20L)(1+1/c)(k+110) / 7.2

  long ptxtSpace = 2;
  double cc = 1.0+(1.0/(double)c);
  long N = (long) ceil((pSize*L+p0Size)*cc*(k+110)/7.2);
  cout << "  bounding phi(m) > " << N << endl;

#if 0  // A small m for debugging purposes
  long m = 15;
#else
  // pre-computed values of [phi(m),m,d]
  long ms[][4] = {
    //phi(m)  m  ord(2) c_m*1000
    { 1176,  1247, 28,  3736},
    { 1936,  2047, 11,  3870},
    { 2880,  3133, 24,  3254},
    { 4096,  4369, 16,  3422},
    { 5292,  5461, 14,  4160},
    { 5760,  8435, 24,  8935},
    { 8190,  8191, 13,  1273},
    {10584, 16383, 14,  8358},
    {10752, 11441, 48,  3607},
    {12000, 13981, 20,  2467},
    {11520, 15665, 24, 14916},
    {14112, 18415, 28, 11278},
    {15004, 15709, 22,  3867},
    {15360, 20485, 24, 12767},
 // {16384, 21845, 16, 12798},
    {17208 ,21931, 24, 18387},
    {18000, 18631, 25,  4208},
    {18816, 24295, 28, 16360},
    {19200, 21607, 40, 35633},
    {21168, 27305, 28, 15407},
    {23040, 23377, 48,  5292},
    {24576, 24929, 48,  5612},
    {27000, 32767, 15, 20021},
    {31104, 31609, 71,  5149},
    {42336, 42799, 21,  5952},
    {46080, 53261, 24, 33409},
    {49140, 57337, 39,  2608},
    {51840, 59527, 72, 21128},
    {61680, 61681, 40,  1273},
    {65536, 65537, 32,  1273},
    {75264, 82603, 56, 36484},
    {84672, 92837, 56, 38520}
  };

#if 0

  for (long i = 0; i < 25; i++) {
    long m = ms[i][1];
    PAlgebra alg(m);
    alg.printout();
    cout << "\n";
    // compute phi(m) directly
    long phim = 0;
    for (long j = 0; j < m; j++)
      if (GCD(j, m) == 1) phim++;

    if (phim != alg.phiM()) cout << "ERROR\n";
  }

  exit(0);


#endif



  // find the first m satisfying phi(m)>=N and d | ord(2) in Z_m^*
  long m = 0;
  for (unsigned i=0; i<sizeof(ms)/sizeof(long[3]); i++) 
    if (ms[i][0]>=N && (ms[i][2] % d) == 0) {
      m = ms[i][1];
      c_m = 0.001 * (double) ms[i][3];
      break;
    }
  if (m==0) Error("Cannot support this L,d combination");
#endif
  //  m = 257;
  FHEcontext context(m);
#if 0
  context.stdev = to_xdouble(0.5); // very low error
#endif
  activeContext = &context; // Mark this as the "current" context

  context.zMstar.printout();
  cout << endl;


  // Set the modulus chain

#if 1
  // The first 1-2 primes of total p0size bits
  #if (NTL_SP_NBITS > p0Size)
    AddPrimesByNumber(context, 1, 1UL<<p0Size); // add a single prime
  #else
    AddPrimesByNumber(context, 2, 1UL<<(p0Size/2)); // add two primes
  #endif
#endif

  // The next L primes, as small as possible
  AddPrimesByNumber(context, L);

  ZZ productOfCtxtPrimes = context.productOfPrimes(context.ctxtPrimes);
  double productSize = context.logOfProduct(context.ctxtPrimes);

  // might as well test that the answer is roughly correct
  cout << "  context.logOfProduct(...)-log(context.productOfPrimes(...)) = "
       << productSize-log(productOfCtxtPrimes) << endl;

  // calculate the size of the digits

  context.digits.resize(c);
  IndexSet s1;
#if 0
  for (long i=0; i<c-1; i++) context.digits[i] = IndexSet(i,i);
  context.digits[c-1] = context.ctxtPrimes / IndexSet(0,c-2);
  AddPrimesByNumber(context, 2, 1, true);
#else
  double sizeSoFar = 0.0;
  double maxDigitSize = 0.0;
  if (c>1) {   // break ciphetext into a few digits
    double dsize = productSize/c;  // initial estimate
    double target = dsize-(pSize/3.0);
    long idx = context.ctxtPrimes.first();
    for (long i=0; i<c-1; i++) { // compute next digit
      IndexSet s;
      while (idx <= context.ctxtPrimes.last() && sizeSoFar < target) {
        s.insert(idx);
	sizeSoFar += log((double)context.ithPrime(idx));
	idx = context.ctxtPrimes.next(idx);
      }
      context.digits[i] = s;
      s1.insert(s);
      double thisDigitSize = context.logOfProduct(s);
      if (maxDigitSize < thisDigitSize) maxDigitSize = thisDigitSize;
      cout << "  digit #"<<i+1<< " " <<s << ": size " << thisDigitSize << endl;
      target += dsize;
    }
    IndexSet s = context.ctxtPrimes / s1; // all the remaining primes
    context.digits[c-1] = s;
    double thisDigitSize = context.logOfProduct(s);
    if (maxDigitSize < thisDigitSize) maxDigitSize = thisDigitSize;
    cout << "  digit #"<<c<< " " <<s << ": size " << thisDigitSize << endl;
  }
  else { 
    maxDigitSize = context.logOfProduct(context.ctxtPrimes);
    context.digits[0] = context.ctxtPrimes;
  }

  // Add primes to the chain for the P factor of key-switching
  double sizeOfSpecialPrimes 
    = maxDigitSize + log(c/(double)w)/2 + log(context.stdev *2);

  AddPrimesBySize(context, sizeOfSpecialPrimes, true);
#endif

  cout << "* ctxtPrimes: " << context.ctxtPrimes 
       << ", log(q0)=" << context.logOfProduct(context.ctxtPrimes) << endl;
  cout << "* specialPrimes: " << context.specialPrimes
       << ", log(P)=" << context.logOfProduct(context.specialPrimes) << endl;

  for (long i=0; i<context.numPrimes(); i++) {
    cout << "  modulus #" << i << " " << context.ithPrime(i) << endl;
  }
  cout << endl;

  setTimersOn();
  const ZZX& PhimX = context.zMstar.PhimX(); // The polynomial Phi_m(X)
  long phim = context.zMstar.phiM();         // The integer phi(m)
  FHESecKey secretKey(context);
  const FHEPubKey& publicKey = secretKey;

#if 0 // Debug mode: use sk=1,2
  DoubleCRT newSk(to_ZZX(2), context);
  long id1 = secretKey.ImportSecKey(newSk, 64, ptxtSpace);
  newSk -= 1;
  long id2 = secretKey.ImportSecKey(newSk, 64, ptxtSpace);
#else
  long id1 = secretKey.GenSecKey(w,ptxtSpace); // A Hamming-weight-w secret key
  long id2 = secretKey.GenSecKey(w,ptxtSpace); // A second Hamming-weight-w secret key
#endif

  ZZX zero = to_ZZX(0);
//  Ctxt zeroCtxt(publicKey);

  /******************************************************************/
  /**                      TESTS BEGIN HERE                       ***/
  /******************************************************************/


  cout << "ptxtSpace = " << ptxtSpace << 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 X;
  SetX(X);
  
#if 1
  // code for rotations...

  {
    GF2X::HexOutput = 1;
    
    const PAlgebra& al = context.zMstar;
    const PAlgebraModTwo& al2 = context.modTwo;

    long ngens = al.numOfGens();
    long nslots = al.NSlots();
    DoubleCRT tmp(context);

    vector< vector< DoubleCRT > > maskTable;

    maskTable.resize(ngens);
    for (long i = 0; i < ngens; i++) {
      if (i==0 && al.SameOrd(i)) continue;
      long ord = al.OrderOf(i);
      maskTable[i].resize(ord+1, tmp);
      for (long j = 0; j <= ord; j++) {
        // initialize the mask that is 1 whenever
        // the ith coordinate is at least j

        vector<GF2X> maps, alphas, betas;

        al2.mapToSlots(maps, G); // Change G to X to get bits in the slots
        alphas.resize(nslots);

        for (long k = 0; k < nslots; k++) 
          if (coordinate(al, i, k) >= j)
               alphas[k] = 1;
          else alphas[k] = 0;

       GF2X ptxt;
       al2.embedInSlots(ptxt, alphas, maps);

       // Sanity-check, make sure that encode/decode works as expected
       al2.decodePlaintext(betas, ptxt, G, maps);
       for (long k = 0; k < nslots; k++) {
	 if (alphas[k] != betas[k]) {
	   cout << " Mask computation failed, i="<<i<<", j="<<j<<"\n";
	   return 0;
	 }
       }
       maskTable[i][j] = to_ZZX(ptxt);
      }
    }

  vector<GF2X> maps;
  al2.mapToSlots(maps, G);

  vector<GF2X> alphas(nslots);
  for (long i=0; i < nslots; i++) 
    random(alphas[i], 8); // random degree-7 polynomial mod 2

  for (long amt = 0; amt < 20; amt++) {

    cout << ".";

     GF2X ptxt;
     al2.embedInSlots(ptxt, alphas, maps);

     DoubleCRT pp(context);
     pp = to_ZZX(ptxt);

     rotate(pp, amt, maskTable);

     GF2X ptxt1 = to_GF2X(to_ZZX(pp));

     vector<GF2X> betas;
     al2.decodePlaintext(betas, ptxt1, G, maps);

     for (long i = 0; i < nslots; i++) {
       if (alphas[i] != betas[(i+amt)%nslots]) {
	 cout << " amt="<<amt<<" oops\n";
          return 0;
       }
     }
   }

   cout << "\n";

#if 0
  long ord0 = al.OrderOf(0);

  for (long i = 0; i < nslots; i++) {
    cout << alphas[i] << " ";
    if ((i+1) % (nslots/ord0) == 0) cout << "\n";
  }
 
  cout << "\n\n";
  cout << betas.size() << "\n";

  for (long i = 0; i < nslots; i++) {
    cout << betas[i] << " ";
    if ((i+1) % (nslots/ord0) == 0) cout << "\n";
  }
#endif


  return 0;
  

  }


#endif

  // an initial sanity check on noise estimates,
  // comparing the estimated variance to the actual average
  cout << "pk:"; checkCiphertext(publicKey.pubEncrKey, zero, secretKey);

  ZZX ptxt[6]; // first four are plaintext, last two are constants
  std::vector<Ctxt> ctxt(4, Ctxt(publicKey));

  // Initialize the plaintext and constants to random 0-1 polynomials
  for (size_t j=0; j<6; j++) {
    ptxt[j].rep.SetLength(phim);
    for (long i = 0; i < phim; i++)
      ptxt[j].rep[i] = RandomBnd(ptxtSpace);
    ptxt[j].normalize();

    if (j<4) { 
      publicKey.Encrypt(ctxt[j], ptxt[j], ptxtSpace);
      cout << "c"<<j<<":"; checkCiphertext(ctxt[j], ptxt[j], secretKey);
    }
  }

  // perform upto 2L levels of computation, each level computing:
  //    1. c0 += c1
  //    2. c1 *= c2            // L1' = max(L1,L2)+1
  //    3. c1.reLinearlize
  //    4. c2 *= p4
  //    5. c2.automorph(k)     // k is the first generator of Zm^* /(2)
  //    6. c2.reLinearlize
  //    7. c3 += p5
  //    8. c3 *= c0            // L3' = max(L3,L0,L1)+1
  //    9. c2 *= c3            // L2' = max(L2,L0+1,L1+1,L3+1)+1
  //   10. c0 *= c0            // L0' = max(L0,L1)+1
  //   11. c0.reLinearlize
  //   12. c2.reLinearlize
  //   13. c3.reLinearlize
  //
  // The levels of the four ciphertexts behave as follows:
  // 0, 0, 0, 0  =>  1, 1, 2, 1  =>  2, 3, 3, 2
  //             =>  4, 4, 5, 4  =>  5, 6, 6, 5
  //             =>  7, 7, 8, 7  =>  8,,9, 9, 10  => [...]
  //
  // We perform the same operations on the plaintext, and after each operation
  // we check that decryption still works, and print the curretn modulus and
  // noise estimate. We stop when we get the first decryption error, or when
  // we reach 2L levels (which really should not happen).

  zz_pContext zzpc;
  zz_p::init(ptxtSpace);
  zzpc.save();
  const zz_pXModulus F = to_zz_pX(PhimX);
  long g = context.zMstar.ZmStarGen(0); // the first generator in Zm*
  zz_pX x2g(g, 1);
  zz_pX p2;

  // generate a key-switching matrix from s(X^g) to s(X)
  secretKey.GenKeySWmatrix(/*powerOfS= */  1,
			   /*powerOfX= */  g,
			   0, 0,
			   /*ptxtSpace=*/  ptxtSpace);

  // generate a key-switching matrix from s^2 to s
  secretKey.GenKeySWmatrix(/*powerOfS= */  2,
			   /*powerOfX= */  1,
			   0, 0,
			   /*ptxtSpace=*/  ptxtSpace);

  // generate a key-switching matrix from s^3 to s
  secretKey.GenKeySWmatrix(/*powerOfS= */  3,
			   /*powerOfX= */  1,
			   0, 0,
			   /*ptxtSpace=*/  ptxtSpace);

  for (long lvl=0; lvl<2*L; lvl++) {
    cout << "=======================================================\n";
    ctxt[0] += ctxt[1];
    ptxt[0] += ptxt[1];
    PolyRed(ptxt[0], ptxtSpace, true);
    cout << "c0+=c1:  "; checkCiphertext(ctxt[0], ptxt[0], secretKey);

    ctxt[1].multiplyBy(ctxt[2]);
    ptxt[1] = (ptxt[1] * ptxt[2]) % PhimX;
    PolyRed(ptxt[1], ptxtSpace, true);
    cout << "c1*=c2:  "; checkCiphertext(ctxt[1], ptxt[1], secretKey);

    ctxt[2].multByConstant(ptxt[4]);
    ptxt[2] = (ptxt[2] * ptxt[4]) % PhimX;
    PolyRed(ptxt[2], ptxtSpace, true);
    cout <<  "c2*=p4:  "; checkCiphertext(ctxt[2], ptxt[2], secretKey);

    ctxt[2] >>= g;
    zzpc.restore();
    p2 = to_zz_pX(ptxt[2]);
    CompMod(p2, p2, x2g, F);
    ptxt[2] = to_ZZX(p2);
    cout << "c2>>="<<g<<":"; checkCiphertext(ctxt[2], ptxt[2], secretKey);

    ctxt[2].reLinearize();
    cout << "c2.relin:"; checkCiphertext(ctxt[2], ptxt[2], secretKey);

    ctxt[3].addConstant(ptxt[5]);
    ptxt[3] += ptxt[5];
    PolyRed(ptxt[3], ptxtSpace, true);
    cout << "c3+=p5:  "; checkCiphertext(ctxt[3], ptxt[3], secretKey);

    ctxt[3].multiplyBy(ctxt[0]);
    ptxt[3] = (ptxt[3] * ptxt[0]) % PhimX;
    PolyRed(ptxt[3], ptxtSpace, true);
    cout << "c3*=c0:  ";    checkCiphertext(ctxt[3], ptxt[3], secretKey);

    ctxt[0].square();
    ptxt[0] = (ptxt[0] * ptxt[0]) % PhimX;
    PolyRed(ptxt[0], ptxtSpace, true);
    cout << "c0*=c0:  ";    checkCiphertext(ctxt[0], ptxt[0], secretKey);

    ctxt[2].multiplyBy(ctxt[3]);
    ptxt[2] = (ptxt[2] * ptxt[3]) % PhimX;
    PolyRed(ptxt[2], ptxtSpace, true);
    cout << "c2*=c3:  ";    checkCiphertext(ctxt[2], ptxt[2], secretKey);
  }
  /******************************************************************/
  /**                       TESTS END HERE                        ***/
  /******************************************************************/
  cout << endl;
  return 0;
}
#include "SwellingFingers.h"

const IndexSet pinkyIndices  = IndexSet() /IndexRange(21,41);
const IndexSet ringIndices   = IndexSet() /IndexRange(42,62);
const IndexSet middleIndices = IndexSet() /IndexRange(63,83);
const IndexSet indexIndices  = IndexSet() /IndexRange(84,104);
const IndexSet thumbIndices  = IndexSet() /IndexRange(0,20);

const IndexSet allFingerIndices = IndexSet()
/IndexRange(21,41)
/IndexRange(42,62)
/IndexRange(63,83)
/IndexRange(84,104)
/IndexRange(0,20);

const IndexSet knuckeIndices = IndexSet() /IndexRange(3,11);

string SwellingFingers::getName() const {
    return "SwellingFingers";
}

void SwellingFingers::initialize(){
    
    timer = 0.0f;
    
    pulseSpeed = 7.0f;
    pulseGapWidth = 0.7f;
    
    swellAmt = 0.0f;
    swellPower = 0.03f;
    
Beispiel #14
0
static void Sample(This *t, Region *region)
{
  csize_t setsize = SetSize;
  creal vol = ldexp(1., -region->div);

  real *x = t->frame, *f = x + t->rule.n*t->ndim;
  Set *first = t->rule.first, *last = t->rule.last, *s;
  Bounds *b, *B = region->bounds + t->ndim;
  Result *result = RegionResult(region), *res, *Res = result + t->ncomp;
  creal *errcoeff = t->rule.errcoeff;
  creal ratio = Sq(IndexSet(first,2)->gen[0]/
                   IndexSet(first,1)->gen[0]);

  ccount offset = 2*t->ndim*t->ncomp;
  count dim, rul, n, maxdim = 0;
  real maxrange = 0;

  for( b = region->bounds, dim = 0; b < B; ++b, ++dim ) {
    creal range = b->upper - b->lower;
    if( range > maxrange ) {
      maxrange = range;
      maxdim = dim;
    }
  }

  for( s = first; s <= last; NextSet(s) )
    if( s->n ) x = ExpandFS(t, region->bounds, s->gen, x);

  DoSample(t, t->rule.n, t->frame, f);

  for( res = result; res < Res; ++res ) {
    real sum[nrules];
    creal *f1 = f;
    creal base = *f1*2*(1 - ratio);
    real maxdiff = 0;
    count bisectdim = maxdim;

    for( dim = 0; dim < t->ndim; ++dim ) {
      creal *fp = f1 + t->ncomp;
      creal *fm = fp + t->ncomp;
      creal fourthdiff = fabs(base +
        ratio*(fp[0] + fm[0]) - (fp[offset] + fm[offset]));
      f1 = fm;
      if( fourthdiff > maxdiff ) {
        maxdiff = fourthdiff;
        bisectdim = dim;
      }
    }
    res->bisectdim = bisectdim;

    f1 = f++;
    Zap(sum);
    for( s = first; s <= last; NextSet(s) )
      for( n = s->n; n; --n ) {
        creal fun = *f1;
        f1 += t->ncomp;
        for( rul = 0; rul < nrules; ++rul )
          sum[rul] += fun*s->weight[rul];
      }

    /* Search for the null rule, in the linear space spanned by two
       successive null rules in our sequence, which gives the greatest
       error estimate among all normalized (1-norm) null rules in this
       space. */

    for( rul = 1; rul < nrules - 1; ++rul ) {
      real maxerr = 0;
      for( s = first; s <= last; NextSet(s) )
        maxerr = Max(maxerr,
          fabs(sum[rul + 1] + s->scale[rul]*sum[rul])*s->norm[rul]);
      sum[rul] = maxerr;
    }

    res->avg = vol*sum[0];
    res->err = vol*(
      (errcoeff[0]*sum[1] <= sum[2] && errcoeff[0]*sum[2] <= sum[3]) ?
        errcoeff[1]*sum[1] :
        errcoeff[2]*Max(Max(sum[1], sum[2]), sum[3]) );
  }

  if( VERBOSE > 2 ) {
    Vector(char, out, 64*NDIM + 128*NCOMP);
    char *oe = out;
    count comp;
    cchar *msg = "\nRegion (" REALF ") - (" REALF ")";

    for( b = region->bounds; b < B; ++b ) {
      oe += sprintf(oe, msg, b->lower, b->upper);
      msg = "\n       (" REALF ") - (" REALF ")";
    }

    for( res = result, comp = 0; res < Res; ++res )
      oe += sprintf(oe, "\n[" COUNT "] "
        REAL " +- " REAL, ++comp, res->avg, res->err);

    Print(out);
  }
Beispiel #15
0
void DMRecon::processFeatures()
{
    progress.status = RECON_FEATURES;
    if (progress.cancelled)  return;
    SingleViewPtr refV = views[settings.refViewNr];
    mve::BundleFile::FeaturePoints const & features = bundle->get_points();

    /* select features that should be processed:
       take features only from master view for the moment */
    std::cout<<"Started to process "<<features.size()<<" features."<<std::endl;
    log<<"Started to process "<<features.size()<<" features."<<std::endl;
    size_t success = 0, processed = 0;

    for (size_t i = 0; i < features.size() && !progress.cancelled; ++i)
    {
        bool useFeature = false;
        if (features[i].contains_view_id(settings.refViewNr))
            useFeature = true;
        else {
            IndexSet::const_iterator id = neighViews.begin();
            while (id != neighViews.end()) {
                if (features[i].contains_view_id(*id)) {
                    useFeature = true;
                    break;
                }
                ++id;
            }
        }
        if (!useFeature)
            continue;
        math::Vec3f featPos(features[i].pos);
        if (!refV->pointInFrustum(featPos)) {
            continue;
        }
        math::Vec2f pixPosF = refV->worldToScreen(featPos);
        int x = round(pixPosF[0]);
        int y = round(pixPosF[1]);
        float initDepth = (featPos - refV->camPos).norm();
        PatchOptimization patch(views, settings, x, y, initDepth,
            0.f, 0.f, neighViews, IndexSet());
        patch.doAutoOptimization();
        ++processed;
        float conf = patch.computeConfidence();
        size_t index = y * this->width + x;
        if (conf == 0) {
            continue;
        }

        // optimization was successful:
        ++success;
        float depth = patch.getDepth();
        math::Vec3f normal = patch.getNormal();
        if (refV->confImg->at(index) < conf) {
            if (refV->confImg->at(index) <= 0) {
                ++progress.filled;
            }
            refV->depthImg->at(index) = depth;
            refV->normalImg->at(index, 0) = normal[0];
            refV->normalImg->at(index, 1) = normal[1];
            refV->normalImg->at(index, 2) = normal[2];
            refV->dzImg->at(index, 0) = patch.getDzI();
            refV->dzImg->at(index, 1) = patch.getDzJ();
            refV->confImg->at(index) = conf;
            QueueData tmpData;
            tmpData.confidence = conf;
            tmpData.depth = depth;
            tmpData.dz_i = patch.getDzI();
            tmpData.dz_j = patch.getDzJ();
            tmpData.localViewIDs = patch.getLocalViewIDs();
            tmpData.x = x;
            tmpData.y = y;
            prQueue.push(tmpData);
        }
    }
    std::cout << "Processed " << processed << " features, from which "
              << success << " succeeded optimization." << std::endl;
    log << "Processed " << processed << " features, from which "
          << success << " succeeded optimization." << std::endl;
}