_The largest aspen grove consists of ~47,000 distinct trees with a shared root structure covering over 100 acres. It is one of the largest organisms in the world and believed to be at least 80,000 years old._

----

This library contains OCaml bindings to Zcash Sapling for the purpose of adding highly efficient zk-SNARKs to Tezos. The original Tezos white paper mentioned Zcash’s predecessor, Zerocash, as an example of technologies that could be easily grafted onto an extensible blockchain protocol.

Until now, generating a single zk-SNARK has taken as long as several minutes and several gigabytes of RAM. With Sapling the Zcash team has completely rewritten their zk-SNARK implementation in Rust using a new hashing algorithm, prover-verifier system, elliptic curves, and finite fields — generating proofs as small as 144 bytes in a matter of seconds on a commodity laptop. This allows even mobile devices to generate zero knowledge proofs and will hopefully bolster the prevalence of shielded transactions, resulting in greater collective privacy.

Sapling represents several years of research and development and the Tezos community can immediately benefit from it.

----

## Shielded Transactions

For transactions to be truly anonymous they must provide a commitment to transfer a quantity of XTZ in a manner that can be stored publicly on the blockchain and verified by third parties without revealing the identities of the sender or recipient. Such transactions are referred to as “shielded”.

Shielded transactions take the form of “cheques” (or "notes" in Zcash). Cheques consist of a value in satoshis, the address of the recipient, and a Pederson [commitment](https://en.wikipedia.org/wiki/Commitment_scheme). Commitments are generated separately for the value alone. [Pederson hashes](https://www.cs.cornell.edu/courses/cs754/2001fa/129.PDF) are also used for Merkle trees, which is responsible for much of the performance gains over SHA-256 in libsnark.

Each cheque also corresponds to a unique identifier, called a “hold” (or “nullifier” in Zcash), which is tracked in the mempool to prevent double spends.

Cheques may be associated with a 512-bit memo field, e.g. “Happy Birthday Alice, from Bob.”

Both the cheque and memo field are encrypted with a variant of the Salsa20 stream cipher along with a Poly1305 message authentication code. They can be decrypted with the full keypair generated by the recipient _or_ with either an “outgoing viewing key” or “incoming viewing key.” Viewing keys can be given to third parties without spending authority and thus facilitate the regulatory compliance required by entities like exchanges without compromising the privacy of individual users.

----

## Zero Knowledge Proofs

As mentioned, we must also prove a given transaction has taken place. We use both a “sign” proof (or "spend in Zcash), generated by the sender, and an “endorse” proof (or "output" in Zcash, similar to a “join split” in Zcash 1.0). A transaction has been completed once both can been verified.

Sapling uses a prover-verifier system designed by [Jens Groth](https://eprint.iacr.org/2016/260). In addition to producing smaller proofs in less time than previous zk-SNARK implementations, particularly when SNARKs are recursively composed, it has been the focus of recent research on security in the case when the common reference string (“trusted setup”) has been subverted. A [subsequent paper](https://eprint.iacr.org/2017/599.pdf) proved it has perfect subversion-resistant zero knowledge with computational soundness (under the subversion generic bilinear group model). If someone were to recover toxic waste from the multi-party ceremony (discussed below) the proofs may remain more secure than in previous zk-SNARK implementations.

zk-SNARKs are generated from systems of linear equations (“rank one constraint systems” or R1CS) encoded as arithmetic circuits. The **sign circuit** takes the following inputs:

- Domain parameters for the elliptic curve

- Pedersen commitment to the value being spent

- Proof generation key corresponding to a particular spending key

- Recipient address

- Random value used to generate the cheque commitment

- Value used for re-randomization in a signature scheme

- Authentication path of the commitment in the Merkle tree

- Merkle root (or "anchor in Zcash)

And for the **endorse circuit**:

- Domain parameters for the elliptic curve

- Value commitment

- Recipient address

- Random value used to generate the cheque commitment

- Private key generated by the recipient for use with Diffie–Hellman

Along with the verification key, the following publicly visible inputs are used to **verify a sign** proof:

- Signature

- Value commitment

- Merkle root

- Hold for the given cheque

And to **verify an endorse** proof:

- Value commitment

- Public key corresponding to the private key used to generate the proof

- Cheque commitment

A signature scheme is used so a device limited in computation and/or memory, e.g. hardware wallets, can delegate proof generation to a third party without exposing their spending key (not currently implemented in this library). The signature is obtained by re-randomizing the address portion of the spending key. This is discussed in the section below on key derivation.

Sapling uses several distinct keys. Understanding the relationship between them, pictured above from the ZCash specification, is helpful for understanding how to use this library. Keys are represented in OCaml as phantom types and can be printed or converted to arrays of 8-bit integers. Many of the keys listed above are not exposed.

Generating a new spending key will return a proof generation key and outgoing viewing key. There’s also an option to generate a “blind spending key”, which only returns a proof generation key. This means cheques cannot be decrypted once the sender has deleted their local copy, which can be useful for operational security if the sender's account becomes compromised.

The proof generation key can be used to derive a full viewing key. The full viewing key can be used to derive an incoming viewing key or, along with an address group, a new address (see below).

Not included in the above diagram, the recipient also generates a key pair for use in the endorse circuit.

----

## Addresses

Shielded transactions use their own addresses, consisting of two parts: a shared address group and a unique address id. New addresses can be generated that share the same group, up to the birthday bound (a twist on a technique referred to as "key diversification"). These addresses cannot be linked to one another without knowledge of the full viewing key, but since they share an incoming viewing key they do not increase the time required to search for their transactions on the blockchain.

It is highly recommended that you **do not use vanity addresses** as they decrease the difficulty of correlating your transactions.

----

## Verification

Verification requires the proof ciphertext, verifying key, and public inputs. It returns `true` if the proof is sound. It’s important to distinguish between the verifier returning `false` due to an unsound proof and errors in verification.

The following errors are propagated through to OCaml:

```

AssignmentMissing -> "an assignment for a variable could not be computed"

UnconstrainedVariable -> "auxillary variable was unconstrained"

```

You shouldn’t see them since the inputs are abstract. If you do please file an issue.

----

## Common Reference String

zk-SNARKs use a common reference string, often referred to as a “trusted setup.” To comply with the recent standardization efforts for zero knowledge proofs (https://zkproof.org/) Sapling uses a _uniform reference string_, i.e. one that is uniformly random.

The CRS/URS is the same for all proofs, which work by embedding a “trap door” in it. The security of zk-SNARKs is contingent on this trap door remaining hidden. If the CRS wasn’t constructed properly then an attacker could potentially reverse engineer the trap door from the string itself. This is why participants in Zcash’s first ceremony went to such lengths to publicly (and theatrically) demonstrate both that no one could have interfered with the randomness they had contributed and that it wasn’t saved after the ceremony was completed. These random inputs are often referred to as “toxic waste.” If the toxic waste from every participant was recovered then the CRS would be compromised.

Sapling uses a [much more sophisticated multi-party computation](https://eprint.iacr.org/2017/1050), the largest to date with [88 participants](https://github.com/ZcashFoundation/powersoftau-attestations). Each participant sampled their own randomness and used it to perform a computation with the output of the previous participant’s. After each step, the results were made public. A “random beacon” is applied to the final result in order to achieve the uniformness noted above.

The scale of the Sapling multi-party ceremony makes it highly unlikely the CRS could be subverted and thus this library uses the same string as Zcash.

(** Returns a new fresh proof generation key. Without an outgoing viewing key cheques cannot be decrypted by sender. Not referentially transparent. **)