This commit is contained in:
didier amyot committed 2014-11-29 23:13:42 -08:00
1 parent f464823c87
commit 3625be471c
4 files changed
+322

No files matched your search

+159
View File
@@ -0,0 +1,159 @@
package elgamal
import (
"bytes"
"crypto/rand"
"math/big"
"reflect"
"testing"
"bitbucket.org/ustraca/crypto"
)
// This is the 1024-bit MODP group from RFC 5114, section 2.1:
const primeHex = "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D" +
"23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACC" +
"BDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC" +
"8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371"
const generatorHex = "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507FD6406CF" +
"F14266D31266FEA1E5C41564B777E690F5504F213160217B4B01B886A5E91547F9E2749F" +
"4D7FBD7D3B9A92EE1909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28AD662A4D" +
"18E73AFA32D779D5918D08BC8858F4DCEF97C2A24855E6EEB22B3B2E5"
func fromSafeHex(s string) *big.Int {
ret, err := crypto.FromHex(s)
if err != nil {
panic(err)
}
return ret
}
func TestEncryptDecrypt(t *testing.T) {
priv := &PrivateKey{
PublicKey: PublicKey{
G: fromSafeHex(generatorHex),
P: fromSafeHex(primeHex),
},
X: fromSafeHex("42"),
}
priv.Y = new(big.Int).Exp(priv.G, priv.X, priv.P)
message := []byte("hello world")
cypher, err := priv.PublicKey.Encrypt(message, rand.Reader)
if err != nil {
t.Errorf("error encrypting: %s", err)
}
message2 := priv.Decrypt(cypher)
if !bytes.Equal(message2, message) {
t.Errorf("decryption failed, got: '%x', want: '%x'", message2, message)
}
}
func TestEncryptDecryptWithSmallNumbers(t *testing.T) {
priv := &PrivateKey{
PublicKey: PublicKey{
G: big.NewInt(33),
P: big.NewInt(71),
},
X: big.NewInt(42),
}
priv.Y = new(big.Int).Exp(priv.G, priv.X, priv.P)
message := big.NewInt(15).Bytes()
cypher, err := priv.PublicKey.Encrypt(message, rand.Reader)
if err != nil {
t.Errorf("error encrypting: %s", err)
}
message2 := priv.Decrypt(cypher)
if !bytes.Equal(message2, message) {
t.Errorf("decryption failed, got: %x, want: %x", message2, message)
}
}
func TestHomomorphicProperties(t *testing.T) {
priv := PrivateKey{
PublicKey: PublicKey{
G: big.NewInt(33),
P: big.NewInt(71),
},
X: big.NewInt(42),
}
priv.Y = new(big.Int).Exp(priv.G, priv.X, priv.P)
message1 := big.NewInt(11).Bytes()
cypher1, _ := priv.PublicKey.Encrypt(message1, rand.Reader)
message2 := big.NewInt(12).Bytes()
cypher2, _ := priv.PublicKey.Encrypt(message2, rand.Reader)
decyphered := priv.Decrypt(new(Cypher).Mul(cypher1, cypher2))
expected := big.NewInt((12 * 11) % 71).Bytes()
if !bytes.Equal(expected, decyphered) {
t.Errorf("decryption failed, got: %x, want: %x", decyphered, expected)
}
}
func TestCypherToJSON(t *testing.T) {
cypher := &Cypher{
C1: big.NewInt(33),
C2: big.NewInt(99),
P: big.NewInt(192),
}
exp := make(map[string]string)
exp["C1"] = "21"
exp["C2"] = "63"
exp["P"] = "c0"
if !reflect.DeepEqual(exp, cypher.ToJSON()) {
t.Error(exp, "is not ", cypher.ToJSON())
}
}
func TestCypherFromJSON(t *testing.T) {
m := make(map[string]string)
m["C1"] = "21"
m["C2"] = "63"
m["P"] = "c0"
cypher, err := new(Cypher).FromJSON(m)
if err != nil {
t.Error(err)
}
if !reflect.DeepEqual(cypher.P, big.NewInt(192)) {
t.Error("P not okay")
}
if !reflect.DeepEqual(cypher.C1, big.NewInt(33)) {
t.Error("C1 not okay")
}
if !reflect.DeepEqual(cypher.C2, big.NewInt(99)) {
t.Error("C2 not okay")
}
}
func TestMarshalling(t *testing.T) {
cypher := &Cypher{
C1: big.NewInt(33),
C2: big.NewInt(99),
P: big.NewInt(192),
}
s, err := cypher.MarshalJSON()
if err != nil {
t.Fail()
}
cypher2 := new(Cypher)
err = cypher2.UnmarshalJSON(s)
if err != nil {
t.Error("could not unmarshal", err)
}
if !reflect.DeepEqual(cypher, cypher2) {
t.Error("the two objects do not match!")
}
}