summaryrefslogtreecommitdiff
path: root/04/48b3742cc395f5a74f2ee8ee5dcee60185a6c9
blob: f9b2431a7e5bf98e3bf35163ef54ff6b20827263 (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
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
Return-Path: <saulo@astrotown.de>
Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org
	[172.17.192.35])
	by mail.linuxfoundation.org (Postfix) with ESMTPS id D51C4137D
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Fri,  4 Oct 2019 09:21:44 +0000 (UTC)
X-Greylist: delayed 00:06:00 by SQLgrey-1.7.6
Received: from astrotown.de (astrotown.de [198.50.146.142])
	by smtp1.linuxfoundation.org (Postfix) with ESMTP id 4FBF734F
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Fri,  4 Oct 2019 09:21:43 +0000 (UTC)
Received: from saulos-imac.fritz.box (ipbcc3afab.dynamic.kabel-deutschland.de
	[188.195.175.171])
	by astrotown.de (Postfix) with ESMTPSA id EFD6F2C60682
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Fri,  4 Oct 2019 05:15:41 -0400 (EDT)
From: Saulo Fonseca <saulo@astrotown.de>
Content-Type: multipart/alternative;
	boundary="Apple-Mail=_1C0B04CE-23E4-4165-91CF-DB8DEDF49EC4"
Mime-Version: 1.0 (Mac OS X Mail 11.5 \(3445.9.1\))
Message-Id: <4E84E4B0-7354-4681-985F-3DBFAA4E856F@astrotown.de>
Date: Fri, 4 Oct 2019 11:15:40 +0200
To: Christian Decker via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org>
X-Mailer: Apple Mail (2.3445.9.1)
X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,HTML_MESSAGE
	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: Fri, 04 Oct 2019 09:42:41 +0000
Subject: [bitcoin-dev] ChainWallet - A way to prevent loss of funds by
	physical violence
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: Fri, 04 Oct 2019 09:21:45 -0000


--Apple-Mail=_1C0B04CE-23E4-4165-91CF-DB8DEDF49EC4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8

Hi everyone

If you are a hodler, I like to propose the creation of a key stretching =
as a new layer of protection over your current wallet. I call it =
ChainWallet. Whatever is the method used to generate your private key, =
we can do the following:

newPrivKey =3D sha256(sha256(sha256(=E2=80=A6sha256(privKey)=E2=80=A6)))
NewWallet =3D PubAddress(newPrivKey)
In this way we create a chain of hashes over your private key and =
generate a new wallet from it. If the chain is very long (billions or =
trillions of hashes) it will take a long time to be created. If you =
don=E2=80=99t keep the newPrivKey, the only way to move coins in the =
NewWallet is to generate the chain again.

The length of the chain can be easy memorized as an exponent such as =
2^40 or 10^12.

What is that gut for? You will not be able to move your coins in an =
unplanned way such as being tortured by a kidnaper. You can create a =
wallet that takes days or even months to return the final address.

Comparison with a BrainWallet

If the first privKey is the hash of a password, your ChainWallet can be =
compared to a BrainWallet with a chain added to it. BrainWallets have a =
bad reputation because it is possible to create a brute-force attack =
against it. There are reports where the attacker was able to guess the =
password by generating hundreds of thousands of hashes per second. But, =
if you use a ChainWallet that takes one second to be generated, it means =
that the speed of an attack would be reduced to one guess per second. =
This makes a brute force attack practically impossible.

Entropy

The ChainWallet adds only a few bits of entropy to your key. The idea =
here is not to increase the entropy, but to add =E2=80=9Ctime=E2=80=9D =
as part of the puzzle.

SHA-256

I am suggesting the use of SHA-256 because it is the most popular hash =
algorithm in the crypto community. But you could use SHA-512 or a slower =
hash algorithm such as Bcrypt to do it. But keep in mind that other hash =
algorithms can reduce the entropy.

The idea is to add time to the key generation. If you use many SHA-256 =
or a few SHA-512, as long as both need the same time to be generated, =
there is no difference.

Other hashes have the advantage that a hardware implementation of it is =
not widespread.

ASICs

Someone could mention that ASICs get more and more powerful and could =
crack a ChainWallet. But they have a huge hash rate because they =
calculate it in parallel. A ChainWallet requires that the output of a =
hash would be the input of the next calculation. This dramatically =
reduces the speed of a hardware implementation of such algorithms.

Let=E2=80=99s pick an example:  The Bitfury Clarke has 8.154 cores and =
runs 120 Gh/s. This means that each core can perform about 14.72 Mh/s. =
This speed is all that you can get with one of the best ASIC on the =
market. 17.72 Mh/s is only about 17,7 times faster than a typical =
computer. This speed can only increase slowly, as technology needs time =
to make the transistors run faster. So, the best way to generate a =
ChainWallet is by using such an ASIC core.

Misuse

Someone could argue that people would misuse it by picking easy to =
remember passwords or small chain length. A wallet implementation could =
solve it by forcing a minimum length for the chain and block commonly =
used words for the password. It is a matter of design.

Theft

The major advantage of a ChainWallet is the ability to avoid a theft. If =
your wallet takes a really long time to be generated and someone tries =
to force you to give your private key, you would not be able to do it, =
even if you really want. You could also give away a wrong password or =
chain length and he/she is not able to verify it. The chances are very =
small that he/she will wait weeks of months for the chain generation of =
even that he/she is able to do the chain calculation.

Final Thoughts

A ChainWallet could be used as an alternative to BIP39. Instead of =
keeping 24 words, you would have a password and two numbers, a base and =
an exponent, that defines the length of the chain. This is easier to =
memorize, so you do not need to write it down.

This is only meant as an additional option along with all others =
available in the crypto environment, such as multisig and smart =
contracts. As for those other ideas, the ChainWallet is not applicable =
in every case.

When the day arrives at which you want to stop hodling and transferring =
your coins to another location, you should re-generate your wallet in a =
planned way with the same original private key and length of the chain. =
Then, after waiting until the program concludes, you will get the new =
private key back.

Web Links
=09
The original idea can be found on this post:

https://www.reddit.com/user/sauloqf/comments/a3q8dt/chainwallet =
<https://www.reddit.com/user/sauloqf/comments/a3q8dt/chainwallet>

A proof of concept in C++ can be found on this link:

https://github.com/Saulo-Fonseca/ChainWallet =
<https://github.com/Saulo-Fonseca/ChainWallet>

The community is testing the concept for a while. You can find =
discussions on this links:

=
https://www.reddit.com/r/Bitcoin/comments/cya467/chainwallet_challenge_get=
_01_btc_if_you_solve_it =
<https://www.reddit.com/r/Bitcoin/comments/cya467/chainwallet_challenge_ge=
t_01_btc_if_you_solve_it>

=
https://www.reddit.com/r/Bitcoin/comments/d9ltec/does_someone_know_how_to_=
submit_a_bip_for_bitcoin =
<https://www.reddit.com/r/Bitcoin/comments/d9ltec/does_someone_know_how_to=
_submit_a_bip_for_bitcoin>

Saulo Fonseca


--Apple-Mail=_1C0B04CE-23E4-4165-91CF-DB8DEDF49EC4
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""><div class=3D"">Hi everyone</div><div class=3D""><br =
class=3D""></div><div class=3D"">If you are a hodler,&nbsp;I like to =
propose the creation of a key stretching as a new layer of protection =
over your current wallet. I call it ChainWallet. Whatever is the method =
used to generate your private key, we can do the following:</div><div =
class=3D""><br class=3D""></div><div class=3D""><ul class=3D""><li =
class=3D"">newPrivKey =3D =
sha256(sha256(sha256(=E2=80=A6sha256(privKey)=E2=80=A6)))</li><li =
class=3D"">NewWallet =3D PubAddress(newPrivKey)</li></ul></div><div =
class=3D"">In this way we create a chain of hashes over your private key =
and generate a new wallet from it. If the chain is very long (billions =
or trillions of hashes) it will take a long time to be created. If you =
don=E2=80=99t keep the newPrivKey, the only way to move coins in the =
NewWallet is to generate the chain again.</div><div class=3D""><br =
class=3D""></div><div class=3D"">The length of the chain can be easy =
memorized as an exponent such as 2^40 or 10^12.</div><div class=3D""><br =
class=3D""></div><div class=3D"">What is that gut for? You will not be =
able to move your coins in an unplanned way such as being tortured by a =
kidnaper. You can create a wallet that takes days or even months to =
return the final address.</div><div class=3D""><br class=3D""></div><div =
class=3D""><b class=3D"">Comparison with a BrainWallet</b></div><div =
class=3D""><br class=3D""></div><div class=3D"">If the first privKey is =
the hash of a password, your ChainWallet can be compared to a =
BrainWallet with a chain added to it. BrainWallets have a bad reputation =
because it is possible to create a brute-force attack against it. There =
are reports where the attacker was able to guess the password by =
generating hundreds of thousands of hashes per second. But, if you use a =
ChainWallet that takes one second to be generated, it means that the =
speed of an attack would be reduced to one guess per second. This makes =
a brute force attack practically impossible.</div><div class=3D""><br =
class=3D""></div><div class=3D""><b class=3D"">Entropy</b></div><div =
class=3D""><br class=3D""></div><div class=3D"">The ChainWallet adds =
only a few bits of entropy to your key. The idea here is not to increase =
the entropy, but to add =E2=80=9Ctime=E2=80=9D as part of the =
puzzle.</div><div class=3D""><br class=3D""></div><div class=3D""><b =
class=3D"">SHA-256</b></div><div class=3D""><br class=3D""></div><div =
class=3D"">I am suggesting the use of SHA-256 because it is the most =
popular hash algorithm in the crypto community. But you could use =
SHA-512 or a slower hash algorithm such as Bcrypt to do it. But keep in =
mind that other hash algorithms can reduce the entropy.</div><div =
class=3D""><br class=3D""></div><div class=3D"">The idea is to add time =
to the key generation. If you use many SHA-256 or a few SHA-512, as long =
as both need the same time to be generated, there is no =
difference.</div><div class=3D""><br class=3D""></div><div =
class=3D"">Other hashes have the advantage that a hardware =
implementation of it is not widespread.</div><div class=3D""><br =
class=3D""></div><div class=3D""><b class=3D"">ASICs</b></div><div =
class=3D""><br class=3D""></div><div class=3D"">Someone could mention =
that ASICs get more and more powerful and could crack a ChainWallet. But =
they have a huge hash rate because they calculate it in parallel. A =
ChainWallet requires that the output of a hash would be the input of the =
next calculation. This dramatically reduces the speed of a hardware =
implementation of such algorithms.</div><div class=3D""><br =
class=3D""></div><div class=3D"">Let=E2=80=99s pick an example: =
&nbsp;The Bitfury Clarke has 8.154 cores and runs 120 Gh/s. This means =
that each core can perform about 14.72 Mh/s. This speed is all that you =
can get with one of the best ASIC on the market. 17.72 Mh/s is only =
about 17,7 times faster than a typical computer. This speed can only =
increase slowly, as technology needs time to make the transistors run =
faster. So, the best way to generate a ChainWallet is by using such an =
ASIC core.</div><div class=3D""><br class=3D""></div><div class=3D""><b =
class=3D"">Misuse</b></div><div class=3D""><br class=3D""></div><div =
class=3D"">Someone could argue that people would misuse it by picking =
easy to remember passwords or small chain length. A wallet =
implementation could solve it by forcing a minimum length for the chain =
and block commonly used words for the password. It is a matter of =
design.</div><div class=3D""><br class=3D""></div><div class=3D""><b =
class=3D"">Theft</b></div><div class=3D""><br class=3D""></div><div =
class=3D"">The major advantage of a ChainWallet is the ability to avoid =
a theft. If your wallet takes a really long time to be generated and =
someone tries to force you to give your private key, you would not be =
able to do it, even if you really want. You could also give away a wrong =
password or chain length and he/she is not able to verify it. The =
chances are very small that he/she will wait weeks of months for the =
chain generation of even that he/she is able to do the chain =
calculation.</div><div class=3D""><br class=3D""></div><div class=3D""><b =
class=3D"">Final Thoughts</b></div><div class=3D""><br =
class=3D""></div><div class=3D"">A ChainWallet could be used as an =
alternative to BIP39. Instead of keeping 24 words, you would have a =
password and two numbers, a base and an exponent, that defines the =
length of the chain. This is easier to memorize, so you do not need to =
write it down.</div><div class=3D""><br class=3D""></div><div =
class=3D"">This is only meant as an additional option along with all =
others available in the crypto environment, such as multisig and smart =
contracts. As for those other ideas, the ChainWallet is not applicable =
in every case.</div><div class=3D""><br class=3D""></div><div =
class=3D"">When the day arrives at which you want to stop hodling and =
transferring your coins to another location, you should re-generate your =
wallet in a planned way with the same original private key and length of =
the chain. Then, after waiting until the program concludes, you will get =
the new private key back.</div><div class=3D""><br class=3D""></div><div =
class=3D""><b class=3D"">Web Links</b></div><div class=3D""><span =
class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span></div><div class=3D"">The original idea can be found on this =
post:</div><div class=3D""><br class=3D""></div><div class=3D""><a =
href=3D"https://www.reddit.com/user/sauloqf/comments/a3q8dt/chainwallet" =
class=3D"">https://www.reddit.com/user/sauloqf/comments/a3q8dt/chainwallet=
</a></div><div class=3D""><br class=3D""></div><div class=3D"">A proof =
of concept in C++ can be found on this link:</div><div class=3D""><br =
class=3D""></div><div class=3D""><a =
href=3D"https://github.com/Saulo-Fonseca/ChainWallet" =
class=3D"">https://github.com/Saulo-Fonseca/ChainWallet</a></div><div =
class=3D""><br class=3D""></div><div class=3D"">The community is testing =
the concept for a while. You can find discussions on this =
links:</div><div class=3D""><br class=3D""></div><div class=3D""><a =
href=3D"https://www.reddit.com/r/Bitcoin/comments/cya467/chainwallet_chall=
enge_get_01_btc_if_you_solve_it" =
class=3D"">https://www.reddit.com/r/Bitcoin/comments/cya467/chainwallet_ch=
allenge_get_01_btc_if_you_solve_it</a></div><div class=3D""><br =
class=3D""></div><div class=3D""><a =
href=3D"https://www.reddit.com/r/Bitcoin/comments/d9ltec/does_someone_know=
_how_to_submit_a_bip_for_bitcoin" =
class=3D"">https://www.reddit.com/r/Bitcoin/comments/d9ltec/does_someone_k=
now_how_to_submit_a_bip_for_bitcoin</a></div><div class=3D""><br =
class=3D""></div><div class=3D""><span style=3D"orphans: 2; text-align: =
-webkit-auto; widows: 2; -webkit-text-decorations-in-effect: none;" =
class=3D"">Saulo Fonseca</span></div></div><div class=3D""><div =
style=3D"color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; =
text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; =
word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: =
after-white-space;" class=3D""><div style=3D"color: rgb(0, 0, 0); =
letter-spacing: normal; orphans: auto; text-align: start; text-indent: =
0px; text-transform: none; white-space: normal; widows: auto; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: =
break-word; -webkit-nbsp-mode: space; -webkit-line-break: =
after-white-space;" class=3D""><div style=3D"color: rgb(0, 0, 0); =
letter-spacing: normal; orphans: auto; text-align: start; text-indent: =
0px; text-transform: none; white-space: normal; widows: auto; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: =
break-word; -webkit-nbsp-mode: space; -webkit-line-break: =
after-white-space;" class=3D""><div style=3D"color: rgb(0, 0, 0); =
letter-spacing: normal; orphans: auto; text-align: start; text-indent: =
0px; text-transform: none; white-space: normal; widows: auto; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: =
break-word; -webkit-nbsp-mode: space; -webkit-line-break: =
after-white-space;" class=3D""><span class=3D"Apple-style-span" =
style=3D"border-collapse: separate; font-variant-ligatures: normal; =
font-variant-position: normal; font-variant-numeric: normal; =
font-variant-alternates: normal; font-variant-east-asian: normal; =
line-height: normal; border-spacing: 0px; =
-webkit-text-decorations-in-effect: none;"><div style=3D"word-wrap: =
break-word; -webkit-nbsp-mode: space; -webkit-line-break: =
after-white-space;" class=3D""><span class=3D"Apple-style-span" =
style=3D"border-collapse: separate; color: rgb(0, 0, 0); font-family: =
Helvetica; font-style: normal; font-variant-ligatures: normal; =
font-variant-position: normal; font-variant-caps: normal; =
font-variant-numeric: normal; font-variant-alternates: normal; =
font-variant-east-asian: normal; font-weight: normal; letter-spacing: =
normal; line-height: normal; orphans: 2; text-align: -webkit-auto; =
text-indent: 0px; text-transform: none; white-space: normal; widows: 2; =
word-spacing: 0px; border-spacing: 0px; =
-webkit-text-decorations-in-effect: none; -webkit-text-stroke-width: =
0px;"><div style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; =
-webkit-line-break: after-white-space;" class=3D""><span =
class=3D"Apple-style-span" style=3D"border-collapse: separate; color: =
rgb(0, 0, 0); font-family: Helvetica; font-style: normal; =
font-variant-ligatures: normal; font-variant-position: normal; =
font-variant-caps: normal; font-variant-numeric: normal; =
font-variant-alternates: normal; font-variant-east-asian: normal; =
font-weight: normal; letter-spacing: normal; line-height: normal; =
orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: =
none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: =
0px; -webkit-text-decorations-in-effect: none; =
-webkit-text-stroke-width: 0px;"><div style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" =
class=3D""><span class=3D"Apple-style-span" style=3D"border-collapse: =
separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: =
normal; font-variant-ligatures: normal; font-variant-position: normal; =
font-variant-caps: normal; font-variant-numeric: normal; =
font-variant-alternates: normal; font-variant-east-asian: normal; =
font-weight: normal; letter-spacing: normal; line-height: normal; =
orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: =
none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: =
0px; -webkit-text-decorations-in-effect: none; =
-webkit-text-stroke-width: 0px;"><div style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" =
class=3D""><span class=3D"Apple-style-span" style=3D"border-collapse: =
separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: =
normal; font-variant-ligatures: normal; font-variant-position: normal; =
font-variant-caps: normal; font-variant-numeric: normal; =
font-variant-alternates: normal; font-variant-east-asian: normal; =
font-weight: normal; letter-spacing: normal; line-height: normal; =
orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: =
none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: =
0px; -webkit-text-decorations-in-effect: none; =
-webkit-text-stroke-width: 0px;"><div style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" =
class=3D""><span class=3D"Apple-style-span" style=3D"border-collapse: =
separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: =
normal; font-variant-ligatures: normal; font-variant-position: normal; =
font-variant-caps: normal; font-variant-numeric: normal; =
font-variant-alternates: normal; font-variant-east-asian: normal; =
font-weight: normal; letter-spacing: normal; line-height: normal; =
orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: =
none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: =
0px; -webkit-text-decorations-in-effect: none; =
-webkit-text-stroke-width: 0px;"><div style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" =
class=3D""><div class=3D""><br =
class=3D""></div></div></span></div></span></div></span></div></span></div=
></span></div></span></div></div></div></div></div></body></html>=

--Apple-Mail=_1C0B04CE-23E4-4165-91CF-DB8DEDF49EC4--