What a commitment is
A commitment is thekeccak256 hash of a ciphertext’s canonical stored bytes. The FHE Engine produces one for every result it computes, and the coprocessor anchors one for every encrypted input it verifies. The engine batches them and writes them to this registry.
Why commitments?
The commitment is a safety check in the decryption flow. Before decrypting anything, Teecryptor confirms that the ciphertext bytes it fetched hash to the commitment anchored onchain. It only ever decrypts a ciphertext the coprocessor actually produced, never a tampered or substituted one. The registry also makes the coprocessor accountable. Every result it has ever produced is committed publicly, permanently, and write-once, so its computation history is tamper-evident and open to independent audit. Commitments for every host chain land on one dedicated registry chain, which gives the decryption path a single place to verify against.Storage shape
commitments is the source-of-truth lookup. handlesByVersion is an array kept in parallel so paginated enumeration is O(limit) instead of O(total). Storage lives at the ERC-7201 slot derived from cofhe.storage.CommitmentRegistry, so the contract is upgrade-safe.
Version lifecycle
version is an opaque bytes32 tag chosen by the coprocessor when FHE parameters change, currently the ASCII tag "2". Every version moves through a small state machine:
The admin-only
setVersionStatus(version, newStatus) enforces these transitions and reverts with InvalidVersionTransition otherwise. The transition emits VersionStatusChanged(version, oldStatus, newStatus).
Write surface
Only accounts holding the poster role can write commitments (postCommitments, postCommitmentsSafe); posts from anyone else revert with OnlyPosterAllowed(caller). Poster management and version transitions are admin-only. In production, the poster role is held by the coprocessor’s relayer signer (OpenZeppelin Relayer).
Writing commitments
(version, handle) → commitHash rows and require:
versionis inActivestate, otherwise the call reverts withVersionNotActive(version).handles.length == commitHashes.lengthand> 0, otherwiseLengthMismatch/EmptyBatch.- Each
commitHash != bytes32(0), otherwiseZeroCommitHash(handle).
postCommitments emits CommitmentsPosted(version, batchSize). postCommitmentsSafe emits CommitmentsPostedSafe(version, newlyPosted, skipped) so the offchain caller can tell whether the round did real work.
Both enforce write-once per (version, handle): a commitment can never be overwritten, only superseded by writing the same handle under a new version.
Reading commitments
The paginated
getHandles is the recommended way to enumerate a version: getSize first to compute pages, then getHandles(version, offset, pageSize) in a loop.