#!/usr/bin/env bash # Sign DRG-XMRig release archives for the wallet's in-app updater (opt-in ed25519 signatures). # # The wallet verifies a detached ed25519 signature over the EXACT archive bytes against a public # key pinned in src/util/xmrig_updater.h (kXmrigSignaturePublicKeyBase64). For each archive # .zip this produces .zip.sig containing the base64 ed25519 signature — upload that # .sig next to the .zip as a release asset. # # Keys are 32-byte ed25519: the secret key signs (keep OFFLINE), the public key goes in the wallet. # # Usage: # scripts/sign-xmrig-release.sh keygen [out-prefix] # -> .ed25519.{key,pub.b64} # scripts/sign-xmrig-release.sh sign ... # -> .sig per file # scripts/sign-xmrig-release.sh pubkey # print the base64 public key to pin # # Requires python3 with PyNaCl (pip install pynacl). PyNaCl uses the same libsodium primitives the # wallet verifies with, so signatures are guaranteed compatible. set -euo pipefail die() { echo "error: $*" >&2; exit 1; } command -v python3 >/dev/null || die "python3 not found" python3 -c 'import nacl.signing' 2>/dev/null || die "PyNaCl missing — run: pip install pynacl" cmd="${1:-}"; shift || true case "$cmd" in keygen) prefix="${1:-drg-xmrig}" python3 - "$prefix" <<'PY' import sys, base64, nacl.signing prefix = sys.argv[1] sk = nacl.signing.SigningKey.generate() open(prefix + ".ed25519.key", "wb").write(bytes(sk)) import os; os.chmod(prefix + ".ed25519.key", 0o600) pub_b64 = base64.standard_b64encode(bytes(sk.verify_key)).decode() open(prefix + ".ed25519.pub.b64", "w").write(pub_b64 + "\n") print("secret key : %s.ed25519.key (KEEP OFFLINE, mode 600)" % prefix) print("public key : %s.ed25519.pub.b64" % prefix) print() print("Pin this in src/util/xmrig_updater.h (kXmrigSignaturePublicKeyBase64):") print(" %s" % pub_b64) PY ;; sign) [ $# -ge 2 ] || die "usage: sign ..." keyfile="$1"; shift for f in "$@"; do [ -f "$f" ] || die "no such file: $f" python3 - "$keyfile" "$f" <<'PY' import sys, base64, nacl.signing keyfile, f = sys.argv[1], sys.argv[2] sk = nacl.signing.SigningKey(open(keyfile, "rb").read()) sig = sk.sign(open(f, "rb").read()).signature # 64-byte detached ed25519 signature open(f + ".sig", "w").write(base64.standard_b64encode(sig).decode() + "\n") print("signed: %s -> %s.sig" % (f, f)) PY done echo "Upload each .sig as a release asset next to its archive." ;; pubkey) [ $# -ge 1 ] || die "usage: pubkey " python3 - "$1" <<'PY' import sys, base64, nacl.signing sk = nacl.signing.SigningKey(open(sys.argv[1], "rb").read()) print(base64.standard_b64encode(bytes(sk.verify_key)).decode()) PY ;; *) die "usage: $0 {keygen [prefix] | sign ... | pubkey }" ;; esac