#!/bin/bash
# Verify the crtlog.com proof-of-life statement.
#
# Downloads the signed statement, the detached Minisign signature, and the
# public key; verifies the signature; and checks that the statement's
# timestamp is not earlier than the referenced Monero block timestamp.
#
# Requires: minisign, jq
#
# Usage:
#   curl -sO https://crtlog.com/verify-proof-of-life.sh
#   bash verify-proof-of-life.sh

set -euo pipefail

BASE_URL="${CRTLOG_BASE_URL:-https://crtlog.com}"
MONERO_RPC_URL="${MONERO_RPC_URL:-http://xmr.stormycloud.org:18089/json_rpc}"

TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
cd "$TMPDIR"

echo "Downloading proof-of-life files from $BASE_URL..."
curl -sS -o proof-of-life.txt "$BASE_URL/proof-of-life.txt"
curl -sS -o proof-of-life.txt.minisig "$BASE_URL/proof-of-life.txt.minisig"
curl -sS -o minisign.pub "$BASE_URL/minisign.pub"

echo
echo "Verifying Minisign signature..."
minisign -Vm proof-of-life.txt -p minisign.pub

echo
echo "Checking Monero block anchor..."

HASH=$(sed -n 's/^Monero top block hash: //p' proof-of-life.txt | tr -d '[:space:]')
HEADER=$(curl -sS -X POST "$MONERO_RPC_URL" \
  -H "Content-Type: application/json" \
  -d "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"get_block_header_by_hash\",\"params\":{\"hash\":\"$HASH\"}}")

BLOCK_HEIGHT=$(echo "$HEADER" | jq -r '.result.block_header.height')
BLOCK_TIME=$(echo "$HEADER" | jq -r '.result.block_header.timestamp')

FILE_TIME=$(date -d "$(sed -n 's/^crtlog.com is under the control of the operator as of //p' proof-of-life.txt)" +%s)
NOW=$(date +%s)

printf 'Monero block height: %s\n' "$BLOCK_HEIGHT"
printf 'Monero block time:   %s\n' "$(date -d "@$BLOCK_TIME" -u '+%Y-%m-%d %H:%M:%S UTC')"
printf 'Statement time:      %s\n' "$(date -d "@$FILE_TIME" -u '+%Y-%m-%d %H:%M:%S UTC')"

if [ "$FILE_TIME" -lt "$BLOCK_TIME" ]; then
  echo "ERROR: statement timestamp is before the Monero block timestamp." >&2
  exit 1
fi

if [ "$FILE_TIME" -gt "$NOW" ]; then
  echo "ERROR: statement timestamp is in the future." >&2
  exit 1
fi

AGE_DAYS=$(( (NOW - FILE_TIME) / 86400 ))
printf '\nStatement age: %s days.\n' "$AGE_DAYS"

printf '\nVerified statement:\n'
cat proof-of-life.txt
