Signature Malleability: Risks, Attacks, and Solutions for Smart Contracts
Jan 8, 2025
20 Minutes
Table of Contents
How signatures are used within Smart Contracts
- Advanced Functionalities
- Key ConsiderationsUnderstanding Signature Malleability
ECDSA Signatures
- Components
- Signature Verification
- Key Properties
Mathematics of ECDSA
- Elliptic Curves
- Digital Signatures
- The Role of Variables (v, r, s)
Malleability Attack
- Why Does It Happen?
- Impact on Smart Contracts
- Examples
Mitigating Signature Malleability
- Best Practices and Tools
Conclusion
1. How signatures are used within Smart Contracts
Signatures in smart contract functions are fundamental for ensuring security, authenticity, and non-repudiation in decentralized systems.
A signature, typically generated using asymmetric cryptography, serves as proof that a transaction or function call has been authorized by the private key owner. This mechanism is essential because, in blockchain networks, there is no central authority to verify identities or permissions. Instead, the validity of a function call relies on the cryptographic signature associated with it, which can be verified using the public key corresponding to the private key.
When a user wishes to interact with a smart contract, they sign the transaction data (which may include details like the contract address, the specific function to be called, and the parameters for the function) using their private key. The signature ensures that only the rightful owner of the private key can initiate the action.
Advanced Functionalities
Signatures also enable more advanced functionality, such as off-chain computation and delegation of actions.
For example, a user can sign a message or data off-chain, allowing another party to submit this signed data to a smart contract to execute the permitted action. This approach is widely used in cases like gasless transactions, where the signer does not directly pay the gas fee but authorizes another party (often a relayer) to perform the transaction on their behalf. This improves usability by reducing the burden on end-users.
Furthermore, off-chain signatures are utilized in meta-transactions, where users sign messages indicating their intent, and these are later relayed to the blockchain. This saves on-chain computation costs, enhances scalability, and provides flexibility for applications like DeFi protocols, NFT marketplaces, and voting systems.
In these scenarios, the signature serves as a binding authorization, ensuring that the smart contract executes only the exact actions approved by the signer. The smart contract checks the validity of the signature, confirms that the signer has granted the specific permissions encoded in the signed message, and rejects any unauthorized submissions. This pattern reinforces decentralized trust and opens up efficient, user-friendly ways to interact with blockchain-based applications.
Key Considerations
Ensuring that signatures are correctly handled by smart contracts is critically important, as mishandling them can lead to severe vulnerabilities, malfunctions, or exploitation.
Smart contracts operate autonomously and cannot be modified once deployed, so any flaw in how signatures are validated can result in irreversible consequences. For instance, if a contract does not properly verify the authenticity of a signature or the permissions it grants, malicious actors could forge transactions or execute unauthorized actions, undermining the security of the system.
A common risk arises from improperly implemented signature verification logic. If the contract fails to confirm that the signer is indeed the intended party (as determined by the public key), it may execute actions on behalf of unauthorized users.
Similarly, overlooking critical aspects such as ensuring that the signed message corresponds to the specific action being performed or validating that the signature hasn’t already been used (to prevent replay attacks) can lead to unintended behavior. For example, a failure to check for a nonce or timestamp might allow attackers to reuse a valid signature in a different context, compromising the integrity of the contract.
In this article, we are focusing on a specific attack: signature malleability.
2. Understanding Signature Malleability
As mentioned earlier in this article, signatures are used by smart contracts to ensure that a specific action has been authorized or submitted by a particular user. However, in the case of signature malleability, an attacker can modify a valid signature in such a way that the altered version is still valid for the same action.
As a result, there will be two different signatures that can authenticate the same action, both considered valid by the system. This exploit, known as signature malleability, can create significant vulnerabilities, as it undermines the uniqueness and immutability that signatures are meant to provide.
This issue is particularly problematic when smart contracts rely on signatures to track unique transactions or approvals. If multiple valid signatures exist for the same action, it may allow replay attacks, duplicate transaction execution, or other unintended behaviors.
3. ECDSA Signatures
ECDSA (Elliptic Curve Digital Signature Algorithm) is a cryptographic algorithm used for signing and verifying messages, commonly in blockchain systems like Bitcoin, as well as in various security protocols. It is based on elliptic curve cryptography (ECC), which is a form of public-key cryptography that uses the algebraic structure of elliptic curves over finite fields. Here's a breakdown of ECDSA signatures:
Components of ECDSA
ECDSA signatures consist of two components: r and s. These values are generated through the following process:
1. Private Key: This is a secret key, known only to the signer, that is used to generate the signature.
2. Message: The data to be signed (a transaction, document, etc.) is first hashed, typically using a hash function like SHA-256.
3. Random Value (k): A random integer chosen for each signature to ensure uniqueness and security.
4. Signature Generation:
- The message is hashed.
- A random number (k) is generated and used in an elliptic curve point multiplication.
- Using the private key and k, a pair of numbers (r, s) is created. These values are the signature components.
5. Signature (r, s): The result of the above process is the signature, which is typically represented as a pair of integers (r, s).
Signature Verification
To verify a signature, the recipient needs the public key (which corresponds to the private key used to generate the signature), the message, and the signature (r, s).
1. The message is hashed.
2. The verification process uses elliptic curve mathematics to check that the signature (r, s) corresponds to the public key and the hash of the message.
3. If the verification algorithm confirms that the signature is valid, the message is authenticated as coming from the owner of the private key.
Key Properties of ECDSA
Security: The security of ECDSA is based on the difficulty of the Elliptic Curve Discrete Logarithm Problem (ECDLP), which makes it computationally infeasible to derive the private key from the public key or the signature.
Compactness: ECDSA signatures are shorter and more efficient than those based on other algorithms like RSA, making them particularly suitable for environments with limited resources, such as mobile devices or blockchain systems.
4. Mathematics of ECDSA
To understand the mathematics behind Elliptic Curve Cryptography (ECC), ECDSA (Elliptic Curve Digital Signature Algorithm), and the components of an ECDSA signature — v, r, and s — we need to break it down into a few key parts. Let’s go step-by-step to understand these concepts mathematically.
Elliptic Curves and Their Mathematical Definition
An elliptic curve is defined by an equation of the form:
y2=x3+ax+b (mod p)
Image Source: Desdevpro
Where:
x and y are the coordinates of points on the curve;
a and b are constants that define the curve;
p is a large prime number, defining a finite field (a set of numbers modulo p).
The curve is called elliptic because its graph looks like an elongated oval, and the points on the curve have special properties that allow elliptic curve operations (such as point addition and multiplication).
ECDSA: Digital Signatures
ECDSA uses elliptic curve operations to create and verify signatures. The key parts of the signature generation and verification process rely on elliptic curve point multiplication and modular arithmetic.
Signature Generation
Let’s assume the private key d and the message m (often hashed before signing). The steps to generate the ECDSA signature are:
1. Hash the Message:
- First, hash the message using a cryptographic hash function (like SHA-256), producing H(m), the hash of the message.
2. Choose a Random Integer k:
- Select a random integer k from a set of numbers modulo p (the prime used in the curve equation). This is crucial for security to ensure the signature is unique each time.
3. Calculate r and s:
- Use elliptic curve point multiplication to calculate the point k⋅G, where G is the base point of the elliptic curve (a fixed point used for generating public keys). The x-coordinate of this point is denoted as r, reduced modulo p: r = (x(k⋅G)) (mod p)
- If r=0, choose a different k.
- Calculate s as follows: s=k^−1(H(m)+r⋅d) (mod p) — where k^−1 is the modular inverse of k modulo p−1..
4. The Signature:
- The signature consists of the two values r and s. The pair (r,s) is the ECDSA signature for the message m.
Signature Verification
To verify an ECDSA signature (r,s) for a given message m, follow these steps:
1. Verify Validity of r and s:
- Ensure that both r and s are in the valid range 0 < r < p and 0 < s < p.
2. Hash the Message:
- Hash the message mmm to get H(m).
3. Calculate z1 and z2:
- Calculate: z1=s^−1 * H(m) (mod p)
- z2=s−^1*r (mod p)
4. Point Calculation:
- Compute the elliptic curve points P1=z1⋅G and P2=z2⋅Q, where Q=d⋅G is the public key.
5. Calculate r′:
- Add the points P1 and P2, then take the x-coordinate of the result modulo p: r′=(x(P1+P2)) (mod p)
6. Compare r′ and r:
- If r′=r, the signature is valid. Otherwise, it’s invalid.
The Role of v, r, and s in ECDSA
In the context of ECDSA:
r: The x-coordinate of the elliptic curve point k⋅G modulo p. It’s part of the signature.
s: A value derived from the private key, the message hash, and the random number k. It’s the second part of the signature.
v: Often seen in signature schemes (like Ethereum), v is used to determine the "recovery" of the public key from the signature. In Ethereum's case, it helps to find out which of the two possible public keys generated a signature.
Point Addition
Point addition on an elliptic curve is a fundamental operation in elliptic curve cryptography. It is the process of adding two points P and Q on an elliptic curve to produce a third point R. This operation forms the basis for more complex operations, such as scalar multiplication, used in cryptographic algorithms like ECDSA.
Source: Hackernoon
If you pick two points on the curve, say P and Q, you can combine them to get another point, R. Here's how:
Draw a Line: Imagine a straight line that passes through both P and Q.
Find Where It Hits the Curve: This line will touch the curve at a third point.
Flip It Over the X-Axis: Take that third point and reflect it across the x-axis to get the result, R.
That's it! You’ve added P and Q, and the result is R.
Scalar Multiplication
Scalar multiplication refers to taking a single point P on the curve and adding it to itself repeatedly. This is different from standard multiplication of numbers but is critical for elliptic curve cryptography (ECC).
Source: Hackernoon
When we talk about scalar multiplication, we mean multiplying a point P on the elliptic curve by a scalar K, which is a whole number. For example:
Q=K⋅P
Here:
P is the starting point.
K is the number of times P is added to itself.
Q is the resulting point after the operation.
Mathematically, it means: Q=P+P+P+…+P(K times).
How Does Scalar Multiplication Work?
To compute Q=K⋅P, we use point addition and point doubling, as follows:
1. Start with P: The point P is given on the elliptic curve.
2. Use Point Doubling: To compute 2⋅P2, draw a tangent line through P on the curve. The tangent intersects the curve at a new point, which, when reflected across the x-axis, gives 2P.
3. Use Point Addition: Add P to 2P to compute 3P. Keep repeating the process.
4. Repeat Efficiently (Binary Method): Instead of manually adding P one step at a time, cryptographers use an efficient method called the double-and-add algorithm. This method leverages the binary representation of K to compute Q=K⋅P much faster.
Key Generation in Cryptography: In ECC, scalar multiplication is used to generate a public key from a private key. The private key is a large number K, and the public key is Q=K⋅G, where G is a predefined point on the curve.
5. Malleability Attack
In blockchain systems, all transactions must be signed before they are included in the blockchain. These signatures use elliptic curve cryptography (ECC) and consist of several parameters: v, r, and s. Signature malleability allows an attacker to modify these parameters while still creating a valid signature. Importantly, the attacker doesn't need access to the original signer's private key to perform this attack.
Why Does It Happen?
Elliptic curves are symmetric by nature. This means that for any given signature (v,r,s), there exists another valid signature (v′,r,s′) that satisfies the same cryptographic relationship. Specifically:
The elliptic curve equation provides multiple valid representations of the same signature due to its inherent symmetry about the x-axis.
For a valid signature (v,r,s), the values of s can sometimes be replaced by their complements (e.g., −s mod n-), resulting in a new, valid signature.
This symmetry allows attackers to craft alternate signatures that can bypass verification when only the correctness of the cryptographic relationship is checked.
Impact on Smart Contracts
Smart contracts often use the Ethereum Virtual Machine (EVM) function ecrecover
to verify signatures. This function requires four parameters: v, r, s, and a hash of the message being signed. The function checks if the provided signature corresponds to a valid public key.
An attacker exploiting signature malleability can:
Modify the v, r, or s values to generate a different but valid signature.
Submit the altered signature to the smart contract.
Cause unintended behavior if the contract logic assumes that each signature is unique or is directly tied to a specific transaction.
Example of the malleability attack
The contract verifies signatures using ecrecover
:
Attack Steps:
1. A legitimate user signs a message, producing a signature (v,r,s).
2. The attacker modifies the signature by flipping the s-value to n−s, where n is the order of the elliptic curve.
3. The attacker submits the modified signature (v,r,n−s) to the smart contract.
4. The
ecrecover
function verifies the altered signature as valid because it still corresponds to the original public key.
6. Mitigation of Signature Malleability
Use OpenZeppelin's ECDSA Library
To mitigate signature malleability effectively in Ethereum smart contracts, developers can use OpenZeppelin's ECDSA library, which includes built-in functions to validate signatures and enforce canonical forms. This library ensures that only signatures with the lower half of the elliptic curve are accepted, discarding the other half.
By leveraging this library, developers can reduce the risk of signature malleability attacks while simplifying signature validation logic.
The ECDSA library in OpenZeppelin includes utility functions for recovering and verifying signatures. Specifically, it implements checks to ensure the s-value of the signature is in the lower half of the curve, i.e., 0≤s≤n/2, where n is the order of the curve. This normalization prevents multiple valid signatures for the same message.
Manual Invalidation of Half of the Curve
In addition to using libraries like OpenZeppelin's ECDSA, signature malleability can also be addressed with a simple manual validation of the s-value. By enforcing that s is in the lower half of the elliptic curve, you ensure the signature is canonical and cannot be altered to create equivalent but different signatures.
Mitigating Signature Malleability Using Direct sss-Value Validation
In addition to using libraries like OpenZeppelin's ECDSA, signature malleability can also be addressed with a simple manual validation of the s-value. By enforcing that s is in the lower half of the elliptic curve, you ensure the signature is canonical and cannot be altered to create equivalent but different signatures.
Elliptic curves are symmetric, so for every valid signature (v,r,s), there exists another valid signature (v,r,−smod n), where n is the order of the elliptic curve. To avoid this ambiguity, we enforce s≤n/2s.
0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A00x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A00x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0
The value above represents n/2n for the SECP256k1 curve, which is the elliptic curve used in Ethereum.
Comparison to OpenZeppelin’s ECDSA Library
Manual s-Check:
- Lightweight and straightforward.
- Requires knowledge of the elliptic curve properties and parameters like n/2n.OpenZeppelin's ECDSA Library:
- Abstracts these checks into reusable functions.
- Offers additional utilities like Ethereum-specific message formatting.
7. Conclusion
In summary, signature malleability presents a notable challenge to blockchain security, enabling vulnerabilities like replay attacks and unauthorized transactions. Developers can proactively mitigate risks by understanding the causes—rooted in the symmetric properties of elliptic curves— and using the right tools and methods, like OpenZeppelin’s ECDSA library and manual validations.