Skip to content

ZK: probar que ganaste sin revelar tu estrategia #14

Description

@leocagli

Es la continuacion natural del duelo verificable, y la que hace que el juego
tenga sentido a largo plazo.

La propiedad del juego sobre la que se apoya esto

El combate de runa es una funcion pura: el mismo estado inicial, el mismo
script y la misma cantidad de ticks dan siempre el mismo resultado. No es una
suposicion, esta medido:

misma semilla, dos corridas de 2500 ticks (con peleas, pociones y muertes)
  -> identico
semilla 7 vs 99  -> distinto (5 kills vs 8, oro 34 vs 41)

Y el lenguaje de scripts no tiene bucles ni recursion (lib/script.js), asi
que una pelea termina siempre y su costo esta acotado de antemano.

Esas dos cosas juntas son la razon de ser de esta issue. En casi cualquier otro
juego, verificar que una partida ocurrio de verdad exige confiar en el cliente o
guardar todo el estado. Aca alcanza con el guion y la semilla.

El problema que resuelve

En el duelo con revelacion, para cobrar tenes que publicar tu guion. Pero en
este juego el guion es tu ventaja: es lo unico que te distingue de otro
jugador. Un torneo donde ganar te obliga a regalar tu estrategia se muere en la
segunda ronda.

Con una prueba de conocimiento cero podes demostrar "vencí a este golem en
menos de 900 ticks, partiendo de este estado"
sin decir con que reglas.

El estado de las primitivas, verificado

Esto no es especulacion. Lo comprobe contra el repositorio de protocolo y contra
las versiones de red, el 2026-08-24:

Estado Protocolo
CAP-0059 BLS12-381 Final 22
CAP-0075 Poseidon / Poseidon2 Final 25
Mainnet y Testnet activos 27

O sea que las dos estan vivas en mainnet hoy. CAP-0059 aporta 16 funciones de
host, entre ellas bls12_381_multi_pairing_check, que es la que necesita un
verificador Groth16. CAP-0075 aporta las permutaciones Poseidon y Poseidon2, que
son el hash barato dentro de un circuito.

Hay ademas un verificador Groth16 de ejemplo
en soroban-examples del que partir.

El enunciado a probar

  • Privado: el texto del guion
  • Publico: hash del estado inicial, id del bicho, semilla, resultado, ticks
    usados, hash del contenido y version del engine

El circuito corre la simulacion y prueba que con ese guion privado se llega a
esas salidas publicas.

La parte dificil, dicha de frente

Meter la simulacion entera adentro de un circuito es caro. Los ticks son
secuenciales y cada uno reevalua el guion, asi que el circuito crece con la
cantidad de ticks. Que el lenguaje no tenga bucles ni recursion acota el trabajo
por tick, que es lo que hace esto viable y no imposible, pero no elimina el
problema.

Antes de escribir el circuito completo hay que medir con una pelea corta y
recien despues decidir. Tres salidas posibles, en orden de ambicion:

  1. Probar la pelea entera. Lo mejor si entra.
  2. Probar solo los ticks decisivos, con el resto comprometido en un arbol de
    Merkle.
  3. Probar unicamente que el guion revelado coincide con el hash comprometido, y
    dejar la simulacion afuera. Es lo mas barato y ya mejora al duelo con
    revelacion.

Empezar por medir, no por elegir.

Alcance

  • Medir el tamaño del circuito con una pelea corta, y publicar el numero
    antes de comprometerse con un alcance
  • Circuito del enunciado de arriba (Noir o circom, a decidir con el numero
    en la mano)
  • Contrato verificador en Soroban, separado del contrato de politica:
    el verificador solo dice si la prueba es valida, la logica de premios vive
    aparte
  • Ligar la prueba a un nonce y a un duelo concreto, para que no se pueda
    reusar
  • Camino de respaldo: si la red destino no soporta las primitivas, el juego
    cae al duelo con revelacion sin romperse
  • Tests de camino negativo: prueba manipulada, entradas publicas que no
    corresponden, prueba de otro duelo, nonce vencido

Advertencia para quien la tome

Que un payload parsee no quiere decir que el enunciado sea el correcto para la
aplicacion. Validar la semantica de las entradas publicas explicitamente, y
separar el dominio del enunciado, es parte del trabajo, no un detalle.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions