github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/hybridencryption.go (about) 1 package privacy 2 3 import ( 4 "encoding/json" 5 "errors" 6 "github.com/incognitochain/go-incognito-sdk/common" 7 "github.com/incognitochain/go-incognito-sdk/common/base58" 8 ) 9 10 // hybridCipherText_Old represents to hybridCipherText_Old for Hybrid encryption 11 // Hybrid encryption uses AES scheme to encrypt message with arbitrary size 12 // and uses Elgamal encryption to encrypt AES key 13 type HybridCipherText struct { 14 msgEncrypted []byte 15 symKeyEncrypted []byte 16 } 17 18 func (ciphertext HybridCipherText) GetMsgEncrypted() []byte { 19 return ciphertext.msgEncrypted 20 } 21 22 func (ciphertext HybridCipherText) GetSymKeyEncrypted() []byte { 23 return ciphertext.symKeyEncrypted 24 } 25 26 // isNil check whether ciphertext is nil or not 27 func (ciphertext HybridCipherText) IsNil() bool { 28 if len(ciphertext.msgEncrypted) == 0 { 29 return true 30 } 31 32 return len(ciphertext.symKeyEncrypted) == 0 33 } 34 35 func (hybridCipherText HybridCipherText) MarshalJSON() ([]byte, error) { 36 data := hybridCipherText.Bytes() 37 temp := base58.Base58Check{}.Encode(data, common.ZeroByte) 38 return json.Marshal(temp) 39 } 40 41 func (hybridCipherText *HybridCipherText) UnmarshalJSON(data []byte) error { 42 dataStr := "" 43 _ = json.Unmarshal(data, &dataStr) 44 temp, _, err := base58.Base58Check{}.Decode(dataStr) 45 if err != nil { 46 return err 47 } 48 hybridCipherText.SetBytes(temp) 49 return nil 50 } 51 52 // Bytes converts ciphertext to bytes array 53 // if ciphertext is nil, return empty byte array 54 func (ciphertext HybridCipherText) Bytes() []byte { 55 if ciphertext.IsNil() { 56 return []byte{} 57 } 58 59 res := make([]byte, 0) 60 res = append(res, ciphertext.symKeyEncrypted...) 61 res = append(res, ciphertext.msgEncrypted...) 62 63 return res 64 } 65 66 // SetBytes reverts bytes array to hybridCipherText_Old 67 func (ciphertext *HybridCipherText) SetBytes(bytes []byte) error { 68 if len(bytes) == 0 { 69 return NewPrivacyErr(InvalidInputToSetBytesErr, nil) 70 } 71 72 if len(bytes) < elGamalCiphertextSize { 73 // out of range 74 return errors.New("out of range Parse ciphertext") 75 } 76 ciphertext.symKeyEncrypted = bytes[0:elGamalCiphertextSize] 77 ciphertext.msgEncrypted = bytes[elGamalCiphertextSize:] 78 return nil 79 } 80 81 // hybridEncrypt_Old encrypts message with any size, using Publickey to encrypt 82 // hybridEncrypt_Old generates AES key by randomize an elliptic point aesKeyPoint and get X-coordinate 83 // using AES key to encrypt message 84 // After that, using ElGamal encryption encrypt aesKeyPoint using publicKey 85 func HybridEncrypt(msg []byte, publicKey *Point) (ciphertext *HybridCipherText, err error) { 86 ciphertext = new(HybridCipherText) 87 88 // Generate a AES key bytes 89 sKeyPoint := RandomPoint() 90 sKeyByte := sKeyPoint.ToBytes() 91 // Encrypt msg using aesKeyByte 92 93 aesKey := sKeyByte[:] 94 aesScheme := &common.AES{ 95 Key: aesKey, 96 } 97 ciphertext.msgEncrypted, err = aesScheme.Encrypt(msg) 98 if err != nil { 99 return nil, err 100 } 101 102 // Using ElGamal cryptosystem for encrypting AES sym key 103 pubKey := new(elGamalPublicKey) 104 pubKey.h = publicKey 105 ciphertext.symKeyEncrypted = pubKey.encrypt(sKeyPoint).Bytes() 106 107 return ciphertext, nil 108 } 109 110 // hybridDecrypt_Old receives a ciphertext and privateKey 111 // it decrypts aesKeyPoint, using ElGamal encryption with privateKey 112 // Using X-coordinate of aesKeyPoint to decrypts message 113 func HybridDecrypt(ciphertext *HybridCipherText, privateKey *Scalar) (msg []byte, err error) { 114 // Validate ciphertext 115 if ciphertext.IsNil() { 116 return []byte{}, errors.New("ciphertext must not be nil") 117 } 118 119 // Get receiving key, which is a private key of ElGamal cryptosystem 120 privKey := new(elGamalPrivateKey) 121 privKey.set(privateKey) 122 123 // Parse encrypted AES key encoded as an elliptic point from EncryptedSymKey 124 encryptedAESKey := new(elGamalCipherText) 125 err = encryptedAESKey.SetBytes(ciphertext.symKeyEncrypted) 126 if err != nil { 127 return []byte{}, err 128 } 129 130 // Decrypt encryptedAESKey using recipient's receiving key 131 aesKeyPoint, err := privKey.decrypt(encryptedAESKey) 132 if err != nil { 133 return []byte{}, err 134 } 135 136 // Get AES key 137 aesKeyByte := aesKeyPoint.ToBytes() 138 aesKey := aesKeyByte[:] 139 aesScheme := &common.AES{ 140 Key: aesKey, 141 } 142 143 // Decrypt encrypted coin randomness using AES keysatt 144 msg, err = aesScheme.Decrypt(ciphertext.msgEncrypted) 145 if err != nil { 146 return []byte{}, err 147 } 148 return msg, nil 149 }