void FieldIdealImpl::myAdd(const ideal& J) { if (IamZero() && !ourGetPtr(J)->IamZero()) myTidyGensValue.push_back(one(myR)); myGensValue.insert(myGensValue.end(), gens(J).begin(), gens(J).end()); IamPrime3Flag = IamMaximal3Flag = IamZero(); }
// Before delegating the resize to the old generation, // the reserved space for the young and old generations // may be changed to accomodate the desired resize. void ParallelScavengeHeap::resize_old_gen(size_t desired_free_space) { if (UseAdaptiveGCBoundary) { if (size_policy()->bytes_absorbed_from_eden() != 0) { size_policy()->reset_bytes_absorbed_from_eden(); return; // The generation changed size already. } gens()->adjust_boundary_for_old_gen_needs(desired_free_space); } // Delegate the resize to the generation. _old_gen->resize(desired_free_space); }
// Before delegating the resize to the young generation, // the reserved space for the young and old generations // may be changed to accomodate the desired resize. void ParallelScavengeHeap::resize_young_gen(size_t eden_size, size_t survivor_size) { if (UseAdaptiveGCBoundary) { if (size_policy()->bytes_absorbed_from_eden() != 0) { size_policy()->reset_bytes_absorbed_from_eden(); return; // The generation changed size already. } gens()->adjust_boundary_for_young_gen_needs(eden_size, survivor_size); } // Delegate the resize to the generation. _young_gen->resize(eden_size, survivor_size); }
bool TTPAttack::LBA( int NWL, int NWR, const vector<ThLeftNormalForm>& theTuple, const Word& z ) { TTPTuple T; T.WL = vector<Word>(NWL); T.WR = vector<Word>(NWR); for ( int j=0;j<theTuple.size();j++) if ( j < NWL ) T.WL[j] = theTuple[j].getWord(); else T.WR[j-NWL] = theTuple[j].getWord(); T.shorten( N ); vector< Word > gens(N-1); for (int i=0;i<N-1;i++) gens[i] = Word(i+1); TTPLBA ttpLBA; TTPTuple red_T; bool red_res = ttpLBA.reduce( N ,BS, T, gens, 600, cout, red_T, z ); // If success check if we have the original z by computing bool same_z = true; if (red_res){ cout << "SAME Z: " << shortenBraid(N,z*red_T.z).length() << endl; for (int i=0;i<red_T.WL.size();i++){ if (shortenBraid(N,red_T.z*red_T.WL[i]*-red_T.z*-T.WL[i]).length() > 0) { same_z = false; break; } } for (int i=0;i<red_T.WR.size();i++){ if (shortenBraid(N,red_T.z*red_T.WR[i]*-red_T.z*-T.WR[i]).length() > 0) { same_z = false; break; } } } if (same_z) cout << "SOLUTION CORRECT" << endl; else cout << "SOLUTION IS NOT CORRECT" << endl; return red_res; }
bool TTPAttack::simpleLBA( int NWL, int NWR, const vector<ThLeftNormalForm>& theTuple, const Word& z ) { TTPTuple T; T.WL = vector<Word>(NWL); T.WR = vector<Word>(NWR); for ( int j=0;j<theTuple.size();j++) if ( j < NWL ) T.WL[j] = theTuple[j].getWord(); else T.WR[j-NWL] = theTuple[j].getWord(); T.shorten( N ); vector< Word > gens(N-1); for (int i=0;i<N-1;i++) gens[i] = Word(i+1); TTPLBA ttpLBA; return ttpLBA.simpleLBA( N,BS,T,z ); }
bool PresentationParser::getGeneratorRange( const Chars& name, VectorOf<Chars>& result, Chars& errMesg ) { if ( curToken != DOT ) error("bool PresentationParser::getGeneratorRange() " "can't read the range"); // Make sure, that we have 3 dots in a row for (int i = 0;i<2;i++){ getToken(); if ( curToken != DOT ) { parseError("Expected '.' here"); errMesg = parseErrorMessage; return false; } } getToken(); // Supose to be ',' if ( curToken != COMMA ) { parseError("Expected ',' here"); errMesg = parseErrorMessage; return false; } getToken(); // Supose to be a generator if ( curToken != GENERATOR ) { parseError("Expected a generator here"); errMesg = parseErrorMessage; return false; } Chars name1; int beginRange; // Generators must be in the form: <name><index>, where // index is the first and the last generator index in a range. // Chars rangeErrMsg = "When defining a set of generators using a range of " "subscripts, both the smallest subscript and the largest subscript" " must be given and the smallest subscript mast be less then the " "largest one"; if ( !getRangeOf(name,name1,beginRange)) { parseError(rangeErrMsg); errMesg = parseErrorMessage; return false; } Chars name2; int endRange; if ( !getRangeOf(tokenName,name2,endRange)) { parseError(rangeErrMsg); errMesg = parseErrorMessage; return false; } // The last index must be greater than the first one if ( endRange <= beginRange) { parseError(rangeErrMsg); errMesg = parseErrorMessage; return false; } // Names gave to be equal if ( name2 != name1) { parseError(rangeErrMsg); errMesg = parseErrorMessage; return false; } // Generate generators of type: name1<index>, where // beginRange < index < endRange int numberOfGens = endRange - beginRange - 1; if (numberOfGens > 0){ VectorOf<Chars> gens(numberOfGens); for(int i = 0;i<numberOfGens;i++){ gens[i] = name1+Chars(beginRange + 1 + i); // Check for duplication and presence of inverses. if ( result.indexOf(gens[i]) >= 0 ) { parseError("Duplicate generator"); errMesg = parseErrorMessage; return false; } else { char str[100]; strcpy(str,gens[i]); invertName(str); if ( result.indexOf(Chars(str)) >= 0 ) { parseError("Duplicate generator: formal inverse"); errMesg = parseErrorMessage; return false; } } } result = concatenate(result, gens); } return true; }
// 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 }
bool TTPLBA::simpleLBA( int N , const BSets& bs, const TTPTuple& theTuple, const Word& z, TTPTuple* ret_T ) { TTPTuple T = theTuple; T.shorten( N ); vector< Word > gens(N-1); for (int i=0;i<N-1;i++) gens[i] = Word(i+1); // DO THE REDUCTION HERE TTPTuple red_T( T.WL,T.WR ); Word z_conj; int minLength = 999999999; while ( 1) { // !red_T.shortAndTestTuples( N ) ) { Word succGen; bool lenReduced = false; // int minLength = 999999999; for ( int i=0;i<gens.size();i++) { // switch for positive negative Word g = gens[i]; for (int s=0;s<=1;s++){ if (s) g = -g; int length=0; // DO LEFT TUPLE for ( int iL=0;iL<T.WL.size();iL++) length += shortenBraid(N,-g*red_T.WL[iL]*g).length(); // DO RIGTH TUPLE for ( int iR=0;iR<T.WR.size();iR++) length += shortenBraid(N,-g*red_T.WR[iR]*g).length(); // cout << "Try " << g << " Length : " << length << endl; if ( length < minLength ){ minLength = length; succGen = g; // cout << "New Length : " << minLength << " by " << g << endl; lenReduced = true; } } } if (!lenReduced) { // if ( !red_T.shortAndTestTuples( N ) ) // else // break; // cout << "Z : " << shortenBraid(N,z) << endl; // cout << "Z': " << shortenBraid(N,z_conj) << endl; Word z_diff = shortenBraid(N,z*z_conj); cout << "Z DIST : " << z_diff.length() << endl; // if (z_diff.length() > 2) // return false; // else // return true; red_T.z = z_conj; if ( equalUpToCommut( N, bs, red_T, z) ) cout << "Z COMMUTE WITH WS" << endl; // It seems that z can be hard to recover // because the difference z*z' may commute with both BL and BR // Then |BL| + |BR| = |(z*z')^-1 BL (z*z')| + |(z*z')^-1 BR (z*z')| // Check it here // int len = 0; // int len_conj = 0; // for ( int i=0;i<red_T.WL.size();i++){ // len += red_T.WL[i].length(); // len_conj += shortenBraid(N,-z_diff*red_T.WL[i]*z_diff).length(); // } // for ( int i=0;i<red_T.WR.size();i++){ // len += red_T.WR[i].length(); // len_conj += shortenBraid(N,-z_diff*red_T.WR[i]*z_diff).length(); // } // if ( len_conj <= len) // cout << "Z COMMUTE WITH WS" << endl; // copy reduced tuple if ( ret_T ) *ret_T = TTPTuple( red_T.WL, red_T.WR, z_conj ); if ( red_T.shortAndTestTuples( N ) ) return true; else return false; } // UPDATE THE TUPLE // UPDATE LEFT TUPLE for ( int iL=0;iL<T.WL.size();iL++){ Word redWord = shortenBraid(N,-succGen*red_T.WL[iL]*succGen); red_T.WL[iL] = redWord; } // UPDATE RIGTH TUPLE for ( int iR=0;iR<T.WR.size();iR++){ Word redWord = shortenBraid(N,-succGen*red_T.WR[iR]*succGen); red_T.WR[iR] = redWord; } z_conj = z_conj*succGen; // z is such that w_red = z^-1 w z. int conj_dist = shortenBraid(N,z*z_conj).length(); int stop_cond = red_T.shortAndTestTuples( N ); cout << "DIST to Z: " << conj_dist << " " << shortenBraid(N,z*z_conj)<< " COND : " << stop_cond << endl; if ( conj_dist == 0 && stop_cond == 0 ) { // show details since it should not happen red_T.shortAndTestTuples( N,true ); } if ( conj_dist == 0 && stop_cond == 1 ) { // // If success check if we have the original z by computing bool same_z = true; // if (red_res){ cout << "Z DIST : " << shortenBraid(N,z*z_conj).length() << endl; for (int i=0;i<red_T.WL.size();i++){ if (shortenBraid(N,z_conj*red_T.WL[i]*-z_conj*-T.WL[i]).length() > 0) { same_z = false; break; } } for (int i=0;i<red_T.WR.size();i++){ if (shortenBraid(N,z_conj*red_T.WR[i]*-z_conj*-T.WR[i]).length() > 0) { same_z = false; break; } } if (same_z) cout << "SOLUTION CORRECT" << endl; else cout << "SOLUTION IS NOT CORRECT" << endl; // copy reduced tuple if ( ret_T ) *ret_T = TTPTuple( red_T.WL, red_T.WR, z_conj ); return true; } } }