Ejemplo n.º 1
0
int main(int argc, char *argv[]) {
    long m, p, r, L, R;
    ArgMapping argmap;
	MDL::Timer timer;
    argmap.arg("m", m, "m");
    argmap.arg("L", L, "L");
    argmap.arg("p", p, "p");
    argmap.arg("r", r, "r");
    argmap.arg("R", R, "R");
    argmap.parse(argc, argv);
	timer.start();
    FHEcontext context(m, p, r);
    buildModChain(context, L);
    FHESecKey sk(context);
    sk.GenSecKey(64);
    addSome1DMatrices(sk);
    FHEPubKey pk = sk;

    auto G       = context.alMod.getFactorsOverZZ()[0];
    EncryptedArray ea(context, G);
	timer.end();
    printf("slots %ld\n", ea.size());
	printf("Key Gen %f\n", timer.second());
    auto data = load_csv("adult.data", R);
    benchmark(ea, pk, sk, data);
}
Ejemplo n.º 2
0
void dump_FHE_setting_to_file(const std::string& file, long k,
                              long m, long p,
                              long r, long L)
{
    FHEcontext context(m, p, r);

    FindM(k, L, 2, p, 0, 1, m, true);
    buildModChain(context, L);
    FHESecKey sk(context);
    sk.GenSecKey(64);
    addSome1DMatrices(sk);
    std::fstream out;
    out.open(file, std::ios::out);

    if (!out.is_open()) {
        std::cerr << "Can not open file: " << file << std::endl;
        return;
    }
    out << context;
    out << sk;
    out.close();
}
int main(){
    
    cout << "This experiment check for different values of parameters, how much time it takes to encrypt and decrypt a \"full\" matrix (nslots*nslots), and multply 2 encrypted matrices\nAlso check for what size of matrices, the multiplication in the server on the encrypted data is faster than for the user than do all the work on his machine. Using this formula: N > n(P)*(2*Enc(P)+Dec(P)) when:\nP is the parameters\nn(P) is the nslots value for these values\nEnc(P) and Dec(P) is the time it takes to encrypt and decrypt the matrics in size nslots*nslots\nNOTE: this formula don't take into account the time it takes to send and recieve the data to and from the server, and the time it took to the server to do the actual multiplication\n" << endl;
    
    /*
    long m=0, r=1; // Native plaintext space
    int p = 65539; // Computations will be 'modulo p'
    long L=16;          // Levels
    long c=3;           // Columns in key switching matrix
    long w=64;          // Hamming weight of secret key
    long d=0;
    long s = 0;  //minimum number of slots  [ default=0 ]
    long security = 128;*/
    long m, r, p, L, c, w, s, d, security, enc1, enc2, dec, encMul, ptMul, recommended;
    char tempChar;
    bool toEncMult = false, toPrint = false, debugMul = false, toSave = false;
    
    //Scan parameters
    
    cout << "Enter HElib's keys paramter. Enter zero for the recommended values" << endl;
    
    while(true){
        cout << "Enter the field of the computations (a prime number): ";
        cin >> p;
        if(isPrime(p))
            break;
        cout << "Error! p must be a prime number! " << endl;
    }
    while(true){
        recommended = 1;
        cout << "Enter r (recommended " << recommended <<"): ";
        cin >> r;
        if(r == 0)
            r = recommended;
        if(r > 0)
            break;
        cout << "Error! r must be a positive number!" << endl;
    }
    while(true){
        recommended = 16;
        cout << "Enter L (recommended " << recommended <<"): ";
        cin >> L;
        if(L == 0)
            L = recommended;
        if(L > 1)
            break;
        cout << "Error! L must be a positive number!" << endl;
    }
    while(true){
        recommended = 3;
        cout << "Enter c (recommended " << recommended <<"): ";
        cin >> c;
        if(c == 0)
            c = recommended;
        if(c > 1)
            break;
        cout << "Error! c must be a positive number!" << endl;
    }
    while(true){
        recommended = 64;
        cout << "Enter w (recommended " << recommended <<"): ";
        cin >> w;
        if(w == 0)
            w = recommended;
        if(w > 1)
            break;
        cout << "Error! w must be a positive number!" << endl;
    }
    while(true){
        recommended = 0;
        cout << "Enter d (recommended " << recommended <<"): ";
        cin >> d;
        if(d >= 0)
            break;
        cout << "Error! d must be a positive or zero!" << endl;
    }
    while(true){
        recommended = 0;
        cout << "Enter s (recommended " << recommended <<"): ";
        cin >> s;
        if(s >= 0)
            break;
        cout << "Error! s must be a positive or zero!" << endl;
    }
    while(true){
        recommended = 128;
        cout << "Enter security (recommended " << recommended << "): ";
        cin >> security;
        if(security == 0)
            security = recommended;
        if(security >= 1)
            break;
        cout << "Error! security must be a positive number " << endl;
    }
    
    ZZX G;
    m = FindM(security,L,c,p, d, s, 0);
    FHEcontext context(m, p, r);
    // initialize context
    buildModChain(context, L, c);
    // modify the context, adding primes to the modulus chain
    FHESecKey secretKey(context);
    // construct a secret key structure
    const FHEPubKey& publicKey = secretKey;
    // an "upcast": FHESecKey is a subclass of FHEPubKey
    
    //if(0 == d)
    G = context.alMod.getFactorsOverZZ()[0];
    
    secretKey.GenSecKey(w);
    // actually generate a secret key with Hamming weight w
    
    addSome1DMatrices(secretKey);
    EncryptedArray ea(context, G);
    // constuct an Encrypted array object ea that is
    // associated with the given context and the polynomial G
    
    long nslots = ea.size(), field = power(p,r);
    cout << "nslots: " << nslots << endl ;
    cout << "Computations will be modulo " << field << endl;
    cout << "m: " << m << endl;
    
    unsigned int sz1, sz2, sz3;
    while(true){
        cout << "Enter number of rows in the first matrix: ";
        cin >> sz1;
        if(sz1 > 1 && sz1 <= nslots)
            break;
        cout << "Error! the value must be between 1 to " << nslots << "!" << endl;
    }
    while(true){
        cout << "Enter number of rows in the first matrix: ";
        cin >> sz2;
        if(sz1 > 2 && sz2 <= nslots)
            break;
        cout << "Error! the value must be between 1 to " << nslots << "!" << endl;
    }
    while(true){
        cout << "Enter number of rows in the first matrix: ";
        cin >> sz3;
        if(sz1 > 3 && sz3 <= nslots)
            break;
        cout << "Error! the value must be between 1 to " << nslots << "!" << endl;
    }
    PTMatrix PTmat1(MatSize(sz1, sz2),field), PTmat2(MatSize(sz2, sz3), field);  //random matrix in size origSize1
    
    while(true){
        cout << "To multiply the encrypted matrices? Not affecting the formula, just for statistic" << endl;
        cout << "Y for yes, N for no: ";
        cin >> tempChar;
        if(tempChar == 'Y' || tempChar == 'y'){
            toEncMult = true;
            break;
        }
        if(tempChar == 'N' || tempChar == 'n'){
            toEncMult = false;
            break;
        }
        cout << "Error! invalid input!" << endl;
    }
    while(toEncMult){
        cout << "Debug the multiplication steps?\nY for yesm N for no :";
        cin >> tempChar;
        if(tempChar == 'Y' || tempChar == 'y'){
            debugMul = true;
            break;
        }
        if(tempChar == 'N' || tempChar == 'n'){
            debugMul = false;
            break;
        }
        cout << "Error! invalid input!" << endl;
    }
    while(true){
        cout << "Print the matrices?" << endl;
        cout << "Y for yes, N for no: ";
        cin >> tempChar;
        if(tempChar == 'Y' || tempChar == 'y'){
            toPrint = true;
            break;
        }
        if(tempChar == 'N' || tempChar == 'n'){
            toPrint = false;
            break;
        }
        cout << "Error! invalid input!" << endl;
    }
    while(true){
        cout << "Save the matrices?" << endl;
        cout << "Y for yes, N for no: ";
        cin >> tempChar;
        if(tempChar == 'Y' || tempChar == 'y'){
            toSave = true;
            break;
        }
        if(tempChar == 'N' || tempChar == 'n'){
            toSave = false;
            break;
        }
        cout << "Error! invalid input!" << endl;
    }
    if(toPrint){
        PTmat1.print();
        PTmat2.print();
    }
    if(toSave){
        ofstream out_mat1("mat1.txt"), out_mat2("mat2.txt");
        PTmat1.save(out_mat1);
        PTmat2.save(out_mat2);
        out_mat1.close(); out_mat2.close();
    }
    
    //encryptions
    cout << "Encrypting the first matrices..." << endl;
    resetTimers();
    EncryptedMatrix encMat1 = PTmat1.encrypt(ea, publicKey);
    enc1 = stopTimers("to encrypt the first matrix");
    cout << "Encrypting the second matrices..." << endl;
    resetTimers();
    EncryptedMatrix encMat2 = PTmat2.encrypt(ea, publicKey);
    enc2 = stopTimers("to encrypt the second matrix");
    
    //multiplication
    if(toEncMult){
        cout << "Multiplying the matrices..." << endl;
        resetTimers();
        if(debugMul)
            encMat1 = encMat1.debugMul(encMat2); //same as encMat1 *= encMat2 but print progress update
        else
            encMat1 *= encMat2;
        encMul = stopTimers("to multiply the matrices");
    }
    
    cout << "Decrypting the result..." << endl;
    resetTimers();
    PTMatrix res = encMat1.decrypt(ea, secretKey);
    dec = stopTimers("to decrypt the result");
    if(toPrint)
        res.print("Solution: ");
    
    resetTimers();
    PTMatrix PTres = PTmat1.mulWithMod(PTmat2,field); //like (PTmat1*PTmat2)%p but do modulu after each multiplication to avoid overflow
    ptMul = stopTimers("to multiply the regular matrices");
    
    if(toSave){
        ofstream out_res("mat_res.txt"), out_ptRes("mat_pt_res.txt");
        res.save(out_res);
        PTres.save(out_ptRes);
        out_res.close(); out_ptRes.close();
    }
    
    //PTres.print("pt result: ");
    
    cout << "\n\n----------------------------------------Summary------------------------------ " << endl;
    cout << "p: " << p << ", r: " << r << ", L: " << L << ", c: " << c << ", w: " << w << ", d: " << d << ", s: " << s << ", security: " << security << endl;
    cout << "nslots: " << nslots << "\nm: " << m << endl;
    cout << "It took " << enc1 << " clock ticks to encrypt the first matrix" << endl;
    cout << "It took " << enc2 << " clock ticks to encrypt the second matrix" << endl;
    cout << "It took " << dec << " clock ticks to decrypt the result" << endl;
    cout << "It took " << ptMul << " clock ticks to multiply the regular matrices" << endl;
    if(toEncMult){
        cout << "It took " << encMul << " clock ticks to multiply the encrypted matrices" << endl;
        cout << "is correct? " << (res==PTres) << endl;
    }
    long N = nslots*(enc1+enc2+dec)/ptMul;
    
    cout << "N should be greater than " << N << endl;

    return 0;
}
Ejemplo n.º 4
0
void  TestIt(long c, long k, long w, long L, long m, long n)
{
  FHEcontext context(m, 2, 1); // p = 2, r = 1
  long d = context.zMStar.getOrdP(); 

  buildModChain(context, L, c);

  context.zMStar.printout();
  cerr << endl;
#ifdef DEBUG
  cerr << context << endl;
#endif

  FHESecKey secretKey(context);
  const FHEPubKey& publicKey = secretKey;
  secretKey.GenSecKey(w); // A Hamming-weight-w secret key


  ZZX G;

  G = makeIrredPoly(2, d); 
  // G = context.alMod.getFactorsOverZZ()[0];

  cerr << "generating key-switching matrices... ";
  addFrbMatrices(secretKey);
  addSome1DMatrices(secretKey);
  cerr << "done\n";


  cerr << "computing masks and tables for rotation...";
  EncryptedArray ea(context, G);
  cerr << "done\n";



  long nslots = ea.size();

  if (n <= 0 || n > d) n = d;
  


  vector<ZZX> v;
  v.resize(nslots);
  for (long i = 0; i < nslots; i++) {
    GF2X f;
    random(f, n);
    conv(v[i], f);
  }

  printBits(v, n);

  Ctxt ctxt(publicKey);
  ea.encrypt(ctxt, publicKey, v);
  // ctxt encrypts a vector where each slots is a random
  // polynomial of degree < n


  Ctxt* res[n];
  for (long j = 0; j < n; j++) res[j] = new Ctxt(publicKey); // allocate

  resetAllTimers();

  incrementalZeroTest(res, ea, ctxt, n);

  for (long j = 0; j < n; j++) {
    vector<ZZX> v1;
    ea.decrypt(*res[j], secretKey, v1); 
    printBits(v1, n);
  }

  for (long j = 0; j < n; j++) delete res[j]; // cleanup
}
Ejemplo n.º 5
0
int main(int argc, char *argv[]) 
{

  // Commandline setup

  ArgMapping amap;

  long m=16;
  long r=8;
  long L=0;
  double epsilon=0.01; // Accepted accuracy
  long R=1;
  long seed=0;
  bool debug = false;

  amap.arg("m", m, "Cyclotomic index");
  amap.note("e.g., m=1024, m=2047");
  amap.arg("r", r, "Bits of precision");
  amap.arg("R", R, "number of rounds");
  amap.arg("L", L, "Number of bits in modulus", "heuristic");
  amap.arg("ep", epsilon, "Accepted accuracy");
  amap.arg("seed", seed, "PRG seed");
  amap.arg("verbose", verbose, "more printouts");
  amap.arg("debug", debug, "for debugging");

  amap.parse(argc, argv);

  if (seed)
    NTL::SetSeed(ZZ(seed));

  if (R<=0) R=1;
  if (R<=2)
    L = 100*R;
  else
    L = 220*(R-1);

  if (verbose) {
    cout << "** m="<<m<<", #rounds="<<R<<", |q|="<<L
         << ", epsilon="<<epsilon<<endl;
  }
  epsilon /= R;
  try{

    // FHE setup keys, context, SKMs, etc

    FHEcontext context(m, /*p=*/-1, r);
    context.scale=4;
    buildModChain(context, L, /*c=*/2);

    FHESecKey secretKey(context);
    secretKey.GenSecKey(); // A +-1/0 secret key
    addSome1DMatrices(secretKey); // compute key-switching matrices

    const FHEPubKey publicKey = secretKey;
    const EncryptedArrayCx& ea = context.ea->getCx();

    if (verbose) {
      ea.getPAlgebra().printout();
      cout << "r = " << context.alMod.getR() << endl;
      cout << "ctxtPrimes="<<context.ctxtPrimes
           << ", specialPrimes="<<context.specialPrimes<<endl<<endl;
    }
    if (debug) {
        dbgKey = & secretKey;
        dbgEa = (EncryptedArray*) context.ea;
    }

    // Run the tests.
    testBasicArith(publicKey, secretKey, ea, epsilon);
    testComplexArith(publicKey, secretKey, ea, epsilon);
    testRotsNShifts(publicKey, secretKey, ea, epsilon);
    testGeneralOps(publicKey, secretKey, ea, epsilon*R, R);
  } 
  catch (exception& e) {
    cerr << e.what() << endl;
    cerr << "***Major FAIL***" << endl;  
  }

  return 0;
}
Ejemplo n.º 6
0
// Testing the I/O of the important classes of the library
// (context, keys, ciphertexts).
int main(int argc, char *argv[])
{
  ArgMapping amap;

  long r=1;
  long p=2;
  long c = 2;
  long w = 64;
  long L = 5;
  long mm=0;
  amap.arg("p", p, "plaintext base");
  amap.arg("r", r,  "lifting");
  amap.arg("c", c, "number of columns in the key-switching matrices");
  amap.arg("m", mm, "cyclotomic index","{31,127,1023}");
  amap.parse(argc, argv);

  bool useTable = (mm==0 && p==2);
  long ptxtSpace = power_long(p,r);
  long numTests = useTable? N_TESTS : 1;

  std::unique_ptr<FHEcontext> contexts[numTests];
  std::unique_ptr<FHESecKey> sKeys[numTests];
  std::unique_ptr<Ctxt> ctxts[numTests];
  std::unique_ptr<EncryptedArray> eas[numTests];
  vector<ZZX> ptxts[numTests];

  // first loop: generate stuff and write it to cout

  // open file for writing
  {fstream keyFile("iotest.txt", fstream::out|fstream::trunc);
   assert(keyFile.is_open());
  for (long i=0; i<numTests; i++) {
    long m = (mm==0)? ms[i][1] : mm;

    cout << "Testing IO: m="<<m<<", p^r="<<p<<"^"<<r<<endl;

    Vec<long> mvec(INIT_SIZE,2);
    mvec[0] = ms[i][4];  mvec[1] = ms[i][5];
    vector<long> gens(2);
    gens[0] = ms[i][6];  gens[1] = ms[i][7];
    vector<long> ords(2);
    ords[0] = ms[i][8];  ords[1] = ms[i][9];

    if (useTable && gens[0]>0)
      contexts[i].reset(new FHEcontext(m, p, r, gens, ords));
    else
      contexts[i].reset(new FHEcontext(m, p, r));
    contexts[i]->zMStar.printout();

    buildModChain(*contexts[i], L, c);  // Set the modulus chain
    if (mm==0 && m==1023) contexts[i]->makeBootstrappable(mvec);

    // Output the FHEcontext to file
    writeContextBase(keyFile, *contexts[i]);
    writeContextBase(cout, *contexts[i]);
    keyFile << *contexts[i] << endl;

    sKeys[i].reset(new FHESecKey(*contexts[i]));
    const FHEPubKey& publicKey = *sKeys[i];
    sKeys[i]->GenSecKey(w,ptxtSpace); // A Hamming-weight-w secret key
    addSome1DMatrices(*sKeys[i]);// compute key-switching matrices that we need
    eas[i].reset(new EncryptedArray(*contexts[i]));

    long nslots = eas[i]->size();

    // Output the secret key to file, twice. Below we will have two copies
    // of most things.
    keyFile << *sKeys[i] << endl;;
    keyFile << *sKeys[i] << endl;;

    vector<ZZX> b;
    long p2r = eas[i]->getContext().alMod.getPPowR();
    ZZX poly = RandPoly(0,to_ZZ(p2r)); // choose a random constant polynomial
    eas[i]->decode(ptxts[i], poly);

    ctxts[i].reset(new Ctxt(publicKey));
    eas[i]->encrypt(*ctxts[i], publicKey, ptxts[i]);
    eas[i]->decrypt(*ctxts[i], *sKeys[i], b);
    assert(ptxts[i].size() == b.size());
    for (long j = 0; j < nslots; j++) assert (ptxts[i][j] == b[j]);

    // output the plaintext
    keyFile << "[ ";
    for (long j = 0; j < nslots; j++) keyFile << ptxts[i][j] << " ";
    keyFile << "]\n";

    eas[i]->encode(poly,ptxts[i]);
    keyFile << poly << endl;

    // Output the ciphertext to file
    keyFile << *ctxts[i] << endl;
    keyFile << *ctxts[i] << endl;
    cerr << "okay " << i << endl<< endl;
  }
  keyFile.close();}
  cerr << "so far, so good\n\n";

  // second loop: read from input and repeat the computation

  // open file for read
  {fstream keyFile("iotest.txt", fstream::in);
  for (long i=0; i<numTests; i++) {

    // Read context from file
    unsigned long m1, p1, r1;
    vector<long> gens, ords;
    readContextBase(keyFile, m1, p1, r1, gens, ords);
    FHEcontext tmpContext(m1, p1, r1, gens, ords);
    keyFile >> tmpContext;
    assert (*contexts[i] == tmpContext);
    cerr << i << ": context matches input\n";

    // We define some things below wrt *contexts[i], not tmpContext.
    // This is because the various operator== methods check equality of
    // references, not equality of the referenced FHEcontext objects.
    FHEcontext& context = *contexts[i];
    FHESecKey secretKey(context);
    FHESecKey secretKey2(tmpContext);
    const FHEPubKey& publicKey = secretKey;
    const FHEPubKey& publicKey2 = secretKey2;

    keyFile >> secretKey;
    keyFile >> secretKey2;
    assert(secretKey == *sKeys[i]);
    cerr << "   secret key matches input\n";

    EncryptedArray ea(context);
    EncryptedArray ea2(tmpContext);

    long nslots = ea.size();

    // Read the plaintext from file
    vector<ZZX> a;
    a.resize(nslots);
    assert(nslots == (long)ptxts[i].size());
    seekPastChar(keyFile, '['); // defined in NumbTh.cpp
    for (long j = 0; j < nslots; j++) {
      keyFile >> a[j];
      assert(a[j] == ptxts[i][j]);
    }
    seekPastChar(keyFile, ']');
    cerr << "   ptxt matches input\n";

    // Read the encoded plaintext from file
    ZZX poly1, poly2;
    keyFile >> poly1;
    eas[i]->encode(poly2,a);
    assert(poly1 == poly2);
    cerr << "   eas[i].encode(a)==poly1 okay\n";

    ea.encode(poly2,a);
    assert(poly1 == poly2);
    cerr << "   ea.encode(a)==poly1 okay\n";

    ea2.encode(poly2,a);
    assert(poly1 == poly2);
    cerr << "   ea2.encode(a)==poly1 okay\n";

    eas[i]->decode(a,poly1);
    assert(nslots == (long)a.size());
    for (long j = 0; j < nslots; j++) assert(a[j] == ptxts[i][j]);
    cerr << "   eas[i].decode(poly1)==ptxts[i] okay\n";

    ea.decode(a,poly1);
    assert(nslots == (long)a.size());
    for (long j = 0; j < nslots; j++) assert(a[j] == ptxts[i][j]);
    cerr << "   ea.decode(poly1)==ptxts[i] okay\n";

    ea2.decode(a,poly1);
    assert(nslots == (long)a.size());
    for (long j = 0; j < nslots; j++) assert(a[j] == ptxts[i][j]);
    cerr << "   ea2.decode(poly1)==ptxts[i] okay\n";

    // Read ciperhtext from file
    Ctxt ctxt(publicKey);
    Ctxt ctxt2(publicKey2);
    keyFile >> ctxt;
    keyFile >> ctxt2;
    assert(ctxts[i]->equalsTo(ctxt,/*comparePkeys=*/false));
    cerr << "   ctxt matches input\n";

    sKeys[i]->Decrypt(poly2,*ctxts[i]);
    assert(poly1 == poly2);
    cerr << "   sKeys[i]->decrypt(*ctxts[i]) == poly1 okay\n";

    secretKey.Decrypt(poly2,*ctxts[i]);
    assert(poly1 == poly2);
    cerr << "   secretKey.decrypt(*ctxts[i]) == poly1 okay\n";

    secretKey.Decrypt(poly2,ctxt);
    assert(poly1 == poly2);
    cerr << "   secretKey.decrypt(ctxt) == poly1 okay\n";

    secretKey2.Decrypt(poly2,ctxt2);
    assert(poly1 == poly2);
    cerr << "   secretKey2.decrypt(ctxt2) == poly1 okay\n";

    eas[i]->decrypt(ctxt, *sKeys[i], a);
    assert(nslots == (long)a.size());
    for (long j = 0; j < nslots; j++) assert(a[j] == ptxts[i][j]);
    cerr << "   eas[i].decrypt(ctxt, *sKeys[i])==ptxts[i] okay\n";

    ea.decrypt(ctxt, secretKey, a);
    assert(nslots == (long)a.size());
    for (long j = 0; j < nslots; j++) assert(a[j] == ptxts[i][j]);
    cerr << "   ea.decrypt(ctxt, secretKey)==ptxts[i] okay\n";

    ea2.decrypt(ctxt2, secretKey2, a);
    assert(nslots == (long)a.size());
    for (long j = 0; j < nslots; j++) assert(a[j] == ptxts[i][j]);
    cerr << "   ea2.decrypt(ctxt2, secretKey2)==ptxts[i] okay\n";

    cerr << "test "<<i<<" okay\n\n";
  }}
  unlink("iotest.txt"); // clean up before exiting
}
Ejemplo n.º 7
0
void TestIt(long idx, long p, long r, long L, long c, long skHwt, int build_cache=0)
{
  Vec<long> mvec;
  vector<long> gens;
  vector<long> ords;

  long phim = mValues[idx][1];
  long m = mValues[idx][2];
  assert(GCD(p, m) == 1);

  append(mvec, mValues[idx][4]);
  if (mValues[idx][5]>1) append(mvec, mValues[idx][5]);
  if (mValues[idx][6]>1) append(mvec, mValues[idx][6]);
  gens.push_back(mValues[idx][7]);
  if (mValues[idx][8]>1) gens.push_back(mValues[idx][8]);
  if (mValues[idx][9]>1) gens.push_back(mValues[idx][9]);
  ords.push_back(mValues[idx][10]);
  if (abs(mValues[idx][11])>1) ords.push_back(mValues[idx][11]);
  if (abs(mValues[idx][12])>1) ords.push_back(mValues[idx][12]);

  if (!noPrint) {
    cout << "*** TestIt";
    if (isDryRun()) cout << " (dry run)";
    cout << ": p=" << p
	 << ", r=" << r
	 << ", L=" << L
	 << ", t=" << skHwt
	 << ", c=" << c
	 << ", m=" << m
	 << " (=" << mvec << "), gens="<<gens<<", ords="<<ords
	 << endl;
    cout << "Computing key-independent tables..." << std::flush;
  }
  setTimersOn();
  setDryRun(false); // Need to get a "real context" to test bootstrapping

  double t = -GetTime();
  FHEcontext context(m, p, r, gens, ords);
  if (scale) {
    context.scale = scale;
  }

  context.zMStar.set_cM(mValues[idx][13]/100.0);
  buildModChain(context, L, c, /*willBeBootstrappable=*/true);

  if (!noPrint) {
    std::cout << "security=" << context.securityLevel()<<endl;
    std::cout << "# small primes = " << context.smallPrimes.card() << "\n";
    std::cout << "# ctxt primes = " << context.ctxtPrimes.card() << "\n";
    std::cout << "# bits in ctxt primes = "
         << long(context.logOfProduct(context.ctxtPrimes)/log(2.0) + 0.5) << "\n";
    std::cout << "# special primes = " << context.specialPrimes.card() << "\n";
    std::cout << "# bits in special primes = "
         << long(context.logOfProduct(context.specialPrimes)/log(2.0) + 0.5) << "\n";
    std::cout << "scale=" << context.scale<<endl;
  }

  context.makeBootstrappable(mvec,/*t=*/skHwt,build_cache,/*alsoThick=*/false);
  // save time...disable some fat boot precomputation

  t += GetTime();

  //if (skHwt>0) context.rcData.skHwt = skHwt;
  if (!noPrint) {
    cout << " done in "<<t<<" seconds\n";
    cout << "  e="    << context.rcData.e
	 << ", e'="   << context.rcData.ePrime
	 << ", a="<< context.rcData.a
	 << ", t="    << context.rcData.skHwt
	 << "\n  ";
    context.zMStar.printout();
  }
  setDryRun(dry); // Now we can set the dry-run flag if desired


  long p2r = context.alMod.getPPowR();

  for (long numkey=0; numkey<OUTER_REP; numkey++) { // test with 3 keys

  t = -GetTime();
  if (!noPrint) cout << "Generating keys, " << std::flush;
  FHESecKey secretKey(context);
  secretKey.GenSecKey(64);      // A Hamming-weight-64 secret key
  addSome1DMatrices(secretKey); // compute key-switching matrices that we need
  addFrbMatrices(secretKey);
  if (!noPrint) cout << "computing key-dependent tables..." << std::flush;
  secretKey.genRecryptData();
  t += GetTime();
  if (!noPrint) cout << " done in "<<t<<" seconds\n";

  FHEPubKey publicKey = secretKey;

  long d = context.zMStar.getOrdP();
  long phim = context.zMStar.getPhiM();
  long nslots = phim/d;

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

  if (debug) {
    dbgKey = &secretKey;
    dbgEa = &ea;
  }

  zz_p::init(p2r);
  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])));
  }

  vector<ZZX> val_const1;
  val_const1.resize(nslots);
  for (long i = 0; i < nslots; i++) {
    val_const1[i] = 1;
  }

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

  Ctxt c2(c1);
  if (!noPrint) CheckCtxt(c2, "before recryption");

  publicKey.thinReCrypt(c2);
  if (!noPrint) CheckCtxt(c2, "after recryption");

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

  if (val1 == val2) 
    cout << "GOOD\n";
  else
    cout << "BAD\n";
  }
}
Ejemplo n.º 8
0
void  TestIt(long m, long p, long r, long d, long L, long bnd, long B)
{
  cout << "*** TestIt" << (isDryRun()? "(dry run):" : ":")
       << " m=" << m
       << ", p=" << p
       << ", r=" << r
       << ", d=" << d
       << ", L=" << L
       << ", bnd=" << bnd
       << ", B=" << B
       << endl;

  setTimersOn();
  FHEcontext context(m, p, r);
  buildModChain(context, L, /*c=*/2);

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

  FHESecKey secretKey(context);
  const FHEPubKey& publicKey = secretKey;
  secretKey.GenSecKey(/*w=*/64); // A Hamming-weight-w secret key

  ZZX G;
  if (d == 0)
    G = context.alMod.getFactorsOverZZ()[0];
  else
    G = makeIrredPoly(p, d); 

  cout << "G = " << G << "\n";
  cout << "generating key-switching matrices... ";
  addSome1DMatrices(secretKey); // compute key-switching matrices that we need
  cout << "done\n";

  cout << "computing masks and tables for rotation...";
  EncryptedArray ea(context, G);
  cout << "done\n";

  PlaintextArray xp0(ea), xp1(ea);
  xp0.random();
  xp1.random();

  Ctxt xc0(publicKey);
  ea.encrypt(xc0, publicKey, xp0);

  ZZX poly_xp1;
  ea.encode(poly_xp1, xp1);

  cout << "** Testing replicate():\n";
  bool error = false;
  Ctxt xc1 = xc0;
  CheckCtxt(xc1, "before replicate");
  replicate(ea, xc1, ea.size()/2);
  if (!check_replicate(xc1, xc0, ea.size()/2, secretKey, ea)) error = true;
  CheckCtxt(xc1, "after replicate");

  // Get some timing results
  for (long i=0; i<20 && i<ea.size(); i++) {
    xc1 = xc0;
    FHE_NTIMER_START(replicate);
    replicate(ea, xc1, i);
    if (!check_replicate(xc1, xc0, i, secretKey, ea)) error = true;
    FHE_NTIMER_STOP(replicate);
  }
  cout << "  Replicate test " << (error? "failed :(\n" : "succeeded :)")
       << endl<< endl;
  printAllTimers();

  cout << "\n** Testing replicateAll()... " << std::flush;
#ifdef DEBUG_PRINTOUT
  replicateVerboseFlag = true;
#else
  replicateVerboseFlag = false;
#endif

  error = false;
  ReplicateTester *handler = new ReplicateTester(secretKey, ea, xp0, B);
  try {
    FHE_NTIMER_START(replicateAll);
    replicateAll(ea, xc0, handler, bnd);
  }
  catch (StopReplicate) {
  }
  cout << (handler->error? "failed :(\n" : "succeeded :)")
       << ", total time=" << handler->t_total << " ("
       << ((B>0)? B : ea.size())
       << " vectors)\n";
  delete handler;
}
Ejemplo n.º 9
0
int main(int argc, char *argv[]) {

  /*************************** INIT ***************************/
  /* most of the init code is copied directly from HElibs general test (https://github.com/shaih/HElib/blob/master/src%2FTest_General.cpp) */

  cerr << "*************************** INIT ***************************" << "\n";

  argmap_t argmap;
  argmap["R"] = "1";
  argmap["p"] = "113";
  argmap["r"] = "1";
  argmap["d"] = "1";
  argmap["c"] = "2";
  argmap["k"] = "80";
  argmap["L"] = "0";
  argmap["s"] = "0";
  argmap["m"] = "0";

  long R = atoi(argmap["R"]);
  long p = atoi(argmap["p"]);
  long r = atoi(argmap["r"]);
  long d = atoi(argmap["d"]);
  long c = atoi(argmap["c"]);
  long k = atoi(argmap["k"]);
  //  long z = atoi(argmap["z"]);
  long L = atoi(argmap["L"]);
  if (L==0) { // determine L based on R,r
    L = 3*R+3;
    if (p>2 || r>1) { // add some more primes for each round
      long addPerRound = 2*ceil(log((double)p)*r*3)/(log(2.0)*NTL_SP_NBITS) +1;
      L += R * addPerRound;
    }
  }
  long s = atoi(argmap["s"]);
  long chosen_m = atoi(argmap["m"]);

  long w = 64; // Hamming weight of secret key
  //  long L = z*R; // number of levels

  long m = FindM(k, L, c, p, d, s, chosen_m, true);

  cerr << "\n\nR=" << R
       << ", p=" << p
       << ", r=" << r
       << ", d=" << d
       << ", c=" << c
       << ", k=" << k
       << ", w=" << w
       << ", L=" << L
       << ", m=" << m
       << endl;

  FHEcontext context(m, p, r);
  buildModChain(context, L, c);

  context.zMStar.printout();
  cerr << endl;

  FHESecKey secretKey(context);
  const FHEPubKey& publicKey = secretKey;
  secretKey.GenSecKey(w); // A Hamming-weight-w secret key

  ZZX G;

  if (d == 0)
    G = context.alMod.getFactorsOverZZ()[0];
  else
    G = makeIrredPoly(p, d);

  cerr << "G = " << G << "\n";
  cerr << "generating key-switching matrices... ";
  addSome1DMatrices(secretKey); // compute key-switching matrices that we need
  cerr << "done\n";

  cerr << "computing masks and tables for rotation...";
  EncryptedArray ea(context, G);
  cerr << "done\n";

  long nslots = ea.size();
  cerr << "slots = " << nslots << "\n";

  // set this to the maximum amount of delegates you want to use
  int delegateLimit = 10;
  if(delegateLimit > nslots) {
    cerr << "delegateLimit must be <= nslots\n";
    exit(1);
  }

  cerr << "delegateLimit = " << delegateLimit << "\n";
  /*************************** INIT ***************************/

  cerr << "*************************** INIT ***************************" << "\n\n";

  cerr << "Reading delegate votes";
  vector<vector <long> > delegateVotes = readDelegateVotes("delegate_votes.txt", nslots, delegateLimit);
  cerr << "done\n";
  cerr << "Encoding delegate votes...\n";
  vector<PlaintextArray> delegateVotesEncoded = encodeVotes(delegateVotes, ea);
  cerr << "Encrypting delegate votes...\n";
  vector<Ctxt> delegateVotesEncrypted = encryptVotes(delegateVotesEncoded, ea, publicKey);

  cerr << "Reading direct votes";
  vector<vector <long> > votes = readVotes("direct_votes.txt", nslots);
  cerr << "done\n";
  cerr << "Encoding direct votes...\n";
  vector<PlaintextArray> votesEncoded = encodeVotes(votes, ea);
  cerr << "Encrypting direct votes...\n";
  vector<Ctxt> votesEncrypted = encryptVotes(votesEncoded, ea, publicKey);

  cerr << "Reading delegations";
  vector<vector <long> > delegations = readVotes("delegations.txt", nslots);
  cerr << "done\n";
  cerr << "Encoding delegations...\n";
  vector<PlaintextArray> delegationsEncoded = encodeVotes(delegations, ea);
  cerr << "Encrypting delegations...\n";
  vector<Ctxt> delegationsEncrypted = encryptVotes(delegationsEncoded, ea, publicKey);

  cerr << "Tallying delegations (+)...\n";
  Ctxt delegateWeights = tallyVotes(delegationsEncrypted);
  vector<Ctxt> weightFactors = getWeightFactors(delegateWeights, ea, publicKey, delegateLimit);
  cerr << "Applying weights (x)...\n";
  vector<Ctxt> weightedDelegateVotes = applyWeights(weightFactors, delegateVotesEncrypted, ea, secretKey);

  cerr << "Tallying direct votes (+)...\n";
  Ctxt directTally = tallyVotes(votesEncrypted);
  cerr << "Final tally (+)...\n";
  Ctxt tally = liquidTally(directTally, weightedDelegateVotes);

  cerr << "Decrypting final tally...\n";
  PlaintextArray totals = decrypt(tally, ea, secretKey);
  printTally(totals);
}
Ejemplo n.º 10
0
int main()
{
  string * tmp_ptr;

  long LLL, DDD, KKK ;

  long m; 
  long ccc;
  FHEcontext * context_ptr;
  FHESecKey  * fhekey_ptr;
  EncryptedArray * ea_ptr;
  
  LLL = 682; DDD=12; KKK=80;

  /*
      pair<long, long> m_c  = get_m_c(LLL, DDD, KKK);
      m = m_c.first;
      ccc = m_c.second;
  */
  m = 15709;
  ccc = 3;

  context_ptr = new FHEcontext(m, 2, 1);
  buildModChain(*context_ptr, DDD, ccc);
  fhekey_ptr = new FHESecKey(*context_ptr);
  fhekey_ptr->clear();
  fhekey_ptr->GenSecKey(64,2);
  addSome1DMatrices(*fhekey_ptr);
  const  FHEPubKey & pub_key =  *fhekey_ptr;

  ZZX G;
  G = ZZX(1,1);
  ea_ptr = new EncryptedArray(*context_ptr, G);

  // Test I/O, write context and public key, then try to read them back
  cout << "KEY\n";
  cout <<"L= " <<LLL<< " D= " << DDD<< " K= " << KKK << endl<< flush;

  {
  stringstream s1;
  writeContextBase(s1, *context_ptr);
  s1 << *context_ptr;

  string s2 = s1.str();
  cout << s2 << endl;  // output context also to external cout

  // Read back context from input stream (s3)
  unsigned long m1, p1, r1;
  stringstream s3(s2);
  readContextBase(s3, m1, p1, r1);
  FHEcontext c1(m1, p1, r1);
  s3 >> c1;
  assert(c1 == *context_ptr);
  }
  {
  stringstream s1;
  s1 << pub_key;

  string s2 = s1.str();
  cout << s2 <<"\nENDKEY" << endl; // output public key also to external cout

  // Read back cpublic key from input stream (s3)
  stringstream s3(s2);
  FHEPubKey pk1(*context_ptr);
  s3 >> pk1;
  assert(pk1 == pub_key);
  }
}
int main(int argc, char **argv)
{
    /* On our trusted system we generate a new key
     * (or read one in) and encrypt the secret data set.
     */

    long m=0, p=2, r=1; // Native plaintext space
                            // Computations will be 'modulo p'
    long L=16;          // Levels
    long c=3;           // Columns in key switching matrix
    long w=64;          // Hamming weight of secret key
    long d=0;
    long security = 128;
    ZZX G;
    m = FindM(security,L,c,p, d, 0, 0);


    FHEcontext context(m, p, r);
    // initialize context
    buildModChain(context, L, c);
    // modify the context, adding primes to the modulus chain
    FHESecKey secretKey(context);
    // construct a secret key structure
    const FHEPubKey& publicKey = secretKey;
    // an "upcast": FHESecKey is a subclass of FHEPubKey

    //if(0 == d)
    G = context.alMod.getFactorsOverZZ()[0];

    secretKey.GenSecKey(w);
    // actually generate a secret key with Hamming weight w

    addSome1DMatrices(secretKey);
    cout << "Generated key..." << endl;

    EncryptedArray ea(context, G);
    // constuct an Encrypted array object ea that is
    // associated with the given context and the polynomial G

    long nslots = ea.size();
    cout << "Vector Size " << nslots << endl;;

    vector<long> v1;
    for(int i = 0 ; i < nslots; i++) {
        v1.push_back(1);
       //v1.push_back(i*2);
    }
    Ctxt ct1(publicKey);
    startFHEtimer("ea.encrypt1");
    ea.encrypt(ct1, publicKey, v1);
    stopFHEtimer("ea.encrypt1");
        
    vector<long> v2;
    Ctxt ct2(publicKey);
    for(int i = 0 ; i < nslots; i++) {
        v2.push_back(1);
        //v2.push_back(i*3);
    }
    startFHEtimer("ea.encrypt2");
    ea.encrypt(ct2, publicKey, v2);
    stopFHEtimer("ea.encrypt2");

    // v1.mul(v2); // c3.multiplyBy(c2) 
    // ct2.multiplyBy(ct1);              
    // CheckCtxt(ct2, "c3*=c2");
    // debugCompare(ea,secretKey,v1,ct2);

    // On the public (untrusted) system we
    // can now perform our computation

    Ctxt ctSum = ct1;
    Ctxt ctProd = ct1;

    startFHEtimer("sum");
    ctSum += ct2;
    stopFHEtimer("sum");
    //ctProd *= ct2;
    startFHEtimer("product");
    ctProd *= ct2;
    //ctProd.multiplyBy(ct2);
    stopFHEtimer("product");
    //ea.mat_mul(ctProd,ct2);
    vector<long> res;

    startFHEtimer("decryptsum");
    ea.decrypt(ctSum, secretKey, res);
    stopFHEtimer("decryptsum");
    //cout << "All computations are modulo " << p << "." << endl;
    for (unsigned int i = 0; i<res.size(); i++){
        cout<< res[i];
    }

    for(unsigned int i = 0; i < res.size(); i++) {
        cout << v1[i] << " + " << v2[i] << " = " << res[i] << endl;
    }

    startFHEtimer("decryptproduct");
    ea.decrypt(ctProd, secretKey, res);
    stopFHEtimer("decryptproduct");
    for (unsigned int i = 0; i<res.size(); i++){
        cout<< res[i];
    }
    
    for(unsigned int i = 0; i < res.size(); i++) {
        cout << v1[i] << " * " << v2[i] << " = " << res[i] << endl;
    }
    printAllTimers();
    cout << endl;
    cout << "All computations are modulo " << p << "." << endl;
    return 0;
}
Ejemplo n.º 12
0
int main(int argc, char **argv)
{
    string inp = "secrets! very secrets!";
    cout << "inp = \"" << inp << "\"" << endl;
    vector<pt_key32> k = pt_genKey();
    pt_expandKey(k);
    printKey(k);

    // initialize helib
    long m=0, p=2, r=1;
    long L=23;
    long c=3;
    long w=64;
    long d=0;
    long security = 128;
    cout << "L=" << L << endl;
    ZZX G;
    cout << "Finding m..." << endl;
    m = FindM(security,L,c,p,d,0,0);
    cout << "Generating context..." << endl;
    FHEcontext context(m, p, r);
    cout << "Building mod-chain..." << endl;
    buildModChain(context, L, c);
    cout << "Generating keys..." << endl;
    FHESecKey seckey(context);
    const FHEPubKey& pubkey = seckey;
    G = context.alMod.getFactorsOverZZ()[0];
    seckey.GenSecKey(w);
    addSome1DMatrices(seckey);
    EncryptedArray ea(context, G);
    global_nslots = ea.size();
    cout << "nslots = " << global_nslots << endl;

    // set up globals
    CTvec maxint (ea, pubkey, transpose(uint32ToBits(0xFFFFFFFF)));
    global_maxint = &maxint;

    // HEencrypt key
    timer(true);
    cout << "Encrypting SIMON key..." << flush;
    vector<CTvec> encryptedKey = heEncrypt(ea, pubkey, k);
    timer();

    // HEencrypt input
    cout << "Encrypting inp..." << flush;
    heblock ct = heEncrypt(ea, pubkey, inp);
    timer();

    cout << "Running protocol..." << endl;
    for (size_t i = 0; i < T; i++) {
        cout << "Round " << i+1 << "/" << T << "..." << flush;
        encRound(encryptedKey[i], ct);
        timer();

        // check intermediate result for noise
        cout << "decrypting..." << flush;
        vector<pt_block> bs = heblockToBlocks(seckey, ct);
        timer();

        printf("block0    : 0x%08x 0x%08x\n", bs[0].x, bs[0].y);

        vector<pt_block> pt_bs = pt_simonEnc(k, inp, i+1);
        printf("should be : 0x%08x 0x%08x\n", pt_bs[0].x, pt_bs[0].y);

        cout << "decrypted : \"" << pt_simonDec(k, bs, i+1) << "\" " << endl;
    }

    return 0;
}
Ejemplo n.º 13
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;
  }
}
int main(){
    long m, r, p, L, c, w, s, d, security, enc, dec, encMul, recommended;
    char tempChar;
    bool toPrint = false, toSave = false;
    
    //Scan parameters
    
    cout << "Enter HElib's keys paramter. Enter zero for the recommended values" << endl;
    
    while(true){
        cout << "Enter the field of the computations (a prime number): ";
        cin >> p;
        if(isPrime(p))
            break;
        cout << "Error! p must be a prime number! " << endl;
    }
    while(true){
        recommended = 1;
        cout << "Enter r (recommended " << recommended <<"): ";
        cin >> r;
        if(r == 0)
            r = recommended;
        if(r > 0)
            break;
        cout << "Error! r must be a positive number!" << endl;
    }
    while(true){
        recommended = 16;
        cout << "Enter L (recommended " << recommended <<"): ";
        cin >> L;
        if(L == 0)
            L = recommended;
        if(L > 1)
            break;
        cout << "Error! L must be a positive number!" << endl;
    }
    while(true){
        recommended = 3;
        cout << "Enter c (recommended " << recommended <<"): ";
        cin >> c;
        if(c == 0)
            c = recommended;
        if(c > 1)
            break;
        cout << "Error! c must be a positive number!" << endl;
    }
    while(true){
        recommended = 64;
        cout << "Enter w (recommended " << recommended <<"): ";
        cin >> w;
        if(w == 0)
            w = recommended;
        if(w > 1)
            break;
        cout << "Error! w must be a positive number!" << endl;
    }
    while(true){
        recommended = 0;
        cout << "Enter d (recommended " << recommended <<"): ";
        cin >> d;
        if(d >= 0)
            break;
        cout << "Error! d must be a positive or zero!" << endl;
    }
    while(true){
        recommended = 0;
        cout << "Enter s (recommended " << recommended <<"): ";
        cin >> s;
        if(s >= 0)
            break;
        cout << "Error! s must be a positive or zero!" << endl;
    }
    while(true){
        recommended = 128;
        cout << "Enter security (recommended " << recommended << "): ";
        cin >> security;
        if(security == 0)
            security = recommended;
        if(security >= 1)
            break;
        cout << "Error! security must be a positive number " << endl;
    }
    
    ZZX G;
    m = FindM(security,L,c,p, d, s, 0);
    FHEcontext context(m, p, r);
    // initialize context
    buildModChain(context, L, c);
    // modify the context, adding primes to the modulus chain
    FHESecKey secretKey(context);
    // construct a secret key structure
    const FHEPubKey& publicKey = secretKey;
    // an "upcast": FHESecKey is a subclass of FHEPubKey
    
    //if(0 == d)
    G = context.alMod.getFactorsOverZZ()[0];
    
    secretKey.GenSecKey(w);
    // actually generate a secret key with Hamming weight w
    
    addSome1DMatrices(secretKey);
    EncryptedArray ea(context, G);
    // constuct an Encrypted array object ea that is
    // associated with the given context and the polynomial G
    
    long nslots = ea.size(), field = power(p,r);
    cout << "nslots: " << nslots << endl ;
    cout << "Computations will be modulo " << field << endl;
    cout << "m: " << m << endl;
    
    unsigned int sz1, sz2, num;
    while(true){
        cout << "Enter number of rows in the matrix: ";
        cin >> sz1;
        if(sz1 > 1 && sz1 <= nslots)
            break;
        cout << "Error! the value must be between 1 to " << nslots << "!" << endl;
    }
    while(true){
        cout << "Enter number of columns in the matrix: ";
        cin >> sz2;
        if(sz1 > 2 && sz2 <= nslots)
            break;
        cout << "Error! the value must be between 1 to " << nslots << "!" << endl;
    }
    cout << "Enter the number you want to multiply the matrix by: ";
    cin >> num;
    
    MatSize sz(sz1, sz2);
    PTMatrix PTmat(sz,field);  //random matrix in size origSize1
    
    while(true){
        cout << "Print the matrices?" << endl;
        cout << "Y for yes, N for no: ";
        cin >> tempChar;
        if(tempChar == 'Y' || tempChar == 'y'){
            toPrint = true;
            break;
        }
        if(tempChar == 'N' || tempChar == 'n'){
            toPrint = false;
            break;
        }
        cout << "Error! invalid input!" << endl;
    }
    while(true){
        cout << "Save the matrices?" << endl;
        cout << "Y for yes, N for no: ";
        cin >> tempChar;
        if(tempChar == 'Y' || tempChar == 'y'){
            toSave = true;
            break;
        }
        if(tempChar == 'N' || tempChar == 'n'){
            toSave = false;
            break;
        }
        cout << "Error! invalid input!" << endl;
    }
    if(toPrint)
        PTmat.print();
    
    if(toSave){
        ofstream out_mat("mat.txt");
        PTmat.save(out_mat);
        out_mat.close();
    }
    
    //encryptions
    cout << "Encrypting the matrix..." << endl;
    resetTimers();
    EncryptedMatrix encMat = PTmat.encrypt(ea, publicKey);
    enc = stopTimers("to encrypt the first matrix");
    
    //Multiply by constant
    cout << "Multiplying the matricex by constant..." << endl;
    resetTimers();
    encMat *= num;
    encMul = stopTimers("to multiply the matrix");
    
    cout << "Decrypting the result..." << endl;
    resetTimers();
    PTMatrix res = encMat.decrypt(ea, secretKey);
    dec = stopTimers("to decrypt the result");
    if(toPrint)
        res.print("Solution: ");
    
    PTMatrix PTres = PTmat;
    for(unsigned int i=1; i < num; i++){
        PTres += PTmat;
    }
    PTres %= field;
    if(toPrint)
        PTres.print("pt Solution: ");
    
    if(toSave){
        ofstream out_res("mat_res.txt"), out_ptRes("mat_pt_res.txt");
        res.save(out_res);
        PTres.save(out_ptRes);
        out_res.close(); out_ptRes.close();
    }
    
    //PTres.print("pt result: ");
    
    cout << "\n\n----------------------------------------Summary------------------------------ " << endl;
    cout << "p: " << p << ", r: " << r << ", L: " << L << ", c: " << c << ", w: " << w << ", d: " << d << ", s: " << s << ", security: " << security << endl;
    cout << "nslots: " << nslots << "\nm: " << m << endl;
    cout << "It took " << enc << " clock ticks to encrypt the matrix" << endl;
    cout << "It took " << dec << " clock ticks to decrypt the result" << endl;
    cout << "It took " << encMul << " clock ticks to add the encrypted matrices" << endl;
    cout << "is correct? " << (res==PTres) << endl;

    return 0;
}
Ejemplo n.º 15
-2
void  TestIt(long R, long p, long r, long d, long c, long k, long w, 
               long L, long m)
{
  cerr << "\n\n******** TestIt: R=" << R 
       << ", p=" << p
       << ", r=" << r
       << ", d=" << d
       << ", c=" << c
       << ", k=" << k
       << ", w=" << w
       << ", L=" << L
       << ", m=" << m
       << endl;

  FHEcontext context(m, p, r);
  buildModChain(context, L, c);

  // context.lazy = false;

  if (context.lazy)
    cerr << "LAZY REDUCTIONS\n";
  else
    cerr << "NON-LAZY REDUCTIONS\n";

  context.zMStar.printout();
  cerr << endl;
#ifdef DEBUG
  cerr << context << endl;
#endif

  FHESecKey secretKey(context);
  const FHEPubKey& publicKey = secretKey;
  secretKey.GenSecKey(w); // A Hamming-weight-w secret key


  ZZX G;

  if (d == 0) {
    G = context.alMod.getFactorsOverZZ()[0];
    d = deg(G);
  }
  else
    G = makeIrredPoly(p, d); 

  cerr << "G = " << G << "\n";
  cerr << "generating key-switching matrices... ";
  addSome1DMatrices(secretKey); // compute key-switching matrices that we need
  addFrbMatrices(secretKey); // compute key-switching matrices that we need
  cerr << "done\n";


  cerr << "computing masks and tables for rotation...";
  EncryptedArray ea(context, G);
  cerr << "done\n";


  long nslots = ea.size();


  // L selects even coefficients
  vector<ZZX> LM(d);
  for (long j = 0; j < d; j++) 
    if (j % 2 == 0) LM[j] = ZZX(j, 1);

  vector<ZZX> C;
  ea.buildLinPolyCoeffs(C, LM);

  PlaintextArray p0(ea);
  p0.random();
  
  Ctxt c0(publicKey);
  ea.encrypt(c0, publicKey, p0);

  Ctxt res(c0);

  applyLinPoly1(ea, res, C);

  PlaintextArray pp0(ea);
  ea.decrypt(res, secretKey, pp0);

  p0.print(cout); cout << "\n";
  pp0.print(cout); cout << "\n";

}