예제 #1
0
        // Verify a DSA signature.
        public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature)
        {
            // Validate the parameters.
            if (rgbHash == null)
            {
                throw new ArgumentNullException("rgbHash");
            }
            if (rgbSignature == null)
            {
                throw new ArgumentNullException("rgbSignature");
            }

            // Make sure that we have sufficient parameters to verify.
            if (dsaParams.G == null)
            {
                throw new CryptographicException
                          (_("Crypto_DSAParamsNotSet"));
            }

            // Unpack the signature blob to get R and S.
            ASN1Parser parser;

            parser = (new ASN1Parser(rgbSignature)).GetSequence();
            byte[] R = parser.GetBigInt();
            byte[] S = parser.GetBigInt();
            parser.AtEnd();

            // Compute W = (S^-1 mod Q)
            byte[] W = CryptoMethods.NumInv(S, dsaParams.Q);

            // Compute U1 = ((hash * W) mod Q)
            byte[] U1 = CryptoMethods.NumMul(rgbHash, W, dsaParams.Q);

            // Compute U2 = ((R * W) mod Q)
            byte[] U2 = CryptoMethods.NumMul(R, W, dsaParams.Q);

            // Compute V = (((G^U1 * Y^U2) mod P) mod Q)
            byte[] temp1 = CryptoMethods.NumPow
                               (dsaParams.G, U1, dsaParams.P);
            byte[] temp2 = CryptoMethods.NumPow
                               (dsaParams.Y, U2, dsaParams.P);
            byte[] temp3 = CryptoMethods.NumMul(temp1, temp2, dsaParams.P);
            byte[] V     = CryptoMethods.NumMod(temp3, dsaParams.Q);

            // Determine if we have a signature match.
            bool result = CryptoMethods.NumEq(V, R);

            // Clear sensitive values.
            Array.Clear(R, 0, R.Length);
            Array.Clear(S, 0, S.Length);
            Array.Clear(W, 0, W.Length);
            Array.Clear(U1, 0, U1.Length);
            Array.Clear(U2, 0, U2.Length);
            Array.Clear(temp1, 0, temp1.Length);
            Array.Clear(temp2, 0, temp2.Length);
            Array.Clear(temp3, 0, temp3.Length);
            Array.Clear(V, 0, V.Length);

            // Done.
            return(result);
        }