mahoa
unknown
c_cpp
5 months ago
35 kB
2
Indexable
//maHoaaa #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 if(keyHex[i]>='a') key[i/2]=keyHex[i]-'a'+10; else key[i/2]=keyHex[i]-'A'+10; i++; if(keyHex[i]<='9') key[i/2]=key[i/2]*16+keyHex[i]-'0'; else if(keyHex[i]>='a') key[i/2]=key[i/2]*16+keyHex[i]-'a'+10; 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 if(keyHex[i]>='a') key[i/2]=keyHex[i]-'a'+10; else key[i/2]=keyHex[i]-'A'+10; i++; if(keyHex[i]<='9') key[i/2]=key[i/2]*16+keyHex[i]-'0'; else if(keyHex[i]>='a') key[i/2]=key[i/2]*16+keyHex[i]-'a'+10; 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 if(keyHex[i]>='a') key[i/2]=keyHex[i]-'a'+10; else key[i/2]=keyHex[i]-'A'+10; i++; if(keyHex[i]<='9') key[i/2]=key[i/2]*16+keyHex[i]-'0'; else if(keyHex[i]>='a') key[i/2]=key[i/2]*16+keyHex[i]-'a'+10; 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 if(keyHex[i]>='a') key[i/2]=keyHex[i]-'a'+10; else key[i/2]=keyHex[i]-'A'+10; i++; if(keyHex[i]<='9') key[i/2]=key[i/2]*16+keyHex[i]-'0'; else if(keyHex[i]>='a') key[i/2]=key[i/2]*16+keyHex[i]-'a'+10; 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 + 4) / 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; } #define MASK 0x7FFFFFFF #define KEYSIZE 16 #define IVSIZE 16 const uint8_t S0[256] = { 0x3e, 0x72, 0x5b, 0x47, 0xca, 0xe0, 0x00, 0x33, 0x04, 0xd1, 0x54, 0x98, 0x09, 0xb9, 0x6d, 0xcb, 0x7b, 0x1b, 0xf9, 0x32, 0xaf, 0x9d, 0x6a, 0xa5, 0xb8, 0x2d, 0xfc, 0x1d, 0x08, 0x53, 0x03, 0x90, 0x4d, 0x4e, 0x84, 0x99, 0xe4, 0xce, 0xd9, 0x91, 0xdd, 0xb6, 0x85, 0x48, 0x8b, 0x29, 0x6e, 0xac, 0xcd, 0xc1, 0xf8, 0x1e, 0x73, 0x43, 0x69, 0xc6, 0xb5, 0xbd, 0xfd, 0x39, 0x63, 0x20, 0xd4, 0x38, 0x76, 0x7d, 0xb2, 0xa7, 0xcf, 0xed, 0x57, 0xc5, 0xf3, 0x2c, 0xbb, 0x14, 0x21, 0x06, 0x55, 0x9b, 0xe3, 0xef, 0x5e, 0x31, 0x4f, 0x7f, 0x5a, 0xa4, 0x0d, 0x82, 0x51, 0x49, 0x5f, 0xba, 0x58, 0x1c, 0x4a, 0x16, 0xd5, 0x17, 0xa8, 0x92, 0x24, 0x1f, 0x8c, 0xff, 0xd8, 0xae, 0x2e, 0x01, 0xd3, 0xad, 0x3b, 0x4b, 0xda, 0x46, 0xeb, 0xc9, 0xde, 0x9a, 0x8f, 0x87, 0xd7, 0x3a, 0x80, 0x6f, 0x2f, 0xc8, 0xb1, 0xb4, 0x37, 0xf7, 0x0a, 0x22, 0x13, 0x28, 0x7c, 0xcc, 0x3c, 0x89, 0xc7, 0xc3, 0x96, 0x56, 0x07, 0xbf, 0x7e, 0xf0, 0x0b, 0x2b, 0x97, 0x52, 0x35, 0x41, 0x79, 0x61, 0xa6, 0x4c, 0x10, 0xfe, 0xbc, 0x26, 0x95, 0x88, 0x8a, 0xb0, 0xa3, 0xfb, 0xc0, 0x18, 0x94, 0xf2, 0xe1, 0xe5, 0xe9, 0x5d, 0xd0, 0xdc, 0x11, 0x66, 0x64, 0x5c, 0xec, 0x59, 0x42, 0x75, 0x12, 0xf5, 0x74, 0x9c, 0xaa, 0x23, 0x0e, 0x86, 0xab, 0xbe, 0x2a, 0x02, 0xe7, 0x67, 0xe6, 0x44, 0xa2, 0x6c, 0xc2, 0x93, 0x9f, 0xf1, 0xf6, 0xfa, 0x36, 0xd2, 0x50, 0x68, 0x9e, 0x62, 0x71, 0x15, 0x3d, 0xd6, 0x40, 0xc4, 0xe2, 0x0f, 0x8e, 0x83, 0x77, 0x6b, 0x25, 0x05, 0x3f, 0x0c, 0x30, 0xea, 0x70, 0xb7, 0xa1, 0xe8, 0xa9, 0x65, 0x8d, 0x27, 0x1a, 0xdb, 0x81, 0xb3, 0xa0, 0xf4, 0x45, 0x7a, 0x19, 0xdf, 0xee, 0x78, 0x34, 0x60 }; const uint8_t S1[256] = { 0x55, 0xc2, 0x63, 0x71, 0x3b, 0xc8, 0x47, 0x86, 0x9f, 0x3c, 0xda, 0x5b, 0x29, 0xaa, 0xfd, 0x77, 0x8c, 0xc5, 0x94, 0x0c, 0xa6, 0x1a, 0x13, 0x00, 0xe3, 0xa8, 0x16, 0x72, 0x40, 0xf9, 0xf8, 0x42, 0x44, 0x26, 0x68, 0x96, 0x81, 0xd9, 0x45, 0x3e, 0x10, 0x76, 0xc6, 0xa7, 0x8b, 0x39, 0x43, 0xe1, 0x3a, 0xb5, 0x56, 0x2a, 0xc0, 0x6d, 0xb3, 0x05, 0x22, 0x66, 0xbf, 0xdc, 0x0b, 0xfa, 0x62, 0x48, 0xdd, 0x20, 0x11, 0x06, 0x36, 0xc9, 0xc1, 0xcf, 0xf6, 0x27, 0x52, 0xbb, 0x69, 0xf5, 0xd4, 0x87, 0x7f, 0x84, 0x4c, 0xd2, 0x9c, 0x57, 0xa4, 0xbc, 0x4f, 0x9a, 0xdf, 0xfe, 0xd6, 0x8d, 0x7a, 0xeb, 0x2b, 0x53, 0xd8, 0x5c, 0xa1, 0x14, 0x17, 0xfb, 0x23, 0xd5, 0x7d, 0x30, 0x67, 0x73, 0x08, 0x09, 0xee, 0xb7, 0x70, 0x3f, 0x61, 0xb2, 0x19, 0x8e, 0x4e, 0xe5, 0x4b, 0x93, 0x8f, 0x5d, 0xdb, 0xa9, 0xad, 0xf1, 0xae, 0x2e, 0xcb, 0x0d, 0xfc, 0xf4, 0x2d, 0x46, 0x6e, 0x1d, 0x97, 0xe8, 0xd1, 0xe9, 0x4d, 0x37, 0xa5, 0x75, 0x5e, 0x83, 0x9e, 0xab, 0x82, 0x9d, 0xb9, 0x1c, 0xe0, 0xcd, 0x49, 0x89, 0x01, 0xb6, 0xbd, 0x58, 0x24, 0xa2, 0x5f, 0x38, 0x78, 0x99, 0x15, 0x90, 0x50, 0xb8, 0x95, 0xe4, 0xd0, 0x91, 0xc7, 0xce, 0xed, 0x0f, 0xb4, 0x6f, 0xa0, 0xcc, 0xf0, 0x02, 0x4a, 0x79, 0xc3, 0xde, 0xa3, 0xef, 0xea, 0x51, 0xe6, 0x6b, 0x18, 0xec, 0x1b, 0x2c, 0x80, 0xf7, 0x74, 0xe7, 0xff, 0x21, 0x5a, 0x6a, 0x54, 0x1e, 0x41, 0x31, 0x92, 0x35, 0xc4, 0x33, 0x07, 0x0a, 0xba, 0x7e, 0x0e, 0x34, 0x88, 0xb1, 0x98, 0x7c, 0xf3, 0x3d, 0x60, 0x6c, 0x7b, 0xca, 0xd3, 0x1f, 0x32, 0x65, 0x04, 0x28, 0x64, 0xbe, 0x85, 0x9b, 0x2f, 0x59, 0x8a, 0xd7, 0xb0, 0x25, 0xac, 0xaf, 0x12, 0x03, 0xe2, 0xf2 }; const uint32_t EK_d[16] = { 0x44D7, 0x26BC, 0x626B, 0x135E, 0x5789, 0x35E2, 0x7135, 0x09AF, 0x4D78, 0x2F13, 0x6BC4, 0x1AF1, 0x5E26, 0x3C4D, 0x789A, 0x47AC }; static uint32_t LFSR_S[16] = {0}; static uint32_t F_R[2] = {0}; static uint32_t BRC_X[4] = {0}; static int w = 0; void hex_to_bytes(char* hex, BYTE* output){ for(int i=0;hex[i]!=0;i++){ if(hex[i]<='9') output[i/2]=hex[i]-'0'; else if(hex[i]>='a') output[i/2]=hex[i]-'a'+10; else output[i/2]=hex[i]-'A'+10; i++; if(hex[i]<='9') output[i/2]=output[i/2]*16+hex[i]-'0'; else if(hex[i]>='a') output[i/2]=output[i/2]*16+hex[i]-'a'+10; else output[i/2]=output[i/2]*16+hex[i]-'A'+10; } } uint32_t AddM(uint32_t a, uint32_t b) { uint32_t c = a + b; c = (c & MASK) + (c >> 31); return c; } uint32_t ROT(uint32_t a, int k) { return (a << k) | (a >> (32 - k)); } uint32_t MulByPow2(uint32_t x, int k) { return ((x << k) | (x >> (31 - k))) & MASK; } void LFSRWithInitialisationMode(uint32_t u) { uint32_t f = 0; uint32_t v = 0; f = LFSR_S[0]; v = MulByPow2(LFSR_S[0], 8); f = AddM(f, v); v = MulByPow2(LFSR_S[4], 20); f = AddM(f, v); v = MulByPow2(LFSR_S[10], 21); f = AddM(f, v); v = MulByPow2(LFSR_S[13], 17); f = AddM(f, v); v = MulByPow2(LFSR_S[15], 15); f = AddM(f, v); f = AddM(f, u); for (int i = 0; i < 15; i++) { LFSR_S[i] = LFSR_S[i + 1]; } LFSR_S[15] = f; } void LFSRWithWorkMode() { uint32_t f = 0; uint32_t v = 0; f = LFSR_S[0]; v = MulByPow2(LFSR_S[0], 8); f = AddM(f, v); v = MulByPow2(LFSR_S[4], 20); f = AddM(f, v); v = MulByPow2(LFSR_S[10], 21); f = AddM(f, v); v = MulByPow2(LFSR_S[13], 17); f = AddM(f, v); v = MulByPow2(LFSR_S[15], 15); f = AddM(f, v); for (int i = 0; i < 15; i++) { LFSR_S[i] = LFSR_S[i + 1]; } LFSR_S[15] = f; } void BitReorganization() { BRC_X[0] = (((LFSR_S[15] & 0x7FFF8000) << 1) | (LFSR_S[14] & 0xFFFF)); BRC_X[1] = (((LFSR_S[11] & 0xFFFF) << 16) | (LFSR_S[9] >> 15)); BRC_X[2] = (((LFSR_S[7] & 0xFFFF) << 16) | (LFSR_S[5] >> 15)); BRC_X[3] = (((LFSR_S[2] & 0xFFFF) << 16) | (LFSR_S[0] >> 15)); } uint32_t L1(uint32_t x) { return x ^ ROT(x, 2) ^ ROT(x, 10) ^ ROT(x, 18) ^ ROT(x, 24); } uint32_t L2(uint32_t X) { return X ^ ROT(X, 8) ^ ROT(X, 14) ^ ROT(X, 22) ^ ROT(X, 30); } uint32_t MAKEU32(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { return ((uint32_t)a << 24) | ((uint32_t)b << 16) | ((uint32_t)c << 8) | ((uint32_t)d); } uint32_t F_func() { uint32_t W, W1, W2; uint32_t u, v; const uint32_t MASK1 = 0xFF; W = (BRC_X[0] ^ F_R[0]) + F_R[1]; W1 = F_R[0] + BRC_X[1]; W2 = F_R[1] ^ BRC_X[2]; u = L1(((W1 << 16) | (W2 >> 16))); v = L2(((W2 << 16) | (W1 >> 16))); F_R[0] = MAKEU32(S0[(u >> 24) & 0xFF], S1[(u >> 16) & MASK1], S0[(u >> 8) & MASK1], S1[u & MASK1]); F_R[1] = MAKEU32(S0[(v >> 24) & 0xFF], S1[(v >> 16) & MASK1], S0[(v >> 8) & MASK1], S1[v & MASK1]); return W; } uint32_t MAKEU31(uint8_t a, uint16_t b, uint8_t c) { return ((uint32_t)a << 23) | ((uint32_t)b << 8) | ((uint32_t)c); } void init_LFSR_key_exp(const uint8_t k[16], const uint8_t iv[16]) { for (int i = 0; i < 16; i++) { LFSR_S[i] = MAKEU31(k[i], EK_d[i], iv[i]) & MASK; } } void Initialization(const uint8_t k[16], const uint8_t iv[16]) { init_LFSR_key_exp(k, iv); F_R[0] = 0; F_R[1] = 0; int nCount = 32; while (nCount > 0) { BitReorganization(); w = F_func(); LFSRWithInitialisationMode(w >> 1); nCount--; } } uint32_t* GenerateKeystream(int KeystreamLen) { uint32_t* pKeystream = (uint32_t*)calloc(KeystreamLen, sizeof(uint32_t)); if (pKeystream == NULL) { exit(1); } BitReorganization(); F_func(); LFSRWithWorkMode(); for (int i = 0; i < KeystreamLen; i++) { BitReorganization(); pKeystream[i] = F_func() ^ BRC_X[3]; LFSRWithWorkMode(); } return pKeystream; } char* encryptZuc128(char* keyHex, char plaintext[500]){ uint8_t* key=(uint8_t*)malloc(16); uint8_t* iv=(uint8_t*)malloc(16); hex_to_bytes(keyHex, key); generateIV(iv,16); Initialization(key, iv); uint32_t* data; int length; data = string_to_uint32_array(plaintext, &length); uint32_t* keystream = GenerateKeystream(length); for(int i =0;i<length;i++) data[i] ^= keystream[i]; char* ivHex=(char*)malloc(33); bytes_to_hex(iv, 16, ivHex); char* ciphertext = (char*) malloc(length*8+33); memcpy(ciphertext, ivHex, 32); uint32_arr_to_hex(data, length, ciphertext+32); return ciphertext; } char* decryptZuc128(char* keyHex, char* ciphertext) { uint8_t* key=(uint8_t*)malloc(16); uint8_t* iv =(uint8_t*)malloc(16); char* ivHex=(char*)malloc(33); memcpy(ivHex, ciphertext, 32); ivHex[32]=0; ciphertext+=32; hex_to_bytes(ivHex, iv); hex_to_bytes(keyHex, key); Initialization(key, iv); int length=strlen(ciphertext)/8; uint32_t* data=(uint32_t*)malloc(length*4); hex_to_uint32(ciphertext, data); uint32_t* keystream = GenerateKeystream(length); for (int i = 0; i < length; i++) { data[i] ^= keystream[i]; } char* result = uint32_array_to_string(data,length); return result; }
Editor is loading...
Leave a Comment