ECDSA Signature Component Validation Using Bitcoin Core Mod N
The Electronic Cash Guidelines (ECG) and the Elliptic Curve Digital Signature Algorithm (ECDSA) are two core components of the Bitcoin protocol. In this article, we will explore how Bitcoin Core validates ECDSA signature components using Mod N.
ECDSA Signing/Verification Procedure
Jimmy Song’s book “Bitcoin Programming” states that the ECDSA signing/verification procedure for a message hash z
involves the following steps:
- Extract the public key P from the private key e.
- Compute the signature of the message hash “z” using the ECDSA algorithm:
S = r * G^x mod M
- Verify the signature by checking that it matches the expected signature for the given public key and message hash:
V = r ^ x mod h_p
S = S ^ V mod h_s
Mod N validation
To validate ECDSA signatures using Mod N, we need to define a suitable modulus “M” and a base point “G” that satisfy certain properties. The property of the key is that the private key “e” is the modular exponent of the generator point “G”.
In Bitcoin Core, the private key “e” is represented by the pair “(d, P)”, where “d” is the private key in decimal form and “P” is the public key (i.e., “(x, y)”). To validate ECDSA signatures using Mod N, we need to define a modulus M such that:
d^e ≡ 1 mod M
G^e ≡ G^x mod M
We can choose an arbitrary modulus “M = p” (a prime number) and define the private exponent “e” as the modular exponent of the generator point “G”. The public key “P” is simply the coordinates “(x, y)”.
Implementation in Bitcoin Core
To implement Mod N validation in Bitcoin Core, we can use the following code snippet:
#include
// Define a structure that represents the components of an ECDSA signature
typedef struct {
uint8_t r[4];
uint8_t x;
} S;
// Function to calculate ECDSA signature and verify it using Mod N
S ecdsa_sign(const uint8_t z, const uint64_t e, const uint8_t p) {
// Extract public key components from private key
const uint32_t d = (z[0] << 24) + (z[1] << 16) + (z[2] << 8) + z[3];
S* signature = new (sizeof(S)) S;
// Calculate ECDSA signature and verify it using Mod N
S r;
for (int i = 0; i < 4; i++) {
r.r[i] = (d >> (i * 8) & 255);
}
signature->r[3] = (z[0] << 24) + (z[1] << 16) + (z[2] << 8) + z[3];
signature->x = r.x;
// Calculate G^e ≡ G^x mod M
S g;
for (int i = 0; i < 4; i++) {
g.r[i] = pow(G, r.r[i], p);
}
return the signature;
}
// Function to verify ECDSA signature using Mod N
bool ecdsa_verify(const S* signature, const uint64_t e, const uint8_t z, const uint32_t p) {
// Extract the public key components from the private key
const uint32_t d = (z[0] << 24) + (z[1] << 16) + (z[2] << 8) + z[3];
// Calculate G^e ≡ G^x mod M
S g;
for (int i = 0; i < 4; i++) {
g.r[i] = pow(G, d >> (i * 8), p);
}
// Compare the calculated signature with the expected signature
uint64_t r, x;
for (int i = 0; i < 4; i++) {
r += g.r[i];
x += (z[1] << 16) + (z[2] << 8) + z[3];
}
return pow(r, e, p) == x;
}
This implementation provides a basic framework for validating ECDSA signatures using Bitcoin Core Mod N. Note that this is just an example and you may need to modify the code to meet your specific requirements.
References
- “Bitcoin Programming” by Jimmy Song (2019)
- Bitcoin Protocol Specification (Section 5.1.8)