Pulsos Aleatorios

Formato

Un pulso aleatorio es la respuesta que entrega el Faro de Aleatoriedad a través de su API. Estos pulsos contienen, además de los 512 bits aleatorios generados en cada minuto, información adicional necesaria para poder verificar que ese valor aleatorio fue generado correctamente. Random UChile responde estos pulsos en formato JSON. Los campos existentes en un pulso aleatorio son:

  1. URI (uri): identificador único del pulso, utilizando la URL en donde se puede acceder.
  2. Versión (version): versión actual de la API.
  3. Cipher Suite (cipherSuite): identificador de los algoritmos utilizados para generar el valor.
  4. Período (period): cantidad de milisegundos entre cada pulso generado.
  5. Certificado Público (certificateId): 512 bits que representan el identificador del certificado público necesario para verificar la firma presente en el pulso.
  6. Id de la Cadena (chainIndex): identificador de la cadena que pertenece el pulso.
  7. Id del Pulso (pulseIndex): identificador (número) del pulso dentro de la cadena.
  8. Tiempo (timeStamp): marca de tiempo que corresponde al pulso actual.
  9. Aleatoriedad Local (localRandomValue): 512 bits que son generados de manera local.
  10. Identificador de la Fuente Externa (external.sourceId):
  11. Estado de la Fuente Externa (external.statusCode):
  12. Valor de la Fuente Externa (external.value):
  13. Valor Aleatorio Anterior (previous): 512 bits del valor aleatorio del pulso inmediatamente anterior
  14. Valor Aleatorio del Primer Pulso de la Hora (hour): 512 bits del valor aleatorio del primer pulso generado en la hora actual.
  15. Valor Aleatorio del Primer Pulso del Día (day): 512 bits del valor aleatorio del primer pulso generado en el día actual.
  16. Valor Aleatorio del Primer Pulso del Mes (month): 512 bits del valor aleatorio del primer pulso generado en el mes actual.
  17. Valor Aleatorio del Primer Pulso del Año (year): 512 bits del valor aleatorio del primer pulso generado en el año actual.
  18. Compromiso del Valor Aleatorio Siguiente (precommitmentValue): 512 bits que representan un commitment del valor aleatorio a utilizar en el siguiente pulso.
  19. Estado del Pulso (statusCode): estado del pulso actual.
  20. Firma del Pulso (signatureValue): 4096 bits que representan la firma realizada con la clave privada de Random UChile del pulso actual.
  21. Valor Aleatorio del Pulso (outputValue): 512 bits generados aleatoriamente.

Verificación

A continuación se pueden encontrar los scripts de verificación del Faro de Aleatoriedad de Random UChile.

El código (en lenguaje Python) y las instrucciones de uso se encuentran en el Repositorio Github del verificador. También es posible descargar el código a través de este enlace (instrucciones de uso en README).

Los scripts de verificación son:

  1. Consistencia de Cadena (chain-consistency-version2.py): este script revisa la correctitud de todos los pulsos entregados por el Faro. En particular verifica las siguientes propiedades:
    • Correcta referencia a pulsos previos.
    • Uso de la entropía generada localmente en el minuto anterior y comprometida (en commitment) en el pulso de dicho minuto.
    • Correcto uso de la función de hash lento (sloth propuesto por Arjen Lenstra and Benjamin Wesolowski descrito en este paper e implementación basada en este repositorio github) para la generación del valor aleatorio final.
    • Firma válida.
  2. Verificador de eventos externos en tiempo real: disponible pronto.

Verificación de la Firma

Certificado Público

El certificado necesario para verificar la firma en cada pulso está disponible a través de la API:

Formato de la Firma

Cada pulso está firmado digitalmente por Random UChile, utilizando el algoritmo RSA-PSS. La firma se realiza sobre la concatenación de los siguientes valores:

strlen(x) retorna el número de carácteres que hay en x.
length(x) retorna el número de bytes en x luego que x ha sido decodificado de su expresión hexadecimal.
Tanto strlen(x) como length(x) están codificados como valores enteros de 4 bytes (big-endian).
El resto de los valores están codificados como valores enteros de 4 bytes, a excepción de chainIndex y pulseIndex que están codificados como valores enteros de 8 bytes.