1

I am tumbling around with CryptoPP and cannot find answer to this specific question. Here is sample source code (partial)

    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)?

With this way, I can generate publicKey using component values. However, I cannot make it work with point compression-which means I don't have Qy value- Is there a way to do it? Initialize method has two overloading but none of them are for point compression situation.

My question is specific with Crypto++ on "PublicKey.Initialize(curve,G,n,Q)". Since I cannot transfer whole publicKey with my current project-which I am force to specify domain parameter as index value and can only transfer Qx value. So I should initialize publicKey using something like "PublicKey.Initialize(curve,G,n,Q)" However, I cannot find such initialization API concerning point compression.

So, this is not about "how to do a point compression" but "Is there a way to initialize public key without having Qy value?"

jww
  • 97,681
  • 90
  • 411
  • 885
  • Tell us precisely what you have. You have never told the parameters you are using at `//Build publicKey using elements (with point compression)?`. If its an ASN.1 encoded values, show it to us in with `dumpasn1`. If the raw form is binary, the show it to us hex encoded. – jww Jan 17 '14 at 08:42

2 Answers2

1

How to Construct ECDSA publicKey using only with x value (Point compression)?

x is the private exponent. The public key is a point on the curve; and it does not use the private exponent.

To get the public key: take the private exponent, and raise your base point to it. That is, Q = G^x.

If you want to set the private exponent on a private key or decryptor, then set the domain parameters (i.e., DL_GroupParameters_EC< ECP > or DL_GroupParameters_EC< EC2M >) and then call SetPrivateExponent(x);.


Have you reviewed your previous question at How can I recover compressed y value from sender?? The community took the time to provide you with an answer and sample code, but you did not acknowledge or follow up.

I think owlstead said it best here:

Why would we care answer you if you are not inclined to accept answers or even follow up to them? Your questions are all right, but the way you treat the community is terrible.

Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
  • I did read your answer on my previous one and it helped me a lot. Thank you again :) – Felixr3136148 Jan 15 '14 at 11:43
  • My apologies if this question looks like that I am ignoring your answer to my previous question. It is not, I did learn a lot from your previous answer and now I can do point compression. This is different question to my mind. – Felixr3136148 Jan 15 '14 at 11:57
1

"Is there a way to initialize public key without having Qy value?"

Yes, there is. Here is an crypto++ example:

#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;
}

I hope this is the answer to your question. I was using ECDH, but it should work equally well with ECDSA class.

sigidagi
  • 864
  • 7
  • 17