在crypto++中有没有什么方法可以检查EC是否包含一个具有给定x坐标的点?
一个解决方案是求解给定x的EC多项式。方程的一边已经用代码完成了。我“只”需要计算它的根(在有限域上)
//clang++ -o ectest ectest.cpp -lcryptopp
#include "cryptopp/eccrypto.h"
#include "cryptopp/oids.h"
int main(int argc, char* argv[]) {
using namespace CryptoPP;
typedef DL_GroupParameters_EC<ECP> GroupParameters;
typedef DL_GroupParameters_EC<ECP>::Element Element;
GroupParameters group;
group.Initialize(ASN1::secp256k1());
//I want to check if the EC has a point with x-cooridnate x=13
Integer x = 13;
Integer ecmod = group.GetCurve().GetField().GetModulus();
ModularArithmetic ma = ModularArithmetic(ecmod);
//the following equation need to be solved:
//y^2 = x^3 + Ax + B \mod ecmod
Integer x3 = ma.Multiply(x,x);
x3 = ma.Multiply(x3,x);
Integer xa = ma.Multiply(group.GetCurve().GetA(),x);
Integer xb = group.GetCurve().GetB();
Integer sr = ma.Add(x3,xa);
sr = ma.Add(sr,xb);
//y^2 = sr
//how to compute the root out of sr?
//or is there any other way to check if the EC contains a point with x?
}
2条答案
按热度按时间v1l68za41#
可以,库支持点的压缩和解压缩,解压缩时,库必须找到
y
。DecodePoint的标头
返回的错误
您可以将点构造为压缩的,或者最好使用DecodePoint中的这一部分;只需将下面几行代码添加到代码中;
产出
20267456347483554069520440766283645831919514026818877192810320909941447705364
注意:如果使用
最后会有一个点,图书馆警告过这一点。
fd3cxomn2#
尽管您已经有了有效且简单的answer,但我仍然决定用纯C从头开始实现我自己的解决方案,因为您的任务非常有趣。
我的大型解决方案没有使用Crypto,而是尝试用C从头开始实现所有算法。它只是出于好奇心和科学及教育目的。它并不打算像纯Crypto解决方案那样快速和简单。
众所周知,如果模是任意形式的任意素数,则可以通过众所周知的非常快速的Tonelli Shanks算法来求平方根,这是以下代码的主要部分。
如果模是
p % 4 == 3
形式的素数,则它的根也可以通过公式root = n^((p + 1) / 4) % p
容易地找到,这比Shanks Tonelli算法短得多,但是Shanks Tonelli对所有情况都有效,即使当p % 4 != 3
时。除了上面提到的算法,我还使用了平方和Euler's Criterion的模指数。
曲线Secp256k1的参数取自here和here:
我的代码可以在编译后立即运行,它在控制台上显示所有计时和结果,请参见下面代码后的示例输出。出于测试目的,我迭代范围[0..50]内的所有X,并显示其中哪些为Y给予有效的根。众所周知,X的50%左右的值将给出正确的解决方案。
为了编译我的程序除了标准的C++库我只使用GMP库为任意整数算术。它可以安装在Linux通过
sudo apt install libgmp-dev
。并在Windows安装VCPKG包管理器后,你可以做vcpkg install gmp
,加上Windows将需要手动提供vckpg包括路径和链接库。我测试了编译和工作的程序在CLang和MSVC。也可以点击下面的
Try it online!
链接在GodBolt服务器上在线测试程序的运行。Try it online!
控制台输出: