You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 lines
1.6 KiB

package elgamal
import (
"math/big"
"github.com/arnaucube/cryptofun/ecc"
)
// EG is the ElGamal data structure
type EG struct {
EC ecc.EC
G ecc.Point
N *big.Int
}
// NewEG defines a new EG data structure
func NewEG(ec ecc.EC, g ecc.Point) (EG, error) {
var eg EG
var err error
eg.EC = ec
eg.G = g
eg.N, err = ec.Order(g)
return eg, err
}
// PubK returns the public key Point calculated from the private key over the elliptic curve
func (eg EG) PubK(privK *big.Int) (ecc.Point, error) {
// privK: rand < ec.Q
privKCopy := new(big.Int).SetBytes(privK.Bytes())
pubK, err := eg.EC.Mul(eg.G, privKCopy)
return pubK, err
}
// Encrypt encrypts a point m with the public key point, returns two points
func (eg EG) Encrypt(m ecc.Point, pubK ecc.Point, r *big.Int) ([2]ecc.Point, error) {
rCopy := new(big.Int).SetBytes(r.Bytes())
p1, err := eg.EC.Mul(eg.G, rCopy)
if err != nil {
return [2]ecc.Point{}, err
}
rCopy = new(big.Int).SetBytes(r.Bytes())
p2, err := eg.EC.Mul(pubK, rCopy)
if err != nil {
return [2]ecc.Point{}, err
}
p3, err := eg.EC.Add(m, p2)
if err != nil {
return [2]ecc.Point{}, err
}
c := [2]ecc.Point{p1, p3}
return c, err
}
// Decrypt decrypts c (two points) with the private key, returns the point decrypted
func (eg EG) Decrypt(c [2]ecc.Point, privK *big.Int) (ecc.Point, error) {
c1 := c[0]
c2 := c[1]
privKCopy := new(big.Int).SetBytes(privK.Bytes())
c1PrivK, err := eg.EC.Mul(c1, privKCopy)
if err != nil {
return ecc.Point{}, err
}
c1PrivKNeg := eg.EC.Neg(c1PrivK)
d, err := eg.EC.Add(c2, c1PrivKNeg)
return d, err
}