github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/elgamal.go (about) 1 package privacy 2 3 // elGamalPublicKeyOld represents to public key in ElGamal encryption 4 // H = G^X, X is private key 5 type elGamalPublicKey struct { 6 h *Point 7 } 8 9 // elGamalPrivateKeyOld represents to private key in ElGamal encryption 10 type elGamalPrivateKey struct { 11 x *Scalar 12 } 13 14 // elGamalCipherTextOld represents to ciphertext in ElGamal encryption 15 // in which C1 = G^k and C2 = H^k * message 16 // k is a random number (32 bytes), message is an elliptic point 17 type elGamalCipherText struct { 18 c1, c2 *Point 19 } 20 21 func (ciphertext *elGamalCipherText) set(c1, c2 *Point) { 22 ciphertext.c1 = c1 23 ciphertext.c2 = c2 24 } 25 26 func (pub *elGamalPublicKey) set(H *Point) { 27 pub.h = H 28 } 29 30 func (pub elGamalPublicKey) GetH() *Point { 31 return pub.h 32 } 33 34 func (priv *elGamalPrivateKey) set(x *Scalar) { 35 priv.x = x 36 } 37 38 func (priv elGamalPrivateKey) GetX() *Scalar { 39 return priv.x 40 } 41 42 // Bytes converts ciphertext to 66-byte array 43 func (ciphertext elGamalCipherText) Bytes() []byte { 44 if ciphertext.c1.IsIdentity() { 45 return []byte{} 46 } 47 b1 := ciphertext.c1.ToBytes() 48 b2 := ciphertext.c2.ToBytes() 49 res := append(b1[:], b2[:]...) 50 return res 51 } 52 53 // SetBytes reverts 66-byte array to ciphertext 54 func (ciphertext *elGamalCipherText) SetBytes(bytes []byte) error { 55 if len(bytes) == 0 { 56 return NewPrivacyErr(InvalidInputToSetBytesErr, nil) 57 } 58 59 if ciphertext == nil { 60 ciphertext = new(elGamalCipherText) 61 } 62 63 var err error 64 65 var tmp [Ed25519KeySize]byte 66 copy(tmp[:], bytes[:Ed25519KeySize]) 67 ciphertext.c1, err = new(Point).FromBytes(tmp) 68 if err != nil { 69 return err 70 } 71 copy(tmp[:], bytes[Ed25519KeySize:]) 72 ciphertext.c2, err = new(Point).FromBytes(tmp) 73 if err != nil { 74 return err 75 } 76 77 return nil 78 } 79 80 // encrypt encrypts plaintext (is an elliptic point) using public key ElGamal 81 // returns ElGamal ciphertext 82 func (pub elGamalPublicKey) encrypt(plaintext *Point) *elGamalCipherText { 83 // r random, S:= h^r where h = g^x 84 r := RandomScalar() 85 S := new(Point).ScalarMult(pub.h, r) 86 87 //return ciphertext (c1, c2) = (g^r, m.s=m.h^r) 88 ciphertext := new(elGamalCipherText) 89 ciphertext.c1 = new(Point).ScalarMultBase(r) 90 ciphertext.c2 = new(Point).Add(plaintext, S) 91 92 return ciphertext 93 } 94 95 // decrypt receives a ciphertext and 96 // decrypts it using private key ElGamal 97 // and returns plain text in elliptic point 98 func (priv elGamalPrivateKey) decrypt(ciphertext *elGamalCipherText) (*Point, error) { 99 S := new(Point).ScalarMult(ciphertext.c1, priv.x) 100 plaintext := new(Point).Sub(ciphertext.c2, S) 101 return plaintext, nil 102 }