Nukez

§ proof · verification guide

The Canonical Attestation & Verification Guide

Each Nukez receipt is gateway-signed, content-addressed JSON record cryptographically bound to the purchasing keypair. Nukez receipts serve as a durable authorization token and is proof of title. External verification is enabled by anchoring receipts on-chain via the Switchboard attestation pipeline.

4 levels · independentSHA-256 · Ed25519 · secp256k1No account required

§ level 1 · file integrity

Did the bytes change?

After downloading a file from a Nukez locker, compute its SHA-256 hash locally and compare against the content_hash recorded in the locker manifest.

import hashlib

# Download the file bytes (via SDK, MCP, or raw HTTP)
file_bytes = downloaded_content

# Compute SHA-256
local_hash = "sha256:" + hashlib.sha256(file_bytes).hexdigest()

# Compare against manifest entry
assert local_hash == manifest_entry["content_hash"]

Match — the file you hold is byte-identical to what was stored. Mismatch — the content has been modified since storage.

§ level 2 · manifest + merkle integrity

Did the set of files change?

The manifest lists every file with filename, size, and content hash. The merkle root is computed deterministically from these entries — any change to any file produces a different root. The normative algorithm and test vectors live in the Merkle V1 spec.

Merkle leaf

leaf = SHA256("{filename}:{size_bytes}:{content_hash}")

content_hash is the raw hex digest in the leaf computation (no sha256: prefix).

Merkle tree (bottom-up)

  • Sort all leaves alphabetically by filename.
  • Compute SHA-256 of each leaf string.
  • Pair leaves left-to-right; if odd, the last leaf pairs with itself.
  • Parent = SHA-256(left_hex + right_hex) — concatenate the hex strings, then hash.
  • Repeat until one root remains.
import hashlib

def build_merkle_root(file_entries):
    """
    file_entries: list of dicts with 'filename', 'size_bytes', 'content_hash'
    content_hash values should be raw hex (no 'sha256:' prefix)
    """
    if not file_entries:
        raise ValueError("empty file lists are invalid for Nukez attestations")

    sorted_entries = sorted(file_entries, key=lambda e: e["filename"])

    # Compute leaf hashes
    leaves = []
    for entry in sorted_entries:
        raw_hash = entry["content_hash"].replace("sha256:", "")
        leaf_data = f"{entry['filename']}:{entry['size_bytes']}:{raw_hash}"
        leaf_hash = hashlib.sha256(leaf_data.encode("utf-8")).hexdigest()
        leaves.append(leaf_hash)

    # Build tree bottom-up
    level = leaves
    while len(level) > 1:
        next_level = []
        for i in range(0, len(level), 2):
            left = level[i]
            right = level[i + 1] if i + 1 < len(level) else level[i]
            combined = hashlib.sha256((left + right).encode("utf-8")).hexdigest()
            next_level.append(combined)
        level = next_level

    return level[0]

Compare your computed root against the merkle_root in the attestation. Match means no file has been added, removed, modified, or reordered since attestation.

Skip the loop: recompute-verify

Rather than rebuilding the tree yourself, you can ask the gateway to do it. This is a convenience, not a trust dependency — you can always recompute locally. The endpoint is public, no authentication required.

recompute-verify is different from /v1/storage/verify. Plain /verify is a cheap, cached snapshot: it trusts the manifest's recorded content hashes and reports the last attested Merkle root. The recompute-verify endpoint does real byte-level work — it re-downloads every file from storage, re-hashes the bytes, rebuilds the tree, and compares to the anchored root. Use /verify for quick status checks; reach for recompute-verify when you need to prove the actual stored bytes still match what was attested. Cost scales with locker size — that's the intended trade-off.

GET /v1/storage/recompute-verify?receipt_id={receipt_id}

# Response
{
    "match": true,
    "receipt_id": "8239fc15efc46042",
    "locker_id": "locker_62e358731c6f",
    "computed": "sha256:6a0c80f5c0a3...",
    "stored":   "sha256:6a0c80f5c0a3...",
    "file_count": 1,
    "recompute_ms": 1040
}

If match is false, either the locker contents changed since attestation, or the stored attestation was tampered with. Either way — you know.

§ level 3 · attestation signature

Did the gateway sign it?

The attestation includes an Ed25519 signature over the merkle root. Verify it with the published signer public key.

from nacl.signing import VerifyKey
import binascii

attestation = get_attestation(receipt_id)
pubkey = published_gateway_pubkey
sig    = attestation["manifest_signature"]

# The signed payload is the merkle_root hex string, UTF-8 encoded.
signed_payload = attestation["merkle_root"].removeprefix("sha256:").encode("utf-8")

vk = VerifyKey(binascii.unhexlify(pubkey))
vk.verify(signed_payload, binascii.unhexlify(sig))  # raises if forged

Combined with Level 2 — which binds the manifest to the merkle root — this transitively binds the manifest to the signer. Any modification to the manifest produces a different root, and the signature no longer covers it.

§ level 4 · on-chain attestation

Did Solana see the same root?

Nukez anchors attestations on Solana through two complementary mechanisms. Either is sufficient on its own; together they give you both a numerical comparison and a permanent log entry.

Switchboard oracle feed

The attestation code (att_code) is pushed to a Switchboard PullFeed account on Solana. The code is derived from the result_hash — so anyone with the verification bundle can recompute it and compare.

def att_code_from_hash(result_hash):
    """First 12 hex chars (48 bits) as int, clamped to 9 digits."""
    h = result_hash.removeprefix("sha256:")
    return int(h[:12], 16) % 1_000_000_000

The oracle's Ed25519 signature over the quote is verified by Solana's Ed25519 precompile — no trust in the oracle itself is needed.

SPL Memo

The full attestation metadata is written as an SPL Memo in the same transaction — permanently readable in the Solana transaction log via any block explorer.

{
    "schema": "nukez/attestation/v1",
    "receipt_id": "8239fc15efc46042",
    "merkle_root": "sha256:abc123...",
    "file_count": 42,
    "attested_at": "2026-02-11T..."
}

Verifying on-chain

  1. Get the tx_signature from the attestation response (or from the receipt's switchboard.tx field).
  2. Look it up: https://explorer.solana.com/tx/{tx_signature}.
  3. Find the “Program Log: Memo” entry.
  4. Confirm the memo contains the expected receipt_id and merkle_root.

§ tamper evidence

Every attack vector. Detected.

Every modification produces a different merkle root. There is no way to modify content and preserve the root — the math does not allow it.

AttackWhat changesDetection
Modify a file's contentContent hash changes → leaf changes → root changesRoot mismatch vs. on-chain attestation
Delete a fileLeaf count drops → tree structure changesRoot mismatch
Add a fileLeaf count increases → new rootRoot mismatch
Swap a file (same name, different content)Content hash changes → leaf changesRoot mismatch
Reorder filesLeaves are sorted by filename — order is canonicalNot possible by construction
Forge the manifestMerkle root changes; receipt signature covers the rootRoot mismatch or signature verification fails

§ extending the chain

Verification further down.

§ cross-agent

No shared keys. No shared accounts.

Agent A stores data and gets a receipt_id. Agent A passes it to Agent B. Agent B verifies — locally or via recompute-verify — using only the receipt ID. Agent B now has independent cryptographic proof of what Agent A stored, when, and that it hasn't been tampered with.

§ gateway self-verify

Verifying the verifier.

The gateway hashes its own running source against an on-chain attestation. If the gateway's code has been modified after deployment, the verification fails.

GET /v1/self-verify

Supported signatures

Both algorithms produce the same receipt structure, the same verification path, and the same attestation chain. Neither is primary — both are first-class.

AlgorithmChainKey formatUse case
Ed25519SolanaBase58 public keySolana-native wallets and agents
secp256k1EVM / MonadEthereum address (0x…)EVM wallets, Monad chain payments

§ cheat sheet

Five questions. Five answers.

QuestionHow to checkWhat it proves
Is my downloaded file authentic?SHA-256 locally; compare to manifest content_hashFile is byte-identical to the stored version
Is the manifest intact?Rebuild merkle tree from file entries; compare to merkle_rootNo files added, removed, or modified since attestation
Was the receipt forged?Ed25519 signature verification with gateway public keyReceipt was produced by the gateway, unaltered
Is the attestation on-chain?Look up tx_signature on Solana Explorer; read SPL MemoMerkle root was committed to Solana at a specific slot
Can I verify without trusting Nukez?Yes — every step uses public data and standard cryptographyThe entire point

§ next

Verify a real receipt.

Paste a receipt ID into the public verifier to inspect the proof checks in one place — or jump to the integration docs to wire verification into your stack.