1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#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()
{
int keysize;
char *chiphertext, *block1, *block2;
char *file_content;
int i, file_length;
double min_hamming_distance, tmp;
int ciphertext_len;
file_length = read_base64_file("6.txt", &file_content);
printf("read: %i, address: %p\n", file_length, file_content);
chiphertext = malloc(file_length+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;
}
|