0% found this document useful (0 votes)
15 views4 pages

Q5 ECC Without Library

Uploaded by

Aravind krishna
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views4 pages

Q5 ECC Without Library

Uploaded by

Aravind krishna
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

#include <iostream>

#include <NTL/ZZ.h>
#include <NTL/ZZ_p.h>

using namespace std;


using namespace NTL;

// Define the elliptic curve parameters for NIST P-192


const char* PRIME_P =
"6277101735386680763835789423207666416083908700390324961279";
const char* A = "-3";
const char* B =
"2455155546008943817740293915197451784769108058161191238065";
const char* GX =
"602046282375688656758213480587526111916698976636884684818";
const char* GY =
"174050332293622031404857552280219410364023488927386650641";
const char* N =
"6277101735386680763835789423176059013767194773182842284081";

struct Point {
ZZ_p x, y;
bool is_infinity = false;

Point() : is_infinity(true) {}
Point(ZZ_p x, ZZ_p y) : x(x), y(y), is_infinity(false) {}
};

// Function to add two points on the curve


Point point_add(const Point& P, const Point& Q, const ZZ_p& a) {
if (P.is_infinity) return Q;
if (Q.is_infinity) return P;

if (P.x == Q.x && P.y == -Q.y) return Point();


ZZ_p m;
if (P.x == Q.x && P.y == Q.y) {
m = (3 * sqr(P.x) + a) / (2 * P.y);
} else {
m = (Q.y - P.y) / (Q.x - P.x);
}

ZZ_p rx = sqr(m) - P.x - Q.x;


ZZ_p ry = m * (P.x - rx) - P.y;

return Point(rx, ry);


}

// Scalar multiplication: k * P
Point scalar_mult(const ZZ& k, const Point& P, const ZZ_p& a) {
Point result; // Infinity
Point current = P;
ZZ n = k;

while (n > 0) {
if (n % 2 == 1) {
result = point_add(result, current, a);
}
current = point_add(current, current, a);
n /= 2;
}

return result;
}

int main() {
// Initialize finite field
ZZ p;
conv(p, PRIME_P);
ZZ_p::init(p);

// Define curve parameters


ZZ_p a, b;
conv(a, A);
conv(b, B);

// Base point G
ZZ_p gx, gy;
conv(gx, GX);
conv(gy, GY);
Point G(gx, gy);

// Order of the curve


ZZ n;
conv(n, N);

// Generate receiver's private key and public key


ZZ private_key = RandomBnd(n); // Receiver's private key
Point public_key = scalar_mult(private_key, G, a); // Receiver's
public key

// Plaintext (message as a point on the curve)


Point M(ZZ_p(12345), ZZ_p(67890)); // Example point (M must be
on the curve)

// Sender generates a random ephemeral key


ZZ k = RandomBnd(n);
Point C1 = scalar_mult(k, G, a);
Point C2 = point_add(M, scalar_mult(k, public_key, a), a);
// Ciphertext: (C1, C2)
cout << "Ciphertext C1: (" << C1.x << ", " << C1.y << ")" <<
endl;
cout << "Ciphertext C2: (" << C2.x << ", " << C2.y << ")" <<
endl;

// Decryption
Point kQ = scalar_mult(private_key, C1, a);
Point decrypted_message = point_add(C2, Point(kQ.x, -kQ.y), a);

cout << "Decrypted Message: (" << decrypted_message.x << ", " <<
decrypted_message.y << ")" << endl;

return 0;
}

You might also like