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}