]> Cypherpunks.ru repositories - udpobfs.git/blob - PROTOCOL
Unify copyright comment format
[udpobfs.git] / PROTOCOL
1 After TLS 1.3 handshake is finished, 512-bit keying material is
2 exported. Various 256-bit keys are derived from it:
3
4     InitEncKey  = BLAKE3-DeriveKey(seed, "go.cypherpunks.ru/udpobfs/v2 init enc")
5     InitMACKey  = BLAKE3-DeriveKey(seed, "go.cypherpunks.ru/udpobfs/v2 init mac")
6     InitObfsKey = BLAKE3-DeriveKey(seed, "go.cypherpunks.ru/udpobfs/v2 init obfs")
7     RespEncKey  = BLAKE3-DeriveKey(seed, "go.cypherpunks.ru/udpobfs/v2 resp enc")
8     RespMACKey  = BLAKE3-DeriveKey(seed, "go.cypherpunks.ru/udpobfs/v2 resp mac")
9     RespObfsKey = BLAKE3-DeriveKey(seed, "go.cypherpunks.ru/udpobfs/v2 resp obfs")
10
11 Each peer has 64-bit packet sequence counter. It is fed to
12 BLAKE3(len=256, key=*EncKey) and then its XOF output is XORed with
13 plaintext packet. Then BLAKE3(len=48, key=*MACKey) is taken over the
14 sequence counter concatenated with the ciphertext. That MAC, lower
15 16-bits of the sequence counter are encrypted with Blowfish(key=*ObfsKey)
16 and prepended to the ciphertext.
17
18     ciphertext = BLAKE3(len=256, key=*EncKey)(SeqNum).XOF(len=len(plaintext))
19     ciphertext = ciphertext XOR plaintext
20     mac = BLAKE3(len=48, key=*MACKey)(SeqNum || ciphertext)
21     send(Blowfish(key=*ObfsKey)(mac || SeqNum[6:]) || ciphertext)
22
23 All of that gives only 8-byte overhead, providing at least some 48-bit
24 authentication and invisibility of cleartext nonces/sequences. BLAKE3 is
25 pretty fast algorithm, however ChaCha20-Poly1305 can be faster for small
26 messages -- so performance depends on message sizes. Blowfish is just
27 the fastest (serious) cipher with 64-bit blocksize in the Go's library.