Skip to content

v1.0.0

Latest

Choose a tag to compare

@peo-machine peo-machine released this 26 Apr 10:03
· 31 commits to main since this release
c68c24a

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