-rw-r--r-- 4285 cryptattacktester-20231020/searchparams.cpp raw
#include <iostream> #include <set> #include <map> #include "bigint.h" #include "problem.h" #include "attack.h" #include "selection.h" using namespace std; struct evaluation { bigint cost; bigfloat prob; bigfloat lgcost; bigfloat lgprob; bigfloat lgratio; evaluation(const vector<bigint> &P,const attack &A,const vector<bigint> &Q) : cost(A.cost(P,Q)), prob(A.prob(P,Q)), lgcost(log2(bigfloat(cost))), lgprob(log2(prob)), lgratio(lgcost-lgprob) { } } ; #define MODS 6 static vector<bigint> modification(const vector<bigint> &Q,bigint pos,bigint mod) { auto result = Q; if (mod == 0) result.at(pos) = Q.at(pos)*2; if (mod == 1) result.at(pos) = Q.at(pos)/2; if (mod == 2) result.at(pos) = (Q.at(pos)*3)/2; if (mod == 3) result.at(pos) = (Q.at(pos)*2+1)/3; if (mod == 4) result.at(pos) = Q.at(pos)+1; if (mod == 5) result.at(pos) = Q.at(pos)-1; return result; } static void printevaluation(const std::string &prefix,const problem &C,const vector<bigint> &P,const attack &A,const vector <bigint> &Q,const evaluation &E) { cout << prefix; cout << " problem=" << C.name; for (bigint j = 0;j < P.size();++j) cout << (j ? ',' : ' ') << C.paramnames.at(j) << "=" << P.at(j); cout << " attack=" << A.name; for (bigint j = 0;j < Q.size();++j) cout << (j ? ',' : ' ') << A.paramnames.at(j) << "=" << Q.at(j); cout << " lgratio " << E.lgratio; cout << " cost " << E.cost; cout << " lgcost " << E.lgcost; cout << " prob " << E.prob; cout << " lgprob " << E.lgprob; cout << '\n' << flush; } int attack_handle(const problem &C,const vector<bigint> &P,const attack &A,const vector<bigint> &Qorig) { if (!A.params_valid) return -1; vector<bigint> Q = Qorig; selection_type S = attack_selection; vector<bool> canchange(Q.size(),1); // becomes 0 if S prohibits a change set<vector<bigint>> Qevaluated; bigint printallevaluations = 0; selection_constrain(S,"printallevaluations",printallevaluations,printallevaluations); bigfloat epsilon = 1/512.0; Qevaluated.insert(Q); evaluation E = evaluation(P,A,Q); if (printallevaluations) printevaluation("evaluation",C,P,A,Q,E); for (;;) { printevaluation("searchparams",C,P,A,Q,E); auto Qbest = Q; auto Ebest = E; for (bigint pos = 0;pos < Q.size();++pos) { if (!canchange.at(pos)) continue; for (bigint mod = 0;mod < MODS;++mod) { auto Qnew = modification(Q,pos,mod); if (Qevaluated.count(Qnew) > 0) continue; // saw already if (!A.params_valid(P,Qnew)) continue; if (!selection_allows(S,A.paramnames.at(pos),Qnew.at(pos).get_str())) { canchange.at(pos) = 0; break; } Qevaluated.insert(Qnew); evaluation Enew(P,A,Qnew); if (printallevaluations) printevaluation("evaluation",C,P,A,Qnew,Enew); if (Enew.lgratio.definitely_less(Ebest.lgratio)) { Ebest = Enew; Qbest = Qnew; } } } if ((Ebest.lgratio+epsilon).definitely_less(E.lgratio)) { Q = Qbest; E = Ebest; continue; } Qbest = Q; Ebest = E; for (bigint pos1 = 0;pos1 < Q.size();++pos1) { if (!canchange.at(pos1)) continue; for (bigint mod1 = 0;mod1 < MODS;++mod1) { auto Q1 = modification(Q,pos1,mod1); for (bigint pos2 = pos1;pos2 < Q.size();++pos2) { if (!canchange.at(pos2)) continue; for (bigint mod2 = 0;mod2 < MODS;++mod2) { auto Qnew = modification(Q1,pos2,mod2); if (Qevaluated.count(Qnew) > 0) continue; if (!A.params_valid(P,Qnew)) continue; if (!selection_allows(S,A.paramnames.at(pos1),Qnew.at(pos1).get_str())) continue; if (!selection_allows(S,A.paramnames.at(pos2),Qnew.at(pos2).get_str())) continue; Qevaluated.insert(Qnew); evaluation Enew(P,A,Qnew); if (printallevaluations) printevaluation("evaluation",C,P,A,Qnew,Enew); if (Enew.lgratio.definitely_less(Ebest.lgratio)) { Ebest = Enew; Qbest = Qnew; } } } } } if ((Ebest.lgratio+epsilon).definitely_less(E.lgratio)) { Q = Qbest; E = Ebest; continue; } return -1; } }