/
rc4_test.c
142 lines (112 loc) · 3.29 KB
/
rc4_test.c
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
** RC4 Cipher in Assembly Test
**
** Author: Charlie Chen
** Website: http://www.CharmySoft.com/
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int rc4_x86(const void *inbuf, void *outbuf, size_t buflen, const char *key, size_t keylen);
int rc4_c(const void *inbuf, void *outbuf, size_t buflen, const char *key, size_t keylen);
char* string_repeat( int n, const char * s );
int main(int argc, char* argv[])
{
char password[] = "password";
char data[] = "This is the data that needs to be encrypted";
size_t datalen = sizeof(data);
char *data_long;
void *encryptedData = malloc(datalen);
void *decryptedData = malloc(datalen);
// Benchmark speed
const int TRIALS = 10000;
int i;
time_t start;
time_t t_c;
time_t t_x86;
// Short data benchmark test
printf("For short data (size %d)\n", datalen);
start = clock();
for (i = 0; i < TRIALS; i++)
rc4_c(data, encryptedData, datalen, password, sizeof(password));
t_c = clock() - start;
printf("C code time consumed: %d ms.\n", t_c);
start = clock();
for (i = 0; i < TRIALS; i++)
rc4_x86(encryptedData, decryptedData, datalen, password, sizeof(password));
t_x86 = clock() - start;
printf("Assembly code time consumed: %d ms.\n", t_x86);
printf("The Assembly version is %.2fx faster than the c version.\n\n", (double)t_c / t_x86);
if(memcmp(data, (char*)decryptedData, datalen) != 0)
printf("Raw data does not match decrypted data! Data damaged!\n\n");
// Long data benchmark test
data_long = string_repeat(1000, "This is the data that needs to be encrypted");
datalen *= 1000;
encryptedData = malloc(datalen);
decryptedData = malloc(datalen);
printf("For long data (size %d):\n", datalen);
start = clock();
for (i = 0; i < TRIALS; i++)
rc4_c(data_long, encryptedData, datalen, password, sizeof(password));
t_c = clock() - start;
printf("C code time consumed: %d ms.\n", t_c);
start = clock();
for (i = 0; i < TRIALS; i++)
rc4_x86(encryptedData, decryptedData, datalen, password, sizeof(password));
t_x86 = clock() - start;
printf("Assembly code time consumed: %d ms.\n", t_x86);
printf("The Assembly version is %.2fx faster than the c version.\n\n", (double)t_c / t_x86);
if(memcmp(data_long, (char*)decryptedData, datalen) != 0)
printf("Raw data does not match decrypted data! Data damaged!\n\n");
free(data_long);
getchar();
return 0;
}
int rc4_c(const void *inbuf, void *outbuf, size_t buflen, const char *key, size_t keylen)
{
char s[256];
char k[256];
unsigned int i;
unsigned char j;
unsigned char temp;
if(buflen <= 0)
return -1;
// Initialize RC4 state
for(i = 0; i < sizeof(s); i++){
// Fill s with 0..255
s[i] = i;
// Generate k
k[i] = key[i % keylen];
}
j = 0;
for(i = 0; i < sizeof(s); i++){
j = j + s[i] + k[i];
temp = s[i]; // swap
s[i] = s[j];
s[j] = temp;
}
j = 0;
for(i = 0; i < buflen; i++){
unsigned char c;
unsigned char t;
c = i + 1;
j += s[c];
temp = s[c]; // swap
s[c] = s[j];
s[j] = temp;
t = s[c] + s[j];
*((char*)outbuf + i) = *((char*)inbuf + i) ^ s[t];
}
return buflen;
}
char * string_repeat( int n, const char * s ) {
size_t slen = strlen(s);
char * dest = (char *)malloc(n*slen+1);
int i; char * p;
for ( i=0, p = dest; i < n; ++i, p += slen ) {
memcpy(p, s, slen);
}
*p = '\0';
return dest;
}