void ShuffleBlamer::CheckShuffle() { for(int gidx = 0; gidx < _group.Count(); gidx++) { if(_rounds[gidx]->GetState() == ShuffleRound::BLAME_SHARE) { continue; } Set(gidx, "Wrong state"); } // If any failures ... let's not try to deal with the logic at this point... if(_set) { return; } _inner_data = _rounds[_group.GetIndex(_shufflers.GetId(0))]->GetShuffleCipherText(); QSharedPointer<Crypto::OnionEncryptor> oe; if(Utils::MultiThreading) { oe = QSharedPointer<Crypto::OnionEncryptor>(new Crypto::ThreadedOnionEncryptor()); } else { oe = QSharedPointer<Crypto::OnionEncryptor>(new Crypto::OnionEncryptor()); } for(int idx = 0; idx < _private_keys.count(); idx++) { QVector<QByteArray> outdata; QVector<int> bad; oe->Decrypt(_private_keys[idx], _inner_data, outdata, &bad); _inner_data = outdata; if(bad.count() == 0) { continue; } foreach(int bidx, bad) { Set(bidx, "Invalid crypto data"); } }
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(); }