Gnoppix Protocol · Noise_IK · ChaCha20Poly1305

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.

ChaCha20 Poly1305 Curve25519 BLAKE2s HKDF

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 + jitter ms (jitter: 0-333 ms random) if no response received
  • If a packet has been received from a peer but none sent back in KEEPALIVE ms, an empty packet is sent
  • If no packet received from a peer in KEEPALIVE + REKEY_TIMEOUT ms, a new handshake is initiated
  • Ephemeral private keys and symmetric session keys are zeroed after REJECT_AFTER_TIME × 3 ms if no new keys exchanged
  • After sending a packet, if the count exceeds REKEY_AFTER_MESSAGES, a new handshake is initiated
  • After REKEY_ATTEMPT_TIME ms 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 bytes
  • DH_GENERATE() — random Curve25519 private key, 32 bytes
  • RAND(len) — random bytes
  • DH_PUBKEY(priv) — Curve25519 public key from private key, 32 bytes
  • AEAD(key, counter, plaintext, authtext) — ChaCha20Poly1305 per RFC7539
  • XAEAD(key, nonce, plaintext, authtext) — XChaCha20Poly1305 with random 24-byte nonce
  • HMAC(key, input) — HMAC-Blake2s(key, input, 32)
  • HASH(input) — Blake2s(input, 32)
  • TAI64N() — TAI64N timestamp, 12 bytes
  • CONSTRUCTION — 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.