Use a signature to generate a public key

In Ethereum one can use the v, r and s parameters of a signature to generate a public key. In this tutorial we will discuss elliptic curve basics and how to generate a public key using a signature in Solidity.

Elliptic curve basics

Elliptic Curve Cryptography (ECC) is a key based technique for encrypting data. It uses pairs of public and private keys for encryption and decryption using the mathematics of elliptic curves. The implementation of elliptic curves in cryptography requires less power consumption, fewer bits of data and is faster then RSA encryption.

An elliptic curve is the set of points that satisfy a specific mathematical equation. The equation for an elliptic curve is: y2 = x3 + ax + b. When plotted on a graph the curve looks like the symbol on the x and y axis below.

Elliptic curves in Ethereum. signature to generate a public key

  • An Elliptic curve has horizontal symmetry
  • Any point on the curve can be reflected over the x axis and remain the same curve
  • Any non-vertical line will intersect the curve in at most three places.

Elliptic curves in Ethereum

The Elliptic Curve Digital Signature Algorithm (ECDSA) consist of r and s output parameters. In Ethereum, signatures contain a third parameter called v which is the recovery id. These three components can be used to generate the public key of the Ethereum account that signed a transaction.

Solidity provides a built-in function called ecRecover that accepts a message hash along with the rs and v parameters and returns the public address that was used to sign the message.

Solidity smart contract functions to generate a public key

The Solidity smart contract example below contains two functions.

  • splitSignature – Input a signature into this function and it returns the v, r and s components of a signature
  • recoverPublicAddress – Input a message hash and corresponding v, r and s values to generate the public key that signed the message.

Deploy the Solidity smart contract below and practice the following example.

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.7.0;


contract SignatureUtility {

 
    //input a signature and determine the v, r and s values
    function splitSignature(bytes memory signature) public pure
        returns (uint8 v, bytes32 r, bytes32 s)
    {
        require(signature.length == 65);

        assembly {
            // first 32 bytes, after the length prefix.
            r := mload(add(signature, 32))
            // second 32 bytes.
            s := mload(add(signature, 64))
            // final byte (first byte of the next 32 bytes).
            v := byte(0, mload(add(signature, 96)))
        }

        return (v, r, s);
    }
    

    //input a message hash, v, r and s values and generate the public key
    function recoverPublicAddress (bytes32 messagehash, uint8 v, bytes32 r, bytes32 s) public pure
    returns (address sender) {
        return ecrecover(messagehash, v, r, s);
  }
}

Try it in Remix

Example: Use a signature to generate a public key

In the example below Bob will prove what account Alice used to sign an Ethereum transaction.

  1. Alice – signs a message with the information below
Public key - 0x1aE0EA34a72D944a8C7603FfB3eC30a6669E454C

Message - test

To sign a message in remix press the sign icon to the right of the address

sign a transaction in Remix. Use a signature to generate a public key

2. Alice sends the signature and hash that was generated to Bob

Signature - 0x187596a467d4a19bf427945864837fc3993b2f24ff25c2939390c800e7d0f7021f2ca461bf0cd47cc1358c5a5faec28e48c90cc9ed6274be194e4a2b03e2eef21c

Hash - 0x4a5c5d454721bbbb25540c3317521e71c373ae36458f960d2ad46ef088110e95

3. Bob wants to prove that Alice signed this message with her account. He uses the signature and hash as input parameters to generate the public key that signed the transaction.

4. Bob inputs the signature in the split signature function in the Solidity contract above. This function generates the r, s and v values of the signature.

5. Bob then uses the output of the split signature function and the message hash as inputs to the recover public address function. This function will generate the public key used to sign the message.

Use a signature to generate a public key

6. Bob can determine that the signature and the hash generated the same address that Alice used to sign the initial transaction.

Blockchain Networks

Below is a list of Mainnet and Testnet blockchain networks. Each link contains network configuration, links to multiple faucets for test ETH and tokens, bridge details, and technical resources for each blockchain. Basically everything you need to test and deploy smart contracts or decentralized applications on each chain. For a list of popular Ethereum forums and chat applications click here.

Ethereum test network configuration and test ETH faucet information
Optimistic Ethereum Mainnet and Testnet configuration, bridge details, etc.
Polygon network Mainnet and Testnet configuration, faucets for test MATIC tokens, bridge details, etc.
Binance Smart Chain Mainnet and Testnet configuration, faucets for test BNB tokens, bridge details, etc.
Fanton networt Mainnet and Testnet configuration, faucets for test FTM tokens, bridge details, etc.

Next – Build a crypto back running trading bot

Ledger Nano X - The secure hardware wallet

1 thought on “Use a signature to generate a public key

Leave a Reply