diff --git a/cmix/key_test.go b/cmix/key_test.go index 348371d6c179c2de66841e601ad65443f4b65ffb..5698e877852d138371e6a3143d4082e20428237c 100644 --- a/cmix/key_test.go +++ b/cmix/key_test.go @@ -57,7 +57,7 @@ var expectStr = "2e4c99e14e0b1cd18c08467c395a4d5c0eb594507595041a5cfa83eb2f5791f // Test for functionality of NewDecryptionKey using pre-canned values func TestNewDecryptionKey(t *testing.T) { - k := NewDecryptionKey(salt, baseKey, &grp) + k := NewDecryptionKey(salt, baseKey, grp) expected := grp.NewIntFromString(expectStr, 16) if k == nil { @@ -73,7 +73,7 @@ func TestNewDecryptionKey(t *testing.T) { // Test for functionality of NewEncryptionKey using pre-canned values func TestNewEncryptionKey(t *testing.T) { - k := NewEncryptionKey(salt, baseKey, &grp) + k := NewEncryptionKey(salt, baseKey, grp) expected := grp.NewIntFromString(expectStr, 16) grp.Inverse(expected, expected) @@ -98,7 +98,7 @@ func makebaseKeys(size int) []*cyclic.Int { // Test that multiple baseKeys return a slice of same size with correct results func TestNewDecryptionKeys(t *testing.T) { - keys := NewDecryptionKeys(salt, makebaseKeys(10), &grp) + keys := NewDecryptionKeys(salt, makebaseKeys(10), grp) expected := grp.NewIntFromString(expectStr, 16) if len(keys) != 10 { t.Errorf("Bad length: expected 10, got %d", len(keys)) @@ -112,7 +112,7 @@ func TestNewDecryptionKeys(t *testing.T) { // Test that an empty base key returns an empty result func TestNewDecryptionKeysEmpty(t *testing.T) { - keys := NewDecryptionKeys(salt, nil, &grp) + keys := NewDecryptionKeys(salt, nil, grp) if len(keys) != 0 { t.Errorf("Bad length: expected 0, got %d", len(keys)) } @@ -120,7 +120,7 @@ func TestNewDecryptionKeysEmpty(t *testing.T) { // Test that multiple baseKeys return a slice of same size with correct results func TestNewEncryptionKeys(t *testing.T) { - keys := NewEncryptionKeys(salt, makebaseKeys(10), &grp) + keys := NewEncryptionKeys(salt, makebaseKeys(10), grp) expected := grp.NewIntFromString(expectStr, 16) grp.Inverse(expected, expected) if len(keys) != 10 { @@ -135,7 +135,7 @@ func TestNewEncryptionKeys(t *testing.T) { // Test that an empty base key returns an empty result func TestNewEncryptionKeysEmpty(t *testing.T) { - keys := NewEncryptionKeys(salt, nil, &grp) + keys := NewEncryptionKeys(salt, nil, grp) if len(keys) != 0 { t.Errorf("Bad length: expected 0, got %d", len(keys)) } diff --git a/cryptops/elgamal.go b/cryptops/elgamal.go new file mode 100644 index 0000000000000000000000000000000000000000..dafe860eec6fa825711ab7584cf3c83a7d105ec1 --- /dev/null +++ b/cryptops/elgamal.go @@ -0,0 +1,29 @@ +package cryptops + +import "gitlab.com/elixxir/crypto/cyclic" + +type ElGamalSignature func(g *cyclic.Group, ecrKeys, cypher, keyInv, privatekey, publicCypherKey *cyclic.Int) + +//Implements the modified version of ElGamal within the cryptops interface. +//Modifies ecrkeys and cypher to make its output. +//ecrkeys = ecrkeys*keyInv*(g^privatekey)%p +//cypher = cypher*(publicCypherKey^privatekey)%p +//More details can be found in the appendix of https://drive.google.com/open?id=1ha8QtUI9Tk_sCIKWN-QE8YHZ7AKofKrV +var ElGamal ElGamalSignature = func(g *cyclic.Group, ecrKeys, cypher, keyInv, privateKey, publicCypherKey *cyclic.Int) { + tmp := g.NewMaxInt() + + g.ExpG(privateKey, tmp) + g.Mul(keyInv, tmp, tmp) + g.Mul(tmp, ecrKeys, ecrKeys) + + g.Exp(publicCypherKey, privateKey, tmp) + g.Mul(tmp, cypher, cypher) +} + +func (ElGamalSignature) GetName() string { + return "ElGamal" +} + +func (ElGamalSignature) GetMinSize() uint32 { + return 1 +} diff --git a/cryptops/elgamal_test.go b/cryptops/elgamal_test.go new file mode 100644 index 0000000000000000000000000000000000000000..d3e73564c20376605ac8842d1178aa82dcbab1c0 --- /dev/null +++ b/cryptops/elgamal_test.go @@ -0,0 +1,93 @@ +package cryptops + +import ( + "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/elixxir/crypto/large" + "testing" +) + +//Tests that Elgamal conforms to the cryptops interface +func TestElGamal_CryptopsInterface(t *testing.T) { + + defer func(t *testing.T) { + if r := recover(); r != nil { + t.Errorf("ElGamal: Does not conform to cryptops interfece: %v", r) + } + }(t) + + var face interface{} + var cryptop Cryptop + face = ElGamal + cryptop = face.(Cryptop) + el := cryptop.(ElGamalSignature) + el.GetName() +} + +//testElGamalSignature_GetMinSize shows that Elgamal.MinSize returns the correct min size +func TestElGamalSignature_GetMinSize(t *testing.T) { + expected := 1 + if ElGamal.GetMinSize() != 1 { + t.Errorf("ElGamal: MinSize not correct: Recieved %v, Expected %v", ElGamal.GetMinSize(), expected) + } +} + +//TestElGamalSignature_GetName shows that Elgamal.GetName returns the correct name +func TestElGamalSignature_GetName(t *testing.T) { + expected := "ElGamal" + if ElGamal.GetName() != expected { + t.Errorf("ElGamal: Name not correct: Recieved %v, Expected %v", ElGamal.GetName(), expected) + } +} + +//Tests properties of Elgamal by undoing the encryption and showing the correct result is obtained +func TestElgamal_Single(t *testing.T) { + primeString := "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + + "15728E5A8AACAA68FFFFFFFFFFFFFFFF" + p := large.NewIntFromString(primeString, 16) + g := large.NewInt(2) + q := large.NewInt(1283) + grp := cyclic.NewGroup(p, g, q) + + tests := 10 + + for i := 0; i < tests; i++ { + cypherPrivateKey := grp.FindSmallCoprimeInverse(grp.NewInt(1), 256) + publicCypherKey := grp.ExpG(cypherPrivateKey, grp.NewInt(1)) + + ecrKeys := grp.NewInt(1) + cypher := grp.NewInt(1) + + keyInv := grp.Random(grp.NewInt(1)) + + privateKey := grp.FindSmallCoprimeInverse(grp.NewInt(1), 256) + + ElGamal(grp, ecrKeys, cypher, keyInv, privateKey, publicCypherKey) + + cypher = grp.RootCoprime(cypher, cypherPrivateKey, grp.NewInt(1)) + + pubkey := grp.ExpG(privateKey, grp.NewInt(1)) + if pubkey.Cmp(cypher) != 0 { + t.Errorf("Elgamal: Decrypted Cypher incorrect, got wrong public key, Expected %v, Recieved: %v", + pubkey.Text(16), cypher.Text(16)) + } + + cypherInv := grp.Inverse(cypher, grp.NewInt(1)) + keyInvActual := grp.Mul(ecrKeys, cypherInv, grp.NewInt(1)) + + if keyInvActual.Cmp(keyInv) != 0 { + t.Errorf("Elgamal: Key not decrypted properly, Expected %v, Recieved: %v", + keyInv.Text(16), keyInvActual.Text(16)) + } + + } + +} diff --git a/cyclic/group.go b/cyclic/group.go index 8a01702ccb545557803b8cc7aabf02e302885341..79b97e13c3de75b76837a5d788e4eddb43cd6da4 100644 --- a/cyclic/group.go +++ b/cyclic/group.go @@ -37,14 +37,14 @@ type Group struct { const GroupFingerprintSize = 8 // NewGroup returns a group with the given prime, generator and Q prime (for DSA) -func NewGroup(p, g, q *large.Int) Group { +func NewGroup(p, g, q *large.Int) *Group { h := sha256.New() h.Write(p.Bytes()) h.Write(g.Bytes()) h.Write(q.Bytes()) hashVal := h.Sum(nil)[:GroupFingerprintSize] value := large.NewIntFromBytes(hashVal) - return Group{ + return &Group{ prime: p, psub1: large.NewInt(1).Sub(p, large.NewInt(1)), psub2: large.NewInt(1).Sub(p, large.NewInt(2)), @@ -304,10 +304,9 @@ func (g *Group) GetPSub1FactorCyclic() *Int { func (g Group) MulMulti(c *Int, ints ...*Int) *Int { g.checkInts(append(ints, c)...) - c.value.SetString("1", 10) + c.value.SetInt64(1) for _, islc := range ints { - g.checkInts(islc) g.Mul(c, islc, c) } @@ -496,7 +495,7 @@ func (g *Group) GobDecode(b []byte) error { gen := large.NewIntFromBytes(s.G) primeQ := large.NewIntFromBytes(s.Q) - *g = NewGroup(prime, gen, primeQ) + *g = *NewGroup(prime, gen, primeQ) return nil } @@ -551,7 +550,7 @@ func (g *Group) UnmarshalJSON(b []byte) error { prime := large.NewIntFromString(jsonObj["prime"], base) gen := large.NewIntFromString(jsonObj["gen"], base) primeQ := large.NewIntFromString(jsonObj["primeQ"], base) - *g = NewGroup(prime, gen, primeQ) + *g = *NewGroup(prime, gen, primeQ) return nil } diff --git a/cyclic/group_test.go b/cyclic/group_test.go index b5950d8fdae740d2744af273dc7f7463f881b3e5..48ec1f869406d120baadd5f44c979186b07be464 100644 --- a/cyclic/group_test.go +++ b/cyclic/group_test.go @@ -646,7 +646,7 @@ func TestModP(t *testing.T) { g := large.NewInt(13) q := large.NewInt(3) - group := make([]Group, 0, len(p)) + group := make([]*Group, 0, len(p)) for i := 0; i < len(p); i++ { group = append(group, NewGroup(p[i], g, q)) } @@ -1553,7 +1553,7 @@ func TestGroup_GobEncode_GobDecode(t *testing.T) { grp2 := Group{} _ = grp2.GobDecode(b) - if !reflect.DeepEqual(grp1, grp2) { + if !reflect.DeepEqual(*grp1, grp2) { t.Errorf("GobDecode() did not produce the the same original undecoded data\n\treceived: %v\n\texpected: %v", grp1, grp2) } } @@ -1581,7 +1581,7 @@ func TestGroup_MarshalJSON_IsValid(t *testing.T) { t.Errorf("UnmarshalJSON() failed to serialize the group: %v", grp1) } - if !reflect.DeepEqual(grp1, grp2) { + if !reflect.DeepEqual(*grp1, grp2) { t.Errorf("UnmarshalJSON() did not produce the the same original undecoded data\n\treceived: %v\n\texpected: %v", grp1, grp2) } } diff --git a/diffieHellman/dhkx_test.go b/diffieHellman/dhkx_test.go index b9e560a046e9ea64b645997564cb302958bfa57b..cbce5287ce1357cce05e8fe8fb8d481b114f4b9b 100644 --- a/diffieHellman/dhkx_test.go +++ b/diffieHellman/dhkx_test.go @@ -36,15 +36,14 @@ func TestDHKX(t *testing.T) { g := large.NewInt(2) q := large.NewInt(3) grp := cyclic.NewGroup(p, g, q) - testGroup := &grp // Creation of two different DH Key Pairs with valid parameters - privKey, pubKey := CreateDHKeyPair(testGroup) - privKey2, pubKey2 := CreateDHKeyPair(testGroup) + privKey, pubKey := CreateDHKeyPair(grp) + privKey2, pubKey2 := CreateDHKeyPair(grp) //Creation of 2 DH Session Keys - sessionKey1, _ := CreateDHSessionKey(pubKey, privKey2, testGroup) - sessionKey2, _ := CreateDHSessionKey(pubKey2, privKey, testGroup) + sessionKey1, _ := CreateDHSessionKey(pubKey, privKey2, grp) + sessionKey2, _ := CreateDHSessionKey(pubKey2, privKey, grp) // Comparison of Two Session Keys (0 means they are equal) if sessionKey1.Cmp(sessionKey2) != 0 { @@ -72,10 +71,9 @@ func TestCreateDHKeyPair(t *testing.T) { g := large.NewInt(2) q := large.NewInt(3) grp := cyclic.NewGroup(p, g, q) - testGroup := &grp defer Catch("TestCreateDHKeyPair():", t) - CreateDHKeyPair(testGroup) + CreateDHKeyPair(grp) } func TestCheckPublicKey(t *testing.T) { @@ -99,10 +97,9 @@ func TestCheckPublicKey(t *testing.T) { g := large.NewInt(2) q := large.NewInt(3) grp := cyclic.NewGroup(p, g, q) - testGroup := &grp // Creation of a DH Key Pair with valid parameters - _, pubKey := CreateDHKeyPair(testGroup) + _, pubKey := CreateDHKeyPair(grp) // Random 2048 bit number that is not a quadratic residue randomNum := "27a0ed88dd37d9d9c041bd31500e239ac050b618502a64e7f703dba20390" + @@ -117,9 +114,9 @@ func TestCheckPublicKey(t *testing.T) { a, _ := hex.DecodeString(randomNum) x := grp.NewIntFromBytes(a) - rightSymbol := CheckPublicKey(testGroup, pubKey) - fakeSymbol := CheckPublicKey(testGroup, grp.NewInt(1)) - falseSymbol := CheckPublicKey(testGroup, x) + rightSymbol := CheckPublicKey(grp, pubKey) + fakeSymbol := CheckPublicKey(grp, grp.NewInt(1)) + falseSymbol := CheckPublicKey(grp, x) if rightSymbol { pass++ diff --git a/e2e/dummykeygen_test.go b/e2e/dummykeygen_test.go index b082adfc7a463c05c4b6464703b8c2085ca9215b..4d4f70380ab82ee16656778ed385c871a65dfce5 100644 --- a/e2e/dummykeygen_test.go +++ b/e2e/dummykeygen_test.go @@ -19,21 +19,21 @@ func TestDummyKeyGen_ValidNumKeys(t *testing.T) { userIds := []uint64{1, 2, 3, 4, 5, 6} users := generateUsers(userIds, t) - keys := KeyGen(currUser, users, &grp) + keys := KeyGen(currUser, users, grp) if len(keys) != len(users) { t.Errorf("Wrong number of keys generated") } userIds = []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} users = generateUsers(userIds, t) - keys = KeyGen(currUser, users, &grp) + keys = KeyGen(currUser, users, grp) if len(keys) != len(users) { t.Errorf("Wrong number of keys generated") } userIds = []uint64{8, 9, 10} users = generateUsers(userIds, t) - keys = KeyGen(currUser, users, &grp) + keys = KeyGen(currUser, users, grp) if len(keys) != len(users) { t.Errorf("Wrong number of keys generated") } @@ -48,12 +48,12 @@ func TestDummyKeyGen_KeysMatch(t *testing.T) { userIds := []uint64{1, 2, 3, 4, 5, 6} users := generateUsers(userIds, t) - keys1 := KeyGen(currUser, users, &grp) + keys1 := KeyGen(currUser, users, grp) userIds = []uint64{6, 5, 4, 3, 2, 1} users = generateUsers(userIds, t) - keys2 := KeyGen(currUser, users, &grp) + keys2 := KeyGen(currUser, users, grp) l := len(keys1) for i, v := range keys1 { @@ -71,9 +71,9 @@ func TestDummyKeyGen_CombinedHashCommutes(t *testing.T) { userB := generateUsers([]uint64{5}, t)[0] - res1 := combinedHash(userA, userB, &grp) + res1 := combinedHash(userA, userB, grp) - res2 := combinedHash(userB, userA, &grp) + res2 := combinedHash(userB, userA, grp) if res1.Cmp(res2) != 0 { t.Errorf("Combined hash order should not matter") diff --git a/e2e/encrypt.go b/e2e/encrypt.go index e4b04f40b95e58dcbe2a091ab328fb5102edcad5..a7f7420b1713c736f7eafd6c457e4c1bf68d1888 100644 --- a/e2e/encrypt.go +++ b/e2e/encrypt.go @@ -8,12 +8,12 @@ import ( ) // Calls encrypt() with crypto.rand.Reader. -func Encrypt(g cyclic.Group, key *cyclic.Int, msg []byte) ([]byte, error) { +func Encrypt(g *cyclic.Group, key *cyclic.Int, msg []byte) ([]byte, error) { return encrypt(g, key, msg, rand.Reader) } // Modular multiplies the key and padded message under the passed group. -func encrypt(g cyclic.Group, key *cyclic.Int, msg []byte, +func encrypt(g *cyclic.Group, key *cyclic.Int, msg []byte, rand io.Reader) ([]byte, error) { // Get the padded message encMsg, err := pad(msg, int(format.TOTAL_LEN), rand) @@ -32,7 +32,7 @@ func encrypt(g cyclic.Group, key *cyclic.Int, msg []byte, // Modular inverts the key under the passed group and modular multiplies it with // the encrypted message under the passed group. -func Decrypt(g cyclic.Group, key *cyclic.Int, encMsg []byte) ([]byte, error) { +func Decrypt(g *cyclic.Group, key *cyclic.Int, encMsg []byte) ([]byte, error) { // Modular invert the key under the group keyInv := g.Inverse(key, g.NewInt(1)) diff --git a/e2e/encrypt_test.go b/e2e/encrypt_test.go index d1aca71bb3873273376ca2f64ad441ccc49e08f7..e21ccc69bcc33e46200f2159cb0c3128fc03438c 100644 --- a/e2e/encrypt_test.go +++ b/e2e/encrypt_test.go @@ -11,7 +11,7 @@ import ( "testing" ) -var grp cyclic.Group +var grp *cyclic.Group // Build global group for tests to utilise func TestMain(m *testing.M) { diff --git a/e2e/keygen_test.go b/e2e/keygen_test.go index fab11130a8fcf388d8738a28d71ca05590cd2bc7..08152450a6a430065d7ceb531e5c014b14d50257 100644 --- a/e2e/keygen_test.go +++ b/e2e/keygen_test.go @@ -29,11 +29,10 @@ func TestKeygen(t *testing.T) { g := large.NewInt(2) q := large.NewInt(3) grp := cyclic.NewGroup(p, g, q) - testGroup := &grp salt := grp.NewInt(1) basekey := grp.NewInt(1) - key := Keygen(testGroup, salt, basekey) + key := Keygen(grp, salt, basekey) if key.Cmp(salt) != 0 { t.Errorf("Dummy keygen should return 1") diff --git a/e2e/keys_test.go b/e2e/keys_test.go index e3e2b66624a9cd4fd7c57f6679a3b3504e61958a..b795041fa351da053bfa670aba2bceacad0bca2d 100644 --- a/e2e/keys_test.go +++ b/e2e/keys_test.go @@ -38,7 +38,7 @@ func TestDeriveSingleKey(t *testing.T) { key := grp.NewIntFromString(TEST_DHKEY, 16) data := append([]byte{}, key.Bytes()...) data = append(data, userID.Bytes()...) - result := deriveSingleKey(sha256.New(), &grp, data, 0) + result := deriveSingleKey(sha256.New(), grp, data, 0) expected := grp.NewIntFromString(EXPECTED_KEY, 16) if result.Cmp(expected) != 0 { t.Errorf("Generated Key %v doesn't match expected %v", @@ -71,9 +71,9 @@ func TestDeriveKeys_DeriveEmergencyKeys(t *testing.T) { var genKeys = []*cyclic.Int{} for _, n := range nkeys { - for _, id := range ids { + for _, iditr := range ids { for _, f := range fut { - genKeys = f(&grp, key, id, n) + genKeys = f(grp, key, iditr, n) // Check array of keys and if the size matches with requested if genKeys == nil { @@ -112,7 +112,7 @@ func TestDeriveKeys_DeriveEmergencyKeys_Differ(t *testing.T) { var genKeys = make([][]*cyclic.Int, len(fut)) for i, f := range fut { - genKeys[i] = f(&grp, key, userID, nkeys) + genKeys[i] = f(grp, key, userID, nkeys) // Check array of keys and if the size matches with requested if genKeys[i] == nil { diff --git a/hash/keys_test.go b/hash/keys_test.go index d9d9a6d10c7ea126aaef2d317531ce11046f271b..a9b9b72149196d577d0ac3df57ead55ae661b0f0 100644 --- a/hash/keys_test.go +++ b/hash/keys_test.go @@ -39,9 +39,9 @@ func TestExpandKey(t *testing.T) { key := []byte("a906df88f30d6afbfa6165a50cc9e208d16b34e70b367068dc5d6bd6e155b2c3") b, _ := NewCMixHash() - x1 := ExpandKey(b, &grp, []byte("key")) + x1 := ExpandKey(b, grp, []byte("key")) b.Reset() - x2 := ExpandKey(b, &grp, key) + x2 := ExpandKey(b, grp, key) if len(x1) != 256 { t.Errorf("TestExpandKey(): Error with the resulting key size") @@ -56,9 +56,9 @@ func TestExpandKey(t *testing.T) { } h := sha512.New() - x1 = ExpandKey(h, &grp, []byte("key")) + x1 = ExpandKey(h, grp, []byte("key")) h.Reset() - x2 = ExpandKey(h, &grp, key) + x2 = ExpandKey(h, grp, key) if len(x1) != 256 { t.Errorf("TestExpandKey(): Error with the resulting key size") diff --git a/registration/keygen_test.go b/registration/keygen_test.go index 1a6eb20d9991002e4c16f91a65c24a3bcd4b637e..5f62400ea9d92e87f520cecd2d382ec338e798bc 100644 --- a/registration/keygen_test.go +++ b/registration/keygen_test.go @@ -15,7 +15,7 @@ import ( "testing" ) -var grp cyclic.Group +var grp *cyclic.Group // Test key generation by using the default DSA group // then creating 2 DSA key pairs, and calling the @@ -38,9 +38,9 @@ func TestGenerateBaseKey(t *testing.T) { // Generate transmission base keys using blake2b as the hash b, _ := hash.NewCMixHash() - ownBaseTKey := GenerateBaseKey(&grp, peerPubKey, ownPrivKey, b) + ownBaseTKey := GenerateBaseKey(grp, peerPubKey, ownPrivKey, b) b.Reset() - peerBaseTKey := GenerateBaseKey(&grp, ownPubKey, peerPrivKey, b) + peerBaseTKey := GenerateBaseKey(grp, ownPubKey, peerPrivKey, b) if ownBaseTKey.Cmp(peerBaseTKey) != 0 { t.Errorf("Generated Base Key using blake2b is different between own and peer") @@ -50,9 +50,9 @@ func TestGenerateBaseKey(t *testing.T) { // Generate reception base keys using sha256 as the hash h := sha256.New() - ownBaseRKey := GenerateBaseKey(&grp, peerPubKey, ownPrivKey, h) + ownBaseRKey := GenerateBaseKey(grp, peerPubKey, ownPrivKey, h) h.Reset() - peerBaseRKey := GenerateBaseKey(&grp, ownPubKey, peerPrivKey, h) + peerBaseRKey := GenerateBaseKey(grp, ownPubKey, peerPrivKey, h) if ownBaseRKey.Cmp(peerBaseRKey) != 0 { t.Errorf("Generated Base Key using sha256 is different between own and peer")