ECDSA Example

This page will walk you through a demonstration of the Elliptic Curve Digital Signature Algorithm using secp256k1.

ECDSA Signing Algorithm in Python

Parameter Value Descrption
p 115792089237316195423570985008687907853269984665640564039457584007908834671663 The elliptic curve is defined over this value. P defines the size of the finite field.
n 115792089237316195423570985008687907852837564279074904382605163141518161494337 This value is the order of the group. It defines the number of possible elliptic curve points given the generator point.
Gx 55066263022277343669578718895168534326250603453777594175500187360389116729240 This value is the x coordinate for the generator point.
Gy 32670510020758816978083085130507043184471273380659243275938904335757337482424 This value is the y coordinate for the generator point.


def ecdsa_sig(m, d):      # ecdsa_sig function takes a message and private key as an integer
    k = random.randint(1, n - 1)     # Create the ephemeral key, k
    m1 = hashlib.sha256()     # Create a hash object
    m1.update(m)
    hashed_message = m1.hexdigest()     # Hash the message
    
    eph_point = Point_Multiplication(Gx, Gy, k, p)     # Calculate ephemeral point using k
    eph_point_x = eph_point[0]

    s_temp = (int(hashed_message, 16) + (d * eph_point_x))
   
    s = (Mod_Inv(k, n) * (s_temp)) % n     # Create s value
    r = eph_point_x     # Create r value
   
    print("Signing Complete")
    print("Eph Point x: " + str(eph_point[0]))
    print("Eph point y: " + str(eph_point[1]))
    print(" ")
    print("R: " + str(r))
    print("S: " + str(s))
   
    """
    1. 0x30 indicates start of DER
    2. One byte to encode length of data
    3. 0x02 header byte indicating integer
    4. One byte to encode length of r
    5. The r value as big-endian integer
    6. 0x02 header byte to indicate integer
    7. One byte to include length of the following s value
    8. The s value as big-endian integer
    """
   
    # DER Format Code Begin
    #------------------------------------------------------------
    r_hex = "00"
    r_hex = r_hex + str(hex(r)[2:])
    s_hex = str(hex(s)[2:])
   
    serial_1 = "30"
    serial_2 = hex(int(((get_length(r_hex) / 2) + (get_length(s_hex) / 2) + 4)))[2:]
    serial_3 = "02"
    serial_4 = hex(int(get_length(hex(r)[2:]) / 2) + 1)[2:]
    serial_5 = "00" + hex(r)[2:]
    serial_6 = "02"
    serial_7 = hex(int(get_length(hex(r)[2:]) / 2))[2:]
    serial_8 = hex(s)[2:]
    
    sig = serial_1 + str(serial_2) + serial_3 + str(serial_4)
    sig = sig + str(serial_5) + serial_6 + str(serial_7) + str(serial_8)
    sig = sig + str(binascii.hexlify(HASH_TYPE))[2:4]
   
    sig = bytes.fromhex(sig)
   
    return sig