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!
- 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).
- 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
- Jacobian: addition, double, multiplication
- Affine: 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.
Acknowledgements
We want to thank the following resources and authors, on which our library has been inspired:
- Comparatively Study of ECC and Jacobian Elliptic Curve Cryptography by Anagha P. Zele and Avinash P. Wadhe
- Ecsol written by Jordi Baylina
- Crypto written by Andreas Olofsson
Contribute to the project!
Please take a look to our GitHub repository and feel free to report issues, propose changes and contribute to the code.