Carteiras HD
Carteiras Hierárquicas Determinísticas
BIP 32: Hierarchical Deterministic Wallets
Uma carteira hierárquica determinística (ou "carteira HD") é uma carteira que gera todas as suas chaves e endereços a partir de uma única fonte.
- Hierárquica – As chaves e os endereços podem ser organizados em uma árvore.
- Determinística – As chaves e os endereços são sempre gerados da mesma forma.
Então, basicamente, uma carteira HD permite gerar bilhões de chaves privadas usando uma única seed. Assim, desde que você lembre da seed, sempre conseguirá recuperar as mesmas chaves e endereços.
Isso as torna muito mais amigáveis que as primeiras carteiras de bitcoin, que geravam e armazenavam as chaves privadas individualmente.
O recurso mais interessante das carteiras HD é que você pode gerar novas chaves públicas sem ter que gerar as chaves privadas delas ao mesmo tempo.
Exemplos
Aqui estão alguns exemplos de carteiras HD populares de que eu gosto:
- Electrum (Desktop)
- Sparrow Wallet (Desktop)
- Trezor (Carteira de Hardware)
- Coldcard (Carteira de Hardware)
Quase todas as carteiras modernas (desde 2013) são hierárquicas determinísticas.
Frase Mnemônica
Ao criar uma carteira HD, você recebe uma frase mnemônica de 12 ou 24 palavras. Ela é a fonte da seed, que então é usada para gerar todas as chaves e endereços da sua carteira.
Por exemplo:
abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
Nunca use uma seed gerada por um site, nem digite a sua seed em um site. Sites podem facilmente salvar a seed e usá-la para roubar todos os seus bitcoins.
Caminhos de Derivação
As chaves da sua carteira HD serão geradas usando um dos seguintes caminhos de derivação, dependendo do tipo de endereços que você quer usar:
m/44'/0'/0' = endereços 1 (P2PKH)
m/49'/0'/0' = endereços 3 (P2SH-P2WPKH)
m/84'/0'/0' = endereços bc1 (P2WPKH) Benefícios
Quais são os benefícios de uma carteira HD?
1. Backup único
Em uma carteira básica, você geraria pares de chaves privadas e chaves públicas de forma independente cada vez que quisesse receber bitcoins.
Isso funciona perfeitamente bem, mas significa que você precisaria fazer backup da carteira toda vez que recebesse um novo pagamento.
No entanto, com uma carteira hierárquica determinística, você pode usar uma única seed para criar uma chave privada mestra, e usá-la para gerar bilhões de "chaves filhas" privadas e públicas.
Então agora tudo o que você precisa guardar em backup é a seed, pois a chave privada mestra que você cria a partir dela sempre gera as chaves da sua carteira da mesma forma (deterministicamente).
2. Organização
Outra coisa legal das carteiras hierárquicas determinísticas é a parte hierárquica.
Cada chave filha da carteira também pode gerar suas próprias chaves, o que significa que você pode criar uma estrutura em árvore (ou hierarquia) para organizar as chaves da sua carteira.
Você então usa diferentes partes da árvore para separar as chaves em diferentes "contas".
3. Gerar chaves públicas independentemente
Mas a parte realmente interessante de uma chave privada mestra é que ela tem uma chave pública mestra correspondente, e esta consegue gerar as mesmas chaves públicas filhas sem as chaves privadas.
Assim, você poderia enviar a chave pública mestra para um computador diferente (por exemplo, o servidor de uma loja online) para gerar novos endereços de recebimento, sem se preocupar que as chaves privadas seriam roubadas caso o servidor fosse hackeado.
Isso pode parecer mágica, mas é tudo apenas matemática.
Isso também é útil para coisas como carteiras de hardware – você pode manter as suas chaves privadas em um dispositivo seguro e gerar novos endereços em um computador diferente para receber pagamentos.
Como funcionam as carteiras HD?
O que se segue é uma visão geral visual de como as carteiras HD funcionam.
Para os detalhes técnicos, veja chaves estendidas.
1. Seed
Para criar uma carteira HD, você começa gerando 64 bytes aleatórios. Essa é a nossa seed.
Exemplo
5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4
2. Chave Privada Mestra
A "chave mestra" é criada passando a seed por uma função de hash (chamada de HMAC) para gerar outro conjunto de 64 bytes.
HMAC-SHA512
Usamos esses 64 bytes para criar a nossa chave privada estendida mestra.
- Os primeiros 32 bytes são a chave privada.
- Os últimos 32 bytes são o chain code.
O chain code é apenas mais 32 bytes que acoplamos à chave privada para criar o que chamamos de chave estendida.
Exemplo
chave privada (primeiros 32 bytes): 1837c1be8e2995ec11cda2b066151be2cfb48adf9e47b151d46adab3a21cdf67 chain code (últimos 32 bytes): 7923408dadd3c7b56eed15567707ae5e5dca089de972e07f3b860450e2a3b70e
Uma "chave estendida" é apenas uma chave normal acoplada a um chain code.
Por que fazemos o hash da seed? Nós poderíamos usar diretamente a seed de 64 bytes para criar a chave privada estendida mestra. No entanto, as futuras chaves estendidas filhas são criadas usando o HMAC, então é bom ser consistente com a forma como criamos ambas.
A chave privada embutida dentro de uma chave estendida pode ser usada para criar uma chave pública correspondente, normalmente:
chave privada: 1837c1be8e2995ec11cda2b066151be2cfb48adf9e47b151d46adab3a21cdf67 chave pública: 03d902f35f560e0470c63313c7369168d9d7df2d49bf295fd9fb7cb109ccee0494
Chave Pública
A verdadeira chave privada estendida mestra em si é apenas a chave privada e o chain code.
3. Chaves Filhas (Básico)
Derivando chaves privadas e chaves públicas
Novas chaves privadas filhas são geradas a partir de uma chave privada estendida passando-a (a chave privada e o chain code) pela função HMAC.
Também incluímos um número de índice a cada vez, o que nos permite criar várias chaves filhas a partir de uma única chave mestra.
Então, essencialmente, novas chaves privadas são geradas fazendo o hash da chave privada estendida mestra com um número de índice.
Exemplo
índice: 2147483648 (0', endurecida/hardened) chave privada filha: c08cf331996482c06db3d259ff99be4bf7083824d53185e33191ee7ceb2bf96f chain code filho: f1c03f5ff97108912fd56761d3fada8879e4173aba45f10da4bbd94b1c497160 chave pública filha: 027f1d87730e460e921b382242911565bf93daf2081ed685b2edd1d01176b2c13c
Há uma etapa matemática extra ao calcular a chave privada filha depois do hash da chave privada estendida pai. É por isso que você não obterá os resultados corretos simplesmente passando a (chave privada de 32 bytes | índice de 4 bytes) e o (chain code de 32 bytes) pelo HMAC. Veja chaves estendidas para os detalhes.
Uma chave estendida pode gerar 2.147.483.648 dessas chaves filhas "básicas" (endurecidas/hardened).
4. Chaves Filhas (Avançado)
Derivando chaves privadas e chaves públicas, e também chaves públicas independentemente
Agora vem a parte divertida.
E se quiséssemos que uma chave privada estendida criasse chaves privadas e chaves públicas filhas, mas também quiséssemos uma chave pública estendida correspondente, capaz de gerar as mesmas chaves públicas filhas?
Em outras palavras, como podemos gerar chaves públicas sem as chaves privadas?
1. Chave Pública Estendida
Primeiro, precisamos construir a chave pública estendida.
Ela é apenas a chave pública da chave privada estendida, acoplada ao mesmo chain code:
Chave Pública
Exemplo
chave pública: 03d902f35f560e0470c63313c7369168d9d7df2d49bf295fd9fb7cb109ccee0494 chain code: 7923408dadd3c7b56eed15567707ae5e5dca089de972e07f3b860450e2a3b70e
2. Filhas da Chave Privada Estendida
A chave privada estendida mestra cria chaves privadas filhas passando o conteúdo da sua chave pública estendida correspondente pela função HMAC e somando o resultado à chave privada original.
Exemplo
índice: 0 (normal) chave privada filha: baa89a8bdd61c5e22b9f10601d8791c9f8fc4b2fa6df9d68d336f0eb03b06eb6 chain code filho: e0e6503ac057cf5dc76e0735e56dd44d193b2e9e271cc2d46bc759c99b021e3c
3. Filhas da Chave Pública Estendida
A chave pública estendida mestra cria chaves públicas filhas passando o seu conteúdo pela função HMAC e somando o resultado à chave pública original.
Exemplo
índice: 0 (normal) chave pública filha: 0376bf533d4b15510fa9f4124b6e48616f07debcf2ef0cfb185cdc4a576450b475 chain code filho: e0e6503ac057cf5dc76e0735e56dd44d193b2e9e271cc2d46bc759c99b021e3c
- Uma chave estendida pode gerar 2.147.483.648 dessas chaves filhas "avançadas" (normais).
- Logo, uma chave estendida pode derivar 4.294.967.296 filhas no total:
- Normais = 2.147.483.648 (índices
0a2147483647) - Endurecidas (hardened) = 2.147.483.648 (índices
2147483648a4294967295)
- Normais = 2.147.483.648 (índices
Agora, como desta vez as chaves filhas foram ajustadas com base na chave privada e na chave pública do pai, a magia da matemática das curvas elípticas faz com que as chaves privadas e chaves públicas filhas sejam correspondentes.
Parece mágica, eu sei, mas é apenas matemática.
Perguntas frequentes
Por que usamos um chain code?
Adicionar um chain code faz com que as chaves filhas não sejam derivadas apenas a partir da chave.
Por exemplo, podemos usar uma das chaves públicas da árvore para receber um pagamento, o que a tornaria visível na blockchain. Se não usássemos chain codes, qualquer pessoa poderia pegar essa chave pública e derivar todas as filhas dela:
Mas, ao usar chain codes (que não vão para a blockchain), outras pessoas ficam incapazes de derivar as filhas a partir da chave pública:
Então, em outras palavras, o chain code é um dado secreto adicional que impede outras pessoas de derivar as filhas de uma chave.
As chaves de uma carteira HD estão conectadas?
Não.
Você não consegue saber que duas chaves públicas (ou endereços) quaisquer da árvore fazem parte da mesma carteira (ou seja, foram derivadas da mesma chave estendida mestra).
Embora as chaves filhas sejam derivadas da chave estendida mestra de forma determinística, as próprias chaves privadas e chaves públicas não guardam nenhuma semelhança entre si.
Então, para o mundo externo, é como se todas as chaves privadas e chaves públicas tivessem sido geradas de forma completamente independente.
As chaves de uma carteira HD são seguras?
Sim, todas as chaves privadas e chaves públicas que você obtém de uma carteira HD são tão seguras quanto se você as tivesse gerado de forma independente usando um gerador de números aleatórios.
No entanto, as chaves estendidas devem ser mantidas extra seguras, pois qualquer pessoa com acesso a elas pode derivar todas as suas filhas.
Por exemplo, se você revelasse a sua chave pública estendida mestra, outras pessoas conseguiriam encontrar todos os endereços da sua carteira. Elas não conseguem roubar nada, porque não conseguem gerar as chaves privadas para eles, mas ainda assim podem ver quanto bitcoin você possui.
Vazar uma chave pública estendida pai e qualquer chave privada filha permite que alguém calcule a chave privada estendida pai.
E se conseguirem calcular a chave privada estendida, conseguem gerar todas as chaves privadas daquele nível da carteira (e abaixo) e roubar os seus bitcoins:
À primeira vista pode parecer que isso não seria possível, mas é, então fique atento.
- Tente não revelar a sua chave pública estendida. Se revelar, outras pessoas conseguem encontrar os endereços da sua carteira.
- Se você revelasse também uma chave privada filha, isso seria tão ruim quanto revelar a chave privada estendida.
Endereço
As chaves privadas estendidas e as chaves públicas estendidas de uma carteira HD têm o seu próprio formato de endereço.
Endereço (Chave Estendida)
Por exemplo, é assim que a nossa chave privada estendida mestra fica quando serializada:
0488ade4 versão (xprv) 00 profundidade (depth) 00000000 fingerprint do pai 00000000 índice 7923408dadd3c7b56eed15567707ae5e5dca089de972e07f3b860450e2a3b70e chain code 001837c1be8e2995ec11cda2b066151be2cfb48adf9e47b151d46adab3a21cdf67 chave (00 | chave privada)
Podemos então transformar isso em um endereço fazendo a codificação base58check dele:
xprv9s21ZrQH143K3GJpoapnV8SFfukcVBSfeCficPSGfubmSFDxo1kuHnLisriDvSnRRuL2Qrg5ggqHKNVpxR86QEC8w35uxmGoggxtQTPvfUu Esse agora é um formato mais útil para a nossa chave privada estendida, pois é mais fácil de compartilhar entre computadores e importar em carteiras.
Veja endereço de chave estendida para os detalhes.
Histórico
Quem inventou as carteiras HD?
- Gregory Maxwell teve a ideia inicial de que é possível ajustar (tweak) chaves públicas para obter novas chaves públicas sem conhecer as chaves privadas delas, o que também é conhecido como derivação homomórfica.
- Armory foi a primeira carteira a implementar essa derivação homomórfica e também introduziu o conceito de usar um chain code.
- Pieter Wuille teve a ideia de usar uma estrutura hierárquica e construiu sobre o esquema usado pela Armory para criar a especificação BIP 32.
A FSF queria aceitar doações em Bitcoin e queria gerar novos endereços para cada usuário, mas não queria deixar sua chave privada no servidor web.
As carteiras HD (BIP32) se basearam no esquema da Armory, mas com mais flexibilidade (a estrutura hierárquica) e acesso aleatório no índice (o esquema da Armory exigia gerar todos os N endereços antes de N para derivar o endereço número n).
Resumo
Uma carteira hierárquica determinística oferece um método útil para gerar novas chaves privadas e chaves públicas.
Ela é determinística porque todas as chaves filhas são geradas a partir de uma única seed da mesma forma a cada vez, e é hierárquica porque você pode organizar as chaves em uma estrutura em árvore (ou hierarquia). O benefício adicional é que é possível derivar as chaves públicas da carteira sem ter nenhum conhecimento das chaves privadas, o que é bastante incrível.
Aqui estão algumas explicações mais técnicas, caso você tenha interesse nos detalhes das carteiras HD:
- Frase Mnemônica – Gerando uma seed amigável para a sua carteira HD.
- Chaves Estendidas – Criando uma chave estendida mestra e derivando filhas a partir dela.
- Caminhos de Derivação – Hierarquias comuns usadas pelas carteiras para organizar as chaves.
Recursos
- https://bitcointalk.org/index.php?topic=19137 – Discussão sobre carteiras determinísticas, por Gregory Maxwell
- https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki – BIP por Pieter Wuille
- https://iancoleman.io/bip39/ – Uma incrível ferramenta web para gerar carteiras HD
- https://github.com/lian/bitcoin-ruby/blob/master/lib/bitcoin/ext_key.rb – Uma implementação limpa em Ruby
- https://www.youtube.com/watch?v=OVvue2dXkJo – Palestra de James Chiang
- https://www.cs.cornell.edu/~iddo/detwal.pdf – Slides de Gregory Maxwell sobre carteiras determinísticas
- https://eprint.iacr.org/2014/998.pdf – Artigo interessante de Gus Gutoski e Douglas Stebila
- Hierarchical determinism: how Bitcoin's HD wallets are born – Uma introdução às carteiras HD com ferramentas interativas