void sorthelper(int * arr, int ind1, int ind2) { int pivot = arr[ind1]; int left = ind1 + 1; int right = ind2; int temp; while(left < right) { while(arr[left] < pivot) { left++; } while(arr[right] > pivot) { right--; } temp = arr[right]; arr[right] = arr[left]; arr[left] = temp; } while(ind1 != ind2) { sorthelper(arr, ind1, left); sorthelper(arr, right, ind2); } }
/** * Sort an (ascending) array of integers * * Arguments: * arr The array to search * length Number of elements in the array * * Uses "quicksort" to sort "arr". Use the first element of the array * as the pivot. * * Your solution MUST use recursive function (or functions) * * quicksort works in the following way: * * find an element in the array (this element is called the * pivot). * * rearrange the array's elements into two parts: the part smaller * than this pivot and the part greater than this pivot; make the pivot * the element between these two parts * * sort the first and the second parts separately by repeating the * procedure described above * * You will receive no point if you use any other sorting algorithm. * You cannot use selection sort, merge sort, or bubble sort. * * Some students are fascinated by the name of bubble sort. In * reality, bubble sort is rarely used because it is slow. It is a * mystery why some students (or even professors) like bubble sort. * Other than the funny name, bubble sort has nothing special and is * inefficient, in both asymptotic complexity and the amount of data * movement. There are many algorithms much better than bubble sort. * You would not lose anything if you do not know (or forget) bubble * sort. * */ void sorthelper(int *arr, int first, int last) { int pivot; int high; int low; int temp; if (first < last) { pivot = first; low = first; high = last; while (low < high) { while(arr[low] <= arr[pivot] && low <= last) { low++; } while ((arr[high] > arr[pivot]) && (high >= first)) { high--; } if (low < high) { temp = arr[low]; arr[low] = arr[high]; arr[high] = temp; } } temp = arr[high]; arr[high] = arr[pivot]; arr[pivot] = temp; sorthelper(arr, first, high - 1); sorthelper(arr, high + 1, last); } }
void sort(int * arr, int length) { sorthelper(arr, 0, length); }
void sort(int * arr, int length) { return sorthelper(arr, 0, length - 1); }
/* * Guess which key bytes could be strong and start actual computation of the key */ int PTW_computeKey(PTW_attackstate * state, uint8_t * keybuf, int keylen, int testlimit) { int strongbytes[KEYHSBYTES]; double normal[KEYHSBYTES]; double ausreisser[KEYHSBYTES]; doublesorthelper helper[KEYHSBYTES]; int simple, onestrong, twostrong; int i,j; onestrong = (testlimit/10)*2; twostrong = (testlimit/10)*1; simple = testlimit - onestrong - twostrong; PTW_tableentry (*table)[n] = alloca(sizeof(PTW_tableentry) * n * keylen); if (table == NULL) { printf("could not allocate memory\n"); exit(-1); } memcpy(table, state->table, sizeof(PTW_tableentry) * n * keylen); // now, sort the table for (i = 0; i < keylen; i++) { qsort(&table[i][0], n, sizeof(PTW_tableentry), &compare); strongbytes[i] = 0; } sorthelper (* sh)[n-1] = alloca(sizeof(sorthelper) * (n-1) * keylen); if (sh == NULL) { printf("could not allocate memory\n"); exit(-1); } for (i = 0; i < keylen; i++) { for (j = 1; j < n; j++) { sh[i][j-1].distance = table[i][0].votes - table[i][j].votes; sh[i][j-1].value = table[i][j].b; sh[i][j-1].keybyte = i; } } qsort(sh, (n-1)*keylen, sizeof(sorthelper), &comparesorthelper); if (doComputation(state, keybuf, keylen, table, (sorthelper *) sh, strongbytes, simple)) { return 1; } // Now one strong byte getdrv(state->table, keylen, normal, ausreisser); for (i = 0; i < keylen-1; i++) { helper[i].keybyte = i+1; helper[i].difference = normal[i+1] - ausreisser[i+1]; } qsort(helper, keylen-1, sizeof(doublesorthelper), &comparedoublesorthelper); strongbytes[helper[0].keybyte] = 1; if (doComputation(state, keybuf, keylen, table, (sorthelper *) sh, strongbytes, onestrong)) { return 1; } // two strong bytes strongbytes[helper[1].keybyte] = 1; if (doComputation(state, keybuf, keylen, table, (sorthelper *) sh, strongbytes, twostrong)) { return 1; } return 0; }
/* * Guess which key bytes could be strong and start actual computation of the key */ int PTW_computeKey(PTW_attackstate * state, unsigned char * keybuf, int keylen, int testlimit, int * bf, int validchars[][n], int attacks) { int strongbytes[PTW_KEYHSBYTES]; double normal[PTW_KEYHSBYTES]; double ausreisser[PTW_KEYHSBYTES]; doublesorthelper helper[PTW_KEYHSBYTES]; int simple, onestrong, twostrong; int i,j; unsigned char fullkeybuf[PTW_KSBYTES]; unsigned char guessbuf[PTW_KSBYTES]; sorthelper(*sh)[n-1]; PTW_tableentry (*table)[n] = (PTW_tableentry (*)[n])alloca(sizeof(PTW_tableentry) * n * keylen); tried=0; sh = NULL; if (table == NULL) { printf("could not allocate memory\n"); exit(-1); } if(!(attacks & NO_KLEIN)) { // Try the original klein attack first for (i = 0; i < keylen; i++) { memset(&table[i][0], 0, sizeof(PTW_tableentry) * n); for (j = 0; j < n; j++) { table[i][j].b = j; } for (j = 0; j < state->packets_collected; j++) { // fullkeybuf[0] = state->allsessions[j].iv[0]; memcpy(fullkeybuf, state->allsessions[j].iv, 3 * sizeof(unsigned char)); guesskeybytes(i+3, fullkeybuf, state->allsessions[j].keystream, guessbuf, 1); table[i][guessbuf[0]].votes += state->allsessions[j].weight; } qsort(&table[i][0], n, sizeof(PTW_tableentry), &compare); j = 0; while(!validchars[i][table[i][j].b]) { j++; } // printf("guessing i = %d, b = %d\n", i, table[0][0].b); fullkeybuf[i+3] = table[i][j].b; } if (correct(state, &fullkeybuf[3], keylen)) { memcpy(keybuf, &fullkeybuf[3], keylen * sizeof(unsigned char)); // printf("hit without correction\n"); return 1; } } if(!(attacks & NO_PTW)) { memcpy(table, state->table, sizeof(PTW_tableentry) * n * keylen); onestrong = (testlimit/10)*2; twostrong = (testlimit/10)*1; simple = testlimit - onestrong - twostrong; // now, sort the table for (i = 0; i < keylen; i++) { qsort(&table[i][0], n, sizeof(PTW_tableentry), &compare); strongbytes[i] = 0; } sh = (sorthelper(*)[n-1])alloca(sizeof(sorthelper) * (n-1) * keylen); if (sh == NULL) { printf("could not allocate memory\n"); exit(-1); } for (i = 0; i < keylen; i++) { for (j = 1; j < n; j++) { sh[i][j-1].distance = table[i][0].votes - table[i][j].votes; sh[i][j-1].value = table[i][j].b; sh[i][j-1].keybyte = i; } } qsort(sh, (n-1)*keylen, sizeof(sorthelper), &comparesorthelper); if (doComputation(state, keybuf, keylen, table, (sorthelper *) sh, strongbytes, simple, bf, validchars)) { return 1; } // Now one strong byte getdrv(state->table, keylen, normal, ausreisser); for (i = 0; i < keylen-1; i++) { helper[i].keybyte = i+1; helper[i].difference = normal[i+1] - ausreisser[i+1]; } qsort(helper, keylen-1, sizeof(doublesorthelper), &comparedoublesorthelper); // do not use bf-bytes as strongbytes i = 0; while(bf[helper[i].keybyte] == 1) { i++; } strongbytes[helper[i].keybyte] = 1; if (doComputation(state, keybuf, keylen, table, (sorthelper *) sh, strongbytes, onestrong, bf, validchars)) { return 1; } // two strong bytes i++; while(bf[helper[i].keybyte] == 1) { i++; } strongbytes[helper[i].keybyte] = 1; if (doComputation(state, keybuf, keylen, table, (sorthelper *) sh, strongbytes, twostrong, bf, validchars)) { return 1; } } return 0; }