Skip to content

Commit

Permalink
fixed message decoding i think
Browse files Browse the repository at this point in the history
  • Loading branch information
Adrian Gunnar Lauterer committed May 19, 2023
1 parent 3f65370 commit c2d362b
Show file tree
Hide file tree
Showing 10 changed files with 423 additions and 95 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"stdfloat": "cpp",
"csignal": "cpp",
"any": "cpp",
"coroutine": "cpp"
"coroutine": "cpp",
"*.ipp": "cpp"
}
}
Binary file modified bin/main
Binary file not shown.
3 changes: 2 additions & 1 deletion include/encryption.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ class Encryption {

public:
static std::string encrypt(const std::string& message, const std::string& publicKey);
static std::string decrypt(const std::string& encryptedMessage, const std::string& privateKey);
static std::string decrypt(const std::string& encryptedMessage);
static std::string getPrivateKey();
static std::string getPublicKey();
static void generateKeypair();
static std::vector<std::string> generateKeypair();
};

#endif // ENCRYPTION_HPP
23 changes: 17 additions & 6 deletions include/mesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,31 @@
#include <iostream>
#include <string>
#include <vector>
#include <list>


class Mesh {
public:

struct Node {
std::string publicKey;
std::string address;
};

std::string bindAddress(){
//return address until the first :
return address.substr(0, address.find(":"));
}

int bindPort(){
//return the port after the first :
return std::stoi(address.substr(address.find(":") + 1));
}
};

struct Edge {
Mesh::Node source;
Mesh::Node target;
};

Mesh();

Expand All @@ -29,13 +44,9 @@ class Mesh {
void printMesh();

private:
struct Edge {
Mesh::Node source;
Mesh::Node target;
};

std::vector<Mesh::Node> nodes;
std::vector<Mesh::Edge> edges;
bool dfs(const Mesh::Node& currentNode, const Mesh::Node& target, std::vector<Mesh::Node>& path, std::list<Mesh::Node>& visitedNodes);
};

#endif // MESH_HPP
22 changes: 18 additions & 4 deletions include/message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,36 @@
#define MESSAGE_HPP

#include <string>
#include "mesh.hpp"

class Message {
public:
Message(const std::string& n, const std::string& c);
Message(const std::string& s);
std::string getContent();
void setNextAddress(const std::string& n);

void setContent(const std::string& c);
std::string getNextAddress() const;
void setNextAddress(const std::string& n);

std::string getContent();

static int getNextPort(const std::string& nextAddress);
static std::string getNextAddress(const std::string& nextAddress);
std::string getNextAddress() const;
std::string getNextAddressFull() const;

void encrypt(std::string publicKey);
Message encode(std::vector<Mesh::Node> path) const;
std::string decode(std::string privateKey);


bool isDestination();
bool isEncrypted();

std::string toString() const;
void print() const;

private:
std::string nextAddress;
std::string content;
bool encrypted;
};
#endif // MESSAGE_HPP
82 changes: 49 additions & 33 deletions src/encryption.cpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,53 @@
/**
* please note that this code is not secure and should not be used for real encryption purposes.
* It's only intended for demonstration purposes, and is not secure enough to be used in production.
*/

#include "encryption.hpp"
#include <iostream>
#include <random>
#include <string>
#include <vector>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "encryption.hpp"

std::string Encryption::privateKey = "YourPrivateEncryptionKey";
std::string Encryption::publicKey = "YourPublicEncryptionKey";
std::string Encryption::privateKey;
std::string Encryption::publicKey;

std::string Encryption::encrypt(const std::string& message, const std::string& publicKey) {
std::string encryptedMessage;
for (size_t i = 0; i < message.size(); ++i) {
encryptedMessage += message[i] ^ publicKey[i % publicKey.size()];
}
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
unsigned char* ciphertext = new unsigned char[message.size() + EVP_MAX_BLOCK_LENGTH];
int ciphertextLength = 0;

EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, reinterpret_cast<const unsigned char*>(publicKey.c_str()), NULL);
EVP_EncryptUpdate(ctx, ciphertext, &ciphertextLength, reinterpret_cast<const unsigned char*>(message.c_str()), message.size());
int finalLength;
EVP_EncryptFinal_ex(ctx, ciphertext + ciphertextLength, &finalLength);
ciphertextLength += finalLength;

std::string encryptedMessage(reinterpret_cast<char*>(ciphertext), ciphertextLength);

delete[] ciphertext;
EVP_CIPHER_CTX_free(ctx);

return encryptedMessage;
}


std::string Encryption::decrypt(const std::string& encryptedMessage) {
std::string privateKey = getPrivateKey();
std::string decryptedMessage;
for (size_t i = 0; i < encryptedMessage.size(); ++i) {
decryptedMessage += encryptedMessage[i] ^ privateKey[i % privateKey.size()];
}
return decrypt(encryptedMessage, privateKey);
}

std::string Encryption::decrypt(const std::string& encryptedMessage, const std::string& privateKey) {
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
unsigned char* plaintext = new unsigned char[encryptedMessage.size() + EVP_MAX_BLOCK_LENGTH];
int plaintextLength = 0;

EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, reinterpret_cast<const unsigned char*>(privateKey.c_str()), NULL);
EVP_DecryptUpdate(ctx, plaintext, &plaintextLength, reinterpret_cast<const unsigned char*>(encryptedMessage.c_str()), encryptedMessage.size());
int finalLength;
EVP_DecryptFinal_ex(ctx, plaintext + plaintextLength, &finalLength);
plaintextLength += finalLength;

std::string decryptedMessage(reinterpret_cast<char*>(plaintext), plaintextLength);

delete[] plaintext;
EVP_CIPHER_CTX_free(ctx);

return decryptedMessage;
}

Expand All @@ -35,19 +59,11 @@ std::string Encryption::getPublicKey() {
return publicKey;
}

void Encryption::generateKeypair() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<char> distribution('A', 'Z');

privateKey = "";
publicKey = "";
for (int i = 0; i < 16; ++i) {
privateKey += distribution(gen);
publicKey += distribution(gen);
}

std::cout << "Generated Keypair:" << std::endl;
std::cout << "Private Key: " << privateKey << std::endl;
std::cout << "Public Key: " << publicKey << std::endl;
std::vector<std::string> Encryption::generateKeypair() {
unsigned char buffer[32];
RAND_bytes(buffer, sizeof(buffer));

privateKey = std::string(reinterpret_cast<char*>(buffer), sizeof(buffer));
publicKey = std::string(reinterpret_cast<char*>(buffer), sizeof(buffer));
return {privateKey, publicKey};
}
125 changes: 116 additions & 9 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,40 @@
#include "mesh.hpp"
#include "message.hpp"
#include "encryption.hpp"
#include "networking.hpp"
#include <iostream>
#include <vector>

int main() {
//encryption test

// Generate encryption key pair
std::vector<std::string> keys = Encryption::generateKeypair();

// Encrypt and decrypt a message
std::string message = "Hello, world!";
std::string encryptedMessage = Encryption::encrypt(message, keys[1]);
std::string decryptedMessage = Encryption::decrypt(encryptedMessage, keys[0]);

std::cout << "Original Message: " << message << std::endl;
std::cout << "Encrypted Message: " << encryptedMessage << std::endl;
std::cout << "Decrypted Message: " << decryptedMessage << std::endl;
std::cout << "Keypair: " << std::endl << keys[0] << ", " << std::endl << keys[1] << std::endl;


//mesh test
Mesh mesh1;
Mesh mesh2;

Mesh::Node node1 = mesh1.addNode("127.0.0.1:8080", "keyA");
Mesh::Node node2 = mesh1.addNode("127.0.0.1:8081", "keyB");
Mesh::Node node3 = mesh2.addNode("127.0.0.1:8082", "keyC");
Mesh::Node node4 = mesh2.addNode("127.0.0.1:8083", "keyD");

std::vector<std::string> keys1 = Encryption::generateKeypair();
Mesh::Node node1 = mesh1.addNode("127.0.0.1:8080", keys1[1]);//all use same public key to test and decrypt with same private key
std::vector<std::string> keys2 = Encryption::generateKeypair();
Mesh::Node node2 = mesh1.addNode("127.0.0.1:8080", keys2[1]);
std::vector<std::string> keys3 = Encryption::generateKeypair();
Mesh::Node node3 = mesh2.addNode("127.0.0.1:8080", keys3[1]);
std::vector<std::string> keys4 = Encryption::generateKeypair();
Mesh::Node node4 = mesh2.addNode("127.0.0.1:8080", keys4[1]);

mesh1.addEdge(node1, node2);
mesh2.addEdge(node3, node4);
Expand All @@ -23,19 +48,101 @@ int main() {
mesh1.mergeMesh(mesh2);

//add a edge between node2 and node3
mesh1.addEdge(node2, node3);

mesh1.addEdge(node1, node4);
mesh1.addEdge(node2, node4);

std::cout << "Merged Mesh: " << std::endl;
mesh1.printMesh();


std::vector<Mesh::Node> randomPath = mesh1.findPath(node1, node4);
std::vector<Mesh::Node> path = mesh1.findPath(node1, node4);

std::cout << "Path: ";
for (const auto& node : path) {
std::cout << node.publicKey << " -> ";
}
std::cout << std::endl;


//message test
//just create a simple message without having a send to address and print it out
Message message1("NULL", "Hello, world!");
std::cout << "Message: "<< std::endl << message1.toString() << std::endl;

std::cout << "Testing message encoding and decoding " << std::endl;

//generate a manual simulated 2 node path and encode the message for a custom path
std::vector<Mesh::Node> path2 = { node1, node2, node3};

std::cout << "Shortest Path: ";
for (const auto& node : randomPath) {
std::cout << "Path2: ";
for (const auto& node : path2) {
std::cout << node.publicKey << " -> ";
}
std::cout << std::endl;

Message message2 = message1.encode(path2);
std::cout << "Encoded Message: " << std::endl << message2.toString() << std::endl;
//decode the message
std::cout << "Decoded Message1: " << std::endl << message2.decode(keys2[0]) << std::endl;

std::cout << "Decoded Message2: " << std::endl << message2.decode(keys3[0]) << std::endl;


std::cout << "Testing path encoded message encoding and decoding " << std::endl;
std::cout << "Path: ";
for (const auto& node : path) {
std::cout << node.publicKey << " -> ";
}
std::cout << std::endl;

//now with the path generated from the mesh
Message message4("NULL", "Hello, world!");
message4 = message4.encode(path);

std::cout << "Encoded Message: " << std::endl << message4.toString() << std::endl;
//decode the message
std::vector<std::string> keysc = {};
//fill keysc with the private keys of the nodes in the path
for (const auto& node : path) {
std::string pub = node.publicKey; //works because the public key is the same as the private key in this implementation of the encryption class
if (keys1[1] == pub)
{
keysc.push_back(keys1[0]);
}
else if (keys2[1] == pub)
{
keysc.push_back(keys2[0]);
}
else if (keys3[1] == pub)
{
keysc.push_back(keys3[0]);
}
else if (keys4[1] == pub)
{
keysc.push_back(keys4[0]);
}
else
{
std::cout << "Error: public key not found" << std::endl;
}
}

for (size_t i = 0; i < path.size()-1; i++) {
std::cout << "Decoded Message: " << " node " << path[i].publicKey << " -> " << std::endl << message4.decode(keysc[i+1]) << std::endl;
}

//network test
//send a message from node1 to node1 using the networking class
Networking networking(node1.bindAddress(), node1.bindPort());
networking.startListeningThread();
std::cout << "Started Listening for messages..." << std::endl;

//encode the message but use the manual path instead of the mesh generated path as decoding with private keys only works if there is multiple nodes and we are simulating a mesh here
Message message3 = message1.encode(path2);
//send the message
networking.sendMessage(node1.bindAddress(), node1.bindPort(), message3.toString());



return 0;
}
Loading

0 comments on commit c2d362b

Please sign in to comment.