Merge pull request #6450 from guggero/taproot-psbt

taproot: add PSBT signing support for Taproot, fix remote signing Taproot support
This commit is contained in:
Oliver Gugger authored and GitHub committed 2022-05-11 11:16:51 +02:00
commit c2adb03e38
16 files changed
+1380 -452

No files matched your search

@@ -25,6 +25,10 @@ addresses](https://github.com/lightningnetwork/lnd/pull/6263). Using
then watch it on chain. Taproot script spends are also supported through the
`signrpc.SignOutputRaw` RPC (`/v2/signer/signraw` in REST).
The `walletrpc.SignPsbt` RPC now also supports [Taproot PSBT
signing](https://github.com/lightningnetwork/lnd/pull/6450) to fully support
remote signing with Taproot outputs.
## MuSig2
The [`signrpc.Signer` RPC service now supports EXPERIMENTAL MuSig2
+2 -2
View File
@@ -6,7 +6,7 @@ require (
github.com/btcsuite/btcd v0.22.0-beta.0.20220413172512-bf64c8bdbbbf
github.com/btcsuite/btcd/btcec/v2 v2.2.0
github.com/btcsuite/btcd/btcutil v1.1.1
github.com/btcsuite/btcd/btcutil/psbt v1.1.3
github.com/btcsuite/btcd/btcutil/psbt v1.1.4
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
github.com/btcsuite/btcwallet v0.15.0
@@ -16,7 +16,6 @@ require (
github.com/btcsuite/btcwallet/wtxmgr v1.5.0
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
github.com/davecgh/go-spew v1.1.1
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1
github.com/dvyukov/go-fuzz v0.0.0-20210602112143-b1f3d6f4ef4e
github.com/go-errors/errors v1.0.1
github.com/golang/protobuf v1.5.2
@@ -76,6 +75,7 @@ require (
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/decred/dcrd/lru v1.0.0 // indirect
github.com/dsnet/compress v0.0.1 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
+2 -2
View File
@@ -87,8 +87,8 @@ github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUB
github.com/btcsuite/btcd/btcutil v1.1.1 h1:hDcDaXiP0uEzR8Biqo2weECKqEw0uHDZ9ixIWevVQqY=
github.com/btcsuite/btcd/btcutil v1.1.1/go.mod h1:nbKlBMNm9FGsdvKvu0essceubPiAcI57pYBNnsLAa34=
github.com/btcsuite/btcd/btcutil/psbt v1.1.1/go.mod h1:KsGzRAzAdEimzgERpK9Xm+RhuCMvc4j2ctK0BEQ8JV0=
github.com/btcsuite/btcd/btcutil/psbt v1.1.3 h1:fMVX0CHlVkI3VSkwMZTArfdVUkfzLuJA+ElQTfqekOU=
github.com/btcsuite/btcd/btcutil/psbt v1.1.3/go.mod h1:GMJ40RHh0brZmhAKjltvYjakbVg9wQqfH+hZF96jIRE=
github.com/btcsuite/btcd/btcutil/psbt v1.1.4 h1:Edx4AfBn+YPam2KP5AobDitulGp4r1Oibm8oruzkMdI=
github.com/btcsuite/btcd/btcutil/psbt v1.1.4/go.mod h1:9AyU6EQVJ9Iw9zPyNT1lcdHd6cnEZdno5wLu5FY74os=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
+3 -3
View File
@@ -9,7 +9,6 @@ import (
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
"golang.org/x/crypto/ripemd160"
)
@@ -1399,7 +1398,7 @@ func TweakPubKeyWithTweak(pubKey *btcec.PublicKey,
tweakJacobian btcec.JacobianPoint
resultJacobian btcec.JacobianPoint
)
tweakKey := secp.PrivKeyFromBytes(tweakBytes)
tweakKey, _ := btcec.PrivKeyFromBytes(tweakBytes)
btcec.ScalarBaseMultNonConst(&tweakKey.Key, &tweakJacobian)
pubKey.AsJacobian(&pubKeyJacobian)
@@ -1549,5 +1548,6 @@ func DeriveRevocationPrivKey(revokeBasePriv *btcec.PrivateKey,
// the key-ring and also to used as a tweak to derive new public+private keys
// for the state.
func ComputeCommitmentPoint(commitSecret []byte) *btcec.PublicKey {
return secp.PrivKeyFromBytes(commitSecret).PubKey()
_, pubKey := btcec.PrivKeyFromBytes(commitSecret)
return pubKey
}
+79 -4
View File
@@ -3,6 +3,7 @@ package input
import (
"encoding/binary"
"errors"
"fmt"
"io"
"github.com/btcsuite/btcd/btcec/v2"
@@ -55,16 +56,29 @@ type SignDescriptor struct {
// DoubleTweak, not both.
DoubleTweak *btcec.PrivateKey
// TapTweak is a 32-byte value that will be used to derive a taproot
// output public key (or the corresponding private key) from an
// internal key and this tweak. The transformation applied is:
// * outputKey = internalKey +
// tagged_hash("tapTweak", internalKey || tapTweak)
//
// When attempting to sign an output derived via BIP 86, then this
// field should be an empty byte array.
//
// When attempting to sign for the key spend path of an output key that
// commits to an actual script tree, the script root should be used.
TapTweak []byte
// WitnessScript is the full script required to properly redeem the
// output. This field should be set to the full script if a p2wsh
// output is being signed. For p2wkh it should be set to the hashed
// script (PkScript).
WitnessScript []byte
// TaprootKeySpend indicates that instead of a witness script being
// spent by the signature that results from this signing request, a
// taproot key spend is performed instead.
TaprootKeySpend bool
// SignMethod specifies how the input should be signed. Depending on the
// selected method, either the TapTweak, WitnessScript or both need to
// be specified.
SignMethod SignMethod
// Output is the target output which should be signed. The PkScript and
// Value fields within the output should be properly populated,
@@ -89,6 +103,67 @@ type SignDescriptor struct {
InputIndex int
}
// SignMethod defines the different ways a signer can sign, given a specific
// input.
type SignMethod uint8
const (
// WitnessV0SignMethod denotes that a SegWit v0 (p2wkh, np2wkh, p2wsh)
// input script should be signed.
WitnessV0SignMethod SignMethod = 0
// TaprootKeySpendBIP0086SignMethod denotes that a SegWit v1 (p2tr)
// input should be signed by using the BIP0086 method (commit to
// internal key only).
TaprootKeySpendBIP0086SignMethod SignMethod = 1
// TaprootKeySpendSignMethod denotes that a SegWit v1 (p2tr)
// input should be signed by using a given taproot hash to commit to in
// addition to the internal key.
TaprootKeySpendSignMethod SignMethod = 2
// TaprootScriptSpendSignMethod denotes that a SegWit v1 (p2tr) input
// should be spent using the script path and that a specific leaf script
// should be signed for.
TaprootScriptSpendSignMethod SignMethod = 3
)
// String returns a human-readable representation of the signing method.
func (s SignMethod) String() string {
switch s {
case WitnessV0SignMethod:
return "witness_v0"
case TaprootKeySpendBIP0086SignMethod:
return "taproot_key_spend_bip86"
case TaprootKeySpendSignMethod:
return "taproot_key_spend"
case TaprootScriptSpendSignMethod:
return "taproot_script_spend"
default:
return fmt.Sprintf("unknown<%d>", s)
}
}
// PkScriptCompatible returns true if the given public key script is compatible
// with the sign method.
func (s SignMethod) PkScriptCompatible(pkScript []byte) bool {
switch s {
// SegWit v0 can be p2wkh, np2wkh, p2wsh.
case WitnessV0SignMethod:
return txscript.IsPayToWitnessPubKeyHash(pkScript) ||
txscript.IsPayToWitnessScriptHash(pkScript) ||
txscript.IsPayToScriptHash(pkScript)
case TaprootKeySpendBIP0086SignMethod, TaprootKeySpendSignMethod,
TaprootScriptSpendSignMethod:
return txscript.IsPayToTaproot(pkScript)
default:
return false
}
}
// WriteSignDescriptor serializes a SignDescriptor struct into the passed
// io.Writer stream.
//
+13 -3
View File
@@ -7,7 +7,17 @@ import (
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcwallet/waddrmgr"
secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
)
const (
// PubKeyFormatCompressedOdd is the identifier prefix byte for a public
// key whose Y coordinate is odd when serialized in the compressed
// format per section 2.3.4 of
// [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.4).
// This is copied from the github.com/decred/dcrd/dcrec/secp256k1/v4 to
// avoid needing to directly reference (and by accident pull in
// incompatible crypto primitives) the package.
PubKeyFormatCompressedOdd byte = 0x03
)
// NewTxSigHashesV0Only returns a new txscript.TxSigHashes instance that will
@@ -56,7 +66,7 @@ func TapscriptFullTree(internalKey *btcec.PublicKey,
tapKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:])
var outputKeyYIsOdd bool
if tapKey.SerializeCompressed()[0] == secp.PubKeyFormatCompressedOdd {
if tapKey.SerializeCompressed()[0] == PubKeyFormatCompressedOdd {
outputKeyYIsOdd = true
}
@@ -85,7 +95,7 @@ func TapscriptPartialReveal(internalKey *btcec.PublicKey,
rootHash := controlBlock.RootHash(revealedLeaf.Script)
tapKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash)
if tapKey.SerializeCompressed()[0] == secp.PubKeyFormatCompressedOdd {
if tapKey.SerializeCompressed()[0] == PubKeyFormatCompressedOdd {
controlBlock.OutputKeyYIsOdd = true
}
+404 -308
View File
@@ -20,6 +20,70 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type SignMethod int32
const (
//
//Specifies that a SegWit v0 (p2wkh, np2wkh, p2wsh) input script should be
//signed.
SignMethod_SIGN_METHOD_WITNESS_V0 SignMethod = 0
//
//Specifies that a SegWit v1 (p2tr) input should be signed by using the
//BIP0086 method (commit to internal key only).
SignMethod_SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086 SignMethod = 1
//
//Specifies that a SegWit v1 (p2tr) input should be signed by using a given
//taproot hash to commit to in addition to the internal key.
SignMethod_SIGN_METHOD_TAPROOT_KEY_SPEND SignMethod = 2
//
//Specifies that a SegWit v1 (p2tr) input should be spent using the script
//path and that a specific leaf script should be signed for.
SignMethod_SIGN_METHOD_TAPROOT_SCRIPT_SPEND SignMethod = 3
)
// Enum value maps for SignMethod.
var (
SignMethod_name = map[int32]string{
0: "SIGN_METHOD_WITNESS_V0",
1: "SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086",
2: "SIGN_METHOD_TAPROOT_KEY_SPEND",
3: "SIGN_METHOD_TAPROOT_SCRIPT_SPEND",
}
SignMethod_value = map[string]int32{
"SIGN_METHOD_WITNESS_V0": 0,
"SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086": 1,
"SIGN_METHOD_TAPROOT_KEY_SPEND": 2,
"SIGN_METHOD_TAPROOT_SCRIPT_SPEND": 3,
}
)
func (x SignMethod) Enum() *SignMethod {
p := new(SignMethod)
*p = x
return p
}
func (x SignMethod) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (SignMethod) Descriptor() protoreflect.EnumDescriptor {
return file_signrpc_signer_proto_enumTypes[0].Descriptor()
}
func (SignMethod) Type() protoreflect.EnumType {
return &file_signrpc_signer_proto_enumTypes[0]
}
func (x SignMethod) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use SignMethod.Descriptor instead.
func (SignMethod) EnumDescriptor() ([]byte, []int) {
return file_signrpc_signer_proto_rawDescGZIP(), []int{0}
}
type KeyLocator struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -228,11 +292,20 @@ type SignDescriptor struct {
//tweakPriv*sha256(tweakPub || pubKey)) mod N
DoubleTweak []byte `protobuf:"bytes,3,opt,name=double_tweak,json=doubleTweak,proto3" json:"double_tweak,omitempty"`
//
//The 32 byte input to the taproot tweak derivation that is used to derive
//the output key from an internal key: outputKey = internalKey +
//tagged_hash("tapTweak", internalKey || tapTweak).
//
//When doing a BIP 86 spend, this field can be an empty byte slice.
//
//When doing a normal key path spend, with the output key committing to an
//actual script root, then this field should be: the tapscript root hash.
TapTweak []byte `protobuf:"bytes,10,opt,name=tap_tweak,json=tapTweak,proto3" json:"tap_tweak,omitempty"`
//
//The full script required to properly redeem the output. This field will
//only be populated if a p2tr, p2wsh or a p2sh output is being signed. In case
//taproot_key_spend is set to true then this value must correspond to the
//taproot root hash (in case of a tapscript output) or the tap hashed internal
//public key (in case of a BIP-0086 output).
//only be populated if a p2tr, p2wsh or a p2sh output is being signed. If a
//taproot script path spend is being attempted, then this should be the raw
//leaf script.
WitnessScript []byte `protobuf:"bytes,4,opt,name=witness_script,json=witnessScript,proto3" json:"witness_script,omitempty"`
//
//A description of the output being spent. The value and script MUST be
@@ -246,11 +319,11 @@ type SignDescriptor struct {
//The target input within the transaction that should be signed.
InputIndex int32 `protobuf:"varint,8,opt,name=input_index,json=inputIndex,proto3" json:"input_index,omitempty"`
//
//Indicates that this should produce a signature that can be used for the key
//spend path of a taproot input. This requires the witness_script field to be
//set to the taproot root hash (in case of a tapscript output) or the tap
//hashed internal public key (in case of a BIP-0086 output).
TaprootKeySpend bool `protobuf:"varint,9,opt,name=taproot_key_spend,json=taprootKeySpend,proto3" json:"taproot_key_spend,omitempty"`
//The sign method specifies how the input should be signed. Depending on the
//method, either the tap_tweak, witness_script or both need to be specified.
//Defaults to SegWit v0 signing to be backward compatible with older RPC
//clients.
SignMethod SignMethod `protobuf:"varint,9,opt,name=sign_method,json=signMethod,proto3,enum=signrpc.SignMethod" json:"sign_method,omitempty"`
}
func (x *SignDescriptor) Reset() {
@@ -306,6 +379,13 @@ func (x *SignDescriptor) GetDoubleTweak() []byte {
return nil
}
func (x *SignDescriptor) GetTapTweak() []byte {
if x != nil {
return x.TapTweak
}
return nil
}
func (x *SignDescriptor) GetWitnessScript() []byte {
if x != nil {
return x.WitnessScript
@@ -334,11 +414,11 @@ func (x *SignDescriptor) GetInputIndex() int32 {
return 0
}
func (x *SignDescriptor) GetTaprootKeySpend() bool {
func (x *SignDescriptor) GetSignMethod() SignMethod {
if x != nil {
return x.TaprootKeySpend
return x.SignMethod
}
return false
return SignMethod_SIGN_METHOD_WITNESS_V0
}
type SignReq struct {
@@ -1849,7 +1929,7 @@ var file_signrpc_signer_proto_rawDesc = []byte{
0x54, 0x78, 0x4f, 0x75, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70,
0x6b, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08,
0x70, 0x6b, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0xbf, 0x02, 0x0a, 0x0e, 0x53, 0x69, 0x67,
0x70, 0x6b, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0xe6, 0x02, 0x0a, 0x0e, 0x53, 0x69, 0x67,
0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x31, 0x0a, 0x08, 0x6b,
0x65, 0x79, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e,
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x44, 0x65, 0x73, 0x63, 0x72,
@@ -1858,236 +1938,248 @@ var file_signrpc_signer_proto_rawDesc = []byte{
0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x54, 0x77, 0x65, 0x61,
0x6b, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x77, 0x65, 0x61,
0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x54,
0x77, 0x65, 0x61, 0x6b, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x5f,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x77, 0x69,
0x74, 0x6e, 0x65, 0x73, 0x73, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x26, 0x0a, 0x06, 0x6f,
0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x69,
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x78, 0x4f, 0x75, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74,
0x70, 0x75, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x69, 0x67, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x73, 0x69, 0x67, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a,
0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a,
0x0a, 0x11, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x70,
0x65, 0x6e, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x74, 0x61, 0x70, 0x72, 0x6f,
0x6f, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x6e, 0x64, 0x22, 0x96, 0x01, 0x0a, 0x07, 0x53,
0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x20, 0x0a, 0x0c, 0x72, 0x61, 0x77, 0x5f, 0x74, 0x78,
0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x61,
0x77, 0x54, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e,
0x5f, 0x64, 0x65, 0x73, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73,
0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72,
0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x73,
0x12, 0x31, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73,
0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63,
0x2e, 0x54, 0x78, 0x4f, 0x75, 0x74, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x76, 0x4f, 0x75, 0x74, 0x70,
0x75, 0x74, 0x73, 0x22, 0x25, 0x0a, 0x08, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12,
0x19, 0x0a, 0x08, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0c, 0x52, 0x07, 0x72, 0x61, 0x77, 0x53, 0x69, 0x67, 0x73, 0x22, 0x46, 0x0a, 0x0b, 0x49, 0x6e,
0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x69, 0x74,
0x6e, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x77, 0x69, 0x74, 0x6e,
0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x53, 0x63, 0x72, 0x69,
0x70, 0x74, 0x22, 0x4c, 0x0a, 0x0f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70,
0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x39, 0x0a, 0x0d, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x73,
0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73,
0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69,
0x70, 0x74, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73,
0x22, 0x92, 0x01, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x2c, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x5f, 0x6c, 0x6f, 0x63,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63,
0x2e, 0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x06, 0x6b, 0x65, 0x79,
0x4c, 0x6f, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x68, 0x61,
0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65,
0x48, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x5f,
0x73, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61,
0x63, 0x74, 0x53, 0x69, 0x67, 0x22, 0x2f, 0x0a, 0x0f, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e,
0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67,
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x5a, 0x0a, 0x10, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79,
0x77, 0x65, 0x61, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x70, 0x5f, 0x74, 0x77, 0x65, 0x61,
0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x61, 0x70, 0x54, 0x77, 0x65, 0x61,
0x6b, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x63, 0x72,
0x69, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x77, 0x69, 0x74, 0x6e, 0x65,
0x73, 0x73, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x26, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70,
0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72,
0x70, 0x63, 0x2e, 0x54, 0x78, 0x4f, 0x75, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74,
0x12, 0x18, 0x0a, 0x07, 0x73, 0x69, 0x67, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28,
0x0d, 0x52, 0x07, 0x73, 0x69, 0x67, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e,
0x70, 0x75, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x0b, 0x73,
0x69, 0x67, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e,
0x32, 0x13, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d,
0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f,
0x64, 0x22, 0x96, 0x01, 0x0a, 0x07, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x20, 0x0a,
0x0c, 0x72, 0x61, 0x77, 0x5f, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x61, 0x77, 0x54, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12,
0x36, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x73, 0x18, 0x02, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69,
0x67, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x73, 0x69,
0x67, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x73, 0x12, 0x31, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x76, 0x5f,
0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x78, 0x4f, 0x75, 0x74, 0x52, 0x0b, 0x70,
0x72, 0x65, 0x76, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x22, 0x25, 0x0a, 0x08, 0x53, 0x69,
0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x69,
0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x61, 0x77, 0x53, 0x69, 0x67,
0x73, 0x22, 0x46, 0x0a, 0x0b, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74,
0x12, 0x18, 0x0a, 0x07, 0x77, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0c, 0x52, 0x07, 0x77, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x69,
0x67, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
0x73, 0x69, 0x67, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x4c, 0x0a, 0x0f, 0x49, 0x6e, 0x70,
0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x39, 0x0a, 0x0d,
0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e,
0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74,
0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73,
0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1c, 0x0a, 0x09,
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75,
0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b,
0x65, 0x79, 0x22, 0x29, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x22, 0xa2, 0x01,
0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x5f,
0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x70,
0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a,
0x07, 0x6b, 0x65, 0x79, 0x5f, 0x6c, 0x6f, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13,
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x61,
0x74, 0x6f, 0x72, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x12,
0x31, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x16, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x44,
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x44, 0x65,
0x73, 0x63, 0x22, 0x32, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x65,
0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x68, 0x61,
0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x22, 0x3d, 0x0a, 0x09, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44,
0x65, 0x73, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x05, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x12, 0x1a, 0x0a, 0x09, 0x69, 0x73, 0x5f,
0x78, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73,
0x58, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x59, 0x0a, 0x10, 0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74,
0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x63, 0x72,
0x69, 0x70, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6b, 0x65,
0x79, 0x5f, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01,
0x28, 0x08, 0x52, 0x0c, 0x6b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x6e, 0x64, 0x4f, 0x6e, 0x6c, 0x79,
0x22, 0xb4, 0x01, 0x0a, 0x18, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69,
0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a,
0x12, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6b,
0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x61, 0x6c, 0x6c, 0x53, 0x69,
0x67, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x74,
0x77, 0x65, 0x61, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x69,
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x52,
0x06, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x73, 0x12, 0x3e, 0x0a, 0x0d, 0x74, 0x61, 0x70, 0x72, 0x6f,
0x6f, 0x74, 0x5f, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74,
0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x52, 0x0c, 0x74, 0x61, 0x70, 0x72, 0x6f,
0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x22, 0x70, 0x0a, 0x19, 0x4d, 0x75, 0x53, 0x69, 0x67,
0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64,
0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x62,
0x69, 0x6e, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x61, 0x70, 0x72, 0x6f,
0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x22, 0x9b, 0x02, 0x0a, 0x14, 0x4d, 0x75,
0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x2c, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x5f, 0x6c, 0x6f, 0x63, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65,
0x79, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x06, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x63,
0x12, 0x2c, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70,
0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x61, 0x6c,
0x6c, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x3b,
0x0a, 0x1a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70,
0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03,
0x28, 0x0c, 0x52, 0x17, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50,
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x74,
0x77, 0x65, 0x61, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x69,
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x52,
0x06, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x73, 0x12, 0x3e, 0x0a, 0x0d, 0x74, 0x61, 0x70, 0x72, 0x6f,
0x6f, 0x74, 0x5f, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74,
0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x52, 0x0c, 0x74, 0x61, 0x70, 0x72, 0x6f,
0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x22, 0xe3, 0x01, 0x0a, 0x15, 0x4d, 0x75, 0x53, 0x69,
0x67, 0x32, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64,
0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64,
0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x69,
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x12, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e,
0x61, 0x6c, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x13, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70,
0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x11, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4e,
0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x68, 0x61, 0x76, 0x65, 0x5f, 0x61, 0x6c,
0x6c, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d,
0x68, 0x61, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x79, 0x0a,
0x1b, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e,
0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x2c, 0x0a, 0x07,
0x6b, 0x65, 0x79, 0x5f, 0x6c, 0x6f, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e,
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x74,
0x6f, 0x72, 0x52, 0x06, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x6f,
0x75, 0x62, 0x6c, 0x65, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
0x0a, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x63,
0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08,
0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x53, 0x69, 0x67, 0x22, 0x2f, 0x0a, 0x0f,
0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12,
0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x5a, 0x0a,
0x10, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65,
0x71, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03,
0x6d, 0x73, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x22, 0x29, 0x0a, 0x11, 0x56, 0x65, 0x72,
0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x14,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x69, 0x64, 0x22, 0xa2, 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b,
0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x70, 0x68,
0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x75,
0x62, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x5f, 0x6c, 0x6f, 0x63, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06,
0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x12, 0x31, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x65,
0x73, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72,
0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72,
0x52, 0x07, 0x6b, 0x65, 0x79, 0x44, 0x65, 0x73, 0x63, 0x22, 0x32, 0x0a, 0x11, 0x53, 0x68, 0x61,
0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d,
0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x22, 0x3d, 0x0a,
0x09, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x77,
0x65, 0x61, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x77, 0x65, 0x61, 0x6b,
0x12, 0x1a, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x78, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20,
0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x58, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x59, 0x0a, 0x10,
0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63,
0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x6f, 0x6f,
0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x5f, 0x6f,
0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6b, 0x65, 0x79, 0x53, 0x70,
0x65, 0x6e, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0xb4, 0x01, 0x0a, 0x18, 0x4d, 0x75, 0x53, 0x69,
0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e,
0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c,
0x52, 0x10, 0x61, 0x6c, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65,
0x79, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x77, 0x65,
0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x52, 0x06, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x73, 0x12, 0x3e,
0x0a, 0x0d, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63,
0x52, 0x0c, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x22, 0x70,
0x0a, 0x19, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b,
0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63,
0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x30,
0x0a, 0x14, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x74, 0x61,
0x70, 0x72, 0x6f, 0x6f, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4b, 0x65, 0x79,
0x22, 0x9b, 0x02, 0x0a, 0x14, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73, 0x73, 0x69,
0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x07, 0x6b, 0x65, 0x79,
0x5f, 0x6c, 0x6f, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x69, 0x67,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x52,
0x06, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x12, 0x2c, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x5f, 0x73,
0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20,
0x03, 0x28, 0x0c, 0x52, 0x10, 0x61, 0x6c, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x75,
0x62, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x73,
0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x6e,
0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x17, 0x6f, 0x74, 0x68, 0x65, 0x72,
0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x6e, 0x63,
0x65, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x77, 0x65,
0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x52, 0x06, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x73, 0x12, 0x3e,
0x0a, 0x0d, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x18,
0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63,
0x52, 0x0c, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x22, 0xe3,
0x01, 0x0a, 0x15, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73,
0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x65,
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x62, 0x69,
0x6e, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63,
0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x61,
0x70, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6b,
0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f,
0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x13,
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x6e,
0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f,
0x68, 0x61, 0x76, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18,
0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x68, 0x61, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x4e, 0x6f,
0x6e, 0x63, 0x65, 0x73, 0x22, 0x79, 0x0a, 0x1b, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x52, 0x65,
0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
0x49, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e,
0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73,
0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x17, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x53, 0x69, 0x67,
0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22,
0x46, 0x0a, 0x1c, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65,
0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x26, 0x0a, 0x0f, 0x68, 0x61, 0x76, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x6e, 0x6f, 0x6e, 0x63,
0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x68, 0x61, 0x76, 0x65, 0x41, 0x6c,
0x6c, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x73, 0x0a, 0x11, 0x4d, 0x75, 0x53, 0x69, 0x67,
0x32, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x6f,
0x74, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6c,
0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52,
0x17, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c,
0x69, 0x63, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x46, 0x0a, 0x1c, 0x4d, 0x75, 0x53, 0x69,
0x67, 0x32, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x68, 0x61, 0x76, 0x65,
0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
0x08, 0x52, 0x0d, 0x68, 0x61, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73,
0x22, 0x73, 0x0a, 0x11, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65,
0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x69, 0x67, 0x65,
0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x18, 0x03, 0x20,
0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x22, 0x4c, 0x0a, 0x12,
0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x72, 0x74,
0x69, 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x15, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61,
0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x72, 0x0a, 0x17, 0x4d, 0x75,
0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53, 0x69, 0x67, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69,
0x6f, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f,
0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x6d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63,
0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x6c,
0x65, 0x61, 0x6e, 0x75, 0x70, 0x22, 0x4c, 0x0a, 0x12, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53,
0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x6c,
0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x67,
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x6c, 0x6f,
0x63, 0x61, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
0x75, 0x72, 0x65, 0x22, 0x72, 0x0a, 0x17, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d,
0x62, 0x69, 0x6e, 0x65, 0x53, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a,
0x18, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73,
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52,
0x16, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x69, 0x67,
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x73, 0x0a, 0x18, 0x4d, 0x75, 0x53, 0x69, 0x67,
0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x68, 0x61, 0x76, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x5f,
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
0x52, 0x11, 0x68, 0x61, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
0x72, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x67,
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x66, 0x69,
0x6e, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x35, 0x0a, 0x14,
0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
0x6e, 0x49, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65,
0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xdb, 0x06, 0x0a,
0x06, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x0d, 0x53, 0x69, 0x67, 0x6e, 0x4f,
0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x61, 0x77, 0x12, 0x10, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72,
0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x69, 0x67,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x40, 0x0a,
0x12, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72,
0x69, 0x70, 0x74, 0x12, 0x10, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69,
0x67, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12,
0x40, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x17,
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70,
0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73,
0x70, 0x12, 0x46, 0x0a, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72,
0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e,
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x48, 0x0a, 0x0f, 0x44, 0x65, 0x72,
0x69, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x2e, 0x73,
0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70,
0x63, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x11, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d,
0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x21, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72,
0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65,
0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, 0x69,
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62,
0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x54, 0x0a, 0x13, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53,
0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63,
0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x14, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x52,
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x24, 0x2e,
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x52, 0x65,
0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75,
0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x18, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x61,
0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73,
0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x16, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50, 0x61, 0x72,
0x74, 0x69, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x73,
0x0a, 0x18, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53,
0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x68, 0x61,
0x76, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x68, 0x61, 0x76, 0x65, 0x41, 0x6c, 0x6c,
0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69,
0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x0e, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
0x75, 0x72, 0x65, 0x22, 0x35, 0x0a, 0x14, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65,
0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73,
0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x4d, 0x75,
0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x2a, 0x9c, 0x01, 0x0a, 0x0a, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x74, 0x68,
0x6f, 0x64, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f,
0x44, 0x5f, 0x57, 0x49, 0x54, 0x4e, 0x45, 0x53, 0x53, 0x5f, 0x56, 0x30, 0x10, 0x00, 0x12, 0x29,
0x0a, 0x25, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x54, 0x41,
0x50, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x53, 0x50, 0x45, 0x4e, 0x44, 0x5f,
0x42, 0x49, 0x50, 0x30, 0x30, 0x38, 0x36, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x49, 0x47,
0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x54, 0x41, 0x50, 0x52, 0x4f, 0x4f, 0x54,
0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x53, 0x50, 0x45, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x24, 0x0a, 0x20,
0x53, 0x49, 0x47, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x54, 0x41, 0x50, 0x52,
0x4f, 0x4f, 0x54, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x53, 0x50, 0x45, 0x4e, 0x44,
0x10, 0x03, 0x32, 0xdb, 0x06, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x34, 0x0a,
0x0d, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x61, 0x77, 0x12, 0x10,
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71,
0x1a, 0x11, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52,
0x65, 0x73, 0x70, 0x12, 0x40, 0x0a, 0x12, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e,
0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x10, 0x2e, 0x73, 0x69, 0x67, 0x6e,
0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x69,
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70,
0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x40, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x12, 0x17, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53,
0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e,
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x46, 0x0a, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66,
0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72,
0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65,
0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12,
0x48, 0x0a, 0x0f, 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b,
0x65, 0x79, 0x12, 0x19, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x68, 0x61,
0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65,
0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x11, 0x4d, 0x75, 0x53,
0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x21,
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43,
0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x22, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69,
0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x13, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x73,
0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73,
0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x69,
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73, 0x73,
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x14, 0x4d,
0x75, 0x53, 0x69, 0x67, 0x32, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e,
0x63, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75,
0x53, 0x69, 0x67, 0x32, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63,
0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x4d, 0x75,
0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x1a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72,
0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d,
0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x57, 0x0a, 0x10, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69,
0x6e, 0x65, 0x53, 0x69, 0x67, 0x12, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53, 0x69, 0x67,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70,
0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53,
0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x4d, 0x75,
0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x12, 0x1d, 0x2e, 0x73, 0x69,
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65, 0x61,
0x6e, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x69, 0x67,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e,
0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69,
0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e,
0x72, 0x70, 0x63, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x73, 0x69, 0x67, 0x6e,
0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x45, 0x0a, 0x0a, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x1a,
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53,
0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x69, 0x67,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x4d, 0x75, 0x53, 0x69, 0x67,
0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53, 0x69, 0x67, 0x12, 0x20, 0x2e, 0x73, 0x69,
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62,
0x69, 0x6e, 0x65, 0x53, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e,
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f,
0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x4e, 0x0a, 0x0d, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75,
0x70, 0x12, 0x1d, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69,
0x67, 0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67,
0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c,
0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f,
0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70,
0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -2102,79 +2194,82 @@ func file_signrpc_signer_proto_rawDescGZIP() []byte {
return file_signrpc_signer_proto_rawDescData
}
var file_signrpc_signer_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_signrpc_signer_proto_msgTypes = make([]protoimpl.MessageInfo, 28)
var file_signrpc_signer_proto_goTypes = []interface{}{
(*KeyLocator)(nil), // 0: signrpc.KeyLocator
(*KeyDescriptor)(nil), // 1: signrpc.KeyDescriptor
(*TxOut)(nil), // 2: signrpc.TxOut
(*SignDescriptor)(nil), // 3: signrpc.SignDescriptor
(*SignReq)(nil), // 4: signrpc.SignReq
(*SignResp)(nil), // 5: signrpc.SignResp
(*InputScript)(nil), // 6: signrpc.InputScript
(*InputScriptResp)(nil), // 7: signrpc.InputScriptResp
(*SignMessageReq)(nil), // 8: signrpc.SignMessageReq
(*SignMessageResp)(nil), // 9: signrpc.SignMessageResp
(*VerifyMessageReq)(nil), // 10: signrpc.VerifyMessageReq
(*VerifyMessageResp)(nil), // 11: signrpc.VerifyMessageResp
(*SharedKeyRequest)(nil), // 12: signrpc.SharedKeyRequest
(*SharedKeyResponse)(nil), // 13: signrpc.SharedKeyResponse
(*TweakDesc)(nil), // 14: signrpc.TweakDesc
(*TaprootTweakDesc)(nil), // 15: signrpc.TaprootTweakDesc
(*MuSig2CombineKeysRequest)(nil), // 16: signrpc.MuSig2CombineKeysRequest
(*MuSig2CombineKeysResponse)(nil), // 17: signrpc.MuSig2CombineKeysResponse
(*MuSig2SessionRequest)(nil), // 18: signrpc.MuSig2SessionRequest
(*MuSig2SessionResponse)(nil), // 19: signrpc.MuSig2SessionResponse
(*MuSig2RegisterNoncesRequest)(nil), // 20: signrpc.MuSig2RegisterNoncesRequest
(*MuSig2RegisterNoncesResponse)(nil), // 21: signrpc.MuSig2RegisterNoncesResponse
(*MuSig2SignRequest)(nil), // 22: signrpc.MuSig2SignRequest
(*MuSig2SignResponse)(nil), // 23: signrpc.MuSig2SignResponse
(*MuSig2CombineSigRequest)(nil), // 24: signrpc.MuSig2CombineSigRequest
(*MuSig2CombineSigResponse)(nil), // 25: signrpc.MuSig2CombineSigResponse
(*MuSig2CleanupRequest)(nil), // 26: signrpc.MuSig2CleanupRequest
(*MuSig2CleanupResponse)(nil), // 27: signrpc.MuSig2CleanupResponse
(SignMethod)(0), // 0: signrpc.SignMethod
(*KeyLocator)(nil), // 1: signrpc.KeyLocator
(*KeyDescriptor)(nil), // 2: signrpc.KeyDescriptor
(*TxOut)(nil), // 3: signrpc.TxOut
(*SignDescriptor)(nil), // 4: signrpc.SignDescriptor
(*SignReq)(nil), // 5: signrpc.SignReq
(*SignResp)(nil), // 6: signrpc.SignResp
(*InputScript)(nil), // 7: signrpc.InputScript
(*InputScriptResp)(nil), // 8: signrpc.InputScriptResp
(*SignMessageReq)(nil), // 9: signrpc.SignMessageReq
(*SignMessageResp)(nil), // 10: signrpc.SignMessageResp
(*VerifyMessageReq)(nil), // 11: signrpc.VerifyMessageReq
(*VerifyMessageResp)(nil), // 12: signrpc.VerifyMessageResp
(*SharedKeyRequest)(nil), // 13: signrpc.SharedKeyRequest
(*SharedKeyResponse)(nil), // 14: signrpc.SharedKeyResponse
(*TweakDesc)(nil), // 15: signrpc.TweakDesc
(*TaprootTweakDesc)(nil), // 16: signrpc.TaprootTweakDesc
(*MuSig2CombineKeysRequest)(nil), // 17: signrpc.MuSig2CombineKeysRequest
(*MuSig2CombineKeysResponse)(nil), // 18: signrpc.MuSig2CombineKeysResponse
(*MuSig2SessionRequest)(nil), // 19: signrpc.MuSig2SessionRequest
(*MuSig2SessionResponse)(nil), // 20: signrpc.MuSig2SessionResponse
(*MuSig2RegisterNoncesRequest)(nil), // 21: signrpc.MuSig2RegisterNoncesRequest
(*MuSig2RegisterNoncesResponse)(nil), // 22: signrpc.MuSig2RegisterNoncesResponse
(*MuSig2SignRequest)(nil), // 23: signrpc.MuSig2SignRequest
(*MuSig2SignResponse)(nil), // 24: signrpc.MuSig2SignResponse
(*MuSig2CombineSigRequest)(nil), // 25: signrpc.MuSig2CombineSigRequest
(*MuSig2CombineSigResponse)(nil), // 26: signrpc.MuSig2CombineSigResponse
(*MuSig2CleanupRequest)(nil), // 27: signrpc.MuSig2CleanupRequest
(*MuSig2CleanupResponse)(nil), // 28: signrpc.MuSig2CleanupResponse
}
var file_signrpc_signer_proto_depIdxs = []int32{
0, // 0: signrpc.KeyDescriptor.key_loc:type_name -> signrpc.KeyLocator
1, // 1: signrpc.SignDescriptor.key_desc:type_name -> signrpc.KeyDescriptor
2, // 2: signrpc.SignDescriptor.output:type_name -> signrpc.TxOut
3, // 3: signrpc.SignReq.sign_descs:type_name -> signrpc.SignDescriptor
2, // 4: signrpc.SignReq.prev_outputs:type_name -> signrpc.TxOut
6, // 5: signrpc.InputScriptResp.input_scripts:type_name -> signrpc.InputScript
0, // 6: signrpc.SignMessageReq.key_loc:type_name -> signrpc.KeyLocator
0, // 7: signrpc.SharedKeyRequest.key_loc:type_name -> signrpc.KeyLocator
1, // 8: signrpc.SharedKeyRequest.key_desc:type_name -> signrpc.KeyDescriptor
14, // 9: signrpc.MuSig2CombineKeysRequest.tweaks:type_name -> signrpc.TweakDesc
15, // 10: signrpc.MuSig2CombineKeysRequest.taproot_tweak:type_name -> signrpc.TaprootTweakDesc
0, // 11: signrpc.MuSig2SessionRequest.key_loc:type_name -> signrpc.KeyLocator
14, // 12: signrpc.MuSig2SessionRequest.tweaks:type_name -> signrpc.TweakDesc
15, // 13: signrpc.MuSig2SessionRequest.taproot_tweak:type_name -> signrpc.TaprootTweakDesc
4, // 14: signrpc.Signer.SignOutputRaw:input_type -> signrpc.SignReq
4, // 15: signrpc.Signer.ComputeInputScript:input_type -> signrpc.SignReq
8, // 16: signrpc.Signer.SignMessage:input_type -> signrpc.SignMessageReq
10, // 17: signrpc.Signer.VerifyMessage:input_type -> signrpc.VerifyMessageReq
12, // 18: signrpc.Signer.DeriveSharedKey:input_type -> signrpc.SharedKeyRequest
16, // 19: signrpc.Signer.MuSig2CombineKeys:input_type -> signrpc.MuSig2CombineKeysRequest
18, // 20: signrpc.Signer.MuSig2CreateSession:input_type -> signrpc.MuSig2SessionRequest
20, // 21: signrpc.Signer.MuSig2RegisterNonces:input_type -> signrpc.MuSig2RegisterNoncesRequest
22, // 22: signrpc.Signer.MuSig2Sign:input_type -> signrpc.MuSig2SignRequest
24, // 23: signrpc.Signer.MuSig2CombineSig:input_type -> signrpc.MuSig2CombineSigRequest
26, // 24: signrpc.Signer.MuSig2Cleanup:input_type -> signrpc.MuSig2CleanupRequest
5, // 25: signrpc.Signer.SignOutputRaw:output_type -> signrpc.SignResp
7, // 26: signrpc.Signer.ComputeInputScript:output_type -> signrpc.InputScriptResp
9, // 27: signrpc.Signer.SignMessage:output_type -> signrpc.SignMessageResp
11, // 28: signrpc.Signer.VerifyMessage:output_type -> signrpc.VerifyMessageResp
13, // 29: signrpc.Signer.DeriveSharedKey:output_type -> signrpc.SharedKeyResponse
17, // 30: signrpc.Signer.MuSig2CombineKeys:output_type -> signrpc.MuSig2CombineKeysResponse
19, // 31: signrpc.Signer.MuSig2CreateSession:output_type -> signrpc.MuSig2SessionResponse
21, // 32: signrpc.Signer.MuSig2RegisterNonces:output_type -> signrpc.MuSig2RegisterNoncesResponse
23, // 33: signrpc.Signer.MuSig2Sign:output_type -> signrpc.MuSig2SignResponse
25, // 34: signrpc.Signer.MuSig2CombineSig:output_type -> signrpc.MuSig2CombineSigResponse
27, // 35: signrpc.Signer.MuSig2Cleanup:output_type -> signrpc.MuSig2CleanupResponse
25, // [25:36] is the sub-list for method output_type
14, // [14:25] is the sub-list for method input_type
14, // [14:14] is the sub-list for extension type_name
14, // [14:14] is the sub-list for extension extendee
0, // [0:14] is the sub-list for field type_name
1, // 0: signrpc.KeyDescriptor.key_loc:type_name -> signrpc.KeyLocator
2, // 1: signrpc.SignDescriptor.key_desc:type_name -> signrpc.KeyDescriptor
3, // 2: signrpc.SignDescriptor.output:type_name -> signrpc.TxOut
0, // 3: signrpc.SignDescriptor.sign_method:type_name -> signrpc.SignMethod
4, // 4: signrpc.SignReq.sign_descs:type_name -> signrpc.SignDescriptor
3, // 5: signrpc.SignReq.prev_outputs:type_name -> signrpc.TxOut
7, // 6: signrpc.InputScriptResp.input_scripts:type_name -> signrpc.InputScript
1, // 7: signrpc.SignMessageReq.key_loc:type_name -> signrpc.KeyLocator
1, // 8: signrpc.SharedKeyRequest.key_loc:type_name -> signrpc.KeyLocator
2, // 9: signrpc.SharedKeyRequest.key_desc:type_name -> signrpc.KeyDescriptor
15, // 10: signrpc.MuSig2CombineKeysRequest.tweaks:type_name -> signrpc.TweakDesc
16, // 11: signrpc.MuSig2CombineKeysRequest.taproot_tweak:type_name -> signrpc.TaprootTweakDesc
1, // 12: signrpc.MuSig2SessionRequest.key_loc:type_name -> signrpc.KeyLocator
15, // 13: signrpc.MuSig2SessionRequest.tweaks:type_name -> signrpc.TweakDesc
16, // 14: signrpc.MuSig2SessionRequest.taproot_tweak:type_name -> signrpc.TaprootTweakDesc
5, // 15: signrpc.Signer.SignOutputRaw:input_type -> signrpc.SignReq
5, // 16: signrpc.Signer.ComputeInputScript:input_type -> signrpc.SignReq
9, // 17: signrpc.Signer.SignMessage:input_type -> signrpc.SignMessageReq
11, // 18: signrpc.Signer.VerifyMessage:input_type -> signrpc.VerifyMessageReq
13, // 19: signrpc.Signer.DeriveSharedKey:input_type -> signrpc.SharedKeyRequest
17, // 20: signrpc.Signer.MuSig2CombineKeys:input_type -> signrpc.MuSig2CombineKeysRequest
19, // 21: signrpc.Signer.MuSig2CreateSession:input_type -> signrpc.MuSig2SessionRequest
21, // 22: signrpc.Signer.MuSig2RegisterNonces:input_type -> signrpc.MuSig2RegisterNoncesRequest
23, // 23: signrpc.Signer.MuSig2Sign:input_type -> signrpc.MuSig2SignRequest
25, // 24: signrpc.Signer.MuSig2CombineSig:input_type -> signrpc.MuSig2CombineSigRequest
27, // 25: signrpc.Signer.MuSig2Cleanup:input_type -> signrpc.MuSig2CleanupRequest
6, // 26: signrpc.Signer.SignOutputRaw:output_type -> signrpc.SignResp
8, // 27: signrpc.Signer.ComputeInputScript:output_type -> signrpc.InputScriptResp
10, // 28: signrpc.Signer.SignMessage:output_type -> signrpc.SignMessageResp
12, // 29: signrpc.Signer.VerifyMessage:output_type -> signrpc.VerifyMessageResp
14, // 30: signrpc.Signer.DeriveSharedKey:output_type -> signrpc.SharedKeyResponse
18, // 31: signrpc.Signer.MuSig2CombineKeys:output_type -> signrpc.MuSig2CombineKeysResponse
20, // 32: signrpc.Signer.MuSig2CreateSession:output_type -> signrpc.MuSig2SessionResponse
22, // 33: signrpc.Signer.MuSig2RegisterNonces:output_type -> signrpc.MuSig2RegisterNoncesResponse
24, // 34: signrpc.Signer.MuSig2Sign:output_type -> signrpc.MuSig2SignResponse
26, // 35: signrpc.Signer.MuSig2CombineSig:output_type -> signrpc.MuSig2CombineSigResponse
28, // 36: signrpc.Signer.MuSig2Cleanup:output_type -> signrpc.MuSig2CleanupResponse
26, // [26:37] is the sub-list for method output_type
15, // [15:26] is the sub-list for method input_type
15, // [15:15] is the sub-list for extension type_name
15, // [15:15] is the sub-list for extension extendee
0, // [0:15] is the sub-list for field type_name
}
func init() { file_signrpc_signer_proto_init() }
@@ -2525,13 +2620,14 @@ func file_signrpc_signer_proto_init() {
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_signrpc_signer_proto_rawDesc,
NumEnums: 0,
NumEnums: 1,
NumMessages: 28,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_signrpc_signer_proto_goTypes,
DependencyIndexes: file_signrpc_signer_proto_depIdxs,
EnumInfos: file_signrpc_signer_proto_enumTypes,
MessageInfos: file_signrpc_signer_proto_msgTypes,
}.Build()
File_signrpc_signer_proto = out.File
+46 -9
View File
@@ -175,6 +175,32 @@ message TxOut {
bytes pk_script = 2;
}
enum SignMethod {
/*
Specifies that a SegWit v0 (p2wkh, np2wkh, p2wsh) input script should be
signed.
*/
SIGN_METHOD_WITNESS_V0 = 0;
/*
Specifies that a SegWit v1 (p2tr) input should be signed by using the
BIP0086 method (commit to internal key only).
*/
SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086 = 1;
/*
Specifies that a SegWit v1 (p2tr) input should be signed by using a given
taproot hash to commit to in addition to the internal key.
*/
SIGN_METHOD_TAPROOT_KEY_SPEND = 2;
/*
Specifies that a SegWit v1 (p2tr) input should be spent using the script
path and that a specific leaf script should be signed for.
*/
SIGN_METHOD_TAPROOT_SCRIPT_SPEND = 3;
}
message SignDescriptor {
/*
A descriptor that precisely describes *which* key to use for signing. This
@@ -209,12 +235,23 @@ message SignDescriptor {
*/
bytes double_tweak = 3;
/*
The 32 byte input to the taproot tweak derivation that is used to derive
the output key from an internal key: outputKey = internalKey +
tagged_hash("tapTweak", internalKey || tapTweak).
When doing a BIP 86 spend, this field can be an empty byte slice.
When doing a normal key path spend, with the output key committing to an
actual script root, then this field should be: the tapscript root hash.
*/
bytes tap_tweak = 10;
/*
The full script required to properly redeem the output. This field will
only be populated if a p2tr, p2wsh or a p2sh output is being signed. In case
taproot_key_spend is set to true then this value must correspond to the
taproot root hash (in case of a tapscript output) or the tap hashed internal
public key (in case of a BIP-0086 output).
only be populated if a p2tr, p2wsh or a p2sh output is being signed. If a
taproot script path spend is being attempted, then this should be the raw
leaf script.
*/
bytes witness_script = 4;
@@ -236,12 +273,12 @@ message SignDescriptor {
int32 input_index = 8;
/*
Indicates that this should produce a signature that can be used for the key
spend path of a taproot input. This requires the witness_script field to be
set to the taproot root hash (in case of a tapscript output) or the tap
hashed internal public key (in case of a BIP-0086 output).
The sign method specifies how the input should be signed. Depending on the
method, either the tap_tweak, witness_script or both need to be specified.
Defaults to SegWit v0 signing to be backward compatible with older RPC
clients.
*/
bool taproot_key_spend = 9;
SignMethod sign_method = 9;
}
message SignReq {
+20 -4
View File
@@ -731,10 +731,15 @@
"format": "byte",
"description": "A private key that will be used in combination with its corresponding\nprivate key to derive the private key that is to be used to sign the target\ninput. Within the Lightning protocol, this value is typically the\ncommitment secret from a previously revoked commitment transaction. This\nvalue is in combination with two hash values, and the original private key\nto derive the private key to be used when signing.\n\nk = (privKey*sha256(pubKey || tweakPub) +\ntweakPriv*sha256(tweakPub || pubKey)) mod N"
},
"tap_tweak": {
"type": "string",
"format": "byte",
"description": "The 32 byte input to the taproot tweak derivation that is used to derive\nthe output key from an internal key: outputKey = internalKey +\ntagged_hash(\"tapTweak\", internalKey || tapTweak).\n\nWhen doing a BIP 86 spend, this field can be an empty byte slice.\n\nWhen doing a normal key path spend, with the output key committing to an\nactual script root, then this field should be: the tapscript root hash."
},
"witness_script": {
"type": "string",
"format": "byte",
"description": "The full script required to properly redeem the output. This field will\nonly be populated if a p2tr, p2wsh or a p2sh output is being signed. In case\ntaproot_key_spend is set to true then this value must correspond to the\ntaproot root hash (in case of a tapscript output) or the tap hashed internal\npublic key (in case of a BIP-0086 output)."
"description": "The full script required to properly redeem the output. This field will\nonly be populated if a p2tr, p2wsh or a p2sh output is being signed. If a\ntaproot script path spend is being attempted, then this should be the raw\nleaf script."
},
"output": {
"$ref": "#/definitions/signrpcTxOut",
@@ -750,9 +755,9 @@
"format": "int32",
"description": "The target input within the transaction that should be signed."
},
"taproot_key_spend": {
"type": "boolean",
"description": "Indicates that this should produce a signature that can be used for the key\nspend path of a taproot input. This requires the witness_script field to be\nset to the taproot root hash (in case of a tapscript output) or the tap\nhashed internal public key (in case of a BIP-0086 output)."
"sign_method": {
"$ref": "#/definitions/signrpcSignMethod",
"description": "The sign method specifies how the input should be signed. Depending on the\nmethod, either the tap_tweak, witness_script or both need to be specified.\nDefaults to SegWit v0 signing to be backward compatible with older RPC\nclients."
}
}
},
@@ -788,6 +793,17 @@
}
}
},
"signrpcSignMethod": {
"type": "string",
"enum": [
"SIGN_METHOD_WITNESS_V0",
"SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086",
"SIGN_METHOD_TAPROOT_KEY_SPEND",
"SIGN_METHOD_TAPROOT_SCRIPT_SPEND"
],
"default": "SIGN_METHOD_WITNESS_V0",
"description": " - SIGN_METHOD_WITNESS_V0: Specifies that a SegWit v0 (p2wkh, np2wkh, p2wsh) input script should be\nsigned.\n - SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086: Specifies that a SegWit v1 (p2tr) input should be signed by using the\nBIP0086 method (commit to internal key only).\n - SIGN_METHOD_TAPROOT_KEY_SPEND: Specifies that a SegWit v1 (p2tr) input should be signed by using a given\ntaproot hash to commit to in addition to the internal key.\n - SIGN_METHOD_TAPROOT_SCRIPT_SPEND: Specifies that a SegWit v1 (p2tr) input should be spent using the script\npath and that a specific leaf script should be signed for."
},
"signrpcSignReq": {
"type": "object",
"properties": {
+76 -14
View File
@@ -361,16 +361,56 @@ func (s *Server) SignOutputRaw(_ context.Context, in *SignReq) (*SignResp,
}
}
// If a witness script isn't passed, then we can't proceed, as
// in the p2wsh case, we can't properly generate the sighash.
// A P2WKH doesn't need a witness script. But SignOutputRaw
// still needs to know the PK script that was used for the
// output. We'll send it in the WitnessScript field, the
// SignOutputRaw RPC will know what to do with it when creating
// the sighash.
if len(signDesc.WitnessScript) == 0 && !signDesc.TaprootKeySpend {
return nil, fmt.Errorf("witness script MUST be " +
"specified for non-taproot-key-spends")
// Check what sign method was selected by the user so, we know
// exactly what we're expecting and can prevent some of the more
// obvious usage errors.
signMethod, err := UnmarshalSignMethod(signDesc.SignMethod)
if err != nil {
return nil, fmt.Errorf("unable to unmarshal sign "+
"method: %v", err)
}
if !signMethod.PkScriptCompatible(signDesc.Output.PkScript) {
return nil, fmt.Errorf("selected sign method %v is "+
"not compatible with given pk script %x",
signMethod, signDesc.Output.PkScript)
}
// Perform input validation according to the sign method. Not
// all methods require the same fields to be provided.
switch signMethod {
case input.WitnessV0SignMethod:
// If a witness script isn't passed, then we can't
// proceed, as in the p2wsh case, we can't properly
// generate the sighash. A P2WKH doesn't need a witness
// script. But SignOutputRaw still needs to know the PK
// script that was used for the output. We'll send it in
// the WitnessScript field, the SignOutputRaw RPC will
// know what to do with it when creating the sighash.
if len(signDesc.WitnessScript) == 0 {
return nil, fmt.Errorf("witness script MUST " +
"be specified for segwit v0 sign " +
"method")
}
case input.TaprootKeySpendBIP0086SignMethod:
if len(signDesc.TapTweak) > 0 {
return nil, fmt.Errorf("tap tweak must be " +
"empty for BIP0086 key spend")
}
case input.TaprootKeySpendSignMethod:
if len(signDesc.TapTweak) != sha256.Size {
return nil, fmt.Errorf("tap tweak must be " +
"specified for key spend with root " +
"hash")
}
case input.TaprootScriptSpendSignMethod:
if len(signDesc.WitnessScript) == 0 {
return nil, fmt.Errorf("witness script MUST " +
"be specified for taproot script " +
"spend method")
}
}
// If the users provided a double tweak, then we'll need to
@@ -390,10 +430,11 @@ func (s *Server) SignOutputRaw(_ context.Context, in *SignReq) (*SignResp,
KeyLocator: keyLoc,
PubKey: targetPubKey,
},
SingleTweak: signDesc.SingleTweak,
DoubleTweak: tweakPrivKey,
WitnessScript: signDesc.WitnessScript,
TaprootKeySpend: signDesc.TaprootKeySpend,
SingleTweak: signDesc.SingleTweak,
DoubleTweak: tweakPrivKey,
TapTweak: signDesc.TapTweak,
WitnessScript: signDesc.WitnessScript,
SignMethod: signMethod,
Output: &wire.TxOut{
Value: signDesc.Output.Value,
PkScript: signDesc.Output.PkScript,
@@ -1097,3 +1138,24 @@ func UnmarshalTweaks(rpcTweaks []*TweakDesc,
return tweaks, nil
}
// UnmarshalSignMethod parses the RPC sign method into the native counterpart.
func UnmarshalSignMethod(rpcSignMethod SignMethod) (input.SignMethod, error) {
switch rpcSignMethod {
case SignMethod_SIGN_METHOD_WITNESS_V0:
return input.WitnessV0SignMethod, nil
case SignMethod_SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086:
return input.TaprootKeySpendBIP0086SignMethod, nil
case SignMethod_SIGN_METHOD_TAPROOT_KEY_SPEND:
return input.TaprootKeySpendSignMethod, nil
case SignMethod_SIGN_METHOD_TAPROOT_SCRIPT_SPEND:
return input.TaprootScriptSpendSignMethod, nil
default:
return 0, fmt.Errorf("unknown RPC sign method <%d>",
rpcSignMethod)
}
}
+259 -20
View File
@@ -6,13 +6,17 @@ import (
"crypto/rand"
"fmt"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcd/btcutil/psbt"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/signrpc"
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
@@ -632,19 +636,22 @@ func testPsbtChanFundingSingleStep(net *lntest.NetworkHarness, t *harnessTest) {
closeChannelAndAssert(t, net, carol, chanPoint, false)
}
// runSignPsbt tests that the SignPsbt RPC works correctly.
// testSignPsbt tests that the SignPsbt RPC works correctly.
func testSignPsbt(net *lntest.NetworkHarness, t *harnessTest) {
runSignPsbt(t, net, net.Alice)
runSignPsbtSegWitV0P2WKH(t, net, net.Alice)
runSignPsbtSegWitV1KeySpendBip86(t, net, net.Alice)
runSignPsbtSegWitV1KeySpendRootHash(t, net, net.Alice)
runSignPsbtSegWitV1ScriptSpend(t, net, net.Alice)
}
// runSignPsbt tests that the SignPsbt RPC works correctly.
func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
// runSignPsbtSegWitV0P2WKH tests that the SignPsbt RPC works correctly for a
// SegWit v0 p2wkh input.
func runSignPsbtSegWitV0P2WKH(t *harnessTest, net *lntest.NetworkHarness,
alice *lntest.HarnessNode) {
ctxb := context.Background()
// Everything we do here should be done within a second or two, so we
// can just keep a single timeout context around for all calls.
ctxb := context.Background()
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
@@ -699,13 +706,224 @@ func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
pkScript, err := txscript.PayToAddrScript(witnessAddr)
require.NoError(t.t, err)
// Send some funds to the output and then try to get a signature through
// the SignPsbt RPC to spend that output again.
assertPsbtSpend(
ctxt, t, net, alice, pkScript,
func(packet *psbt.Packet) {
in := &packet.Inputs[0]
in.Bip32Derivation = []*psbt.Bip32Derivation{{
PubKey: addrPubKey.SerializeCompressed(),
Bip32Path: fullDerivationPath,
}}
in.SighashType = txscript.SigHashAll
},
func(packet *psbt.Packet) {
require.Len(t.t, packet.Inputs, 1)
require.Len(t.t, packet.Inputs[0].PartialSigs, 1)
partialSig := packet.Inputs[0].PartialSigs[0]
require.Equal(
t.t, partialSig.PubKey,
addrPubKey.SerializeCompressed(),
)
require.Greater(
t.t, len(partialSig.Signature), ecdsa.MinSigLen,
)
},
)
}
// runSignPsbtSegWitV1KeySpendBip86 tests that the SignPsbt RPC works correctly
// for a SegWit v1 p2tr key spend BIP-0086 input.
func runSignPsbtSegWitV1KeySpendBip86(t *harnessTest, net *lntest.NetworkHarness,
alice *lntest.HarnessNode) {
// Everything we do here should be done within a second or two, so we
// can just keep a single timeout context around for all calls.
ctxb := context.Background()
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
// Derive a key we can use for signing.
keyDesc, internalKey, fullDerivationPath := deriveInternalKey(
ctxt, t, alice,
)
// Our taproot key is a BIP0086 key spend only construction that just
// commits to the internal key and no root hash.
taprootKey := txscript.ComputeTaprootKeyNoScript(internalKey)
tapScriptAddr, err := btcutil.NewAddressTaproot(
schnorr.SerializePubKey(taprootKey), harnessNetParams,
)
require.NoError(t.t, err)
p2trPkScript, err := txscript.PayToAddrScript(tapScriptAddr)
require.NoError(t.t, err)
// Send some funds to the output and then try to get a signature through
// the SignPsbt RPC to spend that output again.
assertPsbtSpend(
ctxt, t, net, alice, p2trPkScript,
func(packet *psbt.Packet) {
in := &packet.Inputs[0]
in.Bip32Derivation = []*psbt.Bip32Derivation{{
PubKey: keyDesc.RawKeyBytes,
Bip32Path: fullDerivationPath,
}}
in.TaprootBip32Derivation = []*psbt.TaprootBip32Derivation{{
XOnlyPubKey: keyDesc.RawKeyBytes[1:],
Bip32Path: fullDerivationPath,
}}
in.SighashType = txscript.SigHashDefault
},
func(packet *psbt.Packet) {
require.Len(t.t, packet.Inputs, 1)
require.Len(
t.t, packet.Inputs[0].TaprootKeySpendSig, 64,
)
},
)
}
// runSignPsbtSegWitV1KeySpendRootHash tests that the SignPsbt RPC works
// correctly for a SegWit v1 p2tr key spend that also commits to a script tree
// root hash.
func runSignPsbtSegWitV1KeySpendRootHash(t *harnessTest,
net *lntest.NetworkHarness, alice *lntest.HarnessNode) {
// Everything we do here should be done within a second or two, so we
// can just keep a single timeout context around for all calls.
ctxb := context.Background()
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
// Derive a key we can use for signing.
keyDesc, internalKey, fullDerivationPath := deriveInternalKey(
ctxt, t, alice,
)
// Let's create a taproot script output now. This is a hash lock with a
// simple preimage of "foobar".
leaf1 := testScriptHashLock(t.t, []byte("foobar"))
rootHash := leaf1.TapHash()
taprootKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:])
tapScriptAddr, err := btcutil.NewAddressTaproot(
schnorr.SerializePubKey(taprootKey), harnessNetParams,
)
require.NoError(t.t, err)
p2trPkScript, err := txscript.PayToAddrScript(tapScriptAddr)
require.NoError(t.t, err)
// Send some funds to the output and then try to get a signature through
// the SignPsbt RPC to spend that output again.
assertPsbtSpend(
ctxt, t, net, alice, p2trPkScript,
func(packet *psbt.Packet) {
in := &packet.Inputs[0]
in.Bip32Derivation = []*psbt.Bip32Derivation{{
PubKey: keyDesc.RawKeyBytes,
Bip32Path: fullDerivationPath,
}}
in.TaprootBip32Derivation = []*psbt.TaprootBip32Derivation{{
XOnlyPubKey: keyDesc.RawKeyBytes[1:],
Bip32Path: fullDerivationPath,
}}
in.TaprootMerkleRoot = rootHash[:]
in.SighashType = txscript.SigHashDefault
},
func(packet *psbt.Packet) {
require.Len(t.t, packet.Inputs, 1)
require.Len(
t.t, packet.Inputs[0].TaprootKeySpendSig, 64,
)
},
)
}
// runSignPsbtSegWitV1ScriptSpend tests that the SignPsbt RPC works correctly
// for a SegWit v1 p2tr script spend.
func runSignPsbtSegWitV1ScriptSpend(t *harnessTest,
net *lntest.NetworkHarness, alice *lntest.HarnessNode) {
// Everything we do here should be done within a second or two, so we
// can just keep a single timeout context around for all calls.
ctxb := context.Background()
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
// Derive a key we can use for signing.
keyDesc, internalKey, fullDerivationPath := deriveInternalKey(
ctxt, t, alice,
)
// Let's create a taproot script output now. This is a hash lock with a
// simple preimage of "foobar".
leaf1 := testScriptSchnorrSig(t.t, internalKey)
rootHash := leaf1.TapHash()
taprootKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:])
tapScriptAddr, err := btcutil.NewAddressTaproot(
schnorr.SerializePubKey(taprootKey), harnessNetParams,
)
require.NoError(t.t, err)
p2trPkScript, err := txscript.PayToAddrScript(tapScriptAddr)
require.NoError(t.t, err)
// We need to assemble the control block to be able to spend through the
// script path.
tapscript := input.TapscriptPartialReveal(internalKey, leaf1, nil)
controlBlockBytes, err := tapscript.ControlBlock.ToBytes()
require.NoError(t.t, err)
// Send some funds to the output and then try to get a signature through
// the SignPsbt RPC to spend that output again.
assertPsbtSpend(
ctxt, t, net, alice, p2trPkScript,
func(packet *psbt.Packet) {
in := &packet.Inputs[0]
in.Bip32Derivation = []*psbt.Bip32Derivation{{
PubKey: keyDesc.RawKeyBytes,
Bip32Path: fullDerivationPath,
}}
in.TaprootBip32Derivation = []*psbt.TaprootBip32Derivation{{
XOnlyPubKey: keyDesc.RawKeyBytes[1:],
Bip32Path: fullDerivationPath,
LeafHashes: [][]byte{rootHash[:]},
}}
in.SighashType = txscript.SigHashDefault
in.TaprootLeafScript = []*psbt.TaprootTapLeafScript{{
ControlBlock: controlBlockBytes,
Script: leaf1.Script,
LeafVersion: leaf1.LeafVersion,
}}
},
func(packet *psbt.Packet) {
require.Len(t.t, packet.Inputs, 1)
require.Len(
t.t, packet.Inputs[0].TaprootScriptSpendSig, 1,
)
scriptSpendSig := packet.Inputs[0].TaprootScriptSpendSig[0]
require.Len(t.t, scriptSpendSig.Signature, 64)
},
)
}
// assertPsbtSpend creates an output with the given pkScript on chain and then
// attempts to create a sweep transaction that is signed using the SignPsbt RPC
// that spends that output again.
func assertPsbtSpend(ctx context.Context, t *harnessTest,
net *lntest.NetworkHarness, alice *lntest.HarnessNode, pkScript []byte,
decorateUnsigned func(*psbt.Packet), verifySigned func(*psbt.Packet)) {
// Let's send some coins to that address now.
utxo := &wire.TxOut{
Value: 600_000,
PkScript: pkScript,
}
resp, err := alice.WalletKitClient.SendOutputs(
ctxt, &walletrpc.SendOutputsRequest{
ctx, &walletrpc.SendOutputsRequest{
Outputs: []*signrpc.TxOut{{
Value: utxo.Value,
PkScript: utxo.PkScript,
@@ -748,13 +966,9 @@ func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
require.NoError(t.t, err)
// Now let's add the meta information that we need for signing.
packet.Inputs[0].Bip32Derivation = []*psbt.Bip32Derivation{{
PubKey: addrPubKey.SerializeCompressed(),
Bip32Path: fullDerivationPath,
}}
packet.Inputs[0].WitnessUtxo = utxo
packet.Inputs[0].NonWitnessUtxo = prevTx
packet.Inputs[0].SighashType = txscript.SigHashAll
decorateUnsigned(packet)
// That's it, we should be able to sign the PSBT now.
var buf bytes.Buffer
@@ -762,7 +976,7 @@ func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
require.NoError(t.t, err)
signResp, err := alice.WalletKitClient.SignPsbt(
ctxt, &walletrpc.SignPsbtRequest{
ctx, &walletrpc.SignPsbtRequest{
FundedPsbt: buf.Bytes(),
},
)
@@ -774,12 +988,9 @@ func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
)
require.NoError(t.t, err)
require.Len(t.t, signedPacket.Inputs, 1)
require.Len(t.t, signedPacket.Inputs[0].PartialSigs, 1)
partialSig := signedPacket.Inputs[0].PartialSigs[0]
require.Equal(t.t, partialSig.PubKey, addrPubKey.SerializeCompressed())
require.Greater(t.t, len(partialSig.Signature), ecdsa.MinSigLen)
// Allow the caller to also verify (and potentially move) some of the
// returned fields.
verifySigned(signedPacket)
// We should be able to finalize the PSBT and extract the final TX now.
err = psbt.MaybeFinalizeAll(signedPacket)
@@ -794,7 +1005,7 @@ func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
// Publish the second transaction and then mine both of them.
_, err = alice.WalletKitClient.PublishTransaction(
ctxt, &walletrpc.Transaction{
ctx, &walletrpc.Transaction{
TxHex: buf.Bytes(),
},
)
@@ -808,6 +1019,34 @@ func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
assertTxInBlock(t, block, &secondTxHash)
}
// deriveInternalKey derives a signing key and returns its descriptor, full
// derivation path and parsed public key.
func deriveInternalKey(ctx context.Context, t *harnessTest,
alice *lntest.HarnessNode) (*signrpc.KeyDescriptor, *btcec.PublicKey,
[]uint32) {
// For the next step, we need a public key. Let's use a special family
// for this.
keyDesc, err := alice.WalletKitClient.DeriveNextKey(
ctx, &walletrpc.KeyReq{KeyFamily: testTaprootKeyFamily},
)
require.NoError(t.t, err)
// The DeriveNextKey returns a key from the internal 1017 scope.
fullDerivationPath := []uint32{
hdkeychain.HardenedKeyStart + keychain.BIP0043Purpose,
hdkeychain.HardenedKeyStart + harnessNetParams.HDCoinType,
hdkeychain.HardenedKeyStart + uint32(keyDesc.KeyLoc.KeyFamily),
0,
uint32(keyDesc.KeyLoc.KeyIndex),
}
parsedPubKey, err := btcec.ParsePubKey(keyDesc.RawKeyBytes)
require.NoError(t.t, err)
return keyDesc, parsedPubKey, fullDerivationPath
}
// openChannelPsbt attempts to open a channel between srcNode and destNode with
// the passed channel funding parameters. If the passed context has a timeout,
// then if the timeout is reached before the channel pending notification is
+12 -13
View File
@@ -106,7 +106,10 @@ func testRemoteSigner(net *lntest.NetworkHarness, t *harnessTest) {
name: "psbt",
fn: func(tt *harnessTest, wo, carol *lntest.HarnessNode) {
runPsbtChanFunding(net, tt, carol, wo)
runSignPsbt(tt, net, wo)
runSignPsbtSegWitV0P2WKH(tt, net, wo)
runSignPsbtSegWitV1KeySpendBip86(tt, net, wo)
runSignPsbtSegWitV1KeySpendRootHash(tt, net, wo)
runSignPsbtSegWitV1ScriptSpend(tt, net, wo)
},
}, {
name: "sign output raw",
@@ -123,18 +126,14 @@ func testRemoteSigner(net *lntest.NetworkHarness, t *harnessTest) {
)
defer cancel()
// TODO(guggero): Fix remote taproot signing by adding
// the required fields to PSBT.
// testTaprootComputeInputScriptKeySpendBip86(
// ctxt, tt, wo, net,
// )
// testTaprootSignOutputRawScriptSpend(ctxt, tt, wo, net)
// testTaprootSignOutputRawKeySpendBip86(
// ctxt, tt, wo, net,
// )
// testTaprootSignOutputRawKeySpendRootHash(
// ctxt, tt, wo, net,
// )
testTaprootComputeInputScriptKeySpendBip86(
ctxt, tt, wo, net,
)
testTaprootSignOutputRawScriptSpend(ctxt, tt, wo, net)
testTaprootSignOutputRawKeySpendBip86(ctxt, tt, wo, net)
testTaprootSignOutputRawKeySpendRootHash(
ctxt, tt, wo, net,
)
testTaprootMuSig2KeySpendRootHash(ctxt, tt, wo, net)
testTaprootMuSig2ScriptSpend(ctxt, tt, wo, net)
testTaprootMuSig2KeySpendBip86(ctxt, tt, wo, net)
+39 -13
View File
@@ -26,6 +26,9 @@ import (
const (
testTaprootKeyFamily = 77
testAmount = 800_000
signMethodBip86 = signrpc.SignMethod_SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086
signMethodRootHash = signrpc.SignMethod_SIGN_METHOD_TAPROOT_KEY_SPEND
signMethodTapscript = signrpc.SignMethod_SIGN_METHOD_TAPROOT_SCRIPT_SPEND
)
var (
@@ -193,6 +196,7 @@ func testTaprootSignOutputRawScriptSpend(ctxt context.Context, t *harnessTest,
KeyDesc: keyDesc,
Sighash: uint32(txscript.SigHashDefault),
WitnessScript: leaf2.Script,
SignMethod: signMethodTapscript,
}},
},
)
@@ -202,6 +206,27 @@ func testTaprootSignOutputRawScriptSpend(ctxt context.Context, t *harnessTest,
"input 0 is missing its previous outpoint information",
)
// We also want to make sure we get an error when we don't specify the
// correct signing method.
_, err = alice.SignerClient.SignOutputRaw(
ctxt, &signrpc.SignReq{
RawTxBytes: buf.Bytes(),
SignDescs: []*signrpc.SignDescriptor{{
Output: utxoInfo[0],
InputIndex: 0,
KeyDesc: keyDesc,
Sighash: uint32(txscript.SigHashDefault),
WitnessScript: leaf2.Script,
}},
PrevOutputs: utxoInfo,
},
)
require.Error(t.t, err)
require.Contains(
t.t, err.Error(), "selected sign method witness_v0 is not "+
"compatible with given pk script 5120",
)
// Do the actual signing now.
signResp, err := alice.SignerClient.SignOutputRaw(
ctxt, &signrpc.SignReq{
@@ -212,6 +237,7 @@ func testTaprootSignOutputRawScriptSpend(ctxt context.Context, t *harnessTest,
KeyDesc: keyDesc,
Sighash: uint32(txscript.SigHashDefault),
WitnessScript: leaf2.Script,
SignMethod: signMethodTapscript,
}},
PrevOutputs: utxoInfo,
},
@@ -307,12 +333,12 @@ func testTaprootSignOutputRawKeySpendBip86(ctxt context.Context,
ctxt, &signrpc.SignReq{
RawTxBytes: buf.Bytes(),
SignDescs: []*signrpc.SignDescriptor{{
Output: utxoInfo[0],
InputIndex: 0,
KeyDesc: keyDesc,
SingleTweak: dummyKeyTweak[:],
Sighash: uint32(txscript.SigHashDefault),
TaprootKeySpend: true,
Output: utxoInfo[0],
InputIndex: 0,
KeyDesc: keyDesc,
SingleTweak: dummyKeyTweak[:],
Sighash: uint32(txscript.SigHashDefault),
SignMethod: signMethodBip86,
}},
PrevOutputs: utxoInfo,
},
@@ -405,13 +431,13 @@ func testTaprootSignOutputRawKeySpendRootHash(ctxt context.Context,
ctxt, &signrpc.SignReq{
RawTxBytes: buf.Bytes(),
SignDescs: []*signrpc.SignDescriptor{{
Output: utxoInfo[0],
InputIndex: 0,
KeyDesc: keyDesc,
SingleTweak: dummyKeyTweak[:],
Sighash: uint32(txscript.SigHashDefault),
WitnessScript: rootHash[:],
TaprootKeySpend: true,
Output: utxoInfo[0],
InputIndex: 0,
KeyDesc: keyDesc,
SingleTweak: dummyKeyTweak[:],
Sighash: uint32(txscript.SigHashDefault),
TapTweak: rootHash[:],
SignMethod: signMethodRootHash,
}},
PrevOutputs: utxoInfo,
},
+235 -31
View File
@@ -2,12 +2,15 @@ package btcwallet
import (
"bytes"
"crypto/sha256"
"fmt"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/btcutil/psbt"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcwallet/waddrmgr"
"github.com/btcsuite/btcwallet/wallet"
"github.com/lightningnetwork/lnd/input"
@@ -111,7 +114,7 @@ func (b *BtcWallet) SignPsbt(packet *psbt.Packet) error {
prevOutputFetcher := wallet.PsbtPrevOutputFetcher(packet)
sigHashes := txscript.NewTxSigHashes(tx, prevOutputFetcher)
for idx := range tx.TxIn {
in := packet.Inputs[idx]
in := &packet.Inputs[idx]
// We can only sign if we have UTXO information available. Since
// we don't finalize, we just skip over any input that we know
@@ -165,47 +168,248 @@ func (b *BtcWallet) SignPsbt(packet *psbt.Packet) error {
// Do we need to tweak anything? Single or double tweaks are
// sent as custom/proprietary fields in the PSBT input section.
privKey = maybeTweakPrivKeyPsbt(in.Unknowns, privKey)
pubKeyBytes := privKey.PubKey().SerializeCompressed()
// Extract the correct witness and/or legacy scripts now,
// depending on the type of input we sign. The txscript package
// has the peculiar requirement that the PkScript of a P2PKH
// must be given as the witness script in order for it to arrive
// at the correct sighash. That's why we call it subScript here
// instead of witness script.
subScript, scriptSig, err := prepareScripts(in)
// What kind of signature is expected from us and do we have all
// information we need?
signMethod, err := validateSigningMethod(in)
if err != nil {
// We derived the correct key so we _are_ expected to
// sign this. Not being able to sign at this point means
// there's something wrong.
return fmt.Errorf("error deriving script for input "+
"%d: %v", idx, err)
return err
}
// We have everything we need for signing the input now.
sig, err := txscript.RawTxInWitnessSignature(
tx, sigHashes, idx, in.WitnessUtxo.Value, subScript,
in.SighashType, privKey,
)
if err != nil {
return fmt.Errorf("error signing input %d: %v", idx,
err)
switch signMethod {
// For p2wkh, np2wkh and p2wsh.
case input.WitnessV0SignMethod:
err = signSegWitV0(in, tx, sigHashes, idx, privKey)
// For p2tr BIP0086 key spend only.
case input.TaprootKeySpendBIP0086SignMethod:
rootHash := make([]byte, 0)
err = signSegWitV1KeySpend(
in, tx, sigHashes, idx, privKey, rootHash,
)
// For p2tr with script commitment key spend path.
case input.TaprootKeySpendSignMethod:
rootHash := in.TaprootMerkleRoot
err = signSegWitV1KeySpend(
in, tx, sigHashes, idx, privKey, rootHash,
)
// For p2tr script spend path.
case input.TaprootScriptSpendSignMethod:
leafScript := in.TaprootLeafScript[0]
leaf := txscript.TapLeaf{
LeafVersion: leafScript.LeafVersion,
Script: leafScript.Script,
}
err = signSegWitV1ScriptSpend(
in, tx, sigHashes, idx, privKey, leaf,
)
default:
err = fmt.Errorf("unsupported signing method for "+
"PSBT signing: %v", signMethod)
}
if err != nil {
return err
}
packet.Inputs[idx].FinalScriptSig = scriptSig
packet.Inputs[idx].PartialSigs = append(
packet.Inputs[idx].PartialSigs, &psbt.PartialSig{
PubKey: pubKeyBytes,
Signature: sig,
},
)
}
return nil
}
// prepareScripts returns the appropriate witness and/or legacy scripts,
// validateSigningMethod attempts to detect the signing method that is required
// to sign for the given PSBT input and makes sure all information is available
// to do so.
func validateSigningMethod(in *psbt.PInput) (input.SignMethod, error) {
script, err := txscript.ParsePkScript(in.WitnessUtxo.PkScript)
if err != nil {
return 0, fmt.Errorf("error detecting signing method, "+
"couldn't parse pkScript: %v", err)
}
switch script.Class() {
case txscript.WitnessV0PubKeyHashTy, txscript.ScriptHashTy,
txscript.WitnessV0ScriptHashTy:
return input.WitnessV0SignMethod, nil
case txscript.WitnessV1TaprootTy:
if len(in.TaprootBip32Derivation) == 0 {
return 0, fmt.Errorf("cannot sign for taproot input " +
"without taproot BIP0032 derivation info")
}
// Currently, we only support creating one signature per input.
//
// TODO(guggero): Should we support signing multiple paths at
// the same time? What are the performance and security
// implications?
if len(in.TaprootBip32Derivation) > 1 {
return 0, fmt.Errorf("unsupported multiple taproot " +
"BIP0032 derivation info found, can only " +
"sign for one at a time")
}
derivation := in.TaprootBip32Derivation[0]
switch {
// No leaf hashes means this is the internal key we're signing
// with, so it's a key spend. And no merkle root means this is
// a BIP0086 output we're signing for.
case len(derivation.LeafHashes) == 0 &&
len(in.TaprootMerkleRoot) == 0:
return input.TaprootKeySpendBIP0086SignMethod, nil
// A non-empty merkle root means we committed to a taproot hash
// that we need to use in the tap tweak.
case len(derivation.LeafHashes) == 0:
// Getting here means the merkle root isn't empty, but
// is it exactly the length we need?
if len(in.TaprootMerkleRoot) != sha256.Size {
return 0, fmt.Errorf("invalid taproot merkle "+
"root length, got %d expected %d",
len(in.TaprootMerkleRoot), sha256.Size)
}
return input.TaprootKeySpendSignMethod, nil
// Currently, we only support signing for one leaf at a time.
//
// TODO(guggero): Should we support signing multiple paths at
// the same time? What are the performance and security
// implications?
case len(derivation.LeafHashes) == 1:
// If we're supposed to be signing for a leaf hash, we
// also expect the leaf script that hashes to that hash
// in the appropriate field.
if len(in.TaprootLeafScript) != 1 {
return 0, fmt.Errorf("specified leaf hash in " +
"taproot BIP0032 derivation but " +
"missing taproot leaf script")
}
leafScript := in.TaprootLeafScript[0]
leaf := txscript.TapLeaf{
LeafVersion: leafScript.LeafVersion,
Script: leafScript.Script,
}
leafHash := leaf.TapHash()
if !bytes.Equal(leafHash[:], derivation.LeafHashes[0]) {
return 0, fmt.Errorf("specified leaf hash in" +
"taproot BIP0032 derivation but " +
"corresponding taproot leaf script " +
"was not found")
}
return input.TaprootScriptSpendSignMethod, nil
default:
return 0, fmt.Errorf("unsupported number of leaf " +
"hashes in taproot BIP0032 derivation info, " +
"can only sign for one at a time")
}
default:
return 0, fmt.Errorf("unsupported script class for signing "+
"PSBT: %v", script.Class())
}
}
// SignSegWitV0 attempts to generate a signature for a SegWit version 0 input
// and stores it in the PartialSigs (and FinalScriptSig for np2wkh addresses)
// field.
func signSegWitV0(in *psbt.PInput, tx *wire.MsgTx,
sigHashes *txscript.TxSigHashes, idx int,
privKey *btcec.PrivateKey) error {
pubKeyBytes := privKey.PubKey().SerializeCompressed()
// Extract the correct witness and/or legacy scripts now, depending on
// the type of input we sign. The txscript package has the peculiar
// requirement that the PkScript of a P2PKH must be given as the witness
// script in order for it to arrive at the correct sighash. That's why
// we call it subScript here instead of witness script.
subScript, scriptSig, err := prepareScriptsV0(in)
if err != nil {
// We derived the correct key so we _are_ expected to sign this.
// Not being able to sign at this point means there's something
// wrong.
return fmt.Errorf("error deriving script for input %d: %v", idx,
err)
}
// We have everything we need for signing the input now.
sig, err := txscript.RawTxInWitnessSignature(
tx, sigHashes, idx, in.WitnessUtxo.Value, subScript,
in.SighashType, privKey,
)
if err != nil {
return fmt.Errorf("error signing input %d: %v", idx, err)
}
in.FinalScriptSig = scriptSig
in.PartialSigs = append(in.PartialSigs, &psbt.PartialSig{
PubKey: pubKeyBytes,
Signature: sig,
})
return nil
}
// signSegWitV1KeySpend attempts to generate a signature for a SegWit version 1
// (p2tr) input and stores it in the TaprootKeySpendSig field.
func signSegWitV1KeySpend(in *psbt.PInput, tx *wire.MsgTx,
sigHashes *txscript.TxSigHashes, idx int, privKey *btcec.PrivateKey,
tapscriptRootHash []byte) error {
rawSig, err := txscript.RawTxInTaprootSignature(
tx, sigHashes, idx, in.WitnessUtxo.Value,
in.WitnessUtxo.PkScript, tapscriptRootHash, in.SighashType,
privKey,
)
if err != nil {
return fmt.Errorf("error signing taproot input %d: %v", idx,
err)
}
in.TaprootKeySpendSig = rawSig
return nil
}
// signSegWitV1ScriptSpend attempts to generate a signature for a SegWit version
// 1 (p2tr) input and stores it in the TaprootScriptSpendSig field.
func signSegWitV1ScriptSpend(in *psbt.PInput, tx *wire.MsgTx,
sigHashes *txscript.TxSigHashes, idx int, privKey *btcec.PrivateKey,
leaf txscript.TapLeaf) error {
rawSig, err := txscript.RawTxInTapscriptSignature(
tx, sigHashes, idx, in.WitnessUtxo.Value,
in.WitnessUtxo.PkScript, leaf, in.SighashType, privKey,
)
if err != nil {
return fmt.Errorf("error signing taproot script input %d: %v",
idx, err)
}
leafHash := leaf.TapHash()
in.TaprootScriptSpendSig = append(
in.TaprootScriptSpendSig, &psbt.TaprootScriptSpendSig{
XOnlyPubKey: in.TaprootBip32Derivation[0].XOnlyPubKey,
LeafHash: leafHash[:],
// We snip off the sighash flag from the end (if it was
// specified in the first place.)
Signature: rawSig[:schnorr.SignatureSize],
SigHash: in.SighashType,
},
)
return nil
}
// prepareScriptsV0 returns the appropriate witness v0 and/or legacy scripts,
// depending on the type of input that should be signed.
func prepareScripts(in psbt.PInput) ([]byte, []byte, error) {
func prepareScriptsV0(in *psbt.PInput) ([]byte, []byte, error) {
switch {
// It's a NP2WKH input:
case len(in.RedeemScript) > 0:
+8 -6
View File
@@ -372,21 +372,23 @@ func (b *BtcWallet) SignOutputRaw(tx *wire.MsgTx,
// slightly different, so we need to account for that to get the
// raw signature.
var rawSig []byte
if signDesc.TaprootKeySpend {
switch signDesc.SignMethod {
case input.TaprootKeySpendBIP0086SignMethod,
input.TaprootKeySpendSignMethod:
// This function tweaks the private key using the tap
// root key supplied as the tweak. So we pass in the
// original private key to avoid it being double
// tweaked!
// root key supplied as the tweak.
rawSig, err = txscript.RawTxInTaprootSignature(
tx, sigHashes, signDesc.InputIndex,
signDesc.Output.Value, signDesc.Output.PkScript,
signDesc.WitnessScript, signDesc.HashType,
signDesc.TapTweak, signDesc.HashType,
privKey,
)
if err != nil {
return nil, err
}
} else {
case input.TaprootScriptSpendSignMethod:
leaf := txscript.TapLeaf{
LeafVersion: txscript.BaseLeafVersion,
Script: witnessScript,
+178 -20
View File
@@ -544,6 +544,35 @@ func (r *RPCKeyRing) ComputeInputScript(tx *wire.MsgTx,
}
signDesc.WitnessScript = witnessProgram
// If this is a p2tr address, then it must be a BIP0086 key spend if we
// are coming through this path (instead of SignOutputRaw).
switch addr.AddrType() {
case waddrmgr.TaprootPubKey:
signDesc.SignMethod = input.TaprootKeySpendBIP0086SignMethod
signDesc.WitnessScript = nil
sig, err := r.remoteSign(tx, signDesc, sigScript)
if err != nil {
return nil, fmt.Errorf("error signing with remote"+
"instance: %v", err)
}
rawSig := sig.Serialize()
if signDesc.HashType != txscript.SigHashDefault {
rawSig = append(rawSig, byte(signDesc.HashType))
}
return &input.Script{
Witness: wire.TxWitness{
rawSig,
},
}, nil
case waddrmgr.TaprootScript:
return nil, fmt.Errorf("computing input script for taproot " +
"script address not supported")
}
// Let's give the TX to the remote instance now, so it can sign the
// input.
sig, err := r.remoteSign(tx, signDesc, sigScript)
@@ -803,6 +832,19 @@ func (r *RPCKeyRing) remoteSign(tx *wire.MsgTx, signDesc *input.SignDescriptor,
&txIn.PreviousOutPoint,
)
if err != nil {
// Maybe we have an UTXO in the previous output fetcher?
if signDesc.PrevOutputFetcher != nil {
utxo := signDesc.PrevOutputFetcher.FetchPrevOutput(
txIn.PreviousOutPoint,
)
if utxo != nil && utxo.Value != 0 &&
len(utxo.PkScript) > 0 {
packet.Inputs[idx].WitnessUtxo = utxo
continue
}
}
log.Warnf("No UTXO info found for index %d "+
"(prev_outpoint=%v), won't be able to sign "+
"for taproot output!", idx,
@@ -966,6 +1008,73 @@ func (r *RPCKeyRing) remoteSign(tx *wire.MsgTx, signDesc *input.SignDescriptor,
})
}
// Add taproot specific fields.
switch signDesc.SignMethod {
case input.TaprootKeySpendBIP0086SignMethod,
input.TaprootKeySpendSignMethod:
// The key identifying factor for a key spend is that we don't
// provide any leaf hashes to signal we want a signature for the
// key spend path (with the internal key).
d := in.Bip32Derivation[0]
in.TaprootBip32Derivation = []*psbt.TaprootBip32Derivation{{
// The x-only public key is just our compressed public
// key without the first byte (type/parity).
XOnlyPubKey: d.PubKey[1:],
LeafHashes: nil,
MasterKeyFingerprint: d.MasterKeyFingerprint,
Bip32Path: d.Bip32Path,
}}
// If this is a BIP0086 key spend then the tap tweak is empty,
// otherwise it's set to the Taproot root hash.
in.TaprootMerkleRoot = signDesc.TapTweak
case input.TaprootScriptSpendSignMethod:
// The script spend path is a bit more involved when doing it
// through the PSBT method. We need to specify the leaf hash
// that the signer should sign for.
leaf := txscript.TapLeaf{
LeafVersion: txscript.BaseLeafVersion,
Script: signDesc.WitnessScript,
}
leafHash := leaf.TapHash()
d := in.Bip32Derivation[0]
in.TaprootBip32Derivation = []*psbt.TaprootBip32Derivation{{
XOnlyPubKey: d.PubKey[1:],
LeafHashes: [][]byte{leafHash[:]},
MasterKeyFingerprint: d.MasterKeyFingerprint,
Bip32Path: d.Bip32Path,
}}
// We also need to supply a control block. But because we don't
// know the internal key nor the merkle proofs (both is not
// supplied through the SignOutputRaw RPC) and is technically
// not really needed by the signer (since we only want a
// signature, the full witness stack is assembled by the caller
// of this RPC), we can get by with faking certain information
// that we don't have.
fakeInternalKey, _ := btcec.ParsePubKey(d.PubKey)
fakeKeyIsOdd := d.PubKey[0] == input.PubKeyFormatCompressedOdd
controlBlock := txscript.ControlBlock{
InternalKey: fakeInternalKey,
OutputKeyYIsOdd: fakeKeyIsOdd,
LeafVersion: leaf.LeafVersion,
}
blockBytes, err := controlBlock.ToBytes()
if err != nil {
return nil, fmt.Errorf("error serializing control "+
"block: %v", err)
}
in.TaprootLeafScript = []*psbt.TaprootTapLeafScript{{
ControlBlock: blockBytes,
Script: leaf.Script,
LeafVersion: leaf.LeafVersion,
}}
}
// Okay, let's sign the input by the remote signer now.
ctxt, cancel := context.WithTimeout(context.Background(), r.rpcTimeout)
defer cancel()
@@ -996,28 +1105,77 @@ func (r *RPCKeyRing) remoteSign(tx *wire.MsgTx, signDesc *input.SignDescriptor,
return nil, fmt.Errorf("remote signer returned invalid PSBT")
}
in = &signedPacket.Inputs[signDesc.InputIndex]
if len(in.PartialSigs) != 1 {
return nil, fmt.Errorf("remote signer returned invalid "+
"partial signature, wanted 1, got %d",
len(in.PartialSigs))
}
sigWithSigHash := in.PartialSigs[0]
if sigWithSigHash == nil {
return nil, fmt.Errorf("remote signer returned nil signature")
}
// The remote signer always adds the sighash type, so we need to account
// for that.
if len(sigWithSigHash.Signature) < ecdsa.MinSigLen+1 {
return nil, fmt.Errorf("remote signer returned invalid "+
"partial signature: signature too short with %d bytes",
len(sigWithSigHash.Signature))
}
return extractSignature(in, signDesc.SignMethod)
}
// Parse the signature, but chop off the last byte which is the sighash
// type.
sig := sigWithSigHash.Signature[0 : len(sigWithSigHash.Signature)-1]
return ecdsa.ParseDERSignature(sig)
// extractSignature attempts to extract the signature from the PSBT input,
// looking at different fields depending on the signing method that was used.
func extractSignature(in *psbt.PInput,
signMethod input.SignMethod) (input.Signature, error) {
switch signMethod {
case input.WitnessV0SignMethod:
if len(in.PartialSigs) != 1 {
return nil, fmt.Errorf("remote signer returned "+
"invalid partial signature, wanted 1, got %d",
len(in.PartialSigs))
}
sigWithSigHash := in.PartialSigs[0]
if sigWithSigHash == nil {
return nil, fmt.Errorf("remote signer returned nil " +
"signature")
}
// The remote signer always adds the sighash type, so we need to
// account for that.
sigLen := len(sigWithSigHash.Signature)
if sigLen < ecdsa.MinSigLen+1 {
return nil, fmt.Errorf("remote signer returned "+
"invalid partial signature: signature too "+
"short with %d bytes", sigLen)
}
// Parse the signature, but chop off the last byte which is the
// sighash type.
sig := sigWithSigHash.Signature[0 : sigLen-1]
return ecdsa.ParseDERSignature(sig)
// The type of key spend doesn't matter, the signature should be in the
// same field for both of those signing methods.
case input.TaprootKeySpendBIP0086SignMethod,
input.TaprootKeySpendSignMethod:
sigLen := len(in.TaprootKeySpendSig)
if sigLen < schnorr.SignatureSize {
return nil, fmt.Errorf("remote signer returned "+
"invalid key spend signature: signature too "+
"short with %d bytes", sigLen)
}
return schnorr.ParseSignature(
in.TaprootKeySpendSig[:schnorr.SignatureSize],
)
case input.TaprootScriptSpendSignMethod:
if len(in.TaprootScriptSpendSig) != 1 {
return nil, fmt.Errorf("remote signer returned "+
"invalid taproot script spend signature, "+
"wanted 1, got %d",
len(in.TaprootScriptSpendSig))
}
scriptSpendSig := in.TaprootScriptSpendSig[0]
if scriptSpendSig == nil {
return nil, fmt.Errorf("remote signer returned nil " +
"taproot script spend signature")
}
return schnorr.ParseSignature(scriptSpendSig.Signature)
default:
return nil, fmt.Errorf("can't extract signature, unsupported "+
"signing method: %v", signMethod)
}
}
// connectRPC tries to establish an RPC connection to the given host:port with