References: Our main references for PLUME are this ERC draft, Aayush’s blog post, and the ZK-nullifier-sig repo.

PLUME Challenge Point Redefinition:

One of the most expensive parts of the PLUME circuit is computing

$$ c = \text{hash}(g, pk, h, \text{nul}, g^r, h^r) $$

because the SHA256 hash is SNARK-unfriendly. Moving this computation out of circuit would greatly decrease the circuit size at low cost to the Verifier.

The role of $c$ in the circuit is as a Fiat-Shamir challenge point. It binds the Prover to all data that precedes the Verifier challenge step. In this case, that data is $pk, h, \text{nul}, g^r, h^r$.

We propose the following redefinition of $c$:

$$ c = \text{hash}(\text{nul}, g^r, h^r) $$

Before justifying the definition, we explain how this allows us to move computation of $c$ uout of circuit:

Justification:

Since $\text{nul}$ is already binding to $h, pk$, there is no loss of “bindingness” in removing these from the definition of $c$, so long as $\text{nul}$ remains.

The addition of $g^r, h^r$ to the set of public inputs does not sacrifice privacy, since $r$ is distributed randomly. Note that the constraint

$$ \text{nul}^c*h^r = h^s $$

with $\text{nul}, c, h^r$ public inputs implies that $h^s$ is now a public quantity. Because $s$ is distributed randomly, this does not sacrifice privacy.

$\text{nul}$ Binds to h, pk:

The constraint $\text{nul}^ch^r = h^s$ is interpreted as “Prover knows discrete log of $\text{nul}^ch^r$ with respect to $h$.” This is non-trivial because $c$ is binding to $\text{nul}, h^r$. The implication is that the Prover knows the discrete logs of $\text{nul}$ and $h^r$ separately. Moreover, the use of the same values $c, s$ as appeared in $pk^c = g^s*g^r$ implies that the discrete log of $\text{nul}$ with respect to $h$ equals that of $pk$ with respect to $g$. That is, $\text{nul} = h^{sk}$.

Thus these two constraints bind $\text{nul}$ to $h$, which in turn was computed in circuit as $\text{hash}(pk, m).$