github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/signature/type_encoder.go (about)

     1  package signature
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/onflow/crypto"
     7  
     8  	"github.com/onflow/flow-go/model/encoding"
     9  )
    10  
    11  const SigLen = crypto.SignatureLenBLSBLS12381
    12  
    13  // EncodeSingleSig encodes a single signature into signature data as required by the consensus design.
    14  func EncodeSingleSig(sigType encoding.SigType, sig crypto.Signature) []byte {
    15  	t := byte(sigType)
    16  	encoded := make([]byte, 0, len(sig)+1)
    17  	encoded = append(encoded, t)
    18  	encoded = append(encoded, sig[:]...)
    19  	return encoded
    20  }
    21  
    22  // DecodeSingleSig decodes the signature data into a cryptographic signature and a type as required by
    23  // the consensus design. Cryptographic validity of signatures is _not_ checked.
    24  // It returns:
    25  //   - 0, nil, ErrInvalidSignatureFormat if the sig type is invalid (covers nil or empty sigData)
    26  //   - sigType, signature, nil if the sig type is valid and the decoding is done successfully.
    27  func DecodeSingleSig(sigData []byte) (encoding.SigType, crypto.Signature, error) {
    28  	if len(sigData) == 0 {
    29  		return 0, nil, fmt.Errorf("empty sig data: %w", ErrInvalidSignatureFormat)
    30  	}
    31  
    32  	sigType := encoding.SigType(sigData[0])
    33  	if !sigType.Valid() {
    34  		return 0, nil, fmt.Errorf("invalid sig type %v: %w", sigType, ErrInvalidSignatureFormat)
    35  	}
    36  
    37  	sig := crypto.Signature(sigData[1:])
    38  	return sigType, sig, nil
    39  }
    40  
    41  // TODO: to be removed in V3, replace by packer's pack method
    42  // EncodeDoubleSig encodes both the staking signature and random beacon signature
    43  // into one sigData.
    44  func EncodeDoubleSig(stakingSig crypto.Signature, beaconSig crypto.Signature) []byte {
    45  	encoded := make([]byte, 0, len(stakingSig)+len(beaconSig))
    46  	encoded = append(encoded, stakingSig...)
    47  	encoded = append(encoded, beaconSig...)
    48  	return encoded
    49  }
    50  
    51  // TODO: to be removed in V3, replace by packer's unpack method
    52  // DecodeDoubleSig decodes the signature data into a staking signature and an optional
    53  // random beacon signature. The decoding assumes BLS with BLS12-381 is used.
    54  // Cryptographic validity of signatures is _not_ checked.
    55  // Decomposition of the sigData is purely done based on length.
    56  // It returns:
    57  //   - staking signature, random beacon signature, nil:
    58  //     if sigData is twice the size of a BLS signature bytes long, we use the leading half as staking signature
    59  //     and the tailing half random beacon sig
    60  //   - staking signature, nil, nil:
    61  //     if sigData is the size of a BLS signature, we interpret sigData entirely as staking signature
    62  //   - nil, nil, ErrInvalidSignatureFormat if the sig type is invalid (covers nil or empty sigData)
    63  func DecodeDoubleSig(sigData []byte) (crypto.Signature, crypto.Signature, error) {
    64  	sigLen := SigLen
    65  
    66  	switch len(sigData) {
    67  	case sigLen:
    68  		return sigData, nil, nil
    69  	case 2 * sigLen:
    70  		return sigData[:sigLen], sigData[sigLen:], nil
    71  	}
    72  
    73  	return nil, nil, fmt.Errorf("invalid sig data length %d: %w", len(sigData), ErrInvalidSignatureFormat)
    74  }