Contexto: estoy creando un código de ejemplo que demostraría un intercambio atómico entre Elements y Bitcoin, con el objetivo de que las transacciones de intercambio no se puedan vincular de manera trivial, como lo sería con HTLC simple, donde puede buscar el mismo hash/ preimagen en ambas cadenas. Esto se debe a que la clave para revelar es en realidad una suma de claves, (A+B), y para reclamar el otro lado del intercambio, se usa otra clave de suma, (A+C). A, B y C solo son conocidos por (uno o ambos) participantes.
Uso CHECKSIGFROMSTACK en el lado de Elements para obligar a la contraparte a crear una firma con un valor R fijo (la k sería conocida y, por lo tanto, la otra parte puede recuperar la clave)
Me señalaron https://bitcointalk.org/index.php?topic=321228.msg13072047#msg13072047 , donde gmaxwell dice que puede lograr el mismo efecto forzando la divulgación de la clave privada en Bitcoin sin modificar.
Dice que conoce dos formas de lograr esto en Bitcoin sin modificar, una de ellas es:
OP_SIZE 57 OP_LESSTHANOREQUAL OP_VERIFY <P> OP_CHECKSIGVERIFY
Mis preguntas:
en el script mencionado anteriormente, se fuerza que la firma tenga una longitud menor o igual a 57. Esto parece depender de un valor R pequeño conocido, y la suposición de que otros valores R de igual o menor tamaño para algún k conocido no es computacionalmente posible encontrar.
en esta publicación https://crypto.stackexchange.com/questions/60420/what-does-the-special-form-of-the-base-point-of-secp256k1-allow se proporciona un valor R con 90 bits cero iniciales . S tendría que tener un tamaño <= 29 bytes con una longitud R de 21 bytes (166 bits), para que la firma se ajuste al límite de 57 bytes (29+21+6+1=57). Para cumplir con este script utilizando esta pequeña R conocida, el creador de la firma necesitaría buscar el mensaje para firmar que daría como resultado una firma con len(S) <= 29. ¿Se eligió este límite estricto para reducir el 'margen de maniobra'? para fuerza bruta R ?
¿Cuál es el segundo método para lograr esto en Bitcoin sin modificar?
Si estos métodos funcionan, ¿por qué no se han utilizado ampliamente en lugar de las construcciones HTLC, dado que estos métodos (o al menos el presentado) no son mucho más complejos en cuanto a la implementación, pero son más privados (porque no hay un hash público compartido)? /preimagen) ? ¿Cuáles son las desventajas de estos métodos, en comparación con HTLC?
(Nota: las preguntas anteriores son más por curiosidad intelectual que por un propósito práctico concreto, porque cuando las firmas de Schnorr se habilitarán en Bitcoin (espero que no sea demasiado largo), las firmas del adaptador https://github.com/apoelstra /scriptless-scripts/blob/master/md/atomic-swap.md sería una forma mucho mejor de crear intercambios atómicos sin un enlace trivial entre transacciones)
Hice algunas búsquedas e investigaciones, y también obtuve información sobre el canal #elements en bitcoincore slack, así que siento que puedo responderlas ahora (EDITAR: al principio me confundí con el método CODESEPARATOR, pero después de un tiempo más, preguntó Anthony Towns y proporcionó los enlaces a sus mensajes en la lista de desarrolladores de iluminación para explicarlo).
Creo que el tamaño 57 se elige para una mayor garantía contra la posibilidad de que se encuentre otro valor R de tamaño pequeño, que es mayor que 21 bytes, pero lo suficientemente pequeño como para que la molienda para S más pequeña pueda permitir superar el límite de tamaño. También vi otro ejemplo de cómo se podría usar esta técnica ( https://gist.github.com/nothingmuch/683042343c48a4ef07efd3d438e7ee56 ), pero establece 60 para el límite de tamaño. Podría estar asumiendo que el valor R que comienza con 72 bits cero tampoco es factible de encontrar. También puede ser que el límite de 57 bytes sea innecesariamente pequeño. Tenga en cuenta que la molienda para len (S) <= 29 es factible en una computadora de propósito general. Esto podría hacerse cambiando otras entradas/salidas de la transacción para que sighash cambie. Importante:https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000344.html
La segunda forma de lograr esto en bitcoin sin modificar de alguna manera puede implicar el uso de OP_CODESEPARATOR. Habría dos firmas de una clave pública, pero la segunda firma usaría un sighash diferente porque esta firma se verifica después de ejecutar CODESEPARATOR, y sighash se calculará usando solo la parte del script después de CODESEPARATOR. Pero si bien puede tener dos firmas diferentes (en mensajes diferentes) para una clave pública, no me queda claro cómo forzar la reutilización de nonce aquí, si no con el mismo truco de tamaño que se describió anteriormente, o usando los códigos de operación deshabilitados.
EDITAR: Le pregunté a Anthony Towns sobre esto, obtuve una respuesta. Hay una técnica que usa dos separadores de código y tres checkmultisigs, de tal manera que fuerza la reutilización de R. Ver https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000344.html y https:// Lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000363.html
Otros enlaces relevantes: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-December/016594.html https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-December/016592.html Mis guiones experimentales: https://gist.github.com/dgpv/7818a4009f4e90868c0920cc1e238653
Tenga en cuenta que CODESEPARATOR no es estándar para entradas sin segwit en Bitcoin, pero debería estar bien para entradas con segwit. Pero aún no sin cierta controversia: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-March/016732.html (hubo una propuesta para eliminar CODESEPARATOR por completo, o calcular sighash siempre usando el script inicial, sin tener en cuenta efectos de CODESEPARATOR)
HTLC es más simple de implementar, y el programa que crea HTLC no necesita poder trabajar con bignums, además de tener la función que implementa modular inverse en bignums. Los HTLC también serían generalmente de menor tamaño. También son más "conocidos" y, por lo tanto, populares.
Dmitri Petujov