How can I get the uncompressed public key from the compressed public key in openssl?

6

1

Given a private key, I can get the uncompressed or compressed version of the public key like so.

EC_KEY* pKey = EC_KEY_new_by_curve_name(NID_secp256k1);

std::vector<unsigned char> getPubKey(EC_KEY* pKey, bool compressed) const {
    if (compressed)
        EC_KEY_set_conv_form(pKey, POINT_CONVERSION_COMPRESSED);
    else
        EC_KEY_set_conv_form(pKey, POINT_CONVERSION_UNCOMPRESSED);

    int nSize = i2o_ECPublicKey(pKey, NULL);
    std::vector<unsigned char> pubKey(nSize, 0)
    unsigned char* pBegin = &pubKey[0];
    i2o_ECPublicKey(pKey, &pBegin)
    return pubKey;
}

But how can I get the uncompressed public key from the compressed public key without knowing the private key?

user299648

Posted 2014-07-09T16:24:06.003

Reputation: 401

1

I answered the same question here, but with an answer in Python: https://bitcointalk.org/index.php?topic=644919.msg7205689#msg7205689 If a language-agnostic answer is suitable, I can post this as an answer.

Tim S. 2014-07-09T17:59:34.223

Thanks for the solution, but I'm looking fora a canonical solution using openssl.user299648 2014-07-09T19:39:32.610

Answers

2

If you have a compressed octet pubkey, use octet to point, then point to octet.

EC_POINT_oct2point(group, point, data, size, ctx);
EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, data, len, ctx);

Erik Aronesty

Posted 2014-07-09T16:24:06.003

Reputation: 367

2

You could also use the following to get an EC_POINT from a compressed key:

int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
                                             EC_POINT *p,
                                             const BIGNUM *x, int y_bit,
                                             BN_CTX *ctx);

and the following to convert the EC_POINT to an EC_KEY:

 int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);

From EC_POINT_new documentation:

Points can also be described in terms of their compressed co-ordinates. For a point (x, y), for any given value for x such that the point is on the curve there will only ever be two possible values for y. Therefore a point can be set using the EC_POINT_set_compressed_coordinates_GFp() and EC_POINT_set_compressed_coordinates_GF2m() functions where x is the x co-ordinate and y_bit is a value 0 or 1 to identify which of the two possible values for y should be used.

and EC_KEY_new documentation:

The functions EC_KEY_get0_group(), EC_KEY_set_group(), EC_KEY_get0_private_key(), EC_KEY_set_private_key(), EC_KEY_get0_public_key(), and EC_KEY_set_public_key() get and set the EC_GROUP object, the private key, and the EC_POINT public key for the key respectively.

JBaczuk

Posted 2014-07-09T16:24:06.003

Reputation: 6 172