diff --git a/docs/sidebars.js b/docs/sidebars.js index 8adb514e2f..a8da0fce1d 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -301,6 +301,11 @@ module.exports = { id: "developing/runtime-facilities/sysvars", label: "Sysvar Cluster Data", }, + { + type: "doc", + label: "ZK Token Proof Program", + id: "developing/runtime-facilities/zk-token-proof", + } ], }, { diff --git a/docs/src/developing/runtime-facilities/zk-docs/ciphertext_ciphertext_equality.pdf b/docs/src/developing/runtime-facilities/zk-docs/ciphertext_ciphertext_equality.pdf new file mode 100644 index 0000000000..6a8668f594 Binary files /dev/null and b/docs/src/developing/runtime-facilities/zk-docs/ciphertext_ciphertext_equality.pdf differ diff --git a/docs/src/developing/runtime-facilities/zk-docs/ciphertext_commitment_equality.pdf b/docs/src/developing/runtime-facilities/zk-docs/ciphertext_commitment_equality.pdf new file mode 100644 index 0000000000..7e94932dee Binary files /dev/null and b/docs/src/developing/runtime-facilities/zk-docs/ciphertext_commitment_equality.pdf differ diff --git a/docs/src/developing/runtime-facilities/zk-docs/pubkey_proof.pdf b/docs/src/developing/runtime-facilities/zk-docs/pubkey_proof.pdf new file mode 100644 index 0000000000..d202543644 Binary files /dev/null and b/docs/src/developing/runtime-facilities/zk-docs/pubkey_proof.pdf differ diff --git a/docs/src/developing/runtime-facilities/zk-docs/twisted_elgamal.pdf b/docs/src/developing/runtime-facilities/zk-docs/twisted_elgamal.pdf new file mode 100644 index 0000000000..6f577224cb Binary files /dev/null and b/docs/src/developing/runtime-facilities/zk-docs/twisted_elgamal.pdf differ diff --git a/docs/src/developing/runtime-facilities/zk-docs/zero_proof.pdf b/docs/src/developing/runtime-facilities/zk-docs/zero_proof.pdf new file mode 100644 index 0000000000..1415a5d8a9 Binary files /dev/null and b/docs/src/developing/runtime-facilities/zk-docs/zero_proof.pdf differ diff --git a/docs/src/developing/runtime-facilities/zk-token-proof.md b/docs/src/developing/runtime-facilities/zk-token-proof.md new file mode 100644 index 0000000000..4127409eeb --- /dev/null +++ b/docs/src/developing/runtime-facilities/zk-token-proof.md @@ -0,0 +1,122 @@ +--- +title: ZK Token Proof Program +--- + +The native Solana ZK Token proof program verifies a number of zero-knowledge +proofs that are tailored to work with Pedersen commitments and ElGamal +encryption over the elliptic curve +[curve25519](https://www.rfc-editor.org/rfc/rfc7748#section-4.1). The program +was originally designed to verify the zero-knowledge proofs that are required +for the [SPL Token 2022](https://spl.solana.com/token-2022) program. However, +the zero-knowledge proofs in the proof program can be used in more general +contexts outside of SPL Token 2022 as well. + +- Program id: `ZkTokenProof1111111111111111111111111111111` +- Instructions: + [ProofInstruction](https://github.com/solana-labs/solana/blob/master/zk-token-sdk/src/zk_token_proof_instruction.rs) + +### Pedersen commitments and ElGamal encryption + +The ZK Token proof program verifies zero-knowledge proofs for Pedersen +commitments and ElGamal encryption, which are common cryptographic primitives +that are incorporated in many existing cryptographic protocols. + +ElGamal encryption is a popular instantiation of a public-key encryption scheme. +An ElGamal keypair consists of an ElGamal public key and an ElGamal secret key. +Messages can be encrypted under a public key to produce a ciphertext. A +ciphertext can then be decrypted using a corresponding ElGamal secret key. The +variant that is used in the proof program is the +[twisted ElGamal encryption](https://eprint.iacr.org/2019/319) over the elliptic +curve [curve25519](https://www.rfc-editor.org/rfc/rfc7748#section-4.1). + +The Pedersen commitment scheme is a popular instantiation of a cryptographic +commitment scheme. A commitment scheme allows a user to wrap a message into a +commitment with a purpose of revealing the committed message later on. Like a +ciphertext, the resulting commitment does not reveal any information about the +containing message. At the same time, the commitment is binding in that the user +cannot change the original value that is contained in a commitment. + +Interested readers can refer to the following resources for a more in-depth +treatment of Pedersen commitment and the (twisted) ElGamal encryption schemes. + +- [Notes](./zk-docs/twisted_elgamal.pdf) on the twisted ElGamal encryption +- A technical + [overview](https://github.com/solana-labs/solana-program-library/blob/master/token/zk-token-protocol-paper/part1.pdf) + of the SPL Token 2022 confidential extension +- Pretty Good Confidentiality [research paper](https://eprint.iacr.org/2019/319) + +The ZK Token proof program contains proof verification instructions on various +zero-knowledge proofs for working with the Pedersen commitment and ElGamal +encryption schemes. For example, the `VerifyRangeProofU64` instruction verifies +a zero-knowledge proof certifying that a Pedersen commitment contains an +unsigned 64-bit number as the message. The `VerifyPubkeyValidity` instruction +verifies a zero-knowledge proof certifying that an ElGamal public key is a +properly formed public key. + +### Context Data + +The proof data associated with each of the ZK Token proof instructions are +logically divided into two parts: + +- The context component contains the data that a zero-knowledge proof + is certifying. For example, context component for a `VerifyRangeProofU64` + instruction data is the Pedersen commitment that holds an unsigned 64-bit + number. The context component for a `VerifyPubkeyValidity` instruction data is + the ElGamal public key that is properly formed. +- The proof component contains the actual mathematical pieces that + certify different properties of the context data. + +The ZK Token proof program processes a proof instruction in two steps: + +1. Verify the zero-knowledge proof data associated with the proof instruction. +2. If specified in the instruction, the program stores the context data in a + dedicated context state account. + +The simplest way to use a proof instruction is to execute it without producing a +context state account. In this case, the proof instruction can be included as +part of a larger Solana transaction that contains instructions of other Solana +programs. Programs should directly access the context data from the proof +instruction data and use it in its program logic. + +Alternatively, a proof instruction can be executed to produce a context state +account. In this case, the context data associated with a proof instruction +persists even after the transaction containing the proof instruction is finished +with its execution. The creation of context state accounts can be useful in +settings where ZK proofs are required from PDAs or when proof data is too large +to fit inside a single transaction. + +## Proof Instructions + +The ZK Token proof program supports the following list of zero-knowledge proofs. + +#### Proofs on ElGamal encryption + +- `VerifyPubkeyValidity`: + + - The ElGamal public-key validity proof instruction certifies that an ElGamal + public-key is a properly formed public key. + - Mathematical description and proof of security: + [[Notes]](./zk-docs/pubkey_proof.pdf) + +- `VerifyZeroBalance`: + + - The zero-balance proof certifies that an ElGamal ciphertext encrypts the + number zero. + - Mathematical description and proof of security: + [[Notes]](./zk-docs/zero_proof.pdf) + +#### Equality proofs + +- `VerifyCiphertextCommitmentEquality`: + + - The ciphertext-commitment equality proof certifies that an ElGamal + ciphertext and a Pedersen commitment encode the same message. + - Mathematical description and proof of security: + [[Notes]](./zk-docs/ciphertext_commitment_equality.pdf) + +- `VerifyCiphertextCiphertextEquality`: + + - The ciphertext-ciphertext equality proof certifies that two ElGamal + ciphertexts encrypt the same message. + - Mathematical description and proof of security: + [[Notes]](./zk-docs/ciphertext_ciphertext_equality.pdf)