Minerando bitcoins no veterano IBM 1401 de 55 anos

Inspirado na publicação do usuário mark_ablovUsando bitcoin usando papel e caneta ”, decidimos que os leitores do hiktime se interessariam em outras idéias malucas que o autor do post original, Ken Shirriff, conseguiu realizar.

O mainframe da IBM dos anos 60 do século passado pode ser usado para minerar bitcoins? Eu decidi dar uma olhada nessa idéia aparentemente louca. Injetei o algoritmo de hash Bitcoin no código assembler para IBM 1401 e testei-o na prática executando-o em um modelo viável desse mainframe antigo.


O cartão perfurado usado para calcular os hashes SHA-256 no mainframe IBM 1401. Uma impressão é visível atrás do cartão perfurado, mostrando a entrada do algoritmo e o hash resultante

Como se viu, usando este computador você pode minerar, mas esse processo levará tanto tempo que até toda a vida útil do Universo pode não ser suficiente para a mineração bem-sucedida de um bloco.

Embora o hardware moderno permita calcular bilhões de hashes por segundo, o computador 1401 gasta 80 segundos cada para calcular um único hash. O progresso no desempenho do computador nas últimas décadas é evidente, o que é claramente descrito pela lei de Gordon Moore.

Os cartões perfurados que participaram do experimento, bem como a impressão SHA-256 com uma impressora de linha são mostrados na fotografia acima (o primeiro cartão perfurado serve apenas para a beleza - não foi fácil romper esse padrão). Observe que a segunda linha termina com um grupo de zeros; isso significa um hash bem-sucedido.

Princípio de mineração de Bitcoin


Recentemente, a moeda eletrônica Bitcoin (Bitcoin), que os usuários da Internet podem transferir entre si, tem sido muito popular. Para entender a essência do trabalho dessa criptomoeda, o sistema Bitcoin pode ser apresentado na forma de um tipo de diário contábil, que armazena registros sobre o proprietário de moedas digitais (bitcoins) e o número de moedas que ele possui. Os membros do Bitcoin podem transferir moedas digitais entre si.

Note-se que o sistema Bitcoin é descentralizado: não possui um único servidor regulador que monitore o progresso das transações. Em vez disso, os registros são enviados por uma rede distribuída a partir de milhares de computadores na Internet.

A dificuldade é que esse sistema distribuído deve, de alguma forma, garantir que todos os usuários concordem com os registros. Ou seja, usuários conscientes devem confirmar a validade da transação, aprová-la, apesar da possível presença de fraudadores e redes de execução lenta. A solução para esse problema foi a chamada "mineração". Aproximadamente a cada 10 minutos durante o processo de mineração, um bloco de transações de saída é confirmado e, como resultado, é considerado oficialmente confirmado.

O processo de mineração, baseado em criptografia confiável, é extremamente complicado, para que ninguém possa controlar quais transações são mineradoras. Em particular, a ideia principal do sistema Bitcoin é que o resultado do trabalho é difícil e difícil, mas fácil de verificar. Essa é a chamada tecnologia de "prova de trabalho".

O processo de mineração de blocos requer uma enorme quantidade de custo computacional. No entanto, após a confirmação do bloqueio, os usuários ponto a ponto podem verificar facilmente sua validade. A complexidade da mineração impede o uso fraudulento do Bitcoin, e a facilidade de verificar a validade do bloco permite que os usuários confiem na validade das transações.

Um efeito colateral da mineração é a adição de novos bitcoins ao sistema. Atualmente, todo mundo que confirma o bloco recebe 25 bitcoins gerados por isso (agora o custo desse número de moedas virtuais em termos monetários tradicionais é de cerca de 6 mil dólares). Esse incentivo incentiva os mineradores a trabalhar duro e a gastar seus recursos na mineração. Dada a oportunidade de receber 6 mil dólares a cada 10 minutos, a mineração parece ser uma verdadeira “mina de ouro”, incentivando os usuários a gastar quantias significativas em hardware para mineração.


A impressora de linha e o IBM 1401 Mainframe foram apresentados no Computer History Museum. Este computador estava executando meu programa. O console está localizado no canto superior esquerdo. Os painéis retangulares escuros no computador são as “portas” dos racks reclinados, fornecendo acesso para manutenção.

O processo de mineração é extremamente complicado, mas o resultado é muito fácil de verificar. A mineração de Bitcoin usa criptografia com uma função de hash chamada double SHA-256. O hash pega um pedaço de dados na entrada e o reduz para um valor menor de hash (nesse caso, 256 bits).

O algoritmo de hash criptográfico não permitirá que você obtenha o valor de hash desejado sem precisar classificar a massa de dados na entrada. No entanto, depois de encontrar uma entrada que fornece o valor desejado, todos podem verificar facilmente o hash. Portanto, o hash criptográfico é uma boa maneira de implementar bitcoins de "prova de trabalho".

Mais detalhadamente, para criar um bloco, primeiro você precisa coletar novas transações em um bloco. Então você precisa fazer o hash do bloco para obter (essencialmente aleatoriamente) o valor do hash do bloco. Se o valor do hash começar com 16 zeros, o bloco será considerado confirmado com sucesso e enviado à rede Bitcoin. Na maioria das vezes, o hash não é bem-sucedido; portanto, você altera ligeiramente o bloco e tenta repetidamente, após mais de um bilhão de operações computacionais. A cada 10 minutos, alguém consegue confirmar com êxito o bloqueio e o processo inicia novamente. Isso lembra uma loteria na qual os mineradores participam, fazendo uma tentativa após outra, até que alguém se torne um "vencedor". A complexidade do processo de hash é difícil de visualizar: é mais fácil encontrar um grão de areia em toda a areia da Terra do que encontrar um valor válido de hash.Para procurar esses valores de hash, os mineradores usam data centers equipados com hardware especial para mineração.

Eu simplifico deliberadamente muitas das explicações neste artigo. Se você quiser saber mais sobre o sistema Bitcoin e a mineração, recomendo que você estude meus artigos A difícil experiência de minerar bitcoins e as duras lições da mineração de bitcoin .

Algoritmo de hash Bitcoin SHA-256


Agora, analisarei a função hash usada pelo Bitcoin, que é baseada em uma função hash criptográfica padrão chamada SHA-256. O sistema Bitcoin usa um "duplo SHA-256". Isso significa que a função SHA-256 é executada duas vezes. O algoritmo SHA-256 é tão simples que você pode literalmente executá-lo usando apenas lápis e papel , e o algoritmo permite misturar dados de maneira imprevisível. O algoritmo aceita blocos de 64 bytes na entrada, processa os dados criptograficamente e produz 256 bits (32 bytes) de dados criptografados. O algoritmo usa uma rodada, que é repetida 64 vezes. A ilustração abaixo mostra uma rodada do algoritmo, que utiliza oito blocos de 4 bytes, de A a H, executa várias operações e produz novos valores para A e N.


O SHA-256 redondo, como um exemplo da Wikipedia , por kockmeyer, CC BY-SA 3.0 Os

blocos azuis escuros misturam os bits de maneira não linear, o que é difícil para a análise criptográfica. (Se você conseguir encontrar uma maneira matematicamente mais rápida de obter hashes bem-sucedidos, poderá controlar a mineração de bitcoins). A célula “select” Ch seleciona bits de F ou G, com base no valor da entrada E. As células sum “soma” giram os bits A (ou E) gerando três versões cíclicas deslocadas e, em seguida, soma-os no módulo 2.

A célula majoritária Ma verifica os bits em cada posição de A, B e C e seleciona 0 ou 1, dependendo de qual valor está na maioria. Os glóbulos vermelhos realizam adições de 32 bits, gerando novos valores para A e E. A entrada Wt é baseada em entradas levemente processadas. (É aqui que o bloco de entrada é introduzido no algoritmo.) A entrada Kt é uma constante definida para cada rodada.

De acordo com a ilustração acima, apenas A e E. são alterados por rodada.Os valores restantes são ignorados sem alterações. O valor antigo de A se torna o novo valor de B, o valor antigo de B se torna o novo valor de C e assim por diante. Embora cada rodada do SHA-256 altere ligeiramente os dados, após 64 rodadas, os dados de entrada são completamente misturados, fornecendo um valor de hash imprevisível.

Ibm 1401


Decidi executar esse algoritmo no mainframe IBM 1401. Este computador apareceu em 1959 e, em meados dos anos 60, tornou-se o computador mais vendido - naquela época, mais de 10 mil máquinas eram ativamente operadas. O computador 1401 não era um computador muito poderoso, mesmo em 1960. No entanto, era acessível para empresas de médio porte que antes não tinham recursos para ter um computador, devido ao fato de poder ser alugado por pouco dinheiro - US $ 2.500 por mês.

O IBM 1401 não usava chips de silício. Além disso, neste computador não havia chips. Seus transistores foram construídos em semicondutores, cristais de germânio, usados ​​antes do silício. Os transistores, juntamente com outros componentes, foram instalados em placas do tamanho de cartas de baralho chamadas cartões SMS. O computador envolveu milhares dessas placas, que foram instaladas na forma de racks chamados "portas". O IBM 1401 possui vinte dessas "portas" que foram apresentadas para manutenção do computador. Na ilustração acima, uma porta aberta é visível, fornecendo acesso a microchips e cabos.


A ilustração mostra um rack aberto (a chamada “porta”) do mainframe IBM 1401. A fotografia mostra cartões SMS conectados ao circuito. Esse rack conduz unidades de fita

O princípio de funcionamento desse computador era significativamente diferente dos PCs modernos. Este computador não usou bytes de 8 bits, mas caracteres de 6 bits com base no número decimal com código binário (BCD). Como esse computador era uma máquina de calcular para resolver problemas econômicos, usava aritmética decimal em vez de binária, e cada caractere na memória tinha um valor digital de 0 a 9. A memória do computador em núcleos magnéticos continha 4000 caracteres. Um módulo de expansão de memória do tamanho de uma máquina de lavar louça aumentou a capacidade de memória em 12.000 caracteres. A entrada de dados no computador foi realizada com cartões perfurados. O leitor de cartões lê dados e programas de cartões. Os dados de saída foram impressos por uma impressora de drenagem de alta velocidade ou perfurados em mapas.

Museu de História da Computação Museu de História da Computaçãoem Mountain View, ele possui dois mainframes em funcionamento IBM 1401. Em um deles, executei o código hash SHA-256. Eu falo mais sobre o IBM 1401 no meu artigo Fractals on IBM 1401
.

Executando o SHA-256 em um IBM 1401


Certamente o computador IBM 1401 é o pior de todas as máquinas que poderiam ser escolhidas para executar o algoritmo de hash SHA-256. Para funcionar efetivamente, esse algoritmo requer máquinas que possam executar operações de bits em palavras de 32 bits. Infelizmente, o IBM 1401 não suporta palavras de 32 bits ou bytes. Este computador trabalha com caracteres de 6 bits e não permite operações de bits. Além disso, em vez de binário, foi utilizada aritmética decimal. Portanto, o algoritmo no computador 1401 será lento e inconveniente para o usuário.

Acabei usando um caractere por bit. O valor de 32 bits foi armazenado como 32 caracteres, "0" ou "1". Meu código teve que executar operações bit a bit, multiplicações e adições, caractere por caractere, verificando cada caractere e decidindo o que fazer com ele. Como você poderia esperar, a execução do código levou muito tempo.

A seguir, apresento o código do assembler que escrevi. Em geral, o princípio do código é descrito nos comentários. No final do código, há uma tabela de constantes necessárias para o algoritmo SHA-256 na forma hexadecimal. Como o computador 1401 não suporta o formato hexadecimal, tive que escrever minhas próprias rotinas para converter os formatos hexadecimal e binário. Neste artigo, não explicarei o código do assembler para IBM 1401, apenas enfatizo que é muito diferente do que os computadores modernos usam. Este código não chama sub-rotinas e não retorna resultados. Devido à falta de registros de uso geral, as operações são realizadas na memória.

Procure o código abaixo do spoiler:
Texto oculto
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

O programa executável foi aplicado a 85 cartões perfurados (você já os viu no início do artigo). Também fiz um cartão perfurado com um algoritmo de hash. Para executar o programa, tive que carregar o cartão perfurado no leitor de cartões e clicar no botão "Carregar". O leitor de cartões processou 800 cartões por minuto. Assim, demorou apenas alguns segundos para baixar o programa. Durante a execução do programa, o console do computador (veja a ilustração abaixo) piscou febrilmente por 40 segundos. Por fim, a impressora imprimiu para mim o hash final (você também viu a impressão no início do artigo) e os resultados foram aplicados a um novo cartão perfurado. Como a mineração de Bitcoin usa o hash duplo SHA-256, o processo de mineração levou o dobro do tempo (80 segundos).


Trabalho árduo do console IBM 1401 ao calcular o hash SHA-256

Comparação de desempenho


O computador IBM 1401 pode calcular o hash duplo SHA-256 em 80 segundos. Para concluir esta tarefa, o computador consome cerca de 3.000 watts de energia, o mesmo que um fogão elétrico ou um secador de roupas. Ao mesmo tempo, o sistema IBM 1401 básico custava US $ 125.600. Na realidade de 2015, isso equivale a cerca de um milhão de dólares. Ao mesmo tempo, agora você pode comprar uma unidade flash USB para mineração por US $ 50, que possui um circuito integrado especializado (minerador ASIC USB). Esse minerador USB executa 3,6 bilhões de hashes por segundo, enquanto consome cerca de 4 watts.
Esses indicadores significativos de desempenho são devidos a vários fatores: um aumento acentuado no desempenho do computador nos últimos 50 anos, de acordo com a lei de Moore, perda de desempenho associada ao uso da aritmética decimal em computadores para resolver problemas comerciais, que estava ocupado computando um código hash binário e ganho de velocidade com lados do hardware tradicional de mineração de bitcoin.

Para resumir. Para explorar o bloco, levando em consideração os requisitos atuais desse processo, o computador IBM 1401 precisará de cerca de 5x10 ^ 14 anos (40.000 vezes a idade atual do Universo). O custo da eletricidade consumida será de cerca de 10 ^ 18 dólares americanos. Como resultado, você receberá 25 bitcoins, cujo valor em termos monetários será de cerca de 6.000 dólares. Portanto, a mineração de bitcoins no mainframe IBM 1401 não pode ser chamada de negócio lucrativo. As fotografias abaixo comparam os chips dos anos 60 do século passado e as opções modernas, demonstrando claramente o progresso tecnológico.


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


Você pode decidir que os bitcoins são incompatíveis com a tecnologia dos anos 60 do século passado devido à falta de capacidade de transmitir dados pela rede. Alguém precisará enviar cartões perfurados com uma cadeia de blocos para outros computadores? A comunicação entre computadores através da rede surgiu há muito tempo. Desde 1941, a IBM deu suporte ao chamado processo de processamento de dados telemétricos (remotos). Nos anos 60, o IBM 1401 podia ser conectado a um dispositivo de transmissão de dados IBM 1009 ( IBM 1009 Data Transmission Unit) - um modem do tamanho de uma máquina de lavar louça, que permitia aos computadores trocar dados entre si por uma linha telefônica de até 300 caracteres por segundo. Teoricamente, é possível construir uma rede Bitcoin baseada em tecnologias dos anos 60 do século passado. Infelizmente, não consegui obter equipamentos para o teleprocessamento de dados e testar essa teoria.


O dispositivo de transferência de dados IBM 1009. Um modem do tamanho de uma máquina de lavar louça apareceu em 1960. Com ele, foi possível transmitir até 300 caracteres por segundo em uma linha telefônica. Fonte da foto: Introdução ao IBM Data Processing Systems) .

achados


Usar o SHA-256 na linguagem assembly do mainframe antigo tornou-se uma experiência difícil, mas interessante. Eu esperava um desempenho melhor (mesmo comparado ao meu Mandelbrot definido em 12 minutos ). A aritmética decimal de um computador comercial não é a melhor opção para um algoritmo binário como o SHA-256. No entanto, o algoritmo de mineração Bitcoin pode ser executado mesmo em um computador sem circuitos integrados. Portanto, se de repente um certo colapso temporário me levar a 1960, eu posso construir uma rede Bitcoin.

O Museu de História da Computação de Mountain View mostra o IBM 1401 em funcionamento às quartas e sábados.Se estiver por perto, você definitivamente deve dar uma olhada nisso, verificando o horáriotrabalhos. E se você informar à equipe do museu que demonstra executar o IBM 1401 sobre mim, eles podem até lançar meu programa Pi .

Quero agradecer ao Museu da História do Computador e aos membros da equipe de recuperação de computadores do 1401: Robert Garner, Ed Thelen, Van Snyder e, especialmente, Stan Paddock. O site da equipe ibm-1401.info possui muitas informações interessantes sobre o computador 1401 e como recuperá-lo.

Explicação


Vale a pena notar que eu não esmaguei o bloco real da IBM 1401 - o Museu de História da Computação não gostaria. Como eu disse, tendo um IBM 1401 funcionando, você não poderá ganhar dinheiro com mineração. No entanto, consegui implementar e executar o algoritmo SHA-256 em uma máquina IBM 1401, provando assim que a mineração é teoricamente possível. E revelarei o segredo de encontrar um hash válido - acabei de usar o blocominado .

Esperamos que você tenha gostado da nossa tradução

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


All Articles