@ -0,0 +1,60 @@ |
|||||
|
package elgamal |
||||
|
|
||||
|
import ( |
||||
|
ecc "../ecc" |
||||
|
) |
||||
|
|
||||
|
// EG is the ElGamal data structure
|
||||
|
type EG struct { |
||||
|
EC ecc.EC |
||||
|
G ecc.Point |
||||
|
N 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 int) (ecc.Point, error) { |
||||
|
// privK: rand < ec.Q
|
||||
|
pubK, err := eg.EC.Mul(eg.G, privK) |
||||
|
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 int) ([2]ecc.Point, error) { |
||||
|
p1, err := eg.EC.Mul(eg.G, r) |
||||
|
if err != nil { |
||||
|
return [2]ecc.Point{}, err |
||||
|
} |
||||
|
p2, err := eg.EC.Mul(pubK, r) |
||||
|
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 int) (ecc.Point, error) { |
||||
|
c1 := c[0] |
||||
|
c2 := c[1] |
||||
|
c1PrivK, err := eg.EC.Mul(c1, privK) |
||||
|
if err != nil { |
||||
|
return ecc.Point{}, err |
||||
|
} |
||||
|
c1PrivKNeg := eg.EC.Neg(c1PrivK) |
||||
|
d, err := eg.EC.Add(c2, c1PrivKNeg) |
||||
|
return d, err |
||||
|
} |
@ -0,0 +1,77 @@ |
|||||
|
package elgamal |
||||
|
|
||||
|
import ( |
||||
|
"math/big" |
||||
|
"testing" |
||||
|
|
||||
|
ecc "../ecc" |
||||
|
) |
||||
|
|
||||
|
func TestNewEG(t *testing.T) { |
||||
|
ec := ecc.NewEC(1, 18, 19) |
||||
|
g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))} |
||||
|
eg, err := NewEG(ec, g) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
privK := 5 |
||||
|
pubK, err := eg.PubK(privK) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
if !pubK.Equal(ecc.Point{big.NewInt(int64(13)), big.NewInt(int64(9))}) { |
||||
|
t.Errorf("pubK!=(13, 9)") |
||||
|
} |
||||
|
} |
||||
|
func TestEGEncrypt(t *testing.T) { |
||||
|
ec := ecc.NewEC(1, 18, 19) |
||||
|
g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))} |
||||
|
eg, err := NewEG(ec, g) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
privK := 5 |
||||
|
pubK, err := eg.PubK(privK) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
// m: point to encrypt
|
||||
|
m := ecc.Point{big.NewInt(int64(11)), big.NewInt(int64(12))} |
||||
|
c, err := eg.Encrypt(m, pubK, 15) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
if !c[0].Equal(ecc.Point{big.NewInt(int64(8)), big.NewInt(int64(5))}) { |
||||
|
t.Errorf("c[0] != (8, 5), encryption failed") |
||||
|
} |
||||
|
if !c[1].Equal(ecc.Point{big.NewInt(int64(2)), big.NewInt(int64(16))}) { |
||||
|
t.Errorf("c[1] != (2, 16), encryption failed") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func TestEGDecrypt(t *testing.T) { |
||||
|
ec := ecc.NewEC(1, 18, 19) |
||||
|
g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))} |
||||
|
eg, err := NewEG(ec, g) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
privK := 5 |
||||
|
pubK, err := eg.PubK(privK) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
// m: point to encrypt
|
||||
|
m := ecc.Point{big.NewInt(int64(11)), big.NewInt(int64(12))} |
||||
|
c, err := eg.Encrypt(m, pubK, 15) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
d, err := eg.Decrypt(c, privK) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
if !m.Equal(d) { |
||||
|
t.Errorf("m != d, decrypting failed") |
||||
|
} |
||||
|
} |