summaryrefslogtreecommitdiff
path: root/b8/abd252a689355769d63b10158eac9b1329929e
blob: 917d60950b45c97857c80a072312cbf668f04fef (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
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
Received: from sog-mx-4.v43.ch3.sourceforge.com ([172.29.43.194]
	helo=mx.sourceforge.net)
	by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76)
	(envelope-from <memwallet.info@gmail.com>) id 1XWXNj-0004Yr-IM
	for bitcoin-development@lists.sourceforge.net;
	Tue, 23 Sep 2014 21:12:19 +0000
Received-SPF: pass (sog-mx-4.v43.ch3.sourceforge.com: domain of gmail.com
	designates 209.85.223.194 as permitted sender)
	client-ip=209.85.223.194; envelope-from=memwallet.info@gmail.com;
	helo=mail-ie0-f194.google.com; 
Received: from mail-ie0-f194.google.com ([209.85.223.194])
	by sog-mx-4.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128)
	(Exim 4.76) id 1XWXNa-0003zN-Df
	for bitcoin-development@lists.sourceforge.net;
	Tue, 23 Sep 2014 21:12:19 +0000
Received: by mail-ie0-f194.google.com with SMTP id tr6so1923361ieb.1
	for <bitcoin-development@lists.sourceforge.net>;
	Tue, 23 Sep 2014 14:12:04 -0700 (PDT)
MIME-Version: 1.0
X-Received: by 10.50.79.232 with SMTP id m8mr10783112igx.0.1411506724664; Tue,
	23 Sep 2014 14:12:04 -0700 (PDT)
Received: by 10.107.157.130 with HTTP; Tue, 23 Sep 2014 14:12:04 -0700 (PDT)
Date: Tue, 23 Sep 2014 17:12:04 -0400
Message-ID: <CAKzHBKkHpod+7T0uCtESVNFmgFAbGF8-AFJxKmfUwA-pkt_BrA@mail.gmail.com>
From: Mem Wallet <memwallet.info@gmail.com>
To: bitcoin-development@lists.sourceforge.net
Content-Type: multipart/alternative; boundary=089e013a0606ebfde00503c2049d
X-Spam-Score: -0.6 (/)
X-Spam-Report: Spam Filtering performed by mx.sourceforge.net.
	See http://spamassassin.org/tag/ for more details.
	-1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for
	sender-domain
	0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider
	(memwallet.info[at]gmail.com)
	-0.0 SPF_PASS               SPF: sender matches SPF record
	1.0 HTML_MESSAGE           BODY: HTML included in message
	-0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from
	author's domain
	0.1 DKIM_SIGNED            Message has a DKIM or DK signature,
	not necessarily valid
	-0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
X-Headers-End: 1XWXNa-0003zN-Df
Subject: [Bitcoin-development] cryptographic review requested
X-BeenThere: bitcoin-development@lists.sourceforge.net
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: <bitcoin-development.lists.sourceforge.net>
List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/bitcoin-development>,
	<mailto:bitcoin-development-request@lists.sourceforge.net?subject=unsubscribe>
List-Archive: <http://sourceforge.net/mailarchive/forum.php?forum_name=bitcoin-development>
List-Post: <mailto:bitcoin-development@lists.sourceforge.net>
List-Help: <mailto:bitcoin-development-request@lists.sourceforge.net?subject=help>
List-Subscribe: <https://lists.sourceforge.net/lists/listinfo/bitcoin-development>,
	<mailto:bitcoin-development-request@lists.sourceforge.net?subject=subscribe>
X-List-Received-Date: Tue, 23 Sep 2014 21:12:19 -0000

--089e013a0606ebfde00503c2049d
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hello,
I've made a proposal for a standardized ecies scheme for bitcoin
communication. To address gmaxwell's criticism, I'd like to also
follow up with a proposed change to BIP44, such that a structured
wallet would also include a series of identity keys, both addresses
which will be used for signing, and public keys which would be used
as destinations for encrypted messages.

If anyone is familiar with ECIES and would be interested, there is a
working implementation at http://memwallet.info/btcmssgs.html,
which also includes this whitepaper:

Abstract This document describes a scheme for sending signed encrypted
messages using bitcoin public and private keys. Motivation PGP and
Bitmessage and other secure communications channels exist. This standard
allows for secure messaging using a bitcoin wallet alone, without the need
for other software. This standard allows the owner of an address to
conveniently prove ownership to the holder of another address privately
without the need for separate secure communications channels. Specification=
:
Message Format In the rest of this text we will assume the public key
cryptography used in Bitcoin. The || operator is concatenation. All
operations are defined over binary, and not text conversion of the data.
When serializing public keys the compressed encoding is always used, even
if the input parameters are passed as uncompressed. Bitcoin addresses are
always serialized from compressed public keys, and for mainnet. (directives
to use testnet or uncompressed keys ignored) String literals are
represented as if for the C programming language in native UTF-8. No
assumptions are made about the payload message format, it may even be
binary. Caveat Decryptor. Plain unformatted text message payloads are
recommended to use utf-8.

   - CompactSize format is a variable size little endian length field
   serialization format, know as a bitcoin "Variable length integer"
   - CompactSizePrefix(X) =3D CompactSize(X) || X
   - QTHASH(x) =3D SHA256((SHA256( CompactSizePrefix("Bitcoin Signed
   Message:\n") || CompactSizePrefix(x) )

This standard assumes the reader is familiar with the bitcoin compact
signature format, which is a 65 byte signature which allows the verifier to
recover the public key associated with the signature, eliminating the need
to send it with the message. Once consequence of this format is that
signatures of tampered messages will nearly always result in some public
key, but it will not be the same as the orignial signing key. The address
of the sender will be provided to enable validation of the signature. The
format is a 1 byte recid, followed by ECDSA R then S values.

   - CompactSign( PrivateKey, 32 byte QT Hash ) =3D=3D 65 byte message
   - CompactVerify( 65 byte message, 32 bytes Hash ) public key counterpart
   of (PrivateKey)
   - ECIES with HMAC_SHA256 for mac, PBKDF2 for KDF
   - PBKDF2 is used with 2048 iterations, salt=3D( "Bitcoin Secure Message"
   || ecies_nonce_publickey )
   - AES is used with 256 bit keys, and CFB mode, with a 128 bit feedback
   buffer. No padding or envelope, simply a pure byte cipher
   - compact_signed_message =3D 0x01 || CompactSizePrefix(M) ||
   Sender_Address || Signature
   - compact_unsigned_message =3D 0x00 || CompactSizePrefix(M)
   - Secure message format: ECIES( compact_signed_message or
   compact_unsigned_message )

Summary of the functions defined:

   - eM =3D SendMessage( M, Signing_Key, Dest_Pub )
   - M,Sender_Address =3D ReceiveMessage( eM, Decrypting_Key ) It is
   acceptable for deterministic nonces to be used for signatures, however
   nonces generated for ECIES must be high quality random bytes. (excepting
   unit test vectors)

Message Sending Inputs:

   - The message to send "M" (treat as precise binary bytes, no space
   stripping or normalization)
   - The bitcoin private key "Signing_Key" to be used to sign the message
   - The bitcoin public key "Dest_Pub" to be used as the destination of the
   message Algorithm Calculations:
   - Calculate the QTHASH(M) to obtain "M_hash", 32 bytes of data
   - if signing Sign with CompactSign(Signing_Key,M_hash) to obtain
   "Signature", 65 bytes of data ** Calculate the compressed address of
   Signing_Key to obtain "Sender_Address" 21 bytes of data ** Serialize 0x0=
1
   || CompactSizePrefix(M) || Sender_Address || Signature to obtain
   "Signed_Message"
   - if not signing, instead Serialize 0x00 || CompactSizePrefix(M) to
   obtain "Unsigned_Message"
   - Generate 32 random bytes "ecies_nonce_bytes"
   - Generate a bitcoin private key from ecies_nonce_bytes, "Nonce_Key" 32
   bytes of data (retry if invalid)
   - Derive the compressed public key of Nonce_Key, "Nonce_Pub", 33 bytes
   of data
   - ECMultiply Dest_Pub by Nonce_Key to obtain the point
   "Shared_Secret_Point"
   - Serialize Shared_Secret_Point as a compressed point "Shared_Secret"
   - Derive "KeyingBytes" =3D PBKDF2( Shared_Secret ) to get 80 bytes of da=
ta
   - Directly Derive "AES256_Key" from the first 32 bytes of KeyingBytes
   (index 0 to 32)
   - Directly Derive "HMAC_Key" from the second 32 bytes of KeyingBytes
   (index 32 to 64)
   - Directly Derive "AES_IV" from the last 16 bytes of KeyingBytes (index
   64 to 80)
   - Encrypt Signed_Message or Unsigned_Message using AES256_cfb_128 using
   AES_IV and AES256_Key to obtain "Encrypted_Payload". Same length as M
   - Compute the HMAC_SHA256 of Encrypted_Payload using HMAC_Key, truncate
   to the first 8 bytes to obtain "Message_HMAC"

Serialization output

   - Serialize Nonce_Pub || Encrypted_Payload || Message_HMAC to obtain
   "eM" For text transmission eM may be sent encoded with base 64, otherwis=
e
   binary is preferred.

Message Receiving Inputs:

   - The message received "eM" (decode from base64 if needed)
   - The bitcoin private key "Decrypting_Key" to be used to decode the
   message Algorithm Calculations:
   - Deserliaize eM to recover "Nonce_Pub", "Encrypted_Payload", and
   "Message_HMAC"
   - ECMultiply Nonce_Pub by Decrypting_Key to recover
   "Shared_Secret_Point"
   - Serialize Shared_Secret_Point as a compressed point to yield
   "Shared_Secret", 33 bytes of data
   - Derive "KeyingBytes" =3D PBKDF2( Shared_Secret ) to get 80 bytes of da=
ta
   - Directly Derive "AES256_Key" from the first 32 bytes of KeyingBytes
   (index 0 to 32)
   - Directly Derive "HMAC_Key" from the second 32 bytes of KeyingBytes
   (index 32 to 64)
   - Directly Derive "AES_IV" from the last 16 bytes of KeyingBytes (index
   64 to 80)
   - Compute the HMAC_SHA256 of Encrypted_Payload using HMAC_Key, truncate
   to the first 8 bytes to compare with Message_HMAC
   - If the Message_HMAC did not match, the message is corrpted so abort
   - Decrypt Encrypted_Payload using AES256_cfb, AES_IV and AES256_Key to
   recover "Payload_Message"
   - Verify that the first byte is a 0x01 or 0x00, else abort. 0x01
   indicates signed
   - if signed Deserialize "Payload_Message" to obtain "M",
   "Sender_Address", and "Signature"
   - if not signed Deserialize "Payload_Message" to obtain "M", and return
   M
   - Calculate the QTHASH(M) to obtain "M_hash", 32 bytes of data
   - Call CompactVerify(Signature, M_hash) to obtain "Signing_Pubkey"
   - Calculate the compressed address of Signing_Pubkey to obtian
   "Sender_Address_check" 21 bytes of data
   - Compare Sender_Address_check and Sender_Address, if they are not
   identical, fail/stop

Output:

   - Output Sender_Address to indicate who the mesage is from, and that the
   signature is valid and untampered with
   - Output M, considering it is valid and the content untampered with

Test Vectors By convention keys will be in WIF format, public keys in
base58_check format, messages in c style UTF-8 string literals. Encrypted
messages are in Base64 format. Compliant implementations will use random
nonces from a cryptographically strong DRBG. For the units tests, they will
be provided in hex format. The nonce bytes provided are to be used both for
the ECIES ecies_nonce_bytes, as well as for the Signature algorithm. Test
vector 1

   - M =3D "Hello, World!\n"
   - nonce bytes =3D
   7357000000000000000000000000000000000000000000000000000000000000
   - Dest_Pub =3D 6ebngTeKJNTjhVj67YhSw5EBNf6sqdGrz7KAT8kiFRwwL8QjHr
   - Signing_Key =3D L48ftytpCTGe8GCkfmX1BQoR9yq6DZCoeTsNkxGR4UEiHjQV3uDF
   - eM =3D
   A34UI90GVmD1wJ0sMEwSsAaTG6bL+vHE0Ebk078EI7qAHZSWxYBy3rQTKw4XyQUgCnH90pXw=
wJRRfPIzlSINTiHm+rs
   f8hL972pDsnjK5H4mBwu6koi0JCJeisH2j899Z97D9Dy7z9y8V7mW5q3HJDNPiRx99CW2hOD=
HOzNlqHSKIItDyqwqMVoHJH7y1rA=3D
   Decrypting WIF =3D Kwc89APmzQx9bT3u3iUYoCKmhKK4tgcnJih27r9QsxhrHyYY6U8F
   - Signing_Addr =3D 1LCA11Udyw784zBhN3VQYsRadSUbUpeJrw

Test vector 2

   - M =3D "Test Message\n=E4=B8=AD=E6=96=87\n"
   - nonce bytes =3D
   00CDEF3636363636363635c5c5c5c5c5c5c5c5c3e3ee3e5c5c5c5c5c53636363
   - Dest_Pub =3D 5RARVjiFrm4gBSEc3NQkhqSrmxtixY1Q4NNoQr5fhwK8gMQDLr
   - Signing_Key =3D L3uN7ev8T5HV8ckp75YgMLzG6ijZ1AYAL8vKBubvvSmLw72yey4x
   - eM =3D
   AjUnA/xZbNa1uXu/fh2ZrEDFWNtpwBe5lQi4qRoTzUo6RF5EByEZ4n/eZmWk7MaHViGeO4yP=
XhQYyTK4O5XbRknXon4ApQcxsh
   EaTj0QfoDLYYZ2/CL9p9G8aN2RCoXdcDrYwZ7KyRLdFnCZvUuvv4VZNZW8/h4fT7sf0MKl7H=
9eCv9OVaKwPJe2pyaNDshfzY12FMQ=3D

   - Decrypting WIF =3D L5UxEELoqFr8eri8nsrBUX2YFmLKZYG6oYBjEUpRSnXwvofdfbg=
M
   - Signing_Addr =3D 1HxcmSvFiviw1RDyzoPgktJfzgKcJ4pHeh

Implementations http://memwallet.info/btcmssgs.html Acknowledgements
Implementation by: 76NPRHE2g5pSvbLgP8fEEtBvfPB4zte56veXdxXfaXcsQwRjZB aka
1Lk96ASyr3k6ZoTFGLrUgxGuctNKF24V5q Credit Must be given to bitaddress.org
brainwallet.org, and many others who have made crypto and bitcoin easy to
code for in javascript.

--089e013a0606ebfde00503c2049d
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div><div><div><div>Hello,<br></div>I&#39;ve made a p=
roposal for a standardized ecies scheme for bitcoin<br>communication. To ad=
dress gmaxwell&#39;s criticism, I&#39;d like to also<br></div>follow up wit=
h a proposed change to BIP44, such that a structured<br>wallet would also i=
nclude a series of identity keys, both addresses<br>which will be used for =
signing, and public keys which would be used<br></div>as destinations for e=
ncrypted messages.<br><br></div>If anyone is familiar with ECIES and would =
be interested, there is a<br>working implementation at <a href=3D"http://me=
mwallet.info/btcmssgs.html">http://memwallet.info/btcmssgs.html</a>, <br></=
div>which also includes this whitepaper:<br><br><h2>Abstract</h2>

This document describes a scheme for sending signed encrypted messages usin=
g
bitcoin public and private keys.

<h2>Motivation</h2>

PGP and Bitmessage and other secure communications channels exist. This
standard allows for secure messaging using a bitcoin wallet alone, without =
the
need for other software.  This standard allows the owner of an address to
conveniently prove ownership to the holder of another address privately wit=
hout
the need for separate secure communications channels.

<h2>Specification: Message Format</h2>

In the rest of this text we will assume the public key cryptography used in
Bitcoin. The || operator is concatenation. All operations are defined over
binary, and not text conversion of the data.  When serializing public keys
the compressed encoding is always used, even if the input parameters are
passed as uncompressed.  Bitcoin addresses are always serialized from
compressed public keys, and for mainnet. (directives to use testnet or
uncompressed keys ignored) String literals are represented as if
for the C programming language in native UTF-8. No assumptions are made
about the payload message format, it may even be binary. Caveat Decryptor.
Plain unformatted text message payloads are recommended to use utf-8.

<ul><li>CompactSize format is a variable size little endian length field se=
rialization format,
know as a bitcoin &quot;Variable length integer&quot;
</li><li>CompactSizePrefix(X) =3D CompactSize(X) || X
</li><li>QTHASH(x) =3D SHA256((SHA256( CompactSizePrefix(&quot;Bitcoin Sign=
ed Message:\n&quot;) || CompactSizePrefix(x) )
</li></ul>
<p>This standard assumes the reader is familiar with the bitcoin compact si=
gnature format,
which is a 65 byte signature which allows the verifier to recover the publi=
c key associated
with the signature, eliminating the need to send it with the message.
Once consequence of this format is that signatures of tampered messages wil=
l nearly always
result in some public key, but it will not be the same as the orignial sign=
ing key.
The address of the sender will be provided to enable validation of the sign=
ature. The format
is a 1 byte recid, followed by ECDSA R then S values.
</p><ul><li>CompactSign( PrivateKey, 32 byte QT Hash ) =3D=3D 65 byte messa=
ge
</li><li>CompactVerify( 65 byte message, 32 bytes Hash ) public key counter=
part of (PrivateKey)
</li><li>ECIES with HMAC_SHA256 for mac, PBKDF2 for KDF
</li><li>PBKDF2 is used with 2048 iterations, salt=3D( &quot;Bitcoin Secure=
 Message&quot; || ecies_nonce_publickey )
</li><li>AES is used with 256 bit keys, and CFB mode, with a 128 bit feedba=
ck buffer. No padding or
envelope, simply a pure byte cipher
</li><li>compact_signed_message =3D 0x01 || CompactSizePrefix(M) || Sender_=
Address || Signature
</li><li>compact_unsigned_message =3D 0x00 || CompactSizePrefix(M)
</li><li>Secure message format: ECIES( compact_signed_message or compact_un=
signed_message )
</li></ul>
<p>Summary of the functions defined:
</p><ul><li>eM =3D SendMessage( M, Signing_Key, Dest_Pub )
</li><li>M,Sender_Address =3D ReceiveMessage( eM, Decrypting_Key )
It is acceptable for deterministic nonces to be used for signatures, howeve=
r nonces generated for
ECIES must be high quality random bytes. (excepting unit test vectors)
</li></ul>

<h3>Message Sending</h3>

Inputs:
<ul><li>The message to send &quot;M&quot; (treat as precise binary bytes, n=
o space stripping or normalization)
</li><li>The bitcoin private key &quot;Signing_Key&quot; to be used to sign=
 the message
</li><li>The bitcoin public key &quot;Dest_Pub&quot; to be used as the dest=
ination of the message
Algorithm Calculations:
</li><li>Calculate the QTHASH(M) to obtain &quot;M_hash&quot;, 32 bytes of =
data
</li><li>if signing Sign with CompactSign(Signing_Key,M_hash) to obtain &qu=
ot;Signature&quot;, 65 bytes of data
** Calculate the compressed address of Signing_Key to obtain &quot;Sender_A=
ddress&quot; 21 bytes of data
** Serialize 0x01 || CompactSizePrefix(M) || Sender_Address || Signature to=
 obtain &quot;Signed_Message&quot;
</li><li>if not signing, instead Serialize 0x00 || CompactSizePrefix(M) to =
obtain &quot;Unsigned_Message&quot;
</li><li>Generate 32 random bytes &quot;ecies_nonce_bytes&quot;
</li><li>Generate a bitcoin private key from ecies_nonce_bytes, &quot;Nonce=
_Key&quot; 32 bytes of data (retry if invalid)
</li><li>Derive the compressed public key of Nonce_Key, &quot;Nonce_Pub&quo=
t;, 33 bytes of data
</li><li>ECMultiply Dest_Pub by Nonce_Key to obtain the point &quot;Shared_=
Secret_Point&quot;
</li><li>Serialize Shared_Secret_Point as a compressed point &quot;Shared_S=
ecret&quot;
</li><li>Derive &quot;KeyingBytes&quot; =3D PBKDF2( Shared_Secret ) to get =
80 bytes of data
</li><li>Directly Derive &quot;AES256_Key&quot; from the first 32 bytes of =
KeyingBytes (index 0 to 32)
</li><li>Directly Derive &quot;HMAC_Key&quot; from the second 32 bytes of K=
eyingBytes (index 32 to 64)
</li><li>Directly Derive &quot;AES_IV&quot; from the last 16 bytes of Keyin=
gBytes (index 64 to 80)
</li><li>Encrypt Signed_Message or Unsigned_Message using AES256_cfb_128 us=
ing AES_IV and AES256_Key to
obtain &quot;Encrypted_Payload&quot;. Same length as M
</li><li>Compute the HMAC_SHA256 of Encrypted_Payload using HMAC_Key, trunc=
ate to the first 8 bytes to
obtain &quot;Message_HMAC&quot;
</li></ul>
<p>Serialization output
</p><ul><li>Serialize Nonce_Pub || Encrypted_Payload || Message_HMAC to obt=
ain &quot;eM&quot;
For text transmission eM may be sent encoded with base 64, otherwise binary=
 is preferred.
</li></ul>

<h3>Message Receiving</h3>

Inputs:
<ul><li>The message received &quot;eM&quot; (decode from base64 if needed)
</li><li>The bitcoin private key &quot;Decrypting_Key&quot; to be used to d=
ecode the message
Algorithm Calculations:
</li><li>Deserliaize eM to recover &quot;Nonce_Pub&quot;, &quot;Encrypted_P=
ayload&quot;, and &quot;Message_HMAC&quot;
</li><li>ECMultiply Nonce_Pub by Decrypting_Key to recover &quot;Shared_Sec=
ret_Point&quot;
</li><li>Serialize Shared_Secret_Point as a compressed point to yield &quot=
;Shared_Secret&quot;, 33 bytes of data
</li><li>Derive &quot;KeyingBytes&quot; =3D PBKDF2( Shared_Secret ) to get =
80 bytes of data
</li><li>Directly Derive &quot;AES256_Key&quot; from the first 32 bytes of =
KeyingBytes (index 0 to 32)
</li><li>Directly Derive &quot;HMAC_Key&quot; from the second 32 bytes of K=
eyingBytes (index 32 to 64)
</li><li>Directly Derive &quot;AES_IV&quot; from the last 16 bytes of Keyin=
gBytes (index 64 to 80)
</li><li>Compute the HMAC_SHA256 of Encrypted_Payload using HMAC_Key, trunc=
ate to the first 8 bytes to
compare with Message_HMAC
</li><li>If the Message_HMAC did not match, the message is corrpted so abor=
t
</li><li>Decrypt Encrypted_Payload using AES256_cfb, AES_IV and AES256_Key =
to recover &quot;Payload_Message&quot;
</li><li>Verify that the first byte is a 0x01 or 0x00, else abort.  0x01 in=
dicates signed
</li><li>if signed Deserialize &quot;Payload_Message&quot; to obtain &quot;=
M&quot;, &quot;Sender_Address&quot;, and &quot;Signature&quot;
</li><li>if not signed Deserialize &quot;Payload_Message&quot; to obtain &q=
uot;M&quot;, and return M
</li><li>Calculate the QTHASH(M) to obtain &quot;M_hash&quot;, 32 bytes of =
data
</li><li>Call CompactVerify(Signature, M_hash) to obtain &quot;Signing_Pubk=
ey&quot;
</li><li>Calculate the compressed address of Signing_Pubkey to obtian &quot=
;Sender_Address_check&quot; 21 bytes of data
</li><li>Compare Sender_Address_check and Sender_Address, if they are not i=
dentical, fail/stop
</li></ul>

<p>Output:
</p><ul><li>Output Sender_Address to indicate who the mesage is from, and t=
hat the signature is valid and untampered with
</li><li>Output M, considering it is valid and the content untampered with
</li></ul>

<h2>Test Vectors</h2>

By convention keys will be in WIF format, public keys in base58_check forma=
t,
messages in c style UTF-8 string literals. Encrypted messages are in Base64
format.  Compliant implementations will use random nonces from a
cryptographically strong DRBG. For the units tests, they will be provided i=
n
hex format. The nonce bytes provided are to be used both for the ECIES
ecies_nonce_bytes, as well as for the Signature algorithm.

<h3>Test vector 1</h3>

<ul><li>M =3D &quot;Hello, World!\n&quot;
</li><li>nonce bytes =3D 73570000000000000000000000000000000000000000000000=
00000000000000
</li><li>Dest_Pub =3D 6ebngTeKJNTjhVj67YhSw5EBNf6sqdGrz7KAT8kiFRwwL8QjHr
</li><li>Signing_Key =3D L48ftytpCTGe8GCkfmX1BQoR9yq6DZCoeTsNkxGR4UEiHjQV3u=
DF
</li><li>eM =3D A34UI90GVmD1wJ0sMEwSsAaTG6bL+vHE0Ebk078EI7qAHZSWxYBy3rQTKw4=
XyQUgCnH90pXwwJRRfPIzlSINTiHm+rs
f8hL972pDsnjK5H4mBwu6koi0JCJeisH2j899Z97D9Dy7z9y8V7mW5q3HJDNPiRx99CW2hODHOz=
NlqHSKIItDyqwqMVoHJH7y1rA=3D
Decrypting WIF =3D Kwc89APmzQx9bT3u3iUYoCKmhKK4tgcnJih27r9QsxhrHyYY6U8F
</li><li>Signing_Addr =3D 1LCA11Udyw784zBhN3VQYsRadSUbUpeJrw
</li></ul>

<h3>Test vector 2</h3>

<ul><li>M =3D &quot;Test Message\n=E4=B8=AD=E6=96=87\n&quot;
</li><li>nonce bytes =3D 00CDEF3636363636363635c5c5c5c5c5c5c5c5c3e3ee3e5c5c=
5c5c5c53636363
</li><li>Dest_Pub =3D 5RARVjiFrm4gBSEc3NQkhqSrmxtixY1Q4NNoQr5fhwK8gMQDLr
</li><li>Signing_Key =3D L3uN7ev8T5HV8ckp75YgMLzG6ijZ1AYAL8vKBubvvSmLw72yey=
4x
</li><li>eM =3D AjUnA/xZbNa1uXu/fh2ZrEDFWNtpwBe5lQi4qRoTzUo6RF5EByEZ4n/eZmW=
k7MaHViGeO4yPXhQYyTK4O5XbRknXon4ApQcxsh
EaTj0QfoDLYYZ2/CL9p9G8aN2RCoXdcDrYwZ7KyRLdFnCZvUuvv4VZNZW8/h4fT7sf0MKl7H9eC=
v9OVaKwPJe2pyaNDshfzY12FMQ=3D
</li><li>Decrypting WIF =3D L5UxEELoqFr8eri8nsrBUX2YFmLKZYG6oYBjEUpRSnXwvof=
dfbgM
</li><li>Signing_Addr =3D 1HxcmSvFiviw1RDyzoPgktJfzgKcJ4pHeh
</li></ul>

<h2>Implementations</h2>

<a href=3D"http://memwallet.info/btcmssgs.html">http://memwallet.info/btcms=
sgs.html</a>

<h2>Acknowledgements</h2>

Implementation by: 76NPRHE2g5pSvbLgP8fEEtBvfPB4zte56veXdxXfaXcsQwRjZB aka 1=
Lk96ASyr3k6ZoTFGLrUgxGuctNKF24V5q
Credit Must be given to <a href=3D"http://bitaddress.org">bitaddress.org</a=
> <a href=3D"http://brainwallet.org">brainwallet.org</a>, and many others w=
ho
have made crypto and bitcoin easy to code for in javascript.
<br><br><br></div>

--089e013a0606ebfde00503c2049d--