1.头文件部分
#include
#include
#include
2.求乘法逆元
int ecc_mod_inv(int a, int b)
{
int len = 0;
ecc_mod_inv_a(a, b, &len);
return ecc_mod_inv_b(a, b, len);
}
int ecc_mod_inv_a(int a, int b, int *len)
{
int d = 0;
int i = 0;
while(a)
{
d = b % a;
b = a;
a = d;
i++;
}
*len = i;
return 0;
}
int ecc_mod_inv_b(int a, int b, int len)
{
int c[len];
int d = 0;
int e = 0;
int f = 0;
int g = b;
int n = 0;
int i = 0;
memset(c, 0x00, sizeof(c));
while(a)
{
d = b % a;
c[i] = b / a;
b = a;
a = d;
i++;
}
d = 1;
e = c[i-2];
n = i-1;
i = 1;
while(i < n)
{
f = c[n-1-i] * e + d;
f %= g;
d = e;
e = f;
i++;
}
//e %= g;
if(len % 2 == 0) e = g - e;
return e;
}
3.求直线斜率
int ecc_get_u(int a, int p, int xp, int yp, int xq, int yq)
{
int b = yq - yp;
int c = xq - xp;
int d = 3 * xp * xp + a;
int e = 2 * yp;
int f = -1;
int g = 0;
int s = 0;
int t = 0;
if(xp != xq || yp != yq)
{
if(!c) return f;
if(!b) return 0;
if(b > 0 && c < 0)
{
c = -c;
b %= p;
c %= p;
if(c == 1) return p-b;
c = p - c;
g = ecc_mod_inv(c, p);
g = g * b % p;
return g;
}
else if(b > 0 && c > 0)
{
b %= p;
c %= p;
if(c == 1) return b;
g = ecc_mod_inv(c, p);
g = g * b % p;
return g;
}
else if(b < 0 && c > 0)
{
b = -b;
b %= p;
c %= p;
if(c == 1) return p-b;
b = p - b;
g = ecc_mod_inv(c, p);
g = g * b % p;
return g;
}
else if(b < 0 && c < 0)
{
b = -b;
c = -c;
b %= p;
c %= p;
if(c == 1) return b;
b = p - b;
c = p - c;
g = ecc_mod_inv(c, p);
g = g * b % p;
return g;
}
}
else
{
if(!e) return f;
if(!d) return 0;
b = d;
c = e;
if(b > 0 && c < 0)
{
c = -c;
b %= p;
c %= p;
if(c == 1) return p-b;
c = p - c;
g = ecc_mod_inv(c, p);
g = g * b % p;
return g;
}
else if(b > 0 && c > 0)
{
b %= p;
c %= p;
if(c == 1) return b;
g = ecc_mod_inv(c, p);
g = g * b % p;
return g;
}
else if(b < 0 && c > 0)
{
b = -b;
b %= p;
c %= p;
if(c == 1) return p-b;
b = p - b;
g = ecc_mod_inv(c, p);
g = g * b % p;
return g;
}
else if(b < 0 && c < 0)
{
b = -b;
c = -c;
b %= p;
c %= p;
if(c == 1) return b;
b = p - b;
c = p - c;
g = ecc_mod_inv(c, p);
g = g * b % p;
return g;
}
}
return -1;
}
4.椭圆曲线上的加法
int ecc_get_r(int a, int p, int xp, int yp, int xq, int yq, int *xr, int *yr)
{
int u = ecc_get_u(a, p, xp, yp, xq, yq);
int c = u * u;
int d = xp + xq;
int e = 0;
int f = 0;
//printf("u=[%d]\n", u);
if(u < 0)
{
*xr = -1;
*yr = -1;
return 0;
}
if(c >= d) *xr = (c - d) % p;
else *xr = p - (d - c) % p;
f = (u * *xr + yp) % p;
e = u * xp % p;
//printf("e=[%d], f=[%d]\n", e, f);
if(e >= f) *yr = (e - f) % p;
else *yr = p - (f - e) % p;
return 0;
}
5.椭圆曲线上的乘法
int ecc_pow_2_g(int a, int p, int xp, int yp, int n, int *xr, int *yr)
{
int xq = xp;
int yq = yp;
int i = 0;
for(i=0; i
{
ecc_get_r(a, p, xq, yq, xq, yq, &xq, &yq);
}
*xr = xq;
*yr = yq;
return 0;
}
int ecc_int_to_bit(int x, char *y)
{
int w = 0;
int i = 0;
//printf("x=[%d]\n");
for(i=29; i>=0; i--)
{
w = ((x >> i) & 1);
y[29-i] = w;
//printf("y[%d]=[%d]\n", 29-i, y[29-i]);
}
return 0;
}
int ecc_cons_mul(int a, int p, int w, int xp, int yp, int *xr, int *yr)
{
char y[31];
int i = 0;
int xh = 0;
int yh = 0;
int xq = 1;
int yq = 1;
int flag = 0;
//printf("w=[%d]\n", w);
ecc_int_to_bit(w, y);
for(i=0; i<30; i++)
{
if(y[i] == 1)
{
//printf("i=[%d]\n", i);
ecc_pow_2_g(a, p, xp, yp, 30-i, &xq, &yq);
if(xq == -1 || yq == -1)
{
*xr = -1;
*yr = -1;
return -1;
}
if(flag)
{
//printf("xq=[%d], yq=[%d]\n", xq, yq);
ecc_get_r(a, p, xh, yh, xq, yq, &xh, &yh);
if(xh == -1 || yh == -1)
{
*xr = -1;
*yr = -1;
return -1;
}
}
else
{
xh = xq;
yh = yq;
flag = 1;
}
}
}
*xr = xh;
*yr = yh;
return 0;
}
6.计算公钥
int ecc_get_pub(int a, int p, int k, int gx, int gy, int *kx, int *ky)
{
ecc_cons_mul(a, p, k, gx, gy, kx, ky);
return 0;
}
7.加密算法
int ecc_cxt_enc(int a, int p, int r, int mx, int my, int kx, int ky, int gx, int gy, int *sx, int *sy, int *tx, int *ty)
{
int ex;
int ey;
ecc_cons_mul(a, p, r, gx, gy, tx, ty);
ecc_cons_mul(a, p, r, kx, ky, &ex, &ey);
ecc_get_r(a, p, mx, my, ex, ey, sx, sy);
return 0;
}
8.解密算法
int ecc_cxt_dec(int a, int p, int k, int sx, int sy, int tx, int ty, int *mx, int *my)
{
int ex;
int ey;
ecc_cons_mul(a, p, k, tx, ty, &ex, &ey);
ey = -ey;
ecc_get_r(a, p, sx, sy, ex, ey, mx, my);
return 0;
}
9.主函数部分
int main()
{
int a[12] = {0};
int p = 199;
int k = 119;
int r = 133;
int i = 0;
a[0] = 2;
a[1] = 2;
a[4] = 76;
a[5] = 66;
ecc_get_pub(0, p, k, a[0], a[1], a+2, a+3);
printf("G=(%d,%d)\n", *(a+2), *(a+3));
ecc_cxt_enc(0, p, r, a[4], a[5], a[2], a[3], a[0], a[1], a+6, a+7, a+8, a+9);
printf("C1=(%d,%d)\n", *(a+6), *(a+7));
printf("C2=(%d,%d)\n", *(a+8), *(a+9));
ecc_cxt_dec(0, p, k, a[6], a[7], a[8], a[9], a+10, a+11);
printf("M=(%d,%d)\n", *(a+10), *(a+11));
return 0;
}