context: using System;
  using System.Text;
  
  using NUnit.Framework;
  
  using Org.BouncyCastle.Asn1;
  using Org.BouncyCastle.Asn1.TeleTrust;
  using Org.BouncyCastle.Asn1.X509;
  using Org.BouncyCastle.Asn1.X9;
  using Org.BouncyCastle.Crypto;
  using Org.BouncyCastle.Crypto.Digests;
  using Org.BouncyCastle.Crypto.Generators;
  using Org.BouncyCastle.Crypto.Parameters;
  using Org.BouncyCastle.Crypto.Signers;
  using Org.BouncyCastle.Math;
  using Org.BouncyCastle.Math.EC;
  using Org.BouncyCastle.Security;
  using Org.BouncyCastle.Utilities;
  using Org.BouncyCastle.Utilities.Encoders;
  using Org.BouncyCastle.Utilities.Test;
  
  namespace Org.BouncyCastle.Tests
  {
      [TestFixture]
      public class DsaTest
          : SimpleTest
      {
          private static readonly byte[] k1 = Hex.Decode("d5014e4b60ef2ba8b6211b4062ba3224e0427dd3");
          private static readonly byte[] k2 = Hex.Decode("345e8d05c075c3a508df729a1685690e68fcfb8c8117847e89063bca1f85d968fd281540b6e13bd1af989a1fbf17e06462bf511f9d0b140fb48ac1b1baa5bded");
  
          private static readonly SecureRandom random = FixedSecureRandom.From(k1, k2);
  
          // TODO How shall we satisfy this compatibility test?
  //		[Test]
  //		public void TestCompat()
  //		{
  //			if (Security.getProvider("SUN") == null)
  //				return;
  //			ISigner s = SignerUtilities.GetSigner("DSA", "SUN");
  //			KeyPairGenerator g = KeyPairGenerator.GetInstance("DSA", "SUN");
  //			byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
  //
  //			g.initialize(512, new SecureRandom());
  //
  //			KeyPair p = g.generateKeyPair();
  //
  //			PrivateKey sKey = p.Private;
  //			PublicKey vKey = p.Public;
  //
  //			//
  //			// sign SUN - verify with BC
  //			//
  //			s.Init(true, sKey);
  //
  //			s.update(data);
  //
  //			byte[] sigBytes = s.GenerateSignature();
  //
  //			s = SignerUtilities.GetSigner("DSA");
  //
  //			s.Init(false, vKey);
  //
  //			s.update(data);
  //
  //			if (!s.VerifySignature(sigBytes))
  //			{
  //				Fail("SUN -> BC verification failed");
  //			}
  //
  //			//
  //			// sign BC - verify with SUN
  //			//
  //
  //			s.Init(true, sKey);
  //
  //			s.update(data);
  //
  //			sigBytes = s.GenerateSignature();
  //
  //			s = SignerUtilities.GetSigner("DSA", "SUN");
  //
  //			s.Init(false, vKey);
  //
  //			s.update(data);
  //
  //			if (!s.VerifySignature(sigBytes))
  //			{
  //				Fail("BC -> SUN verification failed");
  //			}
  //
  //			//
  //			// key encoding test - BC decoding Sun keys
  //			//
  //			KeyFactory f = KeyFactory.GetInstance("DSA");
  //			X509EncodedKeySpec x509s = new X509EncodedKeySpec(vKey.GetEncoded());
  //			DSAPublicKey k1 = (DSAPublicKey)f.generatePublic(x509s);
  //
  //			if (!k1.Y.Equals(((DSAPublicKey)vKey).Y))
  //			{
  //				Fail("public number not decoded properly");
  //			}
  //
  //			if (!k1.Parameters.G.Equals(((DSAPublicKey)vKey).Parameters.G))
  //			{
  //				Fail("public generator not decoded properly");
  //			}
  //
  //			if (!k1.Parameters.P.Equals(((DSAPublicKey)vKey).Parameters.P))
  //			{
  //				Fail("public p value not decoded properly");
  //			}
  //
  //			if (!k1.Parameters.Q.Equals(((DSAPublicKey)vKey).Parameters.Q))
  //			{
  //				Fail("public q value not decoded properly");
  //			}
  //
  //			PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(sKey.GetEncoded());
  //			DSAPrivateKey k2 = (DSAPrivateKey)f.generatePrivate(pkcs8);
  //
  //			if (!k2.X.Equals(((DSAPrivateKey)sKey).X))
  //			{
  //				Fail("private number not decoded properly");
  //			}
  //
  //			if (!k2.Parameters.G.Equals(((DSAPrivateKey)sKey).Parameters.G))
  //			{
  //				Fail("private generator not decoded properly");
  //			}
  //
  //			if (!k2.Parameters.P.Equals(((DSAPrivateKey)sKey).Parameters.P))
  //			{
  //				Fail("private p value not decoded properly");
  //			}
  //
  //			if (!k2.Parameters.Q.Equals(((DSAPrivateKey)sKey).Parameters.Q))
  //			{
  //				Fail("private q value not decoded properly");
  //			}
  //
  //			//
  //			// key decoding test - SUN decoding BC keys
  //			//
  //			f = KeyFactory.GetInstance("DSA", "SUN");
  //			x509s = new X509EncodedKeySpec(k1.GetEncoded());
  //
  //			vKey = (DSAPublicKey)f.generatePublic(x509s);
  //
  //			if (!k1.Y.Equals(((DSAPublicKey)vKey).Y))
  //			{
  //				Fail("public number not decoded properly");
  //			}
  //
  //			if (!k1.Parameters.G.Equals(((DSAPublicKey)vKey).Parameters.G))
  //			{
  //				Fail("public generator not decoded properly");
  //			}
  //
  //			if (!k1.Parameters.P.Equals(((DSAPublicKey)vKey).Parameters.P))
  //			{
  //				Fail("public p value not decoded properly");
  //			}
  //
  //			if (!k1.Parameters.Q.Equals(((DSAPublicKey)vKey).Parameters.Q))
  //			{
  //				Fail("public q value not decoded properly");
  //			}
  //
  //			pkcs8 = new PKCS8EncodedKeySpec(k2.GetEncoded());
  //			sKey = (DSAPrivateKey)f.generatePrivate(pkcs8);
  //
  //			if (!k2.X.Equals(((DSAPrivateKey)sKey).X))
  //			{
  //				Fail("private number not decoded properly");
  //			}
  //
  //			if (!k2.Parameters.G.Equals(((DSAPrivateKey)sKey).Parameters.G))
  //			{
  //				Fail("private generator not decoded properly");
  //			}
  //
  //			if (!k2.Parameters.P.Equals(((DSAPrivateKey)sKey).Parameters.P))
  //			{
  //				Fail("private p value not decoded properly");
  //			}
  //
  //			if (!k2.Parameters.Q.Equals(((DSAPrivateKey)sKey).Parameters.Q))
  //			{
  //				Fail("private q value not decoded properly");
  //			}
  //		}
  
          [Test]
          public void TestNONEwithDSA()
          {
              byte[] dummySha1 = Hex.Decode("01020304050607080910111213141516");
  
              SecureRandom rand = new SecureRandom();
  
              DsaParametersGenerator pGen = new DsaParametersGenerator();
              pGen.Init(512, 80, rand);
  
              IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("DSA");
              g.Init(new DsaKeyGenerationParameters(rand, pGen.GenerateParameters()));
  
              AsymmetricCipherKeyPair kp = g.GenerateKeyPair();
  
              ISigner sig = SignerUtilities.GetSigner("NONEwithDSA");
              sig.Init(true, kp.Private);
              sig.BlockUpdate(dummySha1, 0, dummySha1.Length);
              byte[] sigBytes = sig.GenerateSignature();
  
              sig.Init(false, kp.Public);
              sig.BlockUpdate(dummySha1, 0, dummySha1.Length);
              sig.VerifySignature(sigBytes);
  
              // reset test
  
              sig.BlockUpdate(dummySha1, 0, dummySha1.Length);
  
              if (!sig.VerifySignature(sigBytes))
              {
                  Fail("NONEwithDSA failed to reset");
              }
  
              // lightweight test
              DsaSigner signer = new DsaSigner();
              Asn1Sequence derSig = Asn1Sequence.GetInstance(Asn1Object.FromByteArray(sigBytes));
  
              signer.Init(false, kp.Public);
  
              if (!signer.VerifySignature(dummySha1,
                  DerInteger.GetInstance(derSig[0]).Value, DerInteger.GetInstance(derSig[1]).Value))
              {
                  Fail("NONEwithDSA not really NONE!");
              }
          }
  
          /**
          * X9.62 - 1998,<br/>
          * J.3.2, Page 155, ECDSA over the field Fp<br/>
          * an example with 239 bit prime
          */
          [Test]
          public void TestECDsa239BitPrime()
          {
              BigInteger r = new BigInteger("308636143175167811492622547300668018854959378758531778147462058306432176");
              BigInteger s = new BigInteger("323813553209797357708078776831250505931891051755007842781978505179448783");
  
              byte[] kData = BigIntegers.AsUnsignedByteArray(
                  new BigInteger("700000017569056646655505781757157107570501575775705779575555657156756655"));
  
              SecureRandom k = FixedSecureRandom.From(kData);
  
              ECCurve curve = new FpCurve(
                  new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q
                  new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a
                  new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b
  
              ECDomainParameters spec = new ECDomainParameters(
                  curve,
                  curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
                  new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n
  
              ECPrivateKeyParameters priKey = new ECPrivateKeyParameters(
                  "ECDSA",
                  new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d
                  spec);
  
              ECPublicKeyParameters pubKey = new ECPublicKeyParameters(
                  "ECDSA",
                  curve.DecodePoint(Hex.Decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q
                  spec);
  
              ISigner sgr = SignerUtilities.GetSigner("ECDSA");
  
  //			KeyFactory f = KeyFactory.GetInstance("ECDSA");
  //			PrivateKey sKey = f.generatePrivate(priKey);
  //			PublicKey vKey = f.generatePublic(pubKey);
              AsymmetricKeyParameter sKey = priKey;
              AsymmetricKeyParameter vKey = pubKey;
  
              sgr.Init(true, new ParametersWithRandom(sKey, k));
  
              byte[] message = Encoding.ASCII.GetBytes("abc");
  
              sgr.BlockUpdate(message, 0, message.Length);
  
              byte[] sigBytes = sgr.GenerateSignature();
  
              sgr.Init(false, vKey);
  
              sgr.BlockUpdate(message, 0, message.Length);
  
              if (!sgr.VerifySignature(sigBytes))
              {
                  Fail("239 Bit EC verification failed");
              }
  
  
gt:             BigInteger[] sig = DerDecode(sigBytes);