Announcing our Verifiable Random Function (VRF) library in Solidity

The first VRF implementation written in Solidity supporting fast and effective VRF proof verifications based on ECC

Recently Gorka Irazoqui Apecechea and me proudly published a VRF Solidity library as an open source project under the MIT license.

The library is a fast and effective Verifiable Random Function (VRF) library written in Solidity, which follows the IETF standard VRF-draft-04 authored by Sharon Goldberg, Moni Naor, Dimitris Papadopoulos, Leonid Reyzin, and Jan Včelák.

This library is the continuation of our work implementing several cutting-edge cryptographic primitives that power the critical components of the Witnet ecosystem. This is also the case of our Elliptic Curve Solidity library and our VRF Rust library.

What are VRFs?

VRFs are cryptographic primitives that provide a pseudo-random function along with a publicly verifiable proof of its outputs’ correctness.

VRFs are widely used in various cryptographic schemes, protocols and systems. For example, the Witnet decentralized oracle network uses VRFs to conduct the secret cryptographic sortition that is used for selecting miners and witnessing committees as part of the underlying consensus protocol.

For more details about VRFs and why they are so important in current cryptographic systems, take a look into this previous post:

Introducing the library

vrf-solidity is a fast and effective implementation of Verifiable Random Functions (VRFs) written in Solidity. In the current 0.1.0 version, the library implements verification functions for VRF proofs based on the secp256k1 elliptic curve.

The library provides two functions for verifying VRF proofs with different cost/security trade-offs.

verify : VRF proof full verification as described in the draft. It has a high associated gas cost as it requires heavy EC computations.

: VRF proof full verification as described in the draft. It has a high associated gas cost as it requires heavy EC computations. fastVerify: VRF proof fast verification by providing additional EC points. It requires far less gas by leveraging the EVM’s ecrecover precompiled function to verify EC multiplications.

Additionally, it provides three convenience functions that ease computation of the required input parameters:

decodeProof : decode from bytes to VRF proof.

: decode from bytes to VRF proof. decodePoint : decode from bytes to EC point.

: decode from bytes to EC point. computeFastVerifyParams: compute the parameters (EC points) required for the VRF fast verification function.

The library implements the SECP256K1_SHA256_TAI cipher suite, i.e. the secp256k1 elliptic curve and the sha256 digest function.

Example

Solidity contracts can use the VRF.sol contract directly either by inheritance or by instantiating it:

pragma solidity ^0.5.0;



import "vrf-solidity/contracts/VRF.sol";





contract MyContract is VRF {



function functionUsingVRF(

uint256[2] memory _publicKey,

uint256[4] memory _proof,

bytes memory _message)

public returns (bool)

{

bool isValid = verify(_publicKey, _proof, _message);

// Do something...

return isValid;

}

}

You can find more advanced examples in the Github repository:

Gas analysis

Gas consumption analysis was conducted in order to understand the associated costs to the usage of the vrf-solidity library given the fact that VRFs primitives entail heavy EC operations.

We performed the gas consumption analysis on a contract inheriting from VRF.sol and wrapping that contract’s functions for different VRF primitives, labelled as _methodName .

Gas consumption and USD price estimation with a gas price of 20 Gwei, derived from ETH Gas Station:

As aforementioned, the library provides two different verification functions with different trade-offs in terms of cost and security. The cost of the fastVerify() function is around 10% that of the verify() function, approximately 200k of gas, which is less than 1 USD with the current gas and ether prices.

The three convenience functions ( decodeProof , decodePoint and computeFastVerifyParams ) are provided in order to facilitate the computation of VRF required input parameters. If possible, they should be used as off-chain operations through a local call in order to avoid gas costs.

Tests

The vrf-solidity library has been tested against test vectors extracted from Chuck Batson and the vrf-rs with the SECP256K1_SHA256_TAI cipher suite.

Please take into consideration that VRFs are currently being standardized and there are not many (if any) resources with test vectors for our very same cipher suite.

Acknowledgements

We would want to acknowledge the following resources as they served as inspiration to increase the performance of some of the EC arithmetic operations: