keyRX is a vanity address grinder: it generates seed phrases and private keys and writes them to a file on your machine. That makes every bug a potential key-safety bug, so this file says how the project is checked, what to report, and how.
Email security@keyrx.tech. Say what you found, how to reproduce it, and which version
(keyrx --version). Expect an acknowledgement within a few days and a fix in the next release;
you will be credited in the CHANGELOG unless you ask not to be. There is no bounty pool yet;
when there is, it will be stated here. Please do not open a public issue for a key-safety bug
before a fix exists. (Everything that is not a vulnerability: dev@keyrx.tech.)
- The
keyrxcrate on crates.io and this repository: derivation (SLIP-0010, BIP32, BIP39), address encoding, matching, the match file, the terminal output,verify,--update. - keyrx.tech: the site and its in-browser suffix demo (which must never create or claim a key).
Out of scope: wallets that import what keyRX produces, the chains themselves, and social engineering of people who run the tool.
The newest release only. The consolidated workflow used for 0.4.13 and later is designed to yank
its governed predecessor only after the registry package, immutable GitHub Release and provenance
agree. A yank never breaks an existing install or lockfile. A Cargo-installed keyrx --update brings
an older install forward; the official prebuilt always points to the verified release archive.
Check crates.io itself for the current public version and yank state.
keyrx verify, on your own machine, before trusting a result: the base58 suffix path against full encoding on 50,000 keys; SLIP-0010 against a pinnedsolana-keygenanswer; the BIP39 passphrase vector; on EVM the "abandon … about" mnemonic's published account and key, EIP-55's four examples, private key 1, and the tool's own public test seed against an independent implementation (node crypto + noble). It then prints the manual cross-checks to run withsolana-keygenandcast(or a throwaway MetaMask).- Tests and clippy run before anything publishes (
publish.yml); every framed line the CLI draws is measured in tests; the site's version is pinned to the crate's by a test. - Trusted publishing: releases produced by the current
publish.ymlworkflow use crates.io's OIDC trust; the repository workflow stores no long-lived publish token. - Provenance: that workflow requires separate signed build-provenance attestations (Sigstore,
via GitHub) for the source crate and the Linux/WSL archive, each naming the commit and workflow
that produced its exact bytes. Check either subject with
gh attestation verify <downloaded-file> --repo keyrx/keyrx, or read it under the repository's Attestations. A crate attestation is never treated as an attestation of a compiled binary. - Release agreement: the one
publish.ymlstate machine preserves the tag-built.crate, uploads those exact source-archive bytes, then downloads the registry copy and requires byte-for-byte equality. Read-only jobs compile the static Linux/WSL binary twice, package it deterministically, independently re-derive the archive, and only then exercise the packaged executable. The effect job compiles or executes none of those candidate bytes. Release preflight binds every packaged source file to the corresponding Git blob at the release commit. To inspect a release yourself, verify the relevant attestation and the exact entry inkeyrx-<version>.SHA256SUMS; a new localcargo packagecan be unpacked and compared by content, but Cargo archive metadata can vary across Cargo versions. - SBOM: the current workflow requires its immutable GitHub Release to attach
keyrx-<version>.cdx.json, the dependency tree with versions and checksums (CycloneDX). cargo audit(audit.yml): the tree against the RustSec advisory database on every change and every week.- OpenSSF Scorecard (
scorecard.yml): an automated reading of repository practice, published; the badge in the README is that live number.
Grinding, estimating, benchmarking, showing and verifying make no network calls. For a source
installation, the explicit --update command invokes Cargo to fetch and install a release. The
official prebuilt refuses and names the manual verified-release path, even if Cargo is also
installed; it does not download or replace itself. There is no daemon, service,
telemetry or account. A seed or key reaches the screen only when you ask (--show-seed,
show --seeds, show --keys); on Unix a default match is written to a mode-0600 file in the
tool's mode-0700 directory before it is printed. A custom --out parent must be owned by the
caller and not group/world-writable. Secret-writing and show commands refuse on non-Unix
platforms until an owner-only ACL implementation is available; Windows users can use WSL.
If a write or durability flush fails, the seed is not printed as a fallback. A losing
candidate's key is never kept.
For a Cargo-installed build on Unix, --update resolves the root containing the running installed
binary (unless an absolute
CARGO_INSTALL_ROOT is explicit), passes that root to Cargo, then opens the installed binary with
no link following. It requires a caller-owned, non-group/world-writable, executable, single-link
regular file and relaunches the held descriptor. Non-Unix automatic relaunch is refused until an
equivalent held-identity boundary exists; the CLI prints a manual supported install path instead.