-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#EDITS: adding redpike and rc6 bare implementation
- Loading branch information
1 parent
d32539b
commit 398ea43
Showing
6 changed files
with
337 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/************************************************************************* | ||
* | ||
* Project | ||
* _____ _____ __ __ _____ | ||
* / ____| __ \| \/ | __ \ | ||
* ___ _ __ ___ _ __ | | __| |__) | \ / | |__) | | ||
* / _ \| '_ \ / _ \ '_ \| | |_ | ___/| |\/| | ___/ | ||
*| (_) | |_) | __/ | | | |__| | | | | | | | | ||
* \___/| .__/ \___|_| |_|\_____|_| |_| |_|_| | ||
* | | | ||
* |_| | ||
* | ||
* Copyright (C) Akiel Aries, <[email protected]>, et al. | ||
* | ||
* This software is licensed as described in the file LICENSE, which | ||
* you should have received as part of this distribution. The terms | ||
* among other details are referenced in the official documentation | ||
* seen here : https://akielaries.github.io/openGPMP/ along with | ||
* important files seen in this project. | ||
* | ||
* You may opt to use, copy, modify, merge, publish, distribute | ||
* and/or sell copies of the Software, and permit persons to whom | ||
* the Software is furnished to do so, under the terms of the | ||
* LICENSE file. As this is an Open Source effort, all implementations | ||
* must be of the same methodology. | ||
* | ||
* | ||
* | ||
* This software is distributed on an AS IS basis, WITHOUT | ||
* WARRANTY OF ANY KIND, either express or implied. | ||
* | ||
************************************************************************/ | ||
|
||
#ifndef RC6_HPP | ||
#define RC6_HPP | ||
|
||
#include <cstdint> | ||
#include <vector> | ||
|
||
/** | ||
* @class RC6 | ||
* @brief Class implementing the RC6 cipher algorithm | ||
*/ | ||
class RC6 { | ||
public: | ||
/** | ||
* @brief Constructor for RC6 class | ||
* @param key The encryption key | ||
*/ | ||
RC6(const std::vector<uint8_t> &key); | ||
|
||
/** | ||
* @brief Encrypts plaintext using RC6 algorithm | ||
* @param plaintext The plaintext to encrypt | ||
* @return The encrypted ciphertext | ||
*/ | ||
std::vector<uint8_t> encrypt(const std::vector<uint8_t> &plaintext); | ||
|
||
/** | ||
* @brief Decrypts ciphertext using RC6 algorithm | ||
* @param ciphertext The ciphertext to decrypt | ||
* @return The decrypted plaintext | ||
*/ | ||
std::vector<uint8_t> decrypt(const std::vector<uint8_t> &ciphertext); | ||
|
||
private: | ||
const int w = 32; /**< Word size */ | ||
const int r = 20; /**< Number of rounds */ | ||
const int b = 16; /**< Number of bytes in key */ | ||
|
||
std::vector<uint32_t> S; /**< Internal state array */ | ||
|
||
/** | ||
* @brief Generates the key schedule from the given key | ||
* @param key The encryption key | ||
*/ | ||
void key_schedule(const std::vector<uint8_t> &key); | ||
|
||
/** | ||
* @brief Performs key expansion | ||
* @param key The encryption key | ||
* @return The expanded key schedule | ||
*/ | ||
std::vector<uint32_t> expand(const std::vector<uint8_t> &key); | ||
|
||
/** | ||
* @brief Performs left rotation | ||
* @param val The value to rotate | ||
* @param shift The number of bits to rotate by | ||
* @return The rotated value | ||
*/ | ||
uint32_t rotl(uint32_t val, int shift); | ||
|
||
/** | ||
* @brief Performs right rotation | ||
* @param val The value to rotate | ||
* @param shift The number of bits to rotate by | ||
* @return The rotated value | ||
*/ | ||
uint32_t rotr(uint32_t val, int shift); | ||
|
||
/** | ||
* @brief Encrypts a single block of plaintext | ||
* @param plaintext The plaintext block to encrypt | ||
* @param ciphertext The resulting ciphertext block | ||
*/ | ||
void encrypt_block(const uint32_t plaintext[2], uint32_t ciphertext[2]); | ||
|
||
/** | ||
* @brief Decrypts a single block of ciphertext | ||
* @param ciphertext The ciphertext block to decrypt | ||
* @param plaintext The resulting plaintext block | ||
*/ | ||
void decrypt_block(const uint32_t ciphertext[2], uint32_t plaintext[2]); | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
/************************************************************************* | ||
* | ||
* Project | ||
* _____ _____ __ __ _____ | ||
* / ____| __ \| \/ | __ \ | ||
* ___ _ __ ___ _ __ | | __| |__) | \ / | |__) | | ||
* / _ \| '_ \ / _ \ '_ \| | |_ | ___/| |\/| | ___/ | ||
*| (_) | |_) | __/ | | | |__| | | | | | | | | ||
* \___/| .__/ \___|_| |_|\_____|_| |_| |_|_| | ||
* | | | ||
* |_| | ||
* | ||
* Copyright (C) Akiel Aries, <[email protected]>, et al. | ||
* | ||
* This software is licensed as described in the file LICENSE, which | ||
* you should have received as part of this distribution. The terms | ||
* among other details are referenced in the official documentation | ||
* seen here : https://akielaries.github.io/openGPMP/ along with | ||
* important files seen in this project. | ||
* | ||
* You may opt to use, copy, modify, merge, publish, distribute | ||
* and/or sell copies of the Software, and permit persons to whom | ||
* the Software is furnished to do so, under the terms of the | ||
* LICENSE file. As this is an Open Source effort, all implementations | ||
* must be of the same methodology. | ||
* | ||
* | ||
* | ||
* This software is distributed on an AS IS basis, WITHOUT | ||
* WARRANTY OF ANY KIND, either express or implied. | ||
* | ||
************************************************************************/ | ||
|
||
#include "../../include/nt/rc6.hpp" | ||
#include <cmath> | ||
#include <cstdint> | ||
|
||
#include <stdexcept> | ||
|
||
RC6::RC6(const std::vector<uint8_t> &key) { | ||
key_schedule(key); | ||
} | ||
|
||
void RC6::key_schedule(const std::vector<uint8_t> &key) { | ||
std::vector<uint32_t> L = expand(key); | ||
S.resize(2 * (r + 1)); | ||
const uint32_t P = 0xB7E15163; | ||
const uint32_t Q = 0x9E3779B9; | ||
S[0] = P; | ||
for (int i = 1; i < 2 * (r + 1); ++i) { | ||
S[i] = S[i - 1] + Q; | ||
} | ||
uint32_t A = 0, B = 0; | ||
int i = 0, j = 0; | ||
for (int k = 0; k < 3 * std::max(b, 2 * (r + 1)); ++k) { | ||
A = S[i] = rotl((S[i] + A + B), 3); | ||
B = L[j] = rotl((L[j] + A + B), (A + B)); | ||
i = (i + 1) % (2 * (r + 1)); | ||
j = (j + 1) % b; | ||
} | ||
} | ||
|
||
std::vector<uint32_t> RC6::expand(const std::vector<uint8_t> &key) { | ||
std::vector<uint32_t> L(b / 4); | ||
for (size_t i = 0; i < key.size(); i++) { | ||
L[i / 4] |= (static_cast<uint32_t>(key[i]) << (8 * (i % 4))); | ||
} | ||
return L; | ||
} | ||
|
||
uint32_t RC6::rotl(uint32_t val, int shift) { | ||
return (val << shift) | (val >> (w - shift)); | ||
} | ||
|
||
uint32_t RC6::rotr(uint32_t val, int shift) { | ||
return (val >> shift) | (val << (w - shift)); | ||
} | ||
|
||
void RC6::encrypt_block(const uint32_t plaintext[2], uint32_t ciphertext[2]) { | ||
uint32_t A = plaintext[0], B = plaintext[1]; | ||
A += S[0]; | ||
B += S[1]; | ||
for (int i = 1; i <= r; ++i) { | ||
A = rotl(A ^ B, B) + S[2 * i]; | ||
B = rotl(B ^ A, A) + S[2 * i + 1]; | ||
} | ||
ciphertext[0] = A; | ||
ciphertext[1] = B; | ||
} | ||
|
||
void RC6::decrypt_block(const uint32_t ciphertext[2], uint32_t plaintext[2]) { | ||
uint32_t A = ciphertext[0], B = ciphertext[1]; | ||
for (int i = r; i >= 1; --i) { | ||
B = rotr(B - S[2 * i + 1], A) ^ A; | ||
A = rotr(A - S[2 * i], B) ^ B; | ||
} | ||
B -= S[1]; | ||
A -= S[0]; | ||
plaintext[0] = A; | ||
plaintext[1] = B; | ||
} | ||
|
||
std::vector<uint8_t> RC6::encrypt(const std::vector<uint8_t> &plaintext) { | ||
if (plaintext.size() % 8 != 0) { | ||
throw std::invalid_argument( | ||
"Plaintext length must be a multiple of 8 bytes"); | ||
} | ||
std::vector<uint8_t> ciphertext; | ||
ciphertext.reserve(plaintext.size()); | ||
for (size_t i = 0; i < plaintext.size(); i += 8) { | ||
uint32_t block[2]; | ||
uint32_t encrypted_block[2]; | ||
for (int j = 0; j < 8; ++j) { | ||
block[j / 4] |= | ||
(static_cast<uint32_t>(plaintext[i + j]) << (8 * (j % 4))); | ||
} | ||
encrypt_block(block, encrypted_block); | ||
for (int j = 0; j < 2; ++j) { | ||
ciphertext.push_back((encrypted_block[j] >> 24) & 0xFF); | ||
ciphertext.push_back((encrypted_block[j] >> 16) & 0xFF); | ||
ciphertext.push_back((encrypted_block[j] >> 8) & 0xFF); | ||
ciphertext.push_back(encrypted_block[j] & 0xFF); | ||
} | ||
} | ||
return ciphertext; | ||
} | ||
|
||
std::vector<uint8_t> RC6::decrypt(const std::vector<uint8_t> &ciphertext) { | ||
if (ciphertext.size() % 8 != 0) { | ||
throw std::invalid_argument( | ||
"Ciphertext length must be a multiple of 8 bytes"); | ||
} | ||
std::vector<uint8_t> plaintext; | ||
plaintext.reserve(ciphertext.size()); | ||
for (size_t i = 0; i < ciphertext.size(); i += 8) { | ||
uint32_t block[2]; | ||
uint32_t decrypted_block[2]; | ||
for (int j = 0; j < 2; ++j) { | ||
block[j] = | ||
(static_cast<uint32_t>(ciphertext[i + 4 * j]) << 24) | | ||
(static_cast<uint32_t>(ciphertext[i + 4 * j + 1]) << 16) | | ||
(static_cast<uint32_t>(ciphertext[i + 4 * j + 2]) << 8) | | ||
static_cast<uint32_t>(ciphertext[i + 4 * j + 3]); | ||
} | ||
decrypt_block(block, decrypted_block); | ||
for (int j = 0; j < 8; ++j) { | ||
plaintext.push_back((decrypted_block[j / 4] >> (8 * (j % 4))) & | ||
0xFF); | ||
} | ||
} | ||
return plaintext; | ||
} |
Oops, something went wrong.