Пример #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;
        }
Пример #2
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.");
              }
        }
Пример #3
0
        public void VoteVerifyTest()
        {
            for (int i = 0; i < 100; i++)
              {
            this.publicKey = parameters.Random();

            Vote vote = new Vote(0, this.parameters.Random(), this.parameters, this.publicKey, new Progress(null));

            Assert.IsTrue(vote.Verify(this.publicKey, this.parameters, RandomNumberGenerator.Create(), BaseParameters.StandardProofCount));
              }
        }
Пример #4
0
        public void VoteInvalidVerifyTest()
        {
            for (int i = 0; i < 100; i++)
              {
            this.publicKey = parameters.Random();

            Vote vote0 = new Vote(2, this.parameters.Random(), this.parameters, this.publicKey, FakeType.BadDisjunction);
            Assert.IsFalse(vote0.Verify(this.publicKey, this.parameters, RandomNumberGenerator.Create(), BaseParameters.StandardProofCount));

            Vote vote1 = new Vote(2, this.parameters.Random(), this.parameters, this.publicKey, FakeType.BadFiatShamir);
            Assert.IsFalse(vote1.Verify(this.publicKey, this.parameters, RandomNumberGenerator.Create(), BaseParameters.StandardProofCount));

            Vote vote2 = new Vote(2, this.parameters.Random(), this.parameters, this.publicKey, FakeType.BadPowerMod);
            Assert.IsFalse(vote2.Verify(this.publicKey, this.parameters, RandomNumberGenerator.Create(), BaseParameters.StandardProofCount));
              }
        }
Пример #5
0
        /// <summary>
        /// Partially deciphers a vote.
        /// </summary>
        /// <remarks>
        /// Observes multiply/divide for linear combination with other
        /// partial deciphers.
        /// </remarks>
        /// <param name="vote">Vote to partially decipher.</param>
        /// <param name="multiply">Linear combination multiplicator.</param>
        /// <param name="divide">Linear combination dividend.</param>
        /// <returns>Partial decipher value.</returns>
        private BigInt PartialDecipher(Vote vote, int multiply, int divide)
        {
            if (vote == null)
            throw new ArgumentNullException("vote");
              if (divide == 0)
            throw new ArgumentException("Divide cannot be 0.");

              CryptoLog.Begin(CryptoLogLevel.Numeric, "Creating partial decipher");
              CryptoLog.Add(CryptoLogLevel.Numeric, "Vote halfkey", vote.HalfKey);
              CryptoLog.Add(CryptoLogLevel.Numeric, "Multiply", multiply);
              CryptoLog.Add(CryptoLogLevel.Numeric, "Divide", divide);
              CryptoLog.Add(CryptoLogLevel.Secret, "Secret key part", this.secretKeyPart);

              //The 12 magic number is inserted to avoid division remainders when
              //dividing partial deciphers for linear combinations by 2, 3 and 4.
              var value = vote.HalfKey.PowerMod(this.secretKeyPart * 12 * multiply / divide, this.parameters.P);

              CryptoLog.Add(CryptoLogLevel.Numeric, "Value", value);
              CryptoLog.End(CryptoLogLevel.Numeric);

              return value;
        }
Пример #6
0
        /// <summary>
        /// Creates all partial deciphers for a vote.
        /// </summary>
        /// <remarks>
        /// Partial deciphers from t+1 authority with the same index are
        /// to be combined to fully decipher the vote.
        /// </remarks>
        /// <param name="vote">Vote to partially decipher.</param>
        /// <returns>List of partial deciphers.</returns>
        public IEnumerable<PartialDecipher> PartialDeciphers(int authorityIndex, Vote vote, int questionIndex, int optionIndex)
        {
            if (vote == null)
            throw new ArgumentNullException("vote");
              if (!questionIndex.InRange(0, parameters.Questions.Count() - 1))
            throw new ArgumentException("Option index must be in range 0..OptionCount-1.");
              if (!optionIndex.InRange(0, parameters.Questions.ElementAt(questionIndex).Options.Count() - 1))
            throw new ArgumentException("Option index must be in range 0..OptionCount-1.");

              List<PartialDecipher> partialDeciphers = new List<PartialDecipher>();

              //The magic numbers for multiply and divide listed here for
              //each authority index and partial decipher group index
              //are computed to provide linear combinations of the partial
              //decipher that yield a full decipher.
              //
              //Example for 5 authorities and threshold 3.
              //f1-f5   polynoms of authorities 1-5
              //
              //each autority j has shares f1(j) to f5(j) which expand to
              //a polynomial of degree 3, namely f1(j) = a0+a1*j+a2*j^2+a3*j^3
              //these shares are summed as x(j) = f1(j)+f2(j)+f3(j)+f4(j)+f5(j)
              //
              //these are then linarly combined to the secret key:
              //x(1)*4 + x(2)*-6 + x(3)*4 + x(4)*-1 = ... = a0(1)+a0(2)+a0(3)+a(4)+a(5)

              switch (Index)
              {
            case 1:
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 2, questionIndex, optionIndex, PartialDecipher(vote, 5, 2)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 3, questionIndex, optionIndex, PartialDecipher(vote, 10, 3)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 4, questionIndex, optionIndex, PartialDecipher(vote, 15, 4)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 5, questionIndex, optionIndex, PartialDecipher(vote, 4, 1)));
              break;
            case 2:
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 1, questionIndex, optionIndex, PartialDecipher(vote, 10, 1)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 3, questionIndex, optionIndex, PartialDecipher(vote, -10, 3)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 4, questionIndex, optionIndex, PartialDecipher(vote, -5, 1)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 5, questionIndex, optionIndex, PartialDecipher(vote, -6, 1)));
              break;
            case 3:
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 1, questionIndex, optionIndex, PartialDecipher(vote, -20, 1)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 2, questionIndex, optionIndex, PartialDecipher(vote, -5, 1)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 4, questionIndex, optionIndex, PartialDecipher(vote, 5, 2)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 5, questionIndex, optionIndex, PartialDecipher(vote, 4, 1)));
              break;
            case 4:
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 1, questionIndex, optionIndex, PartialDecipher(vote, 15, 1)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 2, questionIndex, optionIndex, PartialDecipher(vote, 5, 1)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 3, questionIndex, optionIndex, PartialDecipher(vote, 5, 3)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 5, questionIndex, optionIndex, PartialDecipher(vote, -1, 1)));
              break;
            case 5:
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 1, questionIndex, optionIndex, PartialDecipher(vote, -4, 1)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 2, questionIndex, optionIndex, PartialDecipher(vote, -3, 2)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 3, questionIndex, optionIndex, PartialDecipher(vote, -2, 3)));
              partialDeciphers.Add(new PartialDecipher(authorityIndex, 4, questionIndex, optionIndex, PartialDecipher(vote, -1, 4)));
              break;
            default:
              throw new InvalidOperationException("Bad authority index.");
              }

              return partialDeciphers;
        }
Пример #7
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;
        }
Пример #8
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.");
              }
        }
Пример #9
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;
        }
Пример #10
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.");
              }
        }
Пример #11
0
        /// <summary>
        /// Add two votes to a new one.
        /// </summary>
        /// <param name="a">A vote.</param>
        /// <param name="b">Another vote.</param>
        public Vote(Vote a, Vote b)
        {
            if (a == null)
            throw new ArgumentNullException("a");
              if (b == null)
            throw new ArgumentNullException("b");

              P = a.P;
              HalfKey = (a.HalfKey * b.HalfKey).Mod(P);
              Ciphertext = (a.Ciphertext * b.Ciphertext).Mod(P);
              RangeProves = new List<RangeProof>();
        }