# Pianist

## Introduction

**Pianist (Plonk vIA uNlimited dISTribution)** is a **distributed proof generation system** based on Plonk.

## Protocol Explanation

### Notation

* $$M$$: number of machines
* $$N$$: size of the entire circuit
* $$T$$: size of each sub-circuit, where $$T = \frac{N}{M}$$, a power of 2

### Arithmetic Constraint System for Each Party

Each participant is responsible for a portion $$C\_i$$ of the global circuit $$C$$, and constructs a local constraint system to prove correctness of that sub-circuit.

This system consists of two main parts:

1. **Gate Constraint** — ensures that gate computations are correct
2. **Copy Constraint** — ensures that wire connections are consistent

***

#### Gate Constraint

Plonk targets **fan-in 2 arithmetic circuits**, where each gate has at most two inputs (left and right) and one output.

For each sub-circuit $$C\_i$$ assigned to machine $$P\_i$$, the following **univariate polynomials** are defined for a circuit size $$T$$:

* $$a\_i(X)$$: left input
* $$b\_i(X)$$: right input
* $$o\_i(X)$$: output

Each of these is expressed in the **Lagrange basis** as:

$$
a\_i(X) = \sum\_{j=0}^{T-1} a\_{i,j} L\_j(X)
$$

where $$L\_j(X)$$ is a Lagrange polynomial, and can be computed in $$O(T \log T)$$ time using the [Number Theoretic Transform (NTT)](/intro/primitives/number-theoretic-transform.md).

All gate operations are encoded in a single polynomial equation:

$$
g\_i(X) := q\_{a,i}(X)a\_i(X) + q\_{b,i}(X)b\_i(X) + q\_{o,i}(X)o\_i(X) + q\_{ab,i}(X)a\_i(X)b\_i(X) + q\_{c,i}(X)
$$

The $$q$$ coefficients vary depending on the gate type:

* **Addition Gate**

  $$
  (q\_{a,i}, q\_{b,i}, q\_{o,i}, q\_{ab,i}, q\_{c,i}) = (1, 1, -1, 0, 0)
  \quad \Rightarrow \quad g\_i(X) = a\_i(X) + b\_i(X) - o\_i(X)
  $$
* **Multiplication Gate**

  $$
  (q\_{a,i}, q\_{b,i}, q\_{o,i}, q\_{ab,i}, q\_{c,i}) = (0, 0, -1, 1, 0)
  \quad \Rightarrow \quad g\_i(X) = a\_i(X) b\_i(X) - o\_i(X)
  $$
* **Public Input Gate**

  $$
  (q\_{a,i}, q\_{b,i}, q\_{o,i}, q\_{ab,i}, q\_{c,i}) = (0, 0, -1, 0, \mathsf{in}*{i,j})
  \quad \Rightarrow \quad g\_i(X) = -o\_i(X) + q*{c,i}(X)
  $$

Finally, the gate constraint must hold at all evaluation points in the domain:

$$
g\_i(X) = 0 \quad \forall X \in \Omega\_X
$$

where $$\Omega\_X = { \omega\_X^0, \dots, \omega\_X^{T-1} }$$.

***

#### Copy Constraint

One of the core ideas in Plonk is modeling **wire consistency** using a **permutation argument**. To enable this, the verifier sends two random field elements $$\eta, \gamma \in \mathbb{F}$$. The prover then constructs the following **running product polynomial**:

$$
z\_i(\omega\_X^j) =
\begin{cases}
1 & \text{if } j = 0 \\
\prod\_{k=0}^{j-1} \frac{f\_i(\omega\_X^k)}{f'\_i(\omega\_X^k)} & \text{otherwise}
\end{cases}
$$

Where:

* $$f\_i(X)$$: actual wiring values

  $$
  f\_i(X) := (a\_i(X) + \eta \cdot \sigma\_{a,i}(X) + \gamma)(b\_i(X) + \eta \cdot \sigma\_{b,i}(X) + \gamma)(o\_i(X) + \eta \cdot \sigma\_{c,i}(X) + \gamma)
  $$
* $$f'\_i(X)$$: permuted reference wiring

  $$
  f'\_i(X) := (a\_i(X) + \eta k\_A X + \gamma)(b\_i(X) + \eta k\_B X + \gamma)(o\_i(X) + \eta k\_O X + \gamma)
  $$

Here, $$k\_A = 1$$, and $$k\_B, k\_O$$ are distinct **non-residue constants**.

{% hint style="success" %}
**What are non-residue constants?**\
In general, when constructing permutation or lookup arguments over a finite field $$\mathbb{F}$$, non-residue constants are used to apply distinct "shifts". Specifically, if $$\omega$$ is a primitive $$n$$-th root of unity generating a multiplicative subgroup $$H \subset \mathbb{F}$$, then any $$k \notin H$$ is considered a **non-residue**, or a **coset shift**. One can then define a new **coset domain** $$kH = { kh \mid h \in H }$$ that is disjoint from $$H$$.
{% endhint %}

The prover must prove the following holds:

$$
z\_i(\omega\_X^T) = \prod\_{k=0}^{T-1} \frac{f\_i(\omega\_X^k)}{f'\_i(\omega\_X^k)} = 1
$$

This is enforced via the following constraints:

$$
p\_{i,0}(X) := L\_0(X) \cdot (z\_i(X) - 1)
$$

$$
p\_{i,1}(X) := z\_i(X) \cdot f\_i(X) - z\_i(\omega\_X \cdot X) \cdot f'\_i(X)
$$

***

#### Quotient Polynomial

To consolidate all constraints into a single polynomial relation, we prove the existence of a polynomial $$h\_i(X)$$ satisfying:

$$
g\_i(X) + \lambda \cdot p\_{i,0}(X) + \lambda^2 \cdot p\_{i,1}(X) = V\_X(X) \cdot h\_i(X)
$$

where the vanishing polynomial over the evaluation domain is defined as:

$$
V\_X(X) = X^T - 1
$$

### Constraint System for Data-parallel Circuit

This section presents the **core technique** that aggregates locally proven gate and copy constraints from each machine into a **single unified SNARK proof**.

Assuming the sub-circuits $$C\_0, C\_1, \dots, C\_{M-1}$$ are independent, the goal is to:

* **Aggregate local proof polynomials into a single bivariate polynomial**, and
* **Transform the distributed proof system into a globally verifiable SNARK**

***

#### Naive Approach

The most straightforward idea is to aggregate sub-polynomials using powers of $$Y$$:

$$
A(Y, X) := \sum\_{i=0}^{M-1} Y^i a\_i(X)
$$

A multiplication gate would then be expressed as:

$$
A(Y, X) B(Y, X) - C(Y, X)
\= \left( \sum\_{i=0}^{M-1} Y^i a\_i(X) \right)
\left( \sum\_{i=0}^{M-1} Y^i b\_i(X) \right)

* \left( \sum\_{i=0}^{M-1} Y^i c\_i(X) \right)
  $$

This introduces **cross-terms** such as $$Y^{i+j} a\_i(X) b\_j(X)$$, making it difficult to reason about and distribute the proof efficiently.

***

#### Bivariate Lagrange Polynomial Aggregation

To address this, inspired by [Caulk](https://eprint.iacr.org/2022/621), we use Lagrange basis polynomials in $$Y$$:

$$
A(Y, X) := \sum\_{i=0}^{M-1} R\_i(Y) a\_i(X)
$$

Now, a multiplication gate becomes:

$$
A(Y, X) B(Y, X) - C(Y, X)
\= \left( \sum\_{i=0}^{M-1} R\_i(Y) a\_i(X) \right)
\left( \sum\_{i=0}^{M-1} R\_i(Y) b\_i(X) \right)

* \left( \sum\_{i=0}^{M-1} R\_i(Y) c\_i(X) \right)
  $$

This removes any cross-terms and allows clean aggregation of constraints.

***

#### Global Constraint Definitions

* **Gate Constraint**:

$$
G(Y, X) := Q\_a(Y, X) A(Y, X)

* Q\_b(Y, X) B(Y, X)
* Q\_o(Y, X) O(Y, X)
* Q\_{ab}(Y, X) A(Y, X) B(Y, X)
* Q\_c(Y, X)
  $$

- **Copy Constraint**:

$$
P\_0(Y, X) := L\_0(X) \cdot (Z(Y, X) - 1)
$$

$$
P\_1(Y, X) := Z(Y, X)
\prod\_{S \in {A, B, O}} (S(Y, X) + \eta \cdot \sigma\_s(Y, X) + \gamma)

* Z(Y, \omega\_X X)
  \prod\_{S \in {A, B, O}} (S(Y, X) + \eta \cdot k\_s X + \gamma)
  $$

- **Quotient Polynomial**:

$$
G(Y, X) + \lambda P\_0(Y, X) + \lambda^2 P\_1(Y, X) = V\_X(X) \cdot H\_X(Y, X)
$$

***

#### Verifier Strategy

The verifier checks that for every $$i \in \[0, M-1]$$, the constraint holds at $$Y = \omega\_Y^i$$:

$$
G(Y, X) + \lambda P\_0(Y, X) + \lambda^2 P\_1(Y, X) - V\_X(X) H\_X(Y, X) = V\_Y(Y) H\_Y(Y, X)
$$

where $$V\_Y(Y) = Y^M - 1$$ is the vanishing polynomial for the $$Y$$-domain.

### Constraint System for General Circuit

In the **data-parallel setting**, there are no connections between sub-circuits, so each machine can independently prove its portion. However, real-world circuits such as those in zkEVMs have **highly interconnected gates**.

In this **general setting**, the same wire value may appear across multiple sub-circuits, requiring a **cross-machine copy constraint**. To support this in a distributed setting, we must modify the permutation argument. The key idea is to include not just the position within a sub-circuit (X), but also the machine index (Y).

***

#### Modified Copy Constraint

The global permutation check requires each machine to construct a running product that satisfies:

$$
\prod\_{i=0}^{M-1} \prod\_{j=0}^{T-1} \frac{f\_i(\omega\_X^j)}{f'\_i(\omega\_X^j)} \stackrel{?}{=} 1
$$

Where:

* $$f\_i(X)$$: actual wire expression

  $$
  \begin{aligned}
  f\_i(X) = & (a\_i(X) + \eta\_Y \delta\_{Y,a,i}(X) + \eta\_X \delta\_{X,a,i}(X) + \gamma) \\
  & (b\_i(X) + \eta\_Y \delta\_{Y,b,i}(X) + \eta\_X \delta\_{X,b,i}(X) + \gamma) \\
  & (o\_i(X) + \eta\_Y \delta\_{Y,o,i}(X) + \eta\_X \delta\_{X,o,i}(X) + \gamma)
  \end{aligned}
  $$
* $$f'\_i(X)$$: sorted reference wiring

  $$
  \begin{aligned}
  f'\_i(X) = & (a\_i(X) + \eta\_Y Y + \eta\_X k\_A X + \gamma) \\
  & (b\_i(X) + \eta\_Y Y + \eta\_X k\_B X + \gamma) \\
  & (o\_i(X) + \eta\_Y Y + \eta\_X k\_O X + \gamma)
  \end{aligned}
  $$

Now, the final value of the running product for each machine,

$$
z\_i^\* = z\_i(\omega\_X^{T-1}) \cdot \frac{f\_i(\omega\_X^{T-1})}{f'\_i(\omega\_X^{T-1})}
$$

is no longer guaranteed to be 1. Thus, the constraints must be modified as follows:

$$
p\_{i,0}(X) := L\_0(X) \cdot (z\_i(X) - 1)
$$

$$
p\_{i,1}(X) := (1 - L\_{T-1}(X)) \cdot (z\_i(X) f\_i(X) - z\_i(\omega\_X X) f'\_i(X))
$$

The master node then collects the final values from each machine $$(z\_0^*, \dots, z\_{M-1}^*)$$ and checks:

$$
\prod\_{i=0}^{M-1} \prod\_{j=0}^{T-1} \frac{f\_i(\omega\_X^j)}{f'*i(\omega\_X^j)} = \prod*{i=0}^{M-1} z\_i^\* \stackrel{?}{=} 1
$$

To do this, a new polynomial $$z\_{\mathsf{last}}(X)$$ is constructed as:

$$
z\_{\mathsf{last}}(\omega\_Y^i) = \omega\_i =
\begin{cases}
1 & \text{if } i = 0 \\
\prod\_{k=0}^{i-1} z\_k^\* & \text{otherwise}
\end{cases}
$$

This leads to the following constraints:

$$
p\_{i,2}(X) := \omega\_0 - 1
$$

$$
p\_{i,3}(X) := L\_{T-1}(X) \cdot (\omega\_i z\_i(X) f\_i(X) - \omega\_{(i+1) \mod M} f\_i'(X))
$$

***

#### Quotient Polynomial

All constraints are combined into a single relation by proving the existence of $$h\_i(X)$$ such that:

$$
g\_i(X) + \lambda p\_{i,0}(X) + \lambda^2 p\_{i,1}(X) + \lambda^3 p\_{i,2}(X) = V\_X(X) \cdot h\_i(X)
$$

where $$V\_X(X) = X^T - 1$$ is the vanishing polynomial for the X-domain.

***

#### Global Constraint Definitions

* **Copy Constraints**:

$$
\begin{aligned}
P\_0(Y, X) &:= L\_0(X) \cdot (Z(Y, X) - 1) \\
P\_1(Y, X) &:= (1 - L\_{T-1}(X)) \cdot \left\[ Z(Y, X) F(Y, X) - Z(Y, \omega\_X X) F'(Y, X) \right] \\
P\_2(Y) &:= R\_0(Y) \cdot (W(Y) - 1) \\
P\_3(Y, X) &:= L\_{T-1}(X) \cdot \left\[ W(Y) Z(Y, X) F(Y, X) - W(\omega\_Y Y) F'(Y, X) \right]
\end{aligned}
$$

Here, $$F(Y, X)$$ and $$F'(Y, X)$$ are defined as:

$$
F(Y, X) := \prod\_{S \in {A, B, O}} (S(Y, X) + \eta\_Y \delta\_{Y,S}(Y, X) + \eta\_X \delta\_{X,S}(Y, X) + \gamma)
$$

$$
F'(Y, X) := \prod\_{S \in {A, B, O}} (S(Y, X) + \eta\_Y Y + \eta\_X k\_S X + \gamma)
$$

* **Quotient Polynomial**: All constraints are bundled into a single bivariate relation using $$H\_Y(Y, X)$$:

$$
G(Y, X) + \lambda P\_0(Y, X) + \lambda^2 P\_1(Y, X) + \lambda^3 P\_2(Y) + \lambda^4 P\_3(Y, X) - V\_X(X) H\_X(Y, X) = V\_Y(Y) H\_Y(Y, X)
$$

### Polynomial IOP for Data-parallel and General Circuits

1. $$\mathcal{P} \to \mathcal{V}$$: Send oracles for $${A(Y, X), B(Y, X), C(Y, X)}$$
2. $$\mathcal{V} \to \mathcal{P}$$: Send random challenges $$\textcolor{orange}{\eta\_Y}, \eta\_X, \gamma$$
3. $$\mathcal{P} \to \mathcal{V}$$: Send oracles for $${Z(Y, X), \textcolor{orange}{W(Y)}}$$
4. $$\mathcal{V} \to \mathcal{P}$$: Send random challenge $$\lambda$$
5. $$\mathcal{P} \to \mathcal{V}$$: Send oracle for $$H\_X(Y, X)$$

   $$
   H\_X(Y, X) = \sum\_{i=0}^{M-1} R\_i(Y) \cdot \frac{g\_i(X) + \lambda p\_{i,0}(X) + \lambda^2 p\_{i,1}(X) + \textcolor{orange}{\lambda^4 p\_{i,3}(X)}}{V\_X(X)}
   $$
6. $$\mathcal{V} \to \mathcal{P}$$: Send random challenge $$\alpha$$
7. $$\mathcal{P} \to \mathcal{V}$$: Send oracle for $$H\_Y(Y, \alpha)$$

   $$
   H\_Y(Y, \alpha) = \frac{G(Y, \alpha) + \lambda P\_0(Y, \alpha) + \lambda^2 P\_1(Y, \alpha) + \textcolor{orange}{\lambda^3 P\_2(Y) + \lambda^4 P\_3(Y, \alpha)} - V\_X(\alpha) H\_X(Y, \alpha)}{V\_Y(Y)}
   $$
8. $$\mathcal{V}$$ queries all oracles at $$X = \alpha, Y = \beta$$ and checks:

   $$
   G(\beta, \alpha) + \lambda P\_0(\beta, \alpha) + \lambda^2 P\_1(\beta, \alpha) + \textcolor{orange}{\lambda^3 P\_2(\beta) + \lambda^4 P\_3(\beta, \alpha)} - V\_X(\alpha) H\_X(\beta, \alpha) \stackrel{?}{=} V\_Y(\beta) H\_Y(\beta, \alpha)
   $$

> 🔶 The terms marked in orange are only required in the **General Circuit** case.

The soundness of this protocol is formally proven in [Appendix A](https://eprint.iacr.org/2023/1271.pdf#page=15\&zoom=100,72,513).

***

#### Communication Analysis

Except for $$H\_Y(Y, X)$$ and $$W(Y)$$, all other polynomials can be distributed across $$M$$ machines, with only their commitments needing to be sent.

* For $$W(Y)$$, it can be computed by the master node using the final values $$(z\_0^*, \dots, z\_{M-1}^*)$$ received from all machines.
* For $$H\_Y(Y, X)$$, the prover does not need to send the full polynomial. Instead, the prover collects evaluations at $$X = \alpha$$ from each machine and reconstructs $$H\_Y(Y, \alpha)$$. For example:

  $$
  A(Y, \alpha) = \sum\_{i=0}^{M-1} R\_i(Y) \cdot a\_i(\alpha)
  $$

Therefore, the overall communication complexity is $$O(M)$$.

***

#### Proving Time Analysis

* Each prover $$P\_i$$ computes $$z\_i(X)$$ and $$h\_i(X)$$ in $$O(T \log T)$$
* The master node $$P\_0$$ computes $$W(Y)$$ and $$H\_Y(Y, \alpha)$$ in $$O(M \log M)$$
* So the maximum latency per machine is $$O(T \log T + M \log M)$$
* The total proving time across all machines is $$O(N \log T + M \log M)$$

This is a practical improvement over the original Plonk prover time complexity of $$O(N \log N)$$.

<figure><img src="/files/HX02Ed569TkkYrleujSf" alt=""><figcaption></figcaption></figure>

### Distributed KZG

The original KZG commitment scheme is designed for **univariate polynomials**. Since Pianist models the entire proof system as a **bivariate polynomial** $$f(Y, X)$$, we need to extend KZG to support multiple variables. Furthermore, due to the **distributed nature** of the system, each machine must compute only a portion of the commitment and proof, while the **master node assembles the full result**.

Suppose we have the following bivariate polynomial:

$$
f(Y, X) = \sum\_{i=0}^{M-1} \sum\_{j=0}^{T-1} f\_{i,j} R\_i(Y) L\_j(X)
\quad \text{(where } f\_{i,j} = f\_i(\omega^j) \text{)}
$$

Each machine holds a slice $$f\_i(X)$$ defined as:

$$
f\_i(X) = \sum\_{j=0}^{T-1} f\_{i,j} L\_j(X)
$$

***

#### $$\mathsf{DKZG.KeyGen}(1^\lambda, M, T)$$

Generates the public parameters $$\mathsf{pp}$$:

$$
\mathsf{pp} = \left(
\[1]\_1,
\left(\left( \[R\_i(\tau\_Y) L\_j(\tau\_X)]*1 \right)*{i=0}^{M-1}\right) \_{j=0}^{T-1},
\[1]\_2,
\[\tau\_X]\_2,
\[\tau\_Y]\_2
\right)
$$

***

#### $$\mathsf{DKZG.Commit}(f, \mathsf{pp})$$

Each prover $$\mathcal{P}\_i$$ computes:

$$
\mathsf{com}*{f\_i} = \sum*{j=0}^{T-1} f\_{i,j} \cdot \[R\_i(\tau\_Y) L\_j(\tau\_X)]\_1
$$

The master node $$\mathcal{P}\_0$$ aggregates:

$$
\mathsf{com}*f = \sum*{i=0}^{M-1} \mathsf{com}\_{f\_i} = \[f(\tau\_Y, \tau\_X)]\_1
$$

***

#### $$\mathsf{DKZG.Open}(f, \beta, \alpha, \mathsf{pp})$$

1. Each $$\mathcal{P}\_i$$ computes:

   * $$f\_i(\alpha)$$
   * $$q\_0^{(i)}(X) = \frac{f\_i(X) - f\_i(\alpha)}{X - \alpha}$$
   * $$\pi\_0^{(i)} = \[R\_i(\tau\_Y) \cdot q\_0^{(i)}(\tau\_X)]\_1$$

   Then sends $$f\_i(\alpha), \pi\_0^{(i)}$$ to $$\mathcal{P}\_0$$
2. $$\mathcal{P}\_0$$ computes:
   * $$\pi\_0 = \sum\_{i=0}^{M-1} \pi\_0^{(i)}$$
   * $$f(Y, \alpha) = \sum\_{i=0}^{M-1} R\_i(Y) f\_i(\alpha)$$
3. Then computes:

   * $$f(\beta, \alpha)$$
   * $$q\_1(Y) = \frac{f(Y, \alpha) - f(\beta, \alpha)}{Y - \beta}$$
   * $$\pi\_1 = \[q\_1(\tau\_Y)]\_1$$

   Sends $$(z = f(\beta, \alpha), \pi\_f = (\pi\_0, \pi\_1))$$ to $$\mathcal{V}$$

***

#### $$\mathsf{DKZG.Verify}(\mathsf{com}\_f, \beta, \alpha, z, \pi\_f, \mathsf{pp})$$

The verifier $$\mathcal{V}$$ parses $$\pi\_f = (\pi\_0, \pi\_1)$$ and checks:

$$
e(\mathsf{com}\_f - \[z]\_1, \[1]\_2) \stackrel{?}{=} e(\pi\_0, \[\tau\_X - \alpha]\_2) \cdot e(\pi\_1, \[\tau\_Y - \beta]\_2)
$$

**Proof:**

* The exponent in $$e(\mathsf{com}\_f - \[z]\_1, \[1]\_2)$$ is $$f(\tau\_Y, \tau\_X) - f(\beta, \alpha)$$
* The exponent in $$e(\pi\_0, \[\tau\_X - \alpha]\_2)$$ is:

  $$
  \sum\_{i=0}^{M-1} R\_i(\tau\_Y) \cdot (f\_i(\tau\_X) - f\_i(\alpha)) = f(\tau\_Y, \tau\_X) - f(\tau\_Y, \alpha)
  $$
* The exponent in $$e(\pi\_1, \[\tau\_Y - \beta]\_2)$$ is:

  $$
  f(\tau\_Y, \alpha) - f(\beta, \alpha)
  $$

### Robust Collaborative Proving System for Data-parallel Circuit

Pianist introduces a new proof model to ensure security even in **malicious settings**.

This is called the **Robust Collaborative Proving System (RCPS)** — a protocol that ensures the final proof can still be correctly constructed and verified **even when some machines are faulty or adversarial**.

> 📌 For technical details, see [Section 5 of the paper](https://eprint.iacr.org/2023/1271.pdf#page=8\&zoom=100,420,728).

## Conclusion

<figure><img src="/files/0yuyqkWwCpChftMzLHzi" alt=""><figcaption></figcaption></figure>

While standard Plonk (on a single machine) hits a memory limit at **32 transactions**, Pianist can scale up to **8192 transactions** simply by increasing the number of machines. With 64 machines, Pianist is able to prove 8192 transactions in just **313 seconds**. This demonstrates that **the number of transactions included in a single proof scales proportionally with the number of machines**. Moreover, the time taken by the master node to gather and finalize the proof is just **2–16 ms**, which is **negligible compared to the overall proving time**. This highlights that **communication overhead in Pianist's parallel architecture is minimal**.

***

<figure><img src="/files/OSmvktQ1zLtEtoMKHoA4" alt=""><figcaption></figcaption></figure>

While Figure 1 shows the performance on **data-parallel circuits (e.g., zkRollups)**, Figure 2 extends the evaluation to **general circuits with arbitrary subcircuit connections**. In all circuit sizes tested, **the proving time decreases nearly linearly with the number of machines**, demonstrating **strong scalability even in general circuits**. In smaller circuits, the marginal benefit of scaling beyond 4–8 machines may diminish, but for larger circuits, **the benefits of parallelization become increasingly significant**.\
In other words, Pianist **performs even better on larger circuits**, showcasing a desirable scalability property.

***

<figure><img src="/files/3hyEnSr1501mQ7dcb3mF" alt=""><figcaption></figcaption></figure>

As shown above, **the memory usage per machine decreases significantly as the number of machines increases**. For small circuits, memory savings are minor since the total memory requirement is already low, but for large circuits, **scaling the number of machines directly determines whether proof generation is even feasible**.

***

**In conclusion**, Pianist transforms the original Plonk proving system into a fully distributed, scalable framework that:

* Enables **parallel proving of large circuits across multiple machines**,
* Maintains **constant proof size, verifier time, and communication overhead (all** $$O(1)$$**)**, and
* Offers **high practical utility for real-world zk systems like zkRollups and zkEVMs**.

## References

* <https://eprint.iacr.org/2023/1271>

> Written by [Ryan Kim](mailto:undefined) of Fractalyze


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://fractalyze.gitbook.io/intro/zk/distributed-zk/pianist.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
