What is Sacred?

How Sacred Works

Technical Details

Sacred Terminology

Other Sacred Info

How Sacred Boxes work

Sacred Rules to keep your deposit private

In the diagram above, an arrow represents a hash function (from input to output). Actually, this particular function (Poseidon function) takes in two inputs to produce one output; where it appears that there is only one input, the second input is the appropriate hash of 0,0; let P(x,y) be the Poseidon function with inputs x and y, then a node that is shown to only have one child c at level n is actually the hash of c and the hash of the hash of … the hash of (0,0), such that there are n recursive levels of hashing (or n+1 total hash operations). This can be represented as P(P(P(P(...P(0, 0)...), 0), 0), c) or P(P^n(0,0), c) where the “exponent” represents recursion.

Since the Poseidon function takes in two inputs, each root is actually the root of its own “virtual” binary tree; if there are n levels to the entire structure, then each root could be the root of a tree with 2^n leaves, which is a huge amount! However, this tree is never actually generated in its entirety (only the one branch leading to the current leaf) which serves to obfuscate the leaves. Since hashing only works in one direction, there is no way to compute the leaves from a given root; but it is possible to generate a path from a known leaf to a given root, and this path cannot be faked (only by computationally infeasible brute force).

When a user deposits tokens into a Sacred Box, it was mentioned that the user generates and adds a new leaf value. It is truer to say that the user generates two values, that we can call k and r, and a new Merkle root is computed from a leaf value of the hash of the concatenation of k and r.

To withdraw a deposit, a user must have generated a claim. This is a zk-SNARK of the path from the leaf to a given root (represented in dark blue) that is currently stored in the smart contract. However, this does NOT contain any information on the actual path taken, nor on the leaf involved. Purely, the user’s claim proves that there exists such a leaf and appropriate nodes; revealing this path would de-anonymize the withdrawal. This SNARK is sent to the Sacred Box, along with the nullifier h. By the nature of the functions, it is impossible to tamper with h (the SNARK will not work for a different value of h, because h is the hash of k); the contract will add the value h to a “list” of used nullifiers and check all subsequently submitted proofs to ensure that the h is not reused. Thus, it is impossible to claim the same deposit twice.

New leaves and their roots are added on the right, and the formula by which the tree is generated (it may seem chaotic in the diagram) is specifically designed such that you can get to any leaf from any later-generated root. The n-level structure is designed to support up to 2^n leaves (that’s a lot of leaves!). During implementation, the Sacred Box will store several of the latest roots (constantly cycling the oldest ones out for newer ones) to allow for the case where someone deposits just as someone else is calculating a SNARK.

Last modified 3mo ago

Copy link