|

楼主 |
发表于 2022-6-2 16:36:31
|
显示全部楼层
ECC椭圆曲线加密
ECC的英文全称是: Elliptic Curve Cryptography - 椭圆曲线密码学,是基于有限域的椭圆曲线和复杂的椭圆曲线离散对数.
ECC实现了非对称加密所需要的大部分能力,包括: 加密(encryption)、签名(signatures )、秘钥交换(key exchange).
ECC被认为是RSA密码系统的最好继承者,相对于RSA,ECC的keys更小,在于RSA相同等级下能够更快地生成Key.
ECC的加密原理为:(以下字母为举例说明,与代码无关)
描述一条Fp上的椭圆曲线,常用到六个参量:T=(p,a,b,n,x,y)。
(p 、a 、b) 用来确定一条椭圆曲线,p为素数域内点的个数,a和b是其内的两个大数;
x,y为G基点的坐标,也是两个大数;
n为点G基点的阶;
以上六个量就可以描述一条椭圆曲线,有时候我们还会用到h(椭圆曲线上所有点的个数p与n相除的整数部分)。
现在我们描述一个利用椭圆曲线进行加密通信的过程:
1、选定一条椭圆曲线 Ep(a,b) 并取椭圆曲线上一点,作为基点P。
2、选择一个大数k作为私钥,并生成公钥 Q=kP。
3、将 Ep(a,b) 和点Q、P传给用户。
4、用户接到信息后 ,将待传输的明文编码到Ep(a,b)上的一点M,并产生一个随机整数r。
5、公钥加密(密文C是一个点对):
C={rP, M+rQ}
6、私钥解密(M + rQ - k(rP) ,解密结果就是点M。
代码如下:
- #include <iostream>
- #define Ea 20
- #define Eb 4
- #define Ep 29
- using namespace std;
- int fast_pow(int a, int b, int c)
- {
- int ans = 1; ///记录结果
- a = a % c; ///预处理,使得a处于c的数据范围之下
- while (b != 0)
- {
- if (b & 1)///奇数
- {
- ans = (ans * a) % c;///消除指数为奇数的影响
- }
- b >>= 1; ///二进制的移位操作,不断的遍历b的二进制位
- a = (a * a) % c; ///不断的加倍
- }
- return ans;
- }
- struct point {
- int x;
- int y;
- point():x(0),y(0){}
- point(int a, int b):x(a),y(b) { }
- bool operator==(const point& b) {
- return this->x == b.x && this->y == b.y;
- }
- point operator+(const point& b) {
- point result;
- if (*this == b) {
- long aaa = 3 * this->x * this->x + Ea;
- long bbb = 2 * this->y;
- //int m = (3 * this->x * this->x + Ea) / (2 * this->y) mod Ep;
- long m;
- if (aaa % bbb != 0) {
- m = ((aaa % Ep) * fast_pow(bbb, (Ep - 2), Ep)) % Ep;
- }
- else {
- m = (aaa / bbb) % Ep;
- }
- result.x = (m * m - 2 * this->x) % Ep;
- result.y = (m * (this->x - result.x) - this->y) % Ep;
- }
- else {
- long aaa = b.y - this->y;
- long bbb = b.x - this->x;
- if (bbb == 0) {
- return point(13, 23);
- }
- long m;
- if (aaa % bbb != 0) {
- m = ((aaa % Ep) * fast_pow(bbb, (Ep - 2), Ep)) % Ep;
- }
- else {
- m = (aaa / bbb) % Ep;
- }
- result.x = (m * m - this->x - b.x) % Ep;
- result.y = (m * (this->x - result.x) - this->y) % Ep;
- }
- if (result.x < 0) {
- result.x += Ep;
- }
- if (result.y < 0) {
- result.y += Ep;
- }
- return result;
- }
- point operator-() {
- this->y = Ep - this->y;
- return *this;
- }
- };
- void getG(point x,int& G) {
- point Gx = x;
- G = 1;
- int num = 0;
- do{
- cout<<G<<"x:" << Gx.x << " " << Gx.y << endl;
- Gx = Gx + x;
- G++;
- } while (Gx.x != x.x);
- G++;
- cout << G << "x:" << Gx.x << " " << Gx.y << endl;
- }
- point getNG(point x,int n) {
- point result = x;
- for (int i = 1; i < n; ++i) {
- result = result + x;
- }
- return result;
- }
- void print(point p) {
- cout << "[" << " " << p.x << "," << p.y << " " << "]" << endl;
- }
- int main()
- {
- //Alice
- //椭圆曲线 E29(20,4) 基点(13,23)
- //第一步,计算椭圆曲线的阶数
- int G;
- point* x=new point(13, 23);
- getG(*x, G);
- cout << "阶数为:" << G << endl;
- //求得G=36
- //第二步,选择一个私有密钥p(p<G)
- int p =25;
- //第三步,公开密钥K=p*(13,23)
- point K = getNG(*x, p);
- //将 曲线 基点 密钥 公开
- cout << "公开密钥:"<< endl;
- print(K);
- //Bob
- //第四步,需要加密的信息msg,并将msg按照某种编码方式编码到曲线上一点M
- int msg = 13;
- cout << "需要加密的信息:" << msg << endl;;
- point M(13,23);
- //第五步,产生一个随机数r<G
- //srand(unsigned(time(NULL)));
- int r = 6;
- //第六步,计算c1=M+r*K
- // c2=r*(13,23)
- //(c1,c2)
- point c1 = M;
- for (int i = 0; i < r; ++i) {
- c1 = c1 + K;
- }
- point c2=*x;
- for (int i = 1; i < r; ++i) {
- c2 = c2 + *x;
- }
- cout << "密文为:" << endl;;
- print(c1);
- print(c2);
- //Alice解密
- //第七步:计算c1-p*c2
- point c3;
- point c4=*x;
- p = p*r % G;
- for (int i = 1; i < p; ++i) {
- c4 = c4 + *x;
- }
- c3 = c1 + (-c4);
- cout << "明文为:" << c3.x << endl;
- return 0;
- }
复制代码
|
|