Simulating Bulletproofs Under Adaptive Corruptions
In this post, we show how to reconstruct the state of a honest prover given a simulated Bulletproof and a valid witness of the proof’s statement. Protocols that use Bulletproofs therefore can use our technique to handle adaptive corruptions and no longer need to additionally assume secure erasures.
A zero-knowledge proof [GMR85] allows a prover to convince a verifier that a public statement of an NP-relation is true without revealing the corresponding witness . For example, may be a public key , where generates a group of prime order and is the secret key. A zero-knowledge proof could then convince the verifier that the prover knows the secret key, without revealing any information besides the already known public key . In this post we are particularly interested in non-interactive zero-knowledge proofs, or NIZK [BFM88], which allow the prover to generate such a proof without interacting with the verifier.
In cryptography, we formalize the promise that a proof ‘‘reveals no additional information’’ through simulation. We say a proof is zero-knowledge if an efficient algorithm (called a simulator) that only knows a statement but does not know the witness can produce valid proofs that no efficient verifier can distinguish from an honest proof. Whatever the verifier learns from an honest proof, it could then also have learned from a simulated proof, which carries no information about the witness to begin with.
At first glance, this definition seems paradoxical, since if a simulator can produce valid proofs without knowing the witness, why should a proof convince a verifier? The answer to this question is called a trapdoor, a piece of secret information that the simulator in a security proof knows and lets it simulate proofs. At the same time, no real prover has access to the trapdoor, so proofs from a real prover are sound (can only be computed when knowing a valid witness). For Fiat–Shamir-based proofs [FS86], which are the subject of this post, the simulator’s trapdoor is the power to program the random oracle [BR93], which is of course not possible in real instantiations.
This simulation property is useful when proving the security of a larger protocol, where NIZKs are used as a building block. Throughout the security proof of such a higher-level protocol, the reduction can first use the NIZK’s simulator to generate proofs without knowing a valid witness, and then embed a challenge element in the NIZK’s statement. With our example NIZK of secret-key knowledge, this would allow the reduction to embed a discrete-logarithm (DLog) challenge element into the public key while still producing accepting proofs of knowledge of the secret key. If the adversary breaks the modified protocol, the reduction uses this break to compute the discrete logarithm of the embedded element. Since replacing honest proofs with simulated ones results in an indistinguishable view for the adversary, any adversary that breaks the real protocol can also be used to break the modified protocol, which in turn allows solving DLog. Because DLog is assumed to be hard, no such adversary can exist.
This proof technique is standard in cryptographic literature and yields secure higher-level protocols under static corruptions, where the adversary chooses which parties to corrupt before the protocol starts. Under static corruptions, the reduction must only simulate the remaining honest parties. Additionally, these honest parties stay uncorrupted throughout the execution and the reduction never has to reveal the internal state behind their simulated proofs. For this part of the security argument, producing indistinguishable proofs is sufficient.
However, static corruptions are not a very realistic corruption model, as in practice adversaries typically do not announce prior to a protocol start which parties they eventually will corrupt. Therefore, as a more realistic corruption model, cryptographers use adaptive corruptions [CGJKR99], where the adversary can choose parties to corrupt during the execution of a protocol, based on the protocol messages it has already seen. If the adversary decides to corrupt such a party, then the reduction has to provide all secret information in the state of this party (including all the randomness used so far). The gap between static and adaptive corruptions might seem small at first sight, but adaptive corruptions have a big impact on the way we can do security proofs. For example, an adversary could wait until all honest parties have published a NIZK, and then decide to corrupt a random party afterwards.
While this might not necessarily help the adversary to break the protocol, it can give it the power to complicate our proof. For example, if we want to use the proof strategy discussed above, we cannot simply replace all honest proofs by simulated ones, since the reduction has to reveal the randomness behind a simulated proof as soon as its prover is corrupted. The adversary can check that this randomness is consistent with the public transcript by running the honest prover again. A simulated proof, however, was produced without the witness, and the random choices of the simulator need not be valid coins for the honest prover. Even if the witness becomes available upon corruption, the proof is already fixed and cannot be replaced. Thus, indistinguishability of the proof alone no longer suffices.
There are three ways around this problem. First, the reduction can guess in advance which parties the adversary will corrupt. It then computes the proofs of these parties honestly (it knows their witnesses, since it embeds the challenge only in the statements of the others) and simulates the remaining proofs. If the guess turns out to be wrong, the reduction aborts. For a single corruption among parties, this costs a factor of in the success probability of the reduction, which is still polynomial. Threshold protocols, however, allow the adversary to corrupt up to of the parties, and if it corrupts of them at random, a guess of this set is correct only with probability . For and , the reduction thus loses a factor larger than , which makes the security bound meaningless.
Second, honest parties can use secure erasures [CGJKR99] and delete the randomness of a proof directly after sending it. A later corruption then no longer reveals this randomness. This, however, is an additional assumption on how honest parties are implemented.
Third, the reduction can simulate all proofs anyway and, once the witness becomes available upon corruption, try to reconstruct randomness that makes the honest prover output exactly the proof it already published. For this post we can simply assume that the reduction obtains a valid witness for the statement of a corrupted party, since upon corruption the reduction must hand over the witness as part of the party’s state anyway.
Reconstructing the prover’s state#
Because we do not want to additionally assume secure erasures, and also cannot efficiently guess which parties the adversary will corrupt, we take the third way. This means that we want to reconstruct randomness for a simulated proof given a valid witness.
If a reduction is able to reconstruct the prover’s state behind a simulated proof, this fixes the gap in the sketched adaptive security proof of the higher-level protocol. Throughout the security proof of the higher-level protocol, the reduction can again first use the NIZK’s simulator to generate proofs without knowing a valid witness, and then embed a challenge element in the NIZK’s statement. When the adversary corrupts a party, the reduction obtains this party’s witness, uses it to reconstruct the randomness behind every proof the party has published, and returns this randomness as part of the party’s internal state.
We formalize this property as honest prover state reconstruction, following Groth, Ostrovsky and Sahai [GOS06].
Definition 1 (Honest prover state reconstruction).
Let be a NIZK for a relation in the random oracle model, where takes its randomness as an explicit input and every public parameter is derived from the random oracle . Then has honest prover state reconstruction if there are efficient algorithms and with a shared state such that for every efficient adversary
where is a random function in the first experiment and answers the adversary’s random-oracle queries in the second. Both oracles take a pair , return if , and otherwise answer as follows.
- samples , computes , and returns .
- lets compute a proof on input , programming its random oracle as needed, then computes , and returns .
Note that in the simulated experiment the witness reaches only , after has already fixed the proof, which is what happens in our sketched security proof upon a corruption.
In addition, besides reproducing the proof, the reconstructed randomness must also be distributed like honest coins, to ensure that the adversary’s view with reconstructed randomness is indistinguishable from a real view.
For Fiat–Shamir proofs, the adversary re-runs the prover against the same random oracle, so the randomness has to reproduce the proof under the answers the simulator programmed.
Additionally, we allow the reconstruction algorithm to use the simulator’s retained state, which includes every random-oracle answer the simulator chose, and ask it to reconstruct randomness only for proofs that this simulator produced.
State reconstruction for Schnorr proofs#
The goal of this post is to show that Bulletproofs have honest prover state reconstruction. As a warm-up example, we first recall how to reconstruct the prover’s state for Schnorr proofs [Sch91], again for a Schnorr proof of knowledge of the secret key for a public key . Recall that to compute such a Schnorr proof, the prover samples a random element , sends , and answers the challenge with . To simulate such a proof, the simulator samples uniformly and sets , which satisfies the verification equation . It then programs the random oracle to return on input , provided that this input has not already been queried.
Theorem 1 (Schnorr proofs have honest prover state reconstruction).
Schnorr’s proof of knowledge of a discrete logarithm has honest prover state reconstruction in the sense of Definition 1.
Proof (Reconstructing the Schnorr prover's randomness).
We construct an algorithm that, given the simulator’s state and the witness , computes
Since , this gives , and the honest prover’s response is , so re-running the prover on against the programmed oracle reproduces . In the real experiment is uniform and the challenge is uniform and independent of it. In the simulated experiment and are uniform and independent, and for fixed and subtracting is a bijection, so and are uniform and independent as well. Both experiments therefore give the same joint distribution of and , unless has to program a point that is already defined. Let the adversary make random-oracle queries and proof queries. Since is uniform in a group of order , a single proof hits an already defined point with probability at most , and a union bound over the proofs shows that the two experiments differ by at most , which is negligible in the security parameter.
Our argument naturally generalizes to other Schnorr-type proofs whose responses are linear in the witness, such as proofs of equality of discrete logarithms or of knowledge of a Pedersen opening, where the reconstruction algorithm subtracts the challenge times the witness from each response.
For Schnorr proofs, randomness reconstruction is possible, so they can be simulated in adaptive protocols without assuming secure erasures upon corruption. However, a Schnorr proof sends one response per secret value, so the proof size grows linearly with the witness. To make protocols that use NIZKs for large witnesses more efficient, one can use Bulletproofs [BBB+18] instead of Schnorr proofs. In contrast to Schnorr, Bulletproofs grow only logarithmically in the witness size, but similar to Schnorr, need no trusted setup and rely only on the discrete-logarithm assumption.
Pedersen commitments#
Before we turn to Bulletproofs, we need one more building block, namely Pedersen commitments [Ped91]. Intuitively, a commitment scheme works like a sealed envelope. In the commit phase, a committer puts a value into the envelope and hands it to a receiver, who cannot look inside. In the opening phase, the committer reveals , and the receiver checks that this is indeed the value in the envelope, so the committer cannot change its mind in between. Proof systems use commitments to let the prover fix a value before it sees the verifier’s challenge, without revealing the value already.
To compute a Pedersen commitment to a single value, we need a second generator of our group. To commit to , the committer samples a random and sends . To open the commitment, it reveals and , and the receiver checks that .
A commitment should satisfy two properties. First, it should be hiding, which means that reveals no information about . For Pedersen commitments, this holds since for every pair of values and every , there is exactly one with . Every commitment could thus equally well contain any other value, and since is uniformly random, has the same distribution no matter which value it contains. Second, it should be binding, which means that the committer cannot open to a different value later. If it could, it would know two openings and with and , from which it could compute the discrete logarithm . Pedersen commitments are thus binding as long as the discrete-logarithm assumption between and holds.
On the other hand, Pedersen commitments are equivocable. This means that anyone who knows can compute the randomness from the hiding property, and thus open a commitment to any other value . We call the trapdoor of the commitment. Just like the simulator’s trapdoor for proofs, this trapdoor will become important later. Another interesting property of Pedersen commitments is that they allow us to commit to whole vectors at once in a single group element. This works by using one generator per entry via . Such a vector commitment is binding as long as nobody knows a discrete-logarithm relation between the generators, and anyone who knows the discrete logarithms of all generators to the base can again open it to any vector. To make sure that only a security reduction, but no real protocol participant knows such a relation, one typically derives all generators through the random oracle by hashing public labels [BBB+18].
Bulletproofs#
At their core, Bulletproofs use an inner-product argument (IPA), which proves that two committed vectors have a given inner product. More formally, for generators , and , and writing , the prover of an IPA shows that it knows vectors with for a public group element . Inner-product arguments are a powerful tool for NIZKs, because many statements are inner products. Evaluating a committed polynomial with coefficient vector at a point , for instance, is the inner product , and the constraints of an arithmetic circuit can be checked all at once through a random linear combination that collapses them into a single inner product [BCC+16].
To prove an inner product without sending field elements, Bulletproofs use the split-and-fold technique of [BCC+16, BBB+18]. It splits both vectors into halves and and, for a challenge , folds them into and of half the length, whose inner product is . The folded vectors thus satisfy the same relation once the two cross terms and are accounted for. To account for these cross terms, the prover computes the two group elements and .
Given the two group elements and , both parties can fold the generators to half the length and set , whose extra factors add exactly the two cross terms. Because Fiat–Shamir derives only after and are fixed, the prover cannot choose them to hide a wrong inner product. The result is again an instance of the same relation, but of half the length. To proceed, the prover applies this step recursively, until after rounds each vector is a single scalar. With this technique, the proof consists of group elements and two scalars. Apart from and this prover uses no randomness.
The protocol we described so far is not zero-knowledge, since and the final scalars are functions of the vectors. To make it zero-knowledge, Bulletproofs+ [CHJ+22] use the hiding property of Pedersen commitments and add a random power of to every group element. (Bulletproofs+ actually prove weighted inner products, but for this post we set all weights to .) First, the statement itself becomes a hiding commitment with a random blinding exponent . Then, in every round, the prover samples two fresh exponents and sends the blinded cross terms
Since and are uniformly random, and now reveal no information about the witness vectors. Folding works as before, but the prover additionally keeps track of the blinding exponent of the folded commitment , which is .
In the last round, in which the prover would send the scalars and in the clear, it now proves that it knows , and with a Schnorr-like step. It samples , sends the two commitments
for the folded generators and , and answers the challenge with
Just like in a Schnorr proof, the random and hide and in the responses. The verifier then checks that , where and provide the cross terms and that show up in .
Put together, the Bulletproof inner-product argument for vectors of length consists of the blinded cross terms of all rounds and the messages of the final Schnorr-like step,
With Fiat–Shamir, the challenge of round and the last challenge are hashes of and all previous messages, so the verifier can recompute them from and fold the generators and itself.
With these changes, we get a zero-knowledge argument that the prover knows , and with . Compared to the plain argument, it costs only two more group elements and one more scalar. The original Bulletproofs [BBB+18] make the argument zero-knowledge in a different way, by running it on randomly masked vectors. In this post we focus on the approach of Bulletproofs+, and come back to the original one in Corollary 1.
Simulating Bulletproofs#
To simulate Bulletproofs without knowing a valid witness, the simulator can follow a strategy similar to the one for Schnorr proofs. In the rounds of the argument, the simulator samples every and as a uniformly random group element. These are distributed exactly like the blinded cross terms of an honest prover. The round challenges come from the random oracle as usual. For the last step, the simulator samples the responses and the challenge uniformly, together with a random group element , and then computes such that the verification equation holds. Finally, similar to the Schnorr simulation, the simulator programs the random oracle to return on the transcript ending with and , provided that this input has not already been queried.
Let us now try to reconstruct the prover’s randomness for such a simulated proof, once we know the witness , and . We do this in the opposite order in which the simulator computed the proof. For the last step, we can apply the Schnorr trick from above, computing and . For the blinding exponents, however, we run into a problem. Since the simulator sampled as a random group element, we need a for which the honest prover would have sent the same , namely
The same holds for in every round and for in . Finding such a means computing a discrete logarithm. However, it can also be found with the trapdoor of the Pedersen commitments involved, which consists of the discrete logarithms of all generators to the base .
Our simulator can obtain this trapdoor because the generators come from the random oracle. In the simulated experiment of Definition 1, the simulator answers all random-oracle queries itself, so it also decides what the generators are. It answers the query for honestly, but every other generator query with for a fresh uniform exponent . Since is again a uniformly random group element, the adversary cannot notice this change. This way, the simulator knows scalars with
which we call the generator trapdoor. Once the simulator knows the generator trapdoor, it also knows the discrete logarithms of all folded generators, since folding only raises the generators to known powers of the challenges and multiplies them. For example, . In the same way, it samples every , and as a power of and remembers the exponents, which we denote by , and . Note that this needs no additional assumption, since the simulator already programs the random oracle for the Fiat–Shamir challenges.
With the generator trapdoor, every commitment of the form is simply a power of ,
So if the simulator sampled itself as a power of , it can open to any messages by setting
Opening a commitment thus costs only one subtraction, just like reconstructing the Schnorr prover’s randomness in Theorem 1.
Warning
If a security proof relies on the generator trapdoor, it can no longer rely on the binding property of the Pedersen commitments, since the reduction can equivocate the commitments.
If the surrounding protocol needs binding, its security proof therefore has to establish binding before it switches to the generator trapdoor. This adds two experiments to the sequence from the introduction, which sit between the honest execution and the experiment with simulated NIZK proofs.In the first experiment, the random oracle still answers the generator queries honestly, but the experiment aborts as soon as the adversary opens a commitment to two different values. This experiment differs from the honest execution only if the abort happens, and an adversary that causes it reveals a discrete-logarithm relation between the honest generators, so the abort happens only with negligible probability under DLog.
In the second experiment, the random oracle answers the generator queries with powers of whose exponents the reduction knows. This switch does not change the distribution of the generators, so the adversary cannot distinguish the second experiment from the first. From now on, the reduction no longer needs binding, since every binding break already leads to an abort. Extraction from adversarial Bulletproofs [GOP+22, DG23] is unaffected, because the adversary never learns the trapdoor.
State reconstruction for Bulletproofs#
With the generator trapdoor and the exponents , and , the reconstruction algorithm can now compute all blinding exponents, which gives our main result.
Theorem 2 (Bulletproofs have honest prover state reconstruction).
The zero-knowledge inner-product argument of Bulletproofs+ [CHJ+22] with weight , made non-interactive with Fiat–Shamir and with generators derived from the random oracle, has honest prover state reconstruction in the sense of Definition 1.
For every random value of the honest prover, the simulated proof contains a value that this randomness has to reproduce. The table lists these pairs, in the order in which the reconstruction algorithm computes them.
| Randomness of the honest prover | Simulated value it has to reproduce | How the reconstruction algorithm computes it |
|---|---|---|
| and in every round | and | open and with the generator trapdoor |
| and | and | solve and |
| open with the generator trapdoor | ||
| solve |
The last message needs no row of its own, because once all other values agree, the verification equation leaves only one choice for . The honest prover uses random values for the rounds, and the simulator samples exactly as many values, one for each random value of the honest prover.
Proof (Reconstructing the prover's randomness).
We construct an algorithm that, given the simulator’s state and a valid witness , computes the randomness of the honest prover in the order of the table. In each round, it knows the discrete logarithms of the current generators and sets
and in the same way, where and contain the discrete logarithms of and . With these exponents, the honest prover sends the same and as the simulator, and folds , and as the honest prover does. For the folded , and , it then sets
so that the honest prover sends the same and the same responses. It remains to show that the honest prover also computes the same , which the simulator derived from the verification equation. Since the witness is valid, it opens , and since folding preserves this, the folded witness opens the folded . The honest therefore satisfies the verification equation, in which every other value agrees with the simulation, so it equals the simulated . Re-running the prover on the reconstructed coins thus reproduces the whole proof.
The generators are uniformly random in both experiments. In the real experiment, the coins are uniform, and the last challenge is uniform and independent of them. In the simulated experiment, the exponents and the responses are uniform and independent of the last challenge. For fixed challenges and witness, each step of subtracts a value that the witness and the previous steps determine, and possibly multiplies by , so the reconstruction is a bijection and the reconstructed coins are uniform as well. Both experiments therefore give the same joint distribution of proof and coins, unless has to program a point that is already defined. As for Schnorr proofs, the simulator programs only one point per proof, and this point contains the uniformly random . A union bound over the proofs bounds this probability by , as in the proof of Theorem 1.
Remark 1 (Other weights).
Bulletproofs+ prove the weighted inner product for a weight . Theorem 2 carries over to every such weight. The weight only adds known powers of to some exponents of the cross terms, the folding and the final step. The reconstruction algorithm therefore subtracts slightly different known values, and every step remains a bijection.
Corollary 1 (Range proofs and arithmetic circuits).
The range proofs of Bulletproofs+ [CHJ+22] and of Bulletproofs [BBB+18], as well as the arithmetic-circuit protocol of Bulletproofs, made non-interactive with Fiat–Shamir and with generators derived from the random oracle, have honest prover state reconstruction in the sense of Definition 1.
Proof.
The range proof of Bulletproofs+ shows that a Pedersen commitment contains a value . Its prover first commits to the bits of and to as . After two challenges and , it runs the argument of Theorem 2 with weight on a statement that both parties compute from and . Our simulator samples as a power of , so obtains with the generator trapdoor and then proceeds as in the proof of Theorem 2, which covers weight by Remark 1. The simulator now programs a second point per proof for , which changes the bound to .
The range proof and the circuit protocol of Bulletproofs run the plain argument on masked vectors. The same argument applies to these. In the range proof, the prover commits to vectors derived from the witness in a commitment , and to random masks in a commitment . The inner product of the masked vectors and is a polynomial , where depends only on the witness (up to public terms that encode the range). The prover commits to and in and , and after a challenge , it runs the plain argument on and , whose inner product is . Every commitment hides its content behind a random blinding exponent, so the prover also sends two blinding responses. The response combines the blinding exponents of and in the same way as and combine the vectors and the masks, and combines those of , and in the same way as combines the coefficients. With these responses, the verifier checks in two verification equations that and match and , and that matches , and . The circuit protocol works in the same way, with more commitments and a polynomial of degree six. Our simulator samples , , and uniformly and every commitment as a power of , except for and , which it derives from the two verification equations. With the witness, opens the sampled commitments with the generator trapdoor and solves the responses for the masks and the remaining blinding exponents, as for Schnorr proofs. The honest and then satisfy the verification equations and hence equal the simulated ones, where for we again need that the witness is valid. The plain inner-product argument needs no reconstruction, since its prover samples no randomness, so the same masked vectors lead to the same transcript. All equations that solves are linear with nonzero coefficients, so the reconstructed coins are uniform, and the bound is again .
Conclusion#
Simulating NIZK proofs is a standard step in security proofs, but it becomes much harder once the adversary can corrupt parties adaptively. Upon a corruption, the reduction has to reveal the randomness behind every proof of the corrupted party, including the proofs that it simulated without a witness. Since guessing the corrupted parties in advance is too costly in general, the reduction either relies on secure erasures or has to reconstruct randomness that is consistent with the simulated proofs. For Schnorr proofs, this reconstruction was already established and takes a single subtraction, but for Bulletproofs it was left as an open problem [BLSW24].
In this post, we showed that Bulletproofs have honest prover state reconstruction, both the zero-knowledge argument of Bulletproofs+ [CHJ+22] and the range proof and circuit protocol of the original Bulletproofs [BBB+18]. The key observation is that every group element of a Bulletproof is a Pedersen commitment. A simulator that programs the generators through the random oracle knows their discrete logarithms and can therefore open each of these commitments to the witness it learns upon corruption. Protocols that simulate Bulletproofs in their security proof therefore no longer need to assume secure erasures for the randomness of these proofs.
References
- [GMR85]
- STOC 1985
- [BFM88]
- STOC 1988
- [BR93]
- ACM CCS 1993
- [BBB+18]
- IEEE Symposium on Security and Privacy 2018
- [GOS06]
- EUROCRYPT 2006
- [CHJ+22]
- IEEE Access 2022
- [BLSW24]
- ASIACRYPT 2024
- [Ped91]
- CRYPTO 1991
- [Sch91]
- Journal of Cryptology 1991
- [FS86]
- CRYPTO 1986
- [BCC+16]
- EUROCRYPT 2016
- [CGJKR99]
- CRYPTO 1999
- [DG23]
- EUROCRYPT 2023
- [GOP+22]
- EUROCRYPT 2022