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