bitcoinjs-message
uses traditional signing process which simply sign message with prefix(if not given) \x18Bitcoin Signed Message:\n
. This kind of signing schema has been common but has limitation as it only supports p2pkh. There are implementations which support other type of address with this schema(bitcoinjs-message
also supports p2wpkh and p2sh-p2wpkh, but not p2tr), but there’s no strict standard for it.
BIP322 suggests a new way of signing schema, in which virtual transaction is required to sign and verify all types of addresses while p2pkh uses traditional signing process. However, it’s still in development and not yet implemented in bitcoin-core as I know.
I was also looking for bip322 message signing library, and just end up implementing it by myself. If you need you can use it. My open source bitcoin-sdk-js
has a feature of bip322 signing and verifying message with javascript, which support p2pkh, p2wpkh and p2tr. It’s verified with bip322 test vector so you can use it. I would try to follow development of bitcoin-core. Be careful as BIP322 itself is in transition.
Below is how to implement.
import * as bitcoin from 'bitcoin-sdk-js'
const keyPair = await bitcoin.wallet.generateKeyPair();
const privkey = keyPair.privateKey;
const pubkey = keyPair.publicKey;
const legacyAddress = await bitcoin.address.generateAddress(
pubkey,
'legacy',
);
const segwitAddress = await bitcoin.address.generateAddress(
pubkey,
'segwit',
);
const tapAddress = await bitcoin.address.generateAddress(
(
await bitcoin.tapscript.getTapTweakedPubkey(
pubkey.slice(2),
await bitcoin.tapscript.getTapTweak(pubkey.slice(2)),
)
).tweakedPubKey,
'taproot',
);
const msg = 'message you want to sign';
// When
const sigLegacy = await bitcoin.crypto.signMessage(
msg,
privkey,
legacyAddress,
);
const sigSegwit = await bitcoin.crypto.signMessage(
msg,
privkey,
segwitAddress,
);
const sigTap = await bitcoin.crypto.signMessage(msg, privkey, tapAddress);
// Then
assert.strictEqual(
await bitcoin.crypto.verifyMessage(msg, sigLegacy, legacyAddress),
true,
);
assert.strictEqual(
await bitcoin.crypto.verifyMessage(msg, sigSegwit, segwitAddress),
true,
);
assert.strictEqual(
await bitcoin.crypto.verifyMessage(msg, sigTap, tapAddress),
true,
);
p.s. I think the website you refer might have an issue with non-ASCII encoding, I recommend this website to test traditional message signing.