¿Qué es una clave Bitcoin comprimida?

El cliente estándar de Bitcoin en la versión 0.6 aparentemente introduce claves comprimidas.

¿Qué son? ¿Hay algún inconveniente en usarlos? ¿Alguna incompatibilidad con software antiguo? ¿Reducciones en la fuerza criptográfica?

Respuestas (4)

Una clave comprimida es solo una forma de almacenar una clave pública en menos bytes (33 en lugar de 65). No hay problemas de compatibilidad o seguridad porque son precisamente las mismas claves, solo que se almacenan de una manera diferente. El software original de Bitcoin no usaba claves comprimidas solo porque su uso estaba mal documentado en OpenSSL. No tienen ninguna desventaja aparte de que se necesita un poco de cálculo adicional antes de que puedan usarse para validar una firma.

Si piensa en una clave pública como un punto en algún lugar a lo largo de una letra U gigante, una clave sin comprimir son las coordenadas x e y del punto. Una clave comprimida es qué tan alto en la U está el punto junto con un solo bit que indica si está en el lado izquierdo o derecho. Como puede visualizar, ambos codifican exactamente lo mismo, pero la forma comprimida requiere la mitad de espacio más un bit. (Por supuesto, en realidad son puntos en la curva elíptica secp256k1 , pero el concepto es el mismo).

Entonces, si el software anterior encuentra una clave comprimida (¿cómo sucedería eso? ¿En wallet.dat? ¿En la cadena de bloques? ¿En una transmisión de transacción?) ¿Puede manejarlo?
No, no puede. Pero siempre está prohibido intentar leer un wallet.datarchivo con una versión anterior del software. Eso es un descanso permitido. (Aún podría extraer manualmente el caso, descomprimirlo y ponerlo en la forma anterior si fuera necesario. Pero ese tipo de compatibilidad no es compatible. No puede regresar con un archivo de billetera más nuevo a menos que traduzca los datos. )
Para responder a su otra pregunta, solo en el wallet.dat. Las claves comprimidas aún no se admiten en ningún otro lugar porque sería un cambio que rompería el protocolo.
Si esto es solo para wallet.dat, ¿por qué preocuparse por unos pocos bytes? 31 bytes guardados suman un megabyte solo si tienes 33.825 claves.
Los clientes antiguos pueden validar transacciones con claves públicas comprimidas porque Bitcoin envía claves públicas a OpenSSL sin verificar su formato y OpenSSL procesa automáticamente la clave pública según el byte inicial (0x04 para sin comprimir, 0x02/0x03 para comprimido).
La ventaja es principalmente para la cadena de bloques y la red, ya que las transacciones ahora serán un poco más pequeñas. Son 33 bytes en lugar de 65, por cierto.
Entonces, si entiendo correctamente, una sola clave privada siempre está conectada a una sola clave pública representable en dos formatos diferentes, que está conectada a dos direcciones (de si la forma comprimida y sin comprimir de la clave está codificada)? Entonces, alguien puede enviar monedas a cualquier dirección, pero para usar esas monedas necesito usar la versión correcta de la clave pública (¿que el software más nuevo manejará automáticamente y el software anterior no?)
Tengo un problema para entenderlo: tengo una clave privada sin comprimir, la ingreso en bitaddress.org y obtengo dos direcciones públicas: una comprimida y otra sin comprimir. En uno tengo un millón de dólares, en el otro 0. Y ambos provienen de la misma clave privada. ¿Cómo eso tiene sentido?
@Advanced Una única clave privada tiene una única clave pública correspondiente. Pero esa clave pública se puede expresar de dos formas, comprimida y sin comprimir. Cada formulario de clave pública tiene una dirección de Bitcoin correspondiente. Los bitcoins se pueden enviar a direcciones sin tener en cuenta cómo se formó esa dirección.
@DavidSchwartz El enlace a Secp256k1 en su publicación se ha roto. Pero: ¡Qué excelente explicación de cómo se logra esta compresión!
@Qqwy Gracias. Arreglé el enlace para señalar algo que es al menos un poco relevante.

Formato (claves privadas):

  • sin comprimir: 0x80 + [secreto de 32 bytes] + [4 bytes de Hash() de los 33 bytes anteriores], codificado en base58
  • comprimido: 0x80 + [secreto de 32 bytes] + 0x01 + [4 bytes de Hash() 34 bytes anteriores], codificado en base58

caso 1:

  • secreto (hex): 11111111111111111111111111111111111111111111111111111111111111111
  • sin comprimir:
    • secreto (base58): 5HwoXVkHoRM8sL2KmNRS217n1g8mPPBomrY7yehCuXC1115WWsh
    • clave pública (hexadecimal): 044f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa385b6b1b8ead809ca67454d9683fcf2ba03456d6fe2c4abe2b07f0fbdbb2f1c1
    • dirección (base58): 1MsHWS1BnwMc3tLE8G35UXsS58fKipzB7a
  • comprimido:
    • secreto (base58): KwntMbt59tTsj8xqpqYqRRWufyjGunvhSyeMo3NTYpFYzZbXJ5Hp
    • clave pública (hexadecimal): 034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa
    • dirección (base58): 1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9

Obtenido de la lista de correo de desarrolladores de Bitcoin:

Esta respuesta es diferente de la anterior, donde está el primer byte de comprimido/sin comprimir (0x04 para sin comprimir, 0x02/0x03 para comprimido)
Parece que esta respuesta se refiere al formato de importación/exportación de claves específico de bitcoin, frente al uso de claves comprimidas en sí, es decir, en OpenSSL. Espero que esto ayude a los futuros lectores a contrastar las dos respuestas aquí.
La cita es bastante engañosa. Dado que es una cita, probablemente no debería editarse, pero "4 bytes de Hash () de los […] bytes anteriores" debería haber sido "4 bytes de Hash (Hash ()) de los [...] bytes anteriores". La función hash se aplica dos veces.
@Akater hash aplicado dos veces sigue siendo un hash. Como no dice a qué función Hash()corresponde, la cita es correcta. No sé qué función se usa, así que tal vez, por ejemplo,Hash(x) = SHA256(SHA256(x))

Puede ayudar separar los campos.

04
4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa
385b6b1b8ead809ca67454d9683fcf2ba03456d6fe2c4abe2b07f0fbdbb2f1c1

03 [podría ser 02]
4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa
[el valor descartado se puede calcular a partir del valor anterior]

Hay más detalles omitidos arriba. El 03 puede ser 02 porque el valor descartado tiene que derivarse del valor preservado y se necesita un poco más de información. Eso se debe a que hay dos raíces [más y menos] al sacar una raíz cuadrada.

una buena explicación está disponible en ¿Cómo puedo probar si una dirección de bitcoin está comprimida o no?

Más específicamente, una clave pública en Bitcoin es un par de números enteros (x,y). Para las claves públicas sin comprimir, estos enteros se codifican como enteros big-endian sin firmar de 256 bits, se concatenan y luego se anteponen con un solo byte 0x04. El resultado tiene una longitud de 65 bytes.

Para claves públicas comprimidas, solo se codifica la coordenada x (como arriba, como int big-endian sin firmar de 256 bits). Resulta que la coordenada y solo puede ser uno de dos valores, uno par y otro impar. En lugar de anteponer un solo byte 0x04, se antepone un solo byte 0x02 o 0x03 según el valor de y (0x02 para par, 0x03 para impar). El resultado tiene una longitud de 33 bytes.

es 0x02 para y > 0 y 0x03 para y < 0
@CiscoMmu, ¿cómo saber si y > 0 o < 0?
En el gráfico EC, tiene 2 puntos en la coordenada y (+ve y -ve) por cada punto en la coordenada x.