08-transport.md (43682B)
1 # BOLT #8: Encrypted and Authenticated Transport 2 3 All communications between Lightning nodes is encrypted in order to 4 provide confidentiality for all transcripts between nodes and is authenticated in order to 5 avoid malicious interference. Each node has a known long-term identifier that 6 is a public key on Bitcoin's `secp256k1` curve. This long-term public key is 7 used within the protocol to establish an encrypted and authenticated connection 8 with peers, and also to authenticate any information advertised on behalf 9 of a node. 10 11 # Table of Contents 12 13 * [Cryptographic Messaging Overview](#cryptographic-messaging-overview) 14 * [Authenticated Key Agreement Handshake](#authenticated-key-agreement-handshake) 15 * [Handshake Versioning](#handshake-versioning) 16 * [Noise Protocol Instantiation](#noise-protocol-instantiation) 17 * [Authenticated Key Exchange Handshake Specification](#authenticated-key-exchange-handshake-specification) 18 * [Handshake State](#handshake-state) 19 * [Handshake State Initialization](#handshake-state-initialization) 20 * [Handshake Exchange](#handshake-exchange) 21 * [Lightning Message Specification](#lightning-message-specification) 22 * [Encrypting and Sending Messages](#encrypting-and-sending-messages) 23 * [Receiving and Decrypting Messages](#receiving-and-decrypting-messages) 24 * [Lightning Message Key Rotation](#lightning-message-key-rotation) 25 * [Security Considerations](#security-considerations) 26 * [Appendix A: Transport Test Vectors](#appendix-a-transport-test-vectors) 27 * [Initiator Tests](#initiator-tests) 28 * [Responder Tests](#responder-tests) 29 * [Message Encryption Tests](#message-encryption-tests) 30 * [Acknowledgments](#acknowledgments) 31 * [References](#references) 32 * [Authors](#authors) 33 34 ## Cryptographic Messaging Overview 35 36 Prior to sending any Lightning messages, nodes MUST first initiate the 37 cryptographic session state that is used to encrypt and authenticate all 38 messages sent between nodes. The initialization of this cryptographic session 39 state is completely distinct from any inner protocol message header or 40 conventions. 41 42 The transcript between two nodes is separated into two distinct segments: 43 44 1. Before any actual data transfer, both nodes participate in an 45 authenticated key agreement handshake, which is based on the Noise 46 Protocol Framework<sup>[2](#reference-2)</sup>. 47 2. If the initial handshake is successful, then nodes enter the Lightning 48 message exchange phase. In the Lightning message exchange phase, all 49 messages are Authenticated Encryption with Associated Data (AEAD) ciphertexts. 50 51 ### Authenticated Key Agreement Handshake 52 53 The handshake chosen for the authenticated key exchange is `Noise_XK`. As a 54 pre-message, the initiator must know the identity public key of 55 the responder. This provides a degree of identity hiding for the 56 responder, as its static public key is _never_ transmitted during the handshake. Instead, 57 authentication is achieved implicitly via a series of Elliptic-Curve 58 Diffie-Hellman (ECDH) operations followed by a MAC check. 59 60 The authenticated key agreement (`Noise_XK`) is performed in three distinct 61 steps (acts). During each act of the handshake the following occurs: some (possibly encrypted) keying 62 material is sent to the other party; an ECDH is performed, based on exactly 63 which act is being executed, with the result mixed into the current set of 64 encryption keys (`ck` the chaining key and `k` the encryption key); and 65 an AEAD payload with a zero-length cipher text is sent. As this payload has no 66 length, only a MAC is sent across. The mixing of ECDH outputs into 67 a hash digest forms an incremental TripleDH handshake. 68 69 Using the language of the Noise Protocol, `e` and `s` (both public keys with `e` being 70 the ephemeral key and `s` being the static key which in our case is usually the `nodeid`) 71 indicate possibly encrypted keying material, and `es`, `ee`, and `se` each indicate an 72 ECDH operation between two keys. The handshake is laid out as follows: 73 ``` 74 Noise_XK(s, rs): 75 <- s 76 ... 77 -> e, es 78 <- e, ee 79 -> s, se 80 ``` 81 All of the handshake data sent across the wire, including the keying material, is 82 incrementally hashed into a session-wide "handshake digest", `h`. Note that the 83 handshake state `h` is never transmitted during the handshake; instead, digest 84 is used as the Associated Data within the zero-length AEAD messages. 85 86 Authenticating each message sent ensures that a man-in-the-middle (MITM) hasn't modified 87 or replaced any of the data sent as part of a handshake, as the MAC 88 check would fail on the other side if so. 89 90 A successful check of the MAC by the receiver indicates implicitly that all 91 authentication has been successful up to that point. If a MAC check ever fails 92 during the handshake process, then the connection is to be immediately 93 terminated. 94 95 ### Handshake Versioning 96 97 Each message sent during the initial handshake starts with a single leading 98 byte, which indicates the version used for the current handshake. A version of 0 99 indicates that no change is necessary, while a non-zero version indicate that the 100 client has deviated from the protocol originally specified within this 101 document. 102 103 Clients MUST reject handshake attempts initiated with an unknown version. 104 105 ### Noise Protocol Instantiation 106 107 Concrete instantiations of the Noise Protocol require the definition of 108 three abstract cryptographic objects: the hash function, the elliptic curve, 109 and the AEAD cipher scheme. For Lightning, `SHA-256` is 110 chosen as the hash function, `secp256k1` as the elliptic curve, and 111 `ChaChaPoly-1305` as the AEAD construction. 112 113 The composition of `ChaCha20` and `Poly1305` that are used MUST conform to 114 `RFC 8439`<sup>[1](#reference-1)</sup>. 115 116 The official protocol name for the Lightning variant of Noise is 117 `Noise_XK_secp256k1_ChaChaPoly_SHA256`. The ASCII string representation of 118 this value is hashed into a digest used to initialize the starting handshake 119 state. If the protocol names of two endpoints differ, then the handshake 120 process fails immediately. 121 122 ## Authenticated Key Exchange Handshake Specification 123 124 The handshake proceeds in three acts, taking 1.5 round trips. Each handshake is 125 a _fixed_ sized payload without any header or additional meta-data attached. 126 The exact size of each act is as follows: 127 128 * **Act One**: 50 bytes 129 * **Act Two**: 50 bytes 130 * **Act Three**: 66 bytes 131 132 ### Handshake State 133 134 Throughout the handshake process, each side maintains these variables: 135 136 * `ck`: the **chaining key**. This value is the accumulated hash of all 137 previous ECDH outputs. At the end of the handshake, `ck` is used to derive 138 the encryption keys for Lightning messages. 139 140 * `h`: the **handshake hash**. This value is the accumulated hash of _all_ 141 handshake data that has been sent and received so far during the handshake 142 process. 143 144 * `temp_k1`, `temp_k2`, `temp_k3`: the **intermediate keys**. These are used to 145 encrypt and decrypt the zero-length AEAD payloads at the end of each handshake 146 message. 147 148 * `e`: a party's **ephemeral keypair**. For each session, a node MUST generate a 149 new ephemeral key with strong cryptographic randomness. 150 151 * `s`: a party's **static keypair** (`ls` for local, `rs` for remote) 152 153 The following functions will also be referenced: 154 155 * `ECDH(k, rk)`: performs an Elliptic-Curve Diffie-Hellman operation using 156 `k`, which is a valid `secp256k1` private key, and `rk`, which is a valid public key 157 * The returned value is the SHA256 of the compressed format of the 158 generated point. 159 160 * `HKDF(salt,ikm)`: a function defined in `RFC 5869`<sup>[3](#reference-3)</sup>, 161 evaluated with a zero-length `info` field 162 * All invocations of `HKDF` implicitly return 64 bytes of 163 cryptographic randomness using the extract-and-expand component of the 164 `HKDF`. 165 166 * `encryptWithAD(k, n, ad, plaintext)`: outputs `encrypt(k, n, ad, plaintext)` 167 * Where `encrypt` is an evaluation of `ChaCha20-Poly1305` (IETF variant) 168 with the passed arguments, with nonce `n` encoded as 32 zero bits, 169 followed by a *little-endian* 64-bit value. Note: this follows the Noise 170 Protocol convention, rather than our normal endian. 171 172 * `decryptWithAD(k, n, ad, ciphertext)`: outputs `decrypt(k, n, ad, ciphertext)` 173 * Where `decrypt` is an evaluation of `ChaCha20-Poly1305` (IETF variant) 174 with the passed arguments, with nonce `n` encoded as 32 zero bits, 175 followed by a *little-endian* 64-bit value. 176 177 * `generateKey()`: generates and returns a fresh `secp256k1` keypair 178 * Where the object returned by `generateKey` has two attributes: 179 * `.pub`, which returns an abstract object representing the public key 180 * `.priv`, which represents the private key used to generate the 181 public key 182 * Where the object also has a single method: 183 * `.serializeCompressed()` 184 185 * `a || b` denotes the concatenation of two byte strings `a` and `b` 186 187 ### Handshake State Initialization 188 189 Before the start of Act One, both sides initialize their per-sessions 190 state as follows: 191 192 1. `h = SHA-256(protocolName)` 193 * where `protocolName = "Noise_XK_secp256k1_ChaChaPoly_SHA256"` encoded as 194 an ASCII string 195 196 2. `ck = h` 197 198 3. `h = SHA-256(h || prologue)` 199 * where `prologue` is the ASCII string: `lightning` 200 201 As a concluding step, both sides mix the responder's public key into the 202 handshake digest: 203 204 * The initiating node mixes in the responding node's static public key 205 serialized in Bitcoin's compressed format: 206 * `h = SHA-256(h || rs.pub.serializeCompressed())` 207 208 * The responding node mixes in their local static public key serialized in 209 Bitcoin's compressed format: 210 * `h = SHA-256(h || ls.pub.serializeCompressed())` 211 212 ### Handshake Exchange 213 214 #### Act One 215 216 ``` 217 -> e, es 218 ``` 219 220 Act One is sent from initiator to responder. During Act One, the initiator 221 attempts to satisfy an implicit challenge by the responder. To complete this 222 challenge, the initiator must know the static public key of the responder. 223 224 The handshake message is _exactly_ 50 bytes: 1 byte for the handshake 225 version, 33 bytes for the compressed ephemeral public key of the initiator, 226 and 16 bytes for the `poly1305` tag. 227 228 **Sender Actions:** 229 230 1. `e = generateKey()` 231 2. `h = SHA-256(h || e.pub.serializeCompressed())` 232 * The newly generated ephemeral key is accumulated into the running 233 handshake digest. 234 3. `es = ECDH(e.priv, rs)` 235 * The initiator performs an ECDH between its newly generated ephemeral 236 key and the remote node's static public key. 237 4. `ck, temp_k1 = HKDF(ck, es)` 238 * A new temporary encryption key is generated, which is 239 used to generate the authenticating MAC. 240 5. `c = encryptWithAD(temp_k1, 0, h, zero)` 241 * where `zero` is a zero-length plaintext 242 6. `h = SHA-256(h || c)` 243 * Finally, the generated ciphertext is accumulated into the authenticating 244 handshake digest. 245 7. Send `m = 0 || e.pub.serializeCompressed() || c` to the responder over the network buffer. 246 247 **Receiver Actions:** 248 249 1. Read _exactly_ 50 bytes from the network buffer. 250 2. Parse the read message (`m`) into `v`, `re`, and `c`: 251 * where `v` is the _first_ byte of `m`, `re` is the next 33 252 bytes of `m`, and `c` is the last 16 bytes of `m` 253 * The raw bytes of the remote party's ephemeral public key (`re`) are to be 254 deserialized into a point on the curve using affine coordinates as encoded 255 by the key's serialized composed format. 256 3. If `v` is an unrecognized handshake version, then the responder MUST 257 abort the connection attempt. 258 4. `h = SHA-256(h || re.serializeCompressed())` 259 * The responder accumulates the initiator's ephemeral key into the authenticating 260 handshake digest. 261 5. `es = ECDH(s.priv, re)` 262 * The responder performs an ECDH between its static private key and the 263 initiator's ephemeral public key. 264 6. `ck, temp_k1 = HKDF(ck, es)` 265 * A new temporary encryption key is generated, which will 266 shortly be used to check the authenticating MAC. 267 7. `p = decryptWithAD(temp_k1, 0, h, c)` 268 * If the MAC check in this operation fails, then the initiator does _not_ 269 know the responder's static public key. If this is the case, then the 270 responder MUST terminate the connection without any further messages. 271 8. `h = SHA-256(h || c)` 272 * The received ciphertext is mixed into the handshake digest. This step serves 273 to ensure the payload wasn't modified by a MITM. 274 275 #### Act Two 276 277 ``` 278 <- e, ee 279 ``` 280 281 Act Two is sent from the responder to the initiator. Act Two will _only_ 282 take place if Act One was successful. Act One was successful if the 283 responder was able to properly decrypt and check the MAC of the tag sent at 284 the end of Act One. 285 286 The handshake is _exactly_ 50 bytes: 1 byte for the handshake version, 33 287 bytes for the compressed ephemeral public key of the responder, and 16 bytes 288 for the `poly1305` tag. 289 290 **Sender Actions:** 291 292 1. `e = generateKey()` 293 2. `h = SHA-256(h || e.pub.serializeCompressed())` 294 * The newly generated ephemeral key is accumulated into the running 295 handshake digest. 296 3. `ee = ECDH(e.priv, re)` 297 * where `re` is the ephemeral key of the initiator, which was received 298 during Act One 299 4. `ck, temp_k2 = HKDF(ck, ee)` 300 * A new temporary encryption key is generated, which is 301 used to generate the authenticating MAC. 302 5. `c = encryptWithAD(temp_k2, 0, h, zero)` 303 * where `zero` is a zero-length plaintext 304 6. `h = SHA-256(h || c)` 305 * Finally, the generated ciphertext is accumulated into the authenticating 306 handshake digest. 307 7. Send `m = 0 || e.pub.serializeCompressed() || c` to the initiator over the network buffer. 308 309 **Receiver Actions:** 310 311 1. Read _exactly_ 50 bytes from the network buffer. 312 2. Parse the read message (`m`) into `v`, `re`, and `c`: 313 * where `v` is the _first_ byte of `m`, `re` is the next 33 314 bytes of `m`, and `c` is the last 16 bytes of `m`. 315 3. If `v` is an unrecognized handshake version, then the responder MUST 316 abort the connection attempt. 317 4. `h = SHA-256(h || re.serializeCompressed())` 318 5. `ee = ECDH(e.priv, re)` 319 * where `re` is the responder's ephemeral public key 320 * The raw bytes of the remote party's ephemeral public key (`re`) are to be 321 deserialized into a point on the curve using affine coordinates as encoded 322 by the key's serialized composed format. 323 6. `ck, temp_k2 = HKDF(ck, ee)` 324 * A new temporary encryption key is generated, which is 325 used to generate the authenticating MAC. 326 7. `p = decryptWithAD(temp_k2, 0, h, c)` 327 * If the MAC check in this operation fails, then the initiator MUST 328 terminate the connection without any further messages. 329 8. `h = SHA-256(h || c)` 330 * The received ciphertext is mixed into the handshake digest. This step serves 331 to ensure the payload wasn't modified by a MITM. 332 333 #### Act Three 334 335 ``` 336 -> s, se 337 ``` 338 339 Act Three is the final phase in the authenticated key agreement described in 340 this section. This act is sent from the initiator to the responder as a 341 concluding step. Act Three is executed _if and only if_ Act Two was successful. 342 During Act Three, the initiator transports its static public key to the 343 responder encrypted with _strong_ forward secrecy, using the accumulated `HKDF` 344 derived secret key at this point of the handshake. 345 346 The handshake is _exactly_ 66 bytes: 1 byte for the handshake version, 33 347 bytes for the static public key encrypted with the `ChaCha20` stream 348 cipher, 16 bytes for the encrypted public key's tag generated via the AEAD 349 construction, and 16 bytes for a final authenticating tag. 350 351 **Sender Actions:** 352 353 1. `c = encryptWithAD(temp_k2, 1, h, s.pub.serializeCompressed())` 354 * where `s` is the static public key of the initiator 355 2. `h = SHA-256(h || c)` 356 3. `se = ECDH(s.priv, re)` 357 * where `re` is the ephemeral public key of the responder 358 4. `ck, temp_k3 = HKDF(ck, se)` 359 * The final intermediate shared secret is mixed into the running chaining key. 360 5. `t = encryptWithAD(temp_k3, 0, h, zero)` 361 * where `zero` is a zero-length plaintext 362 6. `sk, rk = HKDF(ck, zero)` 363 * where `zero` is a zero-length plaintext, 364 `sk` is the key to be used by the initiator to encrypt messages to the 365 responder, 366 and `rk` is the key to be used by the initiator to decrypt messages sent by 367 the responder 368 * The final encryption keys, to be used for sending and 369 receiving messages for the duration of the session, are generated. 370 7. `rn = 0, sn = 0` 371 * The sending and receiving nonces are initialized to 0. 372 8. `rck = sck = ck` 373 * The sending and receiving chaining keys are initialized the same. 374 9. Send `m = 0 || c || t` over the network buffer. 375 376 **Receiver Actions:** 377 378 1. Read _exactly_ 66 bytes from the network buffer. 379 2. Parse the read message (`m`) into `v`, `c`, and `t`: 380 * where `v` is the _first_ byte of `m`, `c` is the next 49 381 bytes of `m`, and `t` is the last 16 bytes of `m` 382 3. If `v` is an unrecognized handshake version, then the responder MUST 383 abort the connection attempt. 384 4. `rs = decryptWithAD(temp_k2, 1, h, c)` 385 * At this point, the responder has recovered the static public key of the 386 initiator. 387 * If the MAC check in this operation fails, then the responder MUST 388 terminate the connection without any further messages. 389 5. `h = SHA-256(h || c)` 390 6. `se = ECDH(e.priv, rs)` 391 * where `e` is the responder's original ephemeral key 392 7. `ck, temp_k3 = HKDF(ck, se)` 393 8. `p = decryptWithAD(temp_k3, 0, h, t)` 394 * If the MAC check in this operation fails, then the responder MUST 395 terminate the connection without any further messages. 396 9. `rk, sk = HKDF(ck, zero)` 397 * where `zero` is a zero-length plaintext, 398 `rk` is the key to be used by the responder to decrypt the messages sent 399 by the initiator, 400 and `sk` is the key to be used by the responder to encrypt messages to 401 the initiator 402 * The final encryption keys, to be used for sending and 403 receiving messages for the duration of the session, are generated. 404 10. `rn = 0, sn = 0` 405 * The sending and receiving nonces are initialized to 0. 406 11. `rck = sck = ck` 407 * The sending and receiving chaining keys are initialized the same. 408 409 ## Lightning Message Specification 410 411 At the conclusion of Act Three, both sides have derived the encryption keys, which 412 will be used to encrypt and decrypt messages for the remainder of the 413 session. 414 415 The actual Lightning protocol messages are encapsulated within AEAD ciphertexts. 416 Each message is prefixed with another AEAD ciphertext, which encodes the total 417 length of the following Lightning message (not including its MAC). 418 419 The *maximum* size of _any_ Lightning message MUST NOT exceed `65535` bytes. A 420 maximum size of `65535` simplifies testing, makes memory management 421 easier, and helps mitigate memory-exhaustion attacks. 422 423 In order to make traffic analysis more difficult, the length prefix for 424 all encrypted Lightning messages is also encrypted. Additionally a 425 16-byte `Poly-1305` tag is added to the encrypted length prefix in order to ensure 426 that the packet length hasn't been modified when in-flight and also to avoid 427 creating a decryption oracle. 428 429 The structure of packets on the wire resembles the following: 430 431 ``` 432 +------------------------------- 433 |2-byte encrypted message length| 434 +------------------------------- 435 | 16-byte MAC of the encrypted | 436 | message length | 437 +------------------------------- 438 | | 439 | | 440 | encrypted Lightning | 441 | message | 442 | | 443 +------------------------------- 444 | 16-byte MAC of the | 445 | Lightning message | 446 +------------------------------- 447 ``` 448 449 The prefixed message length is encoded as a 2-byte big-endian integer, 450 for a total maximum packet length of `2 + 16 + 65535 + 16` = `65569` bytes. 451 452 ### Encrypting and Sending Messages 453 454 In order to encrypt and send a Lightning message (`m`) to the network stream, 455 given a sending key (`sk`) and a nonce (`sn`), the following steps are completed: 456 457 1. Let `l = len(m)`. 458 * where `len` obtains the length in bytes of the Lightning message 459 2. Serialize `l` into 2 bytes encoded as a big-endian integer. 460 3. Encrypt `l` (using `ChaChaPoly-1305`, `sn`, and `sk`), to obtain `lc` 461 (18 bytes) 462 * The nonce `sn` is encoded as a 96-bit little-endian number. As the 463 decoded nonce is 64 bits, the 96-bit nonce is encoded as: 32 bits 464 of leading 0s followed by a 64-bit value. 465 * The nonce `sn` MUST be incremented after this step. 466 * A zero-length byte slice is to be passed as the AD (associated data). 467 4. Finally, encrypt the message itself (`m`) using the same procedure used to 468 encrypt the length prefix. Let encrypted ciphertext be known as `c`. 469 * The nonce `sn` MUST be incremented after this step. 470 5. Send `lc || c` over the network buffer. 471 472 ### Receiving and Decrypting Messages 473 474 In order to decrypt the _next_ message in the network stream, the following 475 steps are completed: 476 477 1. Read _exactly_ 18 bytes from the network buffer. 478 2. Let the encrypted length prefix be known as `lc`. 479 3. Decrypt `lc` (using `ChaCha20-Poly1305`, `rn`, and `rk`), to obtain the size of 480 the encrypted packet `l`. 481 * A zero-length byte slice is to be passed as the AD (associated data). 482 * The nonce `rn` MUST be incremented after this step. 483 4. Read _exactly_ `l+16` bytes from the network buffer, and let the bytes be 484 known as `c`. 485 5. Decrypt `c` (using `ChaCha20-Poly1305`, `rn`, and `rk`), to obtain decrypted 486 plaintext packet `p`. 487 * The nonce `rn` MUST be incremented after this step. 488 489 ## Lightning Message Key Rotation 490 491 Changing keys regularly and forgetting previous keys is useful to 492 prevent the decryption of old messages, in the case of later key leakage (i.e. 493 backwards secrecy). 494 495 Key rotation is performed for _each_ key (`sk` and `rk`) _individually_, 496 using `sck` and `rck` respectively. A key 497 is to be rotated after a party encrypts or decrypts 1000 times with it (i.e. every 500 messages). 498 This can be properly accounted for by rotating the key once the nonce dedicated 499 to it reaches 1000. 500 501 Key rotation for a key `k` is performed according to the following steps: 502 503 1. Let `ck` be the chaining key (i.e. `rck` for `rk` or `sck` for `sk`) 504 2. `ck', k' = HKDF(ck, k)` 505 3. Reset the nonce for the key to `n = 0`. 506 4. `k = k'` 507 5. `ck = ck'` 508 509 # Security Considerations 510 511 It is strongly recommended that existing, commonly-used, validated 512 libraries be used for encryption and decryption, to avoid the many possible 513 implementation pitfalls. 514 515 # Appendix A: Transport Test Vectors 516 517 To make a repeatable test handshake, the following specifies what `generateKey()` will 518 return (i.e. the value for `e.priv`) for each side. Note that this 519 is a violation of the spec, which requires randomness. 520 521 ## Initiator Tests 522 523 The initiator SHOULD produce the given output when fed this input. 524 The comments reflect internal states, for debugging purposes. 525 526 ``` 527 name: transport-initiator successful handshake 528 rs.pub: 0x028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 529 ls.priv: 0x1111111111111111111111111111111111111111111111111111111111111111 530 ls.pub: 0x034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa 531 e.priv: 0x1212121212121212121212121212121212121212121212121212121212121212 532 e.pub: 0x036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7 533 # Act One 534 # h=0x9e0e7de8bb75554f21db034633de04be41a2b8a18da7a319a03c803bf02b396c 535 # ss=0x1e2fb3c8fe8fb9f262f649f64d26ecf0f2c0a805a767cf02dc2d77a6ef1fdcc3 536 # HKDF(0x2640f52eebcd9e882958951c794250eedb28002c05d7dc2ea0f195406042caf1,0x1e2fb3c8fe8fb9f262f649f64d26ecf0f2c0a805a767cf02dc2d77a6ef1fdcc3) 537 # ck,temp_k1=0xb61ec1191326fa240decc9564369dbb3ae2b34341d1e11ad64ed89f89180582f,0xe68f69b7f096d7917245f5e5cf8ae1595febe4d4644333c99f9c4a1282031c9f 538 # encryptWithAD(0xe68f69b7f096d7917245f5e5cf8ae1595febe4d4644333c99f9c4a1282031c9f, 0x000000000000000000000000, 0x9e0e7de8bb75554f21db034633de04be41a2b8a18da7a319a03c803bf02b396c, <empty>) 539 # c=0df6086551151f58b8afe6c195782c6a 540 # h=0x9d1ffbb639e7e20021d9259491dc7b160aab270fb1339ef135053f6f2cebe9ce 541 output: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 542 # Act Two 543 input: 0x0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae 544 # re=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 545 # h=0x38122f669819f906000621a14071802f93f2ef97df100097bcac3ae76c6dc0bf 546 # ss=0xc06363d6cc549bcb7913dbb9ac1c33fc1158680c89e972000ecd06b36c472e47 547 # HKDF(0xb61ec1191326fa240decc9564369dbb3ae2b34341d1e11ad64ed89f89180582f,0xc06363d6cc549bcb7913dbb9ac1c33fc1158680c89e972000ecd06b36c472e47) 548 # ck,temp_k2=0xe89d31033a1b6bf68c07d22e08ea4d7884646c4b60a9528598ccb4ee2c8f56ba,0x908b166535c01a935cf1e130a5fe895ab4e6f3ef8855d87e9b7581c4ab663ddc 549 # decryptWithAD(0x908b166535c01a935cf1e130a5fe895ab4e6f3ef8855d87e9b7581c4ab663ddc, 0x000000000000000000000000, 0x38122f669819f906000621a14071802f93f2ef97df100097bcac3ae76c6dc0bf, 0x6e2470b93aac583c9ef6eafca3f730ae) 550 # h=0x90578e247e98674e661013da3c5c1ca6a8c8f48c90b485c0dfa1494e23d56d72 551 # Act Three 552 # encryptWithAD(0x908b166535c01a935cf1e130a5fe895ab4e6f3ef8855d87e9b7581c4ab663ddc, 0x000000000100000000000000, 0x90578e247e98674e661013da3c5c1ca6a8c8f48c90b485c0dfa1494e23d56d72, 0x034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa) 553 # c=0xb9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c3822 554 # h=0x5dcb5ea9b4ccc755e0e3456af3990641276e1d5dc9afd82f974d90a47c918660 555 # ss=0xb36b6d195982c5be874d6d542dc268234379e1ae4ff1709402135b7de5cf0766 556 # HKDF(0xe89d31033a1b6bf68c07d22e08ea4d7884646c4b60a9528598ccb4ee2c8f56ba,0xb36b6d195982c5be874d6d542dc268234379e1ae4ff1709402135b7de5cf0766) 557 # ck,temp_k3=0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01,0x981a46c820fb7a241bc8184ba4bb1f01bcdfafb00dde80098cb8c38db9141520 558 # encryptWithAD(0x981a46c820fb7a241bc8184ba4bb1f01bcdfafb00dde80098cb8c38db9141520, 0x000000000000000000000000, 0x5dcb5ea9b4ccc755e0e3456af3990641276e1d5dc9afd82f974d90a47c918660, <empty>) 559 # t=0x8dc68b1c466263b47fdf31e560e139ba 560 output: 0x00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba 561 # HKDF(0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01,zero) 562 output: sk,rk=0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9,0xbb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442 563 564 name: transport-initiator act2 short read test 565 rs.pub: 0x028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 566 ls.priv: 0x1111111111111111111111111111111111111111111111111111111111111111 567 ls.pub: 0x034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa 568 e.priv: 0x1212121212121212121212121212121212121212121212121212121212121212 569 e.pub: 0x036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7 570 output: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 571 # Act Two 572 input: 0x0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730 573 output: ERROR (ACT2_READ_FAILED) 574 575 name: transport-initiator act2 bad version test 576 rs.pub: 0x028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 577 ls.priv: 0x1111111111111111111111111111111111111111111111111111111111111111 578 ls.pub: 0x034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa 579 e.priv: 0x1212121212121212121212121212121212121212121212121212121212121212 580 e.pub: 0x036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7 581 output: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 582 # Act Two 583 input: 0x0102466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae 584 output: ERROR (ACT2_BAD_VERSION 1) 585 586 name: transport-initiator act2 bad key serialization test 587 rs.pub: 0x028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 588 ls.priv: 0x1111111111111111111111111111111111111111111111111111111111111111 589 ls.pub: 0x034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa 590 e.priv: 0x1212121212121212121212121212121212121212121212121212121212121212 591 e.pub: 0x036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7 592 output: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 593 # Act Two 594 input: 0x0004466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae 595 output: ERROR (ACT2_BAD_PUBKEY) 596 597 name: transport-initiator act2 bad MAC test 598 rs.pub: 0x028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 599 ls.priv: 0x1111111111111111111111111111111111111111111111111111111111111111 600 ls.pub: 0x034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa 601 e.priv: 0x1212121212121212121212121212121212121212121212121212121212121212 602 e.pub: 0x036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7 603 output: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 604 # Act Two 605 input: 0x0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730af 606 output: ERROR (ACT2_BAD_TAG) 607 ``` 608 609 ## Responder Tests 610 611 The responder SHOULD produce the given output when fed this input. 612 613 ``` 614 name: transport-responder successful handshake 615 ls.priv=2121212121212121212121212121212121212121212121212121212121212121 616 ls.pub=028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 617 e.priv=0x2222222222222222222222222222222222222222222222222222222222222222 618 e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 619 # Act One 620 input: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 621 # re=0x036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7 622 # h=0x9e0e7de8bb75554f21db034633de04be41a2b8a18da7a319a03c803bf02b396c 623 # ss=0x1e2fb3c8fe8fb9f262f649f64d26ecf0f2c0a805a767cf02dc2d77a6ef1fdcc3 624 # HKDF(0x2640f52eebcd9e882958951c794250eedb28002c05d7dc2ea0f195406042caf1,0x1e2fb3c8fe8fb9f262f649f64d26ecf0f2c0a805a767cf02dc2d77a6ef1fdcc3) 625 # ck,temp_k1=0xb61ec1191326fa240decc9564369dbb3ae2b34341d1e11ad64ed89f89180582f,0xe68f69b7f096d7917245f5e5cf8ae1595febe4d4644333c99f9c4a1282031c9f 626 # decryptWithAD(0xe68f69b7f096d7917245f5e5cf8ae1595febe4d4644333c99f9c4a1282031c9f, 0x000000000000000000000000, 0x9e0e7de8bb75554f21db034633de04be41a2b8a18da7a319a03c803bf02b396c, 0x0df6086551151f58b8afe6c195782c6a) 627 # h=0x9d1ffbb639e7e20021d9259491dc7b160aab270fb1339ef135053f6f2cebe9ce 628 # Act Two 629 # e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 e.priv=0x2222222222222222222222222222222222222222222222222222222222222222 630 # h=0x38122f669819f906000621a14071802f93f2ef97df100097bcac3ae76c6dc0bf 631 # ss=0xc06363d6cc549bcb7913dbb9ac1c33fc1158680c89e972000ecd06b36c472e47 632 # HKDF(0xb61ec1191326fa240decc9564369dbb3ae2b34341d1e11ad64ed89f89180582f,0xc06363d6cc549bcb7913dbb9ac1c33fc1158680c89e972000ecd06b36c472e47) 633 # ck,temp_k2=0xe89d31033a1b6bf68c07d22e08ea4d7884646c4b60a9528598ccb4ee2c8f56ba,0x908b166535c01a935cf1e130a5fe895ab4e6f3ef8855d87e9b7581c4ab663ddc 634 # encryptWithAD(0x908b166535c01a935cf1e130a5fe895ab4e6f3ef8855d87e9b7581c4ab663ddc, 0x000000000000000000000000, 0x38122f669819f906000621a14071802f93f2ef97df100097bcac3ae76c6dc0bf, <empty>) 635 # c=0x6e2470b93aac583c9ef6eafca3f730ae 636 # h=0x90578e247e98674e661013da3c5c1ca6a8c8f48c90b485c0dfa1494e23d56d72 637 output: 0x0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae 638 # Act Three 639 input: 0x00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba 640 # decryptWithAD(0x908b166535c01a935cf1e130a5fe895ab4e6f3ef8855d87e9b7581c4ab663ddc, 0x000000000100000000000000, 0x90578e247e98674e661013da3c5c1ca6a8c8f48c90b485c0dfa1494e23d56d72, 0xb9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c3822) 641 # rs=0x034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa 642 # h=0x5dcb5ea9b4ccc755e0e3456af3990641276e1d5dc9afd82f974d90a47c918660 643 # ss=0xb36b6d195982c5be874d6d542dc268234379e1ae4ff1709402135b7de5cf0766 644 # HKDF(0xe89d31033a1b6bf68c07d22e08ea4d7884646c4b60a9528598ccb4ee2c8f56ba,0xb36b6d195982c5be874d6d542dc268234379e1ae4ff1709402135b7de5cf0766) 645 # ck,temp_k3=0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01,0x981a46c820fb7a241bc8184ba4bb1f01bcdfafb00dde80098cb8c38db9141520 646 # decryptWithAD(0x981a46c820fb7a241bc8184ba4bb1f01bcdfafb00dde80098cb8c38db9141520, 0x000000000000000000000000, 0x5dcb5ea9b4ccc755e0e3456af3990641276e1d5dc9afd82f974d90a47c918660, 0x8dc68b1c466263b47fdf31e560e139ba) 647 # HKDF(0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01,zero) 648 output: rk,sk=0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9,0xbb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442 649 650 name: transport-responder act1 short read test 651 ls.priv=2121212121212121212121212121212121212121212121212121212121212121 652 ls.pub=028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 653 e.priv=0x2222222222222222222222222222222222222222222222222222222222222222 654 e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 655 # Act One 656 input: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c 657 output: ERROR (ACT1_READ_FAILED) 658 659 name: transport-responder act1 bad version test 660 ls.priv=2121212121212121212121212121212121212121212121212121212121212121 661 ls.pub=028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 662 e.priv=0x2222222222222222222222222222222222222222222222222222222222222222 663 e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 664 # Act One 665 input: 0x01036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 666 output: ERROR (ACT1_BAD_VERSION) 667 668 name: transport-responder act1 bad key serialization test 669 ls.priv=2121212121212121212121212121212121212121212121212121212121212121 670 ls.pub=028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 671 e.priv=0x2222222222222222222222222222222222222222222222222222222222222222 672 e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 673 # Act One 674 input: 0x00046360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 675 output: ERROR (ACT1_BAD_PUBKEY) 676 677 name: transport-responder act1 bad MAC test 678 ls.priv=2121212121212121212121212121212121212121212121212121212121212121 679 ls.pub=028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 680 e.priv=0x2222222222222222222222222222222222222222222222222222222222222222 681 e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 682 # Act One 683 input: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6b 684 output: ERROR (ACT1_BAD_TAG) 685 686 name: transport-responder act3 bad version test 687 ls.priv=2121212121212121212121212121212121212121212121212121212121212121 688 ls.pub=028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 689 e.priv=0x2222222222222222222222222222222222222222222222222222222222222222 690 e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 691 # Act One 692 input: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 693 # Act Two 694 output: 0x0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae 695 # Act Three 696 input: 0x01b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba 697 output: ERROR (ACT3_BAD_VERSION 1) 698 699 name: transport-responder act3 short read test 700 ls.priv=2121212121212121212121212121212121212121212121212121212121212121 701 ls.pub=028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 702 e.priv=0x2222222222222222222222222222222222222222222222222222222222222222 703 e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 704 # Act One 705 input: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 706 # Act Two 707 output: 0x0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae 708 # Act Three 709 input: 0x00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139 710 output: ERROR (ACT3_READ_FAILED) 711 712 name: transport-responder act3 bad MAC for ciphertext test 713 ls.priv=2121212121212121212121212121212121212121212121212121212121212121 714 ls.pub=028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 715 e.priv=0x2222222222222222222222222222222222222222222222222222222222222222 716 e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 717 # Act One 718 input: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 719 # Act Two 720 output: 0x0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae 721 # Act Three 722 input: 0x00c9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba 723 output: ERROR (ACT3_BAD_CIPHERTEXT) 724 725 name: transport-responder act3 bad rs test 726 ls.priv=2121212121212121212121212121212121212121212121212121212121212121 727 ls.pub=028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 728 e.priv=0x2222222222222222222222222222222222222222222222222222222222222222 729 e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 730 # Act One 731 input: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 732 # Act Two 733 output: 0x0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae 734 # Act Three 735 input: 0x00bfe3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa2235536ad09a8ee351870c2bb7f78b754a26c6cef79a98d25139c856d7efd252c2ae73c 736 # decryptWithAD(0x908b166535c01a935cf1e130a5fe895ab4e6f3ef8855d87e9b7581c4ab663ddc, 0x000000000000000000000001, 0x90578e247e98674e661013da3c5c1ca6a8c8f48c90b485c0dfa1494e23d56d72, 0xd7fedc211450dd9602b41081c9bd05328b8bf8c0238880f7b7cb8a34bb6d8354081e8d4b81887fae47a74fe8aab3008653) 737 # rs=0x044f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa 738 output: ERROR (ACT3_BAD_PUBKEY) 739 740 name: transport-responder act3 bad MAC test 741 ls.priv=2121212121212121212121212121212121212121212121212121212121212121 742 ls.pub=028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7 743 e.priv=0x2222222222222222222222222222222222222222222222222222222222222222 744 e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 745 # Act One 746 input: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a 747 # Act Two 748 output: 0x0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae 749 # Act Three 750 input: 0x00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139bb 751 output: ERROR (ACT3_BAD_TAG) 752 ``` 753 754 ## Message Encryption Tests 755 756 In this test, the initiator sends length 5 messages containing "hello" 757 1001 times. Only six example outputs are shown, for brevity and to test 758 two key rotations: 759 760 name: transport-message test 761 ck=0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01 762 sk=0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9 763 rk=0xbb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442 764 # encrypt l: cleartext=0x0005, AD=NULL, sn=0x000000000000000000000000, sk=0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9 => 0xcf2b30ddf0cf3f80e7c35a6e6730b59fe802 765 # encrypt m: cleartext=0x68656c6c6f, AD=NULL, sn=0x000000000100000000000000, sk=0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9 => 0x473180f396d88a8fb0db8cbcf25d2f214cf9ea1d95 766 output 0: 0xcf2b30ddf0cf3f80e7c35a6e6730b59fe802473180f396d88a8fb0db8cbcf25d2f214cf9ea1d95 767 # encrypt l: cleartext=0x0005, AD=NULL, sn=0x000000000200000000000000, sk=0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9 => 0x72887022101f0b6753e0c7de21657d35a4cb 768 # encrypt m: cleartext=0x68656c6c6f, AD=NULL, sn=0x000000000300000000000000, sk=0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9 => 0x2a1f5cde2650528bbc8f837d0f0d7ad833b1a256a1 769 output 1: 0x72887022101f0b6753e0c7de21657d35a4cb2a1f5cde2650528bbc8f837d0f0d7ad833b1a256a1 770 # 0xcc2c6e467efc8067720c2d09c139d1f77731893aad1defa14f9bf3c48d3f1d31, 0x3fbdc101abd1132ca3a0ae34a669d8d9ba69a587e0bb4ddd59524541cf4813d8 = HKDF(0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01, 0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9) 771 # 0xcc2c6e467efc8067720c2d09c139d1f77731893aad1defa14f9bf3c48d3f1d31, 0x3fbdc101abd1132ca3a0ae34a669d8d9ba69a587e0bb4ddd59524541cf4813d8 = HKDF(0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01, 0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9) 772 output 500: 0x178cb9d7387190fa34db9c2d50027d21793c9bc2d40b1e14dcf30ebeeeb220f48364f7a4c68bf8 773 output 501: 0x1b186c57d44eb6de4c057c49940d79bb838a145cb528d6e8fd26dbe50a60ca2c104b56b60e45bd 774 # 0x728366ed68565dc17cf6dd97330a859a6a56e87e2beef3bd828a4c4a54d8df06, 0x9e0477f9850dca41e42db0e4d154e3a098e5a000d995e421849fcd5df27882bd = HKDF(0xcc2c6e467efc8067720c2d09c139d1f77731893aad1defa14f9bf3c48d3f1d31, 0x3fbdc101abd1132ca3a0ae34a669d8d9ba69a587e0bb4ddd59524541cf4813d8) 775 # 0x728366ed68565dc17cf6dd97330a859a6a56e87e2beef3bd828a4c4a54d8df06, 0x9e0477f9850dca41e42db0e4d154e3a098e5a000d995e421849fcd5df27882bd = HKDF(0xcc2c6e467efc8067720c2d09c139d1f77731893aad1defa14f9bf3c48d3f1d31, 0x3fbdc101abd1132ca3a0ae34a669d8d9ba69a587e0bb4ddd59524541cf4813d8) 776 output 1000: 0x4a2f3cc3b5e78ddb83dcb426d9863d9d9a723b0337c89dd0b005d89f8d3c05c52b76b29b740f09 777 output 1001: 0x2ecd8c8a5629d0d02ab457a0fdd0f7b90a192cd46be5ecb6ca570bfc5e268338b1a16cf4ef2d36 778 779 # Acknowledgments 780 781 TODO(roasbeef); fin 782 783 # References 784 1. <a id="reference-1">https://tools.ietf.org/html/rfc8439</a> 785 2. <a id="reference-2">http://noiseprotocol.org/noise.html</a> 786 3. <a id="reference-3">https://tools.ietf.org/html/rfc5869</a> 787 788 # Authors 789 790 FIXME 791 792  793 <br> 794 This work is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/).