Ejemplo n.º 1
0
 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 }));
 }
Ejemplo n.º 2
0
 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);
 }
Ejemplo n.º 3
0
        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);
    }
Ejemplo n.º 5
0
        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
        }
Ejemplo n.º 6
0
 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);
        }
Ejemplo n.º 8
0
        /// <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);
            }
        }
Ejemplo n.º 9
0
        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));
            }
        }
Ejemplo n.º 10
0
 public AccountState AddToBalance(BigInteger amount)
 {
     return(new AccountState(BigInteger.Add(this.balance, amount), this.nonce));
 }
Ejemplo n.º 11
0
        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 }));
        }
Ejemplo n.º 12
0
    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()));
        }
    }
Ejemplo n.º 15
0
        /**
         * Computes the <code>[&#964;]</code>-adic window NAF of an element
         * <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>.
         * @param mu The parameter &#956; of the elliptic curve.
         * @param lambda The element <code>&#955;</code> of
         * <code><b>Z</b>[&#964;]</code> of which to compute the
         * <code>[&#964;]</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>&#945;<sub>u</sub></code>'s for the window width.
         * @return The <code>[&#964;]</code>-adic window NAF of
         * <code>&#955;</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);
        }
Ejemplo n.º 16
0
        /**
         * Computes the <code>&#964;</code>-adic NAF (non-adjacent form) of an
         * element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>.
         * @param mu The parameter <code>&#956;</code> of the elliptic curve.
         * @param lambda The element <code>&#955;</code> of
         * <code><b>Z</b>[&#964;]</code>.
         * @return The <code>&#964;</code>-adic NAF of <code>&#955;</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);
        }
Ejemplo n.º 17
0
        /**
         * Rounds an element <code>&#955;</code> of <code><b>R</b>[&#964;]</code>
         * to an element of <code><b>Z</b>[&#964;]</code>, such that their difference
         * has minimal norm. <code>&#955;</code> is given as
         * <code>&#955; = &#955;<sub>0</sub> + &#955;<sub>1</sub>&#964;</code>.
         * @param lambda0 The component <code>&#955;<sub>0</sub></code>.
         * @param lambda1 The component <code>&#955;<sub>1</sub></code>.
         * @param mu The parameter <code>&#956;</code> of the elliptic curve. Must
         * equal 1 or -1.
         * @return The rounded element of <code><b>Z</b>[&#964;]</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));
            }
        }
Ejemplo n.º 19
0
        /// <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));
 }
Ejemplo n.º 21
0
 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));
 }
Ejemplo n.º 22
0
 public void Add(int count, int leftBits, int rightBits)
 {
     RunBenchmark(count, leftBits, rightBits, (l, r) => BigInteger.Add(l, r));
 }
Ejemplo n.º 23
0
        /// <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);
            }
        }
Ejemplo n.º 24
0
        /*
         * 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 });
        }
Ejemplo n.º 25
0
        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);
            }
        }
Ejemplo n.º 26
0
        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);
        }
Ejemplo n.º 27
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());
        }
Ejemplo n.º 28
0
        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;
        }
Ejemplo n.º 29
0
        /// <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);
        }
Ejemplo n.º 30
0
        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))));
        }
Ejemplo n.º 31
0
        // 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));
        }
Ejemplo n.º 32
0
        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);
        }
Ejemplo n.º 33
0
        /**
         * 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);
        }
Ejemplo n.º 34
0
        //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);
                }
            }
        }
Ejemplo n.º 35
0
		/*
		 * 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 };
		}
Ejemplo n.º 36
0
        //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);
        }
Ejemplo n.º 37
0
        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 }));
        }
Ejemplo n.º 38
0
        /**
         *
         * 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;
        }
Ejemplo n.º 39
0
        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 }));
        }
Ejemplo n.º 40
0
 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;
 }
Ejemplo n.º 41
0
        //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);
                }
            }
        }
Ejemplo n.º 42
0
        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;
        }
Ejemplo n.º 43
0
 protected virtual BigInteger ModAdd(BigInteger x1, BigInteger x2)
 {
     BigInteger x3 = x1.Add(x2);
     if (x3.CompareTo(q) >= 0)
     {
         x3 = x3.Subtract(q);
     }
     return x3;
 }
Ejemplo n.º 44
0
        /**
         * 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.
            }
        }
Ejemplo n.º 45
0
        /// <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;
        }
Ejemplo n.º 46
0
        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");
            }
        }
Ejemplo n.º 47
0
            /*  ----------------------------------------------------------------------------
                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;
            }
Ejemplo n.º 48
0
        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);
        }
Ejemplo n.º 49
0
        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);
        }