public void Add_neg_pos_second_larger_mag() { BigInteger x = new BigInteger(-1, new uint[] { 0x3 }); BigInteger y = new BigInteger(1, new uint[] { 0x5 }); BigInteger z = x.Add(y); Expect(SameValue(z, 1, new uint[] { 0x2 })); }
public void Add_neg_pos_same_mag() { BigInteger x = new BigInteger(-1, new uint[] { 0x3 }); BigInteger y = new BigInteger(1, new uint[] { 0x3 }); BigInteger z = x.Add(y); Expect(z.IsZero); }
public void Add_neg_same_length_some_carry() { BigInteger x = new BigInteger(-1, new uint[] { 0x12345678, 0x12345678, 0xFFFFFFFF }); BigInteger y = new BigInteger(-1, new uint[] { 0x23456789, 0x13243546, 0x11111111 }); BigInteger z = x.Add(y); Expect(SameValue(z, -1, new uint[] { 0x3579BE01, 0x25588BBF, 0x11111110 })); }
internal static ISet GetDeltaCrls(DateTime currentDate, PkixParameters paramsPKIX, X509Crl completeCRL) { X509CrlStoreSelector x509CrlStoreSelector = new X509CrlStoreSelector(); try { IList list = Platform.CreateArrayList(); list.Add(completeCRL.IssuerDN); x509CrlStoreSelector.Issuers = list; } catch (IOException innerException) { throw new Exception("Cannot extract issuer from CRL.", innerException); } BigInteger bigInteger = null; try { Asn1Object extensionValue = GetExtensionValue(completeCRL, X509Extensions.CrlNumber); if (extensionValue != null) { bigInteger = DerInteger.GetInstance(extensionValue).PositiveValue; } } catch (Exception innerException2) { throw new Exception("CRL number extension could not be extracted from CRL.", innerException2); } byte[] issuingDistributionPoint = null; try { Asn1Object extensionValue2 = GetExtensionValue(completeCRL, X509Extensions.IssuingDistributionPoint); if (extensionValue2 != null) { issuingDistributionPoint = extensionValue2.GetDerEncoded(); } } catch (Exception innerException3) { throw new Exception("Issuing distribution point extension value could not be read.", innerException3); } x509CrlStoreSelector.MinCrlNumber = bigInteger?.Add(BigInteger.One); x509CrlStoreSelector.IssuingDistributionPoint = issuingDistributionPoint; x509CrlStoreSelector.IssuingDistributionPointEnabled = true; x509CrlStoreSelector.MaxBaseCrlNumber = bigInteger; ISet set = CrlUtilities.FindCrls(x509CrlStoreSelector, paramsPKIX, currentDate); ISet set2 = new HashSet(); foreach (X509Crl item in set) { if (isDeltaCrl(item)) { set2.Add(item); } } return(set2); }
public Key Derivate(byte[] cc, uint nChild, out byte[] ccChild) { AssertNotDiposed(); #if HAS_SPAN if (!IsCompressed) { throw new InvalidOperationException("The key must be compressed"); } Span <byte> vout = stackalloc byte[64]; vout.Clear(); if ((nChild >> 31) == 0) { Span <byte> pubkey = stackalloc byte[33]; this.PubKey.ToBytes(pubkey, out _); Hashes.BIP32Hash(cc, nChild, pubkey[0], pubkey.Slice(1), vout); } else { Span <byte> privkey = stackalloc byte[32]; this._ECKey.WriteToSpan(privkey); Hashes.BIP32Hash(cc, nChild, 0, privkey, vout); privkey.Fill(0); } ccChild = new byte[32]; vout.Slice(32, 32).CopyTo(ccChild); Secp256k1.ECPrivKey keyChild = _ECKey.TweakAdd(vout.Slice(0, 32)); vout.Clear(); return(new Key(keyChild, true)); #else byte[]? l = null; if ((nChild >> 31) == 0) { var pubKey = PubKey.ToBytes(); l = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.SafeSubarray(1)); } else { l = Hashes.BIP32Hash(cc, nChild, 0, this.ToBytes()); } var ll = l.SafeSubarray(0, 32); var lr = l.SafeSubarray(32, 32); ccChild = lr; var parse256LL = new BigInteger(1, ll); var kPar = new BigInteger(1, vch); var N = ECKey.CURVE.N; if (parse256LL.CompareTo(N) >= 0) { throw new InvalidOperationException("You won a prize ! this should happen very rarely. Take a screenshot, and roll the dice again."); } var key = parse256LL.Add(kPar).Mod(N); if (key == BigInteger.Zero) { throw new InvalidOperationException("You won the big prize ! this has probability lower than 1 in 2^127. Take a screenshot, and roll the dice again."); } var keyBytes = key.ToByteArrayUnsigned(); if (keyBytes.Length < 32) { keyBytes = new byte[32 - keyBytes.Length].Concat(keyBytes).ToArray(); } return(new Key(keyBytes)); #endif }
public SimpleBigDecimal Add(SimpleBigDecimal b) { CheckScale(b); return(new SimpleBigDecimal(bigInt.Add(b.bigInt), scale)); }
public void TestSrpProtocol() { // Choose hash algorithm, g, N, username, password, salt SHA256 sha256 = SHA256.Create(); BigInteger g = BigInteger.ValueOf(2); BigInteger N = AuthenticationHelper.N; string password = "******"; string saltString = "fef2871d83ce2120f9c47a46db303d37"; //Does not have to always be this string BigInteger salt = new BigInteger(saltString, 16); // Compute x = H(s,p) byte[] passBytes = Encoding.UTF8.GetBytes(password); byte[] userIdHash = sha256.ComputeHash(passBytes); byte[] saltBytes = salt.ToByteArray(); byte[] xBytes = new byte[saltBytes.Length + userIdHash.Length]; Buffer.BlockCopy(saltBytes, 0, xBytes, 0, saltBytes.Length); Buffer.BlockCopy(userIdHash, 0, xBytes, saltBytes.Length, userIdHash.Length); byte[] xDigest = sha256.ComputeHash(xBytes); BigInteger x = new BigInteger(1, xDigest); // Compute v = g^x BigInteger v = g.ModPow(x, N); Random random = new Random(); // Generate random a, b, A BigInteger a, b, A; do { a = new BigInteger(16, random); b = new BigInteger(16, random); A = g.ModPow(a, N); } while (A.Mod(N).Equals(BigInteger.Zero)); // Calculate k = H(N, g) byte[] nBytes = N.ToByteArray(); byte[] gBytes = g.ToByteArray(); byte[] content = new byte[nBytes.Length + gBytes.Length]; Buffer.BlockCopy(nBytes, 0, content, 0, nBytes.Length); Buffer.BlockCopy(gBytes, 0, content, nBytes.Length, gBytes.Length); byte[] digest = sha256.ComputeHash(content); BigInteger k = new BigInteger(1, digest); //Calculate B = kv + g^b BigInteger B = (k.Multiply(v)).Add((g.ModPow(b, N))); // Calculate u = H(A,B) byte[] ABytes = A.ToByteArray(); byte[] BBytes = B.ToByteArray(); byte[] ABcat = new byte[ABytes.Length + BBytes.Length]; Buffer.BlockCopy(ABytes, 0, ABcat, 0, ABytes.Length); Buffer.BlockCopy(BBytes, 0, ABcat, ABytes.Length, BBytes.Length); byte[] ABdigest = sha256.ComputeHash(ABcat); BigInteger u = new BigInteger(1, ABdigest); // Calculate user side userS = (B - kg^x) ^ (a + ux) BigInteger userS = (B.Subtract((k.Multiply(g.ModPow(x, N))))).ModPow((a.Add(u.Multiply(x))), N); // Calculate user side userK = H(userS) byte[] userSBytes = userS.ToByteArray(); byte[] userSDigest = sha256.ComputeHash(userSBytes); BigInteger userK = new BigInteger(1, userSDigest); // Calculate host side hostS = (Av^u) ^ b BigInteger hostS = (A.Multiply((v.ModPow(u, N)))).ModPow(b, N); // Calculate host side hostK = H(hostS) byte[] hostSBytes = hostS.ToByteArray(); byte[] hostSDigest = sha256.ComputeHash(hostSBytes); BigInteger hostK = new BigInteger(1, hostSDigest); Assert.Equal(hostS, userS); Assert.Equal(hostK, userK); }
/// <summary> /// Generate a set of M-of-N parts for a specific private key. /// If desiredPrivKey is null, then a random key will be selected. /// </summary> public void Generate(int PartsNeededToDecode, int PartsToGenerate, byte[] desiredPrivKey) { if (PartsNeededToDecode > PartsToGenerate) { throw new ApplicationException("Number of parts needed exceeds number of parts to generate."); } if (PartsNeededToDecode > 8 || PartsToGenerate > 8) { throw new ApplicationException("Maximum number of parts is 8"); } if (PartsNeededToDecode < 1 || PartsToGenerate < 1) { throw new ApplicationException("Minimum number of parts is 1"); } if (desiredPrivKey != null && desiredPrivKey.Length != 32) { throw new ApplicationException("Desired private key must be 32 bytes"); } KeyParts.Clear(); decodedKeyParts.Clear(); SecureRandom sr = new SecureRandom(); // Get 8 random big integers into v[i]. byte[][] vvv = new byte[8][]; BigInteger[] v = new BigInteger[8]; for (int i = 0; i < 8; i++) { byte[] b = new byte[32]; sr.NextBytes(b, 0, 32); // For larger values of i, chop off some most-significant-bits to prevent overflows as they are // multiplied with increasingly larger factors. if (i >= 7) { b[0] &= 0x7f; } v[i] = new BigInteger(1, b); Debug.WriteLine(String.Format("v({0})={1}", i, v[i].ToString())); } // if a certain private key is desired, then specify it. if (desiredPrivKey != null) { // replace v[0] with xor(v[1...7]) xor desiredPrivKey BigInteger newv0 = BigInteger.Zero; for (int i = 1; i < PartsNeededToDecode; i++) { newv0 = newv0.Xor(v[i]); } v[0] = newv0.Xor(new BigInteger(1, desiredPrivKey)); } // Generate the expected private key from all the parts BigInteger privkey = new BigInteger("0"); for (int i = 0; i < PartsNeededToDecode; i++) { privkey = privkey.Xor(v[i]); } // Get the bitcoin address byte[] keybytes = privkey.ToByteArrayUnsigned(); // make sure we have 32 bytes, we'll need it if (keybytes.Length < 32) { byte[] array32 = new byte[32]; Array.Copy(keybytes, 0, array32, 32 - keybytes.Length, keybytes.Length); keybytes = array32; } KeyPair = new KeyPair(keybytes); byte[] checksum = Util.ComputeSha256(BitcoinAddress); // Generate the parts for (int i = 0; i < PartsToGenerate; i++) { BigInteger total = new BigInteger("0"); for (int j = 0; j < PartsNeededToDecode; j++) { int factor = 1; for (int ii = 0; ii <= i; ii++) { factor = factor * (j + 1); } BigInteger bfactor = new BigInteger(factor.ToString()); total = total.Add(v[j].Multiply(bfactor)); } Debug.WriteLine(String.Format(" pc{0}={1}", i, total.ToString())); byte[] parts = new byte[39]; parts[0] = 0x4f; parts[1] = (byte)(0x93 + PartsNeededToDecode); int parts23 = (((checksum[0] << 8) + checksum[1]) & 0x1ff); Debug.WriteLine("checksum " + parts23.ToString()); parts23 += 0x6000; parts23 += (i << 9); byte[] btotal = total.ToByteArrayUnsigned(); for (int jj = 0; jj < btotal.Length; jj++) { parts[jj + 4 + (35 - btotal.Length)] = btotal[jj]; } parts[2] = (byte)((parts23 & 0xFF00) >> 8); parts[3] = (byte)(parts23 & 0xFF); KeyParts.Add(Util.ByteArrayToBase58Check(parts)); decodedKeyParts.Add(parts); } }
public void TestModPow() { try { Two.ModPow(One, Zero); Assert.Fail("expected ArithmeticException"); } catch (ArithmeticException) { } Assert.AreEqual(Zero, Zero.ModPow(Zero, One)); Assert.AreEqual(One, Zero.ModPow(Zero, Two)); Assert.AreEqual(Zero, Two.ModPow(One, One)); Assert.AreEqual(One, Two.ModPow(Zero, Two)); for (int i = 0; i < 10; ++i) { BigInteger m = BigInteger.ProbablePrime(10 + i*3, Rnd); var x = new BigInteger(m.BitLength - 1, Rnd); Assert.AreEqual(x, x.ModPow(m, m)); if (x.Sign != 0) { Assert.AreEqual(Zero, Zero.ModPow(x, m)); Assert.AreEqual(One, x.ModPow(m.Subtract(One), m)); } var y = new BigInteger(m.BitLength - 1, Rnd); var n = new BigInteger(m.BitLength - 1, Rnd); BigInteger n3 = n.ModPow(Three, m); BigInteger resX = n.ModPow(x, m); BigInteger resY = n.ModPow(y, m); BigInteger res = resX.Multiply(resY).Mod(m); BigInteger res3 = res.ModPow(Three, m); Assert.AreEqual(res3, n3.ModPow(x.Add(y), m)); BigInteger a = x.Add(One); // Make sure it's not zero BigInteger b = y.Add(One); // Make sure it's not zero Assert.AreEqual(a.ModPow(b, m).ModInverse(m), a.ModPow(b.Negate(), m)); } }
public AccountState AddToBalance(BigInteger amount) { return(new AccountState(BigInteger.Add(this.balance, amount), this.nonce)); }
public void Add_pos_first_longer_one_carry() { BigInteger x = new BigInteger(1, new uint[] { 0x12345678, 0x12345678, 0xFFFFFFFF, 0x22222222 }); BigInteger y = new BigInteger(1, new uint[] { 0x11111111, 0x11111111 }); BigInteger z = x.Add(y); Expect(SameValue(z, 1, new uint[] { 0x12345678, 0x12345679, 0x11111110, 0x33333333 })); }
public void AddResource(ResourceEntity resource, BigInteger amount) { BigInteger owned = resources.ContainsKey(resource) ? resources[resource] : new BigInteger(0); resources[resource] = BigInteger.Add(owned, amount); }
public override Number Calculate(BigInteger bigint1, BigInteger bigint2) { if (bigint1 == null || bigint2 == null) { return 0; } return bigint1.Add(bigint2); }
/// <summary> /// Revoke the certificate. /// The CRL number is increased by one and the new CRL is returned. /// </summary> public static X509CRL RevokeCertificate( X509Certificate2 issuerCertificate, List <X509CRL> issuerCrls, X509Certificate2Collection revokedCertificates ) { if (!issuerCertificate.HasPrivateKey) { throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Issuer certificate has no private key, cannot revoke certificate."); } using (var cfrg = new CertificateFactoryRandomGenerator()) { // cert generators SecureRandom random = new SecureRandom(cfrg); BigInteger crlSerialNumber = BigInteger.Zero; Org.BouncyCastle.X509.X509Certificate bcCertCA = new X509CertificateParser().ReadCertificate(issuerCertificate.RawData); AsymmetricKeyParameter signingKey = GetPrivateKeyParameter(issuerCertificate); ISignatureFactory signatureFactory = new Asn1SignatureFactory(GetRSAHashAlgorithm(defaultHashSize), signingKey, random); X509V2CrlGenerator crlGen = new X509V2CrlGenerator(); crlGen.SetIssuerDN(bcCertCA.IssuerDN); crlGen.SetThisUpdate(DateTime.UtcNow); crlGen.SetNextUpdate(DateTime.UtcNow.AddMonths(12)); // merge all existing revocation list if (issuerCrls != null) { X509CrlParser parser = new X509CrlParser(); foreach (X509CRL issuerCrl in issuerCrls) { X509Crl crl = parser.ReadCrl(issuerCrl.RawData); crlGen.AddCrl(crl); var crlVersion = GetCrlNumber(crl); if (crlVersion.IntValue > crlSerialNumber.IntValue) { crlSerialNumber = crlVersion; } } } DateTime now = DateTime.UtcNow; if (revokedCertificates == null || revokedCertificates.Count == 0) { // add a dummy revoked cert crlGen.AddCrlEntry(BigInteger.One, now, CrlReason.Unspecified); } else { // add the revoked cert foreach (var revokedCertificate in revokedCertificates) { crlGen.AddCrlEntry(GetSerialNumber(revokedCertificate), now, CrlReason.PrivilegeWithdrawn); } } crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(bcCertCA)); // set new serial number crlSerialNumber = crlSerialNumber.Add(BigInteger.One); crlGen.AddExtension(X509Extensions.CrlNumber, false, new CrlNumber(crlSerialNumber)); // generate updated CRL X509Crl updatedCrl = crlGen.Generate(signatureFactory); return(new X509CRL(updatedCrl.GetEncoded())); } }
/** * Computes the <code>[τ]</code>-adic window NAF of an element * <code>λ</code> of <code><b>Z</b>[τ]</code>. * @param mu The parameter μ of the elliptic curve. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code> of which to compute the * <code>[τ]</code>-adic NAF. * @param width The window width of the resulting WNAF. * @param pow2w 2<sup>width</sup>. * @param tw The auxiliary value <code>t<sub>w</sub></code>. * @param alpha The <code>α<sub>u</sub></code>'s for the window width. * @return The <code>[τ]</code>-adic window NAF of * <code>λ</code>. */ public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda, sbyte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha) { if (!((mu == 1) || (mu == -1))) { throw new ArgumentException("mu must be 1 or -1"); } BigInteger norm = Norm(mu, lambda); // Ceiling of log2 of the norm int log2Norm = norm.BitLength; // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52 int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width; // The array holding the TNAF sbyte[] u = new sbyte[maxLength]; // 2^(width - 1) BigInteger pow2wMin1 = pow2w.ShiftRight(1); // Split lambda into two BigIntegers to simplify calculations BigInteger r0 = lambda.u; BigInteger r1 = lambda.v; int i = 0; // while lambda <> (0, 0) while (!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero)))) { // if r0 is odd if (r0.TestBit(0)) { // uUnMod = r0 + r1*tw Mod 2^width BigInteger uUnMod = r0.Add(r1.Multiply(tw)).Mod(pow2w); sbyte uLocal; // if uUnMod >= 2^(width - 1) if (uUnMod.CompareTo(pow2wMin1) >= 0) { uLocal = (sbyte)uUnMod.Subtract(pow2w).IntValue; } else { uLocal = (sbyte)uUnMod.IntValue; } // uLocal is now in [-2^(width-1), 2^(width-1)-1] u[i] = uLocal; bool s = true; if (uLocal < 0) { s = false; uLocal = (sbyte)-uLocal; } // uLocal is now >= 0 if (s) { r0 = r0.Subtract(alpha[uLocal].u); r1 = r1.Subtract(alpha[uLocal].v); } else { r0 = r0.Add(alpha[uLocal].u); r1 = r1.Add(alpha[uLocal].v); } } else { u[i] = 0; } BigInteger t = r0; if (mu == 1) { r0 = r1.Add(r0.ShiftRight(1)); } else { // mu == -1 r0 = r1.Subtract(r0.ShiftRight(1)); } r1 = t.ShiftRight(1).Negate(); i++; } return(u); }
/** * Computes the <code>τ</code>-adic NAF (non-adjacent form) of an * element <code>λ</code> of <code><b>Z</b>[τ]</code>. * @param mu The parameter <code>μ</code> of the elliptic curve. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code>. * @return The <code>τ</code>-adic NAF of <code>λ</code>. */ public static sbyte[] TauAdicNaf(sbyte mu, ZTauElement lambda) { if (!((mu == 1) || (mu == -1))) { throw new ArgumentException("mu must be 1 or -1"); } BigInteger norm = Norm(mu, lambda); // Ceiling of log2 of the norm int log2Norm = norm.BitLength; // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52 int maxLength = log2Norm > 30 ? log2Norm + 4 : 34; // The array holding the TNAF sbyte[] u = new sbyte[maxLength]; int i = 0; // The actual length of the TNAF int length = 0; BigInteger r0 = lambda.u; BigInteger r1 = lambda.v; while (!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero)))) { // If r0 is odd if (r0.TestBit(0)) { u[i] = (sbyte)BigInteger.Two.Subtract((r0.Subtract(r1.ShiftLeft(1))).Mod(Four)).IntValue; // r0 = r0 - u[i] if (u[i] == 1) { r0 = r0.ClearBit(0); } else { // u[i] == -1 r0 = r0.Add(BigInteger.One); } length = i; } else { u[i] = 0; } BigInteger t = r0; BigInteger s = r0.ShiftRight(1); if (mu == 1) { r0 = r1.Add(s); } else { // mu == -1 r0 = r1.Subtract(s); } r1 = t.ShiftRight(1).Negate(); i++; } length++; // Reduce the TNAF array to its actual length sbyte[] tnaf = new sbyte[length]; Array.Copy(u, 0, tnaf, 0, length); return(tnaf); }
/** * Rounds an element <code>λ</code> of <code><b>R</b>[τ]</code> * to an element of <code><b>Z</b>[τ]</code>, such that their difference * has minimal norm. <code>λ</code> is given as * <code>λ = λ<sub>0</sub> + λ<sub>1</sub>τ</code>. * @param lambda0 The component <code>λ<sub>0</sub></code>. * @param lambda1 The component <code>λ<sub>1</sub></code>. * @param mu The parameter <code>μ</code> of the elliptic curve. Must * equal 1 or -1. * @return The rounded element of <code><b>Z</b>[τ]</code>. * @throws ArgumentException if <code>lambda0</code> and * <code>lambda1</code> do not have same scale. */ public static ZTauElement Round(SimpleBigDecimal lambda0, SimpleBigDecimal lambda1, sbyte mu) { int scale = lambda0.Scale; if (lambda1.Scale != scale) { throw new ArgumentException("lambda0 and lambda1 do not have same scale"); } if (!((mu == 1) || (mu == -1))) { throw new ArgumentException("mu must be 1 or -1"); } BigInteger f0 = lambda0.Round(); BigInteger f1 = lambda1.Round(); SimpleBigDecimal eta0 = lambda0.Subtract(f0); SimpleBigDecimal eta1 = lambda1.Subtract(f1); // eta = 2*eta0 + mu*eta1 SimpleBigDecimal eta = eta0.Add(eta0); if (mu == 1) { eta = eta.Add(eta1); } else { // mu == -1 eta = eta.Subtract(eta1); } // check1 = eta0 - 3*mu*eta1 // check2 = eta0 + 4*mu*eta1 SimpleBigDecimal threeEta1 = eta1.Add(eta1).Add(eta1); SimpleBigDecimal fourEta1 = threeEta1.Add(eta1); SimpleBigDecimal check1; SimpleBigDecimal check2; if (mu == 1) { check1 = eta0.Subtract(threeEta1); check2 = eta0.Add(fourEta1); } else { // mu == -1 check1 = eta0.Add(threeEta1); check2 = eta0.Subtract(fourEta1); } sbyte h0 = 0; sbyte h1 = 0; // if eta >= 1 if (eta.CompareTo(BigInteger.One) >= 0) { if (check1.CompareTo(MinusOne) < 0) { h1 = mu; } else { h0 = 1; } } else { // eta < 1 if (check2.CompareTo(BigInteger.Two) >= 0) { h1 = mu; } } // if eta < -1 if (eta.CompareTo(MinusOne) < 0) { if (check1.CompareTo(BigInteger.One) >= 0) { h1 = (sbyte)-mu; } else { h0 = -1; } } else { // eta >= -1 if (check2.CompareTo(MinusTwo) < 0) { h1 = (sbyte)-mu; } } BigInteger q0 = f0.Add(BigInteger.ValueOf(h0)); BigInteger q1 = f1.Add(BigInteger.ValueOf(h1)); return(new ZTauElement(q0, q1)); }
public void TestModPow() { try { two.ModPow(one, zero); Assert.Fail("expected ArithmeticException"); } catch (ArithmeticException) {} Assert.AreEqual(zero, zero.ModPow(zero, one)); Assert.AreEqual(one, zero.ModPow(zero, two)); Assert.AreEqual(zero, two.ModPow(one, one)); Assert.AreEqual(one, two.ModPow(zero, two)); for (int i = 0; i < 10; ++i) { IBigInteger m = BigInteger.ProbablePrime(10 + i * 3, _random); IBigInteger x = new BigInteger(m.BitLength - 1, _random); Assert.AreEqual(x, x.ModPow(m, m)); if (x.SignValue != 0) { Assert.AreEqual(zero, zero.ModPow(x, m)); Assert.AreEqual(one, x.ModPow(m.Subtract(one), m)); } IBigInteger y = new BigInteger(m.BitLength - 1, _random); IBigInteger n = new BigInteger(m.BitLength - 1, _random); IBigInteger n3 = n.ModPow(three, m); IBigInteger resX = n.ModPow(x, m); IBigInteger resY = n.ModPow(y, m); IBigInteger res = resX.Multiply(resY).Mod(m); IBigInteger res3 = res.ModPow(three, m); Assert.AreEqual(res3, n3.ModPow(x.Add(y), m)); IBigInteger a = x.Add(one); // Make sure it's not zero IBigInteger b = y.Add(one); // Make sure it's not zero Assert.AreEqual(a.ModPow(b, m).ModInverse(m), a.ModPow(b.Negate(), m)); } }
/// <summary> /// Divides each coefficient by a <c>BigInteger</c> and rounds the result to the nearest whole number. /// <para>Does not return a new polynomial but modifies this polynomial.</para> /// </summary> /// /// <param name="Divisor">The divisor</param> public void Divide(BigInteger Divisor) { BigInteger d = Divisor.Add(BigInteger.One.ShiftRight(1)); // d = ceil(divisor/2) for (int i = 0; i < Coeffs.Length; i++) { Coeffs[i] = Coeffs[i].Signum() > 0 ? Coeffs[i].Add(d) : Coeffs[i].Add(d.Negate()); Coeffs[i] = Coeffs[i].Divide(Divisor); } }
public static BigInteger Add(this BigInteger bigInt, BigInteger i, BigInteger j) { return(i.Add(j).Mod(bigInt)); }
public void Add_zero_to_pos() { BigInteger x = new BigInteger(0, new uint[0]); BigInteger y = new BigInteger(1, new uint[] { 0x3 }); BigInteger z = x.Add(y); Expect(z,EqualTo(y)); }
public void Add(int count, int leftBits, int rightBits) { RunBenchmark(count, leftBits, rightBits, (l, r) => BigInteger.Add(l, r)); }
/// <summary> /// Compute the next probable prime greater than <c>N</c> with the specified certainty /// </summary> /// /// <param name="X">An integer number</param> /// <param name="Certainty">The certainty that the generated number is prime</param> /// /// <returns>Returns the next prime greater than <c>N</c></returns> public static BigInteger NextProbablePrime(BigInteger X, int Certainty) { if (X.Signum() < 0 || X.Signum() == 0 || X.Equals(ONE)) return TWO; BigInteger result = X.Add(ONE); // Ensure an odd number if (!result.TestBit(0)) result = result.Add(ONE); while (true) { // Do cheap "pre-test" if applicable if (result.BitLength > 6) { long r = result.Remainder(BigInteger.ValueOf(SMALL_PRIME_PRODUCT)).ToInt64(); if ((r % 3 == 0) || (r % 5 == 0) || (r % 7 == 0) || (r % 11 == 0) || (r % 13 == 0) || (r % 17 == 0) || (r % 19 == 0) || (r % 23 == 0) || (r % 29 == 0) || (r % 31 == 0) || (r % 37 == 0) || (r % 41 == 0)) { result = result.Add(TWO); continue; // Candidate is composite; try another } } // All candidates of bitLength 2 and 3 are prime by this point if (result.BitLength < 4) return result; // The expensive test if (result.IsProbablePrime(Certainty)) return result; result = result.Add(TWO); } }
/* * Finds a pair of prime BigInteger's {p, q: p = 2q + 1} * * (see: Handbook of Applied Cryptography 4.86) */ internal static BigInteger[] GenerateSafePrimes(int size, int certainty, SecureRandom random) { BigInteger p, q; int qLength = size - 1; int minWeight = size >> 2; if (size <= 32) { for (;;) { q = new BigInteger(qLength, 2, random); p = q.ShiftLeft(1).Add(BigInteger.One); if (!p.IsProbablePrime(certainty)) { continue; } if (certainty > 2 && !q.IsProbablePrime(certainty - 2)) { continue; } break; } } else { // Note: Modified from Java version for speed for (;;) { q = new BigInteger(qLength, 0, random); retry: for (int i = 0; i < primeLists.Length; ++i) { int test = q.Remainder(BigPrimeProducts[i]).IntValue; if (i == 0) { int rem3 = test % 3; if (rem3 != 2) { int diff = 2 * rem3 + 2; q = q.Add(BigInteger.ValueOf(diff)); test = (test + diff) % primeProducts[i]; } } int[] primeList = primeLists[i]; for (int j = 0; j < primeList.Length; ++j) { int prime = primeList[j]; int qRem = test % prime; if (qRem == 0 || qRem == (prime >> 1)) { q = q.Add(Six); goto retry; } } } if (q.BitLength != qLength) { continue; } if (!q.RabinMillerTest(2, random)) { continue; } p = q.ShiftLeft(1).Add(BigInteger.One); if (!p.RabinMillerTest(certainty, random)) { continue; } if (certainty > 2 && !q.RabinMillerTest(certainty - 2, random)) { continue; } /* * Require a minimum weight of the NAF representation, since low-weight primes may be * weak against a version of the number-field-sieve for the discrete-logarithm-problem. * * See "The number field sieve for integers of low weight", Oliver Schirokauer. */ if (WNafUtilities.GetNafWeight(p) < minWeight) { continue; } break; } } return(new BigInteger[] { p, q }); }
public bool IsSignatureValid(byte[] messageHash, byte[] signature, byte[] publicKey) { int len = 128; if (signature.Length != len) { return(false); } // Create Q byte[] xByte = new byte[len / 2]; Array.Copy(publicKey, 0, xByte, 0, len / 2); BigInteger tmpX = new BigInteger(1, xByte); byte[] yByte = new byte[len / 2]; Array.Copy(publicKey, len / 2, yByte, 0, len / 2); BigInteger tmpY = new BigInteger(1, yByte); Point P_Q = new Point(tmpX, tmpY); // Stage 1 byte[] rByte = new byte[len / 2]; Array.Copy(signature, 0, rByte, 0, len / 2); BigInteger r = new BigInteger(1, rByte); if (r.CompareTo(BigInteger.Zero) <= 0 || r.CompareTo(Q) >= 0) { return(false); } byte[] sByte = new byte[len / 2]; Array.Copy(signature, len / 2, sByte, 0, len / 2); BigInteger s = new BigInteger(1, sByte); if (s.CompareTo(BigInteger.Zero) <= 0 || s.CompareTo(Q) >= 0) { return(false); } if (messageHash.Length != 64) { throw new Exception("Hash must be 64 bytes length!"); } // Stage 2 byte[] h = messageHash; // Stage 3 BigInteger a = new BigInteger(1, h); BigInteger e = a.Mod(Q); if (e.Equals(BigInteger.Zero)) { e = new BigInteger("1"); } // Stage 4 BigInteger v = e.ModInverse(Q); // Stage 5 BigInteger z1 = s.Multiply(v).Mod(Q); BigInteger z2 = r.Multiply(v).Negate().Mod(Q); if (z2.CompareTo(BigInteger.Zero) < 0) { z2 = z2.Add(Q); } // Stage 6 Point C = Curve.Add(Curve.Multiply(P, z1), Curve.Multiply(P_Q, z2)); BigInteger R = C.X.Mod(Q); // Stage 7 if (R.Equals(r)) { return(true); } else { return(false); } }
public void WeightFilter() { var w1 = new Woo { Value = 1 }; var w2 = new Woo { Value = 2 }; var list = new List <Woo> { w1, w2 }; var ret = list.WeightedFilter(0.3, 0.6, p => p.Value, (p, w) => new Result { Info = p, Weight = w }); var sum = BigInteger.Zero; foreach (Result res in ret) { sum = BigInteger.Add(res.Weight, sum); } sum.Should().Be(BigInteger.Zero); var w3 = new Woo { Value = 3 }; var list2 = new List <Woo> { w1, w2, w3 }; var ret2 = list2.WeightedFilter(0.3, 0.4, p => p.Value, (p, w) => new Result { Info = p, Weight = w }); sum = BigInteger.Zero; foreach (Result res in ret2) { sum = BigInteger.Add(res.Weight, sum); } sum.Should().Be(BigInteger.Zero); CheckArgumentOutOfRangeException(-1, 0.4, p => p.Value, list2); CheckArgumentOutOfRangeException(0.2, 1.4, p => p.Value, list2); CheckArgumentOutOfRangeException(0.8, 0.3, p => p.Value, list2); CheckArgumentOutOfRangeException(0.3, 0.8, p => p.Value, list2); CheckArgumentNullException(0.3, 0.6, null, list2); CheckArgumentNullException(0.3, 0.4, p => p.Value, null); list2.WeightedFilter(0.3, 0.3, p => p.Value, (p, w) => new Result { Info = p, Weight = w }).WeightedAverage(p => p.Weight, p => p.Weight).Should().Be(0); var list3 = new List <Woo>(); list3.WeightedFilter(0.3, 0.6, p => p.Value, (p, w) => new Result { Info = p, Weight = w }).WeightedAverage(p => p.Weight, p => p.Weight).Should().Be(0); }
public static string oldAddrToCashAddr(string oldAddress, out bool isP2PKH, out bool mainnet) { // BigInteger wouldn't be needed, but that would result in the use a MIT License BigInteger address = new BigInteger(0); BigInteger baseFiftyEight = new BigInteger(58); for (int x = 0; x < oldAddress.Length; x++) { int value = DICT_BASE58[oldAddress[x]]; if (value != -1) { address = BigInteger.Multiply(address, baseFiftyEight); address = BigInteger.Add(address, new BigInteger(value)); } else { throw new CashAddrConversionException("Address contains unexpected character."); } } int numZeros = 0; for (; (numZeros < oldAddress.Length) && (oldAddress[numZeros] == Convert.ToChar("1")); numZeros++) { } byte[] addrBytes = address.ToByteArray(); Array.Reverse(addrBytes); // Reminder, addrBytes was converted from BigInteger. So the first byte, // the sign byte should be skipped, **if exists** if (addrBytes[0] == 0) { // because of 0xc4 var temp = new List <byte>(addrBytes); temp.RemoveAt(0); addrBytes = temp.ToArray(); } if (numZeros > 0) { var temp = new List <byte>(addrBytes); for (; numZeros != 0; numZeros--) { temp.Insert(0, 0); } addrBytes = temp.ToArray(); } if (addrBytes.Length != 25) { throw new CashAddrConversionException("Address to be decoded is shorter or longer than expected!"); } switch (addrBytes[0]) { case 0x00: isP2PKH = true; mainnet = true; break; case 0x05: isP2PKH = false; mainnet = true; break; case 0x6f: isP2PKH = true; mainnet = false; break; case 0xc4: isP2PKH = false; mainnet = false; break; case 0x1c: // BitPay P2PKH, obsolete! case 0x28: // BitPay P2SH, obsolete! default: throw new CashAddrConversionException("Unexpected address byte."); } if (addrBytes.Length != 25) { throw new CashAddrConversionException("Old address is longer or shorter than expected."); } SHA256 hasher = SHA256Managed.Create(); byte[] checksum = hasher.ComputeHash(hasher.ComputeHash(addrBytes, 0, 21)); if (addrBytes[21] != checksum[0] || addrBytes[22] != checksum[1] || addrBytes[23] != checksum[2] || addrBytes[24] != checksum[3]) { throw new CashAddrConversionException("Address checksum doesn't match. Have you made a mistake while typing it?"); } addrBytes[0] = (byte)(isP2PKH ? 0x00 : 0x08); byte[] cashAddr = convertBitsEightToFive(addrBytes); var ret = new System.Text.StringBuilder(mainnet ? "bitcoincash:" : "bchtest:"); // https://play.golang.org/p/sM_CE4AQ7Vp ulong mod = PolyMod(cashAddr, (ulong)(mainnet ? 1058337025301 : 584719417569)); for (int i = 0; i < 8; ++i) { cashAddr[i + 34] = (byte)((mod >> (5 * (7 - i))) & 0x1f); } for (int i = 0; i < cashAddr.Length; i++) { ret.Append(CHARSET_CASHADDR[cashAddr[i]]); } return(ret.ToString()); }
public void generate() { SHA256 sha256 = SHA256.Create(); elGamal.h = new BigInteger(sha256.ComputeHash(Document.Data)); if (elGamal.h.SignValue < 0) { elGamal.h = elGamal.h.Abs(); } BigInteger currentQ; BigInteger currentP; do { currentQ = BigInteger.ProbablePrime(264, new Random()); currentP = currentQ.Multiply(BigInteger.Two); currentP = currentP.Add(BigInteger.One); } while (!currentP.IsProbablePrime(50)); elGamal.p = currentP; elGamal.p_prev = elGamal.p.Subtract(BigInteger.One); elGamal.q = currentQ; for (BigInteger i = BigInteger.Two; i.CompareTo(elGamal.p_prev) < 0; i = i.Add(BigInteger.One)) { if (i.ModPow(elGamal.q, elGamal.p).CompareTo(BigInteger.One) != 0) { elGamal.g = i; break; } } elGamal.x = new BigInteger(256, new Random()); elGamal.y = elGamal.g.ModPow(elGamal.x, elGamal.p); BigInteger currentK; do { currentK = new BigInteger(256, new Random()); } while (currentK.Gcd(elGamal.p_prev).CompareTo(BigInteger.One) != 0); elGamal.k = currentK; elGamal.r = elGamal.g.ModPow(elGamal.k, elGamal.p); BigInteger tmp_hxr = elGamal.h.Subtract(elGamal.x.Multiply(elGamal.r)); elGamal.u = tmp_hxr.Mod(elGamal.p_prev); check = evklid.gcd(elGamal.k, elGamal.p_prev); if (evklid.mY.CompareTo(BigInteger.Zero) < 0) { elGamal.k_revers = evklid.mY.Add(elGamal.p_prev); } else { elGamal.k_revers = evklid.mY; } BigInteger tmp_k_revers_u = elGamal.k_revers.Multiply(elGamal.u); elGamal.s = tmp_k_revers_u.Mod(elGamal.p_prev); BigInteger tmp_yr = elGamal.y.ModPow(elGamal.r, elGamal.p); BigInteger tmp_rs = elGamal.r.ModPow(elGamal.s, elGamal.p); BigInteger tmp_yrs = tmp_yr.Multiply(tmp_rs).Mod(elGamal.p); BigInteger tmp_ghp = elGamal.g.ModPow(elGamal.h, elGamal.p); check_left = tmp_yrs; check_right = tmp_ghp; }
/// <summary> /// Recreates the private key of the parent from the private key of the child /// combinated with the public key of the parent (hardened children cannot be /// used to recreate the parent). /// </summary> public ExtKey GetParentExtKey(ExtPubKey parent) { if (parent == null) { throw new ArgumentNullException(nameof(parent)); } if (Depth == 0) { throw new InvalidOperationException("This ExtKey is the root key of the HD tree"); } if (IsHardened) { throw new InvalidOperationException("This private key is hardened, so you can't get its parent"); } var expectedFingerPrint = parent.CalculateChildFingerprint(); if (parent.Depth != Depth - 1 || !expectedFingerPrint.SequenceEqual(_vchFingerprint)) { throw new ArgumentException("The parent ExtPubKey is not the immediate parent of this ExtKey", nameof(parent)); } byte[] l = null; var ll = new byte[32]; var lr = new byte[32]; var pubKey = parent.PubKey.ToBytes(); l = Hashes.BIP32Hash(parent._vchChainCode, _nChild, pubKey[0], pubKey.SafeSubArray(1)); Array.Copy(l, ll, 32); Array.Copy(l, 32, lr, 0, 32); var ccChild = lr; var parse256LL = new BigInteger(1, ll); var N = ECKey.Curve.N; if (!ccChild.SequenceEqual(_vchChainCode)) { throw new InvalidOperationException( "The derived chain code of the parent is not equal to this child chain code"); } var keyBytes = PrivateKey.ToBytes(); var key = new BigInteger(1, keyBytes); var kPar = key.Add(parse256LL.Negate()).Mod(N); var keyParentBytes = kPar.ToByteArrayUnsigned(); if (keyParentBytes.Length < 32) { keyParentBytes = new byte[32 - keyParentBytes.Length].Concat(keyParentBytes).ToArray(); } var parentExtKey = new ExtKey { _vchChainCode = parent._vchChainCode, _nDepth = parent.Depth, _vchFingerprint = parent.Fingerprint, _nChild = parent._nChild, _key = new Key(keyParentBytes) }; return(parentExtKey); }
public static ZTauElement Round(SimpleBigDecimal lambda0, SimpleBigDecimal lambda1, sbyte mu) { SimpleBigDecimal num7; SimpleBigDecimal num8; int scale = lambda0.Scale; if (lambda1.Scale != scale) { throw new ArgumentException("lambda0 and lambda1 do not have same scale"); } if ((mu != 1) && (mu != -1)) { throw new ArgumentException("mu must be 1 or -1"); } BigInteger b = lambda0.Round(); BigInteger integer2 = lambda1.Round(); SimpleBigDecimal num2 = lambda0.Subtract(b); SimpleBigDecimal num3 = lambda1.Subtract(integer2); SimpleBigDecimal num4 = num2.Add(num2); if (mu == 1) { num4 = num4.Add(num3); } else { num4 = num4.Subtract(num3); } SimpleBigDecimal num5 = num3.Add(num3).Add(num3); SimpleBigDecimal num6 = num5.Add(num3); if (mu == 1) { num7 = num2.Subtract(num5); num8 = num2.Add(num6); } else { num7 = num2.Add(num5); num8 = num2.Subtract(num6); } sbyte num9 = 0; sbyte num10 = 0; if (num4.CompareTo(BigInteger.One) >= 0) { if (num7.CompareTo(MinusOne) < 0) { num10 = mu; } else { num9 = 1; } } else if (num8.CompareTo(BigInteger.Two) >= 0) { num10 = mu; } if (num4.CompareTo(MinusOne) < 0) { if (num7.CompareTo(BigInteger.One) >= 0) { num10 = (sbyte)-((int)mu); } else { num9 = -1; } } else if (num8.CompareTo(MinusTwo) < 0) { num10 = (sbyte)-((int)mu); } BigInteger u = b.Add(BigInteger.ValueOf((long)num9)); return(new ZTauElement(u, integer2.Add(BigInteger.ValueOf((long)num10)))); }
// 5.4 pg 29 /** * return true if the value r and s represent a DSA signature for * the passed in message (for standard DSA the message should be * a SHA-1 hash of the real message to be verified). */ public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) { BigInteger n = key.Parameters.N; // r and s should both in the range [1,n-1] if (r.SignValue < 1 || s.SignValue < 1 || r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0) { return(false); } BigInteger e = CalculateE(n, message); BigInteger c = s.ModInverse(n); BigInteger u1 = e.Multiply(c).Mod(n); BigInteger u2 = r.Multiply(c).Mod(n); ECPoint G = key.Parameters.G; ECPoint Q = ((ECPublicKeyParameters)key).Q; ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2); if (point.IsInfinity) { return(false); } /* * If possible, avoid normalizing the point (to save a modular inversion in the curve field). * * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'. * If the cofactor is known and small, we generate those possible field values and project each * of them to the same "denominator" (depending on the particular projective coordinates in use) * as the calculated point.X. If any of the projected values matches point.X, then we have: * (point.X / Denominator mod p) mod n == r * as required, and verification succeeds. * * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in * the libsecp256k1 project (https://github.com/bitcoin/secp256k1). */ ECCurve curve = point.Curve; if (curve != null) { BigInteger cofactor = curve.Cofactor; if (cofactor != null && cofactor.CompareTo(Eight) <= 0) { ECFieldElement D = GetDenominator(curve.CoordinateSystem, point); if (D != null && !D.IsZero) { ECFieldElement X = point.XCoord; while (curve.IsValidFieldElement(r)) { ECFieldElement R = curve.FromBigInteger(r).Multiply(D); if (R.Equals(X)) { return(true); } r = r.Add(n); } return(false); } } } BigInteger v = point.Normalize().AffineXCoord.ToBigInteger().Mod(n); return(v.Equals(r)); }
public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda, sbyte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha) { if ((mu != 1) && (mu != -1)) { throw new ArgumentException("mu must be 1 or -1"); } int bitLength = Norm(mu, lambda).BitLength; int num2 = (bitLength <= 30) ? (0x22 + width) : ((bitLength + 4) + width); sbyte[] numArray = new sbyte[num2]; BigInteger integer2 = pow2w.ShiftRight(1); BigInteger u = lambda.u; BigInteger v = lambda.v; for (int i = 0; !u.Equals(BigInteger.Zero) || !v.Equals(BigInteger.Zero); i++) { if (u.TestBit(0)) { sbyte intValue; BigInteger integer5 = u.Add(v.Multiply(tw)).Mod(pow2w); if (integer5.CompareTo(integer2) >= 0) { intValue = (sbyte)integer5.Subtract(pow2w).IntValue; } else { intValue = (sbyte)integer5.IntValue; } numArray[i] = intValue; bool flag = true; if (intValue < 0) { flag = false; intValue = (sbyte)-((int)intValue); } if (flag) { u = u.Subtract(alpha[(int)intValue].u); v = v.Subtract(alpha[(int)intValue].v); } else { u = u.Add(alpha[(int)intValue].u); v = v.Add(alpha[(int)intValue].v); } } else { numArray[i] = 0; } BigInteger integer6 = u; if (mu == 1) { u = v.Add(u.ShiftRight(1)); } else { u = v.Subtract(u.ShiftRight(1)); } v = integer6.ShiftRight(1).Negate(); } return(numArray); }
/** * return a sqrt root - the routine verifies that the calculation * returns the right value - if none exists it returns null. */ public override ECFieldElement Sqrt() { if (IsZero || IsOne) { return(this); } if (!q.TestBit(0)) { throw Platform.CreateNotImplementedException("even value of q"); } if (q.TestBit(1)) // q == 4m + 3 { BigInteger e = q.ShiftRight(2).Add(BigInteger.One); return(CheckSqrt(new FpFieldElement(q, r, x.ModPow(e, q)))); } if (q.TestBit(2)) // q == 8m + 5 { BigInteger t1 = x.ModPow(q.ShiftRight(3), q); BigInteger t2 = ModMult(t1, x); BigInteger t3 = ModMult(t2, t1); if (t3.Equals(BigInteger.One)) { return(CheckSqrt(new FpFieldElement(q, r, t2))); } // TODO This is constant and could be precomputed BigInteger t4 = BigInteger.Two.ModPow(q.ShiftRight(2), q); BigInteger y = ModMult(t2, t4); return(CheckSqrt(new FpFieldElement(q, r, y))); } // q == 8m + 1 BigInteger legendreExponent = q.ShiftRight(1); if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One))) { return(null); } BigInteger X = this.x; BigInteger fourX = ModDouble(ModDouble(X));; BigInteger k = legendreExponent.Add(BigInteger.One), qMinusOne = q.Subtract(BigInteger.One); BigInteger U, V; do { BigInteger P; do { P = BigInteger.Arbitrary(q.BitLength); }while (P.CompareTo(q) >= 0 || !ModReduce(P.Multiply(P).Subtract(fourX)).ModPow(legendreExponent, q).Equals(qMinusOne)); BigInteger[] result = LucasSequence(P, X, k); U = result[0]; V = result[1]; if (ModMult(V, V).Equals(fourX)) { return(new FpFieldElement(q, r, ModHalfAbs(V))); } }while (U.Equals(BigInteger.One) || U.Equals(qMinusOne)); return(null); }
//Procedure B private void procedure_B(int x0, int c, BigInteger[] pq) { //Verify and perform condition: 0<x<2^16; 0<c<2^16; c - odd. while (x0 < 0 || x0 > 65536) { x0 = init_random.NextInt() / 32768; } while ((c < 0 || c > 65536) || (c / 2 == 0)) { c = init_random.NextInt() / 32768 + 1; } BigInteger [] qp = new BigInteger[2]; BigInteger q = null, Q = null, p = null; BigInteger C = BigInteger.ValueOf(c); BigInteger constA16 = BigInteger.ValueOf(19381); //step1 x0 = procedure_A(x0, c, qp, 256); q = qp[0]; //step2 x0 = procedure_A(x0, c, qp, 512); Q = qp[0]; BigInteger[] y = new BigInteger[65]; y[0] = BigInteger.ValueOf(x0); const int tp = 1024; BigInteger qQ = q.Multiply(Q); step3: for (;;) { //step 3 for (int j = 0; j < 64; j++) { y[j + 1] = (y[j].Multiply(constA16).Add(C)).Mod(BigInteger.Two.Pow(16)); } //step 4 BigInteger Y = BigInteger.Zero; for (int j = 0; j < 64; j++) { Y = Y.Add(y[j].ShiftLeft(16 * j)); } y[0] = y[64]; //step 5 //step 6 BigInteger N = BigInteger.One.ShiftLeft(tp - 1).Divide(qQ).Add( Y.ShiftLeft(tp - 1).Divide(qQ.ShiftLeft(1024))); if (N.TestBit(0)) { N = N.Add(BigInteger.One); } //step 7 for (;;) { //step 11 BigInteger qQN = qQ.Multiply(N); if (qQN.BitLength > tp) { goto step3; //step 9 } p = qQN.Add(BigInteger.One); //step10 if (BigInteger.Two.ModPow(qQN, p).CompareTo(BigInteger.One) == 0 && BigInteger.Two.ModPow(q.Multiply(N), p).CompareTo(BigInteger.One) != 0) { pq[0] = p; pq[1] = q; return; } N = N.Add(BigInteger.Two); } } }
/* * Finds a pair of prime BigInteger's {p, q: p = 2q + 1} * * (see: Handbook of Applied Cryptography 4.86) */ internal static BigInteger[] GenerateSafePrimes(int size, int certainty, SecureRandom random) { BigInteger p, q; int qLength = size - 1; if (size <= 32) { for (;;) { q = new BigInteger(qLength, 2, random); p = q.ShiftLeft(1).Add(BigInteger.One); if (p.IsProbablePrime(certainty) && (certainty <= 2 || q.IsProbablePrime(certainty))) break; } } else { // Note: Modified from Java version for speed for (;;) { q = new BigInteger(qLength, 0, random); retry: for (int i = 0; i < primeLists.Length; ++i) { int test = q.Remainder(PrimeProducts[i]).IntValue; if (i == 0) { int rem3 = test % 3; if (rem3 != 2) { int diff = 2 * rem3 + 2; q = q.Add(BigInteger.ValueOf(diff)); test = (test + diff) % primeProducts[i]; } } int[] primeList = primeLists[i]; for (int j = 0; j < primeList.Length; ++j) { int prime = primeList[j]; int qRem = test % prime; if (qRem == 0 || qRem == (prime >> 1)) { q = q.Add(Six); goto retry; } } } if (q.BitLength != qLength) continue; if (!q.RabinMillerTest(2, random)) continue; p = q.ShiftLeft(1).Add(BigInteger.One); if (p.RabinMillerTest(certainty, random) && (certainty <= 2 || q.RabinMillerTest(certainty - 2, random))) break; } } return new BigInteger[] { p, q }; }
//Procedure A private int procedure_A(int x0, int c, BigInteger[] pq, int size) { //Verify and perform condition: 0<x<2^16; 0<c<2^16; c - odd. while (x0 < 0 || x0 > 65536) { x0 = init_random.NextInt() / 32768; } while ((c < 0 || c > 65536) || (c / 2 == 0)) { c = init_random.NextInt() / 32768 + 1; } BigInteger C = BigInteger.ValueOf(c); BigInteger constA16 = BigInteger.ValueOf(19381); //step1 BigInteger[] y = new BigInteger[1]; // begin length = 1 y[0] = BigInteger.ValueOf(x0); //step 2 int[] t = new int[1]; // t - orders; begin length = 1 t[0] = size; int s = 0; for (int i = 0; t[i] >= 17; i++) { // extension array t int[] tmp_t = new int[t.Length + 1]; /////////////// Array.Copy(t, 0, tmp_t, 0, t.Length); // extension t = new int[tmp_t.Length]; // array t Array.Copy(tmp_t, 0, t, 0, tmp_t.Length); /////////////// t[i + 1] = t[i] / 2; s = i + 1; } //step3 BigInteger[] p = new BigInteger[s + 1]; p[s] = new BigInteger("8003", 16); //set min prime number length 16 bit int m = s - 1; //step4 for (int i = 0; i < s; i++) { int rm = t[m] / 16; //step5 step6 : for (;;) { //step 6 BigInteger[] tmp_y = new BigInteger[y.Length]; //////////////// Array.Copy(y, 0, tmp_y, 0, y.Length); // extension y = new BigInteger[rm + 1]; // array y Array.Copy(tmp_y, 0, y, 0, tmp_y.Length); //////////////// for (int j = 0; j < rm; j++) { y[j + 1] = (y[j].Multiply(constA16).Add(C)).Mod(BigInteger.Two.Pow(16)); } //step 7 BigInteger Ym = BigInteger.Zero; for (int j = 0; j < rm; j++) { Ym = Ym.Add(y[j].ShiftLeft(16 * j)); } y[0] = y[rm]; //step 8 //step 9 BigInteger N = BigInteger.One.ShiftLeft(t[m] - 1).Divide(p[m + 1]).Add( Ym.ShiftLeft(t[m] - 1).Divide(p[m + 1].ShiftLeft(16 * rm))); if (N.TestBit(0)) { N = N.Add(BigInteger.One); } //step 10 for (;;) { //step 11 BigInteger NByLastP = N.Multiply(p[m + 1]); if (NByLastP.BitLength > t[m]) { goto step6; //step 12 } p[m] = NByLastP.Add(BigInteger.One); //step13 if (BigInteger.Two.ModPow(NByLastP, p[m]).CompareTo(BigInteger.One) == 0 && BigInteger.Two.ModPow(N, p[m]).CompareTo(BigInteger.One) != 0) { break; } N = N.Add(BigInteger.Two); } if (--m < 0) { pq[0] = p[0]; pq[1] = p[1]; return(y[0].IntValue); //return for procedure B step 2 } break; //step 14 } } return(y[0].IntValue); }
public void Add_pos_first_longer_carry_extend() { BigInteger x = new BigInteger(1, new uint[] { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x22222222 }); BigInteger y = new BigInteger(1, new uint[] { 0x11111111, 0x11111111 }); BigInteger z = x.Add(y); Expect(SameValue(z, 1, new uint[] { 0x00000001, 0x00000000, 0x00000000, 0x11111110, 0x33333333 })); }
/** * * Based on "New Algorithm for Classical Modular Inverse" Róbert Lórencz. * LNCS 2523 (2002) * * @return a^(-1) mod m */ private static BigInteger ModInverseLorencz(BigInteger a, BigInteger modulo) { // PRE: a is coprime with modulo, a < modulo int max = System.Math.Max(a.numberLength, modulo.numberLength); int[] uDigits = new int[max + 1]; // enough place to make all the inplace operation int[] vDigits = new int[max + 1]; Array.Copy(modulo.Digits, 0, uDigits, 0, modulo.numberLength); Array.Copy(a.Digits, 0, vDigits, 0, a.numberLength); BigInteger u = new BigInteger(modulo.Sign, modulo.numberLength, uDigits); BigInteger v = new BigInteger(a.Sign, a.numberLength, vDigits); BigInteger r = new BigInteger(0, 1, new int[max + 1]); // BigInteger.ZERO; BigInteger s = new BigInteger(1, 1, new int[max + 1]); s.Digits[0] = 1; // r == 0 && s == 1, but with enough place int coefU = 0, coefV = 0; int n = modulo.BitLength; int k; while (!IsPowerOfTwo(u, coefU) && !IsPowerOfTwo(v, coefV)) { // modification of original algorithm: I calculate how many times the algorithm will enter in the same branch of if k = HowManyIterations(u, n); if (k != 0) { BitLevel.InplaceShiftLeft(u, k); if (coefU >= coefV) BitLevel.InplaceShiftLeft(r, k); else { BitLevel.InplaceShiftRight(s, System.Math.Min(coefV - coefU, k)); if (k - (coefV - coefU) > 0) BitLevel.InplaceShiftLeft(r, k - coefV + coefU); } coefU += k; } k = HowManyIterations(v, n); if (k != 0) { BitLevel.InplaceShiftLeft(v, k); if (coefV >= coefU) BitLevel.InplaceShiftLeft(s, k); else { BitLevel.InplaceShiftRight(r, System.Math.Min(coefU - coefV, k)); if (k - (coefU - coefV) > 0) BitLevel.InplaceShiftLeft(s, k - coefU + coefV); } coefV += k; } if (u.Sign == v.Sign) { if (coefU <= coefV) { Elementary.completeInPlaceSubtract(u, v); Elementary.completeInPlaceSubtract(r, s); } else { Elementary.completeInPlaceSubtract(v, u); Elementary.completeInPlaceSubtract(s, r); } } else { if (coefU <= coefV) { Elementary.completeInPlaceAdd(u, v); Elementary.completeInPlaceAdd(r, s); } else { Elementary.completeInPlaceAdd(v, u); Elementary.completeInPlaceAdd(s, r); } } if (v.Sign == 0 || u.Sign == 0) { // math.19: BigInteger not invertible throw new ArithmeticException(Messages.math19); } } if (IsPowerOfTwo(v, coefV)) { r = s; if (v.Sign != u.Sign) u = u.Negate(); } if (u.TestBit(n)) { if (r.Sign < 0) r = r.Negate(); else r = modulo.Subtract(r); } if (r.Sign < 0) r = r.Add(modulo); return r; }
public void Add_pos_same_length_no_carry() { BigInteger x = new BigInteger(1, new uint[] { 0x12345678, 0x12345678 }); BigInteger y = new BigInteger(1, new uint[] { 0x23456789, 0x13243546 }); BigInteger z = x.Add(y); Expect(SameValue(z, 1, new uint[] { 0x3579BE01, 0x25588BBE })); }
protected virtual BigInteger ModReduce(BigInteger x) { if (r == null) { x = x.Mod(q); } else { bool negative = x.SignValue < 0; if (negative) { x = x.Abs(); } int qLen = q.BitLength; if (r.SignValue > 0) { BigInteger qMod = BigInteger.One.ShiftLeft(qLen); bool rIsOne = r.Equals(BigInteger.One); while (x.BitLength > (qLen + 1)) { BigInteger u = x.ShiftRight(qLen); BigInteger v = x.Remainder(qMod); if (!rIsOne) { u = u.Multiply(r); } x = u.Add(v); } } else { int d = ((qLen - 1) & 31) + 1; BigInteger mu = r.Negate(); BigInteger u = mu.Multiply(x.ShiftRight(qLen - d)); BigInteger quot = u.ShiftRight(qLen + d); BigInteger v = quot.Multiply(q); BigInteger bk1 = BigInteger.One.ShiftLeft(qLen + d); v = v.Remainder(bk1); x = x.Remainder(bk1); x = x.Subtract(v); if (x.SignValue < 0) { x = x.Add(bk1); } } while (x.CompareTo(q) >= 0) { x = x.Subtract(q); } if (negative && x.SignValue != 0) { x = q.Subtract(x); } } return x; }
//Procedure B' private void procedure_Bb(long x0, long c, BigInteger[] pq) { //Verify and perform condition: 0<x<2^32; 0<c<2^32; c - odd. while (x0 < 0 || x0 > 4294967296L) { x0 = init_random.NextInt() * 2; } while ((c < 0 || c > 4294967296L) || (c / 2 == 0)) { c = init_random.NextInt() * 2 + 1; } BigInteger [] qp = new BigInteger[2]; BigInteger q = null, Q = null, p = null; BigInteger C = BigInteger.ValueOf(c); BigInteger constA32 = BigInteger.ValueOf(97781173); //step1 x0 = procedure_Aa(x0, c, qp, 256); q = qp[0]; //step2 x0 = procedure_Aa(x0, c, qp, 512); Q = qp[0]; BigInteger[] y = new BigInteger[33]; y[0] = BigInteger.ValueOf(x0); const int tp = 1024; BigInteger qQ = q.Multiply(Q); step3: for (;;) { //step 3 for (int j = 0; j < 32; j++) { y[j + 1] = (y[j].Multiply(constA32).Add(C)).Mod(BigInteger.Two.Pow(32)); } //step 4 BigInteger Y = BigInteger.Zero; for (int j = 0; j < 32; j++) { Y = Y.Add(y[j].ShiftLeft(32 * j)); } y[0] = y[32]; //step 5 //step 6 BigInteger N = BigInteger.One.ShiftLeft(tp - 1).Divide(qQ).Add( Y.ShiftLeft(tp - 1).Divide(qQ.ShiftLeft(1024))); if (N.TestBit(0)) { N = N.Add(BigInteger.One); } //step 7 for (;;) { //step 11 BigInteger qQN = qQ.Multiply(N); if (qQN.BitLength > tp) { goto step3; //step 9 } p = qQN.Add(BigInteger.One); //step10 if (BigInteger.Two.ModPow(qQN, p).CompareTo(BigInteger.One) == 0 && BigInteger.Two.ModPow(q.Multiply(N), p).CompareTo(BigInteger.One) != 0) { pq[0] = p; pq[1] = q; return; } N = N.Add(BigInteger.Two); } } }
private static BigInteger ModInverseLorencz(BigInteger X, BigInteger Modulo) { // Based on "New Algorithm for Classical Modular Inverse" Róbert Lórencz. LNCS 2523 (2002) // PRE: a is coprime with modulo, a < modulo int max = System.Math.Max(X._numberLength, Modulo._numberLength); int[] uDigits = new int[max + 1]; // enough place to make all the inplace operation int[] vDigits = new int[max + 1]; Array.Copy(Modulo._digits, 0, uDigits, 0, Modulo._numberLength); Array.Copy(X._digits, 0, vDigits, 0, X._numberLength); BigInteger u = new BigInteger(Modulo._sign, Modulo._numberLength, uDigits); BigInteger v = new BigInteger(X._sign, X._numberLength, vDigits); BigInteger r = new BigInteger(0, 1, new int[max + 1]); // BigInteger.ZERO; BigInteger s = new BigInteger(1, 1, new int[max + 1]); s._digits[0] = 1; // r == 0 && s == 1, but with enough place int coefU = 0, coefV = 0; int n = Modulo.BitLength; int k; while (!IsPowerOfTwo(u, coefU) && !IsPowerOfTwo(v, coefV)) { // modification of original algorithm: I calculate how many times the algorithm will enter in the same branch of if k = HowManyIterations(u, n); if (k != 0) { BitLevel.InplaceShiftLeft(u, k); if (coefU >= coefV) { BitLevel.InplaceShiftLeft(r, k); } else { BitLevel.InplaceShiftRight(s, System.Math.Min(coefV - coefU, k)); if (k - (coefV - coefU) > 0) BitLevel.InplaceShiftLeft(r, k - coefV + coefU); } coefU += k; } k = HowManyIterations(v, n); if (k != 0) { BitLevel.InplaceShiftLeft(v, k); if (coefV >= coefU) { BitLevel.InplaceShiftLeft(s, k); } else { BitLevel.InplaceShiftRight(r, System.Math.Min(coefU - coefV, k)); if (k - (coefU - coefV) > 0) BitLevel.InplaceShiftLeft(s, k - coefU + coefV); } coefV += k; } if (u.Signum() == v.Signum()) { if (coefU <= coefV) { Elementary.CompleteInPlaceSubtract(u, v); Elementary.CompleteInPlaceSubtract(r, s); } else { Elementary.CompleteInPlaceSubtract(v, u); Elementary.CompleteInPlaceSubtract(s, r); } } else { if (coefU <= coefV) { Elementary.CompleteInPlaceAdd(u, v); Elementary.CompleteInPlaceAdd(r, s); } else { Elementary.CompleteInPlaceAdd(v, u); Elementary.CompleteInPlaceAdd(s, r); } } if (v.Signum() == 0 || u.Signum() == 0) throw new ArithmeticException("BigInteger not invertible"); } if (IsPowerOfTwo(v, coefV)) { r = s; if (v.Signum() != u.Signum()) u = u.Negate(); } if (u.TestBit(n)) { if (r.Signum() < 0) r = r.Negate(); else r = Modulo.Subtract(r); } if (r.Signum() < 0) r = r.Add(Modulo); return r; }
protected virtual BigInteger ModAdd(BigInteger x1, BigInteger x2) { BigInteger x3 = x1.Add(x2); if (x3.CompareTo(q) >= 0) { x3 = x3.Subtract(q); } return x3; }
/** * generate suitable parameters for DSA, in line with * <i>FIPS 186-3 A.1 Generation of the FFC Primes p and q</i>. */ protected virtual DsaParameters GenerateParameters_FIPS186_3() { // A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function IDigest d = digest; int outlen = d.GetDigestSize() * 8; // 1. Check that the (L, N) pair is in the list of acceptable (L, N pairs) (see Section 4.2). If // the pair is not in the list, then return INVALID. // Note: checked at initialisation // 2. If (seedlen < N), then return INVALID. // FIXME This should be configurable (must be >= N) int seedlen = N; byte[] seed = new byte[seedlen / 8]; // 3. n = ceiling(L ⁄ outlen) – 1. int n = (L - 1) / outlen; // 4. b = L – 1 – (n ∗ outlen). int b = (L - 1) % outlen; byte[] output = new byte[d.GetDigestSize()]; for (;;) { // 5. Get an arbitrary sequence of seedlen bits as the domain_parameter_seed. random.NextBytes(seed); // 6. U = Hash (domain_parameter_seed) mod 2^(N–1). Hash(d, seed, output); BigInteger U = new BigInteger(1, output).Mod(BigInteger.One.ShiftLeft(N - 1)); // 7. q = 2^(N–1) + U + 1 – ( U mod 2). BigInteger q = U.SetBit(0).SetBit(N - 1); // 8. Test whether or not q is prime as specified in Appendix C.3. // TODO Review C.3 for primality checking if (!q.IsProbablePrime(certainty)) { // 9. If q is not a prime, then go to step 5. continue; } // 10. offset = 1. // Note: 'offset' value managed incrementally byte[] offset = Arrays.Clone(seed); // 11. For counter = 0 to (4L – 1) do int counterLimit = 4 * L; for (int counter = 0; counter < counterLimit; ++counter) { // 11.1 For j = 0 to n do // Vj = Hash ((domain_parameter_seed + offset + j) mod 2^seedlen). // 11.2 W = V0 + (V1 ∗ 2^outlen) + ... + (V^(n–1) ∗ 2^((n–1) ∗ outlen)) + ((Vn mod 2^b) ∗ 2^(n ∗ outlen)). // TODO Assemble w as a byte array BigInteger W = BigInteger.Zero; for (int j = 0, exp = 0; j <= n; ++j, exp += outlen) { Inc(offset); Hash(d, offset, output); BigInteger Vj = new BigInteger(1, output); if (j == n) { Vj = Vj.Mod(BigInteger.One.ShiftLeft(b)); } W = W.Add(Vj.ShiftLeft(exp)); } // 11.3 X = W + 2^(L–1). Comment: 0 ≤ W < 2L–1; hence, 2L–1 ≤ X < 2L. BigInteger X = W.Add(BigInteger.One.ShiftLeft(L - 1)); // 11.4 c = X mod 2q. BigInteger c = X.Mod(q.ShiftLeft(1)); // 11.5 p = X - (c - 1). Comment: p ≡ 1 (mod 2q). BigInteger p = X.Subtract(c.Subtract(BigInteger.One)); // 11.6 If (p < 2^(L - 1)), then go to step 11.9 if (p.BitLength != L) { continue; } // 11.7 Test whether or not p is prime as specified in Appendix C.3. // TODO Review C.3 for primality checking if (p.IsProbablePrime(certainty)) { // 11.8 If p is determined to be prime, then return VALID and the values of p, q and // (optionally) the values of domain_parameter_seed and counter. // TODO Make configurable (8-bit unsigned)? if (usageIndex >= 0) { BigInteger g = CalculateGenerator_FIPS186_3_Verifiable(d, p, q, seed, usageIndex); if (g != null) { return(new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter, usageIndex))); } } { BigInteger g = CalculateGenerator_FIPS186_3_Unverifiable(p, q, random); return(new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter))); } } // 11.9 offset = offset + n + 1. Comment: Increment offset; then, as part of // the loop in step 11, increment counter; if // counter < 4L, repeat steps 11.1 through 11.8. // Note: 'offset' value already incremented in inner loop } // 12. Go to step 5. } }
/// <summary> /// Computes the square root of a BigInteger modulo a prime employing the Shanks-Tonelli algorithm /// </summary> /// /// <param name="X">The value out of which we extract the square root</param> /// <param name="P">The prime modulus that determines the underlying field</param> /// /// <returns>Returns a number <c>B</c> such that B^2 = A (mod P) if <c>A</c> is a quadratic residue modulo <c>P</c></returns> public static BigInteger Ressol(BigInteger X, BigInteger P) { BigInteger v = null; if (X.CompareTo(ZERO) < 0) X = X.Add(P); if (X.Equals(ZERO)) return ZERO; if (P.Equals(TWO)) return X; // p = 3 mod 4 if (P.TestBit(0) && P.TestBit(1)) { if (Jacobi(X, P) == 1) { // a quadr. residue mod p v = P.Add(ONE); // v = p+1 v = v.ShiftRight(2); // v = v/4 return X.ModPow(v, P); // return a^v mod p } throw new ArgumentException("No quadratic residue: " + X + ", " + P); } long t = 0; // initialization // compute k and s, where p = 2^s (2k+1) +1 BigInteger k = P.Subtract(ONE); // k = p-1 long s = 0; while (!k.TestBit(0)) { // while k is even s++; // s = s+1 k = k.ShiftRight(1); // k = k/2 } k = k.Subtract(ONE); // k = k - 1 k = k.ShiftRight(1); // k = k/2 // initial values BigInteger r = X.ModPow(k, P); // r = a^k mod p BigInteger n = r.Multiply(r).Remainder(P); // n = r^2 % p n = n.Multiply(X).Remainder(P); // n = n * a % p r = r.Multiply(X).Remainder(P); // r = r * a %p if (n.Equals(ONE)) { return r; } // non-quadratic residue BigInteger z = TWO; // z = 2 while (Jacobi(z, P) == 1) { // while z quadratic residue z = z.Add(ONE); // z = z + 1 } v = k; v = v.Multiply(TWO); // v = 2k v = v.Add(ONE); // v = 2k + 1 BigInteger c = z.ModPow(v, P); // c = z^v mod p // iteration while (n.CompareTo(ONE) == 1) { // n > 1 k = n; // k = n t = s; // t = s s = 0; while (!k.Equals(ONE)) { // k != 1 k = k.Multiply(k).Mod(P); // k = k^2 % p s++; // s = s + 1 } t -= s; // t = t - s if (t == 0) { throw new ArgumentException("No quadratic residue: " + X + ", " + P); } v = ONE; for (long i = 0; i < t - 1; i++) { v = v.ShiftLeft(1); // v = 1 * 2^(t - 1) } c = c.ModPow(v, P); // c = c^v mod p r = r.Multiply(c).Remainder(P); // r = r * c % p c = c.Multiply(c).Remainder(P); // c = c^2 % p n = n.Multiply(c).Mod(P); // n = n * c % p } return r; }
public void Backdoor() { var random = new SecureRandom(); var curve = CustomNamedCurves.GetByName("secp521r1"); var gen = new ECKeyPairGenerator("ECDSA"); var G = curve.G; var N = curve.N; var paramz = new ECDomainParameters(curve.Curve, G, N); gen.Init(new ECKeyGenerationParameters(paramz, random)); var kCalc = new RandomDsaKCalculator(); // kCalc generates random values [1, N-1] kCalc.Init(N, random); var attackersKeyPair = gen.GenerateKeyPair(); var v = ((ECPrivateKeyParameters)attackersKeyPair.Private).D; //attacker's private var V = G.Multiply(v); //attackers public var usersKeyPair = gen.GenerateKeyPair(); //user's keypair var D = ((ECPrivateKeyParameters)usersKeyPair.Private).D; //user's private var Q = ((ECPublicKeyParameters)usersKeyPair.Public).Q; //user's public const string message1 = "First message to sign"; var m1 = new BigInteger(1, Hash(Encoding.UTF8.GetBytes(message1))); // hash of m1 //Generate signature 1 var k1 = kCalc.NextK(); // k1 is true random var signaturePoint1 = G.Multiply(k1).Normalize(); //(r1, s1) - signature 1 var r1 = signaturePoint1.AffineXCoord.ToBigInteger().Mod(N); var s1 = k1.ModInverse(N).Multiply(m1.Add(D.Multiply(r1))); //verify signature 1 var w = s1.ModInverse(N); var u1 = m1.Multiply(w).Mod(N); var u2 = r1.Multiply(w).Mod(N); var verifyPoint1 = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2).Normalize(); var valid1 = verifyPoint1.AffineXCoord.ToBigInteger().Mod(N).Equals(r1); //Generate signature 2 const string message2 = "Second message to sign"; var m2 = new BigInteger(1, Hash(Encoding.UTF8.GetBytes(message2))); // hash of m2 //here we generate a,b,h,e < N using seed = hash(m2) kCalc.Init(N, new SecureRandom(new SeededGenerator(Hash(Encoding.UTF8.GetBytes(message2))))); var a = kCalc.NextK(); var b = kCalc.NextK(); var h = kCalc.NextK(); var e = kCalc.NextK(); //u,j - true random var u = (random.Next() % 2) == 1 ? BigInteger.One : BigInteger.Zero; var j = (random.Next() % 2) == 1 ? BigInteger.One : BigInteger.Zero; //compute hidden field element var Z = G.Multiply(k1).Multiply(a) .Add(V.Multiply(k1).Multiply(b)) .Add(G.Multiply(h).Multiply(j)) .Add(V.Multiply(e).Multiply(u)) .Normalize(); var zX = Z.AffineXCoord.ToBigInteger().ToByteArray(); var hash = Hash(zX); var k2 = new BigInteger(1, hash); var signaturePoint2 = G.Multiply(k2).Normalize(); //(r2, s2) = signature 2 var r2 = signaturePoint2.AffineXCoord.ToBigInteger().Mod(N); var s2 = k2.ModInverse(N).Multiply(m2.Add(D.Multiply(r2))); //verify signature 2 w = s2.ModInverse(N); u1 = m2.Multiply(w).Mod(N); u2 = r2.Multiply(w).Mod(N); var verifyPoint2 = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2).Normalize(); var valid2 = verifyPoint2.AffineXCoord.ToBigInteger().Mod(N).Equals(r2); if (valid1 && valid2) { //compute user's private key var d = ExtractUsersPrivateKey(G, N, message1, message2, r1, s1, r2, s2, v, V, Q); Console.WriteLine("Ecdsa private key restored: {0}", d.Equals(D)); } else { Console.WriteLine("Something's wrong"); } }
/* ---------------------------------------------------------------------------- DblToRgbPrecise() Uses big integer arithmetic to get the sequence of digits. */ public static void DblToRgbPrecise(double dbl, byte[] mantissa, out int exponent, out int mantissaSize) { BigInteger biNum = new BigInteger(); BigInteger biDen = new BigInteger(); BigInteger biHi = new BigInteger(); BigInteger biLo = new BigInteger(); BigInteger biT = new BigInteger(); BigInteger biHiLo; byte bT; bool fPow2; int ib, cu; int wExp10, wExp2, w1, w2; int c2Num, c2Den, c5Num, c5Den; double dblT; //uint *rgu = stackalloc uint[2]; uint rgu0, rgu1; uint dblHi, dblLo; dblHi = DblHi(dbl); dblLo = DblLo(dbl); // Caller should take care of 0, negative and non-finite values. Debug.Assert(!IsSpecial(dbl)); Debug.Assert(0 < dbl); // Init the Denominator, Hi error and Lo error bigints. biDen.InitFromDigits(1, 0, 1); biHi.InitFromDigits(1, 0, 1); wExp2 = (int)(((dblHi & 0x7FF00000) >> 20) - 1075); rgu1 = dblHi & 0x000FFFFF; rgu0 = dblLo; cu = 2; fPow2 = false; if (wExp2 == -1075) { // dbl is denormalized. Debug.Assert(0 == (dblHi & 0x7FF00000)); if (0 == rgu1) { cu = 1; } // Get dblT such that dbl / dblT is a power of 2 and 1 <= dblT < 2. // First multiply by a power of 2 to get a normalized value. dblT = BitConverter.Int64BitsToDouble(0x4FF00000L << 32); dblT *= dbl; Debug.Assert(0 != (DblHi(dblT) & 0x7FF00000)); // This is the power of 2. w1 = (int)((DblHi(dblT) & 0x7FF00000) >> 20) - (256 + 1023); dblHi = DblHi(dblT); dblHi &= 0x000FFFFF; dblHi |= 0x3FF00000; dblT = BitConverter.Int64BitsToDouble((long)dblHi << 32 | DblLo(dblT)); // Adjust wExp2 because we don't have the implicit bit. wExp2++; } else { // Get dblT such that dbl / dblT is a power of 2 and 1 <= dblT < 2. // First multiply by a power of 2 to get a normalized value. dblHi &= 0x000FFFFF; dblHi |= 0x3FF00000; dblT = BitConverter.Int64BitsToDouble((long)dblHi << 32 | dblLo); // This is the power of 2. w1 = wExp2 + 52; if (0 == rgu0 && 0 == rgu1 && wExp2 > -1074) { // Power of 2 bigger than smallest normal. The next smaller // representable value is closer than the next larger value. rgu1 = 0x00200000; wExp2--; fPow2 = true; } else { // Normalized and not a power of 2 or the smallest normal. The // representable values on either side are the same distance away. rgu1 |= 0x00100000; } } // Compute an approximation to the base 10 log. This is borrowed from // David ----'s paper. Debug.Assert(1 <= dblT && dblT < 2); dblT = (dblT - 1.5) * 0.289529654602168 + 0.1760912590558 + w1 * 0.301029995663981; wExp10 = (int)dblT; if (dblT < 0 && dblT != wExp10) { wExp10--; } if (wExp2 >= 0) { c2Num = wExp2; c2Den = 0; } else { c2Num = 0; c2Den = -wExp2; } if (wExp10 >= 0) { c5Num = 0; c5Den = wExp10; c2Den += wExp10; } else { c2Num -= wExp10; c5Num = -wExp10; c5Den = 0; } if (c2Num > 0 && c2Den > 0) { w1 = c2Num < c2Den ? c2Num : c2Den; c2Num -= w1; c2Den -= w1; } // We need a bit for the Hi and Lo values. c2Num++; c2Den++; // Initialize biNum and multiply by powers of 5. if (c5Num > 0) { Debug.Assert(0 == c5Den); biHi.MulPow5(c5Num); biNum.InitFromBigint(biHi); if (1 == cu) { biNum.MulAdd(rgu0, 0); } else { biNum.MulAdd(rgu1, 0); biNum.ShiftLeft(32); if (0 != rgu0) { biT.InitFromBigint(biHi); biT.MulAdd(rgu0, 0); biNum.Add(biT); } } } else { Debug.Assert(cu <= 2); biNum.InitFromDigits(rgu0, rgu1, cu); if (c5Den > 0) { biDen.MulPow5(c5Den); } } // BigInteger.DivRem only works if the 4 high bits of the divisor are 0. // It works most efficiently if there are exactly 4 zero high bits. // Adjust c2Den and c2Num to guarantee this. w1 = CbitZeroLeft(biDen[biDen.Length - 1]); w1 = (w1 + 28 - c2Den) & 0x1F; c2Num += w1; c2Den += w1; // Multiply by powers of 2. Debug.Assert(c2Num > 0 && c2Den > 0); biNum.ShiftLeft(c2Num); if (c2Num > 1) { biHi.ShiftLeft(c2Num - 1); } biDen.ShiftLeft(c2Den); Debug.Assert(0 == (biDen[biDen.Length - 1] & 0xF0000000)); Debug.Assert(0 != (biDen[biDen.Length - 1] & 0x08000000)); // Get biHiLo and handle the power of 2 case where biHi needs to be doubled. if (fPow2) { biHiLo = biLo; biHiLo.InitFromBigint(biHi); biHi.ShiftLeft(1); } else { biHiLo = biHi; } for (ib = 0; ; ) { bT = (byte)biNum.DivRem(biDen); if (0 == ib && 0 == bT) { // Our estimate of wExp10 was too big. Oh well. wExp10--; goto LSkip; } // w1 = sign(biNum - biHiLo). w1 = biNum.CompareTo(biHiLo); // w2 = sign(biNum + biHi - biDen). if (biDen.CompareTo(biHi) < 0) { w2 = 1; } else { // biT.InitFromBigint(biDen); biT.Subtract(biHi); w2 = biNum.CompareTo(biT); } // if (biNum + biHi == biDen && even) if (0 == w2 && 0 == (dblLo & 1)) { // Rounding up this digit produces exactly (biNum + biHi) which // StrToDbl will round down to dbl. if (bT == 9) { goto LRoundUp9; } if (w1 > 0) { bT++; } mantissa[ib++] = bT; break; } // if (biNum < biHiLo || biNum == biHiLo && even) if (w1 < 0 || 0 == w1 && 0 == (dblLo & 1)) { // if (biNum + biHi > biDen) if (w2 > 0) { // Decide whether to round up. biNum.ShiftLeft(1); w2 = biNum.CompareTo(biDen); if ((w2 > 0 || 0 == w2 && (0 != (bT & 1))) && bT++ == 9) { goto LRoundUp9; } } mantissa[ib++] = bT; break; } // if (biNum + biHi > biDen) if (w2 > 0) { // Round up and be done with it. if (bT != 9) { mantissa[ib++] = (byte)(bT + 1); break; } goto LRoundUp9; } // Save the digit. mantissa[ib++] = bT; LSkip: biNum.MulAdd(10, 0); biHi.MulAdd(10, 0); if ((object) biHiLo != (object) biHi) { biHiLo.MulAdd(10, 0); } continue; LRoundUp9: while (ib > 0) { if (mantissa[--ib] != 9) { mantissa[ib++]++; goto LReturn; } } wExp10++; mantissa[ib++] = 1; break; } LReturn: exponent = wExp10 + 1; mantissaSize = ib; }
public static byte[] DecodeBase58(string encoded) { if (encoded == null) { throw new ArgumentNullException("encoded"); } var result = new byte[0]; if (encoded.Length == 0) { return(result); } BigInteger bn = BigInteger.Zero; int i = 0; while (IsSpace(encoded[i])) { i++; if (i >= encoded.Length) { return(result); } } for (int y = i; y < encoded.Length; y++) { var p1 = pszBase58.IndexOf(encoded[y]); if (p1 == -1) { while (IsSpace(encoded[y])) { y++; if (y >= encoded.Length) { break; } } if (y != encoded.Length) { throw new FormatException("Invalid base 58 string"); } break; } var bnChar = BigInteger.ValueOf(p1); bn = bn.Multiply(bn58); bn = bn.Add(bnChar); } // Get bignum as little endian data var vchTmp = bn.ToByteArrayUnsigned(); Array.Reverse(vchTmp); if (vchTmp.All(b => b == 0)) { vchTmp = new byte[0]; } // Trim off sign byte if present if (vchTmp.Length >= 2 && vchTmp[vchTmp.Length - 1] == 0 && vchTmp[vchTmp.Length - 2] >= 0x80) { vchTmp = vchTmp.SafeSubarray(0, vchTmp.Length - 1); } // Restore leading zeros int nLeadingZeros = 0; for (int y = i; y < encoded.Length && encoded[y] == pszBase58[0]; y++) { nLeadingZeros++; } result = new byte[nLeadingZeros + vchTmp.Length]; Array.Copy(vchTmp.Reverse().ToArray(), 0, result, nLeadingZeros, vchTmp.Length); return(result); }
public void TestMultiply() { BigInteger one = BigInteger.One; Assert.AreEqual(one, one.Negate().Multiply(one.Negate())); for (int i = 0; i < 100; ++i) { int aLen = 64 + Rnd.Next(64); int bLen = 64 + Rnd.Next(64); BigInteger a = new BigInteger(aLen, Rnd).SetBit(aLen); BigInteger b = new BigInteger(bLen, Rnd).SetBit(bLen); var c = new BigInteger(32, Rnd); BigInteger ab = a.Multiply(b); BigInteger bc = b.Multiply(c); Assert.AreEqual(ab.Add(bc), a.Add(c).Multiply(b)); Assert.AreEqual(ab.Subtract(bc), a.Subtract(c).Multiply(b)); } // Special tests for power of two since uses different code path internally for (int i = 0; i < 100; ++i) { int shift = Rnd.Next(64); BigInteger a = one.ShiftLeft(shift); var b = new BigInteger(64 + Rnd.Next(64), Rnd); BigInteger bShift = b.ShiftLeft(shift); Assert.AreEqual(bShift, a.Multiply(b)); Assert.AreEqual(bShift.Negate(), a.Multiply(b.Negate())); Assert.AreEqual(bShift.Negate(), a.Negate().Multiply(b)); Assert.AreEqual(bShift, a.Negate().Multiply(b.Negate())); Assert.AreEqual(bShift, b.Multiply(a)); Assert.AreEqual(bShift.Negate(), b.Multiply(a.Negate())); Assert.AreEqual(bShift.Negate(), b.Negate().Multiply(a)); Assert.AreEqual(bShift, b.Negate().Multiply(a.Negate())); } }
/** * Fetches delta CRLs according to RFC 3280 section 5.2.4. * * @param currentDate The date for which the delta CRLs must be valid. * @param paramsPKIX The extended PKIX parameters. * @param completeCRL The complete CRL the delta CRL is for. * @return A <code>Set</code> of <code>X509CRL</code>s with delta CRLs. * @throws Exception if an exception occurs while picking the delta * CRLs. */ internal static ISet GetDeltaCrls( DateTime currentDate, PkixParameters paramsPKIX, X509Crl completeCRL) { X509CrlStoreSelector deltaSelect = new X509CrlStoreSelector(); // 5.2.4 (a) try { IList deltaSelectIssuer = Platform.CreateArrayList(); deltaSelectIssuer.Add(completeCRL.IssuerDN); deltaSelect.Issuers = deltaSelectIssuer; } catch (IOException e) { throw new Exception("Cannot extract issuer from CRL.", e); } BigInteger completeCRLNumber = null; try { Asn1Object asn1Object = GetExtensionValue(completeCRL, X509Extensions.CrlNumber); if (asn1Object != null) { completeCRLNumber = CrlNumber.GetInstance(asn1Object).PositiveValue; } } catch (Exception e) { throw new Exception( "CRL number extension could not be extracted from CRL.", e); } // 5.2.4 (b) byte[] idp = null; try { Asn1Object obj = GetExtensionValue(completeCRL, X509Extensions.IssuingDistributionPoint); if (obj != null) { idp = obj.GetDerEncoded(); } } catch (Exception e) { throw new Exception( "Issuing distribution point extension value could not be read.", e); } // 5.2.4 (d) deltaSelect.MinCrlNumber = (completeCRLNumber == null) ? null : completeCRLNumber.Add(BigInteger.One); deltaSelect.IssuingDistributionPoint = idp; deltaSelect.IssuingDistributionPointEnabled = true; // 5.2.4 (c) deltaSelect.MaxBaseCrlNumber = completeCRLNumber; // find delta CRLs ISet temp = CrlUtilities.FindCrls(deltaSelect, paramsPKIX, currentDate); ISet result = new HashSet(); foreach (X509Crl crl in temp) { if (isDeltaCrl(crl)) { result.Add(crl); } } return(result); }