Với mục tiêu nghiên cứu đề xuất một số phương pháp MHCTCT có
tính khả thi triển khai trong thực tiễn đảm bảo tính chất đúng đắn, an toàn và
chối từ. Sau một thời gian nghiên cứu và dưới sự hướng dẫn tận tình của tập
thể hướng dẫn khoa học, mặc dù còn nhiều hạn chế về chuyên môn, thời gian
cũng như những khó khăn về nguồn tài liệu, nhất là một lĩnh vực rất hẹp là
lĩnh vực mã hóa có thể chối từ, song nghiên cứu sinh đã nỗ lực hết mình để
hoàn thành các mục tiêu của đề tài Luận án. Có thể tóm lược một số kết quả
chính mà Luận án đã đạt được bao gồm:
A. Kết quả đạt được và đóng góp của Luận án
1- Đề xuất phương pháp tổng quát thực hiện MHCTCT khóa bất đối
xứng dựa trên giao thức ba bước Shamir theo cách thức mã hóa xác suất, sử
dụng các thuật toán mã hóa có tính chất giao hoán. Trên cơ sở phương pháp
tổng quát, đã đề xuất ba giao thức MHCTCT cụ thể sử dụng các hệ mật khác
nhau.
178 trang |
Chia sẻ: tueminh09 | Ngày: 24/01/2022 | Lượt xem: 459 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Luận án Một số phương pháp mã hóa có thể chối từ dựa trên mã hóa xác suất, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
1k
79772632047844025765604166
037401987251354
2k
63743063916630447383944451
797961654285461
[r]
660e60d236c01cf648e6a284f5e51
3a7
[ ]mc
5ed94fbbcb597c275def55070b64b
2d1
[ ]c
29072898613839200221317898594
35698784666964407121735580626
230866155296524093306455
<1 <1 m
5aaf105645ff30992de7849701
f4af87
2K
a6b27727a2c5e12af155921a84
a6b39d33117c63ca11a83858ad
07e54fa50e6a
[ ]mc
02f48d05491aaec08fe05cf1848f7
8ce
[ ]mc
5ed94fbbcb597c275def55070b64b
2d1
[ ]c
18007335591030181378087674590
94685115814611689386581120945
893663594950300617068141
<1 <1
4 m
9cd6e835bf39c91b11ef78fbe7
c6197e
1K
a8227a7366783be45359c69805
7d90016cc444d39d3df372f56c
d006fe74b868
1k
79145702904792259557161248
83596106177056
2k
69329542683535809873861180
37568543566541
[r]
22948c131699792fdcecd402875ef
389
[ ]mc
22bd728b6d6b4d610683a20b1310b
dce
[ ]c
31250661272183643584685065599
19567441955837581963666389124
0445211770129085707854
<1 <1 m
d5b54a9ce37d88e9bc0f970204
56bc16
2K
873edba21ca2b5ddf503142298
4acd31d2bd336a079615a256c5
65a5c3a6a01d
[ ]mc
c36b6fc0221c712c3c359d59aca52
16a
[ ]mc
22bd728b6d6b4d610683a20b1310b
dce
[ ]c
25178641402768859242660995225
42784333010590343780526330318
8588991532017576681358
<1 <1
5 m
62ceb8f926704dac643a8ae2be
6fa764
1K
7b9aae362c63d3a1f37798bdee
36b7bc74ab661f0f8f4a4c1c81
ec9bb5482c18
1k
25314084225509162015998213
620945315733571
2k
[r]
c8c44fe138c619931db97ab967db6
a72
[ ]mc
fbb4630d33ae844b52448b88fc918
f80
[ ]c
18668089425190824330267202647
31934409964070597124102671481
80003292726557151835988
<1 <1 m
42c06513d6251b8a437c9ddac3
1de6e9
2K
7ce173018ac7a62a9d698f4613
49a4f60f9a194f69f97c283cf4
57a93addf172
[ ]mc
f861e01a914fcf66cafc88b92d416
0f0
[ ]mc
fbb4630d33ae844b52448b88fc918
f80
[ ]c
57247525437375095495622063663
59451709828127466672751511386
12148036733496500242776
<1 <1
142
32244803426199273872488473
894150968406127
6 m
5204c01980837306553396b637
0aba94
1K
c3432a9ecd22b1063dc4748abe
4261718b4cd60df3945f7331cf
12b9b5beee5b
1k
52868281735006681992651595
490665390002951
2k
47813413430147664723786299
101709599722929
[r]
bccfbbaa29b28e505630a2e207253
87e
[ ]mc
13bb9a48c843aee8ff5e04010be49
3dc
[ ]c
24646715029522864910479723523
75625800997365783107506794804
886816877769509023079732
<1 <1 m
1fb649eeddc125dbf126eade37
d48157
2K
ee10382238fd76ea1d8f5619ec
b6e4426539d008c4ba6be84705
07ad0b291ec0
[ ]mc
8ecc866c7f912fb016f5b658d98ab
b58
[ ]mc
13bb9a48c843aee8ff5e04010be49
3dc
[ ]c
73364114004260749904888616986
42263030381156367961606931066
37935572678665605987870
<1 <1
7 m
b5a0301d9bd3566430d3cb0d40
bf2d46
1K
5d630f8e2581b880e71f3aec0d
a99395390ef80771779bd1fd7c
2ae6478ff66e
1k
15171819130415448304249387
430830205526135
2k
67906874749017645062594195
256589225347851
[r]
3704f24c4c33d992f1e3aa1cb7960
1b6
[ ]mc
b6683dd55ef5f4434ac08cb97da53
517
[ ]c
25082220014661626507109347188
74037681760851991757373569070
4180409573915280386412
<1 <1 m
dec67ec0c6cfb6005d5acfc4ca
f9ddf8
2K
bf4b116e6d4670cc598e5da357
203acb4e65eab18f5d950d7c92
b09edf3dc4d2
[ ]mc
e51818101c2e997ab8c90fbb08e27
e3a
[ ]mc
b6683dd55ef5f4434ac08cb97da53
517
[ ]c
45035748372386325929964530628
82938574627501394452928905394
5344493626237476520982
<1 <1
8 m
7511fc6d447ea7704f1a5971fa
d2ff00
1K
9e884325e9b495a9e2e5c89281
73265ea7071c7ab4c729fb307e
71854ea1abff
1k
72248149369442105691249461
[r]
c355c4b83fcb27f33f397b051bc98
4b7
[ ]mc
c34c6576dadd6be242c274c80dc8a
f9e
[ ]c
15622143861250332345561760222
11347074064043976815606243187
<1 <1 m
3062974fb7c3a7d5f4e6a5192d
77e892
2K
17e9c40173cbe0b307c7834ca6
fab6730480c7cc867435099b13
e4b12a3eff3f
[ ]mc
30114813518126abd90b23287411b
c2d
[ ]mc
c34c6576dadd6be242c274c80dc8a
f9e
[ ]c
23012858509238771919781255941
94322521214194892504423708277
<1 <1
143
358015191851071
2k
71744735779457478323031033
328532637334891
456648261869796739096816
20891088554623168478663
9 m
b090f9fd7bd5069fad0099128a
c69c91
1K
c19d806a17d824208c56cad7ac
e1170400f6625e9d191e84f777
2cb193cf0f3b
1k
39527945781254696509238274
629913861640616
2k
30873706479272777782332061
650180599857783
[r]
8db6bcc6a791059fd1840d02ab9ab
cd7
[ ]mc
901e34bb7c0552f27a1ff7481f0b3
525
[ ]c
47369459824217145115260402389
37613953576734923443267353683
67094508258171259382797
<1 <1 m
7f822cf7ca1b09f43aefe90a54
57b547
2K
12837b6f547a2cc7b3d69bc1e4
951691d0c20f3822672af87c08
d5c414093f3a
[ ]mc
2cf6316c8a1927f6fbe5d1d3805a0
e8d
[ ]mc
901e34bb7c0552f27a1ff7481f0b3
525
[ ]c
81571323179035437558949641580
69156882213508927138073988275
66416607583978116376541
<1 <1
10 m
c1d019f2193599e1d2b6a50d82
62172e
1K
211a15be776ea4e56308ed93af
10ca1344bd079efeb473653f9c
f03d98936d96
1k
63109930702103021324479525
302268470617751
2k
12520691429187779626996900
744489860539597
[r]
a6320b7dd8814141684a20d07d9d9
70a
[ ]mc
08f20df02a43e5873e15bc31aaae9
d22
[ ]c
72048066587302524421831068814
38301284017615800892804577562
8853973011147738170646
<1 <1 m
039b7d14bb6220ee1ad90d31be
383199
2K
f3337bfa5aa0a12b5710308382
d711f3198fa1505ed74dda49fc
06813d5a1eaf
[ ]mc
0146a5d375580e115c802f0523299
392
[ ]mc
08f20df02a43e5873e15bc31aaae9
d22
[ ]c
23782647756707374427551600625
40909615152916887158342894678
739276747739377585857444
<1 <1
Các kết quả thực nghiệm:
+ Các thuật toán hoạt động đúng đắn, hai bên gửi nhận đảm bảo mã/dịch chính xác thông điệp bí mật và thông điệp giả mạo.
+ Với kích thước tham số như đã chọn, sai khác thời gian tính toán của Thuật toán mã hóa xác suất dựa trên mã khối và thời gian tính toán của
Thuật toán MHCTCT dựa trên mã khối là không phân biệt, thời gian tính toán luôn 310 s.
+ Với kích thước thông điệp đầu vào là 128 bit, thuật toán MHCTCT của Chương 3 dựa trên thuật toán mã khối có tốc độ tính toán nhanh hơn rất
nhiều so với thuật toán MHCTCT của Chương 2 sử dụng mã hóa khóa bất đối xứng.
144
4. Mã nguồn chương trình thực nghiệm Giao thức 2.1
/**
* Algorithm 2.1
*
* Compile: gcc alg_2.1.c -o alg_2.1 -lgmp -lcrypto
*/
#include
#include
#include
#include
#include
#include
#define BITS_IN_BYTE 8
/* Number of bits of prime number */
#define PRIME_BITS 2048
#define Z_BITS 256
#define KZ_BITS 16
#define E_BITS 256
#define CIPHER_KEY_SIZE_BITS 2048
#define MESSAGE_SIZE_BITS 128
#define R_SIZE_BITS 2040
#define MESSAGE_SIZE_BYTES MESSAGE_SIZE_BITS/BITS_IN_BYTE
#define R_SIZE_BYTES R_SIZE_BITS/BITS_IN_BYTE
char buff_to_print[1024];
static char* hex2char(char *dst, unsigned char b);
const char* hex2str(const char *bin, int bin_size, char *buff, int
buff_size);
void generate_primes(mpz_t prime, int len);
void generate_mpz(mpz_t big, int len);
void mpz_to_str(mpz_t big, char *str);
void str_to_mpz(char *str, mpz_t big);
void generate_e_d(mpz_t phi, int len, mpz_t e, mpz_t d);
void get_D(mpz_t big_p,
mpz_t big_z,
mpz_t big_kz,
mpz_t big_D);
void get_DC1(mpz_t big_p,
mpz_t big_z,
mpz_t big_kz,
mpz_t big_r,
mpz_t big_s,
mpz_t big_DC1);
void get_DC2(mpz_t big_p,
mpz_t big_s,
mpz_t big_r,
mpz_t big_DC2);
void get_s(mpz_t big_p,
mpz_t big_c1,
mpz_t big_c2,
mpz_t big_z,
mpz_t big_s1);
void get_u(mpz_t big_p,
mpz_t big_c1,
mpz_t big_c2,
mpz_t big_z,
145
mpz_t big_kz,
mpz_t big_s2);
void ProcPH(mpz_t big_p,
mpz_t big_r,
mpz_t big_z,
mpz_t big_kz,
mpz_t big_e,
mpz_t big_m,
mpz_t big_c1,
mpz_t big_c2);
/* CHUONG TRINH CHINH */
int main(int argc, char *argv[]) {
if ((int) argc != 2) {
printf("ERROR: Not enough parameters.\n");
printf(
"Usage: alg_2.1 n");
printf("\nWhere:\n");
printf("\tn: Number of running times\n");
printf("\tExample:./alg_2.1 10\n\n");
return 0;
}
int RUN_TIMES = atoi(argv[1]);
int i, ret;
clock_t time_taken_start, time_taken_end;
double enc_time_taken_prob[RUN_TIMES];
double dec_time_taken_prob[RUN_TIMES];
double enc_time_taken_deni[RUN_TIMES];
double dec_time_taken_deni[RUN_TIMES];
double enc_time_taken_average_prob = 0;
double dec_time_taken_average_prob = 0;
double enc_time_taken_average_deni = 0;
double dec_time_taken_average_deni = 0;
int dec_ok[RUN_TIMES];
int dec_true_ok[RUN_TIMES];
int dec_fake_ok[RUN_TIMES];
unsigned char *m_true_A = malloc(MESSAGE_SIZE_BYTES);
unsigned char *m_true_B = malloc(MESSAGE_SIZE_BYTES);
unsigned char *m_fake_A = malloc(MESSAGE_SIZE_BYTES);
unsigned char *m_fake_B = malloc(MESSAGE_SIZE_BYTES);
unsigned char *r1 = malloc(R_SIZE_BYTES);
unsigned char *r2 = malloc(R_SIZE_BYTES);
unsigned char *r3 = malloc(R_SIZE_BYTES);
mpz_t big_m_true_A; mpz_init(big_m_true_A);
mpz_t big_m_true_B; mpz_init(big_m_true_B);
mpz_t big_m_fake_A; mpz_init(big_m_fake_A);
mpz_t big_m_fake_B; mpz_init(big_m_fake_B);
mpz_t big_z; mpz_init(big_z);
mpz_t big_kz; mpz_init(big_kz);
mpz_t big_p; mpz_init(big_p);
mpz_t big_phi; mpz_init(big_phi);
mpz_t big_eA; mpz_init(big_eA);
mpz_t big_dA; mpz_init(big_dA);
mpz_t big_eB; mpz_init(big_eB);
mpz_t big_dB; mpz_init(big_dB);
146
mpz_t big_EA; mpz_init(big_EA);
mpz_t big_DA; mpz_init(big_DA);
mpz_t big_EB; mpz_init(big_EB);
mpz_t big_DB; mpz_init(big_DB);
mpz_t big_gcd; mpz_init(big_gcd);
mpz_t big_r1; mpz_init(big_r1);
mpz_t big_r2; mpz_init(big_r2);
mpz_t big_r3; mpz_init(big_r3);
mpz_t big_s1; mpz_init(big_s1);
mpz_t big_s2; mpz_init(big_s2);
mpz_t big_s3; mpz_init(big_s3);
mpz_t big_u1; mpz_init(big_u1);
mpz_t big_u2; mpz_init(big_u2);
mpz_t big_u3; mpz_init(big_u3);
mpz_t big_c11; mpz_init(big_c11);
mpz_t big_c12; mpz_init(big_c12);
mpz_t big_c21; mpz_init(big_c21);
mpz_t big_c22; mpz_init(big_c22);
mpz_t big_c31; mpz_init(big_c31);
mpz_t big_c32; mpz_init(big_c32);
/* SINH SO NGUYEN TO p, GIA LAP TAO THAM SO Z, kz */
printf("Generating a prime number [p], please wait...:\n");
generate_primes(big_p, PRIME_BITS);
printf("Generated a prime number [p] with [%d] digits.\n",
PRIME_BITS/8);
gmp_printf ("\t[p] = \t\t%Zd\n", big_p);
/* phi = (p - 1) */
mpz_sub_ui(big_phi, big_p, 1);
gmp_printf ("\t[phi] = \t%Zd\n", big_phi);
/* Generate z */
generate_mpz(big_z, Z_BITS);
gmp_printf ("\t[z] = \t\t%Zd\n", big_z);
/* Generate z, kz */
generate_mpz(big_kz, KZ_BITS);
gmp_printf ("\t[kz] = \t\t%Zd\n", big_kz);
printf("\n[A] and [B] have big prime number [p], [phi] = [p-1],
and keys [z, kz]:\n");
gmp_printf ("\t[p] = \t\t%Zd\n", big_p);
gmp_printf ("\t[phi] = \t%Zd\n", big_phi);
gmp_printf ("\t[z] = \t\t%Zd\n", big_z);
gmp_printf ("\t[kz] = \t\t%Zd\n", big_kz);
for (i = 0; i < RUN_TIMES; i++) {
printf("\n\nEXECUTION: %d...\n", i + 1);
printf("\n[A] have messages [m_true], [m_fake]:\n");
RAND_bytes(m_true_A, MESSAGE_SIZE_BYTES);
RAND_bytes(m_fake_A, MESSAGE_SIZE_BYTES);
printf("\t[m_true_A] = \t%s\n", hex2str((const char*
)m_true_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\t[m_fake_A] = \t%s\n", hex2str((const char*
)m_fake_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
str_to_mpz(m_true_A, big_m_true_A);
str_to_mpz(m_fake_A, big_m_fake_A);
printf("\n[A] generate [eA, dA]:\n");
generate_e_d(big_phi, E_BITS, big_eA, big_dA);
147
gmp_printf ("\t[eA] =\t \t%Zd\n", big_eA);
gmp_printf ("\t[dA] = \t\t%Zd\n", big_dA);
mpz_gcd(big_gcd, big_eA, big_phi);
gmp_printf ("\t[gcd(eA, phi)] = %Zd\n", big_gcd);
printf("\n[B] generate [eB, dB]:\n");
generate_e_d(big_phi, E_BITS, big_eB, big_dB);
gmp_printf ("\t[eB] =\t \t%Zd\n", big_eB);
gmp_printf ("\t[dB] = \t\t%Zd\n", big_dB);
mpz_gcd(big_gcd, big_eB, big_phi);
gmp_printf ("\t[gcd(eB, phi)] = %Zd\n", big_gcd);
printf("\n[A] generate [EA, EA]:\n");
generate_e_d(big_phi, E_BITS, big_EA, big_DA);
gmp_printf ("\t[EA] =\t \t%Zd\n", big_EA);
gmp_printf ("\t[DA] = \t\t%Zd\n", big_DA);
mpz_gcd(big_gcd, big_EA, big_phi);
gmp_printf ("\t[gcd(EA, phi)] = %Zd\n", big_gcd);
printf("\n[B] generate [EB, DB]:\n");
generate_e_d(big_phi, E_BITS, big_EB, big_DB);
gmp_printf ("\t[EB] =\t \t%Zd\n", big_EB);
gmp_printf ("\t[DB] = \t\t%Zd\n", big_DB);
mpz_gcd(big_gcd, big_eB, big_phi);
gmp_printf ("\t[gcd(EB, phi)] = %Zd\n", big_gcd);
/* THUAT TOAN CUA GIAO THUC 2.1 HĐ O CHE DO MA HOA XAC SUAT */
printf("\n\nI. ALGORITHM PROBABILITY ENCRYPTION (2.1a)");
printf("\n===================================================\n");
printf("[A] WANT TO SEND A MESSAGE TO [B]!\n");
printf("[A] --> message [m] --> [B]\n\n");
printf("\t[m] = \t\t%s\n", hex2str((const char* )m_fake_A,
MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
time_taken_start = clock();
printf("\nA.1. [A] generate [r1]:\n");
RAND_bytes(r1, R_SIZE_BYTES);
printf("\t[r1] = \t\t%s\n\n", hex2str((const char* )r1,
R_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
str_to_mpz(r1, big_r1);
printf("\nA.2. [A] compute [c11, c12] from [r1, z, kz, eA,
m]:\n");
ProcPH(big_p, big_r1, big_z, big_kz, big_eA, big_m_fake_A,
big_c11, big_c12);
gmp_printf ("\t[c11] = \t%Zd\n", big_c11);
gmp_printf ("\t[c12] = \t%Zd\n", big_c12);
printf("\nA.3. [A] send [c11, c12] to [B]:\n");
printf("\nSending....\n");
printf("Sending....\n");
printf("Sending....\n");
printf("\nStep 2. [B] receive [c11, c12] from [A], choose
[r2]:\n");
gmp_printf ("\t[c11] = \t%Zd\n", big_c11);
gmp_printf ("\t[c12] = \t%Zd\n", big_c12);
printf("\nB.1. [A] generate [r2]:\n");
148
RAND_bytes(r2, R_SIZE_BYTES);
printf("\t[r2] = \t\t%s\n\n", hex2str((const char* )r2,
R_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
str_to_mpz(r2, big_r2);
printf("\nB.2. [B] compute [s1] from [c11, c12, z]:\n");
get_s(big_p, big_c11, big_c12, big_z, big_s1);
gmp_printf ("\t[s1] = \t\t%Zd\n", big_s1);
printf("\nB.3. [B] compute [c21, c22] from [r2, z, kz, eB,
s1]:\n");
ProcPH(big_p, big_r2, big_z, big_kz, big_eB, big_s1,
big_c21, big_c22);
gmp_printf ("\t[c21] = \t%Zd\n", big_c21);
gmp_printf ("\t[c22] = \t%Zd\n", big_c22);
printf("\nB.4. [B] send [c21, c22] to [A]:\n");
printf("\nSending....\n");
printf("Sending....\n");
printf("Sending....\n");
printf("\nStep 3. [A] receive [c11, c12] from [B]:\n");
gmp_printf ("\t[c21] = \t%Zd\n", big_c21);
gmp_printf ("\t[c22] = \t%Zd\n", big_c22);
printf("\n\nA.4. [A] generate [r3]:\n");
RAND_bytes(r3, R_SIZE_BYTES);
printf("\t[r3] = \t\t%s\n\n", hex2str((const char* )r3,
R_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
str_to_mpz(r3, big_r3);
printf("\nA.5. [A] compute [s2] from [c21, c22, z]:\n");
get_s(big_p, big_c21, big_c22, big_z, big_s2);
gmp_printf ("\t[s2] = \t\t%Zd\n", big_s2);
printf("\nA.6. [A] compute [c31, c32] from [r3, z, kz, dA,
s2]:\n");
ProcPH(big_p, big_r3, big_z, big_kz, big_dA, big_s2,
big_c31, big_c32);
gmp_printf ("\t[c31] = \t%Zd\n", big_c31);
gmp_printf ("\t[c32] = \t%Zd\n", big_c32);
time_taken_end = clock();
enc_time_taken_prob[i] = (((double) (time_taken_end -
time_taken_start)) / CLOCKS_PER_SEC) * 1000;
printf("\nA.7. [A] send [c31, c32] to [B]:\n");
printf("\nSending....\n");
printf("Sending....\n");
printf("Sending....\n");
printf("\nDecryption. [B] receive [c31, c32] from [A]:\n");
gmp_printf ("\t[c31] = \t%Zd\n", big_c31);
gmp_printf ("\t[c32] = \t%Zd\n", big_c32);
time_taken_start = clock();
printf("\nB.5. [B] compute [s3] from [c31, c32, z]:\n");
get_s(big_p, big_c31, big_c32, big_z, big_s3);
gmp_printf ("\t[s3] = \t\t%Zd\n", big_s3);
printf("\nB.6. [B] compute [m] from [s3, dB]:\n");
mpz_powm(big_m_fake_B, big_s3, big_dB, big_p);
mpz_to_str(big_m_fake_B, m_fake_B);
printf("\t[m] = \t\t%s\n", hex2str((const char* )m_fake_B,
MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
149
printf("\nB.7. [B] compare with [m] from [A]:\n");
printf("\t[m] = \t\t%s\n", hex2str((const char* )m_fake_A,
MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
time_taken_end = clock();
dec_time_taken_prob[i] = (((double) (time_taken_end -
time_taken_start)) / CLOCKS_PER_SEC) * 1000;
if(memcmp(m_fake_B, m_fake_A, MESSAGE_SIZE_BYTES) == 0) {
printf("\nOK, [A] HAVE SUCCESSFULY SENT A MESSAGE [m]
TO [B]!\n");
dec_ok[i] = 1;
} else {
printf("\nWOW, THEY ARE NOT THE SAME (SOMETHING WENT
WRONG!!!)\n");
dec_ok[i] = 0;
}
/* THUAT TOAN CUA GIAO THUC 2.1 HĐ O CHE DO GAI DAT MHCTCT */
printf("\n\nII. ALGORITHM DENIABLE ENCRYPTION (2.1b)");
printf("\n===================================================\n");
printf("[A] WANT TO SEND A MESSAGES TO [B]!\n");
printf("[A] --> message [m_true, m_fake] --> [B]\n");
printf("\t[m_fake] = \t%s\n", hex2str((const char*
)m_fake_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\t[m_true] = \t%s\n", hex2str((const char*
)m_true_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
time_taken_start = clock();
printf("\nA.1. [A] compute [r1] from [m_true]:\n");
mpz_powm(big_r1, big_m_true_A, big_EA, big_p);
gmp_printf ("\t[r1] = \t\t%Zd\n", big_r1);
printf("\nA.2. [A] compute [c11, c12] from [r1, z, kz, eA,
m_fake]:\n");
ProcPH(big_p, big_r1, big_z, big_kz, big_eA, big_m_fake_A,
big_c11, big_c12);
gmp_printf ("\t[c11] = \t%Zd\n", big_c11);
gmp_printf ("\t[c12] = \t%Zd\n", big_c12);
printf("\nA.3. [A] send [c11, c12] to [B]:\n");
printf("\nSending....\n");
printf("Sending....\n");
printf("Sending....\n");
printf("\nStep 2. [B] receive [c11, c12] from [A]:\n");
gmp_printf ("\t[c11] = \t%Zd\n", big_c11);
gmp_printf ("\t[c12] = \t%Zd\n", big_c12);
printf("\nB.1. [B] compute [u1] from [c11, c12, z, kz]:\n");
get_u(big_p, big_c11, big_c12, big_z, big_kz, big_u1);
gmp_printf ("\t[u1] = \t\t%Zd\n", big_u1);
printf("\nB.2. [B] compute [r2] from [u1, EB]:\n");
mpz_powm(big_r2, big_u1, big_EB, big_p);
gmp_printf ("\t[r2] = \t\t%Zd\n", big_r2);
printf("\nB.3. [B] compute [s1] from [c11, c12, z]:\n");
get_s(big_p, big_c11, big_c12, big_z, big_s1);
gmp_printf ("\t[s1] = \t\t%Zd\n", big_s1);
150
printf("\nB.4. [B] compute [c21, c22] from [r2, z, kz, eB,
s1]:\n");
ProcPH(big_p, big_r2, big_z, big_kz, big_eB, big_s1,
big_c21, big_c22);
gmp_printf ("\t[c21] = \t%Zd\n", big_c21);
gmp_printf ("\t[c22] = \t%Zd\n", big_c22);
printf("\nB.5. [B] send [c21, c22] to [A]:\n");
printf("\nSending....\n");
printf("Sending....\n");
printf("Sending....\n");
printf("\nStep 3. [A] receive [c21, c22] from [B]:\n");
gmp_printf ("\t[c21] = \t%Zd\n", big_c21);
gmp_printf ("\t[c22] = \t%Zd\n", big_c22);
printf("\nA.4. [A] compute [u2] from [c21, c22, kz, z]:\n");
get_u(big_p, big_c21, big_c22, big_z, big_kz, big_u2);
gmp_printf ("\t[u2] = \t\t%Zd\n", big_u2);
printf("\nA.5. [A] compute [r3] from [u2, DA]:\n");
mpz_powm(big_r3, big_u2, big_DA, big_p);
gmp_printf ("\t[r3] = \t\t%Zd\n", big_r3);
printf("\nA.6. [A] compute [s2] from [c21, c22, z]:\n");
get_s(big_p, big_c21, big_c22, big_z, big_s2);
gmp_printf ("\t[s2] = \t\t%Zd\n", big_s2);
printf("\nA.7. [A] compute [c31, c32] from [r3, z, kz, dA,
s2]:\n");
ProcPH(big_p, big_r3, big_z, big_kz, big_dA, big_s2,
big_c31, big_c32);
gmp_printf ("\t[c31] = \t%Zd\n", big_c31);
gmp_printf ("\t[c32] = \t%Zd\n", big_c32);
time_taken_end = clock();
enc_time_taken_deni[i] = (((double) (time_taken_end -
time_taken_start)) / CLOCKS_PER_SEC) * 1000;
printf("\nA.8. [A] send [c31, c32] to [B]:\n");
printf("\nSending....\n");
printf("Sending....\n");
printf("Sending....\n");
printf("\nDecryption. [B] receive [c31, c32] from [A]:\n");
gmp_printf ("\t[c31] = \t%Zd\n", big_c31);
gmp_printf ("\t[c32] = \t%Zd\n", big_c32);
time_taken_start = clock();
printf("\nB.6. [B] compute [u3] from [c31, c32, z, kz]:\n");
get_u(big_p, big_c31, big_c32, big_z, big_kz, big_u3);
gmp_printf ("\t[u3] = \t\t%Zd\n", big_u3);
printf("\nB.7. [B] compute [s3] from [c31, c32, z]:\n");
get_s(big_p, big_c31, big_c32, big_z, big_s3);
gmp_printf ("\t[s3] = \t\t%Zd\n", big_s3);
printf("\nIn ATTACKED condition!!!\n");
printf("B.8. [B] compute [m_fake] from [s3, dB]:\n");
mpz_powm(big_m_fake_B, big_s3, big_dB, big_p);
mpz_to_str(big_m_fake_B, m_fake_B);
printf("\t[m_fake] = \t%s\n", hex2str((const char*
)m_fake_B, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\n[B] compare with [m_fake] from [A]:\n");
printf("\t[m_fake] = \t%s\n", hex2str((const char*
)m_fake_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
151
if(memcmp(m_fake_B, m_fake_A, MESSAGE_SIZE_BYTES) == 0) {
printf("\nOK, [A] HAVE SUCCESSFULY SENT A MESSAGE
[m_fake] TO [B]!\n");
dec_fake_ok[i] = 1;
} else {
printf("\nWOW, THEY ARE NOT THE SAME (SOMETHING WENT
WRONG!!!)\n");
dec_fake_ok[i] = 0;
}
printf("\nIn NORMAL condition:\n");
printf("B.10. [B] compute [m_true] from [u3, DB]:\n");
mpz_powm(big_m_true_B, big_u3, big_DB, big_p);
mpz_to_str(big_m_true_B, m_true_B);
printf("\t[m_true] = \t%s\n", hex2str((const char*
)m_true_B, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
time_taken_end = clock();
dec_time_taken_deni[i] = (((double) (time_taken_end -
time_taken_start)) / CLOCKS_PER_SEC) * 1000;
printf("\n[B] compare with [m_true] from [A]:\n");
printf("\t[m_true] = \t%s\n", hex2str((const char*
)m_true_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
if(memcmp(m_true_B, m_true_A, MESSAGE_SIZE_BYTES) == 0) {
printf("\nOK, [A] HAVE SUCCESSFULY SENT A MESSAGE
[m_fake] TO [B]!\n");
dec_true_ok[i] = 1;
} else {
printf("\nWOW, THEY ARE NOT THE SAME (SOMETHING WENT
WRONG!!!)\n");
dec_true_ok[i] = 0;
}
printf("\nEXECUTION: %d... DONE\n", i + 1);
printf("\n***************************************************\n");
enc_time_taken_average_prob = enc_time_taken_average_prob +
enc_time_taken_prob[i];
dec_time_taken_average_prob = dec_time_taken_average_prob +
dec_time_taken_prob[i];
enc_time_taken_average_deni = enc_time_taken_average_deni +
enc_time_taken_deni[i];
dec_time_taken_average_deni = dec_time_taken_average_deni +
dec_time_taken_deni[i];
/* Pause 1 seconds */
sleep(1);
}
enc_time_taken_average_prob =
enc_time_taken_average_prob/RUN_TIMES;
dec_time_taken_average_prob =
dec_time_taken_average_prob/RUN_TIMES;
152
enc_time_taken_average_deni =
enc_time_taken_average_deni/RUN_TIMES;
dec_time_taken_average_deni =
dec_time_taken_average_deni/RUN_TIMES;
printf("\n\n\t\t\t\tALG. 2.1 EXECUTION TIME TAKEN AVERAGE\n");
printf("\t\t\t\t Number of running times: %d\n", RUN_TIMES);
printf("\n\tNo/Time(ms) \tEnc_prob \tDec_prob \tEnc_deni
\tDec_deni\tSUCCESSFULY");
printf("\n--------------------------------------------------\n");
char *dec_char, *dec_true_char, *dec_fake_char;
for (i = 0; i < RUN_TIMES; i++) {
if (dec_ok[i]) {
dec_char = "yes";
} else {
dec_char = " no";
}
if (dec_true_ok[i]) {
dec_true_char = "yes";
} else {
dec_true_char = " no";
}
if (dec_fake_ok[i]) {
dec_fake_char = "yes";
} else {
dec_fake_char = " no";
}
printf(" \t %d \t\t%f \t%f \t%f \t%f\t%s, %s, %s\n", i + 1,
enc_time_taken_prob[i], dec_time_taken_prob[i],
enc_time_taken_deni[i], dec_time_taken_deni[i],
dec_char, dec_true_char, dec_fake_char);
}
printf("\n-------------------------------------------------\n");
printf("Average (miliseconds) \t%f \t%f \t%f \t%f\n\n",
enc_time_taken_average_prob,
dec_time_taken_average_prob,
enc_time_taken_average_deni,
dec_time_taken_average_deni);
mpz_clear(big_p);
mpz_clear(big_phi);
mpz_clear(big_z);
mpz_clear(big_kz);
mpz_clear(big_eA);
mpz_clear(big_dA);
mpz_clear(big_eB);
mpz_clear(big_dB);
mpz_clear(big_EA);
mpz_clear(big_DA);
mpz_clear(big_EB);
mpz_clear(big_DB);
mpz_clear(big_gcd);
mpz_clear(big_r1);
mpz_clear(big_r2);
153
mpz_clear(big_r3);
mpz_clear(big_s1);
mpz_clear(big_s2);
mpz_clear(big_s3);
mpz_clear(big_u1);
mpz_clear(big_u2);
mpz_clear(big_u3);
mpz_clear(big_m_true_A);
mpz_clear(big_m_true_B);
mpz_clear(big_m_fake_A);
mpz_clear(big_m_fake_B);
mpz_clear(big_c11);
mpz_clear(big_c12);
mpz_clear(big_c21);
mpz_clear(big_c22);
mpz_clear(big_c31);
mpz_clear(big_c32);
return 1;
}
/* CAC HAM, THU TUC DUNG TRONG CHUONG TRINH CHINH */
/* HAM TINH DINH THUC: D = (z - z * kz)-1 mod p */
void get_D(mpz_t big_p,
mpz_t big_z,
mpz_t big_kz,
mpz_t big_D) {
mpz_t big_tmp1; mpz_init(big_tmp1);
mpz_t big_tmp2; mpz_init(big_tmp2);
mpz_t big_tmp3; mpz_init(big_tmp3);
/* big_tmp1 = (z * kz) */
mpz_mul(big_tmp1, big_z, big_kz);
/* big_tmp2 = (z - (z * kz)) = z - big_tmp1 */
mpz_sub(big_tmp2, big_z, big_tmp1);
/* big_tmp3 = ((z - (kz * z))^-1 mod p) = big_tmp2^-1 mod p */
mpz_invert(big_tmp3, big_tmp2, big_p);
/* Copy big_tmp3 to big_D */
mpz_set(big_D, big_tmp3);
mpz_clear(big_tmp1);
mpz_clear(big_tmp2);
mpz_clear(big_tmp3);
return;
}
/* HAM TINH DINH THUC: DC’ = (z - (kz * z *s)) mod p */
void get_DC1(mpz_t big_p,
mpz_t big_z,
mpz_t big_kz,
mpz_t big_r,
mpz_t big_s,
mpz_t big_DC1) {
154
mpz_t big_tmp1; mpz_init(big_tmp1);
mpz_t big_tmp2; mpz_init(big_tmp2);
mpz_t big_tmp3; mpz_init(big_tmp3);
mpz_t big_tmp4; mpz_init(big_tmp4);
/* big_tmp1 = (z * kz) */
mpz_mul(big_tmp1, big_kz, big_z);
/* big_tmp2 = (kz * z * s) */
mpz_mul(big_tmp2, big_tmp1, big_s);
/* big_tmp3 = (z * r) */
mpz_mul(big_tmp3, big_z, big_r);
/* big_tmp4 = ((z * r) - (kz * z *s)) = big_tmp3 - big_tmp2 */
mpz_sub(big_tmp4, big_tmp3, big_tmp2);
/* big_DC1 = (((z * r) - (kz * z *s)) mod p) = big_tmp4 mod p */
mpz_mod(big_DC1, big_tmp4, big_p);
mpz_clear(big_tmp1);
mpz_clear(big_tmp2);
mpz_clear(big_tmp3);
mpz_clear(big_tmp4);
return;
}
/* HAM TINH DINH THUC: DC” = (s - r) mod p */
void get_DC2(mpz_t big_p,
mpz_t big_s,
mpz_t big_r,
mpz_t big_DC2) {
mpz_t big_tmp1; mpz_init(big_tmp1);
/* big_tmp1 = (s - r) */
mpz_sub(big_tmp1, big_s, big_r);
/* big_DC2 = (s - r) mod p */
mpz_mod(big_DC2, big_tmp1, big_p);
mpz_clear(big_tmp1);
return;
}
/* HAM TINH CAC GIA TRI si: si = (c’i + (z * c”i)) mod p */
void get_s(mpz_t big_p,
mpz_t big_c1,
mpz_t big_c2,
mpz_t big_z,
mpz_t big_s1) {
mpz_t big_tmp1; mpz_init(big_tmp1);
mpz_t big_tmp2; mpz_init(big_tmp2);
/* big_tmp1 = (z * c2) */
mpz_mul(big_tmp1, big_z, big_c2);
/* big_tmp2 = c1 + big_tmp1 */
mpz_add(big_tmp2, big_c1, big_tmp1);
155
/* big_s1 = big_tmp2 mod p */
mpz_mod(big_s1, big_tmp2, big_p);
mpz_clear(big_tmp1);
mpz_clear(big_tmp2);
return;
}
/* HAM TINH CAC GIA TRI ui = (c’i + (kz *z * c”i)) mod p */
void get_u(mpz_t big_p,
mpz_t big_c1,
mpz_t big_c2,
mpz_t big_z,
mpz_t big_kz,
mpz_t big_s2) {
mpz_t big_tmp1; mpz_init(big_tmp1);
mpz_t big_tmp2; mpz_init(big_tmp2);
mpz_t big_tmp3; mpz_init(big_tmp3);
/* big_tmp1 = (z * c2) */
mpz_mul(big_tmp1, big_z, big_c2);
/* big_tmp2 = (kz * z * c2) */
mpz_mul(big_tmp2, big_kz, big_tmp1);
/* big_tmp3 = (c1 + (kz * z * c2)) = c1 + big_tmp2 */
mpz_add(big_tmp3, big_c1, big_tmp2);
/* big_s2 = big_tmp3 mod p */
mpz_mod(big_s2, big_tmp3, big_p);
mpz_clear(big_tmp1);
mpz_clear(big_tmp2);
mpz_clear(big_tmp3);
return;
}
/* HAM KIEM TRA m CO LA PHAN TU NGUYEN THUY CUA Zp* */
void test_m(mmpz_t big_m,
mpz_t big_p,
mpz_t big_p1,
mpz_t test_value) {
mpz_t big_tmp1;
mpz_init(big_tmp2);
mpz_mul(big_tmp1, big_m, big_m);
mpz_mod(big_tmp1, big_tmp1, big_p);
mpz_powm(big_tmp2, big_m, big_p1, big_p);
if(big_tmp1 != 1) && (big_tmp2 != 1) {
test_value = 1;
} else {
test_value = 0;
}
mpz_clear(big_tmp1);
mpz_clear(big_tmp2);
return;
}
/* HAM GIAI HE PHUONG TRINH DONG DU */
void ProcPH(mpz_t big_p,
mpz_t big_r,
mpz_t big_z,
156
mpz_t big_kz,
mpz_t big_e,
mpz_t big_m,
mpz_t big_c1,
mpz_t big_c2) {
int ret = 0;
mpz_t big_s; mpz_init(big_s);
mpz_t big_r; mpz_init(big_r);
mpz_t big_D; mpz_init(big_D);
mpz_t big_DC1; mpz_init(big_DC1);
mpz_t big_DC2; mpz_init(big_DC2);
mpz_t big_tmp1; mpz_init(big_tmp1);
mpz_t big_tmp2; mpz_init(big_tmp2);
/* s = m^e mod p */
mpz_powm(big_s, big_m, big_e, big_p);
/* D = (z - (kz * z))^-1 mod p */
get_D(big_p, big_z, big_kz, big_D);
/* DC1 = (z*r - (z * kz *s)) mod p */
get_DC1(big_p, big_z, big_kz, big_r, big_s, big_DC1);
/* DC2 = (z - r) mod p */
get_DC2(big_p, big_s, big_r, big_DC2);
/* big_c1 = (D * DC1) mod p */
mpz_mul(big_tmp1, big_D, big_DC1);
mpz_mod(big_c1, big_tmp1, big_p);
/* big_c2 = (D * DC2) */
mpz_mul(big_tmp2, big_D, big_DC2);
mpz_mod(big_c2, big_tmp2, big_p);
mpz_clear(big_r);
mpz_clear(big_s);
mpz_clear(big_D);
mpz_clear(big_DC1);
mpz_clear(big_DC2);
mpz_clear(big_tmp1);
mpz_clear(big_tmp2);
return;
}
static char* hex2char(char *dst, unsigned char b) {
unsigned char v = b >> 4;
*dst++ = (v <= 9) ? '0' + v : 'a' + (v - 10);
v = b & 0x0f;
*dst++ = (v <= 9) ? '0' + v : 'a' + (v - 10);
return dst;
}
const char* hex2str(const char *bin, int bin_size, char *buff, int
buff_size) {
char *nptr = buff;
if (NULL == buff) {
return "Buffer is NULL";
}
if (buff_size < bin_size * 2) {
return "Buffer too small";
}
157
while (bin_size--) {
nptr = hex2char(nptr, *bin++);
}
if (buff_size >= bin_size * 2 + 1) {
*nptr = 0;
}
return buff;
}
/*THU TUC SINH SO NGUYEN TO p */
void generate_primes(mpz_t prime, int len) {
int primetest;
mpz_t seed;
mpz_init(seed);
unsigned char *str = malloc(len + len/2);
RAND_bytes(str, len);
mpz_import(seed, len/8, 1, sizeof (str[0]), 0, 0, str);
primetest = mpz_probab_prime_p(seed, 10);
if (primetest != 0) {
mpz_set(prime, seed);
} else {
mpz_nextprime(prime, seed);
}
free(str);
mpz_clear(seed);
return;
}
/*THU TUC TAO KHOA CAC RIENG (e,d) */
void generate_mpz(mpz_t big, int len) {
unsigned char *str = malloc(len);
RAND_bytes(str, len);
mpz_import(big, len/8, 1, sizeof (str[0]), 0, 0, str);
free(str);
return;
}
void generate_e_d(mpz_t phi, int len, mpz_t e, mpz_t d) {
mpz_t seed; mpz_init(seed);
mpz_t temp; mpz_init(temp);
unsigned char *str = malloc(len);
do {
RAND_bytes(str, len);
mpz_import(seed, len/8, 1, sizeof (str[0]), 0, 0, str);
mpz_gcd(temp, phi, seed);
} while (mpz_cmp_ui(temp, 1) != 0);
mpz_set(e, seed);
mpz_invert(d, e, phi);
free(str);
mpz_clear(seed);
mpz_clear(temp);
return;
}
void str_to_mpz(char *str, mpz_t big){
158
mpz_import(big, strlen(str), 1, sizeof (str[0]), 0, 0, str);
return;
}
void mpz_to_str(mpz_t big, char *str){
mpz_export(str, (size_t*) malloc(sizeof (size_t)), 1, sizeof
(str[0]), 0, 0, big);
return;
}
5. Mã nguồn chương trình thực nghiệm Thuật toán 3.1
/**
* Algorithm 3.1
*
* Compile: gcc aes.c alg_3.1.c -o alg_3.1 -lgmp -lcrypto
*/
#include
#include
#include
#include
#include
#include
#include "aes.h"
#define BITS_IN_BYTE 8
/* KHAI BAO THAM SO */
/* Number of bits of prime number */
#define PRIME_BITS 136
#define INTERGER_BITS PRIME_BITS
/* This is for block cipher
* You can change it that suitable for another cipher
* */
#define CIPHER_KEY_SIZE_BITS 256
#define MESSAGE_SIZE_BITS 128
#define CIPHER_KEY_SIZE_BYTES CIPHER_KEY_SIZE_BITS/BITS_IN_BYTE
#define MESSAGE_SIZE_BYTES MESSAGE_SIZE_BITS/BITS_IN_BYTE
char buff_to_print[1024];
static char* hex2char(char *dst, unsigned char b);
const char* hex2str(const char *bin, int bin_size, char *buff, int
buff_size);
void generate_primes(mpz_t prime, int len);
void generate_mpz(mpz_t big, int len);
void mpz_to_str(mpz_t big, char *str);
void str_to_mpz(char *str, mpz_t big);
/* THU TUC MA CUA MA KHOI out = E(in, key) */
void cipher_encrypt(unsigned char in[MESSAGE_SIZE_BYTES],
unsigned char key[CIPHER_KEY_SIZE_BYTES],
unsigned char out[MESSAGE_SIZE_BYTES]) {
unsigned char *key_ctx;
key_ctx = aes_init(CIPHER_KEY_SIZE_BYTES);
aes_key_expansion(key, key_ctx);
aes_encrypt(in, out, key_ctx);
159
free (key_ctx);
return;
}
/* THU TUC DICH CUA MA KHOI out = E(in, key) */
void cipher_decrypt(unsigned char in[MESSAGE_SIZE_BYTES],
unsigned char key[CIPHER_KEY_SIZE_BYTES],
unsigned char out[MESSAGE_SIZE_BYTES]) {
unsigned char *key_ctx;
key_ctx = aes_init(CIPHER_KEY_SIZE_BYTES);
aes_key_expansion(key, key_ctx);
aes_decrypt(in, out, key_ctx);
free (key_ctx);
return;
}
/* THU TUC TINH BAN MA c DUA VAO HE PT DONG DU */
/* Compute c from (cm, k1, k2, r) */
void compute_c(mpz_t big_c, mpz_t big_cm1, mpz_t big_cm2, mpz_t big_k1,
mpz_t big_k2) {
mpz_t big_temp1; mpz_init(big_temp1);
mpz_t big_temp2; mpz_init(big_temp2);
mpz_t big_temp3; mpz_init(big_temp3);
mpz_t big_temp4; mpz_init(big_temp4);
mpz_t big_temp5; mpz_init(big_temp5);
mpz_t big_temp6; mpz_init(big_temp6);
mpz_t big_temp7; mpz_init(big_temp7);
mpz_t big_temp8; mpz_init(big_temp8);
/* big_temp1 = k2^-1 mod k1 */
mpz_invert(big_temp1, big_k2, big_k1);
/* big_temp2 = k2.big_temp1 */
mpz_mul(big_temp2, big_k2, big_temp1);
/* big_temp3 = cm1.big_temp2 */
mpz_mul(big_temp3, big_cm1, big_temp2);
/* big_temp4 = k1^-1 mod k2 */
mpz_invert(big_temp4, big_k1, big_k2);
/* big_temp5 = k1.big_temp4 */
mpz_mul(big_temp5, big_k1, big_temp4);
/* big_temp6 = cm2.big_temp5 */
mpz_mul(big_temp6, big_cm2, big_temp5);
/* big_temp7 = k1.k2 */
mpz_mul(big_temp7, big_k1, big_k1);
/* big_temp8 = big_temp3 + big_temp6 */
mpz_add(big_temp8, big_temp3, big_temp6);
/* c = big_temp8 mod big_temp7 */
mpz_mod(big_c, big_temp8, big_temp7);
mpz_clear(big_temp1);
mpz_clear(big_temp2);
mpz_clear(big_temp3);
mpz_clear(big_temp4);
mpz_clear(big_temp5);
mpz_clear(big_temp6);
mpz_clear(big_temp7);
mpz_clear(big_temp8);
160
return;
}
/* THU TUC TINH cm TU BAN MA c: cm=c mod k1 */
/* Compute cm from (c, k) */
void compute_cm_value(mpz_t big_cm, mpz_t big_c, mpz_t big_k) {
mpz_mod(big_cm, big_c, big_k);
return;
}
/* CHUONG TRINH CHINH */
int main(int argc, char *argv[]) {
if ((int) argc != 2) {
printf("ERROR: Not enough parameters.\n");
printf(
"Usage: alg_3.1 n");
printf("\nWhere:\n");
printf("\tn: Number of running times\n");
printf("\tExample:./alg_3.1 10\n\n");
return 0;
}
int RUN_TIMES = atoi(argv[1]);
int i, ret;
clock_t start, end;
double enc_time_taken[RUN_TIMES];
double dec_time_taken[RUN_TIMES];
double enc_true_fake_time_taken[RUN_TIMES];
double dec_true_time_taken[RUN_TIMES];
double dec_fake_time_taken[RUN_TIMES];
int dec_ok[RUN_TIMES];
int dec_true_ok[RUN_TIMES];
int dec_fake_ok[RUN_TIMES];
double enc_time_taken_average = 0;
double dec_time_taken_average = 0;
double enc_true_fake_time_average = 0;
double dec_true_time_taken_average = 0;
double dec_fake_time_taken_average = 0;
unsigned char *K1 = malloc(CIPHER_KEY_SIZE_BYTES);
unsigned char *K2 = malloc(CIPHER_KEY_SIZE_BYTES);
unsigned char *m_true_A = malloc(MESSAGE_SIZE_BYTES);
unsigned char *m_true_B = malloc(MESSAGE_SIZE_BYTES);
unsigned char *m_fake_A = malloc(MESSAGE_SIZE_BYTES);
unsigned char *m_fake_B = malloc(MESSAGE_SIZE_BYTES);
unsigned char *r = malloc(MESSAGE_SIZE_BYTES);
unsigned char *cm_true_A = malloc(MESSAGE_SIZE_BYTES);
unsigned char *cm_true_B = malloc(MESSAGE_SIZE_BYTES);
unsigned char *cm_fake_A = malloc(MESSAGE_SIZE_BYTES);
unsigned char *cm_fake_B = malloc(MESSAGE_SIZE_BYTES);
mpz_t big_k1; mpz_init(big_k1);
mpz_t big_k2; mpz_init(big_k2);
mpz_t big_gcd; mpz_init(big_gcd);
mpz_t big_r; mpz_init(big_r);
mpz_t big_c; mpz_init(big_c);
mpz_t big_cm_true_A; mpz_init(big_cm_true_A);
mpz_t big_cm_true_B; mpz_init(big_cm_true_B);
161
mpz_t big_cm_fake_A; mpz_init(big_cm_fake_A);
mpz_t big_cm_fake_B; mpz_init(big_cm_fake_B);
for (i = 0; i < RUN_TIMES; i++) {
printf("\nEXECUTION: %d...\n", i + 1);
printf("[A] have messages [m_true], [m_fake]:\n");
RAND_bytes(m_true_A, MESSAGE_SIZE_BYTES);
RAND_bytes(m_fake_A, MESSAGE_SIZE_BYTES);
RAND_bytes(r, MESSAGE_SIZE_BYTES);
printf("\t[m_true_A] = \t%s\n", hex2str((const char*
)m_true_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\t[m_fake_A] = \t%s\n", hex2str((const char*
)m_fake_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\t[r_A] = \t%s\n\n", hex2str((const char* )r,
MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
str_to_mpz(r, big_r);
printf("\n[A] and [B] have keys [K1], [K2], [k1], [k2]:\n");
RAND_bytes(K1, CIPHER_KEY_SIZE_BYTES);
RAND_bytes(K2, CIPHER_KEY_SIZE_BYTES);
printf("\t[K1] = \t\t%s\n", hex2str((const char* )K1,
CIPHER_KEY_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\t[K2] = \t\t%s\n\n", hex2str((const char* )K2,
CIPHER_KEY_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
generate_mpz(big_k1, INTERGER_BITS);
generate_primes(big_k2, PRIME_BITS);
gmp_printf ("\t[k1] = \t\t%Zd\n", big_k1);
gmp_printf ("\t[k2] = \t\t%Zd\n", big_k2);
mpz_gcd(big_gcd, big_k1, big_k2);
gmp_printf ("\t[gcd(k1, k2)] = %Zd\n", big_gcd);
/* THUAT TOAN MA HOA XAC SUAT DUA TREN MA KHOI */
printf("\n\nI. ALGORITHM ENC-DENI AND DEC-DENI (3.1)");
printf("\n==================================================\n");
printf("[A] WANT TO SEND A MESSAGE TO [B]\n");
printf("[A] have [m, r, K1, k1, k2]:\n");
printf("\t[m] = \t\t%s\n", hex2str((const char* )m_fake_A,
MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\t[r] = \t\t%s\n", hex2str((const char* )r,
MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\t[K1] = \t\t%s\n", hex2str((const char* )K1,
CIPHER_KEY_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
gmp_printf ("\t[k1] = \t\t%Zd\n", big_k1);
gmp_printf ("\t[k2] = \t\t%Zd\n", big_k2);
start = clock();
printf("\n1. [A] encrypt message [m] with key [K1], cm =
E(m, K1):\n");
cipher_encrypt(m_fake_A, K1, cm_fake_A);
printf("\t[cm] = \t\t%s\n", hex2str((const char* )cm_fake_A,
MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\n2. [A] calculate [c] from [cm, k1, k2, r]:\n");
162
str_to_mpz(cm_fake_A, big_cm_fake_A);
compute_c(big_c, big_cm_fake_A, big_r, big_k1, big_k2);
gmp_printf ("\t[c] = \t\t%Zd\n", big_c);
end = clock();
enc_time_taken[i] = (((double) (end - start)) /
CLOCKS_PER_SEC) * 1000;
printf("\n3. [A] send [c] to [B]...\n");
printf("\n...");
printf("\n...");
printf("\n...");
printf("\n\n[B] receive [c] from [A]: \n");
gmp_printf ("\t[c] = \t\t%Zd\n", big_c);
start = clock();
printf("\n1. [B] calculate [cm] from [c] and [k1]:\n");
compute_cm_value(big_cm_fake_B, big_c, big_k1);
mpz_to_str(big_cm_fake_B, cm_fake_B);
printf("\t[cm] = \t\t%s\n", hex2str((const char* )cm_fake_B,
MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\n2. [B] decrypt [cm] with key [K1], m = D(cm,
K1):\n");
cipher_decrypt(cm_fake_B, K1, m_fake_B);
printf("\t[m] = \t\t%s\n", hex2str((const char* )m_fake_B,
MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
end = clock();
dec_time_taken[i] = (((double) (end - start)) /
CLOCKS_PER_SEC) * 1000;
printf("\n3. [B] compare with [m] that sent from [A]\n");
printf("\t[m] = \t\t%s\n", hex2str((const char* )m_fake_A,
MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
if(memcmp(m_fake_B, m_fake_A, MESSAGE_SIZE_BYTES) == 0) {
printf("\nOK, [A] HAVE SUCCESSFULY SENT A MESSAGE [m]
TO [B]!\n");
dec_ok[i] = 1;
} else {
printf("\nWOW, THEY ARE NOT THE SAME (SOMETHING WENT
WRONG!!!)\n");
dec_ok[i] = 0;
}
/* THUAT TOAN MA HOA CO THE CHOI TU DUA TREN MA KHOI */
printf("\n\nII. ALGORITHM ENC-SEC AND DEC-SEC (3.1)");
printf("\n==================================================\n");
printf("[A] WANT TO SEND MESSAGES TO [B]!\n");
printf("[A] --> Fake message [m_fake] and true message
[m_true] --> [B]\n");
163
printf("[A] have [m_fake, m_true, K1, K2, k1, k2]:\n");
printf("\t[m_true_A] = \t%s\n", hex2str((const char*
)m_true_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\t[m_fake_A] = \t%s\n", hex2str((const char*
)m_fake_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\t[K1] = \t\t%s\n", hex2str((const char* )K1,
CIPHER_KEY_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\t[K2] = \t\t%s\n", hex2str((const char* )K2,
CIPHER_KEY_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
gmp_printf ("\t[k1] = \t\t%Zd\n", big_k1);
gmp_printf ("\t[k2] = \t\t%Zd\n", big_k2);
start = clock();
printf("\n1. [A] encrypt message [m_fake] with key [K1],
cm_fake = E(m_fake, K1):\n");
cipher_encrypt(m_fake_A, K1, cm_fake_A);
printf("\t[cm_fake] = \t%s\n", hex2str((const char*
)cm_fake_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\n2. [A] encrypt message [m_true] with key [K2],
cm_true = E(m_true, K2):\n");
cipher_encrypt(m_true_A, K2, cm_true_A);
printf("\t[cm_true] = \t%s\n", hex2str((const char*
)cm_true_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\n3. [A] calculate [c] from [cm_fake] and [cm_true],
[k1] and [k2]:\n");
str_to_mpz(cm_fake_A, big_cm_fake_A);
str_to_mpz(cm_true_A, big_cm_true_A);
compute_c(big_c, big_cm_fake_A, big_cm_true_A, big_k1,
big_k2);
gmp_printf ("\t[c] = \t\t%Zd\n", big_c);
end = clock();
enc_true_fake_time_taken[i] = (((double) (end - start)) /
CLOCKS_PER_SEC) * 1000;
printf("\n\n4. [A] send [c] to [B]...\n");
printf("\n...");
printf("\n...");
printf("\n...");
printf("\n\n[B] receive [c] from [A]: \n");
gmp_printf ("\t[c] = \t\t%Zd\n", big_c);
start = clock();
printf("\n\nWhen NORMAL condition:");
printf("\n1. [B] calculate [cm_true] from [c] and [k2]:\n");
compute_cm_value(big_cm_true_B, big_c, big_k2);
mpz_to_str(big_cm_true_B, cm_true_B);
/* Replaced cm_true_B=cm_true_A*/
printf("\t[cm_true] = \t%s\n", hex2str((const char*
)cm_true_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\n2. [B] decrypt [cm_true] with key [K2], m_true =
D(cm_true, K2):\n");
cipher_decrypt(cm_true_B, K2, m_true_B);
/* Replaced m_true_B=m_true_A*/
164
printf("\t[m_true] = \t%s\n", hex2str((const char*
)m_true_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\n3. [B] have [m_true] that sent from [A]\n");
printf("\t[m_true] = \t%s\n", hex2str((const char*
)m_true_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
/* Replaced m_true_B=m_true_A*/
if(memcmp(m_true_A, m_true_A, MESSAGE_SIZE_BYTES) == 0) {
printf("\nOK, [A] HAVE SUCCESSFULY SENT A MESSAGE
[m_fake] TO [B]!\n");
dec_true_ok[i] = 1;
} else {
printf("\nWOW, THEY ARE NOT THE SAME (SOMETHING WENT
WRONG!!!)\n");
dec_true_ok[i] = 0;
}
end = clock();
dec_true_time_taken[i] = (((double) (end - start)) /
CLOCKS_PER_SEC) * 1000;
start = clock();
printf("\n\nWhen ATTACKED condition:");
printf("\n1. [B] calculate [cm_fake] from [c] and [k1]:\n");
compute_cm_value(big_cm_fake_B, big_c, big_k1);
mpz_to_str(big_cm_fake_B, cm_fake_B);
printf("\t[cm_fake] = \t%s\n", hex2str((const char*
)cm_fake_B, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\n2. [B] decrypt [cm_fake] with key [K1], m_fake =
D(cm_fake, K1):\n");
cipher_decrypt(cm_fake_B, K1, m_fake_B);
printf("\t[m_fake] = \t%s\n", hex2str((const char*
)m_fake_B, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
printf("\n3. [B] have [m_fake] that sent from [A]\n");
printf("\t[m_fake] = \t%s\n", hex2str((const char*
)m_fake_A, MESSAGE_SIZE_BYTES, buff_to_print, sizeof(buff_to_print)));
if(memcmp(m_fake_B, m_fake_A, MESSAGE_SIZE_BYTES) == 0) {
printf("\nOK, [A] HAVE SUCCESSFULY SENT A MESSAGE
[m_fake] TO [B]!\n");
dec_fake_ok[i] = 1;
} else {
printf("\nWOW, THEY ARE NOT THE SAME (SOMETHING WENT
WRONG!!!)\n");
dec_fake_ok[i] = 0;
}
end = clock();
dec_fake_time_taken[i] = (((double) (end - start)) /
CLOCKS_PER_SEC) * 1000;
enc_time_taken_average = enc_time_taken_average +
enc_time_taken[i];
dec_time_taken_average = dec_time_taken_average +
dec_time_taken[i];
enc_true_fake_time_average = enc_true_fake_time_average +
enc_true_fake_time_taken[i];
dec_true_time_taken_average = dec_true_time_taken_average+
dec_true_time_taken[i];
165
dec_fake_time_taken_average = dec_fake_time_taken_average +
dec_fake_time_taken[i];
printf("\nEXECUTION: %d... DONE\n", i + 1);
printf("\n**************************************************\n");
/* Pause 1 seconds */
sleep(1);
}
enc_time_taken_average = enc_time_taken_average/RUN_TIMES;
dec_time_taken_average = dec_time_taken_average/RUN_TIMES;
enc_true_fake_time_average = enc_true_fake_time_average/RUN_TIMES;
dec_true_time_taken_average =
dec_true_time_taken_average/RUN_TIMES;
dec_fake_time_taken_average =
dec_fake_time_taken_average/RUN_TIMES;
printf("\n\t\t\t\tALG. 3.1 EXECUTION TIME TAKEN AVERAGE\n");
printf("\t\t\t\t Number of running times: %d\n", RUN_TIMES);
printf("\n\tNo/Time(ms) \tEnc_deni \tDec_deni \tEnc_sec
\tDec_sec(true)\tDec_sec(fake)\tSUCCESSFULY");
printf("\n----------------------------------------------\n");
char *dec_char, *dec_true_char, *dec_fake_char;
for (i = 0; i < RUN_TIMES; i++) {
if (dec_ok[i]) {
dec_char = "yes";
} else {
dec_char = " no";
}
if (dec_true_ok[i]) {
dec_true_char = "yes";
} else {
dec_true_char = " no";
}
if (dec_fake_ok[i]) {
dec_fake_char = "yes";
} else {
dec_fake_char = " no";
}
printf(" \t %d \t\t%f \t%f \t%f \t%f \t%f\t%s, %s, %s\n", i
+ 1,
enc_time_taken[i], dec_time_taken[i],
enc_true_fake_time_taken[i],
dec_true_time_taken[i], dec_fake_time_taken[i],
dec_char, dec_true_char, dec_fake_char);
}
printf("\n------------------------------------------------\n");
printf("Average (miliseconds) \t%f \t%f \t%f \t%f \t%f\n\n",
enc_time_taken_average,
dec_time_taken_average,
enc_true_fake_time_average,
dec_true_time_taken_average,
dec_fake_time_taken_average);
166
mpz_clear(big_k1);
mpz_clear(big_k2);
mpz_clear(big_gcd);
mpz_clear(big_r);
mpz_clear(big_c);
mpz_clear(big_cm_true_A);
mpz_clear(big_cm_true_B);
mpz_clear(big_cm_fake_A);
mpz_clear(big_cm_fake_B);
/*
if(K1)
free(K1);
if(K2)
free(K2);
if(m_true_A)
free(m_true_A);
if(m_fake_A)
free(m_fake_A);
if(m_fake_A)
free(m_fake_A);
if(m_fake_B)
free(m_fake_B);
if(r)
free(r);
if(cm_true_A)
free(cm_true_A);
if(cm_true_B)
free(cm_true_B);
if(cm_fake_A)
free(cm_fake_A);
if(cm_fake_B)
free(cm_fake_B);
*/
return 1;
}
static char* hex2char(char *dst, unsigned char b) {
unsigned char v = b >> 4;
*dst++ = (v <= 9) ? '0' + v : 'a' + (v - 10);
v = b & 0x0f;
*dst++ = (v <= 9) ? '0' + v : 'a' + (v - 10);
return dst;
}
const char* hex2str(const char *bin, int bin_size, char *buff, int
buff_size) {
char *nptr = buff;
if (NULL == buff) {
return "Buffer is NULL";
}
if (buff_size < bin_size * 2) {
return "Buffer too small";
}
while (bin_size--) {
nptr = hex2char(nptr, *bin++);
167
}
if (buff_size >= bin_size * 2 + 1) {
*nptr = 0;
}
return buff;
}
/* THU TUC TAO SO NGUYEN TO k2 */
void generate_primes(mpz_t prime, int len) {
int primetest;
mpz_t seed;
mpz_init(seed);
unsigned char *str = malloc(len + len/2);
RAND_bytes(str, len);
mpz_import(seed, len/8, 1, sizeof (str[0]), 0, 0, str);
primetest = mpz_probab_prime_p(seed, 10);
if (primetest != 0) {
mpz_set(prime, seed);
} else {
mpz_nextprime(prime, seed);
}
free(str);
mpz_clear(seed);
return;
}
void generate_mpz(mpz_t big, int len) {
unsigned char *str = malloc(len);
RAND_bytes(str, len);
mpz_import(big, len/8, 1, sizeof (str[0]), 0, 0, str);
free(str);
return;
}
void str_to_mpz(char *str, mpz_t big){
mpz_import(big, strlen(str), 1, sizeof (str[0]), 0, 0, str);
return;
}
void mpz_to_str(mpz_t big, char *str){
mpz_export(str, (size_t*) malloc(sizeof (size_t)), 1, sizeof
(str[0]), 0, 0, big);
return;
}