-rw-r--r-- 4054 cryptattacktester-20231020/isd1_cost.cpp raw
#include <cassert>
#include "ram_cost.h"
#include "bit_cost.h"
#include "bit_vector_cost.h"
#include "bit_matrix_cost.h"
#include "subset_cost.h"
#include "index_cost.h"
#include "sorting_cost.h"
#include "parity_cost.h"
#include "isd1_cost.h"
using namespace std;
bigint isd1_cost(const vector<bigint> ¶ms,const vector<bigint> &attackparams)
{
bigint N = params.at(0);
bigint K = params.at(1);
bigint W = params.at(2);
bigint pos = 0;
bigint ITERS = attackparams.at(pos++);
bigint RESET = attackparams.at(pos++);
bigint X = attackparams.at(pos++);
bigint YX = attackparams.at(pos++); auto Y = X+YX;
bigint PI = attackparams.at(pos++);
bigint L = attackparams.at(pos++);
bigint Z = attackparams.at(pos++);
bigint QUEUE_SIZE = attackparams.at(pos++);
bigint QF = attackparams.at(pos++); auto PERIOD = QF*QUEUE_SIZE;
bigint WINDOW = attackparams.at(pos++);
bigint FW = attackparams.at(pos++);
bigint fwcost = 0;
if (FW) {
fwcost = parity_known_cost(N,K);
--K;
}
bigint R = N - K;
bigint KK = K + L;
bigint RR = N - KK;
bigint idx_bits = nbits((KK-Z+1)/2-1); // XXX: if KK-Z+1 is a power of 2 then can shave some bits off of queue_set etc
bigint left = (KK-Z)/2;
bigint right = KK-Z-left;
bigint result = 0;
bigint column_swaps = column_swaps_cost(N,K,L,X,Y); // column_swaps(s, H, column_map, N, K, L, X, Y);
result += column_swaps;
result += 1; // alwayssystematic &= swapssucceeded;
bigint listsize0 = binomial(left,PI);
bigint listsize1 = binomial(right,PI);
bigint listsize = listsize0+listsize1;
bigint WINDOW1 = min(WINDOW,bigint(listsize0+listsize1-1));
bigint pool = (2*(listsize0+listsize1)-WINDOW1-1)*WINDOW1/2;
result += subset_cost(left,PI,L); // subset(L_sum, L_set, Hs0.at(0).size(), PI, idx_bits, zz, Hs0.at(0));
result += subset_cost(right,PI,L); // subset(L_sum, L_set, Hs0.at(1).size(), PI, idx_bits, s0, Hs0.at(1));
result += sorting_cost(listsize,L+1,PI*idx_bits); // sorting(L_01, L_sum, L_set);
bigint persum = 0;
persum += 2+bit_vector_compare_cost(L); // bit check = L_01.at(i) ^ L_01.at(i+1); ... check = check.andn(bit_vector_compare(L_sum.at(i), L_sum.at(i+1)));
persum += bit_queue1_insert_cost(QUEUE_SIZE); // bit_queue1_insert(queue_valid, check);
persum += QUEUE_SIZE*2*PI*idx_bits*bit_mux_cost; // bit_matrix_queue_insert(queue_set, set, check);
result += pool*persum;
bigint postqueue = 0;
postqueue += R-L+bit_matrix_sum_of_cols_cost(R-L,left,PI); // for b=0: bit_vector_ixor(sum, bit_matrix_sum_of_cols(Hs1.at(b), set_p));
postqueue += R-L+bit_matrix_sum_of_cols_cost(R-L,right,PI); // for b=1: bit_vector_ixor(sum, bit_matrix_sum_of_cols(Hs1.at(1), set_p));
postqueue += 2+bit_vector_hamming_weight_isnot_cost(R-L,W-2*PI); // alwayssystematic.andn(bit_vector_hamming_weight_isnot(sum,T-PI*2)) & queue_valid.at(j);
postqueue += (R-L)*bit_mux_cost; // bit_vector_mux(s_ret, sum, check_w);
postqueue += 2*PI*idx_bits*bit_mux_cost; // bit_matrix_mux(set_ret, queue_set.at(j), check_w);
postqueue += N*nbits(N-1)*bit_mux_cost; // bit_matrix_mux(map_ret, column_map, check_w);
bigint queue_clears = (pool+PERIOD-1)/PERIOD;
result += queue_clears*QUEUE_SIZE*postqueue;
result *= ITERS;
bigint perresetexceptfirst = 0;
perresetexceptfirst += bit_matrix_column_randompermutation_cost(N,K);
if (FW) perresetexceptfirst += 1; // alwayssystematic &= initial_alwayssystematic;
bigint perreset = perresetexceptfirst;
perreset -= column_swaps; // skipped on reset
perreset -= 1; // skipped on reset
perreset += 2*L*(N-K-1)*(N+1); // bit_matrix_randomize_rows
result += perreset*(ITERS/RESET);
result -= perresetexceptfirst; // skipped on iter == 0
result += PI*ram_write_cost(left,idx_bits,1); // ram_write(e, 0, (KK-Z)/2, set_ret.at(i), bit(1));
result += PI*ram_write_cost(right,idx_bits,1); // ram_write(e, (KK-Z)/2, KK-Z, set_ret.at(i), bit(1));
result += N*ram_write_cost(N,nbits(N-1),1); // ram_write(e_ret, map_ret.at(i), e.at(i));
result += fwcost;
return result;
}