oneseed 0.3.0

Deterministic cryptographic keys from a single seed
oneseed-0.3.0 is not a library.

1seed

Rust License: MIT Crates.io zread

Deterministic cryptographic keys from a single seed.

What This Does

  • Derives age, SSH, and signing keys from one master secret
  • Encrypts and decrypts files using age
  • Signs and verifies data using Ed25519
  • Generates site-specific passwords
  • Generates BIP39 mnemonic phrases

What This Does Not Do

  • Store secrets (use files, encrypted with 1seed)
  • Sync secrets (use git)
  • Manage contacts (use a text file)
  • Replace hardware security keys for high-value assets
  • Generate TOTP codes (time-based, not derivable)

Installation

Quick Install

curl -fsSL https://raw.githubusercontent.com/oeo/1seed/master/install.sh | bash

From crates.io

cargo install oneseed

From Source

cargo install --path .

Requires: ssh-add (for agent integration)

Quick Start

# Option 1: Use a seed file (recommended)
dd if=/dev/urandom bs=32 count=1 > ~/.seed
chmod 600 ~/.seed
1seed set seed-file ~/.seed

# Option 2: Use a passphrase (brainwallet)
echo "your long memorable passphrase here" > ~/.seed
chmod 600 ~/.seed
1seed set seed-file ~/.seed

# Option 3: No file, prompt every time
# (just don't set seed-file)

# Show your age public key
1seed age pub

# Add SSH key to agent
1seed ssh add

# Encrypt to self
echo "secret" | 1seed age encrypt > secret.age

# Decrypt
1seed age decrypt < secret.age

# Derive a password
1seed derive password github.com

Commands

Age Encryption

1seed age pub                      Show age public key
1seed age key                      Show age private key
1seed age encrypt [OPTIONS] [FILE]
  -R, --recipient KEY     Add recipient (repeatable)
  -F, --recipients-file   Add recipients from file (repeatable)
  -s, --self              Include self as recipient
  -p, --passphrase        Encrypt with passphrase
  -a, --armor             ASCII armor output
  -o, --output FILE       Output file

1seed age decrypt [OPTIONS] [FILE]
  -k, --key FILE          Key file (instead of derived)
  -p, --passphrase        Decrypt with passphrase
  -o, --output FILE       Output file

Default: encrypt to self, decrypt with derived key.

SSH Keys

1seed ssh pub             Show SSH public key
1seed ssh key             Show SSH private key
1seed ssh add [OPTIONS]   Add SSH key to agent
  -t, --lifetime SEC      Key lifetime
  -c, --confirm           Require confirmation

Signing

1seed sign pub                 Show signing public key
1seed sign data [OPTIONS] [FILE]
  -o, --output FILE       Output file
  --binary                Binary output (default: base64)

1seed sign verify SIGNATURE [FILE]
  -k, --pubkey KEY        Public key (default: derived)

Derivation

1seed derive password [OPTIONS] SITE
  -l, --length N          Password length (default: 16)
  -n, --counter N          Rotation counter (default: 1)
  --no-symbols            Alphanumeric only
  --symbols SET           Symbol set (default: !@#$%^&*)

1seed derive raw [OPTIONS] PATH
  -l, --length N          Byte length (default: 32)
  --hex                   Output as hex (default)
  --base64                Output as base64
  --binary                Output as raw bytes

1seed derive mnemonic [OPTIONS]
  -w, --words N           Word count: 12/15/18/21/24 (default: 24)

Management

1seed status        Show configuration sources and derived keys
1seed update        Update to latest release from GitHub
  --check           Check for updates without installing
1seed set KEY VALUE Set config value (realm, seed-file)
1seed get KEY       Get config value

Realms

Realms namespace all derived keys. Same seed, different realm = different keys.

1seed --realm personal age pub     # Personal age key
1seed --realm work age pub         # Work age key (different)
1seed --realm work ssh add         # Work SSH key

Set a default:

1seed set realm personal

Password Rotation

When a password is compromised:

1seed derive password github.com -n 2   # Increment counter

Same site, different counter = different password.

Backup

Your backup is the seed file (32 bytes) or passphrase.

# Backup seed file
cp ~/.seed /secure/backup/location/

# Or memorize a passphrase
echo "correct horse battery staple piano umbrella" > ~/.seed

From this, everything derives deterministically:

  • Same seed + same realm = same keys (always)
  • Different seeds or realms = different keys (always)

Security Notes

Seed file: 32 random bytes. Maximum entropy.

Passphrase: Processed through scrypt (N=2^20, r=8, p=1). Uses ~1GB RAM, takes ~1 second. Resists brute force, but use a strong passphrase (6+ random words).

Memory: Keys are zeroized when dropped.

Mnemonic warning: Deriving BIP39 phrases means your cryptocurrency keys share fate with your master seed. Consider using a dedicated realm and understand the risk.

Examples

Encrypt for team

# Collect public keys
cat > team.txt << EOF
age1alice...
age1bob...
$(1seed age pub)
EOF

# Encrypt
1seed age encrypt -F team.txt < secrets.json > secrets.json.age

Sign a release

1seed sign data release.tar.gz > release.tar.gz.sig
1seed sign pub > signing-key.pub

# Others verify
1seed sign verify -k "$(cat signing-key.pub)" "$(cat release.tar.gz.sig)" release.tar.gz

Multiple machines

# Machine A
1seed ssh pub >> ~/.ssh/authorized_keys

# Machine B (same seed)
1seed ssh add
ssh user@machine-a  # works

Environment Variables

SEED_FILE    Path to seed file
SEED_REALM   Default realm

Configuration

Config file location: ~/.1seed/config.toml (optional)

Priority: --flag > $ENV_VAR > config.toml > default

realm = "personal"
seed-file = "/Users/you/.seed"

Use 1seed status to see which values are active and their sources.

License

MIT