-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> &params,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; }