A deterministic password generator
Ciranda is a deterministic password generator. Given the same inputs, it produces the same password.
The design is intentionally split into two stages:
This separation keeps the password-hardening concern distinct from the output format concern. Argon2id handles the cost of guessing the seed. The password construction stage handles length, character sets, and deterministic placement.
The CLI prompts for:
seed: the master secret, entered hidden and confirmedcontext: a service, account, or domain labellength: the desired password length, from 4 to 128character sets: uppercase, lowercase, digits, and/or special charactersArgon2 profile: the named derivation-cost profileThe library exposes the same model through:
enhancePasswordSettingsCharacterSetsCharacterSetArgon2ProfileArgon2SettingsThe current derivation pipeline is:
context with BLAKE3 to produce a 16-byte saltseed with Argon2id using that saltThe output depends on all of these values:
Changing any of them can change the generated password.
Ciranda does not store generated passwords. Determinism lets a user regenerate a password from the same stable inputs instead of saving the password somewhere else.
That makes input discipline important. The seed and context must be typed consistently, and profile changes should be treated as derivation-policy changes because they also change the output.
Argon2 exposes low-level parameters, but normal CLI usage should not require users to tune them one by one. Ciranda therefore provides named profiles:
Development: fast, low-cost settings for tests and local iterationStandard: the normal interactive profileHardened: a high-memory profile for capable machinesThe profile controls how expensive seed guessing is. It is not the recommended rotation mechanism. Rotate by changing the seed for global rotation, or by changing or versioning the context for service-specific rotation.
The final stage constructs a password instead of encoding random bytes directly. That gives Ciranda explicit output guarantees:
This is why the output stage uses buckets, deterministic shuffling, and unbiased index selection instead of a direct byte-to-text encoding.