rustyrussell / secp256k1-py

Python FFI bindings for libsecp256k1 (maintained)
MIT License
56 stars 12 forks source link

DER-formatted private keys not supported #16

Open cornwarecjp opened 8 months ago

cornwarecjp commented 8 months ago

The readme says that, when passing a non-True raw value to the secp256k1.PrivateKey constructor, "it is assumed that [privkey] is in the DER format". However, this does not work, and DER parsing does not seem to be implemented.

What happens is that raw==False causes the deserialize method to be called (on line 278). This deserialize method then seems to treat privkey as a hex-encoded raw private key, not a DER-format private key. Passing a DER-formatted key raises an exception, since it is more than 64 bytes long.

I managed to work around this issue in my own code with this way of extracting the secret from the DER-encoded private key:

if priv[0:2] == b'\x30\x81' and priv[3:7] == b'\x02\x01\x01\x04':
    secretLen = priv[7]
    secret = priv[8:8+secretLen]
elif priv[0:3] == b'\x30\x82\x01' and priv[4:8] == b'\x02\x01\x01\x04':
    secretLen = priv[8]
    secret = priv[9:9+secretLen]
else:
    raise Exception('Don\'t know how to parse this private key')

secret = secret.rjust(32, b'\x00')

It's very hacky and certainly not a full DER parser, but the subset of keys for which this works is large enough that it works for my own private key collection (generated by various versions of Bitcoin Core).