Esempio n. 1
0
        /// <summary>
        /// Creates a new ballot for a voter.
        /// </summary>
        /// <param name="vota">Vota the voter wishes to cast for each option.</param>
        /// <param name="parameters">Cryptographic parameters.</param>
        /// <param name="publicKey">Public key of voting authorities.</param>
        /// <param name="progress">Report progress up.</param>
        public Ballot(IEnumerable<int> vota, BaseParameters parameters, Question questionParameters, BigInt publicKey, Progress progress)
        {
            if (progress == null)
            throw new ArgumentNullException("progress");
              if (vota == null)
            throw new ArgumentNullException("vota");
              if (parameters == null)
            throw new ArgumentNullException("parameters");
              if (publicKey == null)
            throw new ArgumentNullException("publicKey");
              if (vota.Count() != questionParameters.Options.Count())
            throw new ArgumentException("Bad vota.");
              if (!vota.All(votum => votum.InRange(0, 1)))
            throw new ArgumentException("Bad vota.");
              if (vota.Sum() != questionParameters.MaxVota)
            throw new ArgumentException("Bad vota.");

              Votes = new List<Vote>();
              BigInt nonceSum = new BigInt(0);
              Vote voteSum = null;

              List<Tuple<int, BigInt, BaseParameters, BigInt>> voteWorkList = new List<Tuple<int, BigInt, BaseParameters, BigInt>>();

              foreach (int votum in vota)
              {
            BigInt nonce = parameters.Random();
            nonceSum += nonce;
            voteWorkList.Add(new Tuple<int, BigInt, BaseParameters, BigInt>(votum, nonce, parameters, publicKey));
              }

              progress.Down(1d / (vota.Count() + 1) * vota.Count());
              List<Vote> voteList = Parallel
            .Work<Tuple<int, BigInt, BaseParameters, BigInt>, Vote>(CreateVote, voteWorkList, progress.Set);
              progress.Up();

              foreach (Vote vote in voteList)
              {
            voteSum = voteSum == null ? vote : voteSum + vote;
            Votes.Add(vote);
              }

              progress.Down(1d / (double)(vota.Count() + 1));
              SumProves = new List<Proof>();
              for (int proofIndex = 0; proofIndex < parameters.ProofCount; proofIndex++)
              {
            SumProves.Add(new Proof(nonceSum * 12, voteSum, publicKey, parameters));
            progress.Add(1d / (double)parameters.ProofCount);
              }
              progress.Up();
        }
Esempio n. 2
0
        /// <summary>
        /// Adds a vote to the vote sum.
        /// </summary>
        /// <remarks>
        /// Verfies the correctness of the vote first.
        /// </remarks>
        /// <param name="envelopeIndex">Index of the envelope.</param>
        /// <param name="signedEnvelope">Signed envelope from voter.</param>
        /// <param name="progress">Report the progress of the tallying.</param>
        public void Add(int envelopeIndex, Signed<Envelope> signedEnvelope, Progress progress)
        {
            if (signedEnvelope == null)
            throw new ArgumentNullException("signedEnvelope");
              if (voteSums == null)
            throw new InvalidOperationException("Must call TallyBegin first.");

              CryptoLog.Begin(CryptoLogLevel.Detailed, "Tallying envelope");
              CryptoLog.Add(CryptoLogLevel.Detailed, "Envelope index", envelopeIndex);
              CryptoLog.Add(CryptoLogLevel.Detailed, "Certificate id", signedEnvelope.Certificate.Id);
              CryptoLog.Add(CryptoLogLevel.Numeric, "Certificate fingerprint", signedEnvelope.Certificate.Fingerprint);
              CryptoLog.Add(CryptoLogLevel.Detailed, "Certificate type", signedEnvelope.Certificate.TypeText);

              if (signedEnvelope.Certificate is VoterCertificate)
              {
            CryptoLog.Add(CryptoLogLevel.Detailed, "Certificate group id", ((VoterCertificate)signedEnvelope.Certificate).GroupId);
              }

              bool acceptVote = true;
              Envelope envelope = signedEnvelope.Value;

              //Certificate is of voter and valid for that canton.
              acceptVote &= signedEnvelope.Certificate is VoterCertificate &&
                    ((VoterCertificate)signedEnvelope.Certificate).GroupId == this.parameters.GroupId;

              //Signature must be valid.
              acceptVote &= signedEnvelope.Verify(this.certificateStorage, envelope.Date);

              CryptoLog.Add(CryptoLogLevel.Detailed, "Certificate status", signedEnvelope.Certificate.Validate(this.certificateStorage, envelope.Date).Text());
              CryptoLog.Add(CryptoLogLevel.Detailed, "Envelope signature", signedEnvelope.Verify(this.certificateStorage, envelope.Date));

              //Voter's vote must not have been counted.
              acceptVote &= !this.countedVoters.Contains(signedEnvelope.Certificate.Id);

              CryptoLog.Add(CryptoLogLevel.Detailed, "Already voted", this.countedVoters.Contains(signedEnvelope.Certificate.Id));

              //Date must be in voting period.
              acceptVote &= envelope.Date.Date >= this.parameters.VotingBeginDate;
              acceptVote &= envelope.Date.Date <= this.parameters.VotingEndDate;

              CryptoLog.Add(CryptoLogLevel.Detailed, "Envelope date", envelope.Date);

              //Ballot must verify (prooves).
              for (int questionIndex = 0; questionIndex < this.parameters.Questions.Count(); questionIndex++)
              {
            Question question = this.parameters.Questions.ElementAt(questionIndex);
            Ballot ballot = envelope.Ballots.ElementAt(questionIndex);

            progress.Down(1d / (double)this.parameters.Questions.Count());
            acceptVote &= ballot.Verify(this.publicKey, this.parameters, question, this.rng, this.proofCheckCount, progress);

            progress.Up();
              }

              CryptoLog.Add(CryptoLogLevel.Detailed, "Envelope accepted", acceptVote);
              CryptoLog.EndWrite();

              lock (this.envelopeSequencerList)
              {
            this.envelopeSequencerList.Add(envelopeIndex, new Tuple<Signed<Envelope>,bool>(signedEnvelope, acceptVote));
              }

              AddInSequence();
        }