As specified in the ZK Account Authentication specification, transactions on the keystore are authenticated using ZK proofs instead of ECDSA signatures in order to abstract the smart account type from the implementation of the keystore. The authentication rule is encapsulated in the vkey for the ZK authentication circuit. We now discuss the vkey format and how to create an authentication rule in Rust using OpenVM.

ZK Authentication Rule Format

The vkey for a ZK authentication circuit is a verification key for a ZK circuit written in Halo2 using halo2-lib. It should have exactly four public inputs PI[0:4], given by:

  • PI[0:2]: bytes32 dataHash in hi-lo format
  • PI[3:4]: bytes32 msgHash in hi-lo format

where bytes32 values (a, b) form a hi-lo representation of a bytes32 value c if a and b are 16-bytes and c = (a << 128) || b, i.e. a forms the upper 16 bytes and b forms the lower 16 bytes of c.

The authentication circuit should interpret these public inputs as:

  • bytes32 dataHash: the Keccak hash dataHash = keccak256(data) of the signing data associated to the keystore account
  • bytes32 msgHash: the Keccak hash msgHash = keccak256(msg) of the message being authenticated

The authentication circuit should be written such that it is possible to generate a proof verifying against vkey only if the owner of the keystore account has authenticated the message msg based on the signing data data.

The message msg used in the msgHash will vary based on what is being authenticated. To see the choice of msg for each transaction type, see the transaction spec.

Writing an Authentication Rule in Rust

We support writing an authentication rule in Rust using OpenVM.