Skip to content
Oblivious pseudorandom function over an elliptic curve
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
dist-web
doc
docs
src
test
.editorconfig
.gitignore
.travis.yml
LICENSE
README.md
package-lock.json
package.json
tsconfig.json
tslint.json
typings.json
webpack.config.js

README.md

OPRF

npm version Build Status Coverage Status

Oblivious pseudo-random function over an elliptic curve (ED25519)

Installation

npm install oprf

Initialization

The sumo version of libsodium must be used

await _sodium.ready;
const oprf = new OPRF(_sodium);

Security Guarantees

A client has input x while a server holds key k. The client receives the output of fk(x) for some pseudorandom function family fk. The server learns nothing.

Dependencies

Public Interface

Contains a masked point and the mask that was applied to it

export interface IMaskedData {
  readonly point: number[];
  readonly mask: BN; // big number
}

Public Functions

hashToPoint: maps string input to a point on the elliptic curve

public hashToPoint(input: string): number[]

maskInput: hashes string input as a point on an elliptic curve and applies a random mask to it

public maskInput(input: string): IMaskedData

generateRandomScalar: generates a random 32-byte array of numbers

public generateRandomScalar(): BN

isValidPoint: returns whether the given point exists on the elliptic curve

public isValidPoint(point: number[]): number

encodePoint: converts an elliptic.js point representation to number array representation

public encodePoint(point: any): number[]

decodePoint: converts a number array to elliptic.js point object representation

public decodePoint(point: number[]): any 

unmaskInput: applies the multiplicative inverse of the mask to the masked point

public unmaskInput(maskedPoint: number[], mask: BN): number[]

OPRF Steps

1.) Client: hash input and mask it using a randomly generated 32-byte number

const input = 'hello world';
const masked = oprf.maskInput(input);

// Send masked.point to server. Do not send masked.mask to the server since it can easily unmask your original input.

2.) Server: salt the masked point using a secret key

// Note: your actual secret key should be a static 32-byte Uint8Array. Do not generate a new scalar for each OPRF unless you have a specific use case for doing so.
const secretKey = oprf.generateRandomScalar(); 
const salted = oprf.scalarMult(maskedPoint, secretKey);

// Send salted back to the client

3.) Client: unmask the salted point from the server to get a high-entropy output

// Make sure that masked.mask corresponds to the original mask used. 
// Otherwise, this will not give you the correct output. 
const unmasked = oprf.unmaskInput(salted, masked.mask);

Implementation inspired by Burns et. al. https://pdfs.semanticscholar.org/5d33/ea1d3fda454875a6a6ee7c535c80c74af512.pdf

You can’t perform that action at this time.