Wire Protocol (version 1) The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119]. LLARP supports by default an authenticated message transport over a datagram based network layer. outer message format: { A: command, B: <16 bytes flow id>, C: , X: } comamnds: A - get handshake cookie obtain a handshake cookie B is randomized X MUST contain the user agent string of the requester. the if the network id differs from the current network's id a reject message is sent: { A: R, B: msg.B, X: "" } MUST be replied to with a message rejected or a give handshake cookie C - give handshake cookie give a handshake cookie to a remote endpoint that asks for one B is the B value from the get handshake cookie message X is a 32 byte handshake cookie, calcuated via: r = RAND(32) a = "" + " " + "" X = HS(a + B + r) R - message rejected B is the flow id from the recipiant X is a reply line reject a message with flow id B S - session negotiation negotiate encrypted session B is the flow id from the recipiant C is the handshake cookie X is encrypted session negotiation data D - encrypted data transmission transmit encrypted data on session B is the flow id from the recipiant X is authenticated and encrypted data BNF: ::= ::= ::= + ::= * | ::= "COOKIE" | "HANDSHAKE" ::= ::= "lokinet" | "testnet" ::= " " ::= "0" ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ::= | ::= | * ::= "." "." ::= session negotiation: The session starts out with each side having 2 session keys rx_K and tx_K for decrypting inbound messages and encrypting outbound messages respectively. The initiator (alice) and the recipiant (bob) start out with static session keys k_a = HS(a.k) k_b = HS(b.k) a.rx_K = k_a b.rx_K = k_b a.tx_K = k_b b.tx_K = k_a inner message format: <32 bytes blake2s keyed hash of following data> <24 bytes nounce> decryption is done via: SD(remaining, rx_K, nounce) encrypted payload is bencoded LIM (see proto_v0.txt) the initiator starts out by sending a LIM a_LIM to the recipiant. the recipiant replies with a LIM b_LIM to the initiator. when the initiator gets a valid LIM from the recipiant the session keys for data transmission are set to: k_a = TKE(a.k, b.k, a.sk, a_LIM.n) k_b = TKE(b.k, a.k, b.sk, b_LIM.n) a.rx_K = k_a b.rx_K = k_b a.tx_K = k_b b.tx_K = k_a afterwards data transmission may happen data tranmission: message format: <10 byte header> header format: <1 byte proto version> <1 byte command> <1 byte flags> <1 byte fragno> <2 bytes fraglen> <4 bytes seqno>