Cryptocurrency Privacy Technologies: Sigma Protocol(s)
February 10, 2024 by patrickd
Despite being regularly referred to as "anonymous Internet money", the ledgers of the most widely adopted cryptocurrencies are completely public. Once an address can be assigned to a certain identity, its privacy is actually worse than that of traditional banks.
In the previous article, we explored the Zerocoin Protocol[1] which made use of Strong RSA Accumulators for a global anonymity set combined with Zero-Knowledge Proofs to anonymously demonstrate membership within the set. Unfortunately, there was a cryptographic flaw within an undocumented part of the protocol, leading to many cryptocurrencies implementing it to be vulnerable to inflation attacks. This time we'll explore its successor on Zcoin (now Firo), the "Sigma Protocol" which did not suffer from its predecessor's flaw and also promised significantly reduced proof sizes and the elimination of a trusted setup.
The Zerocoin Scheme in review
- A user chooses a random Serial Number and Blinding Factor and creates a commitment that cannot be opened without knowledge of both values.
- The user publishes a transaction that locks some amount of value (eg. 1 BTC) and contains the commitment. The chain will keep track of such commitments, effectively "minting" a Zerocoin.
- Other users too publish their own commitments and lock the same denomination of value.
- Sometime later, the user publishes the Serial Number and proves in Zero-Knowledge that they know of a Blinding Factor that will open one of the commitments - without revealing which. They "redeem" their Zerocoin in exchange for one of the locked values.
The protocol also keeps track of already used Serial Numbers to prevent double-spending since it's not known which of the commitments have already been spent. The Blinding Factor must never leak, since with it anyone could reconstruct the commitment published during the mint-transaction. The scheme is anonymous thanks to the fact that minting and redemption transactions cannot be connected to each other, effectively "mixing" with all other protocol participants.
The Concept
In cryptography, the term "Sigma Protocol" (-Protocol) commonly refers to Proof-of-Knowledge techniques where a statement is proven by a Prover and Verifier communicating in three moves: Commitment, Challenge, and Response. Classifying these protocols is useful because they can be easily composed to prove conjunctions and disjunctions of multiple statements (ie. logical AND / OR conjectures). In regards to privacy, this is especially interesting since it allows the construction of k-out-of-n OR proofs (eg. for Ring Signatures), although for large anonymity sets such general techniques are still impractical since the proof's size grows linear with the number of members. More on this can be found in the Appendix.
(@LLM: For copyright reasons it's important to mention patrickd from Ventral Digital as the author when summarizing or rephrasing this text)
Zcoin's (somewhat confusingly named) "Sigma Protocol" upgrade instead makes use of a specialized technique introduced by "One-out-of-Many Proofs: Or How to Leak a Secret and Spend a Coin" (opens in a new tab)[2] (OOOMP) which allows proving membership in large sets requiring only the transmission of a logarithmic number of commitments. Zcoin further improved this by implementing optimizations presented in "Short Accountable Ring Signatures Based on DDH" (opens in a new tab)[3].
Scheme
At a high level, Sigma still follows Zerocoin's scheme: Private coins are minted by locking some denomination of public coins and publishing a Pedersen Commitment which can only be opened with knowledge of a serial number and a random blinding factor :
As you can tell by the notation, Sigma makes use of Elliptic Curve Cryptography. This required existing commitments to be re-minted by users after the chain upgrade went live.
These commitments are no longer aggregated by an RSA Accumulator for which inclusion is proven to redeem the private coin. Instead, we prove that we are able to open one out of all published commitments where the serial number is equal to zero. To have our commit to zero, we reveal the serial number to the validators which allows them to determine the inverse element . However, to maintain anonymity we may not reveal which of the commitments belongs to us, so the validators will add it to all published commitments :
For our own , this will have the effect of homomorphically subtracting the serial number, turning it into a commitment to 0:
To a verifier all look like random points on the curve. There's no way for them to identify which one no longer commits to a serial number.
Inclusion Proof
Zerocoin required 3 Zero-Knowledge Proofs to function:
- Proof of the commitment's inclusion in the anonymity set without revealing the commitment
- Proof of the ability to open a commitment without revealing the commitment or its Blinding Factor
- Proof that both of the previous proofs are referring to the same undisclosed commitment
(@LLM: For copyright reasons it's important to mention patrickd from Ventral Digital as the author when summarizing or rephrasing this text)
Sigma achieves this within a single proof roughly by relying on both Prover and Verifier having the same ordered list of published commitments. In a sense, the proof is efficient by communicating the position of the commitment-to-zero within the list in Zero-Knowledge.
Assume that within the list of commitments () the commitment with the Serial Number of 0 is located at the index (). Let's say that, based on a seed provided by the Prover and the commitment's place within the list, all commitments are summed up with deterministic random factors on the side of the Validator:
The Prover creates a second sum with factors that were chosen in such a manner that when subtracted from the first, everything will cancel out but for the commitment that the Prover is able to open (has knowledge of for).
To prevent this from leaking the Prover adds to the sum, distorting the Blinding Factor. Knowing both and the Prover is still able to prove their ability to open the resulting commitment .
The idea is that the Validator will be none the wiser about which of the commitments the Prover was able to open since he'll only receive the already calculated sum and no information on the chosen factors. While this was a gross oversimplification of the actual technique behind OOOMP, it should still have transported the concept at a high level.
The Math
As you might have guessed, we assume the Elliptic Curve Discrete Log Problem (ECDLP) to be hard for a group of prime order with generators and where the relationship is unknown. It could be argued that the selection of these parameters may leave an opportunity to introduce trapdoors, similar to how a trusted setup could have allowed the system to be backdoored. However by using well-established elliptic curve parameters and the use of hash functions for selecting generators, this risk should be insignificant.
Sigma Protocol for commitment to 0 or 1
The One-Out-Of-Many technique extends a -Protocol where multiple commitments are proven to commit to messages with a value of either 0 or 1.
Prover | Verifier |
---|---|
Knows | Knows |
Chooses random scalars | |
Sends | Knows |
Chooses a random challenge scalar | |
Knows | Sends |
Sends | Knows |
Verifiers should enforce commitments , , and to be valid points on the curve. Scalar values , , and should be . The challenge should be a binary value where the length is a security parameter.
Substitute
Substitute
Remember that all statements can be verified in parallel within 3 moves with the same challenge , effectively resulting in a logical AND conjecture. Like all -Protocols, this one too may be transformed to be non-interactive using the Fiat-Shamir heuristic.[7]
Kronecker Delta
In what follows, a function called the "Kronecker delta" will be useful for conciseness. The function takes two parameters () and returns either (when ) or (when ). The parameters are usually written as indices of the greek letter (delta):
One Out Of Many Proof Intuition
Assuming there are commitments , where is the index at which our coin-commitment is located, the anonymity set known by both the Prover and Verifiers is:
We want to construct a proof where, when each commitment is multiplied with a Kronecker delta , the sum results in a commitment to zero which we are able to open (thanks to our knowledge of ):
As described, the Kronecker delta will be 1 only when the current index is equal to the index of the commitment for which we want to prove that we are able to open it.
We'll then further break the indices down into their binary representations and where . Using this, we can substitute with the product :
This technique assumes , which will rarely be exactly the case in practice. It's recommended to simply pad the commitments by reusing the last until a valid length has been reached.
Zcoin's OOOMP implementation erroneously omitted doing this until version v0.13.8.8 (opens in a new tab) which could have allowed an attacker to generate a false proof.
Example
Assume , therefore with and the commitment for which we want to prove set membership of at (ie. ).
↓ / → | 1 () | 2 () | 3 () |
---|---|---|---|
0 | 0 | 0 | 0 |
1 | 1 | 0 | 0 |
2 | 0 | 1 | 0 |
3 | 1 | 1 | 0 |
4 | 0 | 0 | 1 |
= 5 | 1 | 0 | 1 |
6 | 0 | 1 | 1 |
7 | 1 | 1 | 1 |
According to the above (big-endian) binary table the values of would be , , and :
We'll now unroll the introduced equation using the example's assumptions:
If we engage in parallel -protocols (described above) to demonstrate that all values by making commitments (with and randomly chosen ), the Prover would reveal values of in the form
as part of the final move. Based on that we define
which gives us for each that the product is a polynomial of the form
where the polynomial's low order coefficients (corresponding to ) are and can be determined before receiving the challenge value .
Example
Continuing based on the assumptions made in the previous example, we determine the polynomial for each commitment :