#!/usr/bin/env python3
"""Second, stricter public check of Rekor v2 entry 171750012 (log2025-1.rekor.sigstore.dev).
Checks that (1) the entry Rekor serves at index 171750012 is byte-identical to rekor-entry-1.json,
(2) its RFC 6962 inclusion proof recomputes the Rekor root, (3) that Rekor checkpoint is signed by the
log2025-1 key (pinned below and cross-checked against Sigstore's public trusted_root.json), and
(4) the entry's SHA2-512 digest and Ed25519ph signature cover the honesty.tools checkpoint body
(origin www.honesty.tools/receipts, tree size 23, root 97d2ecae...d72b) under the receipt-log key.
Needs network + pycryptodome and rekor-entry-1.json from the same folder.
Usage: python3 verify_rekor_inclusion1.py"""
import base64, hashlib, json, urllib.request
from Crypto.PublicKey import ECC; from Crypto.Signature import eddsa; from Crypto.Hash import SHA512
IDX = 171750012
BODY = b"www.honesty.tools/receipts\n23\nl9LsroPm6bLAb7D4cRCyd/XoohbAdljZiCIsV7jF1ys=\n"
RECEIPT_LOG_PUB = "QX8nadAqf3QFrnY2MrSOqAhhrKhxFAYBiwrs9R0Pv4I="
REKOR_PUB = "t8rlp1knGwjfbcXAYPYAkn0XiLz1x8O4t0YkEhie244="   # log2025-1 Ed25519 key
H = lambda b: hashlib.sha256(b).digest()
d = json.load(open("rekor-entry-1.json"))
body = base64.b64decode(d["canonicalizedBody"])
n = IDX // 256
tile = urllib.request.urlopen("https://log2025-1.rekor.sigstore.dev/api/v2/tile/entries/x%03d/%03d" % (n // 1000, n % 1000)).read()
ents, i = [], 0
while i < len(tile):
    L = int.from_bytes(tile[i:i+2], "big"); ents.append(tile[i+2:i+2+L]); i += 2 + L
assert ents[IDX % 256] == body, "served entry differs from rekor-entry-1.json"
p = d["inclusionProof"]; assert int(p["logIndex"]) == IDX
fn, sn, r = IDX, int(p["treeSize"]) - 1, H(b"\x00" + body)
for s in p["hashes"]:
    s = base64.b64decode(s)
    if fn & 1 or fn == sn:
        r = H(b"\x01" + s + r)
        while not (fn & 1 or fn == 0): fn >>= 1; sn >>= 1
    else:
        r = H(b"\x01" + r + s)
    fn >>= 1; sn >>= 1
assert sn == 0 and base64.b64encode(r).decode() == p["rootHash"], "inclusion proof does not recompute root"
tr = json.loads(urllib.request.urlopen("https://raw.githubusercontent.com/sigstore/root-signing/main/targets/trusted_root.json").read())
tuf = [base64.b64decode(t["publicKey"]["rawBytes"]) for t in tr["tlogs"] if "log2025-1" in t["baseUrl"]]
assert tuf and base64.b64encode(tuf[0][-32:]).decode() == REKOR_PUB, "Rekor key differs from Sigstore trusted root"
text, sigs = p["checkpoint"]["envelope"].split("\n\n", 1)
assert text.split("\n")[1] == p["treeSize"] and text.split("\n")[2] == p["rootHash"]
sig = [l for l in sigs.splitlines() if l.startswith("\u2014 log2025-1.rekor.sigstore.dev ")][0].split()[-1]
eddsa.new(ECC.import_key(tuf[0]), "rfc8032").verify((text + "\n").encode(), base64.b64decode(sig)[4:])
e = json.loads(body)["spec"]["hashedRekordV002"]
assert base64.b64decode(e["data"]["digest"]) == hashlib.sha512(BODY).digest(), "digest mismatch"
spki = base64.b64decode(e["signature"]["verifier"]["publicKey"]["rawBytes"])
assert base64.b64encode(spki[-32:]).decode() == RECEIPT_LOG_PUB, "public key mismatch"
eddsa.new(ECC.import_key(spki), "rfc8032").verify(SHA512.new(BODY), base64.b64decode(e["signature"]["content"]))
print("OK: entry %d included in Rekor tree size %s (root %s, signed by log2025-1); covers checkpoint size 23 root %s; Ed25519ph sig by key %s"
      % (IDX, p["treeSize"], p["rootHash"], base64.b64decode(BODY.split(b"\n")[2]).hex(), RECEIPT_LOG_PUB))
