maHoa.cpp
hacker98
plain_text
a year ago
25 kB
6
Indexable
jni
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<string.h>
#include<time.h>
#include <malloc.h>
#include <android/log.h>
#define LFSR_SIZE 16
#define FSM_SIZE 3
#define key_len 256
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
typedef unsigned char BYTE;
typedef long DWORD;
static uint32_t LFSR[LFSR_SIZE];
static uint32_t R1, R2, R3;
uint8_t GF_MUL(uint8_t a,uint8_t b){
uint8_t p=0;
uint8_t hi_bit_set;
for(int i=0;i<8;i++){
if(b & 1)
p^=a;
hi_bit_set = (a & 0x80);
a <<= 1;
if(hi_bit_set)
a ^= 0x1B;
b >>= 1;
}
return p;
}
const uint8_t sBox[256] = {
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
};
const uint8_t invSBox[256] = {
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};
const uint8_t rcon[15] = {
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D
};
void string_to_hex(uint8_t* string, char* hex, char string_len){
for(int i = 0; i<string_len; i++){
snprintf(hex + 2 * i, 4, "%02x", string[i]);
}
hex[string_len*2]=0;
}
void hex_to_string(const char* hex, char* string, int hex_len){
int val;
for(int i=0; i<hex_len/2; i++){
sscanf(hex + 2 * i, "%2x", &val);
string[i]=(char)val;
}
string[hex_len/2]=0;
}
void padding(char *input) {
for (int i = strlen(input);i <= strlen(input) + 16;i++)
input[i] = 0;
}
void KeyExpansion(uint8_t* key, uint8_t w[15][4][4]) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
w[0][i][j] = key[i * 4 + j];
}
}
for (int i = 1; i <= 14; i++) {
for (int j = 0; j < 4; j++) {
w[i][0][j] = w[i - 1][0][j] ^ sBox[w[i - 1][1][j]] ^ rcon[i];
for (int k = 1; k < 4; k++) {
w[i][k][j] = w[i - 1][k][j] ^ w[i][k - 1][j];
}
}
}
}
void generateKey256(char* key, int length) {
srand(time(NULL));
for (int i = 0;i < length*2;i++){
int r = rand() % 256;
if(r/16<=9)
key[i]=r/16+'0';
else
key[i]=r/16+'A'-10;
i++;
if(r%16<=9)
key[i]=r%16+'0';
else
key[i]=r%16+'A'-10;
}
key[length*2]=0;
}
void generateIV(uint8_t* iv, int length) {
srand(time(NULL));
for (int i = 0;i < length;i++)
iv[i] = rand() % 256;
}
void subBytes(uint8_t state[4][4]) {
for (int i = 0;i < 4;i++)
for (int j = 0;j < 4;j++)
state[i][j] = sBox[state[i][j]];
}
void shiftRow(uint8_t state[4][4]) {
for (int i = 1;i < 4;i++) {
for (int k = 0;k < i;k++) {
uint8_t temp = state[i][0];
for (int j = 0;j < 3;j++)
state[i][j] = state[i][j + 1];
state[i][3] = temp;
}
}
}
void addRoundKey(uint8_t state[4][4],uint8_t roundKey[4][4]) {
for (int i = 0;i < 4;i++)
for (int j = 0;j < 4;j++)
state[i][j] ^= roundKey[i][j];
}
void mixColumns(uint8_t state[4][4]) {
uint8_t temp[4][4];
for (int j = 0; j < 4; j++) {
temp[0][j] = GF_MUL(0x02, state[0][j]) ^ GF_MUL(0x03, state[1][j]) ^ state[2][j] ^ state[3][j];
temp[1][j] = state[0][j] ^ GF_MUL(0x02, state[1][j]) ^ GF_MUL(0x03, state[2][j]) ^ state[3][j];
temp[2][j] = state[0][j] ^ state[1][j] ^ GF_MUL(0x02, state[2][j]) ^ GF_MUL(0x03, state[3][j]);
temp[3][j] = GF_MUL(0x03, state[0][j]) ^ state[1][j] ^ state[2][j] ^ GF_MUL(0x02, state[3][j]);
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
state[i][j] = temp[i][j];
}
}
}
void invSubBytes(uint8_t state[4][4]) {
for (int i = 0;i < 4;i++)
for (int j = 0;j < 4;j++)
state[i][j] = invSBox[state[i][j]];
}
void invShiftRow(uint8_t state[4][4]) {
for (int i = 1;i < 4;i++) {
for (int k = 0;k < i;k++) {
uint8_t temp = state[i][3];
for (int j = 3;j > 0;j--)
state[i][j] = state[i][j - 1];
state[i][0] = temp;
}
}
}
void invMixColumns(uint8_t state[4][4]){
uint8_t temp[4][4];
for (int j = 0; j < 4; j++) {
temp[0][j] = GF_MUL(0x0E, state[0][j]) ^ GF_MUL(0x0B, state[1][j]) ^ GF_MUL(0x0D,state[2][j]) ^ GF_MUL(0x09,state[3][j]);
temp[1][j] = GF_MUL(0x09, state[0][j]) ^ GF_MUL(0x0E, state[1][j]) ^ GF_MUL(0x0B,state[2][j]) ^ GF_MUL(0x0D,state[3][j]);
temp[2][j] = GF_MUL(0x0D, state[0][j]) ^ GF_MUL(0x09, state[1][j]) ^ GF_MUL(0x0E,state[2][j]) ^ GF_MUL(0x0B,state[3][j]);
temp[3][j] = GF_MUL(0x0B, state[0][j]) ^ GF_MUL(0x0D, state[1][j]) ^ GF_MUL(0x09,state[2][j]) ^ GF_MUL(0x0E,state[3][j]);
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
state[i][j] = temp[i][j];
}
}
}
void enCryptAES(char* input, char* keyHex, char output[256]) {
uint8_t iv[16];
uint8_t state[4][4];
uint8_t roundKey[15][4][4];
uint8_t cipherText[256];
uint8_t* key = (uint8_t*) malloc(33);
for(int i=0;keyHex[i]!=0;i++){
if(keyHex[i]<='9')
key[i/2]=keyHex[i]-'0';
else
key[i/2]=keyHex[i]-'A'+10;
i++;
if(keyHex[i]<='9')
key[i/2]=key[i/2]*16+keyHex[i]-'0';
else
key[i/2]=key[i/2]*16+keyHex[i]-'A'+10;
}
KeyExpansion(key, roundKey);
int len = ((strlen(input) + 16) / 16) * 16;
generateIV(iv, 16);
for (int i = 0;i < 16;i++)
cipherText[i] = iv[i];
padding(input);
for (int block = 0;block < (strlen(input) + 16) / 16;block++) {
if (block == 0) {
for (int i = 0;i < 16;i++)
state[i / 4][i % 4] = iv[i] ^ input[i];
}
else {
for (int i = block*16;i < block*16+16;i++)
state[(i / 4)%4][i % 4] = cipherText[i] ^ input[i];
}
addRoundKey(state, roundKey[0]);
for (int loop = 1;loop < 14;loop++) {
subBytes(state);
shiftRow(state);
mixColumns(state);
addRoundKey(state, roundKey[loop]);
}
subBytes(state);
shiftRow(state);
addRoundKey(state, roundKey[14]);
for (int i = block * 16;i < block * 16 + 16;i++)
cipherText[i+16] = state[(i / 4)%4][i % 4];
}
string_to_hex(cipherText,output,len+16);
}
void deCryptAES(char* plaintext, char* keyHex, char* output){
uint8_t* key = (uint8_t*) malloc(33);
for(int i=0;keyHex[i]!=0;i++){
if(keyHex[i]<='9')
key[i/2]=keyHex[i]-'0';
else
key[i/2]=keyHex[i]-'A'+10;
i++;
if(keyHex[i]<='9')
key[i/2]=key[i/2]*16+keyHex[i]-'0';
else
key[i/2]=key[i/2]*16+keyHex[i]-'A'+10;
}
char input[256];
hex_to_string(plaintext, input, strlen(plaintext));
uint8_t iv[16];
uint8_t roundKey[15][4][4];
KeyExpansion(key,roundKey);
for(int i=0;i<16;i++)
iv[i]=input[i];
int blockCount=strlen(plaintext)/32;
uint8_t state[4][4];
for(int block=blockCount-1; block>0; block--){
for(int i=block*16; i<block*16+16; i++){
state[(i/4)%4][i%4]=input[i];
}
addRoundKey(state, roundKey[14]);
for(int loop=13;loop>0;loop--){
invShiftRow(state);
invSubBytes(state);
addRoundKey(state,roundKey[loop]);
invMixColumns(state);
}
invShiftRow(state);
invSubBytes(state);
addRoundKey(state,roundKey[0]);
if(block==1)
for(int i=0;i<16;i++)
output[i]=iv[i]^state[i/4][i%4];
else{
for(int i=block*16;i<block*16+16;i++)
output[i-16]=input[i-16]^state[(i/4)%4][i%4];
}
}
}
void KeyExpansion_128(uint8_t* key, uint8_t w[11][4][4]) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
w[0][i][j] = key[i * 4 + j];
}
}
for (int i = 1; i <= 10; i++) {
for (int j = 0; j < 4; j++) {
w[i][0][j] = w[i - 1][0][j] ^ sBox[w[i - 1][1][j]] ^ rcon[i];
for (int k = 1; k < 4; k++) {
w[i][k][j] = w[i - 1][k][j] ^ w[i][k - 1][j];
}
}
}
}
void enCryptAES_128(char* input, char* keyHex, char output[256]) {
uint8_t iv[16];
uint8_t state[4][4];
uint8_t roundKey[11][4][4];
uint8_t cipherText[256];
uint8_t* key = (uint8_t*) malloc(17);
for(int i=0;keyHex[i]!=0;i++){
if(keyHex[i]<='9')
key[i/2]=keyHex[i]-'0';
else
key[i/2]=keyHex[i]-'A'+10;
i++;
if(keyHex[i]<='9')
key[i/2]=key[i/2]*16+keyHex[i]-'0';
else
key[i/2]=key[i/2]*16+keyHex[i]-'A'+10;
}
KeyExpansion_128(key, roundKey);
int len = ((strlen(input) + 16) / 16) * 16;
generateIV(iv, 16);
for (int i = 0;i < 16;i++)
cipherText[i] = iv[i];
padding(input);
for (int block = 0;block < (strlen(input) + 16) / 16;block++) {
if (block == 0) {
for (int i = 0;i < 16;i++)
state[i / 4][i % 4] = iv[i] ^ input[i];
}
else {
for (int i = block*16;i < block*16+16;i++)
state[(i / 4)%4][i % 4] = cipherText[i] ^ input[i];
}
addRoundKey(state, roundKey[0]);
for (int loop = 1;loop < 10;loop++) {
subBytes(state);
shiftRow(state);
mixColumns(state);
addRoundKey(state, roundKey[loop]);
}
subBytes(state);
shiftRow(state);
addRoundKey(state, roundKey[10]);
for (int i = block * 16;i < block * 16 + 16;i++)
cipherText[i+16] = state[(i / 4)%4][i % 4];
}
string_to_hex(cipherText,output,len+16);
}
void deCryptAES_128(char* plaintext, char* keyHex, char* output){
uint8_t* key = (uint8_t*) malloc(17);
for(int i=0;keyHex[i]!=0;i++){
if(keyHex[i]<='9')
key[i/2]=keyHex[i]-'0';
else
key[i/2]=keyHex[i]-'A'+10;
i++;
if(keyHex[i]<='9')
key[i/2]=key[i/2]*16+keyHex[i]-'0';
else
key[i/2]=key[i/2]*16+keyHex[i]-'A'+10;
}
char input[256];
hex_to_string(plaintext, input, strlen(plaintext));
uint8_t iv[16];
uint8_t roundKey[11][4][4];
KeyExpansion_128(key,roundKey);
for(int i=0;i<16;i++)
iv[i]=input[i];
int blockCount=strlen(plaintext)/32;
uint8_t state[4][4];
for(int block=blockCount-1; block>0; block--){
for(int i=block*16; i<block*16+16; i++){
state[(i/4)%4][i%4]=input[i];
}
addRoundKey(state, roundKey[10]);
for(int loop=9;loop>0;loop--){
invShiftRow(state);
invSubBytes(state);
addRoundKey(state,roundKey[loop]);
invMixColumns(state);
}
invShiftRow(state);
invSubBytes(state);
addRoundKey(state,roundKey[0]);
if(block==1)
for(int i=0;i<16;i++)
output[i]=iv[i]^state[i/4][i%4];
else{
for(int i=block*16;i<block*16+16;i++)
output[i-16]=input[i-16]^state[(i/4)%4][i%4];
}
}
}
uint32_t* string_to_uint32_array(const char* input, int* out_len) {
int len = strlen(input);
int num_uint32 = (len + 3) / 4;
uint32_t* uint32_array = (uint32_t*)malloc(num_uint32 * sizeof(uint32_t));
for (int i = 0; i < num_uint32; i++) {
uint32_array[i] = 0;
}
for (int i = 0; i < len; i++) {
uint32_array[i / 4] |= (uint32_t)(uint8_t)input[i] << (8 * (3 - (i % 4)));
}
*out_len = num_uint32;
return uint32_array;
}
char* uint32_array_to_string(uint32_t* input, int inp_len) {
char* output = (char*)malloc(inp_len * 4 + 1);
output[inp_len * 4] = 0;
for (int i = 0; i < inp_len * 4;i++) {
output[i] = (char)((input[i / 4] >> (24 - (i % 4) * 8)) & 0XFF);
}
return output;
}
void uint32_arr_to_hex(uint32_t* arr, int inpLen, char* hex){
hex[inpLen*8]=0;
for (int i = 0; i < inpLen * 4;i++) {
BYTE value = (BYTE)((arr[i / 4] >> (24 - (i % 4) * 8)) & 0XFF);
snprintf(hex + i*2, 3, "%02x", value);
}
}
void bytes_to_hex(const BYTE* bytes, DWORD bytes_len, char* hex_output) {
for (DWORD i = 0; i < bytes_len; i++) {
snprintf(hex_output + (i * 2), 3, "%02x", bytes[i]);
}
hex_output[bytes_len * 2] = '\0';
}
void hex_to_uint32(const char *hex, uint32_t* array) {
for(int i=0;i<strlen(hex)/8;i++)
array[i]=0;
for (int i = 0; i < strlen(hex)/2; i++) {
uint32_t value;
if(hex[2*i]<='9')
value=hex[i*2]-'0';
else if(hex[2*i]>='a')
value=hex[i*2]-'a'+10;
else value=hex[i*2]-'A'+10;
if(hex[2*i+1]<='9')
value= value*16 + hex[i*2+1]-'0';
else if(hex[2*i+1]>='a')
value=value*16 + hex[i*2+1]-'a'+10;
else value=value*16 + hex[i*2+1]-'A'+10;
array[i/4] = (array[i/4]<<8) | value;
}
}
void bytes_to_arr_uint32(BYTE* bytes, DWORD bytes_len, uint32_t* output){
for(int i=0;i<bytes_len/4;i++)
output[i]=0;
for(int i=0;i<bytes_len;i++)
output[i/4]= (output[i/4]<<8) | (uint32_t)bytes[i];
}
uint32_t update_FSM() {
uint32_t F = (R1 + R2) ^ R3;
R3 = R2;
R2 = R1;
R1 = LFSR[5] ^ F;
return F;
}
void update_LFSR(uint32_t F) {
uint32_t temp = LFSR[0] ^ F;
for (int i = 0; i < LFSR_SIZE - 1; i++) {
LFSR[i] = LFSR[i + 1];
}
LFSR[LFSR_SIZE - 1] = temp;
}
void initialize(uint32_t key[8], uint32_t iv[4]) {
for (int i = 0; i < 8; i++) {
LFSR[i] = key[i];
}
for (int i = 0; i < 4; i++) {
LFSR[8 + i] = iv[i];
}
for (int i = 12; i < LFSR_SIZE; i++) {
LFSR[i] = key[i - 12] ^ iv[i - 12];
}
R1 = R2 = R3 = 0;
for (int i = 0;i < 32;i++) {
uint32_t F = update_FSM();
update_LFSR(F);
}
}
uint32_t generate_keystream() {
uint32_t F = update_FSM();
uint32_t keystream = LFSR[0] ^ F;
update_LFSR(F);
return keystream;
}
char* snowVencrypt(char* keyHex, char* plaintext) {
uint32_t* key=(uint32_t*)malloc(key_len/8);
uint32_t* iv=(uint32_t*)malloc(4*sizeof(uint32_t));
BYTE* ivByte=(BYTE*) malloc(16);
hex_to_uint32(keyHex, key);
generateIV(ivByte,16);
bytes_to_arr_uint32(ivByte, 16, iv);
initialize(key, iv);
uint32_t* data;
int length;
data = string_to_uint32_array(plaintext, &length);
for (int i = 0; i < length; i++) {
uint32_t keystream = generate_keystream();
data[i] ^= keystream;
}
char* ivHex=(char*)malloc(33);
bytes_to_hex(ivByte, 16, ivHex);
char* ciphertext = (char*) malloc(length*8+33);
memcpy(ciphertext, ivHex, 32);
uint32_arr_to_hex(data, length, ciphertext+32);
return ciphertext;
}
char* snowVdecrypt(char* keyHex, char* ciphertext) {
uint32_t* key=(uint32_t*)malloc(key_len/8);
uint32_t* iv=(uint32_t*)malloc(4*sizeof(uint32_t));
char* ivHex=(char*)malloc(33);
memcpy(ivHex, ciphertext, 32);
ivHex[32]=0;
ciphertext+=32;
hex_to_uint32(ivHex, iv);
hex_to_uint32(keyHex, key);
initialize(key, iv);
int length=strlen(ciphertext)/4;
uint32_t* data=(uint32_t*)malloc(length*4+1);
hex_to_uint32(ciphertext, data);
for (int i = 0; i < length; i++) {
uint32_t keystream = generate_keystream();
data[i] ^= keystream;
}
char* result = uint32_array_to_string(data,length);
return result;
}
static uint8_t snt[30000];
void sangNT() {
for (long i = 2;i <= 21000 / 2;i++) {
if (!snt[i]) {
for (int k = 2;k * i < 21000;k++)
snt[k * i] = 1;
}
}
}
long getPrime(long input) {
long result1;
srand(time(NULL) ^ input);
result1 = rand() % 19000 + 1000;
long result = result1;
while (snt[result] && result < 20000)
result++;
if (result >= 20000) {
result = result1;
while (snt[result])
result--;
}
return result;
}
unsigned long long module(long long e, long long n) {
long long q, r, x=0, x1, x2, nn = n;
x2 = 1;
x1 = 0;
while (1) {
q = e / n;
r = e % n;
if (r == 0)
break;
e = n;
n = r;
x = x2 - q * x1;
x2 = x1;
x1 = x;
}
if (x < 0)
x = nn + x;
return x;
}
void ascii_to_binary(unsigned long long n, char bi[20]) {
int i = 0;
while (n != 0) {
bi[i] = n % 2 + '0';
i++;
n /= 2;
}
bi[i] = 0;
}
unsigned long long nhanBPCL(unsigned long long m, unsigned long long k, unsigned long long n) {
char bi[100];
unsigned long long a = m, b = 1;
ascii_to_binary(k, bi);
for (int i = 0;i < strlen(bi);i++) {
if (bi[i] == '1')
b = (a * b) % n;
a = (a * a) % n;
}
return b;
}
void gopKey(long long a, unsigned long long b, char key[128]) {
int r, i = 1;
while (a > 0) {
r = a % 16;
a /= 16;
if (r < 10)
key[i] = r + '0';
else
key[i] = r - 10 + 'A';
i++;
}
if (i - 1 < 10)
key[0] = i + '0' - 1;
else
key[0] = i - 11 + 'A';
int j = i + 1;
while (b > 0) {
r = b % 16;
b /= 16;
if (r < 10)
key[j] = r + '0';
else
key[j] = r - 10 + 'A';
j++;
}
if (j - i - 1 < 10)
key[i] = j - i - 1 + '0';
else
key[i] = j - i - 11 + 'A';
key[j] = 0;
}
void tachKey(unsigned long long* a, unsigned long long* b, char key[128]) {
*a = 0;*b = 0;
int len, index;
if (key[0] <= '9')
len = key[0] - '0';
else len = key[0] - 'A' + 10;
for (index = len;index >= 1;index--) {
int value;
if (key[index] <= '9')
value = key[index] - '0';
else value = key[index] - 'A' + 10;
*a = (*a)*16+ value;
}
index = len + 1;
if (key[index] <= '9')
len = key[index] - '0';
else len = key[index] - 'A' + 10;
for (int i = len + index ;i >= index + 1;i--) {
int value;
if (key[i] <= '9')
value = key[i] - '0';
else value = key[i] - 'A' + 10;
*b = (*b) * 16 + value;
}
}
void gopChuoi(char s[500], int* index, unsigned long long c) {
int i = *index + 1;
while (c > 0) {
s[i] = c % 10 + '0';
c /= 10;
i++;
}
if (i - *index - 1 <= 9)
s[*index] = i - (*index) - 1 + '0';
else
s[*index] = i - (*index) - 1 + 'A' - 10;
*index = i;
}
void tachChuoi(char s[500], int* index, unsigned long long* c) {
*c = 0;
int i, len;
if (s[*index] <= '9')
len = *index + s[*index] - '0';
else
len = *index + s[*index] - 'A' + 10;
for (i = len;i >=*index + 1;i--) {
*c = (*c) * 10 + s[i] - '0';
}
*index = len+1;
}
char* generateKeyRSA() {
char* publicKey = (char*) malloc(256);
char privateKey[128];
sangNT();
unsigned long long p, q, e, n, phiN, d;
p = getPrime(1245);
q = getPrime(2356);
while (p == q)
p = getPrime(12345);
n = p * q;
phiN = (p - 1) * (q - 1);
e = getPrime(4523);
while(phiN % e==0)
e = getPrime(4523);
d = module(e, phiN);
gopKey(e, n, publicKey);
int len = strlen(publicKey);
publicKey[len]=':';
gopKey(d, n, publicKey+len+1);
return publicKey;
}
char* encrypt_RSA(char plaintext[128], char publicKey[128]) {
unsigned long long n;
unsigned long long e;
int index = 0;
char* cipherText = (char*) malloc(500);
tachKey(&e, &n, publicKey);
for (int i = 0;plaintext[i] != 0;i += 2) {
int m = 0;
if (plaintext[i] <= '9')
m = plaintext[i] - '0';
else m = plaintext[i] - 'A' + 10;
if (plaintext[i + 1] <= '9')
m = m * 16 + plaintext[i + 1] - '0';
else m = m * 16 + plaintext[i + 1] - 'A' + 10;
unsigned long long c = nhanBPCL(m, e, n);
gopChuoi(cipherText, &index, c);
}
cipherText[index] = 0;
return cipherText;
}
char* decrypt_RSA(char cipherText[500], char privateKey[128]) {
unsigned long long n, d;
int index = 0, len = 0;
char* plainText = (char*) malloc(128);
tachKey(&d, &n, privateKey);
while (cipherText[index] != 0) {
unsigned long long c;
tachChuoi(cipherText, &index, &c);
unsigned long long m = nhanBPCL(c, d, n);
if (m / 16 <= 9)
plainText[len] = m / 16 + '0';
else
plainText[len] = m / 16 + 'A'-10;
len++;
if (m % 16 <= 9)
plainText[len] = m % 16 + '0';
else
plainText[len] = m % 16 + 'A'-10;
len++;
}
plainText[len] = 0;
return plainText;
}
Editor is loading...
Leave a Comment