ECDSA-Signatur und den „z“-Wert

Der folgende Link enthält Details zum Umkehren der ECDSA-Signatur, wenn zwei identische "R"-Werte angegeben werden.

http://www.nilsschneider.net/2013/01/28/recovering-bitcoin-private-keys.html

Ich habe dies überlesen und es gibt einen Teil, den ich nicht verstehe; wie er die "z"-Werte bekommen hat.

Erzeugt ein Kopieren und Einfügen von "OP_DUP OP_HASH160 70792fb74a5df745bac07df6fe020f871cbb293b OP_EQUALVERIFY OP_CHECKSIG" (abzüglich der Anführungszeichen) in eine Reifmod-160-Hashing-Funktion dieses Ergebnis?

Musste er im Wesentlichen eine andere Zeichenfolge kopieren und einfügen? Hat er gerade reifemod oder sha 256d? Musste er es mehr als einmal tun?

Ich habe über diese Dinge nachgelesen, aber ich kann ihre Programmierbeschreibung einfach nicht entziffern, wie man es macht. Die Beschreibungen ohne Programmierung zeigen nicht "Hey, auf dieses 'xyzx' beziehe ich mich, wenn ich 'zu signierende Nachricht' sage" oder was auch immer. Viele Dinge auf dieser Seite und auf der

https://blockchain.info/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1

Scheinen, als ob sie angemessen als die "zu signierende Nachricht" beschrieben werden könnten, abgesehen von der Tatsache, dass ich nicht weiß, welche Art von Hash angewendet wird, um meine Berechnungen überhaupt mit den auf dem ersten Link gezeigten zu vergleichen.

Antworten (3)

Die Berechnung der Z-Werte ist für den durchschnittlichen Joe ziemlich kompliziert, deshalb habe ich eine Website erstellt, um dies für Sie zu tun.


Die Z-Werte für das obige Beispiel finden Sie auf dieser Seite.

https://2xoin.com/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1

Ich habe auch die R- und S-Werte getrennt, um es Ihnen einfacher zu machen.

Auf dieser Seite finden Sie die R-, S- und Z-Werte für alle Bitcoin-Transaktionen.

Andere Beispiele,

https://2xoin.com/tx/9312ccafb8aa624afe7fb7b4201a0ccc2a14ca2b8b8a3253093b975a6a85a280

https://2xoin.com/tx/a963c57ba8a384bf708d5cf83c932e9174ebd0f82f3820e25dcc8a3d508aed54

https://2xoin.com/tx/19d66411a5aa716a04b37197c11c93c9446a54694a2d2302093d8b0a93ed5d83

https://2xoin.com/tx/9778355a53f295a4ffd592af170badda4e9ad3153e15a4afd76655dac387abb2

Die Antwort gibt die Standard-JSON-Antwort zurück, die Sie im Bitcoin-Core-Client finden, plus einige zusätzliche Bits, die ich hinzugefügt habe, die die R-, S- und Z-Werte für jede Transaktionseingabe anzeigen.

siehe zB SizR-, SigS- und SigZ-Knoten unten.

{
  "rawtx": "01000000028370ef64eb83519fd14f9d74826059b4ce00eae33b5473629486076c5b3bf215000000008c4930460221009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9022100c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6cffffffffb0385cd9a933545628469aa1b7c151b85cc4a087760a300e855af079eacd25c5000000008b48304502210094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45022007eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6cffffffff01404b4c00000000001976a91402d8103ac969fe0b92ba04ca8007e729684031b088ac00000000"
}
{
  "txid": "82e5e1689ee396c8416b94c86aed9f4fe793a0fa2fa729df4a8312a287bc2d5e",
  "version": 1,
  "locktime": 0,
  "vin": [
    {
      "txid": "15f23b5b6c0786946273543be3ea00ceb4596082749d4fd19f5183eb64ef7083",
      "vout": 0,
      "scriptSig": {
        "asm": "30460221009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9022100c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622[ALL] 04e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c",
        "hex": "4930460221009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9022100c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c"
      },
      "sequence": 4294967295,
      "n": 0,
      "addr": "1KtjBE8yDxoqNTSyLG2re4qtKK19KpvVLT",
      "valueSat": 2500000,
      "value": 0.025,
      "doubleSpentTxID": null,
      "sigR": "009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9",
      "sigS": "00c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622",
      "sigZ": "9f4503ab6cae01b9fc124e40de9f3ec3cb7a794129aa3a5c2dfec3809f04c354"
    },
    {
      "txid": "c525cdea79f05a850e300a7687a0c45cb851c1b7a19a4628565433a9d95c38b0",
      "vout": 0,
      "scriptSig": {
        "asm": "304502210094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45022007eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb[ALL] 04e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c",
        "hex": "48304502210094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45022007eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6c"
      },
      "sequence": 4294967295,
      "n": 1,
      "addr": "1KtjBE8yDxoqNTSyLG2re4qtKK19KpvVLT",
      "valueSat": 2500000,
      "value": 0.025,
      "doubleSpentTxID": null,
      "sigR": "0094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45",
      "sigS": "07eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb",
      "sigZ": "94bbf25ba5b93ba78ee017eff80c986ee4e87804bee5770fae5b486f05608d95"
    }
  ],
  "vout": [
    {
      "value": "0.05000000",
      "n": 0,
      "scriptPubKey": {
        "hex": "76a91402d8103ac969fe0b92ba04ca8007e729684031b088ac",
        "asm": "OP_DUP OP_HASH160 02d8103ac969fe0b92ba04ca8007e729684031b0 OP_EQUALVERIFY OP_CHECKSIG",
        "addresses": [
          "1G3BjSLWsWH6tbPYs29fYMYaz9k8EStQM"
        ],
        "type": "pubkeyhash"
      },
      "spentTxId": "9778355a53f295a4ffd592af170badda4e9ad3153e15a4afd76655dac387abb2",
      "spentIndex": 0,
      "spentHeight": 175915
    }
  ],
  "blockhash": "00000000000006467ae1708979d38dcb6d6fcafbab4c6eccf7414da950379243",
  "blockheight": 175915,
  "confirmations": 309447,
  "time": 1334602008,
  "blocktime": 1334602008,
  "valueOut": 0.05,
  "size": 405,
  "valueIn": 0.05,
  "fees": 0
}

Als ich alle Informationen in diesem Thread recherchierte, erstellte ich einige kleine Hilfsgleichungen, die ich beim Experimentieren häufig verwendete.

K = ((Z + (X * R)) / S) % N

X = (((S * K) - Z) / R) % N

Z = ((S * K) - (X * R)) % N

S = ((Z + (X * R)) / K) % N

R = (((S * K) - Z) / X) % N

In meinen obigen Gleichungen

X ist das Hex des privaten Schlüssels,

K multipliziert mit dem sep256k1 G-Wert ergibt einen ECPoint, dessen x-Wert = R ist

Von R aus können Sie also überprüfen, ob Sie den richtigen K-Wert haben, und wenn Sie den richtigen K-Wert haben, können Sie den richtigen X-Wert erhalten, der das Hex des privaten Schlüssels der Adresse in der Transaktionseingabe ist.

Und hier ist ein Beispielcode für C#.

mit System;
mit System.Linq;
mit Org.BouncyCastle.Math;

Namensraum SeansECDSAtest
{
    Klasse Programm
    {
        static void Main(string[] args)
        {
            BigInteger R = new BigInteger(StringToByteArray("00d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1"));
            BigInteger S = new BigInteger(StringToByteArray("0044e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e"));
            BigInteger Z = new BigInteger(StringToByteArray("00c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e"));
            BigInteger X = new BigInteger(StringToByteArray("00c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96"));
            BigInteger K = new BigInteger(StringToByteArray("007a1a7e52797fc8caaa435d2a4dace39158504bf204fbe19f14dbb427faee50ae"));
            BigInteger N = new BigInteger(StringToByteArray("00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"));

            // R = (((S * K) - Z) / X) % N beweisen
            var verifyR = S.Multiply(K).Subtract(Z).Multiply(X.ModInverse(N)).Mod(N);
            Console.WriteLine("R = " + string.Concat(verifyR.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            // beweist S = ((Z + (X * R)) / K) % N
            var verifyS = Z.Add(X.Multiply(R)).Multiply(K.ModInverse(N)).Mod(N);
            Console.WriteLine("S = " + string.Concat(verifyS.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            // beweist Z = ((S * K) - (X * R)) % N
            var verifyZ = S.Multiply(K).Subtract(X.Multiply(R)).Mod(N);
            Console.WriteLine("Z = " + string.Concat(verifyZ.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            // beweist X = (((S * K) - Z) / R) % N
            var verifyX = S.Multiply(K).Subtract(Z).Multiply(R.ModInverse(N)).Mod(N);
            Console.WriteLine("X = " + string.Concat(verifyX.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            // beweist K = ((Z + (X * R)) / S) % N
            var verifyK = Z.Add(X.Multiply(R)).Multiply(S.ModInverse(N)).Mod(N);
            Console.WriteLine("K = " + string.Concat(verifyK.ToByteArrayUnsigned().Select(b => b.ToString("X2"))));

            Console.ReadLine();
        }

        public static byte[] StringToByteArray(string hex)
        {
            return Enumerable.Range(0, hex.Length)
                             .Wo(x => x % 2 == 0)
                             .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                             .ToArray();
        }
    }
}

Und der gleiche Code in Python

def extended_gcd(aa, bb):
    lastremainder, remainder = abs(aa), abs(bb)
    x, lastx, y, lasty = 0, 1, 1, 0
    while remainder:
        lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder)
        x, lastx = lastx - quotient*x, x
        y, lasty = lasty - quotient*y, y
    return lastremainder, lastx * (-1 if aa < 0 else 1), lasty * (-1 if bb < 0 else 1)

def modinv(a, m):
    g, x, y = extended_gcd(a, m)
    if g != 1:
        raise ValueError
    return x % m

R = 0x00d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1
S = 0x0044e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e
Z = 0x00c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e
X = 0x00c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96
K = 0x007a1a7e52797fc8caaa435d2a4dace39158504bf204fbe19f14dbb427faee50ae

N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

#proving R = (((S * K) - Z) / X) % N
print hex((((S * K) - Z) * modinv(X,N)) % N)

#proving S = ((Z + (X * R)) / K) % N
print hex(((Z + (X * R)) * modinv(K,N)) % N)

#proving Z = ((S * K) - (X * R)) % N
print hex(((S * K) - (X * R)) % N)

#proving X = (((S * K) - Z) / R) % N
print hex((((S * K) - Z) * modinv(R,N)) % N)

#proving K = ((Z + (X * R)) / S) % N
print hex(((Z + (X * R)) * modinv(S,N)) % N)
Danke, aber alles, was ich suche, ist, einen Sinn dafür zu finden, wie ich an Z, den Hash, komme. Den Rest des Algorithmus erhalte ich. Ich verstehe nur nicht, wie man "Z" bekommt. Das ist es. Das Problem ist, dass die meisten Antworten äußerst komplex sind. Ich wäre sehr glücklich, wenn ich nur etwas von der Transaktionsseite einer bestimmten Transaktion kopieren und in eine Website einfügen müsste, auf eine Schaltfläche klicken und, BAM, Z-Wert. Tatsächlich würde ich zu diesem Zeitpunkt letzteres bevorzugen.
Besuchen Sie 2coin.org. Es zeigt die Z-Werte, die Sie kopieren und einfügen können. z.B. 2coin.org/… Im Abschnitt „Eingaben“ werden die Werte der R-, S-, Z- und öffentlichen Schlüssel getrennt. Wenn Sie denken, dass eine API für Sie nützlich sein könnte, könnte ich ziemlich schnell eine zusammenstellen.
Ich habe eine API erstellt, um die Z-Werte von Transaktionen einfach abzurufen. Ich habe die Details zu meinem ursprünglichen Beitrag oben hinzugefügt.
@SeanBradley schau dir meinen Kommentar in der Antwort von Willem an. Kannst du mir bitte helfen? Ich kann das invmod (s1-s2) nicht bekommen, es ist in meinem Fall nicht 0xf7d5417b3844fd8f4b3d909979fa7480ce094fb233d759274fd6c3aa6cf86593.
@SeanBradley your result: 0xb440675bdc7cd712ea08fc875df4a8e9f50991650625f25a3a474b6bd6cdb89eL my result: 0x4188f2f2de07b663f48dd0fc2f0d00953fa26c5cb977d374f2a2beac7d459498L Willem's result: 0xf7d5417b3844fd8f4b3d909979fa7480ce094fb233d759274fd6c3aa6cf86593L. Ich verstehe nicht. Vielen Dank
@lontivero, siehe meine Demo unter ideone.com/o624rX
@lontivero, wenn ich Code in diese Kommentare einfüge, funktioniert es nie, also habe ich einen Druckbildschirm erstellt. Damit bekomme ich das richtige Ergebnis. prntscr.com/5g67tf
Es war mein Fehler, Sean. Danke für deine Hilfe.
@ SeanBradley Vielen Dank (wenn auch spät von meiner Seite) für all die Hilfe, die Sie mir geleistet haben. Obwohl ich die von Ihnen geposteten APIs nicht zum Laufen bringen kann. Sie geben einfach einen Fehler aus und zeigen nichts an. Ich weiß, es ist eine Weile her, aber könnten Sie diese bitte noch einmal überprüfen?
Alle 2coin.org-Links zu biizii.com, sieht aus, als wäre es weg.

Anmerkung: Was Nils Schneider „z“ nennt, nenne ich „m“.

Dieser Kern implementiert all dies: https://gist.github.com/nlitsme/dda36eeef541de37d996

die Berechnung

Die ecdsa-Signierung erfolgt wie folgt:

gegeben eine Nachricht 'm', ein Zeichengeheimnis 'k', einen privaten Schlüssel 'x'

 R = G*k  (elliptic curve scalar multiplication)
 r = xcoordinate(R)
 s = (m + x * r) / k     (mod q)

q = die Gruppenordnung von secp256k1 = 2^256 - 432420386565659656852420866394968145599

Wenn wir nun 2 Signaturen mit identischem k haben, können wir dies wie folgt schreiben:

 s1 * k = ( m1 + x * r ) (mod q)
 s2 * k = ( m2 + x * r ) (mod q)

Subtrahieren Sie diese beiden Gleichungen und erhalten Sie:

(s1-s2)*k = (m1-m2)      (mod q)

das Vorzeichengeheimnis 'k' kann nun also wie folgt berechnet werden:

k = (m1-m2)/(s1-s2)      (mod q)

und gegeben k, kann der private Schlüssel wie folgt berechnet werden:

x = (s1*k-m1) / r        (mod q)

praktisches Beispiel

Dieses Beispiel verwendet diese Transaktion aus dem Jahr 2012.

die ursprüngliche Transaktion

Die folgenden Zeilen stellen dar:

  • das Versionsfeld

  • die Anzahl der Eingänge (02)

  • die 2 Eingänge

  • die Anzahl der Ausgänge (01)

  • die Ausgabe

  • das Sperrzeitfeld

    01 00 00 00
    02
     f6 4c 60 3e 2f 9f 4d af 70 c2 f4 25 2b 2d cd b0 7c c0 19 2b 72 38 bc 9c 3d ac ba e5 55 ba f7 01 01 00 00 00  8a 47 30 44 02 20 d4 7c e4 c0 25 c3 5e c4 40 bc 81 d9 98 34 a6 24 87 51 61 a2 6b f5 6e f7 fd c0 f5 d5 2f 84 3a d1 02 20 44 e1 ff 2d fd 81 02 cf 7a 47 c2 1d 5c 9f d5 70 16 10 d0 49 53 c6 83 65 96 b4 fe 9d d2 f5 3e 3e 01 41 04 db d0 c6 15 32 27 9c f7 29 81 c3 58 4f c3 22 16 e0 12 76 99 63 5c 27 89 f5 49 e0 73 0c 05 9b 81 ae 13 30 16 a6 9c 21 e2 3f 18 59 a9 5f 06 d5 2b 7b f1 49 a8 f2 fe 4e 85 35 c8 a8 29 b4 49 c5 ff  ff ff ff ff
     29 f8 41 db 2b a0 ca fa 3a 2a 89 3c d1 d8 c3 e9 62 e8 67 8f c6 1e be 89 f4 15 a4 6b c8 d9 85 4a 01 00 00 00  8a 47 30 44 02 20 d4 7c e4 c0 25 c3 5e c4 40 bc 81 d9 98 34 a6 24 87 51 61 a2 6b f5 6e f7 fd c0 f5 d5 2f 84 3a d1 02 20 9a 5f 1c 75 e4 61 d7 ce b1 cf 3c ab 90 13 eb 2d c8 5b 6d 0d a8 c3 c6 e2 7e 3a 5a 5b 3f aa 5b ab 01 41 04 db d0 c6 15 32 27 9c f7 29 81 c3 58 4f c3 22 16 e0 12 76 99 63 5c 27 89 f5 49 e0 73 0c 05 9b 81 ae 13 30 16 a6 9c 21 e2 3f 18 59 a9 5f 06 d5 2b 7b f1 49 a8 f2 fe 4e 85 35 c8 a8 29 b4 49 c5 ff  ff ff ff ff
    01
     a0 86 01 00 00 00 00 00 19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac
    00 00 00 00
    

die Eingabeskripte

Das Eingabeskript besteht aus:

  • die Gesamtlänge (8a)

  • die Unterschrift

  • der öffentliche Schlüssel

    8a
    47 30 44 02 20 d4 7c e4 c0 25 c3 5e c4 40 bc 81 d9 98 34 a6 24 87 51 61 a2 6b f5 6e f7 fd c0 f5 d5 2f 84 3a d1 02 20 44 e1 ff 2d fd 7 1 8 c2 1d 5c 9f d5 70 16 10 d0 49 53 c6 83 65 96 b4 fe 9d d2 f5 3e 3e 01 41 04 db d0 c6 15 32 27 9c f7 29 81 c3 58 4f c3 22 16 e0 12 76 8 9 fc 5 2.3 49 e0 73 0c 05 9b 81 ae 13 30 16 a6 9c 21 e2 3f 18 59 a9 5f 06 d5 2b 7b f1 49 a8 f2 fe 4e 85 35 c8 a8 29 b4 49 c5 ff

Die Signatur ist ein asn1-codierter r+s-Wert + ein Hashtyp-Indikator (01)

30 44 
    02 20  d4 7c e4 c0 25 c3 5e c4 40 bc 81 d9 98 34 a6 24 87 51 61 a2 6b f5 6e f7 fd c0 f5 d5 2f 84 3a d1
    02 20  44 e1 ff 2d fd 81 02 cf 7a 47 c2 1d 5c 9f d5 70 16 10 d0 49 53 c6 83 65 96 b4 fe 9d d2 f5 3e 3e
01

Jetzt können wir diese Werte aus der Transaktion extrahieren:

pk 04dbd0c61532279cf72981c3584fc32216e0127699635c2789f549e0730c059b81ae133016a69c21e23f1859a95f06d52b7bf149a8f2fe4e8535c8a829b449c5ff
r  d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1
s1 44e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e
s2 9a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab

Als nächstes müssen wir die Nachrichten-Hashes berechnen.

vorbereiten

Entfernen Sie die Eingabeskripte und fügen Sie den Hashtyp hinzu

01 00 00 00
02
 f6 4c 60 3e 2f 9f 4d af 70 c2 f4 25 2b 2d cd b0 7c c0 19 2b 72 38 bc 9c 3d ac ba e5 55 ba f7 01 01 00 00 00  00  ff ff ff ff
 29 f8 41 db 2b a0 ca fa 3a 2a 89 3c d1 d8 c3 e9 62 e8 67 8f c6 1e be 89 f4 15 a4 6b c8 d9 85 4a 01 00 00 00  00  ff ff ff ff
01
 a0 86 01 00 00 00 00 00 19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac
00 00 00 00
01 00 00 00   <<< hashtype

m1 berechnen

Ersetzen Sie die erste Eingabe durch das entsprechende Ausgabeskript

01 00 00 00
02
 f6 4c 60 3e 2f 9f 4d af 70 c2 f4 25 2b 2d cd b0 7c c0 19 2b 72 38 bc 9c 3d ac ba e5 55 ba f7 01 01 00 00 00  19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac  ff ff ff ff
 29 f8 41 db 2b a0 ca fa 3a 2a 89 3c d1 d8 c3 e9 62 e8 67 8f c6 1e be 89 f4 15 a4 6b c8 d9 85 4a 01 00 00 00  00  ff ff ff ff
01
 a0 86 01 00 00 00 00 00 19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac
00 00 00 00
01 00 00 00

dann mach sha256(sha256(modifizierte Transaktion))

Dies führt zu: c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e

m2 berechnen

Ersetzen Sie die zweite Eingabe durch das entsprechende Ausgabeskript

01 00 00 00
02
 f6 4c 60 3e 2f 9f 4d af 70 c2 f4 25 2b 2d cd b0 7c c0 19 2b 72 38 bc 9c 3d ac ba e5 55 ba f7 01 01 00 00 00  00  ff ff ff ff
 29 f8 41 db 2b a0 ca fa 3a 2a 89 3c d1 d8 c3 e9 62 e8 67 8f c6 1e be 89 f4 15 a4 6b c8 d9 85 4a 01 00 00 00  19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac  ff ff ff ff
01
 a0 86 01 00 00 00 00 00 19 76 a9 14 70 79 2f b7 4a 5d f7 45 ba c0 7d f6 fe 02 0f 87 1c bb 29 3b 88 ac
00 00 00 00
01 00 00 00

dann mach sha256(sha256(modifizierte Transaktion))

Dies führt zu: 17b0f41c8c337ac1e18c98759e83a8cccbc368dd9d89e5f03cb633c265fd0ddc

Beachten Sie, dass die eingelösten Ausgabeskripte und das Ausgabeskript dieser Transaktion in diesem Fall alle identisch sind. Das ist normalerweise nicht so.

Unsere Nachrichten-Hashes sind also:

m1 c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e
m2 17b0f41c8c337ac1e18c98759e83a8cccbc368dd9d89e5f03cb633c265fd0ddc
s1 44e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e
s2 9a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab

m1-m2 =
0xA931DC8C0E011326AE4D6FAB7DED290B196966154E0A73A0DF434413217B3E92

modulare Umkehrung von s1-s2 = 0xf7d5417b3844fd8f4b3d909979fa7480ce094fb233d759274fd6c3aa6cf86593

unser geheimer 'k'-Wert ist also:

-> (m1-m2)/(s1-s2) = 0x7a1a7e52797fc8caaa435d2a4dace39158504bf204fbe19f14dbb427faee50ae

Der private Schlüssel kann dann berechnet werden:

s1*k-m1 = 0x797035d79964e4b74fbbef4460379c410261cd01de43278bc2a7efaa541dd8e9 - 0xc0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e
= 0xB88D652EFF3056CEBFE1E72343C6CA67D7E3DAF5A1F76E366680D6619CDBCDBC

(s1*k-m1)/r = 0xc477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96

Sie können hier mit diesen Berechnungen experimentieren .

Erläuterung der Transaktionsinhalte

Eine Transaktion besteht aus einer Reihe von Eingaben und einer Reihe von Ausgaben.

Eine Eingabe bezieht sich auf eine der Ausgaben einer anderen Transaktion und enthält ein Skript, das beweist, dass diese Transaktion diese Ausgabe einlösen darf.

Eine Ausgabe besteht aus einem BTC-Wert und einem Skript, das verwendet wird, um den im Eingabeskript präsentierten Nachweis zum Zeitpunkt der Einlösung dieser Ausgabe zu validieren.

Wenn eine Ausgabe eingelöst wird, werden die Eingabe- und Ausgabeskripte verkettet und vom Bitcoin-Client ausgewertet. das Ergebnis muss 'TRUE' sein.

Die Skriptsprache ist eine sehr einfache, nicht-turing-vollständige, stapelbasierte Sprache.

Das gebräuchlichste Skript sieht so aus:

---- input script ( aka scriptSig )
PUSH signature
PUSH publickey
---- output script ( aka scriptPubKey )
DUP
HASH160
PUSH pubkeyhash
EQUALVERIFY
CHECKSIG

Beachten Sie, dass „PUSH“ in der Bitcoin-Skriptbeschreibung nicht ausdrücklich als PUSH gekennzeichnet ist.

Im Ausgabeskript wird zunächst überprüft, ob der Adresshash (das ist die Bitcoin-Adresse im Binärformat) dem öffentlichen Schlüssel aus der Eingabe entspricht. Dann CHECKSIGwird damit verifiziert, dass die angegebene Signatur für diese Transaktion gültig ist.

Ich versuche immer noch, diese Antwort zu verstehen, ziemlich komplex. Was ist die Definition einer „Eingabe“ für eine Transaktion? Dass die Anzahl der Adressen, von denen gesendet wird? Und was ist die Definition einer "Ausgabe"? Anzahl der Adressen, an die gesendet wird? Vielleicht sollte ich etwas ähnliches fragen. Welche Informationen benötige ich und wie würde ich sie verwenden, um einfach meine eigene Transaktion an das Netzwerk zu übermitteln? Privater Schlüsselpunkt K-mal mit sich selbst multipliziert, öffentlicher Schlüssel und ... der Hash. Ich denke, meine Hauptschwierigkeit ist "m" oder die "Nachricht", die ganze "Ausgabe", "Eingabe" und "Skript" werfen mich ab
Nun zu den Gleichungen, die Sie gezeigt haben, welche Elemente werden bereits auf blockexplorer.com/rawtx/… und/oder blockchain.info/tx/… angezeigt ? Das heißt, sagen wir, ich habe K und möchte so einfach wie möglich nach x (privater Schlüssel) auflösen, welche Variablen für Ihre ursprünglichen Gleichungen werden mir bereits angezeigt? (Ich weiß, dass dies anscheinend bereits in Ihrem Beitrag beantwortet wurde, aber ich bin in einigen Teilen davon verwirrt, weil ich so viele Definitionen für so viele dieser Dinge gehört habe). –
der öffentliche Schlüssel, 'r'- und 's'-Wert können direkt aus dem Eingabeskript ( scriptSig ) abgerufen werden. der 'm'-Wert muss berechnet werden. „q“ und „G“ sind Konstanten, die von der in Bitcoin verwendeten secp256k1-Kurve angegeben werden
Ich versuche das nochmal. Ich habe den Inhalt des Codefensters unter "Berechnung von m1 - Ersetze die erste Eingabe durch das entsprechende Ausgabeskript" kopiert und eingefügt und in einen sha 256d-Algorithmus-Rechner eingefügt, dann dieses Ergebnis genommen und es gemäß den Anweisungen auch gehasht, die Ergebnisse stimmten nicht mit den richtigen Ergebnissen überein
modulare Umkehrung von s1-s2? hat mod nicht 2 Operanden?
Alle Berechnungen sind Modulo q
Ich bin im Invmod-Schritt blockiert. Folgendes bekomme ich: prntscr.com/5fzzys . Was mache ich falsch? Ich kann die modulare Umkehrung von s1-s2 = 0xf7d5417b3844fd8f4b3d909979fa7480ce094fb233d759274fd6c3aa6cf86593 nicht erhalten
der Wert in deinem Screenshot von s1-s2 ist schon falsch, überprüfe vielleicht deine Eingaben. Hier ist der funktionierende Code: ideone.com/bjSai7
Die .NET Bigint-Klasse ist ein bisschen knifflig, aber ich habe es mit Ihrer Hilfe geschafft! Danke @WillemHengeveld
@WillemHengeveld was ist, wenn es mehr als nur eine Ausgabe gibt? Wie berechne ich die M-Werte? Ich meine, was soll ich im Abschnitt Berechnung von m1 ändern ??
Weitere Ausgaben von was?
In Ihrem praktischen Beispiel hat die Transaktion 2 Eingänge und 1 Ausgang, aber der tx kann n Ausgänge haben. Verstehe ich etwas falsch?
Die Signatur befindet sich im Eingabeskript und verwendet das Ausgabeskript seiner Quelltransaktion bei der Berechnung des Nachrichtenhashs. Die Anzahl der Ausgaben für die Transaktion spielt also keine Rolle, sie werden immer unverändert in den Messagehash für jede Eingabe gehasht.
2xoin.com ist jetzt auch weg, was bedauerlich ist. Aber danke für die ausführliche Beschreibung deiner Berechnungen und nicht nur für die Links.

Wir müssen nur z1 und z2 finden! Dies sind die Hashes der zu signierenden Ausgaben. Lassen Sie uns die Ausgabetransaktionen abrufen und berechnen (wird von OP_CHECKSIG berechnet):

Die Seite des Bitcoin-Wikis auf OP_CHECKSIG und das Bild dort zeigen, was signiert ist: im Wesentlichen die neue Transaktion mit entfernten Txins und eingefügter Transaktionsausgabe. Es ist der Hash dieser Bytes, der tatsächlich signiert ist, nämlich z1und z2.

Dieser Pseudocode könnte helfen zu verdeutlichen, wie die zs verwendet werden:

def sign(priv_key, txin_index):
    z = get_data_to_sign(txin_index) # uses algorithm at https://en.bitcoin.it/w/images/en/7/70/Bitcoin_OpCheckSig_InDetail.png
    r = super_secure_random()
    s = ECDSA_sign(priv_key, z, r)
    return r, s

def verify(pub_key, txin_index, r, s):
    z = get_data_to_sign(txin_index)
    ECDSA_verify(pub_key, z, r, s)

def super_secure_random():
    return 4