I wrote an implementation of a non-interactive zero-knowledge proof system as outline in this research paper. As far as I can tell, it functions flawlessly as intended with text secrets such as authentication passwords.
# USER REGISTRATION:
# CLIENT-SIDE
client_zk = ZKProof.new(bits=256, curve_name="secp256k1")
signature = client_zk.create_signature("Passw0rd")
# send zk.params and signature to server for persistent storage
# USER AUTHENTICATION:
# SERVER-SIDE
server_zk = ZKProof(client_zk.params)
token = ZKProof.random_token(bits=256)
# send token to client
# CLIENT-SIDE
challenge = client_zk.create_challenge("Passw0rd", token)
# send challenge to server
# SERVER-SIDE
if server_zk.prove_challenge(challenge, signature, token):
# user is authenticated...
While this use case is great for something like user databases, it does nothing for data protection. I am designing an application which will store encrypted text on the server. If I use a symmetric encryption algorithm, I can create proofs to ensure that the user is in possession of a particular password (assuming it was honestly registered when the key was created), however I have no way of VERIFYING that the encrypted data received by the server was indeed encrypted using that password since the server does not have access to the plain text OR encryption key. How can I best approach this?
Note: I CAN actually verify that a password (or key) was used to generate a zero-knowledge PROOF, but not the actual integrity of the data itself.