by Weiji Guo from Lightec Labs
Note: by the time of writing, this document has NOT been reviewed. It may contain mistakes of various kinds. Also most claims are NOT backed by benchmarks. This is so far a live document rather than a paper draft intended to be published. We will address reviewing and benchmarking as we move on.
Note: there are some issues rendering latex in GitHub/Browser (Safari better than Chrome). You may also download the document to preview in VS Code.
We are developing the Tea/Horse proving system as the underlying scheme for the proposed OP_ZKP soft-fork upgrade to Bitcoin.
The Tea/Horse proving system consists of three major parts:
- Inner-Product Argument (IPA), thus the (EC)DLP hardness assumption only, and the secp256k1 curve only.
- Aggregated Proving to effectively reduce the symptotical Verifier complexity to sub-linear.
- Single circuit for a recursive verifier, to address the linear verification key issue. The recursive verifier verifies zkStark proofs.
The name Tea/Horse comes from an ancient confidential transaction style, in which people traded tea for horse or vice versa, (perhaps sometimes) keeping the price/bidding information within sleeves, exchanged during hand-shaking. Below picture was taken in Songpan where the author attended a trail running event early July. He came up with the idea of aggregated proving on his flight going there.
As had been explained in an email to the bitcoin developer mailing list, we are considering Inner-Product Argument. We could achieve succinct (sub-linear) verifier with aggregated proving, but are left with one open issue. That is, the verification key is too large for on-chain deployment.
Searching for a commitment scheme to address this open issue does not land a definitive answer. Instead, it seems quite the opposite, that we might not be able to find such a scheme. Circuit constants are essentially matrixes of size O(N^2), however sparse. And as pointed out before, these matrixes may not be sparse any more after adopting aggregated proving.
Luckily there is a third option besides (1)committing to the circuit constants, or (2)turning to Dory. That is, recursive verification. The idea is straightforward. Instead of verifying proofs from individual circuits directly, the OP_ZKP implementation has a verifier to verify proofs from one special circuit (the recursive circuit), which in turn recursively verifies proofs for business logic related circuits (application circuits).
The advantages are two fold:
(1) There is no need to deploy verification keys on-chain. The constants (and scheme-related public parameters) of the recursive verifier could be hard-coded in the Bitcoin client, taking up no block space. As for all application circuits, their circuit constants could be provided as witness to the recursive prover, thus hidden from the recursive verifier.
(2) It is possible to upgrade the recursive prover, the recursive verifier or the circuit without interrupting the applications based on OP_ZKP, in case of critical security patches. Still, it is each application circuit's responsibility to take care of their own security and efficiency.
Note that application circuits need not adopt the aggregated proving technique. As the verification is rather different with that of normal circuits, it is unlikely to have the recursive verifier support both ways.
We use bold lower case letters to denote vectors, for example,
We use
Throughout this document, the commitment scheme is Pedersen vector commitment. We also modify the Inner-Product Argument from Bulletproofs a bit following the Halo paper, as one of the two vectors are usually known.
For EC group
where
We may ignore the public parameters
To open the commitment
IPA reduces the communication cost of opening a Pedersen vector commitment from linear to
For polynomial
Let its commitment value
To open
Instead of providing
Given a challenge value
The new commitment value becomes
where
Based on the values
Rename
Remark Chosing odd/even rather than lower/higher halves is based on the need to align many sub-circuits with different size.
First we describe how to open a commitment value
Let
For each round, in a similar way we may have:
and
Besides necessary values of
Next we describe how to open multiple polynomials at the same point. Suppose we have
Prover first need to commit to each of the polynomials. Let the commitments be
Verifier generates a random value as challenge:
Equivalently there exists a batched polynomial
which is commited to
And this commitment value
We might have hybrid case for the Tea/Horse proving system: opening
Note that the communication costs here are three
In the Tea/Horse proving system, a typical R1CS circuit is organized as many (m) sub-circuits, each having a size of fixed upbound set to
The basic idea is to aggregatedly prove all the sub-circuits. For each sub-circuit, we follow a protocol which is a mixture of Sonic and Halo. Then we have an argument to aggregate them together.
In this section we reiterate the Sonic Arithmetic following notations from Sonic Paper and Halo paper with slight modifications introducing matrix notations. We assume that the circuit has been preprocessed (see Appendix A of Bootleproofs).
Suppose we have an arithmetic circuit
where
For the
Here,
For
where
Embedding all the constraints into a single equation of
which should hold at all points if all the constraint system is satisfied for some witness
Going on with Sonic Arithmetic, let's define some more polynomials:
Note that the constant term of
This part is still mostly Sonic Arithmetization with (modified) IPA. Some ideas come from Halo but we do not use the amortizing part or cycles of curves part. We stick to the secp256k1
curve. Also as we hard-coded some circuit constants in the verifier side, verifier could compute these values on its own.
Prover commits to
Verifier responds with a challenge value
Now let
Prover commits to
Verifier responds with a challenge value
Prover now needs to open a few commitments, and provides open to values and proofs.
Verifier need to verify all the above openings, compute
Passing Identity Test 9 means that
Remark The computation of
The opening of
Specfically,
where
To open
We now consider how we could aggregate the proving of
where
And
where
Finally we can define polynomials
and Verifier responds with a challenge value
Next, Prover may commit to each of
Verifier responds with another challenge value
Then we use
After checking that Equation 10 holds, Verifier compute
For
- commitments to
$r^{(i)}(X, 1), t_ {lo}^{(i)}(X, y), t_ {hi}^{(i)}(X, y)$ , totally$3m$ elements of$\mathbb{G}$ , denoted$3m[G]$ ; - aggregated opening hints
$\delta_ R, \delta_ {T_ {lo}}, \delta_ {T_ {hi}}$ , totally 3 elements of$\mathbb{Z}_ p$ , denoted$3[F]$ ; - aggregated open-to values
$e, f, t_ 1, t_ 2$ , totally 4 elements of$\mathbb{Z}_ p$ , denoted$4[F]$ ; - proof data for opening the aggregated commitment, which is
$2log _ 2(d)[G] + 1[F] = (2log _ 2(N) + 4)[G] + 1[F]$ (remember$d = 4N$ ).
And the verification key include:
- elements of combined
$\textbf{U}, \textbf{V}, \textbf{W}$ , of apparent size$3QN$ , which could be further optimized; - elements of combined
$\textbf{k}$ , of size$Q$ .
Verifier complexity is:
- combining
$3m$ commitments to 3 commitments, that is$3$ multi-scalar multiplications, echo of size$m$ ; - batch opening the combined commitment, dominated by
$d = 4N$ sized multi-scalar multiplication; - computing the aggregated
$s(X, Y)$ and$k(Y)$ , of apparent$O(N^2)$ field operations in$\mathbb{Z}_ p$ , which could be further optimized.
First observe that combined
Next observation is that some circuits are dominated by a few sub-circuits repeated many times. For example, based on the cost analysis above, the recursive verifier for a Tea/Horse proof is dominated by multi-scalar multiplicatioins and some field operations. In that case, the same set of
Last we dicsuss the feasibility of proving the existence of the
Remark Note that Nova in itself cannot be applied here as it requires cycles of elliptic curves. Also Nova requires auxillary zkSnark circuits, which has similar performance characteristics as analyzed below.
For commitment values
- derive a value
$\alpha_ C \in \mathbb{Z}_ p^*$ by hashing$C^{(i)}$ together for$C \in {R, T_ {lo}, T_ {hi}}$ . A field friendly hash would be helpful. However we might need justSha256
for Bitcoin. - compute
$\alpha = \alpha_ R \cdot \alpha_ {T_ {lo}} \cdot \alpha_ {T_ {hi}}$ - use the derived
$\alpha$ to combined the commitment values$C = \sum_ {i=1}^m\alpha^iC^{(i)}$ for$C \in {R, T_ {lo}, T_ {hi}}$
Verifier verifies the proof of the above computation, instead of computing
The circuit needs to
- hash
$3m$ elements of$\mathbb{G}$ - run
$3$ multi-scalar multiplication, each of size$m$
Unfortunately, it costs much more to run MSM in-circiut than directly, both proving and verification with IPA.
Take a step back. We could start from
If we set
At this point our major issues are (1) with the verification key size, which is
The application circuits have to be in a scheme with succinct verifier, for example Tea/Horse or Hyrax. But even with Hyrax the recursive verifier is still very large.
Now let's take a step back and review if we can apply sparse polynomial commitment technique, called Spark
, which was introduced in Spartan and refined in Lasso.
Specifically, we seek to remove the circuit constants from the verifier key, replace them with some commitments. Then we don't need a recursive verifier, the proposed OP_ZKP implementation could verify proof data of application circuits directly. This addresses the two issues mentioned above.
Remark This is a live document. We might change our mind or switch to a better solution in the middle of developing the system.
Based on the Figure 6 of the Spartan paper, we could commit to the constants of each sub-circuit. The circuit constants are of size Spark
achieves
Since we are already dealing with
We now get back to the recursive verifier design. This time we consider any scheme that has transparent setup, and has no pairing requirement, yet with minimal verifier time so that the recursive verifier could be small. It appears zkStark fits our requirement with its
A rough estimation to the verifier cost is based on the assumption that: (1) there exists a hash function that costs only 100-th of SHA256
in terms of R1CS constraints; (2) hashing computation takes up at least 80% of the verifier computation. Further, let's use blowup factor of 32, and security level of
For an application circuit with
According to the Table 1 of Reinforced Concrete, Rescue-Prime
has less than Rescue-Prime
into one sub-circuit. So we need
According to costs analysis, the total proof size to be verified by OP_ZKP
should be
Verifier runtime includes three parts:
- 3 MSM each with size
$m = 52$ - MSM with size
$d= 4N = 2^{18}$ - computing
$s(X, Y)$ and$k(Y)$
The first one is relatively easy to compute. The seond one might cost single thread of a modern computer around 1 second, and of Raspeberry Pi 4 around 10 seconds.
For the last one, note that secp256k1
library. Then 2.4 million multiplication should cost about 0.12 second. (Acutal cost might be a bit higher as we oversimplify here,
Overall, verifier cost is dominated by a large MSM, and the total time looks acceptable, even for a small miner (RP4). Still, there is room for fine tuning and optimization. For example, we could have smaller
The conclusion is that, we can go ahead with aggrepated IPA proving for the recursive verifier + zkStark for the application circuits.
We now move to a new topic regarding how a miner could batch verify multiple OP_ZKP
transactions.
Suppose there are
First the miner need to derive
To verify
Since all the proofs are created under the same public parameters, they are expected to have the same length
When we do so, each
The resulting value
Note that
After the proof verification, the miner has yet to compute
Assuming each OP_ZKP
transaction to be of size less than 7KB, counting in non-proof data such as UTXOs and payment amounts etc. If a bitcoin block consists of OP_ZKP
transaction only, the maximal value of
Combining the proofs together involves
Each
This huge computation burden seems inherent to IPA and hard to optimize or remove. Even if it was feasible to optimize, the proof size of OP_ZKP
transactions will still hinder its adoption. To address both issues together, we consider a new dedicated circuit to further verifies proofs of multiple OP_ZKP
transactioins together.
With a recursive verifier in play, each Bitcoin script containing the OP_ZKP
opcode must have the capability to tell if the verified proof is dedicated to it. This is called attestation. The recursive verifier will also attach to its proof a piece of information as the attestation so that the script or the OP_ZKP
implementation could verify.
Suppose there exists a threshold OP_ZKP
transactions in a dedicated circuit, whose proof will be verified by each node instead. Unlike earlier optimization attempts, this time we may consider those ZKP schemes without batched verification features.
With new choices open to us, we might consider zkStark as it provides
Suppose there is the said threshold OP_ZKP
transactions. Then a regular computer should be able to verify such a block about
Surpassing the threshold, the block prover may kickin to replace the proof data of those OP_ZKP
transactions with another proof, which has a size of a few hundred KBs, and the verification time should be very short, probably well within 1 second as most of the computation is to compute hash values.
This documents has been packed with lots of speculated numbers. So we go no further estimating the constraint count, or incentives designed for the block prover.
We stress that with the block prover to batch verify the proof of all the OP_ZKP
transactions, we can save lots of block space doing so. But again, let's skip any concrete numbers for now.