github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/auth/ibc-tx/sig.go (about) 1 package ibc_tx 2 3 import ( 4 "fmt" 5 6 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec" 7 codectypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types" 8 cryptotypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/crypto/types" 9 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/tx" 10 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/tx/signing" 11 ) 12 13 // SignatureDataToModeInfoAndSig converts a SignatureData to a ModeInfo and raw bytes signature 14 func SignatureDataToModeInfoAndSig(data signing.SignatureData) (*tx.ModeInfo, []byte) { 15 if data == nil { 16 return nil, nil 17 } 18 19 switch data := data.(type) { 20 case *signing.SingleSignatureData: 21 return &tx.ModeInfo{ 22 Sum: &tx.ModeInfo_Single_{ 23 Single: &tx.ModeInfo_Single{Mode: data.SignMode}, 24 }, 25 }, data.Signature 26 //case *signing.MultiSignatureData: 27 // n := len(data.Signatures) 28 // modeInfos := make([]*tx.ModeInfo, n) 29 // sigs := make([][]byte, n) 30 // 31 // for i, d := range data.Signatures { 32 // modeInfos[i], sigs[i] = SignatureDataToModeInfoAndSig(d) 33 // } 34 // 35 // multisig := cryptotypes.MultiSignature{ 36 // Signatures: sigs, 37 // } 38 // sig, err := multisig.Marshal() 39 // if err != nil { 40 // panic(err) 41 // } 42 // 43 // return &tx.ModeInfo{ 44 // Sum: &tx.ModeInfo_Multi_{ 45 // Multi: &tx.ModeInfo_Multi{ 46 // Bitarray: data.BitArray, 47 // ModeInfos: modeInfos, 48 // }, 49 // }, 50 // }, sig 51 default: 52 panic(fmt.Sprintf("unexpected signature data type %T", data)) 53 } 54 } 55 56 // ModeInfoAndSigToSignatureData converts a ModeInfo and raw bytes signature to a SignatureData or returns 57 // an error 58 func ModeInfoAndSigToSignatureData(modeInfo *tx.ModeInfo, sig []byte) (signing.SignatureData, error) { 59 switch modeInfo := modeInfo.Sum.(type) { 60 case *tx.ModeInfo_Single_: 61 return &signing.SingleSignatureData{ 62 SignMode: modeInfo.Single.Mode, 63 Signature: sig, 64 }, nil 65 66 //case *tx.ModeInfo_Multi_: 67 // multi := modeInfo.Multi 68 // 69 // sigs, err := decodeMultisignatures(sig) 70 // if err != nil { 71 // return nil, err 72 // } 73 // 74 // sigv2s := make([]signing.SignatureData, len(sigs)) 75 // for i, mi := range multi.ModeInfos { 76 // sigv2s[i], err = ModeInfoAndSigToSignatureData(mi, sigs[i]) 77 // if err != nil { 78 // return nil, err 79 // } 80 // } 81 // 82 // return &signing.MultiSignatureData{ 83 // BitArray: multi.Bitarray, 84 // Signatures: sigv2s, 85 // }, nil 86 87 default: 88 panic(fmt.Errorf("unexpected ModeInfo data type %T", modeInfo)) 89 } 90 } 91 92 // decodeMultisignatures safely decodes the the raw bytes as a MultiSignature protobuf message 93 //func decodeMultisignatures(bz []byte) ([][]byte, error) { 94 // multisig := cryptotypes.MultiSignature{} 95 // err := multisig.Unmarshal(bz) 96 // if err != nil { 97 // return nil, err 98 // } 99 // // NOTE: it is import to reject multi-signatures that contain unrecognized fields because this is an exploitable 100 // // malleability in the protobuf message. Basically an attacker could bloat a MultiSignature message with unknown 101 // // fields, thus bloating the transaction and causing it to fail. 102 // if len(multisig.XXX_unrecognized) > 0 { 103 // return nil, fmt.Errorf("rejecting unrecognized fields found in MultiSignature") 104 // } 105 // return multisig.Signatures, nil 106 //} 107 108 func (g config) MarshalSignatureJSON(sigs []signing.SignatureV2) ([]byte, error) { 109 descs := make([]*signing.SignatureDescriptor, len(sigs)) 110 111 for i, sig := range sigs { 112 descData := signing.SignatureDataToProto(sig.Data) 113 any, err := codectypes.NewAnyWithValue(sig.PubKey) 114 if err != nil { 115 return nil, err 116 } 117 118 descs[i] = &signing.SignatureDescriptor{ 119 PublicKey: any, 120 Data: descData, 121 Sequence: sig.Sequence, 122 } 123 } 124 125 toJSON := &signing.SignatureDescriptors{Signatures: descs} 126 127 return codec.ProtoMarshalJSON(toJSON, nil) 128 } 129 130 func (g config) UnmarshalSignatureJSON(bz []byte) ([]signing.SignatureV2, error) { 131 var sigDescs signing.SignatureDescriptors 132 err := g.protoCodec.UnmarshalJSON(bz, &sigDescs) 133 if err != nil { 134 return nil, err 135 } 136 137 sigs := make([]signing.SignatureV2, len(sigDescs.Signatures)) 138 for i, desc := range sigDescs.Signatures { 139 pubKey, _ := desc.PublicKey.GetCachedValue().(cryptotypes.PubKey) 140 141 data := signing.SignatureDataFromProto(desc.Data) 142 143 sigs[i] = signing.SignatureV2{ 144 PubKey: pubKey, 145 Data: data, 146 Sequence: desc.Sequence, 147 } 148 } 149 150 return sigs, nil 151 }