testing
This commit is contained in:
14
Advanced-Encryption-Standard/README.md
Normal file
14
Advanced-Encryption-Standard/README.md
Normal 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.
|
||||||
28
Advanced-Encryption-Standard/build/Makefile
Normal file
28
Advanced-Encryption-Standard/build/Makefile
Normal 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
|
||||||
|
|
||||||
BIN
Advanced-Encryption-Standard/build/aes
Executable file
BIN
Advanced-Encryption-Standard/build/aes
Executable file
Binary file not shown.
9
Advanced-Encryption-Standard/include/aes.h
Normal file
9
Advanced-Encryption-Standard/include/aes.h
Normal 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
|
||||||
BIN
Advanced-Encryption-Standard/obj/aes.o
Normal file
BIN
Advanced-Encryption-Standard/obj/aes.o
Normal file
Binary file not shown.
BIN
Advanced-Encryption-Standard/obj/main.o
Normal file
BIN
Advanced-Encryption-Standard/obj/main.o
Normal file
Binary file not shown.
210
Advanced-Encryption-Standard/src/aes.c
Normal file
210
Advanced-Encryption-Standard/src/aes.c
Normal 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);
|
||||||
|
}
|
||||||
31
Advanced-Encryption-Standard/src/main.c
Normal file
31
Advanced-Encryption-Standard/src/main.c
Normal 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
21
Base64_Encoding/README.md
Normal 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.
|
||||||
28
Base64_Encoding/build/Makefile
Normal file
28
Base64_Encoding/build/Makefile
Normal 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
|
||||||
|
|
||||||
BIN
Base64_Encoding/build/base64_encoder
Executable file
BIN
Base64_Encoding/build/base64_encoder
Executable file
Binary file not shown.
9
Base64_Encoding/include/base64_encoder.h
Normal file
9
Base64_Encoding/include/base64_encoder.h
Normal 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
|
||||||
BIN
Base64_Encoding/obj/base64_encoder.o
Normal file
BIN
Base64_Encoding/obj/base64_encoder.o
Normal file
Binary file not shown.
BIN
Base64_Encoding/obj/main.o
Normal file
BIN
Base64_Encoding/obj/main.o
Normal file
Binary file not shown.
96
Base64_Encoding/src/base64_encoder.c
Normal file
96
Base64_Encoding/src/base64_encoder.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
39
Base64_Encoding/src/main.c
Normal file
39
Base64_Encoding/src/main.c
Normal 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
22
Caesar_Cipher/README.md
Normal 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.
|
||||||
|
|
||||||
27
Caesar_Cipher/build/Makefile
Normal file
27
Caesar_Cipher/build/Makefile
Normal 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
BIN
Caesar_Cipher/build/caesar_cipher
Executable file
Binary file not shown.
8
Caesar_Cipher/include/caesar_cipher.h
Normal file
8
Caesar_Cipher/include/caesar_cipher.h
Normal 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
|
||||||
|
|
||||||
BIN
Caesar_Cipher/obj/caesar_cipher.o
Normal file
BIN
Caesar_Cipher/obj/caesar_cipher.o
Normal file
Binary file not shown.
BIN
Caesar_Cipher/obj/main.o
Normal file
BIN
Caesar_Cipher/obj/main.o
Normal file
Binary file not shown.
21
Caesar_Cipher/src/caesar_cipher.c
Normal file
21
Caesar_Cipher/src/caesar_cipher.c
Normal 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
24
Caesar_Cipher/src/main.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
16
Data-Encryption-Standard/README.md
Normal file
16
Data-Encryption-Standard/README.md
Normal 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.
|
||||||
|
|
||||||
28
Data-Encryption-Standard/build/Makefile
Normal file
28
Data-Encryption-Standard/build/Makefile
Normal 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
|
||||||
|
|
||||||
BIN
Data-Encryption-Standard/build/des
Executable file
BIN
Data-Encryption-Standard/build/des
Executable file
Binary file not shown.
7
Data-Encryption-Standard/include/des.h
Normal file
7
Data-Encryption-Standard/include/des.h
Normal 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
|
||||||
BIN
Data-Encryption-Standard/obj/des.o
Normal file
BIN
Data-Encryption-Standard/obj/des.o
Normal file
Binary file not shown.
BIN
Data-Encryption-Standard/obj/main.o
Normal file
BIN
Data-Encryption-Standard/obj/main.o
Normal file
Binary file not shown.
76
Data-Encryption-Standard/src/des.c
Normal file
76
Data-Encryption-Standard/src/des.c
Normal 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);
|
||||||
|
}
|
||||||
25
Data-Encryption-Standard/src/main.c
Normal file
25
Data-Encryption-Standard/src/main.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
14
Diffie-Hellman-Key-Exchange/README.md
Normal file
14
Diffie-Hellman-Key-Exchange/README.md
Normal 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.
|
||||||
27
Diffie-Hellman-Key-Exchange/build/Makefile
Normal file
27
Diffie-Hellman-Key-Exchange/build/Makefile
Normal 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
|
||||||
BIN
Diffie-Hellman-Key-Exchange/build/diffie_hellman
Executable file
BIN
Diffie-Hellman-Key-Exchange/build/diffie_hellman
Executable file
Binary file not shown.
7
Diffie-Hellman-Key-Exchange/include/diffie_hellman.h
Normal file
7
Diffie-Hellman-Key-Exchange/include/diffie_hellman.h
Normal 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
|
||||||
BIN
Diffie-Hellman-Key-Exchange/obj/diffie_hellman.o
Normal file
BIN
Diffie-Hellman-Key-Exchange/obj/diffie_hellman.o
Normal file
Binary file not shown.
BIN
Diffie-Hellman-Key-Exchange/obj/main.o
Normal file
BIN
Diffie-Hellman-Key-Exchange/obj/main.o
Normal file
Binary file not shown.
21
Diffie-Hellman-Key-Exchange/src/diffie_hellman.c
Normal file
21
Diffie-Hellman-Key-Exchange/src/diffie_hellman.c
Normal 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;
|
||||||
|
}
|
||||||
42
Diffie-Hellman-Key-Exchange/src/main.c
Normal file
42
Diffie-Hellman-Key-Exchange/src/main.c
Normal 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;
|
||||||
|
}
|
||||||
78
Elliptic-Curve-Cryptography/README.md
Normal file
78
Elliptic-Curve-Cryptography/README.md
Normal 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.
|
||||||
18
Elliptic-Curve-Cryptography/build/Makefile
Normal file
18
Elliptic-Curve-Cryptography/build/Makefile
Normal 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
|
||||||
BIN
Elliptic-Curve-Cryptography/build/ecc
Executable file
BIN
Elliptic-Curve-Cryptography/build/ecc
Executable file
Binary file not shown.
35
Elliptic-Curve-Cryptography/include/ecc.h
Normal file
35
Elliptic-Curve-Cryptography/include/ecc.h
Normal 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
|
||||||
BIN
Elliptic-Curve-Cryptography/obj/ecc.o
Normal file
BIN
Elliptic-Curve-Cryptography/obj/ecc.o
Normal file
Binary file not shown.
BIN
Elliptic-Curve-Cryptography/obj/main.o
Normal file
BIN
Elliptic-Curve-Cryptography/obj/main.o
Normal file
Binary file not shown.
96
Elliptic-Curve-Cryptography/src/ecc.c
Normal file
96
Elliptic-Curve-Cryptography/src/ecc.c
Normal 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
|
||||||
|
}
|
||||||
|
|
||||||
92
Elliptic-Curve-Cryptography/src/ecc.c.bak
Normal file
92
Elliptic-Curve-Cryptography/src/ecc.c.bak
Normal 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
|
||||||
|
}
|
||||||
33
Elliptic-Curve-Cryptography/src/main.c
Normal file
33
Elliptic-Curve-Cryptography/src/main.c
Normal 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
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# cryptograph-projects Project
|
||||||
|
|
||||||
|
This is a C project generated with the setup tool.
|
||||||
15
Simple_Substitution/README.md
Normal file
15
Simple_Substitution/README.md
Normal 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.
|
||||||
28
Simple_Substitution/build/Makefile
Normal file
28
Simple_Substitution/build/Makefile
Normal 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
|
||||||
|
|
||||||
BIN
Simple_Substitution/build/substitution_cipher
Executable file
BIN
Simple_Substitution/build/substitution_cipher
Executable file
Binary file not shown.
7
Simple_Substitution/include/substitution_cipher.h
Normal file
7
Simple_Substitution/include/substitution_cipher.h
Normal 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
|
||||||
BIN
Simple_Substitution/obj/main.o
Normal file
BIN
Simple_Substitution/obj/main.o
Normal file
Binary file not shown.
BIN
Simple_Substitution/obj/substitution_cipher.o
Normal file
BIN
Simple_Substitution/obj/substitution_cipher.o
Normal file
Binary file not shown.
22
Simple_Substitution/src/main.c
Normal file
22
Simple_Substitution/src/main.c
Normal 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;
|
||||||
|
}
|
||||||
36
Simple_Substitution/src/substitution_cipher.c
Normal file
36
Simple_Substitution/src/substitution_cipher.c
Normal 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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
Vigenère_Cipher/README.md
Normal file
21
Vigenère_Cipher/README.md
Normal 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.
|
||||||
28
Vigenère_Cipher/build/Makefile
Normal file
28
Vigenère_Cipher/build/Makefile
Normal 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
|
||||||
|
|
||||||
BIN
Vigenère_Cipher/build/vigenere_cipher
Executable file
BIN
Vigenère_Cipher/build/vigenere_cipher
Executable file
Binary file not shown.
7
Vigenère_Cipher/include/vigenere_cipher.h
Normal file
7
Vigenère_Cipher/include/vigenere_cipher.h
Normal 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
BIN
Vigenère_Cipher/obj/main.o
Normal file
Binary file not shown.
BIN
Vigenère_Cipher/obj/vigenere_cipher.o
Normal file
BIN
Vigenère_Cipher/obj/vigenere_cipher.o
Normal file
Binary file not shown.
26
Vigenère_Cipher/src/main.c
Normal file
26
Vigenère_Cipher/src/main.c
Normal 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;
|
||||||
|
}
|
||||||
28
Vigenère_Cipher/src/vigenere_cipher.c
Normal file
28
Vigenère_Cipher/src/vigenere_cipher.c
Normal 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
21
XOR_Encryption/README.md
Normal 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.
|
||||||
27
XOR_Encryption/build/Makefile
Normal file
27
XOR_Encryption/build/Makefile
Normal 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
BIN
XOR_Encryption/build/xor_cipher
Executable file
Binary file not shown.
6
XOR_Encryption/include/xor_cipher.h
Normal file
6
XOR_Encryption/include/xor_cipher.h
Normal 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
BIN
XOR_Encryption/obj/main.o
Normal file
Binary file not shown.
BIN
XOR_Encryption/obj/xor_cipher.o
Normal file
BIN
XOR_Encryption/obj/xor_cipher.o
Normal file
Binary file not shown.
54
XOR_Encryption/src/main.c
Normal file
54
XOR_Encryption/src/main.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
10
XOR_Encryption/src/xor_cipher.c
Normal file
10
XOR_Encryption/src/xor_cipher.c
Normal 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
3
rsa-algorithms/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# rsa-algorithms Project
|
||||||
|
|
||||||
|
This is a C project generated with the setup tool.
|
||||||
28
rsa-algorithms/build/Makefile
Normal file
28
rsa-algorithms/build/Makefile
Normal 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
BIN
rsa-algorithms/build/rsa
Executable file
Binary file not shown.
8
rsa-algorithms/include/rsa.h
Normal file
8
rsa-algorithms/include/rsa.h
Normal 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
BIN
rsa-algorithms/obj/main.o
Normal file
Binary file not shown.
BIN
rsa-algorithms/obj/rsa.o
Normal file
BIN
rsa-algorithms/obj/rsa.o
Normal file
Binary file not shown.
33
rsa-algorithms/src/main.c
Normal file
33
rsa-algorithms/src/main.c
Normal 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
81
rsa-algorithms/src/rsa.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user