Skip to content
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

ZIPs 226 & 227 - ZSA Protocol: Transfer, Issuance and Burn #680

Closed
wants to merge 43 commits into from

Conversation

PaulLaux
Copy link
Contributor

@PaulLaux PaulLaux commented Mar 23, 2023

This PR continues the discussion from the outdated #649.

Content:

zip-0227.rst Outdated Show resolved Hide resolved
zip-0227.rst Show resolved Hide resolved
zip-0226.rst Outdated
+-----------------+-------------+-----------------------------------+-------------------------+
| 40*nAssetBurn | vAssetBurn | bytes[40][nAssetBurn] | 32 bytes Asset type_t, |
| | | | 8 bytes of valueBalance |
+-----------------+-------------+-----------------------------------+-------------------------+
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to limit nAssetBurn to some maximum, so that it's clear the scalar field can't overflow, see the calculations in section 4.14 of the protocol spec. It's not really necessary because transactions are limited to 2MB anyway.

@defuse
Copy link
Contributor

defuse commented Mar 24, 2023

How would pool migrations work with shielded assets? I'm guessing that AssetIDs could be shared across pools and the consensus rules could be extended to allow burns in the Orchard pool to create coins of the same AssetID in the new pool automatically. We might want to have that spec'd out in case there's ever an urgent need to switch pools (e.g. security vulnerability) even if we don't implement it now.

One difficulty with this is that some asset issuers might want their assets to remain in one pool, so they'd want to sign some kind of approval before the consensus rules start allowing transfers. But other asset issuers might lose their private key, and then get unintentionally stuck in an old pool.

zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated Show resolved Hide resolved
zip-0226.rst Outdated

In essence, the burn mechanism is a transparent / revealing extension to the transfer protocol that enables a specific amount of any Asset identifier to be sent into “oblivion”. Our burn mechanism does NOT send Assets to a non-spendable address, it simply reduces the total number of units of a given Asset in circulation at the consensus level. It is enforced at the consensus level, by using an extension of the value balance mechanism used for ZEC Assets.
.. math:: \mathsf{bvk = (\sum cv_i^{net})} - \mathsf{ ValueCommit_0^{Orchard}(v^{balanceOrchard})} - \sum_{\mathsf{assetBurn}} \mathsf{ValueCommit_0^{OrchardZSA}(AssetBase, v^{AssetBase}) } = \sum \mathsf{rcv_{i,j}^{net}}\mathcal{R}^{\mathsf{Orchard}}
Copy link
Collaborator

@daira daira May 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The \sums here should technically be the large diamond addition operator used in the spec. I know this is difficult to represent in Markdown; don't worry about it for now and I will include it as an image later.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As explained in § 4.14 Balance and Binding Signature (Orchard), the validators compute $\mathsf{bvk}$ one way, and the signer computes it another way.

zip-0226.rst Outdated Show resolved Hide resolved
@PaulLaux
Copy link
Contributor Author

We started a full top-to-bottom consistency check for both ZIPS by our new team member @AntoineRondelet, tracked here: QED-it#18. We all can expect a much more consistent documents once it is done.

@daira
Copy link
Collaborator

daira commented Jun 6, 2023

Summary of today's meeting:

We discussed the circuit constraints for split notes, specifically the constraints on the nullifier and $\mathsf{pk_d^{old}}$.

The old note commitment has to correspond to an existing note in order to confirm that the value base input to the commitment is correct for some issued asset (i.e. an output of the hash-to-curve). But the nullifier has to be something other than the nullifier for that note, so that the transaction will not be rejected as a double-spend.

The old note commitment fixes $(\mathsf{g_d^{old}}, \mathsf{pk_d^{old}}, \mathsf{v^{old}}, \mathsf{\rho^{old}}, \mathsf{\psi^{old}})$, and (if this is a non-native asset) the value base. If it is a native asset then the value base is constrained to be the base for ZEC.

Suppose that we keep the derived nullifier computation the same and still check that the derived nullifier corresponds to the public $\mathsf{nf^{old}}$; in that case, the only input to $\mathsf{DeriveNullifier}$ that is not fixed by the commitment is $\mathsf{nk}$. And changing $\mathsf{nk}$ (relative to the old note) leads to computing a different $\mathsf{ivk}$, therefore a different $\mathsf{pk_d^{old}}$, which would cause the Diversified address integrity circuit check to fail.

Qedit proposes (🇦) that the check that the derived $\mathsf{pk_d^{old}}$ matches the one from the commitment would be disabled for split notes.
I proposed (🇧) that the check that the derived nullifier matches the public $\mathsf{nf^{old}}$ would be disabled for split notes.

I think either of these can work. Constance said that 🇦 is simpler in terms of circuit changes. I said that I'd ask @str4d and @ebfull for their opinions.

While analysing both alternatives, I noticed that the current proposed circuit does not check that the split note flag is only set for non-native assets. I'm not sure this it's strictly necessary to check that, but I argued that it makes the analysis simpler because it cuts down the number of cases that must be considered. (Without this constraint, you'd have to consider both native and non-native cases for split notes.)

We also talked about whether it was necessary to prove knowledge of the $\mathsf{nk}$ of the original note when using a split note; I concluded that it was not.

There was also an issue of whether adding another check to the Orchard gate would require referencing the previous as well as next row. I wasn't sure whether that actually made any difference to performance, given that we reference the previous row in other gates. I said I would ask @ebfull about that.

@daira
Copy link
Collaborator

daira commented Jun 9, 2023

@ebfull and I looked at this in detail, and found that 🇧 is insecure against a roadblock attack. (See section 8.4 of the protocol spec or slide 24 of my Zcash security presentation at Zcon3, with video here, for discussion of roadblocks and other attacks against spendability.) The reason is that it would be possible for an adversary, who sees some transaction spending a victim note and then front-runs that transaction, to choose the same nullifier for a split note and block the victim note from ever being spent.

Unfortunately, approach 🇦 also falls to a more subtle roadblock attack that I just found. Let's try to prove it secure to see where the proof falls down. The reason why the existing protocol without ZSAs resists roadblock attacks, is that the nullifier can be viewed as being computed as a Pedersen hash that has independent bases for the scalar that an adversary could potentially control (that is, $(\mathsf{PRF^{nfOrchard}_ {nk}}(\rho^{\mathsf{old}}) + \psi^{\mathsf{old}}) \bmod q_ {\mathbb{P}}$), and for the inputs to the note commitment. Sinsemilla, used to compute $\mathsf{cm^{old}}$, reduces to a Pedersen hash with bases independent of $\mathcal{K}^{\mathsf{Orchard}}$. By collision resistance of this Pedersen hash assuming hardness of DL on Pallas, it is infeasible under that assumption to find matching nullifiers for distinct notes. (For Orchard, distinct positioned notes must have different note commitment inputs, and so we need not analyse the effect of note position.)

Without loss of generality we can assume that the attack targets a specific victim note; a similar argument applies even if it is targeting any of multiple notes. There are two cases for a roadblock using a split note:

  • The adversary chooses a split note that is different to the victim note. In that case it has different note commitment inputs, and so it is infeasible to make the nullifier match the victim note's nullifier by the above argument.
  • The adversary chooses the same note as the victim note, and therefore the same $\mathsf{cm^{old}}$. In that case, the possibilities are:
    • The adversary chooses a different $\mathsf{nk}$, which effectively randomises the nullifier making it infeasible to match the victim note's nullifier, under an assumption about second pre-image resistance of $\mathsf{PRF^{nfOrchard}}$ for chosen $\mathsf{nk}$. ($\rho^{\mathsf{old}}$ and $\psi^{\mathsf{old}}$ are the same as in the victim note by the binding property of the note commitment, under hardness of DL on Pallas.)
    • The adversary chooses the same $\mathsf{nk}$ and same $\mathsf{ak}$. In that case they would have to know $\mathsf{ask}$, making them authorized to spend the note, and so this is not a valid attack.

However, nothing prevents the attacker from choosing the same $\mathsf{nk}$, and different $\mathsf{ak}$ for which they know the corresponding $\mathsf{ask}$. This will derive the same nullifier, with different $\mathsf{ivk}$ and $\mathsf{pk_d}$. Because in approach 🇦 the derived $\mathsf{pk_d}$ is allowed to differ from the split note's actual $\mathsf{pk_d^{old}}$, this will not be prevented. So the adversary can roadblock any note that has not been spent yet, provided they know all of its fields — which they can if they have its incoming viewing key.

A solution would be to ensure that the adversary proves they would be authorized to spend the split note, checking $\mathsf{pk_d^{old}}$ as in the non-ZSA circuit. It is always possible to choose a split note that is one of the other notes of the same asset being spent in the same transaction, which is necessarily spendable by the transaction creator.

Then, to prevent the roadblock attack while still allowing the ZSA Action statement to be satisfied, we must have a different derivation for a split note's nullifier that still ensures collision resistance. The best way to do this I think (call this approach 🇨), is to compute the nullifier for a split note as $\mathsf{Extract}_ {\mathbb{P}}([(\mathsf{PRF^{nfOrchard}_ {nk}}(\rho^{\mathsf{old}}) + \psi^{\mathsf{nf}}) \bmod q_ {\mathbb{P}}] \mathcal{K}^{\mathsf{Orchard}} + \mathsf{cm^{old}} + \mathcal{L})$, where $\psi^{\mathsf{nf}}$ is allowed to be different to $\psi^{\mathsf{old}}$ and $\mathcal{L}$ is an independent base. Adding $\mathcal{L}$ effectively acts as a domain separator that makes all split note nullifiers distinct from non-split note nullifiers (for real notes or ZEC dummy inputs), while $\psi^{\mathsf{nf}}$ can be varied to ensure that split note nullifiers derived from the same note are different from each other and appear random. As a bonus, the privacy of all nullifiers remains statistically secure if $\psi^{\mathsf{nf}}$ is chosen uniformly at random. The additional constraint would be that either the split note flag is set or $\psi^{\mathsf{nf}} = \psi^{\mathsf{old}}$.

It would also have been possible to add $[r] \mathcal{L}$ for some random nonzero $r$, but that would require an additional scalar multiplication. Although we compute the nullifier using $\mathsf{cm^{old}}$ which is the result of a Sinsemilla commitment with its own domain separator, we cannot use that domain separator for this purpose, because we still need to compute the note commitment of the original note as-is. Conditionally adding $\mathcal{L}$ and relying on $\psi^{\mathsf{nf}}$ for randomisation appears to be the option with the lowest circuit cost, as well as permitting a fairly straightforward security analysis for all properties and no strengthening of security assumptions. The application of $\mathsf{Extract}_ {\mathbb{P}}$ does not affect collision resistance even though it is not 1-1, by the argument in the proof of Theorem 5.4.3 in the protocol spec. Note that $+$ is complete point addition.

[Edit on 2023-07-05: $\psi' \rightarrow \psi^{\mathsf{nf}}$, to match the naming in the proposed circuit changes.]

vivek-arte and others added 3 commits October 31, 2023 23:52
Co-authored-by: Daira Emma Hopwood <daira@jacaranda.org>
This performs a rename of the Issuance keys as follows:

- `imk : Issuance master key` is renamed to `isk: Issuance authorizing
key`
vivek-arte and others added 3 commits November 2, 2023 16:36
This adds some details to the ZIP 226 Security and Privacy
Considerations section to address this
[comment](zcash#680 (comment))
This makes it clear that the encoding of `ik` used in the Asset Base
derivation is big-endian, as in the case of the underlying BIP 340
Schnorr signature scheme.

It also adds a clarification about the version byte used in the Asset
Base derivation.
Signed-off-by: Daira Emma Hopwood <daira@jacaranda.org>
zip-0230.rst Outdated Show resolved Hide resolved
zip-0230.rst Outdated Show resolved Hide resolved
zip-0230.rst Outdated Show resolved Hide resolved
zip-0230.rst Show resolved Hide resolved
zip-0227.rst Outdated Show resolved Hide resolved
zip-0227.rst Outdated Show resolved Hide resolved
Comment on lines +295 to +311
For all actions ``IssueAction``:

- encode :math:`\mathsf{asset\_desc}` as a UTF-8 byte string of size up to 512.
- compute :math:`\mathsf{AssetDigest}` from the issuance validating key :math:`\mathsf{ik}` and :math:`\mathsf{asset\_desc}` as decribed in the `Specification: Asset Identifier`_ section.
- compute :math:`\mathsf{AssetBase}` from :math:`\mathsf{AssetDigest}` as decribed in the `Specification: Asset Identifier`_ section.
- set the :math:`\mathsf{finalize}` boolean as desired (if more issuance actions are to be created for this :math:`\mathsf{AssetBase}`, set :math:`\mathsf{finalize} = 0`, otherwise set :math:`\mathsf{finalize} = 1`).
- for each recipient :math:`i`:

- generate a ZSA output note that includes the Asset Base. For an Orchard-ZSA note this is :math:`\mathsf{note}_i = (\mathsf{d}_i, \mathsf{pk}_{\mathsf{d}_i}, \mathsf{v}_i, \rho_i, \mathsf{rseed}_i, \mathsf{AssetBase}, \mathsf{rcm}_i)\!`.

- encode the ``IssueAction`` into the vector ``vIssueActions`` of the bundle.

For the ``IssueBundle``:

- encode the ``vIssueActions`` vector.
- encode the :math:`\mathsf{ik}` as 32 byte-string.
- sign the SIGHASH transaction hash with the issuance authorizing key, :math:`\mathsf{isk}`, using the :math:`\mathsf{IssueAuthSig}` signature scheme. The signature is then added to the issuance bundle.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@daira note to self: check whether explicit type declarations or consensus rules are needed here.

zip-0227.rst Outdated Show resolved Hide resolved
zip-0227.rst Outdated Show resolved Hide resolved
zip-0227.rst Show resolved Hide resolved
zip-0227.rst Outdated Show resolved Hide resolved
This fixes a typo in the ZSA-Orchard Action Description table,
wherein one table entry was not updated from 580 to 612 bytes.
This updates the ZSA ZIPs based on the comments made on PR#680.
@vivek-arte
Copy link
Contributor

vivek-arte commented Jan 9, 2024

Thanks for the comments and suggestions @daira! We have addressed them in our latest updates, and believe the PR is ready for merging.

Copy link
Collaborator

@daira daira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK modulo the merge conflict. I will do a follow-up PR to change some formatting and other editorial issues.

daira pushed a commit to daira/zips that referenced this pull request Feb 7, 2024
)

This adds to the specification to provide wallets instructions on displaying Asset information to users in an unambiguous way.

This addresses [this comment](zcash#680 (comment)).
daira pushed a commit to daira/zips that referenced this pull request Feb 7, 2024
daira pushed a commit to daira/zips that referenced this pull request Feb 7, 2024
This adds some details to the ZIP 226 Security and Privacy
Considerations section to address this
[comment](zcash#680 (comment))
@daira
Copy link
Collaborator

daira commented Feb 7, 2024

Superceded by #778.

@daira daira marked this pull request as draft February 7, 2024 19:25
@PaulLaux
Copy link
Contributor Author

As mentioned, closed in favor of #778.

@PaulLaux PaulLaux closed this Feb 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants