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 }