onecrypto sop is the Stateless OpenPGP command line (sop): one subcommand per operation, keys and certificates as files, data on standard input and output, no keyring. Any sop tool takes the same commands, so a script written for Sequoia’s sqop runs with onecrypto sop. It ships as a .NET tool:
dotnet tool install --global RecursiveAI.OneCrypto.Cli --version 0.3.0-preview.2 onecrypto sop version --extended onecrypto --help
You can invoke the tool using the following command: onecrypto Tool 'recursiveai.onecrypto.cli' (version '0.3.0-preview.2') was successfully installed. onecrypto 0.3.0-preview.2 RecursiveAI.OneCrypto.OpenPgp 0.3.0-preview.2 Running on .NET 10.0.11 Usage: onecrypto <command> [arguments] Commands: sop <subcommand> the Stateless OpenPGP command line: sign, verify, encrypt, decrypt, generate-key and the rest sopv <subcommand> the verification-only subset of sop (version, verify, inline-verify, validate-userid) pgp authenticate judge how well a User ID is authenticated by the web of trust `onecrypto sop --help` lists the sop subcommands.
It needs the .NET 10 runtime. onecrypto sop --help lists the sop subcommands and onecrypto sop verify --help shows one subcommand’s options. Generate a key, take its certificate (the public part), then encrypt, decrypt, sign and verify:
onecrypto sop generate-key 'Alice <[email protected]>' > alice.key onecrypto sop extract-cert < alice.key > alice.cert echo 'Meet at the north entrance at 10:00.' > message.txt onecrypto sop encrypt alice.cert < message.txt > message.asc onecrypto sop decrypt alice.key < message.asc onecrypto sop sign alice.key < message.txt > message.sig onecrypto sop verify message.sig alice.cert < message.txt
Meet at the north entrance at 10:00. 2026-11-02T06:53:34Z 076F94B775A852F8E03C7172CB5DF2AE7C266E75 076F94B775A852F8E03C7172CB5DF2AE7C266E75 mode:binary {"signers":["alice.cert"]}
decrypt prints the plaintext; verify prints one line per good signature (time, signing key, primary key, mode, and the certificate files that could have made it) and exits 0, or exits 3 when no signature verifies. Output is ASCII-armored unless you pass --no-armor. The key above is unprotected; add --with-key-password=pw.txt to generate-key to protect it, and give the same option to decrypt and sign. --with-password encrypts to a password instead of a key. The other subcommands: inline-sign, inline-verify, inline-detach, armor, dearmor, change-key-password, revoke-key, update-key, merge-certs, certify-userid, validate-userid and list-profiles.
Which key generate-key makes
Since 0.3.0-preview.2, generate-key makes a version 4 EdDSA/ECDH Curve25519 key by default, the form GnuPG reads; before, the default was version 6. Ask for --profile=rfc9580 for a version 6 key (RFC 9580). The profiles:
onecrypto sop list-profiles generate-keydefault: use the implementer's recommendations: version 4 EdDSA and ECDH keys over Curve25519, which GnuPG, RNP, Sequoia, OpenPGP.js and GopenPGP all read rfc9580: version 6 Ed25519 and X25519 keys rfc9580-v4: version 4 keys with the native Ed25519 and X25519 algorithms rfc9580-ed448: version 6 Ed448 and X448 keys rfc9580-rsa: version 6 keys with RSA-3072 rfc4880: version 4 keys with RSA-3072, readable by RFC 4880 implementations (alias: compatibility) compatibility: alias for rfc4880 draft-koch-eddsa-for-openpgp-00: version 4 EdDSA (legacy) and ECDH Curve25519 keys nist-p256: version 4 ECDSA and ECDH keys on NIST P-256 nist-p384: version 4 ECDSA and ECDH keys on NIST P-384 nist-p521: version 4 ECDSA and ECDH keys on NIST P-521 security: higher security, maybe reduced performance: version 6 Ed448 and X448 keys performance: higher performance, maybe reduced security: version 6 Ed25519 and X25519 keys rfc9980: alias for pqc pqc: version 6 ML-DSA-65 + Ed25519 and ML-KEM-768 + X25519 keys (RFC 9980; needs platform support) pqc-high: version 6 ML-DSA-87 + Ed448 and ML-KEM-1024 + X448 keys (RFC 9980; needs platform support)
Check it with Sequoia
Sequoia’s sqop 0.37.3 takes the same files. It decrypts and verifies what onecrypto wrote, and onecrypto decrypts and verifies what it writes:
sqop decrypt alice.key < message.asc sqop verify message.sig alice.cert < message.txt echo 'Reply from Sequoia.' | sqop encrypt alice.cert > reply.asc onecrypto sop decrypt alice.key < reply.asc echo 'Reply from Sequoia.' > reply.txt sqop sign alice.key < reply.txt > reply.sig onecrypto sop verify reply.sig alice.cert < reply.txt
Meet at the north entrance at 10:00. 2026-11-02T06:53:34Z 076F94B775A852F8E03C7172CB5DF2AE7C266E75 076F94B775A852F8E03C7172CB5DF2AE7C266E75 mode:binary {"signers":["alice.cert"]} Reply from Sequoia. 2026-11-02T06:53:34Z 076F94B775A852F8E03C7172CB5DF2AE7C266E75 076F94B775A852F8E03C7172CB5DF2AE7C266E75 mode:binary {"signers":["alice.cert"]}
Check it with GnuPG
GnuPG 2.4.8 reads the default key as it is: it imports it, decrypts and verifies what onecrypto wrote, and onecrypto opens what GnuPG writes. GNUPGHOME points gpg at a new, empty home for this terminal session, so nothing here touches your own keyring; the later gpg commands on this page use the same home.
export GNUPGHOME="$(mktemp -d)" gpg --batch --import alice.key gpg --batch --decrypt message.asc gpg --verify message.sig message.txt gpg --batch --trust-model always --armor -r [email protected] \ --encrypt < message.txt > from-gpg.asc onecrypto sop decrypt alice.key < from-gpg.asc gpg --batch --armor --detach-sign -u [email protected] < message.txt > from-gpg.sig onecrypto sop verify from-gpg.sig alice.cert < message.txt
gpg: keybox '/tmp/tmp.fxRJX5t6Vs/pubring.kbx' created gpg: /tmp/tmp.fxRJX5t6Vs/trustdb.gpg: trustdb created gpg: key CB5DF2AE7C266E75: public key "Alice <[email protected]>" imported gpg: key CB5DF2AE7C266E75: secret key imported gpg: Total number processed: 1 gpg: imported: 1 gpg: secret keys read: 1 gpg: secret keys imported: 1 gpg: encrypted with cv25519 key, ID 2129DE476AE4AC48, created 2026-11-02 "Alice <[email protected]>" Meet at the north entrance at 10:00. gpg: Signature made Mon 02 Nov 2026 06:53:34 AM UTC gpg: using EDDSA key 076F94B775A852F8E03C7172CB5DF2AE7C266E75 gpg: Good signature from "Alice <[email protected]>" [unknown] gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: 076F 94B7 75A8 52F8 E03C 7172 CB5D F2AE 7C26 6E75 Meet at the north entrance at 10:00. 2026-11-02T06:53:34Z 076F94B775A852F8E03C7172CB5DF2AE7C266E75 076F94B775A852F8E03C7172CB5DF2AE7C266E75 mode:binary {"signers":["alice.cert"]}
GnuPG’s “not certified with a trusted signature” warning means what it says: nothing in its keyring vouches for Alice’s key yet. The same commands from C#: Encrypt and decrypt a file with PGP, Sign and verify with PGP and Generate a PGP key.
Limits
- Not audited. OneCrypto (cryptography, not cryptocurrency) has not been independently audited. It is a preview: 0.3.0-preview.2, and the API can change.
- Version 6 keys and GnuPG.
rfc9580,rfc9580-ed448,rfc9580-rsa,security,performanceand thepqcprofiles make version 6 keys, which GnuPG 2.4 doesn’t read.rfc9580-v4is version 4 with the native Ed25519 algorithms: GnuPG 2.4 imports it but can’t check its signatures.generate-keywrites version 4 and 6 keys only. verifychecks signatures, not identities. A good signature line means the certificate you passed made it; whether that certificate belongs to the person is yours to establish.onecrypto pgp authenticate --root FINGERPRINT FILEcomputes it from certifications (OpenPGP trust models).- The subcommands and options are the sop draft’s (draft-dkg-openpgp-stateless-cli, version 16);
--helpis the tool’s own addition.onecrypto sopvis the verification-only subset. pqcandpqc-highneed ML-DSA and ML-KEM on the platform; elsewhere they exit 13.
When you’re done: dotnet tool uninstall --global RecursiveAI.OneCrypto.Cli. Every subcommand, the interoperability scoreboard against Sequoia and GopenPGP, and the test corpus: onecrypto sop.