¿Cómo puedo obtener la clave pública sin comprimir de la clave pública comprimida en openssl?

Dada una clave privada, puedo obtener la versión sin comprimir o comprimida de la clave pública así.

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

Pero, ¿cómo puedo obtener la clave pública sin comprimir de la clave pública comprimida sin conocer la clave privada?

Respondí la misma pregunta aquí, pero con una respuesta en Python: bitcointalk.org/index.php?topic=644919.msg7205689#msg7205689 Si una respuesta independiente del idioma es adecuada, puedo publicar esto como respuesta.
Gracias por la solución, pero estoy buscando una solución canónica usando openssl.

Respuestas (2)

Si tiene una clave pública de octeto comprimida, use octeto a punto, luego apunte a octeto.

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

También puede usar lo siguiente para obtener un EC_POINTcorreo electrónico de una clave comprimida:

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

y lo siguiente para convertir el EC_POINTa un EC_KEY:

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

De EC_POINT_nueva documentación :

Los puntos también se pueden describir en términos de sus coordenadas comprimidas. Para un punto (x, y), para cualquier valor dado de x tal que el punto esté en la curva, solo habrá dos valores posibles para y. Por lo tanto, se puede establecer un punto usando las funciones EC_POINT_set_compressed_coordinates_GFp() y EC_POINT_set_compressed_coordinates_GF2m() donde x es la coordenada x e y_bit es un valor 0 o 1 para identificar cuál de los dos valores posibles para y debe usarse.

y EC_KEY_nueva documentación :

Las funciones EC_KEY_get0_group(), EC_KEY_set_group(), EC_KEY_get0_private_key(), EC_KEY_set_private_key(), EC_KEY_get0_public_key() y EC_KEY_set_public_key() obtienen y establecen el objeto EC_GROUP, la clave privada y la clave pública EC_POINT para la clave, respectivamente.