int set_union(Set *st, const Set *st1, const Set *st2){ set_init(st, st1->destroy, st1->match); Node *pCurrentNode = list_head(st1); while(pCurrentNode){ /* trust use's st1 is a really set(no duplicate node) */ if(list_push(st, list_node_data(pCurrentNode)) != 0){ set_destroy(st); return -1; } pCurrentNode = list_node_next(pCurrentNode); } pCurrentNode = list_head(st2); while(pCurrentNode){ if(!set_is_member(st, list_node_data(pCurrentNode))){ if(list_push(st, list_node_data(pCurrentNode)) != 0){ set_destroy(st); return -1; } } pCurrentNode = list_node_next(pCurrentNode); } return 0; }
int bucket_insert(Bucket *buk, const void *data){ if(buk == NULL || data == NULL){ return -1; } int index = buk->hash(data) % buk->size; if(buk->buckets[index] == NULL){ if((buk->buckets[index] = (List *)malloc(sizeof(List))) == NULL){ return -1; } list_init(buk->buckets[index], buk->destroy, buk->compare); } Node *pNode = list_head(buk->buckets[index]); if(pNode == NULL){ list_push(buk->buckets[index], data); } else{ while(pNode){ if(buk->compare(data, list_node_data(pNode)) < 0){ list_insert(buk->buckets[index], pNode, data); return 0; } pNode = list_node_next(pNode); } list_push(buk->buckets[index], data); } return 0; }
void merge(List *lst, List *lst1, int (*compare)(const void *data1, const void *data2)){ Node *pNode=NULL, *pNode1=NULL; pNode = list_head(lst); pNode1 = list_head(lst1); List temp; list_init(&temp, NULL, NULL); while(pNode != NULL && pNode1 != NULL) { int cmpval = compare(list_node_data(pNode), list_node_data(pNode1)); if(cmpval < 0){ list_push(&temp, list_node_data(pNode)); pNode = list_node_next(pNode); } else{ list_push(&temp, list_node_data(pNode1)); pNode1 = list_node_next(pNode1); } } if(pNode != NULL){ while(pNode){ list_push(&temp, list_node_data(pNode)); pNode = list_node_next(pNode); } } if(pNode1 != NULL){ while(pNode1){ list_push(&temp, list_node_data(pNode1)); pNode1 = list_node_next(pNode1); } } void *data = NULL; while(list_pop(lst, &data) == 0){ /* nothing */ } pNode = list_head(&temp); while(pNode){ list_push(lst, list_node_data(pNode)); pNode = list_node_next(pNode); } list_destroy(&temp); return 0; }
int set_copy_to(const Set *st, Set *st1){ Node *pCurrentNode = list_head(st); while(pCurrentNode){ if(list_push(st1, list_node_data(pCurrentNode)) != 0){ return -1; } pCurrentNode = list_node_next(pCurrentNode); } }
static void delete_elements_from_tree(struct hash_table *hash, void **tree) { list_node *i; for (i=list_head(&hash->del_list); i != NULL; i=list_node_next(i)) tdelete(list_node_data_ptr(i,struct hash_element),tree, hash_data_cmp); }
static inline list_node_t *__list_iter_fwd(list_iter_t * self) { assert(self != NULL); assert(self->list != NULL); assert(self->node != NULL); if (self->node == &self->list->node) self->node = NULL; else self->node = list_node_next(self->node); return self->node; }
int set_is_subset(const Set *st, const Set *st1){ if(set_len(st) < set_len(st1)){ return 0; } Node *pCurrentNode = list_head(st1); while(pCurrentNode){ if(!set_is_member(st, list_node_data(pCurrentNode))){ return 0; } pCurrentNode = list_node_next(pCurrentNode); } return 1; }
int set_difference(Set *st, const Set *st1, const Set *st2){ set_init(st, st1->destroy, st1->match); Node *pCurrentNode = list_head(st1); while(pCurrentNode){ if(!set_is_member(st2, list_node_data(pCurrentNode))){ if(set_insert(st, list_node_data(pCurrentNode))!=0){ set_destroy(st); return -1; } } pCurrentNode = list_node_next(pCurrentNode); } return 0; }
//FIXME: add GLOBALFUNC, my eclipse goes crazy when i use a define to in function type BYTE* FIND_KEY(BYTE* S) { //C[i] --- + probability with it. SIGNED_BYTE C[P_SIZE] = {0}; SIGNED_BYTE C_bar[P_SIZE] = {0}; get_C_i(S, C, C_bar); //fill the C and C_bar arrays //find the probability of each optional sum of key bytes //TODO: (later) currently we only take the best guess list *current_guesses=list_init(); byte_sum_guess_t *initial_guess=(byte_sum_guess_t*)malloc(sizeof(byte_sum_guess_t)); initial_guess->i1 = 0; initial_guess->i2 = key_length-1; initial_guess->value = find_best_guess_for_s(S); //is this according to the end of 4.3 - any sum of l consecutive bytes indicates a guess for S initial_guess->w = 255; list_add(current_guesses,initial_guess); // initialize counters // TODO: find_best_guess_for_S should be removed, first guess should come from here as // well... BYTE_SUM cur_guess; list *guesses=list_init(); for (int left = 0; left < key_length - 1; ++left) for (int right = left; right < key_length -1; ++right) { // find guesses for the range from left to right. // insert wisely == don't unsigned int base = 0; // current position in S (multiples of key length) //list of guesses for the current values of left and right list *cur_val_list=list_init(); while (base + right < P_SIZE){ cur_guess=C[base + right]; if(base+left>0){ cur_guess -=C[base + left -1]; } cur_guess %= P_SIZE; if(cur_guess<0){ cur_guess+=P_SIZE; } //try to find value in list list_node *tmp=list_head(cur_val_list); for (; tmp!=NULL; tmp = list_node_next(tmp)){ if (list_node_data_ptr(tmp,byte_sum_guess_t)->value == cur_guess){ ++(list_node_data_ptr(tmp,byte_sum_guess_t)->w); break; } } if(tmp==NULL){ // couldn't find in list, enter new element to list byte_sum_guess_t *guess = (byte_sum_guess_t *)malloc(sizeof(byte_sum_guess_t)); guess->i1 = left; guess->i2 = right; guess->w = 1; guess->value = cur_guess; list_add(cur_val_list,guess); } base += key_length; } // while //Insert elements from cur_val_list to guesses list_node *tmp=list_head(cur_val_list); for (; tmp!=NULL; tmp = list_node_next(tmp)){ list_node *iter=list_head(guesses); if(iter==NULL){ list_add(guesses,list_node_data_ptr(tmp,byte_sum_guess_t)); continue; } for(;iter!=NULL ;iter=list_node_next(iter)){ if(list_node_data_ptr(iter,byte_sum_guess_t)->w <= list_node_data_ptr(tmp,byte_sum_guess_t)->w){ list_add_before(guesses,iter,list_node_data_ptr(tmp,byte_sum_guess_t)); break; } } if(iter==NULL){ list_add_tail(guesses, list_node_data_ptr(tmp,byte_sum_guess_t)); } } list_free(cur_val_list,NULL); } // for //we'll start by setting weights by "majority vote" and we'll later move to //assigning them according to the probability estimates (theorems 2 and 3) //see section 4.2 BYTE* ret = RECURSIVE_SUBROUTINE(1, current_guesses, guesses, list_head(guesses)); DEBUG_PRINT("Number of guesses is %ld\nNumber of bad matrices %ld\n",count_guesses,count_bad_matrix); //note: * (intution) we'll probably want to start working with rec-subroutine searching for the sums of a single key-byte // and going up to sums of 2,3 until l-1 key bytes (so that the stage with the "many" guesses is at the start of our recursion // * another option is to reverse it (it will possibly make our guesses better - again this is only intuition) // * a third option is to go for the keys where we have more possible guesses (based on the question if the length of the sum is // a generator of the additive group of 255 (again intuition mostly) //safety - return null return ret; }
//FIXME: add LOCALFUNC? (OR GLOBAL?) BYTE* RECURSIVE_SUBROUTINE(BYTE t, list *cur_guess, list *guesses, list_node *first_guess) { if ( t == key_length) { unsigned char* key=NULL; // generate key from the cur_guess (push guesses into a matrix and use some matrix solving library?) MAT* A; VEC *x,*b; PERM* pivot; A=m_get(key_length,key_length); b=v_get(key_length); x=v_get(key_length); int c=0,r=0; for(list_node* iter=list_head(cur_guess); iter != NULL && r<key_length; iter=list_node_next(iter)){ for(c=list_node_data_ptr(iter,byte_sum_guess_t)->i1; c <= list_node_data_ptr(iter,byte_sum_guess_t)->i2; ++c){ A->me[r][c]=1; } b->ve[r]=list_node_data_ptr(iter,byte_sum_guess_t)->value; ++r; } //Calculate matrix determinant SQRMATRIX A_det; SQRMATRIX_CreateMatrix(&A_det,key_length); for(r=0;r<key_length;++r){ for(c=0;c<key_length;++c){ A_det.array[r][c]=A->me[r][c]; } } int det; det=SQRMATRIX_CalcDeterminant(&A_det); //TODO: return this later SQRMATRIX_DestroyMatrix(&A_det); if(det==0){//If determinant is 0 continue to next guess ++count_bad_matrix; #ifdef __DEBUG //SQRMATRIX_DisplayMatrix(&A_det); v_output(b); #endif DEBUG_PRINT("Matrix determinant is 0\n"); }else{ ++count_guesses; pivot = px_get(A->m); LUfactor(A,pivot); x=LUsolve(A,pivot,b,VNULL); PX_FREE(pivot); //test key (use our RC4 impl) key=(unsigned char*)malloc(sizeof(unsigned char)*key_length); for(int i=0;i<key_length;++i){ key[i]=x->ve[i]; } int res=rc4_test_key(key); if(res){ printf("MAZAL TOV! we got the right key.\n"); print_key(key); printf("\n"); }else{ printf("Tried key: "); print_key(key); printf("\n"); free(key);key=NULL; } } //release matrix vars M_FREE(A); V_FREE(x); V_FREE(b); return key; } byte_sum_guess_t cur; //list *new_list_head=guesses; //TODO: (later) add a for loop running along the "lambeda_t" values here, for the initial impl we'll try the best guess //for () //{ for(int i=0; i<LAMBDA_T; ++i){ cur = *(list_node_data_ptr(first_guess, byte_sum_guess_t)); list_node *biatch = list_add_head(cur_guess, &cur); BYTE* res=RECURSIVE_SUBROUTINE(t+1, cur_guess, guesses, list_node_next(first_guess)); if(res!=NULL){ return res; } list_del(cur_guess,biatch); first_guess = list_node_next(first_guess); } return NULL; //TODO: do something to find the next guess and link it to the current guess //when I say something I mean find best guess (i.e best weight) of all the guesses that give us new information //(i.e not linearily dependent in our byte values and sums matrix that can be deduced from the cur_guess) //see also the note above (intuition) //IMPORTANT! //explaination how cur_guess is a matrix: each entry in cur_guess contains a list of bytes that are part of the sum and a //guess as to the value of the sum. if this matrix is solvable then solving it should give us a value for each byte of the //key thus the entire key //note: we probably should change cur_guess to a smarter database (for example a (L)x(L+1) matrix as an array?) but we //need to consider that we need to keep the ability to backtrack without making it too expensive //TODO: if weight of the guess is too small -> return FAIL (section 4.6) //These are based on section 4.4 //correct suggestions (this can be done later, basic alg should work without it) //adjust weights (this can be done later, basic alg should work without it) //merge counters (section 4.2), also skip for initial impl? need to check //go to next iteration in the recurtion //RECURSIVE_SUBROUTINE(t+1, cur_guess, ); //} end of for }