Validating ECDSA Signature Component with Mod N in Bitcoin Core
The Electronic Cash Guidelines (ECG) and the Elliptic Curve Digital Signature Algorithm (ECDSA) are two fundamental components of the Bitcoin protocol. In this article, we will explore how Bitcoin Core validates ECDSA signature components with Mod N.
ECDSA Signature/Verification Procedure
In the book “Programming Bitcoin” by Jimmy Song, it is mentioned that the ECDSA signature/verification procedure for the message hash “z” includes the following steps:
- Extract the public key “P” from the private key “e”.
- Compute the signature of the message hash
zusing the ECDSA algorithm:
S = r * G^x mod M
- Verify the signature by checking if 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 satisfies certain properties. The key property is that the private key e is a modular exponentiation of the generator point G.
In Bitcoin Core, the private key e is represented by a 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 with mod N, we need to define the modulus M such that:
d^e ≡ 1 mod M
G^e ≡ G^x mod M
We can choose any modulus M = p (a prime number) and define the private exponent e as a modular exponentiation 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 to represent the ECDSA signature components
typedef struct {
uint8_t r[4];
uint8_t x;
} S;
// Function to calculate the ECDSA signature and verify it with Mod N
S ecdsa_sign(const uint8_t z, const uint64_t e, const uint8_t p) {
// Extract public key components from the 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 with Mod N
Sr;
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
Sg;
for (int i = 0; i < 4; i++) {
g.r[i] = pow(G, r.r[i], p);
}
return signature;
}
// Function to verify ECDSA signature with mod N
bool ecdsa_verify(const S* signature, const uint64_t e, const uint8_t z, const uint32_t p) {
// Extract public key components from 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 calculated signature with 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 with Mod N in Bitcoin Core. Note that this is just an example and you may need to adapt the code to your specific needs.
References
- “Programming Bitcoin” by Jimmy Song (2019)
- Bitcoin Protocol Specification (section 5.1.8)
