/vrf-solidity

Verifiable Random Function (VRF) library written in Solidity

Primary LanguageSolidityMIT LicenseMIT

vrf-solidity npm version TravisCI

vrf-solidity is an open source fast and effective implementation of Verifiable Random Functions (VRFs) written in Solidity. More precisely, this library implements verification functions for VRF proofs based on the Elliptic Curve (EC) Secp256k1.

DISCLAIMER: This is experimental software. Use it at your own risk!

The solidity library has been designed aiming at decreasing gas consumption and its complexity due to EC operations.

It provides two main pure functions for verifying VRF proofs:

  • verify:
    • Description: VRF full verification (requires heavy EC computation)
    • Inputs:
      • _publicKey: The public key as an array composed of [pubKey-x, pubKey-y]
      • _proof: The VRF proof as an array composed of [gamma-x, gamma-y, c, s]
      • _message: The message (in bytes) used for computing the VRF
    • Output:
      • true, if VRF proof is valid
  • fastVerify:
    • Description: VRF fast verification by providing additional EC points. It uses the ecrecover precompiled function to verify EC multiplications (lower gas consumption).
    • Inputs:
      • _publicKey: The public key as an array composed of [pubKey-x, pubKey-y]
      • _proof: The VRF proof as an array composed of [gamma-x, gamma-y, c, s]
      • _message: The message (in bytes) used for computing the VRF
      • _uPoint: The u EC point defined as U = s*B - c*Y
      • _vComponents: The components required to compute v as V = s*H - c*Gamma
    • Output:
      • true, if VRF proof is valid

Additionally, the library provides some auxiliary pure functions to facilitate computing the aforementioned input parameters:

  • decodeProof:
    • Description: Decode from bytes to VRF proof
    • Input:
      • _proof: The VRF proof as bytes
    • Output:
      • The VRF proof as an array composed of [gamma-x, gamma-y, c, s]
  • decodePoint:
    • Description: Decode from bytes to EC point
    • Input:
      • _point: The EC point as bytes
    • Output:
      • The point as [point-x, point-y]
  • computeFastVerifyParams:
    • Description: Compute the parameters (EC points) required for the VRF fast verification function
    • Inputs:
      • _publicKey: The public key as an array composed of [pubKey-x, pubKey-y]
      • _proof: The VRF proof as an array composed of [gamma-x, gamma-y, c, s]
      • _message: The message (in bytes) used for computing the VRF
    • Output:
      • The fast verify required parameters as the tuple ([uPointX, uPointY], [sHX, sHY, cGammaX, cGammaY])
  • gammaToHash:
    • Description: Computes the VRF hash output as result of the digest of a ciphersuite-dependent prefix concatenated with the gamma point. This hash can be used for deterministically generating verifiable pseudorandom numbers.
    • Inputs:
      • _gammaX: The x-coordinate of the gamma EC point
      • _gammaY: The y-coordinate of the gamma EC point
    • Output:
      • The VRF hash ouput as shas256 digest

Elliptic Curve VRF (using Secp256k1)

This library follows the algorithms described in VRF-draft-04 in order to provide the VRF verification capability.

The supported cipher suite is SECP256K1_SHA256_TAI, i.e. the aforementioned algorithms using SHA256 as digest function and the secp256k1 curve. For the VRF algorithms the cipher suite code used is 0xFE.

For elliptic curve arithmetic operations vrf-solidity uses the elliptic-curve-solidity library.

Usage

VRF.sol library can be used directly by importing it.

Similarly to the VRFTestHelper.sol from the test project folder, a contract may use the library by instantiation as follows:

pragma solidity 0.6.12;

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


contract VRFTestHelper {

  function functionUsingVRF(
    uint256[2] memory public _publicKey,
    uint256[4] memory public _proof,
    bytes memory _message)
  public returns (bool)
  {
    return VRF.verify(_publicKey, _proof, _message);
  }
}

The tests under the test folder can be seen as additional examples for interacting with the contract using Solidity and Javascript.

Benchmark

Gas consumption analysis was conducted in order to understand the associated costs to the usage of the vrf-solidity library. Only public functions were object of study as they are the only functions meant to be called by other parties.

The three auxiliary public functions (decodeProof, decodePoint and computeFastVerifyParams) are recommended to be used (if possible) as off-chain operations, so that there is not gas costs.

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

·--------------------------------------------|---------------------------|-------------|----------------------------·
|    Solc version: 0.6.12+commit.27d51765    ·  Optimizer enabled: true  ·  Runs: 200  ·  Block limit: 6718946 gas  │
·············································|···························|·············|·····························
|  Methods                                   ·              100 gwei/gas               ·       590.98 usd/eth       │
·················|···························|·············|·············|·············|··············|··············
|  Contract      ·  Method                   ·  Min        ·  Max        ·  Avg        ·  # calls     ·  usd (avg)  │
·················|···························|·············|·············|·············|··············|··············
|  VRF           ·  computeFastVerifyParams  ·    1513058  ·    1831274  ·    1611989  ·          91  ·      95.27  │
·················|···························|·············|·············|·············|··············|··············
|  VRF           ·  decodePoint              ·      55844  ·      55877  ·      55867  ·          10  ·       3.30  │
·················|···························|·············|·············|·············|··············|··············
|  VRF           ·  decodeProof              ·      56839  ·      56860  ·      56851  ·          10  ·       3.36  │
·················|···························|·············|·············|·············|··············|··············
|  VRF           ·  fastVerify               ·     106360  ·     352838  ·     150715  ·          94  ·       8.91  │
·················|···························|·············|·············|·············|··············|··············
|  VRF           ·  gammaToHash              ·      24189  ·      24201  ·      24198  ·          91  ·       1.43  │
·················|···························|·············|·············|·············|··············|··············
|  VRF           ·  verify                   ·    1543493  ·    1862450  ·    1643712  ·          92  ·      97.14  │
·--------------------------------------------|-------------|-------------|-------------|--------------|-------------·

Test Vectors

The following resources have been used for test vectors:

Acknowledgements

Some EC arithmetic operations have been opmitized thanks to the impressive work of the following resources:

License

vrf-rs is published under the MIT license.