使用 Crypto++ 在 secp521r1 上进行标量乘法
Scalar multiplication on secp521r1 using Crypto++
我正在用 C++ 为椭圆曲线中的标量乘法编写以下代码。当我不初始化点的值时,代码运行。但是当我这样做时,它给了我 nullptr 错误。
我试过下面的代码:
ECP r1;
ECPPoint basepoint = ECPPoint(2,3);
ECPPoint point;
ECPPoint s1= ecp.ScalarMultiply(basepoint, x1);
错误:
CryptoPP::ECP::GetField(...) returned nullptr.
ERROR: CryptoPP::ECP::GetField(...) returned nullptr.
对于 Crypto++,您需要加载一条曲线。根据您发布的代码,它看起来并没有完成。加载曲线加载曲线的域参数。对于素数域上的曲线,域参数为 {a,b,p,G,n,h}
,其中 a
和 b
为系数,p
为模,G
为基点顺序为 N,n
是顺序,h
是顺序辅因子。您可以在 eccrypto.cpp
.
中看到它们
对于 secp521r1
最简单的方法可能是按照以下几行。 secp256r1
用于使输出更小,但您应该改用 secp521r1
。
#include "integer.h"
#include "eccrypto.h"
#include "osrng.h"
#include "oids.h"
#include <iostream>
#include <iomanip>
int main(int argc, char* argv[])
{
using namespace CryptoPP;
typedef DL_GroupParameters_EC<ECP> GroupParameters;
typedef DL_GroupParameters_EC<ECP>::Element Element;
AutoSeededRandomPool prng;
GroupParameters group;
group.Initialize(ASN1::secp256r1());
// private key
Integer x(prng, Integer::One(), group.GetMaxExponent());
std::cout << "Private exponent:" << std::endl;
std::cout << " " << std::hex << x << std::endl;
// public key
Element y = group.ExponentiateBase(x);
std::cout << "Public element:" << std::endl;
std::cout << " " << std::hex << y.x << std::endl;
std::cout << " " << std::hex << y.y << std::endl;
// element addition
Element u = group.GetCurve().Add(y, ECP::Point(2,3));
std::cout << "Add:" << std::endl;
std::cout << " " << std::hex << u.x << std::endl;
std::cout << " " << std::hex << u.y << std::endl;
// scalar multiplication
Element v = group.GetCurve().ScalarMultiply(u, Integer::Two());
std::cout << "Mult:" << std::endl;
std::cout << " " << std::hex << v.x << std::endl;
std::cout << " " << std::hex << v.y << std::endl;
return 0;
}
用g++ test.cxx ./libcryptopp.a -o test.exe
编译代码。
运行 代码生成:
$ ./test.exe
Private exponent:
b48e35e8d60918f815857503b034681bc59db689dee0ffc35a140e365bb056dch
Public element:
bb9c8daaace9712f368bc98cf004a4594a14f9c330e2db141906ec67f05ab8d8h
e37e5e161aae15f54f20d67b665311717305932a1479427fe063d84c5be82a1dh
Add:
f5055cd23f23f5721d8a5f6f87bd61206e972a97c19478200cb0b1f24af398ach
107a532732098c4d051efc7f54d9bda78020a6e68f95e01a33700bab56a91f9ah
Mult:
46628d3e4f43da4fd001c652682d33f608c34ce3cf6c13f45b9bd014cbb83ed4h
3b58f98bd0d70196036b77f6fcca6fe206bdf3beda4b2b604d5cb8ae0327a57ch
DL_GroupParameters_EC<ECP> group
看起来很不寻常,因为您使用的是 lower-level 基本接口。我认为这就是您希望基于示例代码的地方。
一般而言,与 EC 齿轮相关的对象层次结构 is/are 如下所示。它同时使用 "is a" 或 "has a" 关系。例如,签名者和解密者各自 "has a" 个私钥。私钥 "is a" GroupParameters.
Encryptor
+- Public key
+- Group parameters
+- Curve
+- Field
Decryptor
+- Private key
+- Group parameters
+- Curve
+- Field
Verifier
+- Public key
+- Group parameters
+- Curve
+- Field
Signer
+- Private key
+- Group parameters
+- Curve
+- Field
例如,Signer 是协议,并在单个包中实现您需要的一切。签名者下面是私钥,它执行乘法和求幂。私钥下方是字段和曲线。依此类推,直到你得到系数和模数。
话虽如此,您通常希望使用更高级别的对象之一。大多数人使用加密器、解密器、Public 密钥和私钥。大多数人不需要深入了解,例如 GroupParameters 或 Curves 等对象。
您可能还对 Crypto++ wiki 中的 Crypto++ Manual and Elliptic Curve Cryptography 感兴趣。
我正在用 C++ 为椭圆曲线中的标量乘法编写以下代码。当我不初始化点的值时,代码运行。但是当我这样做时,它给了我 nullptr 错误。
我试过下面的代码:
ECP r1;
ECPPoint basepoint = ECPPoint(2,3);
ECPPoint point;
ECPPoint s1= ecp.ScalarMultiply(basepoint, x1);
错误:
CryptoPP::ECP::GetField(...) returned nullptr.
ERROR: CryptoPP::ECP::GetField(...) returned nullptr.
对于 Crypto++,您需要加载一条曲线。根据您发布的代码,它看起来并没有完成。加载曲线加载曲线的域参数。对于素数域上的曲线,域参数为 {a,b,p,G,n,h}
,其中 a
和 b
为系数,p
为模,G
为基点顺序为 N,n
是顺序,h
是顺序辅因子。您可以在 eccrypto.cpp
.
对于 secp521r1
最简单的方法可能是按照以下几行。 secp256r1
用于使输出更小,但您应该改用 secp521r1
。
#include "integer.h"
#include "eccrypto.h"
#include "osrng.h"
#include "oids.h"
#include <iostream>
#include <iomanip>
int main(int argc, char* argv[])
{
using namespace CryptoPP;
typedef DL_GroupParameters_EC<ECP> GroupParameters;
typedef DL_GroupParameters_EC<ECP>::Element Element;
AutoSeededRandomPool prng;
GroupParameters group;
group.Initialize(ASN1::secp256r1());
// private key
Integer x(prng, Integer::One(), group.GetMaxExponent());
std::cout << "Private exponent:" << std::endl;
std::cout << " " << std::hex << x << std::endl;
// public key
Element y = group.ExponentiateBase(x);
std::cout << "Public element:" << std::endl;
std::cout << " " << std::hex << y.x << std::endl;
std::cout << " " << std::hex << y.y << std::endl;
// element addition
Element u = group.GetCurve().Add(y, ECP::Point(2,3));
std::cout << "Add:" << std::endl;
std::cout << " " << std::hex << u.x << std::endl;
std::cout << " " << std::hex << u.y << std::endl;
// scalar multiplication
Element v = group.GetCurve().ScalarMultiply(u, Integer::Two());
std::cout << "Mult:" << std::endl;
std::cout << " " << std::hex << v.x << std::endl;
std::cout << " " << std::hex << v.y << std::endl;
return 0;
}
用g++ test.cxx ./libcryptopp.a -o test.exe
编译代码。
运行 代码生成:
$ ./test.exe
Private exponent:
b48e35e8d60918f815857503b034681bc59db689dee0ffc35a140e365bb056dch
Public element:
bb9c8daaace9712f368bc98cf004a4594a14f9c330e2db141906ec67f05ab8d8h
e37e5e161aae15f54f20d67b665311717305932a1479427fe063d84c5be82a1dh
Add:
f5055cd23f23f5721d8a5f6f87bd61206e972a97c19478200cb0b1f24af398ach
107a532732098c4d051efc7f54d9bda78020a6e68f95e01a33700bab56a91f9ah
Mult:
46628d3e4f43da4fd001c652682d33f608c34ce3cf6c13f45b9bd014cbb83ed4h
3b58f98bd0d70196036b77f6fcca6fe206bdf3beda4b2b604d5cb8ae0327a57ch
DL_GroupParameters_EC<ECP> group
看起来很不寻常,因为您使用的是 lower-level 基本接口。我认为这就是您希望基于示例代码的地方。
一般而言,与 EC 齿轮相关的对象层次结构 is/are 如下所示。它同时使用 "is a" 或 "has a" 关系。例如,签名者和解密者各自 "has a" 个私钥。私钥 "is a" GroupParameters.
Encryptor
+- Public key
+- Group parameters
+- Curve
+- Field
Decryptor
+- Private key
+- Group parameters
+- Curve
+- Field
Verifier
+- Public key
+- Group parameters
+- Curve
+- Field
Signer
+- Private key
+- Group parameters
+- Curve
+- Field
例如,Signer 是协议,并在单个包中实现您需要的一切。签名者下面是私钥,它执行乘法和求幂。私钥下方是字段和曲线。依此类推,直到你得到系数和模数。
话虽如此,您通常希望使用更高级别的对象之一。大多数人使用加密器、解密器、Public 密钥和私钥。大多数人不需要深入了解,例如 GroupParameters 或 Curves 等对象。
您可能还对 Crypto++ wiki 中的 Crypto++ Manual and Elliptic Curve Cryptography 感兴趣。