ELIP: 150 Layer: Wallet Title: CT Descriptors for Elements Author: Andrew Poelstra <[email protected]> Tim Ruffing <[email protected]> Comments-Summary: No comments yet. Comments-URI: https://github.com/ElementsProject/elips/wiki/Comments:ELIP-0150 Status: Draft Type: Standards Track Created: 2022-10-06 License: BSD-3-Clause
This document proposes a new wrapper around existing and future Elements descriptor types, which allows attaching a confidential blinding key to an ordinary output script descriptor. It introduces new syntax to support both existing SLIP77-style confidential keys as well as a new, more flexible style.
This document is licensed under the 3-clause BSD license.
Confidential Transactions involve the use of uniformly random "blinding factors" associated to every confidential output. These random values are secret, but must be known by the sender (in order to construct a transaction) as well as recipient (in order to recognize the received assets and amounts, and to spend the outputs). This means they must be chosen by the sender of a transaction and somehow securely communicated to the recipient.
The way this is done is that confidential addresses contain the public key of an extra "blinding key" pair created by the recipient. When blinding, the sender chooses a fresh EC Diffie-Hellman (ECDH) private key, encodes the corresponding public key in the "nonce" field of the transaction, derives an ECDH secret between the fresh private key and the public blinding key, uses the ECDH secret to encrypt the blinding factors for the output, and encodes the encrypted result in the rangeproof. The recipient, when recognizing a scriptPubKey corresponding to the ordinary part of her confidential address, uses the private blinding key for that address in conjunction with the nonce field of the txout to re-derive the ECDH secret and decrypt the blinding factors.
This document defines a standard way for the recipient's wallet to compute blinding key pairs. There are a number of requirements:
- Confidential addresses, including their attached blinding key, should be derivable from a single descriptor without extra data
- Wallets should be able to choose the granularity of their blinding keys, so that the revelation of private blinding keys may unblind one, a subset, or all, of its blinded outputs
- In multiparty settings, each wallet should be able to restrict this granularity
- It should be possible somehow to do public derivation of CT addresses, given only a descriptor containing (extended) public keys
We propose a new ct
descriptor which wraps any other descriptor type in the form ct(<BLINDING_KEY>, <DESCRIPTOR>)
.
Here DESCRIPTOR
refers to any existing descriptor, e.g. elwsh(...)
or eltr(...)
and BLINDING_KEY
is a new expression which must be one of
slip77(<64-character hex>)
which indicates that blinding keys for these addresses are derived via SLIP77; or<KEY>
which is a key expression as described in BIP 380, with the exception that uncompressed and x-only keys are not allowed, moreover single private keys are encoded hex instead of WIF; the blinding key is derived by a Taproot-style tweak of the key with the data of<DESCRIPTOR>
.
<KEY>
expression, all key(s) must be compressed; x-only and uncompressed keys are invalid.
It is permissible, and likely to be common, for a <KEY>
key to be a private key (e.g. an xprv) even if the keys in the actual descriptor are public keys.
Such a descriptor is termed a view descriptor, and the blinding private key a view key.
Later extensions to this ELIP may specify alternate expressions for `KEY`, for example to allow MuSig-combining keys from multiple participants.
- Because there is no sensible way to do multiparty unblinding, the blinding key must be a single key whose private half is known to all participants.
- The use of "view descriptors" which are nominally public but contain secret key data, may lead to user confusion; though we argue it has similar privacy properties to the chaincode value included in xpubs.
- Any party who has a copy of an addresses' view descriptor is able to see the blinding key and unblind coins sent to that address, or *any* derived address in the case of a descriptor containing wildcards.
First, the ct
descriptor is defined as above: its string serialization is given by ct(<BLINDING_KEY>, <DESCRIPTOR>)
where DESCRIPTOR
is the string serialization of an ordinary descriptor.
The scriptPubKey
corresponding to a ct
descriptor is that corresponding to the embedded DESCRIPTOR
. The encoding and semantics of BLINDING_KEY
are given below.
BLINDING_KEY
expressions are one of
- slip77, encoded as
slip77(<64-characters hex>)
, whose semantics are that the 64 hex characters are interpreted as the 32-bytemaster_blinding_key
in SLIP77; thescriptPubKey
for SLIP77 is computed as normal from the ordinary descriptor.- These 32 bytes are the same for both public and private descriptors; they have no "public" equivalent.
- This mode is not recommended because there is no way to express this descriptor without revealing the SLIP77 key, which can be used to unblind every single output received by the wallet.
- bare key, which simply encodes a single key in the same way as the keys in
<DESCRIPTOR>
are encoded. The blinding key is derived from the address by taking the public key K and tweaking it to form a new key Kblind as follows:- Kblind = K + Htag(K,
scriptPubKey
)G, where - Htag is a BIP-340 tagged hash with tag
CT-Blinding-Key/1.0
; - the comma indicates concatenation;
scriptPubKey
is the scriptPubKey of the output, consensus-encoded including its length prefix;- and Htag(K,
scriptPubKey
)G is the public key corresponding to the result of the tagged hash interpreted as a scalar or private key.
- Kblind = K + Htag(K,
In some circumstances, it may make sense for K to be derived deterministically from the descriptor data, rather than being chosen and specified separately. This reduces implementation complexity and the need to store additional keys, at the cost of turning the descriptor unconditionally into a view descriptor. In other words, users of this variant will be unable to provide external parties the ability to derive addresses without also providing them the ability to unblind coins.
In a future ELIP we will specify a standard deterministic key generation scheme for this case.
Using the ct(slip77(<64-byte hex>), <DESCRIPTOR>)
construction, any wallet should be able to express its existing confidential addresses using this new scheme.
The following CT descriptors should be parseable and generate the given addresses:
- Valid Descriptor 1:
ct(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,elpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#y0lg3d5y
- Descriptor blinding public key:
xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL
- Confidential address:
VTpvZZYdbhbyVF3Wa99eMjgXhfvu4LS26dR2FwMfNXq7FDX73HZEsZr3VvgH9EDgQnYK7sP6ACKSuMGw
- Unconfidential address:
Q5WHLVd78iAspUNvzuULvi2F8u693pzAqe
- Descriptor blinding public key:
- Valid Descriptor 2:
ct(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,elwpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#kt4e25qt
- Descriptor blinding public key:
xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL
- Confidential address:
lq1qqg5s7xj7upzl7h4q2k2wj4vq63nvaktn0egqu09nqcr6d44p4evaqknpl78t02k2xqgdh9ltmfmpy9ssk7qfvghdsfr4mvr9c
- Unconfidential address:
ex1qtfsllr4h4t9rqyxmjl4a5asjzcgt0qyktcafre
- Descriptor blinding public key:
- Valid Descriptor 3:
ct(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,elsh(wpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH)))#xg9r4jej
- Descriptor blinding public key:
xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL
- Confidential address:
VJL8znN4XjXEUKzDaYsqdzRASGLY2KHxC4N6g5b5QvrNjXfeKp83Ci9AW2a8QzbZjpEffoy4PEywpLAZ
- Unconfidential address:
Gq6kpy2HiNgsyQVpBsuBKAPRFiir23qKro
- Descriptor blinding public key:
- Valid Descriptor 4:
ct(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,eltr(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#c0pjjxyw
- Descriptor blinding public key:
xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL
- Confidential address:
lq1pq0nsl8du3gsuk7r90sgm78259mmv6mt9d4yvj30zr3u052ufs5meuc2tuvwx7k7g9kvhhpux07vqpm3qjj8uwdj94650265ustv0xy8zrdxdfgp8g9pl
- Unconfidential address:
ex1pv997x8r0t0yzmxtms7r8lxqqacsffr78xez6a284d2wg9k8nzr3qxa9kvf
- Descriptor blinding public key:
- Valid Descriptor 5:
ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),elpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#hw2glz99
- SLIP77 master blinding key:
b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04
- Confidential address:
VTq585ahVjWarEwg2nKQ9yYirmYs5F5j74CeYYA9cq1EZD9obm7hwpx6xqq3J1AY9YRaSavEMzYfr6t7
- Unconfidential address:
Q5WHLVd78iAspUNvzuULvi2F8u693pzAqe
- SLIP77 master blinding key:
- Valid Descriptor 6:
ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),elwpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#545pl285
- SLIP77 master blinding key:
b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04
- Confidential address:
lq1qqdx5wnttttzulcs6ujlg9pfts6mp3r4sdwg5ekdej566n5wxzk88vknpl78t02k2xqgdh9ltmfmpy9ssk7qfvr33xa22hpw23
- Unconfidential address:
ex1qtfsllr4h4t9rqyxmjl4a5asjzcgt0qyktcafre
- SLIP77 master blinding key:
- Valid Descriptor 7:
ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),elsh(wpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH)))#m30vswxr
- SLIP77 master blinding key:
b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04
- Confidential address:
VJLFGQ17aGa3WSVEVyxzDktD9SFixJjfSmqVq8xaWmR9X6gFbiF95KFwKA41PBhu3jNTxJFKTUphHL8J
- Unconfidential address:
Gq6kpy2HiNgsyQVpBsuBKAPRFiir23qKro
- SLIP77 master blinding key:
- Valid Descriptor 8:
ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),eltr(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#n3v4t5cs
- SLIP77 master blinding key:
b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04
- Confidential address:
lq1pq26fndnz8ef6umlz6e2755sm6j5jwxv3tdt2295mr4mx6ux0uf8vcc2tuvwx7k7g9kvhhpux07vqpm3qjj8uwdj94650265ustv0xy8z8wfacw9e5a5t
- Unconfidential address:
ex1pv997x8r0t0yzmxtms7r8lxqqacsffr78xez6a284d2wg9k8nzr3qxa9kvf
- SLIP77 master blinding key:
- Valid Descriptor 9:
ct(02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623,elwpkh(03774eec7a3d550d18e9f89414152025b3b0ad6a342b19481f702d843cff06dfc4))#h5e0p6m9
- Blinding key:
02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623
- Confidential address:
<lq1qq0r6pegudzm0tzpszelc34qjln4fdxawgwmgnza63wwpzdy6jrm0grmqvvk2ce5ksnxcs9ecgtnryt7xg3406y5ccl0k2glns/code>
- Blinding key:
** Unconfidential address: <code>ex1qpasxxt9vv6tgfnvgzuuy9e3j9lryg6hawrval4
- Valid Descriptor 10:
ct(02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623,elwpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#x6sc2de2
- Blinding public key:
02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623
- Confidential address:
lq1qqwkeuelr466ue5u8e0lz3a27q4yk93qnupry5h3q4h9pjpf8vrrzvknpl78t02k2xqgdh9ltmfmpy9ssk7qfvwt93dvuvssha
- Unconfidential address:
ex1qtfsllr4h4t9rqyxmjl4a5asjzcgt0qyktcafre
- Blinding public key:
- View Descriptor:
ct(xprv9s21ZrQH143K28NgQ7bHCF61hy9VzwquBZvpzTwXLsbmQLRJ6iV9k2hUBRt5qzmBaSpeMj5LdcsHaXJvM7iFEivPryRcL8irN7Na9p65UUb,elwpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#j95xktq7
- Descriptor blinding private key:
xprv9s21ZrQH143K28NgQ7bHCF61hy9VzwquBZvpzTwXLsbmQLRJ6iV9k2hUBRt5qzmBaSpeMj5LdcsHaXJvM7iFEivPryRcL8irN7Na9p65UUb
- Confidential address:
lq1qq2r0pdvcknjpwev96qu9975alzqs78cvsut5ju82t7tv8d645dgmwknpl78t02k2xqgdh9ltmfmpy9ssk7qfvtk83xqzx62q4
- Unconfidential address:
ex1qtfsllr4h4t9rqyxmjl4a5asjzcgt0qyktcafre
- Descriptor blinding private key:
- Non-view Descriptor:
ct(xpub661MyMwAqRbcEcT9W98HZP2kFzyzQQZkYnrRnrM8uD8kH8kSeFoQHq1x2iihLgC6PXGy5LrjCL66uSNhJ8pwjfx2rMUTLWuRMns2EG9xnjs,elwpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#elmfpmp9
- Descriptor blinding public key:
xpub661MyMwAqRbcEcT9W98HZP2kFzyzQQZkYnrRnrM8uD8kH8kSeFoQHq1x2iihLgC6PXGy5LrjCL66uSNhJ8pwjfx2rMUTLWuRMns2EG9xnjs
- Confidential address:
lq1qq2r0pdvcknjpwev96qu9975alzqs78cvsut5ju82t7tv8d645dgmwknpl78t02k2xqgdh9ltmfmpy9ssk7qfvtk83xqzx62q4
- Unconfidential address:
ex1qtfsllr4h4t9rqyxmjl4a5asjzcgt0qyktcafre
- Descriptor blinding public key:
This one is a "view descriptor" using ordinary keys rather than extended ones:
- View Descriptor 2:
ct(c25deb86fa11e49d651d7eae27c220ef930fbd86ea023eebfa73e54875647963,elwpkh(021a8fb6bd5a653b021b98a2a785725b8ddacfe3687bc043aa7f4d25d3a48d40b5))#c2kx9zll
- Descriptor blinding private key:
c25deb86fa11e49d651d7eae27c220ef930fbd86ea023eebfa73e54875647963
- Confidential address:
lq1qq265u4g3k3m3qpyxjwpdrtnm293wuxgvs9xzmzcs2ck0mv5rx23w4d7xfsednsmmxrszfe7s9rs0c6cvf3dfytxax3utlmm46
- Unconfidential address:
ex1qklrycvkecdanpcpyulgz3c8udvxyck5jvsv4j5
- Descriptor blinding private key:
- Non-view Descriptor 2:
ct(0286fc9a38e765d955e9b0bcc18fa9ae81b0c893e2dd1ef5542a9c73780a086b90,elwpkh(021a8fb6bd5a653b021b98a2a785725b8ddacfe3687bc043aa7f4d25d3a48d40b5))#m5mvyh29
- Descriptor blinding public key:
0286fc9a38e765d955e9b0bcc18fa9ae81b0c893e2dd1ef5542a9c73780a086b90
- Confidential address:
lq1qq265u4g3k3m3qpyxjwpdrtnm293wuxgvs9xzmzcs2ck0mv5rx23w4d7xfsednsmmxrszfe7s9rs0c6cvf3dfytxax3utlmm46
- Unconfidential address:
ex1qklrycvkecdanpcpyulgz3c8udvxyck5jvsv4j5
- Descriptor blinding public key:
- Invalid Descriptor 1
ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),elsh(wpkh(03774eec7a3d550d18e9f89414152025b3b0ad6a342b19481f702d843cff06dfc4)))#xxxxxxxx
- Reason: Invalid checksum 'xxxxxxxx', expected 'qgjmm4as'
- Invalid Descriptor 2
ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04,b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),elsh(wpkh(03774eec7a3d550d18e9f89414152025b3b0ad6a342b19481f702d843cff06dfc4)))#qs64ccxw
- Reason: slip77() must have exactly one argument, not 2
- Invalid Descriptor 3
ct(slip77,elsh(wpkh(03774eec7a3d550d18e9f89414152025b3b0ad6a342b19481f702d843cff06dfc4)))#8p3zmumf
- Reason: slip77() must have exactly one argument, not 0
- Invalid Descriptor 4
ct(elsh(wpkh(03774eec7a3d550d18e9f89414152025b3b0ad6a342b19481f702d843cff06dfc4)))#u9cwz9f3
- Reason: CT descriptor had 1 arguments rather than 2 (no blinding key)
- Invalid Descriptor 5
ct(02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623,02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623,elwpkh(03774eec7a3d550d18e9f89414152025b3b0ad6a342b19481f702d843cff06dfc4))#cnsp2qsc
- Reason: CT descriptor had 3 arguments rather than 2 (extra data)
- Invalid Descriptor 6
ct(pk(02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623),elwpkh(03774eec7a3d550d18e9f89414152025b3b0ad6a342b19481f702d843cff06dfc4))#nvax6rau
- Reason: first argument is a pk descriptor, not a blinding key
- Invalid Descriptor 7
ct(L3jXxwef3fpB7hcrFozcWgHeJCPSAFiZ1Ji2YJMPxceaGvy3PC1q,elwpkh(03774eec7a3d550d18e9f89414152025b3b0ad6a342b19481f702d843cff06dfc4))#gcy6hcfz
- Reason: single private key is WIF, not hex
We would like to thank Leo Comandini for describing practical requirements by wallet authors, and to Jonas Nick for providing feedback on the cryptographic design.