We Give Away Too Many of our Digital Secrets: Here’s Verifiable Oblivious Pseudorandom Functions…

In our digital world, we give away too many of our secrets, especially where we just have to prove the knowledge of something, rather than…

Photo by Kristina Flour on Unsplash

We Give Away Too Many of our Digital Secrets: Here’s Verifiable Oblivious Pseudorandom Functions (VOPRF)

In our digital world, we give away too many of our secrets, especially where we just have to prove the knowledge of something, rather than actually revealing it. In many of the systems we use, we could just prove things in an oblivious way, and where we could pass a secret but in a blinded form.

With this, a server does not discover our password and for us not to discover the identifier that a server holds on us. But, can we also provide proof back that the right password has been used? Well, with Verifiable Oblivious Pseudorandom Functions (VOPRF), we can generate a random secret based on a key generated on the server (Alice), and which is based on Bob’s secret:

Initially, Bob generates his secret, and the blinds it. This blind value is then sent to Alice, and then who uses her private key to produce proof values to go back to Bob (r). Bob then finalises the PRF, by taking his secret value, and the proof. Overall Alice does not learn about Bob’s secret, and Bob does not learn about Alice’s key. We can set up Bob and Alice with:

key, _ := oprf.GenerateKey(id, rand.Reader)
alice, _ := oprf.NewVerifiableServer(id, key)
bob, _ := oprf.NewVerifiableClient(id, key.Public())

and next Bob can generate the blinded value for his secret (pass) to send to Alice:

cl, _ := bob.Request([][]byte{[]byte(pass)})
EV, _ := alice.Evaluate(cl.BlindedElements(), nil)

The value of EV is then sent back to Bob, who then generates the PRF:

Bob_token, _ := bob.Finalize(cl, EV, nil)

If Alice needs to prove the PRF (pseudorandom function), she can take the actual inputs, and prove with:

rtn := alice.VerifyFinalize([]byte(pass), nil, Bob_token)
token, _ := alice.FullEvaluate([]byte(pass), nil)

A core advantage of VOPRF is that the client (Bob) can check that the server (Alice) has used a committed secret key — and where Alice’s public key verifies that private key that has been used — within the Evaluation() method (on Alice’s side), and which is checked in the Finalize() method on Bob’s side. The full code using Cloudflare CIRCL is here:

https://asecuritysite.com/circl/circl_voprf

The method we have outlined provides an excellent way of creating a trust infrastructure, such as for IoT devices, and where we can generate encryption keys for these devices, using a secret stored on the device, and a trust server’s secret key. For the keys used, we can then prove they usage, if required.

Conclusions

Oblivious transfers (OT) and the blinding of data are just two ways of implementing zero-knowledge proofs. If you want to learn more about these, try here:

https://asecuritysite.com/zero/

and for Cloudflare CIRCL:

https://asecuritysite.com/circl/