commit 3aff0baacf8cffc5abc3e322ab194d30e3c12d6f Author: klein panic Date: Sat Feb 1 16:14:45 2025 -0500 testing diff --git a/Advanced-Encryption-Standard/README.md b/Advanced-Encryption-Standard/README.md new file mode 100644 index 0000000..5d514c5 --- /dev/null +++ b/Advanced-Encryption-Standard/README.md @@ -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. diff --git a/Advanced-Encryption-Standard/build/Makefile b/Advanced-Encryption-Standard/build/Makefile new file mode 100644 index 0000000..6c6464c --- /dev/null +++ b/Advanced-Encryption-Standard/build/Makefile @@ -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 + diff --git a/Advanced-Encryption-Standard/build/aes b/Advanced-Encryption-Standard/build/aes new file mode 100755 index 0000000..5857556 Binary files /dev/null and b/Advanced-Encryption-Standard/build/aes differ diff --git a/Advanced-Encryption-Standard/include/aes.h b/Advanced-Encryption-Standard/include/aes.h new file mode 100644 index 0000000..c958a8b --- /dev/null +++ b/Advanced-Encryption-Standard/include/aes.h @@ -0,0 +1,9 @@ +#ifndef AES_H +#define AES_H + +#include + +void aes_encrypt(uint8_t *message, uint8_t *key); +void aes_decrypt(uint8_t *message, uint8_t *key); + +#endif // AES_H diff --git a/Advanced-Encryption-Standard/obj/aes.o b/Advanced-Encryption-Standard/obj/aes.o new file mode 100644 index 0000000..29a9e0e Binary files /dev/null and b/Advanced-Encryption-Standard/obj/aes.o differ diff --git a/Advanced-Encryption-Standard/obj/main.o b/Advanced-Encryption-Standard/obj/main.o new file mode 100644 index 0000000..5132d38 Binary files /dev/null and b/Advanced-Encryption-Standard/obj/main.o differ diff --git a/Advanced-Encryption-Standard/src/aes.c b/Advanced-Encryption-Standard/src/aes.c new file mode 100644 index 0000000..0513d77 --- /dev/null +++ b/Advanced-Encryption-Standard/src/aes.c @@ -0,0 +1,210 @@ +#include "aes.h" +#include +#include + +// 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); +} diff --git a/Advanced-Encryption-Standard/src/main.c b/Advanced-Encryption-Standard/src/main.c new file mode 100644 index 0000000..353d296 --- /dev/null +++ b/Advanced-Encryption-Standard/src/main.c @@ -0,0 +1,31 @@ +#include "aes.h" +#include +#include + +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; +} diff --git a/Base64_Encoding/README.md b/Base64_Encoding/README.md new file mode 100644 index 0000000..9c994b9 --- /dev/null +++ b/Base64_Encoding/README.md @@ -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. diff --git a/Base64_Encoding/build/Makefile b/Base64_Encoding/build/Makefile new file mode 100644 index 0000000..7d349aa --- /dev/null +++ b/Base64_Encoding/build/Makefile @@ -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 + diff --git a/Base64_Encoding/build/base64_encoder b/Base64_Encoding/build/base64_encoder new file mode 100755 index 0000000..bb36040 Binary files /dev/null and b/Base64_Encoding/build/base64_encoder differ diff --git a/Base64_Encoding/include/base64_encoder.h b/Base64_Encoding/include/base64_encoder.h new file mode 100644 index 0000000..1b52928 --- /dev/null +++ b/Base64_Encoding/include/base64_encoder.h @@ -0,0 +1,9 @@ +#ifndef BASE64_ENCODER_H +#define BASE64_ENCODER_H + +#include // 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 diff --git a/Base64_Encoding/obj/base64_encoder.o b/Base64_Encoding/obj/base64_encoder.o new file mode 100644 index 0000000..e2519d3 Binary files /dev/null and b/Base64_Encoding/obj/base64_encoder.o differ diff --git a/Base64_Encoding/obj/main.o b/Base64_Encoding/obj/main.o new file mode 100644 index 0000000..c8c1e1b Binary files /dev/null and b/Base64_Encoding/obj/main.o differ diff --git a/Base64_Encoding/src/base64_encoder.c b/Base64_Encoding/src/base64_encoder.c new file mode 100644 index 0000000..3612978 --- /dev/null +++ b/Base64_Encoding/src/base64_encoder.c @@ -0,0 +1,96 @@ +#include "base64_encoder.h" +#include +#include +#include +#include + +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; +} + diff --git a/Base64_Encoding/src/main.c b/Base64_Encoding/src/main.c new file mode 100644 index 0000000..0e56bb8 --- /dev/null +++ b/Base64_Encoding/src/main.c @@ -0,0 +1,39 @@ +#include "base64_encoder.h" +#include +#include +#include // 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; +} diff --git a/Caesar_Cipher/README.md b/Caesar_Cipher/README.md new file mode 100644 index 0000000..f1bb603 --- /dev/null +++ b/Caesar_Cipher/README.md @@ -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. + diff --git a/Caesar_Cipher/build/Makefile b/Caesar_Cipher/build/Makefile new file mode 100644 index 0000000..93c8aa2 --- /dev/null +++ b/Caesar_Cipher/build/Makefile @@ -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 diff --git a/Caesar_Cipher/build/caesar_cipher b/Caesar_Cipher/build/caesar_cipher new file mode 100755 index 0000000..5cecd6f Binary files /dev/null and b/Caesar_Cipher/build/caesar_cipher differ diff --git a/Caesar_Cipher/include/caesar_cipher.h b/Caesar_Cipher/include/caesar_cipher.h new file mode 100644 index 0000000..352d686 --- /dev/null +++ b/Caesar_Cipher/include/caesar_cipher.h @@ -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 + diff --git a/Caesar_Cipher/obj/caesar_cipher.o b/Caesar_Cipher/obj/caesar_cipher.o new file mode 100644 index 0000000..abbc4ec Binary files /dev/null and b/Caesar_Cipher/obj/caesar_cipher.o differ diff --git a/Caesar_Cipher/obj/main.o b/Caesar_Cipher/obj/main.o new file mode 100644 index 0000000..41ef7f6 Binary files /dev/null and b/Caesar_Cipher/obj/main.o differ diff --git a/Caesar_Cipher/src/caesar_cipher.c b/Caesar_Cipher/src/caesar_cipher.c new file mode 100644 index 0000000..5dc4667 --- /dev/null +++ b/Caesar_Cipher/src/caesar_cipher.c @@ -0,0 +1,21 @@ +#include "caesar_cipher.h" +#include +#include + +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; + } + } +} diff --git a/Caesar_Cipher/src/main.c b/Caesar_Cipher/src/main.c new file mode 100644 index 0000000..2554f67 --- /dev/null +++ b/Caesar_Cipher/src/main.c @@ -0,0 +1,24 @@ +#include "caesar_cipher.h" +#include + +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; +} + diff --git a/Data-Encryption-Standard/README.md b/Data-Encryption-Standard/README.md new file mode 100644 index 0000000..0360aa4 --- /dev/null +++ b/Data-Encryption-Standard/README.md @@ -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. + diff --git a/Data-Encryption-Standard/build/Makefile b/Data-Encryption-Standard/build/Makefile new file mode 100644 index 0000000..431f568 --- /dev/null +++ b/Data-Encryption-Standard/build/Makefile @@ -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 + diff --git a/Data-Encryption-Standard/build/des b/Data-Encryption-Standard/build/des new file mode 100755 index 0000000..916c4a9 Binary files /dev/null and b/Data-Encryption-Standard/build/des differ diff --git a/Data-Encryption-Standard/include/des.h b/Data-Encryption-Standard/include/des.h new file mode 100644 index 0000000..60e7803 --- /dev/null +++ b/Data-Encryption-Standard/include/des.h @@ -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 diff --git a/Data-Encryption-Standard/obj/des.o b/Data-Encryption-Standard/obj/des.o new file mode 100644 index 0000000..7ae2e7a Binary files /dev/null and b/Data-Encryption-Standard/obj/des.o differ diff --git a/Data-Encryption-Standard/obj/main.o b/Data-Encryption-Standard/obj/main.o new file mode 100644 index 0000000..f7f990f Binary files /dev/null and b/Data-Encryption-Standard/obj/main.o differ diff --git a/Data-Encryption-Standard/src/des.c b/Data-Encryption-Standard/src/des.c new file mode 100644 index 0000000..1b690b5 --- /dev/null +++ b/Data-Encryption-Standard/src/des.c @@ -0,0 +1,76 @@ +#include "des.h" +#include +#include + +// 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); +} diff --git a/Data-Encryption-Standard/src/main.c b/Data-Encryption-Standard/src/main.c new file mode 100644 index 0000000..5874917 --- /dev/null +++ b/Data-Encryption-Standard/src/main.c @@ -0,0 +1,25 @@ +#include "des.h" +#include + +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; +} + diff --git a/Diffie-Hellman-Key-Exchange/README.md b/Diffie-Hellman-Key-Exchange/README.md new file mode 100644 index 0000000..6d438d4 --- /dev/null +++ b/Diffie-Hellman-Key-Exchange/README.md @@ -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. diff --git a/Diffie-Hellman-Key-Exchange/build/Makefile b/Diffie-Hellman-Key-Exchange/build/Makefile new file mode 100644 index 0000000..a1657e2 --- /dev/null +++ b/Diffie-Hellman-Key-Exchange/build/Makefile @@ -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 diff --git a/Diffie-Hellman-Key-Exchange/build/diffie_hellman b/Diffie-Hellman-Key-Exchange/build/diffie_hellman new file mode 100755 index 0000000..0e1064b Binary files /dev/null and b/Diffie-Hellman-Key-Exchange/build/diffie_hellman differ diff --git a/Diffie-Hellman-Key-Exchange/include/diffie_hellman.h b/Diffie-Hellman-Key-Exchange/include/diffie_hellman.h new file mode 100644 index 0000000..d7d8b05 --- /dev/null +++ b/Diffie-Hellman-Key-Exchange/include/diffie_hellman.h @@ -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 diff --git a/Diffie-Hellman-Key-Exchange/obj/diffie_hellman.o b/Diffie-Hellman-Key-Exchange/obj/diffie_hellman.o new file mode 100644 index 0000000..96dc410 Binary files /dev/null and b/Diffie-Hellman-Key-Exchange/obj/diffie_hellman.o differ diff --git a/Diffie-Hellman-Key-Exchange/obj/main.o b/Diffie-Hellman-Key-Exchange/obj/main.o new file mode 100644 index 0000000..d45a944 Binary files /dev/null and b/Diffie-Hellman-Key-Exchange/obj/main.o differ diff --git a/Diffie-Hellman-Key-Exchange/src/diffie_hellman.c b/Diffie-Hellman-Key-Exchange/src/diffie_hellman.c new file mode 100644 index 0000000..cb981dd --- /dev/null +++ b/Diffie-Hellman-Key-Exchange/src/diffie_hellman.c @@ -0,0 +1,21 @@ +#include "diffie_hellman.h" +#include +#include + +// 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; +} diff --git a/Diffie-Hellman-Key-Exchange/src/main.c b/Diffie-Hellman-Key-Exchange/src/main.c new file mode 100644 index 0000000..d852856 --- /dev/null +++ b/Diffie-Hellman-Key-Exchange/src/main.c @@ -0,0 +1,42 @@ +#include "diffie_hellman.h" +#include +#include +#include + +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; +} diff --git a/Elliptic-Curve-Cryptography/README.md b/Elliptic-Curve-Cryptography/README.md new file mode 100644 index 0000000..cc9ad5b --- /dev/null +++ b/Elliptic-Curve-Cryptography/README.md @@ -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. diff --git a/Elliptic-Curve-Cryptography/build/Makefile b/Elliptic-Curve-Cryptography/build/Makefile new file mode 100644 index 0000000..5ad85e9 --- /dev/null +++ b/Elliptic-Curve-Cryptography/build/Makefile @@ -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 diff --git a/Elliptic-Curve-Cryptography/build/ecc b/Elliptic-Curve-Cryptography/build/ecc new file mode 100755 index 0000000..dacbb69 Binary files /dev/null and b/Elliptic-Curve-Cryptography/build/ecc differ diff --git a/Elliptic-Curve-Cryptography/include/ecc.h b/Elliptic-Curve-Cryptography/include/ecc.h new file mode 100644 index 0000000..36a55c9 --- /dev/null +++ b/Elliptic-Curve-Cryptography/include/ecc.h @@ -0,0 +1,35 @@ +#ifndef ECC_H +#define ECC_H + +#include + +// 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 diff --git a/Elliptic-Curve-Cryptography/obj/ecc.o b/Elliptic-Curve-Cryptography/obj/ecc.o new file mode 100644 index 0000000..b9dd9f3 Binary files /dev/null and b/Elliptic-Curve-Cryptography/obj/ecc.o differ diff --git a/Elliptic-Curve-Cryptography/obj/main.o b/Elliptic-Curve-Cryptography/obj/main.o new file mode 100644 index 0000000..90fa8f8 Binary files /dev/null and b/Elliptic-Curve-Cryptography/obj/main.o differ diff --git a/Elliptic-Curve-Cryptography/src/ecc.c b/Elliptic-Curve-Cryptography/src/ecc.c new file mode 100644 index 0000000..684e3ad --- /dev/null +++ b/Elliptic-Curve-Cryptography/src/ecc.c @@ -0,0 +1,96 @@ +#include "ecc.h" +#include +#include + +// 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 +} + diff --git a/Elliptic-Curve-Cryptography/src/ecc.c.bak b/Elliptic-Curve-Cryptography/src/ecc.c.bak new file mode 100644 index 0000000..cbb73c0 --- /dev/null +++ b/Elliptic-Curve-Cryptography/src/ecc.c.bak @@ -0,0 +1,92 @@ +#include "ecc.h" +#include +#include + +// 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 +} diff --git a/Elliptic-Curve-Cryptography/src/main.c b/Elliptic-Curve-Cryptography/src/main.c new file mode 100644 index 0000000..94dfb5f --- /dev/null +++ b/Elliptic-Curve-Cryptography/src/main.c @@ -0,0 +1,33 @@ +#include "ecc.h" +#include + +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; +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..3e7861a --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# cryptograph-projects Project + +This is a C project generated with the setup tool. diff --git a/Simple_Substitution/README.md b/Simple_Substitution/README.md new file mode 100644 index 0000000..da4eaa5 --- /dev/null +++ b/Simple_Substitution/README.md @@ -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. diff --git a/Simple_Substitution/build/Makefile b/Simple_Substitution/build/Makefile new file mode 100644 index 0000000..28b8c38 --- /dev/null +++ b/Simple_Substitution/build/Makefile @@ -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 + diff --git a/Simple_Substitution/build/substitution_cipher b/Simple_Substitution/build/substitution_cipher new file mode 100755 index 0000000..13485a5 Binary files /dev/null and b/Simple_Substitution/build/substitution_cipher differ diff --git a/Simple_Substitution/include/substitution_cipher.h b/Simple_Substitution/include/substitution_cipher.h new file mode 100644 index 0000000..2bcc581 --- /dev/null +++ b/Simple_Substitution/include/substitution_cipher.h @@ -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 diff --git a/Simple_Substitution/obj/main.o b/Simple_Substitution/obj/main.o new file mode 100644 index 0000000..e9ac87d Binary files /dev/null and b/Simple_Substitution/obj/main.o differ diff --git a/Simple_Substitution/obj/substitution_cipher.o b/Simple_Substitution/obj/substitution_cipher.o new file mode 100644 index 0000000..c36069d Binary files /dev/null and b/Simple_Substitution/obj/substitution_cipher.o differ diff --git a/Simple_Substitution/src/main.c b/Simple_Substitution/src/main.c new file mode 100644 index 0000000..0232268 --- /dev/null +++ b/Simple_Substitution/src/main.c @@ -0,0 +1,22 @@ +#include "substitution_cipher.h" +#include +#include + +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; +} diff --git a/Simple_Substitution/src/substitution_cipher.c b/Simple_Substitution/src/substitution_cipher.c new file mode 100644 index 0000000..218f023 --- /dev/null +++ b/Simple_Substitution/src/substitution_cipher.c @@ -0,0 +1,36 @@ +#include "substitution_cipher.h" +#include +#include // 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]); + } + } +} diff --git a/Vigenère_Cipher/README.md b/Vigenère_Cipher/README.md new file mode 100644 index 0000000..1a438fb --- /dev/null +++ b/Vigenère_Cipher/README.md @@ -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. diff --git a/Vigenère_Cipher/build/Makefile b/Vigenère_Cipher/build/Makefile new file mode 100644 index 0000000..b592372 --- /dev/null +++ b/Vigenère_Cipher/build/Makefile @@ -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 + diff --git a/Vigenère_Cipher/build/vigenere_cipher b/Vigenère_Cipher/build/vigenere_cipher new file mode 100755 index 0000000..3d1ea3a Binary files /dev/null and b/Vigenère_Cipher/build/vigenere_cipher differ diff --git a/Vigenère_Cipher/include/vigenere_cipher.h b/Vigenère_Cipher/include/vigenere_cipher.h new file mode 100644 index 0000000..732b133 --- /dev/null +++ b/Vigenère_Cipher/include/vigenere_cipher.h @@ -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 diff --git a/Vigenère_Cipher/obj/main.o b/Vigenère_Cipher/obj/main.o new file mode 100644 index 0000000..0bf36a6 Binary files /dev/null and b/Vigenère_Cipher/obj/main.o differ diff --git a/Vigenère_Cipher/obj/vigenere_cipher.o b/Vigenère_Cipher/obj/vigenere_cipher.o new file mode 100644 index 0000000..e1f28cf Binary files /dev/null and b/Vigenère_Cipher/obj/vigenere_cipher.o differ diff --git a/Vigenère_Cipher/src/main.c b/Vigenère_Cipher/src/main.c new file mode 100644 index 0000000..2e02f30 --- /dev/null +++ b/Vigenère_Cipher/src/main.c @@ -0,0 +1,26 @@ +#include "vigenere_cipher.h" +#include +#include + +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; +} diff --git a/Vigenère_Cipher/src/vigenere_cipher.c b/Vigenère_Cipher/src/vigenere_cipher.c new file mode 100644 index 0000000..9edbcf0 --- /dev/null +++ b/Vigenère_Cipher/src/vigenere_cipher.c @@ -0,0 +1,28 @@ +#include "vigenere_cipher.h" +#include +#include +#include + +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++; + } + } +} diff --git a/XOR_Encryption/README.md b/XOR_Encryption/README.md new file mode 100644 index 0000000..3893493 --- /dev/null +++ b/XOR_Encryption/README.md @@ -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. diff --git a/XOR_Encryption/build/Makefile b/XOR_Encryption/build/Makefile new file mode 100644 index 0000000..b8c3618 --- /dev/null +++ b/XOR_Encryption/build/Makefile @@ -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 diff --git a/XOR_Encryption/build/xor_cipher b/XOR_Encryption/build/xor_cipher new file mode 100755 index 0000000..433f198 Binary files /dev/null and b/XOR_Encryption/build/xor_cipher differ diff --git a/XOR_Encryption/include/xor_cipher.h b/XOR_Encryption/include/xor_cipher.h new file mode 100644 index 0000000..0931b53 --- /dev/null +++ b/XOR_Encryption/include/xor_cipher.h @@ -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 diff --git a/XOR_Encryption/obj/main.o b/XOR_Encryption/obj/main.o new file mode 100644 index 0000000..a330c53 Binary files /dev/null and b/XOR_Encryption/obj/main.o differ diff --git a/XOR_Encryption/obj/xor_cipher.o b/XOR_Encryption/obj/xor_cipher.o new file mode 100644 index 0000000..a1873bc Binary files /dev/null and b/XOR_Encryption/obj/xor_cipher.o differ diff --git a/XOR_Encryption/src/main.c b/XOR_Encryption/src/main.c new file mode 100644 index 0000000..be557fd --- /dev/null +++ b/XOR_Encryption/src/main.c @@ -0,0 +1,54 @@ +#include "xor_cipher.h" +#include +#include + +// 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; +} + diff --git a/XOR_Encryption/src/xor_cipher.c b/XOR_Encryption/src/xor_cipher.c new file mode 100644 index 0000000..a4efb4c --- /dev/null +++ b/XOR_Encryption/src/xor_cipher.c @@ -0,0 +1,10 @@ +#include "xor_cipher.h" +#include +#include + +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]; + } +} diff --git a/rsa-algorithms/README.md b/rsa-algorithms/README.md new file mode 100644 index 0000000..49bcc07 --- /dev/null +++ b/rsa-algorithms/README.md @@ -0,0 +1,3 @@ +# rsa-algorithms Project + +This is a C project generated with the setup tool. diff --git a/rsa-algorithms/build/Makefile b/rsa-algorithms/build/Makefile new file mode 100644 index 0000000..1de23cd --- /dev/null +++ b/rsa-algorithms/build/Makefile @@ -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 + diff --git a/rsa-algorithms/build/rsa b/rsa-algorithms/build/rsa new file mode 100755 index 0000000..ea99719 Binary files /dev/null and b/rsa-algorithms/build/rsa differ diff --git a/rsa-algorithms/include/rsa.h b/rsa-algorithms/include/rsa.h new file mode 100644 index 0000000..5acad33 --- /dev/null +++ b/rsa-algorithms/include/rsa.h @@ -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 diff --git a/rsa-algorithms/obj/main.o b/rsa-algorithms/obj/main.o new file mode 100644 index 0000000..65b28ea Binary files /dev/null and b/rsa-algorithms/obj/main.o differ diff --git a/rsa-algorithms/obj/rsa.o b/rsa-algorithms/obj/rsa.o new file mode 100644 index 0000000..81d21e8 Binary files /dev/null and b/rsa-algorithms/obj/rsa.o differ diff --git a/rsa-algorithms/src/main.c b/rsa-algorithms/src/main.c new file mode 100644 index 0000000..86d0112 --- /dev/null +++ b/rsa-algorithms/src/main.c @@ -0,0 +1,33 @@ +#include "rsa.h" +#include + +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; +} + diff --git a/rsa-algorithms/src/rsa.c b/rsa-algorithms/src/rsa.c new file mode 100644 index 0000000..6e58098 --- /dev/null +++ b/rsa-algorithms/src/rsa.c @@ -0,0 +1,81 @@ +#include "rsa.h" +#include +#include +#include + +// 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; +} +