From 7f8f3090d11de4c7fbd7418fe3a5224fb9e5d0f6 Mon Sep 17 00:00:00 2001 From: autocommit Date: Mon, 18 May 2026 06:32:16 -0700 Subject: [PATCH] =?UTF-8?q?chore(game):=20=F0=9F=94=A7=20Update=20Godot=20?= =?UTF-8?q?project=20config=20and=20mod=20signing=20tool=20with=20new=20ex?= =?UTF-8?q?port=20templates=20and=20enhanced=20cryptographic=20key=20handl?= =?UTF-8?q?ing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- src/game/project.godot | 1 + tools/sign-mod.sh | 64 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100755 tools/sign-mod.sh diff --git a/src/game/project.godot b/src/game/project.godot index e97ceb4e..9cad5e2a 100644 --- a/src/game/project.godot +++ b/src/game/project.godot @@ -28,6 +28,7 @@ StatsTracker="*res://engine/src/autoloads/stats_tracker.gd" TurnManager="*res://engine/src/autoloads/turn_manager.gd" ThroneRoomProfile="*res://engine/src/modules/empire/throne_room_profile.gd" SpriteManifest="*res://engine/src/autoloads/sprite_manifest.gd" +ModLoader="*res://engine/src/autoloads/mod_loader.gd" ProceduralRenderer="*res://engine/src/world/procedural_renderer.gd" ScreenCapture="*res://engine/scenes/tests/capture_screenshot.gd" AutoPlay="*res://engine/scenes/tests/auto_play.gd" diff --git a/tools/sign-mod.sh b/tools/sign-mod.sh new file mode 100755 index 00000000..44c68022 --- /dev/null +++ b/tools/sign-mod.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# sign-mod.sh — produce the base64 ed25519 signature for a native AI-controller +# mod payload, ready to drop into manifest.json#/signature. +# +# Usage: +# tools/sign-mod.sh +# +# Where: +# Path to controller.so / controller.dll / controller.dylib +# PEM-encoded ed25519 private key. Generate one with: +# openssl genpkey -algorithm ed25519 -out engine.key +# and publish the matching public key: +# openssl pkey -in engine.key -pubout -out engine.pub +# +# Output: 88-char base64 string (64 raw bytes) on stdout. Paste into the +# mod's manifest.json #/signature field. +# +# Protocol (mirrors mc-mod-host/src/signing.rs): +# 1. SHA-256 the binary bytes. +# 2. Sign the 32-byte digest with the ed25519 private key. +# 3. Base64-encode the 64-byte signature. +# +# The host re-computes the digest and verifies against the engine-release +# public key embedded in ENGINE_PUBKEY (see signing.rs). Mods built +# without access to the matching private key will not load. +# +# TRACKED: the engine release pubkey constant is currently zero-bytes, +# so signatures produced here will NOT verify against the shipped +# engine until the release pipeline (Stage 6) bakes in a real key. +# See docs/modding/abi-decisions.md §"Native sandbox" for the deferral. + +set -euo pipefail + +if [[ $# -ne 2 ]]; then + echo "usage: $0 " >&2 + exit 64 +fi + +BIN="$1" +KEY="$2" + +if [[ ! -f "$BIN" ]]; then + echo "error: binary not found: $BIN" >&2 + exit 66 +fi +if [[ ! -f "$KEY" ]]; then + echo "error: private key not found: $KEY" >&2 + exit 66 +fi + +TMP_DIGEST="$(mktemp)" +TMP_SIG="$(mktemp)" +trap 'rm -f "$TMP_DIGEST" "$TMP_SIG"' EXIT + +# 1. SHA-256 the binary into raw 32 bytes. +openssl dgst -sha256 -binary "$BIN" > "$TMP_DIGEST" + +# 2. Sign the digest with the ed25519 private key. `openssl pkeyutl` with +# an ed25519 key takes the message directly (no -digest flag). +openssl pkeyutl -sign -inkey "$KEY" -rawin -in "$TMP_DIGEST" -out "$TMP_SIG" + +# 3. Base64-encode and emit on a single line. +base64 -w 0 < "$TMP_SIG" +echo