# Z-Imburse Docs: ZImburseRegistry DKIM In order to authenticate emails as originating from a trusted domain, DKIM public keys are registered in a common and agreed upon registry. Public keys are pedersen hashed into a single field element for efficiency. DKIM key hashes are applicable for a specific scope - in the case of Z-Imburse, we have a set of receipt verifier types (Linode, United Airlines, etc.). To constrain a DKIM key hash to a scope, we employ a map `DKIM Key Hash (bool)` -> `Verifier ID (u8)`. This way, reimbursement claimaints can hash the DKIM key used to verify their email and check the mapping to ensure the dkim key used is valid for the entitlement type they are trying to claim. ## Shared Immutable for Key Hashes The ID of the verifier a DKIM key hash maps to is stored in a `SharedImmutable` type. The benefit here is that a claimant can contrain the lookup of the verifier ID without leaving the private context. The use of SharedMutable introduces additional complexities that are not worth delving into, and PublicMutable would leak the fact that someone is looking up a certain public key, thus leaking that a certain receipt type was claimed. :::info Trust assumption: The issue with SharedImmutable is that DKIM key hashes cannot be revoked. In V1, we do not address this issue. In a later version, we could rectify this by allowing the registry admin to emit a nullifier of the DKIM key hash, and lookups of the DKIM key would also have to prove nullifier non-inclusion to ensure the DKIM key hash is currently valid. ::: ## Functions DKIM Key hashes can be added in one go: ```rust #[public] fn register_dkim(verifier_id: Field, dkim_key_hash: Field); ``` The logic here is fairly simple - 1. the sender is constrained to be the admin stored in the definition 2. the `dkim_key_hash` is checked to not yet be initialized by checking if it maps to 0 (this may be redundant) 3. the `dkim_key_hash` is mapped to equal `verifier_id` 4. a public event is emitted notifying watchers that a new key has been added DKIM key hashes can also be added in bulk: ```rust #[public] fn register_dkim_bulk( verifier_ids: [Field; BULK_KEY_LENGTH], dkim_key_hashes: [Field; BULK_KEY_LENGTH] ); ``` The logic is the same as `register_dkim` except looped. If less than `BULK_KEY_LENGTH` should be added, the values can simply be zeroed to add less keys. There appears to be a limit of 4 public events that can be broadcast in a transaction, forcing the `BULK_KEY_LENGTH` to be 0. If we remove this broadcast step, it should be possible to add up to ~64 key hashes in a single transaction. We believe the audit record that comes with event transmision supercedes the efficiency this would give (in the absence of an indexing layer for Aztec) and have chosen to broadcast public events.