First stable release. Ruby implementation of the 3ncr.org v1 encryption envelope (AES-256-GCM, 12-byte random IV, 16-byte GCM tag, base64 without padding). Ruby 3.1+.
Published on RubyGems as 3ncr. Ruby constants can't start with a digit, so the top-level module is Threencr:
# Gemfile
gem "3ncr"require "3ncr"
tc = Threencr::TokenCrypt.from_sha3("some-high-entropy-api-token")
encrypted = tc.encrypt_3ncr("hello")
tc.decrypt_if_3ncr(encrypted) # => "hello"Constructors
Threencr::TokenCrypt.from_raw_key(key)— primary constructor, takes a 32-byte AES-256 key as a binary string.Threencr::TokenCrypt.from_sha3(secret)— single SHA3-256 hash for high-entropy secrets that are not already 32 bytes.Threencr::TokenCrypt.from_argon2id(secret, salt)— Argon2id KDF for password-strength secrets, parameters per 3ncr.org v1 spec:m=19456 KiB, t=2, p=1, salt ≥ 16 bytes.
encrypt_3ncr(plaintext) produces a 3ncr.org/1#… value; decrypt_if_3ncr(value) decrypts only if the input carries the v1 header, otherwise returns it unchanged.
Per 3ncr.org's new-language convention, the legacy PBKDF2-SHA3 KDF is intentionally omitted. Callers who need to decrypt data from older Go/Node/PHP implementations can derive the key with OpenSSL::KDF.pbkdf2_hmac using digest: OpenSSL::Digest.new("SHA3-256") and pass the result to from_raw_key.
Cross-verified against the canonical v1 test vectors shared with the Go, Node.js, PHP, Python, Rust, Java, and C# reference implementations.
Full changelog: https://github.com/3ncr/tokencrypt-ruby/blob/main/CHANGELOG.md