Skip to main content

BROWSER VERIFIER

Verify a receipt without trusting RANKIGI.

Paste a chain export or load the sample. Verification runs locally in your browser and recomputes the hash chain before showing a result.

INPUT

Chain export

No telemetry. No API key. No upload to RANKIGI.

RESULT

Verification receipt

READY
Pasted
Checked
Verified
VERIFICATION RECORDAWAITING INPUT
STATUS
READY
EVENTS
--
HEAD INDEX
--
HEAD HASH
--
CHECKS
--
ENGINE
SHA-256 via Web Crypto

WHAT THIS PROVES

The submitted export is internally consistent under the verifier checks shown below.

WHAT IT DOES NOT PROVE

It does not prove every real-world action was submitted to RANKIGI.

EXECUTION TRACE

Every check is visible.

The verifier parses the export, recomputes hashes, checks links, validates monotonic indexes, and reports skipped checks explicitly.

01Parse JSONSKIP
02Schema conformanceSKIP
03Hash recomputationSKIP
04Chain link integritySKIP
05Index monotonicSKIP
06Passport validitySKIPno passport in sample
07X.509 cert chainSKIPno certificate in sample

REFERENCE VERIFIER

Run the same logic outside the browser.

The Python reference uses the standard library only. It is included so a reviewer can validate the same chain without this website.

Download verify.py
# SPDX-License-Identifier: MIT
# KYA V10 Steel-Core Verification Engine
import hashlib, json, sys, unicodedata

class RankigiV10:
    def __init__(self):
        self.head = None
        self.count = 0

    def _canonicalize(self, data):
        if isinstance(data, str):
            return json.dumps(
                unicodedata.normalize('NFC', data)
            )
        if isinstance(data, (int, bool)) \
                or data is None:
            return json.dumps(data)
        if isinstance(data, dict):
            items = [
                f"{self._canonicalize(k)}:"
                f"{self._canonicalize(data[k])}"
                for k in sorted(data.keys())
            ]
            return "{" + ",".join(items) + "}"
        if isinstance(data, list):
            return "[" + ",".join(
                self._canonicalize(x) for x in data
            ) + "]"
        raise TypeError(
            f"V10 Protocol Error: "
            f"Unsupported type {type(data)}"
        )

    def verify_event(self, event):
        idx = event.get("chain_index")
        provided_hash = event.get("event_hash")
        prev_hash = event.get(
            "previous_event_hash"
        )
        if idx != self.count:
            raise ValueError(
                f"GAP_DETECTED: Expected "
                f"{self.count}, got {idx}"
            )
        if prev_hash != self.head:
            raise ValueError(
                f"LINKAGE_ERROR: Break at {idx}"
            )
        body = {
            k: v for k, v in event.items()
            if k != "event_hash"
        }
        serialized = self._canonicalize(
            body
        ).encode('utf-8')
        computed = hashlib.sha256(
            serialized
        ).hexdigest()
        if computed != provided_hash:
            raise ValueError(
                f"INTEGRITY_FAILURE: "
                f"Tamper detected at {idx}"
            )
        self.head = computed
        self.count += 1
        return self.head

if __name__ == "__main__":
    engine = RankigiV10()
    try:
        data = json.load(sys.stdin)
        for ev in data:
            engine.verify_event(ev)
        print(
            f"VERIFIED: {engine.count} events"
            f" | HEAD: {engine.head}"
        )
    except Exception as e:
        print(f"SECURITY_ALERT: {str(e)}")
        sys.exit(1)

PASSPORT STATUS

Check revocation without an account.

Query the public revocation endpoint for a passport identifier. Results are fetched fresh and are not cached.