Comprobación de firma solo frente a P2PKH

Me queda claro por qué es potencialmente inseguro usar solo un control en == en scriptPubKey. Por un lado, no verificar una firma en el script de canje significa que alguien podría hacerse pasar por el redentor. De la guía para desarrolladores de Bitcoin :

Esto permite que el script pubkey verifique que Bob posee la clave privada que creó la clave pública.

La firma secp256k1 de Bob no solo prueba que Bob controla su clave privada; también hace que las partes de su transacción que no son de firma sean a prueba de manipulaciones para que Bob pueda transmitirlas de manera segura a través de la red de igual a igual.

¿Por qué no sería seguro usar solo una verificación en V(sigA, pkA, m={txprev_txid, txprev_outid, txprev_scriptPK, tx_scriptPubKey, tx_amount}_skA) == 1? Parece que esto es lo que estamos haciendo en multisig. Es decir, tenga un ScriptSig que consista solo en (una) firma (s) en lugar de firma y pk como en P2PKH.

¿Por qué no verificamos las firmas en lugar de verificar tanto pkhash como una firma?

Respuestas (2)

Vamos a empezar desde el principio.

p2pk

Si observa los bloques iniciales en la cadena, notará que la salida de la transacción de la base de monedas va a un script de bloqueo de clave pública (también conocido como salida o gravamen)

Un script de bloqueo p2pk es simplemente PUSH <pubkey> OP_CHECKSIG. Para gastar esta salida, uno simplemente necesita proporcionar una firma válida. El scriptsig contendría PUSH sig, que cuando se combina con el script de bloqueo produce PUSH sig PUSH <pubkey> OP_CHECKSIG. Si la firma proporcionada es válida para la clave pública dada, puede demostrar tanto la propiedad de las monedas como la intención de gastarlas en un solo movimiento.

p2pkh

p2pk fue reemplazado (quizás no sea el término correcto, ya que Bitcoin 0.1 contenía soporte tanto para p2pk como para p2pkh) por pay-to-pubkey-hash. Esto tiene un par de ventajas sobre el p2pk de vainilla. Por un lado, redujo el tamaño del script de bloqueo. Dado que el conjunto utxo debe contener el script de bloqueo para fines de validación, esto genera un ahorro de espacio directo. Por otro lado, el hash de la clave pública agrega una capa de protección contra cualquier ataque futuro de recuperación de clave ecdsa que pueda desarrollarse, ya que también necesitaría romper la operación HASH160 para recuperar la clave pública primero.

El uso de p2pkh conlleva cierta complejidad adicional. El script de bloqueo ahora toma la forma de OP_DUP OP_HASH160 PUSH <PubkeyHash> OP_EQUALVERIFY OP_CHECKSIG. Dado que ya no tenemos la clave pública real en el script, un script de desbloqueo debe probar dos cosas:

  1. Que tiene la clave privada correcta
  2. Que pretende gastar las monedas

Para 1, debemos demostrar que el hash de clave pública en el script corresponde al hash de clave pública de la clave utilizada para realizar la firma. Para 2, debemos verificar que la firma sea válida contra esa clave pública.

Para lograr esto, el script de desbloqueo toma la forma PUSH sig PUSH pubkey. Cuando se combina con el script de bloqueo, esto producePUSH sig PUSH pubkey OP_DUP OP_HASH160 PUSH <PubkeyHash> OP_EQUALVERIFY OP_CHECKSIG

Ahora, durante la evaluación, la clave pública se duplica. El duplicado se codifica y se compara con el hash almacenado en el script de bloqueo. Si el hash es válido, la firma se valida con la clave pública proporcionada. Este flujo garantiza que se utilice la misma clave pública para la verificación de firma y la comparación con el hash en el script de bloqueo, cumpliendo así ambos requisitos.

p2sh

pay-to-script-hash fue desarrollado para proporcionar una forma estandarizada de usar scripts de bitcoin más avanzados. Para este ejemplo, centrémonos en multisig p2sh. Un típico script de bloqueo de salida de 1 de 2 multisig p2sh será similar a OP_HASH160 PUSH <hash> OP_EQUAL. Esto no contiene ninguna clave pública, ni siquiera un código de operación de verificación de firma, entonces, ¿qué está pasando aquí?

El secreto está en el script de canje. Cada dirección p2sh está respaldada por un script de canje, y el hashvalor en el script de bloqueo es un hash de este script de canje.

Al gastar desde una dirección p2sh, debe proporcionar una secuencia de comandos de desbloqueo que se valide con la secuencia de comandos de canje y la secuencia de comandos de canje en sí. Para nuestra dirección multisig 1of2, un script de canje parece OP_1 PUSH pubkey1 PUSH pubkey2 OP_2 OP_CHECKMULTISIG. Esta secuencia de comandos completa está codificada para la secuencia de comandos de bloqueo. Tenga en cuenta que dado que las claves públicas contenidas en este script ya están codificadas como parte de todo el script de canje, no es necesario codificarlas por separado, como lo hacemos con p2pkh.

Al gastar la salida, proporcionaríamos: OP_0 PUSH sig PUSH redeemscript. Esto da como resultado un script final de OP_0 PUSH sig PUSH redeemscript OP_HASH160 PUSH <hash> OP_EQUAL. Durante la evaluación:

  1. El script de desbloqueo y el script de bloqueo se combinan. Esto da como resultado que las firmas y el script de redención serializado se envíen a la pila. Tenga en cuenta que dado que PUSH redeemscripttrata el script de canje como datos normales, los códigos de operación dentro del script de canje no se interpretan como códigos de operación en este paso.
  2. El script de canje serializado se codifica y valida con el script de bloqueo
  3. Las firmas se validan con la pila extraída, que contiene el script de canje serializado sin su código push op y, por lo tanto, lo interpreta correctamente como un script de bitcoin.

Seguir este orden de operaciones brinda la misma garantía que la salida p2pkh: que la transacción tiene la intención de gastar las monedas y que las claves involucradas son las mismas claves que se comprometieron durante el bloqueo de las monedas.

En una entrada que gasta una salida P2PKH, si solo verificara que la firma es una firma válida con la clave pública en la entrada, entonces un atacante podría usar su propia clave pública y producir una firma válida y, por lo tanto, una transacción válida bajo este modelo. La clave pública no se recupera del script de salida ni la proporciona la salida; más bien se proporciona en la entrada. Por lo tanto, debe asegurarse de que la clave pública proporcionada sea de hecho la clave pública correcta, por lo tanto, verifique que su hash coincida con el hash proporcionado en la salida.

En multisig, las claves públicas se proporcionan en la entrada, además de las firmas. Están en el script redimido. Para evitar los mismos problemas (que el atacante proporcione sus propias claves públicas), el script de redimir tiene un hash y el hash está en el script de salida. Hay una comparación allí para garantizar que el script de redimir sea el script correcto.

Hay un tipo de salida en el que solo proporciona una firma. Este tipo de salida es una secuencia de comandos en la que la clave pública se encuentra en la salida, por lo que no es necesario proporcionar la clave pública en la entrada. Solo se necesita la firma. Esto se conoce como salida Pay to Pubkey (P2PK). Estos no se usan mucho porque las claves públicas son grandes y esto hace que sea más difícil darlas.

Veo. Creo que me confundió la Guía para desarrolladores de Bitcoin . Entiendo que P2SH multisig tiene los pk en la entrada de redimirScript. Esta sección me confundió, lo que hace que parezca que scriptSig solo contiene firmas: Pubkey script: <m> <A pubkey> [B pubkey] [C pubkey...] <n> OP_CHECKMULTISIG; Script de firma: OP_0 <A sig> [B sig] [C sig...]. ¿Significa esto que este scriptPK y scriptSig no se utilizan realmente en la práctica? ¿Pero más bien el multisig P2SH?
En la práctica se utiliza P2SH multisig. Tener el multisig en la salida (conocido como bare multisig) casi nunca se ha usado.