# How Croc's Code Phrase PAKE Authentication Works

> Discover how Croc's PAKE authentication transforms your code phrase into a secure session key. Learn how this method protects your data without sending passwords over the network.

- Repository: [Zack/croc](https://github.com/schollz/croc)
- Tags: internals
- Published: 2026-07-26

---

**Croc uses Password-Authenticated Key Exchange (PAKE) to convert the human-readable code phrase into a strong symmetric session key without ever transmitting the password over the network.**

The open-source file transfer tool **croc** (github.com/schollz/croc) secures peer-to-peer connections using a shared code phrase that acts as a password. Through **croc code phrase PAKE authentication**, this human-readable secret transforms into a cryptographically strong key that encrypts all subsequent data, ensuring that even the relay server cannot read the transferred files.

## Deriving the Room and Password from the Code Phrase

### Room Name Generation and Secret Extraction

In [`src/croc/croc.go`](https://github.com/schollz/croc/blob/main/src/croc/croc.go), the `New` function validates that the code phrase contains at least six characters. The implementation hashes the first four bytes to generate the **room name** used for rendezvous, while the remaining bytes (starting at index 5) serve as the weak password fed into the PAKE algorithm.

### Role-Based PAKE Initialization

Both peers initialize the PAKE object from the `github.com/schollz/pake/v3` library using the same password but with opposite roles. The receiver uses role `0` and the sender uses role `1`. The elliptic curve defaults to `p256` but is configurable via the `--curve` CLI flag defined in [`src/cli/cli.go`](https://github.com/schollz/croc/blob/main/src/cli/cli.go).

## The PAKE Handshake Sequence

The handshake occurs before any file data transmission, establishing an encrypted channel through a two-message exchange.

### Step 1: Sender Initiates PAKE

In `senderWaitForHandshake` ([`src/croc/croc.go`](https://github.com/schollz/croc/blob/main/src/croc/croc.go)), the sender creates a PAKE instance with role `1` and transmits its public value via `SimpleMessage{Kind:"pake1", Bytes:B.Bytes()}` to the receiver.

### Step 2: Receiver Responds

Upon receiving "pake1", the receiver calls `A.Update(dataMessage.Bytes)` and derives the session key `kB` via `A.SessionKey()`. It replies with `SimpleMessage{Kind:"pake2", Bytes:A.Bytes()}` containing its own public value.

### Step 3: Key Confirmation

The sender processes "pake2" by calling `B.Update(dataMessage.Bytes)` and computing `kA` via `B.SessionKey()`. At this point, both sides hold the identical session key (`kA == kB`), though neither has transmitted the original code phrase.

### Step 4: Channel Encryption

All subsequent communication uses `crypt.Encrypt` and `crypt.Decrypt` from [`src/crypt/crypt.go`](https://github.com/schollz/croc/blob/main/src/crypt/crypt.go) with the derived session key. The first encrypted message is the `handshakeRequest`, signaling the completion of the PAKE exchange.

## Security Properties

### Zero Password Transmission

The raw code phrase never leaves the client devices. Only public PAKE values (`A.Bytes()` and `B.Bytes()`) traverse the network, rendering eavesdropping attacks ineffective.

### Authenticated Encryption

The derived session key provides both confidentiality and integrity through the `crypt` package, preventing man-in-the-middle tampering with file metadata or chunks.

## CLI Usage and Configuration

Practical examples of invoking croc with custom code phrases and curves:

```bash

# Sender specifies custom code phrase

croc send --code "my secret phrase" file.txt

# Receiver joins with matching phrase

croc receive --code "my secret phrase"

# Use alternative elliptic curve for PAKE

croc send --curve p384 --code "another secret" file.txt

```

## Core Implementation Files

- [`src/croc/croc.go`](https://github.com/schollz/croc/blob/main/src/croc/croc.go): Contains `New`, `senderWaitForHandshake`, and the PAKE handshake orchestration logic.
- [`src/message/message.go`](https://github.com/schollz/croc/blob/main/src/message/message.go): Defines `message.TypePAKE` and the `SimpleMessage` structure used for PAKE value exchange.
- [`src/crypt/crypt.go`](https://github.com/schollz/croc/blob/main/src/crypt/crypt.go): Implements `Encrypt` and `Decrypt` functions that protect data using the PAKE-derived key.
- [`src/cli/cli.go`](https://github.com/schollz/croc/blob/main/src/cli/cli.go): Exposes the `--curve` parameter allowing selection of elliptic curves like `p256`, `p384`, or `p521`.

## Summary

- Croc requires code phrases of at least six characters, using the first four bytes for room identification and the remainder for PAKE authentication.
- The PAKE exchange assigns role `0` to receivers and role `1` to senders, defaulting to the `p256` elliptic curve.
- Public PAKE values are exchanged via "pake1" and "pake2" messages in `senderWaitForHandshake`, resulting in identical session keys on both peers.
- No password material ever transmits over the network; only public cryptographic values leave the client.
- Post-handshake communication uses authenticated encryption via the `crypt` package with the derived session key.

## Frequently Asked Questions

### What is PAKE and why does croc use it?

PAKE (Password-Authenticated Key Exchange) is a cryptographic protocol that allows two parties to establish a shared secret key using a weak password, without transmitting the password itself. Croc uses PAKE to ensure that the human-readable code phrase never appears on the wire, preventing relay operators or network eavesdroppers from capturing authentication credentials.

### How does croc prevent man-in-the-middle attacks during the handshake?

Croc mitigates man-in-the-middle attacks through the PAKE protocol's mathematical properties: the session key derivation depends on both the shared secret (code phrase) and the public values exchanged. An attacker without the code phrase cannot compute the correct session key, and the subsequent authenticated encryption in [`src/crypt/crypt.go`](https://github.com/schollz/croc/blob/main/src/crypt/crypt.go) rejects any tampered messages.

### Can I use a custom elliptic curve for the PAKE exchange?

Yes. While croc defaults to the `p256` curve for balanced security and performance, you can specify alternatives like `p384` or `p521` using the `--curve` flag. The CLI parser in [`src/cli/cli.go`](https://github.com/schollz/croc/blob/main/src/cli/cli.go) passes this parameter to the PAKE constructor in [`src/croc/croc.go`](https://github.com/schollz/croc/blob/main/src/croc/croc.go).

### What happens if the code phrase is shorter than six characters?

The `New` function in [`src/croc/croc.go`](https://github.com/schollz/croc/blob/main/src/croc/croc.go) enforces a minimum length of six characters for the code phrase. This requirement ensures sufficient entropy for the room name (first four bytes) and the PAKE password (remaining bytes) to maintain security.