示例#1
0
  void RepeatingBulkRound::ProcessDataBase(const Id &from, const QByteArray &data)
  {
    QByteArray payload;
    if(!Verify(from, data, payload)) {
      throw QRunTimeError("Invalid signature or data");
    }

    if(_state == Offline) {
      throw QRunTimeError("Should never receive a message in the bulk"
          " round while offline.");
    }

    QDataStream stream(payload);

    int mtype;
    QByteArray round_id;
    uint phase;
    stream >> mtype >> round_id >> phase;

    MessageType msg_type = (MessageType) mtype;

    Id rid(round_id);
    if(rid != GetRoundId()) {
      throw QRunTimeError("Not this round: " + rid.ToString() + " " +
          GetRoundId().ToString());
    }

    if(_state == Shuffling) {
      _log.Pop();
      _offline_log.Append(data, from);
      return;
    }

    if(_phase != phase) {
      if(_phase == phase - 1 && _state == DataSharing) {
        _log.Pop();
        _offline_log.Append(data, from);
        return;
      } else {
        throw QRunTimeError("Received a message for phase: " + 
            QString::number(phase) + ", while in phase: " +
            QString::number(_phase));
      }
    } else if(_state == PhasePreparation) {
      _log.Pop();
      _offline_log.Append(data, from);
      return;
    }

    switch(msg_type) {
      case BulkData:
        HandleBulkData(stream, from);
        break;
      default:
        throw QRunTimeError("Unknown message type");
    }
  }
示例#2
0
  BaseBulkRound::BaseBulkRound(const Group &group,
      const PrivateIdentity &ident,
      const Id &round_id,
      const QSharedPointer<Network> &network,
      GetDataCallback &get_data,
      const QSharedPointer<BuddyMonitor> &bm,
      CreateRound create_shuffle) :
    Round(group, ident, round_id, network, get_data, bm),
    _get_shuffle_data(this, &BaseBulkRound::GetShuffleData)
  {
    QVariantHash headers = GetNetwork()->GetHeaders();
    headers["bulk"] = true;
    GetNetwork()->SetHeaders(headers);

    QSharedPointer<Network> net(GetNetwork()->Clone());
    headers["bulk"] = false;
    net->SetHeaders(headers);

    Id sr_id(Hash().ComputeHash(GetRoundId().GetByteArray()));

    _shuffle_round = create_shuffle(GetGroup(), GetPrivateIdentity(), sr_id, net,
        _get_shuffle_data, bm);
    _shuffle_round->SetSink(&_shuffle_sink);

    QObject::connect(_shuffle_round.data(), SIGNAL(Finished()),
        this, SLOT(SlotShuffleFinished()));
  }
示例#3
0
  void BulkRound::ProcessDataBase(const Id &from, const QByteArray &data)
  {
    QByteArray payload;
    if(!Verify(from, data, payload)) {
      throw QRunTimeError("Invalid signature or data");
    }

    if(_state == Offline) {
      throw QRunTimeError("Should never receive a message in the bulk"
          " round while offline.");
    }

    QDataStream stream(payload);

    int mtype;
    QByteArray round_id;
    stream >> mtype >> round_id;

    MessageType msg_type = (MessageType) mtype;

    Id rid(round_id);
    if(rid != GetRoundId()) {
      throw QRunTimeError("Not this round: " + rid.ToString() + " " +
          GetRoundId().ToString());
    }

    if(_state == Shuffling) {
      _log.Pop();
      _offline_log.Append(data, from);
      return;
    }

    switch(msg_type) {
      case BulkData:
        HandleBulkData(stream, from);
        break;
      case LoggedBulkData:
        HandleLoggedBulkData(stream, from);
        break;
      case AggregatedBulkData:
        HandleAggregatedBulkData(stream, from);
        break;
      default:
        throw QRunTimeError("Unknown message type");
    }
  }
示例#4
0
 void BulkRound::Finish()
 {
   if(_bad_message_hash.isEmpty()) {
     if(_app_broadcast && IsLeader()) {
       QByteArray msg;
       QDataStream stream(&msg, QIODevice::WriteOnly);
       stream << AggregatedBulkData << GetRoundId() << _cleartexts;
       VerifiableBroadcast(msg);
     }
     _state = Finished;
     SetSuccessful(true);
     Stop("Round successfully finished");
   } else {
     if(_app_broadcast && IsLeader()) {
       QByteArray msg;
       QDataStream stream(&msg, QIODevice::WriteOnly);
       stream << LoggedBulkData << GetRoundId() << _log.Serialize();
       VerifiableBroadcast(msg);
     }
     BeginBlame();
   }
 }
示例#5
0
 void RepeatingBulkRound::ProcessData(const Id &from, const QByteArray &data)
 {
   _log.Append(data, from);
   try {
     ProcessDataBase(from, data);
   } catch (QRunTimeError &err) {
     qWarning() << GetGroup().GetIndex(GetLocalId()) << GetLocalId().ToString() <<
       "received a message from" << GetGroup().GetIndex(from) << from.ToString() <<
       "in session / round" << GetRoundId().ToString() << "in state" <<
       StateToString(_state) << "causing the following exception: " << err.What();
     _log.Pop();
     return;
   }
 }
示例#6
0
      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();
      }
示例#7
0
  void BulkRound::HandleLoggedBulkData(QDataStream &stream, const Id &from)
  {
    if(from == GetLocalId()) {
      return;
    }

    qDebug() << GetGroup().GetIndex(GetLocalId()) << GetLocalId().ToString() <<
      ": received logged bulk data from " << GetGroup().GetIndex(from) <<
      from.ToString();

    if(GetGroup().GetLeader() != from) {
      throw QRunTimeError("Received logged bulk data from non-leader.");
    }

    if(_state != ReceivingLeaderData) {
      throw QRunTimeError("Not expected at this time.");
    }

    QByteArray binary_log;
    stream >> binary_log;
    Log log(binary_log);
    
    if(log.Count() != GetGroup().Count()) {
      throw QRunTimeError("Incorrect number of log messages.");
    }

    _state = ProcessingLeaderData;
    for(int idx = 0; idx < log.Count(); idx++) {
      const QPair<QByteArray, Id> &res = log.At(idx);
      try {
        ProcessDataBase(res.second, res.first);
      } catch (QRunTimeError &err) {
        const Id &from = res.second;
        qWarning() << GetGroup().GetIndex(GetLocalId()) << GetLocalId().ToString() <<
          "leader equivocated in message from" << GetGroup().GetIndex(from) <<
          from.ToString() << "in session / round" << GetRoundId().ToString() <<
          "in state" << StateToString(_state) <<
          "causing the following exception: " << err.What();
        // Should end round.
        break;
      }
    }
  }
示例#8
0
  void BulkRound::PrepareBlameShuffle()
  {
    QSharedPointer<Network> net(GetNetwork()->Clone());
    QVariantHash headers = net->GetHeaders();
    headers["bulk"] = false;
    net->SetHeaders(headers);

    Hash hashalgo;
    QByteArray roundid = GetRoundId().GetByteArray();
    roundid = hashalgo.ComputeHash(roundid);
    roundid = hashalgo.ComputeHash(roundid);
    Id sr_id(roundid);

    _shuffle_round = _create_shuffle(GetGroup(), GetPrivateIdentity(), sr_id, net,
        _get_blame_data);

    _shuffle_round->SetSink(&_shuffle_sink);

    QObject::connect(_shuffle_round.data(), SIGNAL(Finished()),
        this, SLOT(BlameShuffleFinished()));
  }
示例#9
0
      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();
      }
示例#10
0
      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();
      }
示例#11
0
  void BulkRound::GenerateXorMessages()
  {
    QByteArray msg;
    QDataStream stream(&msg, QIODevice::WriteOnly);
    stream << BulkData << GetRoundId();

    _expected_bulk_size = 0;
    for(int idx = 0; idx < _shuffle_sink.Count(); idx++) {
      QPair<QSharedPointer<ISender>, QByteArray> pair(_shuffle_sink.At(idx));
      Descriptor des = ParseDescriptor(pair.second);
      _descriptors.append(des);
      if(_my_idx == -1 && _my_descriptor == des) {
        _my_idx = idx;
      }
      stream << GenerateXorMessage(idx);
    }

    if(_app_broadcast) {
      VerifiableSend(GetGroup().GetLeader(), msg);
    } else {
      VerifiableBroadcast(msg);
    }
  }
示例#12
0
 /**
  * QString rep
  */
 inline virtual QString ToString() const { return "BulkRound: " + GetRoundId().ToString(); }
示例#13
0
 inline virtual QString ToString() const {
     return "ShuffleRound: " + GetRoundId().ToString();
 }
示例#14
0
      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();
      }
 /**
  * Returns the string representation of the round
  */
 inline virtual QString ToString() const
 {
   return "CSBulkRound: " + GetRoundId().ToString() +
     " Phase: " + QString::number(_state_machine.GetPhase());
 }
示例#16
0
 /**
  * QString rep
  */
 inline virtual QString ToString() const
 {
   return "RepeatingBulkRound: " + GetRoundId().ToString() +
     " Phase: " + QString::number(_phase);
 }
示例#17
0
 /**
  * Returns the string representation of the round
  */
 inline virtual QString ToString() const
 {
   QString param = _state ? _state->params->ToString() : "NULL";
   return "BlogDropRound/" + param + ": " + GetRoundId().ToString() +
     " Phase: " + QString::number(_state_machine.GetPhase());
 }