Policy wrapper
A policy proof shows that the requested transaction satisfies the rules in the policy circuit, the program containing the VASP’s checks. Zero knowledge keeps the circuit’s private inputs hidden. Direct verification, however, requires the policy’s verification key. A recognizable key can identify which policy was used even when its inputs remain hidden. Protecting those inputs alone does not hide the choice of policy. The policy wrapper lets the pool verify a registered policy without exposing its verification key or inner proof. It is a second circuit that checks the policy proof and confirms that the key’s hash matches a VASP’s policy registration. The key and policy proof are private inputs to this wrapper. The pool receives a proof of those checks, called the policy-wrapper proof, and verifies it through the common wrapper circuit. This gives different VASPs the same public verification mechanism while allowing their rules to remain private. The wrapper also connects the policy result to the payment being verified and its stage: initiation, acceptance, or rejection. A result for one payment cannot authorize another. The pool learns that the registered policy permits this transaction while the policy itself remains private.Policy registration
Registration connects a VASP to the policy its payments are checked against. The pool’s registry records the institution’s identifier, the hash of its policy verification key, and its messaging public key. The hash records which policy applies without publishing the policy circuit or verification key. These records form a Merkle tree:Recursive verification
The wrapper uses recursive verification: a proof is verified inside another circuit, and a second proof shows that this verification succeeded. MIP410 uses these two layers to separate the private policy from the pool’s shared verification mechanism:verify_inner constrains the policy proof to verify under the supplied key
and public inputs. MIP410’s proving backend also checks that the key’s hash
equals vk_hash, which the wrapper binds to the VASP’s registry record. The five
equalities implement the payment-context comparisons described above. phase
is 0 for initiation, 1 for acceptance, and 2 for rejection.
The policy’s public inputs become private witness values when passed into the
wrapper. The wrapper then exposes the five context values above, together with
the chain ID, pool contract address, and recipient VASP binding commitment.
It also verifies the VASP’s signature over the chain ID, pool contract address,
payment effect hash, phase, and payload commitment using the registered
messaging key. At acceptance or rejection, it checks that the VASP matches the
recipient VASP binding commitment recorded on the hold. This ties the private
policy result to an authorized VASP and the requested transaction.