You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WolfSSL中wc_ecc_mulmod()函数椭圆曲线计算一致性问题咨询

问题:WolfSSL中wc_ecc_mulmod计算(ra1×ra2)×G与ra1×(ra2×G)结果不一致

在使用WolfSSL的wc_ecc_mulmod()函数进行椭圆曲线计算时,发现当ra1和ra2为32位随机数时,计算(ra1×ra2)×G与ra1×(ra2×G)的结果不相等。尝试先计算ra3=ra1×ra2 mod prime后再乘以G,结果仍不一致,但ra1、ra2为较小数值时结果一致(如测试代码中点A与C相等)。请问如何实现(ra1×ra2)×G=ra1×(ra2×G)?

测试代码

#include <iostream>
#include <string>
#include <unistd.h>
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/ssl.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/sp_int.h>
#include <wolfssl/wolfcrypt/integer.h>
#include <wolfssl/wolfcrypt/wolfmath.h>
#include <wolfssl/wolfcrypt/sha.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/hash.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/aes.h>

using namespace std;

int main(){
ecc_key key;
int ret;
WC_RNG rng;
wc_ecc_init(&key);
wc_InitRng(&rng);
int curveId = ECC_SECP256R1;
int keySize = wc_ecc_get_curve_size_from_id(curveId);
ret = wc_ecc_make_key_ex(&rng, keySize, &key, curveId);

//get param of ecc curve
mp_int a,b,prime,order,ra,s;
mp_init_multi(&a,&b,&prime,&order,&ra,&s);
ret = mp_read_radix(&a,key.dp->Af,16);
cout<<"get mp_int af: "<<ret<<endl;
ret = mp_read_radix(&b,key.dp->Bf,16);
cout<<"get mp_int bf: "<<ret<<endl;
ret = mp_read_radix(&prime,key.dp->prime,16);
cout<<"get mp_int prime: "<<ret<<endl;
ret = mp_read_radix(&order,key.dp->order,16);
cout<<"get mp_int order: "<<ret<<endl;
ret = wc_ecc_gen_k(&rng,32,&ra,&order);
cout<<"get mp_int ra: "<<ret<<endl;
ret = mp_copy(&key.k,&s);
cout<<"get mp_int s: "<<ret<<endl;

ecc_point* pointG = wc_ecc_new_point();
ret = wc_ecc_get_generator(pointG,wc_ecc_get_curve_idx(ECC_SECP256R1));
cout<<"get ecc_point pointG: "<<ret<<endl;
ret = wc_ecc_is_point(pointG,&a,&b,&prime);
cout<<"point is on curve: "<<ret<<endl;

//tes1:n1 = 10,n2 = 33,n3 = n1*n2, A = n3*G,B = n2*G,C = n1*B=> A == C
mp_int n1,n2,n3;
mp_init_multi(&n1,&n2,&n3,NULL,NULL,NULL);
mp_set_int(&n1,10);
mp_set_int(&n2,33);
ret = mp_mulmod(&n1,&n2,&prime,&n3);
ecc_point* A = wc_ecc_new_point();
ecc_point* B =wc_ecc_new_point();
ecc_point* C =wc_ecc_new_point();
ret = wc_ecc_mulmod(&n3,pointG,A,&a,&prime,1);
cout<<"n3*G: "<<ret<<endl;
ret = wc_ecc_mulmod(&n1,pointG,B,&a,&prime,1);
cout<<"n1*G: "<<ret<<endl;
ret = wc_ecc_mulmod(&n2,B,C,&a,&prime,1);
cout<<"n2*B: "<<ret<<endl;
ret = wc_ecc_cmp_point(A,C);
cout<<"A is equal to C: "<<ret<<endl;

//test2:ra1,ra2 are big number ra3 = ra1*ra2, D = ra3*G,E = ra2*G,F = ra1*E=> D != F
mp_int ra1,ra2,ra3;
mp_init_multi(&ra1,&ra2,&ra3,NULL,NULL,NULL);
ret = wc_ecc_gen_k(&rng,32,&ra1,&order);
cout<<"get mp_int ra1: "<<ret<<endl;
ret = wc_ecc_gen_k(&rng,32,&ra2,&order);
cout<<"get mp_int ra2: "<<ret<<endl;
ret = mp_mulmod(&ra1,&ra2,&prime,&ra3);
ecc_point* D = wc_ecc_new_point();
ecc_point* E =wc_ecc_new_point();
ecc_point* F =wc_ecc_new_point();
ret = wc_ecc_mulmod(&ra3,pointG,D,&a,&prime,1);
cout<<"ra3*G: "<<ret<<endl;
ret = wc_ecc_mulmod(&ra1,pointG,E,&a,&prime,1);
cout<<"ra1*G: "<<ret<<endl;
ret = wc_ecc_mulmod(&ra2,E,F,&a,&prime,1);
cout<<"ra2*E: "<<ret<<endl;
ret = wc_ecc_cmp_point(D,F);
cout<<"D is equal to F: "<<ret<<endl;
return 0;

}

解决方案

核心问题:模运算对象错误

椭圆曲线标量乘法的本质是椭圆曲线群内的运算,标量需要对**曲线生成元G的阶(order)**取模,而非对曲线的素数模数(prime)取模。根据群论性质,对于生成元G,有k×G = (k mod n)×G,其中n是G的阶(即满足n×G=O的最小正整数,O为无穷远点)。

你的代码中错误地对prime取模,导致标量不符合群运算规则,因此结果不一致。

修复步骤

在test2部分,将模prime的代码替换为模order:

// 原错误代码
ret = mp_mulmod(&ra1,&ra2,&prime,&ra3);

// 修改后的正确代码
ret = mp_mulmod(&ra1,&ra2,&order,&ra3);

补充说明

  • 小数值测试正确是因为当ra1×ra2小于order时,mod prime和mod order的结果可能相同(比如secp256r1的order小于prime),但大数情况下会出现差异
  • WolfSSL的wc_ecc_mulmod函数不会自动对标量取模,必须由用户确保输入的标量是模order后的结果,否则计算结果会偏离椭圆曲线群的运算规则

内容的提问来源于stack exchange,提问作者zihao wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:15:05