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

View File

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

View File

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

Binary file not shown.

View File

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

Binary file not shown.

Binary file not shown.

View File

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

View File

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

View File

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