MuSig2 and DID Aggregation: Multi-Party Beacon Coordination over Nostr

Jun 19, 2026

MuSig2 and DID Aggregation: Multi-Party Beacon Coordination over Nostr

Introduction

If many DID controllers want to anchor their updates in one Bitcoin transaction, they need two things: a multi-party signature scheme and a communication channel. For the first, the did:btcr2 spec gives MuSig2 as a RECOMMENDED example (did:btcr2 spec, Aggregate Beacons). For the second, the spec names Nostr or DIDComm for cohort adverts. The reference implementation uses Nostr or HTTP. With these tools, the Aggregation Service coordinates the signal, but it cannot change the update of a participant.

The Need for Multi-Party Signatures

A btcr2 aggregate beacon transaction commits to a batch of DID updates. If many controllers contribute to the batch, they all must authorize the transaction. A trusted Aggregation Service could hold the signing key. But then that service is a single point of failure and a custody risk.

MuSig2 removes this risk. All participants make one Schnorr signature together, and no party holds the complete private key. On the blockchain, the signature looks the same as a single-signer Schnorr signature. Observers cannot tell if one party or a thousand parties signed the transaction (BIP-327).

MuSig2 Protocol Overview

MuSig2 (BIP-327) is a two-round multi-signature scheme for Schnorr signatures:

Setup Phase

  1. Each participant makes a secp256k1 key pair.
  2. All participants share their public keys.
  3. The Aggregation Service calculates an aggregate public key. This key controls the Pay-to-Taproot (P2TR) beacon address. Each participant calculates the address again and makes sure that its key is in the set (Aggregate Beacons). Key aggregation is n-of-n, so a key-path spend needs a partial signature from every participant.

Round 1: Nonce Exchange

  1. Each participant makes two random secret nonces and the related public nonces. With two nonces, MuSig2 needs only two communication rounds. Earlier schemes such as MuSig1 needed three (BIP-327; MuSig2 paper).
  2. Participants share their public nonce pairs with the other participants, or with one aggregator.
  3. The nonce pairs become one aggregate nonce. BIP-327 permits an untrusted aggregator to do this step and to send the result back to the signers. This makes communication linear, not quadratic, in the number of signers. In btcr2, the Aggregation Service is that aggregator.

Round 2: Partial Signatures

  1. The Aggregation Service builds the beacon transaction. The transaction contains the commitment to the batch of updates.
  2. Each participant calculates a partial signature with its private key and the aggregate nonce.
  3. Each participant sends its partial signature to the Aggregation Service.
  4. The Aggregation Service combines all partial signatures into the final Schnorr signature.

Broadcast

The Aggregation Service broadcasts the complete transaction, with its one aggregate signature, to the Bitcoin network. The transaction is a standard P2TR key-path spend.

Security Properties

  • No trusted dealer: No party makes or holds the full signing key.
  • Accountability: BIP-327 defines partial signature verification to identify a disruptive signer. This check needs the individual public nonce of each signer. With third-party nonce aggregation, the signers do not get those nonces. In btcr2, the Aggregation Service gets them, so the service can do this check. BIP-327 also says that a malicious aggregator can make the signing session fail and blame an honest signer (BIP-327).
  • Unforgeability: The MuSig2 authors proved it unforgeable under the algebraic one-more discrete logarithm (AOMDL) assumption. A malicious aggregator that colludes with all signers except one cannot forge a signature (BIP-327).
  • Privacy: A blockchain observer cannot tell a MuSig2 Taproot output from a single-signer Taproot output. Thus, the chain does not show the number of participants. Script paths in the Taproot tree stay hidden unless a spend uses them (BIP-327).

The Coordination Problem

In MuSig2, participants exchange messages in two rounds. Thus, the participants must find each other and communicate.

Centralized options, for example a web server or a message queue, work. But they add a dependency on one operator. Direct peer-to-peer connections have problems with NAT traversal and discovery.

Nostr as a Transport

The Nostr relay architecture has these properties:

  • Many relays: A client can publish each message to many relays. If the participants use more than one relay, the failure of one relay does not stop the round. The reference implementation connects to four public relays by default, and its docs recommend two or three relays (aggregation docs).
  • Key-based identity: Nostr uses BIP-340 Schnorr signatures over secp256k1 (NIP-01), as btcr2 and Taproot do. Participants can use the key types that they already have. If a participant uses one key for Nostr and for its DID, relays can link the two identities.
  • Asynchronous: Participants do not have to be online at the same time. They publish messages to relays and read them later. But the signal cannot finish until every participant responds.
  • Censorship resistance: If one relay refuses the messages, the participants can use other relays. The docs note that public relays can rate-limit or drop the encrypted events under load (aggregation docs).

The Nostr Adapter

The btcr2 reference implementation (@did-btcr2/aggregation, version 0.7.2 as of September 2026) defines a pluggable Transport interface. The Nostr transport implements this interface. The message flow is as follows (aggregation docs).

Cohort Formation

  1. The Aggregation Service publishes a COHORT_ADVERT message with the cohort conditions.
  2. A participant that wants to join sends a COHORT_OPT_IN message with its public keys. The service accepts it with COHORT_OPT_IN_ACCEPT.
  3. When the cohort has enough members, the service calculates the beacon address. It sends COHORT_READY with the address and the cohort keys. Each participant calculates the address again and compares it.

Update Submission and Validation

  1. Each participant sends SUBMIT_UPDATE with its full signed update. A participant with no update sends an explicit message that it has no update.
  2. The service builds the Beacon Announcement Map or the SMT. It sends DISTRIBUTE_AGGREGATED_DATA to each participant, with the map or the SMT proof of that participant.
  3. Each participant checks that the data includes its update correctly, and sends VALIDATION_ACK.

In this implementation, the service sees the full update of each participant. For the privacy effect on SMT Beacons, see Sparse Merkle Trees for Private DID Updates.

Nonce Exchange

  1. The Aggregation Service sends AUTHORIZATION_REQUEST with the unsigned beacon transaction.
  2. Each participant makes sure that the transaction anchors the signal that it validated (ADR 043). Then it sends its public nonces in a NONCE_CONTRIBUTION message.
  3. The service collects the nonces, calculates the aggregate nonce, and sends it to all participants in an AGGREGATED_NONCE message.
  4. When the participants get the aggregate nonce, Round 2 starts.

Partial Signature Collection

  1. Each participant calculates its partial signature and sends it in a SIGNATURE_AUTHORIZATION message.
  2. The service verifies and collects all partial signatures, and it makes the final signature. The runner gives back the signed transaction, and the operator broadcasts it.

Message Format

Each coordination message is a Nostr event with an application-level message type for the protocol step (nostr.ts):

  • The four cohort-formation messages (COHORT_ADVERT, COHORT_OPT_IN, COHORT_OPT_IN_ACCEPT, COHORT_READY) are plaintext kind-1 events.
  • The update messages and the signature messages are kind-1059 events with NIP-44 encryption.

NIP-44 encrypts each directed message for one recipient. Thus, only that recipient can read it, not the full cohort. NIP-44 does not hide metadata: relays can see the sender key, the time, and the IP address of the client (NIP-44). The plaintext cohort-formation messages show the participant DIDs, the cohort keys, and the beacon address to any reader of the relays. If cohort membership must stay private, we recommend that you use a private relay or the HTTP transport.

Pluggable Communication

As of September 2026, the reference implementation has two production transports behind one interface: a Nostr transport and an HTTP/REST transport. It also defines a DIDComm adapter, but only as a stub (aggregation docs). A full DIDComm adapter would let cohorts coordinate over DIDComm, a DID-native protocol for messages. An organization can also write a custom adapter for its own infrastructure. The MuSig2 protocol logic does not change.

How the Protocol Handles Failures

A distributed protocol must handle participants that go offline. The spec example and the reference implementation handle this in different ways:

  • Timeout in the spec example (n-of-n only): A participant can fail to respond before the round timeout. Then the Aggregation Service can extend the deadline and try again. It cannot continue without that participant, because the aggregate key comes from the full set of cohort keys. A smaller set gives a different beacon address, and each other participant must then publish that address in its DID document. If the participant does not come back, the Aggregate Beacon fails to broadcast Beacon Signals (Aggregate Beacons).
  • Hybrid output (reference implementation): As of September 2026, the beacon address of @did-btcr2/aggregation is a Taproot output with three spend paths (ADR 042; ADR 043). The n-of-n MuSig2 key path is the normal path. A k-of-n script path lets k members sign if other members do not respond, and k is n-1 by default. A timelock recovery path lets the operator get the funds back after a delay.
  • Fall back to a Singleton Beacon: If a participant cannot finish the aggregation round, it can announce its update through a Singleton Beacon. This works only if its DID document lists a Singleton Beacon. The spec RECOMMENDS at least one Singleton Beacon as a fallback (Beacons). Aggregation reduces cost, but it is not a requirement.
  • Aggregation Service failure: If the Aggregation Service goes offline or an attacker controls it, the round fails, and the aggregate beacon does not broadcast. Participants try again in a new round or use a Singleton Beacon. The spec defines no automatic handoff to a different service. BIP-327 forbids two signatures with the same secret nonce (BIP-327). Thus, each new attempt starts with a new nonce exchange.

The hybrid output has tradeoffs. A fallback spend has a larger witness. It also shows the cohort keys on-chain, because a script-path spend reveals the script (BIP-341).

The hybrid output also changes the trust model. The spec says that with its n-of-n setup, no other party "can compromise or invalidate a did:btcr2 identifier of another Aggregation Participant" (Aggregate Beacons). With the hybrid output, k members can spend the beacon UTXO without the other members. The operator can spend it alone after the delay. Honest members sign only a transaction that anchors the signal that they validated, but the script paths do not enforce this rule.

Conclusion

MuSig2 over Nostr gives btcr2 beacon aggregation in which the Aggregation Service needs only limited trust. In the n-of-n design of the spec, no party can forge the aggregate signature. Also, no Beacon Signal goes out without the approval of each member. The reference implementation adds a k-of-n fallback and an operator recovery path. These paths improve liveness, but they relax that approval rule.

The Nostr transport removes the need for a central message server, but each round still depends on one Aggregation Service for liveness. The cohort-formation messages are plaintext on the relays, so we recommend a private relay if cohort membership must stay private. With the pluggable architecture, you can change the communication layer and keep the signature logic.

Jintek LLC