justinwongcn/moonpgp/api does not have a README file

    DecryptResult

    pub(all) enum DecryptResult {
    Data(Bytes)
    Verified(Bytes)
    SignatureError(Bytes)
    } derive(
    Debug
    )

    Outcome of a combined decrypt+verify: data plus signature status.

    DecryptionBuilder

    pub struct DecryptionBuilder {
    // private fields
    }

    Builder for decryption.

    DecryptionBuilder::decryption_key

    DecryptionBuilder::finish

    fn DecryptionBuilder::finish(self : DecryptionBuilder) -> ((String) -> DecryptResult raise)

    DecryptionBuilder::max_decompressed

    fn DecryptionBuilder::max_decompressed(self : DecryptionBuilder, limit : Int) -> DecryptionBuilder

    Override the decompressed-payload ceiling (M4; default 512 MiB).

    DecryptionBuilder::password

    fn DecryptionBuilder::password(self : DecryptionBuilder, pass : String) -> DecryptionBuilder

    DecryptionBuilder::verification_key

    fn DecryptionBuilder::verification_key(self : DecryptionBuilder, key : PublicKey) -> DecryptionBuilder

    EncryptionBuilder

    pub struct EncryptionBuilder {
    // private fields
    }

    Builder for encryption. Fields are private; instances are created via Pgp::encryption and evolve through the chain methods.

    EncryptionBuilder::compress

    Compress the payload before encryption (ZIP or ZLIB; M4). Off by default — the historical behavior of this library — and only honored by the encryption entry points.

    EncryptionBuilder::file_name

    fn EncryptionBuilder::file_name(self : EncryptionBuilder, name : String) -> EncryptionBuilder

    EncryptionBuilder::finish

    fn EncryptionBuilder::finish(self : EncryptionBuilder) -> ((BytesView) -> String raise)

    Finish the builder: at least one password or recipient is required. Returns a closure that encrypts arbitrary payloads with this setup.

    EncryptionBuilder::password

    fn EncryptionBuilder::password(self : EncryptionBuilder, pass : String) -> EncryptionBuilder

    EncryptionBuilder::password_v6

    fn EncryptionBuilder::password_v6(self : EncryptionBuilder, pass : String, aead? :
    AeadMode
    , argon2? : Bool, passes? : Int, parallelism? : Int, memory_exp? : Int) -> EncryptionBuilder

    Add a passphrase recipient in the RFC 9580 v6 shape (v6 SKESK + v2 SEIPD; task 3): Argon2id S2K by default — set argon2=false for the cheaper iterated+salted SHA-256. Cannot be combined with password (v4 shape) in one message.

    EncryptionBuilder::recipient

    EncryptionBuilder::sign_with

    KeyGenBuilder

    pub struct KeyGenBuilder {
    // private fields
    }

    Builder for key generation.

    KeyGenBuilder::add_user_id

    fn KeyGenBuilder::add_user_id(self : KeyGenBuilder, user_id : String) -> KeyGenBuilder

    KeyGenBuilder::expires

    fn KeyGenBuilder::expires(self : KeyGenBuilder, seconds : Int64) -> KeyGenBuilder

    Expire the generated key after seconds (Key Expiration Time, RFC 9580 §5.2.3.6; counts from the key's creation). set_expiry on the finished key extends or clears it later.

    KeyGenBuilder::generate

    fn KeyGenBuilder::generate(self : KeyGenBuilder) -> PrivateKey raise

    KeyGenBuilder::rsa_bits

    fn KeyGenBuilder::rsa_bits(self : KeyGenBuilder, bits : Int) -> KeyGenBuilder

    KeyRing

    pub struct KeyRing {
    // private fields
    } derive(
    Debug
    )

    A collection of public and private keys with id lookup, mirroring the gopenpgp KeyRing role.

    KeyRing::add_private

    fn KeyRing::add_private(self : KeyRing, key : PrivateKey) -> Unit

    Add a private key (available to decryption lookups).

    KeyRing::add_public

    fn KeyRing::add_public(self : KeyRing, key : PublicKey) -> Unit

    Add a public key (available to encryption/verification lookups).

    KeyRing::find_decryption_key

    fn KeyRing::find_decryption_key(self : KeyRing, key_id : BytesView) ->
    SecretKeyPacket
    ? raise

    Find the unlocked private key packet matching a PKESK key id. Deliberately NOT lifecycle-gated: decrypting mail that arrived before a key expired must keep working (mirrors gopenpgp, whose decryption path does not check expiry either).

    KeyRing::find_encryption_key

    fn KeyRing::find_encryption_key(self : KeyRing, key_id : BytesView, now? : Int64) ->
    PublicKeyPacket
    ? raise

    Find an encryption-capable public key packet by 8-octet key id that is still usable at now (lifecycle-checked: revocation, key flags and expiry — a key without key flags counts as capable; now = 0 skips the time checks). All public-key algorithms participate; errors from key-id computation propagate (F15): the keys were parsed on the way in, so a failure here is an invariant violation, not a lookup miss.

    KeyRing::find_verification_key

    fn KeyRing::find_verification_key(self : KeyRing, key_id : BytesView, now? : Int64) -> PublicKey? raise

    Find a transferable key that can verify a signature from key_id and is still usable at now (revocation, sign/certify flags, expiry).

    KeyRing::new

    fn KeyRing::new() -> KeyRing

    Create an empty key ring.

    KeyRing::private_count

    fn KeyRing::private_count(self : KeyRing) -> Int

    Number of private keys in the ring.

    KeyRing::public_count

    fn KeyRing::public_count(self : KeyRing) -> Int

    Number of public keys in the ring.

    KeyRing::to_repr

    Pgp

    pub struct Pgp {
    }

    Top-level facade for the builder API. Stateless — every operation is configured through one of the three builders below.

    Pgp::decryption

    fn Pgp::decryption(_self : Pgp) -> DecryptionBuilder

    Start building a decryption (private keys and optional verifiers).

    Pgp::encryption

    fn Pgp::encryption(_self : Pgp) -> EncryptionBuilder

    Start building an encryption (password or public-key recipients). This is the recommended entry point for new code: chain .password, .password_v6, .recipient, .sign_with, .file_name and .compress, then finish returns a reusable sealing closure.

    Example

    test "builder chain seals a payload" {
    let seal = @api.pgp()
    .encryption()
    .password("hunter2")
    .file_name("msg.txt")
    .finish()
    let armored = seal(b"payload")
    inspect(armored.has_prefix("-----BEGIN PGP MESSAGE-----"), content="true")
    }

    Pgp::key_generation

    fn Pgp::key_generation(_self : Pgp) -> KeyGenBuilder

    Start building a key generation (RSA by default; Ed25519 via generate_ed25519_key).

    PrivateKey

    An OpenPGP transferable private key: v4 RSA primary key, one User ID with its self-certification, and an RSA encryption subkey with its binding signature. Fields are read-only from outside the package — obtain keys through generate_key / from_armored / from_bytes and mutate them through lock / unlock so the cross-field invariants hold.

    PrivateKey::add_encryption_subkey

    fn PrivateKey::add_encryption_subkey(self : PrivateKey, created? : Int) -> PrivateKey raise

    Generate a fresh encryption subkey (Curve25519Legacy ECDH on a v4 key, native X25519 on a v6 one) and bind it to this key — the rotation story for an expiring or compromised encryption subkey. The key must be unlocked. Wire order places the new subkey last, which is the one encryption_key prefers.

    PrivateKey::add_signing_subkey

    fn PrivateKey::add_signing_subkey(self : PrivateKey, created? : Int) -> PrivateKey raise

    Generate a fresh signing subkey (EdDSA legacy on a v4 key, native Ed25519 on a v6 one) and bind it with the cross-certification gpg requires (RFC 9580 §5.2.3.26) — the rotation story for a signing subkey. The key must be unlocked.

    PrivateKey::add_user_id

    fn PrivateKey::add_user_id(self : PrivateKey, user_id : String, created? : Int) -> PrivateKey raise

    Return a copy of key with a new User ID certified by the primary key — the "I also answer to this address" operation. The new certification inherits the key flags of the key-level self-signature so capability statements stay consistent across User IDs. Re-certifying an existing User ID replaces its binding outright (the same last-certification-wins rule import applies), which is how a formerly revoked identity becomes usable again. The key must be unlocked.

    PrivateKey::apply_revocation_certificate

    fn PrivateKey::apply_revocation_certificate(self : PrivateKey, armored : String) -> PrivateKey raise

    Parse an armored standalone revocation certificate, check it is a primary-key revocation that cryptographically verifies over this key, and return a copy with it appended. Anything else (wrong armor type, a non-revocation signature, a signature for another key) is an error — an invalid revocation must not be able to disable a key.

    PrivateKey::can_encrypt

    fn PrivateKey::can_encrypt(self : PrivateKey, now : Int64) -> Bool

    See PublicKey::can_encrypt. Delegates to the public half.

    PrivateKey::can_verify

    fn PrivateKey::can_verify(self : PrivateKey, now : Int64) -> Bool

    See PublicKey::can_verify. Delegates to the public half.

    PrivateKey::fingerprint

    fn PrivateKey::fingerprint(self : PrivateKey) -> Bytes raise

    20-octet v4 fingerprint of the primary key.

    PrivateKey::from_armored

    fn PrivateKey::from_armored(text : String) -> PrivateKey raise

    Parse an armored key block (public or private) into a PrivateKey when it carries secret material.

    Example

    test "armor round trip preserves the fingerprint" {
    let key = @api.generate_ed25519_key("A <a@example.com>")
    let re = @api.PrivateKey::from_armored(key.to_armored())
    assert_eq(re.fingerprint(), key.fingerprint())
    }

    PrivateKey::from_bytes

    fn PrivateKey::from_bytes(data : BytesView) -> PrivateKey raise

    Parse a transferable private key from binary packets. The secret material stays in whatever state the wire had it (locked or unlocked); use PrivateKey::unlock for locked keys.

    PrivateKey::is_aead_protected

    fn PrivateKey::is_aead_protected(self : PrivateKey) -> Bool

    True when any secret component uses the RFC 9580 AEAD protection (S2K usage octet 253).

    PrivateKey::is_expired

    fn PrivateKey::is_expired(self : PrivateKey, now : Int64) -> Bool

    See PublicKey::is_expired. Delegates to the public half.

    PrivateKey::is_locked

    fn PrivateKey::is_locked(self : PrivateKey) -> Bool

    True when any secret component (primary key or a subkey) is still passphrase-protected. unlock unlocks all components together and gopenpgp's IsLocked uses the same "any component" semantics, so looking at the primary alone misreports a key whose subkey is the protected one.

    PrivateKey::is_revoked

    fn PrivateKey::is_revoked(self : PrivateKey, now : Int64) -> Bool

    See PublicKey::is_revoked. Delegates to the public half.

    PrivateKey::is_user_id_revoked

    fn PrivateKey::is_user_id_revoked(self : PrivateKey, user_id : String, now : Int64) -> Bool

    See PublicKey::is_user_id_revoked. Delegates to the public half.

    PrivateKey::key_id

    fn PrivateKey::key_id(self : PrivateKey) -> Bytes raise

    8-octet key id of the primary key (low 64 bits of the v4 fingerprint).

    PrivateKey::lock

    fn PrivateKey::lock(self : PrivateKey, passphrase : String) -> PrivateKey raise

    Protect every secret component with a passphrase (usage 254, CFB + SHA-1), the shape GnuPG 2.4 interoperates with.

    PrivateKey::lock_argon2

    fn PrivateKey::lock_argon2(self : PrivateKey, passphrase : String, passes? : Int, parallelism? : Int, memory_exp? : Int) -> PrivateKey raise

    Protect every secret component with Argon2id + AES-256/OCB (S2K usage octet 253) — the RFC 9580 recommendation, and what the gopenpgp RFC 9580 profile produces. memory_exp is the exponent of the memory size in KiB (default 16 → 64 MiB); passes and parallelism default to go-crypto's t=3, p=4.

    PrivateKey::revoke_user_id

    fn PrivateKey::revoke_user_id(self : PrivateKey, user_id : String, message? : String, created? : Int) -> PrivateKey raise

    Return a copy of key with the named User ID revoked: a CertificationRevocation signature by the primary, attached to the binding. The User ID stays on the certificate — the revocation is the public statement that the identity is no longer valid (what gpg's --quick-revoke-uid writes). Re-certifying the same User ID later is add_user_id. The key must be unlocked.

    PrivateKey::self_signature

    The key-level self-signature: the first User ID certification, or the Direct Key signature of a bare v6 key. Import guarantees one of the two exists, so this never aborts on a key obtained through from_bytes/from_armored/generate_*.

    PrivateKey::set_expiry

    fn PrivateKey::set_expiry(self : PrivateKey, seconds : Int64, created? : Int) -> PrivateKey raise

    Set (or extend, or clear with 0) the primary key's expiry: every governing self-signature — each User ID certification plus the v6 Direct Key signature — is re-issued with a Key Expiration Time of seconds. The lifetime counts from the KEY's creation time (RFC 9580 §5.2.3.6 semantics), so "30 days from key creation" stays 2592000 no matter when the extension happens. The key must be unlocked.

    Example

    test "an expiry is visible through the lifecycle checks" {
    let key = @api.generate_ed25519_key("E <e@example.com>").set_expiry(3600)
    let now = @primitives.unix_now()
    assert_false(key.is_expired(now))
    assert_true(key.is_expired(now + 3601))
    }

    PrivateKey::set_primary_user_id

    fn PrivateKey::set_primary_user_id(self : PrivateKey, user_id : String, created? : Int) -> PrivateKey raise

    Name user_id the certificate's primary identity: its certification is re-issued with the Primary User ID flag (RFC 9580 §5.2.3.20) and every other User ID loses the flag. user_id() then reports it. The key must be unlocked.

    PrivateKey::set_subkey_expiry

    fn PrivateKey::set_subkey_expiry(self : PrivateKey, subkey_id : BytesView, seconds : Int64, created? : Int) -> PrivateKey raise

    Set (or extend, or clear with 0) one subkey's expiry by re-issuing its binding signature with a Key Expiration Time of seconds — gpg --quick-set-expire <fpr> <subkey-fpr>. The subkey is matched by key id; an embedded cross-certification rides in the unhashed area and survives untouched. The key must be unlocked.

    PrivateKey::to_armored

    fn PrivateKey::to_armored(self : PrivateKey) -> String

    Export as ASCII-armored private key block.

    PrivateKey::to_bytes

    fn PrivateKey::to_bytes(self : PrivateKey) -> Bytes

    Serialize to binary packets: SecretKey || [revocation] || [DirectKeySig] || [UserID || cert] || [SecretSubkey || binding ]. A v6 key without a User ID writes only the Direct Key signature.

    PrivateKey::to_public

    fn PrivateKey::to_public(self : PrivateKey) -> PublicKey

    Strip the secret material, producing a transferable public key.

    PrivateKey::unlock

    fn PrivateKey::unlock(self : PrivateKey, passphrase : String, argon2_max_memory_kib? : Int) -> PrivateKey raise

    Unlock the primary key (and its subkey) of a transferable private key with a passphrase. Returns a copy with plaintext secret material. Handles both the CFB (254/255) and the AEAD + Argon2 (253) protections. A wrong passphrase raises the typed WrongPassphrase error (for AEAD protection the same variant also covers a corrupted key; the message text tells the two apart).

    Example

    test "unlock raises the typed WrongPassphrase error" {
    let key = @api.generate_ed25519_key("A <a@example.com>").lock("correct horse")
    try {
    let _ = key.unlock("wrong horse")
    fail("unlocking with the wrong passphrase must fail")
    } catch {
    @error.WrongPassphrase(_) => () // the expected failure class
    _ => fail("expected WrongPassphrase")
    }
    }

    PrivateKey::user_id

    fn PrivateKey::user_id(self : PrivateKey) -> String

    The primary User ID string: the one whose self-certification carries the Primary User ID flag, else the first certified User ID; empty for a bare v6 key.

    PublicKey

    The public half of a transferable key. Read-only like PrivateKey; obtain values via to_public / from_armored / from_bytes.

    PublicKey::apply_revocation_certificate

    fn PublicKey::apply_revocation_certificate(self : PublicKey, armored : String) -> PublicKey raise

    The public-half twin of PrivateKey::apply_revocation_certificate.

    PublicKey::can_encrypt

    fn PublicKey::can_encrypt(self : PublicKey, now : Int64) -> Bool

    True when, at now, the key has an encryption-capable component: neither the key nor the subkey is revoked, some component carries the encryption key flags (absence of the subpacket counts as capable) and that component has not expired.

    PublicKey::can_verify

    fn PublicKey::can_verify(self : PublicKey, now : Int64) -> Bool

    True when, at now, some component may sign or certify: not revoked, primary (or any subkey) flags permit signing/certifying, and the governing signatures have not expired.

    PublicKey::encryption_key

    The public key packet of an encryption-capable key, structurally (no clock): the last subkey whose binding flags permit encryption (absent flags count as capable), otherwise the RSA primary key. The lifecycle-aware choice is encryption_packet_at.

    PublicKey::encryption_packet_at

    fn PublicKey::encryption_packet_at(self : PublicKey, now : Int64) ->
    PublicKeyPacket
    ?

    The encryption-capable packet to use at now: the last usable encryption subkey in wire order (each judged by its own binding — flags, expiry, revocation), otherwise the primary for RSA. None when nothing on the key may encrypt at now.

    PublicKey::fingerprint

    fn PublicKey::fingerprint(self : PublicKey) -> Bytes raise

    20-octet v4 fingerprint of the primary key.

    PublicKey::from_armored

    fn PublicKey::from_armored(text : String) -> PublicKey raise

    Parse an armored key block into a public key; a private-key block is accepted and stripped to its public half.

    PublicKey::from_bytes

    fn PublicKey::from_bytes(data : BytesView) -> PublicKey raise

    Parse a transferable public key from binary packets.

    PublicKey::is_expired

    fn PublicKey::is_expired(self : PublicKey, now : Int64) -> Bool

    True when the primary key expired at now, per the Key Expiration Time of its certification (or, failing that, its Direct Key signature). Subkey expiry is judged separately inside can_encrypt.

    PublicKey::is_revoked

    fn PublicKey::is_revoked(self : PublicKey, now : Int64) -> Bool

    True when a cryptographically valid, already-effective self-revocation of the primary key is on record. Subkey revocations only affect can_encrypt (they say nothing about the primary).

    PublicKey::is_user_id_revoked

    fn PublicKey::is_user_id_revoked(self : PublicKey, user_id : String, now : Int64) -> Bool

    True when the named User ID carries a cryptographically valid, already effective CertificationRevocation — the lazy-verification model used for key revocations (is_revoked): import attaches the signature, and the cryptographic check happens here. now = 0 disables the effective-date question.

    PublicKey::key_id

    fn PublicKey::key_id(self : PublicKey) -> Bytes raise

    8-octet key id of the primary key.

    PublicKey::preferred_aead

    fn PublicKey::preferred_aead(self : PublicKey) -> Array[(Int, Int)]

    The Preferred AEAD Ciphersuites advertised by a key as (cipher, AEAD) id pairs, most preferred first (RFC 9580 §5.2.3.15). Reads the self-signature first, then the Direct Key signature of a v6 key, and returns an empty list when the key advertises none.

    PublicKey::self_signature

    The key-level self-signature: the first User ID certification, or the Direct Key signature of a bare v6 key. Import guarantees one of the two exists, so this never aborts on a key obtained through from_bytes/from_armored/generate_*.

    PublicKey::supports_seipd_v2

    fn PublicKey::supports_seipd_v2(self : PublicKey) -> Bool

    True when the key advertises v2 SEIPD support in its Features subpacket (RFC 9580 §5.2.3.32).

    PublicKey::to_armored

    fn PublicKey::to_armored(self : PublicKey) -> String

    Export as ASCII-armored public key block.

    PublicKey::to_bytes

    fn PublicKey::to_bytes(self : PublicKey) -> Bytes

    Public half to binary packets.

    PublicKey::user_id

    fn PublicKey::user_id(self : PublicKey) -> String

    The primary User ID string: the one whose self-certification carries the Primary User ID flag, else the first certified User ID; empty for a bare v6 key.

    RevocationReason

    pub(all) enum RevocationReason {
    NoReason
    Superseded
    Compromised
    Retired
    } derive(Eq,
    Debug
    )

    Revocation reason codes (RFC 9580 §5.2.3.31). Reason 32 (User ID no longer valid) belongs to certification revocations, which this library does not model.

    RevocationReason::equal

    RevocationReason::not_equal

    fn RevocationReason::not_equal(x : RevocationReason, y : RevocationReason) -> Bool

    RevocationReason::number

    fn RevocationReason::number(self : RevocationReason) -> Int

    SecretSubkeyCert

    The private-key half of one bound subkey: the secret key packet plus the same binding/revocation signatures as its public twin.

    SessionKey

    pub(all) struct SessionKey {
    key : Bytes
    algo :
    CipherAlgo

    } derive(
    Debug
    )

    A symmetric session key with the cipher that interprets it. key must be algo.key_size() octets — SessionKey::new enforces it; direct struct construction bypasses the check and fails at first use inside the block-cipher constructor.

    SessionKey::algo

    The cipher this session key belongs to.

    SessionKey::key

    fn SessionKey::key(self : SessionKey) -> Bytes

    The raw session-key octets.

    SessionKey::new

    Build a session key, validating the key length against the cipher.

    SubkeyCert

    One bound subkey of a public transferable key: the public key packet, the SubkeyBinding signature by the primary (import-verified), and the SubkeyRevocation signature when the wire carried one.

    UserIdBinding

    One certified User ID: the identifier plus the self-signature that binds it to the primary key. A revoked User ID keeps its place on the certificate with the CertificationRevocation signature attached — that is how the wire tells verifiers the identity is no longer valid.

    V6Password

    pub(all) struct V6Password {
    passphrase : String
    aead :
    AeadMode

    argon2 : Bool
    passes : Int
    parallelism : Int
    memory_exp : Int
    }

    One v6 password recipient with its AEAD/S2K options (task 3: the builder's v6 password path; each passphrase gets its own SKESK under the shared session key).

    VerifyStatus

    pub(all) enum VerifyStatus {
    Ok
    NotSigned
    NoVerifier
    Failed
    KeyRevoked
    Expired
    } derive(Eq,
    Debug
    )

    Verification outcome, mirroring gopenpgp's status codes (OK / NOT_SIGNED / NO_VERIFIER / FAILED) plus the lifecycle outcomes gopenpgp v3 folds into a rejected signature.

    VerifyStatus::equal

    VerifyStatus::not_equal

    fn VerifyStatus::not_equal(x : VerifyStatus, y : VerifyStatus) -> Bool

    DEFAULT_MAX_DECOMPRESSED_BYTES

    let DEFAULT_MAX_DECOMPRESSED_BYTES : Int

    Default ceiling on decompressed payload size (M4): a 512 MiB bound on what an untrusted compressed packet may expand to. Mirrors the Argon2 pre-allocation cap policy; override per call with max_decompressed~.

    decrypt_and_verify

    fn decrypt_and_verify(message : String, decryption_keys : Array[PrivateKey], verifier : PublicKey?, max_decompressed? : Int) -> (Bytes, VerifyStatus) raise

    Decrypt an armored message (password OR private keys) and verify an inline signature against verifier. Returns (data, status).

    The plaintext is returned even when the signature does not verify — Failed, KeyRevoked and Expired all arrive with data. Callers that must not act on unverified content check the status first (the DecryptionBuilder wraps this contract as DecryptResult, surfacing the broken-signature case as SignatureError(data)).

    decrypt_binary_with_password

    fn decrypt_binary_with_password(data : BytesView, passphrase : String, argon2_max_memory_kib? : Int, max_decompressed? : Int) -> Bytes raise

    Same as decrypt_with_password but takes binary packet data.

    Every SKESK in the stream is tried until one both unwraps AND opens the message payload (N4): a v4 SKESK has no integrity check of its own, so a wrong passphrase can unwrap to structurally plausible garbage whose wrongness only surfaces at the SEIPD MDC — the retry must therefore span the payload decryption, not just the unwrap.

    decrypt_binary_with_private_key

    fn decrypt_binary_with_private_key(data : BytesView, key : PrivateKey, max_decompressed? : Int) -> Bytes raise

    Decrypt a binary message with an unlocked private key. Matches PKESKs against the key's ids (RSA or ECDH), recovers the session key, checks the session-key checksum, and unwraps the SEIPD payload.

    decrypt_to_session_key

    fn decrypt_to_session_key(message : String, sk : SessionKey) -> Bytes raise

    Decrypt a message with a caller-held session key. The message may be a bare SEIPD container (from encrypt_to_session_key) or a normal PKESK/SKESK-protected message whose session key the caller knows.

    decrypt_with_password

    fn decrypt_with_password(message : String, passphrase : String, argon2_max_memory_kib? : Int, max_decompressed? : Int) -> Bytes raise

    Decrypt an (optionally armored) message using a passphrase. Returns the literal data. Compressed packets are transparently decompressed. A wrong passphrase raises the typed WrongPassphrase error. See encrypt_with_password for a round-trip example.

    decrypt_with_private_key

    fn decrypt_with_private_key(message : String, key : PrivateKey, max_decompressed? : Int) -> Bytes raise

    Decrypt an armored message with an unlocked private key.

    encrypt_to_recipients

    fn encrypt_to_recipients(plaintext : BytesView, recipients : Array[PublicKey], file_name? : String, compress? :
    CompressedAlgo
    ) -> String raise

    Encrypt plaintext to one or more recipients' public keys. Each recipient gets its own fresh PKESK encoding of the session key (RFC 9580 §5.1.3 requires re-encoding per key). Result: armored PGP MESSAGE of PKESK(s) + SEIPD, v2 for v6 recipients and v1 otherwise.

    encrypt_to_session_key

    fn encrypt_to_session_key(plaintext : BytesView, sk : SessionKey, file_name? : String, compress? :
    CompressedAlgo
    ) -> String raise

    Encrypt plaintext under a caller-held session key: a bare SEIPD v1 container with no PKESK/SKESK — only whoever holds sk out of band can read it (the gopenpgp "raw session key" backend). Everything this library encrypts uses AES: CAST5/3DES session keys stay decryption-only.

    encrypt_with_password

    fn encrypt_with_password(plaintext : BytesView, passphrase : String, file_name? : String, aead? : Bool, argon2? : Bool, argon2_memory_exp? : Int, compress? :
    CompressedAlgo
    ) -> String raise

    Encrypt plaintext to a passphrase. Produces an armored PGP MESSAGE with a v4 SKESK (iterated+salted S2K, AES-256 session key wrapped in CFB) followed by a v1 SEIPD packet holding the literal data.

    For new code prefer the builder (pgp().encryption().password(...), which can also mix recipients and a signer) or encrypt_with_password_v6 for the RFC 9580 v6 shape; this entry stays for the classic v4 message.

    Example

    test "password encryption round trip" {
    let armored = @api.encrypt_with_password(b"Hello, world!", "hunter2")
    inspect(armored.has_prefix("-----BEGIN PGP MESSAGE-----"), content="true")
    assert_eq(@api.decrypt_with_password(armored, "hunter2"), b"Hello, world!")
    }

    encrypt_with_password_argon2

    fn encrypt_with_password_argon2(plaintext : BytesView, passphrase : String, file_name? : String, passes? : Int, parallelism? : Int, memory_exp? : Int, compress? :
    CompressedAlgo
    ) -> String raise

    Encrypt plaintext to a passphrase using Argon2id as the S2K specifier (type 4, RFC 9580 §3.7.1.4) — the RFC's recommendation, and the shape of Appendix A.12. The message keeps the v4 SKESK form (CFB with an all-zero IV) plus a v1 SEIPD packet, so every reader that understands Argon2 can consume it.

    memory_exp is the exponent of the Argon2 memory size in KiB (default 16 → 64 MiB, go-crypto's default); passes and parallelism default to t=3, p=4.

    In new code prefer encrypt_with_password_v6 (Argon2 by default) or the builder's .password_v6; this entry produces the v4 message shape with an Argon2 specifier.

    encrypt_with_password_v6

    fn encrypt_with_password_v6(plaintext : BytesView, passphrase : String, file_name? : String, aead? :
    AeadMode
    , argon2? : Bool, passes? : Int, parallelism? : Int, memory_exp? : Int, compress? :
    CompressedAlgo
    ) -> String raise

    Encrypt plaintext to a passphrase in the RFC 9580 v6 shape: a v6 SKESK (AEAD + HKDF-SHA256 key separation, §5.3.2) followed by a v2 SEIPD packet (§5.13.2). argon2 (default true) selects the Argon2id S2K the RFC recommends for v6; set it to false for the much cheaper iterated+salted SHA-256. This is the recommended passphrase entry point for new code; to mix in public-key recipients or a signer, use the builder's .password_v6 instead.

    generate_ed25519_key

    fn generate_ed25519_key(user_id : String) -> PrivateKey raise

    Generate a transferable key with an Ed25519 primary (EdDSA legacy, signing/certification) and a Curve25519Legacy ECDH encryption subkey — the gopenpgp "Default" profile shape. EdDSA signatures require the digest itself as the Ed25519 message (RFC 9580 §5.2.3).

    Example

    test "generate an ed25519 key" {
    let key = @api.generate_ed25519_key("A <a@example.com>")
    assert_eq(key.user_id(), "A <a@example.com>")
    inspect(key.fingerprint().length(), content="20")
    }

    generate_ed25519_v6_key

    fn generate_ed25519_v6_key(user_id : String) -> PrivateKey raise

    Generate a v6 Ed25519 signing key with an X25519 encryption subkey (RFC 9580 §5.5.5.7/§5.5.5.9) — the shape of the Appendix A.3/A.4 sample certificate: a v6 primary key with a User ID self-certification, the Direct Key signature the RFC requires before a v6 key may be used, and a v6 X25519 subkey with a v6 binding signature.

    generate_ed25519_v6_key_with_signing_subkey

    fn generate_ed25519_v6_key_with_signing_subkey(user_id : String) -> PrivateKey raise

    Generate a v6 certificate in the gpg dual-subkey shape: a CERT-ONLY Ed25519 primary (key flags 0x01 — the self-signature withholds the sign flag), an X25519 encryption subkey and an Ed25519 signing subkey whose v6 binding embeds a v6 Primary Key Binding (cross-certification, RFC 9580 §5.2.3.26 — a v6 key's self-signatures MUST be v6, so the embedded signature is v6-shaped). Document signatures then flow through the signing subkey (signing_packet), exactly like the gpg dual-subkey interop fixtures, exercising the v6 cross-certification path end to end.

    generate_key

    fn generate_key(user_id : String, bits? : Int, expiry? : Int64) -> PrivateKey raise

    Generate a fresh transferable key: RSA primary (certify+sign) with a User ID self-certification plus an RSA encryption subkey. expiry sets a Key Expiration Time (seconds from the key's creation; 0, the default, never expires) on both self-certification and binding.

    generate_revocation_certificate

    fn generate_revocation_certificate(key : PrivateKey, reason? : RevocationReason, message? : String, created? : Int) -> String raise

    Generate, but do not apply, a standalone revocation certificate for the primary key: a single key-revocation signature packet in PUBLIC KEY BLOCK armor — the .rev shape gpg --gen-revoke emits (gpg refuses to --import a bare Signature armor block, verified against 2.4.5). The owner distributes it out of band; anyone can apply it to their copy of the public key.

    Example

    test "a revocation certificate is armored" {
    let key = @api.generate_ed25519_key("A <a@example.com>")
    let cert = @api.generate_revocation_certificate(key)
    inspect(
    cert.has_prefix("-----BEGIN PGP PUBLIC KEY BLOCK-----"),
    content="true",
    )
    }

    generate_session_key

    fn generate_session_key(algo? :
    CipherAlgo
    ) -> SessionKey raise

    Generate a fresh random session key (platform entropy; AES-256 unless another cipher is requested).

    pgp

    fn pgp() -> Pgp

    gopenpgp-style entry point: pgp().encryption()....

    recover_session_key_with_key

    fn recover_session_key_with_key(message : String, key : PrivateKey) -> SessionKey raise

    Recover the session key of a message encrypted to key's public key: unwrap the matching PKESK without decrypting the payload. The algorithm id comes from the PKESK payload for the v4 shape and from the SEIPD v2 header for v6.

    recover_session_key_with_password

    fn recover_session_key_with_password(message : String, passphrase : String, argon2_max_memory_kib? : Int) -> SessionKey raise

    Recover the session key of a password-encrypted message (the gopenpgp RetrieveSessionKey flow): unwrap the SKESK without touching the payload.

    revoke_key

    fn revoke_key(key : PrivateKey, reason? : RevocationReason, message? : String, created? : Int) -> PrivateKey raise

    Return a copy of key with a fresh primary-key revocation appended; the certificate round-trips with the revocation intact and every lifecycle gate (is_revoked, can_encrypt, can_verify, signature verification) sees the key as revoked.

    revoke_subkey

    fn revoke_subkey(key : PrivateKey, subkey_id : BytesView, reason? : RevocationReason, message? : String, created? : Int) -> PrivateKey raise

    Return a copy of key with a revocation signature on the subkey whose key id matches subkey_id. A revoked subkey drops out of encryption selection immediately; decryption with it stays possible (mail that arrived before the revocation must keep decrypting, mirroring KeyRing::find_decryption_key).

    sign_and_encrypt

    fn sign_and_encrypt(data : BytesView, signer : PrivateKey, recipients : Array[PublicKey], text_mode? : Bool, compress? :
    CompressedAlgo
    , created? : Int, file_name? : String) -> String raise

    Sign and encrypt in one step (inline signature inside SEIPD).

    created is the signature creation time in seconds since 1970; without it the current time is used (see sign_detached). file_name names the literal packet (N9; default "message.txt").

    sign_cleartext

    fn sign_cleartext(text : String, key : PrivateKey, created? : Int) -> String raise

    Create a cleartext signed message (RFC 9580 §7) over UTF-8 text with the default SHA-256 signature of the primary key.

    created is the signature creation time in seconds since 1970; without it the current time is used (see sign_detached).

    sign_cleartext_with

    fn sign_cleartext_with(text : String, key : PrivateKey, hash :
    HashId
    , created? : Int) -> String raise

    Create a cleartext signed message with an explicit hash algorithm.

    sign_detached

    fn sign_detached(data : BytesView, key : PrivateKey, text_mode? : Bool, created? : Int) -> String raise

    Create a detached ASCII-armored signature over data.

    created is the signature creation time in seconds since 1970; without it the current time is used. Passing the time makes the signature reproducible for RSA PKCS#1 v1.5 and Ed25519 keys, which sign deterministically (for example for reproducible builds).

    Example

    test "detached signature round trip" {
    let key = @api.generate_ed25519_key("A <a@example.com>")
    let sig = @api.sign_detached(b"payload", key)
    inspect(sig.has_prefix("-----BEGIN PGP SIGNATURE-----"), content="true")
    assert_eq(
    @api.verify_detached(b"payload", sig, key.to_public()),
    @api.VerifyStatus::Ok,
    )
    assert_true(@api.verify_detached(b"tampered", sig, key.to_public()) is Failed)
    }

    sign_inline

    fn sign_inline(data : BytesView, key : PrivateKey, text_mode? : Bool, created? : Int, file_name? : String) -> String raise

    Create an inline-signed, armored message: One-Pass-Signature || Literal || Signature.

    created is the signature creation time in seconds since 1970; without it the current time is used (see sign_detached — deterministic for RSA/Ed25519 keys, so the message becomes reproducible). file_name names the literal packet (N9; default "message.txt").

    verify_cleartext

    fn verify_cleartext(message : String, verifier : PublicKey) -> (String, VerifyStatus) raise

    Verify a cleartext signed message. Returns the de-escaped, canonical cleartext and the verification status against verifier.

    verify_detached

    fn verify_detached(data : BytesView, armored_signature : String, verifier : PublicKey) -> VerifyStatus raise

    Verify a detached armored signature over data using verifier.

    verify_inline

    fn verify_inline(message : String, verifier : PublicKey, max_decompressed? : Int) -> (Bytes, VerifyStatus) raise

    Verify an inline-signed armored message; returns the literal data and the verification status against verifier.

    verify_key_signature

    Verify a self-certification or binding signature over key material. Deliberately public (F14 review decision): it is the key-management entry point for validating third-party keys, exercised from outside the package by the gopenpgp self-certification cross-validation tests.