pgp
stableEd25519 key generation, digital signing and verification, PGP ASCII-armoring, XOR-based symmetric encryption, and SHA-256 hashing via the ring cryptography library.
use plugin pgp::{generate_ed25519_keypair, sign, verify, …} Functions (9)
- generate_ed25519_keypair Generate an Ed25519 key pair
- sign Sign a message with a private key
- verify Verify an Ed25519 signature
- armor_wrap Wrap base64 data in PGP armor headers
- armor_unwrap Strip PGP armor and return raw bytes
- key_info Inspect algorithm and length of a public key
- encrypt XOR-encrypt plaintext with a key
- decrypt XOR-decrypt ciphertext with a key
- hash_sha256 Compute SHA-256 digest as hex string
Overview
pgp is a lightweight cryptography toolkit built on the ring library, centered
on the Ed25519 signature scheme. Every key, signature, and ciphertext crosses the
boundary as a plain base64 string rather than an opaque handle, so you can store
and pass values around freely. The plugin pairs asymmetric signing (generate, sign,
verify) with a handful of supporting utilities: SHA-256 hashing, PGP-style ASCII
armoring, and a deliberately simple XOR symmetric cipher.
Use it whenever you need to prove the authenticity of a message, fingerprint data
with a digest, or wrap binary material in a transport-friendly armored block. Note
that encrypt/decrypt are XOR-based and meant for lightweight obfuscation only —
reach for a real AEAD cipher when protecting production secrets.
Common patterns
Generate a key pair, sign a message, and verify the signature end to end:
use plugin pgp::{generate_ed25519_keypair, sign, verify}
let keys = generate_ed25519_keypair()
let msg = "transfer $100 to alice"
let signature = sign(msg, keys["private_key_base64"])
let ok = verify(msg, signature, keys["public_key_base64"])
print("signature valid: {ok}")
Armor a public key for transport, then unwrap it on the other side:
use plugin pgp::{generate_ed25519_keypair, armor_wrap, armor_unwrap}
let keys = generate_ed25519_keypair()
let block = armor_wrap(keys["public_key_base64"], "PUBLIC KEY")
print(block)
let raw = armor_unwrap(block)
print("recovered key payload: {raw}")
Hash content and round-trip it through the XOR cipher with a shared key:
use plugin pgp::{generate_ed25519_keypair, hash_sha256, encrypt, decrypt}
let keys = generate_ed25519_keypair()
let key = keys["public_key_base64"]
let cipher = encrypt("launch codes", key)
print("digest: {hash_sha256(cipher)}")
print("plain: {decrypt(cipher, key)}")
Generate an Ed25519 key pair
Generates a new Ed25519 key pair using a cryptographically secure RNG. Returns a table with public_key_base64 and private_key_base64 (PKCS#8 DER encoded, base64 strings).
use plugin pgp::{generate_ed25519_keypair}
let keys = generate_ed25519_keypair()
print("Public key: {keys["public_key_base64"]}")
Sign a message with a private key
Signs message using the Ed25519 private key (PKCS#8 base64). Returns the 64-byte signature as a base64 string.
use plugin pgp::{generate_ed25519_keypair, sign}
let keys = generate_ed25519_keypair()
let sig = sign("hello world", keys["private_key_base64"])
print("Signature: {sig}")
Verify an Ed25519 signature
Verifies an Ed25519 signature against a message and public key. Returns true if the signature is valid.
use plugin pgp::{generate_ed25519_keypair, sign, verify}
let keys = generate_ed25519_keypair()
let msg = "transfer $100"
let sig = sign(msg, keys["private_key_base64"])
let ok = verify(msg, sig, keys["public_key_base64"])
print("Valid: {ok}")
Verification fails when the message is tampered with after signing — a
mismatched body yields false:
use plugin pgp::{generate_ed25519_keypair, sign, verify}
let keys = generate_ed25519_keypair()
let sig = sign("transfer $100", keys["private_key_base64"])
let tampered = verify("transfer $9000", sig, keys["public_key_base64"])
print("tampered accepted: {tampered}")
Wrap base64 data in PGP armor headers
Wraps base64 data in PGP-style ASCII armor with -----BEGIN PGP TYPE----- and -----END PGP TYPE----- headers, line-wrapped at 76 characters.
use plugin pgp::{generate_ed25519_keypair, armor_wrap}
let keys = generate_ed25519_keypair()
let armored = armor_wrap(keys["public_key_base64"], "PUBLIC KEY")
print(armored)
The type_name is upper-cased into both headers, so any label works for the
kind of block you are emitting:
use plugin pgp::{generate_ed25519_keypair, sign, armor_wrap}
let keys = generate_ed25519_keypair()
let sig = sign("release v1.0", keys["private_key_base64"])
print(armor_wrap(sig, "signature"))
Strip PGP armor and return raw bytes
Parses a PGP ASCII-armored block, strips the headers, and returns the decoded payload. Skips header lines (those containing :).
use plugin pgp::{generate_ed25519_keypair, armor_wrap, armor_unwrap}
let keys = generate_ed25519_keypair()
let armored = armor_wrap(keys["public_key_base64"], "PUBLIC KEY")
let raw = armor_unwrap(armored)
print("Recovered key payload: {raw}")
Inspect algorithm and length of a public key
Returns basic information about a base64-encoded public key as a table with algorithm (always "Ed25519") and key_length_bytes fields.
use plugin pgp::{generate_ed25519_keypair, key_info}
let keys = generate_ed25519_keypair()
let info = key_info(keys["public_key_base64"])
print("Algorithm: {info["algorithm"]}")
print("Key length: {info["key_length_bytes"]} bytes")
XOR-encrypt plaintext with a key
XOR-encrypts plaintext using the base64-decoded key, cycling through the key bytes as a keystream. Returns base64-encoded ciphertext. Suitable for lightweight obfuscation — use a proper AEAD cipher for production secrets.
use plugin pgp::{generate_ed25519_keypair, encrypt, decrypt}
let keys = generate_ed25519_keypair()
let key = keys["public_key_base64"]
let cipher = encrypt("secret message", key)
print("Encrypted: {cipher}")
XOR-decrypt ciphertext with a key
Reverses encrypt by XOR-ing the base64-decoded ciphertext with the key. Returns the original plaintext string.
use plugin pgp::{generate_ed25519_keypair, encrypt, decrypt}
let keys = generate_ed25519_keypair()
let key = keys["public_key_base64"]
let cipher = encrypt("secret message", key)
let plain = decrypt(cipher, key)
print("Decrypted: {plain}")
Compute SHA-256 digest as hex string
Computes the SHA-256 digest of data using the ring library and returns it as a 64-character lowercase hex string.
use plugin pgp::{hash_sha256}
let digest = hash_sha256("hello world")
print("SHA-256: {digest}")
let file_hash = hash_sha256("file contents here")
print("File hash: {file_hash}")