Exemple #1
0
  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();
      }