-
Notifications
You must be signed in to change notification settings - Fork 1
Description
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:
- Specifies which ZSA we rotate keys for (i.e. contains a UID for the ZSA issuance and rotation key)
- Specifies which key (for the given ZSA) is rotated: is it the issuance key? the rotation key itself?
- Contains the new key
- Contains a Proof of Possession for the new key
- 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
ik(the issuance / signing key) is "baked" in theAssetId. ThisAssetIdis used to computeAssetDigestwhich is used to compute theAssetBase. As such, "changing ik" means -> changing the AssetBase, which isn't desired.- We can still stick to the original value of
ik(denotedik_{original}in this doc) inAssetIdeven ifikgets rotated later on. Doing so, "anchors" the chain of key rotations to the initialik_{original}value which itself serves as the root of the "chain of trust" for the key rotation. But, given that the original valueik_{original}is used to computeAssetId, we should understand that after rotating this key, the AssetId isn't "derived" fromikanymore, but from a "successor" to the originalik_{original}(which isn't derived fromik_{original})
- We can still stick to the original value of
- 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.
-
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 anikas 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.
""" -
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.
- In https://zcash-zips-qedit.netlify.app/zip-0227#issuance-protocol we need to clarify what
ikwe need to use to compute theAssetDigest. The sentence:
"""
computeAssetDigestfrom the issuance validating keyik
"""
becomes:
"""
compute AssetDigest from the original issuance validating key ik_{original}
"""
and
"""
For the IssueBundle:
- encode the
vIssueActionsvector. - encode the
ikas 32 byte-string. - sign the SIGHASH transaction hash with the issuance authorizing key,
isk, using theIssueAuthSigsignature scheme. The signature is then added to the issuance bundle.
"""
needs to become something like
"""
For the IssueBundle:
- encode the
vIssueActionsvector. - encode the current
ikasikLengthbyte-string. - sign the SIGHASH transaction hash with the current issuance authorizing key,
isk, using theIssueAuthSigsignature 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)
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
IssueAuthSigis initialized with the sig scheme from BIP340 (this defines the spaces from whichik,iskand the signatures are in at setup). ikis initialized withik_{original}andiskis initialized withisk_{original}, where isk_{original} andik_{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.