示例#1
0
文件: Proof.cs 项目: dbrgn/pi-vote
        /// <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
文件: Vote.cs 项目: dbrgn/pi-vote
        /// <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);
              }
        }
示例#3
0
文件: Proof.cs 项目: dbrgn/pi-vote
        /// <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.");
              }
        }
示例#4
0
文件: Proof.cs 项目: dbrgn/pi-vote
        /// <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;
        }
示例#5
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.");
              }
        }
示例#6
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;
        }
示例#7
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.");
              }
        }
示例#8
0
 /// <summary>
 /// Encrypts data with an RSA public key
 /// </summary>
 /// <param name="data">Data to encrypt</param>
 /// <param name="publicKey">Public key to use for decryption</param>
 /// <returns>The encrypted data</returns>
 internal static byte[] EncryptRsa(byte[] data, byte[] publicKey)
 {
     var m = new BigInt(data);
     var n = new BigInt(publicKey);
     return m.PowerMod(RsaExponent, n).ToByteArray();
 }
示例#9
0
 /// <summary>
 /// Decrypts data with an RSA key pair
 /// </summary>
 /// <param name="data">Data to decrypt</param>
 /// <param name="keyPair">RSA Key pair to use for decryption</param>
 /// <returns>The decrypted data</returns>
 internal static byte[] DecryptRsa(byte[] data, RsaKeyPair keyPair)
 {
     var c = new BigInt(data);
     var d = new BigInt(keyPair.Private);
     var n = new BigInt(keyPair.Public);
     return c.PowerMod(d, n).ToByteArray();
 }