Intro to Cryptography and Signatures in Ethereum (2024)

Immunefi

·

Follow

Published in

Immunefi

·

11 min read

·

Dec 16, 2021

--

Intro to Cryptography and Signatures in Ethereum (3)

Everyone who has ever dealt with a blockchain system like Ethereum knows what blockchain consists of, such as blocks, transactions, and accounts. But we don’t often think about the basics of blockchain systems, just like we don’t often think about how our organs work. As organs need blood and oxygen to function, blockchain needs cryptography to function properly. Without it, the system would crumble, and you would not be able to claim ownership of that shiny new NFT you just minted.

It was inevitable that sooner or later, we would need to talk about cryptography and signatures. But bear with us, as we’re going to make this as digestible as possible.

Two of the main purposes of cryptography are to prove knowledge of a secret without revealing that secret and to prove the authenticity of data (digital signature). Cryptography is used extensively within Ethereum, and one place that users have contact with it is via Ethereum accounts.

Proof of ownership of Externally Owned Accounts (EOAs) is established through private keys and digital signatures. The private keys are used almost everywhere within Ethereum during user interactions, and the Ethereum address of an EOA is derived from the private key. In other words, the Ethereum address is the last 20 bytes of hash of the public key controlling the account with 0x appended in front.

To prove you are the true owner of an EOA, you need to sign a message with the corresponding private key. This means that only you have access to the funds on your account. When making a transaction sending 1 Ether to a contract to mint a new NFT, under the hood, Ethereum verifies the digital signature you created (using the private key) against the corresponding account’s public key hash (the address).

It is similar to going to a bank and asking for a withdrawal of $1,000 from John Doe’s account. The bank needs to verify first that the person asking for the withdrawal is John Doe and not somebody else. Public key cryptography is based on mathematical functions that allow for unique public/private key pairs. Those pairs of keys have special properties, like ease of creation, but it’s extremely hard (nearly impossible) to create a private key from its public key. Having a private key makes it easy to create a public key, but just from knowing a public key, we cannot know which private key was used to create that public key.

One of the most common mathematical ways to compute secure keys is using prime numbers. If we gave you the number 6747437 and told you it was computed using two prime numbers, it would be extremely hard for you to guess which two were used. Calculating the result of multiplying two prime numbers is easy, but doing that in reverse is hard. Of course, we used one of the lower prime numbers from Wikipedia, but if we were to use two large prime numbers, finding them is hard, even for a computer.

As we learned, public key cryptography (also known as asymmetric encryption) is a cryptographic method that uses a key pair system. The one key, called the private key, signs the message. The other key, called the public key, verifies the signature. When we sign any message, whether a transaction on Ethereum or any form of data, we create a digital signature. This is done by hashing the message and running the ECDSA algorithm to combine the hash with the private key, producing a signature. By doing this, any changes to the message will result in a different hash value.

As we can read from the Mastering Ethereum book, “A digital signature can be created to sign any message. For Ethereum transactions, the details of the transaction itself are used as the message. The mathematics of cryptography — in this case, elliptic curve cryptography — provides a way for the message (i.e., the transaction details) to be combined with the private key to create a code that can only be produced with knowledge of the private key. That code is called the digital signature.”

Above is another explanation of digital signatures, but in the context of Ethereum transactions. This explanation introduces us to another, very important subject — elliptic curve cryptography.

Smart contracts on Ethereum have access to the built-in ECDSA signature verification algorithm through the system method ecrecover. The built-in function lets you verify the integrity of the signed hashed data and recover the signer’s public key.

Intro to Cryptography and Signatures in Ethereum (4)

It uses V,R,S from ECDSA and the hash of the message. Remember, digital signatures don’t need to only relate to transactions. With a private key, we can sign any arbitrary data. And thanks to ecrecover, we have a way of verifying signatures from within smart contracts! This opens the door to whole new opportunities and also potential pitfalls. Let’s focus on the positive side for now.

One such opportunity with signature verification on Ethereum smart contracts is a way to create meta-transactions. A meta-transaction is a method for separating the person who pays for the gas of a transaction from the person who benefits from the transaction’s execution. A user signs the inner, meta-transaction and then sends it to an operator or something similar — no gas and blockchain interaction required. The operator takes this signed meta-transaction and submits it to the blockchain, paying for the fees of the outer, regular transaction himself.

An example of the above would be ERC20-Permit, standardized as ERC2612. One awkward problem with the standard ERC20 is that it takes a two-step process to allow a smart contract to use a user’s funds. First, we need to create an approve() transaction. We need to wait for the transaction to mine, and after it, we can call transferFrom() from the contract itself to do some operations. One of the main examples with this workflow is the usage of DEX.

When we want to exchange USDC for WETH, we first need to call approve() on the USDC contract to let the DEX trade our USDC. Then, to make the actual exchange, the DEX will call transferFrom() under the hood in the second transaction. We need two transactions to perform one simple action.

With ERC20-Permit’s permit function, you just sign the meta-transaction with your wallet, and someone else (such as DEX or another application) can submit it to the blockchain on your behalf. This would save you gas and eliminate the need for two transactions, as in the previous case. The permit function is designed to make user experience more frictionless and to enable gas-free transactions.

If you want to read a tutorial about ERC20-Permit, we recommend reading the linked blog post on the topic.

Now we’re coming to the first common issue: a valid signature might be used several times in other places where it’s not intended to be used.

Imagine a scenario where we have a function that transfers funds, but only when a valid signature is provided.

Intro to Cryptography and Signatures in Ethereum (5)

At first glance, the code looks good. We check the address of the ECDSA signature by providing v,r,s values. We compare the returned address with the owner address, and if it’s an owner, we proceed with the transfer of funds.

The problem with the above code is in the message that is signed by the owner using the ECDSA algorithm. The message only contains the receiver address and the amount to be unlocked. There is nothing in the message that could prevent the same signatures from being used multiple times.

Imagine a scenario where the owner sends 1 Ether to Alice using transferFunds, Alice could re-use the same signature (V,R,S) and send to herself another 1 Ether, or even repeat this many times to drain the contract.

To prevent the signature replay attack, we can store the signature we used in the executed mapping. This way, whenever someone would want to replay our signature, it would fail, as we can check if this signature was already used by simply checking the mapping.

Combining the above results in a code function which looks like this:

Intro to Cryptography and Signatures in Ethereum (6)

If you want to check the full code example, we recommend you check the Solidity-by-example signature replay attack chapter.

There are still issues with the code above. It does not follow the recommended best practice for signature verification, especially the S value.

Within Solidity, an ECDSA signature is represented by its r, s and v values. The precise mathematical relationship between the public key, the message hash, r, s, and v can be checked to ensure that only the person who knows the corresponding private key calculates r, s, and v. However, due to the symmetric structure of elliptic curves, for every set of r, s, and v, there is another, easy-to-compute set of r, s, and v that also has the same precise mathematical relationship. This results in TWO valid signatures and violates the idea that only the person with the private key can compute a signature.

Fortunately, it’s easy to detect the duplicate signature.

We’re only interested in one, so we need a way to show which of the two signatures we’re being shown. Like we said, the elliptic curve is symmetric. The v simply indicates which side of the mirror the signature is on. The v can be either 27 (0x1b) or 28 (0x1c). More information on v can be found in the Ethereum Yellow Paper Appendix F.

Intro to Cryptography and Signatures in Ethereum (7)

Choosing the proper “half” is important when talking about an s point. As seen above, an Elliptic Curve is symmetric on the X-axis, meaning two points can exist with the same X value. We can carefully adjust s to produce a valid signature for the same r on the other side of the X-axis.

The meaning behind all of this is we can invert one valid signature to get another valid signature which will still be valid and basically replay a signature! There is a way to prevent that, and the first major hard-fork of Ethereum introduced a solution to this: EIP-2.

EIP-2 introduced limits on the s values to prevent signature malleability by only considering lower levels of s as valid. By restricting the valid range in half, EIP-2 effectively removes half the points from the group, ensuring there is at most one valid point at each x coordinate.

Although the EIP-2 was introduced into EVM, it didn’t affect the precompiled contract ecrecover. So, whenever we’re using plain ecrecover, we’re still prone to signature malleability. Don’t worry, though, because OpenZeppelin created an appropriate library (ECDSA.sol) that solves this issue.

The trick is simple: we restrict the s value to be in the lower-end.

Intro to Cryptography and Signatures in Ethereum (8)

Another way to combat signature malleability and replay is the usage of an application-level nonce. “Nonce” is cryptographer short-hand for “number used once”. We can use a nonce for every signature and store the next nonce inside the contract.

Intro to Cryptography and Signatures in Ethereum (9)

This covers the most common issues with signatures. But wait, there’s more. If two contracts use the same encoding of messages (maybe there’s a non-fungible token that uses keccak256(abi.encodePacked(_to, _tokenId, nonce[_from])) ), a signature used by one contract might also be valid for the other. So we have to go one step further. We have to hash some identifying information about the contract into our message to make sure that other contracts can’t use the signature.

You may ask yourself (or us): is there some standard to follow or should I, as a Solidity developer, implement everything by hand? No, and thank God for EIP and the standards it introduced to the ecosystem.

To help standardize the signature usage in Ethereum, EIP-712 was introduced and currently is widely used and considered a standard that helps developers avoid most common security issues when dealing with signatures.

EIP-712’s major goal is to ensure that users understand exactly what they’re signing, for which contract address and network, and that each signature can only be used by the intended contract. This is accomplished by signing hashes of the necessary configuration data (address, chain id, version, and data kinds), as well as the actual data.

EIP-712 is a hashing and signature standard for typed structured data rather than just byte strings. It includes a:

  • theoretical framework for correctness of encoding functions,
  • specification of structured data similar to and compatible with Solidity structs,
  • safe hashing algorithm for instances of those structures,
  • safe inclusion of those instances in the set of signable messages,
  • an extensible mechanism for domain separation,
  • new RPC call eth_signTypedData, and
  • an optimized implementation of the hashing algorithm in EVM.

The previously mentioned standard, ERC20-Permit, also relies on EIP-712. We will focus on OpenZeppelin’s implementation to explain how EIP-712 works. The code below contains the most important code snippets from ERC20Permit.sol and EIP712.sol.

Intro to Cryptography and Signatures in Ethereum (10)

Domain Separator: _domainSeparatorV4 This ensures that a signature is only utilized on the proper chain id for our provided token contract address. After the Ethereum Classic fork, which continued to utilize a chain id of 1, the chain id was introduced to precisely identify a network. Because after the hardfork there were contracts deployed to the same address on both networks, the chain id needs to be included to distinguish between them.

Struct Hash: bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));

This structHash ensures that the signature may only be used for the specified purpose, i.e. only for the permit() function, callable only from the owner, approved specified value to the spender. It also adds checks regarding the deadline and checks for nonce so it cannot be replayed.

Final EIP712 Hash: bytes32 hash = _hashTypedDataV4(structHash);

This uses EIP-191 signed data standard to define a version number and version-specific data. 0x19 as set prefix, and 0x01 as version byte to indicate that it’s an EIP-712 signature. Later, we pack together the domain separator and our struct hash. Hash we get is our final hashed message. Later still, we can continue to extract signer addresses. Notice the usage of the ECDSA library to account for all kinds of issues with signatures like signature malleability.

We hope that this post has given you a better understanding of digital signatures in Ethereum and how to manage them effectively. The need for this article arose from the fact that we are seeing more issues with signature mishandling in various projects. With all of the previous knowledge, you should be able to validate signature usage in the code and uncover a few issues. Remember that this is merely a brief overview of the subject; there is much more to learn.

Intro to Cryptography and Signatures in Ethereum (2024)

FAQs

What cryptography is used in Ethereum? ›

Ethereum uses the Keccak-256 cryptographic hash function in many places. Keccak-256 was designed as a candidate for the SHA-3 Cryptographic Hash Function Competition held in 2007 by the National Institute of Science and Technology.

What cryptographic technique is used in Ethereum to prove ownership and authorised transactions? ›

In Ethereum, transactions are secured using the ECDSA (Elliptic Curve Digital Signature Algorithm). This algorithm ensures that only the holder of the private key can initiate a transaction, while anyone with the public key can verify its authenticity.

What are the signatures used in Ethereum? ›

ECDSA signatures in Ethereum consist of three parameters: v , r and s . The signature is always 65-bytes in length. and returns the address used to sign the message.

Does Ethereum use elliptic curve cryptography? ›

The Elliptic Curve Digital Signature Algorithm (ECDSA) is a cryptographic algorithm used in Ethereum to ensure that funds can only be spent by their owners. It is a variant of the Digital Signature Algorithm (DSA) which uses elliptic-curve cryptography.

What is the secret key in Ethereum? ›

An Ethereum private key is a 256-bit number usually represented in hexadecimal format (32 bytes or 64 characters when represented in hexadecimal). It serves as a digital identity that enables you to sign transactions and securely manage your Ethereum assets.

What is the math behind Ethereum? ›

An Ethereum public key is a set of x and y coordinates on an elliptic curve that satisfy the elliptic curve equation. It is derived from two numbers that are generated from the private key using elliptic curve multiplication.

How do you verify an Ethereum signature? ›

To verify a signature:
  1. You need the message, the signature (r, s, v), and the public key or Ethereum address of the signer.
  2. Extract the public key from the signature using the recovery id (v).
  3. Verify that the signature corresponds to the given message hash and extracted public key.
Dec 11, 2023

How does signing an Ethereum transaction work? ›

Transactions in Ethereum are cryptographically signed data messages that contain a set of instructions. These instructions can interpret to sending Ether from one Ethereum account to another or interacting with a smart contract deployed on the blockchain.

What type of cryptographic signatures does Bitcoin use? ›

Digital Signatures and Bitcoin

Bitcoin implements a digital signature algorithm called ECDSA which is based on elliptic curve cryptography. While ECDSA allows a private key to sign any type of message, digital signatures are most frequently used to sign transactions and send bitcoin.

What code is ETH written in? ›

Ethereum
Logo
Original author(s)Vitalik Buterin Gavin Wood
Written inGo, Rust, C#, C++, Java, Python, Nim, TypeScript
Operating systemCross-platform
Platformx86-64, ARM
9 more rows

What are the two types of Ethereum? ›

​ Ethereum features two distinct types of accounts: externally owned accounts (EOA) and smart contract accounts. Both account types can send and receive Ether (ETH) as well as interact with smart accounts deployed (i.e., published) on the blockchain.

Which key is used in Ethereum accounts? ›

There are two types of accounts in Ethereum: Externally Owned Accounts (EOA) and Contract Accounts. An EOA is controlled by a private key, has no associated code, and can send transactions. A contract account has an associated code that executes when it receives a transaction from an EOA.

What kind of cryptography does ETH use? ›

Bitcoin and Ethereum use a combination of cryptographic algorithms including SHA-256 (Secure Hash Algorithm 256-bit) for mining and Elliptic Curve Digital Signature Algorithm (ECDSA) for transactions.

How to get public key from private key Ethereum? ›

The public key is simply the private key multiplied by the point G on the secp256k1 elliptic curve. That's it.

What is the encryption algorithm for Ethereum? ›

The most commonly used hash function on Ethereum is Keccak256. However, it's crucial to exercise caution, as some libraries may refer to Keccak256 as SHA-256, which is a distinct hash function. SHA-256 is a variant of SHA-2 (Secure Hash Algorithm 2) with a 256-bit output and is extensively employed by Bitcoin.

Why does Ethereum use ECDSA? ›

In blockchain networks like Bitcoin and Ethereum, ECDSA is used extensively to sign transactions before they are broadcasted to the network. Each transaction includes the sender's digital signature, which proves ownership of the associated cryptocurrency funds.

What is Ethereum coded on? ›

Solidity is a programming language for implementing smart contracts on various blockchain platforms, most notably, Ethereum. Solidity is licensed under GNU General Public License v3. 0.

Is RSA used in Ethereum? ›

A popular public-private key implementation known as Rivest-Shamir Adelman (RSA) algorithm is used for the Bitcoin and Ethereum Blockchain.

What encoding does Ethereum use? ›

Recursive Length Prefix (RLP) serialization is used extensively in Ethereum's execution clients. RLP standardizes the transfer of data between nodes in a space-efficient format.

Top Articles
SSA - POMS: SI 02301.225 - Absence From the United States (N03), Not a United States Resident (N23)
LastPass - Delete Your Account
This website is unavailable in your location. – WSB-TV Channel 2 - Atlanta
Blorg Body Pillow
Citibank Branch Locations In Orlando Florida
Winston Salem Nc Craigslist
Trabestis En Beaumont
Phcs Medishare Provider Portal
T Mobile Rival Crossword Clue
Www.metaquest/Device Code
Braums Pay Per Hour
Giovanna Ewbank Nua
Iron Drop Cafe
Turbocharged Cars
Ap Chem Unit 8 Progress Check Mcq
Craigslist Pets Southern Md
National Office Liquidators Llc
VMware’s Partner Connect Program: an evolution of opportunities
Violent Night Showtimes Near Amc Fashion Valley 18
Daylight Matt And Kim Lyrics
Crawlers List Chicago
Invitation Homes plans to spend $1 billion buying houses in an already overheated market. Here's its presentation to investors setting out its playbook.
Att.com/Myatt.
Busted Campbell County
Pearson Correlation Coefficient
[PDF] NAVY RESERVE PERSONNEL MANUAL - Free Download PDF
Johnnie Walker Double Black Costco
Gs Dental Associates
San Jac Email Log In
Meggen Nut
Greyson Alexander Thorn
100 Million Naira In Dollars
Www.craigslist.com Syracuse Ny
Gwen Stacy Rule 4
Greencastle Railcam
Solemn Behavior Antonym
Main Street Station Coshocton Menu
Spectrum Outage in Genoa City, Wisconsin
Craigslist Free Manhattan
Kornerstone Funeral Tulia
Postgraduate | Student Recruitment
How Much Is 10000 Nickels
Gotrax Scooter Error Code E2
Deepwoken: How To Unlock All Fighting Styles Guide - Item Level Gaming
John M. Oakey & Son Funeral Home And Crematory Obituaries
Eat Like A King Who's On A Budget Copypasta
Conan Exiles Tiger Cub Best Food
Keci News
Plasma Donation Greensburg Pa
Suzanne Olsen Swift River
Syrie Funeral Home Obituary
Bunbrat
Latest Posts
Article information

Author: Jerrold Considine

Last Updated:

Views: 5856

Rating: 4.8 / 5 (58 voted)

Reviews: 81% of readers found this page helpful

Author information

Name: Jerrold Considine

Birthday: 1993-11-03

Address: Suite 447 3463 Marybelle Circles, New Marlin, AL 20765

Phone: +5816749283868

Job: Sales Executive

Hobby: Air sports, Sand art, Electronics, LARPing, Baseball, Book restoration, Puzzles

Introduction: My name is Jerrold Considine, I am a combative, cheerful, encouraging, happy, enthusiastic, funny, kind person who loves writing and wants to share my knowledge and understanding with you.