diff --git a/sdk/examples/remote-signer/app/signer.py b/sdk/examples/remote-signer/app/signer.py index 8ec7a68..fd31d3a 100644 --- a/sdk/examples/remote-signer/app/signer.py +++ b/sdk/examples/remote-signer/app/signer.py @@ -1,6 +1,11 @@ import hashlib -import ecdsa -from ecdsa import SECP256k1 + +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.asymmetric.utils import ( + Prehashed, + decode_dss_signature, +) # secp256k1 curve order half (for low-S check) _HALF_ORDER = 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DBFE92F1A9F2A0746 @@ -29,14 +34,17 @@ def _bitcoin_message_magic(message: bytes) -> bytes: def sign_bytes(message: bytes, private_key_bytes: bytes) -> str: """Sign message bytes using the Bitcoin signed message format.""" - privkey = ecdsa.SigningKey.from_string(private_key_bytes, curve=SECP256k1) + privkey = ec.derive_private_key( + int.from_bytes(private_key_bytes, "big"), ec.SECP256K1() + ) prefixed = _bitcoin_message_magic(message) digest = hashlib.sha256(hashlib.sha256(prefixed).digest()).digest() - raw = privkey.sign_digest(digest, sigencode=ecdsa.util.sigencode_string) + der_sig = privkey.sign(digest, ec.ECDSA(Prehashed(hashes.SHA256()))) + r, s = decode_dss_signature(der_sig) + raw = r.to_bytes(32, "big") + s.to_bytes(32, "big") - s_int = int.from_bytes(raw[32:], "big") - rec_id = 27 if s_int <= _HALF_ORDER else 28 + rec_id = 27 if s <= _HALF_ORDER else 28 return bytes([rec_id]).hex() + raw.hex() diff --git a/sdk/examples/remote-signer/requirements.txt b/sdk/examples/remote-signer/requirements.txt index f8f8cd1..8c1005e 100644 --- a/sdk/examples/remote-signer/requirements.txt +++ b/sdk/examples/remote-signer/requirements.txt @@ -1,7 +1,7 @@ fastapi==0.115.6 uvicorn==0.34.0 -ecdsa==0.19.1 -python-dotenv==1.0.1 -pytest==8.3.4 -pytest-asyncio==0.25.2 +cryptography==44.0.0 +python-dotenv==1.2.2 +pytest==9.0.3 +pytest-asyncio==1.4.0 httpx==0.28.1