package model import ( "strconv" "testing" "time" ) func TestMessagePadding(t *testing.T) { // Setup the Group sarah := GenerateNewProfile("Sarah") alice := GenerateNewProfile("Alice") sarah.AddContact(alice.Onion, &alice.PublicProfile) alice.AddContact(sarah.Onion, &sarah.PublicProfile) gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") sarah.ProcessInvite(invite) group := alice.GetGroup(gid) c1, s1, err := sarah.EncryptMessageToGroup("Hello World 1", group.GroupID) t.Logf("Length of Encrypted Message: %v %v", len(c1), err) alice.AttemptDecryption(c1, s1) c2, s2, _ := alice.EncryptMessageToGroup("Hello World 2", group.GroupID) t.Logf("Length of Encrypted Message: %v", len(c2)) alice.AttemptDecryption(c2, s2) c3, s3, _ := alice.EncryptMessageToGroup("Hello World 3", group.GroupID) t.Logf("Length of Encrypted Message: %v", len(c3)) alice.AttemptDecryption(c3, s3) c4, s4, _ := alice.EncryptMessageToGroup("Hello World this is a much longer message 3", group.GroupID) t.Logf("Length of Encrypted Message: %v", len(c4)) alice.AttemptDecryption(c4, s4) } func TestTranscriptConsistency(t *testing.T) { timeline := new(Timeline) // Setup the Group sarah := GenerateNewProfile("Sarah") alice := GenerateNewProfile("Alice") sarah.AddContact(alice.Onion, &alice.PublicProfile) alice.AddContact(sarah.Onion, &sarah.PublicProfile) // The lightest weight server entry possible (usually we would import a key bundle...) sarah.AddContact("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd", &PublicProfile{Attributes: map[string]string{string(KeyTypeServerOnion): "2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd"}}) gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") sarah.ProcessInvite(invite) group := alice.GetGroup(gid) t.Logf("group: %v, sarah %v", group, sarah) c1, s1, _ := alice.EncryptMessageToGroup("Hello World 1", group.GroupID) t.Logf("Length of Encrypted Message: %v", len(c1)) alice.AttemptDecryption(c1, s1) c2, s2, _ := alice.EncryptMessageToGroup("Hello World 2", group.GroupID) t.Logf("Length of Encrypted Message: %v", len(c2)) alice.AttemptDecryption(c2, s2) c3, s3, _ := alice.EncryptMessageToGroup("Hello World 3", group.GroupID) t.Logf("Length of Encrypted Message: %v", len(c3)) alice.AttemptDecryption(c3, s3) time.Sleep(time.Second * 1) c4, s4, _ := alice.EncryptMessageToGroup("Hello World 4", group.GroupID) t.Logf("Length of Encrypted Message: %v", len(c4)) alice.AttemptDecryption(c4, s4) c5, s5, _ := alice.EncryptMessageToGroup("Hello World 5", group.GroupID) t.Logf("Length of Encrypted Message: %v", len(c5)) _, _, m1, _ := sarah.AttemptDecryption(c1, s1) sarah.AttemptDecryption(c1, s1) // Try a duplicate _, _, m2, _ := sarah.AttemptDecryption(c2, s2) _, _, m3, _ := sarah.AttemptDecryption(c3, s3) _, _, m4, _ := sarah.AttemptDecryption(c4, s4) _, _, m5, _ := sarah.AttemptDecryption(c5, s5) // Now we simulate a client receiving these Messages completely out of order timeline.Insert(m1) timeline.Insert(m5) timeline.Insert(m4) timeline.Insert(m3) timeline.Insert(m2) for i, m := range group.GetTimeline() { if m.Message != "Hello World "+strconv.Itoa(i+1) { t.Fatalf("Timeline Out of Order!: %v %v", i, m) } t.Logf("Messages %v: %v %x %x", i, m.Message, m.Signature, m.PreviousMessageSig) } // Test message by hash lookup... hash := timeline.calculateHash(*m5) t.Logf("Looking up %v ", hash) for key, msgs := range timeline.hashCache { t.Logf("%v %v", key, msgs) } // check a real message.. msgs, err := timeline.GetMessagesByHash(hash) if err != nil || len(msgs) != 1 { t.Fatalf("looking up message by hash %v should have not errored: %v", hash, err) } else if msgs[0].Message.Message != m5.Message { t.Fatalf("%v != %v", msgs[0].Message, m5.Message) } // Check a non existed hash... error if there is no error _, err = timeline.GetMessagesByHash("not a real hash") if err == nil { t.Fatalf("looking up message by hash %v should have errored: %v", hash, err) } }