Merkle proofs
Witness exposes two related inclusion-proof formats. They must not be confused.
Bundle batch inclusion
In a ProofBundle, batch_inclusion is either null or:
BatchInclusion {
batch: AttestationBatch,
merkle_proof: MerkleProof
}
AttestationBatch fields are id, network_id, merkle_root,
period_start, period_end, and attestation_count. MerkleProof fields
are leaf, siblings, leaf_index, tree_size, and root. The leaf is the
attestation hash before Merkle leaf hashing; siblings are bottom-up; the index
is zero-based; and the root and all byte arrays are lowercase hex strings in
JSON.
Bundle verification requires the proof leaf to equal the signed attestation
hash, the proof root to equal the batch root, the batch to belong to the home
network, the index to be below attestation_count, and tree_size to equal
that count. It then checks the position-aware RFC 9162 path. An invalid or
missing optional proof does not invalidate a good home threshold signature,
but it prevents a Batched or Federated result.
Batch proof endpoint
GET /v1/proof/{hash}
This returns MerkleProofResponse with hash, proof, index,
merkle_root, and batch_id. It is a legacy batch response and is distinct
from batch_inclusion in a bundle.
Transparency-log inclusion
GET /v1/log/proof?hash={hash}&tree_size={tree_size}
This returns LogInclusionProofResponse with leaf_index, tree_size,
audit_path, and a SignedTreeHead. Its path is checked against the STH's
committed root. The STH threshold signature must be verified separately with
the network configuration; an inclusion path alone is not an authenticated
checkpoint.