nuckle.cr

NaCl for Knuckleheads — pure Crystal crypto primitives, no libsodium required. Don't use this.

Nuckle

NaCl for Knuckleheads — pure Crystal crypto primitives, no libsodium.

A Crystal port of the Ruby nuckle gem. Same algorithms, same API shape, same "don't use this" disclaimers.

Is it any good?

No. See SECURITY.md.

Don't use this

BigInt arithmetic (used by Curve25519 and Poly1305) is not constant-time, so private keys leak via timing side channels. Use natron (libsodium binding) for anything that matters.

Why does this exist?

  • Zero-dependency environments and CI
  • Seeing how fast Crystal's native UInt32/UInt64 and LLVM codegen are at these algorithms, vs. real libsodium
  • Education — all five primitives fit in ~800 readable lines of Crystal
  • Testing and fuzzing against natron

Primitives

Primitive What it does
Curve25519 ECDH key agreement (RFC 7748)
XSalsa20 Extended-nonce stream cipher (+ HSalsa20, Salsa20)
ChaCha20 Stream cipher, DJB 8-byte-nonce variant
Poly1305 One-time message authenticator (RFC 8439)
BLAKE3 Hash — unkeyed, keyed, derive_key, XOF
SecretBox XSalsa20-Poly1305 symmetric AEAD
Box Curve25519-XSalsa20-Poly1305 public-key AEAD
ChaCha20-BLAKE3 AEAD, wire-compatible with skerkour/chacha20-blake3

Usage

require "nuckle"

# Keypair
sk = Nuckle::PrivateKey.generate
pk = sk.public_key

# Public-key encryption
alice = Nuckle::PrivateKey.generate
bob   = Nuckle::PrivateKey.generate
nonce = Nuckle::Random.random_bytes(24)

box = Nuckle::Box.new(bob.public_key, alice)
ct  = box.encrypt(nonce, "hello".to_slice)

box2 = Nuckle::Box.new(alice.public_key, bob)
pt   = box2.decrypt(nonce, ct)  # => "hello"

# Symmetric
key   = Nuckle::Random.random_bytes(32)
nonce = Nuckle::Random.random_bytes(24)
box   = Nuckle::SecretBox.new(key)
ct    = box.encrypt(nonce, "hello".to_slice)
pt    = box.decrypt(nonce, ct)

API Compatibility

The public API mirrors natron exactly — swap the module name and it Just Works.

Verification

All primitives are tested against official test vectors (RFC 7748, RFC 8439, NaCl distribution, BLAKE3 spec) and cross-validated against libsodium (via natron) to produce byte-identical output.

License

ISC

Repository

nuckle.cr

Owner
Statistic
  • 0
  • 0
  • 0
  • 0
  • 1
  • about 9 hours ago
  • April 24, 2026
License

ISC License

Links
Synced at

Fri, 24 Apr 2026 23:49:19 GMT

Languages