256位NIST素域椭圆曲线运算优化细节之一(单个素数p的加减法)

在素域椭圆曲线运算过程中,256位加法和减法运算结果常常位于区间[0,p)之外的情形,需要做+p或是-p的运算

256位NIST素域椭圆曲线参数p的生成公式为:

p = 2^256 − 2^224 + 2^192 + 2^96 − 1

按照符号将此式分解得:

p = (2^256 + 2^192 + 2^96) - (2^224 + 1)

转化为16进制并按64位分节,变成下面的形式:

+: 0000000000000001 0000000000000000 0000000100000000 0000000000000000
-: 0000000100000000 0000000000000000 0000000000000000 0000000000000001
=: ffffffff
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,需要选择合适的椭圆曲线参数。常用的椭圆曲线参数可以在NIST网站上找到。本例采用secp256k1椭圆曲线和相应参数。 定义椭圆曲线上的加法运算和点倍乘运算: ```c typedef struct { int x, y; } point_t; 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; } ``` 其中,`mod_inv`是求模意义下的乘法逆元函数。 接下来,定义密钥生成、加密和解密函数: ```c int rand_between(int a, int b) { return a + rand() % (b - a + 1); } 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); } 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); } 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; } } ``` 其中,`ecc_encode`是将字符编码为椭圆曲线上的点,`ecc_decode`是将椭圆曲线上的点解码为字符,`ecc_neg`是点的相反点。 完整代码如下:

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值