Exemplo n.º 1
0
        /// <summary>
        /// Creates a new sum proof.
        /// </summary>
        /// <param name="r">The randomness used to encrypt the vote.</param>
        /// <param name="voteSum">The sum of all votes for which to generate a proof.</param>
        /// <param name="publicKey">The public key with which the vote was encrypted.</param>
        /// <param name="parameters">Cryptographic Parameters.</param>
        public Proof(BigInt r, Vote voteSum, BigInt publicKey, BaseParameters parameters)
        {
            if (r == null)
            throw new ArgumentNullException("r");
              if (voteSum == null)
            throw new ArgumentNullException("vote");
              if (publicKey == null)
            throw new ArgumentNullException("publicKey");
              if (parameters == null)
            throw new ArgumentNullException("parameters");

              BigInt r0 = parameters.Random();

              T0 = publicKey.PowerMod(r0, parameters.P);

              MemoryStream serializeStream = new MemoryStream();
              SerializeContext serializer = new SerializeContext(serializeStream);
              serializer.Write(voteSum.Ciphertext);
              serializer.Write(voteSum.HalfKey);
              serializer.Write(publicKey);
              serializer.Write(T0);
              serializer.Close();
              serializeStream.Close();

              SHA512Managed sha512 = new SHA512Managed();
              byte[] hash = sha512.ComputeHash(serializeStream.ToArray());
              C0 = hash[0] | (hash[1] << 8);

              S0 = r0 + r * C0;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates a new encrypted vote.
        /// </summary>
        /// <remarks>
        /// Includes zero-knowledge proof of vote being 0 or 1.
        /// Still need non-interactive zero-knowledge proof of sum of votes.
        /// </remarks>
        /// <param name="votum">Actual vote.</param>
        /// <param name="parameters">Cryptographic parameters.</param>
        /// <param name="publicKey">Public key of the authorities.</param>
        /// <param name="progress">Report the progress up.</param>
        public Vote(int votum, BigInt nonce, BaseParameters parameters, BigInt publicKey, Progress progress)
        {
            if (!votum.InRange(0, 1))
            throw new ArgumentException("Bad votum.");
              if (nonce == null)
            throw new ArgumentNullException("nonce");
              if (parameters == null)
            throw new ArgumentNullException("parameters");
              if (publicKey == null)
            throw new ArgumentNullException("publicKey");

              P = parameters.P;
              HalfKey = parameters.G.PowerMod(nonce, P);

              //The 12 magic number is inserted to avoid division remainders when
              //dividing partial deciphers for linear combinations by 2, 3 and 4.
              Ciphertext = (publicKey.PowerMod(nonce * 12, P) * parameters.F.PowerMod(votum, P)).Mod(P);

              RangeProves = new List<RangeProof>();
              for (int proofIndex = 0; proofIndex < parameters.ProofCount; proofIndex++)
              {
            RangeProves.Add(new RangeProof(votum, nonce * 12, this, publicKey, parameters));
            progress.Add(1d / (double)parameters.ProofCount);
              }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a new sum proof.
        /// </summary>
        /// <param name="r">The randomness used to encrypt the vote.</param>
        /// <param name="voteSum">The sum of all votes for which to generate a proof.</param>
        /// <param name="publicKey">The public key with which the vote was encrypted.</param>
        /// <param name="parameters">Cryptographic Parameters.</param>
        /// /// <param name="fakeType">What fake to create?</param>
        public Proof(BigInt r, Vote voteSum, BigInt publicKey, BaseParameters parameters, FakeType fakeType)
        {
            if (r == null)
            throw new ArgumentNullException("r");
              if (voteSum == null)
            throw new ArgumentNullException("vote");
              if (publicKey == null)
            throw new ArgumentNullException("publicKey");
              if (parameters == null)
            throw new ArgumentNullException("parameters");

              BigInt r0 = parameters.Random();
              MemoryStream serializeStream = new MemoryStream();
              SerializeContext serializer = new SerializeContext(serializeStream);
              SHA512Managed sha512 = new SHA512Managed();

              switch (fakeType)
              {
            case FakeType.BadFiatShamir:

              T0 = publicKey.PowerMod(r0, parameters.P);

              serializer.Write(voteSum.Ciphertext);
              serializer.Write(voteSum.HalfKey);
              serializer.Write(publicKey);
              serializer.Write(T0);
              serializer.Close();
              serializeStream.Close();

              byte[] hash0 = sha512.ComputeHash(serializeStream.ToArray());
              C0 = 0;

              S0 = r0 + r * C0;

              break;

            case FakeType.BadPowerMod:

              T0 = publicKey.PowerMod(0, parameters.P);

              serializer.Write(voteSum.Ciphertext);
              serializer.Write(voteSum.HalfKey);
              serializer.Write(publicKey);
              serializer.Write(T0);
              serializer.Close();
              serializeStream.Close();

              byte[] hash1 = sha512.ComputeHash(serializeStream.ToArray());
              C0 = hash1[0] | (hash1[1] << 8);

              S0 = 1;

              break;

            default:
              throw new NotSupportedException("Cannot generate that type of fake.");
              }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Create a new authority.
        /// </summary>
        /// <param name="index">Index of new authority. Must be at least one.</param>
        /// <param name="parameters">Cryptographic parameters.</param>
        public Authority(int index, BaseParameters parameters)
        {
            if (parameters == null)
            throw new ArgumentNullException("parameters");
              if (!index.InRange(1, parameters.AuthorityCount))
            throw new ArgumentException("Index must be in range 1..AuthorityCount.");

              Index = index;
              this.parameters = parameters;
        }
Exemplo n.º 5
0
        public Authority(DeserializeContext context, BaseParameters parameters)
        {
            Index = context.ReadInt32();
              this.polynomial = context.ReadObject<Polynomial>();

              if (!context.ReadBoolean())
              {
            this.secretKeyPart = context.ReadBigInt();
              }

              this.parameters = parameters;
        }
Exemplo n.º 6
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();
        }
Exemplo n.º 7
0
        /// <summary>
        /// Verifies the correctness of the ballot.
        /// </summary>
        /// <remarks>
        /// Verifies all proof for sum and range of votes.
        /// </remarks>
        /// <param name="publicKey">Public key of the authorities.</param>
        /// <param name="parameters">Cryptographic parameters.</param>
        /// <param name="questionParameters">Parameters of the question.</param>
        /// <param name="rng">Random number generator.</param>
        /// <param name="proofCheckCount">Number of proofs to check.</param>
        /// <param name="progress">Reports on the progress.</param>
        /// <returns>Result of the verification.</returns>
        public bool Verify(BigInt publicKey, BaseParameters parameters, Question questionParameters, RandomNumberGenerator rng, int proofCheckCount, Progress progress)
        {
            if (publicKey == null)
            throw new ArgumentNullException("publicKey");
              if (parameters == null)
            throw new ArgumentNullException("parameters");
              if (questionParameters == null)
            throw new ArgumentNullException("questionParameters");

              bool verifies = true;
              Vote voteSum = null;

              CryptoLog.Begin(CryptoLogLevel.Detailed, "Verifying ballot");
              CryptoLog.Add(CryptoLogLevel.Detailed, "Question", questionParameters.Text.Text);

              foreach (Vote vote in Votes)
              {
            verifies &= vote.Verify(publicKey, parameters, rng, proofCheckCount);
            voteSum = voteSum == null ? vote : voteSum + vote;
            progress.Add(1d / (double)Votes.Count);
              }

              verifies &= SumProves.Count == parameters.ProofCount;
              verifies &= SumProves
            .SelectRandom(rng, proofCheckCount)
            .All(sumProof => sumProof.Verify(voteSum, publicKey, parameters, questionParameters));

              CryptoLog.Add(CryptoLogLevel.Numeric, "Public key", publicKey);
              CryptoLog.Add(CryptoLogLevel.Numeric, "Vote sum ciphertext", voteSum.Ciphertext);
              CryptoLog.Add(CryptoLogLevel.Numeric, "Vote sum halfkey", voteSum.HalfKey);
              CryptoLog.Add(CryptoLogLevel.Detailed, "Verified", verifies);
              CryptoLog.End(CryptoLogLevel.Detailed);

              return verifies;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Verify this share of the secret.
        /// </summary>
        /// <param name="authorityIndex">Index of the verifying authority.</param>
        /// <param name="parameters">Cryptographic parameters.</param>
        /// <param name="polynomial">Polynomial to verify against.</param>
        /// <param name="verificationValues">Verification values. Also known as A(i)(j).</param>
        /// <returns>Was share accepted?</returns>
        public bool Verify(int authorityIndex, BaseParameters parameters, List<VerificationValue> verificationValues)
        {
            if (verificationValues == null)
            throw new ArgumentNullException("verificationValues");
              if (verificationValues
            .Any(verificationValueList => verificationValueList == null))
            throw new ArgumentException("No verification value can be null.");
              if (verificationValues.Count != parameters.Thereshold + 1)
            throw new ArgumentException("Bad verificaton value count.");

              if (DestinationAuthorityIndex != authorityIndex)
            return false;

              BigInt GtoS = parameters.G.PowerMod(Value, parameters.P);
              BigInt aProduct = new BigInt(1);
              for (int k = 0; k <= parameters.Thereshold; k++)
              {
            VerificationValue verificationValue = verificationValues[k];
            if (verificationValue.SourceAuthorityIndex != SourceAuthorityIndex)
              return false;

            aProduct *= verificationValue.Value.PowerMod(new BigInt(authorityIndex).PowerMod(new BigInt(k), parameters.P), parameters.P);
            aProduct = aProduct.Mod(parameters.P);
              }

              return GtoS == aProduct;
        }
Exemplo n.º 9
0
        /// <summary>
        /// Verifies a sum proof.
        /// </summary>
        /// <param name="voteSum">The vote sum for which to verify the proof.</param>
        /// <param name="publicKey">Public key against which to verify the proof.</param>
        /// <param name="parameters">Cryptographic Parameters.</param>
        /// <returns>Wether the proof is valid.</returns>
        public bool Verify(Vote voteSum, BigInt publicKey, BaseParameters parameters, Question questionParameters)
        {
            if (voteSum == null)
            throw new ArgumentNullException("vote");
              if (publicKey == null)
            throw new ArgumentNullException("publicKey");
              if (parameters == null)
            throw new ArgumentNullException("parameters");

              CryptoLog.Begin(CryptoLogLevel.Detailed, "Verifying sum proof");
              CryptoLog.Add(CryptoLogLevel.Numeric, "C", C0);
              CryptoLog.Add(CryptoLogLevel.Numeric, "T", T0);

              if (!C0.InRange(0, 0xffff))
              {
            CryptoLog.Add(CryptoLogLevel.Detailed, "Verified", false);
            CryptoLog.End(CryptoLogLevel.Detailed);
            return false;
              }

              MemoryStream serializeStream = new MemoryStream();
              SerializeContext serializer = new SerializeContext(serializeStream);
              serializer.Write(voteSum.Ciphertext);
              serializer.Write(voteSum.HalfKey);
              serializer.Write(publicKey);
              serializer.Write(T0);
              serializer.Close();
              serializeStream.Close();

              SHA512Managed sha512 = new SHA512Managed();
              byte[] hash = sha512.ComputeHash(serializeStream.ToArray());

              CryptoLog.Add(CryptoLogLevel.Numeric, "SHA 512", hash);

              if (C0 != (hash[0] | (hash[1] << 8)))
              {
            CryptoLog.Add(CryptoLogLevel.Detailed, "Verified", false);
            CryptoLog.End(CryptoLogLevel.Detailed);
            return false;
              }

              if (publicKey.PowerMod(S0, parameters.P) !=
            (T0 * voteSum.Ciphertext.DivideMod(parameters.F.PowerMod(questionParameters.MaxVota, parameters.P), parameters.P).PowerMod(C0, parameters.P)).Mod(parameters.P))
              {
            CryptoLog.Add(CryptoLogLevel.Detailed, "Verified", false);
            CryptoLog.End(CryptoLogLevel.Detailed);
            return false;
              }

              CryptoLog.Add(CryptoLogLevel.Detailed, "Verified", true);
              CryptoLog.End(CryptoLogLevel.Detailed);
              return true;
        }
Exemplo n.º 10
0
        /// <summary>
        /// Creates a new range proof.
        /// </summary>
        /// <param name="votum">The votum. Must be 0 or 1.</param>
        /// <param name="r">The randomness used to encrypt the vote.</param>
        /// <param name="vote">The vote for which to generate a proof.</param>
        /// <param name="publicKey">The public key with which the vote was encrypted.</param>
        /// <param name="parameters">Cryptographic Parameters.</param>
        public RangeProof(int votum, BigInt r, Vote vote, BigInt publicKey, BaseParameters parameters)
        {
            if (r == null)
            throw new ArgumentNullException("r");
              if (vote == null)
            throw new ArgumentNullException("vote");
              if (publicKey == null)
            throw new ArgumentNullException("publicKey");
              if (parameters == null)
            throw new ArgumentNullException("parameters");

              BigInt r0 = parameters.Random();
              BigInt r1 = parameters.Random();

              switch (votum)
              {
            case 0:
              //Create the fake proof.
              C1 = (int)Prime.RandomNumber(16);
              S1 = parameters.Random();
              T1 = (vote.Ciphertext.DivideMod(parameters.F.PowerMod(1, parameters.P), parameters.P).PowerMod(C1, parameters.P).InvertMod(parameters.P) * publicKey.PowerMod(S1, parameters.P)).Mod(parameters.P);

              //First part of the real proof
              T0 = publicKey.PowerMod(r0, parameters.P);
              break;
            case 1:
              //Create the fake proof.
              C0 = (int)Prime.RandomNumber(16);
              S0 = parameters.Random();
              T0 = (vote.Ciphertext.DivideMod(parameters.F.PowerMod(0, parameters.P), parameters.P).PowerMod(C0, parameters.P).InvertMod(parameters.P) * publicKey.PowerMod(S0, parameters.P)).Mod(parameters.P);

              //First part of the real proof
              T1 = publicKey.PowerMod(r1, parameters.P);
              break;
            default:
              throw new ArgumentException("Bad votum.");
              }

              //Put togeather the data to be hashed.
              MemoryStream serializeStream = new MemoryStream();
              SerializeContext serializer = new SerializeContext(serializeStream);
              serializer.Write(vote.Ciphertext);
              serializer.Write(vote.HalfKey);
              serializer.Write(publicKey);
              serializer.Write(T0);
              serializer.Write(T1);
              serializer.Close();
              serializeStream.Close();

              //Hash the proof data.
              SHA512Managed sha512 = new SHA512Managed();
              byte[] hash = sha512.ComputeHash(serializeStream.ToArray());
              //Take the first 16 bits.
              C = hash[0] | (hash[1] << 8);

              switch (votum)
              {
            case 0:
              //Second part of the real proof
              C0 = (int)((BigInt)(C - C1)).Mod(0xffff);
              S0 = r0 + r * C0;
              break;
            case 1:
              //Second part of the real proof
              C1 = (int)((BigInt)(C - C0)).Mod(0xffff);
              S1 = r1 + r * C1;
              break;
            default:
              throw new ArgumentException("Bad votum.");
              }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Verifies a range proof.
        /// </summary>
        /// <param name="vote">The vote for which to verify the proof.</param>
        /// <param name="publicKey">Public key against which to verify the proof.</param>
        /// <param name="parameters">Cryptographic Parameters.</param>
        /// <returns>Wether the proof is valid.</returns>
        public bool Verify(Vote vote, BigInt publicKey, BaseParameters parameters)
        {
            if (vote == null)
            throw new ArgumentNullException("vote");
              if (publicKey == null)
            throw new ArgumentNullException("publicKey");
              if (parameters == null)
            throw new ArgumentNullException("parameters");

              CryptoLog.Begin(CryptoLogLevel.Detailed, "Verifying range proof");
              CryptoLog.Add(CryptoLogLevel.Numeric, "C", C);
              CryptoLog.Add(CryptoLogLevel.Numeric, "C0", C0);
              CryptoLog.Add(CryptoLogLevel.Numeric, "C1", C1);
              CryptoLog.Add(CryptoLogLevel.Numeric, "T0", T0);
              CryptoLog.Add(CryptoLogLevel.Numeric, "T1", T1);

              if (!C.InRange(0, 0xffff))
              {
            CryptoLog.Add(CryptoLogLevel.Detailed, "Verified", false);
            CryptoLog.End(CryptoLogLevel.Detailed);
            return false;
              }

              MemoryStream serializeStream = new MemoryStream();
              SerializeContext serializer = new SerializeContext(serializeStream);
              serializer.Write(vote.Ciphertext);
              serializer.Write(vote.HalfKey);
              serializer.Write(publicKey);
              serializer.Write(T0);
              serializer.Write(T1);
              serializer.Close();
              serializeStream.Close();

              SHA512Managed sha512 = new SHA512Managed();
              byte[] hash = sha512.ComputeHash(serializeStream.ToArray());
              CryptoLog.Add(CryptoLogLevel.Numeric, "SHA512", hash);

              if (C != (hash[0] | (hash[1] << 8)))
              {
            CryptoLog.Add(CryptoLogLevel.Detailed, "Verified", false);
            CryptoLog.End(CryptoLogLevel.Detailed);
            return false;
              }

              if (((C0 + C1) % 0xffff) != C &&
              !(C0 == 3 && (-C0 + C1) % 0xffff == C) &&
              !(C1 == 3 && (C0 - C1) % 0xffff == C))
              {
            CryptoLog.Add(CryptoLogLevel.Detailed, "Verified", false);
            CryptoLog.End(CryptoLogLevel.Detailed);
            return false;
              }

              if (publicKey.PowerMod(S0, parameters.P) !=
            (T0 * vote.Ciphertext.DivideMod(parameters.F.PowerMod(0, parameters.P), parameters.P).PowerMod(C0, parameters.P)).Mod(parameters.P))
              {
            CryptoLog.Add(CryptoLogLevel.Detailed, "Verified", false);
            CryptoLog.End(CryptoLogLevel.Detailed);
            return false;
              }

              if (publicKey.PowerMod(S1, parameters.P) !=
            (T1 * vote.Ciphertext.DivideMod(parameters.F.PowerMod(1, parameters.P), parameters.P).PowerMod(C1, parameters.P)).Mod(parameters.P))
              {
            CryptoLog.Add(CryptoLogLevel.Detailed, "Verified", false);
            CryptoLog.End(CryptoLogLevel.Detailed);
            return false;
              }

              CryptoLog.Add(CryptoLogLevel.Detailed, "Verified", true);
              CryptoLog.End(CryptoLogLevel.Detailed);
              return true;
        }
Exemplo n.º 12
0
        /// <summary>
        /// Creates a new invalid range proof.
        /// </summary>
        /// <remarks>
        /// Used to test proofing mechanism.
        /// </remarks>
        /// <param name="votum">The votum. Must NOT be 0 or 1.</param>
        /// <param name="r">The randomness used to encrypt the vote.</param>
        /// <param name="vote">The vote for which to generate a proof.</param>
        /// <param name="publicKey">The public key with which the vote was encrypted.</param>
        /// <param name="parameters">Cryptographic Parameters.</param>
        /// <param name="fakeType">What is to be wrong?</param>
        public RangeProof(int votum, BigInt r, Vote vote, BigInt publicKey, BaseParameters parameters, FakeType fakeType)
        {
            if (r == null)
            throw new ArgumentNullException("r");
              if (vote == null)
            throw new ArgumentNullException("vote");
              if (publicKey == null)
            throw new ArgumentNullException("publicKey");
              if (parameters == null)
            throw new ArgumentNullException("parameters");

              BigInt r0 = parameters.Random();
              BigInt r1 = parameters.Random();
              MemoryStream serializeStream = new MemoryStream();
              SerializeContext serializer = new SerializeContext(serializeStream);
              SHA512Managed sha512 = new SHA512Managed();

              switch (fakeType)
              {
            case FakeType.BadDisjunction:
              //The C value will not be correct as it is not considered.

              //Create the fake proof.
              C0 = (int)Prime.RandomNumber(16);
              S0 = parameters.Random();
              T0 = (vote.Ciphertext.DivideMod(parameters.F.PowerMod(0, parameters.P), parameters.P).PowerMod(C0, parameters.P).InvertMod(parameters.P) * publicKey.PowerMod(S0, parameters.P)).Mod(parameters.P);

              //Create the fake proof.
              C1 = (int)Prime.RandomNumber(16);
              S1 = parameters.Random();
              T1 = (vote.Ciphertext.DivideMod(parameters.F.PowerMod(1, parameters.P), parameters.P).PowerMod(C1, parameters.P).InvertMod(parameters.P) * publicKey.PowerMod(S1, parameters.P)).Mod(parameters.P);

              //Put togeather the data to be hashed.
              serializer.Write(vote.Ciphertext);
              serializer.Write(vote.HalfKey);
              serializer.Write(publicKey);
              serializer.Write(T0);
              serializer.Write(T1);
              serializer.Close();
              serializeStream.Close();

              //Hash the proof data.
              byte[] hash0 = sha512.ComputeHash(serializeStream.ToArray());
              //Take the first 16 bits.
              C = hash0[0] | (hash0[1] << 8);

              break;

            case FakeType.BadFiatShamir:
              //The C value will not correspond to the hash.

              //Create the fake proof.
              C0 = (int)Prime.RandomNumber(16);
              S0 = parameters.Random();
              T0 = (vote.Ciphertext.DivideMod(parameters.F.PowerMod(0, parameters.P), parameters.P).PowerMod(C0, parameters.P).InvertMod(parameters.P) * publicKey.PowerMod(S0, parameters.P)).Mod(parameters.P);

              //Create the fake proof.
              C1 = (int)Prime.RandomNumber(16);
              S1 = parameters.Random();
              T1 = (vote.Ciphertext.DivideMod(parameters.F.PowerMod(1, parameters.P), parameters.P).PowerMod(C1, parameters.P).InvertMod(parameters.P) * publicKey.PowerMod(S1, parameters.P)).Mod(parameters.P);

              //Put togeather the data to be hashed.
              serializer.Write(vote.Ciphertext);
              serializer.Write(vote.HalfKey);
              serializer.Write(publicKey);
              serializer.Write(T0);
              serializer.Write(T1);
              serializer.Close();
              serializeStream.Close();

              //Hash the proof data.
              byte[] hash1 = sha512.ComputeHash(serializeStream.ToArray());
              //Take the first 16 bits.
              C = C0 + C1;

              break;

            case FakeType.BadPowerMod:

              //Create the fake proof.
              C1 = (int)Prime.RandomNumber(16);
              S1 = parameters.Random();
              T1 = (vote.Ciphertext.DivideMod(parameters.F.PowerMod(1, parameters.P), parameters.P).PowerMod(C1, parameters.P).InvertMod(parameters.P) * publicKey.PowerMod(S1, parameters.P)).Mod(parameters.P);

              //First part of the real proof
              T0 = publicKey.PowerMod(r0, parameters.P);

              //Put togeather the data to be hashed.
              serializer.Write(vote.Ciphertext);
              serializer.Write(vote.HalfKey);
              serializer.Write(publicKey);
              serializer.Write(T0);
              serializer.Write(T1);
              serializer.Close();
              serializeStream.Close();

              //Hash the proof data.
              byte[] hash2 = sha512.ComputeHash(serializeStream.ToArray());
              //Take the first 16 bits.
              C = hash2[0] | (hash2[1] << 8);

              //Second part of the real proof
              C0 = (int)((BigInt)(C - C1)).Mod(0xffff);
              S0 = r0 + r * C0;

              break;

            default:
              throw new NotSupportedException("Cannot fake in that way.");
              }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Crypto base test.
        /// </summary>
        /// <remarks>
        /// Only used during development.
        /// </remarks>
        public void BaseTest()
        {
            BigInt prime = Prime.Find(80);
              BigInt safePrime = Prime.FindSafe(88);

              BaseParameters parameters = new BaseParameters();
              parameters.GenerateNumbers(Files.TestDataPath);

              Question question = new Question(new MultiLanguageString(string.Empty), new MultiLanguageString(string.Empty), new MultiLanguageString(string.Empty), 1);
              question.AddOption(new Option(new MultiLanguageString("Ja"), new MultiLanguageString(string.Empty), new MultiLanguageString(string.Empty)));
              question.AddOption(new Option(new MultiLanguageString("Nein"), new MultiLanguageString(string.Empty), new MultiLanguageString(string.Empty)));
              parameters.AddQuestion(question);

              Authority[] auths = new Authority[5];

              for (int aI = 0; aI < parameters.AuthorityCount; aI++)
              {
            auths[aI] = new Authority(aI + 1, parameters);
              }

              foreach (Authority a in auths)
              {
            a.CreatePolynomial();
              }

              foreach (Authority a in auths)
              {
            List<Share> shares = new List<Share>();
            List<List<VerificationValue>> As = new List<List<VerificationValue>>();

            foreach (Authority b in auths)
            {
              shares.Add(b.Share(a.Index));
              As.Add(new List<VerificationValue>());

              for (int l = 0; l <= parameters.Thereshold; l++)
              {
            As[As.Count - 1].Add(b.VerificationValue(l));
              }
            }

            a.VerifySharing(shares, As);
              }

              BigInt publicKey = new BigInt(1);
              foreach (Authority a in auths)
              {
            publicKey = (publicKey * a.PublicKeyPart).Mod(parameters.P);
              }

              List<Ballot> ballots = new List<Ballot>();
              ballots.Add(new Ballot(new int[] { 0, 1 }, parameters, question, publicKey, null));
              ballots.Add(new Ballot(new int[] { 0, 1 }, parameters, question, publicKey, null));
              ballots.Add(new Ballot(new int[] { 1, 0 }, parameters, question, publicKey, null));
              ballots.Add(new Ballot(new int[] { 0, 1 }, parameters, question, publicKey, null));
              ballots.Add(new Ballot(new int[] { 1, 0 }, parameters, question, publicKey, null));
              ballots.Add(new Ballot(new int[] { 0, 1 }, parameters, question, publicKey, null));

              if (!ballots.All(ballot => ballot.Verify(publicKey, parameters, question, RandomNumberGenerator.Create(), BaseParameters.StandardProofCount, new Progress(null))))
            throw new Exception("Bad proof.");

              for (int optionIndex = 0; optionIndex < question.Options.Count(); optionIndex++)
              {
            IEnumerable<Vote> votes = ballots.Select(ballot => ballot.Votes[optionIndex]);

            Vote sum = null;
            votes.Foreach(vote => sum = sum == null ? vote : sum + vote);

            List<PartialDecipher> partialDeciphers = new List<PartialDecipher>();
            auths.Foreach(authority => partialDeciphers.AddRange(authority.PartialDeciphers(1, sum, 0, optionIndex)));

            IEnumerable<BigInt> partialDeciphers0 = partialDeciphers
              .Where(partialDecipher => partialDecipher.GroupIndex == 1)
              .Select(partialDecipher => partialDecipher.Value);
            int v0 = sum.Decrypt(partialDeciphers0, parameters);

            IEnumerable<BigInt> partialDeciphers1 = partialDeciphers
              .Where(partialDecipher => partialDecipher.GroupIndex == 1)
              .Select(partialDecipher => partialDecipher.Value);
            int v1 = sum.Decrypt(partialDeciphers1, parameters);

            IEnumerable<BigInt> partialDeciphers2 = partialDeciphers
              .Where(partialDecipher => partialDecipher.GroupIndex == 1)
              .Select(partialDecipher => partialDecipher.Value);
            int v2 = sum.Decrypt(partialDeciphers2, parameters);

            IEnumerable<BigInt> partialDeciphers3 = partialDeciphers
              .Where(partialDecipher => partialDecipher.GroupIndex == 1)
              .Select(partialDecipher => partialDecipher.Value);
            int v3 = sum.Decrypt(partialDeciphers3, parameters);

            IEnumerable<BigInt> partialDeciphers4 = partialDeciphers
              .Where(partialDecipher => partialDecipher.GroupIndex == 1)
              .Select(partialDecipher => partialDecipher.Value);
            int v4 = sum.Decrypt(partialDeciphers4, parameters);

            if (v0 == v1 &&
            v0 == v2 &&
            v0 == v3 &&
            v0 == v4)
            {
              throw new Exception("Everything ok.");
            }
            else
            {
              throw new Exception("Bad vote.");
            }
              }
        }
Exemplo n.º 14
0
        /// <summary>
        /// Calculates the result of the vote.
        /// </summary>
        /// <param name="votePower">Vote value equal to F^vote.</param>
        /// <param name="parameters">Cryptographic parameters.</param>
        /// <returns>Result of the vote.</returns>
        private static int Result(BigInt votePower, BaseParameters parameters)
        {
            if (votePower == null)
            throw new ArgumentNullException("votePower");
              if (parameters == null)
            throw new ArgumentNullException("parameters");

              int sumOfVotes = 0;
              while (parameters.F.PowerMod(new BigInt(sumOfVotes), parameters.P) != votePower)
              {
            sumOfVotes++;
            if (sumOfVotes > 10000)
              return -1;
              }

              return sumOfVotes;
        }
Exemplo n.º 15
0
        /// <summary>
        /// Verifies all range proves.
        /// </summary>
        /// <param name="publicKey">Public key to verify against.</param>
        /// <param name="parameters">Cryptographic Parameters.</param>
        /// <param name="rng">Random number generator.</param>
        /// <param name="proofCheckCount">Number of proofs to check.</param>
        /// <returns>All proves are valid.</returns>
        public bool Verify(BigInt publicKey, BaseParameters parameters, RandomNumberGenerator rng, int proofCheckCount)
        {
            if (publicKey == null)
            throw new ArgumentNullException("publicKey");
              if (parameters == null)
            throw new ArgumentNullException("parameters");

              bool verifies = true;

              CryptoLog.Begin(CryptoLogLevel.Detailed, "Verifying option");
              CryptoLog.Add(CryptoLogLevel.Numeric, "Ciphertext", Ciphertext);
              CryptoLog.Add(CryptoLogLevel.Numeric, "Halfkey", HalfKey);

              verifies &= RangeProves.Count == parameters.ProofCount;
              verifies &= RangeProves
            .SelectRandom(rng, proofCheckCount)
            .All(proof => proof.Verify(this, publicKey, parameters));

              CryptoLog.End(CryptoLogLevel.Detailed);

              return verifies;
        }
Exemplo n.º 16
0
        /// <summary>
        /// Decrypts a vote from partial deciphers.
        /// </summary>
        /// <param name="partialDeciphers">Partial deciphers from t+1 authorities.</param>
        /// <param name="parameters">Cryptographic parameters.</param>
        /// <returns>Result of the vote.</returns>
        public int Decrypt(IEnumerable<BigInt> partialDeciphers, BaseParameters parameters)
        {
            if (partialDeciphers == null)
            throw new ArgumentNullException("partialDeciphers");
              if (parameters == null)
            throw new ArgumentNullException("parameters");
              if (partialDeciphers.Count() != parameters.Thereshold + 1)
            throw new ArgumentException("Wrong number of partial deciphers.");

              CryptoLog.Begin(CryptoLogLevel.Numeric, "Calculating authority group result");
              CryptoLog.Add(CryptoLogLevel.Numeric, "Ciphertext", Ciphertext);
              int index = 0;

              foreach (var partialDecipher in partialDeciphers)
              {
            CryptoLog.Add(CryptoLogLevel.Numeric, string.Format("Partial decipher {0}", index) , partialDecipher);
            index++;
              }

              BigInt votePower = Ciphertext;
              partialDeciphers.Foreach(partialDecipher => votePower = votePower.DivideMod(partialDecipher, P));

              CryptoLog.Add(CryptoLogLevel.Numeric, "Vote power", votePower);

              int result = Result(votePower, parameters);
              CryptoLog.Add(CryptoLogLevel.Numeric, "Authority group result", result);
              CryptoLog.End(CryptoLogLevel.Numeric);

              return result;
        }