Cryptographic primitives
We start by describing a number of cryptographic building blocks that are essential for the operations of privacy-preserving payment systems.
Commitment schemes: Commitment schemes allow a party (committer) to commit to a chosen message (chosen statement) while keeping it hidden to others, with the ability to reveal the committed value later. Commitment schemes consist of three operations:
- • params ^ Setup(k), a randomized setup algorithm given input by a security parameter k, and outputting public parameters to be used for the computation of the commitment
- • Cr ^ Commitparams r(m), where a commitment on message m is computed using randomness r
- • (r, v) ^ DeCommitparams(Cr), where the committer opens the commitment to a verifier who can then validate it.
Commitment schemes are designed so that they satisfy the following two properties:
- • Binding: Given a commitment Cr to a message m, the committer cannot change the value or statement m they have committed to. That is, they cannot construct another message m' = m such that m' ^ DeCommitparams(Cr).
- • Hiding: Given a commitment value Cr to a message m, the attacker should not be able to retrieve m.
For the schemes described below, Pedersen commitments [22] will be used, where the hiding property is guaranteed against an information theoretic attacker (information theoretically hiding), and the binding property is guaranteed against a computational attacker (computationally binding).
Zero Knowledge Proofs of Knowledge and Signatures of Knowledge: Proof of knowledge protocols allow a party (prover) to prove that a statement is true to another party (verifier) (e.g., that a value v is part of a language L). Zero- knowledge proofs of knowledge enable the prover to achieve the same property without revealing anything else to the verifier apart from the fact that the statement holds.
Most privacy-preserving payment systems built atop Bitcoin use zero-knowledge proofs of knowledge (ZKPoK), and in particular protocols where the prover proves knowledge of a committed value v, without leaking any information on v. In this chapter, we leverage the ZKPoK schemes of Schnorr [23] and its extensions [24-27], and convert them to noninteractive signatures of knowledge [28] using the Fiat-Shamir heuristic [27].
In signature of knowledge schemes, the knowledge of the secret committed value v is used as signing key. The unforgeability property of these schemes implies that no one but the party that has knowledge of v is able to provide a valid signature on any message m (i.e., a signature on m) that the signature verification algorithm accepts.
In the following, we will use the notation of Camenisch and Stadler [25,28,29] when referring to these proofs. Namely,
![]()
denotes a noninteractive zero-knowledge proof of knowledge of the elements a and в that satisfy both h = ga and c = ge. All values not enclosed in ()s are known to the verifier. Similarly, the extension
![]()
indicates a signature of knowledge of a and в on message m.
Accumulators: Cryptographic accumulators basically constitute one-way membership functions; these functions can be used to answer a query whether a given candidate belongs to a set without revealing any meaningful information about the other set members. For the rest of the chapter, we will be referring to the accumulator Acc introduced by Camenisch and Lysyanskaya [30] that supports the following operations:
- • {N, u} ^ ACC.Setup(k). On input a security parameter k, sample primes p and q (with polynomial dependence on the security parameter), Setup computes the RSA modulus N = pq and chooses value u G QRN, = 1. Finally, Setup outputs (N, u), which will be denoted by params.
- • {Acc} ^ ACC.Accumulate(params, PN). On input params and a set of prime numbers PN = {pi,...,pn|pj g [A,B]}, where A,B can be chosen with arbitrary polynomial dependence on k, as long as 2 < A and B < A2 , ACC. Accumulate computes the accumulator Acc = p1p2 • • • pn ( mod N).
- • ш ^ ACC.GenWitness(params, v, PN). On input params = (N, u), a set of prime numbers PN as described above, and a value v g PN, the witness ш is the accumulation of all the values in Acc besides v (i.e., ш =
ACC.Accumulate(params, Acc|v)).
• {0,1} ^ ACC.Verify(params, Acc, v, ш). On input params (N, u), an element v, and witness ш, ACC.Verify computes Acc' ^ шv(modN) and outputs 1 if and only if Acc' = Acc, v is prime, and v G [A, B].
Accumulators in [30] satisfy the strong collision-resistance property if the strong RSA assumption is hard. Informally, this ensures that no computational adversary can produce a pair (v,w) such that v PN and yet ACC.Verify is satisfied. In fact, in [30], Camenisch and Lysyanskaya describe an efficient ZKPoK scheme that proves that a committed value is contained in an accumulator. We refer to the proof in [30] using the following notation:

As described before, the Fiat-Shamir heuristic [27] can be used to convert this scheme to a noninteractive signature of knowledge.
ZK-Snarks: ZK-SNARKs [31] is a special kind of succinct noninteractive argument of knowledge (SNARK). The latter is a cryptographic primitive that enables a prover to argue that a certain statement satisfies an arithmetic circuit. Similar to signatures of knowledge, ZK-SNARKs are publicly verifiable and ensure zero- knowledge properties.
In what follows, we informally define ZK-SNARKs for arithmetic circuit satisfiability. We refer the reader to [31] for a formal definition.
Let Fa field, and an arithmetic circuit C with bilinear gates. We say that C is a F-arithmetic circuit when its inputs and outputs are elements residing in F. To capture nondeterminism, nondeterministic circuits with input x e Fn, are enhanced with an auxiliary input a e Fh, also known as witness.
The arithmetic circuit satisfiability problem for an F-arithmetic circuit, C : Fn x Fh ^ Fl, relates to the finding of input values (x, a) e Fn x Fh, such that
the output of the gates of C output 0 and can be well represented by the relation

and its language:
![]()
Assuming a field F, a (publicly verifiable preprocessing) ZK-SNARK for an F-arithmetic circuit satisfiability consists of the following algorithms:
- • (pk, vk) ^ KeyGen(A, C), which on input a security parameter A and circuit C, generates a proving key pk and verification key vk, that can henceforth be considered as the public parameters of the system.
- • n ^ Prove(pk, x, a), where with input a proving key pk, a pair of input x, and witness a, where (x, a) e Rc, the prover outputs a noninteractive proof n, that input x is part of C satisfiability language Lc.
• accept/reject ^ Verify(vk, x, l) where the verifier using verification key vk, and proof n for input x, confirms that x e LC (accept), or outputs an error message (reject).
Informally, ZK-SNARKs satisfy the following properties:
Completeness Here, it is required that for any statement that is a member of the circuit language, LC, an honest prover running Prove should be able to convince the verifier; that is, Verify should not output an error message.
Succinctness This property ensures that Prove and Verify run in a number of steps polynomial to the security parameter A.
Proof of knowledge This property ensures that the verifier can only accept proof outputs of a computationally bounded prover running Prove if and only if the prover knows a valid witness for the provided input.
Perfect zero knowledge Based on this property, no information on the secret statements or witnesses is revealed to the verifier. More formally, zero knowledge requires that for a given Verify transcript there is a simulator simulating KeyGen and Prove whose outputs cannot be distinguished from honestly executing KeyGen and Prove.