| name | message-signing |
| description | This skill should be used when the user asks to "sign a message", "verify a signature", "use BSM", "use BRC-77", "implement Sigma signing", "create signed messages", "authenticate with Bitcoin", or mentions message signing, signature verification, or authentication protocols on BSV. |
BSV Message Signing
Three approaches for message signing on BSV, from simple to full-featured.
Quick Reference
| Approach | Package | Use Case |
|---|
| Direct SDK | @bsv/sdk | Simple message signing (BSM, BRC-77) |
| Templates | @bopen-io/templates | Script parsing/creation for protocols |
| Sigma Protocol | sigma-protocol | Transaction-bound signatures |
1. Direct SDK Signing
For simple message authentication without transaction context.
BSM (Bitcoin Signed Message)
import { BSM, PrivateKey, Signature, BigNumber } from "@bsv/sdk";
const privateKey = PrivateKey.fromWif("L1...");
const message = [];
const signature = BSM.sign(message, privateKey, "raw") as Signature;
const h = new BigNumber(BSM.magicHash(message));
const recovery = signature.CalculateRecoveryFactor(privateKey.toPublicKey(), h);
const compactSig = signature.toCompact(recovery, true, "base64");
const sig = Signature.fromCompact(compactSig, "base64");
for (let r = 0; r < 4; r++) {
try {
const pubKey = sig.RecoverPublicKey(r, new BigNumber(BSM.magicHash(message)));
if (BSM.verify(message, sig, pubKey)) {
console.log("Signer:", pubKey.toAddress());
break;
}
} catch { }
}
BRC-77 (SignedMessage)
import { SignedMessage, PrivateKey, PublicKey } from "@bsv/sdk";
const signer = PrivateKey.fromWif("L1...");
const message = [];
const sig = SignedMessage.sign(message, signer);
const valid = SignedMessage.verify(message, sig);
const recipientPubKey = PublicKey.fromString("02...");
const privateSig = SignedMessage.sign(message, signer, recipientPubKey);
const recipientKey = PrivateKey.fromWif("K1...");
const privateValid = SignedMessage.verify(message, privateSig, recipientKey);
See: examples/bsm-sign-verify.ts, examples/brc77-private-sig.ts
2. Template-Based Signing
For working with BitCom protocols and script parsing. Uses @bopen-io/templates.
Sigma Template
import { Sigma, SigmaAlgorithm, BitCom } from "@bopen-io/templates";
import { PrivateKey, Hash } from "@bsv/sdk";
const bitcom = BitCom.decode(script);
const sigmas = Sigma.decode(bitcom);
const inputHash = Array.from(Hash.sha256(outpointBytes));
const dataHash = Array.from(Hash.sha256(scriptDataBytes));
const sigma = Sigma.sign(inputHash, dataHash, privateKey, {
algorithm: SigmaAlgorithm.BRC77,
vin: 0
});
const valid = sigma.verifyWithHashes(inputHash, dataHash);
const lockingScript = sigma.lock();
AIP Template
import { AIP, BitCom } from "@bopen-io/templates";
const bitcom = BitCom.decode(script);
const aips = AIP.decode(bitcom);
const aip = await AIP.sign(dataBytes, privateKey, {
algorithm: "BITCOIN_ECDSA",
fieldIndexes: [0, 1, 2]
});
const valid = aip.verify();
See: examples/sigma-template.ts
Note: Sigma template requires sigma-protocol as peer dependency for Algorithm enum.
3. Sigma Protocol (Full Transaction Signing)
For complete transaction-bound signatures. Use when:
- Signing OP_RETURN data in transactions
- Need multiple signatures on same output
- Want automatic hash calculation from transaction context
bun add sigma-protocol
import { Sigma, Algorithm } from "sigma-protocol";
import { Transaction, PrivateKey } from "@bsv/sdk";
const sigma = new Sigma(tx, targetVout, sigmaInstance, refVin);
const { signedTx } = sigma.sign(privateKey);
const { signedTx: tx2 } = sigma.sign(privateKey, Algorithm.BRC77);
const { signedTx: tx3 } = sigma.sign(privateKey, Algorithm.BRC77, verifierPubKey);
const valid = sigma.verify();
const privateValid = sigma.verify(recipientPrivateKey);
Multiple Signatures
const sigma1 = new Sigma(tx, 0, 0);
const { signedTx } = sigma1.sign(userKey, Algorithm.BSM);
const sigma2 = new Sigma(signedTx, 0, 1);
sigma2.sign(platformKey, Algorithm.BRC77);
sigma2.setSigmaInstance(0);
sigma2.verify();
sigma2.setSigmaInstance(1);
sigma2.verify();
See: examples/sigma-multi-sig.ts
Algorithm Comparison
| Feature | BSM | BRC-77 |
|---|
| Key derivation | Direct | Child key per message |
| Recovery | From signature | Embedded in signature |
| Private verify | No | Yes (with recipient key) |
| SDK module | BSM | SignedMessage |
When to Use What
| Scenario | Approach |
|---|
| Simple message auth | Direct SDK (BSM or BRC-77) |
| BAP identity signing | bsv-bap library |
| Parse existing Sigma/AIP scripts | Templates |
| Build BitCom transaction outputs | Templates |
| Sign transaction OP_RETURN data | sigma-protocol |
| Multiple signatures per output | sigma-protocol |
| Platform + user dual signing | sigma-protocol |
BAP Identity Signing (BSM)
BAP identities use BSM for signing. The bsv-bap library handles this:
import { BAP } from "bsv-bap";
import { Utils } from "@bsv/sdk";
const { toArray } = Utils;
const bap = new BAP({ rootPk: wif });
const identity = bap.getId(bap.listIds()[0]);
const message = toArray("Hello World", "utf8");
const { address, signature } = identity.signMessage(message);
const isValid = bap.verifySignature("Hello World", address, signature);
A CLI is also available: npm install -g bsv-bap (see create-bap-identity skill).
Additional Resources
Reference Files
references/brc-77-spec.md - Full BRC-77 specification
references/sigma-advanced.md - Remote signing, hash details, advanced patterns
Examples
examples/bsm-sign-verify.ts - Direct BSM signing
examples/brc77-private-sig.ts - BRC-77 private signatures
examples/sigma-template.ts - Template-based Sigma operations
examples/sigma-multi-sig.ts - Full sigma-protocol with multi-sig