gitee.com/lh-her-team/common@v1.5.1/crypto/hibe/hibe_amd64/hibeutils.go (about)

     1  package hibe_amd64
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"errors"
     6  	"fmt"
     7  	"math/big"
     8  	"reflect"
     9  	"strings"
    10  
    11  	"gitee.com/lh-her-team/common/crypto"
    12  	"gitee.com/lh-her-team/common/crypto/hash"
    13  	"gitee.com/lh-her-team/common/crypto/hibe/hibe_amd64/hibe"
    14  	"gitee.com/lh-her-team/common/crypto/sym"
    15  )
    16  
    17  // ValidateId is used to validate id format
    18  func ValidateId(id string) error {
    19  	if id == "" {
    20  		return errors.New("invalid parameters, id is nil")
    21  	}
    22  	idStrList := strings.Split(id, "/")
    23  	for _, s := range idStrList {
    24  		if s == "" {
    25  			return fmt.Errorf("invalid parameters, id: %s, format error, only like : \"A/B/C\" can be used", id)
    26  		}
    27  		if strings.Contains(s, " ") {
    28  			return fmt.Errorf("invalid parameters, id: %s, format error, only like : \"A/B/C\" can be used", id)
    29  		}
    30  	}
    31  	return nil
    32  }
    33  
    34  // refineIdsAndParams Remove redundant data (Id)
    35  // Only the lowest level ID is reserved for the ID with superior subordinate relationship
    36  func refineIdsAndParams(ids []string, paramsList []*hibe.Params) ([]string, []*hibe.Params, error) {
    37  	refinedReceiverIds := make([]string, 1)
    38  	refinedReceiverIds[0] = ids[0]
    39  	refinedParamsList := make([]*hibe.Params, 1)
    40  	refinedParamsList[0] = paramsList[0]
    41  	for i := 1; i < len(ids); i++ {
    42  		matched := false
    43  		for j, rId := range refinedReceiverIds {
    44  			iIdSlice := strings.Split(ids[i], "/")
    45  			iLen := len(iIdSlice)
    46  			rIdSlice := strings.Split(rId, "/")
    47  			rLen := len(rIdSlice)
    48  			// 1.They do not have a subordinate relationship
    49  			if iLen == rLen {
    50  				continue
    51  			}
    52  			if rLen > iLen { // 2. refinedReceiverIds[j] has prefix ids[i]
    53  				matched = true
    54  				for k := 0; k < iLen; k++ {
    55  					if iIdSlice[k] != rIdSlice[k] {
    56  						matched = false
    57  						break
    58  					}
    59  				}
    60  				// they have different parameters, return error
    61  				if matched && !reflect.DeepEqual(paramsList[i].Marshal(), refinedParamsList[j].Marshal()) {
    62  					return nil, nil, fmt.Errorf("ID [%s] is matched, but Params are different, please check it",
    63  						ids[i])
    64  				}
    65  			} else { // 3. ids[i] has prefix refinedReceiverIds[j]
    66  				matched = true
    67  				for k := 0; k < rLen; k++ {
    68  					if iIdSlice[k] != rIdSlice[k] {
    69  						matched = false
    70  						break
    71  					}
    72  				}
    73  				// they have different parameters, return error
    74  				if matched && !reflect.DeepEqual(paramsList[i].Marshal(), refinedParamsList[j].Marshal()) {
    75  					return nil, nil, fmt.Errorf("ID [%s] is matched, but Params are different, please check it",
    76  						ids[i])
    77  				}
    78  				if matched {
    79  					refinedReceiverIds[j] = ids[i]
    80  					refinedParamsList[j] = paramsList[i]
    81  					break
    82  				}
    83  			}
    84  		}
    85  		if !matched {
    86  			refinedReceiverIds = append(refinedReceiverIds, ids[i])
    87  			refinedParamsList = append(refinedParamsList, paramsList[i])
    88  		}
    89  	}
    90  	return refinedReceiverIds, refinedParamsList, nil
    91  }
    92  
    93  // idStrList2HibeIds construct HibeId list according to id list
    94  func idStrList2HibeIds(idList []string) [][]*big.Int {
    95  	// construct ids []*big.Int
    96  	hibeIds := make([][]*big.Int, len(idList))
    97  	for i, idStr := range idList {
    98  		_, hibeIds[i] = IdStr2HibeId(idStr)
    99  	}
   100  	return hibeIds
   101  }
   102  
   103  // IdStr2HibeId construct HibeId according to id
   104  func IdStr2HibeId(id string) ([]string, []*big.Int) {
   105  	// idStr eg: "org1/ou1" -> ["org1", "ou1"]
   106  	strId := strings.Split(id, "/")
   107  	// idsStr -> hibeId
   108  	hibeIds := make([]*big.Int, len(strId))
   109  	for i, value := range strId {
   110  		hashedStrId := sha256.Sum256([]byte(value))
   111  		bigIdBytes := hashedStrId[:]
   112  		bigId := new(big.Int)
   113  		bigId.SetBytes(bigIdBytes)
   114  		hibeIds[i] = bigId
   115  	}
   116  	return strId, hibeIds
   117  }
   118  
   119  // generateSymKeyFromGtBytes is used to generate symmetric key according to gtBytes and symKeyType
   120  func generateSymKeyFromGtBytes(gtBytes []byte, symKeyType crypto.KeyType) (crypto.SymmetricKey, error) {
   121  	var symKey crypto.SymmetricKey
   122  	if symKeyType == crypto.AES {
   123  		// not gm
   124  		gtBytesHash, err := hash.Get(crypto.HASH_TYPE_SHA256, gtBytes)
   125  		if err != nil {
   126  			return nil, err
   127  		}
   128  		symKey, err = sym.GenerateSymKey(crypto.AES, gtBytesHash)
   129  		if err != nil {
   130  			return nil, err
   131  		}
   132  	} else if symKeyType == crypto.SM4 {
   133  		// gm
   134  		gtBytesHash, err := hash.Get(crypto.HASH_TYPE_SM3, gtBytes)
   135  		if err != nil {
   136  			return nil, err
   137  		}
   138  		symKey, err = sym.GenerateSymKey(crypto.SM4, gtBytesHash[:16])
   139  		if err != nil {
   140  			return nil, err
   141  		}
   142  	} else {
   143  		return nil, fmt.Errorf("invalid parameters, unsupported symmetric encryption algorithm type : %d", symKeyType)
   144  	}
   145  	return symKey, nil
   146  }