Skip to content

Make ZIP 227 compatible with the Lockbox Disbursement key rotation mechanism #110

@AntoineRondelet

Description

@AntoineRondelet

The Lockbox Disbursement key rotation mechanism (https://hackmd.io/@nuttycom/SJuZdFMbxx) offers a way to rotate issuance keys for ZSA.

TL;DR:

  • It introduces the concept of a "rotation key" which is separate from the issuance key used by the ZSA Issuer.
  • Key rotation bundles can be used to rotate keys (e.g. signing keys or the rotation key itself)
  • A key rotation bundle for ZSA basically:
    1. Specifies which ZSA we rotate keys for (i.e. contains a UID for the ZSA issuance and rotation key)
    2. Specifies which key (for the given ZSA) is rotated: is it the issuance key? the rotation key itself?
    3. Contains the new key
    4. Contains a Proof of Possession for the new key
    5. Contains a "Rotation auth sig" that uses the currently active rotation key to sign the bundle (i.e. prove that the rotation is done the the authorized party)

Few things to note w.r.t applying the key rotation to the ZSA issuance as specified in ZIP227

  1. ik (the issuance / signing key) is "baked" in the AssetId. This AssetId is used to compute AssetDigest which is used to compute the AssetBase. As such, "changing ik" means -> changing the AssetBase, which isn't desired.
    • We can still stick to the original value of ik (denoted ik_{original} in this doc) in AssetId even if ik gets rotated later on. Doing so, "anchors" the chain of key rotations to the initial ik_{original} value which itself serves as the root of the "chain of trust" for the key rotation. But, given that the original value ik_{original} is used to compute AssetId, we should understand that after rotating this key, the AssetId isn't "derived" from ik anymore, but from a "successor" to the original ik_{original} (which isn't derived from ik_{original})
  2. In section: https://zcash-zips-qedit.netlify.app/zip-0227#specification-consensus-rule-changes, we need to change
- The issuance authorization signature, $\mathsf{issueAuthSig}$, MUST be a valid $\mathsf{IssueAuthSig}$ signature over $\mathsf{SigHash}$, i.e. $\mathsf{IssueAuthSig}.\!\mathsf{Validate}(\mathsf{ik}, \mathsf{SigHash}, \mathsf{issueAuthSig}) = 1$. 

to

- The issuance authorization signature, $\mathsf{issueAuthSig}$, MUST be a valid $\mathsf{IssueAuthSig}$ signature over $\mathsf{SigHash}$ under the most recent \mathsf{ik} for the Asset, i.e. $\mathsf{IssueAuthSig}.\!\mathsf{Validate}(\mathsf{ik}, \mathsf{SigHash}, \mathsf{issueAuthSig}) = 1$.
where \mathsf{ik} is the most recent value of the issuance key for this ZSA.

TL;DR: we must now do a lookup in the state to retrieve the latest ik for the asset being issued, to make sure the issuance transaction is signed under this key (and not under the original value ik_{original}).

Note: Given that we can now rotate ik, we need to make sure rotation transactions are properly mined BEFORE carrying out issuance transactions. In fact, imagine Tx1 does a ZSA issuance under ik_1, and imagine Tx2 does a key rotation to rotate ik_1 to ik2. Then, if Tx2 gets mined before Tx1, then the $\mathsf{issueAuthSig}$ check above will fail for Tx1.

  1. The section https://github.com/QED-it/zips/blob/zsa1/zips/zip-0227.rst#hash-of-the-asset-description needs to be changed. Namely, this part:
    """
    The lack of key rotation in this issuance protocol means that it is not sufficient to mark an ik as trusted and then accept whatever asset descriptions are issued by it. Each Asset Identifier needs to be independently verified, which requires some out-of-band protocol that can also convey the corresponding asset description.
    """

  2. We need to add the concept of rotation is multiple sections e.g. https://zcash-zips-qedit.netlify.app/zip-0227#issuance-bundle , https://zcash-zips-qedit.netlify.app/zip-0227#issuance-bundle etc

  • Basically, we need to make it clear that "issueAuthSig is the the signature of the transaction SIGHASH, signed by the current issuance authorizing key, isk, that validates the issuance". TL;DR: we don't have "one isk and ik" anymore. We have a set of such keys, with only ONE tuple being the correct tuple at every single point in time.
  1. In https://zcash-zips-qedit.netlify.app/zip-0227#issuance-protocol we need to clarify what ik we need to use to compute the AssetDigest. The sentence:
    """
    compute AssetDigest from the issuance validating key ik
    """

becomes:
"""
compute AssetDigest from the original issuance validating key ik_{original}
"""

and

"""
For the IssueBundle:

  • encode the vIssueActions vector.
  • encode the ik as 32 byte-string.
  • sign the SIGHASH transaction hash with the issuance authorizing key, isk, using the IssueAuthSig signature scheme. The signature is then added to the issuance bundle.
    """

needs to become something like
"""
For the IssueBundle:

  • encode the vIssueActions vector.
  • encode the current ik as ikLength byte-string.
  • sign the SIGHASH transaction hash with the current issuance authorizing key, isk, using the IssueAuthSig signature scheme. The signature is then added to the issuance bundle.
    """

Moreover, IssueAuthSig needs to become a variable here too because the Lockbox Disbursement protocol states that the "signature protocol" is specified for each key rotation (so, if we rotate an ik generated as specified in BIP340 by an ik for a different signature scheme, then we need to make sure the correct IssueAuthSig scheme is selected to be consistent with the rotated key - see screenshot below - from https://hackmd.io/@nuttycom/SJuZdFMbxx)

Image

Likewise, the length of ik as well as the length of the signature generated with IssueAuthSig will vary based on the signature scheme used. As such, the size of the IssueBundle will be a function of the scheme selected, which itself is obtained by doing a Zcash state lookup to retrieve the current "active" issuance keys.

As such ikLength and issueAuthSigLength (see https://zcash-zips-qedit.netlify.app/zip-0230) are parameters that are retrieved from the Zcash state (which stores the results of the key rotations)

So, in essence, to be compatible with the Lockbox Disbursement key rotation proposal, the ZIP 227 needs to be "parameterized" to support different / changing values for ik and isk, and to support different signature schemes (which means, signatures and public keys of different lengths in the IssueBundles). Then, the ZIP needs to specify the protocol initialization step, which is:

  • The signature scheme IssueAuthSig is initialized with the sig scheme from BIP340 (this defines the spaces from which ik, isk and the signatures are in at setup).
  • ik is initialized with ik_{original} and isk is initialized with isk_{original}, where isk_{original} and ik_{original} are BIP340 keys.

AFAICT, in a transfer, the AssetBase for the ZSAs is passed as a private input to the circuit (see https://docs.google.com/document/d/1DzXBqZl_l3aIs_gcelw3OuZz2OVMnYk6Xe_1lBsTji8/edit?tab=t.0) and doesn't need to be recomputed / validated in the circuit. This means, that we don't need to pass ik_{original} as input to the OrchardZSA circuit. So, we should be good here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions