Taproot
Oradores: Pieter Wuille
Fecha: June 6, 2019
Transcripción De: Bryan Bishop
Traducción Por: Blue Moon
Tags: Taproot, P2c, Quantum resistance
https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki
https://gnusha.org/url/https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-May/016914.html
https://bitcoinmagazine.com/articles/taproot-coming-what-it-and-how-it-will-benefit-bitcoin/
Previamente: http://diyhpl.us/wiki/transcripts/bitcoin-core-dev-tech/2018-03-06-taproot-graftroot-etc/
https://twitter.com/kanzure/status/1136616356827283456
Introducción
Bien, primera pregunta: ¿quién puso mi nombre en esa lista y qué quieren? No fui yo. Voy a hacer preguntas. Puedo hacer un resumen, pero ya se ha hablado mucho y no sé en qué centrarme. ¿Qué le gustaría a sipa que revisáramos en particular al respecto? ¿Qué decisiones de diseño le inspiran menos confianza? ¿Hay algo en lo que le gustaría que otras personas investigaran las decisiones de diseño antes de seguir adelante?
Visión general de Taproot
Permítanme hacer una lista de todas las cosas que se incluyen en bip-taproot. ¿Debo hacer también un breve resumen de cuál es la idea general de taproot? ¿Es ya bien conocida? Vale, cinco minutos de resumen de taproot. Bien, ¿dónde está roasbeef? Esto es difícil, saber por dónde empezar. Empecemos con la suposición de taproot. Es un buen comienzo.
La historia antes de taproot es que hemos tenido p2sh donde movimos el código real del script no lo ponemos en la salida, sólo se revela en la entrada y te comprometes a ello antes de tiempo. La gente se dio cuenta de que se podía hacer esto recursivamente. En lugar de simplemente hacer un hash del script, hazlo un árbol merkle de múltiples scripts, comprométete sólo con la raíz merkle y luego revela sólo la parte del script que vas a usar, bajo la suposición de que vas a dividir tu script en una colección de declaraciones disyuntivas. Sólo revelas un número de ramas a escala logarítmica. Así que puedes tener una raíz al árbol del script, luego scripts aquí y scripts aquí. Así que hay un poco de mejora en la escala de esto y también un poco de privacidad porque sólo estás revelando las partes que estás usando.
Pago por contrato
Greg Maxwell y andytoshi se dio cuenta en un lugar de desayuno en Mountain View mientras yo estaba en el baño era que hay una función llamada la función de pago a contrato que toma como entrada un punto de curva elíptica o clave pública y una secuencia de comandos, que se define como la clave pública más el hash de la clave pública y S … es un compromiso criptográfico. Nadie más, conociendo P y S, no puede encontrar el mismo valor de salida. Es un valor hash raro, pero tiene todas las propiedades de una función hash. En segundo lugar, tiene la propiedad de que si conoces la clave privada de esta clave pública P, entonces también conoces la clave privada de la salida de esta función si también conoces S. Lo que puedes hacer con esto es decir, bueno, vamos a utilizar este árbol de Merkle todavía, pero vamos a añadir un nivel especial en la parte superior de la misma donde tienes P aquí y haces este pago por contrato de esas dos cosas en su lugar. Ahora podemos tener reglas de consenso que le permiten gastar de dos maneras diferentes. Una forma es, pago por contrato es un punto de curva elíptica, es una clave pública. Así que podrías firmar directamente con esa clave pública, lo que puedes hacer si conoces la clave privada. Es como tomar la rama correcta, pero es una rama especial y no tienes que revelar que había otra rama o cualquier ramificación en absoluto. O revelas P más una rama que lleva a uno de los scripts y puedes verificar que esta cosa se compromete con él. Esta es la ruta de gasto de la clave, y estas son las rutas de gasto de los scripts. Revelas la clave pública. Cuando gastas a través del script, revelas la clave pública más la ruta merkle y nada más. Es la clave pública interna. Hay una clave pública de salida, y luego esta es la clave pública interna. Solo revelas la publica intenral cuando gastas usando un script. Cuando gastas usando la clave pública interna, en realidad estás gastando con la clave pública de salida, pero es una versión modificada de la interna.
Suposición Taproot
Lo que estamos llamando la suposición taproot es que, cualquier tipo de construcción de script más complejo en bitcoin realmente sólo codifica las condiciones bajo las cuales las monedas pueden ser gastadas. En cualquier tipo de contrato inteligente en la parte superior, es posible añadir una rama que dice «todo el mundo está de acuerdo» o «al menos algunas personas están de acuerdo». Siempre se puede añadir una rama de unanimidad, o un cierto conjunto de personas. Es un script que consiste sólo en claves públicas. Con firmas adaptadoras, puedes hacer algunas cosas todavía. No hay bloqueos hash o timelocks, etc. Gastar usando esto es lo más barato; lo único que va en la blockchain es una clave pública y una firma. No revelas al mundo ni siquiera la existencia de los otros scripts a los que también se les permitió gastar. Incluso cuando gastas utilizando un script, no estás revelando qué otros scripts existían o si existía una clave pública. La suposición es que la mayoría de los gastos en la red pueden ser escritos como aquellos que sólo consisten en claves públicas. Siempre existe la posibilidad de gastar usando un script, pero creemos que si la opción más barata para gastar es una que sólo tenga una clave pública, entonces la gente optimizará sus scripts para que realmente tengan esta clave pública en la rama de unanimidad, y con el argumento de que -nunca hay un problema con tener una rama para cuando todos están de acuerdo- nunca debería haber un problema con eso.
Sin embargo, hay razones por las que puede que no quieras hacer eso, como esperar que todo el mundo esté conectado a la hora de firmar. Espero que sea bastante común, como un multisig dos de tres, tal vez usted elige los dos más- usted espera que casi siempre va a ser A y B a continuación, poner A y B en esta rama y luego poner otra rama que dice A y C, que es menos probable.
¿Cómo voy con mis cinco minutos?¿Por qué no usar firmas de umbral en ese caso específico? Estoy hablando de múltiples claves públicas, pero en taproot sólo hay una. En musig u otros esquemas de agregación de claves donde podemos representar una combinación de múltiples claves, realmente sólo con una única clave pública, y hay- con musig, puedes hacer argumentos de seguridad muy simples y bastante directos en n-de-n multisig. También puedes hacer umbrales no contables como 3-de-5 o cualquier expresión booleana sobre múltiples claves que puedas codificar en una única clave pública. Pero si no es todo el mundo, entonces siempre tienes una configuración interactiva donde los diferentes participantes tienen que compartir secretos entre sí que necesitan almacenar de forma segura y espero que esto sea un obstáculo importante en las implementaciones prácticas. Probablemente no en algo como Lightning, donde ya hay mucha interactividad; pero para la mayoría de las aplicaciones de monedero, esto probablemente no funcionará. Con n-de-n, se puede hacer una configuración no interactiva, pero hay interacción en el momento de la firma.
Todo se convierte en un árbol merkle con esta rama especial en la parte superior que es obligatoria. Dado que es obligatoria y muy barata de usar, es razonable que la gente la optimice.También da uniformidad. Cada salida va a parecer idéntica ahora. Todos son claves públicas o puntos de curva elíptica. No es realmente obligatorio, puedes usar una clave pública inexistente. Es obligatorio poner un punto ahí, pero no necesita ser una clave válida, por supuesto. Eso es un poco de compromiso. Probablemente hay construcciones donde es más eficiente publicar esto sin una clave pública requerida, pero esto rompe la uniformidad y obtienes menos privacidad. Se trata de un compromiso entre una ligera ventaja de escala, o ventaja de ancho de banda en realidad, frente a la privacidad.
La agregación de claves que utilizas no forma parte del consenso; puedes hacer lo que se le ocurra a la gente. Sí, los monederos deciden. El único requisito que tenemos a nivel de consenso es que sea un esquema de firma que permita la agregación fácilmente.Schnorr lo hace mucho más fácilmente que ECDSA, por eso Schnorr está ahí. Sé que la gente dirá que ECDSA de 2 partes es una cosa, pero es un par de órdenes de magnitud más difícil. Llamar a 2p-ECDSA una cosa es fuerte, hay algunos papeles. Tal vez la gente ya está masiva y ampliamente utilizando esto, específicamente bitconner.
¿Lo de pagar por contratar necesita más ojos? Si modelas el hash como un oráculo aleatorio, entonces se deduce trivialmente. El esquema pay-to-contract fue presentado en la conferencia de 2013 en San José por Tim Ohanka. No incluyó la clave pública aquí; lo que hizo que no fuera un compromiso y por lo tanto se rompió trivialmente.
Así que esa es la explicación de por qué incluir ramas merkle, que es que si ya estás haciendo esta estructura de ejecución taproot y firmas Schnorr, entonces las ramas merkle son literalmente tal vez 10 líneas de código de consenso. Hace que los scripts muy grandes escalen logarítmicamente en lugar de linealmente. Una victoria tan obvia, si vas a cambiar la estructura de todos modos.
¿Ha analizado cuánto tendrían los guiones históricos? No, no lo he hecho. He hecho números sobre lo que podemos esperar para varios tipos de construcciones multisiglas. Es difícil de analizar porque probablemente la mayor ventaja estará en la forma en que la gente utilice el sistema de scripts, no tanto en hacer exactamente lo mismo que se podía hacer antes.
Propuesta bip-taproot
En la propuesta, hay un montón de pequeñas y grandes cosas incluidas. Creo que voy a repasarlas. Tratamos de pensar realmente en la extensibilidad sin ir demasiado lejos, y tal vez fuimos demasiado lejos. El razonamiento aquí es que ya es un par de cosas; hay muchas más ideas, incluso sólo acerca de la estructura de ejecución de secuencias de comandos, hay graftroot, g’root, y los mecanismos de delegación que la gente ha pensado. Hay incentivos como ingeniero para tratar de empaquetar todo junto en una propuesta. Una de las razones es bueno, entonces usted puede analizar cómo interactúan todos y usted puede asegurarse de que todas las combinaciones se hacen de la manera más eficiente y que todos ellos son posibles, y también tiene algunas mejoras fungibilidad porque ahora usted no crea docenas de nuevas versiones de secuencias de comandos observables. Creo que tenemos que reconocer que el incentivo existe, y también elegir una compensación por elegir algunas características pero no todo. A medida que aumenta la complejidad de la propuesta, aumenta la dificultad política de convencer al ecosistema de la necesidad de todo. Este campo está evolucionando, así que para algunas cosas quizá sea mejor esperar. Para compensar la falta de un montón de cosas, pensamos en la extensibilidad en términos de asegurarnos de que algunas de las cosas que podemos imaginar al menos no causarían una caída en la eficiencia si se hicieran por separado.
Uno de ellos es que los scripts en la parte inferior del árbol se les da un número de versión, que estamos llamando la versión de la hoja. Realmente la razón para hacer esto fue porque teníamos 5 o 6 bits disponibles en la serialización, en lugar de decir que tienen que ser este valor, si es un número de versión desconocido, entonces es un gasto libre. La diferencia entre este número de versión, y el número de versión testigo que va en la parte superior, es que estos sólo se revelan junto con el script que realmente se ejecuta. Puedes tener un árbol con un montón de satisfacciones y todas están usando viejos y aburridos scripts, y una usa una nueva característica que existe en una versión futura, no vas a decirle a la red que estás haciendo algo con esa nueva versión a menos que reveles ese script. Así que esto te permite planificar futuras actualizaciones con antelación, sin decírselo a nadie ni revelar nada.
Hay algunos cambios en el lenguaje de scripting, como la validación por lotes, que garantiza que las firmas Schnorr y la validación de pago por contrato (p2c) puedan verificarse por lotes.Esto nos da un factor de aceleración de 2-4x al verificar todas las transacciones o un bloque entero o toda la cadena de bloques.Se pueden agregar millones de firmas.La velocidad aumenta sólo logarítmicamente, pero realmente estamos en un caso de uso en el que la validación por lotes es lo que… realmente tenemos millones de firmas, y lo único que nos importa es que todas sean válidas.Asegurarse de que no hay cosas en el sistema de script que romper esa capacidad de verificación por lotes. Por poner un ejemplo de algo no verificable por lotes es OP_CHECKSIGNOT… podrías escribir un script que dependa de dar una firma inválida para una clave privada dada; está permitido en el lenguaje de scripts aunque no se me ocurre por qué querrías eso. Así que tenemos una regla que dice que todas las firmas que pasen deben ser válidas o estar vacías. Esto hace que el checksig falle sin hacer que el script falle; esta es una regla de estandarización actual. Nulldummy es el de checkmultisig, creo que este es nullfail.
Los opcodes ECDSA han desaparecido y se han sustituido por opcodes Schnorr. Ya no hay OP_CHECKMULTISIG porque no es validable por lotes.En realidad intenta múltiples combinaciones, y si no tienes la información para decir qué coincide con qué, no puedes verificarlo por lotes.En su lugar, está CHECKSIG_ADD, e incrementa un contador con si la segunda comprobación de firma tuvo éxito.Puedes escribir la comprobación de firma como key checksig add number key checksig add number equal verify.Esto es validable por lotes. Todavía hay un límite de 201 opcodes en el lenguaje de scripting, y simular esto costaría 3 opcodes por clave, y con este opcode especial es sólo uno. Con respecto al límite de 200 opcodes, ¿sigues contándolos igual? Sí, no ha cambiado nada respecto a ese límite. CHECKSIGADD es sólo un coste menor. Si usas segwit v0, tienes opcodes ECDSA. Si usas v1 o taproot, solo tienes los opcodes Schnorr.
Hay toda una gama de opcodes inutilizables en el actual lenguaje de scripting de bitcoin que hacen fallar automáticamente tu script, que se convierten en OP_SUCCESS. Es un opcode que hace que el script tenga éxito automáticamente. Es una salida no gravada de nuevo, incluso cuando se encuentra en una rama IF no ejecutada.Hay razones para hacerlo; la ventaja de esto es que ya no estamos restringidos a redefinir opcodes NOP para introducir nueva funcionalidad.Siempre podrías tener una nueva versión de la hoja para reemplazar completamente el lenguaje de script, pero si quieres reemplazar sólo uno de los opcodes, no necesitas el mecanismo de la versión, puedes simplemente usar el opcode OP_SUCCESS y redefinirlo para que tenga un nuevo significado.Esto hace que el script devuelva true, y puede tener cualquier semántica, en lugar de la semántica de «no tocar la pila» para redefinir NOPs.¿Tiene sentido?
Una cosa más es claves públicas que comienzan con un byte desconocido son tratados como un éxito automático también. Esto significa que si a- no en el de nivel superior, sólo en los guiones o las hojas. La razón de esto es que te permite introducir nuevos sistemas criptográficos de clave pública, nuevos modos sighash, o cualquier cosa sin añadir otros 3 opcodes para hacer comprobaciones de firma, en su lugar simplemente lo codificas en la propia clave pública donde tenemos un byte de todas formas.Esto no es como OP_SUCCESS, solo hace que la comprobacion de firma tenga exito.Olvidé la razón de ser de esto.La clave pública es un argumento que se pasa a un CHECKSIG en un script.No necesita ser un push, puede venir de cualquier parte. Es un elemento de la pila que se pasa al opcode CHECKSIG. ¿Cómo evitas que alguien cambie una transacción en vuelo? Te estás comprometiendo con la clave pública en el script. Si la estás pasando en la pila, tienes otro problema, sin restringirlo de otra manera. Oh, cierto. ¿Alguna pregunta sobre esta parte?
Además, las claves públicas sin comprimir han desaparecido porque, en realidad, ¿por qué las seguimos teniendo?
Si más tarde haces un soft-fork, tienes que convertir cosas que antes eran válidas en inválidas. Así que OP_SUCCESS es útil para eso. Al redefinir un opcode NOP, lo único que puedes hacer es no modificar la pila pero puede observarla. Estás restringido a opcodes que no pueden modificar la pila. Por eso CHECKLOCKTIMEVERIFY deja los datos en la pila. Podría haber una variación de OP_SUCCESS llamada OP_RELATIVESUCCESS donde si aciertas el opcode entonces es éxito pero sino no. La razón por la que no hace eso es que, quieres un OP_SUCCESS que redefina todo el lenguaje de script en un potencial soft-fork. Te permite introducir un OP_SUCCESS que cambia la forma de analizar los opcodes, que es algo que haces antes de cualquier ejecución. La regla es que iteras a través de todos los opcodes y si encuentras OP_SUCCESS sin fallar el parseo, no ejecutas nada en absoluto, sólo tiene éxito. Tampoco continúas analizando.
También está la parte de eliminar el límite de sigops. No es eliminarlo del todo. En lugar de tener dos limitaciones de recursos separadas en un bloque - el límite de peso y los límites de sigops, lo que lleva a un molesto problema menor de optimización de los mineros. En su lugar, sólo se permite tener un sigop por cada 50 bytes de testigo. Dado que cada firma requiere 64 bytes para el testigo que se comprueba, más bytes para la clave pública, más la sobrecarga de la propia entrada, esto no debería restringir ninguna característica, pero elimina el problema bidimensional. Ahora, ¿qué pasa si en algún momento hay una razón para introducir un opcode que es muy caro, como decir que alguien quiere OP_CHECKSNARKVERIFY o algo más caro como ejecutar algo o OP_VERIFYETHEREUM o OP_JAVASCRIPT. Puedes imaginar que debido a esta suposición de taproot donde esencialmente asumimos que la mayoría de los spends van a usar el simple keypath, podría ser razonable tener cláusulas de excepción bastante caras en tus scripts de hoja de taproot para satisfacer. Bueno, ¿qué haces si tal opcode es órdenes de magnitud más caro que un sigop ahora? Querrías que eso correspondiera a un aumento de peso, porque proporcionalmente no quieres ir más allá de más de x CPU por ancho de banda realmente. Para hacer eso, temíamos que introducir eso incentivara a la gente a rellenar la transacción con cientos de bytes cero o algo así sólo para no llegar a este límite. Digamos que introducimos un límite que cuesta cien sigops; ahora necesitas un testigo de 5000 bytes que sería un desperdicio para la red sólo por rellenarlo. Así que una idea que tuvimos es, si tuviéramos una manera de modificar el peso de una transacción de una manera incondicional, donde sólo podríamos establecer un marcador en la transacción que dice calcular el peso, pero incrementado en este valor y que el incremento debe tener una propiedad que está firmado por todas las claves de lo contrario la gente podría cambiar el peso de la transacción en vuelo, y también debe ser reconocible fuera de contexto. Incluso cuando no se gasta el UTXO, se debería poder hacer incondicionalmente este ajuste de peso. Por esa razón, tenemos un anexo que es un elemento testigo cuando se gasta una salida taproot que no tiene ningún significado consensuado excepto que va en la firma y de lo contrario se omite. Esta es un área donde los incrementos de peso podrían ir. Digamos que la transacción no tenía un número de secuencia, y queríamos hacer algo como el tiempo de bloqueo relativo, lo que ahora llamamos el campo de secuencia podría haberse puesto en este anexo también. Es esencialmente añadir campos a una entrada de una transacción que no le importa al script. La única regla de consenso incluida ahora en la propuesta de taproot es que puedes tener un anexo identificado de esta cierta manera única con un cierto byte de prefijo, y si es así, entonces se omite. Vive en el testigo, es el último elemento de la pila del testigo, tiene que empezar con el byte 0x50 en hexadecimal. No hay ningún gasto de testigo válido ahora mismo que pueda empezar con el byte 0x50 en p2wsh o p2wpkh.
Otra cosa es, digamos que queremos hacer otro cambio de ejecución de script como graftroot o cosas en ese dominio. Tal vez queramos reutilizar tapscript dentro de esos donde la semántica de ejecución de scripts en realidad sigue siendo la misma y tal vez los incrementos ot el lenguaje de scripting se aplican a ambos. Si esos necesitaran un anexo, entonces… Creo que es útil pensar en las versiones de las hojas como la versión real del script, y la versión en la parte superior es realmente la versión de la estructura de ejecución y podrían ser independientes una de la otra. Hay un número de mecanismos de ejecución, y luego hay un número de versiones de script. Esto podría aumentar la razón por la que querríamos tener este anexo adjunto a los tapscripts.
Creo que eso es todo. Oh, el algoritmo de resumen de transacciones se actualiza. Jonas mencionó, hay una serie de mejoras sighash. Hay más cosas precalculadas para reducir el impacto de grandes scripts. Hashing etiquetado, sí. ¿Por qué? ¿No podrías etiquetarlo de otra manera si quisieras cambiarlo? Sí, se puede, pero por ejemplo no queremos introducir nuevas etiquetas para… no queremos que la introducción de nuevas etiquetas sea algo habitual. Es probable que quieras implementaciones optimizadas para ellas, y aumenta el tamaño del código. Para las cosas simples que se comparten, que desea poner en los datos, y el uso de las etiquetas para asegurarse de que diferentes dominios no interactúan. No me importan mucho los bytes de época.
Parece que el firmante requiere mucho más contexto. En realidad, es menos. El mayor cambio en el sighash es que SIGHASH_ALL ahora firma las cantidades que se gastan de todas las entradas, en lugar de sólo las entradas que se gastan. Esto se debe a un ataque particular contra las billeteras de hardware que es explotable hoy en día. Creo que esto fue discutido en las listas de correo, en realidad, hace un par de meses. Necesitas darle a la billetera de hardware las salidas no gastadas que se están gastando… necesitas los scripts de las salidas que se están gastando de todos modos para que la billetera de hardware pueda… digamos un coinjoin de 1000 personas, tienes una entrada, pero ahora necesitas todos los otros datos de contexto…». Sí, eso es un buen punto. Necesito releer ese hilo en esa lista de correo. Es un buen punto, y no lo había considerado. Esto haría que los PSBT fueran muy muy grandes antes de que pudieras siquiera considerar la posibilidad de firmar. Ya necesitas los vouts y los txids. También necesitas estos datos ahora mismo para calcular la tasa; no necesariamente tienes que calcular la tasa, pero ciertamente deberías y ciertamente deberías querer hacerlo.
Además, hay un cambio en el que siempre se firma la scriptpubkey que se gasta, lo que protege contra el tipo de preocupación de si puedo mutar el sighash que fue diseñado para una cosa P2SH en una cosa que no es P2SH, lo que es posible hoy en día. Esto se arregla incluyendo un bit que dice explícitamente si esto es P2SH pero para eliminar categóricamente esta preocupación se firma el scriptpubkey que se gasta.
Hay un par más de valores precomputados.. Cualquier tipo de datos de longitud variable es pre-hashed, por lo que si usted tiene múltiples checksigs no necesita ser recomputed. El anexo es de longitud variable. El hash del anexo se calcula una vez y se incluye siempre que sea necesario. El número de entradas y el número de salidas son siempre pre-hashed. Los datos introducidos en el cálculo sighash tienen un tamaño limitado, que es de 200 y pico bytes.
Esta es la primera vez que cualquier tipo de prueba de inclusión merkle está cubierto por el consenso. Usted ha hecho un cambio en el sentido de que ordena los pares. ¿Has considerado algún otro cambio? Hashes etiquetados, claro. Teóricamente podría ser cualquier tipo de acumulador, ¿verdad? Así que a lo que John se refiere es que, en este árbol de Merkle no nos importa la posición de las cosas, sólo que algo está ahí. Alguien sugirió, ¿por qué no ordenas las entradas a la función hash en cada nivel? Ahora no necesitas revelar a la red si vas a la izquierda o a la derecha; simplemente le das a la otra rama y siempre podrías combinarla. Esto se deshace de un bit de datos testigo para cada nivel, que no es un gran problema, pero hay un poco de complejidad evitada acerca de cómo hacer frente a la serialización de todos esos bits. Con guiones suficientemente aleatorios, en realidad da un poco de privacidad también porque ya no se filtra información a través del orden de posición en el árbol. Entonces, ¿por qué no cualquier otro tipo de acumulador? ¿Tienes alguna sugerencia? Es semi-serio. ¿Hay algo más por ahí? Creo que incluso un simple acumulador RSA, que tiene problemas con la configuración de confianza… pero en este caso, la configuración es la persona que posee la clave privada, ¿no? ¿Es un acumulador privado? ¿Haces un setup para cada clave? Hice matemáticas para esto en algún momento y llegué a la conclusión de que sólo tiene sentido si tienes más de 16 millones de hojas, sólo en términos de tamaño y CPU no quiero ni pensar. Usted puede tener hasta 4 mil millones de hojas, en realidad. Por encima de eso, usted tendrá dificultades para calcular su dirección.
La ordenación determinista de las hojas, ¿no puede ordenar sus hojas por probabilidad? Todavía se puede hacer eso. Usted quiere construir su árbol como un árbol de Huffman basado en la probabilidad, y luego hay clasificación que voltea en varios niveles, pero la profundidad de cada hoja sigue siendo la misma. Así que a través de eso, todavía filtrar información, obviamente, pero eso es deseable, creo.
Seguridad pos-cuántica
https://twitter.com/pwuille/status/1133838842690060289
Una de las cosas interesantes sobre la seguridad post-cuántica es que, si tienes una salida taproot generada a partir de una clave pública interna con un registro discreto conocido y alguna vez se gasta usando la ruta del script, tienes una prueba transferible de que ECDLP está roto. Alguien con una rotura ECDLP podría elegir no usarlo para esto, porque usarlo convencería al mundo de que realmente tiene una rotura ECDLP.
Esto no es específico de los ordenadores cuánticos. Si alguna vez hay una amenaza sustancial de que ECDLP se rompa, no hay más remedio que poner en la lista negra el gasto utilizando construcciones basadas en ECDLP. Así que en ese momento, o bien dices que sólo hay estas monedas y que ya no pueden moverse en absoluto, o vas hacia una prueba post-cuántica de conocimiento-cero bastante complicada para demostrar que esta clave pública se derivó de esta semilla o de este camino endurecido. Si una convención, y esto es inaplicable, si una convención sobre el uso de taproot es que la clave pública debe aparecer siempre….. la clave pública no tiene que aparecer allí, sin embargo. Puedes simplemente definirlo como otra forma de pasarlo. Podrías hacerlo en un hard-fork; esa es la menor de nuestras preocupaciones. La idea es que, en el mejor de los casos, si ECDLP se rompe, dentro de 10 años habrá suficiente investigación para que tengamos la confianza de que hay una compensación bastante aceptable para un esquema seguro post-cuántico, se define un nuevo tipo de salida, puedes gastarlo y todo bien. Entonces, 20 años después de eso, la gente empieza a decir que en realidad hay un ordenador cuántico de 500 qubits sólo un factor este más antes de que nuestros fondos estén en riesgo… pero para entonces, casi todo el mundo se ha movido a un esquema post-cuántico de todos modos. En el árbol taproot pones algo grande de hash para una situación post-cuántica, como respaldo. ¿Tienes una rama en algún lugar que es como una cosa no gastable pero con un hash de tu clave privada en ella? No no gastable; puedes definir una firma tipo Lamport, que nadie querrá usar porque es enorme, pero siempre puedes ponerla en el árbol de scripts y estará ahí durante años y décadas y nadie la tocará. Se puede añadir más tarde. Si tienes esto durante 10 o 20 años, todas las carteras lo ponen pero nunca gastan de él. Así que si eliminamos el ECDLP, entonces tiene sentido porque los monederos ya lo han estado usando. En cierto modo estoy de acuerdo, pero tiene que ser con suficiente antelación. El gran problema es que en los esquemas seguros post-cuánticos, no podemos hacer cosas divertidas. Pero eso pasa pase lo que pase. Bueno, no necesariamente. Quizás más adelante se encuentren esquemas post-cuánticos seguros que permitan eso. Eso no es una locura. Hay un coste mínimo para hacer esto por si acaso, y si encuentras un esquema post-cuántico mejor que tenga características divertidas, entonces puedes introducirlo más tarde. Necesitas otra rama, pero nunca la ves. Sin embargo, añade complejidad.
Si las claves públicas implicadas se derivan siempre de alguna semilla que conocemos, entonces podrías tener una prueba de conocimiento cero de conocimiento de lo que sea que generó esa semilla, que será enorme, pero eso está bien porque la mayoría de las cosas post-cuánticas son enormes. Esto sería un hard-fork, pero no necesitamos hacer nada excepto asegurarnos de que nuestras claves privadas tienen semillas conocidas que son conocidas por los monederos. O tu clave privada es sólo el hash de otra clave privada.
¿Sería la derivación bip32 demasiado loca para el propósito que describes? No sé cómo sería una prueba de conocimiento-cero. Es difícil predecir cuál sería la eficiencia. Probablemente será de al menos 10 kilobytes. Podrías usar un esquema post-cuántico simple como las firmas Lamport.
La mayoría de los monederos utilizan una de como cinco bibliotecas, así que tan pronto como lo tienes en bitcoinjs estás bien (lamentablemente). Parte del objetivo de taproot es que ya no podrás saber qué monederos usa la gente. Usted tiene un incentivo financiero para tener esos signautres Lamport allí.