Is there a difference between this bip322-js Verifier and the one used in Ledger ?
Closed this issue ยท 7 comments
I'm trying to validate a message signature made with ledger it validates with no problem in there but the script throws the following error:
RangeError [ERR_OUT_OF_RANGE]: The value of "offset" is out of range. It must be >= 0 and <= 64. Received 116
at new NodeError (node:internal/errors:399:5)
at boundsError (node:internal/buffer:88:9)
at Buffer.readUInt8 (node:internal/buffer:254:5)
at Object.decode (C:\Users\PIKO\Desktop\bip-322js\bip322-js\node_modules\bip174\src\lib\converter\varint.js:43:24)
at readVarInt (C:\Users\PIKO\Desktop\bip-322js\bip322-js\node_modules\bitcoinjs-lib\src\psbt.js:1479:24)
at readVarSlice (C:\Users\PIKO\Desktop\bip-322js\bip322-js\node_modules\bitcoinjs-lib\src\psbt.js:1484:22)
at readVector (C:\Users\PIKO\Desktop\bip-322js\bip322-js\node_modules\bitcoinjs-lib\src\psbt.js:1489:49)
at scriptWitnessToWitnessStack (C:\Users\PIKO\Desktop\bip-322js\bip322-js\node_modules\bitcoinjs-lib\src\psbt.js:1492:10)
at C:\Users\PIKO\Desktop\bip-322js\bip322-js\node_modules\bitcoinjs-lib\src\psbt.js:1544:29
at Array.forEach (<anonymous>) {
code: 'ERR_OUT_OF_RANGE'
}
is there any tips or suggestions.
Do you have an example of a signature (and the address associated with that signature) that produce such an error?
Yes here is the example:
{
"address": "bc1ps5pt865e77nr9t9z7fdefryx27lsz0ced875lxcc68lszvc7x3qsxx25fy",
"message": "bitcheckdiuq5gh179v9r5vwmw58ijtkea1vb4idr92khiu",
// Signed signature (from Ledger)
"signature": "HxOxevYmNjW58m/TBcewrpLbOC0NXjwnWO+jccW9tq8JbdtjI8modbmYbJNVO6PpE9MATfiZeU/S/GbmozNhV4Y="
}
I think your signature may not be a valid BIP-322 signature, since a valid simple BIP-322 signature for a single-key spend taproot address should starts with 01 in hexadecimal (which indicates one witness element).
Rather, your signature looks like it may be using the Legacy Signature Scheme which is only supported when used together with legacy address (i.e., address that starts with 1....).
If you need to sign a BIP-322 message with a Ledger device, you can try to use sign-with-ledger-btc developed by me.
If you need further assistance, please provide details on how you create the signature provided (e.g., code sample or software used in the signing process).
ok thank for all the info, the signature was created using sparrow, and it was provided to us to verify through a client so we don't really have that much of control for the testing.
I have take a look at how Sparrow works and I think I have figured out how they sign/verify this type of signature.
The signature produced by Sparrow uses the signMessage API provided by Ledger which will produce a signature under the BIP-137 Legacy Signature Scheme.
During the verification of such signature, normally a public key will be reconstructed from the signature, and then that public key will be used to derive an address of the same type (e.g., P2PKH/P2WPKH) and a signature is considered valid if the address derived matched with the claimed 'signing address'.
From the signature you have provided, it is possible to derive the public key '034ba1207ba951038c4d6b75a9a17041479a58fa726ad9635b47e0e70d7ffd1837', which corresponds to the address '19C7EwHP5FN32YPrMRfW7mkFKg3FYwyAzr' in P2PKH and 'bc1ps5pt865e77nr9t9z7fdefryx27lsz0ced875lxcc68lszvc7x3qsxx25fy' in P2TR.
With that knowledge, you can then use a Bitcoin Signature Verifier to verify that the signature 'HxOxevYmNjW58m/TBcewrpLbOC0NXjwnWO+jccW9tq8JbdtjI8modbmYbJNVO6PpE9MATfiZeU/S/GbmozNhV4Y=' is in fact a valid signature signed by '19C7EwHP5FN32YPrMRfW7mkFKg3FYwyAzr' for the message 'bitcheckdiuq5gh179v9r5vwmw58ijtkea1vb4idr92khiu'.
Since both address '19C7EwHP5FN32YPrMRfW7mkFKg3FYwyAzr' and 'bc1ps5pt865e77nr9t9z7fdefryx27lsz0ced875lxcc68lszvc7x3qsxx25fy' have the same underlying public key, control of the address '19C7EwHP5FN32YPrMRfW7mkFKg3FYwyAzr' do implies that the user also control 'bc1ps5pt865e77nr9t9z7fdefryx27lsz0ced875lxcc68lszvc7x3qsxx25fy'. Hence, the verification is successful.
I believe this is an extended/customized uses of the BIP-137 Legacy Signature Scheme, rather than a BIP-322 signature, since such usage is not mentioned explicitly within the standard.
Considering that the implementation should be rather trivial, and Sparrow wallet is indeed used by lots of people, I think I will implement support for such usage in the next release.
Thanks for reporting the issue.
i know i've been a burden, just one last thing is there a package that can handle the extraction of the public key and the address ?
thank you a lot!
The following code should work after upgrading to the v1.1.0 release:
const { Verifier } = require('bip322-js');
const address = 'bc1ps5pt865e77nr9t9z7fdefryx27lsz0ced875lxcc68lszvc7x3qsxx25fy';
const message = 'bitcheckdiuq5gh179v9r5vwmw58ijtkea1vb4idr92khiu';
const signature = 'HxOxevYmNjW58m/TBcewrpLbOC0NXjwnWO+jccW9tq8JbdtjI8modbmYbJNVO6PpE9MATfiZeU/S/GbmozNhV4Y=';
console.log(Verifier.verifySignature(address, message, signature)); // True
You can also assess the function to extract public key from BIP-137 signature via the BIP137 class, and convert public key into Bitcoin address via the Address class within the package.
Please refer to the documentation for more details.
Thanks again for reporting the issue.