summaryrefslogtreecommitdiff
path: root/38/54ddaf058be7ea892b64a30dd6404101ff226c
blob: bd1f12286da7c4762ed4871905ed7cceee80cf6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
Return-Path: <sjors@sprovoost.nl>
Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org
	[172.17.192.35])
	by mail.linuxfoundation.org (Postfix) with ESMTPS id 4CEB7CCA
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Mon, 10 Sep 2018 12:30:51 +0000 (UTC)
X-Greylist: from auto-whitelisted by SQLgrey-1.7.6
Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com
	[64.147.123.25])
	by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 7A68B782
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Mon, 10 Sep 2018 12:30:50 +0000 (UTC)
Received: from compute1.internal (compute1.nyi.internal [10.202.2.41])
	by mailout.west.internal (Postfix) with ESMTP id C41B9416;
	Mon, 10 Sep 2018 08:30:49 -0400 (EDT)
Received: from mailfrontend1 ([10.202.2.162])
	by compute1.internal (MEProxy); Mon, 10 Sep 2018 08:30:49 -0400
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sprovoost.nl; h=
	content-type:date:from:in-reply-to:message-id:mime-version
	:references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s=
	fm3; bh=b0YDDkevd9VJhw+CYY178Z7IyrEYDFbGNtI+t6A4ofI=; b=Ct8Nz/Hy
	qBUrOqMesQvP6jH247cHb9yzSqz/bfcvInmeHxbypOYfYgOUUP1GCmvDszUeHTam
	Q75IELhv23eSs69Y9RBgiJTq+aSwNnCEZjJopLtf/8MEOW9nhrwBtFzsSkjLFk4N
	6A06pauXDOXDwSUfqRhpyQcVjeaqrRcUlVaTiFMaAQsAv4rM+u4eroQr1xNbjRub
	Wj1rk8iL6Hvgc9Wacj6c+7U/PqCKVRbBRBGjIa/kYCzdmYAmZkgauo/adpEO4HWF
	VVdhxdRoLvns+qTr0wI7uAUpaoiLrKzlVcGX4EKfusq/gtvQ2P+VKQoh7+ndEAjr
	WavZslhtvc0mvQ==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=
	messagingengine.com; h=content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to:x-me-sender
	:x-me-sender:x-sasl-enc; s=fm3; bh=b0YDDkevd9VJhw+CYY178Z7IyrEYD
	FbGNtI+t6A4ofI=; b=sNJrjntWuLqh3jQXZ4+GcqYizzwTSiQgFG2PP+AZ/KN4n
	dugQ9kvQAqO1rQ/SJDA879dv8iUeKIMB9BPksmv+MW8MuDuEBAlrfVUAEsJGBiD6
	MubVIhGRzMlLdos4fOl5Uf3l/WC14jDfpJQlNrGyVs65V4fKtwK7Zkuy5dx//Bjl
	NT8XOh6DK1xScQ8drINgi43CdZHziyClyFFNl33gei2RCbDMoNsuQcpU1kDCiWaK
	qHlIjFlh6AdvOj5uUhlzRV0o/j02ZbyII+F66jtHx8dbSX29PGiMDEqaK6CAXwwy
	hg45UpO5AeLKPkqkVhnyI5IeBCmkX2/VyFxoSZwlg==
X-ME-Proxy: <xmx:-GOWWySSLfNWOQ2a3j1VNzNmuSgDdjELRFsyWQAQp60EjXdWYgF-cg>
	<xmx:-GOWW62SWJ2s-4j7BVt8CAvbJ_Lt0QZs8hNEdZ1dKz4MJqVHke5a5A>
	<xmx:-GOWW6e5FyxUxOxCFCbwDBGnxphO3-16Ba8iT7I85bE0IHcaKgx0Sg>
	<xmx:-GOWW6ON3OeFycwg7nJq9RER7DnM1I5_sxJmmXgMG-hJ19sIOMCHZA>
	<xmx:-GOWW2UpLWAAj1bW_xmrpCxDUc-VbFQpHurfmN2-9T8iZ4j7YUhcOQ>
	<xmx:-WOWW8dAS9Ny52QyiHEOXbm1tFyWo1Nj9DPXdUUgLY3FTLTMIp-NRA>
X-ME-Sender: <xms:-GOWW8AGDMp1pE3nOuvBY7Wfnt8CiDwBpyFv0wEh0lUW4tV0591d5A>
Received: from [192.168.178.185] (54693d0f.cm-12-2a.dynamic.ziggo.nl
	[84.105.61.15])
	by mail.messagingengine.com (Postfix) with ESMTPA id F2912E408D;
	Mon, 10 Sep 2018 08:30:47 -0400 (EDT)
From: Sjors Provoost <sjors@sprovoost.nl>
Content-Type: multipart/signed;
	boundary="Apple-Mail=_35E0A336-43BB-4270-8B25-FDEBE5AD051A";
	protocol="application/pgp-signature"; micalg=pgp-sha256
Mime-Version: 1.0 (Mac OS X Mail 11.5 \(3445.9.1\))
Date: Mon, 10 Sep 2018 14:30:46 +0200
References: <TtjH2zicjKr8PBVCMOvA7ryt2z_XXvtrpC4y1wuWSxexNwMdbPGE7vPmu6UnzmfYqYBMxZ8NNoz4VUnODdIcjR4j-E1sYz_FA6ZZMjKHtuM=@protonmail.com>
To: Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>,
	Rhavar <rhavar@protonmail.com>
In-Reply-To: <TtjH2zicjKr8PBVCMOvA7ryt2z_XXvtrpC4y1wuWSxexNwMdbPGE7vPmu6UnzmfYqYBMxZ8NNoz4VUnODdIcjR4j-E1sYz_FA6ZZMjKHtuM=@protonmail.com>
Message-Id: <82F5C582-1B93-44CF-B5AA-A93AAEA32AB2@sprovoost.nl>
X-Mailer: Apple Mail (2.3445.9.1)
X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED,
	DKIM_VALID,DKIM_VALID_AU,HTML_MESSAGE,RCVD_IN_DNSWL_LOW autolearn=ham
	version=3.3.1
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
	smtp1.linux-foundation.org
X-Mailman-Approved-At: Mon, 10 Sep 2018 13:38:20 +0000
Subject: Re: [bitcoin-dev] bustapay BIP :: a practical sender/receiver
 coinjoin protocol
X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org>
List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>,
	<mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>,
	<mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
X-List-Received-Date: Mon, 10 Sep 2018 12:30:51 -0000


--Apple-Mail=_35E0A336-43BB-4270-8B25-FDEBE5AD051A
Content-Type: multipart/alternative;
	boundary="Apple-Mail=_48127117-8F35-4700-ADFA-F388148ACF8B"


--Apple-Mail=_48127117-8F35-4700-ADFA-F388148ACF8B
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8


> Op 30 aug. 2018, om 22:24 heeft Ryan Havar via bitcoin-dev =
<bitcoin-dev@lists.linuxfoundation.org> het volgende geschreven:
>=20
> =3D=3DMotivation=3D=3D
>=20
> One of the most powerful heuristic's employed by those whose goal is =
to undermine
> bitcoin's fungiblity has been to assume all inputs of a transaction =
are signed by
> a single party. In the few cases this assumption does not hold, it is =
generally
> readibly recognizable (e.g. traditional coinjoins have a very obvious =
structure,
> or multisig outputs are most frequently validated onchain).

In addition to mixers, custodial wallets and exchanges also contribute =
to breaking this heuristic; even though there=E2=80=99s a single entity =
signing multiple inputs, that entity doesn=E2=80=99t represent a single =
owner of the funds. As with mixers, exchanges and custodial wallets can =
sometimes be spotted as well, but we don=E2=80=99t know what percentage =
is missed.

Breaking this heuristic at scale would be good, but do we know to what =
degree it=E2=80=99s already broken? Is there any empirical research =
measuring its accuracy and false positive rate?

> Should bustapay enjoy widespread adoption, a "v2" specification
> will be created with desired extensions.

I would not put future promises in a BIP. Rather, explain how extension =
might work.

> =3D=3DSpecification=3D=3D
>=20
> A bustapay payment is made from a sender to a receiver.
>=20
> Step 1. Sender creates a bitcoin transaction paying the receiver
>=20
> This transaction must be fully valid, signed and all inputs must use =
segwit. This transaction is known as the "template transaction=E2=80=9D.

Using PSBT?

> This transaction must not be propagated on the bitcoin network.

This can=E2=80=99t be guaranteed, and even after step 5 a reorg could =
cause it to get confirmed. It=E2=80=99s useful to explain why this =
doesn=E2=80=99t matter.

>=20
> Step 2. Sender gives the "template transaction" to the receiver
>=20
> This would generally be done as an HTTP POST.
> The exact URL to submit it to could be specified with a bip21 encoded =
address. Such as =
bitcoin:2NABbUr9yeRCp1oUCtVmgJF8HGRCo3ifpTT?bustapay=3Dhttps://bp.bustabit=
.com/submit <https://bp.bustabit.com/submit> and the HTTP body should be =
the raw transaction hex encoded as text.

This seems too detailed. If you want to specify the message protocol, =
maybe that can have it=E2=80=99s own section where you list each of the =
messages, the URL, parameters and encoding. Then you can keep this =
overview section shorter.

The use of HTTPS kind of forces sender and recipient to use a 3rd party =
service, even though this could done bilaterally. What if the payment =
request contained a (single-use) Onion URL an expiration date? The =
recipient would have to keep a hidden service up until the expiration =
date, though the sender could try again if there=E2=80=99s temporary =
reachability issue.

Adding a (onion) URL to the the payment request also makes gradual =
adoption easier, because recipients don=E2=80=99t need to worry if =
senders support this protocol.

> Step 3. Receiver processes the transaction and returns a partially =
signed coinjoin
>=20
> The receiver validates the transaction is valid, pays himself and is =
eligible for propation. The receiver then adds one of his own inputs =
(known as the "contributed input") and increase the output that pays =
himself by the contributed input amount. Doing so will invalidate the =
"template transaction"'s original input signatures, so the sender needs =
to return this "partial transaction" back to the receiver to sign. This =
is returned as a hex-encoded raw transaction a response to the original =
HTTP POST request.

> * Bustapay could be abused by a malicious party to query if you own a =
deposit address or not. So never accept a bustapay transaction that pays =
an already used deposit address


Indeed, once the recipient adds funds, they reveal more about themselves =
to the sender then they would otherwise. I think that needs more =
elaboration.

I assume the transaction in step (1) is some sort of collateral to =
insure they=E2=80=99re not just trying to extract private information =
from you? However if fees are low they could still double-spend it after =
the recipient revealed their address, especially because the recipient =
has no way of RBF=E2=80=99ing the original (though CPFP could help). =
Perhaps require that the original transaction pays a fee based on the =
expected size of the final transaction?

>=20
> Notes for sending applications:
>=20
> * The HTTP response must *not* be trusted. It should be fully =
validated that no unexpected changes have been made to the transaction.

Not trusting anything is obvious. :-) It=E2=80=99s better to explicitly =
state what exactly needs to be verified (amounts, destinations, inputs, =
etc), and maybe list a few obvious shenanigans to watch out for.

A more general concern is that the sender can=E2=80=99t know for sure =
the recipient really supports this protocol, so it should assume that =
whatever information it pings to some API could be used maliciously. In =
what ways could it be abused?

Sjors

--Apple-Mail=_48127117-8F35-4700-ADFA-F388148ACF8B
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=utf-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; =
charset=3Dutf-8"></head><body style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; line-break: after-white-space;" class=3D""><div =
class=3D""><br class=3D""></div><div><blockquote type=3D"cite" =
class=3D""><div class=3D"">Op 30 aug. 2018, om 22:24 heeft Ryan Havar =
via bitcoin-dev &lt;<a =
href=3D"mailto:bitcoin-dev@lists.linuxfoundation.org" =
class=3D"">bitcoin-dev@lists.linuxfoundation.org</a>&gt; het volgende =
geschreven:</div><div class=3D""><div class=3D""><br class=3D""></div><div=
 class=3D"">=3D=3DMotivation=3D=3D<br class=3D""></div><div class=3D""><br=
 class=3D""></div><div class=3D"">One of the most powerful heuristic's =
employed by those whose goal is to undermine<br class=3D""></div><div =
class=3D"">bitcoin's fungiblity has been to assume all inputs of a =
transaction are signed by<br class=3D""></div><div class=3D"">a single =
party. In the few cases this assumption does not hold, it is =
generally<br class=3D""></div><div class=3D"">readibly recognizable =
(e.g. traditional coinjoins have a very obvious structure,<br =
class=3D""></div><div class=3D"">or multisig outputs are most frequently =
validated onchain).</div></div></blockquote><div><br =
class=3D""></div><div>In addition to mixers, custodial wallets and =
exchanges also contribute to breaking this heuristic; even though =
there=E2=80=99s a single entity signing multiple inputs, that entity =
doesn=E2=80=99t represent a single owner of the funds. As with mixers, =
exchanges and custodial wallets can sometimes be spotted as well, but we =
don=E2=80=99t know what percentage is missed.</div><div><br =
class=3D""></div><div>Breaking this heuristic at scale would be good, =
but do we know to what degree it=E2=80=99s already broken? Is there any =
empirical research measuring its accuracy and false positive =
rate?</div><div><br class=3D""></div><blockquote type=3D"cite" =
class=3D""><div class=3D""><div class=3D"">Should bustapay enjoy =
widespread adoption, a "v2" specification</div><div class=3D"">will be =
created with desired extensions.<br =
class=3D""></div></div></blockquote><div><br class=3D""></div><div>I =
would not put future promises in a BIP. Rather, explain how extension =
might work.</div><br class=3D""><blockquote type=3D"cite" class=3D""><div =
class=3D""><div class=3D"">=3D=3DSpecification=3D=3D<br =
class=3D""></div><div class=3D""><br class=3D""></div><div class=3D"">A =
bustapay payment is made from a sender to a receiver.<br =
class=3D""></div><div class=3D""><br class=3D""></div><div class=3D"">Step=
 1. Sender creates a bitcoin transaction paying the receiver<br =
class=3D""></div><div class=3D""><br class=3D""></div><div class=3D"">This=
 transaction must be fully valid, signed and all inputs must use segwit. =
This transaction is known as the "template =
transaction=E2=80=9D.</div></div></blockquote><div><br =
class=3D""></div><div>Using PSBT?</div><br class=3D""><blockquote =
type=3D"cite" class=3D""><div class=3D""><div class=3D""> This =
transaction must not be propagated on the bitcoin network.<br =
class=3D""></div></div></blockquote><div><br class=3D""></div><div>This =
can=E2=80=99t be guaranteed, and even after step 5 a reorg could cause =
it to get confirmed. It=E2=80=99s useful to explain why this doesn=E2=80=99=
t matter.&nbsp;</div><br class=3D""><blockquote type=3D"cite" =
class=3D""><div class=3D""><div class=3D""><br class=3D""></div><div =
class=3D"">Step 2. Sender gives the "template transaction" to the =
receiver<br class=3D""></div><div class=3D""><br class=3D""></div><div =
class=3D"">This would generally be done as an HTTP =
POST.</div></div></blockquote><blockquote type=3D"cite" class=3D""><div =
class=3D""><div class=3D"">The exact URL to submit it to could be =
specified with a bip21 encoded address. Such as =
bitcoin:2NABbUr9yeRCp1oUCtVmgJF8HGRCo3ifpTT?bustapay=3D<a =
href=3D"https://bp.bustabit.com/submit" =
class=3D"">https://bp.bustabit.com/submit</a> and the HTTP body should =
be the raw transaction hex encoded as text.<br =
class=3D""></div></div></blockquote><div><br =
class=3D""></div><div><div>This seems too detailed. If you want to =
specify the message protocol, maybe that can have it=E2=80=99s own =
section where you list each of the messages, the URL, parameters and =
encoding. Then you can keep this overview section shorter.</div><div><br =
class=3D""></div><div>The use of HTTPS kind of forces sender and =
recipient to use a 3rd party service, even though this could done =
bilaterally. What if the payment request contained a (single-use) Onion =
URL an expiration date? The recipient would have to keep a hidden =
service up until the expiration date, though the sender could try again =
if there=E2=80=99s temporary reachability issue.</div><div><br =
class=3D""></div><div>Adding a (onion) URL to the the payment request =
also makes gradual adoption easier, because recipients don=E2=80=99t =
need to worry if senders support this protocol.</div><div><br =
class=3D""></div></div><blockquote type=3D"cite" class=3D""><div =
class=3D""><div class=3D"">Step 3. Receiver processes the transaction =
and returns a partially signed coinjoin<br class=3D""></div><div =
class=3D""><br class=3D""></div><div class=3D"">The receiver validates =
the transaction is valid, pays himself and is eligible for propation. =
The receiver then adds one of his own inputs (known as the "contributed =
input") and increase the output that pays himself by the contributed =
input amount. Doing so will invalidate the "template transaction"'s =
original input signatures, so the sender needs to return this "partial =
transaction" back to the receiver to sign. This is returned as a =
hex-encoded raw transaction a response to the original HTTP POST =
request.<br class=3D""></div></div></blockquote><div><br =
class=3D""></div><div><blockquote type=3D"cite" class=3D""><div =
class=3D"">* Bustapay could be abused by a malicious party to query if =
you own a deposit address or not. So never accept a bustapay transaction =
that pays an already used deposit =
address</div></blockquote></div><div><br class=3D""></div><div>Indeed, =
once the recipient adds funds, they reveal more about themselves to the =
sender then they would otherwise. I think that needs more =
elaboration.</div><div><br class=3D""></div>I assume the transaction in =
step (1) is some sort of collateral to insure they=E2=80=99re not just =
trying to extract private information from you? However if fees are low =
they could still double-spend it after the recipient revealed their =
address, especially because the recipient has no way of RBF=E2=80=99ing =
the original (though CPFP could help). Perhaps require that the original =
transaction pays a fee based on the expected size of the final =
transaction?</div><div><br class=3D""><blockquote type=3D"cite" =
class=3D""><div class=3D""><div class=3D""><br class=3D""></div><div =
class=3D"">Notes for sending applications:</div><div class=3D""><br =
class=3D""></div><div class=3D"">* The HTTP response must *not* be =
trusted. It should be fully validated that no unexpected changes have =
been made to the transaction.<br =
class=3D""></div></div></blockquote><div><br class=3D""></div><div>Not =
trusting anything is obvious. :-) It=E2=80=99s better to explicitly =
state what exactly needs to be verified (amounts, destinations, inputs, =
etc), and maybe list a few obvious shenanigans to watch out =
for.</div><div><br class=3D""></div><div>A more general concern is that =
the sender can=E2=80=99t know for sure the recipient really supports =
this protocol, so it should assume that whatever information it pings to =
some API could be used maliciously. In what ways could it be =
abused?</div></div><br class=3D""><div =
class=3D"">Sjors</div></body></html>=

--Apple-Mail=_48127117-8F35-4700-ADFA-F388148ACF8B--

--Apple-Mail=_35E0A336-43BB-4270-8B25-FDEBE5AD051A
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename=signature.asc
Content-Type: application/pgp-signature;
	name=signature.asc
Content-Description: Message signed with OpenPGP

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEE7ZvfetalXiMuhFJCV/+b28wwEAkFAluWY/YACgkQV/+b28ww
EAmizg//YrJjH+y2VprN2yObWtCfctE3NbCgIslkprtLZFF60mbAPw3HTeZLqZiR
Vzeis3RKJL62M/eli5l+AL8O8cJrzSSWmS2zZKvjuuu192id07AACHrDPgsL+mMc
DDXYgxrtslh8gfWdbgOvc36A2EZXbmwzTVLqkv7j3DMMNLyF23HvL+uPo8mlNP4m
O5j446YXHB/Jj8JGWlluMn6rIJ/tQ988Gif0YQ1L8xK/f/mzwx6Hp9MJX2iKKXFN
05Aj6dHOMA/EXHU/Mkxki23oGUJoxh1TgOYtT2Lt4lrcqaZ2ecwuxBP6Stgsnwbr
+QsKFvhQUqYbURDr5chtzwhclsqZthOOMe06I8Fywmg2UxA2J94kamWwp5I7K98o
VRlw/6ebVyvDY9nps+GiF29BbBMrjYsTPBY335C/Qf3eR/GiWmTfAEmfksOjcpGP
2FmpbnVGVbls/GsUFWqCCCcY9zLMNjFarmZCjr9Lz4AOeXHQ022iL5q1A7RXdZKJ
2GloCXHsblkYtoNn+fRO1ctq6x5ZKIuJVhAO6Fw2/UksxxrImD3kcc63Zy1zX9Fa
hByZ5uRLhDwGViKt+ZcB4a5v8RNNICBIdrjveUSrQb/XVFqgqq4kAXg0GR+2gKs0
MkCC31KavbWAwZWbW1aRclWTBKdkoiTMRoL2DorupnpS97CgjDM=
=ukvu
-----END PGP SIGNATURE-----

--Apple-Mail=_35E0A336-43BB-4270-8B25-FDEBE5AD051A--