commit 10783cc2bd152e5decf8878e8f41b32a93a8ef72 Author: Sky Johnson Date: Thu Jul 31 21:50:57 2025 -0500 first commit diff --git a/rc4.hpp b/rc4.hpp new file mode 100644 index 0000000..580e5d5 --- /dev/null +++ b/rc4.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include + +class RC4 { +public: + void init(const uint8_t* key, size_t keyLen) { + for (int k = 0; k < 256; ++k) + S[k] = static_cast(k); + + uint8_t j = 0; + for (int k = 0; k < 256; ++k) { + j += S[k] + key[k % keyLen]; + std::swap(S[k], S[j]); + } + + i = 0; + j = 0; + } + + void process(uint8_t* data, size_t len) { + for (size_t n = 0; n < len; ++n) { + i += 1; + j += S[i]; + std::swap(S[i], S[j]); + uint8_t k = S[(S[i] + S[j]) & 0xFF]; + data[n] ^= k; + } + } + +private: + uint8_t S[256]; + uint8_t i = 0; + uint8_t j = 0; +}; diff --git a/rc4_eq.hpp b/rc4_eq.hpp new file mode 100644 index 0000000..1e0d8bf --- /dev/null +++ b/rc4_eq.hpp @@ -0,0 +1,46 @@ +// +// EQ2-Compatible RC4 Implementation +// +// It differs from standard RC4 +// - Fixed 64-bit key (int64_t), treated as 8 bytes in little-endian order +// - Key scheduling cycles through the 8 key bytes using (i & 7) +// + +#pragma once + +#include +#include +#include + +class RC4 { +public: + void init(int64_t key) { + for (int i = 0; i < 256; ++i) + S[i] = static_cast(i); + + uint8_t* keyBytes = reinterpret_cast(&key); + uint8_t j = 0; + for (int i = 0; i < 256; ++i) { + j += S[i] + keyBytes[i & 7]; // cycle through 8 key bytes + std::swap(S[i], S[j]); + } + + i = 0; + j = 0; + } + + void process(uint8_t* data, size_t len) { + for (size_t n = 0; n < len; ++n) { + i += 1; + j += S[i]; + std::swap(S[i], S[j]); + uint8_t k = S[(S[i] + S[j]) & 0xFF]; + data[n] ^= k; + } + } + +private: + uint8_t S[256]; + uint8_t i = 0; + uint8_t j = 0; +};