testing
This commit is contained in:
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;
|
||||
}
|
||||
Reference in New Issue
Block a user