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