¿Cómo se generan las PubKeys comprimidas?

Solo lea esto: https://bitcoin.stackexchange.com/a/1715/

¿Cuál es el proceso para generar claves de publicación comprimidas a través de ECDSA?

interesado en escuchar las respuestas: pensé que privkey y pubkey solo estaban vinculados a través de ECDSA. Ambos son simplemente números hexadecimales... (de puntos en la curva tralala). Y usando la clave privada codificada en base58, va a la clave privada WIF. Agregué un "01" hexadecimal adicional antes de codificar, tengo una clave privada WIF-c (comprimida), de la cual obtengo una clave pública comprimida. Esperando las respuestas...

Respuestas (2)

No existe ningún algoritmo para generar claves públicas comprimidas específicamente a partir de claves de claves privadas. De hecho, todos los cálculos internos que involucran puntos se realizan usando las coordenadas x y de los puntos involucrados. yNo hay otra forma de operar en los puntos que no sea usando las (x,y)coordenadas. Una representación comprimida del punto es útil en la transmisión y el almacenamiento de datos porque solo se necesitan 33 bytes en lugar de 65 bytes para transmitir el punto. Es muy fácil pasar de compressed -> uncompressedcuando surge la necesidad de realizar operaciones relacionadas con puntos, y aún más fácil pasar de la uncompressed -> compressedrepresentación. Para responder a su pregunta, generaría la clave pública como lo haría normalmente con una clave pública sin comprimir, y cuando haya terminado, busque la paridad o imparidad de laycoordinado Si es par, codifica solo la xcoordenada con un 0x02byte de prefijo, y si es impar, el prefijo es 0x03. Para volver desde compressed -> uncompressed(realmente solo me refiero a encontrar la ycoordenada original), simplemente resolvería la ecuación de la curva:

y^2 = x^3 + a*x + b

Específicamente para secp256k1, la curva utilizada en Bitcoin aes cero, lo que facilita este cálculo, y hay un atajo: debido a una propiedad del parámetro de la curva p, donde p ≡ 3 mod 4podemos derivar la ycoordenada de una xcoordenada simplemente calculando:

q = (p+1) * invmod(4)  mod p
y = powmod(y^2,q)      mod p

Y ahí tenemos de yvuelta la coordenada original.

"Se necesitan 33 bytes en lugar de 65 bytes para transmitir el punto": ¿incluye los prefijos para los cálculos de puntos?
El prefijo solo lo usa el software para leer y escribir el punto como datos. Le indica al software qué tipo de clave se está leyendo y, si es una clave comprimida, cuál de las dos posibles ycoordenadas debe elegir al descomprimir el punto.

con un poco de ayuda de arubi, llegué a hacer este dibujo. La parte azul es la lógica ECDSA. Las claves WIF y las claves privadas están vinculadas a través de la codificación/descodificación base58check. Dependiendo de cómo proporcione la clave privada (comprimida o sin comprimir), el software decide cómo crear la clave pública y la dirección de bitcoin. Obviamente, la dirección de bitcoin diferirá para las claves comprimidas/sin comprimir. Con las claves sin comprimir, tiene la clave pub de 512 bits con los componentes x/y, mientras que la clave pub comprimida se puede representar solo como el componente x. El software agregaría el prefijo 04 para sin comprimir, o 02 (si es par) o 03 (si es impar), y lo usaría como entrada para sha256/ripemd160 para crear el hash de clave pública. Con el último paso, nuevamente hay codificación base58check, con una suma de verificación involucrada.

privkey - ECDSA - dirección bitcoin

Ejemplo (red de prueba):

privkey Hex:   18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725
privkey WIF:   91msh178DnLBqFhbuYqazuUwWpKBkRQvgj8bggdWMp81nVp9PfM
privkey WIF-c: cNR4jZU2sR5goytD4wXT4aeKcbqGSekbxLxY69v8aryxTU1SMnJZ

pubkey hexadecimal sin comprimir (04 + x + y):

04 50863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B2352 2CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6

pubkey hexadecimal comprimido (02 + x, y=par):

02 50863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B2352

direcciones de bitcoin correspondientes:

  (pubkey uncompressed): mfcSEPR8EkJrpX91YkTJ9iscdAzppJrG9j
  (pubkey compressed):   n3svudhm7bt6j3nTT9uu1A57Cs9pKK3iXW
¡Buen diagrama! Para completar, hay otro tipo de clave pública válida además de comprimida y sin comprimir, que se llama 'Híbrida'. Codifica las coordenadas xy y, y su longitud es de 1 + 64 bytes (como una clave pública sin comprimir), pero el byte de prefijo podría ser 0x07o 0x06.
Básicamente, la uniformidad o imparidad del byte de prefijo sugiere la uniformidad o imparidad de la ycoordenada codificada en la clave. No creo que se haya usado nunca una clave híbrida en la red principal, pero aun así es una clave pública válida y puede aparecer en un script. No hay codificación WIF de una clave privada híbrida, pero cualquiera podría firmar y canjear un script p2pkh usando dicha clave, y no lo sabríamos hasta que se transmita para gastar. Al incorporarlo a su diagrama, la clave pública sería una entrada para el tercer paso.
Nunca he oído hablar de estas claves híbridas, solo me pregunto qué sucede con la clave privada en representación hexadecimal. ¿Algún enlace que conozcas? Por supuesto que quiero probarlo en testnet/regtest. Por cierto: un diagrama similar estaba en el famoso " righto.com/2014/02/bitcoins-hard-way-using-raw-bitcoin.html " de Ken Shirriff. Simplemente fue en sentido contrario a las agujas del reloj, y en contra de la intuición para mí :-). Lo aplané y agregué la lógica comprimida.
La clave privada como un número en hexadecimal es exactamente lo mismo. No hay una interfaz para ninguna billetera que pueda manejar claves híbridas, hasta donde yo sé, por lo que tendría que construir la transacción sin procesar usted mismo. Debería ser lo mismo que gastar cualquier otro script que contenga un checksig. Además, no sé si incluso la política testnet\regtest de nodos permitirá tal gasto. Es posible que deba modificar la política en su propio nodo y extraerla usted mismo.