┌──────┐ ┌──────┐ │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.