我在使用CryptoPP无法解决,无法找到这个具体问题的答案。以下是示例源代码(部分)
AutoSeededRandomPool prng;
//Generate a private key
ECDSA<ECP, CryptoPP::SHA256>::PrivateKey privateKey;
privateKey.Initialize(prng, CryptoPP::ASN1::secp256r1());
// Generate publicKey
ECDSA<ECP, CryptoPP::SHA256>::PublicKey publicKey;
privateKey.MakePublicKey(publicKey);
// Extract Component values
Integer p = privateKey.GetGroupParameters().GetCurve().GetField().GetModulus();
Integer a = privateKey.GetGroupParameters().GetCurve().GetA();
Integer b = privateKey.GetGroupParameters().GetCurve().GetB();
Integer Gx = privateKey.GetGroupParameters().GetSubgroupGenerator().x;
Integer Gy = privateKey.GetGroupParameters().GetSubgroupGenerator().y;
Integer n = privateKey.GetGroupParameters().GetSubgroupOrder();
Integer h = privateKey.GetGroupParameters().GetCofactor();
Integer Qx = publicKey.GetPublicElement().x;
Integer Qy = publicKey.GetPublicElement().y;
Integer x = privateKey.GetPrivateExponent();
// Construct Point elelemt;
ECP curve(p,a,b);
ECP::Point G(Gx,Gy);
ECP::Point Q(Qx,Qy);
//Build publicKey using elements (no point compression)
ECDSA<ECP, CryptoPP::SHA256>::PublicKey GeneratedPublicKey;
GeneratedPublicKey.Initialize(curve,G,n,Q);
assert(GeneratedPublicKey.Validate(prng, 3));
//Build publicKey using elements (with point compression)?
通过这种方式,我可以使用组件值生成publicKey。但是,我不能 使点压缩工作 - 这意味着我没有Qy值 - 是否有 这样做的方法? Initialize方法有两个重载但没有一个是for point 压缩情况。
我的问题是关于“PublicKey.Initialize(curve,G,n,Q)”的Crypto ++。因为我无法使用我当前的项目传输整个publicKey - 我强制指定域 参数作为索引值,只能传递Qx值。所以我应该初始化publicKey 使用像“PublicKey.Initialize(curve,G,n,Q)”之类的东西但是,我找不到关于点压缩的这种初始化API。
所以,这不是关于“如何进行点压缩”,而是“有没有办法初始化 没有Qy值的公钥?“
答案 0 :(得分:1)
如何仅使用x值构建ECDSA publicKey(点压缩)?
x
是私人指数。公钥是曲线上的一个点;并且它不使用私有指数。
获取公钥:获取私有指数,并将基点提升到它。也就是Q = G^x
。
如果要在私钥或解密器上设置私有指数,请设置域参数(即DL_GroupParameters_EC< ECP >
或DL_GroupParameters_EC< EC2M >
),然后调用SetPrivateExponent(x);
。
您是否在How can I recover compressed y value from sender?处查看了上一个问题?社区花时间为您提供答案和示例代码,但您没有承认或跟进。
如果您不倾向于接受答案,我们为什么要关心您 甚至跟进他们?你的问题没问题,但顺便说一下 你对待社区是可怕的。
答案 1 :(得分:1)
“有没有办法在没有Qy值的情况下初始化公钥?”
是的,有。这是一个加密++示例:
#include <string>
#include <iostream>
#include <cryptopp/cryptlib.h>
#include <cryptopp/ecp.h>
#include <cryptopp/eccrypto.h>
#include <cryptopp/hex.h>
#include <cryptopp/oids.h>
#include <cryptopp/osrng.h>
using namespace CryptoPP;
using std::cout;
using std::endl;
int main()
{
OID curve = ASN1::secp256r1();
ECDH<ECP>::Domain domain(curve);
SecByteBlock privKey(domain.PrivateKeyLength());
SecByteBlock pubKey(domain.PublicKeyLength());
AutoSeededRandomPool prng;
domain.GenerateKeyPair(prng, privKey, pubKey);
// Convert public key to string representation
std::string pub_str;
HexEncoder encoder;
encoder.Attach( new StringSink(pub_str) );
encoder.Put( pubKey.data(), pubKey.size() );
encoder.MessageEnd();
// Uncompressed point - first byte '04' in front of the string.
std::cout << "Uncompressed public key (point) " << pub_str << endl;
// Extract x value from the point
std::string public_point_x = pub_str.substr(2, 64);
// Compressed - '02' byte in front of the string.
public_point_x = "02" + public_point_x;
std::cout << "Compressed public key (point) " << public_point_x << endl;
// ----- reconstruct point from compressed point/value.
StringSource ss(public_point_x, true, new HexDecoder);
ECP::Point point;
domain.GetGroupParameters().GetCurve().DecodePoint(point, ss, ss.MaxRetrievable());
cout << "Result after decompression X: " << std::hex << point.x << endl;
cout << "Result after decompression Y: " << std::hex << point.y << endl;
return 0;
}
我希望这是你问题的答案。我正在使用ECDH,但它应该与ECDSA类同样有效。