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?

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

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.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.