是否有点压缩的公钥初始化API?

时间:2014-01-15 03:05:13

标签: crypto++ ecdsa

我在使用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值的公钥?“

2 个答案:

答案 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?处查看了上一个问题?社区花时间为您提供答案和示例代码,但您没有承认或跟进。

我认为owlstead最好说here

  

如果您不倾向于接受答案,我们为什么要关心您   甚至跟进他们?你的问题没问题,但顺便说一下   你对待社区是可怕的。

答案 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类同样有效。