Closed ChristopherA closed 6 years ago
The proper terminology is "public key recovery from ECDSA signature".
Some clues on recovering public key from signature in a bitcoin transaction:
Bitcoin ECDSA Recovery: https://bitcointalk.org/index.php?topic=6430.0
Public key recovery from a signature may result in one of 4 possible keys: https://bitcoin.stackexchange.com/questions/42519/is-it-possible-to-get-the-public-key-from-a-transaction-input-that-is-a-pay-to https://bitcoin.stackexchange.com/questions/41615/why-isnt-bitcoin-using-public-key-extraction-from-signature-to-reduce-the-block
More generically for ECDSA signature: https://crypto.stackexchange.com/questions/18105/how-does-recovering-the-public-key-from-an-ecdsa-signature-work
https://github.com/bitcoin/bitcoin/blob/2aed2b30b112aaaf7d46df4fd947648ca8df4e67/src/key.cpp#L55
@jonasschnelli By any chance does your libbtc have the ability to recover public key(s) from transaction signatures? (I recognize there may be 4 possible keys, but as we are writing the spec we can limit which kinds of private keys are used).
Like Bitcoin, a DID:BTCR transaction ideally never re-uses a private key, however, it does sign both the transaction and the DDO object at the same time. The DDO may have other public keys, like your PGP key, but if you want to change the DDO you do another bitcoin transaction.
@roconnor suggests this Haskell code that implements public key recovery: https://github.com/laanwj/Purecoin/blob/master/Purecoin/Crypto/EcDsaSecp256k1.hs#L79-L86
@ChristopherA: Recoverable pubkeys should be easy to add to libbtc. Libbtc depends on libsecp256k1 which has support for recoverable signatures.
Example: tx1-rk63-uvxf-9pqc-sy
references to a tx with two outputs, first output is a OP_RETURN with a 65-byte recoverable signature, seconds is a P2PKH output which indicates if the key is revoked (when spent).
libsecp256k1.c does support key recovery https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1_recovery.h and bitcoin uses it at https://github.com/bitcoin/bitcoin/blob/master/src/pubkey.cpp#L187
On the question of multiple possible keys recovered from a signature:
With NIST ECDSA for any signature there are actually 8 possible different public keys (Y, -Y), (compressed/uncompressed), h=0/1
However, with bitcoin h today is usually 0 (however, there are some examples of h=1 in the past), and most modern code uses compressed
That leaves Y version -Y — we'll have to look at the libsecp256k1.c library and the bitcoin code to see what it does.
For some very rare signature values with small r values there is more than one x-coordinate that will correspond to it. This doubles the number of possible public keys for those cases.
@jonasschnelli Any progress on adding public key recovery to libbtc? Ideally we'd love to have it for the hackathon starting Monday, but I don't want to put pressure on you given short timeing. It would just be very useful.
@ChristopherA: Just opened the pull request: https://github.com/libbtc/libbtc/pull/94 Will merge soon.
TODO:
This is available in libbtc
already fixed in playground (forgot to close this version of the issue)
Ideally it would be great if you could completely verify that a signed DDO and its corresponding DID:BTCR transaction are both have the same public key purely with Bash & CURL, or C and JSON-RPC, calling a full -txindex version of bitcoin-core's bitdcoind (see https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line/blob/master/12_1_Accessing_Bitcoind_with_Curl.md & https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line/blob/master/12_2_Accessing_Bitcoind_with_C.md), and cross-compare it to values on a public bitcoin blockchain explorer.
However, the pubic key is embedded into the transactions signature rather than being bare. I'm not quite sure how easily you can verify that two signed blobs are both signed by the same public key without using a crypto library. It could that that there is some way to do this with bitcoind's cli with some obscure RPC command, but harder is how to do it with explorer data without having an additional crypto tool (of particular importants to non-node browser-based javascript DID:BTCR verifiers.)
Maybe I'm wrong and its easy. Otherwise, we may need to create a utility using libsecp256k1.c to do this.