State of
Signature Crypto
Overview
 nofn multisig (MuSig variants)
 MuSig2 usage patterns
 implementation status
 discussion about open questions in practice
 tofn threshold sig (FROST)
 signature aggregation
 half aggregation
 full aggregation
MuSig
MuSig Variants
 MuSig1 (deprecated)
 MuSigDN (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
 2round 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:
2of2 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:
2of2 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:
2of2 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\})\)
libsecp256k1zkp implementation
 (draft) key agg spec: src/modules/musig/musigspec.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
 tofn instead of nofn
 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/secp256k1zkp/pull/138
 taurusgroup/multipartysig
 Tim is working on improvements
CrossInput 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 noninteractive (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

Txwide 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 nonrepeating 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/crossinputaggregation
 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)
 generalpurpose 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?
 counterexample: ECDH
 "things relevant to the wider Bitcoin ecosystem"
 should those be in forks like libsecp256k1zkp?
 only stuff used by Core?
 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
 114