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  }