This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*SecureTool is abbreviated to "st" as a prefix of function name.*/ | |
#include<stdio.h> | |
#include<stdint.h> | |
uint64_t st_power(uint64_t base, uint64_t exponent, uint64_t devider) | |
{ | |
uint64_t temp = base; | |
for (int i = 1; i < exponent; i++) | |
{ | |
uint64_t remainder = temp%devider; | |
temp = remainder * base; | |
} | |
return temp % devider; | |
} | |
int st_encrypt(uint64_t* code, uint64_t public_key, uint64_t n,size_t length, uint64_t* output) | |
{ | |
for (int i = 0; i < length; i++) | |
{ | |
output[i] = st_power(code[i], public_key, n); | |
} | |
return 0; | |
} | |
int st_decrypt(uint64_t* code, uint64_t private_key, uint64_t n, size_t length, uint64_t* output) | |
{ | |
for (int i = 0; i < length; i++) | |
{ | |
uint64_t remainder = st_power(code[i],private_key,n); | |
if (remainder > 26 && remainder < 100) | |
{ | |
remainder += n; | |
} | |
output[i] = remainder; | |
} | |
return 0; | |
} | |
uint64_t st_key_inverse (uint64_t public_key, uint64_t devider) | |
{ | |
uint64_t remainder = 1; | |
while(1) | |
{ | |
remainder += devider; | |
if(remainder % public_key == 0) | |
{ | |
return (remainder / public_key); | |
} | |
} | |
} | |
int st_encode(const char* string, char* output) | |
{ | |
unsigned int i = 0; | |
for(const char* s = string; *s; s++) | |
{ | |
if (*s >= 'A' && *s <= 'Z') // Upper case roman character | |
{ | |
output[i++] = *s - 'A'; | |
} | |
else if (*s == ' ') | |
{ | |
output[i++] = 26; | |
} | |
else | |
{ | |
return 1; // ERROR invalid char | |
} | |
} | |
if (i%2) | |
{ | |
output[i++] = 26; | |
} // pad if needed | |
return 0; | |
} | |
int st_decode(uint64_t* code,char* output,size_t length) | |
{ | |
char w = ' ',x = ' '; | |
for(int i = 0; i < length; i++) | |
{ | |
uint64_t v = code[i] / 100; | |
if (v != 26) | |
{ | |
w = v + 'A'; | |
output[i*2] = w; | |
} | |
else | |
{ | |
output[i*2] = ' '; | |
} | |
uint64_t u = code[i] % 100; | |
if(u != 26) | |
{ | |
x = u + 'A'; | |
output[i*2+1] = x; | |
} | |
else | |
{ | |
output[i*2+1] = ' '; | |
} | |
} | |
return 0; | |
} | |
int main() | |
{ | |
const char string[] = "STOP"; | |
printf("plain text:%s\n", string); | |
const size_t string_length = sizeof(string); | |
//printf("text size: %lu\n", string_length); | |
const size_t blocks_length = (string_length) / 2; | |
char blocks[string_length]; | |
uint64_t m[blocks_length], c[blocks_length], m2[blocks_length]; | |
uint64_t e = 13; | |
uint64_t p = 43; | |
uint64_t q = 59; | |
uint64_t n = p * q; | |
uint64_t t = (p - 1) * (q - 1); | |
uint64_t d = st_key_inverse(e, t); | |
printf("p = %lu\nq = %lu\nn = %lu\ne = %lu\n", p, q, n, e); | |
printf("d = %lu\n", d); | |
st_encode(string, (char*)blocks); | |
printf("M = "); | |
for (size_t i = 0; i < blocks_length; i++) | |
{ | |
m[i] = blocks[i*2]*100 + blocks[i*2+1]; | |
printf("%lu ", m[i]); | |
} | |
st_encrypt(m, e, n, blocks_length, c); | |
st_decrypt(c, d, n, blocks_length, m2); | |
printf("\nC = "); | |
for (int i = 0; i < blocks_length; i++){ | |
printf("%lu ", c[i]); | |
} | |
printf("\nafter decoding:"); | |
char text[string_length]; | |
st_decode(m2, text, blocks_length); | |
for (int i = 0; i < blocks_length; i++) | |
{ | |
printf("%lu ",m2[i]); | |
} | |
printf("\ndecoded text:"); | |
for (int i = 0; i < string_length - 1; i++) | |
{ | |
printf("%c", text[i]); | |
} | |
printf("\n"); | |
return 0; | |
} |
沒有留言:
張貼留言