VE + identity consistency

For Anoma, shielded in-band distribution of resources requires encryption used to provide confidentiality to be verifiable in circuits. With the addition of shielded state synchronisation, that conceptually is very similar to verifiable payload encryption, we have more keys to manage. The questions I want to tackle in this post:

  1. Verifiable encryption generalisation
  2. VFMD open questions
  3. How can we verify that the correct receiver identity was used to encrypt the data?
  4. What is the relationship between the VPE and VFMD keys?

Verifiable payload encryption
Verifiable payload encryption is designed as follows:

VPE.sk = DH(pub_{recv}, priv_{send})
ce = VPE.Encrypt(VE.sk, payload)

You can find more details here and here.

With VPE.Encrypt being a symmetric encryption scheme (e.g., for Cairo RM it is Poseidon). To derive the encryption key we either need a combination of the receiver’s public key and the sender’s private key (to encrypt) or the receiver’s private key and the sender’s public key (to decrypt). This implies that both sender and receiver should have their public keys to be discoverable.

Verifiable FMD

Verifiable FMD flag encryption works roughly as follows: flag ciphertext consists of \gamma encryptions of bit 1. With c_i being the encryption of the i-th bit, c_i = FMD.Encrypt(h_i) where h_i corresponds to the i-th public key. Flag ciphertexts, just like VPE ciphertexts, are created by the transaction creator, and therefore we need verifiability for this encryption as well. To do that, the transaction creator (solver) needs to have access to the receiver’s pk = (h_1, ..., h_{\gamma}).

We might want to switch to hybrid encryption like in the case of VE but it doesn’t change much in this context

1. Generalising VPE and VFMD

VE VPE VFMD (i-th bit) VFMD(all)
public key pk pub_{recv} pk = h_i pk = (h_1, ..., h_\gamma)
encryption key ek ek = DH.sk ek = h_i ek= pk (currently)
payload resource object + whatever else needed 1 1^\gamma
Encrypt Poseidon ElGamal (FMD2) ElGamal (FMD2)
Statement ce = VPE.Encrypt(sk, payload, nonce) \vec(f) = VFMD.Encrypt(pk, 1)[1]
Instance ce, pub_{send} (u, y, c_i)[2], ? \vec(f), ?
Witness payload, nonce, priv_{send}, pub_{recv} h_i, r, z, ? pk, r, z, ?

2. VFMD open questions

In the VPE case we can see that:

  1. the encryption algorithm is deterministic and nonce is provided from the outside
  2. we have a binding between the instance and the receiver’s public key through the combination of DH and exposing the sender’s public key

For VFMD:

  1. In the proposal, the flag ciphertext generation scheme is not deterministic (because of random generation of r, z). We probably should take this step out of the encryption algorithm to be able to reproduce it in circuit
  2. Similarly to VPE, we need a way to bind the receiver’s public key to the instance. The difference here is that in VPE we use symmetric encryption and in VFMD we use asymmetric encryption

3. Binding the receiver’s identity to the encrypted data

This problem can’t be solved by adding another ZKP constraint since we can’t prove that the key used for encryption belongs to anyone. However, this can be achieved with the help of intent logics. Let’s consider this scenario: Alice has 3 tokens A and is looking for 2 tokens B. She writes an intent logic that includes the following constraints:

  • the created resource in the transaction contains 2 tokens B
  • the keys to use for VPE/VFMD are pub^{PE}_A and pub^{FMD}_A

When the solver finds a counterparty (Bob) that is willing to give 2 tokens B for 3 tokens A, the transaction includes:

  • consumed resource (3, A, Alice): app A logic proof + Alice’s intent proof
  • created resource (2, B, Alice): …
  • encrypted resource object for Alice: (2, B, Alice) under pub^{PE}_A + priv^{PE}_S
  • FMD flag for Alice under pub^{FMD}_A
  • …
  1. Binding identity to keys: because Alice herself specified what keys to use for encryption, we can ensure the binding between the actual identity and the keys
  2. Binding keys to ciphertexts: By passing the same sets of keys to the intent logic and the VPE/VFMD proofs, we ensure that the key that Alice specified was indeed used for encryption

As a result we get identity-ciphertext binding.

4. The relationship between the VFMD and VPE keys

We don’t need to explicitly bind VPE and VFMD keys to each other because we bind them directly to the identity.

We can derive the two keys from a single master key and operate on this key instead, but conceptually it is the same.


  1. here, r, z should be explicitly provided as input to be able to reproduce the ciphertext ↩︎

  2. Because y = G(u, c_1, ..., c_\gamma), we can’t really split the ciphertext ↩︎

1 Like