@celo/poprf
v0.1.9
Published
A threshold-computable partially-oblivous psuedo-random function
Downloads
71
Keywords
Readme
Pith POPRF
:warning: Functionality in this repository has not undergone detailed security review. It should be used with caution. It may contain unknown vulnerabilities and based on results of further review, it may be changed in backwards incompatible ways.
This repository implements a threshold-computable partially-oblivious pseudo-random function (POPRF) with evaluations that are verifiable by the client.
A partially-oblivious PRF (POPRF) is a protocol between a client and a server to evaluate the keyed pseudo-random function F(k, t, m). The client provides the tag input, t, and message input, m. The server provides the secret key input k. During the exchange the server learns the client-provided tag, but gains no other information. In particular, they learn nothing about the message. The client learns the output of the PRF function F, but no other information about the secret key held by the server.
Building upon the existing BLS threshold signature based OPRF implemented for use on Celo in ODIS, this repository implements an extension to the Pythia POPRF specification to provide threshold computation and verification against a single pre-shared public key. This construction is called Pith for its basis on Pythia and usage in the Celo PIN/Password Encrypted Account Recovery protocol PEAR.
At a high level, the POPRF is a protocol with a client and a service who collectively compute a keyed PRF (i.e. essentially a hash) over a tag input and a message input. The message input is secret to the client, and the private key input is secret to the service. In order to compute the final function the client "blinds" the message and sends it, along with the tag, to the service. The service may choose to compute the POPRF function over this blinded message and plaintext tag, resulting in a blinded evaluation. This is sent back to the client, who unblinds the evaluation to get the final output. More details are available in the specification below.
Specification
The specification linked above is also available in this repository as specification.md.
Applications
Some applications of (P)OPRFs include:
- Password hardening
- Anonymous credentials
- Private set intersection
WASM bindings
This library provides WASM bindings for signing under the ffi/wasm.rs
module. These can be built
via the wasm-pack
tool. Depending on the platform you are
targeting, you'll need to use a different build flag.
Note: You can also replace celo
with your own NPM username to test publish.
# Builds the WASM and wraps it as NPM package @celo/poprf
wasm-pack build --target nodejs --scope celo -- --features=wasm
The bundled WASM package will be under the pkg/
directory. You can then either pack and publish it
with wasm-pack
's pack
and publish
commands, or manually import it in your application.
wasm-pack publish --access public
TypeScript usage
Here is an example of using the library. In practice there will be a client and a server, with the assumption that the client holds the message and the server holds the private key. In this snippet, both client and server are represented.
import * as poprf from '@celo/poprf'
import 'crypto'
const message = Buffer.from("message")
const tag = Buffer.from("tag")
// Generate a local keypair for demonstration purposes.
const keypair = poprf.keygen(crypto.randomBytes(32))
// Client: Blind the message to send to the server.
const { blindedMessage, blindingFactor } = poprf.blindMsg(message, crypto.randomBytes(32))
// Server: Evaluate the POPRF over the blinded message and tag.
const response = poprf.blindEval(keypair.privateKey, tag, blindedMessage)
// Client: Unblind and verify the evaluation returned from the server.
const result = poprf.unblindResp(keypair.publicKey, blindingFactor, tag, response)