Beispiel #1
0
        public override bool Equals(object obj)
        {
            RSAPublicKey p = obj as RSAPublicKey;

            if (p == null)
            {
                return(false);
            }
            return(BigInt.Compare(mod, p.mod) == 0 &&
                   BigInt.Compare(e, p.e) == 0);
        }
Beispiel #2
0
 internal bool Equals(ECCurvePrime curve)
 {
     if (this == curve)
     {
         return(true);
     }
     return(BigInt.Compare(mod, curve.mod) == 0 &&
            BigInt.Compare(a, curve.a) == 0 &&
            BigInt.Compare(b, curve.b) == 0 &&
            BigInt.Compare(gx, curve.gx) == 0 &&
            BigInt.Compare(gy, curve.gy) == 0);
 }
Beispiel #3
0
        public static bool Verify(RSAPublicKey pk,
                                  byte[] header, byte[] headerAlt,
                                  byte[] hash, int hashOff, int hashLen,
                                  byte[] sig, int sigOff, int sigLen)
        {
            /*
             * Signature must be an integer less than the modulus,
             * but encoded over exactly the same size as the modulus.
             */
            byte[] n      = pk.Modulus;
            int    modLen = n.Length;

            if (sigLen != modLen)
            {
                return(false);
            }
            byte[] x = new byte[modLen];
            Array.Copy(sig, sigOff, x, 0, modLen);
            if (BigInt.Compare(x, n) >= 0)
            {
                return(false);
            }

            /*
             * Do the RSA exponentation, then verify and remove the
             * "Type 1" padding (00 01 FF...FF 00 with at least
             * eight bytes of value FF).
             */
            x = BigInt.ModPow(x, pk.Exponent, n);
            if (x.Length < 11 || x[0] != 0x00 || x[1] != 0x01)
            {
                return(false);
            }
            int k = 2;

            while (k < x.Length && x[k] == 0xFF)
            {
                k++;
            }
            if (k < 10 || k == x.Length || x[k] != 0x00)
            {
                return(false);
            }
            k++;

            /*
             * Check that the remaining byte end with the provided
             * hash value.
             */
            int len = modLen - k;

            if (len < hashLen)
            {
                return(false);
            }
            for (int i = 0; i < hashLen; i++)
            {
                if (x[modLen - hashLen + i] != hash[hashOff + i])
                {
                    return(false);
                }
            }
            len -= hashLen;

            /*
             * Header is at offset 'k', and length 'len'. Compare
             * with the provided header(s).
             */
            if (Eq(header, 0, header.Length, x, k, len))
            {
                return(true);
            }
            if (headerAlt != null)
            {
                if (Eq(headerAlt, 0, headerAlt.Length, x, k, len))
                {
                    return(true);
                }
            }
            return(false);
        }
Beispiel #4
0
        /*
         * Create a new instance with the provided elements. Values are
         * in unsigned big-endian representation.
         *
         *   n    modulus
         *   e    public exponent
         *   d    private exponent
         *   p    first modulus factor
         *   q    second modulus factor
         *   dp   d mod (p-1)
         *   dq   d mod (q-1)
         *   iq   (1/q) mod p
         *
         * Rules verified by this constructor:
         *   n must be odd and at least 512 bits
         *   e must be odd
         *   p must be odd
         *   q must be odd
         *   p and q are greater than 1
         *   n is equal to p*q
         *   dp must be non-zero and lower than p-1
         *   dq must be non-zero and lower than q-1
         *   iq must be non-zero and lower than p
         *
         * This constructor does NOT verify that:
         *   p and q are prime
         *   d is equal to dp modulo p-1
         *   d is equal to dq modulo q-1
         *   dp is the inverse of e modulo p-1
         *   dq is the inverse of e modulo q-1
         *   iq is the inverse of q modulo p
         */
        public RSAPrivateKey(byte[] n, byte[] e, byte[] d,
                             byte[] p, byte[] q, byte[] dp, byte[] dq, byte[] iq)
        {
            n  = BigInt.NormalizeBE(n);
            e  = BigInt.NormalizeBE(e);
            d  = BigInt.NormalizeBE(d);
            p  = BigInt.NormalizeBE(p);
            q  = BigInt.NormalizeBE(q);
            dp = BigInt.NormalizeBE(dp);
            dq = BigInt.NormalizeBE(dq);
            iq = BigInt.NormalizeBE(iq);

            if (n.Length < 64 || (n.Length == 64 && n[0] < 0x80))
            {
                throw new CryptoException(
                          "Invalid RSA private key (less than 512 bits)");
            }
            if (!BigInt.IsOdd(n))
            {
                throw new CryptoException(
                          "Invalid RSA private key (even modulus)");
            }
            if (!BigInt.IsOdd(e))
            {
                throw new CryptoException(
                          "Invalid RSA private key (even exponent)");
            }
            if (!BigInt.IsOdd(p) || !BigInt.IsOdd(q))
            {
                throw new CryptoException(
                          "Invalid RSA private key (even factor)");
            }
            if (BigInt.IsOne(p) || BigInt.IsOne(q))
            {
                throw new CryptoException(
                          "Invalid RSA private key (trivial factor)");
            }
            if (BigInt.Compare(n, BigInt.Mul(p, q)) != 0)
            {
                throw new CryptoException(
                          "Invalid RSA private key (bad factors)");
            }
            if (dp.Length == 0 || dq.Length == 0)
            {
                throw new CryptoException(
                          "Invalid RSA private key"
                          + " (null reduced private exponent)");
            }

            /*
             * We can temporarily modify p[] and q[] (to compute
             * p-1 and q-1) since these are freshly produced copies.
             */
            p[p.Length - 1]--;
            q[q.Length - 1]--;
            if (BigInt.Compare(dp, p) >= 0 || BigInt.Compare(dq, q) >= 0)
            {
                throw new CryptoException(
                          "Invalid RSA private key"
                          + " (oversized reduced private exponent)");
            }
            p[p.Length - 1]++;
            q[q.Length - 1]++;
            if (iq.Length == 0 || BigInt.Compare(iq, p) >= 0)
            {
                throw new CryptoException(
                          "Invalid RSA private key"
                          + " (out of range CRT coefficient)");
            }
            this.n  = n;
            this.e  = e;
            this.d  = d;
            this.p  = p;
            this.q  = q;
            this.dp = dp;
            this.dq = dq;
            this.iq = iq;
        }