Validation of ECDSA Signature Component using 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 using Mod N.
ECDSA Signing/Verification Procedure
In the book “Programming Bitcoin” by Jimmy Song, it is mentioned that the ECDSA signing/verification procedure for message hash z
involves the following steps:
- Extract the public key
P
from the private keye
.
- Compute the signature of the message hash
z
using the ECDSA algorithm:
S = r * G^x mode 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 mode 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 using 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 an arbitrary 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 struct to represent ECDSA signature components
typedef struct {
uint8_t r[4];
uint8_t x;
} S;
// Function to compute 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;
// Compute 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;
// Compute 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 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 public key components from private key
const uint32_t d = (z[0] << 24) + (z[1] << 16) + (z[2] << 8) + z[3];
// Compute 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 computed 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 Mod N in Bitcoin Core. Note that this is just an example and you may need to modify the code to suit your specific requirements.
References
- “Programming Bitcoin” by Jimmy Song (2019)
- Bitcoin Protocol Specification (section 5.1.8)