Ethereum: Extracting ECDSA r and s Encoded as Signatures
Electronic Cash Transactions (ECC) are a type of digital currency that uses the Elliptic Curve Digital Signature Algorithm (ECDSA) to create secure and private signatures. In this article, we will explore how to extract the r and s components from an ECDSA signed message in Ethereum.
Overview of ECDSA and Signature Construction
When creating a signature using ECDSA, two key components are produced: r
and s
. These values are used to sign messages, and they are part of the Elliptic Curve. In this article, we will focus on extracting r
and s
from an ECDSA signed message.
How to Extract r and s
The process of extracting r
and s
involves several steps:
- Hashing: First, you need to hash the input signature with the
verifyingKey
(i.e.,v
,p
, andq
). This produces a digest that corresponds to the signed message.
- Splitting the Digest: Next, split the digest into two parts: the first part will be used for extracting
r
ands
, while the second part is discarded.
- Encoding ECDSA Values: In Ethereum, each r and s are encoded as a pair of byte arrays (
[r, s]
). To extract these values, you need to take the first two bytes (or four bytes) from the first half of the digest.
Code Example
To illustrate the process, let’s consider an example in Solidity:
pragma solidity ^0.8.0;
contract signing {
// ... other functions ...
function sign(string memory sigStr) public returns (bytes32 r, bytes32 s) {
// Hash the input signature with the verifying key
bytes32 digest = keccak256(abi.encodePacked(sigStr));
// Split the digest into two halves
uint160 firstHalf = uint160(digest);
uint160 secondHalf = uint160(digest) | 0x80000000;
// Encode ECDSA values as a pair of byte arrays
bytes32 r;
bytes32 s;
uint8 i, j;
for (i = 1; i < firstHalf + 128; i++) {
j = i + 2;
r = keccak256(abi.encodePacked((firstHalf & 0x7FFFFFFF) << (j - 1), (secondHalf >> 64) | ((j - 2) * 65536)));
}
for (i = 1; i < secondHalf + 128; i++) {
j = i + 2;
s = keccak256(abi.encodePacked((firstHalf & 0x7FFFFFFF) << (j - 1), ((secondHalf >> 64) | ((j - 2) * 65536))));
}
return (r, s);
}
}
In this example, the sign
function takes a signed message as input and returns the corresponding r and s values. The function first hashes the input signature with the verifying key and then splits the digest into two halves. Finally, it encodes ECDSA values as a pair of byte arrays using the Keccak-256 hash function.
Conclusion
In this article, we explored how to extract the r
and s
components from an ECDSA signed message in Ethereum. By understanding the process of hashing, splitting the digest, and encoding ECDSA values as a pair of byte arrays, you can now write your own functions to sign messages using ECC signatures.
Leave A Comment