Las Crónicas de ZK: Extensiones Multilineales

Pruebas de Conocimiento CeroPolinomiosExtensiones MultilinealesLema de Schwartz-Zippel
F
Frank Mangone
26 de diciembre de 2025 · 14 min de lectura

En la entrega anterior, vimos nuestra primera instancia de un protocolo que hace uso de un modelo general para la computación: los circuitos.

Aunque interesante en concepto, notamos que idealmente nos gustaría probar que un cómputo, representado como un circuito, fue correctamente ejecutado — no que sabemos cuántas entradas satisfacen el circuito (recordemos que estudiamos #SAT).

La pregunta, sin embargo, es si podemos hacer eso con nuestro conocimiento actual. Y bueno... ¡No podemos!

Ciertamente, se siente como que estamos muy cerca, y para ser justos, lo estamos. Sin embargo, llegar allí requerirá usar un pequeño artilugio matemático del que no hemos hablado hasta ahora.

Aunque las cosas pueden estar un poco más pesadas del lado matemático hoy, no pierdas de vista nuestro objetivo final: ¡probar que tenemos una entrada que satisface algún circuito!

Y así, es hora de introducir un nuevo elemento en esta serie: una pequeña herramienta que será muy útil en lo que viene a continuación.

¡Vamos a la acción!

Construyendo Intuición

Durante el artículo sobre verificación de la suma, mencioné cómo 00 y 11 eran dos entradas especiales debido a lo fácil que era evaluar polinomios en esos puntos.

Pero seamos honestos: en la mayoría de los escenarios del mundo real, realmente no nos importan las evaluaciones en 00 y 11 específicamente. Son solo números como cualquier otro — no tienen ningún significado semántico inherente.

Lo mismo no aplica realmente a la satisfacibilidad de circuitos booleanos, ¡ya que las entradas son verdaderamente variables booleanas desde el principio!

Entonces, cuando la verificación de la suma nos pide verificar sumas sobre un hipercubo booleano, surge una pregunta obvia: ¿a quién le importa?

Kermit con la frase 'ese es un muy buen punto'

¿Cuándo necesitaríamos sumar un polinomio sobre estos puntos específicos?

La respuesta podría sorprenderte: todo el maldito tiempo. Pero para darle sentido a todo esto, necesitamos mirar esos hipercubos booleanos bajo una luz diferente.

Codificando Información

La clave de este asunto es verlos como una forma de codificar información.

Veamos un ejemplo concreto: una simple lista de números. Supongamos que tenemos una pequeña lista de cuatro valores, digamos [2,3,5,8][2, 3, 5, 8]. Para acceder a un valor específico de esa lista, normalmente proporcionarías un índice. Entonces, por ejemplo, para obtener el valor 55, solicitaríamos el valor en la lista en el índice 22.

¡Asumiendo que estamos usando indexación desde cero, por supuesto!

Ahora, acá va una observación: los índices son simplemente enteros, y todos estos tienen representaciones binarias. Es más, esta pequeña lista tiene 4 índices posibles, que se verían así en binario:

  • Índice 000000
  • Índice 110101
  • Índice 221010
  • Índice 331111

¿Ves hacia dónde voy con esto, verdad? ¡Cada índice es simplemente un punto en el hipercubo booleano {0,1}2\{0,1\}^2!

¡Misma información, diferente representación!

Con esto, podemos imaginar la acción de leer la información en nuestra lista en un índice dado como una función, donde ya podemos asumir que los índices son valores en el hipercubo (que en este caso, es solo un cuadrado booleano):

f:{0,1}2Ff: \{0,1\}^2 \rightarrow \mathbb{F}

Que es solo notación matemática para decir "una función ff que toma dos variables booleanas, y devuelve algún valor en un campo".

Entonces, siguiendo el ejemplo, tenemos:

  • f(0,0)=2f(0,0) = 2
  • f(0,1)=3f(0,1) = 3
  • f(1,0)=5f(1,0) = 5
  • f(1,1)=8f(1,1) = 8

Okay, okay. ¿Pero esto no es solo más re-etiquetar sin mucho sentido?

¡En realidad, no! Lo realmente importante aquí radica en esa pequeña función ff que hemos deslizado tan disimuladamente a nuestro campo visual. Implícitamente, estamos diciendo que esta función es capaz de codificar datos.

De hecho, hemos visto un método para obtener dicha función: interpolación. Obviamente, lo que obtenemos de ese proceso es un polinomio. Y es a través de este tipo de codificación que el protocolo de verificación de la suma se volverá relevante.

¡Genial! Lento pero seguro, parece que estamos llegando a algún lado.

Pero quiero que notes algo: en nuestro paso por la interpolación de Lagrange, en realidad nos enfocamos en el caso univariado. La interpolación se presentó como una forma de obtener un polinomio univariado a partir de evaluaciones, que tratamos como pares (x,y)(x, y).

Sin embargo, en el protocolo de verificación de la suma, hacemos uso de algún polinomio gg con vv variables, en lugar de una sola variable. Así que aquí, la interpolación como la describimos no nos llevará al tipo de polinomio que necesitamos.

Por lo tanto, vamos a necesitar algo diferente.

Extensiones Multilineales

Lo que necesitamos es una forma de ir de una función multivariada (como nuestra ff de arriba) definida sobre un hipercubo booleano a un polinomio multivariado. Llamaremos a dicho polinomio gg por conveniencia, dado nuestro paralelo con la verificación de la suma.

Y haremos esto de una manera muy especial. Porque hay dos condiciones importantes a considerar:

  • Coincidencia en el hipercubo: queremos codificar algunos datos, lo que significa que gg debe coincidir con un conjunto de valores en el hipercubo booleano.
  • Extensión más allá del hipercubo: en el protocolo de verificación de la suma, se nos requiere evaluar gg en puntos distintos a los del hipercubo.

Combinadas, estas dos condiciones definen precisamente el comportamiento de gg:

Necesita ser un polinomio multivariado donde cada entrada puede ser un elemento del campo finito, y cuyas salidas coincidan con los valores codificados en el hipercubo booleano

Sí... Eso es un montón. Vamos a desglosarlo.

Primero, estamos diciendo que necesitamos alguna función definida sobre estos conjuntos:

g:FvFg: \mathbb{F}^v \rightarrow \mathbb{F}

Esto es, toma vv entradas en el campo F\mathbb{F}, y nos permitirá codificar un total de 2v2^v valores. Y para esos valores, tenemos una serie de restricciones a la función:

  • g(0,0,...,0,0)g(0, 0, ..., 0, 0) codifica f(0,0,...,0,0)=k0f(0, 0, ..., 0, 0) = k_0, entonces g(0,0,...,0,0)=k0g(0, 0, ..., 0, 0) = k_0, donde k0k_0 es algún elemento en F\mathbb{F}.
  • Luego, g(0,0,...,0,1)g(0, 0, ..., 0, 1) codifica f(0,0,...,0,1)=k1f(0, 0, ..., 0, 1) = k_1, entonces g(0,0,...,0,1)=k1g(0, 0, ..., 0, 1) = k_1.
  • De igual manera, g(0,0,...,1,0)=k2g(0, 0, ..., 1, 0) = k_2.
  • g(0,0,...,1,1)=k3g(0, 0, ..., 1, 1) = k_3

Y así sucesivamente. Por lo tanto, requerimos que:

f(w)=g(w) w{0,1}vf(w) = g(w) \ \forall w \in \{0,1\}^v

Que es solo notación matemática para: g=fg = f solo en el hipercubo.

Esta es la construcción que buscamos. Es como si estuviéramos extendiendo nuestra función original ff para que las entradas puedan tomar valores distintos de 00s y 11s, permitiendo valores en el campo finito más grande. De ahí el nombre: extensiones multilineales.

Loading question...

Pero espera, ¿por qué multilineales? ¿Qué significa eso siquiera?

Multilinealidad

Antes de que ocurra cualquier confusión: multivariado y multilineal no son la misma cosa.

Me atrapaste ahí

Los polinomios pueden tener, como ya sabemos, diferentes grados, ya que los diferentes términos en la expresión pueden elevarse a diferentes potencias enteras. Incluso podríamos estirar un poco el lenguaje aquí y hablar del grado de cada variable, como la máxima potencia a la que una variable dada se eleva a lo largo de toda la expresión.

Decir que un polinomio es multilineal en realidad plantea una restricción fuerte sobre cómo puede verse el mismo: lo que estamos diciendo es que el grado de cada variable es a lo sumo 11. Para ser perfectamente claros, esto es un polinomio multilineal:

g(X1,X2,X3,X4)=X1X4+X2X4+X3X4g(X_1, X_2, X_3, X_4) = X_1X_4 + X_2X_4 + X_3X_4

Y esto no lo es:

g(X1,X2,X3,X4)=X12X4+X2X4+X3X4g'(X_1, X_2, X_3, X_4) = X_1²X_4 + X_2X_4 + X_3X_4

¡Ese único término con X12X_1^2 hace que todo el polinomio sea no lineal!

Loading question...

Bien... Pero, de nuevo, ¿por qué importa esto?

Resulta que imponer esta condición tiene un par de consecuencias interesantes. Verás, en principio, podríamos extender nuestra función original ff usando polinomios de cualquier grado. ¡De hecho, hay infinitas maneras de hacer esto!

Tomemos por ejemplo nuestra lista de 4 elementos [2,3,5,8][2, 3, 5, 8]. Podríamos construir polinomios como:

  • g1(X1,X2)=2+X1+3X2+X1X2g_1(X_1, X_2) = 2 + X_1 + 3X_2 + X_1X_2
  • g2(X1,X2)=2+X13+3X2+X1X25g_2(X_1, X_2) = 2 + X_1^3 + 3X_2 + X_1X_2^5
  • g3(X1,X2)=2+100X17+3X299X17+X1X2g_3(X_1, X_2) = 2 + 100X_1^7 + 3X_2 {-} 99X_1^7 + X_1X_2

Los tres codifican correctamente la lista en {0,1}2\{0,1\}^2, y por supuesto divergen en todos los demás puntos. Entonces... ¿Qué hace que la multilinealidad sea especial, específicamente?

Primero que nada, está el hecho de que una expresión multilineal es simple y eficiente. Estos polinomios requerirán evaluación en algún momento, y en ese sentido, el grado importa. Los polinomios multilineales tienden a ser menos costosos de evaluar que expresiones de mayor grado, y además generalmente tienen menos coeficientes, lo que también impacta los costos de comunicación.

¡Además, algunos argumentos de solidez dependen de que algunos polinomios tengan bajo grado!

Pero esto no es todo. Cuando nos restringimos a polinomios multilineales, resulta que hay solo una manera de definir gg para que coincida con todos nuestros requisitos. En otras palabras, una extensión multilineal (o MLE por sus siglas en inglés) de alguna función ff definida sobre el hipercubo booleano es única.

Diablos, lo voy a repetir en términos aún más fuertes:

Hay una manera natural y única de extender una función ff definida en un hipercubo booleano a un polinomio multilineal

Esto es poderoso. Tanto así, que creo que deberíamos demostrar esta afirmación.

¡Siéntete libre de saltarte esta próxima sección. Solo creo que vale la pena, ya que es una propiedad tan útil de las extensiones multilineales!

Unicidad

Para mostrar esto, primero necesitaremos una estrategia para construir tal función gg.

Esto es lo que haremos: para cada punto ww en {0,1}v\{0,1\}^v, construiremos un polinomio que evalúe a 11 en ww, y a 00 en todos los demás puntos del hipercubo.

Eso debe sonar familiar. ¿Puedes recordar dónde vimos algo similar?

Una imagen de Shrek y Burro, confundidos, y con las caras intercambiadas

¡Sí, eso es exactamente cómo definimos las bases de Lagrange! Eso es prácticamente lo que estamos haciendo aquí.

Muy bien entonces, definamos eso:

χw(X1,...,Xv)=i=1v[wiXi+(1wi)(1Xi)]\chi_w(X_1, ..., X_v) = \prod_{i=1}^{v} [w_iX_i + (1-w_i)(1-X_i)]

La expresión puede verse un poco extraña, pero funciona perfectamente bien:

  • Cuando los valores de XX son las coordenadas de ww, cada término evalúa a wi2+(1wi)2w_i^2 + (1 {-} w_i)^2. Nota que esto es igual a 11 cuando wiw_i es 00 o 11. Por lo tanto, todo el producto resulta en 11.
  • Cuando XX toma algún otro valor diferente de ww, entonces al menos un XiX_i es diferente de wiw_i, entonces o bien Xi=0X_i = 0 y wi=1w_i = 1, o viceversa. En ambos casos, wiXi+(1wi)(1Xi)w_iX_i + (1 {-} w_i)(1 {-} X_i) es igual a 00, colapsando así todo el producto a 00.

Para obtener nuestra extensión, solo necesitamos sumar todos estos términos juntos, multiplicados por el valor codificado en un índice dado, f(w)f(w):

g(X1,...,Xv)=w{0,1}vf(w)χw(X1,...,Xv)g(X_1, ..., X_v) = \sum_{w \in \{0,1\}^v} f(w) \chi_w(X_1,...,X_v)

Puedes verificar por ti mismo que esta expresión es multilineal. ¡Y como tal, hemos construido una MLE válida de ff!

Loading question...

Lo que queda es probar que esta expresión es la única MLE posible para ff.

Voy a empezar a abusar un poco de la notación ahora, para mantener las cosas un poco más condensadas. Cuando digo p(X)p(X), simplemente asume que XX es un vector. ¡Esto tiene sentido en el contexto en el que estamos trabajando, después de todo!

Para hacer esto, haremos algo bastante inteligente. Supongamos que p(X)p(X) y q(X)q(X) son dos MLEs válidas para ff. De ellas, construyamos este polinomio hh, que también es multilineal:

h(X)=p(X)q(X)h(X) = p(X) {-} q(X)

Debido a que p(X)p(X) y q(X)q(X) son MLEs válidas, tienen los mismos valores en el hipercubo booleano, lo que significa que esos valores serán raíces de h(X)h(X).

Más comúnmente, esto se expresa como: h(X)h(X) se anula en {0,1}v\{0,1\}^v.

Sin embargo, para probar que p(X)p(X) y q(X)q(X) son el mismo polinomio, necesitamos mostrar que h(X)h(X) es idénticamente 00 — es decir, su expresión es h(X)=0h(X) = 0.

Ahora, dado que h(X)h(X) es multilineal, tiene grado a lo sumo 11 en cada variable — por lo que su grado total es a lo sumo vv. Como ya sabemos, un polinomio no nulo de grado vv puede tener a lo sumo vv raíces.

Pero... ¡Estamos afirmando que h(X)h(X) tiene 2v2^v raíces distintas!

Eso es imposible: 2v2^v es mayor que vv (para cualquier v1v \geq 1). ¡A menos, por supuesto, que permitamos que h(X)h(X) sea el polinomio cero!

Por lo tanto, la única posibilidad aquí es que h(X)=0h(X) = 0, lo que a su vez significa que p(X)=q(X)p(X) = q(X). Así, la MLE es única, y es exactamente la expresión que construimos.

¿Elegante, no?

Un gato asustado debajo de una mesa
Por favor, que pare...

La unicidad es importante porque previene la falsificación. Con esto, quiero decir que si existieran múltiples extensiones posibles, un probador deshonesto podría intentar construir una para satisfacer sus necesidades malignas.

Pero con las MLEs, hay solo una extensión correcta. ¡El proceso de extensión obtiene protección gratis: unicidad significa que no hay margen de maniobra para los tramposos!

Calculando MLEs

¡Muy bien! Hemos demostrado que las MLEs son únicas y están bien definidas. Pero hay algo más que necesitamos abordar: practicidad.

Echemos otro vistazo rápido a nuestra fórmula:

g(X1,... ,Xv)=w{0,1}vf(w)χw(X1,... ,Xv)g(X_1, ... \ , X_v) = \sum_{w \in \{0,1\}^v} f(w) \chi_w(X_1, ... \ ,X_v)

Nota que estamos sumando sobre 2v2^v elementos, y cada uno de los términos χ\chi involucra vv multiplicaciones. Ingenuamente, evaluar un solo punto en gg tomaría un total de O(v.2v)O(v.2^v) operaciones. Si no tenemos cuidado con cómo usamos estas extensiones, los costos computacionales podrían explotar, haciendo que las MLEs sean imprácticas.

Afortunadamente, hay una optimización inteligente para calcular MLEs que reduce dramáticamente los tiempos de evaluación, y esto es lo que finalmente hace que estos pequeños sean muy útiles.

El truco, una vez más, tiene que ver con una estructura recursiva que podemos explotar. Un ejemplo aquí ayudará a conceptualizar la idea general.

Supongamos que queremos calcular la extensión g(X1,X2,X3)g(X_1, X_2, X_3) de alguna función ff de 3 variables. El hecho de que cada variable sea binaria nos permite escribir gg de esta manera:

g(X1,X2,X3)=(1X1)g0(X2,X3)+X1g1(X2,X3)g(X_1, X_2, X_3) = (1 {-} X_1)g_0(X_2, X_3) + X_1g_1(X_2, X_3)

Donde g0g_0 y g1g_1 son restricciones de la función original gg en X1=0X_1 = 0 y X1=1X_1 = 1 respectivamente.

¡Al usar estas restricciones, hemos dividido la evaluación de nuestra MLE original en la evaluación de dos MLEs más pequeñas! Por supuesto, no necesitamos detenernos ahí: ahora podemos tomar g0g_0 y g1g_1, y hacer exactamente lo mismo, reduciendo su evaluación a dos nuevas MLEs con una variable menos.

g0(X2,X3)=(1X2)g00(X3)+X2g01(X3)g_0(X_2, X_3) = (1 {-} X_2)g_{00}(X_3) + X_2g_{01}(X_3)

Una vez que llegamos a polinomios univariados, su evaluación se vuelve super simple:

g01(X3)=(1X3)f(0,1,0)+X3f(0,1,1)g_{01}(X_3) = (1 {-} X_3)f(0,1,0) + X_3f(0,1,1)

Recuerda: X3X_3, así como las otras variables, tomará valores del campo finito cuando estemos calculando la extensión multilineal — ¡no solo 00 y 11!

Entonces, para evaluar gg, tenemos que ir en la dirección opuesta. Empezamos con las evaluaciones de ff, y tomamos combinaciones de ellas. Siguiendo nuestro ejemplo resultaría en este pequeño gráfico aquí:

El gráfico de evaluación de una extensión multilineal
Click to zoom

La magia ocurre cuando consideramos el contexto en el que se usan estas MLEs. Verás, en nuestro buen protocolo de verificación de la suma, necesitamos calcular gg en puntos como estos en rondas subsecuentes:

  • g(0,0,0),g(0,1,0),g(0,0,1),g(0,1,1),g(1,0,0),...g(0, 0, 0), g(0, 1, 0), g(0, 0, 1), g(0, 1, 1), g(1, 0, 0), ...
  • g(r1,0,0),g(r1,1,0),g(r1,0,1),g(r1,1,1)g(r_1, 0, 0), g(r_1, 1, 0), g(r_1, 0, 1), g(r_1, 1, 1)
  • g(r1,r2,0),g(r1,r2,1)g(r_1, r_2, 0), g(r_1, r_2, 1)

¡Si lo necesitas, ve a revisar el protocolo de nuevo!

En cada ronda, una variable se fija a un valor de desafío rr, pero las variables restantes aún toman combinaciones booleanas que se repiten, y pueden ser reutilizadas.

Podemos ver esto en acción en nuestro pequeño ejemplo. Supongamos que necesitamos encontrar g(0,0,0)g(0,0,0), y luego g(r1,0,0)g(r_1,0,0). La primera evaluación nos lleva a calcular g0(0,0)g_0(0,0) y g1(0,0)g_1(0,0):

Una evaluación que depende de valores precalculados

Si almacenamos esos valores para uso posterior, simplemente podemos reutilizarlos cuando se nos requiera calcular g(r1,0,0)g(r_1,0,0):

g(r1)=(1r1)g0(0,0)+r1g1(0,0)g(r_1) = (1 -r_1)g_0(0,0) + r_1g_1(0,0)

¡Lo que hemos hecho es usar uno de los trucos más antiguos del libro en diseño de algoritmos: memoización!

¡Todo lo que hacemos es almacenar valores intermedios cuando ejecutamos las evaluaciones completas al principio de la verificación de la suma, y luego simplemente los reutilizamos después, reduciendo significativamente los costos de evaluación!

Esta eficiencia ganada principalmente ayuda a mantener manejable el tiempo de ejecución del probador durante el protocolo de verificación de la suma, o realmente, en cualquier otro contexto donde codifiquemos datos de esta manera binaria.

¡Genial! Ahora hemos cubierto la mayoría de los trucos detrás de las MLEs. Pero antes de irnos, necesitaremos hablar de una cosa más, que resulta ser un fundamento que usaremos mucho de aquí en adelante.

El Lema de Schwartz-Zippel

La intuición que usamos hace un momento para probar la unicidad — que un polinomio no nulo de grado dd puede tener a lo sumo dd raíces — es en realidad un caso especial de un resultado más general y poderoso que usaremos muchas veces a lo largo de la serie, llamado el lema de Schwartz-Zippel. ¡Y ahora es el momento perfecto para presentarlo!

Esta es la idea: si p(X1,...,Xv)p(X_1, ..., X_v) es un polinomio no nulo de grado total dd sobre un campo F\mathbb{F}, y elegimos valores aleatorios r1r_1, r2r_2, ..., rvr_v de F\mathbb{F}, ¿cuál es la probabilidad de que caigamos en una raíz?

Este valor resulta ser exactamente:

Pr[p(r1,...,rv)=0]d/F\textrm{Pr}[p(r_1, ..., r_v) = 0] \leq d / |\mathbb{F}|

Mientras dd sea mucho más pequeño que el tamaño del campo finito, ¡entonces esta probabilidad es despreciable! Así, si elegimos un conjunto aleatorio de entradas, y realmente obtenemos p(r1,...,rv)=0p(r_1, ..., r_v) = 0, ¡entonces hay una probabilidad muy alta de que el polinomio original fuera el polinomio constante p(X1,...,Xv)=0p(X_1, ..., X_v) = 0!

Esto parece simple, pero en realidad es una herramienta super poderosa. Una aplicación muy simple es mostrar que dos polinomios son idénticos: dados p(X)p(X) y q(X)q(X), podemos definir h(X)h(X) como:

h(X)=p(X)q(X)h(X) = p(X) {-} q(X)

Cuando seleccionamos un punto aleatorio rr^*, y verificamos que p(r)=q(r)p(r^*) = q(r^*), de hecho estamos diciendo que h(r)=0h(r^*) = 0, lo que significa con alta probabilidad que p(X)p(X) es igual a q(X)q(X).

¡Esto debería recordarte mucho al razonamiento que usamos durante el análisis de solidez del protocolo de verificación de la suma. Aunque no lo dijimos explícitamente, ¡usamos el lema de Schwartz-Zippel!

Loading question...

¡Usaremos esto mucho, así que definitivamente tenlo en mente!

Resumen

¡Muy bien, eso fue probablemente mucho! Hagamos un balance de lo que hemos aprendido hoy.

Primero, el hipercubo booleano funciona bien como una estrategia de indexación. Podríamos aprovecharlo para codificar información, ya que el índice podría servir como una entrada de alguna función, y los datos que queríamos codificar podrían ser su salida.

Luego, para usar esta función en la verificación de la suma, identificamos que necesitaba ser extendida. Así es como llegamos a las extensiones multilineales: extensiones únicas de estas funciones que ya no están limitadas a un hipercubo booleano.

Aunque no lo mencioné explícitamente, es muy fácil construir estas MLEs. Las bases de Lagrange que usamos son super simples. ¡Por esta razón, las MLEs son la opción superior al extender funciones!

Con las MLEs, podemos tomar prácticamente cualquier conjunto de datos — una base de datos, un vector, una matriz — y codificarlo como un polinomio que puede de alguna manera funcionar bien con verificaciones de la suma.

Obviamente, hay algo que no hemos abordado aún: ¿qué papel juegan las verificaciones de la suma en todo esto?

Quiero decir, codificar datos está bien y todo, pero ¿dónde está la computación?

Ahí es donde entran los circuitos. ¡Y ese será nuestro próximo destino, donde las cosas finalmente empezarán a encajar!

¡Nos vemos en la próxima!