/// <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; }
/// <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); } }
/// <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); } }
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())); }
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)); } }
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))); } }
/// <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); }
/// <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(); }
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; }
void Assign(ref BigInt variable, BigInt new_) { variable = Replace(variable, new_); }
/// <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); }
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); }
/// <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; }
// // copies a BigInt value. // internal void CopyFrom (BigInt a) { Array.Copy(a.m_elements, m_elements, m_maxbytes); m_size = a.m_size; }
// // 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); }
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; }
// // 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); }
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; }
/// <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(); }
/// <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; }
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())); }
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; }
// // 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; }
// // 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; }
/// <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; }
// // 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; }