This commit is contained in:
klein panic
2025-02-01 16:14:45 -05:00
commit 3aff0baacf
82 changed files with 1694 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
# AES Encryption Algorithm
## Description
This project implements a basic version of the AES-128 encryption algorithm, with simplified transformations for SubBytes, ShiftRows, MixColumns, and AddRoundKey.
## How to Build
1. Navigate to the `build` directory.
2. Run `make` to compile the project.
## How to Run
1. After building, run the `aes` executable using `./aes`.
## How to Clean
- Run `make clean` to remove all compiled files.

View File

@@ -0,0 +1,28 @@
# Variables
CC = gcc
CFLAGS = -I../include -Wall -Wextra
OBJDIR = ../obj
SRCDIR = ../src
BINDIR = ../build
# Source files
SOURCES = $(SRCDIR)/main.c $(SRCDIR)/aes.c
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/aes.o
# Build target
TARGET = aes
# Rules
all: $(BINDIR)/$(TARGET)
$(BINDIR)/$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -o $(BINDIR)/$(TARGET)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
.PHONY: all clean

Binary file not shown.

View File

@@ -0,0 +1,9 @@
#ifndef AES_H
#define AES_H
#include <stdint.h>
void aes_encrypt(uint8_t *message, uint8_t *key);
void aes_decrypt(uint8_t *message, uint8_t *key);
#endif // AES_H

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,210 @@
#include "aes.h"
#include <stdint.h>
#include <string.h>
// Real AES S-box
static const uint8_t sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
// Real AES inverse S-box
static const uint8_t inv_sbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
// Add round key step
static void add_round_key(uint8_t *state, uint8_t *round_key) {
for (int i = 0; i < 16; i++) {
state[i] ^= round_key[i];
}
}
// Substitute bytes using the S-box
static void sub_bytes(uint8_t *state) {
for (int i = 0; i < 16; i++) {
state[i] = sbox[state[i]];
}
}
// Inverse substitute bytes using the inverse S-box
static void inv_sub_bytes(uint8_t *state) {
for (int i = 0; i < 16; i++) {
state[i] = inv_sbox[state[i]];
}
}
// Shift rows step (left shift each row by its row number)
static void shift_rows(uint8_t *state) {
uint8_t temp;
// Row 1 shift (1-byte left)
temp = state[1];
state[1] = state[5];
state[5] = state[9];
state[9] = state[13];
state[13] = temp;
// Row 2 shift (2-byte left)
temp = state[2];
state[2] = state[10];
state[10] = temp;
temp = state[6];
state[6] = state[14];
state[14] = temp;
// Row 3 shift (3-byte left)
temp = state[3];
state[3] = state[15];
state[15] = state[11];
state[11] = state[7];
state[7] = temp;
}
// Inverse ShiftRows step (right shift each row by its row number)
static void inv_shift_rows(uint8_t *state) {
uint8_t temp;
// Row 1 shift (1-byte right)
temp = state[13];
state[13] = state[9];
state[9] = state[5];
state[5] = state[1];
state[1] = temp;
// Row 2 shift (2-byte right)
temp = state[2];
state[2] = state[10];
state[10] = temp;
temp = state[6];
state[6] = state[14];
state[14] = temp;
// Row 3 shift (3-byte right)
temp = state[3];
state[3] = state[7];
state[7] = state[11];
state[11] = state[15];
state[15] = temp;
}
// Galois field multiplication for MixColumns
static uint8_t gmul(uint8_t a, uint8_t b) {
uint8_t p = 0;
while (b) {
if (b & 1) p ^= a;
if (a & 0x80) a = (a << 1) ^ 0x1b;
else a <<= 1;
b >>= 1;
}
return p;
}
// MixColumns step
static void mix_columns(uint8_t *state) {
for (int i = 0; i < 4; i++) {
uint8_t a = state[i * 4 + 0];
uint8_t b = state[i * 4 + 1];
uint8_t c = state[i * 4 + 2];
uint8_t d = state[i * 4 + 3];
state[i * 4 + 0] = gmul(a, 0x02) ^ gmul(b, 0x03) ^ c ^ d;
state[i * 4 + 1] = a ^ gmul(b, 0x02) ^ gmul(c, 0x03) ^ d;
state[i * 4 + 2] = a ^ b ^ gmul(c, 0x02) ^ gmul(d, 0x03);
state[i * 4 + 3] = gmul(a, 0x03) ^ b ^ c ^ gmul(d, 0x02);
}
}
// Inverse MixColumns step
static void inv_mix_columns(uint8_t *state) {
for (int i = 0; i < 4; i++) {
uint8_t a = state[i * 4 + 0];
uint8_t b = state[i * 4 + 1];
uint8_t c = state[i * 4 + 2];
uint8_t d = state[i * 4 + 3];
state[i * 4 + 0] = gmul(a, 0x0e) ^ gmul(b, 0x0b) ^ gmul(c, 0x0d) ^ gmul(d, 0x09);
state[i * 4 + 1] = gmul(a, 0x09) ^ gmul(b, 0x0e) ^ gmul(c, 0x0b) ^ gmul(d, 0x0d);
state[i * 4 + 2] = gmul(a, 0x0d) ^ gmul(b, 0x09) ^ gmul(c, 0x0e) ^ gmul(d, 0x0b);
state[i * 4 + 3] = gmul(a, 0x0b) ^ gmul(b, 0x0d) ^ gmul(c, 0x09) ^ gmul(d, 0x0e);
}
}
// Perform AES encryption
void aes_encrypt(uint8_t *message, uint8_t *key) {
uint8_t state[16];
memcpy(state, message, 16);
// Perform the initial round key addition
add_round_key(state, key);
// Perform 9 rounds of AES transformations
for (int round = 0; round < 9; round++) {
sub_bytes(state);
shift_rows(state);
mix_columns(state);
add_round_key(state, key); // Using the same key as a placeholder
}
// Final round (no MixColumns)
sub_bytes(state);
shift_rows(state);
add_round_key(state, key);
// Copy the result back into the message
memcpy(message, state, 16);
}
// Perform AES decryption (inverse operations)
void aes_decrypt(uint8_t *message, uint8_t *key) {
uint8_t state[16];
memcpy(state, message, 16);
// Initial round key addition (same as the last round of encryption)
add_round_key(state, key);
// Perform 9 rounds of inverse AES transformations
for (int round = 0; round < 9; round++) {
inv_shift_rows(state);
inv_sub_bytes(state);
add_round_key(state, key); // Using the same key as a placeholder
inv_mix_columns(state);
}
// Final round (no InvMixColumns)
inv_shift_rows(state);
inv_sub_bytes(state);
add_round_key(state, key);
// Copy the result back into the message
memcpy(message, state, 16);
}

View File

@@ -0,0 +1,31 @@
#include "aes.h"
#include <stdio.h>
#include <stdint.h>
int main() {
// Example 128-bit key and plaintext (16 bytes each)
uint8_t message[16] = {0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d,
0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34};
uint8_t key[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
printf("Original message: ");
for (int i = 0; i < 16; i++) printf("%02x ", message[i]);
printf("\n");
// Encrypt the message
aes_encrypt(message, key);
printf("Encrypted message: ");
for (int i = 0; i < 16; i++) printf("%02x ", message[i]);
printf("\n");
// Decrypt the message
aes_decrypt(message, key);
printf("Decrypted message: ");
for (int i = 0; i < 16; i++) printf("%02x ", message[i]);
printf("\n");
return 0;
}

21
Base64_Encoding/README.md Normal file
View File

@@ -0,0 +1,21 @@
# Base64 Encoder
## Description
This project implements a Base64 encoder and decoder for educational purposes. Base64 encoding converts binary data to text, using a set of 64 printable characters.
## Directory Structure
- `include/`: Contains the header files.
- `src/`: Contains the source code files (`main.c` and `base64_encoder.c`).
- `obj/`: Contains the compiled object files.
- `build/`: Contains the Makefile and the compiled binary.
## How to Build
1. Navigate to the `build` directory.
2. Run `make` to compile the project.
## How to Run
1. After building, you will find an executable named `base64_encoder` in the `build` directory.
2. Run it using `./base64_encoder`.
## How to Clean
- Run `make clean` in the `build` directory to remove all compiled files.

View File

@@ -0,0 +1,28 @@
# Variables
CC = gcc
CFLAGS = -I../include -Wall -Wextra
OBJDIR = ../obj
SRCDIR = ../src
BINDIR = ../build
# Source files
SOURCES = $(SRCDIR)/main.c $(SRCDIR)/base64_encoder.c
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/base64_encoder.o
# Build target
TARGET = base64_encoder
# Rules
all: $(BINDIR)/$(TARGET)
$(BINDIR)/$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -o $(BINDIR)/$(TARGET)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
.PHONY: all clean

Binary file not shown.

View File

@@ -0,0 +1,9 @@
#ifndef BASE64_ENCODER_H
#define BASE64_ENCODER_H
#include <stddef.h> // Include this to define size_t
char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length);
unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length);
#endif // BASE64_ENCODER_H

Binary file not shown.

BIN
Base64_Encoding/obj/main.o Normal file

Binary file not shown.

View File

@@ -0,0 +1,96 @@
#include "base64_encoder.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static int base64_char_value(char c) {
if (c >= 'A' && c <= 'Z') return c - 'A';
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
if (c >= '0' && c <= '9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
return -1; // Should never happen for valid Base64 strings
}
char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length) {
*output_length = 4 * ((input_length + 2) / 3);
char *encoded_data = (char *)malloc(*output_length + 1);
if (encoded_data == NULL) return NULL;
for (size_t i = 0, j = 0; i < input_length;) {
uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;
uint32_t triple = (octet_a << 16) | (octet_b << 8) | octet_c;
encoded_data[j++] = base64_chars[(triple >> 18) & 0x3F];
encoded_data[j++] = base64_chars[(triple >> 12) & 0x3F];
encoded_data[j++] = base64_chars[(triple >> 6) & 0x3F];
encoded_data[j++] = base64_chars[triple & 0x3F];
}
for (size_t i = 0; i < ((3 - (input_length % 3)) % 3); i++) {
encoded_data[*output_length - 1 - i] = '=';
}
encoded_data[*output_length] = '\0';
return encoded_data;
}
unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length) {
if (input_length % 4 != 0) {
printf("Error: Input length is not a multiple of 4.\n");
return NULL;
}
// Calculate output length, ignoring padding characters '='
*output_length = (input_length / 4) * 3;
if (data[input_length - 1] == '=') (*output_length)--;
if (data[input_length - 2] == '=') (*output_length)--;
unsigned char *decoded_data = (unsigned char *)malloc(*output_length);
if (decoded_data == NULL) {
printf("Error: Memory allocation failed.\n");
return NULL;
}
size_t i = 0, j = 0;
while (i < input_length) {
if (data[i] == '=') {
break; // Stop if we hit padding
}
// Read four Base64 characters and map them to their 6-bit values
int sextet_a = base64_char_value(data[i++]);
int sextet_b = base64_char_value(data[i++]);
int sextet_c = (i < input_length && data[i] != '=') ? base64_char_value(data[i++]) : 0;
int sextet_d = (i < input_length && data[i] != '=') ? base64_char_value(data[i++]) : 0;
if (sextet_a == -1 || sextet_b == -1 || sextet_c == -1 || sextet_d == -1) {
printf("Error: Invalid Base64 character detected.\n");
free(decoded_data);
return NULL;
}
// Combine the four 6-bit sextets into three bytes
uint32_t triple = (sextet_a << 18) | (sextet_b << 12) | (sextet_c << 6) | sextet_d;
if (j < *output_length) decoded_data[j++] = (triple >> 16) & 0xFF;
if (j < *output_length) decoded_data[j++] = (triple >> 8) & 0xFF;
if (j < *output_length) decoded_data[j++] = triple & 0xFF;
// Break once we have decoded the expected number of bytes
if (j >= *output_length) {
break;
}
}
return decoded_data;
}

View File

@@ -0,0 +1,39 @@
#include "base64_encoder.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h> // Include this for memory management functions like free
int main() {
char message[256];
size_t output_length;
printf("Enter a message to encode: ");
fgets(message, sizeof(message), stdin);
message[strcspn(message, "\n")] = '\0'; // Remove newline character
// Encode the message
char *encoded = base64_encode((unsigned char *)message, strlen(message), &output_length);
if (encoded == NULL) {
printf("Failed to encode the message.\n");
return 1;
}
printf("Encoded message: %s\n", encoded);
// Decode the message
size_t decoded_length;
unsigned char *decoded = base64_decode(encoded, output_length, &decoded_length);
if (decoded == NULL) {
printf("Failed to decode the message.\n");
free(encoded);
return 1;
}
printf("Decoded message: %.*s\n", (int)decoded_length, decoded);
// Clean up
free(encoded);
free(decoded);
return 0;
}

22
Caesar_Cipher/README.md Normal file
View File

@@ -0,0 +1,22 @@
# Caesar Cipher
## Description
This project implements a simple Caesar cipher to demonstrate basic encryption and decryption using a fixed shift value.
## Directory Structure
- `include/`: Contains the header files.
- `src/`: Contains the source code files (`main.c` and `caesar_cipher.c`).
- `obj/`: Contains the compiled object files.
- `build/`: Contains the Makefile and the compiled binary.
## How to Build
1. Navigate to the `build` directory.
2. Run `make` to compile the project.
## How to Run
1. After building, you will find an executable named `caesar_cipher` in the `build` directory.
2. Run it using `./caesar_cipher`.
## How to Clean
- Run `make clean` in the `build` directory to remove all compiled files.

View File

@@ -0,0 +1,27 @@
# Variables
CC = gcc
CFLAGS = -I../include -Wall -Wextra
OBJDIR = ../obj
SRCDIR = ../src
BINDIR = ../build
# Source files
SOURCES = $(SRCDIR)/main.c $(SRCDIR)/caesar_cipher.c
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/caesar_cipher.o
# Build target
TARGET = caesar_cipher
# Rules
all: $(BINDIR)/$(TARGET)
$(BINDIR)/$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -o $(BINDIR)/$(TARGET)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
.PHONY: all clean

BIN
Caesar_Cipher/build/caesar_cipher Executable file

Binary file not shown.

View File

@@ -0,0 +1,8 @@
#ifndef CAESAR_CIPHER_H
#define CAESAR_CIPHER_H
void encrypt(char *plaintext, int shift);
void decrypt(char *ciphertext, int shift);
#endif // CAESAR_CIPHER_H

Binary file not shown.

BIN
Caesar_Cipher/obj/main.o Normal file

Binary file not shown.

View File

@@ -0,0 +1,21 @@
#include "caesar_cipher.h"
#include <stdio.h>
#include <ctype.h>
void encrypt(char *plaintext, int shift) {
for (int i = 0; plaintext[i] != '\0'; i++) {
if (isalpha(plaintext[i])) {
char base = islower(plaintext[i]) ? 'a' : 'A';
plaintext[i] = (plaintext[i] - base + shift) % 26 + base;
}
}
}
void decrypt(char *ciphertext, int shift) {
for (int i = 0; ciphertext[i] != '\0'; i++) {
if (isalpha(ciphertext[i])) {
char base = islower(ciphertext[i]) ? 'a' : 'A';
ciphertext[i] = (ciphertext[i] - base - shift + 26) % 26 + base;
}
}
}

24
Caesar_Cipher/src/main.c Normal file
View File

@@ -0,0 +1,24 @@
#include "caesar_cipher.h"
#include <stdio.h>
int main() {
char message[256];
int shift;
printf("Enter a message to encrypt: ");
fgets(message, sizeof(message), stdin);
printf("Enter shift amount (1-25): ");
scanf("%d", &shift);
// Encrypt the message
encrypt(message, shift);
printf("Encrypted message: %s\n", message);
// Decrypt the message
decrypt(message, shift);
printf("Decrypted message: %s\n", message);
return 0;
}

View File

@@ -0,0 +1,16 @@
# DES Encryption Algorithm
## Description
This project implements a simplified version of the DES encryption algorithm, with encryption and decryption using a symmetric key.
## How to Build
1. Navigate to the `build` directory.
2. Run `make` to compile the project.
## How to Run
1. After building, run the `des` executable using `./des`.
2. You will be prompted to enter a message and a key, both as integers (64-bit).
## How to Clean
- Run `make clean` to remove all compiled files.

View File

@@ -0,0 +1,28 @@
# Variables
CC = gcc
CFLAGS = -I../include -Wall -Wextra
OBJDIR = ../obj
SRCDIR = ../src
BINDIR = ../build
# Source files
SOURCES = $(SRCDIR)/main.c $(SRCDIR)/des.c
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/des.o
# Build target
TARGET = des
# Rules
all: $(BINDIR)/$(TARGET)
$(BINDIR)/$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -o $(BINDIR)/$(TARGET)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
.PHONY: all clean

Binary file not shown.

View File

@@ -0,0 +1,7 @@
#ifndef DES_H
#define DES_H
void des_encrypt(unsigned long long *message, unsigned long long key);
void des_decrypt(unsigned long long *message, unsigned long long key);
#endif // DES_H

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,76 @@
#include "des.h"
#include <stdio.h>
#include <stdint.h>
// A simplified placeholder for the Initial Permutation
static uint64_t initial_permutation(uint64_t message) {
// Apply an initial permutation (just a placeholder for now)
return message; // In a real implementation, this would rearrange the bits
}
// A simplified placeholder for the Final Permutation
static uint64_t final_permutation(uint64_t message) {
// Apply the final permutation (just a placeholder for now)
return message; // In a real implementation, this would rearrange the bits
}
// A simplified placeholder for the Feistel function used in DES rounds
static uint32_t feistel_function(uint32_t half_block, uint64_t subkey) {
// Apply an expansion, substitution, and permutation (placeholder)
return half_block ^ (uint32_t)(subkey); // Simplified XOR with the key
}
// A simplified function to split the message into left and right halves
static void split_message(uint64_t message, uint32_t *left, uint32_t *right) {
*left = (uint32_t)(message >> 32);
*right = (uint32_t)(message & 0xFFFFFFFF);
}
// A simplified function to merge left and right halves into one message
static uint64_t merge_message(uint32_t left, uint32_t right) {
return ((uint64_t)left << 32) | (uint64_t)right;
}
// The main DES encryption function
void des_encrypt(unsigned long long *message, unsigned long long key) {
// Apply the initial permutation
*message = initial_permutation(*message);
uint32_t left, right;
split_message(*message, &left, &right);
// Perform 16 rounds of the Feistel function (simplified for now)
for (int i = 0; i < 16; i++) {
uint32_t temp = right;
right = left ^ feistel_function(right, key); // Simplified function
left = temp;
}
// Merge the halves back together
*message = merge_message(left, right);
// Apply the final permutation
*message = final_permutation(*message);
}
// The main DES decryption function (similar to encryption, but reverse)
void des_decrypt(unsigned long long *message, unsigned long long key) {
// Apply the initial permutation
*message = initial_permutation(*message);
uint32_t left, right;
split_message(*message, &left, &right);
// Perform 16 rounds of the Feistel function (reversed for decryption)
for (int i = 0; i < 16; i++) {
uint32_t temp = left;
left = right ^ feistel_function(left, key); // Simplified function
right = temp;
}
// Merge the halves back together
*message = merge_message(left, right);
// Apply the final permutation
*message = final_permutation(*message);
}

View File

@@ -0,0 +1,25 @@
#include "des.h"
#include <stdio.h>
int main() {
unsigned long long message;
unsigned long long key;
// Ask for a message and key (both as integers for simplicity)
printf("Enter a message to encrypt (as a 64-bit integer): ");
scanf("%llu", &message);
printf("Enter a key (as a 64-bit integer): ");
scanf("%llu", &key);
// Encrypt the message
des_encrypt(&message, key);
printf("Encrypted message: %llu\n", message);
// Decrypt the message
des_decrypt(&message, key);
printf("Decrypted message: %llu\n", message);
return 0;
}

View File

@@ -0,0 +1,14 @@
# Diffie-Hellman Key Exchange
## Description
This project implements a basic version of the Diffie-Hellman key exchange algorithm, allowing two parties (Alice and Bob) to agree on a shared secret over an insecure channel.
## How to Build
1. Navigate to the `build` directory.
2. Run `make` to compile the project.
## How to Run
1. After building, run the `diffie_hellman` executable using `./diffie_hellman`.
## How to Clean
- Run `make clean` to remove all compiled files.

View File

@@ -0,0 +1,27 @@
# Variables
CC = gcc
CFLAGS = -I../include -Wall -Wextra
OBJDIR = ../obj
SRCDIR = ../src
BINDIR = ../build
# Source files
SOURCES = $(SRCDIR)/main.c $(SRCDIR)/diffie_hellman.c
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/diffie_hellman.o
# Build target
TARGET = diffie_hellman
# Rules
all: $(BINDIR)/$(TARGET)
$(BINDIR)/$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -o $(BINDIR)/$(TARGET)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
.PHONY: all clean

Binary file not shown.

View File

@@ -0,0 +1,7 @@
#ifndef DIFFIE_HELLMAN_H
#define DIFFIE_HELLMAN_H
unsigned long long generate_public_key(unsigned long long base, unsigned long long private_key, unsigned long long prime);
unsigned long long generate_shared_secret(unsigned long long received_public_key, unsigned long long private_key, unsigned long long prime);
#endif // DIFFIE_HELLMAN_H

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,21 @@
#include "diffie_hellman.h"
#include <stdio.h>
#include <math.h>
// Generate the public key: A = g^a mod p
unsigned long long generate_public_key(unsigned long long base, unsigned long long private_key, unsigned long long prime) {
unsigned long long result = 1;
for (unsigned long long i = 0; i < private_key; i++) {
result = (result * base) % prime;
}
return result;
}
// Generate the shared secret: s = B^a mod p
unsigned long long generate_shared_secret(unsigned long long received_public_key, unsigned long long private_key, unsigned long long prime) {
unsigned long long result = 1;
for (unsigned long long i = 0; i < private_key; i++) {
result = (result * received_public_key) % prime;
}
return result;
}

View File

@@ -0,0 +1,42 @@
#include "diffie_hellman.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
// Publicly agreed upon base (g) and prime (p)
unsigned long long base = 5;
unsigned long long prime = 23;
// Private keys chosen by Alice and Bob (should be random in practice)
unsigned long long alice_private_key, bob_private_key;
srand(time(NULL));
alice_private_key = rand() % (prime - 1) + 1; // Random private key for Alice
bob_private_key = rand() % (prime - 1) + 1; // Random private key for Bob
printf("Alice's private key: %llu\n", alice_private_key);
printf("Bob's private key: %llu\n", bob_private_key);
// Generate public keys
unsigned long long alice_public_key = generate_public_key(base, alice_private_key, prime);
unsigned long long bob_public_key = generate_public_key(base, bob_private_key, prime);
printf("Alice's public key: %llu\n", alice_public_key);
printf("Bob's public key: %llu\n", bob_public_key);
// Exchange public keys and generate shared secrets
unsigned long long alice_shared_secret = generate_shared_secret(bob_public_key, alice_private_key, prime);
unsigned long long bob_shared_secret = generate_shared_secret(alice_public_key, bob_private_key, prime);
printf("Alice's shared secret: %llu\n", alice_shared_secret);
printf("Bob's shared secret: %llu\n", bob_shared_secret);
// Verify if shared secrets match
if (alice_shared_secret == bob_shared_secret) {
printf("Key exchange successful! Shared secret: %llu\n", alice_shared_secret);
} else {
printf("Key exchange failed.\n");
}
return 0;
}

View File

@@ -0,0 +1,78 @@
# Elliptic Curve Cryptography (ECC) Project
## Introduction
This project implements a basic Elliptic Curve Cryptography (ECC) system in C. ECC is a type of public key encryption based on the mathematics of elliptic curves, which provides the same level of security as other public key cryptosystems (like RSA) but with smaller key sizes.
## How It Works
Elliptic curves are defined by equations of the form:
y² = x³ + ax + b (mod p)
vbnet
Where:
- `a` and `b` are constants defining the curve.
- `p` is the prime modulus.
- Points on the curve follow specific rules for addition and scalar multiplication.
### Encryption and Decryption Steps:
1. **Key Generation**:
- The private key is a random number.
- The public key is computed as a point on the elliptic curve by multiplying the private key with a generator point.
2. **Encryption**:
- A random number `k` is generated.
- Two values are computed: `C1 = kG` (a point on the curve) and `C2 = plaintext XOR kP.x` (where `P` is the recipient's public key).
3. **Decryption**:
- The recipient computes the shared secret `dC1`, where `d` is their private key.
- The plaintext is recovered by XOR'ing `C2` with the shared secret's x-coordinate.
## Expected Output
Here is an example of the output:
Private Key: 3 Public Key: (38, 59) Plaintext: 42 Ciphertext: (C1: 1, 59), C2: 59 Decrypted: 42
markdown
The **decrypted message** should always match the **original plaintext**.
## How to Build and Run
1. To build the project, run:
```bash
make
```
2. To execute the ECC encryption program:
```bash
./ecc
```
3. To clean the build:
```bash
make clean
```
## File Structure
- `src/`: Source code for the ECC implementation.
- `include/`: Header files.
- `build/`: Compiled binary.
- `obj/`: Object files.
## Elliptic Curve Parameters
For simplicity, this implementation uses a small prime `p = 97` and a small generator point `(3, 6)` on the elliptic curve `y² = x³ + 2x + 3`. In real-world applications, much larger prime values and more complex elliptic curves are used for better security.
## Future Work
In the future, this project could be extended by:
- Supporting larger prime numbers and more complex elliptic curves.
- Implementing more advanced elliptic curve encryption algorithms such as Elliptic Curve Diffie-Hellman (ECDH) or Elliptic Curve Digital Signature Algorithm (ECDSA).
## License
This project is open-source and available under the MIT license.

View File

@@ -0,0 +1,18 @@
CC = gcc
CFLAGS = -I../include -Wall -Wextra
OBJDIR = ../obj
BINDIR = ../build
all: $(BINDIR)/ecc
$(BINDIR)/ecc: $(OBJDIR)/main.o $(OBJDIR)/ecc.o
$(CC) $(OBJDIR)/main.o $(OBJDIR)/ecc.o -o $(BINDIR)/ecc
$(OBJDIR)/main.o: ../src/main.c ../include/ecc.h
$(CC) $(CFLAGS) -c ../src/main.c -o $(OBJDIR)/main.o
$(OBJDIR)/ecc.o: ../src/ecc.c ../include/ecc.h
$(CC) $(CFLAGS) -c ../src/ecc.c -o $(OBJDIR)/ecc.o
clean:
rm -f $(OBJDIR)/*.o $(BINDIR)/ecc

Binary file not shown.

View File

@@ -0,0 +1,35 @@
#ifndef ECC_H
#define ECC_H
#include <stdint.h>
// Struct for representing a point on the elliptic curve
typedef struct {
uint64_t x;
uint64_t y;
} ECPoint;
// Define an elliptic curve
typedef struct {
uint64_t a;
uint64_t b;
uint64_t p; // Prime modulus
ECPoint generator; // Generator point
uint64_t n; // Order of the curve
} EllipticCurve;
// Key pair
typedef struct {
uint64_t private_key;
ECPoint public_key;
} ECCKeyPair;
// Function declarations
ECPoint ecc_point_add(ECPoint P, ECPoint Q, EllipticCurve curve);
ECPoint ecc_point_double(ECPoint P, EllipticCurve curve);
ECPoint ecc_scalar_mult(uint64_t k, ECPoint P, EllipticCurve curve);
ECCKeyPair ecc_generate_keypair(EllipticCurve curve);
void ecc_encrypt(uint64_t plaintext, ECPoint public_key, EllipticCurve curve, ECPoint *C1, uint64_t *C2);
uint64_t ecc_decrypt(ECPoint C1, uint64_t C2, uint64_t private_key, EllipticCurve curve);
#endif

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,96 @@
#include "ecc.h"
#include <stdio.h>
#include <stdlib.h>
// Modular inverse using extended Euclidean algorithm
static uint64_t mod_inverse(uint64_t a, uint64_t m) {
int64_t m0 = m, t, q;
int64_t x0 = 0, x1 = 1;
if (m == 1)
return 0;
while (a > 1) {
q = a / m;
t = m;
m = a % m;
a = t;
t = x0;
x0 = x1 - q * x0;
x1 = t;
}
if (x1 < 0)
x1 += m0;
return x1;
}
// Modular arithmetic: Add two points P + Q
ECPoint ecc_point_add(ECPoint P, ECPoint Q, EllipticCurve curve) {
ECPoint R;
if (P.x == 0 && P.y == 0) return Q;
if (Q.x == 0 && Q.y == 0) return P;
if (P.x == Q.x && P.y == Q.y) {
return ecc_point_double(P, curve); // Doubling case
}
uint64_t lambda = ((Q.y + curve.p - P.y) * mod_inverse((Q.x + curve.p - P.x) % curve.p, curve.p)) % curve.p;
R.x = (lambda * lambda + curve.p - P.x + curve.p - Q.x) % curve.p;
R.y = (lambda * (P.x + curve.p - R.x) + curve.p - P.y) % curve.p;
return R;
}
// Doubling case: 2P
ECPoint ecc_point_double(ECPoint P, EllipticCurve curve) {
ECPoint R;
uint64_t lambda = ((3 * P.x * P.x + curve.a) * mod_inverse(2 * P.y, curve.p)) % curve.p;
R.x = (lambda * lambda + curve.p - 2 * P.x) % curve.p;
R.y = (lambda * (P.x + curve.p - R.x) + curve.p - P.y) % curve.p;
return R;
}
// Scalar multiplication: kP (repeated point addition)
ECPoint ecc_scalar_mult(uint64_t k, ECPoint P, EllipticCurve curve) {
ECPoint R = {0, 0}; // Point at infinity
ECPoint temp = P;
while (k > 0) {
if (k & 1) {
R = ecc_point_add(R, temp, curve);
}
temp = ecc_point_double(temp, curve);
k >>= 1;
}
return R;
}
// Key generation: Generate private and public key
ECCKeyPair ecc_generate_keypair(EllipticCurve curve) {
uint64_t private_key = rand() % curve.n;
ECPoint public_key = ecc_scalar_mult(private_key, curve.generator, curve);
ECCKeyPair keypair = {private_key, public_key};
return keypair;
}
// ECC encryption: Encrypts the plaintext and returns C1 (curve point) and C2 (encrypted message)
void ecc_encrypt(uint64_t plaintext, ECPoint public_key, EllipticCurve curve, ECPoint *C1, uint64_t *C2) {
uint64_t k = rand() % curve.n; // Random scalar for encryption
*C1 = ecc_scalar_mult(k, curve.generator, curve); // C1 = kG
ECPoint shared_secret = ecc_scalar_mult(k, public_key, curve); // kP
*C2 = plaintext ^ (shared_secret.x % 256); // XOR plaintext with shared secret's x-coordinate (mod 256)
}
// ECC decryption: Takes C1 and C2 to recover the original plaintext
uint64_t ecc_decrypt(ECPoint C1, uint64_t C2, uint64_t private_key, EllipticCurve curve) {
ECPoint shared_secret = ecc_scalar_mult(private_key, C1, curve); // dC1
return C2 ^ (shared_secret.x % 256); // XOR with shared secret's x-coordinate to recover plaintext
}

View File

@@ -0,0 +1,92 @@
#include "ecc.h"
#include <stdio.h>
#include <stdlib.h>
// Modular inverse using extended Euclidean algorithm
static uint64_t mod_inverse(uint64_t a, uint64_t m) {
int64_t m0 = m, t, q;
int64_t x0 = 0, x1 = 1;
if (m == 1)
return 0;
while (a > 1) {
q = a / m;
t = m;
m = a % m;
a = t;
t = x0;
x0 = x1 - q * x0;
x1 = t;
}
if (x1 < 0)
x1 += m0;
return x1;
}
// Modular arithmetic: Add two points P + Q
ECPoint ecc_point_add(ECPoint P, ECPoint Q, EllipticCurve curve) {
ECPoint R;
if (P.x == Q.x && P.y == Q.y) {
return ecc_point_double(P, curve); // Doubling case
}
uint64_t lambda = ((Q.y + curve.p - P.y) * mod_inverse((Q.x + curve.p - P.x) % curve.p, curve.p)) % curve.p;
R.x = (lambda * lambda + curve.p - P.x + curve.p - Q.x) % curve.p;
R.y = (lambda * (P.x + curve.p - R.x) + curve.p - P.y) % curve.p;
return R;
}
// Doubling case: 2P
ECPoint ecc_point_double(ECPoint P, EllipticCurve curve) {
ECPoint R;
uint64_t lambda = ((3 * P.x * P.x + curve.a) * mod_inverse(2 * P.y, curve.p)) % curve.p;
R.x = (lambda * lambda + curve.p - 2 * P.x) % curve.p;
R.y = (lambda * (P.x + curve.p - R.x) + curve.p - P.y) % curve.p;
return R;
}
// Scalar multiplication: kP (repeated point addition)
ECPoint ecc_scalar_mult(uint64_t k, ECPoint P, EllipticCurve curve) {
ECPoint R = {0, 0}; // Point at infinity
ECPoint temp = P;
while (k > 0) {
if (k & 1) {
R = ecc_point_add(R, temp, curve);
}
temp = ecc_point_double(temp, curve);
k >>= 1;
}
return R;
}
// Key generation: Generate private and public key
ECCKeyPair ecc_generate_keypair(EllipticCurve curve) {
uint64_t private_key = rand() % curve.n;
ECPoint public_key = ecc_scalar_mult(private_key, curve.generator, curve);
ECCKeyPair keypair = {private_key, public_key};
return keypair;
}
// Encryption using ECC
void ecc_encrypt(uint64_t plaintext, ECPoint public_key, EllipticCurve curve, ECPoint *C1, uint64_t *C2) {
uint64_t k = rand() % curve.n;
*C1 = ecc_scalar_mult(k, curve.generator, curve); // C1 = kG
ECPoint shared_secret = ecc_scalar_mult(k, public_key, curve); // kP
*C2 = plaintext ^ shared_secret.x; // XOR plaintext with shared secret's x-coordinate
}
// Decryption using ECC
uint64_t ecc_decrypt(ECPoint C1, uint64_t C2, uint64_t private_key, EllipticCurve curve) {
ECPoint shared_secret = ecc_scalar_mult(private_key, C1, curve); // dC1
return C2 ^ shared_secret.x; // XOR with shared secret to recover plaintext
}

View File

@@ -0,0 +1,33 @@
#include "ecc.h"
#include <stdio.h>
int main() {
// Define the elliptic curve
EllipticCurve curve = {
.a = 2,
.b = 3,
.p = 97, // Small prime for simplicity
.generator = {3, 6}, // Generator point
.n = 5 // Order of the generator
};
// Generate keypair for ECC
ECCKeyPair keypair = ecc_generate_keypair(curve);
printf("Private Key: %lu\n", keypair.private_key);
printf("Public Key: (%lu, %lu)\n", keypair.public_key.x, keypair.public_key.y);
// Encrypt a message
uint64_t plaintext = 42;
printf("Plaintext: %lu\n", plaintext);
ECPoint C1;
uint64_t C2;
ecc_encrypt(plaintext, keypair.public_key, curve, &C1, &C2);
printf("Ciphertext: (C1: %lu, %lu), C2: %lu\n", C1.x, C1.y, C2);
// Decrypt the message
uint64_t decrypted = ecc_decrypt(C1, C2, keypair.private_key, curve);
printf("Decrypted: %lu\n", decrypted);
return 0;
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# cryptograph-projects Project
This is a C project generated with the setup tool.

View File

@@ -0,0 +1,15 @@
# Simple Substitution Cipher
## Description
A simple substitution cipher replaces each letter in the plaintext with another letter from the alphabet, based on a predetermined key.
## How to Build
1. Navigate to the `build` directory.
2. Run `make` to compile the project.
## How to Run
1. After building, you will find an executable named `substitution_cipher` in the `build` directory.
2. Run it using `./substitution_cipher`.
## How to Clean
- Run `make clean` in the `build` directory to remove all compiled files.

View File

@@ -0,0 +1,28 @@
# Variables
CC = gcc
CFLAGS = -I../include -Wall -Wextra
OBJDIR = ../obj
SRCDIR = ../src
BINDIR = ../build
# Source files
SOURCES = $(SRCDIR)/main.c $(SRCDIR)/substitution_cipher.c
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/substitution_cipher.o
# Build target
TARGET = substitution_cipher
# Rules
all: $(BINDIR)/$(TARGET)
$(BINDIR)/$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -o $(BINDIR)/$(TARGET)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
.PHONY: all clean

Binary file not shown.

View File

@@ -0,0 +1,7 @@
#ifndef SUBSTITUTION_CIPHER_H
#define SUBSTITUTION_CIPHER_H
void substitution_encrypt(char *message, const char *key);
void substitution_decrypt(char *message, const char *key);
#endif // SUBSTITUTION_CIPHER_H

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,22 @@
#include "substitution_cipher.h"
#include <stdio.h>
#include <string.h>
int main() {
char message[256];
char key[27] = "QWERTYUIOPLKJHGFDSAZXCVBNM"; // Simple substitution key
printf("Enter a message to encrypt: ");
fgets(message, sizeof(message), stdin);
message[strcspn(message, "\n")] = '\0'; // Remove the newline character
// Encrypt the message
substitution_encrypt(message, key);
printf("Encrypted message: %s\n", message);
// Decrypt the message to verify it works
substitution_decrypt(message, key);
printf("Decrypted message: %s\n", message);
return 0;
}

View File

@@ -0,0 +1,36 @@
#include "substitution_cipher.h"
#include <string.h>
#include <ctype.h> // for isalpha, toupper
// Helper function to find the position of a character in the alphabet
static int find_position(char c) {
c = toupper(c);
return c - 'A';
}
// Encrypt the message using the provided key
void substitution_encrypt(char *message, const char *key) {
for (int i = 0; message[i] != '\0'; i++) {
if (isalpha(message[i])) {
int pos = find_position(message[i]);
//char base = isupper(message[i]) ? 'A' : 'a';
message[i] = isupper(message[i]) ? key[pos] : tolower(key[pos]);
}
}
}
// Decrypt the message using the provided key
void substitution_decrypt(char *message, const char *key) {
char reverse_key[26];
for (int i = 0; i < 26; i++) {
reverse_key[key[i] - 'A'] = 'A' + i;
}
for (int i = 0; message[i] != '\0'; i++) {
if (isalpha(message[i])) {
int pos = find_position(message[i]);
//char base = isupper(message[i]) ? 'A' : 'a';
message[i] = isupper(message[i]) ? reverse_key[pos] : tolower(reverse_key[pos]);
}
}
}

View File

@@ -0,0 +1,21 @@
# Vigenère Cipher
## Description
This project implements a Vigenère cipher to demonstrate basic encryption and decryption using a keyword-based shifting approach.
## Directory Structure
- `include/`: Contains the header files.
- `src/`: Contains the source code files (`main.c` and `vigenere_cipher.c`).
- `obj/`: Contains the compiled object files.
- `build/`: Contains the Makefile and the compiled binary.
## How to Build
1. Navigate to the `build` directory.
2. Run `make` to compile the project.
## How to Run
1. After building, you will find an executable named `vigenere_cipher` in the `build` directory.
2. Run it using `./vigenere_cipher`.
## How to Clean
- Run `make clean` in the `build` directory to remove all compiled files.

View File

@@ -0,0 +1,28 @@
# Variables
CC = gcc
CFLAGS = -I../include -Wall -Wextra
OBJDIR = ../obj
SRCDIR = ../src
BINDIR = ../build
# Source files
SOURCES = $(SRCDIR)/main.c $(SRCDIR)/vigenere_cipher.c
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/vigenere_cipher.o
# Build target
TARGET = vigenere_cipher
# Rules
all: $(BINDIR)/$(TARGET)
$(BINDIR)/$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -o $(BINDIR)/$(TARGET)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
.PHONY: all clean

Binary file not shown.

View File

@@ -0,0 +1,7 @@
#ifndef VIGENERE_CIPHER_H
#define VIGENERE_CIPHER_H
void encrypt(char *plaintext, const char *key);
void decrypt(char *ciphertext, const char *key);
#endif // VIGENERE_CIPHER_H

BIN
Vigenère_Cipher/obj/main.o Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,26 @@
#include "vigenere_cipher.h"
#include <stdio.h>
#include <string.h>
int main() {
char message[256];
char key[256];
printf("Enter a message to encrypt: ");
fgets(message, sizeof(message), stdin);
message[strcspn(message, "\n")] = '\0'; // Remove newline character
printf("Enter the encryption key: ");
fgets(key, sizeof(key), stdin);
key[strcspn(key, "\n")] = '\0'; // Remove newline character
// Encrypt the message
encrypt(message, key);
printf("Encrypted message: %s\n", message);
// Decrypt the message
decrypt(message, key);
printf("Decrypted message: %s\n", message);
return 0;
}

View File

@@ -0,0 +1,28 @@
#include "vigenere_cipher.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void encrypt(char *plaintext, const char *key) {
int keyLen = strlen(key);
for (int i = 0, j = 0; plaintext[i] != '\0'; i++) {
if (isalpha(plaintext[i])) {
char base = islower(plaintext[i]) ? 'a' : 'A';
int shift = (tolower(key[j % keyLen]) - 'a');
plaintext[i] = (plaintext[i] - base + shift) % 26 + base;
j++;
}
}
}
void decrypt(char *ciphertext, const char *key) {
int keyLen = strlen(key);
for (int i = 0, j = 0; ciphertext[i] != '\0'; i++) {
if (isalpha(ciphertext[i])) {
char base = islower(ciphertext[i]) ? 'a' : 'A';
int shift = (tolower(key[j % keyLen]) - 'a');
ciphertext[i] = (ciphertext[i] - base - shift + 26) % 26 + base;
j++;
}
}
}

21
XOR_Encryption/README.md Normal file
View File

@@ -0,0 +1,21 @@
# XOR Cipher
## Description
This project implements a simple XOR cipher for encrypting and decrypting text using a key. XOR encryption is a symmetric operation, meaning the same function is used to both encrypt and decrypt data.
## Directory Structure
- `include/`: Contains the header files.
- `src/`: Contains the source code files (`main.c` and `xor_cipher.c`).
- `obj/`: Contains the compiled object files.
- `build/`: Contains the Makefile and the compiled binary.
## How to Build
1. Navigate to the `build` directory.
2. Run `make` to compile the project.
## How to Run
1. After building, you will find an executable named `xor_cipher` in the `build` directory.
2. Run it using `./xor_cipher`.
## How to Clean
- Run `make clean` in the `build` directory to remove all compiled files.

View File

@@ -0,0 +1,27 @@
# Variables
CC = gcc
CFLAGS = -I../include -Wall -Wextra
OBJDIR = ../obj
SRCDIR = ../src
BINDIR = ../build
# Source files
SOURCES = $(SRCDIR)/main.c $(SRCDIR)/xor_cipher.c
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/xor_cipher.o
# Build target
TARGET = xor_cipher
# Rules
all: $(BINDIR)/$(TARGET)
$(BINDIR)/$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -o $(BINDIR)/$(TARGET)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
.PHONY: all clean

BIN
XOR_Encryption/build/xor_cipher Executable file

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#ifndef XOR_CIPHER_H
#define XOR_CIPHER_H
void xor_encrypt_decrypt(char *data, const char *key);
#endif // XOR_CIPHER_H

BIN
XOR_Encryption/obj/main.o Normal file

Binary file not shown.

Binary file not shown.

54
XOR_Encryption/src/main.c Normal file
View File

@@ -0,0 +1,54 @@
#include "xor_cipher.h"
#include <stdio.h>
#include <string.h>
// Function to display encrypted message in hexadecimal format
void print_hex(const char *data) {
for (int i = 0; data[i] != '\0'; i++) {
printf("%02x ", (unsigned char)data[i]);
}
printf("\n");
}
// Function to safely print decrypted message, replacing nulls with spaces
void print_decrypted_message(const char *data) {
for (int i = 0; data[i] != '\0'; i++) {
// If the character is NULL, print a space instead
putchar(data[i] == '\0' ? ' ' : data[i]);
}
printf("\n");
}
int main() {
char message[256];
char key[256];
// Get the message to encrypt
printf("Enter a message to encrypt: ");
fgets(message, sizeof(message), stdin);
message[strcspn(message, "\n")] = '\0'; // Remove newline character
// Get the encryption key
printf("Enter the encryption key: ");
fgets(key, sizeof(key), stdin);
key[strcspn(key, "\n")] = '\0'; // Remove newline character
// Check if message or key is empty
if (strlen(message) == 0 || strlen(key) == 0) {
printf("Error: Message or key cannot be empty.\n");
return 1;
}
// Encrypt the message
xor_encrypt_decrypt(message, key);
printf("Encrypted message (hexadecimal): ");
print_hex(message);
// Decrypt the message (using the same function, since XOR is symmetric)
xor_encrypt_decrypt(message, key);
printf("Decrypted message: ");
print_decrypted_message(message);
return 0;
}

View File

@@ -0,0 +1,10 @@
#include "xor_cipher.h"
#include <string.h>
#include <stdio.h>
void xor_encrypt_decrypt(char *data, const char *key) {
int keyLength = strlen(key);
for (int i = 0; data[i] != '\0'; i++) {
data[i] ^= key[i % keyLength];
}
}

3
rsa-algorithms/README.md Normal file
View File

@@ -0,0 +1,3 @@
# rsa-algorithms Project
This is a C project generated with the setup tool.

View File

@@ -0,0 +1,28 @@
# Variables
CC = gcc
CFLAGS = -I../include -Wall -Wextra
OBJDIR = ../obj
SRCDIR = ../src
BINDIR = ../build
# Source files
SOURCES = $(SRCDIR)/main.c $(SRCDIR)/rsa.c
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/rsa.o
# Build target
TARGET = rsa
# Rules
all: $(BINDIR)/$(TARGET)
$(BINDIR)/$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -o $(BINDIR)/$(TARGET)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
.PHONY: all clean

BIN
rsa-algorithms/build/rsa Executable file

Binary file not shown.

View File

@@ -0,0 +1,8 @@
#ifndef RSA_H
#define RSA_H
void rsa_generate_keys(unsigned long *e, unsigned long *d, unsigned long *n);
unsigned long rsa_encrypt(unsigned long message, unsigned long e, unsigned long n);
unsigned long rsa_decrypt(unsigned long ciphertext, unsigned long d, unsigned long n);
#endif // RSA_H

BIN
rsa-algorithms/obj/main.o Normal file

Binary file not shown.

BIN
rsa-algorithms/obj/rsa.o Normal file

Binary file not shown.

33
rsa-algorithms/src/main.c Normal file
View File

@@ -0,0 +1,33 @@
#include "rsa.h"
#include <stdio.h>
int main() {
unsigned long e, d, n;
// Generate public and private keys
rsa_generate_keys(&e, &d, &n);
printf("Public Key: (e = %lu, n = %lu)\n", e, n);
printf("Private Key: (d = %lu, n = %lu)\n", d, n);
// Ask for a message to encrypt (assuming it's an integer for simplicity)
unsigned long message;
printf("Enter a message to encrypt (as an integer smaller than %lu): ", n);
scanf("%lu", &message);
// Ensure message is smaller than n
if (message >= n) {
printf("Error: Message must be smaller than %lu.\n", n);
return 1;
}
// Encrypt the message
unsigned long ciphertext = rsa_encrypt(message, e, n);
printf("Encrypted message: %lu\n", ciphertext);
// Decrypt the message
unsigned long decrypted_message = rsa_decrypt(ciphertext, d, n);
printf("Decrypted message: %lu\n", decrypted_message);
return 0;
}

81
rsa-algorithms/src/rsa.c Normal file
View File

@@ -0,0 +1,81 @@
#include "rsa.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Helper function to calculate the greatest common divisor (GCD)
static unsigned long gcd(unsigned long a, unsigned long b) {
while (b != 0) {
unsigned long temp = b;
b = a % b;
a = temp;
}
return a;
}
// Helper function to find the modular inverse using the extended Euclidean algorithm
static unsigned long mod_inverse(unsigned long e, unsigned long phi) {
long t = 0, newt = 1;
unsigned long r = phi, newr = e;
while (newr != 0) {
unsigned long quotient = r / newr;
// Update t and newt
long temp = t;
t = newt;
newt = temp - quotient * newt;
// Update r and newr
unsigned long temp_r = r;
r = newr;
newr = temp_r - quotient * newr;
}
if (r > 1) return 0; // e is not invertible
if (t < 0) t += phi; // Ensure t is positive
return (unsigned long)t;
}
// Generate RSA keys (public and private)
void rsa_generate_keys(unsigned long *e, unsigned long *d, unsigned long *n) {
// Two prime numbers (for simplicity, using small values)
unsigned long p = 61, q = 53;
*n = p * q;
unsigned long phi = (p - 1) * (q - 1);
// Choose e such that 1 < e < phi(n) and gcd(e, phi(n)) = 1
*e = 17; // Commonly chosen small prime number
if (gcd(*e, phi) != 1) {
printf("Error: e and phi(n) are not coprime.\n");
exit(1);
}
// Calculate d, the modular inverse of e mod phi(n)
*d = mod_inverse(*e, phi);
if (*d == 0) {
printf("Error: Could not find modular inverse of e.\n");
exit(1);
}
}
// Encrypt message using public key (e, n)
unsigned long rsa_encrypt(unsigned long message, unsigned long e, unsigned long n) {
unsigned long result = 1;
for (unsigned long i = 0; i < e; i++) {
result = (result * message) % n;
}
return result;
}
// Decrypt ciphertext using private key (d, n)
unsigned long rsa_decrypt(unsigned long ciphertext, unsigned long d, unsigned long n) {
unsigned long result = 1;
for (unsigned long i = 0; i < d; i++) {
result = (result * ciphertext) % n;
}
return result;
}