§ proof · verification guide
Don't trust Nukez. Verify it.
Every Nukez receipt is independently checkable in four ways. No account, no API key, and no trust in Nukez required — the verification path is public by design.
§ the four levels
Four checks. Each one independent.
Each level proves a specific thing. You don't need to do them all — any single one that passes gives you a specific guarantee.
Did the bytes change?
Hash the file you downloaded. Compare to the manifest's content_hash. Match means byte-identical to what was stored.
Did the set of files change?
Rebuild the merkle tree from the manifest entries. Compare to the stored root. Match means no add, remove, modify, or reorder since attestation.
Did the gateway sign it?
Verify the Ed25519 signature over the merkle root using the gateway's public key. Match means the receipt is authentic.
Did Solana see the same root?
Read the Switchboard feed and the SPL Memo on Solana. Compare the on-chain merkle root to the receipt's. Match means the root was committed at a specific slot.
§ 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.
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:
return hashlib.sha256(b"empty").hexdigest()
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.
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 · receipt signature
Did the gateway sign it?
The receipt includes an Ed25519 signature over the merkle root. Verify it with the signer's public key — both ship in the receipt.
from nacl.signing import VerifyKey
import binascii
receipt = get_receipt(receipt_id) # the full receipt object
pubkey = receipt["receipt_signer_pubkey"]
sig = receipt["receipt_sig"]
# The signed payload is the merkle_root hex string, UTF-8 encoded.
signed_payload = receipt["merkle_root"].encode("utf-8")
vk = VerifyKey(binascii.unhexlify(pubkey))
vk.verify(signed_payload, binascii.unhexlify(sig)) # raises if forgedCombined 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 merkle root — so anyone with the root can recompute it and compare.
def att_code_from_hash(h):
"""First 12 hex chars (48 bits) as int, clamped to 9 digits."""
return int(h[:12], 16) % 1_000_000_000The 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
- Get the
tx_signaturefrom the attestation response (or from the receipt'sswitchboard.txfield). - Look it up:
https://explorer.solana.com/tx/{tx_signature}. - Find the “Program Log: Memo” entry.
- Confirm the memo contains the expected
receipt_idandmerkle_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.
| Attack | What changes | Detection |
|---|---|---|
| Modify a file's content | Content hash changes → leaf changes → root changes | Root mismatch vs. on-chain attestation |
| Delete a file | Leaf count drops → tree structure changes | Root mismatch |
| Add a file | Leaf count increases → new root | Root mismatch |
| Swap a file (same name, different content) | Content hash changes → leaf changes | Root mismatch |
| Reorder files | Leaves are sorted by filename — order is canonical | Not possible by construction |
| Forge the manifest | Merkle root changes; receipt signature covers the root | Root mismatch or signature verification fails |
§ extending the chain
Verification further down.
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.
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.
| Algorithm | Chain | Key format | Use case |
|---|---|---|---|
| Ed25519 | Solana | Base58 public key | Solana-native wallets and agents |
| secp256k1 | EVM / Monad | Ethereum address (0x…) | EVM wallets, Monad chain payments |
§ cheat sheet
Five questions. Five answers.
| Question | How to check | What it proves |
|---|---|---|
| Is my downloaded file authentic? | SHA-256 locally; compare to manifest content_hash | File is byte-identical to the stored version |
| Is the manifest intact? | Rebuild merkle tree from file entries; compare to merkle_root | No files added, removed, or modified since attestation |
| Was the receipt forged? | Ed25519 signature verification with gateway public key | Receipt was produced by the gateway, unaltered |
| Is the attestation on-chain? | Look up tx_signature on Solana Explorer; read SPL Memo | Merkle root was committed to Solana at a specific slot |
| Can I verify without trusting Nukez? | Yes — every step uses public data and standard cryptography | The entire point |
§ next
Verify a real receipt.
Paste a receipt ID into the attestation explorer to run all four checks in one place — or jump to the integration docs to wire verification into your stack.
