How Linux Generates Ed25519 SSH Keys

This article provides an overview of how the Linux operating system creates and manages SSH authentication keys using the Ed25519 elliptic curve algorithm. It explores the interaction between user-space tools like OpenSSH, the kernel's entropy and randomness subsystem, the mathematical structure of the Edwards-curve Digital Signature Algorithm (EdDSA), and the filesystem permission standards that secure private credentials.

The Role of OpenSSH and the Command Layer

In Linux, SSH key management is handled primarily by the OpenSSH suite. Generating an Ed25519 key pair begins in user space using the ssh-keygen utility:

ssh-keygen -t ed25519 -C "user@example.com"

The -t ed25519 flag instructs ssh-keygen to use the Edwards-curve Digital Signature Algorithm (EdDSA) instantiated over Curve25519. Unlike RSA, which requires the user to specify key lengths (such as 2048, 3072, or 4096 bits), Ed25519 uses a fixed key size of 256 bits, which translates to a compact 32-byte public key and a 64-byte signature.

Entropy Gathering via the Linux Kernel

The security of any asymmetric cryptosystem depends entirely on the unpredictability of its secret key. During the generation phase, ssh-keygen interacts with the Linux kernel's Cryptographically Secure Pseudorandom Number Generator (CSPRNG).

On modern Linux kernels, the tool relies on the getrandom() system call (or /dev/urandom as a fallback). The kernel gathers hardware noise, interrupt timings, and device inputs to build entropy pools, feeding ChaCha20-based DRNG algorithms. This guarantees that the initial 32-byte seed extracted for the private key possesses maximum cryptographic randomness, preventing predictability or brute-force attacks on the generated keypair.

Mathematical Derivation of the Keypair

Once the 32-byte random seed is acquired from the kernel, OpenSSH processes it according to the Ed25519 specification:

  1. Hashing the Seed: The 32-byte seed is passed through the SHA-512 cryptographic hash function, generating a 64-byte digest.
  2. Scalar Clamping: The lower 32 bytes of the digest are "clamped" (specific bits are cleared and set) to clear small subgroup attacks and ensure the scalar value falls within safe limits.
  3. Public Key Calculation: The clamped 32-byte scalar is multiplied by the standard base point \(B\) on the twisted Edwards curve $ -x^2 + y^2 = 1 - \frac{121665}{121666}x^2y^2 $ over the prime field \(2^{255} - 19\). The resulting coordinate is compressed into a 32-byte public key.
  4. Private Key Storage: The private key consists of the initial 32-byte seed (or the full 64-byte expanded secret along with the public key) to facilitate fast signing.

File Encoding, Passphrase Protection, and Permissions

After computing the keypair, OpenSSH formats and writes the files to the user's home directory, usually inside ~/.ssh/:

Linux enforces mandatory Discretionary Access Control (DAC) file permissions on these assets. OpenSSH refuses to load private keys that are readable by other users, automatically verifying that id_ed25519 has permissions set to 0600 (read/write only by the owner) and the parent .ssh directory is restricted to 0700.