Skip to content

Commit

Permalink
#EDITS: adding redpike and rc6 bare implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
akielaries committed Feb 8, 2024
1 parent d32539b commit 398ea43
Show file tree
Hide file tree
Showing 6 changed files with 337 additions and 44 deletions.
117 changes: 117 additions & 0 deletions include/nt/rc6.hpp
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
62 changes: 48 additions & 14 deletions include/nt/redpike.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,66 @@
#include <cstdint>

namespace gpmp {

namespace nt {

/**
* Red Pike encryption algorithm.
* @class RedPike
*
* @brief Class for encryption and decryption using the RedPike algorithm
*/
class RedPike {
public:
typedef uint32_t word;
constexpr word CONST = 0x9E3779B9;
constexpr int ROUNDS = 16;
/**
* @brief Encrypts the given data using the RedPike algorithm
*
* @param x Pointer to the data to be encrypted
* @param k Pointer to the key used for encryption
*/
void encrypt(uint32_t *x, const uint32_t *k);

/**
* @brief Decrypts the given data using the RedPike algorithm
*
* @param x Pointer to the data to be decrypted
* @param k Pointer to the key used for decryption
*/
void decrypt(uint32_t *x, const uint32_t *k);

private:
/**
* Left rotate operation.
* @param X Value to rotate.
* @param R Number of bits to rotate by.
* @return Rotated value.
* @brief Constant value used in the RedPike algorithm
*/
word ROTL(word X, int R);
uint32_t CONST = 0x9E3779B9;

/**
* Right rotate operation.
* @param X Value to rotate.
* @param R Number of bits to rotate by.
* @return Rotated value.
* @brief Number of rounds in the RedPike algorithm
*/
word ROTR(word X, int R);
int ROUNDS = 16;

/**
* @brief Performs left rotation on the given value
*
* @param X Value to be rotated
* @param R Number of bits to rotate left by
*
* @return Rotated value
*/
uint32_t rotl(uint32_t X, int R);

/**
* @brief Performs right rotation on the given value
*
* @param X Value to be rotated
* @param R Number of bits to rotate right by
*
* @return Rotated value
*/
uint32_t rotr(uint32_t X, int R);
};

} // namespace nt

} // namespace gpmp

#endif
2 changes: 2 additions & 0 deletions modules/nt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ set(SOURCE_FILES
logarithms.cpp
prime_gen.cpp
prime_test.cpp
redpike.cpp
rc4.cpp
rc5.cpp
rc6.cpp
random.cpp
)

Expand Down
152 changes: 152 additions & 0 deletions modules/nt/rc6.cpp
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;
}
Loading

0 comments on commit 398ea43

Please sign in to comment.