Wie kann ich den unkomprimierten öffentlichen Schlüssel aus dem komprimierten öffentlichen Schlüssel in openssl erhalten?

Bei einem privaten Schlüssel kann ich so die unkomprimierte oder komprimierte Version des öffentlichen Schlüssels erhalten.

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

Aber wie kann ich den unkomprimierten öffentlichen Schlüssel aus dem komprimierten öffentlichen Schlüssel erhalten, ohne den privaten Schlüssel zu kennen?

Ich habe die gleiche Frage hier beantwortet, aber mit einer Antwort in Python: bitcointalk.org/index.php?topic=644919.msg7205689#msg7205689 Wenn eine sprachunabhängige Antwort geeignet ist, kann ich dies als Antwort posten.
Danke für die Lösung, aber ich suche nach einer kanonischen Lösung mit openssl.

Antworten (2)

Wenn Sie einen komprimierten Octet-Pubkey haben, verwenden Sie octet to point und zeigen Sie dann auf octet.

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

Sie können auch Folgendes verwenden, um eine EC_POINTvon einem komprimierten Schlüssel zu erhalten:

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

und das Folgende, um das EC_POINTin ein umzuwandeln EC_KEY:

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

Aus der EC_POINT_new-Dokumentation :

Punkte können auch durch ihre komprimierten Koordinaten beschrieben werden. Für einen Punkt (x, y) gibt es für jeden gegebenen Wert für x, sodass der Punkt auf der Kurve liegt, immer nur zwei mögliche Werte für y. Daher kann ein Punkt mit den Funktionen EC_POINT_set_compressed_coordinates_GFp() und EC_POINT_set_compressed_coordinates_GF2m() gesetzt werden, wobei x die x-Koordinate und y_bit ein Wert 0 oder 1 ist, um zu identifizieren, welcher der beiden möglichen Werte für y verwendet werden soll.

und EC_KEY_new Dokumentation :

Die Funktionen EC_KEY_get0_group(), EC_KEY_set_group(), EC_KEY_get0_private_key(), EC_KEY_set_private_key(), EC_KEY_get0_public_key() und EC_KEY_set_public_key() erhalten bzw. setzen das EC_GROUP-Objekt, den privaten Schlüssel und den öffentlichen EC_POINT-Schlüssel für den Schlüssel.