-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbit_encryption_legacy.cpp
More file actions
141 lines (119 loc) · 4.82 KB
/
bit_encryption_legacy.cpp
File metadata and controls
141 lines (119 loc) · 4.82 KB
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
// This code uses a simple XOR-based byte "encryption" and decryption mechanism.
// The encrypt function takes a vector of bytes and a vector of bytes as keys, XORs each byte with each keys (creates effective keys),
// and returns the resulting vector of encrypted bytes.
// You can generate any amount of random keys using the generateKeys function.
// The decrypt function takes the same parameters as the encrypt function, applies the same XOR-based mechanism, and returns the original bytes in a vector.
// Decrypt and encrypt functions return an empty vector on failure.
// This is just a small personal project to demonstrate basic encryption concepts.
// DO NOT USE FOR ACTUAL ENCRYPTION. AN ATTACKER THAT KNOWS WHAT THEY'RE DOING CAN EASILY CRACK THIS.
// includes
#include <vector>
#include <random>
#include <cstdint>
#include <algorithm>
class BitEncryption
{
private:
static constexpr short signatureSize = 3;
static constexpr uint8_t signature[3] = {0x3B, 0x2D, 0x29};
public:
// Encrypt using caller-provided keys, without storing any keys in the output.
std::vector<uint8_t> encrypt(const std::vector<uint8_t> &originalBytes, const std::vector<uint8_t> &keys)
{
// Basic checks
if (originalBytes.empty() || keys.empty())
{
return {};
}
// Define constants
const size_t dataSize = originalBytes.size();
const size_t keyQuantity = keys.size();
// Create effective keys
std::vector<uint8_t> effectiveKeys(dataSize, 0);
if (keyQuantity >= dataSize)
{
for (size_t k = 0; k < keyQuantity; ++k)
{
effectiveKeys[k % dataSize] ^= keys[k];
}
}
else
{
for (size_t i = 0; i < dataSize; ++i)
{
effectiveKeys[i] = keys[i % keyQuantity];
}
}
// Initialize a vector to hold the encrypted bytes (data + signature)
std::vector<uint8_t> encryptedBytes(dataSize + signatureSize);
// XOR each byte in the vector with the effective keys
for (size_t i = 0; i < dataSize; ++i)
{
encryptedBytes[i] = static_cast<uint8_t>(originalBytes[i] ^ effectiveKeys[i]);
}
// Reverse the encrypted bytes
std::reverse(encryptedBytes.begin(), encryptedBytes.begin() + dataSize);
// Add signature at the end
std::copy(signature, signature + signatureSize, encryptedBytes.end() - signatureSize);
return encryptedBytes;
}
// Decrypt bytes produced by encrypt (caller supplies the same keys).
std::vector<uint8_t> decrypt(const std::vector<uint8_t> &encryptedBytes, const std::vector<uint8_t> &keys)
{
// Basic checks
if (keys.empty() || encryptedBytes.size() < static_cast<size_t>(signatureSize + 1))
{
return {};
}
// Validate signature at the end
const size_t totalSize = encryptedBytes.size();
const size_t dataSize = totalSize - static_cast<size_t>(signatureSize);
if (!std::equal(encryptedBytes.begin() + dataSize, encryptedBytes.end(), signature))
{
return {};
}
// Extract the encrypted bytes (without signature) and reverse it back
std::vector<uint8_t> bytes(encryptedBytes.begin(), encryptedBytes.begin() + dataSize);
std::reverse(bytes.begin(), bytes.end());
// Recreate effective keys exactly as in the encrypt function
const size_t keyQuantity = keys.size();
std::vector<uint8_t> effectiveKeys(dataSize, 0);
if (keyQuantity >= dataSize)
{
for (size_t k = 0; k < keyQuantity; ++k)
{
effectiveKeys[k % dataSize] ^= keys[k];
}
}
else
{
for (size_t i = 0; i < dataSize; ++i)
{
effectiveKeys[i] = keys[i % keyQuantity];
}
}
// XOR with effective keys to recover the original bytes
std::vector<uint8_t> originalBytes(dataSize);
for (size_t i = 0; i < dataSize; ++i)
{
originalBytes[i] = static_cast<uint8_t>(bytes[i] ^ effectiveKeys[i]);
}
return originalBytes;
}
// Function to generate a set amount of random keys in range [0, 255] using std::random_device + uniform_int_distribution (unbiased).
std::vector<uint8_t> generateKeys(const size_t count)
{
// Set up the random number generator
std::random_device rd;
std::uniform_int_distribution<int> dist(0, 255);
// Generate the keys
std::vector<uint8_t> keys;
keys.reserve(count);
for (size_t i = 0; i < count; ++i)
{
keys.push_back(static_cast<uint8_t>(dist(rd)));
}
// Return the vector of generated keys
return keys;
}
};