The algebraicdir specification

This document describes the “algebraicdir” format. The current and only version so far of the format is version 1. Note that it is not a “file format” per se in the sense that the resulting bytes are not typically stored in a regular file on disk.

To store encrypted directory names, Algebraic uses the algebraicdir container format. The original directory name is stored encrypted inside this container and can later be retrieved during decryption.

As an implementation detail, Algebraic places the resulting bytes in an xattr named “org.littleroot.algebraic.dirname” in the original directory.

Encryption algorithms

XChaCha20 for encrypting the directory name, and Argon2id for deriving an encryption key from the user-supplied password.

The Argon2id parameters and the XChaCha20 nonce used are saved in the final algebraicdir bytes.

Structure

  Name Size Encrypted
1 Header 50 bytes no
2 Directory name variable length yes
3 Checksum 32 bytes no

The header is the first 50 bytes. It is not encrypted. It primarily consists of a version identifier and the encryption parameters.

The Go struct representation is below. The struct value is binary-encoded in big-endian order.

struct {
    Version uint8 // value: 1

    // Argon2id params.
    Salt    [16]byte
    Time    uint32 // number of passes over memory
    Mem     uint32 // KiB
    Threads uint8

    // XChaCha20 nonce.
    Nonce [24]byte
}

2. Directory name

The encrypted directory name. Variable length. It is assumed to be all the bytes after the header but before the checksum.

3. Checksum

SHA-256 sum of all preceding bytes.