Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@ jobs:
echo "❌ build/crypto.lua missing"
exit 1
fi
# Check portable build (all dependencies bundled)
if [ -f "build/crypto-portable.lua" ]; then
echo "✅ build/crypto-portable.lua exists ($(wc -c < "build/crypto-portable.lua") bytes)"
else
echo "❌ build/crypto-portable.lua missing"
exit 1
fi

- name: Upload artifacts
uses: actions/upload-artifact@v4
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ jobs:
generate_release_notes: true
files: |
build/crypto.lua
build/crypto-portable.lua
12 changes: 9 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,19 @@ make test-matrix # across Lua 5.1–5.4 + LuaJIT

## Building

`amalg` produces a single-file distribution from `src/crypto/init.lua`:
`amalg` produces two single-file distributions from `src/crypto/init.lua`:

```bash
make build # Output: build/crypto.lua (bitn bundled in)
make build # Output: build/crypto.lua (core; bitn excluded via `-i bitn`)
# build/crypto-portable.lua (all dependencies bundled)
```

Version is automatically injected from git tags during release.
`crypto.lua` is the **canonical core build**: it excludes `bitn` and expects it
on the Lua path, so it composes with other libraries that share `bitn` without
duplicating it (e.g. lua-noiseprotocol vendors this as `vendor/crypto.lua`
alongside its own `vendor/bitn.lua`). `crypto-portable.lua` bundles every
dependency for a single drop-in file with zero external requires. Version is
injected from git tags during release.

## CI/CD

Expand Down
16 changes: 10 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,23 @@ build/amalg.cache: src/crypto/init.lua
build: build/amalg.cache
@echo "Building single-file distribution..."
@if command -v amalg.lua >/dev/null 2>&1; then \
LUA_PATH="$(LUA_PATH_LOCAL)" amalg.lua -o build/crypto.lua -C ./build/amalg.cache || exit 1;\
echo "Built build/crypto.lua"; \
LUA_PATH="$(LUA_PATH_LOCAL)" amalg.lua -o build/crypto.lua -C ./build/amalg.cache -i "bitn" || exit 1;\
echo "Built build/crypto.lua (core; bitn excluded, expected on the path)"; \
LUA_PATH="$(LUA_PATH_LOCAL)" amalg.lua -o build/crypto-portable.lua -C ./build/amalg.cache || exit 1; \
echo "Built build/crypto-portable.lua (portable; all dependencies bundled)"; \
VERSION=$$(git describe --exact-match --tags 2>/dev/null || echo "dev"); \
if [ "$$VERSION" != "dev" ]; then \
echo "Injecting version $$VERSION..."; \
sed -i.bak 's/VERSION = "dev"/VERSION = "'$$VERSION'"/' build/crypto.lua && rm build/crypto.lua.bak; \
sed -i.bak 's/VERSION = "dev"/VERSION = "'$$VERSION'"/' build/crypto-portable.lua && rm build/crypto-portable.lua.bak; \
fi; \
echo "Testing version function..."; \
LUA_VERSION=$$(lua -e 'local b = require("build.crypto"); print(b.version())' 2>/dev/null || echo "test failed"); \
if [ "$$LUA_VERSION" = "$$VERSION" ]; then \
echo "Version correctly set to: $$VERSION"; \
CORE_VERSION=$$(LUA_PATH="$(LUA_PATH_LOCAL)" lua -e 'local b = require("build.crypto"); print(b.version())' 2>/dev/null || echo "test failed"); \
PORTABLE_VERSION=$$(LUA_PATH="$(LUA_PATH_LOCAL)" lua -e 'local b = require("build.crypto-portable"); print(b.version())' 2>/dev/null || echo "test failed"); \
if [ "$$CORE_VERSION" = "$$VERSION" ] && [ "$$PORTABLE_VERSION" = "$$VERSION" ]; then \
echo "Version correctly set to: $$VERSION (core + portable)"; \
else \
echo "Version test failed. Expected: $$VERSION, Got: $$LUA_VERSION"; \
echo "Version test failed. Expected: $$VERSION, core: $$CORE_VERSION, portable: $$PORTABLE_VERSION"; \
fi; \
else \
echo "Error: amalg not found."; \
Expand Down
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,12 @@ pure-Lua implementations** regardless of this flag, because the shipped
Download a pre-built single-file module from the
[Releases](https://github.com/finitelabs/lua-crypto/releases) page:

- **`crypto.lua`** — complete bundle with all dependencies included (zero
external dependencies)
- **`crypto.lua`** — the canonical **core** build. Requires `bitn`
([lua-bitn](https://github.com/finitelabs/lua-bitn)) on the Lua path. Use this
when composing with other libraries that already provide `bitn`, so the shared
dependency is vendored only once.
- **`crypto-portable.lua`** — **portable** build with every dependency bundled
in (zero external dependencies). Use this when you want a single drop-in file.

### Option 2: From Source

Expand Down Expand Up @@ -87,11 +91,11 @@ local tag = crypto.sha256.hmac_sha256_hex(key, message)
local sealed = crypto.chacha20_poly1305.encrypt(key, nonce, plaintext, aad)
local opened = crypto.chacha20_poly1305.decrypt(key, nonce, sealed, aad)

-- Diffie-Hellman (X25519)
local alice = crypto.x25519.generate_keypair()
local bob = crypto.x25519.generate_keypair()
local shared_a = crypto.x25519.diffie_hellman(alice.private_key, bob.public_key)
local shared_b = crypto.x25519.diffie_hellman(bob.private_key, alice.public_key)
-- Diffie-Hellman (X25519); generate_keypair() returns private, public
local alice_priv, alice_pub = crypto.x25519.generate_keypair()
local bob_priv, bob_pub = crypto.x25519.generate_keypair()
local shared_a = crypto.x25519.diffie_hellman(alice_priv, bob_pub)
local shared_b = crypto.x25519.diffie_hellman(bob_priv, alice_pub)
assert(shared_a == shared_b)
```

Expand Down
Loading