┌──────┐ ┌──────┐
│Client│ │Server│
└──┬───┘ └──┬───┘
│ R, enc(H(DSAPub), R, El(CDHPub)) │ ╔══════════════════════╗
│ ──────────────────────────────────────> ║R=rand(64bit) ░║
│ │ ║CDHPriv=rand(256bit) ║
│ │ ╚══════════════════════╝
│ │ ╔══════════════════════════╗
│ enc(H(DSAPub), R+1, El(SDHPub)) │ ║SDHPriv=rand(256bit) ░║
│ enc(K, R, RS+SS) │ ║K=H(DH(SDHPriv, CDHPub)) ║
│ <────────────────────────────────────── ║RS=rand(64bit) ║
│ │ ║SS=rand(256bit) ║
│ │ ╚══════════════════════════╝
│ │ ╔══════════════════════════╗
│ enc(K, R+1, RS+RC+SC+Sign(DSAPriv, K))│ ║K=H(DH(CDHPriv, SDHPub)) ░║
│ ──────────────────────────────────────> ║RC=rand(64bit) ║
│ │ ║SC=rand(256bit) ║
│ │ ╚══════════════════════════╝
│ │ ╔═════════════════════════════════════╗
│ enc(K, R+2, RC) │ ║compare(RS) ░║
│ <────────────────────────────────────── ║compare(RC) ║
│ │ ║Verify(DSAPub, Sign(DSAPriv, K), K) ║
│ │ ║MasterKey=SS XOR SC ║
│ │ ╚═════════════════════════════════════╝
Each handshake message ends with so called IDtag: it is
BLAKE2b-MAC of the first 64 bits of the handshake message, with client’s
Identity used as a key. It is used to transmit identity and to
mark packet as handshake message.
If noise is enabled, then data is padded to fill up packet to MTU’s size.
Preparation stage:
DSAPub.
DSAPriv and
DSAPub. H() is BLAKE2b-256 hash function.
CDHPub and CDHPriv.
Also it generates random 64-bit R that is used as a nonce for
symmetric encryption. El() is Elligator point encoding (and vice
versa) algorithm.
Interaction stage:
El(CDHPub).
El() encoding and gets CDHPub.
SDHPriv/SDHPub.
K = H(DH(SDHPriv, CDHPub)).
RS.
SS.
El(SDHPub).
El() encoding and gets SDHPub.
K.
RS and SS.
SS.
RC.
SC.
DSAPriv key K.
RS, RC, SC,
Sign(DSAPriv, K).
RS with its own one sent before. Server
decrypts RS, RC, SC with key K, compares
RS with its own one sent before.
K signature with verifier DSAPub.
MasterKey=SS XOR SC.
RC
MasterKey is high entropy 256-bit key. K DH-derived one
has 128-bit security margin and that is why are not in use except in
handshake process. R* are required for handshake randomization
and two-way authentication.
In encryptionless mode each enc() is replaced with
AONT and chaffing function over the noised data.