summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenedict <benedict@0xb8000.de>2017-02-02 00:32:26 +0100
committerBenedict <benedict@0xb8000.de>2017-02-21 13:00:27 +0100
commit1fd84c7dc70a0a6e6d8651fafa50c51dd697ae77 (patch)
treeaf5de3c7952e071c8e27800c41d9f945fa86c9e7
parent9dcc7348ad53cab8fd9396699de0177bac6729d5 (diff)
added random stuff which hasn't beend added because yeah
-rw-r--r--lib/.lib6.c.swpbin0 -> 24576 bytes
-rwxr-xr-xlib/a.outbin0 -> 18736 bytes
-rw-r--r--lib/lib.h1
-rw-r--r--lib/lib2.c31
-rw-r--r--lib/lib2.h3
-rw-r--r--lib/lib4.c196
-rw-r--r--lib/lib4.h16
-rw-r--r--lib/lib5.c6
-rw-r--r--lib/lib5.h2
-rw-r--r--lib/lib6.c216
-rw-r--r--lib/lib6.h30
-rw-r--r--lib/md4.c251
-rw-r--r--lib/mt_19937_tempering.txt34
-rw-r--r--lib/sha1.c391
-rw-r--r--lib/sha1.h56
-rw-r--r--lib/test.c24
-rw-r--r--lib/test_list.c51
-rwxr-xr-xlib/util/a.outbin0 -> 19368 bytes
-rw-r--r--lib/util/circulardoublelinkedlist.h54
-rw-r--r--lib/util/doublelinkedlist.h (renamed from lib/circulardoublelinkedlist.h)18
-rw-r--r--lib/util/hashtable.h (renamed from lib/hashtable.h)58
-rw-r--r--lib/util/hashtable.h.gchbin0 -> 2500240 bytes
-rw-r--r--lib/util/set.h39
-rw-r--r--lib/util/set.h.gchbin0 -> 2077904 bytes
-rw-r--r--lib/util/test_hash.c48
-rw-r--r--lib/util/util.c25
-rw-r--r--lib/util/util.h10
-rw-r--r--set2/task15.c12
-rw-r--r--set2/task9.c2
-rw-r--r--set3/task17.c59
-rw-r--r--set3/task17_01
-rw-r--r--set3/task17_11
-rw-r--r--set3/task17_21
-rw-r--r--set3/task17_31
-rw-r--r--set3/task17_41
-rw-r--r--set3/task17_51
-rw-r--r--set3/task17_61
-rw-r--r--set3/task17_71
-rw-r--r--set3/task17_81
-rw-r--r--set3/task17_91
-rw-r--r--set3/task19.c35
-rw-r--r--set3/task19_data/task19_001
-rw-r--r--set3/task19_data/task19_011
-rw-r--r--set3/task19_data/task19_021
-rw-r--r--set3/task19_data/task19_031
-rw-r--r--set3/task19_data/task19_041
-rw-r--r--set3/task19_data/task19_051
-rw-r--r--set3/task19_data/task19_061
-rw-r--r--set3/task19_data/task19_071
-rw-r--r--set3/task19_data/task19_081
-rw-r--r--set3/task19_data/task19_091
-rw-r--r--set3/task19_data/task19_101
-rw-r--r--set3/task19_data/task19_111
-rw-r--r--set3/task19_data/task19_121
-rw-r--r--set3/task19_data/task19_131
-rw-r--r--set3/task19_data/task19_141
-rw-r--r--set3/task19_data/task19_151
-rw-r--r--set3/task19_data/task19_161
-rw-r--r--set3/task19_data/task19_171
-rw-r--r--set3/task19_data/task19_181
-rw-r--r--set3/task19_data/task19_191
-rw-r--r--set3/task19_data/task19_201
-rw-r--r--set3/task19_data/task19_211
-rw-r--r--set3/task19_data/task19_221
-rw-r--r--set3/task19_data/task19_231
-rw-r--r--set3/task19_data/task19_241
-rw-r--r--set3/task19_data/task19_251
-rw-r--r--set3/task19_data/task19_261
-rw-r--r--set3/task19_data/task19_271
-rw-r--r--set3/task19_data/task19_281
-rw-r--r--set3/task19_data/task19_291
-rw-r--r--set3/task19_data/task19_301
-rw-r--r--set3/task19_data/task19_311
-rw-r--r--set3/task19_data/task19_321
-rw-r--r--set3/task19_data/task19_331
-rw-r--r--set3/task19_data/task19_341
-rw-r--r--set3/task19_data/task19_351
-rw-r--r--set3/task19_data/task19_361
-rw-r--r--set3/task19_data/task19_371
-rw-r--r--set3/task19_data/task19_381
-rw-r--r--set3/task19_data/task19_391
-rw-r--r--set3/task19_data/task19_all40
-rw-r--r--set3/task20_data/20.txt60
-rw-r--r--set3/task20_data/task20_001
-rw-r--r--set3/task20_data/task20_011
-rw-r--r--set3/task20_data/task20_021
-rw-r--r--set3/task20_data/task20_031
-rw-r--r--set3/task20_data/task20_041
-rw-r--r--set3/task20_data/task20_051
-rw-r--r--set3/task20_data/task20_061
-rw-r--r--set3/task20_data/task20_071
-rw-r--r--set3/task20_data/task20_081
-rw-r--r--set3/task20_data/task20_091
-rw-r--r--set3/task20_data/task20_101
-rw-r--r--set3/task20_data/task20_111
-rw-r--r--set3/task20_data/task20_121
-rw-r--r--set3/task20_data/task20_131
-rw-r--r--set3/task20_data/task20_141
-rw-r--r--set3/task20_data/task20_151
-rw-r--r--set3/task20_data/task20_161
-rw-r--r--set3/task20_data/task20_171
-rw-r--r--set3/task20_data/task20_181
-rw-r--r--set3/task20_data/task20_191
-rw-r--r--set3/task20_data/task20_201
-rw-r--r--set3/task20_data/task20_211
-rw-r--r--set3/task20_data/task20_221
-rw-r--r--set3/task20_data/task20_231
-rw-r--r--set3/task20_data/task20_241
-rw-r--r--set3/task20_data/task20_251
-rw-r--r--set3/task20_data/task20_261
-rw-r--r--set3/task20_data/task20_271
-rw-r--r--set3/task20_data/task20_281
-rw-r--r--set3/task20_data/task20_291
-rw-r--r--set3/task20_data/task20_301
-rw-r--r--set3/task20_data/task20_311
-rw-r--r--set3/task20_data/task20_321
-rw-r--r--set3/task20_data/task20_331
-rw-r--r--set3/task20_data/task20_341
-rw-r--r--set3/task20_data/task20_351
-rw-r--r--set3/task20_data/task20_361
-rw-r--r--set3/task20_data/task20_371
-rw-r--r--set3/task20_data/task20_381
-rw-r--r--set3/task20_data/task20_391
-rw-r--r--set3/task20_data/task20_401
-rw-r--r--set3/task20_data/task20_411
-rw-r--r--set3/task20_data/task20_421
-rw-r--r--set3/task20_data/task20_431
-rw-r--r--set3/task20_data/task20_441
-rw-r--r--set3/task20_data/task20_451
-rw-r--r--set3/task20_data/task20_461
-rw-r--r--set3/task20_data/task20_471
-rw-r--r--set3/task20_data/task20_481
-rw-r--r--set3/task20_data/task20_491
-rw-r--r--set3/task20_data/task20_501
-rw-r--r--set3/task20_data/task20_511
-rw-r--r--set3/task20_data/task20_521
-rw-r--r--set3/task20_data/task20_531
-rw-r--r--set3/task20_data/task20_541
-rw-r--r--set3/task20_data/task20_551
-rw-r--r--set3/task20_data/task20_561
-rw-r--r--set3/task20_data/task20_571
-rw-r--r--set3/task20_data/task20_581
-rw-r--r--set3/task20_data/task20_591
-rw-r--r--set4/task29.c67
-rw-r--r--set4/task30.c58
145 files changed, 1966 insertions, 37 deletions
diff --git a/lib/.lib6.c.swp b/lib/.lib6.c.swp
new file mode 100644
index 0000000..50e56d4
--- /dev/null
+++ b/lib/.lib6.c.swp
Binary files differ
diff --git a/lib/a.out b/lib/a.out
new file mode 100755
index 0000000..8fecb11
--- /dev/null
+++ b/lib/a.out
Binary files differ
diff --git a/lib/lib.h b/lib/lib.h
index a561442..20db486 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -25,5 +25,6 @@ int isprintable(char *string, int length);
int read_base64_file(const char *file, char **out);
int string_is_ecb_encrypted(char *string, int length_string, int blocksize);
char **transpose_blocks(char *ciphertext, int blocksize, int length);
+int isprintable(char *string, int length);
#endif /* __CYRPTO_LIB__ */
diff --git a/lib/lib2.c b/lib/lib2.c
index f9904b6..2d62305 100644
--- a/lib/lib2.c
+++ b/lib/lib2.c
@@ -71,20 +71,22 @@ int aes_cbc(char *in, int length_in, char *out, unsigned char *string_key, char
AES_KEY key;
int number_blocks = length_in / 16;
int i, j;
+ unsigned char debug[16];
unsigned char ciphertext[128+1];
unsigned char tmp_after_aes[128+1];
unsigned char cleartext[128+1];
// set the key and bits
+ memset(tmp_after_aes, 0, 129);
if(encrypt)
AES_set_encrypt_key(string_key, 128, &key);
else
AES_set_decrypt_key(string_key, 128, &key);
- memcpy(init_vector, iv, 16);
+ memcpy(iv, init_vector, 16);
// implement cbc mode
for(i=0;i<number_blocks;i++) {
- if (!encrypt) {
+ if (encrypt == 0) {
//do aes decryption
AES_decrypt(&in[i*16], tmp_after_aes, &key);
// xor
@@ -94,7 +96,7 @@ int aes_cbc(char *in, int length_in, char *out, unsigned char *string_key, char
iv[j] = in[i*16+j];
}
}
- else {
+ else if (encrypt == 1) {
// first xor
xor_string(iv, &in[i*16], tmp_after_aes, 16, 16);
// aes encrypt
@@ -109,6 +111,18 @@ int aes_cbc(char *in, int length_in, char *out, unsigned char *string_key, char
}
+int aes_cbc_padded(char *in, int length_in, char **out, unsigned char *string_key, char *init_vector, int encrypt)
+{
+ int padding, padded_length;
+ char *in_padded = __pkcs7_padding(in, length_in, 16, &padding);
+ padded_length = length_in + padding;
+ *out = malloc(padded_length + 16);
+ aes_cbc(in_padded, padded_length, *out, string_key, init_vector, encrypt);
+ memcpy(&((*out)[padded_length]), iv, 16);
+ return padded_length;
+}
+
+
int aes_ecb(char *in, int length_in, char *out, unsigned char *string_key,
int blocksize_bytes, int encrypt)
{
@@ -138,6 +152,17 @@ int random_number_between(int min, int max)
return (rand() % (max-min) + min);
}
+int generate_random_hex(char *buf, int length)
+{
+ int i;
+
+ for(i=0;i<length;i++) {
+ if (random_number_between(0,15) > 9)
+ buf[i] = random_number_between(48,57);
+ else
+ buf[i] = random_number_between(97,102);
+ }
+}
int generate_random_bytes(char *buf, int length_key_bytes)
{
diff --git a/lib/lib2.h b/lib/lib2.h
index 8e1ae98..f3c7e7b 100644
--- a/lib/lib2.h
+++ b/lib/lib2.h
@@ -21,6 +21,7 @@ int aes_cbc(char *in, int length_in, char *out, unsigned char *string_key, char
int valid_pkcs7_padding(const char *in, int length_in, char *unpadded, int blocksize);
int aes_ecb(char *in, int length_in, char *out, unsigned char *string_key,
int blocksize, int encrypt);
+int generate_random_hex(char *buf, int length_key_bytes);
int generate_random_bytes(char *buf, int length_key_bytes);
int random_number_between(int min, int max);
char *encrypt_with_random_bytes(char *toencrypt, int length, int ecb);
@@ -34,6 +35,6 @@ int challenge16_encrypt(char *input, char **encrypted, int cbc_mode);
void challenge16_decrypt(char *encrypted, int length, int cbc_mode);
int challenge12_and_14_oracle(char *attacker_data, int attacker_data_lengthn, char **ciphertext, int prepend_data);
int aes_ecb_detect_prepended_data();
-
+int aes_cbc_padded(char *in, int length_in, char **out, unsigned char *string_key, char *init_vector, int encrypt);
#endif
diff --git a/lib/lib4.c b/lib/lib4.c
index 1b25ef9..224adf0 100644
--- a/lib/lib4.c
+++ b/lib/lib4.c
@@ -22,6 +22,126 @@ int aes_ctr_edit(char *ciphertext, int ciphertext_length, int offset, char *newt
}
+unsigned int left_rotate(int shift, int value)
+{
+ // TODO make use of the x86 instruction rol, ror
+ unsigned int ret = value;
+ unsigned int mask = 0xFFFFFFFF << shift;
+ ret = ret << shift;
+ ret |= ((value & mask) >> (32-shift));
+ return ret;
+}
+
+void sha1_helper_copy_chunk(char *chunk, int *dest)
+{
+ int i;
+ for(i=0;i<16;i++) {
+ memcpy(&dest[i], &chunk[i], 4);
+ }
+}
+
+void sha1_hash(char *text, int text_length)
+{
+ unsigned char *padding;
+ char *hash;
+ int padding_len = sha1_padding(text_length, &padding);
+
+ char *to_hash = malloc(text_length + padding_len);
+
+ memcpy(to_hash, text, text_length);
+ memcpy(&to_hash[text_length], padding, padding_len);
+ hash_sha1_core(to_hash, (text_length + padding_len), &hash);
+ int i;
+ for(i=0;i<64;i++)
+ printf("%02x", hash[i]);
+ printf("\n");
+}
+
+void hash_sha1_core(char *text, int text_length, char **sha1_hash)
+{
+ *sha1_hash = malloc(20);
+ int i,j;
+ unsigned int h0 = 0x67452301;
+ unsigned int h1 = 0xEFCDAB89;
+ unsigned int h2 = 0x98BADCFE;
+ unsigned int h3 = 0x10325476;
+ unsigned int h4 = 0xC3D2E1F0;
+
+ unsigned int temp;
+ int chunks = (text_length*8) / 512;
+ unsigned int w[80];
+ unsigned int a,b,c,d,e,f,k;
+ char *chunk;
+
+ for(i=0;i<chunks;i++) {
+ // chunk is text[i*512]
+ // fill the first w[0]...w[15]
+ sha1_helper_copy_chunk(&text[i*512], w);
+
+ for(j=16;j<80;j++) {
+ w[j] = (w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16]);
+ w[j] = left_rotate(1, w[j]);
+ }
+
+ a = h0;
+ b = h1;
+ c = h2;
+ d = h3;
+ c = h4;
+
+ for(j=0;j<80;j++) {
+ if (i >= 0 && i <= 19) {
+ f = (b & c) | ((~b) & d);
+ k = 0x5A827999;
+ }
+ else if (i >= 20 && i <= 39) {
+ f = b ^ c ^ d;
+ k = 0x6ED9EBA1;
+ }
+ else if (i>= 40 && i <= 59) {
+ f = (b & c) | (b & d) | (c & d);
+ k = 0x8F1BBCDC;
+ }
+ else if (i >= 60 && i <= 79) {
+ f = b ^ c ^ d;
+ k = 0xCA62C1D6;
+ }
+
+ temp = left_rotate(5 ,a);
+ temp += f + e + k + w[j];
+ e = d;
+ d = c;
+ c = left_rotate(30, b);
+ b = a;
+ a = temp;
+
+ }
+
+ h0 += a;
+ h1 += b;
+ h2 += c;
+ h3 += d;
+ h4 += e;
+ }
+
+ // copy h_i into sha_hash
+ memcpy(*sha1_hash, &h0, 4);
+ memcpy(&((*sha1_hash)[4]), &h1, 4);
+ memcpy(&((*sha1_hash)[8]), &h2, 4);
+ memcpy(&((*sha1_hash)[12]), &h3, 4);
+ memcpy(&((*sha1_hash)[16]), &h4, 4);
+}
+
+void sha1_set_magic_nr(SHA1Context *sh, unsigned int *magic)
+{
+ sh->Message_Digest[0] = magic[0];
+ sh->Message_Digest[1] = magic[1];
+ sh->Message_Digest[2] = magic[2];
+ sh->Message_Digest[3] = magic[3];
+ sh->Message_Digest[4] = magic[4];
+}
+
+
void sha1_hmac(unsigned int *mac, unsigned char *message, unsigned int msg_len,
unsigned char *key, unsigned int key_len)
{
@@ -47,11 +167,21 @@ int sha1_hmac_verify(unsigned int *mac, unsigned char *msg, unsigned int msg_len
sha1_hmac(com_mac, msg, msg_len, key, key_len);
+ printf("mac of msg is:\n");
+ int i;
+ for(i=0;i<5;i++)
+ printf("%02x", com_mac[i]);
+ printf("\n");
+ printf("to compate with\n");
+ for(i=0;i<5;i++)
+ printf("%02x", mac[i]);
+ printf("\n");
+
return !memcmp(com_mac, mac, 20);
}
-int sha1_padding(unsigned long msg_len, char **result)
+int sha1_padding(unsigned long msg_len, unsigned char **result)
{
int i;
unsigned int padding_len = 64 - (msg_len % 64);
@@ -62,8 +192,7 @@ int sha1_padding(unsigned long msg_len, char **result)
memset((*result), 0x00, padding_len);
// append 1
- memset(&(*result)[0], 0x80, 1);
- //(*result)[0] = 0x80;
+ (*result)[0] = 0x80;
// write the 8 byte msg_len at the end bytewise
for(i=0;i<8;i++) {
@@ -77,12 +206,67 @@ void sha1_hmac_forge(unsigned int *mac, unsigned char *text, unsigned int text_l
unsigned int *sha1_registers)
{
SHA1Context sh;
- SHA1Reset(&sh);
+ SHA1Reset_Mod(&sh, sha1_registers);
- sha1_set_magic_nr(&sh, sha1_registers);
SHA1Input(&sh, text, text_len);
- SHA1Result(&sh);
+ SHA1Result_Forged(&sh);
memcpy(mac, &(sh.Message_Digest), 20);
}
+
+void md4_prefix_key_mac(uint32_t **mac, unsigned char *text, unsigned int text_len,
+ unsigned char *key, unsigned int key_len)
+{
+ char *res = malloc(text_len + key_len);
+
+ memcpy(res, text, text_len);
+ memcpy(res+text_len, key, key_len);
+
+ MD4(res, (text_len + key_len), mac, NULL);
+}
+
+int md4_prefix_key_verify(uint32_t *mac, unsigned char *text, unsigned int text_len,
+ unsigned char *key, unsigned int key_len)
+{
+ uint32_t *hash;
+
+ MD4(text, text_len, &hash, NULL);
+ printf("computed mac is:\n");
+ int i;
+ for(i=0;i<4;i++)
+ printf("%02x", hash[i]);
+ printf("\n");
+ return !memcmp(hash, mac, 4*sizeof(uint32_t));
+}
+
+void md4_prefix_key_forge(uint32_t **mac, unsigned char *text, unsigned int text_len,
+ unsigned int *md4_registers)
+{
+ MD4(text, text_len, mac, md4_registers);
+}
+
+uint32_t stringToUint32(char *s){
+ uint32_t l;
+ int i;
+ l=0;
+ for(i=0; i<4; i++){
+ l = l|(((uint32_t)((unsigned char)s[i]))<<(8*(3-i)));
+ }
+ return l;
+}
+
+uint32_t changeEndianness(uint32_t x){
+ return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | ((x & 0xFF000000) >> 24);
+}
+
+int md4_padding(unsigned long msg_len, unsigned char **result)
+{
+ int len = sha1_padding(msg_len, result);
+ int i;
+ //change endianess
+ for(i=0;i<len;i+=4)
+ (*result)[i] = changeEndianness(stringToUint32(&(*result)[i]));
+
+ return len;
+}
diff --git a/lib/lib4.h b/lib/lib4.h
index 08ecbcc..e159780 100644
--- a/lib/lib4.h
+++ b/lib/lib4.h
@@ -3,14 +3,26 @@
#include "sha1.h"
// sha1 constants
+#include <stdint.h>
-
+unsigned int left_rotate(int shift, int value);
int aes_ctr_edit(char *ciphertext, int ciphertext_length, int offset, char *newtext);
+void hash_sha1_core(char *text, int text_length, char **sha1_hash);
+void hash_sha1(char *text, int text_length, char **sha1_hash);
+void sha1_hash(char *text, int text_length);
void sha1_hmac(unsigned int *mac, unsigned char *message, unsigned int msg_len, unsigned char *key,
unsigned int key_len);
int sha1_hmac_verify(unsigned int *mac, unsigned char *msg, unsigned int msg_len,
unsigned char *key, unsigned int key_len);
-int sha1_padding(unsigned long msg_len, char **result);
+int sha1_padding(unsigned long msg_len, unsigned char **result);
void sha1_hmac_forge(unsigned int *mac, unsigned char *text, unsigned int text_len,
unsigned int *sha1_registers);
+void MD4(char *str, int len, uint32_t **hash, uint32_t *md4_registers);
+void md4_prefix_key_mac(uint32_t **mac, unsigned char *text, unsigned int text_len,
+ unsigned char *key, unsigned int key_len);
+int md4_prefix_key_verify(uint32_t *mac, unsigned char *text, unsigned int text_len,
+ unsigned char *key, unsigned int key_len);
+void md4_prefix_key_forge(uint32_t **mac, unsigned char *text, unsigned int text_len,
+ unsigned int *md4_registers);
+int md4_padding(unsigned long msg_len, unsigned char **result);
#endif
diff --git a/lib/lib5.c b/lib/lib5.c
index 1eb25e3..3be330d 100644
--- a/lib/lib5.c
+++ b/lib/lib5.c
@@ -417,12 +417,6 @@ int rsa_decrpyt(int message, struct rsa_key *private)
return modulo((message^private->exponent), private->modulo);
}
-void die(char *message)
-{
- printf("%s\n", message);
- exit(1);
-}
-
int rsa_encrypt_bignum(BIGNUM *message, BIGNUM *res, struct rsa_key_bignum *public)
{
return BN_mod_exp(res, message, public->exponent, public->modulo, ctx);
diff --git a/lib/lib5.h b/lib/lib5.h
index 43d8165..d30a2c0 100644
--- a/lib/lib5.h
+++ b/lib/lib5.h
@@ -7,6 +7,7 @@
#include <math.h>
#include <openssl/bn.h>
#include<openssl/bio.h>
+#include "util/util.h"
struct dh_param {
mpz_t A;
@@ -90,7 +91,6 @@ void sha1_key_from_dh(struct dh_param *dh, unsigned char *key);
void dh_mitm(struct dh_param *dh);
int rsa_decrypt_bignum(BIGNUM *message, BIGNUM *res, struct rsa_key_bignum *private);
int rsa_encrypt_bignum(BIGNUM *message, BIGNUM *res, struct rsa_key_bignum *public);
-void die(char *message);
int rsa_decrpyt(int message, struct rsa_key *private);
int rsa_encrypt(int message, struct rsa_key *public);
int modulo(int a, int b);
diff --git a/lib/lib6.c b/lib/lib6.c
index 5999e91..85dbd9e 100644
--- a/lib/lib6.c
+++ b/lib/lib6.c
@@ -4,6 +4,7 @@
#include "lib3.h"
#include "lib2.h"
#include "lib.h"
+#include "util/set.h"
#include <openssl/sha.h>
@@ -31,21 +32,20 @@ int rsa_verify_bignum(BIGNUM *signed_message, BIGNUM *org_message, struct rsa_ke
**/
void pkcs1_5_padding(char *message, char *result, unsigned int target_length_byte)
{
- SHA1Context sha1;
+ SHA_CTX sha1;
char sha1_hash[20];
int i;
memset(result, 0xff, target_length_byte);
result[0] = 0x00;
- result[1] = 0x01;
+ result[1] = 0x02;
result[target_length_byte-21] = 0x00;
// TODO ASN.1 things
- SHA1Reset(&sha1);
- SHA1Input(&sha1, message, strlen(message));
- SHA1Result(&sha1);
- memcpy(sha1_hash, &(sha1.Message_Digest), 20);
+ SHA1_Init(&sha1);
+ SHA1_Update(&sha1, message, strlen(message));
+ SHA1_Final(sha1_hash, &sha1);
for(i = 20;i>0;i--)
result[target_length_byte-i] = sha1_hash[20-i];
@@ -95,6 +95,9 @@ int shitty_pkcs1_5_padding_verify(char *to_verify, int len, char *message)
return 0;
}
+ char buf[(1024/8)*2];
+ hex_binary_to_string(to_verify, buf, len);
+ printf("got:\n%s\n", buf);
return 1;
}
@@ -245,3 +248,204 @@ int rsa_parity_orcale(BIGNUM *message, struct rsa_key_bignum *private)
rsa_decrypt_bignum(message, decrypted, private);
return BN_is_odd(decrypted);
}
+
+int rsa_bleichenbacher_orcale(BIGNUM *ciphertext, struct rsa_key_bignum *priv)
+{
+ int ret = 0;
+ BIGNUM *plaintext = BN_new();
+ rsa_decrypt_bignum(ciphertext, plaintext, priv);
+ char *p = malloc(BN_num_bytes(plaintext));
+ BN_bn2bin(plaintext, p);
+
+ if(p[0] == 0x02)
+ ret = 1;
+
+ free(p);
+ BN_free(plaintext);
+ return ret;
+}
+
+int bleichenbacher_prepare(BIGNUM *c_0, struct rsa_key_bignum *public,
+ struct bb_attack *b)
+{
+ b->_2a = BN_new();
+ b->one = BN_new();
+ b->two = BN_new();
+ b->three = BN_new();
+ b->B = BN_new();
+ b->_2B = BN_new();
+ b->_3B = BN_new();
+ b->c_0 = BN_new();
+ BIGNUM *tmp2 = BN_new();
+
+ BN_set_word(b->one, 1);
+ BN_set_word(b->two, 2);
+ BN_set_word(b->three, 3);
+ BN_copy(b->c_0, c_0);
+
+ unsigned long long k = (BN_num_bytes(public->modulo) - 2) * 8;
+ BN_set_word(tmp2, k);
+ BN_mod_exp(b->B, b->two, tmp2, public->modulo, ctx);
+ BN_mod_mul(b->_3B, b->B, b->three, public->modulo, ctx);
+ BN_mod_mul(b->_2B, b->B, b->two, public->modulo, ctx);
+ BN_div(b->_2a, NULL, public->modulo, b->_3B, ctx);
+ printf("\n2a\n");
+ BN_print(out, b->_2a);
+ printf("\n");
+}
+
+int bleichenbacher_step_2a(BIGNUM *s_i, struct rsa_key_bignum *public,
+ struct rsa_key_bignum *private, struct bb_attack *b)
+{
+ printf("bleichenbacher attack: step 2a\n");
+ BIGNUM *new_c = BN_new();
+
+ // start from 2a = c_0/3B
+ BN_copy(s_i, b->_2a);
+ printf("start with s_i:\n");
+ BN_print(out, s_i);
+
+ while(1) {
+ // c_0 * s^e = m_0 * s
+ BN_mod_exp(new_c, s_i, public->exponent, public->modulo, ctx);
+ BN_mod_mul(new_c, new_c, b->c_0, public->modulo, ctx);
+ // asking orcale if this ciphertext has valid pkcs
+ if(rsa_bleichenbacher_orcale(new_c, private)) {
+ break;
+ }
+ // try next number
+ BN_mod_add(s_i, s_i, b->one, public->modulo, ctx);
+ }
+ printf("\ns_i from step 2a:\n");
+ BN_print(out, s_i);
+}
+/**
+ * when methods get called, s_i contains s_i-1
+ **/
+int bleichenbacher_step_2c(struct interval *m, BIGNUM *s_i, struct rsa_key_bignum *public,
+ struct rsa_key_bignum *private, struct bb_attack *b)
+{
+ BIGNUM *r_i = BN_new();
+ BIGNUM *r_i_start = BN_new();
+ BIGNUM *s_i_1 = BN_new();
+ BIGNUM *tmp= BN_new();
+ BIGNUM *si_upper = BN_new();
+ BIGNUM *si_lower = BN_new();
+ BIGNUM *new_c = BN_new();
+
+ BN_copy(s_i_1, s_i);
+ // TODO set it here to look if it works for the first step
+ BN_copy(m->lower, b->_2B);
+ BN_copy(m->upper, b->_3B);
+
+ BN_mul(tmp, s_i_1, m->upper, ctx);
+ BN_sub(tmp, tmp, b->_2B);
+ BN_mul(tmp, tmp, b->two, ctx);
+ BN_div(r_i_start, NULL, tmp, public->modulo, ctx);
+ printf("tmp:\n");
+ BN_print(out, tmp);
+
+ printf("\nr_i start is:\n");
+ BN_print(out, r_i_start);
+
+ printf("\nout out out\n");
+ // compute s_i intervall, increment r_i in this loop
+ while(1) {
+ BN_mul(tmp, r_i, public->modulo, ctx);
+ BN_add(si_lower, b->_2B, tmp);
+ BN_div(si_lower, NULL, si_lower, m->upper, ctx);
+ BN_add(si_upper, b->_3B, tmp);
+ BN_div(si_upper, NULL, si_upper, m->lower, ctx);
+ printf("\nsi_lower\n");
+ BN_print(out, si_lower);
+ printf("\nsi_upper\n");
+ BN_print(out, si_upper);
+ // try all s_i in [si_lower, si_upper]
+ while(BN_cmp(s_i, si_upper) != 1) {
+ // for all s_i between [si_lower, si_upper]
+ BN_mod_exp(tmp, s_i, public->exponent, public->modulo, ctx);
+ BN_mod_mul(new_c, tmp, b->c_0, public->modulo, ctx);
+ // try if we get valid pkcs padding
+ if(rsa_bleichenbacher_orcale(new_c, private))
+ goto found_si;
+
+ BN_add(s_i, s_i, b->one);
+ }
+ }
+
+
+found_si:
+ printf("found s_i in step 2c:\n");
+ BN_print(out, s_i);
+}
+
+/**
+ * Narrowing down the solution
+ **/
+
+/**
+int bleichenbacher_step_3(BIGNUM *s_i, set_t *m_i1)
+{
+ struct list *intervall, *head;
+ // compute m_i from m_i-1
+ LIST_TO_END(intervall, head) {
+
+ }
+
+}
+**/
+
+BIGNUM *BN_max(BIGNUM *e1, BIGNUM *e2)
+{
+ if(BN_cmp(e1, e2) == 1)
+ return e1;
+ else
+ return e2;
+}
+
+/**
+ * returns 1 if the intervall have been merged (one intervall),
+ * 2 if intevalls not overlapping (two intervalls)
+ **/
+int iv_merge2(struct interval *left, struct interval *right)
+{
+ if(!(BN_cmp(left->upper, right->lower) == -1)) {
+ BN_copy(left->upper, BN_max(left->upper, right->upper));
+ return 1;
+ }
+
+ return 2;
+}
+
+/**
+ * returns 1 if all three intervalls have merged to one, res in left
+ * returns 2 if the left + middle has been merged and the right not, res in left
+ * returns 3 if none have been merged
+ * retuern 4 if the middle and the right has been merged and left not, res in middle
+ *
+ **/
+
+int iv_merge3(struct interval *left, struct interval *middle, struct interval *rigth)
+{
+ if(iv_merge2(left, middle) == 1) {
+ if (iv_merge2(left, rigth) == 1)
+ return 1;
+ else
+ return 2;
+ } else {
+ if(iv_merge2(middle, rigth) == 1)
+ return 4;
+ else
+ return 3;
+ }
+
+}
+
+void iv_printf(struct interval *e1)
+{
+ printf("lower:");
+ BN_print(out, e1->lower);
+ printf("\nupper:");
+ BN_print(out, e1->upper);
+ printf("\n");
+}
diff --git a/lib/lib6.h b/lib/lib6.h
index a1cfa15..3923bbf 100644
--- a/lib/lib6.h
+++ b/lib/lib6.h
@@ -6,6 +6,25 @@
#include "lib3.h"
#include "lib2.h"
#include "lib.h"
+#include "util/doublelinkedlist.h"
+
+
+struct bb_attack {
+ BIGNUM *_2a;
+ BIGNUM *B;
+ BIGNUM *_2B;
+ BIGNUM *_3B;
+ BIGNUM *one;
+ BIGNUM *two;
+ BIGNUM *three;
+ BIGNUM *c_0;
+};
+
+struct interval {
+ BIGNUM *lower;
+ BIGNUM *upper;
+ struct list list;
+};
struct dsa_public_params {
@@ -43,4 +62,15 @@ void dsa_recover_k_from_repeated_nonce(BIGNUM *mess1_hash, BIGNUM *mess2_hash,
void dsa_generate_magic_signature(struct dsa_public_params *pub, struct dsa_per_user_param
*priv, BIGNUM *mess_hash);
int rsa_parity_orcale(BIGNUM *message, struct rsa_key_bignum *private);
+void pkcs1_5_padding(char *message, char *result, unsigned int target_length_byte);
+int bleichenbacher_prepare(BIGNUM *c_0, struct rsa_key_bignum *public, struct bb_attack *b);
+int bleichenbacher_step_2a(BIGNUM *s_i, struct rsa_key_bignum *public,
+ struct rsa_key_bignum *private, struct bb_attack *b);
+int bleichenbacher_step_2c(struct interval *m, BIGNUM *s_i, struct rsa_key_bignum *public,
+ struct rsa_key_bignum *privat, struct bb_attack *b);
+//int bleichenbacher_step_3(BIGNUM *s_i, set_t *m_i1);
+int iv_merge2(struct interval *left, struct interval *right);
+int iv_merge3(struct interval *left, struct interval *middle, struct interval *rigth);
+int iv_list_insert(struct interval *iv, struct list *list);
+void iv_printf(struct interval *e1);
#endif /* __LIB_6_H__ */
diff --git a/lib/md4.c b/lib/md4.c
new file mode 100644
index 0000000..031e74b
--- /dev/null
+++ b/lib/md4.c
@@ -0,0 +1,251 @@
+/*
+ *
+ * Author: George Mossessian
+ *
+ * The MD4 hash algorithm, as described in https://tools.ietf.org/html/rfc1320
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+
+typedef struct string{
+ char *c;
+ int len;
+ char sign;
+}string;
+
+static uint32_t *MD4Digest(uint32_t *w, int len);
+static void setMD4Registers(uint32_t AA, uint32_t BB, uint32_t CC, uint32_t DD);
+static uint32_t changeEndianness(uint32_t x);
+static void resetMD4Registers(void);
+static string stringCat(string first, string second);
+static string uint32ToString(uint32_t l);
+static uint32_t stringToUint32(string s);
+
+static const char *BASE16 = "0123456789abcdef=";
+
+#define F(X,Y,Z) (((X)&(Y))|((~(X))&(Z)))
+#define G(X,Y,Z) (((X)&(Y))|((X)&(Z))|((Y)&(Z)))
+#define H(X,Y,Z) ((X)^(Y)^(Z))
+
+#define LEFTROTATE(A,N) ((A)<<(N))|((A)>>(32-(N)))
+
+#define MD4ROUND1(a,b,c,d,x,s) a += F(b,c,d) + x; a = LEFTROTATE(a, s);
+#define MD4ROUND2(a,b,c,d,x,s) a += G(b,c,d) + x + (uint32_t)0x5A827999; a = LEFTROTATE(a, s);
+#define MD4ROUND3(a,b,c,d,x,s) a += H(b,c,d) + x + (uint32_t)0x6ED9EBA1; a = LEFTROTATE(a, s);
+
+static uint32_t A = 0x67452301;
+static uint32_t B = 0xefcdab89;
+static uint32_t C = 0x98badcfe;
+static uint32_t D = 0x10325476;
+
+string newString(char * c, int t){
+ string r;
+ int i;
+ if(c!=NULL){
+ r.len = (t<=0)?strlen(c):t;
+ r.c=(char *)malloc(sizeof(char)*(r.len+1));
+ for(i=0; i<r.len; i++) r.c[i]=c[i];
+ r.c[r.len]='\0';
+ return r;
+ }
+ r.len=t;
+ r.c=(char *)malloc(sizeof(char)*(r.len+1));
+ memset(r.c,(char)0,sizeof(char)*(t+1));
+ r.sign = 1;
+ return r;
+}
+
+string stringCat(string first, string second){
+ string str=newString(NULL, first.len+second.len);
+ int i;
+
+ for(i=0; i<first.len; i++){
+ str.c[i]=first.c[i];
+ }
+ for(i=first.len; i<str.len; i++){
+ str.c[i]=second.c[i-first.len];
+ }
+ return str;
+}
+
+string base16Encode(string in){
+ string out=newString(NULL, in.len*2);
+ int i,j;
+
+ j=0;
+ for(i=0; i<in.len; i++){
+ out.c[j++]=BASE16[((in.c[i] & 0xF0)>>4)];
+ out.c[j++]=BASE16[(in.c[i] & 0x0F)];
+ }
+ out.c[j]='\0';
+ return out;
+}
+
+
+string uint32ToString(uint32_t l){
+ string s = newString(NULL,4);
+ int i;
+ for(i=0; i<4; i++){
+ s.c[i] = (l >> (8*(3-i))) & 0xFF;
+ }
+ return s;
+}
+
+uint32_t stringToUint32(string s){
+ uint32_t l;
+ int i;
+ l=0;
+ for(i=0; i<4; i++){
+ l = l|(((uint32_t)((unsigned char)s.c[i]))<<(8*(3-i)));
+ }
+ return l;
+}
+
+void MD4(char *str, int len, uint32_t **hash, uint32_t *start){
+ string m=newString(str, len);
+ uint32_t *w;
+ uint64_t mlen=m.len;
+ unsigned char oneBit = 0x80;
+ int i, wlen = m.len+2;
+
+ if(!start) {
+ m=stringCat(m, newString((char *)&oneBit,1));
+
+ //append 0 ≤ k < 512 bits '0', such that the resulting message length in bits
+ //is congruent to −64 ≡ 448 (mod 512)4
+ i=((56-m.len)%64);
+ if(i<0) i+=64;
+ m=stringCat(m,newString(NULL, i));
+
+ w = malloc(sizeof(uint32_t)*(m.len/4+2));
+
+ //append length, in bits (hence <<3), least significant word first
+ for(i=0; i<m.len/4; i++){
+ w[i]=stringToUint32(newString(&(m.c[4*i]), 4));
+ }
+ w[i++] = (mlen<<3) & 0xFFFFFFFF;
+ w[i++] = (mlen>>29) & 0xFFFFFFFF;
+
+ wlen=i;
+ }
+ else {
+ w = malloc(sizeof(uint32_t)*(m.len/4+2));
+ for(i=0;i<m.len/4;i++)
+ w[i] = stringToUint32(newString(&(m.c[4*i]),4));
+ }
+
+ //change endianness, but not for the appended message length, for some reason?
+ for(i=0; i<wlen-2; i++){
+ w[i]=changeEndianness(w[i]);
+ }
+
+ if (start)
+ setMD4Registers(start[0], start[1], start[2], start[3]);
+
+ *hash = MD4Digest(w,wlen);
+
+ for(i=0; i<4; i++){
+ (*hash)[i]=changeEndianness((*hash)[i]);
+ }
+}
+
+uint32_t *MD4Digest(uint32_t *w, int len){
+ //assumes message.len is a multiple of 64 bytes.
+ int i,j;
+ uint32_t X[16];
+ uint32_t *digest = malloc(sizeof(uint32_t)*4);
+ uint32_t AA, BB, CC, DD;
+
+ for(i=0; i<len/16; i++){
+ for(j=0; j<16; j++){
+ X[j]=w[i*16+j];
+ }
+
+ AA=A;
+ BB=B;
+ CC=C;
+ DD=D;
+
+ MD4ROUND1(A,B,C,D,X[0],3);
+ MD4ROUND1(D,A,B,C,X[1],7);
+ MD4ROUND1(C,D,A,B,X[2],11);
+ MD4ROUND1(B,C,D,A,X[3],19);
+ MD4ROUND1(A,B,C,D,X[4],3);
+ MD4ROUND1(D,A,B,C,X[5],7);
+ MD4ROUND1(C,D,A,B,X[6],11);
+ MD4ROUND1(B,C,D,A,X[7],19);
+ MD4ROUND1(A,B,C,D,X[8],3);
+ MD4ROUND1(D,A,B,C,X[9],7);
+ MD4ROUND1(C,D,A,B,X[10],11);
+ MD4ROUND1(B,C,D,A,X[11],19);
+ MD4ROUND1(A,B,C,D,X[12],3);
+ MD4ROUND1(D,A,B,C,X[13],7);
+ MD4ROUND1(C,D,A,B,X[14],11);
+ MD4ROUND1(B,C,D,A,X[15],19);
+
+ MD4ROUND2(A,B,C,D,X[0],3);
+ MD4ROUND2(D,A,B,C,X[4],5);
+ MD4ROUND2(C,D,A,B,X[8],9);
+ MD4ROUND2(B,C,D,A,X[12],13);
+ MD4ROUND2(A,B,C,D,X[1],3);
+ MD4ROUND2(D,A,B,C,X[5],5);
+ MD4ROUND2(C,D,A,B,X[9],9);
+ MD4ROUND2(B,C,D,A,X[13],13);
+ MD4ROUND2(A,B,C,D,X[2],3);
+ MD4ROUND2(D,A,B,C,X[6],5);
+ MD4ROUND2(C,D,A,B,X[10],9);
+ MD4ROUND2(B,C,D,A,X[14],13);
+ MD4ROUND2(A,B,C,D,X[3],3);
+ MD4ROUND2(D,A,B,C,X[7],5);
+ MD4ROUND2(C,D,A,B,X[11],9);
+ MD4ROUND2(B,C,D,A,X[15],13);
+
+ MD4ROUND3(A,B,C,D,X[0],3);
+ MD4ROUND3(D,A,B,C,X[8],9);
+ MD4ROUND3(C,D,A,B,X[4],11);
+ MD4ROUND3(B,C,D,A,X[12],15);
+ MD4ROUND3(A,B,C,D,X[2],3);
+ MD4ROUND3(D,A,B,C,X[10],9);
+ MD4ROUND3(C,D,A,B,X[6],11);
+ MD4ROUND3(B,C,D,A,X[14],15);
+ MD4ROUND3(A,B,C,D,X[1],3);
+ MD4ROUND3(D,A,B,C,X[9],9);
+ MD4ROUND3(C,D,A,B,X[5],11);
+ MD4ROUND3(B,C,D,A,X[13],15);
+ MD4ROUND3(A,B,C,D,X[3],3);
+ MD4ROUND3(D,A,B,C,X[11],9);
+ MD4ROUND3(C,D,A,B,X[7],11);
+ MD4ROUND3(B,C,D,A,X[15],15);
+
+ A+=AA;
+ B+=BB;
+ C+=CC;
+ D+=DD;
+ }
+
+ digest[0]=A;
+ digest[1]=B;
+ digest[2]=C;
+ digest[3]=D;
+ resetMD4Registers();
+ return digest;
+}
+
+uint32_t changeEndianness(uint32_t x){
+ return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | ((x & 0xFF000000) >> 24);
+}
+
+void setMD4Registers(uint32_t AA, uint32_t BB, uint32_t CC, uint32_t DD){
+ A=AA;
+ B=BB;
+ C=CC;
+ D=DD;
+}
+
+void resetMD4Registers(void){
+ setMD4Registers(0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476);
+}
diff --git a/lib/mt_19937_tempering.txt b/lib/mt_19937_tempering.txt
new file mode 100644
index 0000000..dfdda7a
--- /dev/null
+++ b/lib/mt_19937_tempering.txt
@@ -0,0 +1,34 @@
+Why can we reverse the tempering function?
+
+There are to kinds of operations in the tempering function of the MT:
+
+ 1) Right shift
+ 2) Left shift with an AND
+
+To undo the first operation, a simple shift is straight forward. Let's consider
+the following example of a 24-bit number
+
+ 0010 1010 1011 1101 1111 0111 y
+ 0000 0000 0000 0000 0000 1010 1010 1111 0111 1101 11 y >> 18 := N
+ ^
+ orginal string
+ 0010 1010 1011 1101 1111 1101 y ^ (y>>18) := M
+
+
+On can see, that the first 18 bits of M are the same than y. That's clear,
+because we have shifted 18 new 0 into it. But now we also now N completly, since
+the last 6 bits are the first 6 of M (N is a shifted version of M).
+If you shift less than 24/2 = 12 bits, you have to do the above steps in a
+loop, because you cannot determin N completly one step.
+
+To understand why one can undo the second operation was a bit harder for me.
+For me it was the easiest to understand it with the feistel network.
+
+
+ y y << 15
+ | |
+ | |
+ XOR<--------- F <-----------
+ | |
+ \_______________________ /
+ /\______________________
diff --git a/lib/sha1.c b/lib/sha1.c
new file mode 100644
index 0000000..5a0b117
--- /dev/null
+++ b/lib/sha1.c
@@ -0,0 +1,391 @@
+/*
+ * sha1.c
+ *
+ * Copyright (C) 1998, 2009
+ * Paul E. Jones <paulej@packetizer.com>
+ * All Rights Reserved
+ *
+ *****************************************************************************
+ * $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $
+ *****************************************************************************
+ *
+ * Description:
+ * This file implements the Secure Hashing Standard as defined
+ * in FIPS PUB 180-1 published April 17, 1995.
+ *
+ * The Secure Hashing Standard, which uses the Secure Hashing
+ * Algorithm (SHA), produces a 160-bit message digest for a
+ * given data stream. In theory, it is highly improbable that
+ * two messages will produce the same message digest. Therefore,
+ * this algorithm can serve as a means of providing a "fingerprint"
+ * for a message.
+ *
+ * Portability Issues:
+ * SHA-1 is defined in terms of 32-bit "words". This code was
+ * written with the expectation that the processor has at least
+ * a 32-bit machine word size. If the machine word size is larger,
+ * the code should still function properly. One caveat to that
+ * is that the input functions taking characters and character
+ * arrays assume that only 8 bits of information are stored in each
+ * character.
+ *
+ * Caveats:
+ * SHA-1 is designed to work with messages less than 2^64 bits
+ * long. Although SHA-1 allows a message digest to be generated for
+ * messages of any number of bits less than 2^64, this
+ * implementation only works with messages with a length that is a
+ * multiple of the size of an 8-bit character.
+ *
+ */
+
+#include "sha1.h"
+
+/*
+ * Define the circular shift macro
+ */
+#define SHA1CircularShift(bits,word) \
+ ((((word) << (bits)) & 0xFFFFFFFF) | \
+ ((word) >> (32-(bits))))
+
+/* Function prototypes */
+void SHA1ProcessMessageBlock(SHA1Context *);
+void SHA1PadMessage(SHA1Context *);
+
+/*
+ * SHA1Reset
+ *
+ * Description:
+ * This function will initialize the SHA1Context in preparation
+ * for computing a new message digest.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to reset.
+ *
+ * Returns:
+ * Nothing.
+ *
+ * Comments:
+ *
+ */
+void SHA1Reset(SHA1Context *context)
+{
+ context->Length_Low = 0;
+ context->Length_High = 0;
+ context->Message_Block_Index = 0;
+
+ context->Message_Digest[0] = 0x67452301;
+ context->Message_Digest[1] = 0xEFCDAB89;
+ context->Message_Digest[2] = 0x98BADCFE;
+ context->Message_Digest[3] = 0x10325476;
+ context->Message_Digest[4] = 0xC3D2E1F0;
+
+ context->Computed = 0;
+ context->Corrupted = 0;
+}
+
+void SHA1Reset_Mod(SHA1Context *context, unsigned int *init)
+{
+ context->Length_Low = 0;
+ context->Length_High = 0;
+ context->Message_Block_Index = 0;
+
+ context->Message_Digest[0] = init[0];
+ context->Message_Digest[1] = init[1];
+ context->Message_Digest[2] = init[2];
+ context->Message_Digest[3] = init[3];
+ context->Message_Digest[4] = init[4];
+
+ context->Computed = 0;
+ context->Corrupted = 0;
+}
+/*
+ * SHA1Result
+ *
+ * Description:
+ * This function will return the 160-bit message digest into the
+ * Message_Digest array within the SHA1Context provided
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to use to calculate the SHA-1 hash.
+ *
+ * Returns:
+ * 1 if successful, 0 if it failed.
+ *
+ * Comments:
+ *
+ */
+int SHA1Result(SHA1Context *context)
+{
+
+ if (context->Corrupted) {
+ return 0;
+ }
+
+ if (!context->Computed) {
+ SHA1PadMessage(context);
+ context->Computed = 1;
+ }
+
+ return 1;
+}
+
+int SHA1Result_Forged(SHA1Context *context)
+{
+ if (context->Corrupted) {
+ return 0;
+ }
+
+ if (!context->Computed) {
+ // do not pad forged extension
+ // we added the padding ourselves
+ context->Computed = 1;
+ }
+
+ return 1;
+}
+
+/*
+ * SHA1Input
+ *
+ * Description:
+ * This function accepts an array of octets as the next portion of
+ * the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA-1 context to update
+ * message_array: [in]
+ * An array of characters representing the next portion of the
+ * message.
+ * length: [in]
+ * The length of the message in message_array
+ *
+ * Returns:
+ * Nothing.
+ *
+ * Comments:
+ *
+ */
+void SHA1Input(SHA1Context *context, const unsigned char *message_array, unsigned length)
+{
+ if (!length) {
+ return;
+ }
+
+ if (context->Computed || context->Corrupted) {
+ context->Corrupted = 1;
+ return;
+ }
+
+ while(length-- && !context->Corrupted) {
+ context->Message_Block[context->Message_Block_Index++] = (*message_array & 0xFF);
+
+ context->Length_Low += 8;
+ /* Force it to 32 bits */
+ context->Length_Low &= 0xFFFFFFFF;
+ if (context->Length_Low == 0) {
+ context->Length_High++;
+ /* Force it to 32 bits */
+ context->Length_High &= 0xFFFFFFFF;
+ if (context->Length_High == 0) {
+ /* Message is too long */
+ context->Corrupted = 1;
+ }
+ }
+
+ if (context->Message_Block_Index == 64) {
+ SHA1ProcessMessageBlock(context);
+ }
+
+ message_array++;
+ }
+// printf("\n");
+}
+
+/*
+ * SHA1ProcessMessageBlock
+ *
+ * Description:
+ * This function will process the next 512 bits of the message
+ * stored in the Message_Block array.
+ *
+ * Parameters:
+ * None.
+ *
+ * Returns:
+ * Nothing.
+ *
+ * Comments:
+ * Many of the variable names in the SHAContext, especially the
+ * single character names, were used because those were the names
+ * used in the publication.
+ *
+ *
+ */
+void SHA1ProcessMessageBlock(SHA1Context *context)
+{
+ const unsigned K[] = /* Constants defined in SHA-1 */
+ {
+ 0x5A827999,
+ 0x6ED9EBA1,
+ 0x8F1BBCDC,
+ 0xCA62C1D6
+ };
+ int t; /* Loop counter */
+ unsigned temp; /* Temporary word value */
+ unsigned W[80]; /* Word sequence */
+ unsigned A, B, C, D, E; /* Word buffers */
+
+ /*
+ * Initialize the first 16 words in the array W
+ */
+ for(t = 0; t < 16; t++)
+ {
+ W[t] = ((unsigned) context->Message_Block[t * 4]) << 24;
+ W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16;
+ W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8;
+ W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]);
+ }
+
+ for(t = 16; t < 80; t++)
+ {
+ W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
+ }
+
+ A = context->Message_Digest[0];
+ B = context->Message_Digest[1];
+ C = context->Message_Digest[2];
+ D = context->Message_Digest[3];
+ E = context->Message_Digest[4];
+
+ for(t = 0; t < 20; t++)
+ {
+ temp = SHA1CircularShift(5,A) +
+ ((B & C) | ((~B) & D)) + E + W[t] + K[0];
+ temp &= 0xFFFFFFFF;
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for(t = 20; t < 40; t++)
+ {
+ temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
+ temp &= 0xFFFFFFFF;
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for(t = 40; t < 60; t++)
+ {
+ temp = SHA1CircularShift(5,A) +
+ ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
+ temp &= 0xFFFFFFFF;
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for(t = 60; t < 80; t++)
+ {
+ temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
+ temp &= 0xFFFFFFFF;
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ context->Message_Digest[0] =
+ (context->Message_Digest[0] + A) & 0xFFFFFFFF;
+ context->Message_Digest[1] =
+ (context->Message_Digest[1] + B) & 0xFFFFFFFF;
+ context->Message_Digest[2] =
+ (context->Message_Digest[2] + C) & 0xFFFFFFFF;
+ context->Message_Digest[3] =
+ (context->Message_Digest[3] + D) & 0xFFFFFFFF;
+ context->Message_Digest[4] =
+ (context->Message_Digest[4] + E) & 0xFFFFFFFF;
+
+ context->Message_Block_Index = 0;
+}
+
+/*
+ * SHA1PadMessage
+ *
+ * Description:
+ * According to the standard, the message must be padded to an even
+ * 512 bits. The first padding bit must be a '1'. The last 64
+ * bits represent the length of the original message. All bits in
+ * between should be 0. This function will pad the message
+ * according to those rules by filling the Message_Block array
+ * accordingly. It will also call SHA1ProcessMessageBlock()
+ * appropriately. When it returns, it can be assumed that the
+ * message digest has been computed.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to pad
+ *
+ * Returns:
+ * Nothing.
+ *
+ * Comments:
+ *
+ */
+void SHA1PadMessage(SHA1Context *context)
+{
+ /*
+ * Check to see if the current message block is too small to hold
+ * the initial padding bits and length. If so, we will pad the
+ * block, process it, and then continue padding into a second
+ * block.
+ */
+ if (context->Message_Block_Index > 55)
+ {
+ context->Message_Block[context->Message_Block_Index++] = 0x80;
+ while(context->Message_Block_Index < 64)
+ {
+ context->Message_Block[context->Message_Block_Index++] = 0;
+ }
+
+ SHA1ProcessMessageBlock(context);
+
+ while(context->Message_Block_Index < 56)
+ {
+ context->Message_Block[context->Message_Block_Index++] = 0;
+ }
+ }
+ else
+ {
+ context->Message_Block[context->Message_Block_Index++] = 0x80;
+ while(context->Message_Block_Index < 56)
+ {
+ context->Message_Block[context->Message_Block_Index++] = 0;
+ }
+ }
+
+ /*
+ * Store the message length as the last 8 octets
+ */
+ context->Message_Block[56] = (context->Length_High >> 24) & 0xFF;
+ context->Message_Block[57] = (context->Length_High >> 16) & 0xFF;
+ context->Message_Block[58] = (context->Length_High >> 8) & 0xFF;
+ context->Message_Block[59] = (context->Length_High) & 0xFF;
+ context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF;
+ context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF;
+ context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF;
+ context->Message_Block[63] = (context->Length_Low) & 0xFF;
+ SHA1ProcessMessageBlock(context);
+}
+
diff --git a/lib/sha1.h b/lib/sha1.h
new file mode 100644
index 0000000..27f98d2
--- /dev/null
+++ b/lib/sha1.h
@@ -0,0 +1,56 @@
+/*
+ * sha1.h
+ *
+ * Copyright (C) 1998, 2009
+ * Paul E. Jones <paulej@packetizer.com>
+ * All Rights Reserved
+ *
+ *****************************************************************************
+ * $Id: sha1.h 12 2009-06-22 19:34:25Z paulej $
+ *****************************************************************************
+ *
+ * Description:
+ * This class implements the Secure Hashing Standard as defined
+ * in FIPS PUB 180-1 published April 17, 1995.
+ *
+ * Many of the variable names in the SHA1Context, especially the
+ * single character names, were used because those were the names
+ * used in the publication.
+ *
+ * Please read the file sha1.c for more information.
+ *
+ */
+
+#ifndef _SHA1_H_
+#define _SHA1_H_
+#include <stdio.h>
+/*
+ * This structure will hold context information for the hashing
+ * operation
+ */
+typedef struct SHA1Context
+{
+ unsigned Message_Digest[5]; /* Message Digest (output) */
+
+ unsigned Length_Low; /* Message length in bits */
+ unsigned Length_High; /* Message length in bits */
+
+ unsigned char Message_Block[64]; /* 512-bit message blocks */
+ int Message_Block_Index; /* Index into message block array */
+
+ int Computed; /* Is the digest computed? */
+ int Corrupted; /* Is the message digest corruped? */
+} SHA1Context;
+
+/*
+ * Function Prototypes
+ */
+void SHA1Reset(SHA1Context *);
+void SHA1Reset_Mod(SHA1Context *context, unsigned int *init);
+int SHA1Result(SHA1Context *);
+int SHA1Result_Forged(SHA1Context *);
+void SHA1Input( SHA1Context *,
+ const unsigned char *,
+ unsigned);
+
+#endif
diff --git a/lib/test.c b/lib/test.c
new file mode 100644
index 0000000..36f3b1c
--- /dev/null
+++ b/lib/test.c
@@ -0,0 +1,24 @@
+#include <gmp.h>
+
+int main()
+{
+ mpz_t a, b, m, r;
+
+ mpz_init_set_str(a, "fafbababcabfebdefbed344523334456a6b4a5c486ac4e86f4684", 16);
+ mpz_init_set_str(b, "2351399303373464486466122544523690094744"
+ "975233415544072992656881240319", 0);
+ mpz_init(m);
+ mpz_ui_pow_ui(m, 10, 40);
+
+ mpz_init(r);
+ mpz_powm(r, a, b, m);
+
+ gmp_printf("%Zd\n", r); /* ...16808958343740453059 */
+
+ mpz_clear(a);
+ mpz_clear(b);
+ mpz_clear(m);
+ mpz_clear(r);
+
+ return 0;
+}
diff --git a/lib/test_list.c b/lib/test_list.c
new file mode 100644
index 0000000..7e72fb8
--- /dev/null
+++ b/lib/test_list.c
@@ -0,0 +1,51 @@
+#include "doublelinkedlist.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+
+struct in {
+ int low;
+ int max;
+ struct list next;
+};
+
+int main()
+{
+ struct in tmp;
+ struct in tmp2;
+ struct in tmp3;
+ struct in tmp4;
+ struct list *iter, *head;
+
+ tmp.low = 1;
+ tmp.max = 3;
+ tmp2.low = 5;
+ tmp2.max = 9;
+ tmp3.low = 14;
+ tmp3.max = 16;
+ tmp4.low = 23;
+ tmp4.max = 35;
+
+ LIST_INIT(&tmp.next);
+ LIST_INIT(&tmp2.next);
+ LIST_INIT(&tmp3.next);
+ LIST_INIT(&tmp4.next);
+
+ list_insert_after(&tmp.next, &tmp2.next);
+ list_insert_after(&tmp2.next, &tmp3.next);
+ list_insert_after(&tmp3.next, &tmp4.next);
+
+ head = &tmp2.next;
+
+ LIST_TO_END(iter, head) {
+ struct in *i = CONTAINER_OF(iter, struct in, next);
+ printf("low: %i, max: %i\n", i->low, i->max);
+ }
+
+ list_delete(&tmp4.next);
+ LIST_TO_END(iter, head) {
+ struct in *i = CONTAINER_OF(iter, struct in, next);
+ printf("low: %i, max: %i\n", i->low, i->max);
+ }
+
+}
diff --git a/lib/util/a.out b/lib/util/a.out
new file mode 100755
index 0000000..2457844
--- /dev/null
+++ b/lib/util/a.out
Binary files differ
diff --git a/lib/util/circulardoublelinkedlist.h b/lib/util/circulardoublelinkedlist.h
new file mode 100644
index 0000000..3e5c524
--- /dev/null
+++ b/lib/util/circulardoublelinkedlist.h
@@ -0,0 +1,54 @@
+#ifndef __CIRCULARLIST__
+#define __CIRCULARLIST__
+
+/**
+ * ciruclar double linked list implementation
+ *
+ **/
+#include "util.h"
+#include<stdio.h>
+
+struct circular_list {
+ struct circular_list *next;
+ struct circular_list *prev;
+};
+
+#define CIRCULARLIST_INIT(name) do { (name)->next = (name); (name)->prev = (name); } while(0);
+
+static int inline __circular_list_insert(struct circular_list *prev, struct circular_list *new, struct circular_list *next)
+{
+ prev->next = new;
+ new->prev = prev;
+ new->next = next;
+ next->prev = new;
+}
+
+static int inline circular_list_insert_after(struct circular_list *list, struct circular_list *new_elem)
+{
+ return __circular_list_insert(list, new_elem, list->next);
+}
+
+static int inline circular_list_insert_before(struct circular_list *list, struct circular_list *new_elem)
+{
+ return __circular_list_insert(list->prev, new_elem, list);
+}
+
+static void inline __circular_list_delete(struct circular_list *prev, struct circular_list *elem, struct circular_list *next)
+{
+ prev->next = next;
+ next->prev = prev;
+ elem->next = elem;
+ elem->prev = elem;
+}
+static void inline circular_list_delete(struct circular_list *elem)
+{
+ __circular_list_delete(elem->prev, elem, elem->next);
+}
+
+#define circular_list_get_prev(elem) (elem)->prev
+#define circular_list_get_next(elem) (elem)->next
+
+#define CIRCULARLIST_FOR_EACH(pos, head) for(pos = head->next; pos != head; pos = pos->next)
+#define CONTAINER_OF(ptr, type, member) ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
+
+#endif
diff --git a/lib/circulardoublelinkedlist.h b/lib/util/doublelinkedlist.h
index 5cda46d..460d799 100644
--- a/lib/circulardoublelinkedlist.h
+++ b/lib/util/doublelinkedlist.h
@@ -2,7 +2,7 @@
#define __LIST__
/**
- * ciruclar double linked list implementation
+ * double linked list implementation
*
**/
@@ -13,14 +13,16 @@ struct list {
struct list *prev;
};
-#define LIST_INIT(name) do { (name)->next = (name); (name)->prev = (name); } while(0);
+#define LIST_INIT(name) do { (name)->next = NULL; (name)->prev = NULL; } while(0);
static int inline __list_insert(struct list *prev, struct list *new, struct list *next)
{
- prev->next = new;
+ if(prev != NULL)
+ prev->next = new;
new->prev = prev;
new->next = next;
- next->prev = new;
+ if(next != NULL)
+ next->prev = new;
}
static int inline list_insert_after(struct list *list, struct list *new_elem)
@@ -35,8 +37,10 @@ static int inline list_insert_before(struct list *list, struct list *new_elem)
static void inline __list_delete(struct list *prev, struct list *elem, struct list *next)
{
- prev->next = next;
- next->prev = prev;
+ if(prev != NULL)
+ prev->next = next;
+ if(next != NULL)
+ next->prev = prev;
elem->next = elem;
elem->prev = elem;
}
@@ -48,7 +52,7 @@ static void inline list_delete(struct list *elem)
#define list_get_prev(elem) (elem)->prev
#define list_get_next(elem) (elem)->next
-#define LIST_FOR_EACH(pos, head) for(pos = head->next; pos != head; pos = pos->next)
+#define LIST_TO_END(pos, head) for(pos = head; pos != NULL; pos = pos->next)
#define CONTAINER_OF(ptr, type, member) ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
#endif
diff --git a/lib/hashtable.h b/lib/util/hashtable.h
index ff501cc..57ac495 100644
--- a/lib/hashtable.h
+++ b/lib/util/hashtable.h
@@ -31,6 +31,11 @@ int __ht_init(struct hashtable *ht, unsigned int number_elem,
ht->hash_function = func;
}
+int ht_destroy(struct hashtable *ht)
+{
+ free(ht->begin);
+}
+
void compute_hash_sha1(void *data, unsigned int data_length, char *res)
{
SHA_CTX sha1;
@@ -56,7 +61,7 @@ void *ht_is_in_list(struct list *list, char *hash, int hash_length)
if(memcmp(res->hash, hash, hash_length) == 0)
return res->data;
- LIST_FOR_EACH(iter,head) {
+ CIRCULARLIST_FOR_EACH(iter,head) {
res = CONTAINER_OF(iter, struct ht_item, list);
if(memcmp(res->hash, hash, hash_length) == 0)
return res->data;
@@ -75,7 +80,7 @@ void ht_add(struct hashtable *ht, void *data, unsigned int data_length,
memcpy(new_elem->data, data, data_length);
new_elem->data_length = data_length;
- LIST_INIT(&new_elem->list);
+ CIRCULARLIST_INIT(&new_elem->list);
ht->hash_function(key, key_length, new_elem->hash);
memcpy(&index, new_elem->hash, sizeof(unsigned long));
@@ -89,7 +94,6 @@ void ht_add(struct hashtable *ht, void *data, unsigned int data_length,
if(ht_is_in_list(&(ht->begin[index]->list), new_elem->hash,
ht->hash_length) == NULL) {
list_insert_after(&(ht->begin[index]->list), &new_elem->list);
- printf("kollision\n");
return;
}
}
@@ -103,7 +107,53 @@ void *ht_get(struct hashtable *ht, void *key, unsigned int key_length)
memcpy(&index, hash, sizeof(unsigned long));
index = index % ht->length;
- return ht_is_in_list(&(ht->begin[index]->list), hash, ht->hash_length);
+ struct ht_item *res = ht_is_in_list(&(ht->begin[index]->list), hash, ht->hash_length);
+ free(hash);
+ return res;
+}
+
+void __ht_delete_item(struct ht_item *delete)
+{
+ free(delete->hash);
+ free(delete->data);
+ free(delete);
+}
+
+void ht_list_delete(struct list *list, unsigned long index, char *hash,
+ unsigned int hash_length)
+{
+ struct list *head, *iter;
+ struct ht_item *res;
+
+ head = list;
+ res = CONTAINER_OF(head, struct ht_item, list);
+ if (memcmp(res->hash, hash, hash_length) == 0) {
+ list_delete(head);
+ __ht_delete_item(res);
+ return;
+ }
+
+ CIRCULARLIST_FOR_EACH(iter, head) {
+ res = CONTAINER_OF(iter, struct ht_item, list);
+ if (memcmp(res->hash, hash, hash_length) == 0) {
+ list_delete(iter);
+ __ht_delete_item(res);
+ return;
+ }
+ }
+}
+
+void ht_delete(struct hashtable *ht, void *key, unsigned int key_length)
+{
+ char *hash = xmalloc(ht->hash_length);
+ unsigned long index;
+
+ ht->hash_function(key, key_length, hash);
+ memcpy(&index, hash, sizeof(unsigned long));
+ index = index % ht->length;
+
+ ht_list_delete(&ht->begin[index]->list, index, hash, ht->hash_length);
+ free(hash);
}
#endif
diff --git a/lib/util/hashtable.h.gch b/lib/util/hashtable.h.gch
new file mode 100644
index 0000000..cf2b3d2
--- /dev/null
+++ b/lib/util/hashtable.h.gch
Binary files differ
diff --git a/lib/util/set.h b/lib/util/set.h
new file mode 100644
index 0000000..bd05351
--- /dev/null
+++ b/lib/util/set.h
@@ -0,0 +1,39 @@
+#ifndef __SET_H__
+#define __SET_H__
+#include <stdlib.h>
+#include "hashtable.h"
+
+/**
+ * implementation of a set based on a hashtable implementation
+ *
+ **/
+
+typedef struct hashtable set_t;
+
+void set_init(set_t *set)
+{
+ ht_init_sha1(set);
+}
+
+
+void set_insert(set_t *set, void *data, unsigned int data_length)
+{
+ ht_add(set, data, data_length, data, data_length);
+}
+
+unsigned int set_is_in_set(set_t *set, void *data, unsigned int data_length)
+{
+ if(ht_get(set, data, data_length) == NULL)
+ return 0;
+ else
+ return 1;
+}
+
+void set_delete(set_t *set, void *data, unsigned int data_length)
+{
+ ht_delete(set, data, data_length);
+}
+
+#define SET_FOR_EACH
+
+#endif
diff --git a/lib/util/set.h.gch b/lib/util/set.h.gch
new file mode 100644
index 0000000..2c1b1fe
--- /dev/null
+++ b/lib/util/set.h.gch
Binary files differ
diff --git a/lib/util/test_hash.c b/lib/util/test_hash.c
new file mode 100644
index 0000000..19d2aae
--- /dev/null
+++ b/lib/util/test_hash.c
@@ -0,0 +1,48 @@
+#include "hashtable.h"
+#include "set.h"
+
+
+int main()
+{
+ int i;
+ struct hashtable ht;
+
+ char *msg = malloc(100);
+ memcpy(msg, "Hallo dies ist meine Message\n", 20);
+ char *key = malloc(20);
+
+ ht_init_sha1(&ht);
+ key[1] = '\n';
+ for(i=0;i<156;i++) {
+ key[0] = i;
+ msg[0] = i;
+ ht_add(&ht, msg, strlen(msg), key, strlen(key));
+ }
+
+
+ ht_delete(&ht, key, strlen(key));
+ char *ret = ht_get(&ht, key, strlen(key));
+ if(ret != NULL)
+ printf("uuh das sollte eigtl nicht mehr da sein\n");
+
+ key[0] = 'a' + 3;
+ ret = ht_get(&ht, key, strlen(key));
+ if(ret == NULL)
+ printf("did not found data\n");
+
+ printf("message is: %s\n", msg);
+ printf("got data from ht: %s\n", ret);
+
+
+ set_t t;
+
+ set_init(&t);
+ set_insert(&t, msg, strlen(msg));
+ if(set_is_in_set(&t, msg, strlen(msg)) == 1)
+ printf("im set, alles gut\n");
+
+ set_delete(&t, msg, strlen(msg));
+ if(set_is_in_set(&t, msg, strlen(msg)) == 0)
+ printf("nicht merg im set, alles gut\n");
+
+}
diff --git a/lib/util/util.c b/lib/util/util.c
new file mode 100644
index 0000000..dd06869
--- /dev/null
+++ b/lib/util/util.c
@@ -0,0 +1,25 @@
+#include "util.h"
+
+void *die(char *text)
+{
+ printf("dieing: %s\n", text);
+ exit(1);
+}
+
+void *xmalloc(unsigned int size)
+{
+ void *mem = malloc(size);
+ if(mem == NULL)
+ die("out of memory");
+ else
+ return mem;
+}
+
+void *xrealloc(void *data, unsigned int size)
+{
+ void *mem = realloc(data, size);
+ if(mem == NULL)
+ die("out of memory");
+ else
+ return mem;
+}
diff --git a/lib/util/util.h b/lib/util/util.h
new file mode 100644
index 0000000..b998ef8
--- /dev/null
+++ b/lib/util/util.h
@@ -0,0 +1,10 @@
+#ifndef __UTIL_H__
+#define __UTIL_H__
+
+#include <stdlib.h>
+#include <stdio.h>
+
+void *die(char *text);
+void *xmalloc(unsigned int size);
+void *xrealloc(void *data, unsigned int size);
+#endif
diff --git a/set2/task15.c b/set2/task15.c
index a40ecf3..4c03047 100644
--- a/set2/task15.c
+++ b/set2/task15.c
@@ -43,4 +43,16 @@ int main(int argc, char **Argv)
printf("valid padding: %s\n", unpadded);
else
printf("invalid padding\n");
+
+ string = "YELLOW SUBMARIN";
+ padded_text = pkcs7_padding(string, strlen(string), 16);
+
+ printf("%i, %i\n",strlen(string), strlen(padded_text));
+ printf("padded text: %s\n", padded_text);
+ result = valid_pkcs7_padding(padded_text, strlen(padded_text),unpadded, 16);
+
+ if(result)
+ printf("valid padding: %s\n", unpadded);
+ else
+ printf("invalid padding\n");
}
diff --git a/set2/task9.c b/set2/task9.c
index 9b91174..9f9bc8e 100644
--- a/set2/task9.c
+++ b/set2/task9.c
@@ -6,7 +6,7 @@ int main(int argc, char **argv)
// implemten PKCS#7 padding
char *result = NULL;
- result = pkcs7_padding("YELLOW SUBMARINE", 16, 10);
+ result = pkcs7_padding("YELLOW SUBMARINE", 16, 16);
printf("%s\n", result);
free(result);
diff --git a/set3/task17.c b/set3/task17.c
new file mode 100644
index 0000000..d2bb7e0
--- /dev/null
+++ b/set3/task17.c
@@ -0,0 +1,59 @@
+#include "../lib/lib.h"
+#include "../lib/lib2.h"
+#include "../lib/lib3.h"
+#include <time.h>
+
+/**
+ * First we try to break the last byte of a block.
+ * Do this by trying every byte
+ *
+ * Good description of the attack:
+ * https://blog.cloudflare.com/padding-oracles-and-the-decline-of-cbc-mode-ciphersuites/
+ */
+
+#define BLOCKSIZE 16
+int main()
+{
+ // intialize
+ srand(time(NULL));
+ generate_random_bytes(key, 16);
+ generate_random_bytes(iv, 16);
+
+ int length = 0, i;
+ char *encrypted = challenge17_encrypt(&length);
+
+ // detecting the length of the padding (need at least two blocks)
+ int nr_blocks = length / BLOCKSIZE;
+ nr_blocks--;
+
+ printf("length: %i, blocks: %i\n", length, nr_blocks);
+
+ char *tmp = malloc(length);
+ char *decrypted = malloc(length);;
+ memset(decrypted, 0xAA, length);
+ // try to break the last byte of the first block
+ char j;
+ int k;
+ for(k=nr_blocks-1;k>=0;k--) {
+ memcpy(tmp, encrypted, length);
+ printf("k is %i\n", k);
+ for(j=1;j<=BLOCKSIZE;j++) {
+ // created the right padding for the last j bytes
+ for(i=1;i<j;i++)
+ tmp[(k*BLOCKSIZE)+BLOCKSIZE-i] = decrypted[((k+1)*BLOCKSIZE)+BLOCKSIZE-i] ^ encrypted[(k*BLOCKSIZE)+BLOCKSIZE-i] ^ j;
+
+ for(i=0;i<256;i++) {
+ // cbc bit flipping
+ tmp[(k*BLOCKSIZE)+BLOCKSIZE-j] = i;
+ // retursn 1 if paddign is valid
+ if(cbc_padding_oracle(&tmp[k*BLOCKSIZE], 2*BLOCKSIZE)) {
+ // 0x01 for the last padding byte, next step it is 0x02
+ decrypted[((k+1)*BLOCKSIZE)+BLOCKSIZE-j] = (char) (i ^ (encrypted[(k*BLOCKSIZE)+BLOCKSIZE-j]) ^ j);
+ printf("got a hit %c\n", decrypted[((k+1)*BLOCKSIZE)+BLOCKSIZE-j+1]);
+ break;
+ }
+ }
+ }
+ }
+ printf("recovered plaintext: %s\n", &decrypted[BLOCKSIZE]);
+}
diff --git a/set3/task17_0 b/set3/task17_0
new file mode 100644
index 0000000..3cde4d1
--- /dev/null
+++ b/set3/task17_0
@@ -0,0 +1 @@
+MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=
diff --git a/set3/task17_1 b/set3/task17_1
new file mode 100644
index 0000000..2ba2eaa
--- /dev/null
+++ b/set3/task17_1
@@ -0,0 +1 @@
+MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=
diff --git a/set3/task17_2 b/set3/task17_2
new file mode 100644
index 0000000..0cc5bce
--- /dev/null
+++ b/set3/task17_2
@@ -0,0 +1 @@
+MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==
diff --git a/set3/task17_3 b/set3/task17_3
new file mode 100644
index 0000000..b10f8d4
--- /dev/null
+++ b/set3/task17_3
@@ -0,0 +1 @@
+MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==
diff --git a/set3/task17_4 b/set3/task17_4
new file mode 100644
index 0000000..4765c7d
--- /dev/null
+++ b/set3/task17_4
@@ -0,0 +1 @@
+MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl
diff --git a/set3/task17_5 b/set3/task17_5
new file mode 100644
index 0000000..5b99081
--- /dev/null
+++ b/set3/task17_5
@@ -0,0 +1 @@
+MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==
diff --git a/set3/task17_6 b/set3/task17_6
new file mode 100644
index 0000000..1a5e976
--- /dev/null
+++ b/set3/task17_6
@@ -0,0 +1 @@
+MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==
diff --git a/set3/task17_7 b/set3/task17_7
new file mode 100644
index 0000000..41f022f
--- /dev/null
+++ b/set3/task17_7
@@ -0,0 +1 @@
+MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=
diff --git a/set3/task17_8 b/set3/task17_8
new file mode 100644
index 0000000..adb9041
--- /dev/null
+++ b/set3/task17_8
@@ -0,0 +1 @@
+MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=
diff --git a/set3/task17_9 b/set3/task17_9
new file mode 100644
index 0000000..8dc72a5
--- /dev/null
+++ b/set3/task17_9
@@ -0,0 +1 @@
+MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93
diff --git a/set3/task19.c b/set3/task19.c
new file mode 100644
index 0000000..a036f4f
--- /dev/null
+++ b/set3/task19.c
@@ -0,0 +1,35 @@
+#include "../lib/lib.h"
+#include "../lib/lib2.h"
+#include "../lib/lib3.h"
+#include <time.h>
+
+#define CHALLENGE19_FILE_NR 40
+int main()
+{
+ int i;
+ char **file = malloc(sizeof(char *)*CHALLENGE19_FILE_NR);
+ int length_file[CHALLENGE19_FILE_NR];
+ int length[CHALLENGE19_FILE_NR];
+ char **plaintext= malloc(sizeof(char *)*CHALLENGE19_FILE_NR);
+ char **ciphertext= malloc(sizeof(char *)*CHALLENGE19_FILE_NR);
+ char filename[] = "./task19_data/task19_00";
+
+ char nonce[16];
+ generate_random_bytes(key, 16);
+ generate_random_bytes(nonce, 16);
+
+ for(i=0;i<CHALLENGE19_FILE_NR;i++) {
+ filename[strlen(filename)-1] = ((i % 10)+ '0');
+ filename[strlen(filename)-2] = ((i / 10) + '0');
+ length_file[i] = read_base64_file(filename, &file[i]);
+ plaintext[i] = malloc(length_file[i]);
+ length[i] = decode_base64(file[i], plaintext[i]);
+ printf("%s\n", plaintext[i]);
+ ciphertext[i] = malloc(length[i]);
+ aes_ctr(plaintext[i], length[i], ciphertext[i], key, nonce);
+ }
+
+ // let the cracking begin
+
+
+}
diff --git a/set3/task19_data/task19_00 b/set3/task19_data/task19_00
new file mode 100644
index 0000000..ded873a
--- /dev/null
+++ b/set3/task19_data/task19_00
@@ -0,0 +1 @@
+SSBoYXZlIG1ldCB0aGVtIGF0IGNsb3NlIG9mIGRheQ==
diff --git a/set3/task19_data/task19_01 b/set3/task19_data/task19_01
new file mode 100644
index 0000000..2ef0ae1
--- /dev/null
+++ b/set3/task19_data/task19_01
@@ -0,0 +1 @@
+Q29taW5nIHdpdGggdml2aWQgZmFjZXM=
diff --git a/set3/task19_data/task19_02 b/set3/task19_data/task19_02
new file mode 100644
index 0000000..a9b546e
--- /dev/null
+++ b/set3/task19_data/task19_02
@@ -0,0 +1 @@
+RnJvbSBjb3VudGVyIG9yIGRlc2sgYW1vbmcgZ3JleQ==
diff --git a/set3/task19_data/task19_03 b/set3/task19_data/task19_03
new file mode 100644
index 0000000..2ea23fa
--- /dev/null
+++ b/set3/task19_data/task19_03
@@ -0,0 +1 @@
+RWlnaHRlZW50aC1jZW50dXJ5IGhvdXNlcy4=
diff --git a/set3/task19_data/task19_04 b/set3/task19_data/task19_04
new file mode 100644
index 0000000..7ea2a43
--- /dev/null
+++ b/set3/task19_data/task19_04
@@ -0,0 +1 @@
+SSBoYXZlIHBhc3NlZCB3aXRoIGEgbm9kIG9mIHRoZSBoZWFk
diff --git a/set3/task19_data/task19_05 b/set3/task19_data/task19_05
new file mode 100644
index 0000000..ba3f268
--- /dev/null
+++ b/set3/task19_data/task19_05
@@ -0,0 +1 @@
+T3IgcG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==
diff --git a/set3/task19_data/task19_06 b/set3/task19_data/task19_06
new file mode 100644
index 0000000..a5e1a79
--- /dev/null
+++ b/set3/task19_data/task19_06
@@ -0,0 +1 @@
+T3IgaGF2ZSBsaW5nZXJlZCBhd2hpbGUgYW5kIHNhaWQ=
diff --git a/set3/task19_data/task19_07 b/set3/task19_data/task19_07
new file mode 100644
index 0000000..6b43132
--- /dev/null
+++ b/set3/task19_data/task19_07
@@ -0,0 +1 @@
+UG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==
diff --git a/set3/task19_data/task19_08 b/set3/task19_data/task19_08
new file mode 100644
index 0000000..8cc6a9a
--- /dev/null
+++ b/set3/task19_data/task19_08
@@ -0,0 +1 @@
+QW5kIHRob3VnaHQgYmVmb3JlIEkgaGFkIGRvbmU=
diff --git a/set3/task19_data/task19_09 b/set3/task19_data/task19_09
new file mode 100644
index 0000000..b2c7bd8
--- /dev/null
+++ b/set3/task19_data/task19_09
@@ -0,0 +1 @@
+T2YgYSBtb2NraW5nIHRhbGUgb3IgYSBnaWJl
diff --git a/set3/task19_data/task19_10 b/set3/task19_data/task19_10
new file mode 100644
index 0000000..734f4d8
--- /dev/null
+++ b/set3/task19_data/task19_10
@@ -0,0 +1 @@
+VG8gcGxlYXNlIGEgY29tcGFuaW9u
diff --git a/set3/task19_data/task19_11 b/set3/task19_data/task19_11
new file mode 100644
index 0000000..a1f04b4
--- /dev/null
+++ b/set3/task19_data/task19_11
@@ -0,0 +1 @@
+QXJvdW5kIHRoZSBmaXJlIGF0IHRoZSBjbHViLA==
diff --git a/set3/task19_data/task19_12 b/set3/task19_data/task19_12
new file mode 100644
index 0000000..864a764
--- /dev/null
+++ b/set3/task19_data/task19_12
@@ -0,0 +1 @@
+QmVpbmcgY2VydGFpbiB0aGF0IHRoZXkgYW5kIEk=
diff --git a/set3/task19_data/task19_13 b/set3/task19_data/task19_13
new file mode 100644
index 0000000..23a2eb1
--- /dev/null
+++ b/set3/task19_data/task19_13
@@ -0,0 +1 @@
+QnV0IGxpdmVkIHdoZXJlIG1vdGxleSBpcyB3b3JuOg==
diff --git a/set3/task19_data/task19_14 b/set3/task19_data/task19_14
new file mode 100644
index 0000000..5865e2c
--- /dev/null
+++ b/set3/task19_data/task19_14
@@ -0,0 +1 @@
+QWxsIGNoYW5nZWQsIGNoYW5nZWQgdXR0ZXJseTo=
diff --git a/set3/task19_data/task19_15 b/set3/task19_data/task19_15
new file mode 100644
index 0000000..cc8e0a4
--- /dev/null
+++ b/set3/task19_data/task19_15
@@ -0,0 +1 @@
+QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=
diff --git a/set3/task19_data/task19_16 b/set3/task19_data/task19_16
new file mode 100644
index 0000000..4db1ffe
--- /dev/null
+++ b/set3/task19_data/task19_16
@@ -0,0 +1 @@
+VGhhdCB3b21hbidzIGRheXMgd2VyZSBzcGVudA==
diff --git a/set3/task19_data/task19_17 b/set3/task19_data/task19_17
new file mode 100644
index 0000000..64da3a8
--- /dev/null
+++ b/set3/task19_data/task19_17
@@ -0,0 +1 @@
+SW4gaWdub3JhbnQgZ29vZCB3aWxsLA==
diff --git a/set3/task19_data/task19_18 b/set3/task19_data/task19_18
new file mode 100644
index 0000000..740bb98
--- /dev/null
+++ b/set3/task19_data/task19_18
@@ -0,0 +1 @@
+SGVyIG5pZ2h0cyBpbiBhcmd1bWVudA==
diff --git a/set3/task19_data/task19_19 b/set3/task19_data/task19_19
new file mode 100644
index 0000000..26b01e1
--- /dev/null
+++ b/set3/task19_data/task19_19
@@ -0,0 +1 @@
+VW50aWwgaGVyIHZvaWNlIGdyZXcgc2hyaWxsLg==
diff --git a/set3/task19_data/task19_20 b/set3/task19_data/task19_20
new file mode 100644
index 0000000..15b6e63
--- /dev/null
+++ b/set3/task19_data/task19_20
@@ -0,0 +1 @@
+V2hhdCB2b2ljZSBtb3JlIHN3ZWV0IHRoYW4gaGVycw==
diff --git a/set3/task19_data/task19_21 b/set3/task19_data/task19_21
new file mode 100644
index 0000000..95eb336
--- /dev/null
+++ b/set3/task19_data/task19_21
@@ -0,0 +1 @@
+V2hlbiB5b3VuZyBhbmQgYmVhdXRpZnVsLA==
diff --git a/set3/task19_data/task19_22 b/set3/task19_data/task19_22
new file mode 100644
index 0000000..1fe7f50
--- /dev/null
+++ b/set3/task19_data/task19_22
@@ -0,0 +1 @@
+U2hlIHJvZGUgdG8gaGFycmllcnM/
diff --git a/set3/task19_data/task19_23 b/set3/task19_data/task19_23
new file mode 100644
index 0000000..f6a3b04
--- /dev/null
+++ b/set3/task19_data/task19_23
@@ -0,0 +1 @@
+VGhpcyBtYW4gaGFkIGtlcHQgYSBzY2hvb2w=
diff --git a/set3/task19_data/task19_24 b/set3/task19_data/task19_24
new file mode 100644
index 0000000..cceb1bf
--- /dev/null
+++ b/set3/task19_data/task19_24
@@ -0,0 +1 @@
+QW5kIHJvZGUgb3VyIHdpbmdlZCBob3JzZS4=
diff --git a/set3/task19_data/task19_25 b/set3/task19_data/task19_25
new file mode 100644
index 0000000..157f7f8
--- /dev/null
+++ b/set3/task19_data/task19_25
@@ -0,0 +1 @@
+VGhpcyBvdGhlciBoaXMgaGVscGVyIGFuZCBmcmllbmQ=
diff --git a/set3/task19_data/task19_26 b/set3/task19_data/task19_26
new file mode 100644
index 0000000..ccca06e
--- /dev/null
+++ b/set3/task19_data/task19_26
@@ -0,0 +1 @@
+V2FzIGNvbWluZyBpbnRvIGhpcyBmb3JjZTs=
diff --git a/set3/task19_data/task19_27 b/set3/task19_data/task19_27
new file mode 100644
index 0000000..985b7a6
--- /dev/null
+++ b/set3/task19_data/task19_27
@@ -0,0 +1 @@
+SGUgbWlnaHQgaGF2ZSB3b24gZmFtZSBpbiB0aGUgZW5kLA==
diff --git a/set3/task19_data/task19_28 b/set3/task19_data/task19_28
new file mode 100644
index 0000000..fc8e2d5
--- /dev/null
+++ b/set3/task19_data/task19_28
@@ -0,0 +1 @@
+U28gc2Vuc2l0aXZlIGhpcyBuYXR1cmUgc2VlbWVkLA==
diff --git a/set3/task19_data/task19_29 b/set3/task19_data/task19_29
new file mode 100644
index 0000000..448495a
--- /dev/null
+++ b/set3/task19_data/task19_29
@@ -0,0 +1 @@
+U28gZGFyaW5nIGFuZCBzd2VldCBoaXMgdGhvdWdodC4=
diff --git a/set3/task19_data/task19_30 b/set3/task19_data/task19_30
new file mode 100644
index 0000000..c42a69a
--- /dev/null
+++ b/set3/task19_data/task19_30
@@ -0,0 +1 @@
+VGhpcyBvdGhlciBtYW4gSSBoYWQgZHJlYW1lZA==
diff --git a/set3/task19_data/task19_31 b/set3/task19_data/task19_31
new file mode 100644
index 0000000..5e3e2e7
--- /dev/null
+++ b/set3/task19_data/task19_31
@@ -0,0 +1 @@
+QSBkcnVua2VuLCB2YWluLWdsb3Jpb3VzIGxvdXQu
diff --git a/set3/task19_data/task19_32 b/set3/task19_data/task19_32
new file mode 100644
index 0000000..fa3b3aa
--- /dev/null
+++ b/set3/task19_data/task19_32
@@ -0,0 +1 @@
+SGUgaGFkIGRvbmUgbW9zdCBiaXR0ZXIgd3Jvbmc=
diff --git a/set3/task19_data/task19_33 b/set3/task19_data/task19_33
new file mode 100644
index 0000000..e0777a4
--- /dev/null
+++ b/set3/task19_data/task19_33
@@ -0,0 +1 @@
+VG8gc29tZSB3aG8gYXJlIG5lYXIgbXkgaGVhcnQs
diff --git a/set3/task19_data/task19_34 b/set3/task19_data/task19_34
new file mode 100644
index 0000000..7b63d9e
--- /dev/null
+++ b/set3/task19_data/task19_34
@@ -0,0 +1 @@
+WWV0IEkgbnVtYmVyIGhpbSBpbiB0aGUgc29uZzs=
diff --git a/set3/task19_data/task19_35 b/set3/task19_data/task19_35
new file mode 100644
index 0000000..dafc9ab
--- /dev/null
+++ b/set3/task19_data/task19_35
@@ -0,0 +1 @@
+SGUsIHRvbywgaGFzIHJlc2lnbmVkIGhpcyBwYXJ0
diff --git a/set3/task19_data/task19_36 b/set3/task19_data/task19_36
new file mode 100644
index 0000000..56f63ac
--- /dev/null
+++ b/set3/task19_data/task19_36
@@ -0,0 +1 @@
+SW4gdGhlIGNhc3VhbCBjb21lZHk7
diff --git a/set3/task19_data/task19_37 b/set3/task19_data/task19_37
new file mode 100644
index 0000000..74e011b
--- /dev/null
+++ b/set3/task19_data/task19_37
@@ -0,0 +1 @@
+SGUsIHRvbywgaGFzIGJlZW4gY2hhbmdlZCBpbiBoaXMgdHVybiw=
diff --git a/set3/task19_data/task19_38 b/set3/task19_data/task19_38
new file mode 100644
index 0000000..40e0406
--- /dev/null
+++ b/set3/task19_data/task19_38
@@ -0,0 +1 @@
+VHJhbnNmb3JtZWQgdXR0ZXJseTo=
diff --git a/set3/task19_data/task19_39 b/set3/task19_data/task19_39
new file mode 100644
index 0000000..cc8e0a4
--- /dev/null
+++ b/set3/task19_data/task19_39
@@ -0,0 +1 @@
+QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=
diff --git a/set3/task19_data/task19_all b/set3/task19_data/task19_all
new file mode 100644
index 0000000..affd17b
--- /dev/null
+++ b/set3/task19_data/task19_all
@@ -0,0 +1,40 @@
+SSBoYXZlIG1ldCB0aGVtIGF0IGNsb3NlIG9mIGRheQ==
+Q29taW5nIHdpdGggdml2aWQgZmFjZXM=
+RnJvbSBjb3VudGVyIG9yIGRlc2sgYW1vbmcgZ3JleQ==
+RWlnaHRlZW50aC1jZW50dXJ5IGhvdXNlcy4=
+SSBoYXZlIHBhc3NlZCB3aXRoIGEgbm9kIG9mIHRoZSBoZWFk
+T3IgcG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==
+T3IgaGF2ZSBsaW5nZXJlZCBhd2hpbGUgYW5kIHNhaWQ=
+UG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==
+QW5kIHRob3VnaHQgYmVmb3JlIEkgaGFkIGRvbmU=
+T2YgYSBtb2NraW5nIHRhbGUgb3IgYSBnaWJl
+VG8gcGxlYXNlIGEgY29tcGFuaW9u
+QXJvdW5kIHRoZSBmaXJlIGF0IHRoZSBjbHViLA==
+QmVpbmcgY2VydGFpbiB0aGF0IHRoZXkgYW5kIEk=
+QnV0IGxpdmVkIHdoZXJlIG1vdGxleSBpcyB3b3JuOg==
+QWxsIGNoYW5nZWQsIGNoYW5nZWQgdXR0ZXJseTo=
+QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=
+VGhhdCB3b21hbidzIGRheXMgd2VyZSBzcGVudA==
+SW4gaWdub3JhbnQgZ29vZCB3aWxsLA==
+SGVyIG5pZ2h0cyBpbiBhcmd1bWVudA==
+VW50aWwgaGVyIHZvaWNlIGdyZXcgc2hyaWxsLg==
+V2hhdCB2b2ljZSBtb3JlIHN3ZWV0IHRoYW4gaGVycw==
+V2hlbiB5b3VuZyBhbmQgYmVhdXRpZnVsLA==
+U2hlIHJvZGUgdG8gaGFycmllcnM/
+VGhpcyBtYW4gaGFkIGtlcHQgYSBzY2hvb2w=
+QW5kIHJvZGUgb3VyIHdpbmdlZCBob3JzZS4=
+VGhpcyBvdGhlciBoaXMgaGVscGVyIGFuZCBmcmllbmQ=
+V2FzIGNvbWluZyBpbnRvIGhpcyBmb3JjZTs=
+SGUgbWlnaHQgaGF2ZSB3b24gZmFtZSBpbiB0aGUgZW5kLA==
+U28gc2Vuc2l0aXZlIGhpcyBuYXR1cmUgc2VlbWVkLA==
+U28gZGFyaW5nIGFuZCBzd2VldCBoaXMgdGhvdWdodC4=
+VGhpcyBvdGhlciBtYW4gSSBoYWQgZHJlYW1lZA==
+QSBkcnVua2VuLCB2YWluLWdsb3Jpb3VzIGxvdXQu
+SGUgaGFkIGRvbmUgbW9zdCBiaXR0ZXIgd3Jvbmc=
+VG8gc29tZSB3aG8gYXJlIG5lYXIgbXkgaGVhcnQs
+WWV0IEkgbnVtYmVyIGhpbSBpbiB0aGUgc29uZzs=
+SGUsIHRvbywgaGFzIHJlc2lnbmVkIGhpcyBwYXJ0
+SW4gdGhlIGNhc3VhbCBjb21lZHk7
+SGUsIHRvbywgaGFzIGJlZW4gY2hhbmdlZCBpbiBoaXMgdHVybiw=
+VHJhbnNmb3JtZWQgdXR0ZXJseTo=
+QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=
diff --git a/set3/task20_data/20.txt b/set3/task20_data/20.txt
new file mode 100644
index 0000000..d601f0b
--- /dev/null
+++ b/set3/task20_data/20.txt
@@ -0,0 +1,60 @@
+SSdtIHJhdGVkICJSIi4uLnRoaXMgaXMgYSB3YXJuaW5nLCB5YSBiZXR0ZXIgdm9pZCAvIFBvZXRzIGFyZSBwYXJhbm9pZCwgREoncyBELXN0cm95ZWQ=
+Q3V6IEkgY2FtZSBiYWNrIHRvIGF0dGFjayBvdGhlcnMgaW4gc3BpdGUtIC8gU3RyaWtlIGxpa2UgbGlnaHRuaW4nLCBJdCdzIHF1aXRlIGZyaWdodGVuaW4nIQ==
+QnV0IGRvbid0IGJlIGFmcmFpZCBpbiB0aGUgZGFyaywgaW4gYSBwYXJrIC8gTm90IGEgc2NyZWFtIG9yIGEgY3J5LCBvciBhIGJhcmssIG1vcmUgbGlrZSBhIHNwYXJrOw==
+WWEgdHJlbWJsZSBsaWtlIGEgYWxjb2hvbGljLCBtdXNjbGVzIHRpZ2h0ZW4gdXAgLyBXaGF0J3MgdGhhdCwgbGlnaHRlbiB1cCEgWW91IHNlZSBhIHNpZ2h0IGJ1dA==
+U3VkZGVubHkgeW91IGZlZWwgbGlrZSB5b3VyIGluIGEgaG9ycm9yIGZsaWNrIC8gWW91IGdyYWIgeW91ciBoZWFydCB0aGVuIHdpc2ggZm9yIHRvbW9ycm93IHF1aWNrIQ==
+TXVzaWMncyB0aGUgY2x1ZSwgd2hlbiBJIGNvbWUgeW91ciB3YXJuZWQgLyBBcG9jYWx5cHNlIE5vdywgd2hlbiBJJ20gZG9uZSwgeWEgZ29uZSE=
+SGF2ZW4ndCB5b3UgZXZlciBoZWFyZCBvZiBhIE1DLW11cmRlcmVyPyAvIFRoaXMgaXMgdGhlIGRlYXRoIHBlbmFsdHksYW5kIEknbSBzZXJ2aW4nIGE=
+RGVhdGggd2lzaCwgc28gY29tZSBvbiwgc3RlcCB0byB0aGlzIC8gSHlzdGVyaWNhbCBpZGVhIGZvciBhIGx5cmljYWwgcHJvZmVzc2lvbmlzdCE=
+RnJpZGF5IHRoZSB0aGlydGVlbnRoLCB3YWxraW5nIGRvd24gRWxtIFN0cmVldCAvIFlvdSBjb21lIGluIG15IHJlYWxtIHlhIGdldCBiZWF0IQ==
+VGhpcyBpcyBvZmYgbGltaXRzLCBzbyB5b3VyIHZpc2lvbnMgYXJlIGJsdXJyeSAvIEFsbCB5YSBzZWUgaXMgdGhlIG1ldGVycyBhdCBhIHZvbHVtZQ==
+VGVycm9yIGluIHRoZSBzdHlsZXMsIG5ldmVyIGVycm9yLWZpbGVzIC8gSW5kZWVkIEknbSBrbm93bi15b3VyIGV4aWxlZCE=
+Rm9yIHRob3NlIHRoYXQgb3Bwb3NlIHRvIGJlIGxldmVsIG9yIG5leHQgdG8gdGhpcyAvIEkgYWluJ3QgYSBkZXZpbCBhbmQgdGhpcyBhaW4ndCB0aGUgRXhvcmNpc3Qh
+V29yc2UgdGhhbiBhIG5pZ2h0bWFyZSwgeW91IGRvbid0IGhhdmUgdG8gc2xlZXAgYSB3aW5rIC8gVGhlIHBhaW4ncyBhIG1pZ3JhaW5lIGV2ZXJ5IHRpbWUgeWEgdGhpbms=
+Rmxhc2hiYWNrcyBpbnRlcmZlcmUsIHlhIHN0YXJ0IHRvIGhlYXI6IC8gVGhlIFItQS1LLUktTSBpbiB5b3VyIGVhcjs=
+VGhlbiB0aGUgYmVhdCBpcyBoeXN0ZXJpY2FsIC8gVGhhdCBtYWtlcyBFcmljIGdvIGdldCBhIGF4IGFuZCBjaG9wcyB0aGUgd2Fjaw==
+U29vbiB0aGUgbHlyaWNhbCBmb3JtYXQgaXMgc3VwZXJpb3IgLyBGYWNlcyBvZiBkZWF0aCByZW1haW4=
+TUMncyBkZWNheWluZywgY3V6IHRoZXkgbmV2ZXIgc3RheWVkIC8gVGhlIHNjZW5lIG9mIGEgY3JpbWUgZXZlcnkgbmlnaHQgYXQgdGhlIHNob3c=
+VGhlIGZpZW5kIG9mIGEgcmh5bWUgb24gdGhlIG1pYyB0aGF0IHlvdSBrbm93IC8gSXQncyBvbmx5IG9uZSBjYXBhYmxlLCBicmVha3MtdGhlIHVuYnJlYWthYmxl
+TWVsb2RpZXMtdW5tYWthYmxlLCBwYXR0ZXJuLXVuZXNjYXBhYmxlIC8gQSBob3JuIGlmIHdhbnQgdGhlIHN0eWxlIEkgcG9zc2Vz
+SSBibGVzcyB0aGUgY2hpbGQsIHRoZSBlYXJ0aCwgdGhlIGdvZHMgYW5kIGJvbWIgdGhlIHJlc3QgLyBGb3IgdGhvc2UgdGhhdCBlbnZ5IGEgTUMgaXQgY2FuIGJl
+SGF6YXJkb3VzIHRvIHlvdXIgaGVhbHRoIHNvIGJlIGZyaWVuZGx5IC8gQSBtYXR0ZXIgb2YgbGlmZSBhbmQgZGVhdGgsIGp1c3QgbGlrZSBhIGV0Y2gtYS1za2V0Y2g=
+U2hha2UgJ3RpbGwgeW91ciBjbGVhciwgbWFrZSBpdCBkaXNhcHBlYXIsIG1ha2UgdGhlIG5leHQgLyBBZnRlciB0aGUgY2VyZW1vbnksIGxldCB0aGUgcmh5bWUgcmVzdCBpbiBwZWFjZQ==
+SWYgbm90LCBteSBzb3VsJ2xsIHJlbGVhc2UhIC8gVGhlIHNjZW5lIGlzIHJlY3JlYXRlZCwgcmVpbmNhcm5hdGVkLCB1cGRhdGVkLCBJJ20gZ2xhZCB5b3UgbWFkZSBpdA==
+Q3V6IHlvdXIgYWJvdXQgdG8gc2VlIGEgZGlzYXN0cm91cyBzaWdodCAvIEEgcGVyZm9ybWFuY2UgbmV2ZXIgYWdhaW4gcGVyZm9ybWVkIG9uIGEgbWljOg==
+THlyaWNzIG9mIGZ1cnkhIEEgZmVhcmlmaWVkIGZyZWVzdHlsZSEgLyBUaGUgIlIiIGlzIGluIHRoZSBob3VzZS10b28gbXVjaCB0ZW5zaW9uIQ==
+TWFrZSBzdXJlIHRoZSBzeXN0ZW0ncyBsb3VkIHdoZW4gSSBtZW50aW9uIC8gUGhyYXNlcyB0aGF0J3MgZmVhcnNvbWU=
+WW91IHdhbnQgdG8gaGVhciBzb21lIHNvdW5kcyB0aGF0IG5vdCBvbmx5IHBvdW5kcyBidXQgcGxlYXNlIHlvdXIgZWFyZHJ1bXM7IC8gSSBzaXQgYmFjayBhbmQgb2JzZXJ2ZSB0aGUgd2hvbGUgc2NlbmVyeQ==
+VGhlbiBub25jaGFsYW50bHkgdGVsbCB5b3Ugd2hhdCBpdCBtZWFuIHRvIG1lIC8gU3RyaWN0bHkgYnVzaW5lc3MgSSdtIHF1aWNrbHkgaW4gdGhpcyBtb29k
+QW5kIEkgZG9uJ3QgY2FyZSBpZiB0aGUgd2hvbGUgY3Jvd2QncyBhIHdpdG5lc3MhIC8gSSdtIGEgdGVhciB5b3UgYXBhcnQgYnV0IEknbSBhIHNwYXJlIHlvdSBhIGhlYXJ0
+UHJvZ3JhbSBpbnRvIHRoZSBzcGVlZCBvZiB0aGUgcmh5bWUsIHByZXBhcmUgdG8gc3RhcnQgLyBSaHl0aG0ncyBvdXQgb2YgdGhlIHJhZGl1cywgaW5zYW5lIGFzIHRoZSBjcmF6aWVzdA==
+TXVzaWNhbCBtYWRuZXNzIE1DIGV2ZXIgbWFkZSwgc2VlIGl0J3MgLyBOb3cgYW4gZW1lcmdlbmN5LCBvcGVuLWhlYXJ0IHN1cmdlcnk=
+T3BlbiB5b3VyIG1pbmQsIHlvdSB3aWxsIGZpbmQgZXZlcnkgd29yZCdsbCBiZSAvIEZ1cmllciB0aGFuIGV2ZXIsIEkgcmVtYWluIHRoZSBmdXJ0dXJl
+QmF0dGxlJ3MgdGVtcHRpbmcuLi53aGF0ZXZlciBzdWl0cyB5YSEgLyBGb3Igd29yZHMgdGhlIHNlbnRlbmNlLCB0aGVyZSdzIG5vIHJlc2VtYmxhbmNl
+WW91IHRoaW5rIHlvdSdyZSBydWZmZXIsIHRoZW4gc3VmZmVyIHRoZSBjb25zZXF1ZW5jZXMhIC8gSSdtIG5ldmVyIGR5aW5nLXRlcnJpZnlpbmcgcmVzdWx0cw==
+SSB3YWtlIHlhIHdpdGggaHVuZHJlZHMgb2YgdGhvdXNhbmRzIG9mIHZvbHRzIC8gTWljLXRvLW1vdXRoIHJlc3VzY2l0YXRpb24sIHJoeXRobSB3aXRoIHJhZGlhdGlvbg==
+Tm92b2NhaW4gZWFzZSB0aGUgcGFpbiBpdCBtaWdodCBzYXZlIGhpbSAvIElmIG5vdCwgRXJpYyBCLidzIHRoZSBqdWRnZSwgdGhlIGNyb3dkJ3MgdGhlIGp1cnk=
+WW8gUmFraW0sIHdoYXQncyB1cD8gLyBZbywgSSdtIGRvaW5nIHRoZSBrbm93bGVkZ2UsIEUuLCBtYW4gSSdtIHRyeWluZyB0byBnZXQgcGFpZCBpbiBmdWxs
+V2VsbCwgY2hlY2sgdGhpcyBvdXQsIHNpbmNlIE5vcmJ5IFdhbHRlcnMgaXMgb3VyIGFnZW5jeSwgcmlnaHQ/IC8gVHJ1ZQ==
+S2FyYSBMZXdpcyBpcyBvdXIgYWdlbnQsIHdvcmQgdXAgLyBaYWtpYSBhbmQgNHRoIGFuZCBCcm9hZHdheSBpcyBvdXIgcmVjb3JkIGNvbXBhbnksIGluZGVlZA==
+T2theSwgc28gd2hvIHdlIHJvbGxpbicgd2l0aCB0aGVuPyBXZSByb2xsaW4nIHdpdGggUnVzaCAvIE9mIFJ1c2h0b3duIE1hbmFnZW1lbnQ=
+Q2hlY2sgdGhpcyBvdXQsIHNpbmNlIHdlIHRhbGtpbmcgb3ZlciAvIFRoaXMgZGVmIGJlYXQgcmlnaHQgaGVyZSB0aGF0IEkgcHV0IHRvZ2V0aGVy
+SSB3YW5uYSBoZWFyIHNvbWUgb2YgdGhlbSBkZWYgcmh5bWVzLCB5b3Uga25vdyB3aGF0IEknbSBzYXlpbic/IC8gQW5kIHRvZ2V0aGVyLCB3ZSBjYW4gZ2V0IHBhaWQgaW4gZnVsbA==
+VGhpbmtpbicgb2YgYSBtYXN0ZXIgcGxhbiAvICdDdXogYWluJ3QgbnV0aGluJyBidXQgc3dlYXQgaW5zaWRlIG15IGhhbmQ=
+U28gSSBkaWcgaW50byBteSBwb2NrZXQsIGFsbCBteSBtb25leSBpcyBzcGVudCAvIFNvIEkgZGlnIGRlZXBlciBidXQgc3RpbGwgY29taW4nIHVwIHdpdGggbGludA==
+U28gSSBzdGFydCBteSBtaXNzaW9uLCBsZWF2ZSBteSByZXNpZGVuY2UgLyBUaGlua2luJyBob3cgY291bGQgSSBnZXQgc29tZSBkZWFkIHByZXNpZGVudHM=
+SSBuZWVkIG1vbmV5LCBJIHVzZWQgdG8gYmUgYSBzdGljay11cCBraWQgLyBTbyBJIHRoaW5rIG9mIGFsbCB0aGUgZGV2aW91cyB0aGluZ3MgSSBkaWQ=
+SSB1c2VkIHRvIHJvbGwgdXAsIHRoaXMgaXMgYSBob2xkIHVwLCBhaW4ndCBudXRoaW4nIGZ1bm55IC8gU3RvcCBzbWlsaW5nLCBiZSBzdGlsbCwgZG9uJ3QgbnV0aGluJyBtb3ZlIGJ1dCB0aGUgbW9uZXk=
+QnV0IG5vdyBJIGxlYXJuZWQgdG8gZWFybiAnY3V6IEknbSByaWdodGVvdXMgLyBJIGZlZWwgZ3JlYXQsIHNvIG1heWJlIEkgbWlnaHQganVzdA==
+U2VhcmNoIGZvciBhIG5pbmUgdG8gZml2ZSwgaWYgSSBzdHJpdmUgLyBUaGVuIG1heWJlIEknbGwgc3RheSBhbGl2ZQ==
+U28gSSB3YWxrIHVwIHRoZSBzdHJlZXQgd2hpc3RsaW4nIHRoaXMgLyBGZWVsaW4nIG91dCBvZiBwbGFjZSAnY3V6LCBtYW4sIGRvIEkgbWlzcw==
+QSBwZW4gYW5kIGEgcGFwZXIsIGEgc3RlcmVvLCBhIHRhcGUgb2YgLyBNZSBhbmQgRXJpYyBCLCBhbmQgYSBuaWNlIGJpZyBwbGF0ZSBvZg==
+RmlzaCwgd2hpY2ggaXMgbXkgZmF2b3JpdGUgZGlzaCAvIEJ1dCB3aXRob3V0IG5vIG1vbmV5IGl0J3Mgc3RpbGwgYSB3aXNo
+J0N1eiBJIGRvbid0IGxpa2UgdG8gZHJlYW0gYWJvdXQgZ2V0dGluJyBwYWlkIC8gU28gSSBkaWcgaW50byB0aGUgYm9va3Mgb2YgdGhlIHJoeW1lcyB0aGF0IEkgbWFkZQ==
+U28gbm93IHRvIHRlc3QgdG8gc2VlIGlmIEkgZ290IHB1bGwgLyBIaXQgdGhlIHN0dWRpbywgJ2N1eiBJJ20gcGFpZCBpbiBmdWxs
+UmFraW0sIGNoZWNrIHRoaXMgb3V0LCB5byAvIFlvdSBnbyB0byB5b3VyIGdpcmwgaG91c2UgYW5kIEknbGwgZ28gdG8gbWluZQ==
+J0NhdXNlIG15IGdpcmwgaXMgZGVmaW5pdGVseSBtYWQgLyAnQ2F1c2UgaXQgdG9vayB1cyB0b28gbG9uZyB0byBkbyB0aGlzIGFsYnVt
+WW8sIEkgaGVhciB3aGF0IHlvdSdyZSBzYXlpbmcgLyBTbyBsZXQncyBqdXN0IHB1bXAgdGhlIG11c2ljIHVw
+QW5kIGNvdW50IG91ciBtb25leSAvIFlvLCB3ZWxsIGNoZWNrIHRoaXMgb3V0LCB5byBFbGk=
+VHVybiBkb3duIHRoZSBiYXNzIGRvd24gLyBBbmQgbGV0IHRoZSBiZWF0IGp1c3Qga2VlcCBvbiByb2NraW4n
+QW5kIHdlIG91dHRhIGhlcmUgLyBZbywgd2hhdCBoYXBwZW5lZCB0byBwZWFjZT8gLyBQZWFjZQ==
diff --git a/set3/task20_data/task20_00 b/set3/task20_data/task20_00
new file mode 100644
index 0000000..ac2e746
--- /dev/null
+++ b/set3/task20_data/task20_00
@@ -0,0 +1 @@
+SSdtIHJhdGVkICJSIi4uLnRoaXMgaXMgYSB3YXJuaW5nLCB5YSBiZXR0ZXIgdm9pZCAvIFBvZXRzIGFyZSBwYXJhbm9pZCwgREoncyBELXN0cm95ZWQ=
diff --git a/set3/task20_data/task20_01 b/set3/task20_data/task20_01
new file mode 100644
index 0000000..6943297
--- /dev/null
+++ b/set3/task20_data/task20_01
@@ -0,0 +1 @@
+Q3V6IEkgY2FtZSBiYWNrIHRvIGF0dGFjayBvdGhlcnMgaW4gc3BpdGUtIC8gU3RyaWtlIGxpa2UgbGlnaHRuaW4nLCBJdCdzIHF1aXRlIGZyaWdodGVuaW4nIQ==
diff --git a/set3/task20_data/task20_02 b/set3/task20_data/task20_02
new file mode 100644
index 0000000..14536ba
--- /dev/null
+++ b/set3/task20_data/task20_02
@@ -0,0 +1 @@
+QnV0IGRvbid0IGJlIGFmcmFpZCBpbiB0aGUgZGFyaywgaW4gYSBwYXJrIC8gTm90IGEgc2NyZWFtIG9yIGEgY3J5LCBvciBhIGJhcmssIG1vcmUgbGlrZSBhIHNwYXJrOw==
diff --git a/set3/task20_data/task20_03 b/set3/task20_data/task20_03
new file mode 100644
index 0000000..1a5e846
--- /dev/null
+++ b/set3/task20_data/task20_03
@@ -0,0 +1 @@
+WWEgdHJlbWJsZSBsaWtlIGEgYWxjb2hvbGljLCBtdXNjbGVzIHRpZ2h0ZW4gdXAgLyBXaGF0J3MgdGhhdCwgbGlnaHRlbiB1cCEgWW91IHNlZSBhIHNpZ2h0IGJ1dA==
diff --git a/set3/task20_data/task20_04 b/set3/task20_data/task20_04
new file mode 100644
index 0000000..27afef9
--- /dev/null
+++ b/set3/task20_data/task20_04
@@ -0,0 +1 @@
+U3VkZGVubHkgeW91IGZlZWwgbGlrZSB5b3VyIGluIGEgaG9ycm9yIGZsaWNrIC8gWW91IGdyYWIgeW91ciBoZWFydCB0aGVuIHdpc2ggZm9yIHRvbW9ycm93IHF1aWNrIQ==
diff --git a/set3/task20_data/task20_05 b/set3/task20_data/task20_05
new file mode 100644
index 0000000..ceecbfa
--- /dev/null
+++ b/set3/task20_data/task20_05
@@ -0,0 +1 @@
+TXVzaWMncyB0aGUgY2x1ZSwgd2hlbiBJIGNvbWUgeW91ciB3YXJuZWQgLyBBcG9jYWx5cHNlIE5vdywgd2hlbiBJJ20gZG9uZSwgeWEgZ29uZSE=
diff --git a/set3/task20_data/task20_06 b/set3/task20_data/task20_06
new file mode 100644
index 0000000..d62512b
--- /dev/null
+++ b/set3/task20_data/task20_06
@@ -0,0 +1 @@
+SGF2ZW4ndCB5b3UgZXZlciBoZWFyZCBvZiBhIE1DLW11cmRlcmVyPyAvIFRoaXMgaXMgdGhlIGRlYXRoIHBlbmFsdHksYW5kIEknbSBzZXJ2aW4nIGE=
diff --git a/set3/task20_data/task20_07 b/set3/task20_data/task20_07
new file mode 100644
index 0000000..1b0cdc6
--- /dev/null
+++ b/set3/task20_data/task20_07
@@ -0,0 +1 @@
+RGVhdGggd2lzaCwgc28gY29tZSBvbiwgc3RlcCB0byB0aGlzIC8gSHlzdGVyaWNhbCBpZGVhIGZvciBhIGx5cmljYWwgcHJvZmVzc2lvbmlzdCE=
diff --git a/set3/task20_data/task20_08 b/set3/task20_data/task20_08
new file mode 100644
index 0000000..167d125
--- /dev/null
+++ b/set3/task20_data/task20_08
@@ -0,0 +1 @@
+RnJpZGF5IHRoZSB0aGlydGVlbnRoLCB3YWxraW5nIGRvd24gRWxtIFN0cmVldCAvIFlvdSBjb21lIGluIG15IHJlYWxtIHlhIGdldCBiZWF0IQ==
diff --git a/set3/task20_data/task20_09 b/set3/task20_data/task20_09
new file mode 100644
index 0000000..c572a4c
--- /dev/null
+++ b/set3/task20_data/task20_09
@@ -0,0 +1 @@
+VGhpcyBpcyBvZmYgbGltaXRzLCBzbyB5b3VyIHZpc2lvbnMgYXJlIGJsdXJyeSAvIEFsbCB5YSBzZWUgaXMgdGhlIG1ldGVycyBhdCBhIHZvbHVtZQ==
diff --git a/set3/task20_data/task20_10 b/set3/task20_data/task20_10
new file mode 100644
index 0000000..8e58d06
--- /dev/null
+++ b/set3/task20_data/task20_10
@@ -0,0 +1 @@
+VGVycm9yIGluIHRoZSBzdHlsZXMsIG5ldmVyIGVycm9yLWZpbGVzIC8gSW5kZWVkIEknbSBrbm93bi15b3VyIGV4aWxlZCE=
diff --git a/set3/task20_data/task20_11 b/set3/task20_data/task20_11
new file mode 100644
index 0000000..1b4f6fd
--- /dev/null
+++ b/set3/task20_data/task20_11
@@ -0,0 +1 @@
+Rm9yIHRob3NlIHRoYXQgb3Bwb3NlIHRvIGJlIGxldmVsIG9yIG5leHQgdG8gdGhpcyAvIEkgYWluJ3QgYSBkZXZpbCBhbmQgdGhpcyBhaW4ndCB0aGUgRXhvcmNpc3Qh
diff --git a/set3/task20_data/task20_12 b/set3/task20_data/task20_12
new file mode 100644
index 0000000..699eaf0
--- /dev/null
+++ b/set3/task20_data/task20_12
@@ -0,0 +1 @@
+V29yc2UgdGhhbiBhIG5pZ2h0bWFyZSwgeW91IGRvbid0IGhhdmUgdG8gc2xlZXAgYSB3aW5rIC8gVGhlIHBhaW4ncyBhIG1pZ3JhaW5lIGV2ZXJ5IHRpbWUgeWEgdGhpbms=
diff --git a/set3/task20_data/task20_13 b/set3/task20_data/task20_13
new file mode 100644
index 0000000..f891df2
--- /dev/null
+++ b/set3/task20_data/task20_13
@@ -0,0 +1 @@
+Rmxhc2hiYWNrcyBpbnRlcmZlcmUsIHlhIHN0YXJ0IHRvIGhlYXI6IC8gVGhlIFItQS1LLUktTSBpbiB5b3VyIGVhcjs=
diff --git a/set3/task20_data/task20_14 b/set3/task20_data/task20_14
new file mode 100644
index 0000000..e9280e7
--- /dev/null
+++ b/set3/task20_data/task20_14
@@ -0,0 +1 @@
+VGhlbiB0aGUgYmVhdCBpcyBoeXN0ZXJpY2FsIC8gVGhhdCBtYWtlcyBFcmljIGdvIGdldCBhIGF4IGFuZCBjaG9wcyB0aGUgd2Fjaw==
diff --git a/set3/task20_data/task20_15 b/set3/task20_data/task20_15
new file mode 100644
index 0000000..dc0266b
--- /dev/null
+++ b/set3/task20_data/task20_15
@@ -0,0 +1 @@
+U29vbiB0aGUgbHlyaWNhbCBmb3JtYXQgaXMgc3VwZXJpb3IgLyBGYWNlcyBvZiBkZWF0aCByZW1haW4=
diff --git a/set3/task20_data/task20_16 b/set3/task20_data/task20_16
new file mode 100644
index 0000000..6d45b04
--- /dev/null
+++ b/set3/task20_data/task20_16
@@ -0,0 +1 @@
+TUMncyBkZWNheWluZywgY3V6IHRoZXkgbmV2ZXIgc3RheWVkIC8gVGhlIHNjZW5lIG9mIGEgY3JpbWUgZXZlcnkgbmlnaHQgYXQgdGhlIHNob3c=
diff --git a/set3/task20_data/task20_17 b/set3/task20_data/task20_17
new file mode 100644
index 0000000..6ef9c4e
--- /dev/null
+++ b/set3/task20_data/task20_17
@@ -0,0 +1 @@
+VGhlIGZpZW5kIG9mIGEgcmh5bWUgb24gdGhlIG1pYyB0aGF0IHlvdSBrbm93IC8gSXQncyBvbmx5IG9uZSBjYXBhYmxlLCBicmVha3MtdGhlIHVuYnJlYWthYmxl
diff --git a/set3/task20_data/task20_18 b/set3/task20_data/task20_18
new file mode 100644
index 0000000..0fa105b
--- /dev/null
+++ b/set3/task20_data/task20_18
@@ -0,0 +1 @@
+TWVsb2RpZXMtdW5tYWthYmxlLCBwYXR0ZXJuLXVuZXNjYXBhYmxlIC8gQSBob3JuIGlmIHdhbnQgdGhlIHN0eWxlIEkgcG9zc2Vz
diff --git a/set3/task20_data/task20_19 b/set3/task20_data/task20_19
new file mode 100644
index 0000000..ea62d7a
--- /dev/null
+++ b/set3/task20_data/task20_19
@@ -0,0 +1 @@
+SSBibGVzcyB0aGUgY2hpbGQsIHRoZSBlYXJ0aCwgdGhlIGdvZHMgYW5kIGJvbWIgdGhlIHJlc3QgLyBGb3IgdGhvc2UgdGhhdCBlbnZ5IGEgTUMgaXQgY2FuIGJl
diff --git a/set3/task20_data/task20_20 b/set3/task20_data/task20_20
new file mode 100644
index 0000000..aa92a4d
--- /dev/null
+++ b/set3/task20_data/task20_20
@@ -0,0 +1 @@
+SGF6YXJkb3VzIHRvIHlvdXIgaGVhbHRoIHNvIGJlIGZyaWVuZGx5IC8gQSBtYXR0ZXIgb2YgbGlmZSBhbmQgZGVhdGgsIGp1c3QgbGlrZSBhIGV0Y2gtYS1za2V0Y2g=
diff --git a/set3/task20_data/task20_21 b/set3/task20_data/task20_21
new file mode 100644
index 0000000..3d2f0cd
--- /dev/null
+++ b/set3/task20_data/task20_21
@@ -0,0 +1 @@
+U2hha2UgJ3RpbGwgeW91ciBjbGVhciwgbWFrZSBpdCBkaXNhcHBlYXIsIG1ha2UgdGhlIG5leHQgLyBBZnRlciB0aGUgY2VyZW1vbnksIGxldCB0aGUgcmh5bWUgcmVzdCBpbiBwZWFjZQ==
diff --git a/set3/task20_data/task20_22 b/set3/task20_data/task20_22
new file mode 100644
index 0000000..bb86671
--- /dev/null
+++ b/set3/task20_data/task20_22
@@ -0,0 +1 @@
+SWYgbm90LCBteSBzb3VsJ2xsIHJlbGVhc2UhIC8gVGhlIHNjZW5lIGlzIHJlY3JlYXRlZCwgcmVpbmNhcm5hdGVkLCB1cGRhdGVkLCBJJ20gZ2xhZCB5b3UgbWFkZSBpdA==
diff --git a/set3/task20_data/task20_23 b/set3/task20_data/task20_23
new file mode 100644
index 0000000..82b150e
--- /dev/null
+++ b/set3/task20_data/task20_23
@@ -0,0 +1 @@
+Q3V6IHlvdXIgYWJvdXQgdG8gc2VlIGEgZGlzYXN0cm91cyBzaWdodCAvIEEgcGVyZm9ybWFuY2UgbmV2ZXIgYWdhaW4gcGVyZm9ybWVkIG9uIGEgbWljOg==
diff --git a/set3/task20_data/task20_24 b/set3/task20_data/task20_24
new file mode 100644
index 0000000..e5bde2d
--- /dev/null
+++ b/set3/task20_data/task20_24
@@ -0,0 +1 @@
+THlyaWNzIG9mIGZ1cnkhIEEgZmVhcmlmaWVkIGZyZWVzdHlsZSEgLyBUaGUgIlIiIGlzIGluIHRoZSBob3VzZS10b28gbXVjaCB0ZW5zaW9uIQ==
diff --git a/set3/task20_data/task20_25 b/set3/task20_data/task20_25
new file mode 100644
index 0000000..f2bdd91
--- /dev/null
+++ b/set3/task20_data/task20_25
@@ -0,0 +1 @@
+TWFrZSBzdXJlIHRoZSBzeXN0ZW0ncyBsb3VkIHdoZW4gSSBtZW50aW9uIC8gUGhyYXNlcyB0aGF0J3MgZmVhcnNvbWU=
diff --git a/set3/task20_data/task20_26 b/set3/task20_data/task20_26
new file mode 100644
index 0000000..ddd7843
--- /dev/null
+++ b/set3/task20_data/task20_26
@@ -0,0 +1 @@
+WW91IHdhbnQgdG8gaGVhciBzb21lIHNvdW5kcyB0aGF0IG5vdCBvbmx5IHBvdW5kcyBidXQgcGxlYXNlIHlvdXIgZWFyZHJ1bXM7IC8gSSBzaXQgYmFjayBhbmQgb2JzZXJ2ZSB0aGUgd2hvbGUgc2NlbmVyeQ==
diff --git a/set3/task20_data/task20_27 b/set3/task20_data/task20_27
new file mode 100644
index 0000000..d3c97e1
--- /dev/null
+++ b/set3/task20_data/task20_27
@@ -0,0 +1 @@
+VGhlbiBub25jaGFsYW50bHkgdGVsbCB5b3Ugd2hhdCBpdCBtZWFuIHRvIG1lIC8gU3RyaWN0bHkgYnVzaW5lc3MgSSdtIHF1aWNrbHkgaW4gdGhpcyBtb29k
diff --git a/set3/task20_data/task20_28 b/set3/task20_data/task20_28
new file mode 100644
index 0000000..ee11c9b
--- /dev/null
+++ b/set3/task20_data/task20_28
@@ -0,0 +1 @@
+QW5kIEkgZG9uJ3QgY2FyZSBpZiB0aGUgd2hvbGUgY3Jvd2QncyBhIHdpdG5lc3MhIC8gSSdtIGEgdGVhciB5b3UgYXBhcnQgYnV0IEknbSBhIHNwYXJlIHlvdSBhIGhlYXJ0
diff --git a/set3/task20_data/task20_29 b/set3/task20_data/task20_29
new file mode 100644
index 0000000..6a3d89c
--- /dev/null
+++ b/set3/task20_data/task20_29
@@ -0,0 +1 @@
+UHJvZ3JhbSBpbnRvIHRoZSBzcGVlZCBvZiB0aGUgcmh5bWUsIHByZXBhcmUgdG8gc3RhcnQgLyBSaHl0aG0ncyBvdXQgb2YgdGhlIHJhZGl1cywgaW5zYW5lIGFzIHRoZSBjcmF6aWVzdA==
diff --git a/set3/task20_data/task20_30 b/set3/task20_data/task20_30
new file mode 100644
index 0000000..7a67926
--- /dev/null
+++ b/set3/task20_data/task20_30
@@ -0,0 +1 @@
+TXVzaWNhbCBtYWRuZXNzIE1DIGV2ZXIgbWFkZSwgc2VlIGl0J3MgLyBOb3cgYW4gZW1lcmdlbmN5LCBvcGVuLWhlYXJ0IHN1cmdlcnk=
diff --git a/set3/task20_data/task20_31 b/set3/task20_data/task20_31
new file mode 100644
index 0000000..93dccdb
--- /dev/null
+++ b/set3/task20_data/task20_31
@@ -0,0 +1 @@
+T3BlbiB5b3VyIG1pbmQsIHlvdSB3aWxsIGZpbmQgZXZlcnkgd29yZCdsbCBiZSAvIEZ1cmllciB0aGFuIGV2ZXIsIEkgcmVtYWluIHRoZSBmdXJ0dXJl
diff --git a/set3/task20_data/task20_32 b/set3/task20_data/task20_32
new file mode 100644
index 0000000..bea3372
--- /dev/null
+++ b/set3/task20_data/task20_32
@@ -0,0 +1 @@
+QmF0dGxlJ3MgdGVtcHRpbmcuLi53aGF0ZXZlciBzdWl0cyB5YSEgLyBGb3Igd29yZHMgdGhlIHNlbnRlbmNlLCB0aGVyZSdzIG5vIHJlc2VtYmxhbmNl
diff --git a/set3/task20_data/task20_33 b/set3/task20_data/task20_33
new file mode 100644
index 0000000..923dacb
--- /dev/null
+++ b/set3/task20_data/task20_33
@@ -0,0 +1 @@
+WW91IHRoaW5rIHlvdSdyZSBydWZmZXIsIHRoZW4gc3VmZmVyIHRoZSBjb25zZXF1ZW5jZXMhIC8gSSdtIG5ldmVyIGR5aW5nLXRlcnJpZnlpbmcgcmVzdWx0cw==
diff --git a/set3/task20_data/task20_34 b/set3/task20_data/task20_34
new file mode 100644
index 0000000..400c011
--- /dev/null
+++ b/set3/task20_data/task20_34
@@ -0,0 +1 @@
+SSB3YWtlIHlhIHdpdGggaHVuZHJlZHMgb2YgdGhvdXNhbmRzIG9mIHZvbHRzIC8gTWljLXRvLW1vdXRoIHJlc3VzY2l0YXRpb24sIHJoeXRobSB3aXRoIHJhZGlhdGlvbg==
diff --git a/set3/task20_data/task20_35 b/set3/task20_data/task20_35
new file mode 100644
index 0000000..08387b4
--- /dev/null
+++ b/set3/task20_data/task20_35
@@ -0,0 +1 @@
+Tm92b2NhaW4gZWFzZSB0aGUgcGFpbiBpdCBtaWdodCBzYXZlIGhpbSAvIElmIG5vdCwgRXJpYyBCLidzIHRoZSBqdWRnZSwgdGhlIGNyb3dkJ3MgdGhlIGp1cnk=
diff --git a/set3/task20_data/task20_36 b/set3/task20_data/task20_36
new file mode 100644
index 0000000..1baef68
--- /dev/null
+++ b/set3/task20_data/task20_36
@@ -0,0 +1 @@
+WW8gUmFraW0sIHdoYXQncyB1cD8gLyBZbywgSSdtIGRvaW5nIHRoZSBrbm93bGVkZ2UsIEUuLCBtYW4gSSdtIHRyeWluZyB0byBnZXQgcGFpZCBpbiBmdWxs
diff --git a/set3/task20_data/task20_37 b/set3/task20_data/task20_37
new file mode 100644
index 0000000..f538f91
--- /dev/null
+++ b/set3/task20_data/task20_37
@@ -0,0 +1 @@
+V2VsbCwgY2hlY2sgdGhpcyBvdXQsIHNpbmNlIE5vcmJ5IFdhbHRlcnMgaXMgb3VyIGFnZW5jeSwgcmlnaHQ/IC8gVHJ1ZQ==
diff --git a/set3/task20_data/task20_38 b/set3/task20_data/task20_38
new file mode 100644
index 0000000..c22e18b
--- /dev/null
+++ b/set3/task20_data/task20_38
@@ -0,0 +1 @@
+S2FyYSBMZXdpcyBpcyBvdXIgYWdlbnQsIHdvcmQgdXAgLyBaYWtpYSBhbmQgNHRoIGFuZCBCcm9hZHdheSBpcyBvdXIgcmVjb3JkIGNvbXBhbnksIGluZGVlZA==
diff --git a/set3/task20_data/task20_39 b/set3/task20_data/task20_39
new file mode 100644
index 0000000..baa3a60
--- /dev/null
+++ b/set3/task20_data/task20_39
@@ -0,0 +1 @@
+T2theSwgc28gd2hvIHdlIHJvbGxpbicgd2l0aCB0aGVuPyBXZSByb2xsaW4nIHdpdGggUnVzaCAvIE9mIFJ1c2h0b3duIE1hbmFnZW1lbnQ=
diff --git a/set3/task20_data/task20_40 b/set3/task20_data/task20_40
new file mode 100644
index 0000000..727f26b
--- /dev/null
+++ b/set3/task20_data/task20_40
@@ -0,0 +1 @@
+Q2hlY2sgdGhpcyBvdXQsIHNpbmNlIHdlIHRhbGtpbmcgb3ZlciAvIFRoaXMgZGVmIGJlYXQgcmlnaHQgaGVyZSB0aGF0IEkgcHV0IHRvZ2V0aGVy
diff --git a/set3/task20_data/task20_41 b/set3/task20_data/task20_41
new file mode 100644
index 0000000..dc92f01
--- /dev/null
+++ b/set3/task20_data/task20_41
@@ -0,0 +1 @@
+SSB3YW5uYSBoZWFyIHNvbWUgb2YgdGhlbSBkZWYgcmh5bWVzLCB5b3Uga25vdyB3aGF0IEknbSBzYXlpbic/IC8gQW5kIHRvZ2V0aGVyLCB3ZSBjYW4gZ2V0IHBhaWQgaW4gZnVsbA==
diff --git a/set3/task20_data/task20_42 b/set3/task20_data/task20_42
new file mode 100644
index 0000000..ec235cb
--- /dev/null
+++ b/set3/task20_data/task20_42
@@ -0,0 +1 @@
+VGhpbmtpbicgb2YgYSBtYXN0ZXIgcGxhbiAvICdDdXogYWluJ3QgbnV0aGluJyBidXQgc3dlYXQgaW5zaWRlIG15IGhhbmQ=
diff --git a/set3/task20_data/task20_43 b/set3/task20_data/task20_43
new file mode 100644
index 0000000..1961536
--- /dev/null
+++ b/set3/task20_data/task20_43
@@ -0,0 +1 @@
+U28gSSBkaWcgaW50byBteSBwb2NrZXQsIGFsbCBteSBtb25leSBpcyBzcGVudCAvIFNvIEkgZGlnIGRlZXBlciBidXQgc3RpbGwgY29taW4nIHVwIHdpdGggbGludA==
diff --git a/set3/task20_data/task20_44 b/set3/task20_data/task20_44
new file mode 100644
index 0000000..53fe8f7
--- /dev/null
+++ b/set3/task20_data/task20_44
@@ -0,0 +1 @@
+U28gSSBzdGFydCBteSBtaXNzaW9uLCBsZWF2ZSBteSByZXNpZGVuY2UgLyBUaGlua2luJyBob3cgY291bGQgSSBnZXQgc29tZSBkZWFkIHByZXNpZGVudHM=
diff --git a/set3/task20_data/task20_45 b/set3/task20_data/task20_45
new file mode 100644
index 0000000..feee2f5
--- /dev/null
+++ b/set3/task20_data/task20_45
@@ -0,0 +1 @@
+SSBuZWVkIG1vbmV5LCBJIHVzZWQgdG8gYmUgYSBzdGljay11cCBraWQgLyBTbyBJIHRoaW5rIG9mIGFsbCB0aGUgZGV2aW91cyB0aGluZ3MgSSBkaWQ=
diff --git a/set3/task20_data/task20_46 b/set3/task20_data/task20_46
new file mode 100644
index 0000000..3674e29
--- /dev/null
+++ b/set3/task20_data/task20_46
@@ -0,0 +1 @@
+SSB1c2VkIHRvIHJvbGwgdXAsIHRoaXMgaXMgYSBob2xkIHVwLCBhaW4ndCBudXRoaW4nIGZ1bm55IC8gU3RvcCBzbWlsaW5nLCBiZSBzdGlsbCwgZG9uJ3QgbnV0aGluJyBtb3ZlIGJ1dCB0aGUgbW9uZXk=
diff --git a/set3/task20_data/task20_47 b/set3/task20_data/task20_47
new file mode 100644
index 0000000..767b9e4
--- /dev/null
+++ b/set3/task20_data/task20_47
@@ -0,0 +1 @@
+QnV0IG5vdyBJIGxlYXJuZWQgdG8gZWFybiAnY3V6IEknbSByaWdodGVvdXMgLyBJIGZlZWwgZ3JlYXQsIHNvIG1heWJlIEkgbWlnaHQganVzdA==
diff --git a/set3/task20_data/task20_48 b/set3/task20_data/task20_48
new file mode 100644
index 0000000..085376b
--- /dev/null
+++ b/set3/task20_data/task20_48
@@ -0,0 +1 @@
+U2VhcmNoIGZvciBhIG5pbmUgdG8gZml2ZSwgaWYgSSBzdHJpdmUgLyBUaGVuIG1heWJlIEknbGwgc3RheSBhbGl2ZQ==
diff --git a/set3/task20_data/task20_49 b/set3/task20_data/task20_49
new file mode 100644
index 0000000..d555793
--- /dev/null
+++ b/set3/task20_data/task20_49
@@ -0,0 +1 @@
+U28gSSB3YWxrIHVwIHRoZSBzdHJlZXQgd2hpc3RsaW4nIHRoaXMgLyBGZWVsaW4nIG91dCBvZiBwbGFjZSAnY3V6LCBtYW4sIGRvIEkgbWlzcw==
diff --git a/set3/task20_data/task20_50 b/set3/task20_data/task20_50
new file mode 100644
index 0000000..ab56c37
--- /dev/null
+++ b/set3/task20_data/task20_50
@@ -0,0 +1 @@
+QSBwZW4gYW5kIGEgcGFwZXIsIGEgc3RlcmVvLCBhIHRhcGUgb2YgLyBNZSBhbmQgRXJpYyBCLCBhbmQgYSBuaWNlIGJpZyBwbGF0ZSBvZg==
diff --git a/set3/task20_data/task20_51 b/set3/task20_data/task20_51
new file mode 100644
index 0000000..a16af8d
--- /dev/null
+++ b/set3/task20_data/task20_51
@@ -0,0 +1 @@
+RmlzaCwgd2hpY2ggaXMgbXkgZmF2b3JpdGUgZGlzaCAvIEJ1dCB3aXRob3V0IG5vIG1vbmV5IGl0J3Mgc3RpbGwgYSB3aXNo
diff --git a/set3/task20_data/task20_52 b/set3/task20_data/task20_52
new file mode 100644
index 0000000..716e574
--- /dev/null
+++ b/set3/task20_data/task20_52
@@ -0,0 +1 @@
+J0N1eiBJIGRvbid0IGxpa2UgdG8gZHJlYW0gYWJvdXQgZ2V0dGluJyBwYWlkIC8gU28gSSBkaWcgaW50byB0aGUgYm9va3Mgb2YgdGhlIHJoeW1lcyB0aGF0IEkgbWFkZQ==
diff --git a/set3/task20_data/task20_53 b/set3/task20_data/task20_53
new file mode 100644
index 0000000..297a7dd
--- /dev/null
+++ b/set3/task20_data/task20_53
@@ -0,0 +1 @@
+U28gbm93IHRvIHRlc3QgdG8gc2VlIGlmIEkgZ290IHB1bGwgLyBIaXQgdGhlIHN0dWRpbywgJ2N1eiBJJ20gcGFpZCBpbiBmdWxs
diff --git a/set3/task20_data/task20_54 b/set3/task20_data/task20_54
new file mode 100644
index 0000000..1e7e995
--- /dev/null
+++ b/set3/task20_data/task20_54
@@ -0,0 +1 @@
+UmFraW0sIGNoZWNrIHRoaXMgb3V0LCB5byAvIFlvdSBnbyB0byB5b3VyIGdpcmwgaG91c2UgYW5kIEknbGwgZ28gdG8gbWluZQ==
diff --git a/set3/task20_data/task20_55 b/set3/task20_data/task20_55
new file mode 100644
index 0000000..c943c24
--- /dev/null
+++ b/set3/task20_data/task20_55
@@ -0,0 +1 @@
+J0NhdXNlIG15IGdpcmwgaXMgZGVmaW5pdGVseSBtYWQgLyAnQ2F1c2UgaXQgdG9vayB1cyB0b28gbG9uZyB0byBkbyB0aGlzIGFsYnVt
diff --git a/set3/task20_data/task20_56 b/set3/task20_data/task20_56
new file mode 100644
index 0000000..95796f5
--- /dev/null
+++ b/set3/task20_data/task20_56
@@ -0,0 +1 @@
+WW8sIEkgaGVhciB3aGF0IHlvdSdyZSBzYXlpbmcgLyBTbyBsZXQncyBqdXN0IHB1bXAgdGhlIG11c2ljIHVw
diff --git a/set3/task20_data/task20_57 b/set3/task20_data/task20_57
new file mode 100644
index 0000000..a456bfd
--- /dev/null
+++ b/set3/task20_data/task20_57
@@ -0,0 +1 @@
+QW5kIGNvdW50IG91ciBtb25leSAvIFlvLCB3ZWxsIGNoZWNrIHRoaXMgb3V0LCB5byBFbGk=
diff --git a/set3/task20_data/task20_58 b/set3/task20_data/task20_58
new file mode 100644
index 0000000..cfa083a
--- /dev/null
+++ b/set3/task20_data/task20_58
@@ -0,0 +1 @@
+VHVybiBkb3duIHRoZSBiYXNzIGRvd24gLyBBbmQgbGV0IHRoZSBiZWF0IGp1c3Qga2VlcCBvbiByb2NraW4n
diff --git a/set3/task20_data/task20_59 b/set3/task20_data/task20_59
new file mode 100644
index 0000000..9e6988d
--- /dev/null
+++ b/set3/task20_data/task20_59
@@ -0,0 +1 @@
+QW5kIHdlIG91dHRhIGhlcmUgLyBZbywgd2hhdCBoYXBwZW5lZCB0byBwZWFjZT8gLyBQZWFjZQ==
diff --git a/set4/task29.c b/set4/task29.c
new file mode 100644
index 0000000..4b6f4d0
--- /dev/null
+++ b/set4/task29.c
@@ -0,0 +1,67 @@
+#include "../lib/lib.h"
+#include "../lib/lib2.h"
+#include "../lib/lib3.h"
+#include "../lib/lib4.h"
+#include <time.h>
+
+
+int main(int argc, char **argv)
+{
+ if(argc != 2)
+ printf("Please provide ONE key as argument!\n");
+ uint32_t *hmac;
+ uint32_t *hmac2;
+ int i;
+ unsigned char *text = "comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon";
+ unsigned char *append = ";admin=true";
+ unsigned char *key = argv[1];
+ printf("Using secret key: %s\n", key);
+
+ unsigned char *padded;
+ int padding_len = md4_padding(strlen(key)+strlen(text), &padded);
+
+ printf("MD4 padding is:\n");
+ for(i=0;i<padding_len;i++)
+ printf("%02x", padded);
+
+ md4_prefix_key_mac(&hmac, text, strlen(text), key, strlen(key));
+ printf("MAC of original message:\n");
+ for(i=0;i<5;i++)
+ printf("%02x", hmac[i]);
+
+ printf("\n");
+
+ /*
+ * We are appending a text to the original message without knowign the
+ * key. Actually we don't know the message here, just the hash of the orginal
+ * message. We have to append the right padding here, e.g. the size of the
+ * *complete* message, not only append
+ */
+ unsigned int new_msg_len = strlen(text)+strlen(append)+padding_len;
+ unsigned char *new_msg = malloc(new_msg_len);
+ memcpy(new_msg, text, strlen(text));
+ memcpy(&new_msg[strlen(text)], padded, padding_len);
+ memcpy(&new_msg[strlen(text)+padding_len], append, strlen(append));
+
+ unsigned char *padding2;
+ // mesage + padding + append + padding
+ int padding2_len = md4_padding(new_msg_len+strlen(key), &padding2);
+ unsigned char *tmp2 = malloc(strlen(append)+padding2_len);
+ memcpy(tmp2, append, strlen(append));
+ memcpy(&tmp2[strlen(append)], padding2, padding2_len);
+ md4_prefix_key_forge(&hmac2, tmp2, (strlen(append)+padding2_len), hmac);
+ printf("MAC of forged message:\n");
+ for(i=0;i<5;i++)
+ printf("%02x", hmac2[i]);
+
+ printf("\n");
+
+ /*
+ * create the message we forged. Send this plus the hmac to the
+ * victim. He knows the secret and test and will think that
+ * this is a message from Alice
+ */
+ printf("Verifying...\n");
+ if(md4_prefix_key_verify(hmac2, new_msg, new_msg_len, key, strlen(key)))
+ printf("Forged MAC got accepted!\n");
+}
diff --git a/set4/task30.c b/set4/task30.c
new file mode 100644
index 0000000..e0b2906
--- /dev/null
+++ b/set4/task30.c
@@ -0,0 +1,58 @@
+#include "../lib/lib.h"
+#include "../lib/lib2.h"
+#include "../lib/lib3.h"
+#include "../lib/lib4.h"
+#include <time.h>
+
+
+int main(int argc, char **argv)
+{
+ int i;
+
+ if(argc != 2)
+ printf("Please provide ONE key as argument!\n");
+ uint32_t *hex;
+ uint32_t *hex2;
+ char *text = "comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon";
+ char *append = ";admin=true";
+ char *key = argv[1];
+
+ printf("Using secret key: %s\n", key);
+
+ unsigned char *padded;
+ // padding in MD4 is the same as in SHA1
+ int padding_len = sha1_padding(strlen(text), &padded);
+
+ md4_prefix_key_mac(&hex, text, strlen(text), key, strlen(key));
+ printf("MAC of original message:\n");
+ for(i=0;i<5;i++)
+ printf("%02x", hex[i]);
+
+ printf("\n");
+
+ /*
+ * We are appending a text to the original message without knowign the
+ * key. Actually we don't know the message here, just the length of
+ * the message.
+ */
+ md4_prefix_key_forge(&hex2, append, strlen(append), hex);
+ printf("MAC of forged message:\n");
+ for(i=0;i<5;i++)
+ printf("%02x", hex2[i]);
+
+ printf("\n");
+
+ /*
+ * create the message we forged. Send this plus the hmac to the
+ * victim. He knows the secret and test and will think that
+ * this is a message from Alice
+ */
+ unsigned int new_msg_len = strlen(text)+strlen(append)+padding_len;
+ char *new_msg = malloc(new_msg_len);
+ memcpy(new_msg, text, strlen(text));
+ memcpy(&new_msg[strlen(text)], padded, padding_len);
+ memcpy(&new_msg[strlen(text)+padding_len], append, strlen(append));
+
+ if(md4_prefix_key_verify(hex2, new_msg, new_msg_len, key, strlen(key)))
+ printf("Forged MAC got accepted!\n");
+}