Q6 Digital Signature With ECC
Q6 Digital Signature With ECC
h>
#include <iostream>
#include <string>
#include <random>
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);
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;
}
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);
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 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;
}
}
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 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");
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;
if (V.isInfinity || V.x % n == r) {
cout << "Signature is invalid!" << endl;
} else {
cout << "Signature is valid!" << endl;
}
return 0;
}