Protocol &
Cryptography
Gnoppix VPN is based on the WireGuard protocol — the most secure, fastest, and most audited VPN protocol in the world. Here is how it works under the hood.
Primitives
Gnoppix VPN uses the following cryptographic primitives from the Gnoppix protocol:
- ChaCha20 — symmetric encryption, authenticated with Poly1305, using RFC7539's AEAD construction
- Curve25519 — Elliptic Curve Diffie-Hellman (ECDH) key exchange
- BLAKE2s — hashing and keyed hashing, described in RFC7693
- SipHash24 — hashtable keys for high-speed hash tables
- HKDF — key derivation, as described in RFC5869
These primitives are independently audited, battle-tested, and considered among the most secure choices available in modern cryptography.
Connection-less Protocol
Gnoppix VPN uses a connection-less protocol design. A simple handshake establishes symmetric keys for data transfer, occurring every few minutes to provide rotating keys for perfect forward secrecy. The handshake is time-based, not packet-content-based, so it gracefully handles packet loss.
A clever pulse mechanism keeps keys up to date, automatically renegotiating when needed. Separate packet queues per peer minimize packet loss during handshakes. Once connected, everything is handled automatically — no manual reconnection or reinitialization required.
Key Timers
- A handshake initiation is retried after
REKEY_TIMEOUT + jitterms (jitter: 0-333 ms random) if no response received - If a packet has been received from a peer but none sent back in
KEEPALIVEms, an empty packet is sent - If no packet received from a peer in
KEEPALIVE + REKEY_TIMEOUTms, a new handshake is initiated - Ephemeral private keys and symmetric session keys are zeroed after
REJECT_AFTER_TIME × 3ms if no new keys exchanged - After sending a packet, if the count exceeds
REKEY_AFTER_MESSAGES, a new handshake is initiated - After
REKEY_ATTEMPT_TIMEms of retries, the handshake attempt ceases and queues are cleared
Key Exchange and Data Packets
Gnoppix VPN uses the Noise_IK handshake from the Noise Protocol Framework, building on CurveCP, NaCL, KEA+, SIGMA, FHMQV, and HOMQV. All packets are sent over UDP.
Security Properties
- Avoids key-compromise impersonation
- Avoids replay attacks
- Perfect forward secrecy
- Achieves "AKE security"
- Identity hiding
An optional pre-shared key provides an additional layer of symmetric-key crypto (e.g., for post-quantum resistance). When not in use, the pre-shared key is an all-zero 32-byte string.
Function Definitions
DH(priv, pub)— Curve25519 point multiplication, returns 32 bytesDH_GENERATE()— random Curve25519 private key, 32 bytesRAND(len)— random bytesDH_PUBKEY(priv)— Curve25519 public key from private key, 32 bytesAEAD(key, counter, plaintext, authtext)— ChaCha20Poly1305 per RFC7539XAEAD(key, nonce, plaintext, authtext)— XChaCha20Poly1305 with random 24-byte nonceHMAC(key, input)— HMAC-Blake2s(key, input, 32)HASH(input)— Blake2s(input, 32)TAI64N()— TAI64N timestamp, 12 bytesCONSTRUCTION— UTF-8 value"Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"IDENTIFIER— UTF-8 value"Gnoppix v1 zx2c4 Jason@zx2c4.com"
First Message: Initiator to Responder
The initiator (client) sends a handshake initiation message containing the sender index, an unencrypted ephemeral public key, the static public key encrypted with AEAD, an encrypted TAI64N timestamp, and two MAC fields for DoS mitigation.
msg = handshake_initiation {
u8 message_type
u8 reserved_zero[3]
u32 sender_index
u8 unencrypted_ephemeral[32]
u8 encrypted_static[AEAD_LEN(32)]
u8 encrypted_timestamp[AEAD_LEN(12)]
u8 mac1[16]
u8 mac2[16]
}
The chaining key and hash are derived from the construction string and the responder's static public key. The ephemeral private key is freshly generated. The encrypted static key and timestamp are authenticated against the hash state to prevent tampering.
Second Message: Responder to Initiator
The responder (server) processes the first message and replies with its own ephemeral public key, an encrypted empty payload (for key confirmation), and MAC fields.
msg = handshake_response {
u8 message_type
u8 reserved_zero[3]
u32 sender_index
u32 receiver_index
u8 unencrypted_ephemeral[32]
u8 encrypted_nothing[AEAD_LEN(0)]
u8 mac1[16]
u8 mac2[16]
}
The responder generates its own ephemeral key, performs ECDH with the initiator's ephemeral and static keys, and mixes in the pre-shared key (if used). The encrypted empty payload confirms the handshake.
Data Keys Derivation
After both handshake messages are exchanged, sending and receiving keys are derived using HKDF:
temp1 = HMAC(chaining_key, [empty])
temp2 = HMAC(temp1, 0x1)
temp3 = HMAC(temp1, temp2 || 0x2)
sender_key = temp2
receiver_key = temp3
The initiator's sending key becomes the responder's receiving key, and vice versa. All previous chaining keys, ephemeral keys, and hashes are zeroed out immediately after derivation.
Subsequent Messages: Exchange of Data Packets
Once keys are established, data packets are encrypted and authenticated using the derived session keys with a 64-bit counter nonce:
msg = packet_data {
u8 message_type
u8 reserved_zero[3]
u32 receiver_index
u64 counter
u8 encrypted_encapsulated_packet[]
}
Each data packet increments the counter, ensuring nonces are never reused. Zero padding is added to make the plaintext length a multiple of 16 bytes.
DoS Mitigation
Gnoppix VPN's protocol authenticates the first handshake message without allocating server state — the server does not even respond to unauthorized clients. This keeps it silent and invisible to scanners.
The TAI64N timestamp in the first message prevents replay attacks that could disrupt legitimate sessions. The server tracks the greatest timestamp per client and discards older ones.
Under load, the server uses cookie reply packets to require proof of IP ownership before processing CPU-intensive ECDH operations:
msg = packet_cookie_reply {
u8 message_type
u8 reserved_zero[3]
u32 receiver_index
u8 nonce[24]
u8 encrypted_cookie[AEAD_LEN(16)]
}
Cookies expire after two minutes and are a MAC of the sender's IP address using a rotating server secret as the MAC key. This allows fair rate limiting while keeping the server silent to unauthenticated traffic.
Nonce Reuse & Replay Attacks
Nonces are never reused. A 64-bit counter is used and cannot be wound backward. To handle UDP out-of-order delivery, a sliding window tracks the greatest counter received and roughly 2000 prior values — checked after the authentication tag is verified.
This design avoids replay attacks while maintaining UDP's out-of-order delivery performance.
DiffServ Considerations
All handshake packets use DSCP value 0x88 (AF41) — prioritized to avoid dropping. All transport data packets use DSCP 0 — the inner packet's DSCP is never copied to the outer packet, preventing data leakage about encrypted content.
ECN (Explicit Congestion Notification) bits are copied to and from inner packets as described in RFC6040.
Ready for Maximum Privacy?
Gnoppix VPN puts this battle-tested protocol to work for you. One price, all features, zero tracking.