椭圆曲线上的群和构造方法

实数域上的群

  什么是椭圆曲线?

  椭圆曲线是点的集合。一般由方程 y 2 = x 3 + a x + b , 4 a 3 + 27 b 2 ≠ 0 y^2 = x^3+ax+b,4a^3+27b^2\neq0 y2=x3+ax+b4a3+27b2=0定义。(除去超奇异椭圆曲线)
在由椭圆曲线上的点构成集合上定义一个二元运算加法。对于椭圆曲线上的两个点 P P P和点 Q Q Q,过P和Q两点作一条直线,该直线与椭圆曲线交于第三点R’,R’关于x轴对称的点R就是 P + Q P+Q P+Q
  椭圆曲线上的点和无穷远点关于这个加法运算构成阿贝尔群。

阿贝尔群的四个属性:

  1. 闭包:如果P和Q是椭圆曲线上的点,那么 P + Q P+Q P+Q也是椭圆曲线上的点。
  2. 可结合。 ( P + Q ) + S =
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的椭圆曲线加密算法的实现,使用的是secp256k1椭圆曲线。 首先,需要定义椭圆曲线的参数和点结构体: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> // 定义有限域Fp和椭圆曲线y^2 = x^3 + ax + b (mod p) const int p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F; const int a = 0; const int b = 7; // 定义椭圆曲线上的点结构体 typedef struct { int x, y; } point_t; ``` 接下来,需要实现椭圆曲线上的加法和点倍乘运算: ```c // 求模意义下的乘法逆元 int mod_inv(int a, int m) { int x, y; int g = ext_gcd(a, m, &x, &y); if (g == 1) { return (x + m) % m; } else { return 0; } } // 扩展欧几里得算法 int ext_gcd(int a, int b, int* x, int* y) { if (b == 0) { *x = 1; *y = 0; return a; } else { int g = ext_gcd(b, a % b, y, x); *y -= a / b * (*x); return g; } } // 椭圆曲线上的加法运算 point_t ecc_add(point_t P, point_t Q) { point_t R; int lambda; if (P.x == Q.x && P.y == Q.y) { lambda = (3 * P.x * P.x + a) * mod_inv(2 * P.y, p); } else { lambda = (Q.y - P.y) * mod_inv(Q.x - P.x, p); } R.x = (lambda * lambda - P.x - Q.x + p) % p; R.y = (lambda * (P.x - R.x) - P.y + p) % p; return R; } // 椭圆曲线上的点倍乘运算 point_t ecc_mul(int d, point_t P) { point_t R = {0, 0}; while (d) { if (d & 1) { R = ecc_add(R, P); } P = ecc_add(P, P); d >>= 1; } return R; } ``` 然后,需要实现密钥生成、加密和解密函数: ```c // 生成随机私钥和对应的公钥 void ecc_gen_keypair(point_t G, int n, int* d, point_t* Q) { *d = rand_between(1, n - 1); *Q = ecc_mul(*d, G); } // 加密消息msg,返回密文C point_t ecc_encrypt(char* msg, int len, point_t G, point_t Q) { int k = rand_between(1, n - 1); point_t C1 = ecc_mul(k, G); point_t C2 = {0, 0}; for (int i = 0; i < len; i++) { C2 = ecc_add(C2, ecc_mul(k, ecc_encode(msg[i]))); } return ecc_add(C1, C2); } // 解密密文C,返回明文msg和长度len void ecc_decrypt(point_t C, int d, char* msg, int* len) { point_t C1 = ecc_mul(d, C.x); point_t C2 = ecc_mul(d, C.y); C2 = ecc_add(C2, ecc_neg(C1)); *len = 0; while (C2.x || C2.y) { msg[(*len)++] = ecc_decode(ecc_mul(d, C2.x).x); C2 = ecc_neg(C2); C2 = ecc_add(C2, ecc_encode(msg[*len - 1])); } for (int i = 0; i < *len / 2; i++) { char t = msg[i]; msg[i] = msg[*len - i - 1]; msg[*len - i - 1] = t; } } ``` 其中,`rand_between`是生成指定范围内的随机整数函数,`ecc_encode`是将字符编码为椭圆曲线上的点,`ecc_decode`是将椭圆曲线上的点解码为字符,`ecc_neg`是点的相反点。 最后,可以编写一个简单的测试程序: ```c int main() { // 选择secp256k1椭圆曲线的基点G和阶n point_t G = {0x79BE667EF9DCBBAC, 0x55A06295CE870B07}; int n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; // 生成随机密钥对 srand(time(NULL)); int d; point_t Q; ecc_gen_keypair(G, n, &d, &Q); printf("私钥d: %d\n", d); printf("公钥Q: (%llx, %llx)\n", Q.x, Q.y); // 加密消息 char msg[] = "hello world"; int len = strlen(msg); point_t C = ecc_encrypt(msg, len, G, Q); printf("密文C: (%llx, %llx)\n", C.x, C.y); // 解密消息 char dec[100]; int dec_len; ecc_decrypt(C, d, dec, &dec_len); printf("明文: %s\n", dec); return 0; } ``` 完整代码如下:

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值