¿Cómo se generan diferentes direcciones a partir de la misma clave privada?

Estaba leyendo en " Antecedentes técnicos de las direcciones de Bitcoin de la versión 1 " que las direcciones son una función de la clave privada. Más o menos:

Private Key -> Public Key -> Address

Si la clave pública es la única entrada necesaria para generar una dirección, ¿cómo es que una billetera genera una dirección diferente cada vez? ¿Qué está cambiando?

Una billetera determinista es una forma de generar una clave privada a partir de una frase de contraseña. La pregunta aquí es que parece que se pueden generar diferentes direcciones a partir de una sola clave privada. Al menos esa es la impresión que me da mi administrador de cartera.
Bien, ahora lo veo. La respuesta son carteras deterministas secuenciales o jerárquicas. Este anunciante lo explica: bitcoin.stackexchange.com/questions/718/…
En lugar de profundizar en matemáticas complejas, usemos una herramienta de generación de contraseñas de Linux de línea de comandos ya existente y práctica llamada pwgen. Puede proporcionar pwgenun archivo semilla y siempre arrojará el mismo conjunto de contraseñas, por ejemplo, en miles. Aquí es cómo:bash echo "sowing the seeds of love" > /tmp/seedfile.txt pwgen -H /tmp/seedfile.txt -N 1000

Respuestas (4)

La clave pública y privada corresponden a un punto en la curva secp256k1. Tienen una relación de uno a uno.

La dirección se deriva de la clave pública realizando un ripemd160hash después de un sha256hash en la clave pública. El hash de múltiples claves públicas a la misma dirección, ya que el espacio de direcciones es de solo 160 bits, mientras que el espacio de claves públicas es de 256 bits.

Dado que ambas derivaciones ( private key > public key > address) son deterministas, no puede derivar más de una dirección de una clave privada. *

Lo que puede hacer es derivar claves privadas adicionales de una "clave privada maestra" con una regla de derivación determinada. Estas claves privadas adicionales obviamente corresponden a nuevas direcciones. Este tipo de gestión de direcciones se denomina "cartera determinista jerárquica".

*Estrictamente hablando, puede crear varias direcciones diferenciando entre claves comprimidas y sin comprimir. Vea las respuestas de Sven y skaht para más detalles.

Con Bitcoin, una única clave privada tendrá asociados pares de claves privadas/públicas comprimidas y sin comprimir . Las direcciones de clave pública sin comprimir son más grandes que las direcciones públicas comprimidas más nuevas. (Contraste 1b y 2b a continuación). Las claves públicas sin comprimir y comprimidas tendrán diferentes direcciones de Bitcoin asociadas. Las claves privadas codificadas en formato de entrada de billetera (WIF) se comunicarán implícitamente con una billetera caliente si se van a usar claves sin comprimir o comprimidas. Una Blockchain registra los fondos enviados a cualquier dirección sin comprimir o comprimidos de forma independiente.

Aquí hay ejemplos ilustrativos que usan la interfaz de línea de comando bitcoin-explorer ( bx ) de libbitcoin que usa una de las peores claves privadas codificadas hexadecimales del mundo que obviamente tiene una longitud de 256 bits.0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff

1a) Clave privada sin comprimir con codificación WIF:

% echo "0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff" | bx base58check-encode -v 128

5HpHb4pzVWwsDAHNwwUS3VViCkwzcutaSJ57T4GNFw5UBNLSrRV

1b) Clave pública sin comprimir:

% echo "0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff" | bx ec-to-public -u

040d47568a5e517067a2836c3823fbc58169a7662bfae934a4d41da3e23c98d816e7202dd702ffe038147f78aee4973a581972960a1460312ffb6f3f0f13d4a52c

1c) Dirección pública sin comprimir:

% echo "0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff" | bx ec-to-public -u | bx ec-a-dirección -v 0

1NGoV1EGZrwM7yvUYqRC7TMBMj7ftpjR2B

2a) Clave privada comprimida con codificación WIF:

% echo "00001111222233334444455556666777788889999aaaabbbbccccddddeeeeffff01" | bx base58check-encode -v 128

KwDiDMtpksBAcfyHsVS5XzmirtyjKWSeaeM9U1QppugixMUeKMqp

2b) Clave pública comprimida:

% echo "0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff" | bx ec-to-public

020d47568a5e517067a2836c3823fbc58169a7662bfae934a4d41da3e23c98d816

2c) Dirección Pública Comprimida:

% echo "0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff" | bx ec-a-público | bx ec-a-dirección -v 0

1PbStXjfDNBU6FZA2iSeisVWwCFN9GK1eQ <- Ningún bot fue lo suficientemente rápido aquí para interceptar mi experimentación

Siempre que intente explicar Bitcoin a alguien, tiene mucho sentido simplemente afirmar que la derivación private key > public key > addresses determinista. Sin embargo, si está interesado en escribir su propio código o estudiar la base de código existente de varias bibliotecas, es posible que desee saber que una clave privada en realidad puede generar dos claves públicas (una en forma comprimida y otra sin comprimir), ambas siendo codificaciones del mismo punto en elsecp256k1curva elíptica pero que conduce a dos valores hash diferentes. Por lo tanto, tenemos dos valores hash posibles y cada valor hash puede, a su vez, conducir a dos direcciones diferentes (pago a hash de clave pública) (una para la red principal de bitcoin y otra para la red de prueba). Entonces, en general (desde la perspectiva de un desarrollador en lugar de un mero usuario de Bitcoin), una clave privada puede conducir a 4 direcciones posibles. Adjunto un javafragmento:

import java.math.BigInteger;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.Address;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.TestNet3Params;

public class Test {

  public static void main(String[] args){

  // An example of private key from the book 'Mastering Bitcoin'
  String k = "1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD";

  // Converting our string encoding as an actual number
  BigInteger priv = new BigInteger(k,16);

  // Creating a key object from our private key, with compressed public key
  ECKey k1 = ECKey.fromPrivate(priv, true);

  // Creating a key object from our private key, with uncompressed public key
  ECKey k2 = ECKey.fromPrivate(priv, false);


  // 03f028892bad7ed57d2fb57bf33081d5cfcf6f9ed3d3d7f159c2e2fff579dc341a
  System.out.println(k1.getPublicKeyAsHex()); // compressed

  // 04f028892bad7ed57d2fb57bf33081d5cfcf6f9ed3d3d7f159c2e2fff579dc341a...
  //...07cf33da18bd734c600b96a72bbc4749d5141c90ec8ac328ae52ddfe2e505bdb
  System.out.println(k2.getPublicKeyAsHex()); // uncompressed

  NetworkParameters main = MainNetParams.get();   // main bitcoin network
  NetworkParameters test = TestNet3Params.get();  // test bitcoin network

  Address addr1 = k1.toAddress(main); // main network, compressed
  Address addr2 = k1.toAddress(test); // test network, compressed
  Address addr3 = k2.toAddress(main); // main network, uncompressed
  Address addr4 = k2.toAddress(test); // test network, uncompressed

  System.out.println(addr1.toString()); // 1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy
  System.out.println(addr2.toString()); // mxdivjAqQSQj4LrAMX1XLQidyfU3pCWeS7
  System.out.println(addr3.toString()); // 1424C2F4bC9JidNjjTUZCbUxv6Sa1Mt62x
  System.out.println(addr4.toString()); // miY1V5L3QDaZVjrMT2Sw2WhHn63GzsNFQB

  }
}
Para aclarar su declaración, una clave privada puede conducir a 4 direcciones, 2 que son válidas en la red de prueba y 2 que son válidas en la red en vivo

Puede generar un número ilimitado de direcciones a partir de la misma clave privada. La clave privada es simplemente un número. a partir del cual puede generar claves públicas comprimidas y sin comprimir. a partir de las claves públicas, puede generar direcciones para cada red (prueba, principal, registro) para diferentes tipos de altcoins cambiando el byte de la red.

Por ilimitado, me refiero a cada uno (altcoin, compresión, red) que hay.
-1 Si bien eso es cierto, no es lo que se pregunta aquí.