Thanks to visit codestin.com
Credit goes to lib.rs

2 releases

0.2.1 Aug 8, 2024
0.2.0 Jan 27, 2024
0.1.0 Jan 14, 2024

#825 in Cryptography

Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App

2,029 downloads per month
Used in morf-mqtt-bridge

Apache-2.0

19KB
331 lines

MoRF

MoRF is a mutually-authenticated, encrypted communication protocol over lossy packet links with small MTUs, e.g. LoRa. Inspired by Noise.

  • no_std compatible, no dynamic memory allocation
  • Minimum supported MTU: 49 bytes, overhead per data packet: 19 bytes
  • Primitives: X25519 + BLAKE3 + ChaCha20-Poly1305
  • Identity hiding, forward secrecy, replay protection

Handshake

To establish an encrypted session, a client initiates a handshake to a server to exchange keys. Both peers are required to have ahead-of-time knowledge of each other's public key.

Notations

  • $CE_{pub}$, $CE_{sec}$: Client ephemeral X25519 public/secret key
  • $SE_{pub}$, $SE_{sec}$: Server ephemeral X25519 public/secret key
  • $CS_{pub}$, $CS_{sec}$: Client static X25519 public/secret key
  • $SS_{pub}$, $SS_{sec}$: Server static X25519 public/secret key
  • $X25519(secret, public)$: X25519 Diffie-Hellman key agreement
  • $ChaCha20(key, payload)$: Apply (unauthenticated) ChaCha20 keystream derived from $key$ to $payload$
  • $Mac(key, payload)$: Apply BLAKE3 keyed hash with $key$ to $payload$, and truncate the output to the first 16 bytes.
  • $DeriveKey(key, info)$: Derive a 32-byte subkey from $key$ using BLAKE3 as a KDF with $info$ as the info string
  • $Hash(payload)$: Calculate the BLAKE3 hash of $payload$ and truncate the output to the first 16 bytes.
  • $InitialEncryptionKeyInfo$: The string initial_encryption_key
  • $ServerEphemeralPublicKeyMacKeyInfo$: The string server_ephemeral_public_key_mac_key

Packet 1: client to server (49 bytes)

Let $InitialKey = DeriveKey(X25519(CE_{sec}, SS_{pub}), InitialEncryptionKeyInfo)$.

Field Length
$Const(3)$ 1
$CE_{pub}$ 32
$ChaCha20(InitialKey, Hash(CS_{pub}))$ 16

Packet 2: server to client (49 bytes)

Lookup client static public key $CS_{pub}$ from the provided hash.

Let $ServerSepkMacKey = DeriveKey(X25519(SS_{sec}, CE_{pub}), ServerEphemeralPublicKeyMacKeyInfo)$.

Let $ServerSessionKey = Concat(X25519(SE_{sec}, CS_{pub}), X25519(SE_{sec}, CE_{pub}))$.

Field Length
$Const(1)$ 1
$SE_{pub}$ 32
$Mac(ServerSepkMacKey, SE_{pub})$ 16

Finalize (client)

Let $ClientSepkMacKey = DeriveKey(X25519(CE_{sec}, SS_{pub}), ServerEphemeralPublicKeyMacKeyInfo)$.

Check that:

$Mac(ClientSepkMacKey, Packet2[1:33]) == Packet2[33:49]$

Let $ClientSessionKey = Concat(X25519(CS_{sec}, SE_{pub}), X25519(CE_{sec}, SE_{pub}))$.

Dependencies

~3.5–5MB
~109K SLoC