I'm switching from the pure Python ecdsa
library to the much faster coincurve
library for signing data. I would also like to switch to coincurve
for verifying the signatures (including the old signatures created by the ecdsa
library).
It appears that signatures created with ecdsa
are not (always?) valid in coincurve
. Could someone please explain why this is not working? Also, it seems that cryptography
library is able to validate both ecdsa
signatures and coincurve
signatures without issues, consistently.
What is even more confusing, if you run below script a few times, is that sometimes it prints point 3 and other times it does not. Why would coincurve
only occasionally find the signature valid?
pip install ecdsa cryptography coincurve
import ecdsa
import hashlib
import coincurve
from coincurve.ecdsa import deserialize_compact, cdata_to_der
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
ecdsa_private_key = ecdsa.SigningKey.generate(ecdsa.SECP256k1, None, hashlib.sha256)
ecdsa_pub = ecdsa_private_key.get_verifying_key()
message = b"Hello world!"
digest = hashlib.sha256(message).digest()
serialized_signature = ecdsa_private_key.sign_digest_deterministic(digest, hashfunc=hashlib.sha256)
signature = cdata_to_der(deserialize_compact(serialized_signature))
cc_private_key = coincurve.PrivateKey(ecdsa_private_key.to_string())
cc_pub = cc_private_key.public_key
crypto_pub = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256K1(), cc_pub.format(True))
if ecdsa_pub.verify_digest(serialized_signature, digest) is True:
print("1. ecdsa can validate its own signature")
crypto_pub.verify(signature, digest, ec.ECDSA(Prehashed(hashes.SHA256())))
print("2. cryptography can validate ecdsa signature (raises exception if not valid)")
if cc_pub.verify(signature, digest, None) is False:
print("3. coincurve will not validate ecdsa signature")
signature = cc_private_key.sign(digest, None)
crypto_pub.verify(signature, digest, ec.ECDSA(Prehashed(hashes.SHA256())))
print("4. cryptography can validate coincurve signature (raises exception if not valid)")
if cc_pub.verify(signature, digest, None) is True:
print("5. coincurve will validate its own signature")