Пример #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 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
        /// <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.");
              }
        }
 internal static void Divide(BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder)
 {
     if (numerator < denominator)
     {
         quotient.Clear();
         remainder.CopyFrom(numerator);
     }
     else if (numerator == denominator)
     {
         quotient.Clear();
         quotient.SetDigit(0, 1);
         remainder.Clear();
     }
     else
     {
         BigInt a = new BigInt();
         a.CopyFrom(numerator);
         BigInt num2 = new BigInt();
         num2.CopyFrom(denominator);
         uint num3 = 0;
         while (num2.Size < a.Size)
         {
             num2.Multiply(0x100);
             num3++;
         }
         if (num2 > a)
         {
             num2.Divide(0x100);
             num3--;
         }
         int num4 = 0;
         int digit = 0;
         int b = 0;
         BigInt c = new BigInt();
         quotient.Clear();
         for (int i = 0; i <= num3; i++)
         {
             num4 = (a.Size == num2.Size) ? a.GetDigit(a.Size - 1) : ((0x100 * a.GetDigit(a.Size - 1)) + a.GetDigit(a.Size - 2));
             digit = num2.GetDigit(num2.Size - 1);
             b = num4 / digit;
             if (b >= 0x100)
             {
                 b = 0xff;
             }
             Multiply(num2, b, ref c);
             while (c > a)
             {
                 b--;
                 Multiply(num2, b, ref c);
             }
             quotient.Multiply(0x100);
             Add(quotient, (byte) b, ref quotient);
             Subtract(a, c, ref a);
             num2.Divide(0x100);
         }
         remainder.CopyFrom(a);
     }
 }
Пример #5
0
        public void BallotVerifyTest()
        {
            for (int i = 0; i < 100; i++)
              {
            this.publicKey = this.parameters.Random();

            Ballot ballot = new Ballot(new int[] { 0, 1, 0, 1 }, this.parameters, this.parameters.Questions.ElementAt(0), this.publicKey, new Progress(null));
            Assert.IsTrue(ballot.Verify(this.publicKey, this.parameters, this.parameters.Questions.ElementAt(0), RandomNumberGenerator.Create(), BaseParameters.StandardProofCount, new Progress(null)));
              }
        }
 public void AddIssuerSerial(string issuerName, string serialNumber)
 {
     System.Security.Cryptography.BigInt num = new System.Security.Cryptography.BigInt();
     num.FromHexadecimal(serialNumber);
     if (this.m_issuerSerials == null)
     {
         this.m_issuerSerials = new ArrayList();
     }
     this.m_issuerSerials.Add(new X509IssuerSerial(issuerName, num.ToDecimal()));
 }
Пример #7
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));
              }
        }
Пример #8
0
        public void BallotInvalidVerifyTest()
        {
            for (int i = 0; i < 100; i++)
              {
            this.publicKey = this.parameters.Random();

            Ballot ballot0 = new Ballot(new int[] { 0, 1, 0, 1 }, this.parameters, this.parameters.Questions.ElementAt(0), this.publicKey, FakeType.BadFiatShamir);
            Assert.IsFalse(ballot0.Verify(this.publicKey, this.parameters, this.parameters.Questions.ElementAt(0), RandomNumberGenerator.Create(), BaseParameters.StandardProofCount, new Progress(null)));

            Ballot ballot1 = new Ballot(new int[] { 0, 1, 0, 1 }, this.parameters, this.parameters.Questions.ElementAt(0), this.publicKey, FakeType.BadPowerMod);
            Assert.IsFalse(ballot1.Verify(this.publicKey, this.parameters, this.parameters.Questions.ElementAt(0), RandomNumberGenerator.Create(), BaseParameters.StandardProofCount, new Progress(null)));
              }
        }
Пример #9
0
        /// <summary>
        /// Create a new response to shares.
        /// </summary>
        /// <param name="votingId">Id of the voting procedure.</param>
        /// <param name="authorityIndex">Index of the issuing authority.</param>
        /// <param name="acceptShares">Does the authority accept all the shares?</param>
        /// <param name="publicKeyPart">Public key part from that authority.</param>
        /// <param name="signedVotingParameters">Signed voting parameters.</param>
        public ShareResponse(Guid votingId, int authorityIndex, bool acceptShares, BigInt publicKeyPart, Signed<VotingParameters> signedVotingParameters)
        {
            if (publicKeyPart == null)
            throw new ArgumentNullException("publicKeyPart");

              VotingId = votingId;
              AuthorityIndex = authorityIndex;
              AcceptShares = acceptShares;
              PublicKeyPart = publicKeyPart;
              byte[] votingParametersData = signedVotingParameters.ToBinary();
              SHA256Managed sha256 = new SHA256Managed();
              VotingParametersHash = sha256.ComputeHash(votingParametersData);
        }
Пример #10
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();
        }
Пример #11
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));
              }
        }
 internal static void Add(BigInt a, byte b, ref BigInt c)
 {
     byte digit = b;
     int num2 = 0;
     int size = a.Size;
     int num4 = 0;
     for (int i = 0; i < size; i++)
     {
         num2 = a.GetDigit(i) + digit;
         c.SetDigit(i, (byte) (num2 & 0xff), ref num4);
         digit = (byte) ((num2 >> 8) & 0xff);
     }
     if (digit != 0)
     {
         c.SetDigit(a.Size, digit, ref num4);
     }
     c.Size = num4;
 }
Пример #13
0
 void Assign(ref BigInt variable, BigInt new_)
 {
     variable = Replace(variable, new_);
 }
Пример #14
0
        /// <summary>
        /// Sets the numbers needed for cryptography.
        /// </summary>
        /// <remarks>
        /// This includes Q, P, G and F.
        /// </remarks>
        /// <param name="prime">A prime number.</param>
        /// <param name="safePrime">A safe prime.</param>
        public void SetNumbers(
            BigInt prime,
            BigInt safePrime)
        {
            if (prime == null)
            throw new ArgumentNullException("prime");
              if (safePrime == null)
            throw new ArgumentNullException("safePrime");

              Q = prime;
              P = safePrime;

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

              G = r0.PowerMod(Q, P);
              F = G.PowerMod(r1, P);
        }
Пример #15
0
        internal string ToDecimal ()
        {
            if (IsZero())
                return "0";

            BigInt ten = new BigInt(0xA);
            BigInt numerator = new BigInt();
            BigInt quotient = new BigInt();
            BigInt remainder = new BigInt();

            numerator.CopyFrom(this);

            // Each hex digit can account for log(16) = 1.21 decimal digits. Times two hex digits in a byte
            // and m_size bytes used in this BigInt, yields the maximum number of characters for the decimal
            // representation of the BigInt.
            char[] dec = new char[(int)Math.Ceiling(m_size * 2 * 1.21)];

            int index = 0;
            do
            {
                Divide(numerator, ten, ref quotient, ref remainder);
                dec[index++] = decValues[remainder.IsZero() ? 0 : (int)remainder.m_elements[0]];
                numerator.CopyFrom(quotient);
            } while (quotient.IsZero() == false);

            Array.Reverse(dec, 0, index);
            return new String(dec, 0, index);
        }
Пример #16
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;
        }
Пример #17
0
        //
        // copies a BigInt value.
        //

        internal void CopyFrom (BigInt a) {
            Array.Copy(a.m_elements, m_elements, m_maxbytes);
            m_size = a.m_size;
        }
Пример #18
0
        //
        // Imports a decimal string into a BigInt bit representation.
        //

        internal void FromDecimal (string decNum) {
            BigInt c = new BigInt();
            BigInt tmp = new BigInt();
            int length = decNum.Length;
            for (int index = 0; index < length; index++) {
                // just ignore invalid characters. No need to raise an exception.
                if (decNum[index] > '9' || decNum[index] < '0')
                    continue;
                Multiply(c, 10, ref tmp);
                Add(tmp, (byte) (decNum[index] - '0'), ref c);
            }
            CopyFrom(c);
        }
Пример #19
0
        private static void Multiply (BigInt a, int b, ref BigInt c) {
            if (b == 0) {
                c.Clear();
                return;
            }
                
            int carry = 0, product = 0;
            int size = a.Size;
            int newSize = 0;
            for (int index = 0; index < size; index++) {
                product = b * a.GetDigit(index) + carry;
                carry = product / m_base;
                c.SetDigit(index, (byte) (product % m_base), ref newSize);
            }

            if (carry != 0) {
                byte[] bytes = BitConverter.GetBytes(carry);
                for (int index = 0; index < bytes.Length; index++) {
                    c.SetDigit(size + index, bytes[index], ref newSize);
                }
            }

            c.Size = newSize;
        }
Пример #20
0
        //
        // Integer division of one BigInt by another.
        //

        internal static void Divide (BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder) {
            // Avoid extra computations in special cases.

            if (numerator < denominator) {
                quotient.Clear();
                remainder.CopyFrom(numerator);
                return;
            }
    
            if (numerator == denominator) {
                quotient.Clear(); quotient.SetDigit(0, 1); 
                remainder.Clear();
                return;
            }

            BigInt dividend = new BigInt();
            dividend.CopyFrom(numerator);
            BigInt divisor = new BigInt();
            divisor.CopyFrom(denominator);

            uint zeroCount = 0;
            // We pad the divisor with zeros until its size equals that of the dividend.
            while (divisor.Size < dividend.Size) {
                divisor.Multiply(m_base);
                zeroCount++; 
            }

            if (divisor > dividend) {
                divisor.Divide(m_base);
                zeroCount--;
            }

            // Use school division techniques, make a guess for how many times
            // divisor goes into dividend, making adjustment if necessary.
            int a = 0;
            int b = 0;
            int c = 0;

            BigInt hold = new BigInt();
            quotient.Clear();
            for (int index = 0; index <= zeroCount; index++) {
                a = dividend.Size == divisor.Size ? dividend.GetDigit(dividend.Size - 1) :
                                                    m_base * dividend.GetDigit(dividend.Size - 1) + dividend.GetDigit(dividend.Size - 2);
                b = divisor.GetDigit(divisor.Size - 1);
                c = a / b;

                if (c >= m_base) 
                    c = 0xFF;

                Multiply(divisor, c, ref hold);
                while (hold > dividend) {
                    c--;
                    Multiply(divisor, c, ref hold);
                }

                quotient.Multiply(m_base);
                Add(quotient, (byte) c, ref quotient);
                Subtract(dividend, hold, ref dividend);
                divisor.Divide(m_base);
            }
            remainder.CopyFrom(dividend);
        }
Пример #21
0
        public Projective EcMult(BigInt d, Projective s)
        {
            var size = s.x.Length;

            if (d.IsZero() || s.z.IsZero())
            {
                return new Projective() { x = new BigInt(1, size), y = new BigInt(1, size), z = new BigInt(0, size) };
            }
            if (d.IsOne())
            {
                return s.Clone();
            }
            if (!s.z.IsOne())
            {
                var affine = EcAffinify(s);
                s = EcProjectify(affine);
                affine.Clear();
            }
            else
            {
                s = s.Clone();
            }
            var r = s.Clone();
            var h = d.Mul3();

            for (var i = h.BitCount() - 2; i >= 1; i--)
            {
                var rTmp = r;
                r = EcDouble(r);
                rTmp.Clear();

                if (h.BitAt(i) && !d.BitAt(i))
                {
                    var u = EcFullAdd(r, s);
                    r.Clear();
                    r = u;
                }
                else if (!h.BitAt(i) && d.BitAt(i))
                {
                    var u = EcFullSub(r, s);
                    r.Clear();
                    r = u;
                }
            }
            h.Clear();

            return r;
        }
Пример #22
0
        /// <summary>
        /// Creates a new summation of votes.
        /// </summary>
        /// <param name="parameters">Voting parameters.</param>
        /// <param name="certificateStorage">Certificate storage to verify against.</param>
        /// <param name="publicKey">Public key with which the votes where encrypted.</param>
        public Tally(
            VotingParameters parameters,
            CertificateStorage certificateStorage,
            BigInt publicKey,
            int checkProofCount)
        {
            this.rng = RandomNumberGenerator.Create();
              this.parameters = parameters;
              this.proofCheckCount = Math.Min(parameters.ProofCount, checkProofCount);
              this.certificateStorage = certificateStorage;
              this.publicKey = publicKey;

              this.voteSums = new Vote[this.parameters.Questions.Count()][];
              for (int questionIndex = 0; questionIndex < this.parameters.Questions.Count(); questionIndex++)
              {
            Question question = this.parameters.Questions.ElementAt(questionIndex);
            this.voteSums[questionIndex] = new Vote[question.Options.Count()];
              }

              this.result = new VotingResult(this.parameters.VotingId, this.parameters);
              this.partialDeciphers = new List<PartialDecipher>();
              this.countedVoters = new List<Guid>();
              this.nextEnvelopeIndex = 0;
              this.envelopeSequencerList = new Dictionary<int, Tuple<Signed<Envelope>, bool>>();

              EnvelopeHash = new byte[] { };
              EnvelopeCount = 0;
              ValidEnvelopeCount = 0;

              CryptoLog.Begin(CryptoLogLevel.Summary, "Begin tallying");
              CryptoLog.Add(CryptoLogLevel.Summary, "Voting id", parameters.VotingId);
              CryptoLog.Add(CryptoLogLevel.Summary, "Voting title", parameters.Title.Text);
              CryptoLog.Add(CryptoLogLevel.Detailed, "ProofCount", parameters.ProofCount);
              CryptoLog.Add(CryptoLogLevel.Detailed, "Thereshold", parameters.Thereshold);
              CryptoLog.Add(CryptoLogLevel.Numeric, "P", parameters.P);
              CryptoLog.Add(CryptoLogLevel.Numeric, "G", parameters.G);
              CryptoLog.Add(CryptoLogLevel.Numeric, "F", parameters.F);
              CryptoLog.Add(CryptoLogLevel.Numeric, "Q", parameters.Q);
              CryptoLog.EndWrite();
        }
Пример #23
0
        /// <summary>
        /// Initializes the crypto part of the parameters.
        /// </summary>
        /// <remarks>
        /// Prime must be lower than safePrime.
        /// </remarks>
        /// <param name="prime">Prime number p for group Zp*.</param>
        /// <param name="safePrime">Safe prime for q.</param>
        /// <param name="thereshold">Maximal tolerable number of compromised authorities.</param>
        /// <param name="authorityCount">Number of authorities.</param>
        /// <param name="optionCount">Number of options.</param>
        /// <param name="maxVota">Maximum number of votes castable by a voter.</param>
        /// <param name="proofCount">Number of proof required to proof each fact.</param>
        public void InitilizeCrypto(
            BigInt prime,
            BigInt safePrime,
            int thereshold,
            int authorityCount,
            int optionCount,
            int maxVota,
            int proofCount)
        {
            if (prime == null)
            throw new ArgumentNullException("prime");
              if (safePrime == null)
            throw new ArgumentNullException("safePrime");
              if (prime >= safePrime)
            throw new ArgumentException("Prime must be smaller than safePrime.");
              if (!authorityCount.InRange(3, 23))
            throw new ArgumentException("Authority count must be in range from 3 to 23.");
              if (!thereshold.InRange(1, authorityCount - 1))
            throw new ArgumentException("Thereshold must be in range from 1 to authorityCount - 1.");
              if (optionCount < 2)
            throw new ArgumentException("Option count must be at least 2.");
              if (!maxVota.InRange(1, optionCount))
            throw new ArgumentException("Maximum vota number must be in range from 1 to optionCount.");

              Q = prime;
              P = safePrime;

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

              G = r0.PowerMod(Q, P);
              F = G.PowerMod(r1, P);

              Thereshold = thereshold;
              AuthorityCount = authorityCount;
              OptionCount = optionCount;
              MaxVota = maxVota;
              ProofCount = proofCount;
        }
Пример #24
0
 public void AddIssuerSerial(string issuerName, string serialNumber) {
     BigInt h = new BigInt();
     h.FromHexadecimal(serialNumber);
     if (m_issuerSerials == null)
         m_issuerSerials = new ArrayList();
     m_issuerSerials.Add(new X509IssuerSerial(issuerName, h.ToDecimal()));
 }
Пример #25
0
        public Projective EcTwinMult(BigInt d0, Projective S, BigInt d1, Projective T)
        {
            var d = new BigInt[2] { d0, d1 };

            var SpT = EcFullAdd(S, T);
            var SmT = EcFullSub(S, T);

            var m0 = d0.BitCount();
            var m1 = d1.BitCount();
            var m = Math.Max(m0, m1);

            var c = new int[2][];
            c[0] = new int[6] { 0, 0, d0.BitAt(m - 1) ? 1 : 0, d0.BitAt(m - 2) ? 1 : 0, d0.BitAt(m - 3) ? 1 : 0, d0.BitAt(m - 4) ? 1 : 0 };
            c[1] = new int[6] { 0, 0, d1.BitAt(m - 1) ? 1 : 0, d1.BitAt(m - 2) ? 1 : 0, d1.BitAt(m - 3) ? 1 : 0, d1.BitAt(m - 4) ? 1 : 0 };

            var R = new Projective() { x = new BigInt(1, S.x.Length), y = new BigInt(1, S.x.Length), z = new BigInt(0, S.x.Length) };

            int[] h = new int[2], u = new int[2];

            for (var k = m; k >= 0; k--)
            {
                for (var i = 0; i <= 1; i++)
                {
                    h[i] = (c[i][1] << 4) + (c[i][2] << 3) + (c[i][3] << 2) + (c[i][4] << 1) + c[i][5];
                    if (c[i][0] == 1)
                        h[i] = 31 - h[i];
                }
                for (var i = 0; i <= 1; i++)
                {
                    var t = h[1 - i];
                    int f;
                    if (18 <= t && t < 22)
                        f = 9;
                    else if (14 <= t && t < 18)
                        f = 10;
                    else if (22 <= t && t < 24)
                        f = 11;
                    else if (4 <= t && t < 12)
                        f = 14;
                    else
                        f = 12;
                    if (h[i] < f)
                        u[i] = 0;
                    else
                        u[i] = (c[i][0] & 1) != 0 ? -1 : 1;
                }
                for (var i = 0; i < 2; i++)
                {
                    c[i][0] = ((u[i] != 0) ^ (c[i][1] != 0)) ? 1 : 0;
                    c[i][1] = c[i][2];
                    c[i][2] = c[i][3];
                    c[i][3] = c[i][4];
                    c[i][4] = c[i][5];
                    c[i][5] = d[i].BitAt(k - 5) ? 1 : 0;
                }
                    R = EcDouble(R);
                if (u[0] == -1)
                {
                    if (u[1] == -1)
                        R = EcFullSub(R, SpT);
                    else if (u[1] == 0)
                        R = EcFullSub(R, S);
                    else
                        R = EcFullSub(R, SmT);
                }
                else if (u[0] == 0)
                {
                    if (u[1] == -1)
                        R = EcFullSub(R, T);
                    else if (u[1] == 1)
                        R = EcFullAdd(R, T);
                }
                else if (u[0] == 1)
                {
                    if (u[1] == -1)
                        R = EcFullAdd(R, SmT);
                    else if (u[1] == 0)
                        R = EcFullAdd(R, S);
                    else
                        R = EcFullAdd(R, SpT);
                }
            }

            return R;
        }
 public void AddIssuerSerial(string issuerName, string serialNumber)
 {
     System.Security.Cryptography.BigInt num = new System.Security.Cryptography.BigInt();
     num.FromHexadecimal(serialNumber);
     if (this.m_issuerSerials == null)
     {
         this.m_issuerSerials = new ArrayList();
     }
     this.m_issuerSerials.Add(new X509IssuerSerial(issuerName, num.ToDecimal()));
 }
Пример #27
0
        //
        // Subtracts b from a and outputs the result in c.
        //

        internal static void Subtract (BigInt a, BigInt b, ref BigInt c) {
            byte borrow = 0;
            int diff = 0;

            if (a < b) {
                Subtract(b, a, ref c);
                Negate(ref c);
                return;
            }

            int index = 0;
            int size = a.Size;
            int newSize = 0;
            for (index = 0; index < size; index++) {
                diff = a.GetDigit(index) - b.GetDigit(index) - borrow;
                borrow = 0;
                if (diff < 0) {
                    diff += m_base;
                    borrow = 1;
                }
                c.SetDigit(index, (byte) (diff & 0xFF), ref newSize);
            }

            c.Size = newSize;
        }
        private unsafe static Cryptography.SafeCertStoreHandle FindCertInStore(Cryptography.SafeCertStoreHandle safeSourceStoreHandle, X509FindType findType, Object findValue, bool validOnly) {
            if (findValue == null)
                throw new ArgumentNullException("findValue");

            IntPtr pvFindPara = IntPtr.Zero;
            object pvCallbackData1 = null;
            object pvCallbackData2 = null;
            FindProcDelegate pfnCertCallback1 = null;
            FindProcDelegate pfnCertCallback2 = null;
            uint dwFindType = CAPI.CERT_FIND_ANY;
            string subject, issuer;

            CAPI.CRYPTOAPI_BLOB HashBlob = new CAPI.CRYPTOAPI_BLOB();
            SafeLocalAllocHandle pb = SafeLocalAllocHandle.InvalidHandle;
            _FILETIME ft = new _FILETIME();
            string oidValue = null;

            switch(findType) {
            case X509FindType.FindByThumbprint:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                byte[] hex = X509Utils.DecodeHexString((string) findValue);
                pb = X509Utils.ByteToPtr(hex);
                HashBlob.pbData = pb.DangerousGetHandle(); 
                HashBlob.cbData = (uint) hex.Length;
                dwFindType = CAPI.CERT_FIND_HASH;
                pvFindPara = new IntPtr(&HashBlob);
                break;

            case X509FindType.FindBySubjectName:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                subject = (string) findValue;
                dwFindType = CAPI.CERT_FIND_SUBJECT_STR;
                pb = X509Utils.StringToUniPtr(subject);
                pvFindPara = pb.DangerousGetHandle();
                break;

            case X509FindType.FindBySubjectDistinguishedName:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                subject = (string) findValue;
                pfnCertCallback1 = new FindProcDelegate(FindSubjectDistinguishedNameCallback);
                pvCallbackData1 = subject;
                break;

            case X509FindType.FindByIssuerName:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                issuer = (string) findValue;
                dwFindType = CAPI.CERT_FIND_ISSUER_STR;
                pb = X509Utils.StringToUniPtr(issuer);
                pvFindPara = pb.DangerousGetHandle();
                break;

            case X509FindType.FindByIssuerDistinguishedName:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                issuer = (string) findValue;
                pfnCertCallback1 = new FindProcDelegate(FindIssuerDistinguishedNameCallback);
                pvCallbackData1 = issuer;
                break;

            case X509FindType.FindBySerialNumber:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                pfnCertCallback1 = new FindProcDelegate(FindSerialNumberCallback);
                pfnCertCallback2 = new FindProcDelegate(FindSerialNumberCallback);
                BigInt h = new BigInt();
                h.FromHexadecimal((string) findValue);
                pvCallbackData1 = (byte[]) h.ToByteArray();
                h.FromDecimal((string) findValue);
                pvCallbackData2 = (byte[]) h.ToByteArray();
                break;

            case X509FindType.FindByTimeValid:
                if (findValue.GetType() != typeof(DateTime))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                *((long*) &ft) = ((DateTime) findValue).ToFileTime();
                pfnCertCallback1 = new FindProcDelegate(FindTimeValidCallback);
                pvCallbackData1 = ft; 
                break;

            case X509FindType.FindByTimeNotYetValid:
                if (findValue.GetType() != typeof(DateTime))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                *((long*) &ft) = ((DateTime) findValue).ToFileTime();
                pfnCertCallback1 = new FindProcDelegate(FindTimeNotBeforeCallback);
                pvCallbackData1 = ft; 
                break;

            case X509FindType.FindByTimeExpired:
                if (findValue.GetType() != typeof(DateTime))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                *((long*) &ft) = ((DateTime) findValue).ToFileTime();
                pfnCertCallback1 = new FindProcDelegate(FindTimeNotAfterCallback);
                pvCallbackData1 = ft; 
                break;

            case X509FindType.FindByTemplateName:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                pvCallbackData1 = (string) findValue; 
                pfnCertCallback1 = new FindProcDelegate(FindTemplateNameCallback);
                break;

            case X509FindType.FindByApplicationPolicy:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                // If we were passed the friendly name, retrieve the value string.
                oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, (string) findValue, Cryptography.OidGroup.Policy);
                if (oidValue == null) {
                    oidValue = (string) findValue;
                    X509Utils.ValidateOidValue(oidValue);
                }
                pvCallbackData1 = oidValue;
                pfnCertCallback1 = new FindProcDelegate(FindApplicationPolicyCallback);
                break;

            case X509FindType.FindByCertificatePolicy:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                // If we were passed the friendly name, retrieve the value string.
                oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, (string)findValue, Cryptography.OidGroup.Policy);
                if (oidValue == null) {
                    oidValue = (string) findValue;
                    X509Utils.ValidateOidValue(oidValue);
                }
                pvCallbackData1 = oidValue;
                pfnCertCallback1 = new FindProcDelegate(FindCertificatePolicyCallback);
                break;

            case X509FindType.FindByExtension:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                // If we were passed the friendly name, retrieve the value string.
                oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, (string)findValue, Cryptography.OidGroup.ExtensionOrAttribute);
                if (oidValue == null) {
                    oidValue = (string) findValue;
                    X509Utils.ValidateOidValue(oidValue);
                }
                pvCallbackData1 = oidValue;
                pfnCertCallback1 = new FindProcDelegate(FindExtensionCallback);
                break;

            case X509FindType.FindByKeyUsage:
                // The findValue object can be either a friendly name, a X509KeyUsageFlags enum or an integer.
                if (findValue.GetType() == typeof(string)) {
                    CAPI.KEY_USAGE_STRUCT[] KeyUsages = new CAPI.KEY_USAGE_STRUCT[] { 
                        new CAPI.KEY_USAGE_STRUCT("DigitalSignature", CAPI.CERT_DIGITAL_SIGNATURE_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("NonRepudiation",   CAPI.CERT_NON_REPUDIATION_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("KeyEncipherment",  CAPI.CERT_KEY_ENCIPHERMENT_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("DataEncipherment", CAPI.CERT_DATA_ENCIPHERMENT_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("KeyAgreement",     CAPI.CERT_KEY_AGREEMENT_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("KeyCertSign",      CAPI.CERT_KEY_CERT_SIGN_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("CrlSign",          CAPI.CERT_CRL_SIGN_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("EncipherOnly",     CAPI.CERT_ENCIPHER_ONLY_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("DecipherOnly",     CAPI.CERT_DECIPHER_ONLY_KEY_USAGE)
                    };

                    for (uint index = 0; index < KeyUsages.Length; index++) {
                        if (String.Compare(KeyUsages[index].pwszKeyUsage, (string) findValue, StringComparison.OrdinalIgnoreCase) == 0) {
                            pvCallbackData1 = KeyUsages[index].dwKeyUsageBit;
                            break;
                        }
                    }
                    if (pvCallbackData1 == null)
                        throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindType));
                } else if (findValue.GetType() == typeof(X509KeyUsageFlags)) {
                    pvCallbackData1 = findValue;
                } else if (findValue.GetType() == typeof(uint) || findValue.GetType() == typeof(int)) {
                    // We got the actual DWORD
                    pvCallbackData1 = findValue;
                } else 
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindType));

                pfnCertCallback1 = new FindProcDelegate(FindKeyUsageCallback);
                break;

            case X509FindType.FindBySubjectKeyIdentifier:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                pvCallbackData1 = (byte[]) X509Utils.DecodeHexString((string) findValue);
                pfnCertCallback1 = new FindProcDelegate(FindSubjectKeyIdentifierCallback);
                break;

            default:
                throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindType));
            }

            // First, create a memory store
            Cryptography.SafeCertStoreHandle safeTargetStoreHandle = CAPI.CertOpenStore(new IntPtr(CAPI.CERT_STORE_PROV_MEMORY), 
                                                                           CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, 
                                                                           IntPtr.Zero, 
                                                                           CAPI.CERT_STORE_ENUM_ARCHIVED_FLAG | CAPI.CERT_STORE_CREATE_NEW_FLAG, 
                                                                           null);
            if (safeTargetStoreHandle == null || safeTargetStoreHandle.IsInvalid)
                throw new CryptographicException(Marshal.GetLastWin32Error());

            // FindByCert will throw an exception in case of failures.
            FindByCert(safeSourceStoreHandle, 
                       dwFindType,
                       pvFindPara, 
                       validOnly, 
                       pfnCertCallback1,
                       pfnCertCallback2, 
                       pvCallbackData1,
                       pvCallbackData2, 
                       safeTargetStoreHandle);

            pb.Dispose();
            return safeTargetStoreHandle;
        }
Пример #29
0
        //
        // Adds a and b and outputs the result in c.
        //

        internal static void Add (BigInt a, byte b, ref BigInt c) {
            byte carry = b;
            int sum = 0;

            int size = a.Size;
            int newSize = 0;
            for (int index = 0; index < size; index++) {
                sum = a.GetDigit(index) + carry;
                c.SetDigit(index, (byte) (sum & 0xFF), ref newSize);
                carry = (byte) ((sum >> 8) & 0xFF);
            }

            if (carry != 0)
                c.SetDigit(a.Size, carry, ref newSize);

            c.Size = newSize;
        }
Пример #30
0
        /// <summary>
        /// Creates a random number in Zp*
        /// </summary>
        /// <returns>New random number.</returns>
        public BigInt Random()
        {
            BigInt value = 0;

              while (value < 1)
              {
            byte[] data = new byte[P.BitLength / 8 + 1];
            RandomNumberGenerator.Create().GetBytes(data);
            value = new BigInt(data).Mod(P);
              }

              return value;
        }
Пример #31
0
        //
        // Negates a BigInt value. Each byte is complemented, then we add 1 to it.
        //

        internal static void Negate (ref BigInt a) {
            int newSize = 0;
            for (int index = 0; index < m_maxbytes; index++) {
                a.SetDigit(index, (byte) (~a.GetDigit(index) & 0xFF), ref newSize);
            }
            for (int index = 0; index < m_maxbytes; index++) {
                a.SetDigit(index, (byte) (a.GetDigit(index) + 1), ref newSize);
                if ((a.GetDigit(index) & 0xFF) != 0) break;
                a.SetDigit(index, (byte) (a.GetDigit(index) & 0xFF), ref newSize);
            }            
            a.Size = newSize;
        }