Using wallets like XVerse, users can sign a message using their ordinal btc address, let's say bc1XXX, the message is hashed based on BIP0322.
So I have:
- User wallet: bc1XXX
- Message hash: YYY
- Signature signed by bc1XXX: ZZZ
So this data is sent to my backend server, and I want to verify that ZZZ was indeed signed by bc1XXX (and contains YYY as message).
I'm using this so far:
const msgHash = bip0322Hash(message);
const signatureBuffer = Buffer.from(signatureStr, 'base64');
const decodedSignature = signatureBuffer.slice(2, 66);
const recoveryId = signatureBuffer[0];
// Extract public key from the signature
const recoveredPublicKeyBuffer = secp.recoverPublicKey(
msgHash,
decodedSignature,
recoveryId, // Recovery ID (0 or 1)
false
);
console.log(publicKeyToTaprootAddress(recoveredPublicKeyBuffer)); //no match with my original pubkey that signed the message
But I have a hard time getting the correct address from recoveredPublicKeyBuffer
which I can't match with the public key address of my test set.
I'm trying to use this function, but the output doesn't match my pubkey:
function publicKeyToTaprootAddress(publicKey: Uint8Array) {
// Compute the SHA-256 hash of the public key
const hash = sha256(Buffer.from(publicKey));
// Construct the human-readable part and the data part of the Bech32m string
const hrp = 'bc';
const data = sha256(Buffer.from([0x01].concat(Array.from(hash))));
const data2 = bech32m.toWords(Buffer.from(data));
// Encode the Bech32m string
return bech32m.encode(hrp, data2);
}
from Recent Questions - Bitcoin Stack Exchange
May 18, 2023 at 12:33AM