Bitcoins auf dem 55-jährigen IBM 1401 abbauen

Inspiriert von der Veröffentlichung des Benutzers mark_ablov" Mit Bitcoin mit Papier und Stift " entschieden wir, dass Hiktime-Leser daran interessiert sein würden, welche anderen verrückten Ideen der Autor des ursprünglichen Beitrags, Ken Shirriff, verwirklicht hat.

Kann der IBM-Mainframe aus den 60er Jahren des letzten Jahrhunderts für den Abbau von Bitcoins verwendet werden? Ich beschloss, diese scheinbar verrückte Idee auszuprobieren. Ich habe den Bitcoin-Hash-Algorithmus in Assembler-Code für IBM 1401 eingebettet und ihn in der Praxis getestet, indem ich ihn auf einem funktionsfähigen Modell dieses alten Mainframes ausgeführt habe.


Die Lochkarte, die zur Berechnung der SHA-256-Hashes auf dem IBM 1401-Mainframe verwendet wird. Hinter der Lochkarte ist ein Ausdruck sichtbar, der die Eingabe des Algorithmus und den resultierenden Hash zeigt

Wie sich herausstellte, können Sie diesen Computer abbauen, aber dieser Vorgang wird so lange dauern, dass selbst die gesamte Lebensdauer des Universums möglicherweise nicht ausreicht, um einen Block erfolgreich abzubauen.

Während Sie mit moderner Hardware Milliarden von Hashes pro Sekunde berechnen können, benötigt der Computer 1401 jeweils 80 Sekunden, um einen einzelnen Hash zu berechnen. Die Fortschritte bei der Computerleistung in den letzten Jahrzehnten sind offensichtlich, was durch das Gesetz von Gordon Moore klar beschrieben wird.

Die Lochkarten, die an dem Experiment teilgenommen haben, sowie der Ausdruck SHA-256 mit einem Zeilendrucker sind auf dem Foto oben dargestellt (die erste Lochkarte dient nur der Schönheit - es war nicht einfach, dieses Muster zu durchbrechen). Beachten Sie, dass die zweite Zeile mit einer Gruppe von Nullen endet. Dies bedeutet einen erfolgreichen Hash.

Bitcoin-Mining-Prinzip


In jüngster Zeit war die elektronische Währung Bitcoin (Bitcoin), die Internetnutzer untereinander übertragen können, sehr beliebt. Um das Wesentliche der Arbeit dieser Kryptowährung zu verstehen, kann das Bitcoin-System in Form einer Art Buchhaltungsjournal dargestellt werden, in dem Aufzeichnungen über den Besitzer digitaler Münzen (Bitcoins) und die Anzahl der Münzen gespeichert sind, über die er verfügt. Bitcoin-Mitglieder können digitale Münzen untereinander übertragen.

Es ist zu beachten, dass das Bitcoin-System dezentralisiert ist: Es verfügt nicht über einen einzigen Regulierungsserver, der den Fortschritt von Transaktionen überwacht. Stattdessen werden Datensätze über ein verteiltes Netzwerk von Tausenden von Computern im Internet gesendet.

Die Schwierigkeit besteht darin, dass ein solches verteiltes System irgendwie sicherstellen muss, dass alle Benutzer den Aufzeichnungen zustimmen. Das heißt, gewissenhafte Benutzer müssen die Gültigkeit der Transaktion bestätigen und genehmigen, obwohl möglicherweise Betrüger und langsam laufende Netzwerke vorhanden sind. Die Lösung für dieses Problem war der sogenannte "Bergbau". Ungefähr alle 10 Minuten während des Mining-Prozesses wird ein Block ausgehender Transaktionen bestätigt, sodass er als offiziell bestätigt gilt.

Der auf zuverlässiger Kryptografie basierende Mining-Prozess ist äußerst kompliziert, sodass niemand steuern kann, welche Transaktionen abgebaut werden. Die Schlüsselidee des Bitcoin-Systems ist insbesondere, dass das Ergebnis der Arbeit schwierig und schwierig ist, aber leicht zu überprüfen ist. Dies ist die sogenannte „Proof-of-Work“ -Technologie.

Der Prozess des Block Mining erfordert einen enormen Rechenaufwand. Nachdem der Block bestätigt wurde, können Peer-to-Peer-Benutzer seine Gültigkeit leicht überprüfen. Die Komplexität des Mining verhindert die betrügerische Verwendung von Bitcoin, und die einfache Überprüfung der Gültigkeit des Blocks ermöglicht es Benutzern, sich auf die Gültigkeit von Transaktionen zu verlassen.

Ein Nebeneffekt des Bergbaus ist das Hinzufügen neuer Bitcoins zum System. Derzeit erhält jeder, der den Block bestätigt, 25 generierte Bitcoins dafür (jetzt betragen die Kosten für diese Anzahl virtueller Münzen in traditionellen Geldbeträgen etwa 6.000 US-Dollar). Diese Ermutigung ermutigt die Bergleute, hart zu arbeiten und ihre Ressourcen für den Bergbau auszugeben. Angesichts der Möglichkeit, alle 10 Minuten 6.000 US-Dollar zu erhalten, scheint der Bergbau eine echte „Goldmine“ zu sein, die die Benutzer dazu ermutigt, erhebliche Beträge für Hardware für den Bergbau auszugeben.


Der Zeilendrucker und der IBM 1401 Mainframe wurden im Computer History Museum vorgestellt. Auf diesem Computer wurde mein Programm ausgeführt. Die Konsole befindet sich oben links. Die dunklen rechteckigen Paneele am Computer sind die „Türen“ der zurücklehnenden Racks, die den Zugang für Wartungsarbeiten ermöglichen.

Der Abbauprozess ist äußerst kompliziert, aber das Ergebnis ist sehr einfach zu überprüfen. Beim Bitcoin-Mining wird Kryptografie mit einer Hash-Funktion namens Double SHA-256 verwendet. Der Hash nimmt einen Datenblock am Eingang und reduziert ihn auf einen niedrigeren Hashwert (in diesem Fall 256 Bit).

Mit dem kryptografischen Hashing-Algorithmus können Sie den gewünschten Hash-Wert nicht abrufen, ohne die Datenmasse an der Eingabe sortieren zu müssen. Nachdem Sie jedoch eine Eingabe gefunden haben, die den gewünschten Wert liefert, kann jeder den Hash leicht überprüfen. Daher ist kryptografisches Hashing eine gute Möglichkeit, Bitcoins mit „Proof-of-Work“ zu implementieren.

Um einen Block zu glänzen, müssen Sie zunächst neue Transaktionen in einem Block sammeln. Dann müssen Sie den Block hashen, um (im Wesentlichen zufällig) den Hash-Wert des Blocks zu erhalten. Wenn der Hashwert mit 16 Nullen beginnt, wird der Block als erfolgreich bestätigt betrachtet und an das Bitcoin-Netzwerk gesendet. Meistens ist der Hash nicht erfolgreich, daher ändern Sie den Block leicht und versuchen es nach mehr als einer Milliarde Rechenoperationen immer wieder. Ungefähr alle 10 Minuten gelingt es jemandem, den Block erfolgreich zu bestätigen, und der Prozess beginnt erneut. Dies erinnert an eine Lotterie, an der Bergleute teilnehmen und einen Versuch nach dem anderen machen, bis jemand zum „Gewinner“ wird. Die Komplexität des Hashing-Prozesses ist schwer zu visualisieren: Es ist einfacher, ein Sandkorn im gesamten Sand der Erde zu finden, als einen gültigen Hash-Wert zu finden.Um nach solchen Hashwerten zu suchen, verwenden Bergleute Rechenzentren, die mit spezieller Hardware für den Bergbau ausgestattet sind.

Ich vereinfache bewusst viele der Erklärungen in diesem Artikel. Wenn Sie mehr über das Bitcoin-System und den Bergbau erfahren möchten, empfehle ich Ihnen, meine Artikel zu lesen. Die schwierigen Erfahrungen beim Bergbau von Bitcoins und die harten Lehren aus dem Bitcoin-Bergbau .

Bitcoin SHA-256 Hash-Algorithmus


Jetzt werde ich mir die von Bitcoin verwendete Hash-Funktion ansehen, die auf einer kryptografischen Standard-Hash-Funktion namens SHA-256 basiert. Das Bitcoin-System verwendet einen "doppelten SHA-256". Dies bedeutet, dass die SHA-256-Funktion zweimal ausgeführt wird. Der SHA-256-Algorithmus ist so einfach, dass Sie ihn buchstäblich nur mit Bleistift und Papier ausführen können. Mit dem Algorithmus können Sie Daten auf unvorhersehbare Weise mischen. Der Algorithmus akzeptiert 64-Byte-Blöcke am Eingang, verarbeitet die Daten kryptografisch und erzeugt 256 Bit (32 Byte) verschlüsselte Daten. Der Algorithmus verwendet eine Runde, die 64 Mal wiederholt wird. Die folgende Abbildung zeigt eine Runde des Algorithmus, der acht 4-Byte-Blöcke A bis H benötigt, mehrere Operationen ausführt und neue Werte für A bis N erzeugt.


Runde SHA-256, als Beispiel aus Wikipedia , von Kockmeyer, CC BY-SA 3.0

Dunkelblaue Blöcke mischen Bits nichtlinear, was für die kryptografische Analyse schwierig ist. (Wenn Sie einen mathematisch schnelleren Weg finden, um erfolgreiche Hashes zu erhalten, können Sie das Mining von Bitcoins steuern.) Die Zelle "select" Ch wählt Bits aus F oder G basierend auf dem Wert von Eingang E aus. Zellen Σ "sum" drehen die Bits A (oder E), erzeugen drei zyklisch verschobene Versionen und summieren sie dann Modulo 2.

Die Ma-Mehrheitszelle prüft die Bits an jeder Position von A, B und C und wählt 0 oder 1 aus, je nachdem, welcher Wert in der Mehrheit ist. Rote Blutkörperchen führen 32-Bit-Additionen durch und generieren neue Werte für A und E. Die Eingabe Wt basiert auf einer leicht verarbeiteten Eingabe. (Hier wird der Eingabeblock in den Algorithmus eingeführt.) Die Eingabe Kt ist eine Konstante, die für jede Runde definiert wird.

Gemäß der obigen Abbildung werden nur A und E pro Runde geändert. Die verbleibenden Werte werden unverändert übersprungen. Der alte Wert von A wird zum neuen Wert von B, der alte Wert von B wird zum neuen Wert von C und so weiter. Obwohl jede Runde von SHA-256 die Daten geringfügig ändert, werden die Eingabedaten nach 64 Runden vollständig gemischt, was einen unvorhersehbaren Hashwert ergibt.

Ibm 1401


Ich entschied mich, diesen Algorithmus auf dem IBM 1401-Mainframe auszuführen. Dieser Computer erschien 1959 und wurde Mitte der 60er Jahre zum meistverkauften Computer - zu dieser Zeit wurden mehr als 10.000 Maschinen aktiv betrieben. Der Computer 1401 war selbst für 1960 kein sehr leistungsfähiger Computer. Es war jedoch für mittelständische Unternehmen erschwinglich, die sich einen Computer bisher nicht leisten konnten, da er für wenig Geld gemietet werden konnte - 2.500 USD pro Monat.

Der IBM 1401 verwendete keine Siliziumchips. Außerdem gab es in diesem Computer überhaupt keine Chips. Seine Transistoren wurden auf Halbleitern, Germaniumkristallen, aufgebaut, die vor Silizium verwendet wurden. Transistoren wurden zusammen mit anderen Komponenten auf Karten installiert, die die Größe von Spielkarten hatten, die als SMS-Karten bezeichnet wurden. Der Computer umfasste Tausende solcher Karten, die in Form von Gestellen installiert wurden, die als „Türen“ bezeichnet wurden. Der IBM 1401 verfügt über zwanzig solcher „Türen“, die für die Computerwartung vorgeschlagen wurden. In der obigen Abbildung ist eine offene Tür sichtbar, die den Zugang zu Mikrochips und Kabeln ermöglicht.


Die Abbildung zeigt ein offenes Rack (die sogenannte „Tür“) des IBM 1401-Mainframes. Das Foto zeigt an die Schaltung angeschlossene SMS-Karten. Dieses Rack steuert Bandlaufwerke

Das Funktionsprinzip eines solchen Computers unterschied sich erheblich von modernen PCs. Dieser Computer verwendete keine 8-Bit-Bytes, sondern 6-Bit-Zeichen basierend auf der binär codierten Dezimalzahl (BCD). Da dieser Computer eine Rechenmaschine zur Lösung wirtschaftlicher Probleme war, verwendete er eher Dezimal- als Binärarithmetik, und jedes Zeichen im Speicher hatte einen digitalen Wert von 0 bis 9. Der Computerspeicher auf Magnetkernen enthielt 4000 Zeichen. Ein Speichererweiterungsmodul von der Größe eines Geschirrspülers erhöhte die Speicherkapazität um 12.000 Zeichen. Die Dateneingabe in den Computer erfolgte mit Lochkarten. Kartenleser liest Daten und Programme von Karten. Die Ausgabedaten wurden mit einem Hochgeschwindigkeits-Drain-Drucker ausgedruckt oder auf Karten gestanzt.

Museum für Computergeschichte Computer History MuseumIn Mountain View gibt es zwei funktionsfähige IBM 1401-Mainframes. Auf einem davon habe ich den SHA-256-Hashcode ausgeführt. Ich spreche mehr über IBM 1401 in meinem Artikel Fraktale auf IBM 1401
.

Ausführen von SHA-256 auf einem IBM 1401


Sicherlich ist der IBM 1401-Computer der schlechteste aller Computer, die für die Ausführung des SHA-256-Hash-Algorithmus ausgewählt werden könnten. Um effektiv zu arbeiten, benötigt dieser Algorithmus Maschinen, die Bitoperationen in 32-Bit-Wörtern ausführen können. Leider unterstützt IBM 1401 weder 32-Bit-Wörter noch Bytes. Dieser Computer arbeitet mit 6-Bit-Zeichen und erlaubt keine Bitoperationen. Darüber hinaus wurde darin anstelle von Binär eine Dezimalarithmetik verwendet. Daher ist der Algorithmus auf dem Computer 1401 langsam und für den Benutzer unpraktisch.

Am Ende habe ich ein Zeichen pro Bit verwendet. Der 32-Bit-Wert wurde als 32 Zeichen gespeichert, entweder "0" oder "1". Mein Code musste zeichenweise bitweise Operationen, Multiplikationen und Additionen ausführen, jedes Zeichen überprüfen und entscheiden, was damit zu tun ist. Wie zu erwarten war, dauerte die Codeausführung lange.

Als nächstes präsentiere ich den Assembler-Code, den ich geschrieben habe. Im Allgemeinen wird das Prinzip des Codes in den Kommentaren beschrieben. Am Ende des Codes befindet sich eine Tabelle mit Konstanten, die für den SHA-256-Algorithmus in hexadezimaler Form erforderlich sind. Da der Computer 1401 das Hexadezimalformat nicht unterstützt, musste ich meine eigenen Routinen zum Konvertieren des Hexadezimal- und Binärformats schreiben. In diesem Artikel werde ich den Assembler-Code für IBM 1401 nicht erläutern. Ich möchte nur betonen, dass er sich stark von dem unterscheidet, was moderne Computer verwenden. Dieser Code ruft keine Unterprogramme auf und gibt keine Ergebnisse zurück. Aufgrund des Fehlens von Allzweckregistern werden Operationen im Speicher ausgeführt.

Suchen Sie nach dem Code unter dem Spoiler:
Versteckter Text
job  bitcoin
     * SHA-256 hash
     * Ken Shirriff  http://righto.com
               ctl  6641

               org  087
     X1        dcw  @000@
               org  092
     X2        dcw  @000@
               org  097
     X3        dcw  @000@
     
               org  333
     start     cs   299
               r
               sw   001
               lca  064, input0
               mcw  064, 264
               w
     * Initialize word marks on storage
               mcw  +s0, x3

     wmloop    sw   0&x3  
               ma   @032@, x3
               c    +h7+32, x3
               bu   wmloop
     
               mcw  +input-127, x3      * Put input into warr[0] to warr[15]
               mcw  +warr, x1
               mcw  @128@, tobinc
               b    tobin
     
     * Compute message schedule array w[0..63]
  
               mcw  @16@, i
     * i is word index 16-63   
     * x1 is start of warr[i-16], i.e. bit 0 (bit 0 on left, bit 31 on right)   
               mcw  +warr, x1
     wloop     c    @64@, i
               be   wloopd
     
     * Compute s0
               mcw  +s0, x2
               za   +0, 31&x2               * Zero s0
     * Add w[i-15] rightrotate 7
               sw   7&x2               * Wordmark at bit 7 (from left) of s0
               a    56&x1, 31&x2       * Right shifted: 32+31-7 = bit 24 of w[i-15], 31 = end of s0
               a    63&x1, 6&x2        * Wrapped: 32+31 = end of w[i-15], 7-1 = bit 6 of s0   
               cw   7&x2               * Clear wordmark
     * Add w[i-15] rightrotate 18
               sw   18&x2              * Wordmark at bit 18 (from left) of s0
               a    45&x1, 31&x2       * Right shifted: 32+31-18 = bit 13 of w[i-15], 31 = end of s0
               a    63&x1, 17&x2       * Wrapped: 32+31 = end of w[i-15], 18-1 = bit 17 of s0   
               cw   18&x2              * Clear wordmark
     * Add w[i-15] rightshift 3
               sw   3&x2               * Wordmark at bit 3 (from left) of s0
               a    60&x1, 31&x2       * Right shifted: 32+31-3 = bit 28 of w[i-15], 31 = end of s0
               cw   3&x2               * Clear wordmark
     * Convert sum to xor
               mcw  x1, x1tmp
               mcw  +s0+31, x1         * x1 = right end of s0
               mcw  @032@, x2          * Process 32 bits
               b    xor
               sw   s0                 * Restore wordmark cleared by xor
     
               mcw  x1tmp, x1
     
     * Compute s1         
               mcw  +s1, x2
               za   +0, 31&x2               * Zero s1
     * Add w[i-2] rightrotate 17
               sw   17&x2              * Wordmark at bit 17 (from left) of s1
               a    462&x1, 31&x2      * Right shifted: 14*32+31-17 = bit 14 of w[i-2], 31 = end of s1
               a    479&x1, 16&x2      * Wrapped: 14*32+31 = end of w[i-2], 17-1 = bit 16 of s1   
               cw   17&x2              * Clear wordmark
     * Add w[i-2] rightrotate 19
               sw   19&x2              * Wordmark at bit 19 (from left) of s1
               a    460&x1, 31&x2      * Right shifted: 14*32+31-19 = bit 12 of w[i-2], 31 = end of s1
               a    479&x1, 18&x2      * Wrapped: 14*32+31 = end of w[i-2], 19-1 = bit 18 of s1  
               cw   19&x2              * Clear wordmark
     * Add w[i-2] rightshift 10
               sw   10&x2              * Wordmark at bit 10 (from left) of s1
               a    469&x1, 31&x2      * Right shifted: 14*32+31-10 = bit 21 of w[i-2], 31 = end of s1
               cw   10&x2              * Clear wordmark
     * Convert sum to xor
               mcw  +s1+31, x1         * x1 = right end of s1
               mcw  @032@, x2          * Process 32 bits
               b    xor
               sw   s1                 * Restore wordmark cleared by xor
     
     * Compute w[i] := w[i-16] + s0 + w[i-7] + s1
               mcw  x1tmp, x1
               a    s1+31, s0+31       * Add s1 to s0
               a    31&x1, s0+31       * Add w[i-16] to s0
               a    319&x1, s0+31      * Add 9*32+31 = w[i-7] to s0
     * Convert bit sum to 32-bit sum
               mcw  +s0+31, x1         * x1 = right end of s0
               mcw  @032@, x2          * Process 32 bits
               b    sum
               sw   s0                 * Restore wordmark cleared by sum
     

     
               mcw  x1tmp, x1
               mcw  s0+31, 543&x1      * Move s0 to w[i]
       
              
               ma   @032@, x1
               a    +1, i
               mz   @0@, i
               b    wloop
     
     x1tmp     dcw  #5
     

     * Initialize: Copy hex h0init-h7init into binary h0-h7
     wloopd    mcw  +h0init-7, x3
               mcw  +h0, x1
               mcw  @064@, tobinc       * 8*8 hex digits
               b    tobin
     
     
     * Initialize a-h from h0-h7
               mcw  @000@, x1
     ilp       mcw  h0+31&x1, a+31&x1
               ma   @032@, x1
               c    x1, @256@
               bu   ilp
     
               mcw  @000@, bitidx      * bitidx = i*32 = bit index
               mcw  @000@, kidx        * kidx = i*8 = key index
                

     * Compute s1 from e        
     mainlp    mcw  +e, x1
               mcw  +s1, x2
               za   +0, 31&x2               * Zero s1
     * Add e rightrotate 6
               sw   6&x2               * Wordmark at bit 6 (from left) of s1
               a    25&x1, 31&x2       * Right shifted: 31-6 = bit 25 of e, 31 = end of s1
               a    31&x1, 5&x2        * Wrapped: 31 = end of e, 6-1 = bit 5 of s1   
               cw   6&x2               * Clear wordmark
     * Add e rightrotate 11
               sw   11&x2              * Wordmark at bit 11 (from left) of s1
               a    20&x1, 31&x2       * Right shifted: 31-11 = bit 20 of e, 31 = end of s1
               a    31&x1, 10&x2       * Wrapped: 31 = end of e, 11-1 = bit 10 of s1   
               cw   11&x2              * Clear wordmark
     * Add e rightrotate 25
               sw   25&x2              * Wordmark at bit 25 (from left) of s1
               a    6&x1, 31&x2        * Right shifted: 31-25 = bit 6 of e, 31 = end of s1
               a    31&x1, 24&x2       * Wrapped: 31 = end of e, 25-1 = bit 24 of s1   
               cw   25&x2              * Clear wordmark
     * Convert sum to xor
               mcw  +s1+31, x1         * x1 = right end of s1
               mcw  @032@, x2          * Process 32 bits
               b    xor
               sw   s1                 * Restore wordmark cleared by xor

     * Compute ch: choose function
               mcw  @000@, x1          * x1 is index from 0 to 31
     chl       c    e&x1, @0@
               be   chzero
               mn   f&x1, ch&x1        * for 1, select f bit
               b    chincr
     chzero    mn   g&x1, ch&x1        * for 0, select g bit
     chincr    a    +1, x1
               mz   @0@, x1
               c    @032@, x1
               bu   chl

     * Compute temp1: k[i] + h + S1 + ch + w[i]
               cs   299
               mcw  +k-7, x3            * Convert k[i] to binary in temp1
               ma   kidx, x3
               mcw  +temp1, x1
               mcw  @008@, tobinc       * 8 hex digits
               b    tobin
               mcw  @237@, x3
               mcw  +temp1, x1
               mcw  @008@, tobinc
               b    tohex
               a    h+31, temp1+31     * +h
               a    s1+31, temp1+31    * +s1
               a    ch+31, temp1+31    * +ch
               mcw  bitidx, x1
               a    warr+31&x1, temp1+31         * + w[i]
     * Convert bit sum to 32-bit sum
               mcw  +temp1+31, x1      * x1 = right end of temp1
               b    sum
  

     * Compute s0 from a
               mcw  +a, x1
               mcw  +s0, x2
               za   +0, 31&x2               * Zero s0
     * Add a rightrotate 2
               sw   2&x2               * Wordmark at bit 2 (from left) of s0
               a    29&x1, 31&x2       * Right shifted: 31-2 = bit 29 of a, 31 = end of s0
               a    31&x1, 1&x2        * Wrapped: 31 = end of a, 2-1 = bit 1 of s0   
               cw   2&x2               * Clear wordmark
     * Add a rightrotate 13
               sw   13&x2              * Wordmark at bit 13 (from left) of s0
               a    18&x1, 31&x2       * Right shifted: 31-13 = bit 18 of a, 31 = end of s0
               a    31&x1, 12&x2       * Wrapped: 31 = end of a, 13-1 = bit 12 of s0   
               cw   13&x2              * Clear wordmark
     * Add a rightrotate 22
               sw   22&x2              * Wordmark at bit 22 (from left) of s0
               a    9&x1, 31&x2        * Right shifted: 31-22 = bit 9 of a, 31 = end of s0
               a    31&x1, 21&x2       * Wrapped: 31 = end of a, 22-1 = bit 21 of s0   
               cw   22&x2              * Clear wordmark
     * Convert sum to xor
               mcw  +s0+31, x1         * x1 = right end of s0
               mcw  @032@, x2          * Process 32 bits
               b    xor
               sw   s0                 * Restore wordmark cleared by xor

     * Compute maj(a, b, c): majority function
               za   +0, maj+31
               a    a+31, maj+31
               a    b+31, maj+31
               a    c+31, maj+31
               mz   @0@, maj+31
               mcw  @000@, x1          * x1 is index from 0 to 31
     mjl       c    maj&x1, @2@
               bh   mjzero
               mn   @1@, maj&x1       * majority of the 3 bits is 1
               b    mjincr
     mjzero    mn   @0@, maj&x1       * majority of the 3 bits is 0
     mjincr    a    +1, x1
               mz   @0@, x1
               c    @032@, x1
               bu   mjl

     * Compute temp2: S0 + maj
               za   +0, temp2+31
               a    s0+31, temp2+31
               a    maj+31, temp2+31
     * Convert bit sum to 32-bit sum
               mcw  +temp2+31, x1      * x1 = right end of temp1
               b    sum
     
               mcw  g+31, h+31         * h := g
               mcw  f+31, g+31         * g := f
               mcw  e+31, f+31         * f := e
               za   +0, e+31           * e := d + temp1
               a    d+31, e+31
               a    temp1+31, e+31
               mcw  +e+31, x1          * Convert sum to 32-bit sum
               b    sum
               mcw  c+31, d+31         * d := c
               mcw  b+31, c+31         * c := b
               mcw  a+31, b+31         * b := a
               za   +0, a+31           * a := temp1 + temp2
               a    temp1+31, a+31
               a    temp2+31, a+31
               mcw  +a+31, x1          * Convert sum to 32-bit sum
               b    sum

               a    @8@, kidx          * Increment kidx by 8 chars
               mz   @0@, kidx
               ma   @032@, bitidx      * Increment bitidx by 32 bits
               c    @!48@, bitidx      * Compare to 2048
               bu   mainlp

     * Add a-h to h0-h7
               cs   299
               mcw  @00000@, x1tmp  
     add1      mcw  x1tmp, x1
               a    a+31&x1, h0+31&x1
               ma   +h0+31, x1          * Convert sum to 32-bit sum
               b    sum     
               ma   @032@, x1tmp
               c    @00256@, x1tmp
               bu   add1
               mcw  @201@, x3
               mcw  +h0, x1
               mcw  @064@, tobinc
               b    tohex
               w
               mcw  280, 180
               p
               p

     finis     h
               b    finis

      
     * Converts sum of bits to xor
     * X1 is right end of word
     * X2 is bit count    
     * Note: clears word marks
     xor       sbr  xorx&3
     xorl      c    @000@, x2
               be   xorx
     xorfix    mz   @0@, 0&x1          * Clear zone
               c    0&x1, @2@
               bh   xorok
               sw   0&x1               * Subtract 2 and loop
               s    +2, 0&x1
               cw   0&x1
               b    xorfix
     xorok     ma   @I9I@, x1         * x1 -= 1
               s    +1, x2             * x2 -= 1
               mz   @0@, x2
               b    xorl               * loop
     
     xorx      b    @000@
     
     * Converts sum of bits to sum (i.e. propagate carries if digit > 1)
     * X1 is right end of word
     * Ends at word mark
     sum       sbr  sumx&3
     suml      mz   @0@, 0&x1          * Clear zone
               c    0&x1, @2@          * If digit is <2, then ok
               bh   sumok
               s    +2, 0&x1           * Subtract 2 from digit
               bwz  suml, 0&x1, 1      * Skip carry if at wordmark
               a    @1@, 15999&x1      * Add 1 to previous position
               b    suml               * Loop
     sumok     bwz  sumx,0&x1,1        * Quit if at wordmark
               ma   @I9I@, x1          * x1 -= 1
               b    suml               * loop
     sumx      b    @000@              * return
     
     * Converts binary to string of hex digits
     * X1 points to start (left) of binary
     * X3 points to start (left) of hex buffer
     * X1, X2, X3 destroyed
     * tobinc holds count (# of hex digits)
     tohex     sbr  tohexx&3
     tohexl    c    @000@, tobinc      * check counter
               be   tohexx
               s    @1@, tobinc        * decrement counter
               mz   @0@, tobinc
               b    tohex4
               mcw  hexchr, 0&x3
               ma   @004@, X1
               ma   @001@, X3
               b    tohexl             * loop
     tohexx    b    @000@ 
     

     
     * X1 points to 4 bits
     * Convert to hex char and write into hexchr
     * X2 destroyed

     tohex4    sbr  tohx4x&3
               mcw  @000@, x2
               c    3&X1, @1@
               bu   tohx1
               a    +1, x2
     tohx1     c    2&X1, @1@
               bu   tohx2
               a    +2, x2
     tohx2     c    1&x1, @1@
               bu   tohx4
               a    +4, x2
     tohx4     c    0&x1, @1@
               bu   tohx8
               a    +8, x2
     tohx8     mz   @0@, x2
               mcw  hextab-15&x2, hexchr
     tohx4x    b    @000@
     
     * Converts string of hex digits to binary
     * X3 points to start (left) of hex digits
     * X1 points to start (left) of binary digits
     * tobinc holds count (# of hex digits)
     * X1, X3 destroyed
     tobin     sbr  tobinx&3
     tobinl    c    @000@, tobinc      * check counter
               be   tobinx
               s    @1@, tobinc        * decrement counter
               mz   @0@, tobinc
               mcw  0&X3, hexchr
               b    tobin4             * convert 1 char
               ma   @004@, X1
               ma   @001@, X3
               b    tobinl             * loop
     tobinx    b    @000@
               
     
     tobinc    dcw  @000@
     * Convert hex digit to binary
     * Digit in hexchr (destroyed)
     * Bits written to x1, ..., x1+3
     tobin4    sbr  tobn4x&3
               mcw  @0000@, 3+x1   * Start with zero bits
               bwz  norm,hexchr,2  * Branch if no zone
              
               mcw  @1@, 0&X1
               a    @1@, hexchr    * Convert letter to value: A (1) -> 2, F (6) -> 7
               mz   @0@, hexchr
               b    tob4
     norm      c    @8@, hexchr
               bl   tob4
               mcw  @1@, 0&X1
               s    @8@, hexchr
               mz   @0@, hexchr
     tob4      c    @4@, hexchr
               bl   tob2
               mcw  @1@, 1&X1
               s    @4@, hexchr
               mz   @0@, hexchr
     tob2      c    @2@, hexchr
               bl   tob1
               mcw  @1@, 2&X1
               s    @2@, hexchr
               mz   @0@, hexchr
     tob1      c    @1@, hexchr
               bl   tobn4x
               mcw  @1@, 3&X1
     tobn4x    b    @000@          


     
     * Message schedule array is 64 entries of 32 bits = 2048 bits.
               org  3000
     warr      equ  3000
     
     s0        equ  warr+2047                *32 bits
     s1        equ  s0+32 
     ch        equ  s1+32              *32 bits

     temp1     equ  ch+32               *32 bits
     
     temp2     equ  temp1+32                *32 bits
     
     maj       equ  temp2+32                *32 bits
     
     a         equ  maj+32
     b         equ  a+32
     c         equ  b+32
     d         equ  c+32
     e         equ  d+32
     f         equ  e+32
     g         equ  f+32
     h         equ  g+32
     h0        equ  h+32
     h1        equ  h0+32
     h2        equ  h1+32
     h3        equ  h2+32
     h4        equ  h3+32
     h5        equ  h4+32
     h6        equ  h5+32
     h7        equ  h6+32
               org  h7+32
 
     hexchr    dcw  @0@
     hextab    dcw  @0123456789abcdef@    
     i         dcw  @00@               * Loop counter for w computation
     bitidx    dcw  #3
     kidx      dcw  #3         
     
     * 64 round constants for SHA-256
     k         dcw  @428a2f98@
               dcw  @71374491@
               dcw  @b5c0fbcf@
               dcw  @e9b5dba5@
               dcw  @3956c25b@
               dcw  @59f111f1@
               dcw  @923f82a4@
               dcw  @ab1c5ed5@
               dcw  @d807aa98@
               dcw  @12835b01@
               dcw  @243185be@
               dcw  @550c7dc3@
               dcw  @72be5d74@
               dcw  @80deb1fe@
               dcw  @9bdc06a7@
               dcw  @c19bf174@
               dcw  @e49b69c1@
               dcw  @efbe4786@
               dcw  @0fc19dc6@
               dcw  @240ca1cc@
               dcw  @2de92c6f@
               dcw  @4a7484aa@
               dcw  @5cb0a9dc@
               dcw  @76f988da@
               dcw  @983e5152@
               dcw  @a831c66d@
               dcw  @b00327c8@
               dcw  @bf597fc7@
               dcw  @c6e00bf3@
               dcw  @d5a79147@
               dcw  @06ca6351@
               dcw  @14292967@
               dcw  @27b70a85@
               dcw  @2e1b2138@
               dcw  @4d2c6dfc@
               dcw  @53380d13@
               dcw  @650a7354@
               dcw  @766a0abb@
               dcw  @81c2c92e@
               dcw  @92722c85@
               dcw  @a2bfe8a1@
               dcw  @a81a664b@
               dcw  @c24b8b70@
               dcw  @c76c51a3@
               dcw  @d192e819@
               dcw  @d6990624@
               dcw  @f40e3585@
               dcw  @106aa070@
               dcw  @19a4c116@
               dcw  @1e376c08@
               dcw  @2748774c@
               dcw  @34b0bcb5@
               dcw  @391c0cb3@
               dcw  @4ed8aa4a@
               dcw  @5b9cca4f@
               dcw  @682e6ff3@
               dcw  @748f82ee@
               dcw  @78a5636f@
               dcw  @84c87814@
               dcw  @8cc70208@
               dcw  @90befffa@
               dcw  @a4506ceb@
               dcw  @bef9a3f7@
               dcw  @c67178f2@
     * 8 initial hash values for SHA-256
     h0init    dcw  @6a09e667@
     h1init    dcw  @bb67ae85@
     h2init    dcw  @3c6ef372@
     h3init    dcw  @a54ff53a@
     h4init    dcw  @510e527f@
     h5init    dcw  @9b05688c@
     h6init    dcw  @1f83d9ab@
     h7init    dcw  @5be0cd19@


     input0    equ  h7init+64
               org  h7init+65

               dc   @80000000000000000000000000000000@
     input     dc   @00000000000000000000000000000100@      * 512 bits with the mostly-zero padding

               end  start

Das ausführbare Programm wurde auf 85 Lochkarten angewendet (Sie haben sie bereits am Anfang des Artikels gesehen). Ich habe auch eine Lochkarte mit einem Hash-Algorithmus erstellt. Um das Programm auszuführen, musste ich die Lochkarte in den Kartenleser laden und auf die Schaltfläche „Laden“ klicken. Der Kartenleser verarbeitete 800 Karten pro Minute. Daher dauerte das Herunterladen des Programms nur wenige Sekunden. Während der Programmausführung blinkte die Computerkonsole (siehe Abbildung unten) 40 Sekunden lang fieberhaft. Schließlich druckte der Drucker für mich den endgültigen Hash (Sie haben auch den Ausdruck am Anfang des Artikels gesehen), und die Ergebnisse wurden auf eine neue Lochkarte angewendet. Da beim Bitcoin-Mining das doppelte SHA-256-Hashing verwendet wird, dauerte der Mining-Hashing-Vorgang doppelt so lange (80 Sekunden).


Harte Arbeit der IBM 1401-Konsole bei der Berechnung des SHA-256-Hash

Leistungsvergleich


Der IBM 1401-Computer kann den SHA-256-Doppel-Hash in 80 Sekunden berechnen. Um diese Aufgabe zu erledigen, verbraucht der Computer ungefähr 3.000 Watt Strom, ungefähr so ​​viel wie ein Elektroherd oder ein Wäschetrockner. Zu einer Zeit kostete das IBM 1401-Basissystem 125.600 US-Dollar. In der Realität von 2015 beläuft sich dies auf rund eine Million US-Dollar. Gleichzeitig können Sie jetzt für 50 US-Dollar ein USB-Flash-Laufwerk für den Bergbau kaufen , das über eine spezielle integrierte Schaltung (ASIC USB Miner) verfügt. Dieser USB-Miner führt 3,6 Milliarden Hashes pro Sekunde aus und verbraucht dabei etwa 4 Watt.
Solche signifikanten Leistungsindikatoren sind auf mehrere Faktoren zurückzuführen: einen starken Anstieg der Computerleistung in den letzten 50 Jahren nach dem Moore'schen Gesetz, Leistungsverlust im Zusammenhang mit der Verwendung von Dezimalarithmetik in Computern zur Lösung kommerzieller Probleme, die mit der Berechnung eines binären Hash-Codes beschäftigt waren, sowie Geschwindigkeitsgewinn mit Seiten traditioneller Bitcoin-Mining-Hardware.

Zusammenfassen. Um den Block abzubauen, benötigt der IBM 1401-Computer unter Berücksichtigung der aktuellen Anforderungen für diesen Prozess etwa 5 x 10 ^ 14 Jahre (was dem 40.000-fachen des aktuellen Alters des Universums entspricht). Die Kosten für den Stromverbrauch betragen ca. 10 ^ 18 US-Dollar. Als Ergebnis erhalten Sie 25 Bitcoins, deren monetärer Wert etwa 6.000 US-Dollar beträgt. Das Mining von Bitcoins auf dem IBM 1401-Mainframe kann daher nicht als profitables Geschäft bezeichnet werden. Die folgenden Fotos vergleichen die Computerchips der 60er Jahre des letzten Jahrhunderts mit modernen Optionen und zeigen deutlich den technologischen Fortschritt.


: SMS , IBM 1401. . . : Bitfury ASIC 2-3 . : zeptobars (CC BY 3.0)


Sie können entscheiden, dass Bitcoins mit der Technologie der 60er Jahre des letzten Jahrhunderts nicht kompatibel sind, da Daten nicht über das Netzwerk übertragen werden können. Muss jemand Lochkarten mit einer Blockkette an andere Computer senden? Die Kommunikation zwischen Computern über das Netzwerk ist schon lange her. Bereits 1941 unterstützte IBM den sogenannten telemetrischen (Remote-) Datenverarbeitungsprozess. In den 60er Jahren konnte IBM 1401 mit einem IBM 1009-Datenübertragungsgerät ( IBM 1009 Data Transmission Unit) verbunden werden) - ein Modem von der Größe eines Geschirrspülers, mit dem Computer Daten über eine Telefonleitung mit bis zu 300 Zeichen pro Sekunde miteinander austauschen konnten. Das heißt, theoretisch ist es durchaus möglich, ein Bitcoin-Netzwerk aufzubauen, das auf Technologien der 60er Jahre des letzten Jahrhunderts basiert. Leider konnte ich keine Ausrüstung für die Teleprozessdaten erhalten und diese Theorie testen.


Das IBM 1009-Datenübertragungsgerät. 1960 erschien ein Modem in der Größe eines Geschirrspülers. Damit war es möglich, bis zu 300 Zeichen pro Sekunde über eine Telefonleitung zu übertragen. Fotoquelle: Einführung in IBM Datenverarbeitungssysteme) .

Ergebnisse


Die Verwendung von SHA-256 in der Assemblersprache des alten Mainframes ist zu einer schwierigen, aber interessanten Erfahrung geworden. Ich habe eine bessere Leistung erwartet (sogar im Vergleich zu meinem Mandelbrot-Set in 12 Minuten ). Die Dezimalarithmetik eines kommerziellen Computers ist nicht die beste Option für einen binären Algorithmus wie SHA-256. Der Bitcoin-Mining-Algorithmus kann jedoch auch auf einem Computer ohne integrierte Schaltkreise ausgeführt werden. Wenn mich plötzlich ein bestimmter vorübergehender Zusammenbruch bis 1960 führt, kann ich ein Bitcoin-Netzwerk aufbauen.

Das Mountain View Museum für Computergeschichte zeigt mittwochs und samstags den laufenden IBM 1401. Wenn Sie sich in der Nähe befinden, sollten Sie dies unbedingt anhand des Zeitplans überprüfenArbeit. Und wenn Sie Museumsmitarbeitern, die IBM 1401 ausführen, von mir erzählen, können sie sogar mein Pi-Programm starten .

Ich möchte dem Computer History Museum und den Mitgliedern des 1401 Computer Recovery Teams danken: Robert Garner, Ed Thelen, Van Snyder und insbesondere Stan Paddock. Auf der Team- Website von ibm-1401.info finden Sie viele interessante Informationen zum 1401-Computer und zur Wiederherstellung.

Erläuterung


Es ist erwähnenswert, dass ich den echten Block auf IBM 1401 nicht zerschlagen habe - das Museum für Computergeschichte würde es nicht mögen. Wie ich bereits sagte, können Sie mit einem funktionierenden IBM 1401 kein Geld für den Bergbau verdienen. Es gelang mir jedoch, den SHA-256-Algorithmus auf einem IBM 1401-Computer zu implementieren und auszuführen, um zu beweisen, dass Mining theoretisch möglich ist. Und ich werde das Geheimnis der Suche nach einem gültigen Hash enthüllen - ich habe gerade den bereits abgebauten Block verwendet .

Wir hoffen, Ihnen hat unsere Übersetzung gefallen

Source: https://habr.com/ru/post/de380635/


All Articles