c语言简单实现elgamal椭圆曲线算法

#include<cstdio>
#include<cmath>
#include<iostream>
#include<time.h>




using namespace std;
struct zuobiao
{
int x;
int y;
};


int  EX_gcd(int a, int b, int &s,int &t)//无问题
{
if (a == 0 && b == 0) {
return -1;
}
if (b == 0) {
s = 1;
t = 0;
return a;
}
int  d = EX_gcd(b, a%b, t,s);
t -= a / b*s;
return d;
}
int  f1(zuobiao P,zuobiao q,int a,int p) //求λ的值  这里的除法a/b=a*b^-1(modp)
{ int  k,c,b,e,t;
if ((P.x==q.x)&&(P.y==q.y)) { //此处只有加法规则的第三步,无(1)(2)
c = ((3 * q.x*q.x + a)%p+p)%p;
b= (2 *P.y);
EX_gcd(b, p, e,t);
while (e < 0) {
e = (e + p)% p;
}
k = (c*e+p)%p;
//cout << k << endl;
}
else {
c = ((q.y - P.y) % p + p ) % p;
b = ((q.x - P.x) % p + p) % p;
EX_gcd(b, p, e,t);
while (e < 0) {
e = (e + p) % p;
}
k = (c*e+p)%p;
}
/*cout << "输出k的值:" << endl;
cout << k << endl;*/
return k;
}






zuobiao add(zuobiao p,zuobiao g,int a,int n,int b) //abel群内的加法运算 a为曲线方程a,n为乘数,b为素数p
{
int  k;
int e;
for (int i = 0; i < n-1; i++){
k = f1(p, g, a,b);
e = p.x;
p.x = (k*k - p.x - g.x+b)%b;
while (p.x < 0) {
p.x = p.x + b;
}
p.y = (k*(e - p.x) - p.y + b) % b;
while (p.y < 0) {
p.y = p.y + b;
}
}
return p;


}
int qiujie(zuobiao g,int a,int b) //g为生成元,n为g的阶,a为椭圆曲线方程y^2=x^3+a*x+b中的a,b为大素数
{
int n;
zuobiao p;
p = g;
int  k;
int e;
int i;
for ( i = 1; i < 10000; i++) {
k = f1(p, g, a, b);
e = p.x;
p.x = (k*k - p.x - g.x + b) % b;
while (p.x < 0) {
p.x = p.x + b;
}
p.y = (k*(e - p.x) - p.y + b) % b;
while (p.y < 0) {
p.y = p.y + b;
}
if (p.x == g.x&&p.y == g.y) {
n = i; //此时n即为生成元的阶
break;
}
}
if (i == 10000) {
cout << "g不为该椭圆曲线的一个生成元,请重新举例!" << endl;
}
return n;


}


void encrypt(zuobiao g,zuobiao P,zuobiao m,int a,int r,int p)
{
zuobiao c1, c2;
c1 = g;
c1 = add(c1, g, a, r, p);
cout << "输出密文c1的值:" << endl;
cout << c1.x << " " << c1.y << endl;
c2 = P;
c2 = add(c2, P, a, r, p);
c2 = add(m, c2, a, 2, p);
cout << "输出密文c2的值:" << endl;
cout << c2.x << " " << c2.y << endl;
}
void decipher(zuobiao c2,zuobiao c1,int a,int d,int b) //g为生成元,c1 c2为密文,d为私钥,r为随机数,b为大素数
{
zuobiao p,m;
p = c1;
p = add(p, c1, a, d, b);
p.y = -p.y;
int k,e;
k = f1(c2, p, a, b);
e = c2.x;
m.x = ((k*k - c2.x - p.x)%b+ b) % b;
m.y = ((k*(e - m.x) - c2.y)%b + b) % b;
cout << "解密得到的明文为:" << endl;
cout << m.x << " " << m.y << endl;
}


int main()
{
int a, b; //椭圆曲线方程为y^2=x^3+a*x+b
cout << "请输入椭圆曲线方程a和b的值:" << endl;
cin >> a >> b;
int p;
cout << "请给定一个素数p:" << endl;
cin >> p;
if ((4 * a ^ 3 + 27 * b ^ 2) % p == 0) {
cout << "输入的p不满足条件!" << endl;
}
srand((unsigned)time(NULL));
int d; // 随机选择一个整数d;
//d = rand() % (n- 2)+2;
int n;//n为g的阶
cout << "请输入d:" << endl;
cin >> d; //d为私钥
zuobiao g;
cout << "请给定一个生成元G" << endl;
cin >> g.x >> g.y;
//n = qiujie(g, a, p);
zuobiao P = g;
P=add(P, g, a, d,p);
cout<<"输出P的值:"<<endl;
cout << P.x<<" "<<P.y << endl;
/*zuobiao P;
cout << "请输入公钥p的值:" << endl;
cin >> P.x >> P.y;
//cout << P.x << P.y << endl;*/
zuobiao m;//明文m
cout << "请输入明文m:" << endl;
cin >> m.x >> m.y;
int r;//随机数r
//r=rand()%n;
cout << "请输入r:" << endl;
cin >> r;
encrypt(g, P, m, a, r, p);
cout << "*************************" << endl;
cout << "下面为解密过程" << endl;
zuobiao c1, c2;
cout << "请输入密文c1:" << endl;
cin >> c1.x >> c1.y;
cout << "请输入密文c2:" << endl;
cin >> c2.x >> c2.y;
decipher(c2, c1, a, d, p);
return 0;

}
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
ElGamal算法是一种非对称加密算法,与RSA算法类似,它也是基于数论的,但是与RSA算法不同的是它的加密和解密使用的是同一个密钥对,而且加密和解密过程都需要进行一些随机化处理。 下面是ElGamal算法的加解密C语言实现: 加密过程: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> // 求模幂运算 a^b mod m long long mod_pow(long long a, long long b, long long m) { long long ans = 1; while (b > 0) { if (b & 1) { ans = (ans * a) % m; } a = (a * a) % m; b >>= 1; } return ans; } // 生成一个大素数 long long get_prime(long long min, long long max) { long long i, j; for (i = min; i <= max; i++) { for (j = 2; j <= sqrt(i); j++) { if (i % j == 0) { break; } } if (j > sqrt(i)) { return i; } } return -1; } // 生成一个随机数 long long get_random(long long min, long long max) { return rand() % (max - min + 1) + min; } int main() { long long p, g, x, y, k, m, c1, c2; srand(time(0)); // 生成大素数 p p = get_prime(10000, 20000); // 选择一个原根 g for (g = 2; g < p; g++) { int flag = 1; for (int i = 1; i < p - 1; i++) { if (mod_pow(g, i, p) == 1) { flag = 0; break; } } if (flag) { break; } } // 生成私钥 x x = get_random(2, p - 2); // 计算公钥 y y = mod_pow(g, x, p); // 加密 printf("请输入要加密的明文:"); scanf("%lld", &m); k = get_random(2, p - 2); c1 = mod_pow(g, k, p); c2 = m * mod_pow(y, k, p) % p; printf("密文为:(%lld, %lld)\n", c1, c2); return 0; } ``` 解密过程: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> // 求模幂运算 a^b mod m long long mod_pow(long long a, long long b, long long m) { long long ans = 1; while (b > 0) { if (b & 1) { ans = (ans * a) % m; } a = (a * a) % m; b >>= 1; } return ans; } int main() { long long p, x, c1, c2, m; scanf("%lld%lld%lld%lld", &p, &x, &c1, &c2); // 解密 m = c2 * mod_pow(c1, p - 1 - x, p) % p; printf("明文为:%lld\n", m); return 0; } ``` 其中,加密过程中,首先生成一个大素数p,然后选择一个原根g,然后生成私钥x和公钥y。加密时,选择一个随机数k,计算密文c1和c2。解密时,根据公式,将密文c1、c2、私钥x和大素数p带入即可计算出明文m。 需要注意的是,由于ElGamal算法加密过程中需要进行随机化处理,因此同样的明文在不同的加密过程中得到的密文是不同的,这也是ElGamal算法的特点之一。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值