Warum ist die Signatur immer 65 (1+32+32) Bytes lang?

Eine vom Bitcoin-Qt-Client erstellte Signatur kann immer in ein 65-Byte-Array dekodiert (base64) werden. Dieses Array scheint (laut https://github.com/bitcoin/bitcoin/blob/master/src/key.cpp#L217 ) ein Header-Byte, einen 32-Byte-R-Teil und einen 32-Byte-S-Teil zu enthalten .

Ich habe einige (R,S)-Paare aus einigen ECDSA-Signaturen extrahiert, die im DER-Format codiert sind. Ich habe festgestellt, dass R und S nicht unbedingt 32 Byte groß sind. Sie können manchmal 33 Bytes lang sein. Kann mir jemand sagen, warum die vom Qt-Client erstellte Signatur immer 65 Byte groß ist oder ob es in Ordnung ist, sowohl R als auch S immer in ein 32-Byte-Array zu konvertieren? Vielen Dank.

Antworten (1)

Es werden zwei unterschiedliche Kodierungen verwendet.

Alles im Bitcoin-Protokoll, einschließlich Transaktionssignaturen und Alarmsignaturen , verwendet die DER-Codierung . Dies führt zu 71-Byte-Signaturen (im Durchschnitt), da mehrere Header-Bytes vorhanden sind und die R- und S-Werte eine variable Länge haben.

Für Nachrichtensignaturen wird eine benutzerdefinierte Codierung verwendet, die kompakter (und neuer) ist und die Wiederherstellung öffentlicher Schlüssel unterstützt (bei einer Nachricht und einer Signatur finden Sie heraus, welcher öffentliche Schlüssel sie erstellt hätte). Der Code, auf den Sie sich in der Frage beziehen, dient zum Erstellen solcher Signaturen.

Eine korrekte DER-codierte Signatur hat folgende Form:

  • 0x30: ein Header-Byte, das eine zusammengesetzte Struktur anzeigt.
  • Ein 1-Byte-Längendeskriptor für alles Folgende.
  • 0x02: ein Header-Byte, das eine Ganzzahl angibt.
  • Ein 1-Byte-Längendeskriptor für den R-Wert
  • Die R-Koordinate als Big-Endian-Ganzzahl.
  • 0x02: ein Header-Byte, das eine Ganzzahl angibt.
  • Ein 1-Byte-Längendeskriptor für den S-Wert.
  • Die S-Koordinate als Big-Endian-Ganzzahl.

Wo Anfangsbytes 0x00für R und S nicht erlaubt sind, außer wenn ihr erstes Byte sonst oben wäre 0x7F(in diesem Fall ist ein einzelnes 0x00davor erforderlich). Beachten Sie auch, dass innerhalb von Transaktionssignaturen ein zusätzliches Hashtyp-Byte auf die eigentlichen Signaturdaten folgt.

Danke Pieter! Jetzt verstehe ich, warum wir das erste Byte in den 33-Byte-Fällen getrost ignorieren können.
Warum sind Werte über 0x7F im ersten Byte von R oder S nicht erlaubt? Vielleicht etwas mit DER zu tun? Die Signaturen, die für mich gedruckt werden, scheinen das 0x00 in etwa 50% der Fälle unzusammenhängend vor dem R, S zu haben.
@ StephenM347 Wenn das erste Byte sein höchstes Bit gesetzt hat (> 0x7F), sagt BER (von dem DER eine Spezialisierung ist), dass es als negative Zahl zu interpretieren ist. OpenSSL, das weiß, dass Signaturen nur positive Zahlen enthalten, ignoriert dies, aber dies verstößt gegen die Spezifikation. Ab v0.8.0 erfordert Bitcoin Core die strikte Einhaltung von DER für Signaturen, obwohl alles, was OpenSSL akzeptiert, vorerst in der Blockchain gültig ist (obwohl BIP62 vorschlägt, es zu einer Netzwerkregel zu machen, die eine strikte DER erfordert).
Vielen Dank. Irgendwie wünschte Satoshi, er hätte nur Daten-Pushs für R und S auf dem Stack verwendet, anstatt diese ganze DER-Sache, aber was können Sie tun! :)
Können Sie das benutzerdefinierte Format näher erläutern? Ich versuche, den QT-Signaturprozess neu zu erstellen. C++ geht jedoch weit über mein Verständnis hinaus.
Wie wäre es mit Schnorr Signature, beide (R,s)-Werte sind im Signaturfeld enthalten
@CiscoMmu Ja, in BIP340-Signaturen sind die ersten 32 Bytes die X-Koordinate von R (und die Y-Koordinate ist implizit gerade), und die letzten 32 Bytes sind s.
danke Pieter, ich habe mich ein paar Tage umgesehen (ich frage mich, warum der öffentliche Nonce-Wert nirgendwo erwähnt wurde), bis ich herausfand, dass die ECDSA-Signatur tatsächlich aus Signatur und öffentlichem Nonce besteht. Ich nehme an, dass es bei SCHNorr genauso ist. deswegen habe ich gefragt.