tests/testthat/test-interop-fixtures.R

# Decrypt ciphertexts generated by the reference age implementation
# (FiloSottile's Go `age`, an independent codebase). These files are checked
# in, so this runs everywhere -- no external binary needed at test time.

interop_dir <- test_path("fixtures", "interop")
ref_key <- file.path(interop_dir, "key.txt")

test_that("we decrypt reference-age binary ciphertext (multi-word payload)", {
  id <- age_identity(ref_key)
  pt <- age_decrypt_raw(
    readBin(file.path(interop_dir, "big.age"), "raw", 1e6),
    identities = id
  )
  expect_identical(rawToChar(pt), "The quick brown fox jumps over the lazy dog.\n")
})

test_that("we decrypt reference-age ASCII-armored ciphertext", {
  id <- age_identity(ref_key)
  pt <- age_decrypt_raw(
    readBin(file.path(interop_dir, "big.age.armor"), "raw", 1e6),
    identities = id
  )
  expect_identical(rawToChar(pt), "The quick brown fox jumps over the lazy dog.\n")
})

test_that("we decrypt a reference-age ciphertext of a sub-probe-size input", {
  # "hi" is 2 bytes, well under the 35-byte armor-detection probe; this locks
  # in interop of the short-input fix against an externally generated file.
  id <- age_identity(ref_key)
  pt <- age_decrypt_raw(
    readBin(file.path(interop_dir, "small.age"), "raw", 1e6),
    identities = id
  )
  expect_identical(rawToChar(pt), "hi")
})

test_that("a reference age-keygen key file is readable and parses one identity", {
  expect_match(age_pubkey(age_identity(ref_key)), "^age1[0-9a-z]{58}$")
})

test_that("we decrypt reference-age ciphertext across a boundary-crossing size sweep", {
  # sweep/ holds reference-age ciphertexts of strrep("A", n) for sizes spanning
  # the 35-byte armor probe and the 64 KiB STREAM chunk boundary, both binary
  # and ASCII-armored (regenerate with tools/gen-interop-fixtures.R). The payload
  # is reconstructed from the file name, so only the ciphertext is committed.
  sweep <- file.path(interop_dir, "sweep")
  files <- list.files(sweep, pattern = "\\.age$", full.names = TRUE)
  expect_gt(length(files), 0L)
  id <- age_identity(ref_key)
  for (f in files) {
    n <- as.integer(sub("^size-(\\d+)-(bin|arm)\\.age$", "\\1", basename(f)))
    pt <- age_decrypt_raw(readBin(f, "raw", 1e7), identities = id)
    expect_identical(rawToChar(pt), strrep("A", n), info = basename(f))
  }
})

Try the agecrypt package in your browser

Any scripts or data that you put into this service are public.

agecrypt documentation built on Aug. 5, 2026, 9:08 a.m.