I’m trying to understand the output format for Trezor signatures so I can verify it from another library programmatically. And I’m trying to use trezorctl to sign 32 byte messages and passing them in as base64 to the cli.
trezorctl get_public_node -n “m/44’/0’/0’/0/0”
Gives me a proper hex encoded public key that I can decode properly.
trezorctl sign-message -n “m/44’/0’/0’/0/0” “my_32_byte_b64encoded_message_here”
Gives me an output with an address, the message in encoded format, and the signature also in b64 format.
When I decode the b64 signature, it’s 65 bytes long, and I’m expecting 64 bytes to be the signature digest, and 1 byte at the front to be the recovery id (this was the only information I could find online and seems to match up.)
Recovery ids only can be 0,1,2,3 as a value, and what I got back was 31 or 32 on a different attempt.
I tried using all the possible recovery ids and using a Secp256k1 recovery function with the same message, and it yields a public key that does NOT match the output of get_public_node.
What am I not understanding here? I’ve gone through the trezorctl python code but I can’t find the encoder / decoders for this. Most other libraries for recoveryIds just represent them as a value with 4 possibilities.
Can anyone point me to any reference for how to decode this signature in compact format? I actually don’t even care about recovering the public key, the problem is that the signature fails to verify in the library I’m using (rust bitcoin lib,) so I was trying to double check that I’m decoding the signature properly. If I could just have a sanity check from anyone who knows what is going on here and knows how to decode the recoverable id and/or get the public key to match get_public_node it would help a lot. Maybe I am making some trivial mistake here?
I also tried using the GUI verify_message with the outputs it produced, and it worked entirely, I don’t think trezor is the issue here, I just can’t figure out how to manually decode the signature for use in another library.