C语言椭圆曲线加密算法
椭圆曲线加密算法简易的实现,主要就是针对点对点之间的转换
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <windows.h>
void MultipleP(int P[2], int multiple, int a, int b, int p, int A[2]);
void AddPandQ(int P[2], int Q[2], int a, int b, int p, int P_Q[2]);
int mod_invese(int d, int n);
int main(void)
{
int a;
int b;
int p;
int x;
int y;
int k;
int i = 0;
int multiple;
int feature;
int P[2], Q[2], P_Q[2], G[2], kPa[2], kG[2];
double run_time;
double dqFreq; //计时器频率
while (1)
{
printf("\n请输入所选择的功能:1.求椭圆曲线上的所有点\t2.求点与点的加法运算\t3.求点的倍数运算\t4.加解密运算\t5.退出程序!\nInput the feature you want:");
scanf("%d", &feature);
if (feature == 5)
{
return 0;
break;
}
printf("\n请输入整数a,b以及素数p:");
scanf("%d%d%d", &a, &b, &p);
switch (feature)
{
case 1:
printf("\n则椭圆曲线上的所有整点为:\n");
for (x = 0; x < p - 1; x++)
{
for (y = 0; y < p - 1; y++)
{
for (k = -pow(p, 2); k < pow(p, 2); k++)
{
if ((pow(x, 3) + a * x + b + k * p) == pow(y, 2))
{
i++;
printf(" [%2d,%2d] ", x, y);
printf(" [%2d,%2d] ", x, p - y);
}
}
}
}
printf("\n总计%d个点\n", 2 * i);
break;
case 2:
printf("\n请输入点P:\n");
for (k = 0; k < 2; k++)
scanf("%d", &P[k]);
printf("\n请输入点Q:\n");
for (k = 0; k < 2; k++)
scanf("%d", &Q[k]);
AddPandQ(P, Q, a, b, p, P_Q);
printf("\nP + Q = (%2d,%2d)", P_Q[0], P_Q[1]);
break;
case 3:
printf("\n请输入点P:\n");
for (k = 0; k < 2; k++)
scanf("%d", &P[k]);
printf("\n请输入要计算的倍数 multiple = ");
scanf("%d", &multiple);
MultipleP(P, multiple, a, b, p, P_Q);
printf("\n%dP = (%2d,%2d)", multiple, P_Q[0], P_Q[1]);
break;
case 4:
P[0] = 201;
P[1] = 5;
G[0] = 0;
G[1] = 376;
printf("\n公开参数为:(%2d,%2d)\n", a, b);
printf("\n生成元为:G=(%2d,%2d)\n", G[0], G[1]);
printf("\nA的公开钥为:Pa=(%2d,%2d)\n", P[0], P[1]);
printf("\n请输入要发送的消息:Pm:\n");
for (k = 0; k < 2; k++)
{
scanf("%d", &Q[k]);
}
LARGE_INTEGER time_start; //开始时间
LARGE_INTEGER time_over; //结束时间
LARGE_INTEGER f; //计时器频率
QueryPerformanceFrequency(&f);
dqFreq = (double)f.QuadPart;
QueryPerformanceCounter(&time_start); //计时开始
multiple = 386; // k=rand()%p;
MultipleP(G, multiple, a, b, p, kG);
printf("\n%dG = (%2d,%2d)", multiple, kG[0], kG[1]);
MultipleP(P, multiple, a, b, p, kPa);
AddPandQ(Q, kPa, a, b, p, P_Q);
printf("\nPm+kPa=(%2d,%2d)", P_Q[0], P_Q[1]);
printf("\n密文为:{(%2d,%2d),(%2d,%2d)}", kG[0], kG[1], P_Q[0], P_Q[1]);
//计时结束
QueryPerformanceCounter(&time_over); //计时结束
run_time = 1000000 * (time_over.QuadPart - time_start.QuadPart) / dqFreq;
printf("\n总计用时: %.2f us\n", run_time);
break;
default:
printf("\n请输入正确的功能编号!\n");
break;
}
}
}
void MultipleP(int P[2], int multiple, int a, int b, int p, int P_Q[2])
{
int k, i;
int Q[2];
for (i = 0; i < 2; i++)
{
Q[i] = P[i];
}
for (k = 0; k < multiple - 1; k++)
{
AddPandQ(P, Q, a, b, p, P_Q);
for (i = 0; i < 2; i++)
{
Q[i] = P_Q[i];
}
// printf("\n%dPa=(%2d, %2d)", k + 2, P_Q[0], P_Q[1]);
}
}
void AddPandQ(int P[2], int Q[2], int a, int b, int p, int P_Q[2])
{
int k;
int lamada_1, lamada_2, lamada;
if (P[0] == Q[0] && P[1] == Q[1])
{
lamada_1 = 3 * P[0] * P[0] + a;
lamada_2 = 2 * P[1];
}
else
{
lamada_1 = Q[1] - P[1];
lamada_2 = Q[0] - P[0];
// printf("\nlamada_1=%d", lamada_1);
// printf("\nlamada_2=%d", lamada_2);
}
if (lamada_2 != 0)
{
if (floor((double)(lamada_1 / lamada_2) + 0.5) != (double)lamada_1 / lamada_2)
{
k = mod_invese(lamada_2, p);
if (lamada_2 < 0)
lamada = -lamada_1 * k;
else
lamada = lamada_1 * k;
lamada = lamada >= 0 ? lamada % p : lamada % p + p;
// printf("\nlamada=%d", lamada);
}
else
{
lamada = lamada_1 / lamada_2 > 0 ? (lamada_1 / lamada_2) % p : (lamada_1 / lamada_2) % p + p;
}
P_Q[0] = lamada * lamada - P[0] - Q[0];
P_Q[0] = P_Q[0] > 0 ? P_Q[0] % p : P_Q[0] % p + p;
P_Q[1] = lamada * (P[0] - P_Q[0]) - P[1];
P_Q[1] = P_Q[1] >= 0 ? P_Q[1] % p : P_Q[1] % p + p;
// printf("\nlamada=%d", lamada);
// printf("\nP_Q[0]=%d", P_Q[0]);
// printf("\nP_Q[1]=%d", P_Q[1]);
}
else if (lamada_2 == 0)
{
P_Q[0] = p;
P_Q[1] = p;
}
}
int mod_invese(int d, int n) //求d模n的逆,n 为正整数
{
int a; //被除数
int b; //除数
int q; //商
int r;
int u = 0;
int v = 1;
int t;
a = n;
b = (d >= 0) ? (d % n) : -(d % n); //规定正负数mod(n)都取正;
while (b != 0)
{
q = (int)a / b;
r = a - b * q;
a = b;
b = r;
t = v;
v = u - q * v;
u = t; //把每次没有进行运算的v的值给u
} //辗转相除,直到余数b=0,跳出循环
if (a != 1)
return 0;
return ((u < 0) ? u + n : u); //返回的值都是mod(n)后的值,使得最后的值是正数;
}