ECDSA: (v, r, s), was ist v?

Das deterministische Signieren eines Tx mit RFC6979 gibt zurück v, r, s, wobei rund sdie beiden Werte sind, die in Standard-ECDSA-Signaturen verwendet werden. v = 27 + (y % 2), also 27 + die Parität von r, wie pybitcointools anzeigt .

Also für gerade rbekommen wir v = 27, ungerade rbekommen wir v = 28.

Wie wichtig ist der Wert von v(27 oder 28)? Warum ist es notwendig, einen vWert zu haben? Außerdem, warum ist es 27?

Scheint eine Art Versionsbyte zu sein, ähnlich dem Versionsbyte, das zum Codieren von Adressen verwendet wird. Ich bin mir der Bedeutung von 27/28 nicht sicher.
Ihr Link zu github ist defekt; Ich würde es beheben, aber anscheinend muss ich mindestens 6 Zeichen ändern, damit es eine gültige Bearbeitung ist.
@DavidGrayson Link behoben. Vielleicht kann Peter Wuille etwas dazu sagen, da ich glaube gelesen zu haben, dass 27 willkürlich ausgewählt wurde, weil es "auf halbem Weg" zwischen den Byte-Auswahlmöglichkeiten der verwendeten Version lag, obwohl ich diese Quelle für mein ganzes Leben nicht finden kann
Das ist richtig. Es war damals eine willkürliche Wahl für eine Zahl, weil wir ein Byte brauchten, um Informationen zur Wiederherstellung öffentlicher Schlüssel zu übermitteln. Ich werde versuchen, später eine vollständige Antwort zu schreiben.

Antworten (4)

Das hat nichts mit RFC6979 zu tun, sondern mit ECDSA Signing und Public Key Recovery.

(r, s) ist die normale Ausgabe einer ECDSA-Signatur, wobei r als die X-Koordinate eines Punktes R berechnet wird, Modulo der Kurvenordnung n.

In Bitcoin verwenden wir für Nachrichtensignaturen einen Trick namens Public Key Recovery. Tatsache ist, dass Sie, wenn Sie den vollständigen R-Punkt (nicht nur seine X-Koordinate) und s sowie eine Nachricht haben, berechnen können, für welchen öffentlichen Schlüssel dies eine gültige Signatur wäre. Dies ermöglicht es, eine Nachricht mit einer Adresse zu „verifizieren“, ohne den vollständigen Schlüssel kennen zu müssen (wir führen einfach die Wiederherstellung des öffentlichen Schlüssels für die Signatur durch und hashen dann den wiederhergestellten Schlüssel und vergleichen ihn mit der Adresse).

Dies bedeutet jedoch, dass wir die vollständigen R-Koordinaten benötigen. Es kann bis zu 4 verschiedene Punkte mit einer gegebenen "X-Koordinate modulo n" geben. (2, weil jede X-Koordinate zwei mögliche Y-Koordinaten hat, und 2, weil r+n immer noch eine gültige X-Koordinate sein kann). Diese Zahl zwischen 0 und 3 nennen wir die Wiederherstellungs-ID oder Recid. Daher geben wir ein zusätzliches Byte zurück, das auch als Header-Byte fungiert, indem wir 27+recid (für unkomprimierte wiederhergestellte Pubkeys) oder 31+recid (für komprimierte wiederhergestellte Pubkeys) verwenden.

Genau genommen ist die Recid nicht erforderlich, da wir einfach alle möglichen Koordinatenpaare durchlaufen und prüfen können, ob eines davon mit der Signatur übereinstimmt. Die recid beschleunigt nur diese Überprüfung.

Wenn h der Kofaktor ist, beträgt im Allgemeinen die maximale Anzahl unterschiedlicher Punkte mit gegebener "X-Koordinate modulo n" 2(h+1). Im Fall von secp256k1 mit Cofaktor 1 erhalten wir 2(1+1) = 4.

Können Sie auf den Code verlinken, der dies implementiert? Ich werde anfangen, C++ zu lernen, indem ich Funktionen wie diese verwende, die ich verstehe
Der Signaturcode befindet sich in libsecp256k1, das auch einen Verifizierungscode enthält, der jedoch derzeit nicht verwendet wird. Zur Überprüfung gibt es C-Code in Bitcoin Core (siehe pubkey.cpp), der eine Reihe von OpenSSL-Aufrufen durchführt, um den Großteil der Arbeit zu erledigen. Ich bin mir nicht sicher, ob das Lesen von kryptografischem C-Code der beste Weg ist, C++ zu lernen :)
Es ist eher eine Möglichkeit, Dinge zu lernen, die ich bereits ziemlich gut verstehe und an denen ich interessiert bin. Ich habe Python auf diese Weise gelernt, und das ultimative Ziel ist es, auch die Kernsoftware zu kennen
@PeterWuille There can be up to 4 different points with a given "X coordinate modulo n". (2 because each X coordinate has two possible Y coordinates, and 2 because r+n may still be a valid X coordinate).Ich verstehe ersteres (2 y-Werte für jedes x wegen der Symmetrie) ... Aber wie funktioniert letzteres? dh r+n may still be a valid X coordinate??
X- und Y-Koordinaten sind Zahlen modulo p, die Feldgröße, die für secp256k1 etwa 2^256 - 2^32 beträgt. Die Werte r und s in der Signatur sind jedoch modulo n, die Gruppenordnung, die etwa 2^256 - 2^128 beträgt. Wenn Rx zwischen n und p liegt, wird r auf Rx-n reduziert. Wenn Sie also einen r-Wert unter 2^128-2^32 haben, können ihm 2 gültige Rx-Werte entsprechen.
@PieterWuille - Ist dies spezifisch für secp2561k oder kann dies für alle elliptischen Kurvensignaturen verallgemeinert werden? Wie hängt es auch mit dieser Antwort auf Crypto SE zusammen - crypto.stackexchange.com/questions/18105/… ?
ECDSA unterstützt immer öffentliche Schlüssel, unabhängig von der Kurve. Für Kurven mit Kofaktor > 1 ist es etwas komplizierter. Diese verknüpfte Antwort erklärt das Verfahren.
Welche der 4 möglichen Ausgaben (27..30) entspricht bitte welchem ​​der möglichen Ergebnisse. Bsp.: 0 = positiv Y und X1? wo ist das dokumentiert?
@Sentinel Vollständige Informationen zur Wiederherstellungsmethode erhalten Sie hier: secg.org/sec1-v2.pdf
27 = niedrigeres X gerades Y. 28 = niedrigeres X ungerades Y. 29 = höheres X gerades Y. 30 = höheres X ungerades Y. Beachten Sie, dass 29 und 30 äußerst selten sind und in der Praxis immer nur in speziell generierten Beispielen zu sehen sind. Es gibt nur zwei mögliche X-Werte, wenn r zwischen 1 und (p mod n) liegt, was eine Chance von etwa 0,00000000000000000000000000000000000000000000000373 % hat, zufällig zu passieren.
@Souza / Pieter - Danke. Ich hatte es bereits geschafft, die Antwort darauf zu finden – es hat ewig gedauert! Ich habe diese ASN.1 tatsächlich in sec1-v2.pdf nach einer enormen Menge an Graben gefunden. Als ich es fand, dachte ich, ich wäre auf Gold gestoßen. Das Problem ist, dass die Ethereum-Dokumentation (ich implementiere einen Ethereum-Light-Client) keine detaillierten Protokollinformationen enthält, und offizielle Implementierungen neigen dazu, sich auf Bibliotheken zu verlassen, die dorthin gehen, wo Bitcoin bereits getreten ist, sodass Details wie der Parameter „v“ verloren gehen/vergraben werden in sehr, sehr obskurem Code.
@Sentinel, mein Kampf ist der gleiche. Ich arbeite auf der Grundlage des Ethereum-Protokolls und sie sagen wenig bis gar nichts darüber. Und Sie haben Recht, beide verwenden libsecp256k1.
@Souza - einverstanden. Es ist ein Kampf. Ich versuche, die Ethereum Foundation zu kontaktieren, um eine zugängliche Protokolldokumentation zusammenzustellen und die Finanzierung dafür zu erhalten. Ich stelle einen leichten Client mit reaktiven Erweiterungen und .NET zusammen, bei dem ich alle Protokollnachrichten als Streams behandle, die durch Stack-Layer-Adapter fließen, und versuche, das Protokoll der obersten Ebene von Unterschieden auf niedrigerer Ebene zu isolieren (z. B. Discv4 vs. v5 usw.). . Wenn ich fertig bin, sollte ich in der Lage sein, ein Buch darüber zu schreiben.

Ich glaube nicht, dass das von Ihnen beschriebene v Teil von RFC6979 ist, da ich es in diesem Dokument nicht finden kann. Dieses v ist zufällig Teil der ecdsa_raw_signRohzeichenfunktion in pybitcointools, die aufruft deterministic_generate_k, was eine Implementierung von RFC6979 ist.

RFC6979 hilft Ihnen nur dabei, einen deterministischen k - Wert zum Signieren zu generieren. Es hilft Ihnen nicht, r und s zu generieren . Um r und s zu generieren , verwenden Sie einfach den normalen ECDSA-Algorithmus; Sie müssen nicht auf RFC6979 verweisen, nachdem Sie es zum Generieren von k verwendet haben . RFC6979 generiert k , was eine Eingabe für den Signaturalgorithmus ist, der r und s generieren kann .

Richtig, aber verscheint über Implementierungen hinweg? Pybitcointools ist nicht die einzige Implementierung, die es verwendet, glaube ich.
Die einzige andere Implementierung, die ich gesehen habe, ist libsecp256k1 , die keine AV-Nummer zurückgibt. Diese Bibliothek stellt eine Funktion namens bereit, secp256k1_nonce_function_rfc6979deren einzige Ausgabe ein 32-Byte-Datenpuffer ist.
secp256k1_ecdsa_sign_compact (alte API) oder secp256k1_pubkey_serialize_compact (neue API) geben die Wiederherstellungs-ID zurück (den Wert v, aber ohne den konstanten Begriff 27). Siehe meine Antwort.
Ja, das vhat mit Signieren zu tun, nicht mit RFC6979.
@DavidGrayson ja, Titel geändert :)

Wie alle anderen Antworten bereits skizzieren: vist erforderlich, um den richtigen öffentlichen Schlüssel für eine Signatur wiederherzustellen, da manchmal (auch mit geringer Wahrscheinlichkeit) mehr als ein gültiger öffentlicher Schlüssel durch eine Signatur abgerufen werden kann.

Hier ist ein Spickzettel:

  • 27unkomprimierter öffentlicher Schlüssel, y-Parität 0, Größe xkleiner als die Kurvenordnung
  • 28unkomprimierter öffentlicher Schlüssel, y-Parität 1, Größe xkleiner als die Kurvenordnung
  • 29unkomprimierter öffentlicher Schlüssel, y-Parität 0, Größe x größer als die Kurvenordnung
  • 30unkomprimierter öffentlicher Schlüssel, y-Parität 1, Größe x größer als die Kurvenordnung
  • 31 komprimierter öffentlicher Schlüssel, y-Parität 0, Größe xkleiner als die Kurvenordnung
  • 32 komprimierter öffentlicher Schlüssel, y-Parität 1, Größe xkleiner als die Kurvenordnung
  • 33 komprimierter öffentlicher Schlüssel, y-Parität 0, Größe x größer als die Kurvenordnung
  • 34 komprimierter öffentlicher Schlüssel, y-Parität 1, Größe x größer als die Kurvenordnung

Für alle v >= 35, die Sie möglicherweise mit Ethereum-Signaturen gemäß EIP-155 zu tun haben :

v = recovery_id + CHAIN_ID * 2 + 35

vwird benötigt, um den öffentlichen Schlüssel wiederherzustellen. Als Ergebnis der Wiederherstellung des öffentlichen Schlüssels aus der ECDSA-Signatur können 0, 1 oder 2 Punkte zurückgegeben werden. Um genau anzugeben, welcher Punkt dem "ursprünglichen" öffentlichen Schlüssel entspricht, wird ein zusätzliches Byte verwendet