Bitcoin Digital Signature Verification Process - step by step python code
This is how the Digital Signature in Bitcoin transaction is verified without revealing the private key
The digital signature is verified as valid because the x
coordinate of the resulting_point
matches the r
value from the signature.
Here’s a breakdown of why this is the key to verification:
Signature Creation: When a message is signed, it generates a pair
(r, s)
:r
is derived from thex
coordinate of a specific point on the elliptic curve, which involves the private key and the hashed message.s
is another value that ties the signature to the private key and the message hash.
Signature Verification: To verify the signature without knowing the private key, we use a mathematical approach with
r
,s
, the public key, and the message hash:By calculating
u
andv
(which involve the inverse ofs
and the hashed message), we reconstruct the elliptic curve point used in the signature process.The
x
coordinate of thisresulting_point
should matchr
if the signature is valid.
Match of
x
andr
: Sincex
fromresulting_point
matchesr
(as you observed), it confirms that:The signature was created with the corresponding private key.
The message wasn’t altered after signing.
This process essentially ensures that only someone with the private key could have generated the signature, while keeping that private key hidden. So, in summary, the
verification hinges on this x == r
equality.
Run Python codes below:
# make sure to run "pip install ecdsa" in your python instance first
# codes below simulate the process of digital signature creation and verification
# you will be asked to add a message, this is arbitrary, you can write anything
# in bitcoin, the message contains the transaction data, something like "Send 1 bitcoin from address A to address B"
# at the end, the code will check if the resulting x coodrinate is equal r, if they are equal then the signature is correct.
# this is how the bitcoin network verifies the correctness of the transaction without the need to revealing the sender's private key
import ecdsa
from ecdsa.curves import SECP256k1
from ecdsa.ellipticcurve import Point
import secrets
import hashlib
# Step 1: Generate a random number (for demonstration purposes)
random_number = secrets.randbelow(SECP256k1.order)
print(f"Step 1: Generated a random number for demonstration: {random_number}")
# Step 2: Generate a private key (think of this as a 'secret' key only known by the signer)
private_key = secrets.randbelow(SECP256k1.order)
print(f"Step 2: Generated a private key: {private_key} (This remains private!)")
# Step 3: Get the generator point on the elliptic curve (a fixed point everyone uses)
generator_point = SECP256k1.generator
print(f"Step 3: Generator Point on the curve (constant and public): {generator_point}")
# Step 4: Multiply the private key with the generator point to get the public key
public_key = generator_point * private_key
print(f"Step 4: Derived public key from the private key (this can be shared): {public_key}")
# Step 5: Create a message (like a transaction to sign)
message = input("\nEnter a message to sign (for example, a Bitcoin transaction): ")
print(f"\nMessage to be signed: '{message}'")
# Step 6: Hash the message (transforms the message into a fixed-size hash)
message_hash = hashlib.sha256(message.encode()).digest()
print(f"Step 6: Hash of the message (unique to this message): {message_hash.hex()}")
# Step 7: Create a signing key from the private key
signing_key = ecdsa.SigningKey.from_secret_exponent(private_key, curve=ecdsa.SECP256k1)
# Step 8: Sign the message hash (creates a digital signature)
signature = signing_key.sign_digest(message_hash, sigencode=ecdsa.util.sigencode_string)
print(f"Step 8: Digital Signature created (r, s values combined): {signature.hex()}")
# Step 9: Extract r and s values from the signature (to understand the signature structure)
r = int.from_bytes(signature[:32], byteorder='big')
s = int.from_bytes(signature[32:], byteorder='big')
print(f"\nSignature Breakdown:\nr: {r}\ns: {s}")
# Step 10: Calculate the inverse of s (used in verification)
s_inv = ecdsa.numbertheory.inverse_mod(s, SECP256k1.order)
print(f"Step 10: Calculated inverse of s: {s_inv}")
# Step 11: Calculate u and v (scalars for verification)
u = int.from_bytes(message_hash, byteorder='big') * s_inv % SECP256k1.order
v = r * s_inv % SECP256k1.order
print(f"Step 11: Calculated u: {u}\nCalculated v: {v}")
# Step 12: Calculate the resulting point using u, v, generator point, and public key
resulting_point = u * generator_point + v * public_key
print(f"Step 12: Resulting Point (derived using u, v, generator, and public key): x = {resulting_point.x()}, y = {resulting_point.y()}")
# Step 13: Verify the signature by comparing resulting_point.x() with r
if resulting_point.x() % SECP256k1.order == r:
print("\n✅ The signature is valid! This verifies that the message came from the holder of the private key without revealing it.")
else:
print("\n❌ The signature is not valid. There may be an error in the process or an invalid signature.")
Further Explanation:
Bitcoin Digital Signature Verification Explained
In Bitcoin, digital signatures enable users to securely sign transactions, proving ownership of their Bitcoin without exposing their private keys. Here’s how this process works and how the code simulates the actual mechanism used in Bitcoin.
Private and Public Key Generation
Every Bitcoin user generates a private key, a secret number that must be kept secure, and a public key, which is derived from the private key. The public key can be shared freely and serves as the “address” others can use to verify the ownership of Bitcoin.Code Representation: The code generates a private key and calculates the public key using a fixed elliptic curve point known as the generator.
Message Creation and Hashing
When a Bitcoin transaction is created, it’s effectively a message instructing the network to transfer Bitcoin from the sender’s address to the recipient’s address. To sign this transaction, the message is first hashed. Hashing transforms the transaction message into a fixed-size string unique to that message, ensuring its integrity.Code Representation: The code takes a user-input message (simulating a Bitcoin transaction) and hashes it using SHA-256, the same hashing algorithm Bitcoin uses.
Signature Creation
Using the private key, the sender creates a digital signature for the hashed transaction message. This signature consists of two parts,r
ands
, which encapsulate the private key’s influence without revealing it. The signature is then added to the transaction before broadcasting to the network.Code Representation: The code signs the hashed message with the private key, producing a unique
r
ands
pair as the signature. This signature binds the transaction to the sender’s private key.
Signature Verification Process
When a Bitcoin node receives the transaction, it checks the signature to verify that it was indeed signed by the private key associated with the sender’s public key, without ever knowing the private key itself. This verification is crucial, as it confirms the sender’s ownership of the funds being transferred.The verification process includes the following steps:
Using the signature (
r
ands
), the public key, and the hashed message, the network reconstructs a point on the elliptic curve.If the x-coordinate of this point matches
r
, the transaction is verified as authentic.Code Representation: The code reconstructs the elliptic curve point from the message hash,
r
,s
, and the public key. If thex-coordinate
of this point matchesr
, the code confirms the signature as valid.
Security of the Process
The digital signature scheme used by Bitcoin (based on the ECDSA algorithm) ensures that only the holder of the private key could produce a signature matching the public key. This mechanism allows Bitcoin transactions to be trustlessly verified by anyone, without risking exposure of the private key.Code Representation: The code demonstrates how ECDSA verification confirms a message’s authenticity without exposing the private key, reflecting Bitcoin’s trustless transaction model.
This digital signature verification mechanism is at the core of Bitcoin’s security model, allowing decentralized and secure transfer of value across the network. By running code that simulates this process, users can appreciate the role of cryptography in enabling trustless, peer-to-peer digital transactions.