Wiki de ZooBC
Proof of Participation

La semilla del bloque (VRF)

Cada bloque de ZooBC lleva una semilla de 64 bytes, la fuente de aleatoriedad de la cadena. Decide quién puede producir el siguiente bloque, quién gana la lotería coinbase, qué recibos muestra un productor y cómo se asignan los pares entre sí. A partir de la versión 0.5.8 la semilla es la salida de una función aleatoria verificable (VRF): para un productor dado y una semilla anterior dada existe exactamente un valor válido, y una breve prueba en la cabecera del bloque permite a cada nodo comprobarlo.

Por qué la semilla no debe poder elegirse

Si un productor pudiera escoger la semilla de su bloque entre varias candidatas, podría inclinar el siguiente sorteo de productores hacia sí mismo o hacia un socio, sesgar la lotería coinbase o decidir el resultado de la apuesta de una app. Una firma digital normal no bastaría como semilla: sobre el mismo mensaje puede existir más de una firma válida, así que un productor podría probar varias y quedarse con la que le gustara.

Una VRF cierra esa puerta. Funciona como una firma que solo tiene un resultado válido: quien tiene la clave puede calcular la salida y una prueba, cualquiera con la clave pública puede verificar la prueba, y toda prueba válida para la misma clave y la misma entrada da la misma salida.

Izquierda: una semilla basada en una firma tiene muchas salidas válidas y el productor elige una. Derecha: una semilla VRF tiene exactamente un valor más una prueba de 80 bytes que comprueba cada validador.
Izquierda: una semilla basada en una firma tiene muchas salidas válidas y el productor elige una. Derecha: una semilla VRF tiene exactamente un valor más una prueba de 80 bytes que comprueba cada validador.

Cómo se hace una semilla

  1. La entrada, llamada alpha, es el hash SHA3-256 de la semilla de 64 bytes del bloque anterior (32 bytes).
  2. El productor ejecuta ECVRF sobre Ed25519, en una variante de ZooBC, con su clave de nodo (véase claves de un nodo).
  3. La salida es la nueva semilla de 64 bytes. La prueba ocupa 80 bytes: un punto de la curva de 32 bytes, un desafío de 16 bytes y un escalar de 32 bytes.
  4. La prueba va en la cabecera del bloque, que la firma del bloque cubre: se firman 284 bytes de cabecera (204 bytes de otros campos más la prueba de 80 bytes) y se aplica el hash a 348 bytes.

Los validadores exigen la prueba, la verifican con la clave del productor sobre alpha y rechazan un bloque cuya semilla no sea la salida de la prueba.

Nada del bloque nuevo es una entrada: ni sus transacciones ni su marca de tiempo. Por tanto, un productor no puede dirigir la semilla reorganizando su bloque, y la cadena de semillas puede comprobarse desde cualquier bloque hasta el bloque génesis, cuya semilla son todo ceros. Un número aleatorio generado en el propio ordenador del productor no podría verificarlo nadie, y por eso no se usa ninguno.

La semilla anterior se convierte con un hash en alpha; alpha y la clave de nodo del productor entran en ECVRF, que da la semilla de 64 bytes y la prueba de 80 bytes, ambas en la cabecera. Las transacciones y la marca de tiempo no son entradas.
La semilla anterior se convierte con un hash en alpha; alpha y la clave de nodo del productor entran en ECVRF, que da la semilla de 64 bytes y la prueba de 80 bytes, ambas en la cabecera. Las transacciones y la marca de tiempo no son entradas.

La variante de ZooBC

La ECVRF de ZooBC es una variante de ECVRF-EDWARDS25519-SHA512-TAI. El hash a la curva solo acepta puntos candidatos de orden primo y los usa sin el cofactor, y la verificación rechaza además una prueba cuyo desafío o escalar sea cero. Por eso una biblioteca estándar de RFC 9381 da salidas distintas; quien escriba un nodo o un verificador debe implementar la variante.

Para aproximadamente uno de cada 15 millones de pares de clave y entrada (una probabilidad de (15/16)^256, unos 6.7 × 10^-8) no existe ninguna prueba válida. El productor sorteado no puede entonces producir ese bloque, y el turno pasa al productor de la ronda siguiente.

La única palanca que queda: abstenerse

Un productor sorteado al que no le guste la semilla que llevaría su bloque tiene una opción: no entregar el bloque. El turno pasa entonces al siguiente nodo sorteado, 15 segundos después, que produce el bloque con su propia semilla, igual de impredecible. Retener el bloque vuelve a tirar los dados una vez; nunca elige el resultado.

Además tiene un precio. El productor saltado suma un turno perdido y queda «ausente» hasta su siguiente bloque propio, sin ganar nada y perdiendo puntuación de participación (véase turnos perdidos, suspensión y expulsión). El bloque posterior pesa menos en la elección de bifurcación. El análisis de diseño de Proof of Participation estima la probabilidad de que un adversario con una fracción a de las plazas pueda predecir la semilla n bloques por adelantado en aproximadamente a elevado a n: con un tercio de las plazas, alrededor de 1 entre 27 para tres bloques.

Dos reglas más cierran las puertas laterales:

  • Un cambio de clave de nodo surte efecto solo 120 bloques (30 minutos) después del bloque que lo incluye, de modo que un productor no puede dirigir la siguiente semilla de un socio con una rotación de clave firmada de antemano.
  • El productor del bloque anterior queda degradado en el siguiente sorteo, de modo que ningún nodo tiene a la vez el contenido de un bloque y la semilla que lo resuelve mientras otro nodo pueda responder (véase rondas de prioridad, bloques vacíos y el productor anterior).

Lo que decide la semilla

Las semillas son públicas: cualquiera puede leerlas en la cadena y repetir cada uno de estos sorteos.

Véase también