PGPony
com.pgpony.android
Zapstore _@zapstore.dev Encrypt, decrypt and sign with OpenPGP. Post-quantum keys and security keys.
Republished from GitHub / F-Droid by the Zapstore main account.
PGPony brings real OpenPGP encryption to Android, with post-quantum cryptography and hardware security key support. Generate PGP keys, then encrypt, decrypt, sign and verify messages and files on your device. No account, no server, no tracking. Fully compatible with GnuPG (GPG), OpenKeychain and other OpenPGP tools. NEW: Pairing with PGPony Desktop, SSH login with your PGP keys, and post-quantum ML-DSA signatures. ▌POST-QUANTUM ENCRYPTION - Quantum-resistant ML-KEM-768 and ML-KEM-1024 (Kyber) composite encryption keys - Post-quantum ML-DSA-65 and ML-DSA-87 (Dilithium) signatures on OpenPGP v6 keys - IETF standard format, plus the LibrePGP format GnuPG 2.5 uses - Protects your messages from "harvest now, decrypt later" attacks ▌EMAIL, PASSWORDS AND SSH - OpenPGP provider for Thunderbird for Android, K-9 Mail and FairEmail - A modern successor to OpenKeychain: same API, actively maintained - You approve every connected app and can revoke any of them in Settings - Read your pass (password-store) entries, including ones on a hardware key - SSH login with a PGPony key through an ssh-agent in Termux ▌HARDWARE SECURITY KEYS - Use a YubiKey, Token2 or other OpenPGP smartcard over NFC or USB - Your private key never leaves the hardware; the PIN confirms every operation - Generate keys on the card, sign, decrypt and encrypt-and-sign; optional PIN caching - Change PINs and reset the card; KDF-protected PINs supported ▌PGP KEY MANAGEMENT - Generate Ed25519, RSA, OpenPGP v6 or post-quantum key pairs - Import and export armored keys; add subkeys and User IDs; set expiry; revoke - Encrypted keyring backup and restore, including OpenKeychain backups ▌ENCRYPT, DECRYPT, SIGN - Encrypt text or files for one or many recipients - Verify signatures with a clear verified-signer badge - PGP/MIME email: decrypt messages with attachments, compose .eml ▌OPENPGP V4 + V6 + PQC COMPATIBILITY - Full OpenPGP v4 (RFC 4880) and v6 (RFC 9580): generate, encrypt, decrypt, sign - AEAD-OCB authenticated encryption and Argon2id key protection - Byte-exact GnuPG interoperability, tested on every release ▌EASY KEY EXCHANGE - Share your public key as a QR code, file or text; scan to import - Import a key from a link and check its fingerprint before adding it - Key server and Web Key Directory (WKD) lookup, including keys.openpgp.org - Pair with PGPony Desktop (macOS, Windows, Linux) or another phone - Autocrypt support and a built-in contacts list ▌PRIVACY BY DESIGN - Encryption runs 100% on your device: no account, no telemetry - Offline mode turns off every network feature - Route key server traffic through Tor with Orbot - Private keys in encrypted storage backed by Android Keystore - Optional biometric lock, fingerprint-to-sign and auto-clearing clipboard ▌WHO PGPONY IS FOR - Journalists, researchers and activists handling sensitive information - Thunderbird, K-9 Mail and FairEmail users who need a crypto provider - Developers and sysadmins using PGP for code signing, releases or SSH - GnuPG users who want a mobile companion, or an OpenKeychain replacement - Anyone who wants encryption that stays private in the quantum era ▌WHY PGPONY Most "secure messaging" apps ask you to trust their servers. PGPony doesn't need any. Your keys are generated and stored on your device and never leave unless you share them. If you use GnuPG on the desktop, you already know PGPony. New to PGP? It's built to be the easiest place to start. ▌OPEN SOURCE - Apache-2.0 licensed, with the OpenPGP core published as its own library - Reproducible builds: anyone can check the release APKs against the source - Free, with no ads and no in-app purchases ▌PRIVACY COMMITMENT PGPony does not collect, store or transmit any personal data. No account system, no tracking SDKs. Full privacy policy: pgpony.app/privacy Made by an indie developer in Alabama. Questions or requests? Tap Send Feedback in the app, or write NorseHorse@norsehor.se.
First release: Aug 1, 2026, 20 total releases.
Most recent release: Oct 30, 2026.
Appears in 0 app stacks.
0 sats / 0 zaps received in the past year.
Sats Received
Underlying data available via MCP: app_zaps, app_releases.
Zap Count
Underlying data available via MCP: app_zaps, app_releases.
Releases
- Oct 30, 2026 4.7.3# PGPony 4.7.3 A patch for keys made with Curve 448 in GnuPG or Kleopatra. 4.7.3 carries versionCode 473 and installs in place over 4.7.2. It went through a release candidate published as a GitHub pre-release with its own signed tag; docs/RC_HISTORY.md lists it. The tag v4.7.3-rc1 went onto the 4.7.2 release commit by mistake, the gate caught it, and nothing was built or published from it, so RC2 is the only build. The release APK is the RC2 file itself, with the same whole-file SHA-256. ## Ed448 keys from GnuPG and Kleopatra
More…
GnuPG 2.3 and later make Curve 448 keys as LibrePGP v5 keys, with an Ed448 primary key for signing and an X448 subkey for encryption. PGPony imported them but could not exchange messages or signatures with anyone else using one. Reported by email, and checked on RC2 with the reporter's own key against Kleopatra in both directions. Encrypting to such a key works. It used to fail with "exception constructing public key", because GnuPG stores the X448 public value without the prefix byte Bouncy Castle expects. Messages encrypted to the X448 subkey decrypt. GnuPG writes the sender's ephemeral X448 value without that prefix and keeps the secret scalar in its own byte order, and PGPony now reads both. ## Signatures from v5 keys Signatures from a v5 key verify, whether inline, detached or cleartext. For a v5 signature over a document, GnuPG hashes a few extra octets: the literal data's format, file name and date for an inline signature, and a fixed block for detached and cleartext signatures. PGPony left them out, so no v5 document signature verified before. Signatures PGPony makes with a v5 key verify in GnuPG. Bouncy Castle wrote them with a 4-octet trailer length where v5 needs 8, and without the extra document octets, so gpg reported every one as BAD and PGPony could not verify its own either. This covers signed messages and files, cleartext signing, signed and encrypted messages, and the self-signatures written when you add a user ID, change the expiry or revoke. Signing and verifying with v4 and v6 keys goes through the same Bouncy Castle code as in 4.7.2. PGPony Desktop 3.0.3 carries the same changes. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 82617be87e493fbb165864483c7834cd13a854d023b790fa124806cf034d3b84 ``` Content hash (for rebuilders; excludes signature, see docs/REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` 4637e545efcf06a240cafb0c72872f1e3b2e9f0d527f340384468928345bd890 ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release, along with the armored release key (NorseHorse-release-key.asc) and PGPony-4.7.3-signing-keys.txt with the OpenPGP fingerprint and the APK signing certificate's SHA-256. Check the fingerprint against pgpony.app, keys.openpgp.org or keys.pgpony.app rather than trusting the copy in the release alone. - Oct 28, 2026 4.7.2# PGPony 4.7.2 Fixes for typing on Encrypt and Decrypt, passphrase entry, pasted messages and hardware key decryption. 4.7.2 carries versionCode 472 and installs in place over 4.7.1. It went through release candidates published as GitHub pre-releases, each with its own signed tag; docs/RC_HISTORY.md lists them. RC6 was tagged but did not build, so it has no download. The release APK is the RC7 file itself, with the same whole-file SHA-256. ## The keyboard on Encrypt and Decrypt A tap outside a text field on Encrypt, Decrypt or the recipient picker closes the keyboard. Scrolling and moving
More…
between fields keep it open. Both screens also scroll while the keyboard is open, so the options and the Encrypt or Decrypt button under it can be reached without closing it. ## Passphrases The passphrase prompts on Encrypt and Decrypt show the key's email under its name, so keys with the same name can be told apart. The prompts and the passphrase fields on Decrypt have a show or hide button, and open masked. The passphrase field on Decrypt is used for one attempt and emptied after it, when a new message is pasted, and when the prompt is closed. It used to keep the last passphrase behind the dots. A pasted passphrase was added after it and read as wrong, and the leftover passphrase kept a key usable after the passphrase cache time set in Settings had run out. ## Text pasted around a message Decrypt reads only the PGP MESSAGE block. Text pasted with it, such as an email signature below the message that starts with a line of dashes, made the message fail as malformed. ## Hardware keys (#108) When a message is encrypted to more than one subkey of your key, PGPony decrypts with the one in the card's encryption slot. It used to take the first subkey it recognised, so a message that listed another subkey first failed with "encrypted to a different key" although the card could open it. gpg writes messages like this for a key whose authentication subkeys carry the ADSK flag. On a card with Curve25519 keys, a message for a key the card doesn't hold now says it was encrypted to a different key. It used to fail with "checksum failed". A message that hides its recipient (gpg -R) opens on a card when your key has more than one encryption subkey; before, PGPony could stop after the first subkey that didn't fit. Opened as a file, such a message now offers your hardware key once none of your software keys opens it, as a pasted one already did. Decrypting with the card's authentication slot, for a message whose only matching subkey sits in that slot, is planned for 4.8.0. ## A crash in the key lists The recipient list and the Sign as list show each key once. A key that appeared twice could crash PGPony while the list scrolled, reported through Google Play. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 872ae77e479cab5ae33e6b4dd2f2676ba03e2a3cec266f8d84a0bd4ee3319508 ``` Content hash (for rebuilders; excludes signature, see docs/REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` 6ae822feb4e7730104b701c924e16f515e0825bd992dba468ea1543460d9fb94 ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release, along with the armored release key (NorseHorse-release-key.asc) and PGPony-4.7.2-signing-keys.txt with the OpenPGP fingerprint and the APK signing certificate's SHA-256. Check the fingerprint against pgpony.app, keys.openpgp.org or keys.pgpony.app rather than trusting the copy in the release alone. - Oct 24, 2026 4.7.1# PGPony 4.7.1 Two fixes on top of 4.7.0. 4.7.1 carries versionCode 471 and installs in place over 4.7.0. ## Opening the full text of a long message The inline result of a decrypt shows the first 4,000 characters, and Open full text shows the rest. That view laid out the whole message at once, which could take long enough on a slower phone for Android to report PGPony as not responding. It now loads the text in blocks and lays out only the ones on screen. You can select text within a block; Copy still copies the complete message.
More…
## Signing with ECDSA keys on a security key (#102) A security key holding ECDSA keys (secp256k1, the NIST curves or brainpool) could not sign: the card returns its signature as two raw numbers, PGPony passed them on unchanged, and the OpenPGP library expects them in a different encoding, so signing failed with "exception decoding signature" after the PIN and the tap. PGPony now converts the signature, and hashes with SHA-256 on 256-bit curves, SHA-384 on 384-bit curves and SHA-512 on P-521 and brainpoolP512r1. This covers every card signature: messages, files, mail apps, certifications and expiry changes. The labels were wrong for those keys too. Key Details named every ECDH subkey X25519, and a card on one of these curves was stored as Ed25519 + Cv25519. Both now show the real curve. An entry stored with the wrong label is corrected the next time you scan the card. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 99d36b8c6aa7ac6bbfbea0a3f03bd3ba242fa28b8e3ddaa160aba6b721d1dc45 ``` Content hash (for rebuilders; excludes signature, see docs/REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` b4d1a98acf62b7d1d38d8c1a047785756869c238318c79f2e0e76668764de29b ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release, along with the armored release key (NorseHorse-release-key.asc) and PGPony-4.7.1-signing-keys.txt with the OpenPGP fingerprint and the APK signing certificate's SHA-256. Check the fingerprint against pgpony.app, keys.openpgp.org or keys.pgpony.app rather than trusting the copy in the release alone. - Oct 20, 2026 4.7.0# PGPony 4.7.0 Moving existing keys onto a security key, certifying other people's keys, an app PIN with a duress PIN, and a long list of changes from tester reports. 4.7.0 carries versionCode 470 and installs in place over 4.6.4. ## Move a key onto a security key (#71) Key Details > Move to a security key does what gpg's keytocard does. Each slot (Signature, Decryption, Authentication) gets one key that fits it, the newest subkey for that use by default, or is left as it is. PGPony offers to save a backup first, checks the user PIN before writing anything, then uses each slot once
More…
(a signature, a test decryption, an authentication) and reads the card's fingerprints back. Only after every check passes does anything on the phone change. By default the moved keys are removed from the phone and kept as pointers to the card, as gpg does. It works over NFC and USB with v4 RSA 2048, 3072 and 4096, Ed25519 and Cv25519 keys. v6 keys and NIST or brainpool curves cannot be moved yet; the sheet lists each key that cannot move and why. You can also move only the subkeys and keep the primary on the phone. Signing and decrypting then use the card, and the edits that need the primary (User IDs, expiry, certifying other keys, Refresh self-signatures) keep working with the key's passphrase. ## Security keys - Thunderbird and other mail apps can decrypt and sign with a USB security key, not only over NFC (#36). - A key generated on a card now shows as your own key: avatar, an ON CARD pill, "Key pair on a security key", and a line in Key Details saying the primary key sits in the Signature slot (#43). - A card scanned before its public key was imported now pairs when you import the key, also when the Signature slot holds a subkey. Until then Key Details says what is missing (#71). - A key that does not open OpenPGP over NFC (the Nitrokey 3 among them) says so and points to USB, instead of failing with a bare error (#43). - The card scan screen stopped answering after Change PIN and back. Fixed (#79). ## Certify other people's keys (#79) Key Details of a public key has Certify…: pick the User IDs, your certifying key (on the phone or on a security key), the level (no claim, persona, casual or positive), an optional expiry, and Local only. Certify stays off until you confirm you compared the full fingerprint. Exportable certifications travel with the key when you share it. Local-only ones never leave the phone: no share, export, QR code, upload, backup or pairing carries them. Each User ID lists who certified it, with the certifier's short fingerprint, and you can revoke your own. Long lists show three, then Show all (#85). A trust signature (gpg's tsign) shows its amount and depth (#79). A certification from a key you do not hold has Look up, which finds the certifier's key on your key servers and checks the certification after import (#88). ## Trust levels (#75) New shields for each level, and a new Don't use level. PGPony asks before encrypting to or signing with a Don't use key, never picks one for a mail app, and turns the verify banner red for a signature from one. Key pairs you generate in PGPony now start at Ultimate; imported keys keep Unknown. ## Expiry and self-signatures (#86) - Changing the primary key's expiry set the same date on every subkey, expired ones included, which brought them back. Now it changes the User IDs only, with an option to also set it on subkeys that are still valid, and each subkey has its own Edit expiration. - Before anything is signed, a confirmation shows the current and new date and what gets re-signed, then asks for your screen lock when Protect destructive actions is on. - Expiry changes dropped part of the old self-signature: User IDs lost their feature flags, AEAD and key server preferences, and subkey bindings kept only their key flags. The new self-signature now carries everything forward. - Refresh self-signatures re-signs every User ID and subkey binding with SHA-256, keeping each expiry. It also brings back subkeys that were dropped for a SHA-1 binding. ## Signing subkeys (#82, #83) - Signing could pick an expired subkey. PGPony now signs only with a subkey that is valid now (bound, cross certified, not revoked, not expired), newest first, then the primary. - Add Subkey has written signing subkeys without a back-signature since 4.2.0, so gpg warned about them and PGPony's own check did not accept them. New subkeys get one. For an existing one, change its expiry and it is bound again with a back-signature; until then PGPony signs with the primary when the primary can sign. - Use for signing: on a key pair with two or more valid signing subkeys, Key Details lets you pick one or leave it on Automatic, which names the key it picks. Coming from OpenKeychain: PGPony signs with the newest valid signing subkey, where OpenKeychain used the older one. If others expect your signatures from a particular subkey, pick it under Use for signing. ## Import and re-import - Re-importing your own key edited in gpg applies the changes: newer self-signatures (#78), subkeys added in gpg (#82), and, as an opt-in, the secret keys from the file after a passphrase change in gpg (#78). The result says what was applied, or why nothing was. - The import preview lists each subkey it leaves out and why, and Key Details shows where each subkey's secret is: on this phone, offline, on a card, or not present (#82). - Offline primary keys (secret subkeys only, as gpg exports with --export-secret-subkeys) import, sign and decrypt. The edits that need the primary are hidden behind one banner that says why. - User IDs bound only with SHA-1 vanished on import or restore and the key showed as Unknown. They are kept now, with a Weak hash mark (#67). A key restored without its names needs one more restore or re-import. - A key's shown name follows its primary User ID, so a revoked first User ID no longer stops publishing. - GitHub lookup: enter a username, @name or profile link and PGPony fetches that user's OpenPGP keys, through Tor or your proxy when those are on (#81). - Import's QR, Server and GitHub now open the Exchange page, and Exchange's Key Server tab has GitHub (#92). ## Key Details and Keyring - Copy a subkey's key ID (#91), the primary key's Usage (#89), and the last key server check with server and date (#90). A network failure during that check is reported as an error, not as "not found". - Keyring > Select keys exports several public keys as one .asc file (#93). - The list behind a key count badge scrolls (#87). - Key selectors show the name and email with the short fingerprint. - Toggle and checkbox rows respond to a tap anywhere on the row (#79). ## App lock and duress PIN Settings > Security > Lock method: device unlock as before, or a PGPony PIN of 6 to 16 digits, with Unlock with fingerprint as an option. A Duress PIN erases PGPony's keys and data when entered, and Erase after wrong PINs (5, 10 or 20, off by default) does the same. Without it, repeated wrong PINs add a delay. PINs are stored as Argon2id hashes. Clear All Data now also removes the keys in Recently Deleted, mail app and SSH approvals, and every setting. ## Mail apps - When an address has no usable key, PGPony asks which keys to use instead of failing with "No PGPony key found" (#25). Keys the request already includes show ticked, with the address that includes them. FairEmail asks several times for one send; your picks are reused for 30 minutes for the same addresses. - A long passphrase duration ("Until I clear it" and others) was lost after a few minutes on Xiaomi phones, because the system stopped PGPony's mail app process. While a passphrase is held for mail apps, a notification now keeps it alive, with Clear to forget it. - Signed mail now names the hash its signature used (micalg) (#84). - The passphrase and card PIN prompts open with the field focused and the keyboard up (#59). ## Files and Quick Actions - With several files, the package screen offers Each file on its own: encrypt, encrypt and sign, or sign only with a .sig per file, then Save to a folder or Share all (#72). - Several encrypted files shared to PGPony decrypt one by one, each with its own signature result, instead of being encrypted again as a package (#72). - Saving a large file shows progress and can be cancelled, and a save that fails or is cancelled removes its partial file (#73). - Encrypting and signing a large file with an ML-DSA key ran out of memory. It streams now; a 2 GB file was checked both ways with GpgFrontend (#73). - ML-DSA keys made by sq signed with their certify-only primary, so every verifier rejected the signature. They sign with their signing subkey now (#67). - Decrypt results name the key and subkey that signed and the one that decrypted, as gpg's key IDs (#79). - A Quick Actions decrypt of an ML-DSA-signed file keeps its file name (#67). - Shared text holding a PGP block can be encrypted whole with Encrypt all of it (#58). ## Network - With Tor or a custom proxy on, host names are looked up through the proxy too. - The keys.pgpony.app onion mirror is off by default. A choice you already made is kept. - Further message and key import hardening from an internal review. ## Contributed fixes - The contact email lookup handles a contacts provider that leaves out a column (#97). - The French and Portuguese "keys need regenerating" message shows its count, so 0 no longer reads as one key (#99). - Test infrastructure (#94). ## Signed source Release tags and the commits on main are now signed with the norsehorse-dev SSH signing key. The README's Verify a release section has the key and the git commands to check a tag. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` a78977fe4b6c957cc7599389766a5df664f92a2e09133a171a1e3c9ad32ef059 ``` Content hash (for rebuilders; excludes signature, see docs/REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` 9c1010def9fc2f4daae6fb99f1528c2fee8c0179c6221182d5eae409f0e503b3 ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release, along with the armored release key (NorseHorse-release-key.asc) and PGPony-4.7.0-signing-keys.txt with the OpenPGP fingerprint and the APK signing certificate's SHA-256. Check the fingerprint against pgpony.app, keys.openpgp.org or keys.pgpony.app rather than trusting the copy in the release alone. - Oct 5, 2026 4.6.3# PGPony 4.6.3 Pairing with PGPony Desktop, and the bug fixes that were waiting for 4.7.0. 4.6.3 carries versionCode 463 and installs in place over 4.6.2. ## Pair with another device Settings and the Keyring menu have a new Pair with another device. It moves public keys, key pairs or a full backup between this phone and PGPony Desktop 3.0 or another phone on the same network. One device waits and shows a QR code and its address; the other scans the code or types the address. The
More…
joining device shows a six-digit code, and its user confirms the waiting device shows the same one, while the waiting device's user types the code from the joining screen. After that, either side can send. The receiving side picks what it wants and sees each key, read from the key itself, before anything is added. A key pair always travels under a passphrase: one that has none is protected with a transfer passphrase you choose for the trip. A backup restores with the recovery code the sending screen shows, and takes no trust levels or settings from the other device. Every item gets its own line with how it went: added on the other device, skipped there, or not imported and why, with the key's fingerprint so you can compare it with the other screen. Done ends the session and shows what was sent, received and skipped, with a button to open each key that arrived. The phone only pairs over Wi-Fi, Ethernet, tethering or USB, never over mobile data, and only with a device on the local network. Offline mode blocks pairing. Sending a key pair or a backup asks for your fingerprint or screen lock first, as exporting a private key does. Nothing is kept: leaving the screen ends the session and wipes its keys. ## Mail apps keep your passphrase for the time you chose (#15) A passphrase entered while decrypting in Thunderbird or another mail app stayed for exactly 5 minutes, whatever you set in Settings. The part of PGPony that answers mail apps runs in its own process and never saw your setting; the 4.6.1 fix for this did not reach it. The setting now lives where both parts of the app read it on every check. The passphrase prompt also says what it is for (sign, decrypt or SSH login) and how long PGPony keeps it, where it used to say "sign" and "5 minutes" every time. Settings no longer claims nothing is remembered when a mail app holds a passphrase, and Clear now reaches it. ## SSH agents with several keys (#68) PGPony remembered only one SSH key per app, so with two or more keys loaded in OkcAgent every approval undid the last one and git operations raised a stream of approval prompts. Each key is now approved once and stays approved. Settings > Connected apps lists every approved key with its own Remove. ## Post-quantum fixes - A message encrypted by an rPGP-based app (GpgFrontend, for one) to a PGPony ML-DSA-65 v6 key could not be decrypted. PGPony read the key ID from the wrong end of a v6 fingerprint. (#73) - Adding a User ID to, or revoking a subkey on, a passphrase-protected ML-DSA key always failed, even with the right passphrase. - Package mode can sign with an ML-DSA key; it used to say the key could not be unlocked. (#72) - Encrypting to a recipient PGPony cannot load now stops with a message naming that recipient. Before, some paths (package mode, the hardware key encrypt-and-sign, the mail app send through a hardware key) left that recipient out of the message without saying so. ## Other fixes - An image shared into PGPony (PNG, and some JPEG) landed in the signature field of Verify. A file now counts as a signature only when it is one. An encrypted .gpg or .pgp file whose recipients PGPony could not list opens to Decrypt instead of Encrypt. (#67) - The "tap the +" tip no longer flashes on the Keyring at every start. (#74) - Several freezes on slow storage and long key edits: adding a subkey, other Key Details edits and changing a passphrase run in the background; picking a file from a cloud provider, and saving or sharing a large encrypted or decrypted file, no longer block the screen. - Fixed a crash when PGPony was opened from a share before its screens were ready, a crash on picking a very large file to import as a key (now "too large to be a key"), and a crash on verifying a signature whose block was damaged (now reported as damaged). - Message handling hardening. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 3af5ca347c5e53331ab84793bba98140673f00a7f1f772cb365c8001fbeaf208 ``` Content hash (for rebuilders; excludes signature, see docs/REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` 1f81b818e9d84834a49bb57a0d8a470e7d842dcaa740814cd7ddbf89aec1cb74 ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. From this release on, every release also carries the armored release key (NorseHorse-release-key.asc) and PGPony-4.6.3-signing-keys.txt with the OpenPGP fingerprint and the APK signing certificate's SHA-256, and is published as an immutable release, so its assets can't be changed afterwards. Check the fingerprint against pgpony.app, keys.openpgp.org or keys.pgpony.app rather than trusting the copy in the release alone. (#77) - Sep 28, 2026 4.6.2# PGPony 4.6.2 Three new languages, Simplified Chinese, Ukrainian and Turkish, and the parts of the app that stayed in English whatever language you chose are now translated too. 4.6.2 carries versionCode 462 and installs in place over 4.6.1. ## New languages Simplified Chinese (简体中文), Ukrainian (Українська) and Turkish (Türkçe) are now in the language list in Settings and in Android's per-app language settings. A phone already set to one of them switches to it on its own.
More…
These translations are mostly machine-made. About a third of the Chinese strings reuse the wording of PGPony for iOS, which a Chinese-speaking tester translated, so both apps use the same terms for keys, signatures and passphrases. The rest of the Chinese, and all of the Ukrainian and Turkish, is machine translation. I checked every string for placeholders and plural forms, but I don't read these languages, so some wording will be wrong or stiff. Corrections are welcome in the PGPony-Translations repository on GitHub (github.com/norsehorse-dev/PGPony-Translations) or by email to NorseHorse@norsehor.se. Phones set to Traditional Chinese (Taiwan, Hong Kong, Macau) stay in English rather than getting Simplified text. ## Korean A volunteer is translating Korean. This release adds the strings finished so far, about 180 more, for roughly 650 of the app's strings. Korean is still not in the language list because much of the app is untranslated; a phone set to Korean already uses what is there and English for the rest. ## Text that stayed in English Some text was written straight into the code instead of the translation files, so every language showed it in English: about 80 labels, buttons and messages (the empty Keyring, the key access recovery dialog, parts of Exchange, Contacts, the hardware key screens and backup), and about 360 error messages from the encryption, hardware key, key store, backup and mail app code. All of it now comes from the translation files, in every language. Error messages are translated where they are shown, so the encryption code that raises them is unchanged, and a message from a library PGPony has no translation for still appears as it is. German, Spanish, French, Japanese, Portuguese (Brazil) and Russian also gain the 11 or 12 strings each was missing, among them the "Allow expired keys" setting, the expired key warnings and the question about restoring settings from a backup. ## Smaller fixes - An error that read "Decryption failed: Decryption failed: ..." now names the failure once. The same goes for encryption, signing and import errors. - Counts use real plural forms (keys found or linked, recipients, extra keys in an import), which matters in languages with more than two forms. - Dates on Key Details and the card screen use your language's date format, and file sizes use your phone's number format. - Key Details shows the trust level in your language. - On Android 8 to 12, error messages follow the language chosen in PGPony rather than the phone's language. ## A build check for translations Every build now compares the format arguments (%1$s, %2$d) of each translated string with the English one, and checks that plurals carry every form their language needs. A mismatch stops the build, so a translation mistake can no longer reach the app as a crash. The check only reads the string files and does not change the APK. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 856ab53741eac9154474a5e4ea8c728b82d4f4652d468f4ce5a083fc7b3cc743 ``` Content hash (for rebuilders; excludes signature, see docs/REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` 6c94aa270a854d6344d6fca678142969aa3015e914862efc271041254109ea25 ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Sep 26, 2026 4.6.1# PGPony 4.6.1 Fixes for the share menu and for the passphrase cache in mail apps, and memory tagging on phones that support it. 4.6.1 carries versionCode 461 and installs in place over 4.6.0. ## Post-quantum recipients in the share menu (#67) Encrypting a shared file or text to a composite ML-DSA key, or to a v4 key with an ML-KEM subkey, did not work from the share menu. With that key as the only recipient it failed with "No recipient keys in your keyring", even though the same key worked from the Encrypt screen. With other recipients selected as well, it was worse: the key was left out without a warning and the file was encrypted to everyone else, so that person could not
More…
open it. The share menu loaded recipients with a loader that cannot read these keys, while the Encrypt screen uses one that reaches their ML-KEM encryption subkey. The share menu now loads recipients the same way, and if any selected recipient still cannot be used it stops and names the key instead of encrypting without it. If you encrypted a file from the share menu to several people, one of them with an ML-DSA key or a v4 key with an ML-KEM subkey, that person may not be able to open it. Encrypt it again with 4.6.1. ## Importing a private key from the share menu (#67) Sharing a private key file or text to PGPony only offered to encrypt or sign it as text; only public keys were recognized as keys. A private key block now gets Import key, which opens it in the usual import preview, where the key pair and its fingerprint are shown before anything is added. ## Mail apps follow the passphrase cache duration (#15) Settings lets you keep a passphrase unlocked for 1 minute to 1 hour, until you clear it, or until the phone locks. A passphrase entered while decrypting in a mail app stayed for 5 minutes whatever was chosen. The part of PGPony that answers mail apps runs in its own background process, and that process read the setting once and kept the old value. It now reads the current setting every time, so mail apps, security key PINs and the app itself all follow the same duration. ## Memory tagging (#70) PGPony now asks for Arm Memory Tagging Extension (MTE) in asynchronous mode. Where MTE is available (GrapheneOS on supported Pixels, or Pixel 8 and later with MTE turned on in developer options), the system tags the app's native memory and stops the app on a use-after-free or out-of-bounds access instead of letting it run on corrupted memory. Other phones ignore the setting. Origin: Sami32 (#70). ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 681d13767d4ece6a79a5f2da095c2a3a1f5495ea0d8feb91737c6d89693ecbda ``` Content hash (for rebuilders; excludes signature, see docs/REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` 75fcea38ca8435f9348c1a1305cb023de3408f3f897fac9c1bb3423b0c5cd716 ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Sep 24, 2026 4.6.0# PGPony 4.6.0 SSH logins with your PGPony keys, one share dialog that works out what you shared, a round of key-server fixes, and security hardening from an internal review. 4.6.0 carries versionCode 460 and installs in place over 4.5.3. ## SSH with your PGPony keys (#68) PGPony now answers OpenKeychain's SSH authentication API, so an ssh-agent bridge can log you in with a key
More…
held in PGPony. The private key never leaves PGPony or your security key. - Key generation can add an authentication subkey (Ed25519, or RSA to match an RSA key), and you can add one to a key you already have. Key Detail has Copy SSH Public Key for a server's authorized_keys. - Ed25519, RSA (rsa-sha2-256 and rsa-sha2-512) and ECDSA P-256/384/521 authentication subkeys all work, including a classical one on a composite ML-DSA key. Smart cards sign through the card's authentication slot. - Only a dedicated authentication subkey is used. A subkey that can also sign or certify is not. - For Termux, PGPony links to a maintained OkcAgent fork that works with the stock okc-agents package. Settings and Key Detail both have "Set Up SSH in Termux" with the steps. ## Sharing to PGPony (#58) Sharing text to PGPony opens one dialog, and its options depend on what the text holds: Import or Import and encrypt for a key, Decrypt for an encrypted message, Verify for a signed-only message, and Encrypt, Sign or Encrypt and sign for plain text. When a PGP block sits inside other text, only the block is decrypted. ## Keys - A key's note shows as a label on its keyring row and under the Key Detail header. - Import a public key from a link. The key shows in the import preview with its fingerprint and the full source link before anything is added. - ML-DSA-87 with ML-KEM-1024 is a new post-quantum key type, and ML-KEM-768 with brainpoolP256r1 (the LibrePGP form GnuPG 2.5 uses) is in the Advanced group. Post-quantum options now say "Limited app support". - RSA subkeys can be added to composite ML-DSA keys. GnuPG and Thunderbird cannot read v6 certificates yet, so for them a separate v4 key is still the way. - ML-KEM subkeys on a classical key now show in Key Detail, and editing such a key (adding a subkey, changing a User ID, expiry or passphrase, revoking) no longer drops them. - A keyring row whose address is shared by other keys shows how many, and lists them. - When a post-quantum key signs a message encrypted to a classical-only recipient, PGPony asks whether to include the signature, since only PGPony can read it there. ## Key servers - Upload stays on the menu after the first upload, and shows when each server last got the key and whether each address is confirmed. - A key edited since it was published is marked as out of date, with an Update action. - Refreshing from a key server merges what the server has into your copy instead of replacing it, and your own key pairs keep your local User IDs and primary choice. - A lookup answer that is not a key (an error page, say) is now "no key found", not an import offer. - Offline mode hides the key-server menu items. ## Key Detail and Keyring - The avatar shortcut on a key pair sets that key for decrypting, and on a public key it adds the key to your current recipients. Each has its own one-time hint, and Reset tips brings both back (#63). - The Default Key picker is back to the right of its title with the star. - Deleting a public key says it moves to Recently Deleted for 14 days, as it already did (#58). - The import methods wrap onto a second line instead of squeezing their labels. ## Other apps (the OpenPGP provider) - Settings > Connected apps shows what each app can do, OpenPGP or SSH, and removes each separately. An app allowed for one gets nothing from the other, and an SSH app can use only the key you picked for it. Apps you had already connected keep OpenPGP access only, so an app that also uses SSH asks once more. - Composite ML-DSA signatures verify through the share Quick Action. ## Security hardening This release includes hardening from an internal security review: stricter checks on keys and key-server answers, tighter limits on untrusted input (message size and nesting, file names, archives), and tighter handling of other apps' access. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 0995431de506531682a17e0e3e0c06cb5dc9c90b1656b4f946c3112d71675dbf ``` Content hash (for rebuilders; excludes signature, see REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` bcd8bb459fc57614d4442a9c686fc1bfda22014952461c384201e737c7343787 ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Sep 22, 2026 4.5.3# PGPony 4.5.3 A bug-fix release for a device-specific key-storage failure. On some phones, PGPony would suddenly report that it could not export or use a key it clearly still listed, and mail apps talking to it through the OpenPGP provider failed the same way. This release moves key storage onto a more resilient foundation and, where the damage has already happened, says so plainly instead of showing a misleading error. 4.5.3 carries versionCode 448 and installs in place over 4.5.2.
More…
## Key storage that stops reading on some devices A few users hit a state where PGPony still showed their keys in the key list and the signing picker, but every operation that needed the actual key material failed: exporting the key, encrypting to yourself, signing, and the same operations from FairEmail, K-9 Mail, or Thunderbird through the OpenPGP provider. It affected every key at once regardless of type, and on one report a freshly generated key worked for a couple of days and then went unusable. It could not be reproduced on most hardware. The cause was the storage layer. Key metadata lives in a plain database, but the key material was kept in an encrypted store built on a deprecated Android security library. That library wraps its encryption key in the device's hardware keystore, keeps a separate keyset that can be regenerated, and was opened from two app processes at once. On certain builds, some realme and ColorOS devices and Android 16 among the reports, the keystore key or that keyset gets invalidated. When it does, the metadata survives but the key bytes can no longer be decrypted, so the key looks present while nothing that needs it works. Key material now lives in app-private files. Each key's bytes are encrypted with a per-key data key, and that data key is wrapped two ways: once under a stable hardware-keystore key, and, when the key has a passphrase, once under a key derived from that passphrase. Reads use the hardware wrap. If the OS invalidates the hardware key, a key that has a passphrase is recovered by unlocking it once, which re-establishes a working hardware wrap, so it survives the wipe instead of being lost. This also removes the regenerable-keyset and two-process problems that caused most reports. Existing keys migrate over automatically the first time they are read, and the old store is left in place untouched. A passphrase-less key has no second factor, so if the hardware key is wiped it cannot be recovered and PGPony will tell you to re-import it. Setting a passphrase on a key is what lets it survive this class of failure, so it's worth doing for any key you rely on. ## Signing files with an ML-DSA key An ML-DSA key could sign text but not files. A detached file signature failed with "No signing-capable key found in key ring," and signing a file while encrypting it produced no error but left the file unsigned, so it decrypted as merely encrypted. Text signing with the same key worked. The text paths were taught about these composite keys in 4.5.2 and the file paths were not, so file signing still went through the classical signer, which cannot see an ML-DSA signing key. Both file paths now sign through the composite signer, so a detached file signature and a signed-and-encrypted file from an ML-DSA key both work and verify. ## Verifying ML-DSA signatures on files and in mail apps The companion to the fix above. An ML-DSA (composite) signature verified fine on a text message opened in PGPony, but the same signature on a decrypted file, or on any message a mail app decrypted through the OpenPGP provider, showed as unsigned. The streaming decrypt path that files and the provider use only ran the classical BouncyCastle verifier, which cannot parse a composite signature packet, so it never saw the signature at all. The in-app text path had its own composite handling and the streaming path did not. The streaming path now detects a composite inline signature and verifies it against the stored composite public key, the same way text decryption already did. A signed-and-encrypted file from an ML-DSA key, and a message a mail app decrypts through PGPony, now report the signature and signer instead of coming up unsigned. Classical messages take the unchanged streaming path exactly as before. Note this is about PGPony reading composite signatures. A third-party tool that does not implement the composite ML-DSA algorithms still cannot verify them, and that is a limitation of that tool, not of the message. ## Signatures not verified in the Quick Action A signed, encrypted message opened through the share-target Quick Action came up unverified, while the same message verified fine when opened in the decrypt screen or as a file. The share-decrypt and file paths handed the decryptor the stored public keys to check the signature against; the Quick Action passed none, so it decrypted the message but had nothing to verify the signature with and reported it unsigned. All three Quick Action decrypt paths now pass the stored public keys, so a signed message verifies there the same as everywhere else. This was separate from the display issue in some mail apps, where an encrypted message that is signed inside shows no signature indicator. That reproduces with other OpenPGP providers too, so it is the mail app's own handling of inline-signed-and-encrypted mail, not PGPony withholding the signature. ## Comment header ignored the setting in mail apps The customizable "Comment:" line in armored output followed the setting only for in-app encryption. Anything encrypted through the OpenPGP provider (FairEmail, K-9, Thunderbird) always carried the default comment, whether the setting was turned off or set to custom text. The provider runs in a separate process that skips the startup step which loads that setting, so its copy stayed on the default. The provider now reads the setting before it builds armored output, so the comment matches what you chose there too. The blank line between the armor headers and the encoded body is not the comment and is not removable; it is required by the OpenPGP armor format. ## Signature banner now shows whether the signer key is confirmed When PGPony verified a signature it showed a plain green "Verified, Signed by ..." no matter whether the signer's key was one you had verified or an unconfirmed key sitting in your keyring. Since anyone can publish a key for any address, a valid signature from an unconfirmed key is a weaker statement than one from a key you have verified, and the banner did not say which it was. The status was already sent to mail apps (FairEmail shows "valid but not confirmed"), it just was not shown inside PGPony. The decrypt and file verification banner now reflects the signer key's trust level: a verified or ultimate key keeps the green "Verified", while an unknown or unverified signer key shows an amber "Signed, key not verified" instead. The signature is still cryptographically valid in both cases; the difference is whether you have confirmed the key belongs to who it claims. ## Expired keys are blocked from signing and encrypting An expired key could still be used to sign or to encrypt with no warning; only decrypting or verifying afterward flagged it. PGPony now refuses to sign with, or encrypt to, an expired key. The Encrypt screen shows which key has expired, and the operation stops with a message pointing to the new setting rather than silently producing output that the other side will reject. This applies both in the app and to sends made through the OpenPGP provider from a mail app, so an expired key is refused there too. For the occasional deliberate case, Settings has a new "Allow expired keys" toggle, off by default. With it on, expired keys work as before, and the screen still shows the expiry so it is never silent. The check is on the key's overall (primary) expiry. A finer per-subkey expiry warning is noted for later. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 85381b486459b97db61898759e1e9e9b9e6f3e6faf7d2d8bb040480762db16a1 ``` Content hash (for rebuilders; excludes signature, see REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` 3bccc3ccc10e28615cd9de9343ee176b26d9f5da2c9c023b3062d7c33e381a6b ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Sep 18, 2026 4.5.2# PGPony 4.5.2 A bug-fix release for the post-quantum key work from 4.4.0 and 4.5.0. The composite ML-DSA keys looked done but three things did not actually work end to end: signing an encrypted message, adding subkeys, and using these keys from other mail apps. All three are fixed here. 4.5.2 carries versionCode 447 and installs in place over 4.5.1. ## Signing an encrypted message
More…
Encrypt-and-sign with an ML-DSA-65 key produced a message with no signature in it, so the recipient saw an unverified origin even though the sender had signed. Signing on its own always worked, which is what made this easy to miss. The combined encrypt-and-sign path now attaches the signature the same way the sign-only path does, and decrypt verifies it, so a signed-and-encrypted message from a modern key shows a verified signature. ## Subkeys on ML-DSA keys Adding a subkey to an ML-DSA key failed before it started, on every subkey type, because the key could not be loaded into the form the add-subkey code expected. You can add subkeys to an ML-DSA key now: ML-KEM encryption subkeys, ML-DSA signing subkeys, and classical Ed25519 or X25519 subkeys. Added subkeys show in the key's Subkeys list with the right capability, and a passphrase re-protects them along with the rest of the key. ## Other apps (the OpenPGP provider) Mail apps that talk to PGPony through the OpenPGP API, such as FairEmail, K-9 Mail, and Thunderbird for Android, could not use a modern ML-DSA key at all: the key would not export to the app, and signing and sign-and-encrypt failed. Those paths went through a code path that cannot read these keys. Exporting the key, encrypting to it, signing, and sign-and-encrypt now all work with an ML-DSA key from an external mail app. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 0dd192d4a8768da2cd84df8b61a408f9e3a090252bdcf60b781f40b39235b019 ``` Content hash (for rebuilders; excludes signature, see REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` 346ecab9c7c05a0831b2c4e240767d3fa57c0f1827dcbfbde3c1fa831a705b0a ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Sep 16, 2026 4.5.0# PGPony 4.5.0 The post-quantum release. 4.5.0 makes ML-DSA and ML-KEM keys usable end to end, adds real key management on keys you already have, hardens the app, and clears a batch of tester reports from #36, #55, #58, and #62. 4.5.0 carries versionCode 444 and installs in place over 4.4.x. ## Post-quantum
More…
You can now generate a post-quantum-only key (composite ML-DSA), not just a classical key with a PQC subkey. Key generation can also produce a v4 ML-KEM-768+X25519 encryption key (algorithm 35) for interop with other implementations, and you can add post-quantum subkeys to a key you already own instead of starting over. A composite ML-DSA key can now carry more than one User ID, and it works as an encryption recipient through its ML-KEM subkey. When you encrypt to a mix of post-quantum and classical recipients, PGPony warns you that the message drops to classical security for everyone rather than doing it silently. ## Key management Key creation is more granular, so you choose what goes on the key instead of taking a fixed template. You can delete or revoke a subkey, and the delete dialog for a key pair now offers "revoke instead", since a revocation certificate cannot be made after the key is gone. Keys can be generated without an email address. You can point the app at your own key server repositories and use Web Key Directory, and a public key shared into PGPony can be used to encrypt straight away, not only imported. ## Security Settings has an offline-mode toggle that keeps the app from reaching the network. Destructive actions (deleting a key, removing a subkey, clearing all data) sit behind one switch that requires device authentication, on by default. The cipher paths had a hardening pass. ## Smartcard Decryption with a nistp521 secret key on a SmartPGP JavaCard now works. The Cipher DO for the card was written with short-form TLV lengths, which a 133-byte P-521 point overflows, and the KDF used a fixed curve OID. Both are fixed, and the other NIST curves are covered too. Confirmed on hardware by wreps8Owt (#62). ## Fixed Decrypting a file to an imported composite ML-KEM key failed on the file path while the same message pasted as text worked. The streaming decrypt never handed the imported composite key to the part that opens the ML-KEM subkey. It does now, with a regression test built from the reporter's own key and file. Reported by Umotas (#36). A message encrypted to several recipients including your own composite ML-KEM key failed to decrypt. That path is fixed. Adding a second email to a key set the new address as primary once the key was uploaded, even when it was not marked primary. A fresh key's first User ID is only implicitly primary, so the newer self-signature won on the server. Adding a non-primary User ID now pins the original as primary explicitly. Reported by Bart. A truncated or incomplete PGP message showed a raw range error instead of a clear "incomplete message". A post-quantum-only key could not produce a QR code, even a multipart one. A key's primary expiry could show a stale "Never" next to a live subkey date. Several Google Play stability reports from the September vitals review are addressed. ## Improved The encrypt and decrypt key pickers show the email under the name, so two keys with the same name are easy to tell apart. Encrypt and decrypt gained a subkey selector when a key offers more than one target. Key algorithm and curve labels are detected correctly, so ML-KEM-1024, the NIST and brainpool curves, and RSA sizes read right. The key-generation publish prompt is clearer, with an offline case and a pgpony.app opt-out, and there is an onboarding toggle to drop the PGPony armor comment. The unlock-signing-key dialog opens the keyboard on its own. The v5 LibrePGP post-quantum interop is deemphasized in the UI in favor of the standard scheme. Importing or sharing a key tolerates extra surrounding text. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 9842e68809d115bf15c7f1c9af67a0cdc941399c15ebc646175535fedbb3766e ``` Content hash (for rebuilders; excludes signature, see REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` 08f02c6be12da1e11f971ad64ec20400cb1cdf497a0114e69790068ba2f6600a ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Sep 1, 2026 4.4.1# PGPony 4.4.1 A fixes-only release addressing four reports against 4.4.0's post-quantum support, raised on #36 (Umotas) and #55 (elnardosa). 4.4.1 carries versionCode 434 and installs in place over 4.4.0. ## Fixed Encrypted files were much larger than they should be. A v6 (post-quantum)
More…
encrypted file used a 64-byte AEAD chunk, so the OCB integrity layer added a 16-byte authentication tag for every 64 bytes of data, about a 25% size increase on top of the file. The chunk size is now 64 KiB, which drops that overhead to a fraction of a percent, so an encrypted file lands close to its compressed size. The file was already being compressed; the tags were the whole difference. Existing files still decrypt unchanged. Reported with packet dumps by Umotas (#36). Encrypting to a composite ML-DSA key failed. A v6 ML-DSA signing key carries an ML-KEM encryption subkey, so it can receive encrypted messages, but selecting it as the only recipient failed with a misleading "no recipients" error. The key could not be read through the normal path because the library does not parse its composite primary, so it was dropped before its encryption subkey was reached. That subkey is now lifted out and used, so a composite ML-DSA key works as an encryption recipient, and the message shown when a key genuinely has no encryption subkey is clearer. Reported by Umotas (#36). ML-KEM-1024 keys were shown as ML-KEM-768. In LibrePGP the two share one algorithm number and differ only by curve, so the label defaulted to 768. The key material was correct all along; only the label was wrong. Key detection now reads the curve and reports the right level. Reported by elnardosa (#55). An imported RSA 8192 key was shown as RSA 4096. Key-size detection keyed off the algorithm number, which does not carry the modulus size, and capped the label at 4096. It now reads the actual modulus size, so RSA 3072, 4096, and 8192 are each labeled correctly. Reported by elnardosa (#55). ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 55075c11f90833dae75b66162c0adcd636eec223a8fc98d2c22408209335e257 ``` Content hash (for rebuilders; excludes signature, see REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` 2707269a69c39650ea99ced72077a68d5fbf18fcd6df0253f5784d581975cead ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Aug 28, 2026 4.4.0# PGPony 4.4.0 The post-quantum signatures release. 4.4.0 adds the signature half of RFC 9980 to match the encryption half PGPony has shipped since the 4.0 line, reworks how a signing key is chosen when an address carries more than one, adds Tor stream isolation, and clears a batch of key-management and interface reports from the candidate cycle. 4.4.0 carries versionCode 433 and installs in place over the 4.3.x line; this is the final.
More…
## Added Composite ML-DSA signatures (RFC 9980). PGPony now generates, signs with, verifies, imports, and labels composite ML-DSA-65+Ed25519 signing keys (RFC 9980 signature ID 30, the MUST), the post-quantum counterpart to the composite ML-KEM encryption keys already supported. Signatures are produced and verified over both messages and certifications, and round-trip against GnuPG 2.5.x in both directions. Requested on the core repo (PGPonyCore #1). Choose the signing key per send. When a mail app hands PGPony an outgoing message to sign or encrypt, the first key picked for that account was remembered and never offered again, so a second key on the same address was unreachable. PGPony now remembers the choice per address, offers a "Sign with a different key" control on the passphrase prompt, and has an "ask which key to sign with" setting for people who switch every send. Reported by RandomNam3, tested against FairEmail with two keys on one address (#51). Tor stream isolation. The proxy section gains an optional SOCKS5 username and password for Orbot and Custom, so distinct credential pairs land on distinct Tor circuits. Every outbound path routes through the one shared client, the connection fails closed when the proxy is unreachable rather than falling back to a direct request, and the target hostname resolves at the proxy, not on device. Off by default, so no existing setup changes on update. Offline switch. A setting that turns off every online key lookup, for people who want the app to make no network requests at all. The signer lookup on a decrypted message drops its online affordance while it is on. A text-encrypt armor toggle, contact identities, and composite-key passphrase protection carried through decrypt and export. ## Changed The decrypted-message view names the key that actually decrypted, so a passphraseless key that silently matches can no longer be mistaken for the one shown in the picker. The Decrypt tab icon fills with a solid open padlock when selected, like every other tab, and the Keyring tab returns to its list from the Key Detail, NFC, and Recently Deleted screens instead of stranding you there. The doubled inset band above the tab bar is gone. All reported by CertainBot (#45). The message search box keeps its placeholder to a single line so the field no longer looks oversized. ## Fixed Key generation no longer produces a duplicate entry or freezes partway (#48). A password (symmetric) encrypted message showed a recipient count and a "can decrypt" list that do not apply to passphrase encryption, and the same "Password protected" state could bleed onto a following signed message. The result now reads the true per-operation state: password messages show a password note and no recipients, and a signed message is never mislabeled. Reported by CertainBot (#53). Decrypting a password message no longer shows the "no signature, origin unverified" banner, which says nothing useful about a message sealed to a passphrase rather than sent from a key. A password message that is also signed still shows its verification result. From CertainBot (#53). The recipient picker sheet scrolls its own list instead of dragging the whole sheet down. Reported by CertainBot (#53). The per-address signing key now reaches the signer across the provider's separate process, so the chosen key is the one that actually signs (#51). A provider hang on certain operations is resolved. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 3c10b9ea225a748d87dacbf5a233e20bdf456b4cfc2313ba700e6e06e10ae411 ``` Content hash (for rebuilders; excludes signature, see REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` c7f352eefd3253d2dec97cf591f2a8d9546471bfcf0727835d7de1ef7f1255fd ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Aug 23, 2026 4.3.2# PGPony 4.3.2 ## Passphrase encryption now opens in GnuPG on Linux by default Password-protected files and messages are now encrypted with a key-derivation function (iterated-salted SHA-256, S2K type 3) that every version of GnuPG can read. Earlier builds defaulted to Argon2id, which needs GnuPG 2.4 or newer built against a recent libgcrypt. On Linux machines without that, gpg reported "unknown S2K mode 4" and could not open the file even though nothing was wrong with it. Thanks to darkvegas for the report and the exact gpg output. Argon2id is still available as a Settings toggle, "Stronger passphrase protection". It is off by default; turn it on if your recipients are all on GnuPG 2.4 or newer and you want the memory-hard key derivation. Files you already encrypted with Argon2 still decrypt normally. ## Verify this build
More…
Whole-file SHA-256 (is this download the published file): ``` ffe915922a64dddd000ba6e5373fb0bed07a6acb19cca2bc16527c3618f9d2d8 ``` Content hash (for rebuilders; excludes signature, see REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` 75eb5635082757b54a31e2a5c6b5e7b6da0e11d505390fac9269d4a2795237b2 ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Aug 21, 2026 4.3.1# PGPony 4.3.1 A small follow-up to 4.3.0, fixing two issues CertainBot found in the 4.3.0 release and cleaning up the English interface copy. ## Fixed The Trust Level sheet opens fully expanded. It was stopping at its half-height position, so all four levels only showed after you dragged it up. Now every level is visible as soon as it opens.
More…
Recently Deleted is reachable from the Keyring. Deleted keys go to a recycle bin that 4.3.0 only exposed in Settings, which is not where you look after deleting a key. The Keyring's overflow menu (the three-dot menu, top right) now opens it directly. It is still in Settings too. Both reported by CertainBot (#44). ## Changed Reworked the English interface copy to drop the em dashes, so error messages, help text, and labels read consistently. No wording meaning changed. Other languages are unaffected. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` f09e1577d5c20b0514980063d445d8d184ce26980dd59a3e60bf0647453175e5 ``` Content hash (for rebuilders; excludes signature, see REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` d6006d76f6779c4350f21e5e166eb2cdc5b1e11021f9b964b6b2d12d40eb8715 ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Aug 20, 2026 4.3.0# PGPony 4.3.0 The key-security release. 4.3.0 fills in the key-management and session work deferred from 4.2.0, adds full GnuPG composite-key interoperability, and ships a seventh language. It is the largest release since the 4.0 line. Every build in the 4.3.0 candidate cycle carried versionCode 430 and installed in place; this is the final.
More…
## Added Key recycle bin. Deleting a key now soft-deletes it. Deleted keys move to Keys, then Recently Deleted, where you can restore them or purge them for good, and they auto-purge after 14 days. The delete sheet also shows whether the key is in a backup before you confirm, so a delete is no longer a one-way door. Requested by AraafRoyall (#36). Session policy. A new "until the phone locks" option ends a passphrase session on device lock rather than on a timer, and the provider passphrase cache, the card PIN cache, and the in-app prompts now answer to one policy instead of three that could disagree. Changing a key's passphrase clears its cached entry at once. GnuPG composite-key interoperability. PGPony imports, labels, and decrypts composite ML-KEM keys produced by GnuPG 2.5.x and GPG4WIN, including the brainpoolP384r1 variant, and can export a composite secret key in GnuPG's native format so it imports cleanly into GPG4WIN. A "GnuPG-compatible format" toggle on the private-key export sheet drives it. Reported by homehsu (#2). Animated QR for large keys. A post-quantum key does not fit in one QR symbol, so it is split across frames that now rotate on their own, with play/pause and manual step controls, on both the Key Detail and Exchange screens. Requested and scanner-tested by CertainBot (#37). Verify a signed-only file. A file that was signed but not encrypted (the form Thunderbird saves for a signed plain-text message) is now verified in place instead of failing with "not encrypted". Raised by CertainBot. Zip output. File and bundle encryption can wrap the ciphertext in a .zip for transport over channels that mangle .gpg or .asc attachments, and decryption accepts a zip containing a PGP message. Requested by AraafRoyall (#31). Editable key notations, a signing-key picker for keys with more than one signing subkey, a default sharing method, a per-key last-backed-up indicator, an opt-in update check for sideloaded builds that only notifies and links (it downloads and installs nothing, and is off on F-Droid), and a link to ScrubPony under More from NorseHorse. Russian. PGPony is now available in Russian, its seventh language. ## Changed Change a key's passphrase, set one on a key that had none, or remove it, from Key Detail. Requested by AraafRoyall (#26). The trust marks were unified into one shield ladder across the app, and the Key Detail actions were reorganized into clearer menus. Both from AraafRoyall (#24, #36). Switching languages is now seamless. The change lands in place without the black flash and without dropping you back to the top of Settings. The encrypted-bundle result sheet is split into a Send as email block and a Send as file block, so the Wrap in .zip toggle plainly governs the file and not the email. From AraafRoyall's retest of #31. The Bouncy Castle version shown on the About, FAQ, and security-info screens now reads 1.85, matching the library the app has actually used since 4.0.0. Reported and fixed by White-Sun-08 (#42). ## Fixed WKD key import re-armors correctly, so a key served as ASCII armor is no longer double-wrapped. Reported by ThePharaohArt (#41). A key deleted or a trust level changed from Key Detail now updates the Keyring immediately instead of after an app restart. Found by CertainBot. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 6b534dc4f96fd014d8475e3a05543f30aca07c14358537494a2fc07dd73dd61f ``` Content hash (for rebuilders; excludes signature, see REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` cbb23ff8021f47604ebced73969b888a49979fbf5bb7461e0f0faac88f943504 ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Aug 16, 2026 4.2.1# PGPony 4.2.1 A point release fixing one bug in the multiple-identities feature that shipped in 4.2.0. ## Fixed Encrypting to a key by one of its additional identities now works. 4.2.0 added multiple identities per key, but a mail client resolves a recipient address through the OpenPGP provider, and that lookup matched only a key's
More…
primary identity. A message addressed to a secondary identity found no key, so the client would not offer to encrypt it. The provider now matches any identity on the key, across all three places it resolves an address: offering encryption, performing it, and reporting Autocrypt status. Reported by bluemle with v6 ML-KEM-1024 keys. In-app encryption was not affected, since the recipient picker selects a key directly rather than by typing an address. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` a6db202812b5fc30ea78cad29ff5eedda81bc4cebc7edb1dbc1979852aa6764f ``` Content hash (for rebuilders; excludes signature, see REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` afb0fd16cb1beef6c98a059d26013e98d060695c40d6fcb25126cf2495f1d390 ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Aug 14, 2026 4.2.0# PGPony 4.2.0 The largest release since 4.0.0, shaped over six release candidates by the people in the issue tracker. Thank you to everyone who tested, reported, and retested. ## Post-quantum - The ML-KEM 1024 hybrid suite joins 768, interoperating with GnuPG 2.5.x in both directions (#1). The 1024 suite pairs ML-KEM with X448 inside
More…
the composite key. - File decryption with composite (v5/v6 PQC) keys is fixed. File decrypt used a separate code path that did not understand composite keys, so files encrypted to them would not open at all (#33). ## If you generated a 768 key before 4.2.0 Early 768 composite keys carry an encoding gpg cannot encrypt to. The keyring shows a notice on affected keys and the app will suggest regenerating them. Keys generated in 4.2.0 or later are not affected. ## Large files and bundles Encryption and decryption now stream from disk end to end. A file or bundle is never held in memory whole, at any size, in any of the ways content enters the app: File mode, Bundle mode, or sharing from another app (#32, and the remaining large-file case of #33). Very large encrypted .eml files, which previously could not be decrypted at all past a few MB, decrypt now. Practical note: mail servers refuse attachments far below these sizes; a very large bundle travels as a file, not as email. ## Key management - Multiple identities (user IDs) per key, with add and revoke (#29). - Subkeys are displayed per key, and new subkeys can be added (#25). - Per-key fallback decryption keys: older keys can be enabled, in your order, as fallbacks for a newer key, with an optional strict mode that disables the compatibility net (#34). - Per-key signing defaults: choose which key signs on behalf of another for PQC recipients, classical recipients, and sign-only, so pre-v6 recipients can verify your mail while your primary key stays modern (#34, #22). - Change of import verification: the import preview shows the complete fingerprint in standard four-character groups (#35). ## Mail client interoperability Clients without v6/composite support (OpenKeychain, and K-9 for import) cannot read messages addressed to composite keys. The signing defaults above exist for exactly this. When a signing substitution is active and your own key is among the recipients, encrypt-to-self follows the substitute key, so a Thunderbird sent-folder copy stays readable and pre-v6 recipients receive mail they can open (#34). Thunderbird 21.1+ handles v6 directly. ## Safeguards After a tester permanently lost three keys, deletion got serious friction. Deleting a key pair offers a backup first, requires an explicit acknowledgement, and asks for biometric or device credential whenever the device supports it (#21, #36). Clear All Data lists every key it will destroy, requires two acknowledgements, a typed confirmation word, a five-second countdown, and biometric, then resets the app to first-run like a fresh install (#16). ## Settings and UI - Settings reorganized into category pages. - Passphrase cache duration is configurable: 1 minute to 1 hour, or until cleared (#15). - Font scaling fixes: key creation and other sheets are fully usable at large font sizes (#23). - Shared-file encryption results have a proper Save button and cleaner layout (#13), save confirmations show in green, and assorted small fixes from the RC cycle (refresh indicator, biometric lock switch state after onboarding). - Localization pass across German, Spanish, French, Japanese, and Brazilian Portuguese. ## iOS Feature parity with this release lands in PGPony iOS 8.2.0. ## Verify this build Whole-file SHA-256 (is this download the published file): ``` 59a0aa492982072d81c2ccd706d5d7096758c999a7ad065354e191b126563e2a ``` Content hash (for rebuilders; excludes signature, see REPRODUCIBLE_BUILDS_PLAYBOOK.md): ``` eae3f95d80391cf73779d58ebb435a407f07efb9ade102eede5e67c2720daced ``` The APK is signed with the NorseHorse release key (A0CBC8F65AACE56F1C5B767753F9798E4919DE62); the detached signature is attached to this release. - Aug 3, 2026 4.1.1PGPony 4.1.1 One fix, promised on issue #23 and shipped as its own patch rather than waiting for 4.2.0. Creating a key was impossible at a large display or font size. The onboarding slides could not scroll: their content is centered, so once a slide grew taller than the screen it clipped at both ends, and the button that creates your first key sat below the screen edge with no way to reach it. A fresh install at those settings had no route to a key at all. Reported by Nikon6302, whose screen recording named the surface exactly. The same missing scroll turned up in two more places once every screen without a scroll container was audited. The bundle encryption result sheet could push its Done button off the bottom at a large font scale, and the biometric lock screen could in principle do the same to Unlock, which would seal the whole app. All three now scroll, using the same fix the key generation form received in 4.1.0. Nothing moves at default display settings; the scroll only engages when content no longer fits the screen. versionCode is 411 and upgrades in place from 4.1.0 with no reinstall and no keyring loss.
More…
Verifying this build gpg --verify PGPony-4.1.1-foss.apk.asc PGPony-4.1.1-foss.apk shasum -a 256 PGPony-4.1.1-foss.apk SHA-256 of the published APK (PGPony-4.1.1-foss.apk, the foss flavor, signed with the same certificate as every release): 15e9d5052dfcbc8fd5ee6a59783f2f3e4b2c730822ac9553bdb596917a214bd3 The detached signature is made with A0CB C8F6 5AAC E56F 1C5B 7677 53F9 798E 4919 DE62. Check the fingerprint, not just that gpg reports a good signature. The APK signing certificate is 446bf9e621222a40c66cd2476e1a97105ccb2a9b16a01a91c1c7eb90765b50dc. Reproducible builds This release was checked by building tag v4.1.1 twice from clean clones, on isolated Gradle homes, and comparing the results. The unsigned APK built from v4.1.1 has SHA-256: e7853f0a04db9d7e17763add5f045b1eafe8cdeaaf08a461e094386583f9a4aa Anyone can reproduce it: clone the tag, build :app:assembleFossRelease with no signing configuration, and compare. That number is not the same as the hash of the published APK, and should not be. Signing appends a block to the file, so the download you verify with shasum above will hash to something else. The unsigned number is for people rebuilding from source; the signed one is for people checking a download. - Aug 1, 2026 4.1.0Hardware keys over USB, multi-part QR for large keys, and the Samsung key-generation blocker fixed. Twelve reported issues closed. versionCode is 410, unchanged from the release candidates, so this upgrades in place from any 4.1.0-rc build with no reinstall. Hardware keys over USB and OTG Plug an OpenPGP card into a USB-C or OTG port and sign, decrypt, change its PIN or read its details over the cable. NFC is unchanged, and PGPony picks whichever link is usable, preferring a key you have already plugged in. Implemented as a CCID transport behind the same CardTransport interface the NFC path uses, so the protocol layer did not change at all. No vendor filtering: any class 0x0B reader is accepted, the same posture NFC has always had. Validated on a non-Yubico FIDO2 security key reporting SHORT_AND_EXTENDED_APDU, maxApdu=2334, including PIN verify and a full decrypt over the wire.
More…
Key generation on Samsung The Generate Key sheet had no scroll container, so anything taller than the viewport was clipped. It fit with room to spare on Roboto and overflowed on One UI, whose system font is wider. Affected users could not create a key at all, with no workaround, and had not been able to since 4.0.0. Fixed, along with an audit of every other bottom sheet in the app for the same missing inset and scroll treatment. Large bundles decrypt properly A bundle over 4 MB decrypted to a single unusable file. Above that threshold the plaintext streams to disk rather than being held in memory, and the streamed path never attempted to read the bundle structure, so what you got was the raw container written out whole. Bundle contents are now extracted to disk and listed individually at any size. Peak memory is one 64 KB buffer plus a bounded text body, so a dozen large photos costs the same as three small ones. Reported by AraafRoyall, who supplied the file sizes that made it findable. Multi-part QR A public key too large for a single QR code is split across up to 16 frames, and the scanner collects them in any order with a running count of what is still missing. Out-of-order scans and switching keys mid-scan are both handled. This is PGPony to PGPony: the frame format is ours and other QR readers cannot reassemble a split key. A key that fits in one code still produces an ordinary QR that anything can read. Mail clients The remaining crash on the OpenPGP API boundary is fixed, and that path now has its own test suite that reproduces the failure with no mail account involved, so it cannot regress silently the way it did in 4.0.4. Covers FairEmail, K-9 and Thunderbird equally. Also fixed: a bundle shared as .eml failed to decrypt outright when the sender's Autocrypt header was large. Found by writing the test rather than by a report. Smaller, and all reported Passphrase fields are published to Android's autofill service, so password managers can offer to fill them Your security key no longer wakes Yubico Authenticator when left resting on the phone after an operation The share sheet offers one PGPony entry instead of two Sharing a file in to encrypt it now offers Save as well as Share, on every result screen in the share flow The keyring is grouped into My Keys, Contacts and Public Keys, and a card-backed key now appears under My Keys instead of among other people's The Decrypt tab no longer stalls on paste with a large keyring, and long results are bounded with an Open full text button Bundle attachment lists collapse past 8 files so the recipients and the Encrypt button stay reachable Revocation certificates are cached at key generation again. That had silently done nothing since 4.0.3 Navigation labels no longer truncate to "Keyrin" and "Encryp" on One UI Hidden recipient messages a software key can open no longer prompt for a card Not in this release ML-KEM-1024 is not here. It exists only paired with X448 at IETF code point 36, so there is no 1024 with X25519 that could have shipped sooner. It is the reason 4.2.0 exists. Verifying this build sha256sum PGPony-4.1.0.apk gpg --verify PGPony-4.1.0.apk.asc PGPony-4.1.0.apk The APK signing certificate is 446bf9e621222a40c66cd2476e1a97105ccb2a9b16a01a91c1c7eb90765b50dc. F-Droid builds are signed by F-Droid with its own key and will not install over a build from here, or the other way round.