npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@thoisoithree/fcrypt-darwin-arm64

v0.3.1

Published

Prebuilt fcrypt binary for macOS arm64

Readme

fcrypt

fcrypt is a cross-platform Rust CLI for local file encryption, decryption, key generation, and post-quantum asymmetric encryption.

The crate name is filecrypt; the installed binary is fcrypt.

fcrypt is designed for large files. It processes data as authenticated chunks, writes outputs through temporary files, and finalizes results only after the operation succeeds.

Release 0.3.x compatibility notice

Version 0.3.0 introduced the opaque .bin container format, retained by the 0.3.x releases. It does not provide backward compatibility for pre-0.3.0 encrypted files.

To read old files created by fcrypt 0.2.0 or earlier, use fcrypt version 0.2.0.

Highlights

  • Opaque password-based encrypted files with no cleartext magic bytes, version, algorithm identifiers, or recipient identifiers.
  • Password slots use a fixed opaque v1 Argon2id profile: 128 MiB, time cost 3, parallelism 1.
  • Post-quantum asymmetric encryption with ML-KEM-1024 + HQC-256 recipient slots.
  • AES-256-GCM streaming payload encryption with u64 chunk indexes.
  • Detached ML-DSA-87 signatures for opaque ciphertext files.
  • Explicit identity creation with identity create <name> for recipient and signing key pairs. The legacy asym encrypt workflow retains its historical automatic key generation behavior.
  • Random password generation and Diceware-style passphrase generation from the embedded EFF large wordlist.
  • Atomic output workflow: plaintext, ciphertext, signature, and key files are written through temporary files first.
  • npm packages with prebuilt binaries for Linux, macOS, and Windows on x64 and arm64.

Security model

Password encryption

Password mode uses the opaque container format:

password -> fixed Argon2id profile -> password slot -> manifest key
manifest key -> encrypted manifest -> file secret
file secret -> HKDF-SHA3-512 -> AES-256-GCM payload chunks

The password is entered through a hidden terminal prompt. The password is not stored in the encrypted file and is not logged.

Asymmetric encryption

Asymmetric mode uses recipient keys:

ML-KEM-1024 shared secret ┐
                          ├─ HKDF-SHA3-512 ── slot key ── manifest key
HQC-256 shared secret ────┘

manifest key -> encrypted manifest -> file secret
file secret  -> HKDF-SHA3-512 -> AES-256-GCM payload chunks

ML-KEM-1024 and HQC-256 provide two independent post-quantum KEM layers for recipient access.

Optional detached signatures use ML-DSA-87:

opaque ciphertext transcript -> ML-DSA-87 signature -> <ciphertext>.sig

A recipient key and a signing key are different keys:

  • *_recipient_default.pub is shared with people who should encrypt files for the recipient.
  • *_recipient_default.sec decrypts matching opaque files and must remain secret.
  • *_signer_mldsa87.pub is shared with people who should verify signatures.
  • *_signer_mldsa87.sec creates signatures and must remain secret.

Never share .sec files.

Install

npm

npm install -g @thoisoithree/fcrypt
fcrypt --help

The npm package installs a small launcher and a prebuilt platform binary for the current OS/CPU.

Published platform packages:

  • @thoisoithree/fcrypt-linux-x64
  • @thoisoithree/fcrypt-linux-arm64
  • @thoisoithree/fcrypt-darwin-x64
  • @thoisoithree/fcrypt-darwin-arm64
  • @thoisoithree/fcrypt-win32-x64
  • @thoisoithree/fcrypt-win32-arm64

GitHub release binaries

GitHub Releases provide raw binary files and .sha256 checksum files for:

  • Linux x64: fcrypt-linux-x64
  • Linux arm64: fcrypt-linux-arm64
  • macOS Intel: fcrypt-darwin-x64
  • macOS Apple Silicon: fcrypt-darwin-arm64
  • Windows x64: fcrypt-win32-x64.exe
  • Windows arm64: fcrypt-win32-arm64.exe

Build from source

cargo build --release --locked

Asymmetric PQC mode is enabled by default through the pqc feature and uses Open Quantum Safe liboqs through Rust oqs bindings. Building with PQC support can require:

  • Rust stable
  • C compiler
  • CMake
  • platform build tools

To build only the password-based mode:

cargo build --release --locked --no-default-features

When built without the pqc feature, fcrypt asym ... / fcrypt assym ... commands return a clear error and password mode remains available.

Help

Short command-local help:

fcrypt -h
fcrypt encrypt -h
fcrypt decrypt -h
fcrypt identity -h
fcrypt sign -h
fcrypt verify -h

Full help for every command, option, alias, and example:

fcrypt help-all

The compatibility forms -ha and --help-all are also accepted. They are handled before command parsing, except after --, so a file literally named -ha remains a valid input path.

fcrypt --help-all

Command overview

# Recommended commands
fcrypt encrypt <INPUT> [-o <OUTPUT>]
fcrypt decrypt <INPUT.bin> [-o <OUTPUT>]
fcrypt sign <INPUT.bin> --key <SIGNER.SEC>
fcrypt verify <INPUT.bin> --key <SIGNER.PUB>
fcrypt identity create <NAME>
fcrypt identity list
fcrypt identity inspect <KEY>
fcrypt password generate --length <N>
fcrypt phrase generate --words <N>

# Compatibility commands
fcrypt asym ...
fcrypt assym ...
fcrypt keygen ...

encrypt and encode are aliases. decrypt and decode are aliases. The legacy asym, assym, and keygen command groups remain supported.

Password-based usage

Encrypt a file:

fcrypt encrypt report.pdf

Equivalent alias:

fcrypt encode report.pdf

The output is:

report.pdf.bin

Decrypt:

fcrypt decrypt report.pdf.bin

Equivalent alias:

fcrypt decode report.pdf.bin

Force overwrite of an existing output file:

fcrypt decrypt report.pdf.bin --force

Choose a specific output path:

fcrypt encrypt report.pdf --output archive.bin
fcrypt decrypt archive.bin --output report-restored.pdf

For automation, read a password from a protected file. A single trailing LF or CRLF is removed; other whitespace remains part of the password:

fcrypt encrypt report.pdf --password-file ./fcrypt-password.txt --json
fcrypt decrypt report.pdf.bin --password-file ./fcrypt-password.txt --quiet

--json emits one machine-readable result to stdout. --quiet suppresses normal success messages and progress, while --no-progress keeps final output but hides progress indicators. Passwords must never be supplied as command-line arguments.

Asymmetric PQC opaque usage

Recommended recipient-key workflow

fcrypt identity create alice
fcrypt encrypt report.pdf --recipient ./alice_recipient_default.pub

The unified command never creates a recipient key silently. Use --new-identity <NAME> when intentional one-off identity creation is desired. Back up the generated recipient .sec file: without it, encrypted data cannot be recovered.

Sign and verify ciphertexts without decrypting:

fcrypt sign report.pdf.bin --key ./alice_signer_mldsa87.sec
fcrypt verify report.pdf.bin --key ./alice_signer_mldsa87.pub
fcrypt decrypt report.pdf.bin \
  --identity ./alice_recipient_default.sec \
  --verify ./alice_signer_mldsa87.pub

Generate named recipient and signing keys

Generate four key files in the current directory:

fcrypt keygen pair alice

Output files:

alice_recipient_default.pub
alice_recipient_default.sec
alice_signer_mldsa87.pub
alice_signer_mldsa87.sec

Keys are non-expiring by default. To create keys with a lifetime in days:

fcrypt keygen pair alice 365

Encrypt for an existing recipient

fcrypt asym encrypt report.pdf -r ./alice_recipient_default.pub

Long option:

fcrypt asym encrypt report.pdf --recipient-public ./alice_recipient_default.pub

When -r / --recipient-public is provided, no new recipient keypair is generated.

Choose a key directory

By default, keys are saved next to the input file in <file_stem>_keys:

report.pdf        -> report_keys/
docs/report.pdf   -> docs/report_keys/
archive.tar.gz    -> archive.tar_keys/

Override it with -k / --keys-dir:

fcrypt asym encrypt report.pdf -k ./keys

When --keys-dir is provided, fcrypt uses that directory directly and does not create a nested report_keys/ directory.

Decrypt

fcrypt asym decrypt report.pdf.bin -i ./report_keys/a13f2c9b_recipient_default.sec

Equivalent alias:

fcrypt asym decode report.pdf.bin -i ./report_keys/a13f2c9b_recipient_default.sec

If -i / --identity is omitted, fcrypt tries available recipient secret keys in the default or provided keys directory:

fcrypt asym decrypt report.pdf.bin
fcrypt asym decrypt report.pdf.bin -k ./report_keys

Opaque ciphertexts do not reveal which recipient key should be tried. Auto-discovery is therefore bounded to 32 matching recipient secret key files; use -i to select a specific key when needed.

Encrypt and sign

Generate a signing key automatically and create a detached signature:

fcrypt asym encrypt report.pdf -s

Generated files:

report.pdf.bin
report.pdf.bin.sig
report_keys/
  <label8>_recipient_default.pub
  <label8>_recipient_default.sec
  <label8>_signer_mldsa87.pub
  <label8>_signer_mldsa87.sec

Sign with an existing signing key:

fcrypt asym encrypt report.pdf -S ./alice_signer_mldsa87.sec

-S / --sign-key automatically enables signing, so this is equivalent to -s -S ./alice_signer_mldsa87.sec.

Sign an existing opaque file

Create a detached signature:

fcrypt asym sign report.pdf.bin

Output:

report.pdf.bin.sig

Use an existing signing key:

fcrypt asym sign report.pdf.bin -S ./alice_signer_mldsa87.sec

Embedded signatures are not supported for opaque files.

Verify signatures while decrypting

Verify with a signer public key:

fcrypt asym decrypt report.pdf.bin \
  -i ./report_keys/a13f2c9b_recipient_default.sec \
  -v ./alice_signer_mldsa87.pub

Require a valid signature:

fcrypt asym decrypt report.pdf.bin \
  -i ./report_keys/a13f2c9b_recipient_default.sec \
  -v ./alice_signer_mldsa87.pub \
  -R

When --verify <signer.pub> is used, a valid detached signature is required before decryption. The legacy -R / --require-signature option remains accepted for compatibility and still requires a verification key.

Options

encrypt / encode

<INPUT>, -i, --input <FILE>     Path to the input file.
-f, --force                     Overwrite the destination file without asking.

decrypt / decode

<INPUT>, -i, --input <FILE>     Path to the input file.
-f, --force                     Overwrite the destination file without asking.

asym encrypt / asym encode

-o, --output <FILE>             Destination .bin file. Defaults to <INPUT>.bin.
-r, --recipient-public <FILE>   Recipient public key bundle.
-k, --keys-dir <DIR>            Directory for generated or discovered keys.
-s, --sign                      Create a detached ML-DSA-87 signature.
-S, --sign-key <FILE>           Signing secret key. Implies --sign.
-f, --force                     Overwrite output and signature files without asking.

asym decrypt / asym decode

-o, --output <FILE>             Destination plaintext file. Defaults to <INPUT.bin without .bin>.
-i, --identity <FILE>           Recipient secret key bundle.
-k, --keys-dir <DIR>            Directory for recipient secret key auto-discovery.
-v, --verify <FILE>             Signing public key for signature verification.
-R, --require-signature         Require a valid signature before decrypting.
-f, --force                     Overwrite the destination file without asking.

asym sign

-o, --output <FILE>             Detached signature output. Defaults to <INPUT>.sig.
-S, --sign-key <FILE>           Signing secret key bundle. Generated if omitted.
-k, --keys-dir <DIR>            Directory for generated signing keys.
-e, --embed                     Unsupported for opaque files.
-f, --force                     Overwrite the signature file without asking.

Key generation

Random password

fcrypt password generate --length 32

password generate writes a random password with N characters to stdout followed by a newline. N must be between 1 and 4096.

The password generator uses the operating system CSPRNG and this portable alphabet:

A-Z a-z 0-9 ! # $ % & ( ) * + , - . / : ; < = > ? @ [ ] ^ _ { | } ~

Random passphrase

Generate a phrase from the embedded EFF large wordlist:

fcrypt phrase generate --words 7

Use a custom separator:

fcrypt phrase generate --words 7 --separator .
fcrypt phrase generate --words 7 --separator _
fcrypt phrase generate --words 7 --separator " "

keygen phrase uses the embedded EFF large wordlist with 7,776 words. Word selection is cryptographically random and uniform. The default separator is -.

Named asymmetric key pairs

fcrypt identity create alice
fcrypt identity create alice --lifetime-days 365

identity create writes one recipient keypair and one signing keypair. The optional lifetime is in days. The key filename prefix accepts ASCII letters, digits, ., _, and -, and must not start with ..

Opaque file format

Both password and asymmetric encryption use the same opaque .bin container. The outer file has no magic bytes, cleartext format version, cleartext algorithm identifiers, cleartext KDF parameters, or cleartext recipient key id.

Fixed outer layout:

32 bytes        file nonce
8 * 16384      recipient slots
4112 bytes     encrypted manifest
rest           encrypted payload chunks

The encrypted manifest contains the internal format version, plaintext length, chunk size, chunk count, tag length, and random payload file secret.

Password slots use opaque v1 Argon2id:

memory:      131072 KiB (128 MiB)
time cost:   3
parallelism: 1
output:      32 bytes

Payload chunks use AES-256-GCM. Chunk nonces are:

4-byte per-file nonce base || 8-byte big-endian chunk index

See docs/OPAQUE_FORMAT.md for implementation-level details.

Output naming

Encryption appends .bin to the full filename:

report.pdf -> report.pdf.bin

Decryption removes .bin when present:

report.pdf.bin -> report.pdf

Legacy .enc suffixes are accepted only for output-path mapping:

old-file.enc -> old-file

They do not imply legacy file format support in 0.3.x.

If the input has neither .bin nor .enc, decryption appends .dec:

archive.dat -> archive.dat.dec

Source files are never modified in place.

Release artifacts and package repositories

The release workflow builds raw binaries and SHA-256 checksum files for Linux, macOS, and Windows. Tagging a release with vX.Y.Z triggers GitHub Actions release automation.

APT and RPM repositories are published by the package repository workflow when repository signing secrets are configured. See docs/PACKAGE_REPOSITORIES.md for setup and install commands.

Release process details are documented in RELEASE.md.

Development

Run tests:

cargo test --locked

Run clippy:

cargo clippy --all-targets --all-features -- -D warnings

Build release:

cargo build --release --locked

Build without asymmetric PQC mode:

cargo build --release --locked --no-default-features

Test coverage

The test suite covers:

  • password small-file, empty-file, and chunk-boundary roundtrips;
  • wrong password, corrupted ciphertext, and truncated file failures;
  • opaque prelude tamper detection;
  • fixed password KDF profile behavior;
  • asymmetric opaque roundtrips;
  • explicit recipient public key encryption and secret key decryption;
  • bounded recipient key auto-discovery;
  • detached ML-DSA-87 signatures;
  • standalone signature verification and unified password/PQC CLI workflows;
  • required signature failures;
  • named keygen pair generation with and without lifetime;
  • output naming rules;
  • overwrite behavior;
  • random password and EFF wordlist passphrase generation;
  • help-all and compatibility -ha / --help-all output.

Security notes

  • Keep .sec files private.
  • Share only .pub files.
  • A recipient .sec key can decrypt matching opaque files.
  • A signer .sec key can create signatures as that signer.
  • Use --verify <signer.pub> when authenticity is mandatory during decryption.
  • Expired recipient secret keys remain usable for archival decryption, and expired signing public keys remain usable for historical verification. Expired recipient public keys and signing secret keys cannot be used for new work.
  • Keep backups of recipient secret keys; losing the matching recipient .sec key makes recovery impossible.
  • Password-based files cannot be recovered without the original password.
  • fcrypt 0.3.x cannot read pre-0.3.0 encrypted files. Use version 0.2.0 for those files.

License

MIT. See LICENSE.