Skip to content

Latest commit

 

History

History
192 lines (152 loc) · 18.5 KB

elip-0150.mediawiki

File metadata and controls

192 lines (152 loc) · 18.5 KB

  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

Table of Contents

Introduction

Abstract

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.

Copyright

This document is licensed under the 3-clause BSD license.

Motivation

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
The current most popular scheme, SLIP-77, does not satisfy any of these criteria, which limits its usefulness as we move toward a descriptor-centric setting in which multiparty addresses are common.

Design

Overview

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>.
In the <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.

Drawbacks

  • 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.
The latter point is the intended use of view descriptors, and is listed as a drawback only because it may be surprising.

Specification

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-byte master_blinding_key in SLIP77; the scriptPubKey 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.
Because the scriptPubKey is revealed on the blockchain, its role in the tagged hash is merely to ensure that blinding keys are not reused across multiple outputs, unless they are identical (in which case the reuse amounts to ordinary address reuse). Privacy and security are provided by the untweaked key K, which is never revealed on-chain.

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.

Backwards Compatibility

Using the ct(slip77(<64-byte hex>), <DESCRIPTOR>) construction, any wallet should be able to express its existing confidential addresses using this new scheme.

Test Vectors

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
  • Valid Descriptor 2: ct(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,elwpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#kt4e25qt
    • Descriptor blinding public key: xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL
    • Confidential address: lq1qqg5s7xj7upzl7h4q2k2wj4vq63nvaktn0egqu09nqcr6d44p4evaqknpl78t02k2xqgdh9ltmfmpy9ssk7qfvghdsfr4mvr9c
    • Unconfidential address: ex1qtfsllr4h4t9rqyxmjl4a5asjzcgt0qyktcafre
  • Valid Descriptor 3: ct(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,elsh(wpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH)))#xg9r4jej
    • Descriptor blinding public key: xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL
    • Confidential address: VJL8znN4XjXEUKzDaYsqdzRASGLY2KHxC4N6g5b5QvrNjXfeKp83Ci9AW2a8QzbZjpEffoy4PEywpLAZ
    • Unconfidential address: Gq6kpy2HiNgsyQVpBsuBKAPRFiir23qKro
  • Valid Descriptor 4: ct(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,eltr(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#c0pjjxyw
    • Descriptor blinding public key: xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL
    • Confidential address: lq1pq0nsl8du3gsuk7r90sgm78259mmv6mt9d4yvj30zr3u052ufs5meuc2tuvwx7k7g9kvhhpux07vqpm3qjj8uwdj94650265ustv0xy8zrdxdfgp8g9pl
    • Unconfidential address: ex1pv997x8r0t0yzmxtms7r8lxqqacsffr78xez6a284d2wg9k8nzr3qxa9kvf
  • Valid Descriptor 5: ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),elpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#hw2glz99
    • SLIP77 master blinding key: b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04
    • Confidential address: VTq585ahVjWarEwg2nKQ9yYirmYs5F5j74CeYYA9cq1EZD9obm7hwpx6xqq3J1AY9YRaSavEMzYfr6t7
    • Unconfidential address: Q5WHLVd78iAspUNvzuULvi2F8u693pzAqe
  • Valid Descriptor 6: ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),elwpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#545pl285
    • SLIP77 master blinding key: b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04
    • Confidential address: lq1qqdx5wnttttzulcs6ujlg9pfts6mp3r4sdwg5ekdej566n5wxzk88vknpl78t02k2xqgdh9ltmfmpy9ssk7qfvr33xa22hpw23
    • Unconfidential address: ex1qtfsllr4h4t9rqyxmjl4a5asjzcgt0qyktcafre
  • Valid Descriptor 7: ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),elsh(wpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH)))#m30vswxr
    • SLIP77 master blinding key: b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04
    • Confidential address: VJLFGQ17aGa3WSVEVyxzDktD9SFixJjfSmqVq8xaWmR9X6gFbiF95KFwKA41PBhu3jNTxJFKTUphHL8J
    • Unconfidential address: Gq6kpy2HiNgsyQVpBsuBKAPRFiir23qKro
  • Valid Descriptor 8: ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),eltr(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#n3v4t5cs
    • SLIP77 master blinding key: b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04
    • Confidential address: lq1pq26fndnz8ef6umlz6e2755sm6j5jwxv3tdt2295mr4mx6ux0uf8vcc2tuvwx7k7g9kvhhpux07vqpm3qjj8uwdj94650265ustv0xy8z8wfacw9e5a5t
    • Unconfidential address: ex1pv997x8r0t0yzmxtms7r8lxqqacsffr78xez6a284d2wg9k8nzr3qxa9kvf
  • Valid Descriptor 9: ct(02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623,elwpkh(03774eec7a3d550d18e9f89414152025b3b0ad6a342b19481f702d843cff06dfc4))#h5e0p6m9
    • Blinding key: 02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623
    • Confidential address: <lq1qq0r6pegudzm0tzpszelc34qjln4fdxawgwmgnza63wwpzdy6jrm0grmqvvk2ce5ksnxcs9ecgtnryt7xg3406y5ccl0k2glns/code>
** Unconfidential address: <code>ex1qpasxxt9vv6tgfnvgzuuy9e3j9lryg6hawrval4
  • Valid Descriptor 10: ct(02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623,elwpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#x6sc2de2
    • Blinding public key: 02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623
    • Confidential address: lq1qqwkeuelr466ue5u8e0lz3a27q4yk93qnupry5h3q4h9pjpf8vrrzvknpl78t02k2xqgdh9ltmfmpy9ssk7qfvwt93dvuvssha
    • Unconfidential address: ex1qtfsllr4h4t9rqyxmjl4a5asjzcgt0qyktcafre
This one is a "view descriptor" which has a private blinding key but otherwise public keys:

  • View Descriptor: ct(xprv9s21ZrQH143K28NgQ7bHCF61hy9VzwquBZvpzTwXLsbmQLRJ6iV9k2hUBRt5qzmBaSpeMj5LdcsHaXJvM7iFEivPryRcL8irN7Na9p65UUb,elwpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#j95xktq7
    • Descriptor blinding private key: xprv9s21ZrQH143K28NgQ7bHCF61hy9VzwquBZvpzTwXLsbmQLRJ6iV9k2hUBRt5qzmBaSpeMj5LdcsHaXJvM7iFEivPryRcL8irN7Na9p65UUb
    • Confidential address: lq1qq2r0pdvcknjpwev96qu9975alzqs78cvsut5ju82t7tv8d645dgmwknpl78t02k2xqgdh9ltmfmpy9ssk7qfvtk83xqzx62q4
    • Unconfidential address: ex1qtfsllr4h4t9rqyxmjl4a5asjzcgt0qyktcafre
  • Non-view Descriptor: ct(xpub661MyMwAqRbcEcT9W98HZP2kFzyzQQZkYnrRnrM8uD8kH8kSeFoQHq1x2iihLgC6PXGy5LrjCL66uSNhJ8pwjfx2rMUTLWuRMns2EG9xnjs,elwpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#elmfpmp9
    • Descriptor blinding public key: xpub661MyMwAqRbcEcT9W98HZP2kFzyzQQZkYnrRnrM8uD8kH8kSeFoQHq1x2iihLgC6PXGy5LrjCL66uSNhJ8pwjfx2rMUTLWuRMns2EG9xnjs
    • Confidential address: lq1qq2r0pdvcknjpwev96qu9975alzqs78cvsut5ju82t7tv8d645dgmwknpl78t02k2xqgdh9ltmfmpy9ssk7qfvtk83xqzx62q4
    • Unconfidential address: ex1qtfsllr4h4t9rqyxmjl4a5asjzcgt0qyktcafre
The non-view descriptor is the same as the view descriptor except that its private blinding key has been replaced with a public key. Notice that the generated addresses are the same in both cases.

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
  • Non-view Descriptor 2: ct(0286fc9a38e765d955e9b0bcc18fa9ae81b0c893e2dd1ef5542a9c73780a086b90,elwpkh(021a8fb6bd5a653b021b98a2a785725b8ddacfe3687bc043aa7f4d25d3a48d40b5))#m5mvyh29
    • Descriptor blinding public key: 0286fc9a38e765d955e9b0bcc18fa9ae81b0c893e2dd1ef5542a9c73780a086b90
    • Confidential address: lq1qq265u4g3k3m3qpyxjwpdrtnm293wuxgvs9xzmzcs2ck0mv5rx23w4d7xfsednsmmxrszfe7s9rs0c6cvf3dfytxax3utlmm46
    • Unconfidential address: ex1qklrycvkecdanpcpyulgz3c8udvxyck5jvsv4j5
Finally, the following are invalid test vectors that should not be parseable:

  • 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

Acknowledgements

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.