Announcing our own Elliptic Curve Cryptography in Solidity

A cost-efficient, ergonomic and generic crypto library written in Solidity

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

But, why have we implemented our own crypto library? As you all know, developing your own crypto libraries is not usually encouraged. However, we found several reasons to do so:

Curve agnostic : we found out that most of the operations were generic for prime elliptic curves, so there was not special reason to particularize it to only one!

: we found out that most of the operations were generic for prime elliptic curves, so there was not special reason to particularize it to only one! Generic library: most libraries are widely used for key derivations or signatures validations. However, we needed elliptic curve operations for other crypto operations, e.g. for a library implementing Verifiable Random Functions (VRFs).

most libraries are widely used for key derivations or signatures validations. However, we needed elliptic curve operations for other crypto operations, e.g. for a library implementing Verifiable Random Functions (VRFs). Homogeneous functions: we tried to have a clear distinction between arithmetic operations in Affine and Jacobian operations.

Introducing the library

elliptic-curve-solidity is a cost-efficient, flexible and ergonomic library for Elliptic Curve arithmetic operations. It has been generalized in order to support any elliptic curve based on prime numbers up to 256 bits.

The library has been designed with only pure functions aiming at decreasing gas consumption as much as possible. It aims to be as complete as possible by providing the following operations.

Modular : inverse, exponentiation

: inverse, exponentiation Jacobian : addition, double, multiplication

: addition, double, multiplication Affine : inverse, addition, subtraction, multiplication

: inverse, addition, subtraction, multiplication Auxiliary: convert to affine, derive coordinate Y, point on curve

The supported and tested curves are secp256k1, secp256r1 (P-256), secp192r1 (P-192), and secp224r1 (P-224).

Usage

EllipticCurve.sol contract can be used directly by inheritance or by instantiating it. The following Secp256k1 example depicts how to inherit the library by providing a function to derive a public key from a secret key:

pragma solidity ^0.5.0; import "./EllipticCurve.sol"; contract Secp256k1 is EllipticCurve { uint256 constant GX = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798;

uint256 constant GY = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8;

uint256 constant PP = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;

uint256 constant AA = 0;

uint256 constant BB = 7; function derivePubKey(uint256 privKey) public pure returns(uint256 qx, uint256 qy) {

(qx, qy) = ecMul(

privKey,

GX,

GY,

AA,

PP

);

}

}

Benchmark — gas analysis

The repository includes a thorough gas consumption analysis of all library functions.

As illustrative example, the cost of a key derivation operation in Secp256k1 is around 550k gas.

Gas consumption of key derivation operation on curve Secp256k1

Acknowledgements

We want to thank the following resources and authors, on which our library has been inspired: