Pular para conteúdo

SHA-256

SHA-256 ("Secure Hash Algoritm 256-bit") é a função específica de hash que o Bitcoin usa para mineração, IDs de transação, hashes de bloco e árvores Merkle. Este capítulo vai dentro do algoritmo em si (não apenas como chamá-lo, mas o que ele realmente faz com os bits que você alimenta) porque Bitcoin processo de mineração (coberto em Prova de Trabalho) é, mecanicamente, nada mais do que chamar esta função específica bilhões de vezes por segundo.

Origem

SHA-256 faz parte da família SHA-2, projetada pela Agência de Segurança Nacional dos EUA e publicada pelo NIST (Instituto Nacional de Padrões e Tecnologia) em 2001 como FIPS 180-2, superando o anterior SHA-1, que começou a mostrar fraquezas teóricas. O SHA-2 resistiu a mais de duas décadas de criptoanálise pública sem que fosse encontrado um ataque de colisão prático, o que faz parte do motivo pelo qual continua a ser confiável para a segurança do Bitcoin apesar da sua origem da NSA. Seu design e especificação completa são públicos, e tem sido objeto de escrutínio acadêmico sustentado e contraditório, ao contrário de uma função cujos internos são mantidos em segredo.

Como funciona, passo a passo

SHA-256 processa a entrada em blocos de 512 bits (64-byte), executando cada uma através de 64 rodadas de operações de mistura, e produz uma saída de 256 bits (32-byte). Aqui está o processo quebrado em suas etapas reais:

1. Padding

A mensagem é acolchoada então seu comprimento é um múltiplo de 512 bits. O tampo sempre adiciona um único 1 bit, seguido de suficiente 0 bits, seguido por um inteiro de 64 bits big-endian codificando o comprimento da mensagem original em bits. Este esquema de enchimento (chamado de Merkle–Damgård strengthening) não garante duas mensagens de comprimento diferente para o mesmo formulário acolchoado, que importa para as provas de segurança da função.

2. Quebrando em blocos

A mensagem acolchoada é dividida em pedaços de 512 bits. Cada pedaço é processado sequencialmente, com a saída de processar um pedaço de alimentação para o processamento do próximo. Este encadeamento é porque SHA-256 pertence à família de Construção Merkle–Damgård funções de hash.

3. Expansão do calendário da mensagem

Cada bloco de 512 bits é quebrado em dezesseis palavras de 32 bits, então expandido para sessenta e quatro palavras de 32 bits usando uma fórmula de recorrência envolvendo rotações de bits, deslocamentos e operações XOR em palavras anteriores no cronograma. Esta expansão é o que faz cada uma das 64 rodadas de compressão operar em diferentes dados derivados em vez de repetir as mesmas 16 palavras.

4. A função de compressão

SHA-256 mantém oito variáveis de trabalho de 32 bits (convencionalmente designadas a através h), inicializado para o primeiro bloco de oito constantes fixas derivadas das partes fracionárias das raízes quadradas dos primeiros oito números primos (2, 3, 5, 7, 11, 13, 17, 19). Para cada uma das 64 rodadas, o algoritmo combina as variáveis de trabalho atuais com uma palavra do cronograma de mensagens e uma das 64 constantes de rodadas (derivadas da mesma forma, das partes fracionárias das raizes cúbicas dos primeiros 64 primes) usando bitwise AND, XOR, NOT, adição modular e rotações fixas, projetadas coletivamente para que cada bit de saída dependa, após rodadas suficientes, de cada bit de entrada de uma forma que seja rápida de calcular para frente, mas não tenha uma forma eficiente de calcular para trás.

A escolha específica das constantes derivadas de raizes de números primos (às vezes chamadas de "nada-para-meu-leva") é uma escolha de projeto deliberada: demonstra que as constantes não foram secretamente escolhidas para criar uma fraqueza oculta (um backdoor), uma vez que foram derivadas através de um procedimento matemático óbvio, publicamente reprodutível em vez de escolhidos arbitrariamente.

5. Chaining e saída

Depois de processar todas as 64 rodadas para um bloco, as variáveis de trabalho resultantes são adicionadas (modulo 2^32) ao estado carregado de antes desse bloco, produzindo o novo estado passado para o próximo bloco. Após o bloco final, as oito variáveis de trabalho de 32 bits são concatenadas para formar a saída de 256 bits.

Message ──► Pad to multiple of 512 bits ──► Split into 512-bit blocks
                                                     │
                        ┌────────────────────────────┘
                        ▼
              Block 1 ──► Compression function ──► intermediate state
                                                     │
                        ┌────────────────────────────┘
                        ▼
              Block 2 ──► Compression function ──► intermediate state
                                                     │
                                                    ...
                                                     │
                                                     ▼
                                          Final 256-bit hash output

SHA-256d: Escolha real do Bitcoin

Bitcoin não usa um único passe SHA-256 para a maior parte de seu hashing. Utiliza SHA-256 aplicado duas vezes, escrito SHA-256d(x) = SHA-256(SHA-256(x))Esta escolha foi feita para atenuar uma preocupação teórica específica denominada ataque de extensão de comprimento, que afeta funções de hash Merkle–Damgård, incluindo SHA-256 simples: dado H(x) e o comprimento de x (mas não x em si), um atacante pode calcular H(x || y) para um sufixo escolhido y, sem saber x, porque a construção Merkle–Damgård final estado interno é a saída, e esse estado sozinho é suficiente para continuar processando blocos adicionais. Aplicando SHA-256 uma segunda vez à saída do primeiro hash significa que um atacante precisaria reverter o segundo hash para montar este ataque, que preimage resistance (ver Resistência à Preimagem) previne. É por isso que cada referência neste livro à "função hash do Bitcoin" sem mais qualificação geralmente significa SHA-256d especificamente, nem um único passe SHA-256. Ver Prova de Trabalho e Cabeçalhos de Blocos para onde esta função exata é aplicada.

Exemplo

import { createHash } from "node:crypto";

function sha256(buf: Buffer): Buffer {
  return createHash("sha256").update(buf).digest();
}

function sha256d(buf: Buffer): Buffer {
  return sha256(sha256(buf));
}

const message = Buffer.from("hello");
console.log("SHA-256:  ", sha256(message).toString("hex"));
console.log("SHA-256d: ", sha256d(message).toString("hex"));
SHA-256:   2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
SHA-256d:  9595c9df90075148eb06860365df33584b75bff782a510c6cd4883a419833d50

As duas saídas são completamente diferentes uma da outra, como esperado. SHA-256d não é "SHA-256 mas mais forte contra cada ataque", é especificamente SHA-256 composto por si mesmo para fechar a distância comprimento-extensão.

Comércio

SHA-256 é rápido em CPUs de uso geral, o que foi bom para os primeiros anos do Bitcoin, mas esta mesma velocidade tornou-se uma responsabilidade uma vez que a mineração tornou-se competitiva: porque SHA-256d pode ser calculada extremamente rapidamente e em paralelo por hardware especializado, mineração de Bitcoin rapidamente se moveu de CPUs para GPUs para FPGAs para ASICs projetados (Circuitos Integrados Específicos de Aplicação, veja ASICs) ao longo de seus primeiros anos, concentrando a capacidade de mineração entre aqueles que podem pagar e implantar hardware especializado em escala. Esta é uma consequência directa e documentada da escolha de uma função de hash rápida e compatível com o hardware para um sistema de prova de trabalho, e é uma pressão de centralização real discutida mais adiante em Pools de MineraçãoUma troca de design de outros sistemas de prova de trabalho (como alguns que escolheram deliberadamente funções duras de memória para resistir à especialização ASIC) feita de forma diferente.

Conceitos errôneos comuns

SHA-256 não é "encriptação", e os endereços Bitcoin não são dados "encriptados". Hashing é um caminho; nada está sendo mantido confidencial e depois descriptografado. Ver Funções do Hash.

Nenhuma colisão prática foi encontrada em SHA-256. Isso é distinto do SHA-1, que teve uma colisão prática demonstrada publicamente em 2017 (o ataque "Chattered" por pesquisadores do Google e da CWI Amsterdam). SHA-1 e SHA-256 são algoritmos diferentes com diferentes margens de segurança, e configurando uma fraqueza SHA-1 com SHA-256 é uma generalização comum, mas incorreta.

Outras leituras


← Anterior: Funções de Hash · Voltar à Criptografia · Próximo: colisões de hash →