summaryrefslogtreecommitdiff
path: root/set1/task6.c
diff options
context:
space:
mode:
authorBenedict <benedict@0xb8000.de>2017-02-21 12:52:02 +0100
committerBenedict <benedict@0xb8000.de>2017-02-21 13:00:25 +0100
commitddce9b2d44ab48fc566870c5155b39c8fc06f24d (patch)
tree61e6f8d636190ef19f75bfd9cd8e4861ee04cf4f /set1/task6.c
parentf71df313c4480fb3edd91edb572d8013bec6d352 (diff)
moved files of set1 into subdir
Diffstat (limited to 'set1/task6.c')
-rw-r--r--set1/task6.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/set1/task6.c b/set1/task6.c
new file mode 100644
index 0000000..7055044
--- /dev/null
+++ b/set1/task6.c
@@ -0,0 +1,129 @@
+#include "../lib/lib.h"
+
+/**
+ * split ciphertext in blocks of size blocksize
+ * @return returns an array of string of size with blocksize elements
+ */
+
+
+char **transpose_blocks(char *ciphertext, int blocksize, int length)
+{
+ char **blocks;
+ int i, j;
+ int number_blocks = length / blocksize;
+
+ blocks = malloc(blocksize*(sizeof(char*)));
+
+ for(i=0;i<blocksize;i++) {
+ blocks[i] = malloc(number_blocks+1);
+ }
+
+ for(j=0;j<blocksize;j++) {
+ for(i=0;i<number_blocks;i++) {
+ blocks[j][i] = ciphertext[(i*blocksize)+j];
+ }
+ }
+
+ return blocks;
+}
+
+int main()
+{
+ FILE *fp;
+ int keysize;
+ char ch;
+ char *file_content, *new_file_content, *chiphertext, *block1, *block2;
+ int file_size = 60, file_pos = 0;
+ int i;
+ double min_hamming_distance, tmp;
+
+ fp = fopen("6.txt", "r");
+
+ if (fp == NULL) {
+ printf("Error open file\n");
+ exit(1);
+ }
+
+ file_content = malloc(file_size);
+
+ if (file_content == NULL) {
+ perror("out of memory");
+ exit(1);
+ }
+
+ // read data and decode it from base64
+ // result is not a hex strin or?
+
+ while ( (ch = fgetc(fp)) != EOF) {
+ // ignore new lines as this is part of base64
+ if (ch == '\n' || ch == '\r')
+ continue;
+
+ if (file_pos+1 >= file_size) {
+ new_file_content = realloc(file_content, (file_size+60));
+ if (new_file_content != NULL) {
+ file_content = new_file_content;
+ file_size += 60;
+ }
+ else {
+ printf("error allocating memory\n");
+ exit(1);
+ }
+ }
+ file_content[file_pos++] = ch;
+ }
+ file_content[file_pos] = '\0';
+
+ int ciphertext_len = 0;
+
+ chiphertext = malloc(file_pos+1);
+ ciphertext_len = decode_base64(file_content, chiphertext);
+
+ block1 = malloc(41);
+ block2 = malloc(41);
+
+ // max. hamming distacne is 100.
+ min_hamming_distance = 101;
+
+ int j=0;
+ // split ciphertext in 4 blocks of size 2 to 40
+ // and compute hamming distance of these blocks
+ for(i=2; i <= 40; i++) {
+ for(j=0;j< ciphertext_len/i;j++) {
+ memcpy(block1, &chiphertext[j], i);
+ block1[i+1] = '\0';
+ memcpy(block2, &chiphertext[j+i], i);
+ block2[i+1] = '\0';
+
+ tmp += (double) hamming_distance_equal_length(block1, block2, i);
+ }
+ tmp = ((double)tmp / (double) (ciphertext_len/i)/ (double)i);
+ if (tmp <= min_hamming_distance) {
+ min_hamming_distance = tmp;
+ keysize = i;
+ }
+ }
+
+ int number_blocks = ciphertext_len/keysize;
+ printf("use keysize: %i with hammind_distance: %f, number of blocks:%i\n", keysize, min_hamming_distance, number_blocks);
+ // split into keysize blcoks and transpose them
+ char **transposed_blocks = transpose_blocks(chiphertext, keysize, ciphertext_len);
+
+ char key[keysize+1];
+ struct key_and_freq tmp_NOT_USED_HERE;
+
+ for(i=0;i<keysize;i++) {
+ key[i] = brute_force_single_byte_xor(transposed_blocks[i],
+ number_blocks, &tmp_NOT_USED_HERE);
+ }
+
+ key[keysize+1] = '\0';
+ char *cleartext = malloc(ciphertext_len+1);
+ // xor with all single byte keys on the whole data
+ cleartext[ciphertext_len] = '\0';
+ xor_string(chiphertext, key, cleartext, keysize, ciphertext_len);
+
+ printf("%s\n", cleartext);
+ printf("used key: %s\n", key);
+ return 0;
+}