summaryrefslogtreecommitdiff
path: root/set6/task46.c
blob: 069e858204ecf4011af7792deebc1fa6fbf7b53b (plain)
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);
}