I am trying to build a fast cryptography algorithm. The algorithm works fine, but I am worried if there are any potential flaws that might make the algorithm vulnerable to any kind of attack. Here is my code.
Encryptor.cpp
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Encryptor
{
private:
unsigned char *key; //256 byte
unsigned char key16[16]; //16 byte
public:
Encryptor(unsigned char *k)
{
key = k;
for (int i = 0; i < 256; i += 16)
{
for (int j = 0; j < 16; j++)
{
if (i < 16)
{
key16[j] = key[j];
}
else
{
key16[j] = key16[j] ^ key[i + j];
}
}
}
srand(time(0));
}
string encrypt(string txt)
{
int totalRounds = (txt.size() / 256);
if (txt.size() % 256)
totalRounds++;
string cipher(totalRounds * 16 + txt.size(), 0);
for (int i = 0; i < totalRounds; i++)
{
unsigned char randKey[16];
int txtIndex = i * 256;
int cipherIndex = i * (16 + 256);
int txtSize = (i == (totalRounds - 1)) ? txt.size() % 256 : 256;
for (int j = 0; j < 16; j++)
{
randKey[j] = random(1, 254);
cipher[cipherIndex] = key16[j] ^ randKey[j];
cipherIndex++;
}
for (int j = 0; j < txtSize; j++)
{
cipher[cipherIndex] = key[j] ^ randKey[j % 16] ^ txt[txtIndex];
cipherIndex++;
txtIndex++;
}
}
return cipher;
}
string decrypt(string cipher)
{
int totalRounds = (cipher.size() / (256 + 16));
if (cipher.size() % (256 + 16))
totalRounds++;
string txt(cipher.size() - totalRounds * 16, 0);
for (int i = 0; i < totalRounds; i++)
{
unsigned char randKey[16];
int txtIndex = i * 256;
int cipherIndex = i * (16 + 256);
int txtSize = (i == (totalRounds - 1)) ? (cipher.size() % (256 + 16)) - 16 : 256;
for (int j = 0; j < 16; j++)
{
randKey[j] = cipher[cipherIndex] ^ key16[j];
cipherIndex++;
}
for (int j = 0; j < txtSize; j++)
{
txt[txtIndex] = cipher[cipherIndex] ^ key[j] ^ randKey[j % 16];
cipherIndex++;
txtIndex++;
}
}
return txt;
}
int random(int lower, int upper)
{
return (rand() % (upper - lower + 1)) + lower;
}
};
main.cpp
#include <iostream>
#include "Encryptor.cpp"
using namespace std;
int main()
{
unsigned char key[256] = {239, 222, 80, 163, 48, 26, 182, 101, 123, 51, 145, 28, 106, 157, 105, 1, 51, 129, 222, 124, 80, 254, 118, 220, 208, 75, 225, 127, 180, 192, 125, 149, 22, 140, 218, 162, 89, 45, 237, 250, 71, 85, 245, 75, 59, 122, 146, 95, 68, 130, 33, 62, 124, 11, 203, 252, 72, 141, 140, 12, 241, 218, 89, 147, 58, 124, 209, 177, 71, 254, 201, 3, 166, 10, 179, 89, 194, 72, 150, 32, 97, 197, 119, 50, 185, 11, 202, 164, 175, 115, 239, 113, 146, 7, 84, 62, 49, 124, 25, 108, 111, 107, 250, 168, 75, 137, 87, 219, 115, 242, 237, 23, 79, 53, 95, 45, 180, 59, 243, 138, 37, 219, 174, 13, 188, 19, 62, 104, 176, 154, 183, 242, 177, 19, 215, 42, 197, 88, 149, 246, 40, 54, 184, 31, 187, 9, 115, 152, 128, 165, 116, 105, 179, 242, 145, 195, 250, 153, 139, 247, 96, 51, 225, 237, 86, 97, 97, 196, 146, 67, 73, 88, 30, 135, 192, 29, 64, 189, 123, 95, 152, 22, 31, 5, 71, 38, 136, 6, 68, 247, 93, 206, 200, 229, 243, 140, 11, 137, 60, 197, 22, 92, 118, 44, 3, 47, 121, 249, 88, 27, 101, 242, 222, 36, 112, 45, 188, 46, 170, 201, 244, 90, 115, 224, 88, 157, 109, 136, 228, 134, 186, 124, 154, 3, 78, 49, 225, 57, 249, 172, 103, 44, 74, 84, 158, 48, 139, 185, 207, 9, 58, 143, 211, 177, 62, 32};
Encryptor e(key);
for (int i = 0; i < 100; i++)
{
string c = e.encrypt("my secret");
cout << "cipher: " << c << endl;
cout << "After decryption: " << e.decrypt(c) << endl;
}
return 0;
}
Algorithm:
- user provides 256 byte key where the value of any byte can't be 0 or 255
- 16 byte internal key is generated from the user provided key
encryption:
- plain text is processed in 256-byte blocks (same as the key length) except the last one which depends on the length of the plain text.
- 16-byte random key is generated for every block where the value of each byte is between 1,254.
- for each plain text block additional 16 byte is added in the beginning of cipher text block that increases the cipher text block size to 256+16 byte
- the first 16 bytes of each cipher text block contains the XOR result of the block random key and the internal key
- the 17th byte of the cipher text = key[first byte] xor random key[first byte] xor plain text block[first byte]
- the 18th byte of the cipher text = key[second byte] xor random key[second byte] xor plain text block[second byte]
.... - when the random key reaches its last byte, as it is shorter than the block size, it repeats from the beginning.
The decryption process is reverse of the encryption process.