080-short-wire-subject.rst (8700B)
1 DD 80: Alternative wire transfer subjects 2 ######################################### 3 4 Summary 5 ======= 6 7 Some mediums and clients do not support subjects large enough to contain an entire reserve public key, 8 and filling in the subject manually is very error-prone. 9 We need a way to generate new input methods for wire transfers that are linked to the metadata currenlty stored in the unstructured subject. 10 We also need support for recurring transfers. 11 12 Problem 13 ======= 14 15 Swiss users are used to QR-code based payments with a numeric payment 16 identifier for invoices. Some Swiss banking apps do not support the 17 (long-ish) public key wire transfer subject we use today. Furthermore, 18 banks in NZ use an even shorter encoding with 3 very short fields to 19 encode the reasons for a wire transfer. Other countries may also have 20 restrictions that are, well, unfortunate. Finally, for Depolymerization 21 we used a hack to encode the reserve public key, but also could be 22 more efficient if we could use less entropy. 23 24 Handling small encoding space 25 ----------------------------- 26 27 Using a very restricive alphabet like numeric and a very short wire subject 28 length can leed us to quickly exaust most of the encoding space. We thus need 29 a way to recycle old short subjects. 30 31 Parsing unstructured subjects 32 ----------------------------- 33 34 We currently support two kinds of keys: reserve keys and KYC keys. We expect 35 to need more key kind in the future, and using new crypto will make the 36 encoded keys bigger. 37 38 We quickly found that users inputing those keys had a tendency to add 39 undesirable separators and worst, some client even add them automatically. 40 Those users where than very frustrated by the experience and somtimes where 41 completly prevented from using Taler. 42 43 We also currently try to identify wire transfer subjects that are not 44 well-formed and automatically bounce such wire transfers immediately. It 45 would be great if we could make sure this happens more consistently 46 (as right now small typos MAY still decode to a proper public key). 47 48 Repeated wire transfers 49 ----------------------- 50 51 Users may want to setup a periodic wire transfer into their wallet, which 52 automatically tops-up their balance once a week or once a month. Here, we 53 need to allow them to re-use the same wire transfer subject for a long 54 time. However, the exchange logic requires a fresh reserve public key to 55 be used each time. 56 57 58 Proposed Solution 59 ================= 60 61 Wire transfer subject generation 62 -------------------------------- 63 64 We need a new public endpoint where wallets can request a fresh wire transfer 65 subject to be generated for them. The result MUST be some JSON as the 66 different wire methods will require one or more fields with different 67 constraints (see NZ vs. CH). Some may be numbers, others may be strings, there 68 may be checksum-constraints (or not), we simply cannot enumerate all 69 possibilities. So the new public API of the wire gateway (discoverable via 70 the exchange) must have a plugin architecture and depending on the wire method 71 generate a JSON object with fields specific to the wire method. If the 72 underlying wire transfer subject format has no checksums, our wire 73 transfer subject generator *should* add some (unless the entropy space is 74 so tiny that even a small checksum is impractical). 75 76 We also need to associate a fresh wire transfer subject with a public key at 77 that point, so the client should POST its **registration** public key to the 78 backend. 79 80 The registration must have an **expiration**. How long can be configurable, 81 the default should probably be at least a quarter. Usage of the registered 82 wire transfer subject (by making such a wire transfer) should **extend** the 83 expiration deadline. The current expiration should be **returned** by the 84 service. Wallets must communicate the expiration in the user interface, 85 making it clear that the registration will lapse (unless used) and then funds 86 may end up with a different user. 87 88 The wire subject generation logic **should** avoid re-using wire transfer 89 subjects, for example by (1) linearly going over the entropy space (modulo 90 checksums and other constraints of the format), and (2) after cycling 91 through it, skipping not only registered entries but also "recently expired" 92 registrations (basically, keeping registrations around as blockers for a 93 few days/weeks/months instead of immediately freeing the number). 94 95 Finally, we protect the service against exhaustion attacks where an attacker 96 drains our entropy space by sending too many registration requests. Here, an 97 adaptive proof-of-work is the only reasonable solution. Basically, as our 98 available entropy space goes down, we exponentially increase the 99 difficulty. The current difficulty could be exposed via ``/config``. The 100 proof-of-work would be specific to the client's public key being 101 registered. Unless the difficulty increased, the client is *allowed* to re-use 102 the proof-of-work in subsequent registration requests (if the original once 103 expired). If a client's public key is already registered, we simply return 104 the same wire transfer subject again (idempotency!). However, once the 105 registration expired, the client is likely to get a different wire transfer 106 subject. 107 108 For wire transfer methods without actual restrictions on the wire transfer 109 subject, we could simply return the registration public key in a suitable 110 field of the response, in extreme cases skip storing data in our database, and 111 might even accept a zero-cost proof-of-work. 112 113 Mapping to reserves 114 ------------------- 115 116 Another endpoint allows wallets to map a registration public key to a unique 117 reserve public key and a **transaction type** (like regular withdraw, KYC-auth, 118 WAD, etc.). For this endpoint, the wallet would have to sign using the 119 registration key. Each mapping is used at most once. If a client sends a new 120 mapping before the old mapping has been used, the old mapping is simply 121 discarded. Unused mappings expire when the registration expires. 122 123 Handling incoming wire transfers 124 -------------------------------- 125 126 If the incoming wire transfer subject has a wire transfer gateway defined 127 checksum, it should be checked and possibly bounced if the subject is 128 not well-formed. 129 130 The wire transfer MUST also be bounced if the incomig wire transfer subject is 131 not registered, or if the registration is expired, and if the wire transfer 132 subject is not recognized as a registration public key (if the wire method has 133 no entropy constraints and we skipped writing registrations to the database). 134 For backwards-compatibility, reserve public keys (possibly with "KYC"-flag) 135 should also be supported initially and not be bounced. 136 137 If a reserve public key and transaction type are already registered 138 for the registration public key, the exchange is informed. Otherwise, 139 the wire transfer is put in a "hold" state until either it passes some 140 configurable **hold delay** or such a registration is received. 141 142 Subject derivation 143 ------------------ 144 145 The subject derivation must be deterministic and and use the entire coding space. 146 147 We will continue to support the current encoding for simple cases. 148 149 All subject derivation starts by making a hash of the key using SHA 256. 150 151 Then the hash bits are encoded differently for each subject format: 152 153 Swiss QR-bill 154 ^^^^^^^^^^^^^ 155 156 Treat the whole hash as a big integer then modulo by 10 power 26. 157 Encode the remainder into a string and add the 27th checksum character according to QR-bill spec. 158 159 Auditor 160 ------- 161 162 By running the subject derivation logic itself and using the new authorization public key and signature fields in the wire gateway API, the auditor can match corresponding transfers. 163 164 Taler Wire Transfer HTTP API 165 ---------------------------- 166 167 See the :ref:`Taler Wire Transfer <taler-wire-transfer-gateway-http-api>` documentation. 168 169 Test Plan 170 ========= 171 172 173 Definition of Done 174 ================== 175 176 * New API supported by all wire gateways 177 * Support for Swiss QR Bill wire transfer subjects 178 * Exchange points wallets/merchants to wire transfer API 179 * Wallets support registration 180 * Wallets have UI where the user can specify "periodic" 181 wire transfers where the wallets periodically try to 182 map new reserve public keys to an existing registration 183 * *Optional*: remove legacy mode? 184 185 186 Alternatives 187 ============ 188 189 The mapping of registration key to reserve key could also specify the 190 amount. That may help map multiple wire transfers to the "right" key, but 191 would create problems for the UX if the user got the amount wrong. 192 193 194 Drawbacks 195 ========= 196 197 Theoretically, transfering money using a long-expired wire transfer 198 subject may send money to a different wallet. This seems to be 199 unavoidable with low-entropy wire transfer subjects. 200 201 202 203 Discussion / Q&A 204 ================