diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cbeee39..9367d6a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d4d3103..f4cf9fd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -45,3 +45,4 @@ jobs: generate_release_notes: true files: | build/crypto.lua + build/crypto-portable.lua diff --git a/CLAUDE.md b/CLAUDE.md index 7a86adb..ce703e1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 diff --git a/Makefile b/Makefile index e1cc88f..65ef503 100644 --- a/Makefile +++ b/Makefile @@ -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."; \ diff --git a/README.md b/README.md index 5167051..e381b68 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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) ```