Published in

MyCrypto

# What is a cryptographic signature?

When we talk about signatures in cryptography, we talk about some kind of proof of ownership, validity, integrity, etc. For example, they can be used for:

## Signing and verifying using ECDSA

ECDSA signatures consist of two numbers (integers): `r` and `s`. Ethereum also uses an additional `v` (recovery identifier) variable. The signature can be notated as `{r, s, v}`.

1. Calculate a hash (`e`) from the message to sign.
2. Generate a secure random value for `k`.
3. Calculate point `(x₁, y₁)` on the elliptic curve by multiplying `k` with the `G` constant of the elliptic curve.
4. Calculate `r = x₁ mod n`. If `r` equals zero, go back to step 2.
5. Calculate `s = k⁻¹(e + rdₐ) mod n`. If `s` equals zero, go back to step 2.
• Calculate the hash (`e`) for the message to recover.
• Calculate point `R = (x₁, y₁)` on the elliptic curve, where x₁ is `r` for `v = 27`, or `r + n` for `v = 28`.
• Calculate `u₁ = -zr⁻¹ mod n` and `u₂ = sr⁻¹ mod n`.
• Calculate point `Qₐ = (xₐ, yₐ) = u₁ × G + u₂ × R`.

## The recovery identifier (“v”)

`v` is the last byte of the signature, and is either 27 (`0x1b`) or 28 (`0x1c`). This identifier is important because since we are working with elliptic curves, multiple points on the curve can be calculated from `r` and `s` alone. This would result in two different public keys (thus addresses) that can be recovered. The `v` simply indicates which one of these points to use.

## Signed transactions

So far we’ve mostly talked about signatures in the context of messages. Transactions are, just like messages, signed as well before sending them. For hardware wallets like Ledger and Trezor devices, this happens on the device itself. For private keys (or keystore files, mnemonic phrases), this is done directly on MyCrypto. This uses a method that is very similar to how messages are signed, but the transactions are encoded a bit differently.

`0xf86c0a8502540be400825208944bbeeb066ed09b7aed07bf39eee0460dfa261520880de0b6b3a7640000801ca0f3ae52c1ef3300f44df0bcfd1341c232ed6134672b16e35699ae3f5fe2493379a023d23d2955a239dd6f61c4e8b2678d174356ff424eac53da53e17706c43ef871`
• Encode the transaction parameters: `RLP(nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0)`.
• Get the Keccak256 hash of the RLP-encoded, unsigned transaction.
• Sign the hash with a private key using the ECDSA algorithm, according to the steps described above.
• Encode the signed transaction: `RLP(nonce, gasPrice, gasLimit, to, value, data, v, r, s)`.

# Standardisation of signed messages

There are multiple proposals for defining a standard structure for signed messages. Currently, none of these proposals are finalised, and the `personal_sign` format, first implemented by Geth, is still the most common. Nonetheless, some of these proposals are very interesting.

`"\x19Ethereum Signed Message:\n" + length(message) + message`
`"\x19Ethereum Signed Message:\n32" + Keccak256(message)`

## EIP-191: Signed Data Standard

EIP-191 is a very simple proposal: It defines a version number and version specific data. The format looks like this:

`0x19 <1 byte version> <version specific data> <data to sign>`
• `0x00`: Data with “intended validator.” In the case of a contract, this can be the address of the contract.
• `0x01`: Structured data, as defined in EIP-712. This will be explained further on.
• `0x45`: Regular signed messages, like the current behaviour of `personal_sign`.

## EIP-712: Ethereum typed structured data hashing and signing

Not to be confused with ERC-721, the non-fungible token standard, EIP-712 is a proposal for “typed” signed data. This makes signing data more verifiable, by presenting it in a human-readable way.

`0x1901fb502c9363785a728bf2d9a150ff634e6c6eda4a88196262e490b191d5067cceee82daae26b730caeb3f79c5c62cd998926589b40140538f456915af319370899015d824eda913cd3bfc2991811b955516332ff2ef14fe0da1b3bc4c0f424929`

# Verifying signatures with smart contracts

What makes message signatures more interesting is that we can use smart contracts to verify the ECDSA signatures. Solidity has a built-in function called `ecrecover` (which is actually a precompiled contract at address 0x1) that will recover the address of the private key that a message was signed with. A (very) basic contract implementation looks like this:

# Conclusion

Signatures are a key part of the blockchain and decentralisation. Not only for sending transactions, but also for interacting with decentralised exchanges, multisig contracts, and other smart contracts. There is no clear standard for signing messages yet, and further adoption of the EIP-712 specification would help the ecosystem to improve the user experience, as well as to have one standard for message signatures.

--

--

## More from MyCrypto

The Official MyCrypto Blog