diff options
| author | Benedict <benedict@0xb8000.de> | 2016-12-19 20:06:52 +0100 |
|---|---|---|
| committer | Benedict <benedict@0xb8000.de> | 2017-02-21 13:00:26 +0100 |
| commit | 530fcd5aaf841210a9d2d189f551c309970916e9 (patch) | |
| tree | b82ff437605f29e157874922a39ea25957ec8225 /set6 | |
| parent | 7e8ed345e50edd4253d9c409c10650b08a39fa87 (diff) | |
set6: challenge 46: completed
Diffstat (limited to 'set6')
| -rw-r--r-- | set6/task46.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/set6/task46.c b/set6/task46.c new file mode 100644 index 0000000..069e858 --- /dev/null +++ b/set6/task46.c @@ -0,0 +1,79 @@ +#include "../lib/lib.h" +#include "../lib/lib2.h" +#include "../lib/lib4.h" +#include "../lib/lib5.h" +#include "../lib/lib6.h" +#include <openssl/sha.h> + +int main() +{ + struct rsa_key_bignum private, public; + + out = BIO_new(BIO_s_file()); + BIO_set_fp(out, stdout, BIO_NOCLOSE); + ctx = BN_CTX_new(); + + private.modulo = BN_new(); + private.exponent = BN_new(); + public.modulo = BN_new(); + public.exponent = BN_new(); + + + __rsa_generate_key_bignum(&public, &private, 512); + + char *message_base64 = "VGhhdCdzIHdoeSBJIGZvdW5kIHlvdSBkb24ndCBwbGF5IG" + "Fyb3VuZCB3aXRoIHRoZSBGdW5reSBDb2xkIE1lZGluYQ=="; + + char *message = malloc(strlen(message_base64)*2); + int message_len = decode_base64(message_base64, message); + + BIGNUM *message_bn = BN_new(); + BIGNUM *encrypted = BN_new(); + BIGNUM *decrypted = BN_new(); + BN_bin2bn(message, message_len, message_bn); + // encrpyted message now + rsa_encrypt_bignum(message_bn, encrypted, &public); + printf("encrypted is\n"); + BN_print(out, encrypted); + + rsa_decrypt_bignum(encrypted, decrypted, &private); + printf("\ndecrypted:\n"); + BN_print(out, decrypted); + + // so all we want if finding a number between [0,N] which represents + // the plaintext. + // doing kind of binary search here, always split in half + int odd = 0; + BIGNUM *min = BN_new(); + BIGNUM *max = BN_new(); + BIGNUM *n2 = BN_new(); + BIGNUM *ne2 = BN_new(); + BIGNUM *tmp = BN_new(); + BIGNUM *diff = BN_new(); + BN_set_word(n2, 2); + BN_mod_exp(ne2, n2, public.exponent, public.modulo, ctx); + BN_copy(tmp, encrypted); + BN_zero(min); + BN_copy(max, public.modulo); + + // when min and max are equal we found our plaintext + while(BN_cmp(min,max) != 1) { + BN_sub(diff, max, min); + if(BN_is_one(diff)) + break; + BN_div(diff, NULL, diff, n2, ctx); + // multiply ciphertext with 2^e so that plaintext is multiplied + // by 2 + BN_mod_mul(tmp, ne2, tmp, public.modulo, ctx); + odd = rsa_parity_orcale(tmp, &private); + if (!odd) + BN_sub(max, max, diff); + else + BN_add(min, min, diff); + } + printf("\ndecrypted plaintext is:\n"); + BN_print(out, max); + char *readable_mess = malloc(BN_num_bytes(max)); + BN_bn2bin(max, readable_mess); + printf("\nmessage is: %s\n", readable_mess); +} |
