A range proof in the context of inner product arguments is a proof that the scalar has been committed to and is less than for some non-negative integer .
This article shows how the Bulletproofs paper constructs such a proof. The high level idea is that if we can prove that a vector consists only of ones and zeros and that is the binary representation of , then must be less than . This is analogous to saying that a number that fits in an 8 bit unsigned integer must be less than 256.
The advantage of using Bulletproofs for range proofs is that the range proof can be directly constructed without the need of an arithmetic circuit.
Monero uses Bulletproof Range Proofs (the algorithm presented here) to ensure that the sum of transactions is not negative (in a finite field, the negative numbers are the elements greater than as they are additive inverses of the elements less than or equal where is the field order).
This article is part of a series on ZK Bulletproofs.
Notation
is an dimensional vector of all zeros.
is an dimensional vector of all ones.
is an dimensional vector
is an dimensional vector
is an dimensional vector
Note that .
Range proof overview
Proving that is a commitment to a scalar with a value less than requires proving the following:
- is binary (only holds values and ).
- The inner product .
The second point is easy to prove, we do a normal inner product proof then reveal is one of the vectors in the commitment – or have the verifier construct the commitment of themselves. However, proving that is binary without an arithmetic circuit requires a couple algebraic tricks.
Four useful tricks
The bulletproofs paper implicitly uses four algebraic tricks that are best taught explicitly before looking at the range proof algorithm directly.
1. Proving is binary
The statement is binary is equivalent to the following two assertions:
For example, if then .
In this case, because
Now consider a case where is not binary, for example . will be The Hadamard product of and will be .
More generally, if has a non-binary entry, that entry will be subtracted by , and the resulting entry in will be non-zero. When the Hadamard product is computed, then at that particular index, and will both be non-zero and the product will be non-zero, meaning .
However, if a particular entry in is , then will be at that index so that the Hadamard product at that index will be zero, too.
Finally, if a particular entry in is , then will be at that index and their element-wise product will still be zero at that index.
Therefore, if is binary and is computed as , then .
2. Proving a vector is all zero
Suppose we wish to prove that the Pedersen commitment holds a zero vector. We create the Pedersen commitment and wish to prove to a verifier that .
It might seem sufficient to simply send the blinding term , but to make our solution more composable, we do not want to reveal the blinding term because that might affect other commitments we have created.
Instead, the prover sends to the verifier, and the verifier responds a vector full of random values . The prover must now prove that
Note that this is a probabilistic test. It is possible, with negligible probability, that for , but it is not possible for the prover to forge such an because they do not know in advance what will be.
However, transmitting requires communication overhead, so the verifier instead only sends a single random element and the prover computes and uses as a the random vector.
Then, the prover proves that .
We don’t yet have a mechanism to prove that , as that is a Hadamard product, not an inner product. However, stating the vector is identically is the same as stating that . By the inner product rules, we can move to the other side of the inner product and we now have .
The verifier will receive commitments to and , not . It will be up to the verifier to construct a commitment to so they are convinced the prover used as the second vector in the inner product.
The key trick we rely on is that the prover uses the basis vectors and to commit their vectors, but the verifier uses and .
When the prover sends the evaluation , the prover must ensure that terms will cancel with the in the verifier’s basis vector .
Specifically, the prover constructs the commitments
And sends to the verifier. There is no need to commit and send because it is zero in this case.
The prover’s polynomials will be
Crucially, the prover has Hadamard multiplied by . Previously, was computed as (without the . This will later allow all of the terms to be canceled when the verifier computes the commitment . Under the hood, is so the will cancel when the verifier computes , i.e.
However, the prover cannot compute or yet because the verifier hasn’t sent yet. Therefore, after receiving the verifier sends and the prover computes and computes the polynomial :
where
The prover commits to the coefficients and as
and sends to the verifier. The verifier responds with and the prover evaluates the vector polynomials and :
Note that only includes the blinding terms for and . In the previous implementation, was computed as , where is the blinding term for , which is also the constant coefficient of the polynomial .
There is no blinding term because there is no commitment to , i.e. is not secret – it is . The prover sends and the verifier checks that:
The first crucial difference is that the commitment to is done with respect to the basis vector instead of for the reasons discussed earlier.
Second, has no constant commitment. Normally, the equation is , but is a commitment to in this case.
In general, if contains values known to the verifier, the verifier can construct the commitment to as we show in the next section.
4. Proving an inner product when an additive public constant is involved
As alluded in the section above, the verifier can reconstruct commitments if the verifier knows the underlying vector.
For example, suppose we are proving that
where and are a vectors known to the verifier and is a scalar known to the verifier in advance. Unlike , these vectors and scalar are known before the proof begins. Note that is not Hadamard multiplied by in this example.
The prover still only commits to the secret values , and as usual:
As usual, the polynomials and are such that the constant term is the vector from the original inner product and the linear terms are and . Upon receiving from the verifier, the prover computes and crafts but does not evaluate and :
Note that is not Hadamard multiplied with , but the linear term still is. We will show how the verifier handles this later.
For now, we compute as
where
Note that the constant term in is and not . The commitments are computed as
and sent to the verifier who then sends the random value .
The prover computes:
Note that the constant term in is . The prover sends . Finally, the verifier computes:
and contain and respectively, but and do not. Hence, the verifier computes commitments to those vectors and adds them to the commitments and . In the case of , the basis vector will cause to become , so the commitment must be computed with respect to . Finally, the blinding term contains but does not contain . Therefore, the prover must multiply by .
By computing , and , the verifier can be sure the inner product computation actually included those terms.
Range proof
To prove that is a value less than we have three things to prove:
- the inner product , i.e. is the binary representation of
The last two claims are not directly in the form of an inner product. However, we can modify them slightly to accomplish this. What we are really saying is that the vectors
are both . We can use the trick from a previous section to prove that they are zero. That is, the the prover needs to establish that
and
where is the random vector derived from the value sent from the verifier.
The original bulletproofs paper slightly modifies the first claim as follows so that we can use the third trick in the previous section:
Therefore, the prover has three inner products to establish:
Combining three inner products into one
The three inner products can be combined into a single one using a random linear combination with randomness provided from the verifier.
With some very hefty inner product algebra, we can combine all the inner products as follows. We show the derivation in the appendix.
The terms in boxes below contain values known to the verifier, so we will construct our verification algorithm to explicitly check for those values. That is, the verifier will compute commitments to the values in the boxed terms, not the prover:
To save space, the Bulletproofs paper refers to the term as , so the inner product can be written as
Note that is a value the verifier can compute.
Range Proof Algorithm
The prover chooses and it’s binary representation and computes .
The prover then randomly chooses the blinding term and computes the combined commitment of and using basis vectors and as
The prover then chooses the linear terms of the soon-to-be-created vector polynomials and as and and commits to them
The prover commits the inner product to as with respect to of an unknown discrete log (unrelated to ):
The prover sends to the verifier.
The verifier responds with random values which the prover will use to combine the three inner products into a single one.
The left part of the inner product will be the constant term of and will be the constant term of .
Thus, we construct as
and we construct as
Note that we element-wise multiplied with for the reasons we discussed in part 3 of the prerequisites section above.
The prover can now construct with constant coefficient , linear coefficient and quadratic coefficient as:
where
The prover sends commitments to and as
There is no need to commit to – observe that it is exactly the inner product we are trying to prove, so the verifier already has the commitment as .
The verifier sends randomness and the prover computes
Note that the constant term of is multiplied by to reflect the term of the original inner product.
The verifier then computes a new basis vector and runs the following checks:
Recall that the prover did not commit the entire vectors they used for the left and right side of the inner product, but only and . The rest of the vectors were additive public vectors known to the verifier, so the verifier reconstructed the commitments to the vectors by constructing commitments to the constant terms and adding them to the commitment of the secret vectors supplied by the prover.
By way of reminder, here is the original inner product with the values known to the verifier boxed:
The reader is encouraged to verify that the boxed terms (values known to the verifier) in the original product were reconstructed by the verifier in the boxed terms in the set of equality checks above.
By replicating a portion of the prover’s computation, the verifier asserts that the prover actually carried out the computation as claimed.
Correctness of the verification algorithm
We now show that the final verification checks are identically correct if the prover was honest.
Below we show the exact algebra, but intuitively the verifier is “reconstructing” the left vector in the inner product , the right vector in the inner product and the output .
The verifier is not given commitments to and but to and . Similarly, the verifier is not given a commitment to the output but only to .
The additive terms and the terms element-wise multiplied by must be reconstructed by the verifier.
Correctness of
For the check, this is true by definition, as that is how the prover computed .
Correctness of the committed and with respect to and
For
we make the following substitution:
All the terms cancel as follows:
The blinding terms related to cancel as follows:
The cancels with the terms:
Split the inner products:
Cancel terms that appear on both sides of the equation:
Move to the other side:
Correctness of the evaluation of
To see that
is correct, we could substitute the terms as follows:
with , , , :
However, such algebra would be extremely messy. Instead, we observe that is the constant term of the vector polynomial inner product of of . To cancel out the blinding term in in , observe that contains , so this will cancel with the gamma term in .
Since Pedersen commitments are additively homomorphic, the verifier can simply compute and add to to compute the commitment to the constant term of the polynomial .
Logarithmic-sized range proof
We can reduce the size of the data transmission by sending a commitment to and and proving that the committed vectors have inner product using the logarithmic-sized proof, and then verifying that
and
with respect to the basis vectors and .
Using the range proof algorithm for the subset sum
The subset sum problem asks, "given a set of numbers, does a subset (possibly including the entire set) sum up to ? For example if and the set is the answer is yes because . However if , then the answer is no.
The subset sum problem is NP-Complete, meaning that, similar to a Boolean circuit or arithmetic circuit, it can represent any problem in NP. That is, any problem in NP can be rewritten (the technical word is “reduced”) to a subset sum instance.
By replacing with , we can prove we know a solution to a subset sum without revealing the answer. Specifically, the prover would know that if . In general, a one entry in means we include that element in the subset and a zero means it is not included in the subset.
Therefore, Bulletproofs are capable of proving knowledge of any witness for any problem in NP.
Appendix: Derivation of combining three inner products into one
Starting with the three inner products
we show how to derive the final result
using the inner product algebra we learned previously.
- The middle term can be split into separate inner products:
-
We can move the constant terms inside the inner products:
-
Move the values known to the verifier to the right:
- Convert the terms to both be :
- Combine the terms into one:
- Combine the two terms on the left:
- Split the last left-hand side term into two inner products:
- Combine the terms:
- We can use the rule to combine the terms that contain . Here is , is , and is .
- We now break up the terms on the right-hand side:
- Take the scalars out of the inner products on the right:
- Factor out :
Since , we have:
This completes the derivation.