1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
#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);
}
|