-rw-r--r-- 4285 cryptattacktester-20230614/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;
}
}