TEST_P(PairingGroupTest, EncodeAndPair) { QSharedPointer<PairingG1Group> group1(PairingG1Group::GetGroup((PairingGroup::GroupSize)GetParam())); QSharedPointer<PairingGTGroup> groupT(PairingGTGroup::GetGroup((PairingGroup::GroupSize)GetParam())); ASSERT_EQ(group1->GetByteArray(), groupT->GetByteArray()); Library *lib = CryptoFactory::GetInstance().GetLibrary(); QScopedPointer<Dissent::Utils::Random> rand(lib->GetRandomNumberGenerator()); QByteArray out; for(int i=0; i<100; i++) { QByteArray msg(rand->GetInt(1, groupT->BytesPerElement()), 0); rand->GenerateBlock(msg); Element a = group1->RandomElement(); Element b = group1->RandomElement(); Element m = groupT->EncodeBytes(msg); // compute c = m * e(a,b) * e(a, b^-1) Element t1 = groupT->ApplyPairing(a, b); Element t2 = groupT->ApplyPairing(a, group1->Inverse(b)); Element c = groupT->Multiply(groupT->Multiply(t1, t2), m); // check m == c EXPECT_EQ(m, c); EXPECT_TRUE(groupT->DecodeBytes(c, out)); EXPECT_EQ(msg, out); } }
void ShufflePrimitivesTest(OnionEncryptor &oe) { int count = Random::GetInstance().GetInt(10, 20); Library *lib = CryptoFactory::GetInstance().GetLibrary(); QVector<QSharedPointer<AsymmetricKey> > private_keys; QVector<QSharedPointer<AsymmetricKey> > public_keys; for(int idx = 0; idx < count; idx++) { private_keys.append(QSharedPointer<AsymmetricKey>(lib->CreatePrivateKey())); public_keys.append(QSharedPointer<AsymmetricKey>(private_keys.last()->GetPublicKey())); } QVector<QByteArray> cleartexts; QVector<QByteArray> ciphertexts; QVector<QVector<QByteArray> > random_bits; QScopedPointer<Random> rand(lib->GetRandomNumberGenerator()); for(int idx = 0; idx < count; idx++) { QByteArray cleartext(1500, 0); rand->GenerateBlock(cleartext); QByteArray ciphertext; QVector<QByteArray> random; EXPECT_EQ(oe.Encrypt(public_keys, cleartext, ciphertext, &random), -1); cleartexts.append(cleartext); ciphertexts.append(ciphertext); random_bits.append(random); } QVector<QVector<QByteArray> > order_random_bits; EXPECT_EQ(oe.ReorderRandomBits(random_bits, order_random_bits), -1); EXPECT_TRUE(oe.VerifyOne(private_keys.first(), cleartexts, order_random_bits.first())); for(int idx = 1; idx < count - 1; idx++) { EXPECT_TRUE(oe.VerifyOne(private_keys[idx], order_random_bits[idx - 1], order_random_bits[idx])); } EXPECT_TRUE(oe.VerifyOne(private_keys.last(), order_random_bits.last(), ciphertexts)); QVector<QVector<QByteArray> > onions(count + 1); onions.last() = ciphertexts; for(int idx = count - 1; idx >= 0; idx--) { EXPECT_TRUE(oe.Decrypt(private_keys[idx], onions[idx + 1], onions[idx], 0)); oe.RandomizeBlocks(onions[idx]); } QBitArray bad; EXPECT_TRUE(oe.VerifyAll(private_keys, onions, bad)); for(int idx = 0; idx < count; idx++) { EXPECT_TRUE(onions.first().contains(cleartexts[idx])); EXPECT_FALSE(bad[idx]); } }
virtual QByteArray GenerateXorMessage(int idx) { if(_bad == -1) { _bad = Random::GetInstance().GetInt(0, GetShuffleSink().Count()); } QByteArray msg = BulkRound::GenerateXorMessage(idx); if(GetDescriptors().size() != _bad + 1) { return msg; } SetTriggered(); Library *lib = CryptoFactory::GetInstance().GetLibrary(); QScopedPointer<Random> rng(lib->GetRandomNumberGenerator()); rng->GenerateBlock(msg); return msg; }
TEST(Base64, basic) { Library *lib = CryptoFactory::GetInstance().GetLibrary(); QSharedPointer<Random> rand(lib->GetRandomNumberGenerator()); QByteArray data(50, 0); for(int idx = 0; idx < 50; idx++) { rand->GenerateBlock(data); QByteArray base64 = ToUrlSafeBase64(data); QByteArray unbase64 = FromUrlSafeBase64(base64); ASSERT_EQ(data, unbase64); if(base64.contains('-') || base64.contains('_')) { continue; } QByteArray reg_base64 = data.toBase64(); ASSERT_EQ(base64, reg_base64); ASSERT_EQ(data, QByteArray::fromBase64(base64)); } }
void OnionEncryptorDecrypt(OnionEncryptor &oe) { int count = 100; Library *lib = CryptoFactory::GetInstance().GetLibrary(); QVector<QSharedPointer<AsymmetricKey> > private_keys; QVector<QSharedPointer<AsymmetricKey> > public_keys; for(int idx = 0; idx < count; idx++) { private_keys.append(QSharedPointer<AsymmetricKey>(lib->CreatePrivateKey())); public_keys.append(QSharedPointer<AsymmetricKey>(private_keys.last()->GetPublicKey())); } QVector<QByteArray> cleartexts; QVector<QByteArray> ciphertexts; QScopedPointer<Random> rand(lib->GetRandomNumberGenerator()); for(int idx = 0; idx < count; idx++) { QByteArray cleartext(1500, 0); rand->GenerateBlock(cleartext); QByteArray ciphertext; EXPECT_EQ(oe.Encrypt(public_keys, cleartext, ciphertext), -1); cleartexts.append(cleartext); ciphertexts.append(ciphertext); } QVector<QVector<QByteArray> > onions(count + 1); onions.last() = ciphertexts; QVector<QVector<QByteArray> > oonions(count + 1); oonions.last() = ciphertexts; for(int idx = count - 1; idx >= 0; idx--) { EXPECT_TRUE(oe.Decrypt(private_keys[idx], onions[idx + 1], onions[idx])); } for(int idx = 0; idx < count; idx++) { EXPECT_TRUE(onions.first().contains(cleartexts[idx])); } }
void PublicKeySwapTest(OnionEncryptor &oe) { int count = Random::GetInstance().GetInt(10, 20); int changed = Random::GetInstance().GetInt(0, count); Library *lib = CryptoFactory::GetInstance().GetLibrary(); QVector<QSharedPointer<AsymmetricKey> > private_keys; QVector<QSharedPointer<AsymmetricKey> > public_keys; for(int idx = 0; idx < count; idx++) { private_keys.append(QSharedPointer<AsymmetricKey>(lib->CreatePrivateKey())); public_keys.append(QSharedPointer<AsymmetricKey>(private_keys.last()->GetPublicKey())); } private_keys[changed] = QSharedPointer<AsymmetricKey>(lib->CreatePrivateKey()); QVector<QByteArray> cleartexts; QVector<QByteArray> ciphertexts; QScopedPointer<Random> rand(lib->GetRandomNumberGenerator()); for(int idx = 0; idx < count; idx++) { QByteArray cleartext(1500, 0); rand->GenerateBlock(cleartext); QByteArray ciphertext; EXPECT_EQ(oe.Encrypt(public_keys, cleartext, ciphertext, 0), -1); cleartexts.append(cleartext); ciphertexts.append(ciphertext); } QVector<QVector<QByteArray> > onions(count + 1); onions.last() = ciphertexts; for(int idx = count - 1; idx > changed; idx--) { EXPECT_TRUE(oe.Decrypt(private_keys[idx],onions[idx + 1], onions[idx], 0)); oe.RandomizeBlocks(onions[idx]); } EXPECT_FALSE(oe.Decrypt(private_keys[changed], onions[changed + 1], onions[changed], 0)); }
void SoMuchEvil(OnionEncryptor &oe) { int count = Random::GetInstance().GetInt(10, 20); int changed0 = Random::GetInstance().GetInt(0, count - 5); int changed1 = Random::GetInstance().GetInt(changed0 + 1, count + 1); int mchanged0 = Random::GetInstance().GetInt(0, count); int mchanged1 = Random::GetInstance().GetInt(0, count); Library *lib = CryptoFactory::GetInstance().GetLibrary(); QVector<QSharedPointer<AsymmetricKey> > private_keys; QVector<QSharedPointer<AsymmetricKey> > public_keys; for(int idx = 0; idx < count; idx++) { private_keys.append(QSharedPointer<AsymmetricKey>(lib->CreatePrivateKey())); public_keys.append(QSharedPointer<AsymmetricKey>(private_keys.last()->GetPublicKey())); } QVector<QByteArray> cleartexts; QVector<QByteArray> ciphertexts; QScopedPointer<Random> rand(lib->GetRandomNumberGenerator()); for(int idx = 0; idx < count; idx++) { QByteArray cleartext(1500, 0); rand->GenerateBlock(cleartext); QByteArray ciphertext; EXPECT_EQ(oe.Encrypt(public_keys, cleartext, ciphertext, 0), -1); cleartexts.append(cleartext); ciphertexts.append(ciphertext); } QVector<QVector<QByteArray> > onions(count + 1); onions.last() = ciphertexts; // Find first evil peer for(int idx = count - 1; idx >= changed1; idx--) { EXPECT_TRUE(oe.Decrypt(private_keys[idx], onions[idx + 1], onions[idx], 0)); oe.RandomizeBlocks(onions[idx]); } QVector<QSharedPointer<AsymmetricKey> > swap_keys(public_keys); swap_keys.resize(changed1); QByteArray cleartext(1500, 0); rand->GenerateBlock(cleartext); EXPECT_EQ(oe.Encrypt(swap_keys, cleartext, onions[changed1][mchanged1], 0), -1); // Find second evil peer for(int idx = changed1 - 1; idx >= changed0; idx--) { EXPECT_TRUE(oe.Decrypt(private_keys[idx], onions[idx + 1], onions[idx], 0)); oe.RandomizeBlocks(onions[idx]); } swap_keys.resize(changed0); rand->GenerateBlock(cleartext); EXPECT_EQ(oe.Encrypt(swap_keys, cleartext, onions[changed0][mchanged0], 0), -1); for(int idx = changed0 - 1; idx >= 0; idx--) { EXPECT_TRUE(oe.Decrypt(private_keys[idx], onions[idx + 1], onions[idx], 0)); oe.RandomizeBlocks(onions[idx]); } QBitArray bad; EXPECT_FALSE(oe.VerifyAll(private_keys, onions, bad)); int good_count = 0; int bad_count = 0; for(int idx = 0; idx < count; idx++) { if(idx == changed0 || idx == changed1) { EXPECT_TRUE(bad[idx]); } else { EXPECT_FALSE(bad[idx]); } onions.first().contains(cleartexts[idx]) ? good_count++ : bad_count++; } EXPECT_TRUE(good_count >= count - 2); EXPECT_TRUE(good_count < count); EXPECT_TRUE(bad_count > 0); EXPECT_TRUE(bad_count <= 2); }
void RoundTest_PeerDisconnectMiddle(CreateSessionCallback callback, CreateGroupGenerator cgg) { Timer::GetInstance().UseVirtualTime(); int count = Random::GetInstance().GetInt(TEST_RANGE_MIN, TEST_RANGE_MAX); int leader = Random::GetInstance().GetInt(0, count); int sender = Random::GetInstance().GetInt(0, count); int disconnecter = Random::GetInstance().GetInt(0, count); QVector<TestNode *> nodes; Group *group; ConstructOverlay(count, nodes, group); for(int idx = 0; idx < count; idx++) { for(int jdx = 0; jdx < count; jdx++) { if(idx == jdx) { continue; } EXPECT_TRUE(nodes[idx]->cm.GetConnectionTable().GetConnection(nodes[jdx]->cm.GetId())); } } for(int idx = 0; idx < count; idx++) { EXPECT_TRUE(nodes[idx]->sink.Count() == 0); } Id leader_id = nodes[leader]->cm.GetId(); Id session_id; CreateSessions(nodes, *group, leader_id, session_id, callback, cgg); Library *lib = CryptoFactory::GetInstance().GetLibrary(); QScopedPointer<Dissent::Utils::Random> rand(lib->GetRandomNumberGenerator()); QByteArray msg(512, 0); rand->GenerateBlock(msg); nodes[sender]->session->Send(msg); for(int idx = 0; idx < count; idx++) { nodes[idx]->session->Start(); } TestNode::calledback = 0; qint64 next = Timer::GetInstance().VirtualRun(); // XXX This needs to be improved, but what we are doing is issuing a // disconnect approximately 1 to count steps into the Round qint64 run_before_disc = Time::GetInstance().MSecsSinceEpoch() + Random::GetInstance().GetInt(10, 10 * count); while(next != -1 && TestNode::calledback < count && Time::GetInstance().MSecsSinceEpoch() < run_before_disc) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } if(Time::GetInstance().MSecsSinceEpoch() >= run_before_disc) { nodes[disconnecter]->cm.Disconnect(); } while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } if(Time::GetInstance().MSecsSinceEpoch() < run_before_disc) { std::cout << "RoundTest_PeerDisconnectMiddle never caused a disconnect, " "consider rerunning." << std::endl; for(int idx = 0; idx < count; idx++) { EXPECT_EQ(msg, nodes[idx]->sink.Last().first); } } else { foreach(TestNode *node, nodes) { EXPECT_TRUE(node->session->Stopped()); } }
void RoundTest_PeerDisconnectEnd(CreateSessionCallback callback, CreateGroupGenerator cgg) { Timer::GetInstance().UseVirtualTime(); int count = Random::GetInstance().GetInt(TEST_RANGE_MIN, TEST_RANGE_MAX); int leader = Random::GetInstance().GetInt(0, count); int disconnecter = Random::GetInstance().GetInt(0, count); while(leader != disconnecter) { disconnecter = Random::GetInstance().GetInt(0, count); } QVector<TestNode *> nodes; Group *group; ConstructOverlay(count, nodes, group); Id leader_id = nodes[leader]->cm.GetId(); Id session_id; CreateSessions(nodes, *group, leader_id, session_id, callback, cgg); for(int idx = 0; idx < count; idx++) { nodes[idx]->session->Start(); } TestNode::calledback = 0; qint64 next = Timer::GetInstance().VirtualRun(); while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } nodes[disconnecter]->session->Stop(); nodes[disconnecter]->cm.Disconnect(); EXPECT_TRUE(nodes[disconnecter]->session->Stopped()); TestNode::calledback = 0; next = Timer::GetInstance().VirtualRun(); while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } Library *lib = CryptoFactory::GetInstance().GetLibrary(); QScopedPointer<Dissent::Utils::Random> rand(lib->GetRandomNumberGenerator()); QByteArray msg(512, 0); rand->GenerateBlock(msg); nodes[(leader + disconnecter) % count]->session->Send(msg); TestNode::calledback = 0; next = Timer::GetInstance().VirtualRun(); while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } for(int idx = 0; idx < count; idx++) { EXPECT_TRUE(nodes[idx]->sink.Count() == 0); EXPECT_TRUE(nodes[idx]->session->Stopped()); } delete nodes[disconnecter]; nodes.remove(disconnecter); CleanUp(nodes); delete group; }
void RoundTest_MultiRound(CreateSessionCallback callback, CreateGroupGenerator cgg) { Timer::GetInstance().UseVirtualTime(); int count = Random::GetInstance().GetInt(TEST_RANGE_MIN, TEST_RANGE_MAX); int leader = Random::GetInstance().GetInt(0, count); int sender0 = Random::GetInstance().GetInt(0, count); int sender1 = Random::GetInstance().GetInt(0, count); while(sender0 != sender1) { sender1 = Random::GetInstance().GetInt(0, count); } QVector<TestNode *> nodes; Group *group; ConstructOverlay(count, nodes, group); Id leader_id = nodes[leader]->cm.GetId(); Id session_id; CreateSessions(nodes, *group, leader_id, session_id, callback, cgg); Library *lib = CryptoFactory::GetInstance().GetLibrary(); QScopedPointer<Dissent::Utils::Random> rand(lib->GetRandomNumberGenerator()); QByteArray msg(512, 0); rand->GenerateBlock(msg); nodes[sender0]->session->Send(msg); SignalCounter sc; for(int idx = 0; idx < count; idx++) { QObject::connect(&nodes[idx]->sink, SIGNAL(DataReceived()), &sc, SLOT(Counter())); nodes[idx]->session->Start(); } TestNode::calledback = 0; qint64 next = Timer::GetInstance().VirtualRun(); while(next != -1 && sc.GetCount() < count && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } sc.Reset(); for(int idx = 0; idx < count; idx++) { EXPECT_EQ(msg, nodes[idx]->sink.Last().first); } rand->GenerateBlock(msg); nodes[sender1]->session->Send(msg); TestNode::calledback = 0; next = Timer::GetInstance().VirtualRun(); while(next != -1 && sc.GetCount() < count && TestNode::calledback < count * 2) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } for(int idx = 0; idx < count; idx++) { EXPECT_EQ(msg, nodes[idx]->sink.Last().first); } CleanUp(nodes); delete group; }