State of
Signature Crypto

Overview

  • n-of-n multisig (MuSig variants)
  • MuSig2 usage patterns
    • implementation status
    • discussion about open questions in practice
  • t-of-n threshold sig (FROST)
  • signature aggregation
    • half aggregation
    • full aggregation

MuSig

MuSig Variants

  • MuSig1 (deprecated)
  • MuSig-DN (or alternatively GKMN'21 https://eprint.iacr.org/2021/1055.pdf )
  • MuSig2

MuSig2:
High Level Explanation

  • multiple parties (each having an individual pubkey) sign the same message under a *single* aggregate pubkey
    • great for Taproot
  • simple key setup: everybody can compute aggregate pubkey from individual pubkeys
  • 2-round signing protocol
    (all signers send two broadcast messages)
  • first round can be run before message to be signed (transaction) is known
    • effectively one round

MuSig2:
2-of-2 example

\(X_1\)

\(X_2\)

\( R_1', R_1''\)

\( R_2', R_2''\)

\(s_1\)

\(s_2\)

\( R_i=R_i'(R_i'')^b\)

\(  b = H_\textit{non}(\widetilde X,m, R_1'R_2', R_1''R_2'')\)

\( c = H_\textit{sig}(\widetilde X, R_1R_2, m) \)

\(\text{return}\ (R_1R_2,s_1+s_2)\)

\(\widetilde X=X_1^{\textcolor{#00c3ff}{}{a_1}}\cdot X_2^{\textcolor{#00c3ff}{}{a_2}}\)

\( a_i = H_\textit{agg}(X_i, \{\textit{pk}_1, \textit{pk}_2\})\)

MuSig2:
2-of-2 example

\(X_1\)

\(X_2\)

\( R_1', R_1'', m\)

\( R_2', R_2''\)

\(s_2\)

\(\text{return}\ (R_1R_2,s_1+s_2)\)

\(\widetilde X=X_1^{\textcolor{#00c3ff}{}{a_1}}\cdot X_2^{\textcolor{#00c3ff}{}{a_2}}\)

\( a_i = H_\textit{agg}(X_i, \{\textit{pk}_1, \textit{pk}_2\})\)

MuSig2:
2-of-2 example (precomp)

\(X_1\)

\(X_2\)

\( R_1', R_1''\)

\( R_2', R_2''\)

\(s_2, m\)

\(\text{return}\ (R_1R_2,s_1+s_2)\)

\(\widetilde X=X_1^{\textcolor{#00c3ff}{}{a_1}}\cdot X_2^{\textcolor{#00c3ff}{}{a_2}}\)

\( a_i = H_\textit{agg}(X_i, \{\textit{pk}_1, \textit{pk}_2\})\)

libsecp256k1-zkp implementation

  • (draft) key agg spec: src/modules/musig/musig-spec.mediawiki
  • Jonas' MuSig2 PR #131 (needs review)
  • API is safe to use, if you
    • provide fresh, uniform randomness to nonce gen fn (which returns a "secnonce")
    • the secnonce structure is never copied or serialized.
    • opaque data structures are never written to or read from directly.

Discussion

  • (Hardware) Wallets
    • need to keep state between rounds
    • current workflow vs MuSig2 workflow
    • sweet case:
      Taproot(key = 2of2 MuSig,
        script = 2of3 multisig)
  • Key derivation and descriptors?
    • musig(xpub1/*, xpub2/*) vs
    • musig(xpub1, xpub2)/*
      • it would mean that to the outside world, the combined wallet is just an xpub.

  • PSBT

Threshold

  • t-of-n instead of n-of-n
  • looks similar but key setup in fact much more involved
    • no spontaneous key aggregation as in MuSig
    • secure broadcast channel necessary
    • key shares of other parties need to be backed up
  • candidate scheme: FROST
    • signing very similar to MuSig2
    • looks solid
    • there are bip340 compatible implementations
      • ElementsProject/secp256k1-zkp/pull/138
      • taurusgroup/multi-party-sig
    •  Tim is working on improvements

Cross-Input Signature Aggregation

Signature Aggregation

  • AggVerify((pk_1, m_1), ..., (pk_n, m_n), sig) -> {true, false}
    
  • ​​Trivial solution:

      sig = (sig_1, ..., sig_n)
  • Goal Nr 2: sig should be short

  • Note the different messages != multisignatures, MuSig, etc.

Schnorr Half Aggregation

  • Aggregate(sig_1, ..., sig_n) -> sig
  • |sig| ≈ 1/2 (|sig_1| + ... + |sig_n|)
  • aggregation is non-interactive (can be done by block producers)
  • proposed on Bitcoin mailing list ~2017, recent academic paper (Chalkias et al.)

Schnorr Full Aggregation

  • |sig| = |sig_1|

  • aggregation _is_ interactive

  • Tx-wide aggregation

  • can be combined with half aggregation

Consensus

  • Requires new signature verification algorithm
  • Only available update path: new SegWit version due to interactions with OP_SUCCESS
  • Option: new SegWit version, only allow aggregation of key path spends
    • But that's limiting
  • Better: Move public keys out of Script
    • instead of taproot merkle tree leafs being scripts
    • leafs consist of both pubkey and script
    • in order to spend need both sig for pubkey and script inputs
  • Most advanced in that family of ideas: entroot (surprisingly elegant & simple update)

Savings for typical tx

|                                               | bytes | weight units |
|-----------------------------------------------+-------+--------------|
| half aggregation                              | 20.6% |         7.6% |
| full aggregation                              | 26.1% |         9.6% |
| both                                          | 33.6% |        12.4% |
| max (like infinite large full agged coinjoin)  | 41.2% |        15.2% |

Discussion

  • full aggregation: nonce generation similar to MuSig. Unless all other partial signatures come from trusted signers, no deterministic nonce generation, hence randomness (or non-repeating counter) required
  • half aggregation:
    • how to resubmit transactions after a reorgs (only a problem if used across transactions)?
    • breaks adaptor sigs?
    • more CPU/byte necessary to verify a block
  • github.com/ElementsProject/cross-input-aggregation
  • https://www.youtube.com/watch?v=Dns_9jaNPNk

State of libsecp256k1

libsecp256k1

  • started by Pieter Wuille in 2013 to replace OpenSSL's ECDSA implementation in Bitcoin Core
  • written in C (... C89)
  • general-purpose library but written with Bitcoin Core as a main user in mind
  • ECDSA and tweaking keys (e.g., for BIP32)
  • modules for
    • ECDSA with key recovery
    • ECDH
    • Schnorr sigs (experimental?!)
    • extra keys (experimental?!)

Problems

  • No clear rule what should be in libsecp256k1
    • only stuff used by Core?
      • counter-example: ECDH
    • "things relevant to the wider Bitcoin ecosystem"
      • should those be in forks like libsecp256k1-zkp?
  • No release ever
    • experimental modules
  • Lack of developers
    • lots of abandoned PRs
    • people think they can't contribute because they lack expertise in cryptography but that's just not true

CoreDev

By iamjon

CoreDev

  • 364