Skip to main content

Overview

This document specifies how Cowboy private keys are stored on disk, encoded for transport, and backed up by users. Cowboy uses a self-describing, checksummed PEM envelope as the primary storage format, BIP-39 mnemonics with BIP-32/44 HD derivation as the human-readable backup and multi-key format, and an encrypted JSON keystore for production deployments. Cowboy uses secp256k1 (ECDSA) for all account keys. This is the same curve used by Ethereum and Bitcoin, which gives Cowboy native Ethereum key compatibility — the same private key can control both a Cowboy account and an EVM address.
Design Principle: Keys should be self-describing, checksummed, and familiar. A developer should be able to cat .cowboy/key and immediately understand what they’re looking at.

Key Format: PEM Envelope

File Format (.cowboy/key)

The primary on-disk format is a PEM-style envelope with base64-encoded key material:

Structure

Specification

1

Header and Footer

The file MUST begin with -----BEGIN COWBOY PRIVATE KEY----- and end with -----END COWBOY PRIVATE KEY-----, each on their own line. These markers make the format self-describing and prevent accidental use of non-key files.
2

Metadata Headers

Between the header and the base64 body, zero or more Key: Value metadata lines MAY appear. Defined headers:Unknown headers MUST be ignored by parsers (forward compatibility).
3

Body

A single line of standard base64 (RFC 4648) encoding of the raw 32-byte private key. The line MUST NOT contain whitespace.
4

Trailing Newline

The file SHOULD end with a single trailing newline after the footer. Parsers MUST tolerate missing or extra trailing newlines.

Address Derivation

From a secp256k1 private key, the Cowboy address is derived using the Ethereum-standard method:
  1. Compute the uncompressed public key (64 bytes, without the 04 prefix).
  2. Hash with Keccak-256.
  3. Take the last 20 bytes as the address.
This means a Cowboy address is an Ethereum address — the same key produces the same 0x... address on both chains.

Checksum Calculation

The checksum provides corruption detection:
On load, the CLI:
  1. Decodes the base64 body to get the raw key bytes.
  2. Computes SHA-256(raw_key_bytes).
  3. Compares the first 4 hex characters against the Checksum header.
  4. If they don’t match, prints an error and refuses to use the key.
Four hex characters (16 bits) catch 99.998% of random corruptions — sufficient for a local file that is rarely edited by hand.

Parsing Rules

Example: Full Round-Trip

Backup & Recovery: BIP-39 Mnemonic

For human-readable backup and recovery, Cowboy uses BIP-39 mnemonics as the seed format. Combined with BIP-32/44 hierarchical deterministic (HD) derivation, a single 24-word mnemonic can derive an unlimited number of Cowboy keys.

Export

Import

Mnemonic Specification

The mnemonic is generated from 256 bits of cryptographically random entropy:
  1. Generate 32 bytes (256 bits) of random entropy.
  2. Compute SHA-256 of the entropy; take the first 8 bits as a checksum.
  3. Concatenate: 256 bits of entropy + 8 bits of checksum = 264 bits.
  4. Split into 24 groups of 11 bits.
  5. Each 11-bit value maps to a word in the BIP-39 English wordlist (2048 words).
The mnemonic is then converted to a 512-bit seed via PBKDF2-HMAC-SHA512 (2048 rounds) with the passphrase "mnemonic" (no user passphrase by default). This seed feeds into BIP-32 HD derivation.
Only the BIP-39 English wordlist is supported. The wordlist is well-established, widely available, and avoids internationalization complexity.

HD Derivation (BIP-32/44)

Cowboy uses standard BIP-32/44 hierarchical deterministic derivation to produce account keys from a mnemonic seed. This is the same scheme used by Ethereum wallets (MetaMask, Ledger, Trezor), which means:
  • A Cowboy mnemonic imported into MetaMask produces the same addresses
  • A MetaMask/Ledger mnemonic imported into Cowboy produces the same addresses
  • Hardware wallets work out of the box

Derivation Path

Cowboy uses Ethereum’s coin type (60') rather than registering a separate coin type. This is intentional — Cowboy accounts are Ethereum addresses, and using the same derivation path means full wallet compatibility.
The default account is index 0. When cowboy wallet create --from-mnemonic or cowboy wallet import --mnemonic is used without specifying an index, account 0 is derived.

Deriving Multiple Keys

Hardware Wallet Support

Cowboy supports signing transactions via hardware wallets (Ledger, Trezor) using the same BIP-44 derivation path. The private key never leaves the hardware device.

How It Works

  1. The CLI constructs the transaction and computes the signing hash (keccak256(CBOR(tx))).
  2. The hash is sent to the hardware wallet over USB/HID.
  3. The user confirms on the device screen.
  4. The device signs with the private key at the specified BIP-44 path and returns the signature.
  5. The CLI attaches the signature and broadcasts the transaction.

CLI Usage

Supported Devices

Since Cowboy uses the standard Ethereum derivation path (m/44'/60'/0'/0/n) and secp256k1 signing, hardware wallets require no custom firmware or app — the existing Ethereum app on Ledger/Trezor works directly.

Auto-Discovery with Hardware Wallets

When --ledger or --trezor is passed, the CLI skips file-based key discovery entirely and communicates with the device directly. Hardware wallet flags take priority over all other key sources.

Environment Variable Format

When using the COWBOY_PRIVATE_KEY environment variable, the value is the raw 32-byte key in hex encoding (with or without 0x prefix):
Hex is the right choice for environment variables because:
  • It’s a single-line value (no PEM headers)
  • It’s commonly used for secrets in environment variables across the ecosystem
  • It’s easy to set programmatically

CLI Commands

Wallet commands:

Security Considerations

The CLI MUST set .cowboy/key to mode 0600 (owner read/write only) on creation. On load, if the file is group- or world-readable, the CLI SHOULD print a warning:
When displaying mnemonics, the CLI MUST:
  • Print a warning about secure storage before showing the words.
  • Never write mnemonics to log files or shell history.
  • Clear terminal scrollback is recommended but not enforced.
When reading mnemonics for import, the CLI SHOULD use a no-echo input mode where supported.
Unencrypted PEM keys are protected by filesystem permissions (0600), which is sufficient for local development. For production or shared machines, use the encrypted keystore format (cowboy wallet encrypt), which wraps the key in AES-256-GCM with an Argon2id-derived passphrase.
Hardware wallets provide the strongest key security — the private key is generated on-device and never exposed to the host machine. For high-value accounts or production validators, hardware wallet signing is strongly recommended.

Encrypted Keystore

For production deployments and shared machines, Cowboy supports passphrase-encrypted key files. An encrypted keystore wraps the PEM key material in an AES-256-GCM envelope, with the encryption key derived from a user passphrase via Argon2id.

File Format (.cowboy/key.enc)

Encryption Specification

1

Key Derivation

The passphrase is fed into Argon2id to derive a 32-byte encryption key:Argon2id is chosen over scrypt (used by Ethereum’s keystore v3) because it provides stronger resistance to both GPU and side-channel attacks.
2

Encryption

The raw 32-byte private key is encrypted with AES-256-GCM:
  1. Generate a 12-byte random nonce.
  2. Encrypt the key bytes with AES-256-GCM using the derived key and nonce.
  3. Store the ciphertext and 16-byte authentication tag separately.
AES-256-GCM provides authenticated encryption — any tampering with the ciphertext, nonce, or tag causes decryption to fail.
3

Checksum

The checksum field contains the same SHA-256-based checksum as the PEM format (first 4 hex chars of SHA-256(raw_key_bytes)). This allows verifying the key after decryption without exposing any information about the plaintext key in the encrypted file.The checksum is computed over the plaintext key bytes before encryption and verified after decryption.

CLI Commands

Auto-Discovery with Encrypted Keys

The key auto-discovery order is extended to check for encrypted keystores:
  1. --ledger / --trezor flag (hardware wallet, skips file discovery)
  2. --private-key <path> flag
  3. COWBOY_PRIVATE_KEY environment variable (hex)
  4. .cowboy/key file (PEM)
  5. .cowboy/key.enc file (encrypted keystore) — prompts for passphrase
When an encrypted keystore is found, the CLI prompts for a passphrase interactively. For non-interactive environments (CI/CD), the passphrase can be provided via the COWBOY_KEY_PASSPHRASE environment variable.

Passphrase Requirements

The CLI enforces minimum passphrase quality on creation:
  • Minimum 8 characters
  • No maximum length
  • No character-class requirements (length is the primary security factor)
Weak passphrases (under 12 characters) trigger a warning but are allowed:

When to Use Each Format

Further Reading