bls-solidity
is an open source fast and effective implementation of the 256-bit Barreto-Naehrig (BN256) curve operations written in Solidity. More precisely, this library implements all the necessary curve arithmetic to perform BLS signatures. Currently only the Elliptic Curve (EC) bn256
is supported, as this is the only curve for which certain operations are subsidized by the EVM in the form of precompiled functions. However, adding support to new curves should be straight forward.
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. For that reasons, the BN256G1
library makes use of the precompiled functions made available by the EVM. The operations in G2 are not subsidized, and therefore implementations for the most basic operations are available.
Exported functions in field G1:
-
add:
- Description: adds two points in Jacobian coordinates in G1
- Inputs:
- input: The two points as an array composed of
[pt1-x, pt1-y, pt2-x, pt2-y]
- input: The two points as an array composed of
- Output:
- an array with pt3 = pt1 + pt2 represented as
[pt3-x, pt3-y]
- an array with pt3 = pt1 + pt2 represented as
-
multiply:
- Description: Multiplies an input pt with an scalar k.
- Inputs:
- input: an array containing the point and scalar represented as
[pt-x, pt-y, k]
- input: an array containing the point and scalar represented as
- Output:
- an array with pt2 = pt*k represented as
[pt2-x, pt2-y]
- an array with pt2 = pt*k represented as
-
isOnCurveSubsidized:
- Description: Checks whether the provided point exists in BN256 G1. It uses the precompiled function.
- Inputs:
- input: an array containing the point represented as
[pt-x, pt-y]
- input: an array containing the point represented as
- Output:
- true if the point provided is valid on the curve.
-
isOnCurve:
- Description: Checks whether the provided point exists in BN256 G1. It uses the elliptic-curve-solidity library function.
- Inputs:
- input: an array containing the point represented as
[pt-x, pt-y]
- input: an array containing the point represented as
- Output:
- true if the point provided is valid on the curve.
-
bn256CheckPairing:
- Description: Checks whether e(P, Q) = e(R,S)
- Input:
- input: an array containing the points represented as
[P-x, P-y, Q-x-re, Q-x-im, Q-y-re, Q-y-im, R-x, R-y, S-x-re, S-x-im, S-y-re, S-y-im]
- input: an array containing the points represented as
- Output:
- true if e(P, Q) is equal to e(R, S).
-
bn256CheckPairingBatch:
- Description: Checks whether e(P, Q) = e(R,S) * e(T, U)...
- Input:
- input: an array containing the points represented as
[P-x, P-y, Q-x-re, Q-x-im, Q-y-re, Q-y-im, R-x, R-y, S-x-re, S-x-im, S-y-re, S-y-im, T-x, T-y, U-x-re, U-x-im, U-y-re, U-y-im,...]
- input: an array containing the points represented as
- Output:
- true if e(P, Q) is equal to e(R, S) * e(T, U) * ....
Exported functions in field G2:
-
ecTwistAdd:
- Description: adds two points in Jacobian coordinates in G2
- Inputs:
- input: The two points as an array composed of
[pt1-x-re, pt1-x-im, pt1-y-re, pt1-y-im, pt1-x-re, pt1-x-im, pt1-y-re, pt1-y-im]
- input: The two points as an array composed of
- Output:
- an array with pt3 = pt1 + pt2 represented as
[pt3-x-re, pt3-x-im, pt3-y-re, pt3-y-im]
- an array with pt3 = pt1 + pt2 represented as
-
ecTwistMul:
- Description: Multiplies a point in Jacobian coordinates in G2 with a scalar
- Inputs:
- input: The point and the scalar as an array composed of
[pt-x-re, pt-x-im, pt-y-re, pt-y-im, k]
- input: The point and the scalar as an array composed of
- Output:
- an array with pt2 = pt * k represented as
[pt2-x-re, pt2-x-im, pt2-y-re, pt2-y-im]
- an array with pt2 = pt * k represented as
BN256G1.sol
and BN256G2.sol
library can be used directly by importing it.
Similarly to the BN256G1Helper.sol
from the test
project folder, a contract may use the library by instantiation as follows:
pragma solidity 0.6.8;
import "bls-solidity/contracts/BN256G1.sol";
contract BN256G1Helper {
function functionUsingBN256G1(
uint256[4] memory public _input)
public returns (uint256[2] memory)
{
return BN256G1.add(_input);
}
}
The tests under the test
folder can be seen as additional examples for interacting with the contract using Solidity and Javascript.
Gas consumption analysis was conducted in order to understand the associated costs to the usage of the bls-solidity
library. Only public or external
functions were object of study as they are the only functions meant to be called by other parties.
Gas consumption and USD price estimation with a gas price of 20 Gwei, derived from ETH Gas Station:
·············································|···························|·············|·····························
| Methods · 20 gwei/gas · 213.78 usd/eth │
·················|···························|·············|·············|·············|··············|··············
| Contract · Method · Min · Max · Avg · # calls · usd (avg) │
·················|···························|·············|·············|·············|··············|··············
| BN256G2Helper · _bn128_g2_add · - · - · 54401 · 8 · 0.2 │
·················|···························|·············|·············|·············|··············|··············
| BN256G2Helper · _bn128_g2_multiply · 2944704 · 3140352 · 3057658 · 15 · 10.31 │
·················|···························|·············|·············|·············|··············|··············
| Deployments · · % of limit · │
·············································|·············|·············|·············|··············|··············
| BN256G2Helper · - · - · 214244 · 3.2 % · 0.9 │
·--------------------------------------------|-------------|-------------|-------------|--------------|-------------·
·············································|···························|·············|·····························
| Methods · 20 gwei/gas · 213.78 usd/eth │
·················|···························|·············|·············|·············|··············|··············
| Contract · Method · Min · Max · Avg · # calls · usd (avg) │
·················|···························|·············|·············|·············|··············|··············
| BN256G1Helper · _add · 23374 · 24910 · 24154 · 12 · 0.1 │
·················|···························|·············|·············|·············|··············|··············
| BN256G1Helper · _bn256CheckPairing · 140843 · 141587 · 141433 · 10 · 0.6 │
·················|···························|·············|·············|·············|··············|··············
| BN256G1Helper · _bn256CheckPairingBatch · 179150 · 179186 · 179170 · 5 · 0.8 │
·················|···························|·············|·············|·············|··············|··············
| BN256G1Helper · _isOnCurve · 21981 · 22966 · 22747 · 9 · 0.1 │
·················|···························|·············|·············|·············|··············|··············
| BN256G1Helper · _isOnCurveSubsidized · 22844 · 23612 · 23458 · 10 · 0.1 │
·················|···························|·············|·············|·············|··············|··············
| BN256G1Helper · _multiply · 29902 · 30286 · 30075 · 36 · 0.1 │
·················|···························|·············|·············|·············|··············|··············
| Deployments · · % of limit · │
·············································|·············|·············|·············|··············|··············
| BN256G1Helper · - · - · 710293 · 10.6 % · 2.9 │
·--------------------------------------------|-------------|-------------|-------------|--------------|-------------·
The following resources have been used for test vectors:
Some bn256 operations have been adapted from the following resources:
bls-solidity
is published under the MIT license.