Only allow specific types of data to be transmitted via an end-to-end encryption service I have a service that allows multiple parties to share domain-specific textual data. This data is also end-to-end encrypted. How can I be sure the sharing parties don't send non-domain-specific data, considering I receive it encrypted?

For example, assuming I require a specific algorithm to be used for the encryption, is there either:


a zero-knowledge proof that would verify that the original data matches a given regular expression


or


a homomorphic identity operation that, applied to valid domain-specific encrypted data, would result in no change to the data, but applied to anything else, would result in undecryptable garbage
One (very generalized) solution would be to use a general ZKP solution like libsnark.

In libsnark (and other tools like it), you would write a function that accepts both public and private inputs, and outputs a proof that the inputs satisfy the logic of the function. This proof can then be verified, at a much lower cost than it took to generate it.

E.g., you might have:

public_inputs = { encrypted_string, regex, length }
private_inputs = { plaintext_string }

function(public_inputs, private_inputs)
  s = encrypt(plaintext_string)
  check1 = (encrypted_string == s)
  check2 = (length(plaintext_string) == length)
  check3 = string_fits_regex(plaintext_string, regex
  return (check1 and check2 and check3)


Libsnark gives you one algorithm for "prove" and one for "verify".

The sender would then call "prove", which would generate the proof, and then send the proof along with the encrypted string.

Then you (or the receiver), could call "verify" with the same public inputs and it would say "yes" or "no".

There's a lot more details, check the references at the end of that repo's README page. Here's a good illustration from a (somewhat related) blog post.

I bet there are other, even better (less computationally intensive) solutions as well.