1

我在 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 方法有两个重载,但都不是针对点压缩的情况。

我的问题是关于“PublicKey.Initialize(curve,G,n,Q)”的 Crypto++ 的具体问题。由于我无法使用当前项目传输整个 publicKey - 我被迫将域参数指定为索引值并且只能传输 Qx 值。所以我应该使用“PublicKey.Initialize(curve,G,n,Q)”之类的东西来初始化 publicKey 但是,我找不到这样的关于点压缩的初始化 API。

所以,这不是关于“如何进行点压缩”,而是“有没有办法在没有 Qy 值的情况下初始化公钥?”

4

2 回答 2

1

如何仅使用 x 值(点压缩)构造 ECDSA publicKey?

x是私人指数。公钥是曲线上的一个点;并且它不使用私有指数。

获取公钥:取私有指数,并将基点提高到它。即,Q = G^x

如果要在私钥或解密器上设置私钥,请设置域参数(即,DL_GroupParameters_EC< ECP >DL_GroupParameters_EC< EC2M >),然后调用SetPrivateExponent(x);.


您是否在如何从发件人处恢复压缩的 y 值?? 社区花时间为您提供答案和示例代码,但您没有承认或跟进。

我认为owlstead在这里说得最好:

如果您不倾向于接受答案甚至不跟进答案,我们为什么要关心回答您?你的问题没问题,但你对待社区的方式很糟糕。

于 2014-01-15T06:21:34.400 回答
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 类。

于 2017-08-21T11:52:02.523 回答