Skip to content

Commit e87dc22

Browse files
committed
psbt: add new PSBT_GLOBAL_GENERIC_SINGED_MESSAGE field
This new field is required to signal to signers that the PSBT being signed is actually for producing a BIP-0322 generic message signature.
1 parent 51e9b53 commit e87dc22

3 files changed

Lines changed: 40 additions & 7 deletions

File tree

btcutil/psbt/psbt.go

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ type Packet struct {
142142
// derived.
143143
XPubs []XPub
144144

145+
// GenericSignedMessage contains a BIP-0322 generic message to be
146+
// signed. An empty message is a valid message, that's why this field
147+
// is a nillable string.
148+
GenericSignedMessage *string
149+
145150
// Unknowns are the set of custom types (global only) within this PSBT.
146151
Unknowns []*Unknown
147152
}
@@ -240,8 +245,9 @@ func NewFromRawBytes(r io.Reader, b64 bool) (*Packet, error) {
240245
// Next we parse any unknowns that may be present, making sure that we
241246
// break at the separator.
242247
var (
243-
xPubSlice []XPub
244-
unknownSlice []*Unknown
248+
xPubSlice []XPub
249+
genericSignedMessage *string
250+
unknownSlice []*Unknown
245251
)
246252
for {
247253
keyint, keydata, err := getKey(r)
@@ -275,6 +281,12 @@ func NewFromRawBytes(r io.Reader, b64 bool) (*Packet, error) {
275281

276282
xPubSlice = append(xPubSlice, *xPub)
277283

284+
case GenericSignedMessageType:
285+
// Golang's default string encoding is UTF-8, so we
286+
// don't need to worry about the encoding here.
287+
messageString := string(value)
288+
genericSignedMessage = &messageString
289+
278290
default:
279291
keyintanddata := []byte{byte(keyint)}
280292
keyintanddata = append(keyintanddata, keydata...)
@@ -313,11 +325,12 @@ func NewFromRawBytes(r io.Reader, b64 bool) (*Packet, error) {
313325

314326
// Populate the new Packet object.
315327
newPsbt := Packet{
316-
UnsignedTx: msgTx,
317-
Inputs: inSlice,
318-
Outputs: outSlice,
319-
XPubs: xPubSlice,
320-
Unknowns: unknownSlice,
328+
UnsignedTx: msgTx,
329+
Inputs: inSlice,
330+
Outputs: outSlice,
331+
XPubs: xPubSlice,
332+
GenericSignedMessage: genericSignedMessage,
333+
Unknowns: unknownSlice,
321334
}
322335

323336
// Extended sanity checking is applied here to make sure the
@@ -369,6 +382,17 @@ func (p *Packet) Serialize(w io.Writer) error {
369382
}
370383
}
371384

385+
// Serialize the generic signed message.
386+
if p.GenericSignedMessage != nil {
387+
msgBytes := []byte(*p.GenericSignedMessage)
388+
err := serializeKVPairWithType(
389+
w, uint8(GenericSignedMessageType), nil, msgBytes,
390+
)
391+
if err != nil {
392+
return err
393+
}
394+
}
395+
372396
// Unknown is a special case; we don't have a key type, only a key and
373397
// a value field
374398
for _, kv := range p.Unknowns {

btcutil/psbt/psbt_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ var validPsbtBase64 = map[int]string{
107107
7: "cHNidP8BAFICAAAAAZ38ZijCbFiZ/hvT3DOGZb/VXXraEPYiCXPfLTht7BJ2AQAAAAD/////AfA9zR0AAAAAFgAUezoAv9wU0neVwrdJAdCdpu8TNXkAAAAATwEENYfPAto/0AiAAAAAlwSLGtBEWx7IJ1UXcnyHtOTrwYogP/oPlMAVZr046QADUbdDiH7h1A3DKmBDck8tZFmztaTXPa7I+64EcvO8Q+IM2QxqT64AAIAAAACATwEENYfPAto/0AiAAAABuQRSQnE5zXjCz/JES+NTzVhgXj5RMoXlKLQH+uP2FzUD0wpel8itvFV9rCrZp+OcFyLrrGnmaLbyZnzB1nHIPKsM2QxqT64AAIABAACAAAEBKwBlzR0AAAAAIgAgLFSGEmxJeAeagU4TcV1l82RZ5NbMre0mbQUIZFuvpjIBBUdSIQKdoSzbWyNWkrkVNq/v5ckcOrlHPY5DtTODarRWKZyIcSEDNys0I07Xz5wf6l0F1EFVeSe+lUKxYusC4ass6AIkwAtSriIGAp2hLNtbI1aSuRU2r+/lyRw6uUc9jkO1M4NqtFYpnIhxENkMak+uAACAAAAAgAAAAAAiBgM3KzQjTtfPnB/qXQXUQVV5J76VQrFi6wLhqyzoAiTACxDZDGpPrgAAgAEAAIAAAAAAACICA57/H1R6HV+S36K6evaslxpL0DukpzSwMVaiVritOh75EO3kXMUAAACAAAAAgAEAAIAA",
108108
// Case: PSBT with `PSBT_GLOBAL_XPUB`.
109109
8: "cHNidP8BAJ0BAAAAAnEOp2q0XFy2Q45gflnMA3YmmBgFrp4N/ZCJASq7C+U1AQAAAAD/////GQmU1qizyMgsy8+y+6QQaqBmObhyqNRHRlwNQliNbWcAAAAAAP////8CAOH1BQAAAAAZdqkUtrwsDuVlWoQ9ea/t0MzD991kNAmIrGBa9AUAAAAAFgAUEYjvjkzgRJ6qyPsUHL9aEXbmoIgAAAAATwEEiLIeA55TDKyAAAAAPbyKXJdp8DGxfnf+oVGGAyIaGP0Y8rmlTGyMGsdcvDUC8jBYSxVdHH8c1FEgplPEjWULQxtnxbLBPyfXFCA3wWkQJ1acUDEAAIAAAACAAAAAgAABAR8A4fUFAAAAABYAFDO5gvkbKPFgySC0q5XljOUN2jpKIgIDMJaA8zx9446mpHzU7NZvH1pJdHxv+4gI7QkDkkPjrVxHMEQCIC1wTO2DDFapCTRL10K2hS3M0QPpY7rpLTjnUlTSu0JFAiAthsQ3GV30bAztoITyopHD2i1kBw92v5uQsZXn7yj3cgEiBgMwloDzPH3jjqakfNTs1m8fWkl0fG/7iAjtCQOSQ+OtXBgnVpxQMQAAgAAAAIAAAACAAAAAAAEAAAAAAQEfAOH1BQAAAAAWABQ4j7lEMH63fvRRl9CwskXgefAR3iICAsd3Fh9z0LfHK57nveZQKT0T8JW8dlatH1Jdpf0uELEQRzBEAiBMsftfhpyULg4mEAV2ElQ5F5rojcqKncO6CPeVOYj6pgIgUh9JynkcJ9cOJzybFGFphZCTYeJb4nTqIA1+CIJ+UU0BIgYCx3cWH3PQt8crnue95lApPRPwlbx2Vq0fUl2l/S4QsRAYJ1acUDEAAIAAAACAAAAAgAAAAAAAAAAAAAAiAgLSDKUC7iiWhtIYFb1DqAY3sGmOH7zb5MrtRF9sGgqQ7xgnVpxQMQAAgAAAAIAAAACAAAAAAAQAAAAA",
110+
// Case: PSBT wich `PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE`.
111+
9: "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwABCS1VVEYtOCBzdXBwb3J0OiDDtsOkw7zDqcOgw6gg5rWL6K+V5paH5pysIPCfmIQAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAAAA",
110112
}
111113

112114
// These are all invalid PSBTs for the indicated reasons.

btcutil/psbt/types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ const (
3030
// extended public key.
3131
XPubType GlobalType = 1
3232

33+
// GenericSignedMessageType is used to house a BIP-0322 generic signed
34+
// message, encoded as UTF-8.
35+
//
36+
// The key is ({0x09}|{message}), and the value is the UTF-8 encoded
37+
// message.
38+
GenericSignedMessageType GlobalType = 0x09
39+
3340
// VersionType houses the global version number of this PSBT. There is
3441
// no key (only contains the byte type), then the value if omitted, is
3542
// assumed to be zero.

0 commit comments

Comments
 (0)