0% found this document useful (0 votes)
9 views9 pages

Q6 Digital Signature With ECC

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)
9 views9 pages

Q6 Digital Signature With ECC

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
You are on page 1/ 9

#include <NTL/ZZ.

h>
#include <iostream>
#include <string>
#include <random>

using namespace std;


using namespace NTL;

ZZ stringToZZ(const string &str) {


ZZ result = ZZ(0);
for (char ch : str) {
result *= 256; // Shift left by 8 bits
result += static_cast<unsigned char>(ch);
}
return result;
}

ZZ mypow(ZZ a, ZZ b){
ZZ result = ZZ(1);
ZZ multi = ZZ(a);
while(b > 0){
if(b % 2 == 1){
result *= multi;
}
multi *= multi;
b >>= 1;
}
return result;
}

ZZ generate_large_number(int bits){
ZZ value = ZZ(1);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 1);

for(int i = 0; i < bits; i++){


if(dis(gen) == 0){
value += mypow(ZZ(2), ZZ(i));
}
}

return value;
}

int randomNumber(){
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, (int)1e9);

return dis(gen);
}

ZZ myPowModN(ZZ a, ZZ b, ZZ mod){
ZZ result = ZZ(1);
ZZ multi = ZZ(a);
while(b > 0){
if(b%2 == 1){
result *= multi;
result %= mod;
}
multi *= multi;
multi %= mod;
b = b>>1;
}
return result%mod;
}

bool myProbPrime(ZZ number){


if(number < 2 || number %2 == 0) return false;

ZZ d = number - 1;
ZZ s = ZZ(0);
while(d % 2 == 0){
s++;
d /= 2;
}

ZZ random_between_two_and_n_minus_2 = number/randomNumber();

ZZ x_a_power_d_mod_n =
myPowModN(random_between_two_and_n_minus_2, d, number);

if(x_a_power_d_mod_n == 1 || x_a_power_d_mod_n == (number - 1)){


return true;
}
int tries = 2000;

while(tries > 0){


if(x_a_power_d_mod_n == 1 || x_a_power_d_mod_n == (number -
1)){
return true;
}
x_a_power_d_mod_n = myPowModN(x_a_power_d_mod_n, ZZ(2),
number);
tries--;
}
return false;
}

ZZ generate_prime(int bits){
ZZ prime;
// generate large number
int tries = 0;
ZZ number = generate_large_number(bits);
while(!myProbPrime(number)){
number = generate_large_number(bits);
cout<<number<<endl;
tries++;
}
cout<<"Number of tries: "<<tries<<endl;

return number;

ZZ extended_gcd(ZZ a, ZZ b, ZZ& x, ZZ& y){


if(a == 0){
x = 0;
y = 1;
return b;
}

ZZ x1, y1;
ZZ gcd = extended_gcd(b%a, a, x1, y1);

x = y1 - (b/a) * x1;
y = x1;

return gcd;
}

ZZ modInv(ZZ e, ZZ d){
ZZ x, y;
ZZ gcd = extended_gcd(e, d, x, y);

if(gcd != 1){
return ZZ(-1);
}else{
return x%d;
}
}

// Define the elliptic curve parameters


struct EllipticCurve {
ZZ a; // Coefficient a in the curve equation
ZZ b; // Coefficient b in the curve equation
ZZ p; // Prime modulus
};

// Define a point on the curve


struct Point {
ZZ x;
ZZ y;
bool isInfinity; // To represent the point at infinity

Point() : x(0), y(0), isInfinity(true) {}


Point(ZZ x, ZZ y) : x(x), y(y), isInfinity(false) {}
};

// Check if a point is valid on the elliptic curve


bool isPointOnCurve(const EllipticCurve &curve, const Point &P) {
if (P.isInfinity) return true; // Infinity point is valid
ZZ lhs = PowerMod(P.y, 2, curve.p); // y^2 mod p
ZZ rhs = (PowerMod(P.x, 3, curve.p) + curve.a * P.x + curve.b) %
curve.p; // x^3 + ax + b mod p
return lhs == rhs;
}

// Add two points on the elliptic curve


Point pointAdd(const EllipticCurve &curve, const Point &P, const
Point &Q) {
if (P.isInfinity) return Q;
if (Q.isInfinity) return P;

if (P.x == Q.x && (P.y != Q.y || P.y == 0)) {


return Point(); // Point at infinity (P + (-P) = O)
}

ZZ lambda;
if (P.x == Q.x && P.y == Q.y) {
// Point doubling
lambda = (3 * myPowModN(P.x, ZZ(2), curve.p) + curve.a) *
modInv(2 * P.y, curve.p) % curve.p;
} else {
// Regular addition
lambda = (Q.y - P.y) * modInv(Q.x - P.x, curve.p) % curve.p;
}

ZZ xr = (PowerMod(lambda, 2, curve.p) - P.x - Q.x) % curve.p;


ZZ yr = (lambda * (P.x - xr) - P.y) % curve.p;

if (xr < 0) xr += curve.p;


if (yr < 0) yr += curve.p;

return Point(xr, yr);


}

// Multiply a point by a scalar (scalar multiplication)


Point scalarMultiply(const EllipticCurve &curve, const Point &P,
const ZZ &k) {
Point result; // Start with the point at infinity
Point base = P;

ZZ k_copy = k;
while (k_copy > 0) {
if (k_copy % 2 == 1) {
result = pointAdd(curve, result, base);
}
base = pointAdd(curve, base, base);
k_copy /= 2;
}

return result;
}

int main() {
// Define curve parameters (NIST P-192 example)
EllipticCurve curve;
curve.a = to_ZZ(-3);
curve.b =
to_ZZ("2455155546008943817740293915197451784769108058161191238065");
curve.p =
to_ZZ("6277101735386680763835789423207666416083908700390324961279");

// Define the base point G


Point
G(to_ZZ("602046282375688656758213480587526111916698976636884684818")
,
to_ZZ("1740503322936220314048575522802194103640234889273
86650641"));
// Define the order of the base point
ZZ n =
to_ZZ("6277101735386680763835789423176059013767194773182842284081");

// Check if G is on the curve


if (!isPointOnCurve(curve, G)) {
cerr << "Error: Base point G is not on the curve!" << endl;
return 1;
}

cout << "Base point G is valid." << endl;

// Step 1: Key generation


ZZ d = RandomBnd(n); // Private key: Random number in [1, n-1]
Point Q = scalarMultiply(curve, G, d); // Public key: Q = d * G

cout << "Private key (d): " << d << endl;


cout << "Public key (Q): (" << Q.x << ", " << Q.y << ")" <<
endl;

// Step 2: Sign a message (using hash = message for simplicity)


const string message = "Hello, ECC!";
ZZ hash = (stringToZZ(message)) % n; // Simplified hash (ensure
it fits in [1, n-1])

ZZ k = RandomBnd(n - 1) + 1; // Random k in [1, n-1]


Point R = scalarMultiply(curve, G, k);
ZZ r = R.x % n;

if (r == 0) {
cerr << "Error: r is zero. Choose a different k." << endl;
return 1;
}
ZZ s = (modInv(k, n) * (hash + d * r)) % n;
if (s == 0) {
cerr << "Error: s is zero. Choose a different k." << endl;
return 1;
}

cout << "Signature: (r, s) = (" << r << ", " << s << ")" <<
endl;

// Step 3: Verify the signature


ZZ w = modInv(s, n);
ZZ u1 = (hash * w) % n;
ZZ u2 = (r * w) % n;

Point P1 = scalarMultiply(curve, G, u1);


Point P2 = scalarMultiply(curve, Q, u2);
Point V = pointAdd(curve, P1, P2);

if (V.isInfinity || V.x % n == r) {
cout << "Signature is invalid!" << endl;
} else {
cout << "Signature is valid!" << endl;
}

return 0;
}

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy