arnaucube
arnaucube/cryptofunPublic Self-hosted repository
cryptofun/ElGamal/elGamal.go
ElGamal/elGamal.goRaw
 1package elgamal
 2
 3import (
 4	ecc "../ecc"
 5)
 6
 7// EG is the ElGamal data structure
 8type EG struct {
 9	EC ecc.EC
10	G  ecc.Point
11	N  int
12}
13
14// NewEG defines a new EG data structure
15func NewEG(ec ecc.EC, g ecc.Point) (EG, error) {
16	var eg EG
17	var err error
18	eg.EC = ec
19	eg.G = g
20	eg.N, err = ec.Order(g)
21	return eg, err
22}
23
24// PubK returns the public key Point calculated from the private key over the elliptic curve
25func (eg EG) PubK(privK int) (ecc.Point, error) {
26	// privK: rand < ec.Q
27	pubK, err := eg.EC.Mul(eg.G, privK)
28	return pubK, err
29}
30
31// Encrypt encrypts a point m with the public key point, returns two points
32func (eg EG) Encrypt(m ecc.Point, pubK ecc.Point, r int) ([2]ecc.Point, error) {
33	p1, err := eg.EC.Mul(eg.G, r)
34	if err != nil {
35		return [2]ecc.Point{}, err
36	}
37	p2, err := eg.EC.Mul(pubK, r)
38	if err != nil {
39		return [2]ecc.Point{}, err
40	}
41	p3, err := eg.EC.Add(m, p2)
42	if err != nil {
43		return [2]ecc.Point{}, err
44	}
45	c := [2]ecc.Point{p1, p3}
46	return c, err
47}
48
49// Decrypt decrypts c (two points) with the private key, returns the point decrypted
50func (eg EG) Decrypt(c [2]ecc.Point, privK int) (ecc.Point, error) {
51	c1 := c[0]
52	c2 := c[1]
53	c1PrivK, err := eg.EC.Mul(c1, privK)
54	if err != nil {
55		return ecc.Point{}, err
56	}
57	c1PrivKNeg := eg.EC.Neg(c1PrivK)
58	d, err := eg.EC.Add(c2, c1PrivKNeg)
59	return d, err
60}