Codificación ECDSA r, s como firma

Un algoritmo ECDSA al firmar un mensaje dado produce un par de salidas, r y s . ¿Cómo, dado un sigStr de un Tx, se puede extraer r y s? ¿Son solo matrices de bytes concatenadas de una longitud específica, o hay más?

Respuestas (2)

Si lo desea, puede pagar $100 por el estándar, ANSI X9.62 . O bien, puede hacer trampa y consultar RFC3278, sección 8.2 . Está en formato DER y consta de una SECUENCIA de dos ENTEROS. El primer ENTERO es r, el segundo s.

Si observa esta transacción , puede ver que una de las firmas es:

3045 0220
316eb3cad8b66fcf1494a6e6f9542c3555addbf337f04b62bf4758483fdc881d
022100
bf46d26cef45d998a2cb5d2d0b8342d70973bc3c37ae72624b01

Si analizamos eso como DER, obtenemos:

 0:d=0  hl=2 l= 69 cons: SEQUENCE          
 2:d=1  hl=2 l= 32 prim: INTEGER :316EB3CAD8B66FCF1494A6E6F9542C3555ADDBF337F04B62BF4758483FDC881D
36:d=1  hl=2 l= 33 prim: INTEGER :BF46D26CEF45D998A2CB5D2D0B8342D70973FA7C3C37AE72234696524B2BC812

También puede echar un vistazo al código fuente de OpenSSL, archivo ecdsa/ecs_asn1.c:

ASN1_SEQUENCE(ECDSA_SIG) = {
        ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
        ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
} ASN1_SEQUENCE_END(ECDSA_SIG)
Hmm, logré codificar y decodificar los dos enteros, pero parece que a mi codificación le falta el byte 01 al final. ¿Alguna idea de por qué podría ser así? Usé el formulario de código aquí: stackoverflow.com/questions/8693513/…
De hecho, no tengo idea de qué está haciendo ese 01 allí. Intentaré averiguar y actualizar mi respuesta.
01 es SIGHASH_ALL, utilizado por OP_CHECKSIG para decidir cómo cifrar la transacción que se está firmando.

R y S son visibles en cada una de las entradas tx. Puedes verlos ya extraídos en este sitio. También proporciono el valor Z.

https://2xoin.com/tx/711b6457b4b2b51e56b94ab541a75d02908648a9de26a3c0ce5b2c3b10573d4e

Consulte la especificación del protocolo bitcoin para obtener más información sobre el orden de los bytes. https://en.bitcoin.it/wiki/Protocol_specification#tx

A continuación se muestra un ejemplo de una entrada hexadecimal de TX,

4830450220657912a72d3ac8169fe8eaecd5ab401c94fc9981717e3e6dd4971889f785790c022100ed3bf3456eb76677fd899c8ccd1cc6d1ebc631b94c42f7c4578f28590d651c6e0141049b5506df53ff5eff7dc553131043bb993f55d2b0fddd866984f593777023c8226920ff05747ccb963f0fe459cb217d502e57dcf8afec786c3dcee4d1558f85fa

Ahora separados para que sea más fácil de leer,

48

3045

0220 (El Hex 20 dice que los siguientes 32 bytes son el valor R)

657912a72d3ac8169fe8eaecd5ab401c94fc9981717e3e6dd4971889f785790c

0221 (El 21 hexadecimal dice que los siguientes 33 bytes son el valor S)

00ed3bf3456eb76677fd899c8ccd1cc6d1ebc631b94c42f7c4578f28590d651c6e

0141 (El 41 hexadecimal dice que los siguientes 65 bytes son la clave pública)

049b5506df53ff5eff7dc553131043bb993f55d2b0fddd866984f593777023c8226920ff05747ccb963f0fe459cb217d502e57dcf8afec786c3dcee4d1558f85fa