Mastodon

Entropia com Dados: Como Gerar Sua Seed BIP39 Totalmente Offline, Sem Confiar em Ninguém

Gerar uma seed completamente offline, com dados físicos, sem depender de elemento seguro, firmware ou site algum.

Compartilhar
Entropia com Dados: Como Gerar Sua Seed BIP39 Totalmente Offline, Sem Confiar em Ninguém
Photo by el pepe / Unsplash

A matemática implacável da autocustódia — ou por que a ColdCard foi de Americanas e quem rolou dados sobreviveu


Bom dia, caros crypto lovers, cripto entusiastas, fauceteiros e mineradores do BLOCO.

Este texto nasceu do episódio #1002 do Morning Crypto — e nasceu de um pedido coletivo. Twitter, Instagram, produção. Todo mundo queria a mesma coisa: rever o processo de gerar uma seed completamente offline, com dados físicos, sem depender de elemento seguro, firmware ou site algum.

O timing não é coincidência. Uma semana antes, a ColdCard "foi de ColdCard" — o novo eufemismo do blocoVerso para desastres de confiança. Um erro de guarda de compilação (#ifndef que testa a existência de uma macro, não o seu valor) desligou silenciosamente o caminho do gerador de hardware e ativou um fallback: a PRNG Yasmarang via MicroPython. Resultado: entropia determinística dado o número de série do dispositivo — cerca de 40 bits efetivos nas Mk2/Mk3 e ~72 bits nas Mk4/Q/Mk5 (reseed de apenas 32 bits do elemento seguro), em vez dos 128 a 256 bits esperados. Detalhei tudo no artigo anterior. O ponto aqui é outro: quem gerou a seed manualmente não sofreu absolutamente nada — porque o caminho dos dados nunca tocava o gerador quebrado.

E note a ironia que dói: o firmware da ColdCard tem código disponível. O bug ficou cinco anos à vista de todos, invisível mesmo assim. A lição não é bonita: entropia não é auditável retroativamente. Você não consegue olhar para uma seed e medir quanta aleatoriedade ela tem. Por isso o processo de geração precisa ser verificável na hora — bit a bit, nas suas mãos.

Essa é a lição. Vamos ao processo.

Por Que Dados? A Mecânica da Entropia de Shannon

Primeiro, o básico que muita gente confunde: entropia não é o hash. Entropia é a matéria-prima.

Entropia pertence ao processo, não aos dígitos. Um resultado anotado é dado fixo — a aleatoriedade existiu apenas enquanto o dado rolava. Guarde o processo (jogadas frescas, sem câmera, sem software espiando) e os dígitos cuidam de si mesmos.

Existem dois tipos de geradores de números aleatórios:

  • PRNG (Pseudo-Random Number Generator): software. Determinístico por natureza. Foi o fallback que derrubou a ColdCard.
  • TRNG (True Random Number Generator): hardware dedicado — o elemento seguro. A OneKey Pro, por exemplo, tem quatro elementos seguros certificados EAL6+. Vale a ressalva: certificação EAL avalia processo, não a qualidade do gerador — e elemento seguro continua sendo uma caixa-preta que você não pode auditar. É o estado da arte da indústria, não da desconfiança.

Mas existe uma terceira via, ancestral e soberana: você e um conjunto de dados.

A entropia de cada jogada segue a distribuição de Shannon, e o cálculo é brutalmente simples:

$$ ({\text{bits por jogada}}) = \log_2 (\text{número de faces}) $$

Quantos bits é isso? Um bit é uma jogada honesta de moeda — a resposta a uma única pergunta de sim ou não. 256 bits é um número na casa de \(10^{77}\), na escala do número de átomos do universo observável. Adivinhar por força bruta não é uma preocupação prática.

O cálculo de quantas jogadas compram 256 bits é direto — alvo dividido pelos bits por jogada, arredondado para cima:

$$ \text{total de jogadas} = \left\lceil \frac{256}{\log_2 (n)} \right\rceil $$

Gerador Bits por jogada 256 ÷ H (exato) Jogadas mínimas Bits obtidos
Moeda 1,000 256,00 256 256,0
D6 2,585 99,03 100 258,5
D20 4,322 59,23 60 259,3
D30 4,907 52,17 53 260,1

Repare na curva. A escala é logarítmica: do D6 para o D20 o salto é de ~1,67× (para dobrar de verdade, seria preciso um D36). Do D20 para o D30, a diferença já encolhe para +13%. Fabricar um D300 é contorcionismo geométrico com ganho marginal ridículo — a curva estabiliza e você só ganha dor de cabeça de balanceamento. Bits fracionários como 2,585 são desconfortáveis em strings de bits crus; é por isso que o SHA-256 entra mais adiante para arrumar a casa.

O Segredo: Matando o Viés dos Dados

Todo dado tem vício. Peso imperfeito, bolha de ar no material, centro de gravidade deslocado, cantos chanfrados. Dados de cassino são os menos viciados — e mesmo eles têm viés. Um dado impresso em casa, lixado à mão? Obviamente viciado. E aqui vai a honestidade que falta em muito tutorial: dados impressos em 3D estão entre os piores RNGs físicos que existem — infill assimétrico, warping, vazios de adesão entre camadas. Se puder, use dados de precisão. Se imprimir os seus, teste antes: flutuação em água salgada revela desbalanceamento grosseiro; algumas centenas de jogadas anotadas e um teste qui-quadrado revelam o resto.

💡
Qui-quadrado não é feitiçaria. É aritmética que transforma "acho que esse dado cai mais no 6" em "\( \chi^2 = 18{,}3, p < 0{,}01 \) — esse dado é lixo". Para dados impressos em 3D, onde infill, warping e adesão entre camadas criam vieses invisíveis a olho nu, o teste é a única honestidade que resta. Gaste 20 minutos rolando e anotando. A matemática não mente.

A solução, de qualquer forma, não é o dado perfeito. É a distribuição do vício:

  1. Dados diferentes: tamanhos, materiais e projetos distintos mudam centro de gravidade e peso. Um único dado repetido 100 vezes repete o mesmo viés 100 vezes — misturar dados decorrelaciona os vícios sistemáticos entre si (cada dado continua viciado, mas não todos na mesma direção).
  2. Jogue mais que o mínimo: de 1,5× a 2× o necessário. O D20 pede 60 jogadas? Jogue 90 a 120. O mecanismo aqui não é "diluir" o viés — cada jogada continua amostrando a mesma distribuição viciada. O que acontece é que a min-entropia total acumula linearmente com jogadas independentes, e o hash final atua como extrator: se o viés for leve (1–2% por face, invisível ao olho, mas existente), a sobra cobre a diferença com folga.
  3. Não seja preguiçoso: dado que desliza de lado não rolou. Está roubando. Use um copo — no meu caso, o entrocopo.

No setup da live:

$$ 2 \times \text{D30} + 8 \times \text{D20} = 44{,}39 \text{ bits por rodada coletiva} $$

(em entropia de Shannon, assumindo dados honestos). Mínimo de 6 rodadas para 256 bits; jogamos 10 rodadas, gerando ~443 bits de entropia bruta.

E grave a palavra-chave do parágrafo anterior: Shannon. Os 44,39 bits são a entropia nominal de dados perfeitamente honestos. O que protege sua seed é a min-entropia — o pior caso, não o caso médio. Com viés leve e 67% de sobra (10 rodadas em vez de 6), a min-entropia real continua acima de 256 bits. Mas nenhum excesso de jogadas salva um dado catastroficamente viciado: se uma face sai 90% das vezes, você pode jogar o dia inteiro que não chega a 256 bits de segurança real. A sobra absorve viés leve — não milagre.

A Regra do Zero (Que Todo Mundo Esquece)

Aqui mora um erro silencioso que destrói entropia. O perigo real está nos dados com faces de dois dígitos: duas jogadas de D20 — 12, depois 3 — concatenadas viram 123. Mas 1, depois 23, também viram 123. A mesma string para entradas diferentes. Você perdeu entropia na anotação.

A correção é um padding simples: todo resultado abaixo de 10 recebe um zero à esquerda.

$$ 12, 03 \neq 01, 23 \neq 01, 02, 03 $$

Sequências absolutamente distintas. Cada jogada tem sua própria assinatura. Sem exceções. (No D6 o padding é desnecessário — 6 é o máximo e tem um dígito só — mas não faz mal; o que interessa é que a codificação seja injetiva.)

SHA-256: O Harmonizador, Não o Mágico

Com os resultados anotados (258 caracteres na nossa sessão), aplicamos o SHA-256 sobre toda a sequência:

shasum -a 256 entropia.txt

Por quê? O hash distribui e uniformiza o viés residual — desde que a min-entropia de entrada seja suficiente (condição que acabamos de garantir com a sobra de jogadas). É determinístico — troque um único dígito da entrada e, em média, metade dos bits da saída flipa. O exemplo abaixo é real: duas strings de 100 jogadas de D6 que diferem em um único dígito terminal (3 vs 4):

…56256224**3**  →  fa8585ce 34e74278 d00ea439 610c8635…
…56256224**4**  →  42065cca ea007a8f f6f6bba5 d263660d…

Hashes completamente diferentes. O avalanche é a propriedade que torna o hash uma assinatura digital honesta da entropia — ninguém consegue trabalhar do hash de volta para a sequência de jogadas, e o hash é seguro de manusear como a própria seed.

Mas grave isto, porque é onde tanta gente morre:

O SHA-256 preserva e limita entropia. Ele nunca cria entropia.

Um SHA-256 de 40 bits de entropia continua tendo 40 bits de entropia — a saída é limitada pelo mínimo entre a entrada e os 256 bits do digest. Não adianta hashear palavra de dicionário. A entropia de entrada precisa ser forte; o hash apenas a harmoniza. É a matemática implacável.

Da Entropia às 24 Palavras: O Processo Completo

O fluxo, de ponta a ponta, executável num Linux ou Mac desconectado da internet:

1. Entropia → SHA-256 → Binário. Convertemos o hash hexadecimal em 256 bits puros:

echo -n "<entropia>" | shasum -a 256 | xxd -r -p | xxd -b -c 256

Duas armadilhas aqui. Primeiro: o -n no echo, para não injetar uma quebra de linha no final. Segundo, e mais traiçoeiro: o xxd -b imprime colunas de offset (00000000:) e uma coluna ASCII à direita — e esses caracteres vão contaminar qualquer comando que consuma a saída. Sempre extraia apenas a coluna de bits (remova o offset, corte tudo após o espaço duplo que precede a coluna ASCII):

echo -n "<entropia>" | shasum -a 256 | xxd -r -p | xxd -b -c 256 | sed -e "s/^[0-9a-f]*: //" -e "s/  .*$//" | tr -d ' \n'

2. O problema das 24 palavras. Cada palavra BIP39 carrega 11 bits. Mas 256 ÷ 24 = 10,66 — faltam 8 bits para completar a última palavra.

3. Checksum. Fazemos o SHA-256 do próprio binário — e aqui o detalhe técnico crítico: o -0 no comando diz que a entrada é binária, não texto (um caractere são 8 bits; aqui cada dígito é 1 bit, e todo caractere que não for 0 ou 1 é ignorado):

echo -n "<entropia>" | shasum -a 256 | xxd -r -p | xxd -b -c 256 | sed -e "s/^[0-9a-f]*: //" -e "s/ .*$//" | tr -d ' \n' | shasum -a 256 -0

Dos 256 bits resultantes, pegamos apenas os 8 primeiros (os dois primeiros caracteres hex convertidos para binário) e os anexamos ao final: 264 bits = 24 grupos exatos de 11.

O layout dos bits fica assim:

├── ENT: 256 bits (do SHA-256 da entropia) ──┤├ CS: 8 bits ┤
└─────────────────── 264 bits = 24 × 11 ───────────────────┘

4. Binário → Decimal → Palavras. Cada grupo de 11 bits vira um número de 0 a 2047 (índice 0 = "abandon", índice 2047 = "zoo"). A conversão roda na calculadora da própria máquina air-gapped (bc, Python, a calculadora do sistema) ou no papel — jamais no celular, que é um dispositivo conectado e não deve tocar nada que cheire a entropia viva. Depois, a lista oficial BIP39 (salva localmente, junto com o Ian Coleman).

E aqui confesso, com a humildade de quem errou ao vivo pela segunda vez: o índice começa em zero. O número 692 corresponde à palavra de posição 693 na lista numerada de 1 a 2048. Erramos isso no episódio 839 e erramos de novo no 1002 — a diferença é que desta vez o chat me corrigiu em tempo real.

Duas lições saem dessa confissão, e nenhuma delas é "tanto faz". Primeira: em geração de seed nova, um índice deslocado ainda produz uma seed válida de 256 bits — qualquer conjunto de 24 palavras com checksum correto é uma seed forte. Mas essa tolerância só vale se o erro for consistente entre o que você deriva e o que você grava no metal — e erro que você não detectou, por definição, você não sabe se foi consistente. Segunda, e mais importante: a taxa de erro humano aqui é empiricamente 2 em 2 — eu errei nas duas tentativas ao vivo. É exatamente por isso que o passo 5 não é opcional. O processo manual não é superior por ser infalível; é superior por ser verificável. E na restauração de uma seed existente, o índice exato é inegociável: uma palavra errada e você está diante de uma wallet diferente, vazia, que não é a sua.

5. Verificação. Baixe o Ian Coleman (open source) e rode-o offline, jamais conectado. Cole o hash da entropia em "raw entropy" — a ferramenta calcula o checksum ela mesma e deriva as palavras. Confira se os índices batem: 692, 1975, 1952... Atenção à assimetria: como o Ian Coleman gera o próprio checksum, ele não detecta um checksum manual errado — o único sinal de divergência é a palavra 24. Se a sua palavra 24 manual não bater com a da ferramenta, o erro está no seu processo, não nela. Bateram as 24? A seed está correta.

💡
Extra: como a wallet deriva as chaves: As 24 palavras não são a chave final — são o ponto de partida. A wallet as estica com PBKDF2-HMAC-SHA512 (2048 rounds, salt "mnemonic" + sua passphrase opcional) num seed de 512 bits, e a partir dela BIP32 deriva a árvore de chaves que gera todos endereços. Quem segura as palavras segura tudo — passphrase salva à parte, em local separado.

O Protocolo de Segurança Final

A live inteira foi um exercício de transparência — o que significa que aquela seed específica nasceu pública e morta. Qualquer satoshi enviado a ela será roubado em segundos. Isso vale para qualquer entropia que já tenha visto a luz de uma tela, um VOD ou um screenshot.

Para a sua seed real, nesta ordem:

  • Primeiro verifique, depois destrua: insira as 24 palavras na hardware wallet, resete, insira de novo. Confirme antes de confiar. Só então destrua o rastro: anotações de jogadas, hash, binário, checksum — tudo isso é descartável. O BIP39 existe justamente para você não precisar guardar nada disso. Não fotografe. Não deixe no Notepad.
  • Guarde apenas as 24 palavras (ou os números): em metal, em dois locais físicos separados.
  • Passphrase forte (a "25ª palavra"): nada de palavras de dicionário. Use maiúsculas, minúsculas, números, símbolos. Guardada separada da seed — passphrase junto com a seed não adianta de nada.
  • Jamais mantenha a única cópia em arquivo digital.

Conclusão: Não Existe Felicidade com Entropia Fraca

A lição da ColdCard se repete em toda ferramenta delegada — mas repete com precisão: a licença proprietária removeu os incentivos para que o código fosse usado e auditado. Foi um fallback silencioso num código disponível, invisível por cinco anos porque ninguém consegue medir a entropia de uma seed olhando para ela. Auditoria de código pega bug de lógica; não pega gerador desligado por uma macro. Quem confiou cegamente pagou o preço. Processos verificáveis na hora da geração permanecem; promessas de firmware, não.

E honestidade completa exige a outra metade: o método manual também falha — eu mesmo errei o índice duas vezes ao vivo. A diferença não é que suas mãos sejam infalíveis. É que no processo manual todo erro é detectável por verificação independente, enquanto o firmware quebrado não emite sinal algum. Soberania não é ausência de erro; é a capacidade de conferir.

E ela começa aqui: dez dados de RPG, um copo, dez rodadas, um SHA-256 e um caderno. Um processo que nenhum firmware defeituoso, nenhuma biblioteca capada, nenhum hack de supply chain pode tocar.

A ColdCard nos ensinou o preço da confiança delegada. Os dados nos devolvem a alternativa: entropia forte, gerada pelas suas próprias mãos, verificável bit a bit.

Seu Primeiro Passo — Hoje

Teoria sem prática é só entretenimento. Então aqui está o ritual, executável neste fim de semana:

  1. Consiga os dados: dados de precisão de cassino são o ideal; um bom set de RPG resolve; se imprimir em 3D, teste o balanceamento antes (água salgada + algumas centenas de jogadas anotadas) — os projetos que usei estão no MakerWorld ("balanced D30 dice", "parametric D20") e no Thingiverse ("dramatic balanced D20").
  2. Baixe o Ian Coleman no seu computador: iancoleman.io/bip39 — salve a página e rode local.
  3. Desconecte o cabo de rede. Desligue o Wi-Fi. Celular longe da mesa. Air-gap de verdade.
  4. Gere uma seed de teste que você vai destruir. Jogue os dados 10 vezes, anote com o zero à esquerda e ordem fixa, faça o hash, derive as palavras, verifique no Ian Coleman — e confira especialmente a palavra 24. Depois jogue tudo fora.

A prática com uma seed morta é o único treino que importa. Quando você executar o processo de ponta a ponta uma vez, a segunda já é memória muscular — e aí sim você gera a seed real do seu cofre.

Existem mil maneiras de se preparar. Invente a sua — mas com entropia forte. Porque não dá para ser feliz com entropia fraca.


Assista ao corte

(Processo da geração da entropia e Ian Coleman - para derivar as palavras manualmente, assista a live completa)


📦 Materiais

Fontes e referências

Send sats if you liked.

⚡️eddieoz@sats4.life