diff --git a/diffieHellman/dhkx.go b/diffieHellman/dhkx.go index e363f5df515e0b48af20b33782835143881e715d..dd79319aeb8144d53906dd0716b0f8bad9bbbf8b 100644 --- a/diffieHellman/dhkx.go +++ b/diffieHellman/dhkx.go @@ -12,6 +12,7 @@ import ( "fmt" "gitlab.com/elixxir/crypto/csprng" "gitlab.com/elixxir/crypto/cyclic" + "io" ) const DefaultPrivateKeyLengthBits = 256 @@ -22,7 +23,7 @@ const DefaultPrivateKeyLength = DefaultPrivateKeyLengthBits / 8 // group. It is recommended to use the "DefaultPrivateKeyLength" // for most use cases. // key size must be divisible by 8 -func GeneratePrivateKey(size int, group *cyclic.Group, source csprng.Source) *cyclic.Int { +func GeneratePrivateKey(size int, group *cyclic.Group, source io.Reader) *cyclic.Int { k1, err := csprng.GenerateInGroup(group.GetPBytes(), size, source) diff --git a/e2e/auth/ownership.go b/e2e/auth/ownership.go new file mode 100644 index 0000000000000000000000000000000000000000..d9b5c23fc9c5759f2c875d54bb3dc7637da98b23 --- /dev/null +++ b/e2e/auth/ownership.go @@ -0,0 +1,39 @@ +package auth + +import ( + "bytes" + jww "github.com/spf13/jwalterweatherman" + "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/elixxir/crypto/diffieHellman" + "gitlab.com/elixxir/crypto/hash" +) + +const ownershipVector = "ownershipVector" + +// Ownership proofs allow users to build short proofs they own public DH keys +func MakeOwnershipProof(myHistoricalPrivKey, partnerHistoricalPubKey *cyclic.Int, + grp *cyclic.Group) []byte { + + historicalBaseKey := diffieHellman.GenerateSessionKey(myHistoricalPrivKey, + partnerHistoricalPubKey, grp) + + h, err := hash.NewCMixHash() + if err != nil { + jww.FATAL.Panicf("Could not get hash: %+v", err) + } + + h.Write(historicalBaseKey.Bytes()) + h.Write([]byte(ownershipVector)) + + return h.Sum(nil) +} + +// verifies that an ownership proof is valid +func VerifyOwnershipProof(myHistoricalPrivKey, partnerHistoricalPubKey *cyclic.Int, + grp *cyclic.Group, proof []byte) bool { + + generatedProof := MakeOwnershipProof(myHistoricalPrivKey, + partnerHistoricalPubKey, grp) + + return bytes.Equal(generatedProof, proof) +} diff --git a/e2e/auth/ownership_test.go b/e2e/auth/ownership_test.go new file mode 100644 index 0000000000000000000000000000000000000000..c8db3d7026113bce4aa3dbfb5025705216d0b993 --- /dev/null +++ b/e2e/auth/ownership_test.go @@ -0,0 +1,93 @@ +package auth + +import ( + "encoding/base64" + "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/elixxir/crypto/diffieHellman" + "gitlab.com/elixxir/crypto/large" + "math/rand" + "testing" +) + +//Tests that the generated proofs do not change +func TestMakeOwnershipProof_Consistency(t *testing.T) { + + expected := []string{ + "wQ1qLb7GEpZ3EqJ8bvO9fLiRQWPg6zp885pc8mtTUik=", + "dAtL2QxNF+3UpFb3as7i+0FR4EpF77SJzhZYDgjzzKg=", + "N6eQTmXGD0XdJjj4mP/Gf+DJ64HurjBWXxyZ6fGxcWc=", + "4tPUddOr6ItHlqeZk7f56hXa+Fg5msd240Tcvs7cAYQ=", + "NT50KHtItDioL9xa5amz8RObnAOH2slKwcxFxsTk4AQ=", + } + + grp := getGrp() + prng := rand.New(rand.NewSource(42)) + + for i := 0; i < len(expected); i++ { + myPrivKey := diffieHellman.GeneratePrivateKey(512, grp, prng) + partnerPubKey := diffieHellman.GeneratePublicKey(diffieHellman.GeneratePrivateKey(512, grp, prng), grp) + proof := MakeOwnershipProof(myPrivKey, partnerPubKey, grp) + proof64 := base64.StdEncoding.EncodeToString(proof) + if expected[i] != proof64 { + t.Errorf("received and expected do not match at index %v\n"+ + "\treceived: %s\n\texpected: %s", i, proof64, expected[i]) + } + } +} + +//Tests that the generated proofs are verified +func TestMakeOwnershipProof_Verified(t *testing.T) { + + const numTests = 100 + + grp := getGrp() + prng := rand.New(rand.NewSource(69)) + + for i := 0; i < numTests; i++ { + myPrivKey := diffieHellman.GeneratePrivateKey(512, grp, prng) + partnerPubKey := diffieHellman.GeneratePublicKey(diffieHellman.GeneratePrivateKey(512, grp, prng), grp) + proof := MakeOwnershipProof(myPrivKey, partnerPubKey, grp) + + if !VerifyOwnershipProof(myPrivKey, partnerPubKey, grp, proof) { + t.Errorf("Proof could not be verified at index %v", i) + } + } +} + +//Tests that bad proofs are not verified +func TestVerifyOwnershipProof_Bad(t *testing.T) { + + const numTests = 100 + + grp := getGrp() + prng := rand.New(rand.NewSource(420)) + + for i := 0; i < numTests; i++ { + myPrivKey := diffieHellman.GeneratePrivateKey(512, grp, prng) + partnerPubKey := diffieHellman.GeneratePublicKey(diffieHellman.GeneratePrivateKey(512, grp, prng), grp) + proof := make([]byte, 32) + prng.Read(proof) + + if VerifyOwnershipProof(myPrivKey, partnerPubKey, grp, proof) { + t.Errorf("Proof was verified at index %v when it is bad", i) + } + + } +} + +func getGrp() *cyclic.Group { + primeString := "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + + "15728E5A8AACAA68FFFFFFFFFFFFFFFF" + p := large.NewIntFromString(primeString, 16) + g := large.NewInt(2) + return cyclic.NewGroup(p, g) +}