context.go raw

   1  // Copyright (c) 2013-2022 The btcsuite developers
   2  
   3  package musig2
   4  
   5  import (
   6  	"fmt"
   7  
   8  	"next.orly.dev/pkg/nostr/crypto/ec"
   9  	"next.orly.dev/pkg/nostr/crypto/ec/schnorr"
  10  	"next.orly.dev/pkg/lol/chk"
  11  )
  12  
  13  var (
  14  	// ErrSignersNotSpecified is returned when a caller attempts to create
  15  	// a context without specifying either the total number of signers, or
  16  	// the complete set of singers.
  17  	ErrSignersNotSpecified = fmt.Errorf(
  18  		"total number of signers or all " +
  19  			"signers must be known",
  20  	)
  21  	// ErrSignerNotInKeySet is returned when a the secret key for a signer
  22  	// isn't included in the set of signing public keys.
  23  	ErrSignerNotInKeySet = fmt.Errorf(
  24  		"signing key is not found in key" +
  25  			" set",
  26  	)
  27  	// ErrAlreadyHaveAllNonces is called when RegisterPubNonce is called too
  28  	// many times for a given signing session.
  29  	//
  30  	// ErrAlreadyHaveAllNonces is returned when a caller attempts to
  31  	// register a signer, once we already have the total set of known
  32  	// signers.
  33  	ErrAlreadyHaveAllNonces = fmt.Errorf("already have all nonces")
  34  	// ErrNotEnoughSigners is returned when a caller attempts to create a
  35  	// session from a context, but before all the required signers are
  36  	// known.
  37  	//
  38  	// ErrNotEnoughSigners is returned if a caller attempts to obtain an
  39  	// early nonce when it wasn't specified
  40  	ErrNotEnoughSigners      = fmt.Errorf("not enough signers")
  41  	ErrAlreadyHaveAllSigners = fmt.Errorf("all signers registered")
  42  	// ErrAlredyHaveAllSigs is called when CombineSig is called too many
  43  	// times for a given signing session.
  44  	ErrAlredyHaveAllSigs = fmt.Errorf("already have all sigs")
  45  	// ErrSigningContextReuse is returned if a user attempts to sign using
  46  	// the same signing context more than once.
  47  	ErrSigningContextReuse = fmt.Errorf("nonce already used")
  48  	// ErrFinalSigInvalid is returned when the combined signature turns out
  49  	// to be invalid.
  50  	ErrFinalSigInvalid = fmt.Errorf("final signature is invalid")
  51  	// ErrCombinedNonceUnavailable is returned when a caller attempts to
  52  	// sign a partial signature, without first having collected all the
  53  	// required combined nonces.
  54  	ErrCombinedNonceUnavailable = fmt.Errorf("missing combined nonce")
  55  	// ErrTaprootInternalKeyUnavailable is returned when a user attempts to
  56  	// obtain the
  57  	ErrTaprootInternalKeyUnavailable = fmt.Errorf("taproot tweak not used")
  58  	ErrNoEarlyNonce                  = fmt.Errorf("no early nonce available")
  59  )
  60  
  61  // Context is a managed signing context for musig2. It takes care of things
  62  // like securely generating secret nonces, aggregating keys and nonces, etc.
  63  type Context struct {
  64  	// signingKey is the key we'll use for signing.
  65  	signingKey *btcec.SecretKey
  66  	// pubKey is our even-y coordinate public  key.
  67  	pubKey *btcec.PublicKey
  68  	// combinedKey is the aggregated public key.
  69  	combinedKey *AggregateKey
  70  	// uniqueKeyIndex is the index of the second unique key in the keySet.
  71  	// This is used to speed up signing and verification computations.
  72  	uniqueKeyIndex int
  73  	// keysHash is the hash of all the keys as defined in musig2.
  74  	keysHash []byte
  75  	// opts is the set of options for the context.
  76  	opts *contextOptions
  77  	// shouldSort keeps track of if the public keys should be sorted before
  78  	// any operations.
  79  	shouldSort bool
  80  	// sessionNonce will be populated if the earlyNonce option is true.
  81  	// After the first session is created, this nonce will be blanked out.
  82  	sessionNonce *Nonces
  83  }
  84  
  85  // ContextOption is a functional option argument that allows callers to modify
  86  // the musig2 signing is done within a context.
  87  type ContextOption func(*contextOptions)
  88  
  89  // contextOptions houses the set of functional options that can be used to
  90  // musig2 signing protocol.
  91  type contextOptions struct {
  92  	// tweaks is the set of optinoal tweaks to apply to the combined public
  93  	// key.
  94  	tweaks []KeyTweakDesc
  95  	// taprootTweak specifies the taproot tweak. If specified, then we'll
  96  	// use this as the script root for the BIP 341 taproot (x-only) tweak.
  97  	// Normally we'd just apply the raw 32 byte tweak, but for taproot, we
  98  	// first need to compute the aggregated key before tweaking, and then
  99  	// use it as the internal key. This is required as the taproot tweak
 100  	// also commits to the public key, which in this case is the aggregated
 101  	// key before the tweak.
 102  	taprootTweak []byte
 103  	// bip86Tweak if true, then the weak will just be
 104  	// h_tapTweak(internalKey) as there is no true script root.
 105  	bip86Tweak bool
 106  	// keySet is the complete set of signers for this context.
 107  	keySet []*btcec.PublicKey
 108  	// numSigners is the total number of signers that will eventually be a
 109  	// part of the context.
 110  	numSigners int
 111  	// earlyNonce determines if a nonce should be generated during context
 112  	// creation, to be automatically passed to the created session.
 113  	earlyNonce bool
 114  }
 115  
 116  // defaultContextOptions returns the default context options.
 117  func defaultContextOptions() *contextOptions { return &contextOptions{} }
 118  
 119  // WithTweakedContext specifies that within the context, the aggregated public
 120  // key should be tweaked with the specified tweaks.
 121  func WithTweakedContext(tweaks ...KeyTweakDesc) ContextOption {
 122  	return func(o *contextOptions) { o.tweaks = tweaks }
 123  }
 124  
 125  // WithTaprootTweakCtx specifies that within this context, the final key should
 126  // use the taproot tweak as defined in BIP 341: outputKey = internalKey +
 127  // h_tapTweak(internalKey || scriptRoot). In this case, the aggreaged key
 128  // before the tweak will be used as the internal key.
 129  func WithTaprootTweakCtx(scriptRoot []byte) ContextOption {
 130  	return func(o *contextOptions) { o.taprootTweak = scriptRoot }
 131  }
 132  
 133  // WithBip86TweakCtx specifies that within this context, the final key should
 134  // use the taproot tweak as defined in BIP 341, with the BIP 86 modification:
 135  // outputKey = internalKey + h_tapTweak(internalKey)*G. In this case, the
 136  // aggreaged key before the tweak will be used as the internal key.
 137  func WithBip86TweakCtx() ContextOption {
 138  	return func(o *contextOptions) { o.bip86Tweak = true }
 139  }
 140  
 141  // WithKnownSigners is an optional parameter that should be used if a session
 142  // can be created as soon as all the singers are known.
 143  func WithKnownSigners(signers []*btcec.PublicKey) ContextOption {
 144  	return func(o *contextOptions) {
 145  		o.keySet = signers
 146  		o.numSigners = len(signers)
 147  	}
 148  }
 149  
 150  // WithNumSigners is a functional option used to specify that a context should
 151  // be created without knowing all the signers. Instead the total number of
 152  // signers is specified to ensure that a session can only be created once all
 153  // the signers are known.
 154  //
 155  // NOTE: Either WithKnownSigners or WithNumSigners MUST be specified.
 156  func WithNumSigners(n int) ContextOption {
 157  	return func(o *contextOptions) { o.numSigners = n }
 158  }
 159  
 160  // WithEarlyNonceGen allow a caller to specify that a nonce should be generated
 161  // early, before the session is created. This should be used in protocols that
 162  // require some partial nonce exchange before all the signers are known.
 163  //
 164  // NOTE: This option must only be specified with the WithNumSigners option.
 165  func WithEarlyNonceGen() ContextOption {
 166  	return func(o *contextOptions) { o.earlyNonce = true }
 167  }
 168  
 169  // NewContext creates a new signing context with the passed singing key and set
 170  // of public keys for each of the other signers.
 171  //
 172  // NOTE: This struct should be used over the raw Sign API whenever possible.
 173  func NewContext(
 174  	signingKey *btcec.SecretKey, shouldSort bool,
 175  	ctxOpts ...ContextOption,
 176  ) (*Context, error) {
 177  
 178  	// First, parse the set of optional context options.
 179  	opts := defaultContextOptions()
 180  	for _, option := range ctxOpts {
 181  		option(opts)
 182  	}
 183  	pubKey := signingKey.PubKey()
 184  	ctx := &Context{
 185  		signingKey: signingKey,
 186  		pubKey:     pubKey,
 187  		opts:       opts,
 188  		shouldSort: shouldSort,
 189  	}
 190  	switch {
 191  	// We know all the signers, so we can compute the aggregated key, along
 192  	// with all the other intermediate state we need to do signing and
 193  	// verification.
 194  	case opts.keySet != nil:
 195  		if err := ctx.combineSignerKeys(); chk.T(err) {
 196  			return nil, err
 197  		}
 198  	// The total signers are known, so we add ourselves, and skip key
 199  	// aggregation.
 200  	case opts.numSigners != 0:
 201  		// Otherwise, we'll add ourselves as the only known signer, and
 202  		// await further calls to RegisterSigner before a session can
 203  		// be created.
 204  		opts.keySet = make([]*btcec.PublicKey, 0, opts.numSigners)
 205  		opts.keySet = append(opts.keySet, pubKey)
 206  	default:
 207  		return nil, ErrSignersNotSpecified
 208  	}
 209  	// If early nonce generation is specified, then we'll generate the
 210  	// nonce now to pass in to the session once all the callers are known.
 211  	if opts.earlyNonce {
 212  		var err error
 213  		ctx.sessionNonce, err = GenNonces(
 214  			WithPublicKey(ctx.pubKey),
 215  			WithNonceSecretKeyAux(signingKey),
 216  		)
 217  		if err != nil {
 218  			return nil, err
 219  		}
 220  	}
 221  	return ctx, nil
 222  }
 223  
 224  // combineSignerKeys is used to compute the aggregated signer key once all the
 225  // signers are known.
 226  func (c *Context) combineSignerKeys() error {
 227  	// As a sanity check, make sure the signing key is actually
 228  	// amongst the sit of signers.
 229  	var keyFound bool
 230  	for _, key := range c.opts.keySet {
 231  		if key.IsEqual(c.pubKey) {
 232  			keyFound = true
 233  			break
 234  		}
 235  	}
 236  	if !keyFound {
 237  		return ErrSignerNotInKeySet
 238  	}
 239  
 240  	// Now that we know that we're actually a signer, we'll
 241  	// generate the key hash finger print and second unique key
 242  	// index so we can speed up signing later.
 243  	c.keysHash = keyHashFingerprint(c.opts.keySet, c.shouldSort)
 244  	c.uniqueKeyIndex = secondUniqueKeyIndex(
 245  		c.opts.keySet, c.shouldSort,
 246  	)
 247  	keyAggOpts := []KeyAggOption{
 248  		WithKeysHash(c.keysHash),
 249  		WithUniqueKeyIndex(c.uniqueKeyIndex),
 250  	}
 251  	switch {
 252  	case c.opts.bip86Tweak:
 253  		keyAggOpts = append(
 254  			keyAggOpts, WithBIP86KeyTweak(),
 255  		)
 256  	case c.opts.taprootTweak != nil:
 257  		keyAggOpts = append(
 258  			keyAggOpts, WithTaprootKeyTweak(c.opts.taprootTweak),
 259  		)
 260  	case len(c.opts.tweaks) != 0:
 261  		keyAggOpts = append(keyAggOpts, WithKeyTweaks(c.opts.tweaks...))
 262  	}
 263  	// Next, we'll use this information to compute the aggregated
 264  	// public key that'll be used for signing in practice.
 265  	var err error
 266  	c.combinedKey, _, _, err = AggregateKeys(
 267  		c.opts.keySet, c.shouldSort, keyAggOpts...,
 268  	)
 269  	if err != nil {
 270  		return err
 271  	}
 272  	return nil
 273  }
 274  
 275  // EarlySessionNonce returns the early session nonce, if available.
 276  func (c *Context) EarlySessionNonce() (*Nonces, error) {
 277  	if c.sessionNonce == nil {
 278  		return nil, ErrNoEarlyNonce
 279  	}
 280  	return c.sessionNonce, nil
 281  }
 282  
 283  // RegisterSigner allows a caller to register a signer after the context has
 284  // been created. This will be used in scenarios where the total number of
 285  // signers is known, but nonce exchange needs to happen before all the signers
 286  // are known.
 287  //
 288  // A bool is returned which indicates if all the signers have been registered.
 289  //
 290  // NOTE: If the set of keys are not to be sorted during signing, then the
 291  // ordering each key is registered with MUST match the desired ordering.
 292  func (c *Context) RegisterSigner(pub *btcec.PublicKey) (bool, error) {
 293  	haveAllSigners := len(c.opts.keySet) == c.opts.numSigners
 294  	if haveAllSigners {
 295  		return false, ErrAlreadyHaveAllSigners
 296  	}
 297  	c.opts.keySet = append(c.opts.keySet, pub)
 298  	// If we have the expected number of signers at this point, then we can
 299  	// generate the aggregated key and other necessary information.
 300  	haveAllSigners = len(c.opts.keySet) == c.opts.numSigners
 301  	if haveAllSigners {
 302  		if err := c.combineSignerKeys(); chk.T(err) {
 303  			return false, err
 304  		}
 305  	}
 306  	return haveAllSigners, nil
 307  }
 308  
 309  // NumRegisteredSigners returns the total number of registered signers.
 310  func (c *Context) NumRegisteredSigners() int { return len(c.opts.keySet) }
 311  
 312  // CombinedKey returns the combined public key that will be used to generate
 313  // multi-signatures  against.
 314  func (c *Context) CombinedKey() (*btcec.PublicKey, error) {
 315  	// If the caller hasn't registered all the signers at this point, then
 316  	// the combined key won't be available.
 317  	if c.combinedKey == nil {
 318  		return nil, ErrNotEnoughSigners
 319  	}
 320  	return c.combinedKey.FinalKey, nil
 321  }
 322  
 323  // PubKey returns the public key of the signer of this session.
 324  func (c *Context) PubKey() btcec.PublicKey { return *c.pubKey }
 325  
 326  // SigningKeys returns the set of keys used for signing.
 327  func (c *Context) SigningKeys() []*btcec.PublicKey {
 328  	keys := make([]*btcec.PublicKey, len(c.opts.keySet))
 329  	copy(keys, c.opts.keySet)
 330  	return keys
 331  }
 332  
 333  // TaprootInternalKey returns the internal taproot key, which is the aggregated
 334  // key _before_ the tweak is applied. If a taproot tweak was specified, then
 335  // CombinedKey() will return the fully tweaked output key, with this method
 336  // returning the internal key. If a taproot tweak wasn't specified, then this
 337  // method will return an error.
 338  func (c *Context) TaprootInternalKey() (*btcec.PublicKey, error) {
 339  	// If the caller hasn't registered all the signers at this point, then
 340  	// the combined key won't be available.
 341  	if c.combinedKey == nil {
 342  		return nil, ErrNotEnoughSigners
 343  	}
 344  	if c.opts.taprootTweak == nil && !c.opts.bip86Tweak {
 345  		return nil, ErrTaprootInternalKeyUnavailable
 346  	}
 347  	return c.combinedKey.PreTweakedKey, nil
 348  }
 349  
 350  // SessionOption is a functional option argument that allows callers to modify
 351  // the musig2 signing is done within a session.
 352  type SessionOption func(*sessionOptions)
 353  
 354  // sessionOptions houses the set of functional options that can be used to
 355  // modify the musig2 signing protocol.
 356  type sessionOptions struct {
 357  	externalNonce *Nonces
 358  }
 359  
 360  // defaultSessionOptions returns the default session options.
 361  func defaultSessionOptions() *sessionOptions { return &sessionOptions{} }
 362  
 363  // WithPreGeneratedNonce allows a caller to start a session using a nonce
 364  // they've generated themselves. This may be useful in protocols where all the
 365  // signer keys may not be known before nonce exchange needs to occur.
 366  func WithPreGeneratedNonce(nonce *Nonces) SessionOption {
 367  	return func(o *sessionOptions) { o.externalNonce = nonce }
 368  }
 369  
 370  // Session represents a musig2 signing session. A new instance should be
 371  // created each time a multi-signature is needed. The session struct handles
 372  // nonces management, incremental partial sig vitrifaction, as well as final
 373  // signature combination. Errors are returned when unsafe behavior such as
 374  // nonce re-use is attempted.
 375  //
 376  // NOTE: This struct should be used over the raw Sign API whenever possible.
 377  type Session struct {
 378  	opts          *sessionOptions
 379  	ctx           *Context
 380  	localNonces   *Nonces
 381  	pubNonces     [][PubNonceSize]byte
 382  	combinedNonce *[PubNonceSize]byte
 383  	msg           [32]byte
 384  	ourSig        *PartialSignature
 385  	sigs          []*PartialSignature
 386  	finalSig      *schnorr.Signature
 387  }
 388  
 389  // NewSession creates a new musig2 signing session.
 390  func (c *Context) NewSession(options ...SessionOption) (*Session, error) {
 391  	opts := defaultSessionOptions()
 392  	for _, opt := range options {
 393  		opt(opts)
 394  	}
 395  	// At this point we verify that we know of all the signers, as
 396  	// otherwise we can't proceed with the session. This check is intended
 397  	// to catch misuse of the API wherein a caller forgets to register the
 398  	// remaining signers if they're doing nonce generation ahead of time.
 399  	if len(c.opts.keySet) != c.opts.numSigners {
 400  		return nil, ErrNotEnoughSigners
 401  	}
 402  	// If an early nonce was specified, then we'll automatically add the
 403  	// corresponding session option for the caller.
 404  	var localNonces *Nonces
 405  	if c.sessionNonce != nil {
 406  		// Apply the early nonce to the session, and also blank out the
 407  		// session nonce on the context to ensure it isn't ever re-used
 408  		// for another session.
 409  		localNonces = c.sessionNonce
 410  		c.sessionNonce = nil
 411  	} else if opts.externalNonce != nil {
 412  		// Otherwise if there's a custom nonce passed in via the
 413  		// session options, then use that instead.
 414  		localNonces = opts.externalNonce
 415  	}
 416  	// Now that we know we have enough signers, we'll either use the caller
 417  	// specified nonce, or generate a fresh set.
 418  	var err error
 419  	if localNonces == nil {
 420  		// At this point we need to generate a fresh nonce. We'll pass
 421  		// in some auxiliary information to strengthen the nonce
 422  		// generated.
 423  		localNonces, err = GenNonces(
 424  			WithPublicKey(c.pubKey),
 425  			WithNonceSecretKeyAux(c.signingKey),
 426  			WithNonceCombinedKeyAux(c.combinedKey.FinalKey),
 427  		)
 428  		if err != nil {
 429  			return nil, err
 430  		}
 431  	}
 432  	s := &Session{
 433  		opts:        opts,
 434  		ctx:         c,
 435  		localNonces: localNonces,
 436  		pubNonces:   make([][PubNonceSize]byte, 0, c.opts.numSigners),
 437  		sigs:        make([]*PartialSignature, 0, c.opts.numSigners),
 438  	}
 439  	s.pubNonces = append(s.pubNonces, localNonces.PubNonce)
 440  	return s, nil
 441  }
 442  
 443  // PublicNonce returns the public nonce for a signer. This should be sent to
 444  // other parties before signing begins, so they can compute the aggregated
 445  // public nonce.
 446  func (s *Session) PublicNonce() [PubNonceSize]byte {
 447  	return s.localNonces.PubNonce
 448  }
 449  
 450  // NumRegisteredNonces returns the total number of nonces that have been
 451  // regsitered so far.
 452  func (s *Session) NumRegisteredNonces() int { return len(s.pubNonces) }
 453  
 454  // RegisterPubNonce should be called for each public nonce from the set of
 455  // signers. This method returns true once all the public nonces have been
 456  // accounted for.
 457  func (s *Session) RegisterPubNonce(nonce [PubNonceSize]byte) (bool, error) {
 458  	// If we already have all the nonces, then this method was called too
 459  	// many times.
 460  	haveAllNonces := len(s.pubNonces) == s.ctx.opts.numSigners
 461  	if haveAllNonces {
 462  		return false, ErrAlreadyHaveAllNonces
 463  	}
 464  	// Add this nonce and check again if we already have tall the nonces we
 465  	// need.
 466  	s.pubNonces = append(s.pubNonces, nonce)
 467  	haveAllNonces = len(s.pubNonces) == s.ctx.opts.numSigners
 468  	// If we have all the nonces, then we can go ahead and combine them
 469  	// now.
 470  	if haveAllNonces {
 471  		combinedNonce, err := AggregateNonces(s.pubNonces)
 472  		if err != nil {
 473  			return false, err
 474  		}
 475  		s.combinedNonce = &combinedNonce
 476  	}
 477  	return haveAllNonces, nil
 478  }
 479  
 480  // Sign generates a partial signature for the target message, using the target
 481  // context. If this method is called more than once per context, then an error
 482  // is returned, as that means a nonce was re-used.
 483  func (s *Session) Sign(
 484  	msg [32]byte,
 485  	signOpts ...SignOption,
 486  ) (*PartialSignature, error) {
 487  
 488  	switch {
 489  	// If no local nonce is present, then this means we already signed, so
 490  	// we'll return an error to prevent nonce re-use.
 491  	case s.localNonces == nil:
 492  		return nil, ErrSigningContextReuse
 493  	// We also need to make sure we have the combined nonce, otherwise this
 494  	// funciton was called too early.
 495  	case s.combinedNonce == nil:
 496  		return nil, ErrCombinedNonceUnavailable
 497  	}
 498  	switch {
 499  	case s.ctx.opts.bip86Tweak:
 500  		signOpts = append(
 501  			signOpts, WithBip86SignTweak(),
 502  		)
 503  	case s.ctx.opts.taprootTweak != nil:
 504  		signOpts = append(
 505  			signOpts, WithTaprootSignTweak(s.ctx.opts.taprootTweak),
 506  		)
 507  	case len(s.ctx.opts.tweaks) != 0:
 508  		signOpts = append(signOpts, WithTweaks(s.ctx.opts.tweaks...))
 509  	}
 510  	partialSig, err := Sign(
 511  		s.localNonces.SecNonce, s.ctx.signingKey, *s.combinedNonce,
 512  		s.ctx.opts.keySet, msg, signOpts...,
 513  	)
 514  	// Now that we've generated our signature, we'll make sure to blank out
 515  	// our signing nonce.
 516  	s.localNonces = nil
 517  	if err != nil {
 518  		return nil, err
 519  	}
 520  	s.msg = msg
 521  	s.ourSig = partialSig
 522  	s.sigs = append(s.sigs, partialSig)
 523  	return partialSig, nil
 524  }
 525  
 526  // CombineSig buffers a partial signature received from a signing party. The
 527  // method returns true once all the signatures are available, and can be
 528  // combined into the final signature.
 529  func (s *Session) CombineSig(sig *PartialSignature) (bool, error) {
 530  	// First check if we already have all the signatures we need. We
 531  	// already accumulated our own signature when we generated the sig.
 532  	haveAllSigs := len(s.sigs) == len(s.ctx.opts.keySet)
 533  	if haveAllSigs {
 534  		return false, ErrAlredyHaveAllSigs
 535  	}
 536  	// TODO(roasbeef): incremental check for invalid sig, or just detect at
 537  	// the very end?
 538  	//
 539  	// Accumulate this sig, and check again if we have all the sigs we
 540  	// need.
 541  	s.sigs = append(s.sigs, sig)
 542  	haveAllSigs = len(s.sigs) == len(s.ctx.opts.keySet)
 543  	// If we have all the signatures, then we can combine them all into the
 544  	// final signature.
 545  	if haveAllSigs {
 546  		var combineOpts []CombineOption
 547  		switch {
 548  		case s.ctx.opts.bip86Tweak:
 549  			combineOpts = append(
 550  				combineOpts, WithBip86TweakedCombine(
 551  					s.msg, s.ctx.opts.keySet,
 552  					s.ctx.shouldSort,
 553  				),
 554  			)
 555  		case s.ctx.opts.taprootTweak != nil:
 556  			combineOpts = append(
 557  				combineOpts, WithTaprootTweakedCombine(
 558  					s.msg, s.ctx.opts.keySet,
 559  					s.ctx.opts.taprootTweak, s.ctx.shouldSort,
 560  				),
 561  			)
 562  		case len(s.ctx.opts.tweaks) != 0:
 563  			combineOpts = append(
 564  				combineOpts, WithTweakedCombine(
 565  					s.msg, s.ctx.opts.keySet,
 566  					s.ctx.opts.tweaks, s.ctx.shouldSort,
 567  				),
 568  			)
 569  		}
 570  		finalSig := CombineSigs(s.ourSig.R, s.sigs, combineOpts...)
 571  		// We'll also verify the signature at this point to ensure it's
 572  		// valid.
 573  		//
 574  		// TODO(roasbef): allow skipping?
 575  		if !finalSig.Verify(s.msg[:], s.ctx.combinedKey.FinalKey) {
 576  			return false, ErrFinalSigInvalid
 577  		}
 578  		s.finalSig = finalSig
 579  	}
 580  	return haveAllSigs, nil
 581  }
 582  
 583  // FinalSig returns the final combined multi-signature, if present.
 584  func (s *Session) FinalSig() *schnorr.Signature { return s.finalSig }
 585