feat(crypto): add ARC4 implementation

This commit is contained in:
fallenoak 2023-03-23 12:48:16 -05:00 committed by GitHub
parent d7fc37cef1
commit a9bfaa02fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 127 additions and 0 deletions

View file

@ -4,6 +4,7 @@ check_cxx_compiler_flag(-Wno-invalid-offsetof HAS_NO_INVALID_OFFSETOF)
file(GLOB STORM_SOURCES
"*.cpp"
"big/*.cpp"
"crypto/*.cpp"
"hash/*.cpp"
"queue/*.cpp"
"string/*.cpp"

57
storm/Crypto.cpp Normal file
View file

@ -0,0 +1,57 @@
#include "storm/Crypto.hpp"
#include "storm/Error.hpp"
#include <cstring>
void SARC4PrepareKey(const void* data, uint32_t len, SARC4Key* key) {
STORM_ASSERT(data);
STORM_VALIDATE(data, ERROR_INVALID_PARAMETER);
key->x = 0;
key->y = 0;
// ARC4 key-scheduling algorithm
for (uint32_t i = 0; i < 256; i++) {
key->state[i] = i;
}
uint32_t j = 0;
for (uint32_t i = 0; i < 256; i++) {
j = (j + key->state[i] + static_cast<const uint8_t*>(data)[i % len]) % 256;
// Swap values
auto si = key->state[i];
auto sj = key->state[j];
key->state[i] = sj;
key->state[j] = si;
}
}
void SARC4ProcessBuffer(void* data, uint32_t len, const SARC4Key* inKey, SARC4Key* outKey) {
if (inKey != outKey) {
memcpy(outKey, inKey, sizeof(SARC4Key));
}
// Note: The original implementation uses two loops. The first loop decrypts/encrypts data
// 4-bytes-at-a-time. The second loop decrypts/encrypts all bytes outside of that alignment
// 1-byte-at-a-time. For simplicity's sake, our implementation handles 1-byte-at-a-time.
auto x = outKey->x;
auto y = outKey->y;
for (uint32_t i = 0; i < len; i++) {
x += 1;
auto sx = outKey->state[x];
y += sx;
auto sy = outKey->state[y];
outKey->state[x] = sy;
outKey->state[y] = sx;
static_cast<uint8_t*>(data)[i] ^= outKey->state[static_cast<uint8_t>(sx + sy)];
}
outKey->x = x;
outKey->y = y;
}

10
storm/Crypto.hpp Normal file
View file

@ -0,0 +1,10 @@
#ifndef STORM_CRYPTO_HPP
#define STORM_CRYPTO_HPP
#include "storm/crypto/SARC4Key.hpp"
void SARC4PrepareKey(const void* data, uint32_t len, SARC4Key* key);
void SARC4ProcessBuffer(void* data, uint32_t len, const SARC4Key* inKey, SARC4Key* outKey);
#endif

12
storm/crypto/SARC4Key.hpp Normal file
View file

@ -0,0 +1,12 @@
#ifndef STORM_CRYPTO_S_ARC4_KEY_HPP
#define STORM_CRYPTO_S_ARC4_KEY_HPP
#include <cstdint>
struct SARC4Key {
uint8_t state[256];
uint8_t x;
uint8_t y;
};
#endif