#include <stdio.h>
#include <stdlib.h>
// 计算模幂运算 a^b % mod
long long mod_pow(long long a, long long b, long long mod) {
long long result = 1;
a = a % mod;
while (b > 0) {
if (b & 1)
result = (result * a) % mod;
b = b >> 1;
a = (a * a) % mod;
}
return result;
}
// 扩展欧几里得算法,用于计算模逆元
long long extended_gcd(long long a, long long b, long long *x, long long *y) {
if (b == 0) {
*x = 1;
*y = 0;
return a;
}
long long x1, y1;
long long gcd = extended_gcd(b, a % b, &x1, &y1);
*x = y1;
*y = x1 - (a / b) * y1;
return gcd;
}
// 计算模逆元
long long mod_inverse(long long a, long long mod) {
long long x, y;
long long gcd = extended_gcd(a, mod, &x, &y);
if (gcd != 1) {
printf("Modular inverse does not exist!\n");
return -1;
}
return (x % mod + mod) % mod;
}
// ElGamal签名算法
void elgamal_sign(long long p, long long a, long long x, long long h_m, long long k, long long *r, long long *s) {
*r = mod_pow(a, k, p);
long long k_inv = mod_inverse(k, p - 1);
*s = (k_inv * (h_m - x * (*r))) % (p - 1);
if (*s < 0)
*s += p - 1;
}
// ElGamal验证算法
int elgamal_verify(long long p, long long a, long long y, long long h_m, long long r, long long s) {
long long left = mod_pow(y, r, p) * mod_pow(r, s, p) % p;
long long right = mod_pow(a, h_m, p);
return left == right;
}
int main() {
long long p, a, x, h_m, k;
long long r, s;
// 从键盘输入p、a、用户私钥x、消息m的散列码H(m)、签名的随机数k
printf("Enter prime number p: ");
scanf("%lld", &p);
printf("Enter primitive root a: ");
scanf("%lld", &a);
printf("Enter private key x: ");
scanf("%lld", &x);
printf("Enter hash of message H(m): ");
scanf("%lld", &h_m);
printf("Enter random number k: ");
scanf("%lld", &k);
// 生成公钥y
long long y = mod_pow(a, x, p);
// 进行签名
elgamal_sign(p, a, x, h_m, k, &r, &s);
printf("Signature (r, s): (%lld, %lld)\n", r, s);
// 进行验证
int valid = elgamal_verify(p, a, y, h_m, r, s);
if (valid)
printf("Signature is valid.\n");
else
printf("Signature is invalid.\n");
return 0;
}
输出结果大一点
最新发布