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

     1  package hibe_amd64
     2  
     3  import (
     4  	"crypto/rand"
     5  	"encoding/base64"
     6  	"errors"
     7  	"fmt"
     8  	"strings"
     9  
    10  	"gitee.com/lh-her-team/common/crypto"
    11  	"gitee.com/lh-her-team/common/crypto/hibe/hibe_amd64/hibe"
    12  	"gitee.com/lh-her-team/common/crypto/hibe/hibe_amd64/hibe/bn256"
    13  )
    14  
    15  const (
    16  	// hibe message's cipher text key
    17  	hibeMsgCipherTextKey = "CT"
    18  )
    19  
    20  // EncryptHibeMsg is used to encrypt plainText by receiverIds and their paramsList
    21  // plaintext: plain text bytes
    22  // receiverIds: message receivers' id list, using "/" to separate hierarchy identity in each id string
    23  // paramsList: HIBE parameters list of the message receiver, len(paramsList) should be equal to len(receiverIds),
    24  //   paramsList[i] are the HIBE parameters of receiverIds[i]
    25  // symKeyType: symmetric key type (aes or sm4), used to symmetric encrypt the plain text first
    26  func EncryptHibeMsg(plaintext []byte, receiverIds []string, paramsList []*hibe.Params,
    27  	symKeyType crypto.KeyType) (map[string]string, error) {
    28  	// input parameter validation
    29  	if len(plaintext) == 0 {
    30  		return nil, errors.New("invalid parameters, plaintext is nil")
    31  	}
    32  	if len(receiverIds) == 0 {
    33  		return nil, errors.New("invalid parameters, receiverIds is nil")
    34  	}
    35  	for _, id := range receiverIds {
    36  		if err := ValidateId(id); err != nil {
    37  			return nil, err
    38  		}
    39  	}
    40  	if len(paramsList) == 0 {
    41  		return nil, errors.New("invalid parameters, paramsList is nil")
    42  	}
    43  	if len(receiverIds) != len(paramsList) {
    44  		return nil, errors.New("invalid parameters, receiverIds and paramsList do not match, place check them")
    45  	}
    46  	if symKeyType != crypto.AES && symKeyType != crypto.SM4 {
    47  		return nil, fmt.Errorf("invalid parameters, unsupported symmetric encryption algorithm type : %d", symKeyType)
    48  	}
    49  	// generate symmetric encryption (like AES, SM4) Key
    50  	// generate a random point from GT
    51  	_, randG1, err := bn256.RandomG1(rand.Reader)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	_, randG2, err := bn256.RandomG2(rand.Reader)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  	gt := bn256.Pair(randG1, randG2)
    60  	gtBytes := gt.Marshal()
    61  	symKey, err := generateSymKeyFromGtBytes(gtBytes, symKeyType)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	// use sym key to encrypt plaintext
    66  	encryptedMessage, err := symKey.Encrypt(plaintext)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	encryptedMessageStr := base64.StdEncoding.EncodeToString(encryptedMessage)
    71  	// Remove redundant data (Id)
    72  	// Only the lowest level ID is reserved
    73  	refinedReceiverIds, refinedParamsList, err := refineIdsAndParams(receiverIds, paramsList)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	hibeIds := idStrList2HibeIds(refinedReceiverIds)
    78  	// ciphertext []byte -> string
    79  	ciphertextsStr := make([]string, len(refinedReceiverIds))
    80  	for i, id := range hibeIds {
    81  		ciphertext, err := hibe.Encrypt(rand.Reader, refinedParamsList[i], id[:], gt)
    82  		if err != nil {
    83  			return nil, err
    84  		}
    85  		ciphertextsStr[i] = base64.StdEncoding.EncodeToString(ciphertext.Marshal())
    86  	}
    87  	hibeMsgMap := make(map[string]string)
    88  	hibeMsgMap[hibeMsgCipherTextKey] = encryptedMessageStr
    89  	for i, ciphertextStr := range ciphertextsStr {
    90  		hibeMsgMap[refinedReceiverIds[i]] = ciphertextStr
    91  	}
    92  	return hibeMsgMap, nil
    93  }
    94  
    95  // DecryptHibeMsg is used to decrypt the HIBE message constructed by EncryptHibeMsg
    96  // localId: hibe Id
    97  // hibeParams: HIBE parameters of the HIBE system to which ID belongs
    98  // prvKey: the localId's hibe private Key
    99  // hibeMsgMap: HIBE message encrypt by EncryptHibeMsg
   100  // symKeyType: symmetric key type (aes or sm4), used to symmetric encrypt the plain text first
   101  func DecryptHibeMsg(localId string, hibeParams *hibe.Params, prvKey *hibe.PrivateKey,
   102  	hibeMsgMap map[string]string, symKeyType crypto.KeyType) ([]byte, error) {
   103  	// input parameter validation
   104  	if err := ValidateId(localId); err != nil {
   105  		return nil, err
   106  	}
   107  	if hibeParams == nil {
   108  		return nil, errors.New("invalid parameters, hibeParams is nil")
   109  	}
   110  	if prvKey == nil {
   111  		return nil, errors.New("invalid parameters, prvKey is nil")
   112  	}
   113  	if hibeMsgMap == nil {
   114  		return nil, errors.New("invalid parameters, hibeMsgMap is nil")
   115  	}
   116  	if symKeyType != crypto.AES && symKeyType != crypto.SM4 {
   117  		return nil, fmt.Errorf("invalid parameters, unsupported symmetric encryption algorithm type : %d", symKeyType)
   118  	}
   119  	matchedId := ""
   120  	for id := range hibeMsgMap {
   121  		if id == hibeMsgCipherTextKey {
   122  			continue
   123  		}
   124  		if strings.HasPrefix(id, localId) {
   125  			matchedId = id
   126  			break
   127  		}
   128  	}
   129  	if matchedId == "" {
   130  		return nil, errors.New("no permission")
   131  	}
   132  	matchedPrvKey := new(hibe.PrivateKey)
   133  	if matchedId != localId {
   134  		matchedIdStr, hibeIds := IdStr2HibeId(matchedId)
   135  		localIdStrLen := len(strings.Split(localId, "/"))
   136  		var err error
   137  		for i := localIdStrLen + 1; i <= len(matchedIdStr); i++ {
   138  			prvKey, err = hibe.KeyGenFromParent(rand.Reader, hibeParams, prvKey, hibeIds[:i])
   139  			if err != nil {
   140  				return nil, err
   141  			}
   142  		}
   143  		matchedPrvKey = prvKey
   144  	}
   145  	matchedPrvKey = prvKey
   146  	// get Gt
   147  	encryptGt := &hibe.Ciphertext{}
   148  	encryptGtBytes, err := base64.StdEncoding.DecodeString(hibeMsgMap[matchedId])
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  	if encryptGtBytes == nil {
   153  		return nil, errors.New("no permission")
   154  	}
   155  	encryptGt, ok := encryptGt.Unmarshal(encryptGtBytes)
   156  	if !ok {
   157  		return nil, errors.New("encryptGt.Unmarshal failed, please check it")
   158  	}
   159  	// get GT
   160  	gt := hibe.Decrypt(matchedPrvKey, encryptGt)
   161  	// generate symmetric encryption (like AES, SM4) Key
   162  	// generate a random point from GT
   163  	gtBytes := gt.Marshal()
   164  	symKey, err := generateSymKeyFromGtBytes(gtBytes, symKeyType)
   165  	if err != nil {
   166  		return nil, err
   167  	}
   168  	// decrypt messageBytes
   169  	// encryptedMessage -> []byte
   170  	encryptedMessageBytes, err := base64.StdEncoding.DecodeString(hibeMsgMap[hibeMsgCipherTextKey])
   171  	if err != nil {
   172  		return nil, err
   173  	}
   174  	// use sym key to encrypt plaintext
   175  	message, err := symKey.Decrypt(encryptedMessageBytes)
   176  	if err != nil {
   177  		return nil, err
   178  	}
   179  	return message, nil
   180  }