Jak uzyskać klucz publiczny ECDSA z podpisu Bitcoin? … SEC1 4.1.6 odzyskiwanie kluczy dla krzywych (mod p) -fields

Aktualizacja: Częściowe rozwiązanie dostępne w Git

EDYCJA: Skompilowana wersja jest dostępna pod adresemhttps://github.com/makerofthings7/Bitcoin-MessageSignerVerifier

Pamiętaj, że wiadomość do zweryfikowania musi miećBitcoin Signed Message:\n jako prefiks.Źródło1 Source2

Coś jest nie tak w implementacji C #, że prawdopodobnie mogę to poprawićta implementacja Pythona

Wydaje się, że ma problem z wymyśleniem poprawnego adresu Base 58.

Mam następujący komunikat, podpis i adres Base58 poniżej. Zamierzam wyodrębnić klucz z podpisu, skrótu tego klucza i porównać skróty Base58.

Mój problem to: Jak wyodrębnić klucz z podpisu? (EdytowaćZnalazłem kod c ++ na dole tego posta, potrzebujesz go w Bouncy Castle / lub C #)

Wiadomość

StackOverflow test 123

Podpis

IB7XjSi9TdBbB3dVUK4+Uzqf2Pqk71XkZ5PUsVUN+2gnb3TaZWJwWW2jt0OjhHc4B++yYYRy1Lg2kl+WaiF+Xsc=

Adres Base58 Bitcoin „hash”

1Kb76YK9a4mhrif766m321AMocNvzeQxqV

Ponieważ adres Base58 Bitcoin jest tylko hashem, nie mogę go użyć do walidacji komunikatu Bitcoin. Możliwe jest jednak wyodrębnienie klucza publicznego z apodpis.

Edytować: Podkreślam, że czerpię klucz publiczny z samego podpisu, a nie z skrótu klucza publicznego Base58. Jeśli chcę (i rzeczywiście chcę), powinienem być w stanie przekonwertować te bity klucza publicznego do skrótu Base58. Nie potrzebuję pomocy w tym, po prostu potrzebuję pomocy w wyodrębnieniu bitów klucza publicznego i weryfikacji podpisu.

Pytanie

W jakim podpisie znajduje się ten podpis? PKCS10? (Odpowiedź: nie, to zastrzeżonejak opisano tutaj)

jak wyodrębnić klucz publiczny w Bouncy Castle?

Jaki jest właściwy sposób weryfikacji podpisu? (załóżmy, że już wiem, jak przekonwertować bity klucza publicznego na hash równy powyższemu hashowi Bitcoin)

Wcześniejsze badania

Ten link opisuje sposób korzystania z krzywych ECDSA, a poniższy kod pozwoli mi przekonwertować klucz publiczny na obiekt BC, ale nie jestem pewien, w jaki sposób uzyskać punktQ z podpisu.

W poniższej próbce Q jest wartością zakodowaną na stałe

  Org.BouncyCastle.Asn1.X9.X9ECParameters ecp = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");
  ECDomainParameters params = new ECDomainParameters(ecp.Curve, ecp.G, ecp.N, ecp.H);
  ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(
  ecp .curve.decodePoint(Hex.decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q
        params);
  PublicKey  pubKey = f.generatePublic(pubKeySpec);


 var signer = SignerUtilities.GetSigner("ECDSA"); // possibly similar to SHA-1withECDSA
 signer.Init(false, pubKey);
 signer.BlockUpdate(plainTextAsBytes, 0, plainTextAsBytes.Length);
 return signer.VerifySignature(signature);

Dodatkowe badania:

TO jest źródłem Bitcoin, które weryfikuje wiadomość.

Po zdekodowaniu Base64 podpisuRecoverCompact (hash wiadomości, podpis) jest nazywany. Nie jestem programistą C ++, więc zakładam, że muszę się dowiedzieć, jak to zrobićkey.Recover Prace. To lubkey.GetPubKey

To jest kod C ++, którego potrzebuję w C #, najlepiej w nadmuchiwanym zamku ... ale wezmę wszystko, co działa.

// reconstruct public key from a compact signature
// This is only slightly more CPU intensive than just verifying it.
// If this function succeeds, the recovered public key is guaranteed to be valid
// (the signature is a valid signature of the given data for that key)
bool Recover(const uint256 &hash, const unsigned char *p64, int rec)
{
    if (rec<0 || rec>=3)
        return false;
    ECDSA_SIG *sig = ECDSA_SIG_new();
    BN_bin2bn(&p64[0],  32, sig->r);
    BN_bin2bn(&p64[32], 32, sig->s);
    bool ret = ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), rec, 0) == 1;
    ECDSA_SIG_free(sig);
    return ret;
}

... kod dlaECDSA_SIG_recover_key_GFp jest tutaj

Niestandardowy format podpisu w Bitcoin

Ta odpowiedź mówi, że są 4 możliwe klucze publiczne, które mogą tworzyć sygnaturę, a to jest kodowane w nowszych sygnaturach.

questionAnswers(2)

yourAnswerToTheQuestion