New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pay-to-verification-key payments #2425
Comments
This is good stuff! Clarification Can you explain this more:
What is 'them'? Use Cases What I'd like to do is sketch out designs for implementing these cases on top of this proposal so that we're sure we're capturing the requirements for these use cases:
Parameterization: If we use those cases as strictly defining of the requirements, then we may nail down a specific set of predicate inputs to meet those cases. Some of these inputs are within the note commitment (eg hash image requirement), and some are public consensus values (eg block height). OTOH, that may preclude some smart contracts we're not thinking of. So now I'm wondering what if the note commitment contains both the predicate's verification key commitment, and then it also contains an arbitrary 'predicate parameter input' that might be a large arbitrary bitfield. We then see if we can sensibly pack the committed inputs for different cases there. For example, for an XCAT-like predicate there's Along the same lines, we may with to provide a lot of public consensus parameters to enable a broader range of smart contracts: block height, arbitrary coinbase data, difficulty level, coin supply, shielded coin supply. Privacy In terms of privacy, this would add a distinguisher of at least the verification key. Can we nail this down so that only the verification key is the only distinguisher? Furthermore, this is only disclosed on spending the input, so the privacy is similar to MAST (https://github.com/bitcoin/bips/blob/master/bip-0114.mediawiki) in that on a spend the predicate is revealed. (The obvious difference here is that the details of the predicate are not disclosed in our scheme.) Transitive Predicates There may be some new valuable applications that rely on transitive predicates where |
Them is the verification keys. I originally thought that it would be feasible to randomize them in the circuit, but after some calculations it seems far too inefficient. As such, your statement...
... is correct. The verification key will be distinguishable. I am pretty sure everything else can be kept indistinguishable though, yes. |
I've been working a little harder to figure out how to achieve full indistinguishability of the verification keys, which would be nice if it were possible. As in #2247, we rely on a modified form of Jens Groth's 2016 protocol that extends the CRS such that all possible circuits (of reasonable size) may rely on fixed I take an additional step now to evaluate Now, only The question now is: can we efficiently randomize |
I estimate that G1 affine point additions can be performed about as efficiently as SHA256 hashes are, which isn't too bad, but leads me to believe we will need to split the "randomization" off into another circuit so that users that aren't using pay-to-verification-key don't have to pay for it. I believe we can allow for 128-bit scalar multiplications of delta in the circuit through the use of precomputed window tables queried with merkle tree lookups. 16-bit window tables would require around 155 CRH's and 7 G1 point additions, which puts it at around 100 - 300k constraints depending on the CRH used. |
IIUC that we need a common format for public and private parameters to the predicate circuits. Those public parameters are at risk of compromising distinguishability if directly exposed in a transaction. Brainstorms of kinds of predicate inputs: a. secrets committed to within a note. Examples: blockheight lock, multisig pubkeys. (*) A block height attestation is an integer, Imagine one or more predicates rely on block height attestations. For indistinguishability, every transaction must either include a block height attestation, even if most transactions are not predicated on block height. The same is true of every general "consensus-enforced attestation". This seems to limit some of the expressiveness of these predicates: either we must anticipate all of them in advance, or we must sacrifice indistinguishability for this kind of input. |
One solution is to have, as part of this interface, a merkle tree (or other layered commitment) of information that we anticipate these scripts will need. If we want to change the consensus rules and supply even more information, we can do so without changing the interface or affecting the scripts. |
More thoughts on category b - "generalized consensus-enforced attestation inputs": We should scour all of the "blockchain query" style opcodes from Ethereum and see which are applicable to Zcash blockchain as one way to anticipate which of these would be useful. A quick stab based on this list:
There are some other Ethereum queries that could be adapted for Zcash, but that feels too radical to me, atm. For examples:
We could expose the coinbase recipients and/or fee amount? (Not clear to me which helpful use cases this enables.) Thinking along the same lines of expanding the potential use cases by exposing more and more consensus inputs:
Anyway this all feels very speculative except for the first batch (block height, timestamp, difficulty). |
Remember that the inputs to the proof are fixed at the time the proof is created. This means it is not possible to pass in things like the current block height or hash. You can pass in a "minimum" block height or something like that, and the outside consensus rules can guarantee it's sensible. I think you can pass in some normalized version of the transaction itself so that you can do covenants and other such things. |
Hey, I noticed something here that's incongruous with how I think of Bitcoin and I'm curious why there is a difference: IIUC, this feature proposal places a predicate that's scoped to an address, whereas Bitcoin Oh, I guess multisig Bitcoin addresses are an example of address-scoped predicates? |
It's possible to make pay-to-verification addresses indistinguishable from vanilla shielded addresses to the payer. (Recall that it's only when funds are spent from a pay-to-verification address that the verification key comes into play.) Consider the scheme in #2277 (comment) , which has:
Change vk to be PRFvkak(verification_key). This allows the circuit [*] to check that verification_key, given as a private input, matches the randomized verification key that is made public in the spend description. The signature proving knowledge of ρ.sk and the address diversification work exactly as they do for vanilla shielded addresses. [*] I'm assuming that pay-to-verification spends will have a second circuit that is like the main Sapling spending circuit but also has the randomization check. Something like that seems to be necessary to guarantee that balance is preserved, without encumbering the main circuit with the expense of randomization. |
[Deleted incorrect comment.] |
Is P2VK necessary for shielded XCAT in Sapling (using just z-addresses and hiding the ZEC amount)? |
This needs a lot of product validation to see if this should be implemented and if so, how. |
One of the features of the Sonic proving system is that the circuit-specific verification key is publicly derivable. I haven't explored this entirely, but it is also possible to perfectly blind the result so that circuits are indistinguishable from each other. This would allow us to achieve p2vk payments without downstream users needing to perform their own trusted setups. In fact, exploring this feature is partly responsible for how we managed to turn Sonic into a SNARK. |
I think we shouldn't do this in NU3 for the following reasons:
|
The idea of "paying to a verification key" was floated around in discussions a year ago surrounding #608 but never really written up. Ian recently revived it.
Essentially, add an additional field to the note commitment which commits to a zk-SNARK verification key. Inside of the zk-SNARK we will need to "randomize" them with a secret
r
and reveal the randomized key through a public input to the circuit. The outside consensus rules can verify this zk-SNARK, given additional contextual inputs like the block height and other things that may be useful to scripts.I believe this allows us to support, in one fell swoop, private multisig, private HTLC, BOLT, and other exotic payment schedules and protocols that we've discussed before. It also comes at significantly less up-front engineering effort; we can have a Sapling hardfork in the pipeline while we're designing a multisig interface.
I think this is much preferable to hardcoding in specific workflows for particular protocols, which additionally complicates security proof and analysis.
The text was updated successfully, but these errors were encountered: