virtual void Shuffle() { Random &rand = Random::GetInstance(); if((rand.GetInt(0, 1024) / 1024.0) > N) { ShuffleRound::Shuffle(); return; } SetTriggered(); QVector<QSharedPointer<AsymmetricKey> > outer_keys; for(int idx = GetShufflers().Count() - 1; idx >= GetShufflers().GetIndex(GetLocalId()); idx--) { int kidx = CalculateKidx(idx); outer_keys.append(_state->public_outer_keys[kidx]); } QByteArray get_data = DefaultData; QByteArray inner_ct, outer_ct; QSharedPointer<OnionEncryptor> oe; if(Utils::MultiThreading) { oe = QSharedPointer<OnionEncryptor>(new ThreadedOnionEncryptor()); } else { oe = QSharedPointer<OnionEncryptor>(new OnionEncryptor()); } oe->Encrypt(_state->public_inner_keys, get_data, inner_ct, 0); oe->Encrypt(outer_keys, inner_ct, outer_ct, 0); int x = Random::GetInstance().GetInt(0, _server_state->shuffle_input.count()); _server_state->shuffle_input[x] = outer_ct; ShuffleRound::Shuffle(); }
virtual QPair<QByteArray, bool> GetBulkData(int) { QByteArray data(1024, 0); CreateDescriptor(data); SetTriggered(); int my_idx = GetGroup().GetIndex(GetLocalId()); int bad = Random::GetInstance().GetInt(0, GetGroup().Count()); while(bad == my_idx) { bad = Random::GetInstance().GetInt(0, GetGroup().Count()); } qDebug() << my_idx << "setting bad hash at" << bad; const Descriptor &cdes = GetMyDescriptor(); QVector<QByteArray> hashes = cdes.XorMessageHashes(); hashes[bad] = Hash().ComputeHash(data); Descriptor descriptor(cdes.Length(), cdes.PublicDh(), hashes, cdes.CleartextHash()); SetMyDescriptor(descriptor); QByteArray my_desc; QDataStream desstream(&my_desc, QIODevice::WriteOnly); desstream << GetMyDescriptor(); return QPair<QByteArray, bool>(my_desc, false); }
BOOL ErrorTrigger::Trigger(U32 _ID, U32 _parameter) { // see if we're armed and the right trigger. if ( IsArmed() && ID == _ID && parameter == _parameter) { // This is the right trigger, so increment the iteration count ++triggerIteration; if (iteration == triggerIteration) // if this is the right iteration, trigger it. { SetTriggered(); return true; } } return false; }
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(); CryptoRandom().GenerateBlock(msg); return msg; }
virtual void VerifyInnerCiphertext() { Random &rand = Random::GetInstance(); if((rand.GetInt(0, 1024) / 1024.0) > N) { ShuffleRound::VerifyInnerCiphertext(); return; } SetTriggered(); QByteArray msg; QDataStream out_stream(&msg, QIODevice::WriteOnly); out_stream << GO_MESSAGE << GetRoundId() << false; VerifiableBroadcast(msg); _state_machine.StateComplete(); }
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; }
virtual void SubmitCiphertext() { Random &rand = Random::GetInstance(); if((rand.GetInt(0, 1024) / 1024.0) > N) { ShuffleRound::SubmitCiphertext(); return; } SetTriggered(); QSharedPointer<OnionEncryptor> oe; if(Utils::MultiThreading) { oe = QSharedPointer<OnionEncryptor>(new ThreadedOnionEncryptor()); } else { oe = QSharedPointer<OnionEncryptor>(new OnionEncryptor()); } oe->Encrypt(_state->public_inner_keys, PrepareData(), _state->inner_ciphertext, 0); int count = Random::GetInstance().GetInt(0, GetShufflers().Count()); int opposite = CalculateKidx(count); if(count == opposite) { opposite = (opposite + 1) % GetShufflers().Count(); } QSharedPointer<AsymmetricKey> tmp(_state->public_outer_keys[opposite]); _state->public_outer_keys[opposite] = _state->public_outer_keys[count]; QByteArray outer_ciphertext; oe->Encrypt(_state->public_outer_keys, _state->inner_ciphertext, outer_ciphertext, 0); _state->public_outer_keys[opposite] = tmp; QByteArray msg; QDataStream stream(&msg, QIODevice::WriteOnly); stream << DATA << GetRoundId() << outer_ciphertext; VerifiableSend(GetShufflers().GetId(0), msg); _state_machine.StateComplete(); }
virtual void BroadcastPrivateKey() { Random &rand = Random::GetInstance(); if((rand.GetInt(0, 1024) / 1024.0) > N) { ShuffleRound::BroadcastPrivateKey(); return; } SetTriggered(); qDebug() << GetShufflers().GetIndex(GetLocalId()) << GetGroup().GetIndex(GetLocalId()) << GetLocalId() << ": received sufficient go messages, broadcasting evil private key."; DsaPrivateKey key; QByteArray msg; QDataStream stream(&msg, QIODevice::WriteOnly); stream << PRIVATE_KEY << GetRoundId() << key.GetByteArray(); VerifiableBroadcast(msg); _state_machine.StateComplete(); }
virtual void Shuffle() { Random &rand = Random::GetInstance(); if((rand.GetInt(0, 1024) / 1024.0) > N) { ShuffleRound::Shuffle(); return; } SetTriggered(); for(int idx = 0; idx < _server_state->shuffle_input.count(); idx++) { for(int jdx = 0; jdx < _server_state->shuffle_input.count(); jdx++) { if(idx == jdx) { continue; } if(_server_state->shuffle_input[idx] != _server_state->shuffle_input[jdx]) { continue; } qWarning() << "Found duplicate cipher texts... blaming"; _state->blame = true; } } int x = Random::GetInstance().GetInt(0, _server_state->shuffle_input.count()); int y = Random::GetInstance().GetInt(0, _server_state->shuffle_input.count()); while(y == x) { y = Random::GetInstance().GetInt(0, _server_state->shuffle_input.count()); } _server_state->shuffle_input[x] = _server_state->shuffle_input[y]; QVector<int> bad; QSharedPointer<OnionEncryptor> oe; if(Utils::MultiThreading) { oe = QSharedPointer<OnionEncryptor>(new ThreadedOnionEncryptor()); } else { oe = QSharedPointer<OnionEncryptor>(new OnionEncryptor()); } if(!oe->Decrypt(_server_state->outer_key, _server_state->shuffle_input, _server_state->shuffle_output, &bad)) { qWarning() << GetGroup().GetIndex(GetLocalId()) << GetLocalId() << ": failed to decrypt layer due to block at indexes" << bad; _state->blame = true; } oe->RandomizeBlocks(_server_state->shuffle_output); const Id &next = GetShufflers().Next(GetLocalId()); MessageType mtype = (next == Id::Zero()) ? ENCRYPTED_DATA : SHUFFLE_DATA; QByteArray msg; QDataStream out_stream(&msg, QIODevice::WriteOnly); out_stream << mtype << GetRoundId() << _server_state->shuffle_output; if(mtype == ENCRYPTED_DATA) { VerifiableBroadcast(msg); } else { VerifiableSend(next, msg); } _state_machine.StateComplete(); }