Skip to main content

Age Encryption (Age)

This is what "a scoped, self-encrypting context" from the Mission page actually looks like in practice — a document (or part of one) encrypted so only the holder of a specific key, or passphrase, can read it back.

Age.generate(context: obj = self) -> Data<Age>

Generates a new identity — a public/private keypair — attached to the given object.

generate.stof
#[main]
fn main() {
  const identity = Age.generate();
  pln(Age.public(identity).len() > 0);
}
Output

Age.public(age: Data<Age>) -> str

The public half of an identity — safe to share, since it can only encrypt, not decrypt.

public.stof
#[main]
fn main() {
  const identity = Age.generate();
  pln(Age.public(identity));
}
Output

Age.blobify(recipients: str | list | Data<Age>, format: str = 'stof', context?: obj) -> blob

Like Std.blobify, but encrypted to one or more recipients' public keys — only the matching private key can read the result back.

blobify.stof
secret: "the launch codes"

#[main]
fn main() {
  const identity = Age.generate();
  const pubkey = Age.public(identity);

  const encrypted = Age.blobify(pubkey);
  pln(encrypted.len() > 0);
}
Output

Age.parse(age: Data<Age>, bin: blob, context: obj = self, format: str = "stof") -> bool

The other half of Age.blobify — decrypts using the matching identity, then parses the result into context the same way Std.parse would:

parse.stof
secret: "the launch codes"

#[main]
fn main() {
  const identity = Age.generate();
  const pubkey = Age.public(identity);
  const encrypted = Age.blobify(pubkey);

  const decrypted = new {};
  const ok = Age.parse(identity, encrypted, decrypted);
  pln(ok, decrypted.secret);
}
Output

Age.pass_blobify(passphrase: str, format: str = 'stof', context?: obj) -> blob

The simpler alternative to Age.blobify — a shared passphrase instead of a generated identity, when there's no real recipient to manage keys for.

pass-blobify.stof
secret: "the launch codes"

#[main]
fn main() {
  const encrypted = Age.pass_blobify("correct-horse-battery-staple");
  pln(encrypted.len() > 0);
}
Output

Age.pass_parse(passphrase: str, bin: blob, context: obj = self, format: str = "stof") -> bool

Decrypts what Age.pass_blobify produced — the same passphrase in, the original document back out:

pass-parse.stof
secret: "the launch codes"

#[main]
fn main() {
  const encrypted = Age.pass_blobify("correct-horse-battery-staple");

  const decrypted = new {};
  const ok = Age.pass_parse("correct-horse-battery-staple", encrypted, decrypted);
  pln(ok, decrypted.secret);
}
Output