From 03a8f8b86524664d2d61076a5f81ebe402c404ff Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Fri, 24 Jan 2014 15:17:40 +0700 Subject: Implementation of homogeneous coordinates for Fp Various changes to point methods to deal with non-affine points Changes in client code and tests to apply point normalization --- crypto/src/crypto/agreement/ECDHBasicAgreement.cs | 23 +- crypto/src/crypto/agreement/ECDHCBasicAgreement.cs | 10 +- .../crypto/agreement/ECDHWithKdfBasicAgreement.cs | 7 +- crypto/src/crypto/agreement/ECMqvBasicAgreement.cs | 51 +- .../crypto/agreement/ECMqvWithKdfBasicAgreement.cs | 7 +- crypto/src/crypto/signers/ECDsaSigner.cs | 10 +- crypto/src/crypto/signers/ECGOST3410Signer.cs | 8 +- crypto/src/crypto/signers/ECNRSigner.cs | 344 +- crypto/src/math/ec/ECCurve.cs | 28 +- crypto/src/math/ec/ECPoint.cs | 610 ++- crypto/src/math/ec/abc/Tnaf.cs | 1652 ++++--- crypto/src/x509/SubjectPublicKeyInfoFactory.cs | 240 +- crypto/test/src/crypto/test/ECTest.cs | 1780 ++++---- .../src/math/ec/test/ECPointPerformanceTest.cs | 13 +- crypto/test/src/math/ec/test/ECPointTest.cs | 162 +- crypto/test/src/test/CertTest.cs | 4648 ++++++++++---------- crypto/test/src/test/DHTest.cs | 841 ++-- crypto/test/src/test/ECDSA5Test.cs | 390 +- crypto/test/src/test/ECEncodingTest.cs | 8 +- crypto/test/src/test/PKCS10CertRequestTest.cs | 806 ++-- 20 files changed, 6012 insertions(+), 5626 deletions(-) diff --git a/crypto/src/crypto/agreement/ECDHBasicAgreement.cs b/crypto/src/crypto/agreement/ECDHBasicAgreement.cs index fa587b234..c33f16f78 100644 --- a/crypto/src/crypto/agreement/ECDHBasicAgreement.cs +++ b/crypto/src/crypto/agreement/ECDHBasicAgreement.cs @@ -1,3 +1,5 @@ +using System; + using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Crypto; @@ -20,19 +22,19 @@ namespace Org.BouncyCastle.Crypto.Agreement * Section 7.2.2). */ public class ECDHBasicAgreement - : IBasicAgreement + : IBasicAgreement { protected internal ECPrivateKeyParameters privKey; public virtual void Init( - ICipherParameters parameters) + ICipherParameters parameters) { - if (parameters is ParametersWithRandom) - { - parameters = ((ParametersWithRandom)parameters).Parameters; - } + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom)parameters).Parameters; + } - this.privKey = (ECPrivateKeyParameters)parameters; + this.privKey = (ECPrivateKeyParameters)parameters; } public virtual int GetFieldSize() @@ -44,11 +46,12 @@ namespace Org.BouncyCastle.Crypto.Agreement ICipherParameters pubKey) { ECPublicKeyParameters pub = (ECPublicKeyParameters) pubKey; - ECPoint P = pub.Q.Multiply(privKey.D); + ECPoint P = pub.Q.Multiply(privKey.D).Normalize(); - // if ( p.IsInfinity ) throw new Exception("d*Q == infinity"); + if (P.IsInfinity) + throw new InvalidOperationException("Infinity is not a valid agreement value for ECDH"); - return P.X.ToBigInteger(); + return P.AffineXCoord.ToBigInteger(); } } } diff --git a/crypto/src/crypto/agreement/ECDHCBasicAgreement.cs b/crypto/src/crypto/agreement/ECDHCBasicAgreement.cs index e1c572373..89be7061e 100644 --- a/crypto/src/crypto/agreement/ECDHCBasicAgreement.cs +++ b/crypto/src/crypto/agreement/ECDHCBasicAgreement.cs @@ -52,11 +52,15 @@ namespace Org.BouncyCastle.Crypto.Agreement { ECPublicKeyParameters pub = (ECPublicKeyParameters) pubKey; ECDomainParameters parameters = pub.Parameters; - ECPoint P = pub.Q.Multiply(parameters.H.Multiply(key.D)); - // if ( p.IsInfinity ) throw new Exception("Invalid public key"); + BigInteger hd = parameters.H.Multiply(key.D).Mod(parameters.N); - return P.X.ToBigInteger(); + ECPoint P = pub.Q.Multiply(hd).Normalize(); + + if (P.IsInfinity) + throw new InvalidOperationException("Infinity is not a valid agreement value for ECDHC"); + + return P.AffineXCoord.ToBigInteger(); } } } diff --git a/crypto/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs b/crypto/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs index 28437a268..1de80d1e5 100644 --- a/crypto/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs +++ b/crypto/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs @@ -44,7 +44,7 @@ namespace Org.BouncyCastle.Crypto.Agreement DHKdfParameters dhKdfParams = new DHKdfParameters( new DerObjectIdentifier(algorithm), keySize, - bigIntToBytes(result)); + BigIntToBytes(result)); kdf.Init(dhKdfParams); @@ -54,10 +54,9 @@ namespace Org.BouncyCastle.Crypto.Agreement return new BigInteger(1, keyBytes); } - private byte[] bigIntToBytes( - BigInteger r) + private byte[] BigIntToBytes(BigInteger r) { - int byteLength = X9IntegerConverter.GetByteLength(privKey.Parameters.G.X); + int byteLength = X9IntegerConverter.GetByteLength(privKey.Parameters.Curve); return X9IntegerConverter.IntegerToBytes(r, byteLength); } } diff --git a/crypto/src/crypto/agreement/ECMqvBasicAgreement.cs b/crypto/src/crypto/agreement/ECMqvBasicAgreement.cs index 3559d3e81..f55ae46af 100644 --- a/crypto/src/crypto/agreement/ECMqvBasicAgreement.cs +++ b/crypto/src/crypto/agreement/ECMqvBasicAgreement.cs @@ -35,15 +35,18 @@ namespace Org.BouncyCastle.Crypto.Agreement ECPrivateKeyParameters staticPrivateKey = privParams.StaticPrivateKey; - ECPoint agreement = calculateMqvAgreement(staticPrivateKey.Parameters, staticPrivateKey, + ECPoint agreement = CalculateMqvAgreement(staticPrivateKey.Parameters, staticPrivateKey, privParams.EphemeralPrivateKey, privParams.EphemeralPublicKey, - pubParams.StaticPublicKey, pubParams.EphemeralPublicKey); + pubParams.StaticPublicKey, pubParams.EphemeralPublicKey).Normalize(); - return agreement.X.ToBigInteger(); + if (agreement.IsInfinity) + throw new InvalidOperationException("Infinity is not a valid agreement value for MQV"); + + return agreement.AffineXCoord.ToBigInteger(); } - + // The ECMQV Primitive as described in SEC-1, 3.4 - private static ECPoint calculateMqvAgreement( + private static ECPoint CalculateMqvAgreement( ECDomainParameters parameters, ECPrivateKeyParameters d1U, ECPrivateKeyParameters d2U, @@ -55,36 +58,32 @@ namespace Org.BouncyCastle.Crypto.Agreement int e = (n.BitLength + 1) / 2; BigInteger powE = BigInteger.One.ShiftLeft(e); - // The Q2U public key is optional - ECPoint q; - if (Q2U == null) - { - q = parameters.G.Multiply(d2U.D); - } - else - { - q = Q2U.Q; - } + ECCurve curve = parameters.Curve; - BigInteger x = q.X.ToBigInteger(); + ECPoint[] points = new ECPoint[]{ + // The Q2U public key is optional + ECAlgorithms.ImportPoint(curve, Q2U == null ? parameters.G.Multiply(d2U.D) : Q2U.Q), + ECAlgorithms.ImportPoint(curve, Q1V.Q), + ECAlgorithms.ImportPoint(curve, Q2V.Q) + }; + + curve.NormalizeAll(points); + + ECPoint q2u = points[0], q1v = points[1], q2v = points[2]; + + BigInteger x = q2u.AffineXCoord.ToBigInteger(); BigInteger xBar = x.Mod(powE); BigInteger Q2UBar = xBar.SetBit(e); - BigInteger s = d1U.D.Multiply(Q2UBar).Mod(n).Add(d2U.D).Mod(n); + BigInteger s = d1U.D.Multiply(Q2UBar).Add(d2U.D).Mod(n); - BigInteger xPrime = Q2V.Q.X.ToBigInteger(); + BigInteger xPrime = q2v.AffineXCoord.ToBigInteger(); BigInteger xPrimeBar = xPrime.Mod(powE); BigInteger Q2VBar = xPrimeBar.SetBit(e); BigInteger hs = parameters.H.Multiply(s).Mod(n); - //ECPoint p = Q1V.Q.Multiply(Q2VBar).Add(Q2V.Q).Multiply(hs); - ECPoint p = ECAlgorithms.SumOfTwoMultiplies( - Q1V.Q, Q2VBar.Multiply(hs).Mod(n), Q2V.Q, hs); - - if (p.IsInfinity) - throw new InvalidOperationException("Infinity is not a valid agreement value for MQV"); - - return p; + return ECAlgorithms.SumOfTwoMultiplies( + q1v, Q2VBar.Multiply(hs).Mod(n), q2v, hs); } } } diff --git a/crypto/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs b/crypto/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs index 093ce4056..7d79fc468 100644 --- a/crypto/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs +++ b/crypto/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs @@ -44,7 +44,7 @@ namespace Org.BouncyCastle.Crypto.Agreement DHKdfParameters dhKdfParams = new DHKdfParameters( new DerObjectIdentifier(algorithm), keySize, - bigIntToBytes(result)); + BigIntToBytes(result)); kdf.Init(dhKdfParams); @@ -54,10 +54,9 @@ namespace Org.BouncyCastle.Crypto.Agreement return new BigInteger(1, keyBytes); } - private byte[] bigIntToBytes( - BigInteger r) + private byte[] BigIntToBytes(BigInteger r) { - int byteLength = X9IntegerConverter.GetByteLength(privParams.StaticPrivateKey.Parameters.G.X); + int byteLength = X9IntegerConverter.GetByteLength(privParams.StaticPrivateKey.Parameters.Curve); return X9IntegerConverter.IntegerToBytes(r, byteLength); } } diff --git a/crypto/src/crypto/signers/ECDsaSigner.cs b/crypto/src/crypto/signers/ECDsaSigner.cs index d602ec3bb..3b0b8ddf1 100644 --- a/crypto/src/crypto/signers/ECDsaSigner.cs +++ b/crypto/src/crypto/signers/ECDsaSigner.cs @@ -84,10 +84,10 @@ namespace Org.BouncyCastle.Crypto.Signers } while (k.SignValue == 0 || k.CompareTo(n) >= 0); - ECPoint p = key.Parameters.G.Multiply(k); + ECPoint p = key.Parameters.G.Multiply(k).Normalize(); // 5.3.3 - BigInteger x = p.X.ToBigInteger(); + BigInteger x = p.AffineXCoord.ToBigInteger(); r = x.Mod(n); } @@ -95,7 +95,7 @@ namespace Org.BouncyCastle.Crypto.Signers BigInteger d = ((ECPrivateKeyParameters)key).D; - s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r).Mod(n))).Mod(n); + s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r))).Mod(n); } while (s.SignValue == 0); @@ -131,12 +131,12 @@ namespace Org.BouncyCastle.Crypto.Signers ECPoint G = key.Parameters.G; ECPoint Q = ((ECPublicKeyParameters) key).Q; - ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2); + ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2).Normalize(); if (point.IsInfinity) return false; - BigInteger v = point.X.ToBigInteger().Mod(n); + BigInteger v = point.AffineXCoord.ToBigInteger().Mod(n); return v.Equals(r); } diff --git a/crypto/src/crypto/signers/ECGOST3410Signer.cs b/crypto/src/crypto/signers/ECGOST3410Signer.cs index 294d4791a..3d71ace04 100644 --- a/crypto/src/crypto/signers/ECGOST3410Signer.cs +++ b/crypto/src/crypto/signers/ECGOST3410Signer.cs @@ -88,9 +88,9 @@ namespace Org.BouncyCastle.Crypto.Signers } while (k.SignValue == 0); - ECPoint p = key.Parameters.G.Multiply(k); + ECPoint p = key.Parameters.G.Multiply(k).Normalize(); - BigInteger x = p.X.ToBigInteger(); + BigInteger x = p.AffineXCoord.ToBigInteger(); r = x.Mod(n); } @@ -144,12 +144,12 @@ namespace Org.BouncyCastle.Crypto.Signers ECPoint G = key.Parameters.G; // P ECPoint Q = ((ECPublicKeyParameters)key).Q; - ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2); + ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2).Normalize(); if (point.IsInfinity) return false; - BigInteger R = point.X.ToBigInteger().Mod(n); + BigInteger R = point.AffineXCoord.ToBigInteger().Mod(n); return R.Equals(r); } diff --git a/crypto/src/crypto/signers/ECNRSigner.cs b/crypto/src/crypto/signers/ECNRSigner.cs index 1d9af3d13..ba953aca4 100644 --- a/crypto/src/crypto/signers/ECNRSigner.cs +++ b/crypto/src/crypto/signers/ECNRSigner.cs @@ -9,181 +9,181 @@ using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Crypto.Signers { - /** - * EC-NR as described in IEEE 1363-2000 - */ - public class ECNRSigner - : IDsa - { - private bool forSigning; - private ECKeyParameters key; - private SecureRandom random; - - public string AlgorithmName - { - get { return "ECNR"; } - } - - public void Init( - bool forSigning, - ICipherParameters parameters) - { - this.forSigning = forSigning; - - if (forSigning) - { - if (parameters is ParametersWithRandom) - { - ParametersWithRandom rParam = (ParametersWithRandom) parameters; - - this.random = rParam.Random; - parameters = rParam.Parameters; - } - else - { - this.random = new SecureRandom(); - } - - if (!(parameters is ECPrivateKeyParameters)) - throw new InvalidKeyException("EC private key required for signing"); - - this.key = (ECPrivateKeyParameters) parameters; - } - else - { - if (!(parameters is ECPublicKeyParameters)) - throw new InvalidKeyException("EC public key required for verification"); - - this.key = (ECPublicKeyParameters) parameters; - } - } - - // Section 7.2.5 ECSP-NR, pg 34 - /** - * generate a signature for the given message using the key we were - * initialised with. Generally, the order of the curve should be at - * least as long as the hash of the message of interest, and with - * ECNR it *must* be at least as long. - * - * @param digest the digest to be signed. - * @exception DataLengthException if the digest is longer than the key allows - */ - public BigInteger[] GenerateSignature( - byte[] message) - { - if (!this.forSigning) - { - // not properly initilaized... deal with it - throw new InvalidOperationException("not initialised for signing"); - } - - BigInteger n = ((ECPrivateKeyParameters) this.key).Parameters.N; - int nBitLength = n.BitLength; - - BigInteger e = new BigInteger(1, message); - int eBitLength = e.BitLength; - - ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)key; - - if (eBitLength > nBitLength) - { - throw new DataLengthException("input too large for ECNR key."); - } - - BigInteger r = null; - BigInteger s = null; - - AsymmetricCipherKeyPair tempPair; - do // generate r - { - // generate another, but very temporary, key pair using - // the same EC parameters - ECKeyPairGenerator keyGen = new ECKeyPairGenerator(); - - keyGen.Init(new ECKeyGenerationParameters(privKey.Parameters, this.random)); - - tempPair = keyGen.GenerateKeyPair(); - - // BigInteger Vx = tempPair.getPublic().getW().getAffineX(); - ECPublicKeyParameters V = (ECPublicKeyParameters) tempPair.Public; // get temp's public key - BigInteger Vx = V.Q.X.ToBigInteger(); // get the point's x coordinate - - r = Vx.Add(e).Mod(n); - } - while (r.SignValue == 0); - - // generate s - BigInteger x = privKey.D; // private key value - BigInteger u = ((ECPrivateKeyParameters) tempPair.Private).D; // temp's private key value - s = u.Subtract(r.Multiply(x)).Mod(n); - - return new BigInteger[]{ r, s }; - } - - // Section 7.2.6 ECVP-NR, pg 35 - /** - * return true if the value r and s represent a signature for the - * message passed in. Generally, the order of the curve should be at - * least as long as the hash of the message of interest, and with - * ECNR, it *must* be at least as long. But just in case the signer - * applied mod(n) to the longer digest, this implementation will - * apply mod(n) during verification. - * - * @param digest the digest to be verified. - * @param r the r value of the signature. - * @param s the s value of the signature. - * @exception DataLengthException if the digest is longer than the key allows - */ - public bool VerifySignature( - byte[] message, - BigInteger r, - BigInteger s) - { - if (this.forSigning) - { - // not properly initilaized... deal with it - throw new InvalidOperationException("not initialised for verifying"); - } - - ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key; - BigInteger n = pubKey.Parameters.N; - int nBitLength = n.BitLength; - - BigInteger e = new BigInteger(1, message); - int eBitLength = e.BitLength; - - if (eBitLength > nBitLength) - { - throw new DataLengthException("input too large for ECNR key."); - } - - // r in the range [1,n-1] - if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) - { - return false; - } - - // TODO So why is this different from the spec? - // s in the range [0,n-1] NB: ECNR spec says 0 - if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0) - { - return false; - } - - // compute P = sG + rW - - ECPoint G = pubKey.Parameters.G; - ECPoint W = pubKey.Q; - // calculate P using Bouncy math - ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r); + /** + * EC-NR as described in IEEE 1363-2000 + */ + public class ECNRSigner + : IDsa + { + private bool forSigning; + private ECKeyParameters key; + private SecureRandom random; + + public string AlgorithmName + { + get { return "ECNR"; } + } + + public void Init( + bool forSigning, + ICipherParameters parameters) + { + this.forSigning = forSigning; + + if (forSigning) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom) parameters; + + this.random = rParam.Random; + parameters = rParam.Parameters; + } + else + { + this.random = new SecureRandom(); + } + + if (!(parameters is ECPrivateKeyParameters)) + throw new InvalidKeyException("EC private key required for signing"); + + this.key = (ECPrivateKeyParameters) parameters; + } + else + { + if (!(parameters is ECPublicKeyParameters)) + throw new InvalidKeyException("EC public key required for verification"); + + this.key = (ECPublicKeyParameters) parameters; + } + } + + // Section 7.2.5 ECSP-NR, pg 34 + /** + * generate a signature for the given message using the key we were + * initialised with. Generally, the order of the curve should be at + * least as long as the hash of the message of interest, and with + * ECNR it *must* be at least as long. + * + * @param digest the digest to be signed. + * @exception DataLengthException if the digest is longer than the key allows + */ + public BigInteger[] GenerateSignature( + byte[] message) + { + if (!this.forSigning) + { + // not properly initilaized... deal with it + throw new InvalidOperationException("not initialised for signing"); + } + + BigInteger n = ((ECPrivateKeyParameters) this.key).Parameters.N; + int nBitLength = n.BitLength; + + BigInteger e = new BigInteger(1, message); + int eBitLength = e.BitLength; + + ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)key; + + if (eBitLength > nBitLength) + { + throw new DataLengthException("input too large for ECNR key."); + } + + BigInteger r = null; + BigInteger s = null; + + AsymmetricCipherKeyPair tempPair; + do // generate r + { + // generate another, but very temporary, key pair using + // the same EC parameters + ECKeyPairGenerator keyGen = new ECKeyPairGenerator(); + + keyGen.Init(new ECKeyGenerationParameters(privKey.Parameters, this.random)); + + tempPair = keyGen.GenerateKeyPair(); + + // BigInteger Vx = tempPair.getPublic().getW().getAffineX(); + ECPublicKeyParameters V = (ECPublicKeyParameters) tempPair.Public; // get temp's public key + ECPoint vq = V.Q.Normalize(); + BigInteger Vx = vq.AffineXCoord.ToBigInteger(); // get the point's x coordinate + + r = Vx.Add(e).Mod(n); + } + while (r.SignValue == 0); + + // generate s + BigInteger x = privKey.D; // private key value + BigInteger u = ((ECPrivateKeyParameters) tempPair.Private).D; // temp's private key value + s = u.Subtract(r.Multiply(x)).Mod(n); + + return new BigInteger[]{ r, s }; + } + + // Section 7.2.6 ECVP-NR, pg 35 + /** + * return true if the value r and s represent a signature for the + * message passed in. Generally, the order of the curve should be at + * least as long as the hash of the message of interest, and with + * ECNR, it *must* be at least as long. But just in case the signer + * applied mod(n) to the longer digest, this implementation will + * apply mod(n) during verification. + * + * @param digest the digest to be verified. + * @param r the r value of the signature. + * @param s the s value of the signature. + * @exception DataLengthException if the digest is longer than the key allows + */ + public bool VerifySignature( + byte[] message, + BigInteger r, + BigInteger s) + { + if (this.forSigning) + { + // not properly initilaized... deal with it + throw new InvalidOperationException("not initialised for verifying"); + } + + ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key; + BigInteger n = pubKey.Parameters.N; + int nBitLength = n.BitLength; + + BigInteger e = new BigInteger(1, message); + int eBitLength = e.BitLength; + + if (eBitLength > nBitLength) + { + throw new DataLengthException("input too large for ECNR key."); + } + + // r in the range [1,n-1] + if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) + { + return false; + } + + // s in the range [0,n-1] NB: ECNR spec says 0 + if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0) + { + return false; + } + + // compute P = sG + rW + + ECPoint G = pubKey.Parameters.G; + ECPoint W = pubKey.Q; + // calculate P using Bouncy math + ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r).Normalize(); if (P.IsInfinity) return false; - BigInteger x = P.X.ToBigInteger(); - BigInteger t = r.Subtract(x).Mod(n); + BigInteger x = P.AffineXCoord.ToBigInteger(); + BigInteger t = r.Subtract(x).Mod(n); - return t.Equals(e); - } - } + return t.Equals(e); + } + } } diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs index 38daa719c..d369cb2b7 100644 --- a/crypto/src/math/ec/ECCurve.cs +++ b/crypto/src/math/ec/ECCurve.cs @@ -99,6 +99,8 @@ namespace Org.BouncyCastle.Math.EC protected abstract ECCurve CloneCurve(); + protected internal abstract ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression); + protected virtual ECMultiplier CreateDefaultMultiplier() { return new WNafMultiplier(); @@ -145,7 +147,7 @@ namespace Org.BouncyCastle.Math.EC // TODO Default behaviour could be improved if the two curves have the same coordinate system by copying any Z coordinates. p = p.Normalize(); - return CreatePoint(p.X.ToBigInteger(), p.Y.ToBigInteger(), p.IsCompressed); + return CreatePoint(p.XCoord.ToBigInteger(), p.YCoord.ToBigInteger(), p.IsCompressed); } /** @@ -375,6 +377,20 @@ namespace Org.BouncyCastle.Math.EC return new FpCurve(m_q, m_r, m_a, m_b); } + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_AFFINE: + case COORD_HOMOGENEOUS: + //case COORD_JACOBIAN: + //case COORD_JACOBIAN_MODIFIED: + return true; + default: + return false; + } + } + public virtual BigInteger Q { get { return m_q; } @@ -395,6 +411,11 @@ namespace Org.BouncyCastle.Math.EC return new FpFieldElement(this.m_q, this.m_r, x); } + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new FpPoint(this, x, y, withCompression); + } + public override ECPoint CreatePoint( BigInteger X1, BigInteger Y1, @@ -710,6 +731,11 @@ namespace Org.BouncyCastle.Math.EC return base.CreateDefaultMultiplier(); } + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new F2mPoint(this, x, y, withCompression); + } + public override ECPoint Infinity { get { return m_infinity; } diff --git a/crypto/src/math/ec/ECPoint.cs b/crypto/src/math/ec/ECPoint.cs index 7a4450ac1..86134f80c 100644 --- a/crypto/src/math/ec/ECPoint.cs +++ b/crypto/src/math/ec/ECPoint.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Diagnostics; +using System.Text; using Org.BouncyCastle.Math.EC.Multiplier; @@ -51,24 +52,18 @@ namespace Org.BouncyCastle.Math.EC protected internal PreCompInfo m_preCompInfo = null; - protected ECPoint( - ECCurve curve, - ECFieldElement x, - ECFieldElement y, - bool withCompression) + protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : this(curve, x, y, GetInitialZCoords(curve), withCompression) { - this.m_curve = curve; - this.m_x = x; - this.m_y = y; - this.m_withCompression = withCompression; } - protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs) + internal ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) { this.m_curve = curve; this.m_x = x; this.m_y = y; this.m_zs = zs; + this.m_withCompression = withCompression; } public virtual ECCurve Curve @@ -85,12 +80,84 @@ namespace Org.BouncyCastle.Math.EC } } + /** + * Normalizes this point, and then returns the affine x-coordinate. + * + * Note: normalization can be expensive, this method is deprecated in favour + * of caller-controlled normalization. + */ + [Obsolete("Use AffineXCoord, or Normalize() and XCoord, instead")] public virtual ECFieldElement X { - get { return m_x; } + get { return Normalize().XCoord; } } + /** + * Normalizes this point, and then returns the affine y-coordinate. + * + * Note: normalization can be expensive, this method is deprecated in favour + * of caller-controlled normalization. + */ + [Obsolete("Use AffineYCoord, or Normalize() and YCoord, instead")] public virtual ECFieldElement Y + { + get { return Normalize().YCoord; } + } + + /** + * Returns the affine x-coordinate after checking that this point is normalized. + * + * @return The affine x-coordinate of this point + * @throws IllegalStateException if the point is not normalized + */ + public virtual ECFieldElement AffineXCoord + { + get + { + CheckNormalized(); + return XCoord; + } + } + + /** + * Returns the affine y-coordinate after checking that this point is normalized + * + * @return The affine y-coordinate of this point + * @throws IllegalStateException if the point is not normalized + */ + public virtual ECFieldElement AffineYCoord + { + get + { + CheckNormalized(); + return YCoord; + } + } + + /** + * Returns the x-coordinate. + * + * Caution: depending on the curve's coordinate system, this may not be the same value as in an + * affine coordinate system; use Normalize() to get a point where the coordinates have their + * affine values, or use AffineXCoord if you expect the point to already have been normalized. + * + * @return the x-coordinate of this point + */ + public virtual ECFieldElement XCoord + { + get { return m_x; } + } + + /** + * Returns the y-coordinate. + * + * Caution: depending on the curve's coordinate system, this may not be the same value as in an + * affine coordinate system; use Normalize() to get a point where the coordinates have their + * affine values, or use AffineYCoord if you expect the point to already have been normalized. + * + * @return the y-coordinate of this point + */ + public virtual ECFieldElement YCoord { get { return m_y; } } @@ -112,6 +179,16 @@ namespace Org.BouncyCastle.Math.EC return copy; } + protected virtual ECFieldElement RawXCoord + { + get { return m_x; } + } + + protected virtual ECFieldElement RawYCoord + { + get { return m_y; } + } + protected virtual void CheckNormalized() { if (!IsNormalized()) @@ -124,8 +201,8 @@ namespace Org.BouncyCastle.Math.EC return coord == ECCurve.COORD_AFFINE || coord == ECCurve.COORD_LAMBDA_AFFINE - || IsInfinity; - //|| zs[0].isOne(); + || IsInfinity + || GetZCoord(0).IsOne; } /** @@ -163,27 +240,30 @@ namespace Org.BouncyCastle.Math.EC internal virtual ECPoint Normalize(ECFieldElement zInv) { - throw new InvalidOperationException("not a projective coordinate system"); - - //switch (this.CurveCoordinateSystem) - //{ - // case ECCurve.COORD_HOMOGENEOUS: - // case ECCurve.COORD_LAMBDA_PROJECTIVE: - // { - // return CreateScaledPoint(zInv, zInv); - // } - // case ECCurve.COORD_JACOBIAN: - // case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: - // case ECCurve.COORD_JACOBIAN_MODIFIED: - // { - // ECFieldElement zInv2 = zInv.Square(), zInv3 = zInv2.Multiply(zInv); - // return CreateScaledPoint(zInv2, zInv3); - // } - // default: - // { - // throw new InvalidOperationException("not a projective coordinate system"); - // } - //} + switch (this.CurveCoordinateSystem) + { + case ECCurve.COORD_HOMOGENEOUS: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + return CreateScaledPoint(zInv, zInv); + } + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + ECFieldElement zInv2 = zInv.Square(), zInv3 = zInv2.Multiply(zInv); + return CreateScaledPoint(zInv2, zInv3); + } + default: + { + throw new InvalidOperationException("not a projective coordinate system"); + } + } + } + + protected virtual ECPoint CreateScaledPoint(ECFieldElement sx, ECFieldElement sy) + { + return Curve.CreateRawPoint(RawXCoord.Multiply(sx), RawYCoord.Multiply(sy), IsCompressed); } public bool IsInfinity @@ -208,26 +288,87 @@ namespace Org.BouncyCastle.Math.EC if (null == other) return false; + ECCurve c1 = this.Curve, c2 = other.Curve; + bool n1 = (null == c1), n2 = (null == c2); bool i1 = IsInfinity, i2 = other.IsInfinity; + if (i1 || i2) { - return i1 && i2; + return (i1 && i2) && (n1 || n2 || c1.Equals(c2)); + } + + ECPoint p1 = this, p2 = other; + if (n1 && n2) + { + // Points with null curve are in affine form, so already normalized + } + else if (n1) + { + p2 = p2.Normalize(); + } + else if (n2) + { + p1 = p1.Normalize(); + } + else if (!c1.Equals(c2)) + { + return false; + } + else + { + // TODO Consider just requiring already normalized, to avoid silent performance degradation + + ECPoint[] points = new ECPoint[] { this, c1.ImportPoint(p2) }; + + // TODO This is a little strong, really only requires coZNormalizeAll to get Zs equal + c1.NormalizeAll(points); + + p1 = points[0]; + p2 = points[1]; } - return X.Equals(other.X) && Y.Equals(other.Y); + return p1.XCoord.Equals(p2.XCoord) && p1.YCoord.Equals(p2.YCoord); } public override int GetHashCode() { - int hc = 0; - if (!IsInfinity) + ECCurve c = this.Curve; + int hc = (null == c) ? 0 : ~c.GetHashCode(); + + if (!this.IsInfinity) { - hc ^= X.GetHashCode() * 17; - hc ^= Y.GetHashCode() * 257; + // TODO Consider just requiring already normalized, to avoid silent performance degradation + + ECPoint p = Normalize(); + + hc ^= p.XCoord.GetHashCode() * 17; + hc ^= p.YCoord.GetHashCode() * 257; } + return hc; } + public override string ToString() + { + if (this.IsInfinity) + { + return "INF"; + } + + StringBuilder sb = new StringBuilder(); + sb.Append('('); + sb.Append(RawXCoord); + sb.Append(','); + sb.Append(RawYCoord); + for (int i = 0; i < m_zs.Length; ++i) + { + sb.Append(','); + sb.Append(m_zs[i]); + } + sb.Append(')'); + return sb.ToString(); + } + public virtual byte[] GetEncoded() { return GetEncoded(m_withCompression); @@ -280,6 +421,11 @@ namespace Org.BouncyCastle.Math.EC { } + protected internal ECPointBase(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + /** * return the field element encoded with point compression. (S 4.3.6) */ @@ -292,7 +438,7 @@ namespace Org.BouncyCastle.Math.EC ECPoint normed = Normalize(); - byte[] X = normed.X.GetEncoded(); + byte[] X = normed.XCoord.GetEncoded(); if (compressed) { @@ -302,7 +448,7 @@ namespace Org.BouncyCastle.Math.EC return PO; } - byte[] Y = normed.Y.GetEncoded(); + byte[] Y = normed.YCoord.GetEncoded(); { byte[] PO = new byte[X.Length + Y.Length + 1]; @@ -374,9 +520,14 @@ namespace Org.BouncyCastle.Math.EC throw new ArgumentException("Exactly one of the field elements is null"); } + internal FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + protected internal override bool CompressionYTilde { - get { return this.Y.TestBitZero(); } + get { return this.AffineYCoord.TestBitZero(); } } // B.3 pg 62 @@ -396,28 +547,84 @@ namespace Org.BouncyCastle.Math.EC return Twice(); } - ECFieldElement X1 = this.X, Y1 = this.Y; - ECFieldElement X2 = b.X, Y2 = b.Y; + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; - ECFieldElement dx = X2.Subtract(X1), dy = Y2.Subtract(Y1); + ECFieldElement X1 = this.XCoord, Y1 = this.YCoord; + ECFieldElement X2 = b.XCoord, Y2 = b.YCoord; - if (dx.IsZero) + switch (coord) { - if (dy.IsZero) + case ECCurve.COORD_AFFINE: { - // this == b, i.e. this must be doubled - return Twice(); + ECFieldElement dx = X2.Subtract(X1), dy = Y2.Subtract(Y1); + + if (dx.IsZero) + { + if (dy.IsZero) + { + // this == b, i.e. this must be doubled + return Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return Curve.Infinity; + } + + ECFieldElement gamma = dy.Divide(dx); + ECFieldElement X3 = gamma.Square().Subtract(X1).Subtract(X2); + ECFieldElement Y3 = gamma.Multiply(X1.Subtract(X3)).Subtract(Y1); + + return new FpPoint(Curve, X3, Y3, IsCompressed); } - // this == -b, i.e. the result is the point at infinity - return Curve.Infinity; - } + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Z1 = this.GetZCoord(0); + ECFieldElement Z2 = b.GetZCoord(0); + + bool Z1IsOne = Z1.IsOne; + bool Z2IsOne = Z2.IsOne; + + ECFieldElement u1 = Z1IsOne ? Y2 : Y2.Multiply(Z1); + ECFieldElement u2 = Z2IsOne ? Y1 : Y1.Multiply(Z2); + ECFieldElement u = u1.Subtract(u2); + ECFieldElement v1 = Z1IsOne ? X2 : X2.Multiply(Z1); + ECFieldElement v2 = Z2IsOne ? X1 : X1.Multiply(Z2); + ECFieldElement v = v1.Subtract(v2); + + // Check if b == this or b == -this + if (v.IsZero) + { + if (u.IsZero) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + // TODO Optimize for when w == 1 + ECFieldElement w = Z1IsOne ? Z2 : Z2IsOne ? Z1 : Z1.Multiply(Z2); + ECFieldElement vSquared = v.Square(); + ECFieldElement vCubed = vSquared.Multiply(v); + ECFieldElement vSquaredV2 = vSquared.Multiply(v2); + ECFieldElement A = u.Square().Multiply(w).Subtract(vCubed).Subtract(Two(vSquaredV2)); - ECFieldElement gamma = dy.Divide(dx); - ECFieldElement X3 = gamma.Square().Subtract(X1).Subtract(X2); - ECFieldElement Y3 = gamma.Multiply(X1.Subtract(X3)).Subtract(Y1); + ECFieldElement X3 = v.Multiply(A); + ECFieldElement Y3 = vSquaredV2.Subtract(A).Multiply(u).Subtract(vCubed.Multiply(u2)); + ECFieldElement Z3 = vCubed.Multiply(w); - return new FpPoint(Curve, X3, Y3, IsCompressed); + return new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } } // B.3 pg 62 @@ -428,20 +635,65 @@ namespace Org.BouncyCastle.Math.EC return this; } - ECFieldElement Y1 = this.Y; + ECCurve curve = this.Curve; + + ECFieldElement Y1 = this.YCoord; if (Y1.IsZero) { - return Curve.Infinity; + return curve.Infinity; } - ECFieldElement X1 = this.X; + int coord = curve.CoordinateSystem; + + ECFieldElement X1 = this.XCoord; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement X1Squared = X1.Square(); + ECFieldElement gamma = Three(X1Squared).Add(this.Curve.A).Divide(Two(Y1)); + ECFieldElement X3 = gamma.Square().Subtract(Two(X1)); + ECFieldElement Y3 = gamma.Multiply(X1.Subtract(X3)).Subtract(Y1); - ECFieldElement X1Squared = X1.Square(); - ECFieldElement gamma = Three(X1Squared).Add(this.Curve.A).Divide(Two(Y1)); - ECFieldElement X3 = gamma.Square().Subtract(Two(X1)); - ECFieldElement Y3 = gamma.Multiply(X1.Subtract(X3)).Subtract(Y1); + return new FpPoint(Curve, X3, Y3, IsCompressed); + } + + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Z1 = this.GetZCoord(0); + + bool Z1IsOne = Z1.IsOne; + + // TODO Optimize for small negative a4 and -3 + ECFieldElement w = curve.A; + if (!w.IsZero && !Z1IsOne) + { + w = w.Multiply(Z1.Square()); + } + w = w.Add(Three(X1.Square())); + + ECFieldElement s = Z1IsOne ? Y1 : Y1.Multiply(Z1); + ECFieldElement t = Z1IsOne ? Y1.Square() : s.Multiply(Y1); + ECFieldElement B = X1.Multiply(t); + ECFieldElement _4B = Four(B); + ECFieldElement h = w.Square().Subtract(Two(_4B)); + + ECFieldElement _2s = Two(s); + ECFieldElement X3 = h.Multiply(_2s); + ECFieldElement _2t = Two(t); + ECFieldElement Y3 = _4B.Subtract(h).Multiply(w).Subtract(Two(_2t.Square())); + ECFieldElement _4sSquared = Z1IsOne ? Two(_2t) : _2s.Square(); + ECFieldElement Z3 = Two(_4sSquared).Multiply(s); + + return new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } - return new FpPoint(Curve, X3, Y3, IsCompressed); + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } } public override ECPoint TwicePlus(ECPoint b) @@ -459,79 +711,106 @@ namespace Org.BouncyCastle.Math.EC return Twice(); } - ECFieldElement Y1 = this.Y; + ECFieldElement Y1 = this.YCoord; if (Y1.IsZero) { return b; } - ECFieldElement X1 = this.X; - ECFieldElement X2 = b.X, Y2 = b.Y; - - ECFieldElement dx = X2.Subtract(X1), dy = Y2.Subtract(Y1); + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; - if (dx.IsZero) + switch (coord) { - if (dy.IsZero) + case ECCurve.COORD_AFFINE: { - // this == b i.e. the result is 3P - return ThreeTimes(); - } + ECFieldElement X1 = this.XCoord; + ECFieldElement X2 = b.XCoord, Y2 = b.YCoord; - // this == -b, i.e. the result is P - return this; - } + ECFieldElement dx = X2.Subtract(X1), dy = Y2.Subtract(Y1); - /* - * Optimized calculation of 2P + Q, as described in "Trading Inversions for - * Multiplications in Elliptic Curve Cryptography", by Ciet, Joye, Lauter, Montgomery. - */ + if (dx.IsZero) + { + if (dy.IsZero) + { + // this == b i.e. the result is 3P + return ThreeTimes(); + } - ECFieldElement X = dx.Square(), Y = dy.Square(); - ECFieldElement d = X.Multiply(Two(X1).Add(X2)).Subtract(Y); - if (d.IsZero) - { - return Curve.Infinity; - } + // this == -b, i.e. the result is P + return this; + } - ECFieldElement D = d.Multiply(dx); - ECFieldElement I = D.Invert(); - ECFieldElement L1 = d.Multiply(I).Multiply(dy); - ECFieldElement L2 = Two(Y1).Multiply(X).Multiply(dx).Multiply(I).Subtract(L1); - ECFieldElement X4 = (L2.Subtract(L1)).Multiply(L1.Add(L2)).Add(X2); - ECFieldElement Y4 = (X1.Subtract(X4)).Multiply(L2).Subtract(Y1); + /* + * Optimized calculation of 2P + Q, as described in "Trading Inversions for + * Multiplications in Elliptic Curve Cryptography", by Ciet, Joye, Lauter, Montgomery. + */ - return new FpPoint(Curve, X4, Y4, IsCompressed); + ECFieldElement X = dx.Square(), Y = dy.Square(); + ECFieldElement d = X.Multiply(Two(X1).Add(X2)).Subtract(Y); + if (d.IsZero) + { + return Curve.Infinity; + } + + ECFieldElement D = d.Multiply(dx); + ECFieldElement I = D.Invert(); + ECFieldElement L1 = d.Multiply(I).Multiply(dy); + ECFieldElement L2 = Two(Y1).Multiply(X).Multiply(dx).Multiply(I).Subtract(L1); + ECFieldElement X4 = (L2.Subtract(L1)).Multiply(L1.Add(L2)).Add(X2); + ECFieldElement Y4 = (X1.Subtract(X4)).Multiply(L2).Subtract(Y1); + + return new FpPoint(Curve, X4, Y4, IsCompressed); + } + default: + { + return Twice().Add(b); + } + } } public override ECPoint ThreeTimes() { - if (IsInfinity || this.Y.IsZero) + if (IsInfinity || this.YCoord.IsZero) { return this; } - ECFieldElement X1 = this.X, Y1 = this.Y; - - ECFieldElement _2Y1 = Two(Y1); - ECFieldElement X = _2Y1.Square(); - ECFieldElement Z = Three(X1.Square()).Add(Curve.A); - ECFieldElement Y = Z.Square(); + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; - ECFieldElement d = Three(X1).Multiply(X).Subtract(Y); - if (d.IsZero) + switch (coord) { - return Curve.Infinity; - } + case ECCurve.COORD_AFFINE: + { + ECFieldElement X1 = this.XCoord, Y1 = this.YCoord; - ECFieldElement D = d.Multiply(_2Y1); - ECFieldElement I = D.Invert(); - ECFieldElement L1 = d.Multiply(I).Multiply(Z); - ECFieldElement L2 = X.Square().Multiply(I).Subtract(L1); + ECFieldElement _2Y1 = Two(Y1); + ECFieldElement X = _2Y1.Square(); + ECFieldElement Z = Three(X1.Square()).Add(Curve.A); + ECFieldElement Y = Z.Square(); - ECFieldElement X4 = (L2.Subtract(L1)).Multiply(L1.Add(L2)).Add(X1); - ECFieldElement Y4 = (X1.Subtract(X4)).Multiply(L2).Subtract(Y1); - return new FpPoint(Curve, X4, Y4, IsCompressed); + ECFieldElement d = Three(X1).Multiply(X).Subtract(Y); + if (d.IsZero) + { + return Curve.Infinity; + } + + ECFieldElement D = d.Multiply(_2Y1); + ECFieldElement I = D.Invert(); + ECFieldElement L1 = d.Multiply(I).Multiply(Z); + ECFieldElement L2 = X.Square().Multiply(I).Subtract(L1); + + ECFieldElement X4 = (L2.Subtract(L1)).Multiply(L1.Add(L2)).Add(X1); + ECFieldElement Y4 = (X1.Subtract(X4)).Multiply(L2).Subtract(Y1); + return new FpPoint(Curve, X4, Y4, IsCompressed); + } + default: + { + // NOTE: Be careful about recursions between twicePlus and threeTimes + return Twice().Add(this); + } + } } protected virtual ECFieldElement Two(ECFieldElement x) @@ -583,14 +862,14 @@ namespace Org.BouncyCastle.Math.EC } ECCurve curve = this.Curve; - //int coord = curve.CoordinateSystem; + int coord = curve.CoordinateSystem; - //if (ECCurve.COORD_AFFINE != coord) - //{ - // return new FpPoint(curve, X, Y.Negate(), this.m_zs, IsCompressed); - //} + if (ECCurve.COORD_AFFINE != coord) + { + return new FpPoint(curve, XCoord, YCoord.Negate(), this.m_zs, IsCompressed); + } - return new FpPoint(curve, X, Y.Negate(), IsCompressed); + return new FpPoint(curve, XCoord, YCoord.Negate(), IsCompressed); } } @@ -637,10 +916,18 @@ namespace Org.BouncyCastle.Math.EC F2mFieldElement.CheckFieldElements(x, y); // Check if x and a are elements of the same field - F2mFieldElement.CheckFieldElements(x, curve.A); + if (curve != null) + { + F2mFieldElement.CheckFieldElements(x, curve.A); + } } } + internal F2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + /** * Constructor for point at infinity */ @@ -655,10 +942,28 @@ namespace Org.BouncyCastle.Math.EC { get { - // X9.62 4.2.2 and 4.3.6: - // if x = 0 then ypTilde := 0, else ypTilde is the rightmost - // bit of y * x^(-1) - return !this.X.IsZero && this.Y.Divide(this.X).TestBitZero(); + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + { + return false; + } + + ECFieldElement Y = this.RawYCoord; + + switch (this.CurveCoordinateSystem) + { + case ECCurve.COORD_LAMBDA_AFFINE: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + // Y is actually Lambda (X + Y/X) here + return Y.Subtract(X).TestBitZero(); + } + default: + { + return Y.Divide(X).TestBitZero(); + } + } + } } @@ -706,30 +1011,30 @@ namespace Org.BouncyCastle.Math.EC if (b.IsInfinity) return this; - F2mFieldElement x2 = (F2mFieldElement) b.X; - F2mFieldElement y2 = (F2mFieldElement) b.Y; + F2mFieldElement x2 = (F2mFieldElement) b.XCoord; + F2mFieldElement y2 = (F2mFieldElement) b.YCoord; // Check if b == this or b == -this - if (this.X.Equals(x2)) + if (this.XCoord.Equals(x2)) { // this == b, i.e. this must be doubled - if (this.Y.Equals(y2)) + if (this.YCoord.Equals(y2)) return (F2mPoint) this.Twice(); // this = -other, i.e. the result is the point at infinity return (F2mPoint) Curve.Infinity; } - ECFieldElement xSum = this.X.Add(x2); + ECFieldElement xSum = this.XCoord.Add(x2); F2mFieldElement lambda - = (F2mFieldElement)(this.Y.Add(y2)).Divide(xSum); + = (F2mFieldElement)(this.YCoord.Add(y2)).Divide(xSum); F2mFieldElement x3 = (F2mFieldElement)lambda.Square().Add(lambda).Add(xSum).Add(Curve.A); F2mFieldElement y3 - = (F2mFieldElement)lambda.Multiply(this.X.Add(x3)).Add(x3).Add(this.Y); + = (F2mFieldElement)lambda.Multiply(this.XCoord.Add(x3)).Add(x3).Add(this.YCoord); return new F2mPoint(Curve, x3, y3, IsCompressed); } @@ -763,6 +1068,39 @@ namespace Org.BouncyCastle.Math.EC return AddSimple((F2mPoint) b.Negate()); } + public virtual F2mPoint Tau() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + ECFieldElement X1 = this.XCoord; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + case ECCurve.COORD_LAMBDA_AFFINE: + { + ECFieldElement Y1 = this.YCoord; + return new F2mPoint(curve, X1.Square(), Y1.Square(), IsCompressed); + } + case ECCurve.COORD_HOMOGENEOUS: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + ECFieldElement Y1 = this.YCoord, Z1 = this.GetZCoord(0); + return new F2mPoint(curve, X1.Square(), Y1.Square(), new ECFieldElement[] { Z1.Square() }, IsCompressed); + } + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + /* (non-Javadoc) * @see Org.BouncyCastle.Math.EC.ECPoint#twice() */ @@ -774,15 +1112,15 @@ namespace Org.BouncyCastle.Math.EC // if x1 == 0, then (x1, y1) == (x1, x1 + y1) // and hence this = -this and thus 2(x1, y1) == infinity - if (this.X.IsZero) + if (this.XCoord.IsZero) { return Curve.Infinity; } - F2mFieldElement lambda = (F2mFieldElement) this.X.Add(this.Y.Divide(this.X)); + F2mFieldElement lambda = (F2mFieldElement) this.XCoord.Add(this.YCoord.Divide(this.XCoord)); F2mFieldElement x2 = (F2mFieldElement)lambda.Square().Add(lambda).Add(Curve.A); ECFieldElement ONE = Curve.FromBigInteger(BigInteger.One); - F2mFieldElement y2 = (F2mFieldElement)this.X.Square().Add( + F2mFieldElement y2 = (F2mFieldElement)this.XCoord.Square().Add( x2.Multiply(lambda.Add(ONE))); return new F2mPoint(Curve, x2, y2, IsCompressed); @@ -795,13 +1133,13 @@ namespace Org.BouncyCastle.Math.EC return this; } - ECFieldElement X1 = this.X; + ECFieldElement X1 = this.XCoord; if (X1.IsZero) { return this; } - return new F2mPoint(Curve, X1, X1.Add(this.Y), IsCompressed); + return new F2mPoint(Curve, X1, X1.Add(this.YCoord), IsCompressed); } } } diff --git a/crypto/src/math/ec/abc/Tnaf.cs b/crypto/src/math/ec/abc/Tnaf.cs index 225fc3075..0ba414e68 100644 --- a/crypto/src/math/ec/abc/Tnaf.cs +++ b/crypto/src/math/ec/abc/Tnaf.cs @@ -2,833 +2,827 @@ using System; namespace Org.BouncyCastle.Math.EC.Abc { - /** - * Class holding methods for point multiplication based on the window - * τ-adic nonadjacent form (WTNAF). The algorithms are based on the - * paper "Improved Algorithms for Arithmetic on Anomalous Binary Curves" - * by Jerome A. Solinas. The paper first appeared in the Proceedings of - * Crypto 1997. - */ - internal class Tnaf - { - private static readonly BigInteger MinusOne = BigInteger.One.Negate(); - private static readonly BigInteger MinusTwo = BigInteger.Two.Negate(); - private static readonly BigInteger MinusThree = BigInteger.Three.Negate(); - private static readonly BigInteger Four = BigInteger.ValueOf(4); - - /** - * The window width of WTNAF. The standard value of 4 is slightly less - * than optimal for running time, but keeps space requirements for - * precomputation low. For typical curves, a value of 5 or 6 results in - * a better running time. When changing this value, the - * αu's must be computed differently, see - * e.g. "Guide to Elliptic Curve Cryptography", Darrel Hankerson, - * Alfred Menezes, Scott Vanstone, Springer-Verlag New York Inc., 2004, - * p. 121-122 - */ - public const sbyte Width = 4; - - /** - * 24 - */ - public const sbyte Pow2Width = 16; - - /** - * The αu's for a=0 as an array - * of ZTauElements. - */ - public static readonly ZTauElement[] Alpha0 = - { - null, - new ZTauElement(BigInteger.One, BigInteger.Zero), null, - new ZTauElement(MinusThree, MinusOne), null, - new ZTauElement(MinusOne, MinusOne), null, - new ZTauElement(BigInteger.One, MinusOne), null - }; - - /** - * The αu's for a=0 as an array - * of TNAFs. - */ - public static readonly sbyte[][] Alpha0Tnaf = - { - null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, 1} - }; - - /** - * The αu's for a=1 as an array - * of ZTauElements. - */ - public static readonly ZTauElement[] Alpha1 = - { - null, - new ZTauElement(BigInteger.One, BigInteger.Zero), null, - new ZTauElement(MinusThree, BigInteger.One), null, - new ZTauElement(MinusOne, BigInteger.One), null, - new ZTauElement(BigInteger.One, BigInteger.One), null - }; - - /** - * The αu's for a=1 as an array - * of TNAFs. - */ - public static readonly sbyte[][] Alpha1Tnaf = - { - null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, -1} - }; - - /** - * Computes the norm of an element λ of - * Z[τ]. - * @param mu The parameter μ of the elliptic curve. - * @param lambda The element λ of - * Z[τ]. - * @return The norm of λ. - */ - public static BigInteger Norm(sbyte mu, ZTauElement lambda) - { - BigInteger norm; - - // s1 = u^2 - BigInteger s1 = lambda.u.Multiply(lambda.u); - - // s2 = u * v - BigInteger s2 = lambda.u.Multiply(lambda.v); - - // s3 = 2 * v^2 - BigInteger s3 = lambda.v.Multiply(lambda.v).ShiftLeft(1); - - if (mu == 1) - { - norm = s1.Add(s2).Add(s3); - } - else if (mu == -1) - { - norm = s1.Subtract(s2).Add(s3); - } - else - { - throw new ArgumentException("mu must be 1 or -1"); - } - - return norm; - } - - /** - * Computes the norm of an element λ of - * R[τ], where λ = u + vτ - * and u and u are real numbers (elements of - * R). - * @param mu The parameter μ of the elliptic curve. - * @param u The real part of the element λ of - * R[τ]. - * @param v The τ-adic part of the element - * λ of R[τ]. - * @return The norm of λ. - */ - public static SimpleBigDecimal Norm(sbyte mu, SimpleBigDecimal u, SimpleBigDecimal v) - { - SimpleBigDecimal norm; - - // s1 = u^2 - SimpleBigDecimal s1 = u.Multiply(u); - - // s2 = u * v - SimpleBigDecimal s2 = u.Multiply(v); - - // s3 = 2 * v^2 - SimpleBigDecimal s3 = v.Multiply(v).ShiftLeft(1); - - if (mu == 1) - { - norm = s1.Add(s2).Add(s3); - } - else if (mu == -1) - { - norm = s1.Subtract(s2).Add(s3); - } - else - { - throw new ArgumentException("mu must be 1 or -1"); - } - - return norm; - } - - /** - * Rounds an element λ of R[τ] - * to an element of Z[τ], such that their difference - * has minimal norm. λ is given as - * λ = λ0 + λ1τ. - * @param lambda0 The component λ0. - * @param lambda1 The component λ1. - * @param mu The parameter μ of the elliptic curve. Must - * equal 1 or -1. - * @return The rounded element of Z[τ]. - * @throws ArgumentException if lambda0 and - * lambda1 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); - } - - /** - * Approximate division by n. For an integer - * k, the value λ = s k / n is - * computed to c bits of accuracy. - * @param k The parameter k. - * @param s The curve parameter s0 or - * s1. - * @param vm The Lucas Sequence element Vm. - * @param a The parameter a of the elliptic curve. - * @param m The bit length of the finite field - * Fm. - * @param c The number of bits of accuracy, i.e. the scale of the returned - * SimpleBigDecimal. - * @return The value λ = s k / n computed to - * c bits of accuracy. - */ - public static SimpleBigDecimal ApproximateDivisionByN(BigInteger k, - BigInteger s, BigInteger vm, sbyte a, int m, int c) - { - int _k = (m + 5)/2 + c; - BigInteger ns = k.ShiftRight(m - _k - 2 + a); - - BigInteger gs = s.Multiply(ns); - - BigInteger hs = gs.ShiftRight(m); - - BigInteger js = vm.Multiply(hs); - - BigInteger gsPlusJs = gs.Add(js); - BigInteger ls = gsPlusJs.ShiftRight(_k-c); - if (gsPlusJs.TestBit(_k-c-1)) - { - // round up - ls = ls.Add(BigInteger.One); - } - - return new SimpleBigDecimal(ls, c); - } - - /** - * Computes the τ-adic NAF (non-adjacent form) of an - * element λ of Z[τ]. - * @param mu The parameter μ of the elliptic curve. - * @param lambda The element λ of - * Z[τ]. - * @return The τ-adic NAF of λ. - */ - 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; - } - - /** - * Applies the operation τ() to an - * F2mPoint. - * @param p The F2mPoint to which τ() is applied. - * @return τ(p) - */ - public static F2mPoint Tau(F2mPoint p) - { - if (p.IsInfinity) - return p; - - ECFieldElement x = p.X; - ECFieldElement y = p.Y; - - return new F2mPoint(p.Curve, x.Square(), y.Square(), p.IsCompressed); - } - - /** - * Returns the parameter μ of the elliptic curve. - * @param curve The elliptic curve from which to obtain μ. - * The curve must be a Koblitz curve, i.e. a Equals - * 0 or 1 and b Equals - * 1. - * @return μ of the elliptic curve. - * @throws ArgumentException if the given ECCurve is not a Koblitz - * curve. - */ - public static sbyte GetMu(F2mCurve curve) - { - BigInteger a = curve.A.ToBigInteger(); - - sbyte mu; - if (a.SignValue == 0) - { - mu = -1; - } - else if (a.Equals(BigInteger.One)) - { - mu = 1; - } - else - { - throw new ArgumentException("No Koblitz curve (ABC), TNAF multiplication not possible"); - } - return mu; - } - - /** - * Calculates the Lucas Sequence elements Uk-1 and - * Uk or Vk-1 and - * Vk. - * @param mu The parameter μ of the elliptic curve. - * @param k The index of the second element of the Lucas Sequence to be - * returned. - * @param doV If set to true, computes Vk-1 and - * Vk, otherwise Uk-1 and - * Uk. - * @return An array with 2 elements, containing Uk-1 - * and Uk or Vk-1 - * and Vk. - */ - public static BigInteger[] GetLucas(sbyte mu, int k, bool doV) - { - if (!(mu == 1 || mu == -1)) - throw new ArgumentException("mu must be 1 or -1"); - - BigInteger u0; - BigInteger u1; - BigInteger u2; - - if (doV) - { - u0 = BigInteger.Two; - u1 = BigInteger.ValueOf(mu); - } - else - { - u0 = BigInteger.Zero; - u1 = BigInteger.One; - } - - for (int i = 1; i < k; i++) - { - // u2 = mu*u1 - 2*u0; - BigInteger s = null; - if (mu == 1) - { - s = u1; - } - else - { - // mu == -1 - s = u1.Negate(); - } - - u2 = s.Subtract(u0.ShiftLeft(1)); - u0 = u1; - u1 = u2; - // System.out.println(i + ": " + u2); - // System.out.println(); - } - - BigInteger[] retVal = {u0, u1}; - return retVal; - } - - /** - * Computes the auxiliary value tw. If the width is - * 4, then for mu = 1, tw = 6 and for - * mu = -1, tw = 10 - * @param mu The parameter μ of the elliptic curve. - * @param w The window width of the WTNAF. - * @return the auxiliary value tw - */ - public static BigInteger GetTw(sbyte mu, int w) - { - if (w == 4) - { - if (mu == 1) - { - return BigInteger.ValueOf(6); - } - else - { - // mu == -1 - return BigInteger.ValueOf(10); - } - } - else - { - // For w <> 4, the values must be computed - BigInteger[] us = GetLucas(mu, w, false); - BigInteger twoToW = BigInteger.Zero.SetBit(w); - BigInteger u1invert = us[1].ModInverse(twoToW); - BigInteger tw; - tw = BigInteger.Two.Multiply(us[0]).Multiply(u1invert).Mod(twoToW); - //System.out.println("mu = " + mu); - //System.out.println("tw = " + tw); - return tw; - } - } - - /** - * Computes the auxiliary values s0 and - * s1 used for partial modular reduction. - * @param curve The elliptic curve for which to compute - * s0 and s1. - * @throws ArgumentException if curve is not a - * Koblitz curve (Anomalous Binary Curve, ABC). - */ - public static BigInteger[] GetSi(F2mCurve curve) - { - if (!curve.IsKoblitz) - throw new ArgumentException("si is defined for Koblitz curves only"); - - int m = curve.M; - int a = curve.A.ToBigInteger().IntValue; - sbyte mu = curve.GetMu(); - int h = curve.H.IntValue; - int index = m + 3 - a; - BigInteger[] ui = GetLucas(mu, index, false); - - BigInteger dividend0; - BigInteger dividend1; - if (mu == 1) - { - dividend0 = BigInteger.One.Subtract(ui[1]); - dividend1 = BigInteger.One.Subtract(ui[0]); - } - else if (mu == -1) - { - dividend0 = BigInteger.One.Add(ui[1]); - dividend1 = BigInteger.One.Add(ui[0]); - } - else - { - throw new ArgumentException("mu must be 1 or -1"); - } - - BigInteger[] si = new BigInteger[2]; - - if (h == 2) - { - si[0] = dividend0.ShiftRight(1); - si[1] = dividend1.ShiftRight(1).Negate(); - } - else if (h == 4) - { - si[0] = dividend0.ShiftRight(2); - si[1] = dividend1.ShiftRight(2).Negate(); - } - else - { - throw new ArgumentException("h (Cofactor) must be 2 or 4"); - } - - return si; - } - - /** - * Partial modular reduction modulo - * m - 1)/(τ - 1). - * @param k The integer to be reduced. - * @param m The bitlength of the underlying finite field. - * @param a The parameter a of the elliptic curve. - * @param s The auxiliary values s0 and - * s1. - * @param mu The parameter μ of the elliptic curve. - * @param c The precision (number of bits of accuracy) of the partial - * modular reduction. - * @return ρ := k partmod (τm - 1)/(τ - 1) - */ - public static ZTauElement PartModReduction(BigInteger k, int m, sbyte a, - BigInteger[] s, sbyte mu, sbyte c) - { - // d0 = s[0] + mu*s[1]; mu is either 1 or -1 - BigInteger d0; - if (mu == 1) - { - d0 = s[0].Add(s[1]); - } - else - { - d0 = s[0].Subtract(s[1]); - } - - BigInteger[] v = GetLucas(mu, m, true); - BigInteger vm = v[1]; - - SimpleBigDecimal lambda0 = ApproximateDivisionByN( - k, s[0], vm, a, m, c); - - SimpleBigDecimal lambda1 = ApproximateDivisionByN( - k, s[1], vm, a, m, c); - - ZTauElement q = Round(lambda0, lambda1, mu); - - // r0 = n - d0*q0 - 2*s1*q1 - BigInteger r0 = k.Subtract(d0.Multiply(q.u)).Subtract( - BigInteger.ValueOf(2).Multiply(s[1]).Multiply(q.v)); - - // r1 = s1*q0 - s0*q1 - BigInteger r1 = s[1].Multiply(q.u).Subtract(s[0].Multiply(q.v)); - - return new ZTauElement(r0, r1); - } - - /** - * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint} - * by a BigInteger using the reduced τ-adic - * NAF (RTNAF) method. - * @param p The F2mPoint to Multiply. - * @param k The BigInteger by which to Multiply p. - * @return k * p - */ - public static F2mPoint MultiplyRTnaf(F2mPoint p, BigInteger k) - { - F2mCurve curve = (F2mCurve) p.Curve; - int m = curve.M; - sbyte a = (sbyte) curve.A.ToBigInteger().IntValue; - sbyte mu = curve.GetMu(); - BigInteger[] s = curve.GetSi(); - ZTauElement rho = PartModReduction(k, m, a, s, mu, (sbyte)10); - - return MultiplyTnaf(p, rho); - } - - /** - * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint} - * by an element λ of Z[τ] - * using the τ-adic NAF (TNAF) method. - * @param p The F2mPoint to Multiply. - * @param lambda The element λ of - * Z[τ]. - * @return λ * p - */ - public static F2mPoint MultiplyTnaf(F2mPoint p, ZTauElement lambda) - { - F2mCurve curve = (F2mCurve)p.Curve; - sbyte mu = curve.GetMu(); - sbyte[] u = TauAdicNaf(mu, lambda); - - F2mPoint q = MultiplyFromTnaf(p, u); - - return q; - } - - /** - * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint} - * by an element λ of Z[τ] - * using the τ-adic NAF (TNAF) method, given the TNAF - * of λ. - * @param p The F2mPoint to Multiply. - * @param u The the TNAF of λ.. - * @return λ * p - */ - public static F2mPoint MultiplyFromTnaf(F2mPoint p, sbyte[] u) - { - F2mCurve curve = (F2mCurve)p.Curve; - F2mPoint q = (F2mPoint) curve.Infinity; - for (int i = u.Length - 1; i >= 0; i--) - { - q = Tau(q); - if (u[i] == 1) - { - q = (F2mPoint)q.AddSimple(p); - } - else if (u[i] == -1) - { - q = (F2mPoint)q.SubtractSimple(p); - } - } - return q; - } - - /** - * Computes the [τ]-adic window NAF of an element - * λ of Z[τ]. - * @param mu The parameter μ of the elliptic curve. - * @param lambda The element λ of - * Z[τ] of which to compute the - * [τ]-adic NAF. - * @param width The window width of the resulting WNAF. - * @param pow2w 2width. - * @param tw The auxiliary value tw. - * @param alpha The αu's for the window width. - * @return The [τ]-adic window NAF of - * λ. - */ - 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; - } - - /** - * Does the precomputation for WTNAF multiplication. - * @param p The ECPoint for which to do the precomputation. - * @param a The parameter a of the elliptic curve. - * @return The precomputation array for p. - */ - public static F2mPoint[] GetPreComp(F2mPoint p, sbyte a) - { - F2mPoint[] pu; - pu = new F2mPoint[16]; - pu[1] = p; - sbyte[][] alphaTnaf; - if (a == 0) - { - alphaTnaf = Tnaf.Alpha0Tnaf; - } - else - { - // a == 1 - alphaTnaf = Tnaf.Alpha1Tnaf; - } - - int precompLen = alphaTnaf.Length; - for (int i = 3; i < precompLen; i = i + 2) - { - pu[i] = Tnaf.MultiplyFromTnaf(p, alphaTnaf[i]); - } - - return pu; - } - } + /** + * Class holding methods for point multiplication based on the window + * τ-adic nonadjacent form (WTNAF). The algorithms are based on the + * paper "Improved Algorithms for Arithmetic on Anomalous Binary Curves" + * by Jerome A. Solinas. The paper first appeared in the Proceedings of + * Crypto 1997. + */ + internal class Tnaf + { + private static readonly BigInteger MinusOne = BigInteger.One.Negate(); + private static readonly BigInteger MinusTwo = BigInteger.Two.Negate(); + private static readonly BigInteger MinusThree = BigInteger.Three.Negate(); + private static readonly BigInteger Four = BigInteger.ValueOf(4); + + /** + * The window width of WTNAF. The standard value of 4 is slightly less + * than optimal for running time, but keeps space requirements for + * precomputation low. For typical curves, a value of 5 or 6 results in + * a better running time. When changing this value, the + * αu's must be computed differently, see + * e.g. "Guide to Elliptic Curve Cryptography", Darrel Hankerson, + * Alfred Menezes, Scott Vanstone, Springer-Verlag New York Inc., 2004, + * p. 121-122 + */ + public const sbyte Width = 4; + + /** + * 24 + */ + public const sbyte Pow2Width = 16; + + /** + * The αu's for a=0 as an array + * of ZTauElements. + */ + public static readonly ZTauElement[] Alpha0 = + { + null, + new ZTauElement(BigInteger.One, BigInteger.Zero), null, + new ZTauElement(MinusThree, MinusOne), null, + new ZTauElement(MinusOne, MinusOne), null, + new ZTauElement(BigInteger.One, MinusOne), null + }; + + /** + * The αu's for a=0 as an array + * of TNAFs. + */ + public static readonly sbyte[][] Alpha0Tnaf = + { + null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, 1} + }; + + /** + * The αu's for a=1 as an array + * of ZTauElements. + */ + public static readonly ZTauElement[] Alpha1 = + { + null, + new ZTauElement(BigInteger.One, BigInteger.Zero), null, + new ZTauElement(MinusThree, BigInteger.One), null, + new ZTauElement(MinusOne, BigInteger.One), null, + new ZTauElement(BigInteger.One, BigInteger.One), null + }; + + /** + * The αu's for a=1 as an array + * of TNAFs. + */ + public static readonly sbyte[][] Alpha1Tnaf = + { + null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, -1} + }; + + /** + * Computes the norm of an element λ of + * Z[τ]. + * @param mu The parameter μ of the elliptic curve. + * @param lambda The element λ of + * Z[τ]. + * @return The norm of λ. + */ + public static BigInteger Norm(sbyte mu, ZTauElement lambda) + { + BigInteger norm; + + // s1 = u^2 + BigInteger s1 = lambda.u.Multiply(lambda.u); + + // s2 = u * v + BigInteger s2 = lambda.u.Multiply(lambda.v); + + // s3 = 2 * v^2 + BigInteger s3 = lambda.v.Multiply(lambda.v).ShiftLeft(1); + + if (mu == 1) + { + norm = s1.Add(s2).Add(s3); + } + else if (mu == -1) + { + norm = s1.Subtract(s2).Add(s3); + } + else + { + throw new ArgumentException("mu must be 1 or -1"); + } + + return norm; + } + + /** + * Computes the norm of an element λ of + * R[τ], where λ = u + vτ + * and u and u are real numbers (elements of + * R). + * @param mu The parameter μ of the elliptic curve. + * @param u The real part of the element λ of + * R[τ]. + * @param v The τ-adic part of the element + * λ of R[τ]. + * @return The norm of λ. + */ + public static SimpleBigDecimal Norm(sbyte mu, SimpleBigDecimal u, SimpleBigDecimal v) + { + SimpleBigDecimal norm; + + // s1 = u^2 + SimpleBigDecimal s1 = u.Multiply(u); + + // s2 = u * v + SimpleBigDecimal s2 = u.Multiply(v); + + // s3 = 2 * v^2 + SimpleBigDecimal s3 = v.Multiply(v).ShiftLeft(1); + + if (mu == 1) + { + norm = s1.Add(s2).Add(s3); + } + else if (mu == -1) + { + norm = s1.Subtract(s2).Add(s3); + } + else + { + throw new ArgumentException("mu must be 1 or -1"); + } + + return norm; + } + + /** + * Rounds an element λ of R[τ] + * to an element of Z[τ], such that their difference + * has minimal norm. λ is given as + * λ = λ0 + λ1τ. + * @param lambda0 The component λ0. + * @param lambda1 The component λ1. + * @param mu The parameter μ of the elliptic curve. Must + * equal 1 or -1. + * @return The rounded element of Z[τ]. + * @throws ArgumentException if lambda0 and + * lambda1 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); + } + + /** + * Approximate division by n. For an integer + * k, the value λ = s k / n is + * computed to c bits of accuracy. + * @param k The parameter k. + * @param s The curve parameter s0 or + * s1. + * @param vm The Lucas Sequence element Vm. + * @param a The parameter a of the elliptic curve. + * @param m The bit length of the finite field + * Fm. + * @param c The number of bits of accuracy, i.e. the scale of the returned + * SimpleBigDecimal. + * @return The value λ = s k / n computed to + * c bits of accuracy. + */ + public static SimpleBigDecimal ApproximateDivisionByN(BigInteger k, + BigInteger s, BigInteger vm, sbyte a, int m, int c) + { + int _k = (m + 5)/2 + c; + BigInteger ns = k.ShiftRight(m - _k - 2 + a); + + BigInteger gs = s.Multiply(ns); + + BigInteger hs = gs.ShiftRight(m); + + BigInteger js = vm.Multiply(hs); + + BigInteger gsPlusJs = gs.Add(js); + BigInteger ls = gsPlusJs.ShiftRight(_k-c); + if (gsPlusJs.TestBit(_k-c-1)) + { + // round up + ls = ls.Add(BigInteger.One); + } + + return new SimpleBigDecimal(ls, c); + } + + /** + * Computes the τ-adic NAF (non-adjacent form) of an + * element λ of Z[τ]. + * @param mu The parameter μ of the elliptic curve. + * @param lambda The element λ of + * Z[τ]. + * @return The τ-adic NAF of λ. + */ + 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; + } + + /** + * Applies the operation τ() to an + * F2mPoint. + * @param p The F2mPoint to which τ() is applied. + * @return τ(p) + */ + public static F2mPoint Tau(F2mPoint p) + { + return p.Tau(); + } + + /** + * Returns the parameter μ of the elliptic curve. + * @param curve The elliptic curve from which to obtain μ. + * The curve must be a Koblitz curve, i.e. a Equals + * 0 or 1 and b Equals + * 1. + * @return μ of the elliptic curve. + * @throws ArgumentException if the given ECCurve is not a Koblitz + * curve. + */ + public static sbyte GetMu(F2mCurve curve) + { + BigInteger a = curve.A.ToBigInteger(); + + sbyte mu; + if (a.SignValue == 0) + { + mu = -1; + } + else if (a.Equals(BigInteger.One)) + { + mu = 1; + } + else + { + throw new ArgumentException("No Koblitz curve (ABC), TNAF multiplication not possible"); + } + return mu; + } + + /** + * Calculates the Lucas Sequence elements Uk-1 and + * Uk or Vk-1 and + * Vk. + * @param mu The parameter μ of the elliptic curve. + * @param k The index of the second element of the Lucas Sequence to be + * returned. + * @param doV If set to true, computes Vk-1 and + * Vk, otherwise Uk-1 and + * Uk. + * @return An array with 2 elements, containing Uk-1 + * and Uk or Vk-1 + * and Vk. + */ + public static BigInteger[] GetLucas(sbyte mu, int k, bool doV) + { + if (!(mu == 1 || mu == -1)) + throw new ArgumentException("mu must be 1 or -1"); + + BigInteger u0; + BigInteger u1; + BigInteger u2; + + if (doV) + { + u0 = BigInteger.Two; + u1 = BigInteger.ValueOf(mu); + } + else + { + u0 = BigInteger.Zero; + u1 = BigInteger.One; + } + + for (int i = 1; i < k; i++) + { + // u2 = mu*u1 - 2*u0; + BigInteger s = null; + if (mu == 1) + { + s = u1; + } + else + { + // mu == -1 + s = u1.Negate(); + } + + u2 = s.Subtract(u0.ShiftLeft(1)); + u0 = u1; + u1 = u2; + // System.out.println(i + ": " + u2); + // System.out.println(); + } + + BigInteger[] retVal = {u0, u1}; + return retVal; + } + + /** + * Computes the auxiliary value tw. If the width is + * 4, then for mu = 1, tw = 6 and for + * mu = -1, tw = 10 + * @param mu The parameter μ of the elliptic curve. + * @param w The window width of the WTNAF. + * @return the auxiliary value tw + */ + public static BigInteger GetTw(sbyte mu, int w) + { + if (w == 4) + { + if (mu == 1) + { + return BigInteger.ValueOf(6); + } + else + { + // mu == -1 + return BigInteger.ValueOf(10); + } + } + else + { + // For w <> 4, the values must be computed + BigInteger[] us = GetLucas(mu, w, false); + BigInteger twoToW = BigInteger.Zero.SetBit(w); + BigInteger u1invert = us[1].ModInverse(twoToW); + BigInteger tw; + tw = BigInteger.Two.Multiply(us[0]).Multiply(u1invert).Mod(twoToW); + //System.out.println("mu = " + mu); + //System.out.println("tw = " + tw); + return tw; + } + } + + /** + * Computes the auxiliary values s0 and + * s1 used for partial modular reduction. + * @param curve The elliptic curve for which to compute + * s0 and s1. + * @throws ArgumentException if curve is not a + * Koblitz curve (Anomalous Binary Curve, ABC). + */ + public static BigInteger[] GetSi(F2mCurve curve) + { + if (!curve.IsKoblitz) + throw new ArgumentException("si is defined for Koblitz curves only"); + + int m = curve.M; + int a = curve.A.ToBigInteger().IntValue; + sbyte mu = curve.GetMu(); + int h = curve.H.IntValue; + int index = m + 3 - a; + BigInteger[] ui = GetLucas(mu, index, false); + + BigInteger dividend0; + BigInteger dividend1; + if (mu == 1) + { + dividend0 = BigInteger.One.Subtract(ui[1]); + dividend1 = BigInteger.One.Subtract(ui[0]); + } + else if (mu == -1) + { + dividend0 = BigInteger.One.Add(ui[1]); + dividend1 = BigInteger.One.Add(ui[0]); + } + else + { + throw new ArgumentException("mu must be 1 or -1"); + } + + BigInteger[] si = new BigInteger[2]; + + if (h == 2) + { + si[0] = dividend0.ShiftRight(1); + si[1] = dividend1.ShiftRight(1).Negate(); + } + else if (h == 4) + { + si[0] = dividend0.ShiftRight(2); + si[1] = dividend1.ShiftRight(2).Negate(); + } + else + { + throw new ArgumentException("h (Cofactor) must be 2 or 4"); + } + + return si; + } + + /** + * Partial modular reduction modulo + * m - 1)/(τ - 1). + * @param k The integer to be reduced. + * @param m The bitlength of the underlying finite field. + * @param a The parameter a of the elliptic curve. + * @param s The auxiliary values s0 and + * s1. + * @param mu The parameter μ of the elliptic curve. + * @param c The precision (number of bits of accuracy) of the partial + * modular reduction. + * @return ρ := k partmod (τm - 1)/(τ - 1) + */ + public static ZTauElement PartModReduction(BigInteger k, int m, sbyte a, + BigInteger[] s, sbyte mu, sbyte c) + { + // d0 = s[0] + mu*s[1]; mu is either 1 or -1 + BigInteger d0; + if (mu == 1) + { + d0 = s[0].Add(s[1]); + } + else + { + d0 = s[0].Subtract(s[1]); + } + + BigInteger[] v = GetLucas(mu, m, true); + BigInteger vm = v[1]; + + SimpleBigDecimal lambda0 = ApproximateDivisionByN( + k, s[0], vm, a, m, c); + + SimpleBigDecimal lambda1 = ApproximateDivisionByN( + k, s[1], vm, a, m, c); + + ZTauElement q = Round(lambda0, lambda1, mu); + + // r0 = n - d0*q0 - 2*s1*q1 + BigInteger r0 = k.Subtract(d0.Multiply(q.u)).Subtract( + BigInteger.ValueOf(2).Multiply(s[1]).Multiply(q.v)); + + // r1 = s1*q0 - s0*q1 + BigInteger r1 = s[1].Multiply(q.u).Subtract(s[0].Multiply(q.v)); + + return new ZTauElement(r0, r1); + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint} + * by a BigInteger using the reduced τ-adic + * NAF (RTNAF) method. + * @param p The F2mPoint to Multiply. + * @param k The BigInteger by which to Multiply p. + * @return k * p + */ + public static F2mPoint MultiplyRTnaf(F2mPoint p, BigInteger k) + { + F2mCurve curve = (F2mCurve) p.Curve; + int m = curve.M; + sbyte a = (sbyte) curve.A.ToBigInteger().IntValue; + sbyte mu = curve.GetMu(); + BigInteger[] s = curve.GetSi(); + ZTauElement rho = PartModReduction(k, m, a, s, mu, (sbyte)10); + + return MultiplyTnaf(p, rho); + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint} + * by an element λ of Z[τ] + * using the τ-adic NAF (TNAF) method. + * @param p The F2mPoint to Multiply. + * @param lambda The element λ of + * Z[τ]. + * @return λ * p + */ + public static F2mPoint MultiplyTnaf(F2mPoint p, ZTauElement lambda) + { + F2mCurve curve = (F2mCurve)p.Curve; + sbyte mu = curve.GetMu(); + sbyte[] u = TauAdicNaf(mu, lambda); + + F2mPoint q = MultiplyFromTnaf(p, u); + + return q; + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint} + * by an element λ of Z[τ] + * using the τ-adic NAF (TNAF) method, given the TNAF + * of λ. + * @param p The F2mPoint to Multiply. + * @param u The the TNAF of λ.. + * @return λ * p + */ + public static F2mPoint MultiplyFromTnaf(F2mPoint p, sbyte[] u) + { + F2mCurve curve = (F2mCurve)p.Curve; + F2mPoint q = (F2mPoint) curve.Infinity; + for (int i = u.Length - 1; i >= 0; i--) + { + q = Tau(q); + if (u[i] == 1) + { + q = (F2mPoint)q.AddSimple(p); + } + else if (u[i] == -1) + { + q = (F2mPoint)q.SubtractSimple(p); + } + } + return q; + } + + /** + * Computes the [τ]-adic window NAF of an element + * λ of Z[τ]. + * @param mu The parameter μ of the elliptic curve. + * @param lambda The element λ of + * Z[τ] of which to compute the + * [τ]-adic NAF. + * @param width The window width of the resulting WNAF. + * @param pow2w 2width. + * @param tw The auxiliary value tw. + * @param alpha The αu's for the window width. + * @return The [τ]-adic window NAF of + * λ. + */ + 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; + } + + /** + * Does the precomputation for WTNAF multiplication. + * @param p The ECPoint for which to do the precomputation. + * @param a The parameter a of the elliptic curve. + * @return The precomputation array for p. + */ + public static F2mPoint[] GetPreComp(F2mPoint p, sbyte a) + { + F2mPoint[] pu; + pu = new F2mPoint[16]; + pu[1] = p; + sbyte[][] alphaTnaf; + if (a == 0) + { + alphaTnaf = Tnaf.Alpha0Tnaf; + } + else + { + // a == 1 + alphaTnaf = Tnaf.Alpha1Tnaf; + } + + int precompLen = alphaTnaf.Length; + for (int i = 3; i < precompLen; i = i + 2) + { + pu[i] = Tnaf.MultiplyFromTnaf(p, alphaTnaf[i]); + } + + return pu; + } + } } diff --git a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs index 54ca78090..bb6f37831 100644 --- a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs +++ b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs @@ -26,162 +26,162 @@ namespace Org.BouncyCastle.X509 { } - /// + /// /// Create a Subject Public Key Info object for a given public key. /// /// One of ElGammalPublicKeyParameters, DSAPublicKeyParameter, DHPublicKeyParameters, RsaKeyParameters or ECPublicKeyParameters /// A subject public key info object. /// Throw exception if object provided is not one of the above. public static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo( - AsymmetricKeyParameter key) + AsymmetricKeyParameter key) { - if (key == null) - throw new ArgumentNullException("key"); + if (key == null) + throw new ArgumentNullException("key"); if (key.IsPrivate) throw new ArgumentException("Private key passed - public key expected.", "key"); - if (key is ElGamalPublicKeyParameters) + if (key is ElGamalPublicKeyParameters) { - ElGamalPublicKeyParameters _key = (ElGamalPublicKeyParameters)key; - ElGamalParameters kp = _key.Parameters; + ElGamalPublicKeyParameters _key = (ElGamalPublicKeyParameters)key; + ElGamalParameters kp = _key.Parameters; - SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( - new AlgorithmIdentifier( - OiwObjectIdentifiers.ElGamalAlgorithm, - new ElGamalParameter(kp.P, kp.G).ToAsn1Object()), - new DerInteger(_key.Y)); + SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( + new AlgorithmIdentifier( + OiwObjectIdentifiers.ElGamalAlgorithm, + new ElGamalParameter(kp.P, kp.G).ToAsn1Object()), + new DerInteger(_key.Y)); - return info; + return info; } - if (key is DsaPublicKeyParameters) + if (key is DsaPublicKeyParameters) { DsaPublicKeyParameters _key = (DsaPublicKeyParameters) key; - DsaParameters kp = _key.Parameters; - Asn1Encodable ae = kp == null - ? null - : new DsaParameter(kp.P, kp.Q, kp.G).ToAsn1Object(); + DsaParameters kp = _key.Parameters; + Asn1Encodable ae = kp == null + ? null + : new DsaParameter(kp.P, kp.Q, kp.G).ToAsn1Object(); - return new SubjectPublicKeyInfo( + return new SubjectPublicKeyInfo( new AlgorithmIdentifier(X9ObjectIdentifiers.IdDsa, ae), - new DerInteger(_key.Y)); + new DerInteger(_key.Y)); } - if (key is DHPublicKeyParameters) + if (key is DHPublicKeyParameters) { DHPublicKeyParameters _key = (DHPublicKeyParameters) key; - DHParameters kp = _key.Parameters; + DHParameters kp = _key.Parameters; - SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( + SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( new AlgorithmIdentifier( - _key.AlgorithmOid, - new DHParameter(kp.P, kp.G, kp.L).ToAsn1Object()), - new DerInteger(_key.Y)); + _key.AlgorithmOid, + new DHParameter(kp.P, kp.G, kp.L).ToAsn1Object()), + new DerInteger(_key.Y)); - return info; + return info; } // End of DH if (key is RsaKeyParameters) { RsaKeyParameters _key = (RsaKeyParameters) key; - SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( - new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance), - new RsaPublicKeyStructure(_key.Modulus, _key.Exponent).ToAsn1Object()); + SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( + new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance), + new RsaPublicKeyStructure(_key.Modulus, _key.Exponent).ToAsn1Object()); - return info; + return info; } // End of RSA. - if (key is ECPublicKeyParameters) + if (key is ECPublicKeyParameters) { ECPublicKeyParameters _key = (ECPublicKeyParameters) key; - if (_key.AlgorithmName == "ECGOST3410") - { - if (_key.PublicKeyParamSet == null) - throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); - - ECPoint q = _key.Q; - BigInteger bX = q.X.ToBigInteger(); - BigInteger bY = q.Y.ToBigInteger(); - - byte[] encKey = new byte[64]; - ExtractBytes(encKey, 0, bX); - ExtractBytes(encKey, 32, bY); - - Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( - _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); - - AlgorithmIdentifier algID = new AlgorithmIdentifier( - CryptoProObjectIdentifiers.GostR3410x2001, - gostParams.ToAsn1Object()); - - return new SubjectPublicKeyInfo(algID, new DerOctetString(encKey)); - } - else - { - X962Parameters x962; - if (_key.PublicKeyParamSet == null) - { - ECDomainParameters kp = _key.Parameters; - X9ECParameters ecP = new X9ECParameters(kp.Curve, kp.G, kp.N, kp.H, kp.GetSeed()); - - x962 = new X962Parameters(ecP); - } - else - { - x962 = new X962Parameters(_key.PublicKeyParamSet); - } - - Asn1OctetString p = (Asn1OctetString)(new X9ECPoint(_key.Q).ToAsn1Object()); - - AlgorithmIdentifier algID = new AlgorithmIdentifier( - X9ObjectIdentifiers.IdECPublicKey, x962.ToAsn1Object()); - - return new SubjectPublicKeyInfo(algID, p.GetOctets()); - } - } // End of EC - - if (key is Gost3410PublicKeyParameters) - { - Gost3410PublicKeyParameters _key = (Gost3410PublicKeyParameters) key; - - if (_key.PublicKeyParamSet == null) - throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); - - byte[] keyEnc = _key.Y.ToByteArrayUnsigned(); - byte[] keyBytes = new byte[keyEnc.Length]; - - for (int i = 0; i != keyBytes.Length; i++) - { - keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // must be little endian - } - - Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters( - _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); - - AlgorithmIdentifier algID = new AlgorithmIdentifier( - CryptoProObjectIdentifiers.GostR3410x94, - algParams.ToAsn1Object()); - - return new SubjectPublicKeyInfo(algID, new DerOctetString(keyBytes)); - } - - throw new ArgumentException("Class provided no convertible: " + key.GetType().FullName); - } - - private static void ExtractBytes( - byte[] encKey, - int offset, - BigInteger bI) - { - byte[] val = bI.ToByteArray(); - int n = (bI.BitLength + 7) / 8; - - for (int i = 0; i < n; ++i) - { - encKey[offset + i] = val[val.Length - 1 - i]; - } - } - } + if (_key.AlgorithmName == "ECGOST3410") + { + if (_key.PublicKeyParamSet == null) + throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); + + ECPoint q = _key.Q.Normalize(); + BigInteger bX = q.AffineXCoord.ToBigInteger(); + BigInteger bY = q.AffineYCoord.ToBigInteger(); + + byte[] encKey = new byte[64]; + ExtractBytes(encKey, 0, bX); + ExtractBytes(encKey, 32, bY); + + Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( + _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); + + AlgorithmIdentifier algID = new AlgorithmIdentifier( + CryptoProObjectIdentifiers.GostR3410x2001, + gostParams.ToAsn1Object()); + + return new SubjectPublicKeyInfo(algID, new DerOctetString(encKey)); + } + else + { + X962Parameters x962; + if (_key.PublicKeyParamSet == null) + { + ECDomainParameters kp = _key.Parameters; + X9ECParameters ecP = new X9ECParameters(kp.Curve, kp.G, kp.N, kp.H, kp.GetSeed()); + + x962 = new X962Parameters(ecP); + } + else + { + x962 = new X962Parameters(_key.PublicKeyParamSet); + } + + Asn1OctetString p = (Asn1OctetString)(new X9ECPoint(_key.Q).ToAsn1Object()); + + AlgorithmIdentifier algID = new AlgorithmIdentifier( + X9ObjectIdentifiers.IdECPublicKey, x962.ToAsn1Object()); + + return new SubjectPublicKeyInfo(algID, p.GetOctets()); + } + } // End of EC + + if (key is Gost3410PublicKeyParameters) + { + Gost3410PublicKeyParameters _key = (Gost3410PublicKeyParameters) key; + + if (_key.PublicKeyParamSet == null) + throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); + + byte[] keyEnc = _key.Y.ToByteArrayUnsigned(); + byte[] keyBytes = new byte[keyEnc.Length]; + + for (int i = 0; i != keyBytes.Length; i++) + { + keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // must be little endian + } + + Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters( + _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); + + AlgorithmIdentifier algID = new AlgorithmIdentifier( + CryptoProObjectIdentifiers.GostR3410x94, + algParams.ToAsn1Object()); + + return new SubjectPublicKeyInfo(algID, new DerOctetString(keyBytes)); + } + + throw new ArgumentException("Class provided no convertible: " + key.GetType().FullName); + } + + private static void ExtractBytes( + byte[] encKey, + int offset, + BigInteger bI) + { + byte[] val = bI.ToByteArray(); + int n = (bI.BitLength + 7) / 8; + + for (int i = 0; i < n; ++i) + { + encKey[offset + i] = val[val.Length - 1 - i]; + } + } + } } diff --git a/crypto/test/src/crypto/test/ECTest.cs b/crypto/test/src/crypto/test/ECTest.cs index 70702e730..0360c62dc 100644 --- a/crypto/test/src/crypto/test/ECTest.cs +++ b/crypto/test/src/crypto/test/ECTest.cs @@ -19,901 +19,901 @@ using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.Crypto.Tests { - /** - * ECDSA tests are taken from X9.62. - */ - [TestFixture] - public class ECTest - : SimpleTest - { - /** - * X9.62 - 1998,
- * J.3.1, Page 152, ECDSA over the field Fp
- * an example with 192 bit prime - */ - [Test] - public void TestECDsa192bitPrime() - { - BigInteger r = new BigInteger("3342403536405981729393488334694600415596881826869351677613"); - BigInteger s = new BigInteger("5735822328888155254683894997897571951568553642892029982342"); - - byte[] kData = BigIntegers.AsUnsignedByteArray(new BigInteger("6140507067065001063065065565667405560006161556565665656654")); - - SecureRandom k = FixedSecureRandom.From(kData); - - FpCurve curve = new FpCurve( - new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q - new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a - new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b - - ECDomainParameters parameters = new ECDomainParameters( - curve, - curve.DecodePoint(Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), // G - new BigInteger("6277101735386680763835789423176059013767194773182842284081")); // n - - ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( - "ECDSA", - new BigInteger("651056770906015076056810763456358567190100156695615665659"), // d - parameters); - - ParametersWithRandom param = new ParametersWithRandom(priKey, k); - - ECDsaSigner ecdsa = new ECDsaSigner(); - - ecdsa.Init(true, param); - - byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").ToByteArray(); - BigInteger[] sig = ecdsa.GenerateSignature(message); - - if (!r.Equals(sig[0])) - { - Fail("r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } - - if (!s.Equals(sig[1])) - { - Fail("s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - - // Verify the signature - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( - "ECDSA", - curve.DecodePoint(Hex.Decode("0262b12d60690cdcf330babab6e69763b471f994dd702d16a5")), // Q - parameters); - - ecdsa.Init(false, pubKey); - if (!ecdsa.VerifySignature(message, sig[0], sig[1])) - { - Fail("verification fails"); - } - } - - [Test] - public void TestDecode() - { - FpCurve curve = new FpCurve( - new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q - new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a - new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b - - ECPoint p = curve.DecodePoint(Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")); - - if (!p.X.ToBigInteger().Equals(new BigInteger("188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", 16))) - { - Fail("x uncompressed incorrectly"); - } - - if (!p.Y.ToBigInteger().Equals(new BigInteger("7192b95ffc8da78631011ed6b24cdd573f977a11e794811", 16))) - { - Fail("y uncompressed incorrectly"); - } - - byte[] encoding = p.GetEncoded(); - - if (!AreEqual(encoding, Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012"))) - { - Fail("point compressed incorrectly"); - } - } - - /** - * X9.62 - 1998,
- * J.3.2, Page 155, ECDSA over the field Fp
- * 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); - - FpCurve curve = new FpCurve( - new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q - new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a - new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b - - ECDomainParameters parameters = new ECDomainParameters( - curve, - curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G - new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n - - ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( - "ECDSA", - new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d - parameters); - - ECDsaSigner ecdsa = new ECDsaSigner(); - ParametersWithRandom param = new ParametersWithRandom(priKey, k); - - ecdsa.Init(true, param); - - byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").ToByteArray(); - BigInteger[] sig = ecdsa.GenerateSignature(message); - - if (!r.Equals(sig[0])) - { - Fail("r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } - - if (!s.Equals(sig[1])) - { - Fail("s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - - // Verify the signature - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( - "ECDSA", - curve.DecodePoint(Hex.Decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q - parameters); - - ecdsa.Init(false, pubKey); - if (!ecdsa.VerifySignature(message, sig[0], sig[1])) - { - Fail("signature fails"); - } - } - - - /** - * X9.62 - 1998,
- * J.2.1, Page 100, ECDSA over the field F2m
- * an example with 191 bit binary field - */ - [Test] - public void TestECDsa191bitBinary() - { - BigInteger r = new BigInteger("87194383164871543355722284926904419997237591535066528048"); - BigInteger s = new BigInteger("308992691965804947361541664549085895292153777025772063598"); - - byte[] kData = BigIntegers.AsUnsignedByteArray(new BigInteger("1542725565216523985789236956265265265235675811949404040041")); - - SecureRandom k = FixedSecureRandom.From(kData); - - F2mCurve curve = new F2mCurve( - 191, // m - 9, //k - new BigInteger("2866537B676752636A68F56554E12640276B649EF7526267", 16), // a - new BigInteger("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", 16)); // b - - ECDomainParameters parameters = new ECDomainParameters( - curve, - curve.DecodePoint(Hex.Decode("0436B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB")), // G - new BigInteger("1569275433846670190958947355803350458831205595451630533029"), // n - BigInteger.Two); // h - - ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( - "ECDSA", - new BigInteger("1275552191113212300012030439187146164646146646466749494799"), // d - parameters); - - ECDsaSigner ecdsa = new ECDsaSigner(); - ParametersWithRandom param = new ParametersWithRandom(priKey, k); - - ecdsa.Init(true, param); - - byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").ToByteArray(); - BigInteger[] sig = ecdsa.GenerateSignature(message); - - if (!r.Equals(sig[0])) - { - Fail("r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } - - if (!s.Equals(sig[1])) - { - Fail("s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - - // Verify the signature - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( - "ECDSA", - curve.DecodePoint(Hex.Decode("045DE37E756BD55D72E3768CB396FFEB962614DEA4CE28A2E755C0E0E02F5FB132CAF416EF85B229BBB8E1352003125BA1")), // Q - parameters); - - ecdsa.Init(false, pubKey); - if (!ecdsa.VerifySignature(message, sig[0], sig[1])) - { - Fail("signature fails"); - } - } - - /** - * X9.62 - 1998,
- * J.2.1, Page 100, ECDSA over the field F2m
- * an example with 191 bit binary field - */ - [Test] - public void TestECDsa239bitBinary() - { - BigInteger r = new BigInteger("21596333210419611985018340039034612628818151486841789642455876922391552"); - BigInteger s = new BigInteger("197030374000731686738334997654997227052849804072198819102649413465737174"); - - byte[] kData = BigIntegers.AsUnsignedByteArray(new BigInteger("171278725565216523967285789236956265265265235675811949404040041670216363")); - - SecureRandom k = FixedSecureRandom.From(kData); - - F2mCurve curve = new F2mCurve( - 239, // m - 36, //k - new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a - new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b - - ECDomainParameters parameters = new ECDomainParameters( - curve, - curve.DecodePoint(Hex.Decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G - new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n - BigInteger.ValueOf(4)); // h - - ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( - "ECDSA", - new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d - parameters); - - ECDsaSigner ecdsa = new ECDsaSigner(); - ParametersWithRandom param = new ParametersWithRandom(priKey, k); - - ecdsa.Init(true, param); - - byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").ToByteArray(); - BigInteger[] sig = ecdsa.GenerateSignature(message); - - if (!r.Equals(sig[0])) - { - Fail("r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } - - if (!s.Equals(sig[1])) - { - Fail("s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - - // Verify the signature - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( - "ECDSA", - curve.DecodePoint(Hex.Decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q - parameters); - - ecdsa.Init(false, pubKey); - if (!ecdsa.VerifySignature(message, sig[0], sig[1])) - { - Fail("signature fails"); - } - } - - // L 4.1 X9.62 2005 - [Test] - public void TestECDsaP224Sha224() - { - X9ECParameters p = NistNamedCurves.GetByName("P-224"); - ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); - ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( - new BigInteger("6081831502424510080126737029209236539191290354021104541805484120491"), // d - parameters); - SecureRandom k = FixedSecureRandom.From(BigIntegers.AsUnsignedByteArray(new BigInteger("15456715103636396133226117016818339719732885723579037388121116732601"))); + /** + * ECDSA tests are taken from X9.62. + */ + [TestFixture] + public class ECTest + : SimpleTest + { + /** + * X9.62 - 1998,
+ * J.3.1, Page 152, ECDSA over the field Fp
+ * an example with 192 bit prime + */ + [Test] + public void TestECDsa192bitPrime() + { + BigInteger r = new BigInteger("3342403536405981729393488334694600415596881826869351677613"); + BigInteger s = new BigInteger("5735822328888155254683894997897571951568553642892029982342"); + + byte[] kData = BigIntegers.AsUnsignedByteArray(new BigInteger("6140507067065001063065065565667405560006161556565665656654")); + + SecureRandom k = FixedSecureRandom.From(kData); + + FpCurve curve = new FpCurve( + new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q + new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a + new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b + + ECDomainParameters parameters = new ECDomainParameters( + curve, + curve.DecodePoint(Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), // G + new BigInteger("6277101735386680763835789423176059013767194773182842284081")); // n + + ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( + "ECDSA", + new BigInteger("651056770906015076056810763456358567190100156695615665659"), // d + parameters); + + ParametersWithRandom param = new ParametersWithRandom(priKey, k); + + ECDsaSigner ecdsa = new ECDsaSigner(); + + ecdsa.Init(true, param); + + byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").ToByteArray(); + BigInteger[] sig = ecdsa.GenerateSignature(message); + + if (!r.Equals(sig[0])) + { + Fail("r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } + + if (!s.Equals(sig[1])) + { + Fail("s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + + // Verify the signature + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + "ECDSA", + curve.DecodePoint(Hex.Decode("0262b12d60690cdcf330babab6e69763b471f994dd702d16a5")), // Q + parameters); + + ecdsa.Init(false, pubKey); + if (!ecdsa.VerifySignature(message, sig[0], sig[1])) + { + Fail("verification fails"); + } + } + + [Test] + public void TestDecode() + { + FpCurve curve = new FpCurve( + new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q + new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a + new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b + + ECPoint p = curve.DecodePoint(Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")).Normalize(); + + if (!p.AffineXCoord.ToBigInteger().Equals(new BigInteger("188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", 16))) + { + Fail("x uncompressed incorrectly"); + } + + if (!p.AffineYCoord.ToBigInteger().Equals(new BigInteger("7192b95ffc8da78631011ed6b24cdd573f977a11e794811", 16))) + { + Fail("y uncompressed incorrectly"); + } + + byte[] encoding = p.GetEncoded(); + + if (!AreEqual(encoding, Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012"))) + { + Fail("point compressed incorrectly"); + } + } + + /** + * X9.62 - 1998,
+ * J.3.2, Page 155, ECDSA over the field Fp
+ * 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); + + FpCurve curve = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b + + ECDomainParameters parameters = new ECDomainParameters( + curve, + curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G + new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n + + ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( + "ECDSA", + new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d + parameters); + + ECDsaSigner ecdsa = new ECDsaSigner(); + ParametersWithRandom param = new ParametersWithRandom(priKey, k); + + ecdsa.Init(true, param); + + byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").ToByteArray(); + BigInteger[] sig = ecdsa.GenerateSignature(message); + + if (!r.Equals(sig[0])) + { + Fail("r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } + + if (!s.Equals(sig[1])) + { + Fail("s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + + // Verify the signature + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + "ECDSA", + curve.DecodePoint(Hex.Decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q + parameters); + + ecdsa.Init(false, pubKey); + if (!ecdsa.VerifySignature(message, sig[0], sig[1])) + { + Fail("signature fails"); + } + } + + + /** + * X9.62 - 1998,
+ * J.2.1, Page 100, ECDSA over the field F2m
+ * an example with 191 bit binary field + */ + [Test] + public void TestECDsa191bitBinary() + { + BigInteger r = new BigInteger("87194383164871543355722284926904419997237591535066528048"); + BigInteger s = new BigInteger("308992691965804947361541664549085895292153777025772063598"); + + byte[] kData = BigIntegers.AsUnsignedByteArray(new BigInteger("1542725565216523985789236956265265265235675811949404040041")); + + SecureRandom k = FixedSecureRandom.From(kData); + + F2mCurve curve = new F2mCurve( + 191, // m + 9, //k + new BigInteger("2866537B676752636A68F56554E12640276B649EF7526267", 16), // a + new BigInteger("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", 16)); // b + + ECDomainParameters parameters = new ECDomainParameters( + curve, + curve.DecodePoint(Hex.Decode("0436B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB")), // G + new BigInteger("1569275433846670190958947355803350458831205595451630533029"), // n + BigInteger.Two); // h + + ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( + "ECDSA", + new BigInteger("1275552191113212300012030439187146164646146646466749494799"), // d + parameters); + + ECDsaSigner ecdsa = new ECDsaSigner(); + ParametersWithRandom param = new ParametersWithRandom(priKey, k); + + ecdsa.Init(true, param); + + byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").ToByteArray(); + BigInteger[] sig = ecdsa.GenerateSignature(message); + + if (!r.Equals(sig[0])) + { + Fail("r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } + + if (!s.Equals(sig[1])) + { + Fail("s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + + // Verify the signature + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + "ECDSA", + curve.DecodePoint(Hex.Decode("045DE37E756BD55D72E3768CB396FFEB962614DEA4CE28A2E755C0E0E02F5FB132CAF416EF85B229BBB8E1352003125BA1")), // Q + parameters); + + ecdsa.Init(false, pubKey); + if (!ecdsa.VerifySignature(message, sig[0], sig[1])) + { + Fail("signature fails"); + } + } + + /** + * X9.62 - 1998,
+ * J.2.1, Page 100, ECDSA over the field F2m
+ * an example with 191 bit binary field + */ + [Test] + public void TestECDsa239bitBinary() + { + BigInteger r = new BigInteger("21596333210419611985018340039034612628818151486841789642455876922391552"); + BigInteger s = new BigInteger("197030374000731686738334997654997227052849804072198819102649413465737174"); + + byte[] kData = BigIntegers.AsUnsignedByteArray(new BigInteger("171278725565216523967285789236956265265265235675811949404040041670216363")); + + SecureRandom k = FixedSecureRandom.From(kData); + + F2mCurve curve = new F2mCurve( + 239, // m + 36, //k + new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a + new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b + + ECDomainParameters parameters = new ECDomainParameters( + curve, + curve.DecodePoint(Hex.Decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G + new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n + BigInteger.ValueOf(4)); // h + + ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( + "ECDSA", + new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d + parameters); + + ECDsaSigner ecdsa = new ECDsaSigner(); + ParametersWithRandom param = new ParametersWithRandom(priKey, k); + + ecdsa.Init(true, param); + + byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").ToByteArray(); + BigInteger[] sig = ecdsa.GenerateSignature(message); + + if (!r.Equals(sig[0])) + { + Fail("r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } + + if (!s.Equals(sig[1])) + { + Fail("s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + + // Verify the signature + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + "ECDSA", + curve.DecodePoint(Hex.Decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q + parameters); + + ecdsa.Init(false, pubKey); + if (!ecdsa.VerifySignature(message, sig[0], sig[1])) + { + Fail("signature fails"); + } + } + + // L 4.1 X9.62 2005 + [Test] + public void TestECDsaP224Sha224() + { + X9ECParameters p = NistNamedCurves.GetByName("P-224"); + ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); + ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( + new BigInteger("6081831502424510080126737029209236539191290354021104541805484120491"), // d + parameters); + SecureRandom k = FixedSecureRandom.From(BigIntegers.AsUnsignedByteArray(new BigInteger("15456715103636396133226117016818339719732885723579037388121116732601"))); - byte[] M = Hex.Decode("8797A3C693CC292441039A4E6BAB7387F3B4F2A63D00ED384B378C79"); + byte[] M = Hex.Decode("8797A3C693CC292441039A4E6BAB7387F3B4F2A63D00ED384B378C79"); - ECDsaSigner dsa = new ECDsaSigner(); + ECDsaSigner dsa = new ECDsaSigner(); - dsa.Init(true, new ParametersWithRandom(priKey, k)); + dsa.Init(true, new ParametersWithRandom(priKey, k)); - BigInteger[] sig = dsa.GenerateSignature(M); + BigInteger[] sig = dsa.GenerateSignature(M); - BigInteger r = new BigInteger("26477406756127720855365980332052585411804331993436302005017227573742"); - BigInteger s = new BigInteger("17694958233103667059888193972742186995283044672015112738919822429978"); + BigInteger r = new BigInteger("26477406756127720855365980332052585411804331993436302005017227573742"); + BigInteger s = new BigInteger("17694958233103667059888193972742186995283044672015112738919822429978"); - if (!r.Equals(sig[0])) - { - Fail("r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } - - if (!s.Equals(sig[1])) - { - Fail("s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - - // Verify the signature - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( - parameters.Curve.DecodePoint(Hex.Decode("03FD44EC11F9D43D9D23B1E1D1C9ED6519B40ECF0C79F48CF476CC43F1")), // Q - parameters); - - dsa.Init(false, pubKey); - if (!dsa.VerifySignature(M, sig[0], sig[1])) - { - Fail("signature fails"); - } - } - - [Test] - public void TestECDsaSecP224k1Sha256() - { - X9ECParameters p = SecNamedCurves.GetByName("secp224k1"); - ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); - ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( - new BigInteger("BE6F6E91FE96840A6518B56F3FE21689903A64FA729057AB872A9F51", 16), // d - parameters); - SecureRandom k = FixedSecureRandom.From(Hex.Decode("00c39beac93db21c3266084429eb9b846b787c094f23a4de66447efbb3")); + if (!r.Equals(sig[0])) + { + Fail("r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } + + if (!s.Equals(sig[1])) + { + Fail("s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + + // Verify the signature + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + parameters.Curve.DecodePoint(Hex.Decode("03FD44EC11F9D43D9D23B1E1D1C9ED6519B40ECF0C79F48CF476CC43F1")), // Q + parameters); + + dsa.Init(false, pubKey); + if (!dsa.VerifySignature(M, sig[0], sig[1])) + { + Fail("signature fails"); + } + } + + [Test] + public void TestECDsaSecP224k1Sha256() + { + X9ECParameters p = SecNamedCurves.GetByName("secp224k1"); + ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); + ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( + new BigInteger("BE6F6E91FE96840A6518B56F3FE21689903A64FA729057AB872A9F51", 16), // d + parameters); + SecureRandom k = FixedSecureRandom.From(Hex.Decode("00c39beac93db21c3266084429eb9b846b787c094f23a4de66447efbb3")); - byte[] M = Hex.Decode("E5D5A7ADF73C5476FAEE93A2C76CE94DC0557DB04CDC189504779117920B896D"); - - ECDsaSigner dsa = new ECDsaSigner(); - - dsa.Init(true, new ParametersWithRandom(priKey, k)); - - BigInteger[] sig = dsa.GenerateSignature(M); - - BigInteger r = new BigInteger("8163E5941BED41DA441B33E653C632A55A110893133351E20CE7CB75", 16); - BigInteger s = new BigInteger("D12C3FC289DDD5F6890DCE26B65792C8C50E68BF551D617D47DF15A8", 16); - - if (!r.Equals(sig[0])) - { - Fail("r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } - - if (!s.Equals(sig[1])) - { - Fail("s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - - // Verify the signature - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( - parameters.Curve.DecodePoint(Hex.Decode("04C5C9B38D3603FCCD6994CBB9594E152B658721E483669BB42728520F484B537647EC816E58A8284D3B89DFEDB173AFDC214ECA95A836FA7C")), // Q - parameters); - - dsa.Init(false, pubKey); - if (!dsa.VerifySignature(M, sig[0], sig[1])) - { - Fail("signature fails"); - } - } - - // L4.2 X9.62 2005 - [Test] - public void TestECDsaP256Sha256() - { - X9ECParameters p = NistNamedCurves.GetByName("P-256"); - ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); - ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( - new BigInteger("20186677036482506117540275567393538695075300175221296989956723148347484984008"), // d - parameters); - SecureRandom k = FixedSecureRandom.From(BigIntegers.AsUnsignedByteArray(new BigInteger("72546832179840998877302529996971396893172522460793442785601695562409154906335"))); - - byte[] M = Hex.Decode("1BD4ED430B0F384B4E8D458EFF1A8A553286D7AC21CB2F6806172EF5F94A06AD"); - - ECDsaSigner dsa = new ECDsaSigner(); - - dsa.Init(true, new ParametersWithRandom(priKey, k)); - - BigInteger[] sig = dsa.GenerateSignature(M); - - BigInteger r = new BigInteger("97354732615802252173078420023658453040116611318111190383344590814578738210384"); - BigInteger s = new BigInteger("98506158880355671805367324764306888225238061309262649376965428126566081727535"); - - if (!r.Equals(sig[0])) - { - Fail("r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } - - if (!s.Equals(sig[1])) - { - Fail("s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - - // Verify the signature - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( - parameters.Curve.DecodePoint(Hex.Decode("03596375E6CE57E0F20294FC46BDFCFD19A39F8161B58695B3EC5B3D16427C274D")), // Q - parameters); - - dsa.Init(false, pubKey); - if (!dsa.VerifySignature(M, sig[0], sig[1])) - { - Fail("signature fails"); - } - } - - [Test] - public void TestECDsaP224OneByteOver() - { - X9ECParameters p = NistNamedCurves.GetByName("P-224"); - ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); - ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( - new BigInteger("6081831502424510080126737029209236539191290354021104541805484120491"), // d - parameters); - SecureRandom k = FixedSecureRandom.From(BigIntegers.AsUnsignedByteArray(new BigInteger("15456715103636396133226117016818339719732885723579037388121116732601"))); - - byte[] M = Hex.Decode("8797A3C693CC292441039A4E6BAB7387F3B4F2A63D00ED384B378C79FF"); - - ECDsaSigner dsa = new ECDsaSigner(); - - dsa.Init(true, new ParametersWithRandom(priKey, k)); - - BigInteger[] sig = dsa.GenerateSignature(M); - - BigInteger r = new BigInteger("26477406756127720855365980332052585411804331993436302005017227573742"); - BigInteger s = new BigInteger("17694958233103667059888193972742186995283044672015112738919822429978"); - - if (!r.Equals(sig[0])) - { - Fail("r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } - - if (!s.Equals(sig[1])) - { - Fail("s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - - // Verify the signature - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( - parameters.Curve.DecodePoint(Hex.Decode("03FD44EC11F9D43D9D23B1E1D1C9ED6519B40ECF0C79F48CF476CC43F1")), // Q - parameters); - - dsa.Init(false, pubKey); - if (!dsa.VerifySignature(M, sig[0], sig[1])) - { - Fail("signature fails"); - } - } - - // L4.3 X9.62 2005 - [Test] - public void TestECDsaP521Sha512() - { - X9ECParameters p = NistNamedCurves.GetByName("P-521"); - ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); - ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( - new BigInteger("617573726813476282316253885608633222275541026607493641741273231656161177732180358888434629562647985511298272498852936680947729040673640492310550142822667389"), // d - parameters); - SecureRandom k = FixedSecureRandom.From(BigIntegers.AsUnsignedByteArray(new BigInteger("6806532878215503520845109818432174847616958675335397773700324097584974639728725689481598054743894544060040710846048585856076812050552869216017728862957612913"))); - - byte[] M = Hex.Decode("6893B64BD3A9615C39C3E62DDD269C2BAAF1D85915526083183CE14C2E883B48B193607C1ED871852C9DF9C3147B574DC1526C55DE1FE263A676346A20028A66"); - - ECDsaSigner dsa = new ECDsaSigner(); - - dsa.Init(true, new ParametersWithRandom(priKey, k)); - - BigInteger[] sig = dsa.GenerateSignature(M); - - BigInteger r = new BigInteger("1368926195812127407956140744722257403535864168182534321188553460365652865686040549247096155740756318290773648848859639978618869784291633651685766829574104630"); - BigInteger s = new BigInteger("1624754720348883715608122151214003032398685415003935734485445999065609979304811509538477657407457976246218976767156629169821116579317401249024208611945405790"); - - if (!r.Equals(sig[0])) - { - Fail("r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } - - if (!s.Equals(sig[1])) - { - Fail("s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - - // Verify the signature - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( - parameters.Curve.DecodePoint(Hex.Decode("020145E221AB9F71C5FE740D8D2B94939A09E2816E2167A7D058125A06A80C014F553E8D6764B048FB6F2B687CEC72F39738F223D4CE6AFCBFF2E34774AA5D3C342CB3")), // Q - parameters); - - dsa.Init(false, pubKey); - if (!dsa.VerifySignature(M, sig[0], sig[1])) - { - Fail("signature fails"); - } - } - - /** - * General test for long digest. - */ - [Test] - public void TestECDsa239bitBinaryAndLargeDigest() - { - BigInteger r = new BigInteger("21596333210419611985018340039034612628818151486841789642455876922391552"); - BigInteger s = new BigInteger("144940322424411242416373536877786566515839911620497068645600824084578597"); - - byte[] kData = BigIntegers.AsUnsignedByteArray( - new BigInteger("171278725565216523967285789236956265265265235675811949404040041670216363")); - - SecureRandom k = FixedSecureRandom.From(kData); - - F2mCurve curve = new F2mCurve( - 239, // m - 36, //k - new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a - new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b - - ECDomainParameters parameters = new ECDomainParameters( - curve, - curve.DecodePoint( - Hex.Decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G - new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n - BigInteger.ValueOf(4)); // h - - ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( - "ECDSA", - new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d - parameters); - - ECDsaSigner ecdsa = new ECDsaSigner(); - ParametersWithRandom param = new ParametersWithRandom(priKey, k); - - ecdsa.Init(true, param); - - byte[] message = new BigInteger("968236873715988614170569073515315707566766479517968236873715988614170569073515315707566766479517968236873715988614170569073515315707566766479517").ToByteArray(); - BigInteger[] sig = ecdsa.GenerateSignature(message); - - if (!r.Equals(sig[0])) - { - Fail("r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } - - if (!s.Equals(sig[1])) - { - Fail("s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - - // Verify the signature - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( - "ECDSA", - curve.DecodePoint( - Hex.Decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q - parameters); - - ecdsa.Init(false, pubKey); - if (!ecdsa.VerifySignature(message, sig[0], sig[1])) - { - Fail("signature fails"); - } - } - - /** - * key generation test - */ - [Test] - public void TestECDsaKeyGenTest() - { - SecureRandom random = new SecureRandom(); - - FpCurve curve = new FpCurve( - new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q - new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a - new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b - - ECDomainParameters parameters = new ECDomainParameters( - curve, - curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G - new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n - - - ECKeyPairGenerator pGen = new ECKeyPairGenerator(); - ECKeyGenerationParameters genParam = new ECKeyGenerationParameters( - parameters, - random); - - pGen.Init(genParam); - - AsymmetricCipherKeyPair pair = pGen.GenerateKeyPair(); - - ParametersWithRandom param = new ParametersWithRandom(pair.Private, random); - - ECDsaSigner ecdsa = new ECDsaSigner(); - - ecdsa.Init(true, param); - - byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").ToByteArray(); - BigInteger[] sig = ecdsa.GenerateSignature(message); - - ecdsa.Init(false, pair.Public); - - if (!ecdsa.VerifySignature(message, sig[0], sig[1])) - { - Fail("signature fails"); - } - } - - /** - * Basic Key Agreement Test - */ - [Test] - public void TestECBasicAgreementTest() - { - SecureRandom random = new SecureRandom(); - - FpCurve curve = new FpCurve( - new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q - new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a - new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b - - ECDomainParameters parameters = new ECDomainParameters( - curve, - curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G - new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n - - - ECKeyPairGenerator pGen = new ECKeyPairGenerator(); - ECKeyGenerationParameters genParam = new ECKeyGenerationParameters(parameters, random); - - pGen.Init(genParam); - - AsymmetricCipherKeyPair p1 = pGen.GenerateKeyPair(); - AsymmetricCipherKeyPair p2 = pGen.GenerateKeyPair(); - - // - // two way - // - IBasicAgreement e1 = new ECDHBasicAgreement(); - IBasicAgreement e2 = new ECDHBasicAgreement(); - - e1.Init(p1.Private); - e2.Init(p2.Private); - - BigInteger k1 = e1.CalculateAgreement(p2.Public); - BigInteger k2 = e2.CalculateAgreement(p1.Public); - - if (!k1.Equals(k2)) - { - Fail("calculated agreement test failed"); - } - - // - // two way - // - e1 = new ECDHCBasicAgreement(); - e2 = new ECDHCBasicAgreement(); - - e1.Init(p1.Private); - e2.Init(p2.Private); - - k1 = e1.CalculateAgreement(p2.Public); - k2 = e2.CalculateAgreement(p1.Public); - - if (!k1.Equals(k2)) - { - Fail("calculated agreement test failed"); - } - } - - [Test] - public void TestECMqvTestVector1() - { - // Test Vector from GEC-2 - - X9ECParameters x9 = SecNamedCurves.GetByName("secp160r1"); - ECDomainParameters p = new ECDomainParameters( - x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()); - - AsymmetricCipherKeyPair U1 = new AsymmetricCipherKeyPair( - new ECPublicKeyParameters( - p.Curve.DecodePoint(Hex.Decode("0251B4496FECC406ED0E75A24A3C03206251419DC0")), p), - new ECPrivateKeyParameters( - new BigInteger("AA374FFC3CE144E6B073307972CB6D57B2A4E982", 16), p)); - - AsymmetricCipherKeyPair U2 = new AsymmetricCipherKeyPair( - new ECPublicKeyParameters( - p.Curve.DecodePoint(Hex.Decode("03D99CE4D8BF52FA20BD21A962C6556B0F71F4CA1F")), p), - new ECPrivateKeyParameters( - new BigInteger("149EC7EA3A220A887619B3F9E5B4CA51C7D1779C", 16), p)); - - AsymmetricCipherKeyPair V1 = new AsymmetricCipherKeyPair( - new ECPublicKeyParameters( - p.Curve.DecodePoint(Hex.Decode("0349B41E0E9C0369C2328739D90F63D56707C6E5BC")), p), - new ECPrivateKeyParameters( - new BigInteger("45FB58A92A17AD4B15101C66E74F277E2B460866", 16), p)); - - AsymmetricCipherKeyPair V2 = new AsymmetricCipherKeyPair( - new ECPublicKeyParameters( - p.Curve.DecodePoint(Hex.Decode("02706E5D6E1F640C6E9C804E75DBC14521B1E5F3B5")), p), - new ECPrivateKeyParameters( - new BigInteger("18C13FCED9EADF884F7C595C8CB565DEFD0CB41E", 16), p)); - - BigInteger x = calculateAgreement(U1, U2, V1, V2); - - if (x == null - || !x.Equals(new BigInteger("5A6955CEFDB4E43255FB7FCF718611E4DF8E05AC", 16))) - { - Fail("MQV Test Vector #1 agreement failed"); - } - } - - [Test] - public void TestECMqvTestVector2() - { - // Test Vector from GEC-2 - - X9ECParameters x9 = SecNamedCurves.GetByName("sect163k1"); - ECDomainParameters p = new ECDomainParameters( - x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()); - - AsymmetricCipherKeyPair U1 = new AsymmetricCipherKeyPair( - new ECPublicKeyParameters( - p.Curve.DecodePoint(Hex.Decode("03037D529FA37E42195F10111127FFB2BB38644806BC")), p), - new ECPrivateKeyParameters( - new BigInteger("03A41434AA99C2EF40C8495B2ED9739CB2155A1E0D", 16), p)); - - AsymmetricCipherKeyPair U2 = new AsymmetricCipherKeyPair( - new ECPublicKeyParameters( - p.Curve.DecodePoint(Hex.Decode("02015198E74BC2F1E5C9A62B80248DF0D62B9ADF8429")), p), - new ECPrivateKeyParameters( - new BigInteger("032FC4C61A8211E6A7C4B8B0C03CF35F7CF20DBD52", 16), p)); - - AsymmetricCipherKeyPair V1 = new AsymmetricCipherKeyPair( - new ECPublicKeyParameters( - p.Curve.DecodePoint(Hex.Decode("03072783FAAB9549002B4F13140B88132D1C75B3886C")), p), - new ECPrivateKeyParameters( - new BigInteger("57E8A78E842BF4ACD5C315AA0569DB1703541D96", 16), p)); - - AsymmetricCipherKeyPair V2 = new AsymmetricCipherKeyPair( - new ECPublicKeyParameters( - p.Curve.DecodePoint(Hex.Decode("03067E3AEA3510D69E8EDD19CB2A703DDC6CF5E56E32")), p), - new ECPrivateKeyParameters( - new BigInteger("02BD198B83A667A8D908EA1E6F90FD5C6D695DE94F", 16), p)); - - BigInteger x = calculateAgreement(U1, U2, V1, V2); - - if (x == null - || !x.Equals(new BigInteger("038359FFD30C0D5FC1E6154F483B73D43E5CF2B503", 16))) - { - Fail("MQV Test Vector #2 agreement failed"); - } - } - - [Test] - public void TestECMqvRandom() - { - SecureRandom random = new SecureRandom(); - - FpCurve curve = new FpCurve( - new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q - new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a - new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b - - ECDomainParameters parameters = new ECDomainParameters( - curve, - curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G - new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n - - ECKeyPairGenerator pGen = new ECKeyPairGenerator(); - - pGen.Init(new ECKeyGenerationParameters(parameters, random)); - - - // Pre-established key pairs - AsymmetricCipherKeyPair U1 = pGen.GenerateKeyPair(); - AsymmetricCipherKeyPair V1 = pGen.GenerateKeyPair(); - - // Ephemeral key pairs - AsymmetricCipherKeyPair U2 = pGen.GenerateKeyPair(); - AsymmetricCipherKeyPair V2 = pGen.GenerateKeyPair(); - - BigInteger x = calculateAgreement(U1, U2, V1, V2); - - if (x == null) - { - Fail("MQV Test Vector (random) agreement failed"); - } - } - - private static BigInteger calculateAgreement( - AsymmetricCipherKeyPair U1, - AsymmetricCipherKeyPair U2, - AsymmetricCipherKeyPair V1, - AsymmetricCipherKeyPair V2) - { - ECMqvBasicAgreement u = new ECMqvBasicAgreement(); - u.Init(new MqvPrivateParameters( - (ECPrivateKeyParameters)U1.Private, - (ECPrivateKeyParameters)U2.Private, - (ECPublicKeyParameters)U2.Public)); - BigInteger ux = u.CalculateAgreement(new MqvPublicParameters( - (ECPublicKeyParameters)V1.Public, - (ECPublicKeyParameters)V2.Public)); - - ECMqvBasicAgreement v = new ECMqvBasicAgreement(); - v.Init(new MqvPrivateParameters( - (ECPrivateKeyParameters)V1.Private, - (ECPrivateKeyParameters)V2.Private, - (ECPublicKeyParameters)V2.Public)); - BigInteger vx = v.CalculateAgreement(new MqvPublicParameters( - (ECPublicKeyParameters)U1.Public, - (ECPublicKeyParameters)U2.Public)); - - if (ux.Equals(vx)) - return ux; - - return null; - } - - public override string Name - { - get { return "EC"; } - } - - public override void PerformTest() - { - TestDecode(); - TestECDsa192bitPrime(); - TestECDsa239bitPrime(); - TestECDsa191bitBinary(); - TestECDsa239bitBinary(); - TestECDsaKeyGenTest(); - TestECBasicAgreementTest(); - - TestECDsaP224Sha224(); - TestECDsaP224OneByteOver(); - TestECDsaP256Sha256(); - TestECDsaP521Sha512(); - TestECDsaSecP224k1Sha256(); - TestECDsa239bitBinaryAndLargeDigest(); - - TestECMqvTestVector1(); - TestECMqvTestVector2(); - TestECMqvRandom(); - } - - public static void Main( - string[] args) - { - RunTest(new ECTest()); - } - } + byte[] M = Hex.Decode("E5D5A7ADF73C5476FAEE93A2C76CE94DC0557DB04CDC189504779117920B896D"); + + ECDsaSigner dsa = new ECDsaSigner(); + + dsa.Init(true, new ParametersWithRandom(priKey, k)); + + BigInteger[] sig = dsa.GenerateSignature(M); + + BigInteger r = new BigInteger("8163E5941BED41DA441B33E653C632A55A110893133351E20CE7CB75", 16); + BigInteger s = new BigInteger("D12C3FC289DDD5F6890DCE26B65792C8C50E68BF551D617D47DF15A8", 16); + + if (!r.Equals(sig[0])) + { + Fail("r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } + + if (!s.Equals(sig[1])) + { + Fail("s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + + // Verify the signature + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + parameters.Curve.DecodePoint(Hex.Decode("04C5C9B38D3603FCCD6994CBB9594E152B658721E483669BB42728520F484B537647EC816E58A8284D3B89DFEDB173AFDC214ECA95A836FA7C")), // Q + parameters); + + dsa.Init(false, pubKey); + if (!dsa.VerifySignature(M, sig[0], sig[1])) + { + Fail("signature fails"); + } + } + + // L4.2 X9.62 2005 + [Test] + public void TestECDsaP256Sha256() + { + X9ECParameters p = NistNamedCurves.GetByName("P-256"); + ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); + ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( + new BigInteger("20186677036482506117540275567393538695075300175221296989956723148347484984008"), // d + parameters); + SecureRandom k = FixedSecureRandom.From(BigIntegers.AsUnsignedByteArray(new BigInteger("72546832179840998877302529996971396893172522460793442785601695562409154906335"))); + + byte[] M = Hex.Decode("1BD4ED430B0F384B4E8D458EFF1A8A553286D7AC21CB2F6806172EF5F94A06AD"); + + ECDsaSigner dsa = new ECDsaSigner(); + + dsa.Init(true, new ParametersWithRandom(priKey, k)); + + BigInteger[] sig = dsa.GenerateSignature(M); + + BigInteger r = new BigInteger("97354732615802252173078420023658453040116611318111190383344590814578738210384"); + BigInteger s = new BigInteger("98506158880355671805367324764306888225238061309262649376965428126566081727535"); + + if (!r.Equals(sig[0])) + { + Fail("r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } + + if (!s.Equals(sig[1])) + { + Fail("s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + + // Verify the signature + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + parameters.Curve.DecodePoint(Hex.Decode("03596375E6CE57E0F20294FC46BDFCFD19A39F8161B58695B3EC5B3D16427C274D")), // Q + parameters); + + dsa.Init(false, pubKey); + if (!dsa.VerifySignature(M, sig[0], sig[1])) + { + Fail("signature fails"); + } + } + + [Test] + public void TestECDsaP224OneByteOver() + { + X9ECParameters p = NistNamedCurves.GetByName("P-224"); + ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); + ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( + new BigInteger("6081831502424510080126737029209236539191290354021104541805484120491"), // d + parameters); + SecureRandom k = FixedSecureRandom.From(BigIntegers.AsUnsignedByteArray(new BigInteger("15456715103636396133226117016818339719732885723579037388121116732601"))); + + byte[] M = Hex.Decode("8797A3C693CC292441039A4E6BAB7387F3B4F2A63D00ED384B378C79FF"); + + ECDsaSigner dsa = new ECDsaSigner(); + + dsa.Init(true, new ParametersWithRandom(priKey, k)); + + BigInteger[] sig = dsa.GenerateSignature(M); + + BigInteger r = new BigInteger("26477406756127720855365980332052585411804331993436302005017227573742"); + BigInteger s = new BigInteger("17694958233103667059888193972742186995283044672015112738919822429978"); + + if (!r.Equals(sig[0])) + { + Fail("r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } + + if (!s.Equals(sig[1])) + { + Fail("s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + + // Verify the signature + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + parameters.Curve.DecodePoint(Hex.Decode("03FD44EC11F9D43D9D23B1E1D1C9ED6519B40ECF0C79F48CF476CC43F1")), // Q + parameters); + + dsa.Init(false, pubKey); + if (!dsa.VerifySignature(M, sig[0], sig[1])) + { + Fail("signature fails"); + } + } + + // L4.3 X9.62 2005 + [Test] + public void TestECDsaP521Sha512() + { + X9ECParameters p = NistNamedCurves.GetByName("P-521"); + ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); + ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( + new BigInteger("617573726813476282316253885608633222275541026607493641741273231656161177732180358888434629562647985511298272498852936680947729040673640492310550142822667389"), // d + parameters); + SecureRandom k = FixedSecureRandom.From(BigIntegers.AsUnsignedByteArray(new BigInteger("6806532878215503520845109818432174847616958675335397773700324097584974639728725689481598054743894544060040710846048585856076812050552869216017728862957612913"))); + + byte[] M = Hex.Decode("6893B64BD3A9615C39C3E62DDD269C2BAAF1D85915526083183CE14C2E883B48B193607C1ED871852C9DF9C3147B574DC1526C55DE1FE263A676346A20028A66"); + + ECDsaSigner dsa = new ECDsaSigner(); + + dsa.Init(true, new ParametersWithRandom(priKey, k)); + + BigInteger[] sig = dsa.GenerateSignature(M); + + BigInteger r = new BigInteger("1368926195812127407956140744722257403535864168182534321188553460365652865686040549247096155740756318290773648848859639978618869784291633651685766829574104630"); + BigInteger s = new BigInteger("1624754720348883715608122151214003032398685415003935734485445999065609979304811509538477657407457976246218976767156629169821116579317401249024208611945405790"); + + if (!r.Equals(sig[0])) + { + Fail("r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } + + if (!s.Equals(sig[1])) + { + Fail("s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + + // Verify the signature + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + parameters.Curve.DecodePoint(Hex.Decode("020145E221AB9F71C5FE740D8D2B94939A09E2816E2167A7D058125A06A80C014F553E8D6764B048FB6F2B687CEC72F39738F223D4CE6AFCBFF2E34774AA5D3C342CB3")), // Q + parameters); + + dsa.Init(false, pubKey); + if (!dsa.VerifySignature(M, sig[0], sig[1])) + { + Fail("signature fails"); + } + } + + /** + * General test for long digest. + */ + [Test] + public void TestECDsa239bitBinaryAndLargeDigest() + { + BigInteger r = new BigInteger("21596333210419611985018340039034612628818151486841789642455876922391552"); + BigInteger s = new BigInteger("144940322424411242416373536877786566515839911620497068645600824084578597"); + + byte[] kData = BigIntegers.AsUnsignedByteArray( + new BigInteger("171278725565216523967285789236956265265265235675811949404040041670216363")); + + SecureRandom k = FixedSecureRandom.From(kData); + + F2mCurve curve = new F2mCurve( + 239, // m + 36, //k + new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a + new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b + + ECDomainParameters parameters = new ECDomainParameters( + curve, + curve.DecodePoint( + Hex.Decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G + new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n + BigInteger.ValueOf(4)); // h + + ECPrivateKeyParameters priKey = new ECPrivateKeyParameters( + "ECDSA", + new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d + parameters); + + ECDsaSigner ecdsa = new ECDsaSigner(); + ParametersWithRandom param = new ParametersWithRandom(priKey, k); + + ecdsa.Init(true, param); + + byte[] message = new BigInteger("968236873715988614170569073515315707566766479517968236873715988614170569073515315707566766479517968236873715988614170569073515315707566766479517").ToByteArray(); + BigInteger[] sig = ecdsa.GenerateSignature(message); + + if (!r.Equals(sig[0])) + { + Fail("r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } + + if (!s.Equals(sig[1])) + { + Fail("s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + + // Verify the signature + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + "ECDSA", + curve.DecodePoint( + Hex.Decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q + parameters); + + ecdsa.Init(false, pubKey); + if (!ecdsa.VerifySignature(message, sig[0], sig[1])) + { + Fail("signature fails"); + } + } + + /** + * key generation test + */ + [Test] + public void TestECDsaKeyGenTest() + { + SecureRandom random = new SecureRandom(); + + FpCurve curve = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b + + ECDomainParameters parameters = new ECDomainParameters( + curve, + curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G + new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n + + + ECKeyPairGenerator pGen = new ECKeyPairGenerator(); + ECKeyGenerationParameters genParam = new ECKeyGenerationParameters( + parameters, + random); + + pGen.Init(genParam); + + AsymmetricCipherKeyPair pair = pGen.GenerateKeyPair(); + + ParametersWithRandom param = new ParametersWithRandom(pair.Private, random); + + ECDsaSigner ecdsa = new ECDsaSigner(); + + ecdsa.Init(true, param); + + byte[] message = new BigInteger("968236873715988614170569073515315707566766479517").ToByteArray(); + BigInteger[] sig = ecdsa.GenerateSignature(message); + + ecdsa.Init(false, pair.Public); + + if (!ecdsa.VerifySignature(message, sig[0], sig[1])) + { + Fail("signature fails"); + } + } + + /** + * Basic Key Agreement Test + */ + [Test] + public void TestECBasicAgreementTest() + { + SecureRandom random = new SecureRandom(); + + FpCurve curve = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b + + ECDomainParameters parameters = new ECDomainParameters( + curve, + curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G + new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n + + + ECKeyPairGenerator pGen = new ECKeyPairGenerator(); + ECKeyGenerationParameters genParam = new ECKeyGenerationParameters(parameters, random); + + pGen.Init(genParam); + + AsymmetricCipherKeyPair p1 = pGen.GenerateKeyPair(); + AsymmetricCipherKeyPair p2 = pGen.GenerateKeyPair(); + + // + // two way + // + IBasicAgreement e1 = new ECDHBasicAgreement(); + IBasicAgreement e2 = new ECDHBasicAgreement(); + + e1.Init(p1.Private); + e2.Init(p2.Private); + + BigInteger k1 = e1.CalculateAgreement(p2.Public); + BigInteger k2 = e2.CalculateAgreement(p1.Public); + + if (!k1.Equals(k2)) + { + Fail("calculated agreement test failed"); + } + + // + // two way + // + e1 = new ECDHCBasicAgreement(); + e2 = new ECDHCBasicAgreement(); + + e1.Init(p1.Private); + e2.Init(p2.Private); + + k1 = e1.CalculateAgreement(p2.Public); + k2 = e2.CalculateAgreement(p1.Public); + + if (!k1.Equals(k2)) + { + Fail("calculated agreement test failed"); + } + } + + [Test] + public void TestECMqvTestVector1() + { + // Test Vector from GEC-2 + + X9ECParameters x9 = SecNamedCurves.GetByName("secp160r1"); + ECDomainParameters p = new ECDomainParameters( + x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()); + + AsymmetricCipherKeyPair U1 = new AsymmetricCipherKeyPair( + new ECPublicKeyParameters( + p.Curve.DecodePoint(Hex.Decode("0251B4496FECC406ED0E75A24A3C03206251419DC0")), p), + new ECPrivateKeyParameters( + new BigInteger("AA374FFC3CE144E6B073307972CB6D57B2A4E982", 16), p)); + + AsymmetricCipherKeyPair U2 = new AsymmetricCipherKeyPair( + new ECPublicKeyParameters( + p.Curve.DecodePoint(Hex.Decode("03D99CE4D8BF52FA20BD21A962C6556B0F71F4CA1F")), p), + new ECPrivateKeyParameters( + new BigInteger("149EC7EA3A220A887619B3F9E5B4CA51C7D1779C", 16), p)); + + AsymmetricCipherKeyPair V1 = new AsymmetricCipherKeyPair( + new ECPublicKeyParameters( + p.Curve.DecodePoint(Hex.Decode("0349B41E0E9C0369C2328739D90F63D56707C6E5BC")), p), + new ECPrivateKeyParameters( + new BigInteger("45FB58A92A17AD4B15101C66E74F277E2B460866", 16), p)); + + AsymmetricCipherKeyPair V2 = new AsymmetricCipherKeyPair( + new ECPublicKeyParameters( + p.Curve.DecodePoint(Hex.Decode("02706E5D6E1F640C6E9C804E75DBC14521B1E5F3B5")), p), + new ECPrivateKeyParameters( + new BigInteger("18C13FCED9EADF884F7C595C8CB565DEFD0CB41E", 16), p)); + + BigInteger x = calculateAgreement(U1, U2, V1, V2); + + if (x == null + || !x.Equals(new BigInteger("5A6955CEFDB4E43255FB7FCF718611E4DF8E05AC", 16))) + { + Fail("MQV Test Vector #1 agreement failed"); + } + } + + [Test] + public void TestECMqvTestVector2() + { + // Test Vector from GEC-2 + + X9ECParameters x9 = SecNamedCurves.GetByName("sect163k1"); + ECDomainParameters p = new ECDomainParameters( + x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()); + + AsymmetricCipherKeyPair U1 = new AsymmetricCipherKeyPair( + new ECPublicKeyParameters( + p.Curve.DecodePoint(Hex.Decode("03037D529FA37E42195F10111127FFB2BB38644806BC")), p), + new ECPrivateKeyParameters( + new BigInteger("03A41434AA99C2EF40C8495B2ED9739CB2155A1E0D", 16), p)); + + AsymmetricCipherKeyPair U2 = new AsymmetricCipherKeyPair( + new ECPublicKeyParameters( + p.Curve.DecodePoint(Hex.Decode("02015198E74BC2F1E5C9A62B80248DF0D62B9ADF8429")), p), + new ECPrivateKeyParameters( + new BigInteger("032FC4C61A8211E6A7C4B8B0C03CF35F7CF20DBD52", 16), p)); + + AsymmetricCipherKeyPair V1 = new AsymmetricCipherKeyPair( + new ECPublicKeyParameters( + p.Curve.DecodePoint(Hex.Decode("03072783FAAB9549002B4F13140B88132D1C75B3886C")), p), + new ECPrivateKeyParameters( + new BigInteger("57E8A78E842BF4ACD5C315AA0569DB1703541D96", 16), p)); + + AsymmetricCipherKeyPair V2 = new AsymmetricCipherKeyPair( + new ECPublicKeyParameters( + p.Curve.DecodePoint(Hex.Decode("03067E3AEA3510D69E8EDD19CB2A703DDC6CF5E56E32")), p), + new ECPrivateKeyParameters( + new BigInteger("02BD198B83A667A8D908EA1E6F90FD5C6D695DE94F", 16), p)); + + BigInteger x = calculateAgreement(U1, U2, V1, V2); + + if (x == null + || !x.Equals(new BigInteger("038359FFD30C0D5FC1E6154F483B73D43E5CF2B503", 16))) + { + Fail("MQV Test Vector #2 agreement failed"); + } + } + + [Test] + public void TestECMqvRandom() + { + SecureRandom random = new SecureRandom(); + + FpCurve curve = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b + + ECDomainParameters parameters = new ECDomainParameters( + curve, + curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G + new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n + + ECKeyPairGenerator pGen = new ECKeyPairGenerator(); + + pGen.Init(new ECKeyGenerationParameters(parameters, random)); + + + // Pre-established key pairs + AsymmetricCipherKeyPair U1 = pGen.GenerateKeyPair(); + AsymmetricCipherKeyPair V1 = pGen.GenerateKeyPair(); + + // Ephemeral key pairs + AsymmetricCipherKeyPair U2 = pGen.GenerateKeyPair(); + AsymmetricCipherKeyPair V2 = pGen.GenerateKeyPair(); + + BigInteger x = calculateAgreement(U1, U2, V1, V2); + + if (x == null) + { + Fail("MQV Test Vector (random) agreement failed"); + } + } + + private static BigInteger calculateAgreement( + AsymmetricCipherKeyPair U1, + AsymmetricCipherKeyPair U2, + AsymmetricCipherKeyPair V1, + AsymmetricCipherKeyPair V2) + { + ECMqvBasicAgreement u = new ECMqvBasicAgreement(); + u.Init(new MqvPrivateParameters( + (ECPrivateKeyParameters)U1.Private, + (ECPrivateKeyParameters)U2.Private, + (ECPublicKeyParameters)U2.Public)); + BigInteger ux = u.CalculateAgreement(new MqvPublicParameters( + (ECPublicKeyParameters)V1.Public, + (ECPublicKeyParameters)V2.Public)); + + ECMqvBasicAgreement v = new ECMqvBasicAgreement(); + v.Init(new MqvPrivateParameters( + (ECPrivateKeyParameters)V1.Private, + (ECPrivateKeyParameters)V2.Private, + (ECPublicKeyParameters)V2.Public)); + BigInteger vx = v.CalculateAgreement(new MqvPublicParameters( + (ECPublicKeyParameters)U1.Public, + (ECPublicKeyParameters)U2.Public)); + + if (ux.Equals(vx)) + return ux; + + return null; + } + + public override string Name + { + get { return "EC"; } + } + + public override void PerformTest() + { + TestDecode(); + TestECDsa192bitPrime(); + TestECDsa239bitPrime(); + TestECDsa191bitBinary(); + TestECDsa239bitBinary(); + TestECDsaKeyGenTest(); + TestECBasicAgreementTest(); + + TestECDsaP224Sha224(); + TestECDsaP224OneByteOver(); + TestECDsaP256Sha256(); + TestECDsaP521Sha512(); + TestECDsaSecP224k1Sha256(); + TestECDsa239bitBinaryAndLargeDigest(); + + TestECMqvTestVector1(); + TestECMqvTestVector2(); + TestECMqvRandom(); + } + + public static void Main( + string[] args) + { + RunTest(new ECTest()); + } + } } diff --git a/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs b/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs index 6b9e2efce..f9e89eccf 100644 --- a/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs +++ b/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs @@ -57,6 +57,7 @@ namespace Org.BouncyCastle.Math.EC.Tests Console.WriteLine(label); int[] coords = ECCurve.GetAllCoordinateSystems(); + //int[] coords = new int[] { ECCurve.COORD_HOMOGENEOUS }; for (int i = 0; i < coords.Length; ++i) { int coord = coords[i]; @@ -134,11 +135,15 @@ namespace Org.BouncyCastle.Math.EC.Tests ISet oids = new HashSet(); foreach (string name in names) { - DerObjectIdentifier oid = ECNamedCurveTable.GetOid(name); - if (!oids.Contains(oid)) + //if (name.StartsWith("P-")) + //if (name.Equals("secp256r1")) { - oids.Add(oid); - RandMult(name); + DerObjectIdentifier oid = ECNamedCurveTable.GetOid(name); + if (!oids.Contains(oid)) + { + oids.Add(oid); + RandMult(name); + } } } } diff --git a/crypto/test/src/math/ec/test/ECPointTest.cs b/crypto/test/src/math/ec/test/ECPointTest.cs index 54c54d1d4..b4cabec78 100644 --- a/crypto/test/src/math/ec/test/ECPointTest.cs +++ b/crypto/test/src/math/ec/test/ECPointTest.cs @@ -4,6 +4,7 @@ using NUnit.Framework; using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto.EC; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Security; @@ -143,8 +144,7 @@ namespace Org.BouncyCastle.Math.EC.Tests try { - F2mPoint bad = new F2mPoint(F2m.curve, new F2mFieldElement( - F2m.m, F2m.k1, new BigInteger("1011")), null); + ECPoint bad = F2m.curve.CreatePoint(new BigInteger("1011"), null); Assert.Fail(); } catch (ArgumentException) @@ -154,9 +154,7 @@ namespace Org.BouncyCastle.Math.EC.Tests try { - F2mPoint bad = new F2mPoint(F2m.curve, null, - new F2mFieldElement(F2m.m, F2m.k1, - new BigInteger("1011"))); + ECPoint bad = F2m.curve.CreatePoint(null, new BigInteger("1011")); Assert.Fail(); } catch (ArgumentException) @@ -173,14 +171,14 @@ namespace Org.BouncyCastle.Math.EC.Tests * @param infinity * The point at infinity on the respective curve. */ - private void implTestAdd(ECPoint[] p, ECPoint infinity) + private void ImplTestAdd(ECPoint[] p, ECPoint infinity) { - Assert.AreEqual(p[2], p[0].Add(p[1]), "p0 plus p1 does not equal p2"); - Assert.AreEqual(p[2], p[1].Add(p[0]), "p1 plus p0 does not equal p2"); + AssertPointsEqual("p0 plus p1 does not equal p2", p[2], p[0].Add(p[1])); + AssertPointsEqual("p1 plus p0 does not equal p2", p[2], p[1].Add(p[0])); for (int i = 0; i < p.Length; i++) { - Assert.AreEqual(p[i], p[i].Add(infinity), "Adding infinity failed"); - Assert.AreEqual(p[i], infinity.Add(p[i]), "Adding to infinity failed"); + AssertPointsEqual("Adding infinity failed", p[i], p[i].Add(infinity)); + AssertPointsEqual("Adding to infinity failed", p[i], infinity.Add(p[i])); } } @@ -191,8 +189,8 @@ namespace Org.BouncyCastle.Math.EC.Tests [Test] public void TestAdd() { - implTestAdd(Fp.p, Fp.infinity); - implTestAdd(F2m.p, F2m.infinity); + ImplTestAdd(Fp.p, Fp.infinity); + ImplTestAdd(F2m.p, F2m.infinity); } /** @@ -201,10 +199,10 @@ namespace Org.BouncyCastle.Math.EC.Tests * @param p * The array of literature values. */ - private void implTestTwice(ECPoint[] p) + private void ImplTestTwice(ECPoint[] p) { - Assert.AreEqual(p[3], p[0].Twice(), "Twice incorrect"); - Assert.AreEqual(p[3], p[0].Add(p[0]), "Add same point incorrect"); + AssertPointsEqual("Twice incorrect", p[3], p[0].Twice()); + AssertPointsEqual("Add same point incorrect", p[3], p[0].Add(p[0])); } /** @@ -214,16 +212,16 @@ namespace Org.BouncyCastle.Math.EC.Tests [Test] public void TestTwice() { - implTestTwice(Fp.p); - implTestTwice(F2m.p); + ImplTestTwice(Fp.p); + ImplTestTwice(F2m.p); } - private void implTestThreeTimes(ECPoint[] p) + private void ImplTestThreeTimes(ECPoint[] p) { ECPoint P = p[0]; ECPoint _3P = P.Add(P).Add(P); - Assert.AreEqual(_3P, P.ThreeTimes(), "ThreeTimes incorrect"); - Assert.AreEqual(_3P, P.TwicePlus(P), "TwicePlus incorrect"); + AssertPointsEqual("ThreeTimes incorrect", _3P, P.ThreeTimes()); + AssertPointsEqual("TwicePlus incorrect", _3P, P.TwicePlus(P)); } /** @@ -233,8 +231,8 @@ namespace Org.BouncyCastle.Math.EC.Tests [Test] public void TestThreeTimes() { - implTestThreeTimes(Fp.p); - implTestThreeTimes(F2m.p); + ImplTestThreeTimes(Fp.p); + ImplTestThreeTimes(F2m.p); } /** @@ -248,18 +246,18 @@ namespace Org.BouncyCastle.Math.EC.Tests * @param infinity * The point at infinity on the elliptic curve. */ - private void implTestAllPoints(ECPoint p, ECPoint infinity) + private void ImplTestAllPoints(ECPoint p, ECPoint infinity) { ECPoint adder = infinity; ECPoint multiplier = infinity; - int i = 1; + + BigInteger i = BigInteger.One; do { adder = adder.Add(p); - multiplier = p.Multiply(new BigInteger(i.ToString())); - Assert.AreEqual(adder, multiplier, - "Results of add() and multiply() are inconsistent " + i); - i++; + multiplier = p.Multiply(i); + AssertPointsEqual("Results of Add() and Multiply() are inconsistent " + i, adder, multiplier); + i = i.Add(BigInteger.One); } while (!(adder.Equals(infinity))); } @@ -273,12 +271,12 @@ namespace Org.BouncyCastle.Math.EC.Tests { for (int i = 0; i < Fp.p.Length; i++) { - implTestAllPoints(Fp.p[0], Fp.infinity); + ImplTestAllPoints(Fp.p[0], Fp.infinity); } for (int i = 0; i < F2m.p.Length; i++) { - implTestAllPoints(F2m.p[0], F2m.infinity); + ImplTestAllPoints(F2m.p[0], F2m.infinity); } } @@ -293,17 +291,20 @@ namespace Org.BouncyCastle.Math.EC.Tests * The multiplier. * @return The result of the point multiplication kP. */ - private ECPoint multiply(ECPoint p, BigInteger k) + private ECPoint Multiply(ECPoint p, BigInteger k) { ECPoint q = p.Curve.Infinity; int t = k.BitLength; for (int i = 0; i < t; i++) { + if (i != 0) + { + p = p.Twice(); + } if (k.TestBit(i)) { q = q.Add(p); } - p = p.Twice(); } return q; } @@ -320,12 +321,12 @@ namespace Org.BouncyCastle.Math.EC.Tests * The bitlength of the random number by which p * is multiplied. */ - private void implTestMultiply(ECPoint p, int numBits) + private void ImplTestMultiply(ECPoint p, int numBits) { BigInteger k = new BigInteger(numBits, secRand); - ECPoint reff = multiply(p, k); + ECPoint reff = Multiply(p, k); ECPoint q = p.Multiply(k); - Assert.AreEqual(reff, q, "ECPoint.multiply is incorrect"); + AssertPointsEqual("ECPoint.Multiply is incorrect", reff, q); } /** @@ -340,16 +341,16 @@ namespace Org.BouncyCastle.Math.EC.Tests * @param numBits * Try every multiplier up to this bitlength */ - private void implTestMultiplyAll(ECPoint p, int numBits) + private void ImplTestMultiplyAll(ECPoint p, int numBits) { - BigInteger bound = BigInteger.Two.Pow(numBits); + BigInteger bound = BigInteger.One.ShiftLeft(numBits); BigInteger k = BigInteger.Zero; do { - ECPoint reff = multiply(p, k); + ECPoint reff = Multiply(p, k); ECPoint q = p.Multiply(k); - Assert.AreEqual(reff, q, "ECPoint.multiply is incorrect"); + AssertPointsEqual("ECPoint.Multiply is incorrect", reff, q); k = k.Add(BigInteger.One); } while (k.CompareTo(bound) < 0); @@ -364,14 +365,16 @@ namespace Org.BouncyCastle.Math.EC.Tests * @param infinity * The point at infinity on the same curve as p. */ - private void implTestAddSubtract(ECPoint p, ECPoint infinity) + private void ImplTestAddSubtract(ECPoint p, ECPoint infinity) { - Assert.AreEqual(p.Twice(), p.Add(p), "Twice and Add inconsistent"); - Assert.AreEqual(p, p.Twice().Subtract(p), "Twice p - p is not p"); - Assert.AreEqual(infinity, p.Subtract(p), "p - p is not infinity"); - Assert.AreEqual(p, p.Add(infinity), "p plus infinity is not p"); - Assert.AreEqual(p, infinity.Add(p), "infinity plus p is not p"); - Assert.AreEqual(infinity, infinity.Add(infinity), "infinity plus infinity is not infinity "); + AssertPointsEqual("Twice and Add inconsistent", p.Twice(), p.Add(p)); + AssertPointsEqual("Twice p - p is not p", p, p.Twice().Subtract(p)); + AssertPointsEqual("TwicePlus(p, -p) is not p", p, p.TwicePlus(p.Negate())); + AssertPointsEqual("p - p is not infinity", infinity, p.Subtract(p)); + AssertPointsEqual("p plus infinity is not p", p, p.Add(infinity)); + AssertPointsEqual("infinity plus p is not p", p, infinity.Add(p)); + AssertPointsEqual("infinity plus infinity is not infinity ", infinity, infinity.Add(infinity)); + AssertPointsEqual("Twice infinity is not infinity ", infinity, infinity.Twice()); } /** @@ -383,20 +386,20 @@ namespace Org.BouncyCastle.Math.EC.Tests { for (int iFp = 0; iFp < Fp.pointSource.Length / 2; iFp++) { - implTestAddSubtract(Fp.p[iFp], Fp.infinity); + ImplTestAddSubtract(Fp.p[iFp], Fp.infinity); // Could be any numBits, 6 is chosen at will - implTestMultiplyAll(Fp.p[iFp], 6); - implTestMultiplyAll(Fp.infinity, 6); + ImplTestMultiplyAll(Fp.p[iFp], 6); + ImplTestMultiplyAll(Fp.infinity, 6); } for (int iF2m = 0; iF2m < F2m.pointSource.Length / 2; iF2m++) { - implTestAddSubtract(F2m.p[iF2m], F2m.infinity); + ImplTestAddSubtract(F2m.p[iF2m], F2m.infinity); // Could be any numBits, 6 is chosen at will - implTestMultiplyAll(F2m.p[iF2m], 6); - implTestMultiplyAll(F2m.infinity, 6); + ImplTestMultiplyAll(F2m.p[iF2m], 6); + ImplTestMultiplyAll(F2m.infinity, 6); } } @@ -406,21 +409,39 @@ namespace Org.BouncyCastle.Math.EC.Tests * @param p * The point to be encoded and decoded. */ - private void implTestEncoding(ECPoint p) + private void ImplTestEncoding(ECPoint p) { // Not Point Compression - ECPoint unCompP = p.Curve.CreatePoint(p.X.ToBigInteger(), p.Y.ToBigInteger(), false); + ECPoint unCompP = p.Curve.CreatePoint(p.AffineXCoord.ToBigInteger(), p.AffineYCoord.ToBigInteger(), false); // Point compression - ECPoint compP = p.Curve.CreatePoint(p.X.ToBigInteger(), p.Y.ToBigInteger(), true); + ECPoint compP = p.Curve.CreatePoint(p.AffineXCoord.ToBigInteger(), p.AffineYCoord.ToBigInteger(), true); byte[] unCompBarr = unCompP.GetEncoded(); ECPoint decUnComp = p.Curve.DecodePoint(unCompBarr); - Assert.AreEqual(p, decUnComp, "Error decoding uncompressed point"); + AssertPointsEqual("Error decoding uncompressed point", p, decUnComp); byte[] compBarr = compP.GetEncoded(); ECPoint decComp = p.Curve.DecodePoint(compBarr); - Assert.AreEqual(p, decComp, "Error decoding compressed point"); + AssertPointsEqual("Error decoding compressed point", p, decComp); + } + + private void ImplAddSubtractMultiplyTwiceEncodingTest(X9ECParameters x9ECParameters) + { + BigInteger n = x9ECParameters.N; + + // The generator is multiplied by random b to get random q + BigInteger b = new BigInteger(n.BitLength, secRand); + ECPoint g = x9ECParameters.G; + ECPoint q = g.Multiply(b).Normalize(); + + // Get point at infinity on the curve + ECPoint infinity = x9ECParameters.Curve.Infinity; + + ImplTestAddSubtract(q, infinity); + ImplTestMultiply(q, n.BitLength); + ImplTestMultiply(infinity, n.BitLength); + ImplTestEncoding(q); } /** @@ -434,22 +455,19 @@ namespace Org.BouncyCastle.Math.EC.Tests foreach (string name in SecNamedCurves.Names) { X9ECParameters x9ECParameters = SecNamedCurves.GetByName(name); + ImplAddSubtractMultiplyTwiceEncodingTest(x9ECParameters); - BigInteger n = x9ECParameters.N; - - // The generator is multiplied by random b to get random q - BigInteger b = new BigInteger(n.BitLength, secRand); - ECPoint g = x9ECParameters.G; - ECPoint q = g.Multiply(b); - - // Get point at infinity on the curve - ECPoint infinity = x9ECParameters.Curve.Infinity; - - implTestAddSubtract(q, infinity); - implTestMultiply(q, n.BitLength); - implTestMultiply(infinity, n.BitLength); - implTestEncoding(q); + x9ECParameters = CustomNamedCurves.GetByName(name); + if (x9ECParameters != null) + { + ImplAddSubtractMultiplyTwiceEncodingTest(x9ECParameters); + } } } + + private void AssertPointsEqual(string message, ECPoint a, ECPoint b) + { + Assert.AreEqual(a, b, message); + } } -} \ No newline at end of file +} diff --git a/crypto/test/src/test/CertTest.cs b/crypto/test/src/test/CertTest.cs index 382ff326d..2aef010d0 100644 --- a/crypto/test/src/test/CertTest.cs +++ b/crypto/test/src/test/CertTest.cs @@ -25,221 +25,221 @@ using Org.BouncyCastle.X509.Extension; namespace Org.BouncyCastle.Tests { - [TestFixture] - public class CertTest - : SimpleTest - { - // - // server.crt - // - private static readonly byte[] cert1 = Base64.Decode( - "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" - + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" - + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" - + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" - + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" - + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" - + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" - + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" - + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" - + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" - + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" - + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" - + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" - + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" - + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" - + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" - + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" - + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" - + "5/8="); - - // - // ca.crt - // - private static readonly byte[] cert2 = Base64.Decode( - "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" - + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" - + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" - + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" - + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2" - + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" - + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" - + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u" - + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t" - + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv" - + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s" - + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur" - + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl" - + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E" - + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG" - + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk" - + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz" - + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ" - + "DhkaJ8VqOMajkQFma2r9iA=="); - - // - // testx509.pem - // - private static readonly byte[] cert3 = Base64.Decode( - "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" - + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" - + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" - + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" - + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" - + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" - + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" - + "zl9HYIMxATFyqSiD9jsx"); - - // - // v3-cert1.pem - // - private static readonly byte[] cert4 = Base64.Decode( - "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx" - + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz" - + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw" - + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu" - + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2" - + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp" - + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C" - + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK" - + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x" - + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR" - + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB" - + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21" - + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3" - + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO"); - - // - // v3-cert2.pem - // - private static readonly byte[] cert5 = Base64.Decode( - "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD" - + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0" - + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu" - + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1" - + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV" - + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx" - + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA" - + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT" - + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ" - + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm" - + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc" - + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz" - + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap" - + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU="); - - // - // pem encoded pkcs7 - // - private static readonly byte[] cert6 = Base64.Decode( - "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w" - + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG" - + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy" - + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw" - + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi" - + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A" - + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH" - + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF" - + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d" - + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix" - + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR" - + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD" - + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj" - + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy" - + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy" - + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j" - + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg" - + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B" - + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB" - + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc" - + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG" - + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv" - + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B" - + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0" - + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg" - + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ" - + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln" - + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB" - + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx" - + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy" - + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD" - + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl" - + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz" - + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m" - + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv" - + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb" - + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK" - + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB" - + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0" - + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo" - + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB" - + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R" - + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y" - + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j" - + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu" - + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE" - + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg" - + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG" - + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU" - + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG" - + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w" - + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O" - + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy" - + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA=="); - - // - // dsaWithSHA1 cert - // - private static readonly byte[] cert7 = Base64.Decode( - "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG" - + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7" - + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh" - + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj" - + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z" - + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa" - + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw" - + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj" - + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE" - + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3" - + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn" - + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc" - + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg" - + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q" - + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH" - + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC" - + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC" - + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY" - + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1" - + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ" - + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T" - + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU" - + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji" - + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID" - + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh" - + "cg=="); - - // - // testcrl.pem - // - private static readonly byte[] crl1 = Base64.Decode( - "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT" - + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy" - + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw" - + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw" - + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw" - + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw" - + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw" - + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw" - + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw" - + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw" - + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF" - + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ" - + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt" - + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v"); - - // - // ecdsa cert with extra octet string. - // + [TestFixture] + public class CertTest + : SimpleTest + { + // + // server.crt + // + private static readonly byte[] cert1 = Base64.Decode( + "MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2" + + "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + + "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l" + + "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv" + + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re" + + "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO" + + "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE" + + "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy" + + "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0" + + "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw" + + "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL" + + "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4" + + "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF" + + "5/8="); + + // + // ca.crt + // + private static readonly byte[] cert2 = Base64.Decode( + "MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx" + + "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY" + + "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB" + + "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ" + + "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2" + + "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW" + + "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM" + + "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u" + + "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t" + + "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv" + + "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s" + + "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur" + + "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl" + + "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E" + + "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG" + + "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk" + + "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz" + + "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ" + + "DhkaJ8VqOMajkQFma2r9iA=="); + + // + // testx509.pem + // + private static readonly byte[] cert3 = Base64.Decode( + "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV" + + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz" + + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM" + + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF" + + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO" + + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE" + + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ" + + "zl9HYIMxATFyqSiD9jsx"); + + // + // v3-cert1.pem + // + private static readonly byte[] cert4 = Base64.Decode( + "MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx" + + "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz" + + "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw" + + "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu" + + "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2" + + "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp" + + "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C" + + "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK" + + "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x" + + "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR" + + "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB" + + "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21" + + "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3" + + "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO"); + + // + // v3-cert2.pem + // + private static readonly byte[] cert5 = Base64.Decode( + "MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD" + + "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0" + + "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu" + + "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1" + + "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV" + + "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx" + + "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA" + + "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT" + + "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ" + + "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm" + + "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc" + + "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz" + + "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap" + + "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU="); + + // + // pem encoded pkcs7 + // + private static readonly byte[] cert6 = Base64.Decode( + "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJbzCCAj0w" + + "ggGmAhEAzbp/VvDf5LxU/iKss3KqVTANBgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUG" + + "A1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2Vy" + + "dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTYwMTI5MDAwMDAwWhcNMjgwODAxMjM1OTU5WjBfMQsw" + + "CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi" + + "bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0A" + + "MIGJAoGBAOUZv22jVmEtmUhx9mfeuY3rt56GgAqRDvo4Ja9GiILlc6igmyRdDR/MZW4MsNBWhBiH" + + "mgabEKFz37RYOWtuwfYV1aioP6oSBo0xrH+wNNePNGeICc0UEeJORVZpH3gCgNrcR5EpuzbJY1zF" + + "4Ncth3uhtzKwezC6Ki8xqu6jZ9rbAgMBAAEwDQYJKoZIhvcNAQECBQADgYEATD+4i8Zo3+5DMw5d" + + "6abLB4RNejP/khv0Nq3YlSI2aBFsfELM85wuxAc/FLAPT/+Qknb54rxK6Y/NoIAK98Up8YIiXbix" + + "3YEjo3slFUYweRb46gVLlH8dwhzI47f0EEA8E8NfH1PoSOSGtHuhNbB7Jbq4046rPzidADQAmPPR" + + "cZQwggMuMIICl6ADAgECAhEA0nYujRQMPX2yqCVdr+4NdTANBgkqhkiG9w0BAQIFADBfMQswCQYD" + + "VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVibGlj" + + "IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNOTgwNTEyMDAwMDAwWhcNMDgwNTEy" + + "MjM1OTU5WjCBzDEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy" + + "dXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5j" + + "b3JwLiBCeSBSZWYuLExJQUIuTFREKGMpOTgxSDBGBgNVBAMTP1ZlcmlTaWduIENsYXNzIDEgQ0Eg" + + "SW5kaXZpZHVhbCBTdWJzY3JpYmVyLVBlcnNvbmEgTm90IFZhbGlkYXRlZDCBnzANBgkqhkiG9w0B" + + "AQEFAAOBjQAwgYkCgYEAu1pEigQWu1X9A3qKLZRPFXg2uA1Ksm+cVL+86HcqnbnwaLuV2TFBcHqB" + + "S7lIE1YtxwjhhEKrwKKSq0RcqkLwgg4C6S/7wju7vsknCl22sDZCM7VuVIhPh0q/Gdr5FegPh7Yc" + + "48zGmo5/aiSS4/zgZbqnsX7vyds3ashKyAkG5JkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEG" + + "MEcGA1UdIARAMD4wPAYLYIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNv" + + "bS9yZXBvc2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B" + + "AQIFAAOBgQCIuDc73dqUNwCtqp/hgQFxHpJqbS/28Z3TymQ43BuYDAeGW4UVag+5SYWklfEXfWe0" + + "fy0s3ZpCnsM+tI6q5QsG3vJWKvozx74Z11NMw73I4xe1pElCY+zCphcPXVgaSTyQXFWjZSAA/Rgg" + + "5V+CprGoksVYasGNAzzrw80FopCubjCCA/gwggNhoAMCAQICEBbbn/1G1zppD6KsP01bwywwDQYJ" + + "KoZIhvcNAQEEBQAwgcwxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln" + + "biBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBB" + + "IEluY29ycC4gQnkgUmVmLixMSUFCLkxURChjKTk4MUgwRgYDVQQDEz9WZXJpU2lnbiBDbGFzcyAx" + + "IENBIEluZGl2aWR1YWwgU3Vic2NyaWJlci1QZXJzb25hIE5vdCBWYWxpZGF0ZWQwHhcNMDAxMDAy" + + "MDAwMDAwWhcNMDAxMjAxMjM1OTU5WjCCAQcxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD" + + "VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3Jl" + + "cG9zaXRvcnkvUlBBIEluY29ycC4gYnkgUmVmLixMSUFCLkxURChjKTk4MR4wHAYDVQQLExVQZXJz" + + "b25hIE5vdCBWYWxpZGF0ZWQxJzAlBgNVBAsTHkRpZ2l0YWwgSUQgQ2xhc3MgMSAtIE1pY3Jvc29m" + + "dDETMBEGA1UEAxQKRGF2aWQgUnlhbjElMCMGCSqGSIb3DQEJARYWZGF2aWRAbGl2ZW1lZGlhLmNv" + + "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxBsdeNmSvFqhMNwhQgNzM8mdjX9eSXb" + + "DawpHtQHjmh0AKJSa3IwUY0VIsyZHuXWktO/CgaMBVPt6OVf/n0R2sQigMP6Y+PhEiS0vCJBL9aK" + + "0+pOo2qXrjVBmq+XuCyPTnc+BOSrU26tJsX0P9BYorwySiEGxGanBNATdVL4NdUCAwEAAaOBnDCB" + + "mTAJBgNVHRMEAjAAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQgwKjAoBggrBgEFBQcCARYcaHR0" + + "cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTARBglghkgBhvhCAQEEBAMCB4AwMwYDVR0fBCwwKjAo" + + "oCagJIYiaHR0cDovL2NybC52ZXJpc2lnbi5jb20vY2xhc3MxLmNybDANBgkqhkiG9w0BAQQFAAOB" + + "gQBC8yIIdVGpFTf8/YiL14cMzcmL0nIRm4kGR3U59z7UtcXlfNXXJ8MyaeI/BnXwG/gD5OKYqW6R" + + "yca9vZOxf1uoTBl82gInk865ED3Tej6msCqFzZffnSUQvOIeqLxxDlqYRQ6PmW2nAnZeyjcnbI5Y" + + "syQSM2fmo7n6qJFP+GbFezGCAkUwggJBAgEBMIHhMIHMMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5j" + + "LjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWdu" + + "LmNvbS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIEJ5IFJlZi4sTElBQi5MVEQoYyk5ODFIMEYGA1UE" + + "AxM/VmVyaVNpZ24gQ2xhc3MgMSBDQSBJbmRpdmlkdWFsIFN1YnNjcmliZXItUGVyc29uYSBOb3Qg" + + "VmFsaWRhdGVkAhAW25/9Rtc6aQ+irD9NW8MsMAkGBSsOAwIaBQCggbowGAYJKoZIhvcNAQkDMQsG" + + "CSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDAxMDAyMTczNTE4WjAjBgkqhkiG9w0BCQQxFgQU" + + "gZjSaBEY2oxGvlQUIMnxSXhivK8wWwYJKoZIhvcNAQkPMU4wTDAKBggqhkiG9w0DBzAOBggqhkiG" + + "9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwBwYFKw4DAh0w" + + "DQYJKoZIhvcNAQEBBQAEgYAzk+PU91/ZFfoiuKOECjxEh9fDYE2jfDCheBIgh5gdcCo+sS1WQs8O" + + "HreQ9Nop/JdJv1DQMBK6weNBBDoP0EEkRm1XCC144XhXZC82jBZohYmi2WvDbbC//YN58kRMYMyy" + + "srrfn4Z9I+6kTriGXkrpGk9Q0LSGjmG2BIsqiF0dvwAAAAAAAA=="); + + // + // dsaWithSHA1 cert + // + private static readonly byte[] cert7 = Base64.Decode( + "MIIEXAYJKoZIhvcNAQcCoIIETTCCBEkCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + + "SIb3DQEHAaCCAsMwggK/MIIB4AIBADCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7" + + "d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPh" + + "fVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABj" + + "TUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/z" + + "m8Q12PFp/PjOhh+nMA4xDDAKBgNVBAMTA0lEMzAeFw05NzEwMDEwMDAwMDBa" + + "Fw0zODAxMDEwMDAwMDBaMA4xDDAKBgNVBAMTA0lEMzCB8DCBpwYFKw4DAhsw" + + "gZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULj" + + "w3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FE" + + "WA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3" + + "SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nA0QAAkEAkYkXLYMtGVGWj9OnzjPn" + + "sB9sefSRPrVegZJCZbpW+Iv0/1RP1u04pHG9vtRpIQLjzUiWvLMU9EKQTThc" + + "eNMmWDCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxg" + + "Y61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/Q" + + "F4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jH" + + "SqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nAy8AMCwC" + + "FBY3dBSdeprGcqpr6wr3xbG+6WW+AhRMm/facKJNxkT3iKgJbp7R8Xd3QTGC" + + "AWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAY" + + "BgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMjA1" + + "MjQyMzEzMDdaMCMGCSqGSIb3DQEJBDEWBBS4WMsoJhf7CVbZYCFcjoTRzPkJ" + + "xjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61T" + + "X5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BU" + + "j+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqji" + + "jUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVALID" + + "dt+MHwawrDrwsO1Z6sXBaaJsAhRaKssrpevmLkbygKPV07XiAKBG02Zvb2Jh" + + "cg=="); + + // + // testcrl.pem + // + private static readonly byte[] crl1 = Base64.Decode( + "MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT" + + "F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy" + + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw" + + "MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw" + + "MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw" + + "MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw" + + "MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw" + + "MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw" + + "MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw" + + "NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw" + + "NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF" + + "AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ" + + "wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt" + + "JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v"); + + // + // ecdsa cert with extra octet string. + // // private static readonly byte[] oldEcdsa = Base64.Decode( // "MIICljCCAkCgAwIBAgIBATALBgcqhkjOPQQBBQAwgY8xCzAJBgNVBAYTAkFVMSgwJ" // + "gYDVQQKEx9UaGUgTGVnaW9uIG9mIHRoZSBCb3VuY3kgQ2FzdGxlMRIwEAYDVQQHEw" @@ -256,703 +256,703 @@ namespace Org.BouncyCastle.Tests // + "CwYHKoZIzj0EAQUAA0MAMEACHnz6t4UNoVROp74ma4XNDjjGcjaqiIWPZLK8Bdw3G" // + "QIeLZ4j3a6ividZl344UH+UPUE7xJxlYGuy7ejTsqRR"); - private static readonly byte[] uncompressedPtEC = Base64.Decode( - "MIIDKzCCAsGgAwIBAgICA+kwCwYHKoZIzj0EAQUAMGYxCzAJBgNVBAYTAkpQ" - + "MRUwEwYDVQQKEwxuaXRlY2guYWMuanAxDjAMBgNVBAsTBWFpbGFiMQ8wDQYD" - + "VQQDEwZ0ZXN0Y2ExHzAdBgkqhkiG9w0BCQEWEHRlc3RjYUBsb2NhbGhvc3Qw" - + "HhcNMDExMDEzMTE1MzE3WhcNMjAxMjEyMTE1MzE3WjBmMQswCQYDVQQGEwJK" - + "UDEVMBMGA1UEChMMbml0ZWNoLmFjLmpwMQ4wDAYDVQQLEwVhaWxhYjEPMA0G" - + "A1UEAxMGdGVzdGNhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0Y2FAbG9jYWxob3N0" - + "MIIBczCCARsGByqGSM49AgEwggEOAgEBMDMGByqGSM49AQECKEdYWnajFmnZ" - + "tzrukK2XWdle2v+GsD9l1ZiR6g7ozQDbhFH/bBiMDQcwVAQoJ5EQKrI54/CT" - + "xOQ2pMsd/fsXD+EX8YREd8bKHWiLz8lIVdD5cBNeVwQoMKSc6HfI7vKZp8Q2" - + "zWgIFOarx1GQoWJbMcSt188xsl30ncJuJT2OoARRBAqJ4fD+q6hbqgNSjTQ7" - + "htle1KO3eiaZgcJ8rrnyN8P+5A8+5K+H9aQ/NbBR4Gs7yto5PXIUZEUgodHA" - + "TZMSAcSq5ZYt4KbnSYaLY0TtH9CqAigEwZ+hglbT21B7ZTzYX2xj0x+qooJD" - + "hVTLtIPaYJK2HrMPxTw6/zfrAgEPA1IABAnvfFcFDgD/JicwBGn6vR3N8MIn" - + "mptZf/mnJ1y649uCF60zOgdwIyI7pVSxBFsJ7ohqXEHW0x7LrGVkdSEiipiH" - + "LYslqh3xrqbAgPbl93GUo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB" - + "/wQEAwIBxjAdBgNVHQ4EFgQUAEo62Xm9H6DcsE0zUDTza4BRG90wCwYHKoZI" - + "zj0EAQUAA1cAMFQCKAQsCHHSNOqfJXLgt3bg5+k49hIBGVr/bfG0B9JU3rNt" - + "Ycl9Y2zfRPUCKAK2ccOQXByAWfsasDu8zKHxkZv7LVDTFjAIffz3HaCQeVhD" - + "z+fauEg="); - - private static readonly byte[] keyUsage = Base64.Decode( - "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE" - + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50" - + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs" - + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp" - + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0" - + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa" - + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV" - + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw" - + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50" - + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50" - + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL" - + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv" - + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV" - + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173" - + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw" - + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50" - + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff" - + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE" - + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50" - + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD" - + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D" - + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx" - + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW" - + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG" - + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI" - + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ" - + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU" - + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE" - + "PHayXOw="); - - private static readonly byte[] nameCert = Base64.Decode( - "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE"+ - "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg"+ - "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0"+ - "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I"+ - "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4"+ - "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ"+ - "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug"+ - "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps"+ - "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z"+ - "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD"+ - "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k"+ - "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu"+ - "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1"+ - "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0"+ - "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG"+ - "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi"+ - "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT"+ - "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB"+ - "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3"+ - "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg"+ - "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs"+ - "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l"); - - private static readonly byte[] probSelfSignedCert = Base64.Decode( - "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF" - + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV" - + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy" - + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT" - + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB" - + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m" - + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt" - + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB" - + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU" - + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB" - + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0" - + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" - + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9" - + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/" - + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs="); - - - private static readonly byte[] gost34102001base = Base64.Decode( - "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G" - + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv" - + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw" - + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2" - + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK" - + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0" - + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA" - + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+" - + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA" - + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb" - + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA=="); - - private static readonly byte[] gost341094base = Base64.Decode( - "MIICDzCCAbwCEBcxKsIb0ghYvAQeUjfQdFAwCgYGKoUDAgIEBQAwaTEdMBsG" - + "A1UEAwwUR29zdFIzNDEwLTk0IGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1By" - + "bzELMAkGA1UEBhMCUlUxJzAlBgkqhkiG9w0BCQEWGEdvc3RSMzQxMC05NEBl" - + "eGFtcGxlLmNvbTAeFw0wNTAyMDMxNTE2NTFaFw0xNTAyMDMxNTE2NTFaMGkx" - + "HTAbBgNVBAMMFEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlw" - + "dG9Qcm8xCzAJBgNVBAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAt" - + "OTRAZXhhbXBsZS5jb20wgaUwHAYGKoUDAgIUMBIGByqFAwICIAIGByqFAwIC" - + "HgEDgYQABIGAu4Rm4XmeWzTYLIB/E6gZZnFX/oxUJSFHbzALJ3dGmMb7R1W+" - + "t7Lzk2w5tUI3JoTiDRCKJA4fDEJNKzsRK6i/ZjkyXJSLwaj+G2MS9gklh8x1" - + "G/TliYoJgmjTXHemD7aQEBON4z58nJHWrA0ILD54wbXCtrcaqCqLRYGTMjJ2" - + "+nswCgYGKoUDAgIEBQADQQBxKNhOmjgz/i5CEgLOyKyz9pFGkDcaymsWYQWV" - + "v7CZ0pTM8IzMzkUBW3GHsUjCFpanFZDfg2zuN+3kT+694n9B"); - - private static readonly byte[] gost341094A = Base64.Decode( - "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOZGVmYXVsdDM0MTAtOTQx" - + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1vbGExDDAKBgNVBAgT" - + "A01FTDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" - + "MzExNTdaFw0wNjAzMjkxMzExNTdaMIGBMRcwFQYDVQQDEw5kZWZhdWx0MzQxMC05NDENMAsGA1UE" - + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLW9sYTEMMAoGA1UECBMDTUVMMQsw" - + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" - + "hQMCAiACBgcqhQMCAh4BA4GEAASBgIQACDLEuxSdRDGgdZxHmy30g/DUYkRxO9Mi/uSHX5NjvZ31" - + "b7JMEMFqBtyhql1HC5xZfUwZ0aT3UnEFDfFjLP+Bf54gA+LPkQXw4SNNGOj+klnqgKlPvoqMGlwa" - + "+hLPKbS561WpvB2XSTgbV+pqqXR3j6j30STmybelEV3RdS2Now8wDTALBgNVHQ8EBAMCB4AwCgYG" - + "KoUDAgIEBQADQQBCFy7xWRXtNVXflKvDs0pBdBuPzjCMeZAXVxK8vUxsxxKu76d9CsvhgIFknFRi" - + "wWTPiZenvNoJ4R1uzeX+vREm"); - - private static readonly byte[] gost341094B = Base64.Decode( - "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOcGFyYW0xLTM0MTAtOTQx" - + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNVBAgT" - + "A01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" - + "MzEzNTZaFw0wNjAzMjkxMzEzNTZaMIGBMRcwFQYDVQQDEw5wYXJhbTEtMzQxMC05NDENMAsGA1UE" - + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMDTWVsMQsw" - + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" - + "hQMCAiADBgcqhQMCAh4BA4GEAASBgEa+AAcZmijWs1M9x5Pn9efE8D9ztG1NMoIt0/hNZNqln3+j" - + "lMZjyqPt+kTLIjtmvz9BRDmIDk6FZz+4LhG2OTL7yGpWfrMxMRr56nxomTN9aLWRqbyWmn3brz9Y" - + "AUD3ifnwjjIuW7UM84JNlDTOdxx0XRUfLQIPMCXe9cO02Xskow8wDTALBgNVHQ8EBAMCB4AwCgYG" - + "KoUDAgIEBQADQQBzFcnuYc/639OTW+L5Ecjw9KxGr+dwex7lsS9S1BUgKa3m1d5c+cqI0B2XUFi5" - + "4iaHHJG0dCyjtQYLJr0OZjRw"); - - private static readonly byte[] gost34102001A = Base64.Decode( - "MIICCzCCAbigAwIBAgIBATAKBgYqhQMCAgMFADCBhDEaMBgGA1UEAxMRZGVmYXVsdC0zNDEwLTIw" - + "MDExDTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNV" - + "BAgTA01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAz" - + "MjkxMzE4MzFaFw0wNjAzMjkxMzE4MzFaMIGEMRowGAYDVQQDExFkZWZhdWx0LTM0MTAtMjAwMTEN" - + "MAsGA1UEChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMD" - + "TWVsMQswCQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MGMwHAYGKoUDAgIT" - + "MBIGByqFAwICIwEGByqFAwICHgEDQwAEQG/4c+ZWb10IpeHfmR+vKcbpmSOClJioYmCVgnojw0Xn" - + "ned0KTg7TJreRUc+VX7vca4hLQaZ1o/TxVtfEApK/O6jDzANMAsGA1UdDwQEAwIHgDAKBgYqhQMC" - + "AgMFAANBAN8y2b6HuIdkD3aWujpfQbS1VIA/7hro4vLgDhjgVmev/PLzFB8oTh3gKhExpDo82IEs" - + "ZftGNsbbyp1NFg7zda0="); - - private static readonly byte[] gostCA1 = Base64.Decode( - "MIIDNDCCAuGgAwIBAgIQZLcKDcWcQopF+jp4p9jylDAKBgYqhQMCAgQFADBm" - + "MQswCQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MRcwFQYDVQQKEw5PT08g" - + "Q3J5cHRvLVBybzEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFzAVBgNVBAMTDkNQ" - + "IENTUCBUZXN0IENBMB4XDTAyMDYwOTE1NTIyM1oXDTA5MDYwOTE1NTkyOVow" - + "ZjELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEXMBUGA1UEChMOT09P" - + "IENyeXB0by1Qcm8xFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5D" - + "UCBDU1AgVGVzdCBDQTCBpTAcBgYqhQMCAhQwEgYHKoUDAgIgAgYHKoUDAgIe" - + "AQOBhAAEgYAYglywKuz1nMc9UiBYOaulKy53jXnrqxZKbCCBSVaJ+aCKbsQm" - + "glhRFrw6Mwu8Cdeabo/ojmea7UDMZd0U2xhZFRti5EQ7OP6YpqD0alllo7za" - + "4dZNXdX+/ag6fOORSLFdMpVx5ganU0wHMPk67j+audnCPUj/plbeyccgcdcd" - + "WaOCASIwggEeMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" - + "DgQWBBTe840gTo4zt2twHilw3PD9wJaX0TCBygYDVR0fBIHCMIG/MDygOqA4" - + "hjYtaHR0cDovL2ZpZXdhbGwvQ2VydEVucm9sbC9DUCUyMENTUCUyMFRlc3Ql" - + "MjBDQSgzKS5jcmwwRKBCoECGPmh0dHA6Ly93d3cuY3J5cHRvcHJvLnJ1L0Nl" - + "cnRFbnJvbGwvQ1AlMjBDU1AlMjBUZXN0JTIwQ0EoMykuY3JsMDmgN6A1hjMt" - + "ZmlsZTovL1xcZmlld2FsbFxDZXJ0RW5yb2xsXENQIENTUCBUZXN0IENBKDMp" - + "LmNybC8wEgYJKwYBBAGCNxUBBAUCAwMAAzAKBgYqhQMCAgQFAANBAIJi7ni7" - + "9rwMR5rRGTFftt2k70GbqyUEfkZYOzrgdOoKiB4IIsIstyBX0/ne6GsL9Xan" - + "G2IN96RB7KrowEHeW+k="); - - private static readonly byte[] gostCA2 = Base64.Decode( - "MIIC2DCCAoWgAwIBAgIQe9ZCugm42pRKNcHD8466zTAKBgYqhQMCAgMFADB+" - + "MRowGAYJKoZIhvcNAQkBFgtzYmFAZGlndC5ydTELMAkGA1UEBhMCUlUxDDAK" - + "BgNVBAgTA01FTDEUMBIGA1UEBxMLWW9zaGthci1PbGExDTALBgNVBAoTBERp" - + "Z3QxDzANBgNVBAsTBkNyeXB0bzEPMA0GA1UEAxMGc2JhLUNBMB4XDTA0MDgw" - + "MzEzMzE1OVoXDTE0MDgwMzEzNDAxMVowfjEaMBgGCSqGSIb3DQEJARYLc2Jh" - + "QGRpZ3QucnUxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNNRUwxFDASBgNVBAcT" - + "C1lvc2hrYXItT2xhMQ0wCwYDVQQKEwREaWd0MQ8wDQYDVQQLEwZDcnlwdG8x" - + "DzANBgNVBAMTBnNiYS1DQTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMC" - + "Ah4BA0MABEDMSy10CuOH+i8QKG2UWA4XmCt6+BFrNTZQtS6bOalyDY8Lz+G7" - + "HybyipE3PqdTB4OIKAAPsEEeZOCZd2UXGQm5o4HaMIHXMBMGCSsGAQQBgjcU" - + "AgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" - + "DgQWBBRJJl3LcNMxkZI818STfoi3ng1xoDBxBgNVHR8EajBoMDGgL6Athito" - + "dHRwOi8vc2JhLmRpZ3QubG9jYWwvQ2VydEVucm9sbC9zYmEtQ0EuY3JsMDOg" - + "MaAvhi1maWxlOi8vXFxzYmEuZGlndC5sb2NhbFxDZXJ0RW5yb2xsXHNiYS1D" - + "QS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwCgYGKoUDAgIDBQADQQA+BRJHbc/p" - + "q8EYl6iJqXCuR+ozRmH7hPAP3c4KqYSC38TClCgBloLapx/3/WdatctFJW/L" - + "mcTovpq088927shE"); - - private static readonly byte[] inDirectCrl = Base64.Decode( - "MIIdXjCCHMcCAQEwDQYJKoZIhvcNAQEFBQAwdDELMAkGA1UEBhMCREUxHDAaBgNV" - +"BAoUE0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0" - +"MS4wDAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBO" - +"Fw0wNjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIbfzB+AgQvrj/pFw0wMzA3" - +"MjIwNTQxMjhaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" - +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" - +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+oXDTAzMDcyMjA1NDEyOFowZzBlBgNV" - +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" - +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" - +"UE4wfgIEL64/5xcNMDQwNDA1MTMxODE3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" - +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" - +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/oFw0wNDA0" - +"MDUxMzE4MTdaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" - +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" - +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+UXDTAzMDExMzExMTgxMVowZzBlBgNV" - +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" - +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" - +"UE4wfgIEL64/5hcNMDMwMTEzMTExODExWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" - +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" - +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/jFw0wMzAx" - +"MTMxMTI2NTZaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" - +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" - +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+QXDTAzMDExMzExMjY1NlowZzBlBgNV" - +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" - +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" - +"UE4wfgIEL64/4hcNMDQwNzEzMDc1ODM4WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" - +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" - +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/eFw0wMzAy" - +"MTcwNjMzMjVaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" - +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" - +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP98XDTAzMDIxNzA2MzMyNVowZzBlBgNV" - +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" - +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" - +"UE4wfgIEL64/0xcNMDMwMjE3MDYzMzI1WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" - +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" - +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/dFw0wMzAx" - +"MTMxMTI4MTRaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" - +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" - +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP9cXDTAzMDExMzExMjcwN1owZzBlBgNV" - +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" - +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" - +"UE4wfgIEL64/2BcNMDMwMTEzMTEyNzA3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" - +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" - +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/VFw0wMzA0" - +"MzAxMjI3NTNaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" - +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" - +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP9YXDTAzMDQzMDEyMjc1M1owZzBlBgNV" - +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" - +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" - +"UE4wfgIEL64/xhcNMDMwMjEyMTM0NTQwWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" - +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" - +"BgEKBxQTATEwGAYDVQQDFBFUVEMgVGVzdCBDQSAxMTpQTjCBkAIEL64/xRcNMDMw" - +"MjEyMTM0NTQwWjB5MHcGA1UdHQEB/wRtMGukaTBnMQswCQYDVQQGEwJERTEcMBoG" - +"A1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEQMA4GA1UECxQHVGVsZVNlYzEoMAwG" - +"BwKCBgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNTpQTjB+AgQvrj/CFw0w" - +"MzAyMTIxMzA5MTZaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRww" - +"GgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNV" - +"BAMUEVRUQyBUZXN0IENBIDExOlBOMIGQAgQvrj/BFw0wMzAyMTIxMzA4NDBaMHkw" - +"dwYDVR0dAQH/BG0wa6RpMGcxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2No" - +"ZSBUZWxla29tIEFHMRAwDgYDVQQLFAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAY" - +"BgNVBAMUEVNpZ0cgVGVzdCBDQSA1OlBOMH4CBC+uP74XDTAzMDIxNzA2MzcyNVow" - +"ZzBlBgNVHR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRz" - +"Y2hlIFRlbGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRVFRDIFRlc3Qg" - +"Q0EgMTE6UE4wgZACBC+uP70XDTAzMDIxNzA2MzcyNVoweTB3BgNVHR0BAf8EbTBr" - +"pGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcx" - +"EDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBU" - +"ZXN0IENBIDU6UE4wgZACBC+uP7AXDTAzMDIxMjEzMDg1OVoweTB3BgNVHR0BAf8E" - +"bTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20g" - +"QUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2ln" - +"RyBUZXN0IENBIDU6UE4wgZACBC+uP68XDTAzMDIxNzA2MzcyNVoweTB3BgNVHR0B" - +"Af8EbTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVr" - +"b20gQUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQR" - +"U2lnRyBUZXN0IENBIDU6UE4wfgIEL64/kxcNMDMwNDEwMDUyNjI4WjBnMGUGA1Ud" - +"HQEB/wRbMFmkVzBVMQswCQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVs" - +"ZWtvbSBBRzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFUVEMgVGVzdCBDQSAxMTpQ" - +"TjCBkAIEL64/khcNMDMwNDEwMDUyNjI4WjB5MHcGA1UdHQEB/wRtMGukaTBnMQsw" - +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEQMA4GA1UE" - +"CxQHVGVsZVNlYzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0Eg" - +"NTpQTjB+AgQvrj8/Fw0wMzAyMjYxMTA0NDRaMGcwZQYDVR0dAQH/BFswWaRXMFUx" - +"CzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYH" - +"AoIGAQoHFBMBMTAYBgNVBAMUEVRUQyBUZXN0IENBIDExOlBOMIGQAgQvrj8+Fw0w" - +"MzAyMjYxMTA0NDRaMHkwdwYDVR0dAQH/BG0wa6RpMGcxCzAJBgNVBAYTAkRFMRww" - +"GgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMRAwDgYDVQQLFAdUZWxlU2VjMSgw" - +"DAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cgVGVzdCBDQSA1OlBOMH4CBC+uPs0X" - +"DTAzMDUyMDA1MjczNlowZzBlBgNVHR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUx" - +"HDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgG" - +"A1UEAxQRVFRDIFRlc3QgQ0EgMTE6UE4wgZACBC+uPswXDTAzMDUyMDA1MjczNlow" - +"eTB3BgNVHR0BAf8EbTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRz" - +"Y2hlIFRlbGVrb20gQUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwEx" - +"MBgGA1UEAxQRU2lnRyBUZXN0IENBIDY6UE4wfgIEL64+PBcNMDMwNjE3MTAzNDE2" - +"WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQswCQYDVQQGEwJERTEcMBoGA1UEChQTRGV1" - +"dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFUVEMgVGVz" - +"dCBDQSAxMTpQTjCBkAIEL64+OxcNMDMwNjE3MTAzNDE2WjB5MHcGA1UdHQEB/wRt" - +"MGukaTBnMQswCQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBB" - +"RzEQMA4GA1UECxQHVGVsZVNlYzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFTaWdH" - +"IFRlc3QgQ0EgNjpQTjCBkAIEL64+OhcNMDMwNjE3MTAzNDE2WjB5MHcGA1UdHQEB" - +"/wRtMGukaTBnMQswCQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtv" - +"bSBBRzEQMA4GA1UECxQHVGVsZVNlYzEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFT" - +"aWdHIFRlc3QgQ0EgNjpQTjB+AgQvrj45Fw0wMzA2MTcxMzAxMDBaMGcwZQYDVR0d" - +"AQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxl" - +"a29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVRUQyBUZXN0IENBIDExOlBO" - +"MIGQAgQvrj44Fw0wMzA2MTcxMzAxMDBaMHkwdwYDVR0dAQH/BG0wa6RpMGcxCzAJ" - +"BgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMRAwDgYDVQQL" - +"FAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cgVGVzdCBDQSA2" - +"OlBOMIGQAgQvrj43Fw0wMzA2MTcxMzAxMDBaMHkwdwYDVR0dAQH/BG0wa6RpMGcx" - +"CzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMRAwDgYD" - +"VQQLFAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cgVGVzdCBD" - +"QSA2OlBOMIGQAgQvrj42Fw0wMzA2MTcxMzAxMDBaMHkwdwYDVR0dAQH/BG0wa6Rp" - +"MGcxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMRAw" - +"DgYDVQQLFAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cgVGVz" - +"dCBDQSA2OlBOMIGQAgQvrj4zFw0wMzA2MTcxMDM3NDlaMHkwdwYDVR0dAQH/BG0w" - +"a6RpMGcxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFH" - +"MRAwDgYDVQQLFAdUZWxlU2VjMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEVNpZ0cg" - +"VGVzdCBDQSA2OlBOMH4CBC+uPjEXDTAzMDYxNzEwNDI1OFowZzBlBgNVHR0BAf8E" - +"WzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20g" - +"QUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRVFRDIFRlc3QgQ0EgMTE6UE4wgZAC" - +"BC+uPjAXDTAzMDYxNzEwNDI1OFoweTB3BgNVHR0BAf8EbTBrpGkwZzELMAkGA1UE" - +"BhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxEDAOBgNVBAsUB1Rl" - +"bGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDY6UE4w" - +"gZACBC+uPakXDTAzMTAyMjExMzIyNFoweTB3BgNVHR0BAf8EbTBrpGkwZzELMAkG" - +"A1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxEDAOBgNVBAsU" - +"B1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDY6" - +"UE4wgZACBC+uPLIXDTA1MDMxMTA2NDQyNFoweTB3BgNVHR0BAf8EbTBrpGkwZzEL" - +"MAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxEDAOBgNV" - +"BAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENB" - +"IDY6UE4wgZACBC+uPKsXDTA0MDQwMjA3NTQ1M1oweTB3BgNVHR0BAf8EbTBrpGkw" - +"ZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcxEDAO" - +"BgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0" - +"IENBIDY6UE4wgZACBC+uOugXDTA1MDEyNzEyMDMyNFoweTB3BgNVHR0BAf8EbTBr" - +"pGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20gQUcx" - +"EDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBU" - +"ZXN0IENBIDY6UE4wgZACBC+uOr4XDTA1MDIxNjA3NTcxNloweTB3BgNVHR0BAf8E" - +"bTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVrb20g" - +"QUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2ln" - +"RyBUZXN0IENBIDY6UE4wgZACBC+uOqcXDTA1MDMxMDA1NTkzNVoweTB3BgNVHR0B" - +"Af8EbTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRlbGVr" - +"b20gQUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQR" - +"U2lnRyBUZXN0IENBIDY6UE4wgZACBC+uOjwXDTA1MDUxMTEwNDk0NloweTB3BgNV" - +"HR0BAf8EbTBrpGkwZzELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" - +"bGVrb20gQUcxEDAOBgNVBAsUB1RlbGVTZWMxKDAMBgcCggYBCgcUEwExMBgGA1UE" - +"AxQRU2lnRyBUZXN0IENBIDY6UE4wgaoCBC+sbdUXDTA1MTExMTEwMDMyMVowgZIw" - +"gY8GA1UdHQEB/wSBhDCBgaR/MH0xCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0" - +"c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLFBZQcm9kdWt0emVudHJ1bSBUZWxlU2Vj" - +"MS8wDAYHAoIGAQoHFBMBMTAfBgNVBAMUGFRlbGVTZWMgUEtTIFNpZ0cgQ0EgMTpQ" - +"TjCBlQIEL64uaBcNMDYwMTIzMTAyNTU1WjB+MHwGA1UdHQEB/wRyMHCkbjBsMQsw" - +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEWMBQGA1UE" - +"CxQNWmVudHJhbGUgQm9ubjEnMAwGBwKCBgEKBxQTATEwFwYDVQQDFBBUVEMgVGVz" - +"dCBDQSA5OlBOMIGVAgQvribHFw0wNjA4MDEwOTQ4NDRaMH4wfAYDVR0dAQH/BHIw" - +"cKRuMGwxCzAJBgNVBAYTAkRFMRwwGgYDVQQKFBNEZXV0c2NoZSBUZWxla29tIEFH" - +"MRYwFAYDVQQLFA1aZW50cmFsZSBCb25uMScwDAYHAoIGAQoHFBMBMTAXBgNVBAMU" - +"EFRUQyBUZXN0IENBIDk6UE6ggZswgZgwCwYDVR0UBAQCAhEMMB8GA1UdIwQYMBaA" - +"FANbyNumDI9545HwlCF26NuOJC45MA8GA1UdHAEB/wQFMAOEAf8wVwYDVR0SBFAw" - +"ToZMbGRhcDovL3Brc2xkYXAudHR0Yy5kZS9vdT1ULVRlbGVTZWMgVGVzdCBESVIg" - +"ODpQTixvPURldXRzY2hlIFRlbGVrb20gQUcsYz1kZTANBgkqhkiG9w0BAQUFAAOB" - +"gQBewL5gLFHpeOWO07Vk3Gg7pRDuAlvaovBH4coCyCWpk5jEhUfFSYEDuaQB7do4" - +"IlJmeTHvkI0PIZWJ7bwQ2PVdipPWDx0NVwS/Cz5jUKiS3BbAmZQZOueiKLFpQq3A" - +"b8aOHA7WHU4078/1lM+bgeu33Ln1CGykEbmSjA/oKPi/JA=="); - - private static readonly byte[] directCRL = Base64.Decode( - "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" - +"MQ=="); - - private static readonly byte[] pkcs7CrlProblem = Base64.Decode( - "MIIwSAYJKoZIhvcNAQcCoIIwOTCCMDUCAQExCzAJBgUrDgMCGgUAMAsGCSqG" - + "SIb3DQEHAaCCEsAwggP4MIIC4KADAgECAgF1MA0GCSqGSIb3DQEBBQUAMEUx" - + "CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQD" - + "ExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUwHhcNMDQxMjAyMjEyNTM5WhcNMDYx" - + "MjMwMjEyNTM5WjBMMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMR2VvVHJ1c3Qg" - + "SW5jMSYwJAYDVQQDEx1HZW9UcnVzdCBBZG9iZSBPQ1NQIFJlc3BvbmRlcjCB" - + "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4gnNYhtw7U6QeVXZODnGhHMj" - + "+OgZ0DB393rEk6a2q9kq129IA2e03yKBTfJfQR9aWKc2Qj90dsSqPjvTDHFG" - + "Qsagm2FQuhnA3fb1UWhPzeEIdm6bxDsnQ8nWqKqxnWZzELZbdp3I9bBLizIq" - + "obZovzt60LNMghn/unvvuhpeVSsCAwEAAaOCAW4wggFqMA4GA1UdDwEB/wQE" - + "AwIE8DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8BAgEwgcYwgZAGCCsG" - + "AQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMgYmVlbiBpc3N1ZWQg" - + "aW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENyZWRlbnRpYWxzIENQ" - + "UyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNl" - + "cy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jl" - + "c291cmNlcy9jcHMwEwYDVR0lBAwwCgYIKwYBBQUHAwkwOgYDVR0fBDMwMTAv" - + "oC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5j" - + "cmwwHwYDVR0jBBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwDQYJKoZIhvcN" - + "AQEFBQADggEBAENJf1BD7PX5ivuaawt90q1OGzXpIQL/ClzEeFVmOIxqPc1E" - + "TFRq92YuxG5b6+R+k+tGkmCwPLcY8ipg6ZcbJ/AirQhohzjlFuT6YAXsTfEj" - + "CqEZfWM2sS7crK2EYxCMmKE3xDfPclYtrAoz7qZvxfQj0TuxHSstHZv39wu2" - + "ZiG1BWiEcyDQyTgqTOXBoZmfJtshuAcXmTpgkrYSrS37zNlPTGh+pMYQ0yWD" - + "c8OQRJR4OY5ZXfdna01mjtJTOmj6/6XPoLPYTq2gQrc2BCeNJ4bEhLb7sFVB" - + "PbwPrpzTE/HRbQHDrzj0YimDxeOUV/UXctgvYwHNtEkcBLsOm/uytMYwggSh" - + "MIIDiaADAgECAgQ+HL0oMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVT" - + "MSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UE" - + "CxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3Qg" - + "Q0EwHhcNMDMwMTA4MjMzNzIzWhcNMjMwMTA5MDAwNzIzWjBpMQswCQYDVQQG" - + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" - + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" - + "b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE9UhPen" - + "ouczU38/nBKIayyZR2d+Dx65rRSI+cMQ2B3w8NWfaQovWTWwzGypTJwVoJ/O" - + "IL+gz1Ti4CBmRT85hjh+nMSOByLGJPYBErA131XqaZCw24U3HuJOB7JCoWoT" - + "aaBm6oCREVkqmwh5WiBELcm9cziLPC/gQxtdswvwrzUaKf7vppLdgUydPVmO" - + "rTE8QH6bkTYG/OJcjdGNJtVcRc+vZT+xqtJilvSoOOq6YEL09BxKNRXO+E4i" - + "Vg+VGMX4lp+f+7C3eCXpgGu91grwxnSUnfMPUNuad85LcIMjjaDKeCBEXDxU" - + "ZPHqojAZn+pMBk0GeEtekt8i0slns3rSAQIDAQABo4IBTzCCAUswEQYJYIZI" - + "AYb4QgEBBAQDAgAHMIGOBgNVHR8EgYYwgYMwgYCgfqB8pHoweDELMAkGA1UE" - + "BhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMR0w" - + "GwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UEAxMNQWRvYmUg" - + "Um9vdCBDQTENMAsGA1UEAxMEQ1JMMTArBgNVHRAEJDAigA8yMDAzMDEwODIz" - + "MzcyM1qBDzIwMjMwMTA5MDAwNzIzWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgw" - + "FoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFIK3OEqTqpsQ74C7" - + "2VTi8Q/7gJzeMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjYu" - + "MDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQAy2p9DdcH6b8lv26sdNjc+" - + "vGEZNrcCPB0jWZhsnu5NhedUyCAfp9S74r8Ad30ka3AvXME6dkm10+AjhCpx" - + "aiLzwScpmBX2NZDkBEzDjbyfYRzn/SSM0URDjBa6m02l1DUvvBHOvfdRN42f" - + "kOQU8Rg/vulZEjX5M5LznuDVa5pxm5lLyHHD4bFhCcTl+pHwQjo3fTT5cujN" - + "qmIcIenV9IIQ43sFti1oVgt+fpIsb01yggztVnSynbmrLSsdEF/bJ3Vwj/0d" - + "1+ICoHnlHOX/r2RAUS2em0fbQqV8H8KmSLDXvpJpTaT2KVfFeBEY3IdRyhOy" - + "Yp1PKzK9MaXB+lKrBYjIMIIEyzCCA7OgAwIBAgIEPhy9tTANBgkqhkiG9w0B" - + "AQUFADBpMQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJ" - + "bmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYw" - + "FAYDVQQDEw1BZG9iZSBSb290IENBMB4XDTA0MDExNzAwMDMzOVoXDTE1MDEx" - + "NTA4MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" - + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTCCASIwDQYJKoZI" - + "hvcNAQEBBQADggEPADCCAQoCggEBAKfld+BkeFrnOYW8r9L1WygTDlTdSfrO" - + "YvWS/Z6Ye5/l+HrBbOHqQCXBcSeCpz7kB2WdKMh1FOE4e9JlmICsHerBLdWk" - + "emU+/PDb69zh8E0cLoDfxukF6oVPXj6WSThdSG7H9aXFzRr6S3XGCuvgl+Qw" - + "DTLiLYW+ONF6DXwt3TQQtKReJjOJZk46ZZ0BvMStKyBaeB6DKZsmiIo89qso" - + "13VDZINH2w1KvXg0ygDizoNtbvgAPFymwnsINS1klfQlcvn0x0RJm9bYQXK3" - + "5GNZAgL3M7Lqrld0jMfIUaWvuHCLyivytRuzq1dJ7E8rmidjDEk/G+27pf13" - + "fNZ7vR7M+IkCAwEAAaOCAZ0wggGZMBIGA1UdEwEB/wQIMAYBAf8CAQEwUAYD" - + "VR0gBEkwRzBFBgkqhkiG9y8BAgEwODA2BggrBgEFBQcCARYqaHR0cHM6Ly93" - + "d3cuYWRvYmUuY29tL21pc2MvcGtpL2Nkc19jcC5odG1sMBQGA1UdJQQNMAsG" - + "CSqGSIb3LwEBBTCBsgYDVR0fBIGqMIGnMCKgIKAehhxodHRwOi8vY3JsLmFk" - + "b2JlLmNvbS9jZHMuY3JsMIGAoH6gfKR6MHgxCzAJBgNVBAYTAlVTMSMwIQYD" - + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" - + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0ExDTAL" - + "BgNVBAMTBENSTDEwCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFIK3OEqTqpsQ" - + "74C72VTi8Q/7gJzeMB0GA1UdDgQWBBSrgFnDZYNtHX0TvRnD7BqPDUdqozAZ" - + "BgkqhkiG9n0HQQAEDDAKGwRWNi4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA" - + "PzlZLqIAjrFeEWEs0uC29YyJhkXOE9mf3YSaFGsITF+Gl1j0pajTjyH4R35Q" - + "r3floW2q3HfNzTeZ90Jnr1DhVERD6zEMgJpCtJqVuk0sixuXJHghS/KicKf4" - + "YXJJPx9epuIRF1siBRnznnF90svmOJMXApc0jGnYn3nQfk4kaShSnDaYaeYR" - + "DJKcsiWhl6S5zfwS7Gg8hDeyckhMQKKWnlG1CQrwlSFisKCduoodwRtWgft8" - + "kx13iyKK3sbalm6vnVc+5nufS4vI+TwMXoV63NqYaSroafBWk0nL53zGXPEy" - + "+A69QhzEViJKn2Wgqt5gt++jMMNImbRObIqgfgF1VjCCBUwwggQ0oAMCAQIC" - + "AgGDMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1H" - + "ZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUw" - + "HhcNMDYwMzI0MTU0MjI5WhcNMDkwNDA2MTQ0MjI5WjBzMQswCQYDVQQGEwJV" - + "UzELMAkGA1UECBMCTUExETAPBgNVBAoTCEdlb1RydXN0MR0wGwYDVQQDExRN" - + "YXJrZXRpbmcgRGVwYXJ0bWVudDElMCMGCSqGSIb3DQEJARYWbWFya2V0aW5n" - + "QGdlb3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB" - + "ANmvajTO4XJvAU2nVcLmXeCnAQX7RZt+7+ML3InmqQ3LCGo1weop09zV069/" - + "1x/Nmieol7laEzeXxd2ghjGzwfXafqQEqHn6+vBCvqdNPoSi63fSWhnuDVWp" - + "KVDOYgxOonrXl+Cc43lu4zRSq+Pi5phhrjDWcH74a3/rdljUt4c4GFezFXfa" - + "w2oTzWkxj2cTSn0Szhpr17+p66UNt8uknlhmu4q44Speqql2HwmCEnpLYJrK" - + "W3fOq5D4qdsvsLR2EABLhrBezamLI3iGV8cRHOUTsbTMhWhv/lKfHAyf4XjA" - + "z9orzvPN5jthhIfICOFq/nStTgakyL4Ln+nFAB/SMPkCAwEAAaOCAhYwggIS" - + "MA4GA1UdDwEB/wQEAwIF4DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8B" - + "AgEwgcYwgZAGCCsGAQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMg" - + "YmVlbiBpc3N1ZWQgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENy" - + "ZWRlbnRpYWxzIENQUyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3Qu" - + "Y29tL3Jlc291cmNlcy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2Vv" - + "dHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwOgYDVR0fBDMwMTAvoC2gK4YpaHR0" - + "cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5jcmwwHwYDVR0j" - + "BBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwRAYIKwYBBQUHAQEEODA2MDQG" - + "CCsGAQUFBzABhihodHRwOi8vYWRvYmUtb2NzcC5nZW90cnVzdC5jb20vcmVz" - + "cG9uZGVyMBQGA1UdJQQNMAsGCSqGSIb3LwEBBTA8BgoqhkiG9y8BAQkBBC4w" - + "LAIBAYYnaHR0cDovL2Fkb2JlLXRpbWVzdGFtcC5nZW90cnVzdC5jb20vdHNh" - + "MBMGCiqGSIb3LwEBCQIEBTADAgEBMAwGA1UdEwQFMAMCAQAwDQYJKoZIhvcN" - + "AQEFBQADggEBAAOhy6QxOo+i3h877fvDvTa0plGD2bIqK7wMdNqbMDoSWied" - + "FIcgcBOIm2wLxOjZBAVj/3lDq59q2rnVeNnfXM0/N0MHI9TumHRjU7WNk9e4" - + "+JfJ4M+c3anrWOG3NE5cICDVgles+UHjXetHWql/LlP04+K2ZOLb6LE2xGnI" - + "YyLW9REzCYNAVF+/WkYdmyceHtaBZdbyVAJq0NAJPsfgY1pWcBo31Mr1fpX9" - + "WrXNTYDCqMyxMImJTmN3iI68tkXlNrhweQoArKFqBysiBkXzG/sGKYY6tWKU" - + "pzjLc3vIp/LrXC5zilROes8BSvwu1w9qQrJNcGwo7O4uijoNtyYil1Exgh1Q" - + "MIIdTAIBATBLMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ" - + "bmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUCAgGDMAkGBSsO" - + "AwIaBQCgggxMMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwIwYJKoZIhvcN" - + "AQkEMRYEFP4R6qIdpQJzWyzrqO8X1ZfJOgChMIIMCQYJKoZIhvcvAQEIMYIL" - + "+jCCC/agggZ5MIIGdTCCA6gwggKQMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV" - + "BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9U" - + "cnVzdCBDQSBmb3IgQWRvYmUXDTA2MDQwNDE3NDAxMFoXDTA2MDQwNTE3NDAx" - + "MFowggIYMBMCAgC5Fw0wNTEwMTEyMDM2MzJaMBICAVsXDTA0MTEwNDE1MDk0" - + "MVowEwICALgXDTA1MTIxMjIyMzgzOFowEgIBWhcNMDQxMTA0MTUwOTMzWjAT" - + "AgIA5hcNMDUwODI3MDQwOTM4WjATAgIAtxcNMDYwMTE2MTc1NTEzWjATAgIA" - + "hhcNMDUxMjEyMjIzODU1WjATAgIAtRcNMDUwNzA2MTgzODQwWjATAgIA4BcN" - + "MDYwMzIwMDc0ODM0WjATAgIAgRcNMDUwODAyMjIzMTE1WjATAgIA3xcNMDUx" - + "MjEyMjIzNjUwWjASAgFKFw0wNDExMDQxNTA5MTZaMBICAUQXDTA0MTEwNDE1" - + "MDg1M1owEgIBQxcNMDQxMDAzMDEwMDQwWjASAgFsFw0wNDEyMDYxOTQ0MzFa" - + "MBMCAgEoFw0wNjAzMDkxMjA3MTJaMBMCAgEkFw0wNjAxMTYxNzU1MzRaMBIC" - + "AWcXDTA1MDMxODE3NTYxNFowEwICAVEXDTA2MDEzMTExMjcxMVowEgIBZBcN" - + "MDQxMTExMjI0ODQxWjATAgIA8RcNMDUwOTE2MTg0ODAxWjATAgIBThcNMDYw" - + "MjIxMjAxMDM2WjATAgIAwRcNMDUxMjEyMjIzODE2WjASAgFiFw0wNTAxMTAx" - + "NjE5MzRaMBICAWAXDTA1MDExMDE5MDAwNFowEwICAL4XDTA1MDUxNzE0NTYx" - + "MFowDQYJKoZIhvcNAQEFBQADggEBAEKhRMS3wVho1U3EvEQJZC8+JlUngmZQ" - + "A78KQbHPWNZWFlNvPuf/b0s7Lu16GfNHXh1QAW6Y5Hi1YtYZ3YOPyMd4Xugt" - + "gCdumbB6xtKsDyN5RvTht6ByXj+CYlYqsL7RX0izJZ6mJn4fjMkqzPKNOjb8" - + "kSn5T6rn93BjlATtCE8tPVOM8dnqGccRE0OV59+nDBXc90UMt5LdEbwaUOap" - + "snVB0oLcNm8d/HnlVH6RY5LnDjrT4vwfe/FApZtTecEWsllVUXDjSpwfcfD/" - + "476/lpGySB2otALqzImlA9R8Ok3hJ8dnF6hhQ5Oe6OJMnGYgdhkKbxsKkdib" - + "tTVl3qmH5QAwggLFMIIBrQIBATANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQG" - + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" - + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" - + "b290IENBFw0wNjAxMjcxODMzMzFaFw0wNzAxMjcwMDAwMDBaMIHeMCMCBD4c" - + "vUAXDTAzMDEyMTIzNDY1NlowDDAKBgNVHRUEAwoBBDAjAgQ+HL1BFw0wMzAx" - + "MjEyMzQ3MjJaMAwwCgYDVR0VBAMKAQQwIwIEPhy9YhcNMDMwMTIxMjM0NzQy" - + "WjAMMAoGA1UdFQQDCgEEMCMCBD4cvWEXDTA0MDExNzAxMDg0OFowDDAKBgNV" - + "HRUEAwoBBDAjAgQ+HL2qFw0wNDAxMTcwMTA5MDVaMAwwCgYDVR0VBAMKAQQw" - + "IwIEPhy9qBcNMDQwMTE3MDEzOTI5WjAMMAoGA1UdFQQDCgEEoC8wLTAKBgNV" - + "HRQEAwIBDzAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jANBgkq" - + "hkiG9w0BAQUFAAOCAQEAwtXF9042wG39icUlsotn5tpE3oCusLb/hBpEONhx" - + "OdfEQOq0w5hf/vqaxkcf71etA+KpbEUeSVaHMHRPhx/CmPrO9odE139dJdbt" - + "9iqbrC9iZokFK3h/es5kg73xujLKd7C/u5ngJ4mwBtvhMLjFjF2vJhPKHL4C" - + "IgMwdaUAhrcNzy16v+mw/VGJy3Fvc6oCESW1K9tvFW58qZSNXrMlsuidgunM" - + "hPKG+z0SXVyCqL7pnqKiaGddcgujYGOSY4S938oVcfZeZQEODtSYGlzldojX" - + "C1U1hCK5+tHAH0Ox/WqRBIol5VCZQwJftf44oG8oviYq52aaqSejXwmfT6zb" - + "76GCBXUwggVxMIIFbQoBAKCCBWYwggViBgkrBgEFBQcwAQEEggVTMIIFTzCB" - + "taIWBBS+8EpykfXdl4h3z7m/NZfdkAQQERgPMjAwNjA0MDQyMDIwMTVaMGUw" - + "YzA7MAkGBSsOAwIaBQAEFEb4BuZYkbjBjOjT6VeA/00fBvQaBBT3fTSQniOp" - + "BbHBSkz4xridlX0bsAICAYOAABgPMjAwNjA0MDQyMDIwMTVaoBEYDzIwMDYw" - + "NDA1MDgyMDE1WqEjMCEwHwYJKwYBBQUHMAECBBIEEFqooq/R2WltD7TposkT" - + "BhMwDQYJKoZIhvcNAQEFBQADgYEAMig6lty4b0JDsT/oanfQG5x6jVKPACpp" - + "1UA9SJ0apJJa7LeIdDFmu5C2S/CYiKZm4A4P9cAu0YzgLHxE4r6Op+HfVlAG" - + "6bzUe1P/hi1KCJ8r8wxOZAktQFPSzs85RAZwkHMfB0lP2e/h666Oye+Zf8VH" - + "RaE+/xZ7aswE89HXoumgggQAMIID/DCCA/gwggLgoAMCAQICAXUwDQYJKoZI" - + "hvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" - + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNDEyMDIy" - + "MTI1MzlaFw0wNjEyMzAyMTI1MzlaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK" - + "EwxHZW9UcnVzdCBJbmMxJjAkBgNVBAMTHUdlb1RydXN0IEFkb2JlIE9DU1Ag" - + "UmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiCc1iG3Dt" - + "TpB5Vdk4OcaEcyP46BnQMHf3esSTprar2SrXb0gDZ7TfIoFN8l9BH1pYpzZC" - + "P3R2xKo+O9MMcUZCxqCbYVC6GcDd9vVRaE/N4Qh2bpvEOydDydaoqrGdZnMQ" - + "tlt2ncj1sEuLMiqhtmi/O3rQs0yCGf+6e++6Gl5VKwIDAQABo4IBbjCCAWow" - + "DgYDVR0PAQH/BAQDAgTwMIHlBgNVHSABAf8EgdowgdcwgdQGCSqGSIb3LwEC" - + "ATCBxjCBkAYIKwYBBQUHAgIwgYMagYBUaGlzIGNlcnRpZmljYXRlIGhhcyBi" - + "ZWVuIGlzc3VlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIEFjcm9iYXQgQ3Jl" - + "ZGVudGlhbHMgQ1BTIGxvY2F0ZWQgYXQgaHR0cDovL3d3dy5nZW90cnVzdC5j" - + "b20vcmVzb3VyY2VzL2NwczAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90" - + "cnVzdC5jb20vcmVzb3VyY2VzL2NwczATBgNVHSUEDDAKBggrBgEFBQcDCTA6" - + "BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxz" - + "L2Fkb2JlY2ExLmNybDAfBgNVHSMEGDAWgBSrgFnDZYNtHX0TvRnD7BqPDUdq" - + "ozANBgkqhkiG9w0BAQUFAAOCAQEAQ0l/UEPs9fmK+5prC33SrU4bNekhAv8K" - + "XMR4VWY4jGo9zURMVGr3Zi7Eblvr5H6T60aSYLA8txjyKmDplxsn8CKtCGiH" - + "OOUW5PpgBexN8SMKoRl9YzaxLtysrYRjEIyYoTfEN89yVi2sCjPupm/F9CPR" - + "O7EdKy0dm/f3C7ZmIbUFaIRzINDJOCpM5cGhmZ8m2yG4BxeZOmCSthKtLfvM" - + "2U9MaH6kxhDTJYNzw5BElHg5jlld92drTWaO0lM6aPr/pc+gs9hOraBCtzYE" - + "J40nhsSEtvuwVUE9vA+unNMT8dFtAcOvOPRiKYPF45RX9Rdy2C9jAc20SRwE" - + "uw6b+7K0xjANBgkqhkiG9w0BAQEFAASCAQC7a4yICFGCEMPlJbydK5qLG3rV" - + "sip7Ojjz9TB4nLhC2DgsIHds8jjdq2zguInluH2nLaBCVS+qxDVlTjgbI2cB" - + "TaWS8nglC7nNjzkKAsa8vThA8FZUVXTW0pb74jNJJU2AA27bb4g+4WgunCrj" - + "fpYp+QjDyMmdrJVqRmt5eQN+dpVxMS9oq+NrhOSEhyIb4/rejgNg9wnVK1ms" - + "l5PxQ4x7kpm7+Ua41//owkJVWykRo4T1jo4eHEz1DolPykAaKie2VKH/sMqR" - + "Spjh4E5biKJLOV9fKivZWKAXByXfwUbbMsJvz4v/2yVHFy9xP+tqB5ZbRoDK" - + "k8PzUyCprozn+/22oYIPijCCD4YGCyqGSIb3DQEJEAIOMYIPdTCCD3EGCSqG" - + "SIb3DQEHAqCCD2Iwgg9eAgEDMQswCQYFKw4DAhoFADCB+gYLKoZIhvcNAQkQ" - + "AQSggeoEgecwgeQCAQEGAikCMCEwCQYFKw4DAhoFAAQUoT97qeCv3FXYaEcS" - + "gY8patCaCA8CAiMHGA8yMDA2MDQwNDIwMjA1N1owAwIBPAEB/wIIO0yRre3L" - + "8/6ggZCkgY0wgYoxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNl" - + "dHRzMRAwDgYDVQQHEwdOZWVkaGFtMRUwEwYDVQQKEwxHZW9UcnVzdCBJbmMx" - + "EzARBgNVBAsTClByb2R1Y3Rpb24xJTAjBgNVBAMTHGFkb2JlLXRpbWVzdGFt" - + "cC5nZW90cnVzdC5jb22gggzJMIIDUTCCAjmgAwIBAgICAI8wDQYJKoZIhvcN" - + "AQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4x" - + "HjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNTAxMTAwMTI5" - + "MTBaFw0xNTAxMTUwODAwMDBaMIGKMQswCQYDVQQGEwJVUzEWMBQGA1UECBMN" - + "TWFzc2FjaHVzZXR0czEQMA4GA1UEBxMHTmVlZGhhbTEVMBMGA1UEChMMR2Vv" - + "VHJ1c3QgSW5jMRMwEQYDVQQLEwpQcm9kdWN0aW9uMSUwIwYDVQQDExxhZG9i" - + "ZS10aW1lc3RhbXAuZ2VvdHJ1c3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GN" - + "ADCBiQKBgQDRbxJotLFPWQuuEDhKtOMaBUJepGxIvWxeahMbq1DVmqnk88+j" - + "w/5lfPICPzQZ1oHrcTLSAFM7Mrz3pyyQKQKMqUyiemzuG/77ESUNfBNSUfAF" - + "PdtHuDMU8Is8ABVnFk63L+wdlvvDIlKkE08+VTKCRdjmuBVltMpQ6QcLFQzm" - + "AQIDAQABo4GIMIGFMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwuZ2Vv" - + "dHJ1c3QuY29tL2NybHMvYWRvYmVjYTEuY3JsMB8GA1UdIwQYMBaAFKuAWcNl" - + "g20dfRO9GcPsGo8NR2qjMA4GA1UdDwEB/wQEAwIGwDAWBgNVHSUBAf8EDDAK" - + "BggrBgEFBQcDCDANBgkqhkiG9w0BAQUFAAOCAQEAmnyXjdtX+F79Nf0KggTd" - + "6YC2MQD9s09IeXTd8TP3rBmizfM+7f3icggeCGakNfPRmIUMLoa0VM5Kt37T" - + "2X0TqzBWusfbKx7HnX4v1t/G8NJJlT4SShSHv+8bjjU4lUoCmW2oEcC5vXwP" - + "R5JfjCyois16npgcO05ZBT+LLDXyeBijE6qWmwLDfEpLyILzVRmyU4IE7jvm" - + "rgb3GXwDUvd3yQXGRRHbPCh3nj9hBGbuzyt7GnlqnEie3wzIyMG2ET/wvTX5" - + "4BFXKNe7lDLvZj/MXvd3V7gMTSVW0kAszKao56LfrVTgp1VX3UBQYwmQqaoA" - + "UwFezih+jEvjW6cYJo/ErDCCBKEwggOJoAMCAQICBD4cvSgwDQYJKoZIhvcN" - + "AQEFBQAwaTELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMg" - + "SW5jb3Jwb3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEW" - + "MBQGA1UEAxMNQWRvYmUgUm9vdCBDQTAeFw0wMzAxMDgyMzM3MjNaFw0yMzAx" - + "MDkwMDA3MjNaMGkxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0" - + "ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2Vydmlj" - + "ZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA" - + "A4IBDwAwggEKAoIBAQDMT1SE96ei5zNTfz+cEohrLJlHZ34PHrmtFIj5wxDY" - + "HfDw1Z9pCi9ZNbDMbKlMnBWgn84gv6DPVOLgIGZFPzmGOH6cxI4HIsYk9gES" - + "sDXfVeppkLDbhTce4k4HskKhahNpoGbqgJERWSqbCHlaIEQtyb1zOIs8L+BD" - + "G12zC/CvNRop/u+mkt2BTJ09WY6tMTxAfpuRNgb84lyN0Y0m1VxFz69lP7Gq" - + "0mKW9Kg46rpgQvT0HEo1Fc74TiJWD5UYxfiWn5/7sLd4JemAa73WCvDGdJSd" - + "8w9Q25p3zktwgyONoMp4IERcPFRk8eqiMBmf6kwGTQZ4S16S3yLSyWezetIB" - + "AgMBAAGjggFPMIIBSzARBglghkgBhvhCAQEEBAMCAAcwgY4GA1UdHwSBhjCB" - + "gzCBgKB+oHykejB4MQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lz" - + "dGVtcyBJbmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZp" - + "Y2VzMRYwFAYDVQQDEw1BZG9iZSBSb290IENBMQ0wCwYDVQQDEwRDUkwxMCsG" - + "A1UdEAQkMCKADzIwMDMwMTA4MjMzNzIzWoEPMjAyMzAxMDkwMDA3MjNaMAsG" - + "A1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jAd" - + "BgNVHQ4EFgQUgrc4SpOqmxDvgLvZVOLxD/uAnN4wDAYDVR0TBAUwAwEB/zAd" - + "BgkqhkiG9n0HQQAEEDAOGwhWNi4wOjQuMAMCBJAwDQYJKoZIhvcNAQEFBQAD" - + "ggEBADLan0N1wfpvyW/bqx02Nz68YRk2twI8HSNZmGye7k2F51TIIB+n1Lvi" - + "vwB3fSRrcC9cwTp2SbXT4COEKnFqIvPBJymYFfY1kOQETMONvJ9hHOf9JIzR" - + "REOMFrqbTaXUNS+8Ec6991E3jZ+Q5BTxGD++6VkSNfkzkvOe4NVrmnGbmUvI" - + "ccPhsWEJxOX6kfBCOjd9NPly6M2qYhwh6dX0ghDjewW2LWhWC35+kixvTXKC" - + "DO1WdLKduastKx0QX9sndXCP/R3X4gKgeeUc5f+vZEBRLZ6bR9tCpXwfwqZI" - + "sNe+kmlNpPYpV8V4ERjch1HKE7JinU8rMr0xpcH6UqsFiMgwggTLMIIDs6AD" - + "AgECAgQ+HL21MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVTMSMwIQYD" - + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" - + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwHhcN" - + "MDQwMTE3MDAwMzM5WhcNMTUwMTE1MDgwMDAwWjBFMQswCQYDVQQGEwJVUzEW" - + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0Eg" - + "Zm9yIEFkb2JlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp+V3" - + "4GR4Wuc5hbyv0vVbKBMOVN1J+s5i9ZL9nph7n+X4esFs4epAJcFxJ4KnPuQH" - + "ZZ0oyHUU4Th70mWYgKwd6sEt1aR6ZT788Nvr3OHwTRwugN/G6QXqhU9ePpZJ" - + "OF1Ibsf1pcXNGvpLdcYK6+CX5DANMuIthb440XoNfC3dNBC0pF4mM4lmTjpl" - + "nQG8xK0rIFp4HoMpmyaIijz2qyjXdUNkg0fbDUq9eDTKAOLOg21u+AA8XKbC" - + "ewg1LWSV9CVy+fTHREmb1thBcrfkY1kCAvczsuquV3SMx8hRpa+4cIvKK/K1" - + "G7OrV0nsTyuaJ2MMST8b7bul/Xd81nu9Hsz4iQIDAQABo4IBnTCCAZkwEgYD" - + "VR0TAQH/BAgwBgEB/wIBATBQBgNVHSAESTBHMEUGCSqGSIb3LwECATA4MDYG" - + "CCsGAQUFBwIBFipodHRwczovL3d3dy5hZG9iZS5jb20vbWlzYy9wa2kvY2Rz" - + "X2NwLmh0bWwwFAYDVR0lBA0wCwYJKoZIhvcvAQEFMIGyBgNVHR8Egaowgacw" - + "IqAgoB6GHGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Nkcy5jcmwwgYCgfqB8pHow" - + "eDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jw" - + "b3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UE" - + "AxMNQWRvYmUgUm9vdCBDQTENMAsGA1UEAxMEQ1JMMTALBgNVHQ8EBAMCAQYw" - + "HwYDVR0jBBgwFoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFKuA" - + "WcNlg20dfRO9GcPsGo8NR2qjMBkGCSqGSIb2fQdBAAQMMAobBFY2LjADAgSQ" - + "MA0GCSqGSIb3DQEBBQUAA4IBAQA/OVkuogCOsV4RYSzS4Lb1jImGRc4T2Z/d" - + "hJoUawhMX4aXWPSlqNOPIfhHflCvd+Whbarcd83NN5n3QmevUOFUREPrMQyA" - + "mkK0mpW6TSyLG5ckeCFL8qJwp/hhckk/H16m4hEXWyIFGfOecX3Sy+Y4kxcC" - + "lzSMadifedB+TiRpKFKcNphp5hEMkpyyJaGXpLnN/BLsaDyEN7JySExAopae" - + "UbUJCvCVIWKwoJ26ih3BG1aB+3yTHXeLIorextqWbq+dVz7me59Li8j5PAxe" - + "hXrc2phpKuhp8FaTScvnfMZc8TL4Dr1CHMRWIkqfZaCq3mC376Mww0iZtE5s" - + "iqB+AXVWMYIBgDCCAXwCAQEwSzBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN" - + "R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0EgZm9yIEFkb2Jl" - + "AgIAjzAJBgUrDgMCGgUAoIGMMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB" - + "BDAcBgkqhkiG9w0BCQUxDxcNMDYwNDA0MjAyMDU3WjAjBgkqhkiG9w0BCQQx" - + "FgQUp7AnXBqoNcarvO7fMJut1og2U5AwKwYLKoZIhvcNAQkQAgwxHDAaMBgw" - + "FgQU1dH4eZTNhgxdiSABrat6zsPdth0wDQYJKoZIhvcNAQEBBQAEgYCinr/F" - + "rMiQz/MRm9ZD5YGcC0Qo2dRTPd0Aop8mZ4g1xAhKFLnp7lLsjCbkSDpVLDBh" - + "cnCk7CV+3FT5hlvt8OqZlR0CnkSnCswLFhrppiWle6cpxlwGqyAteC8uKtQu" - + "wjE5GtBKLcCOAzQYyyuNZZeB6oCZ+3mPhZ62FxrvvEGJCgAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); - - private static readonly byte[] emptyDNCert = Base64.Decode( - "MIICfTCCAeagAwIBAgIBajANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJVUzEMMAoGA1UEChMD" - + "Q0RXMQkwBwYDVQQLEwAxCTAHBgNVBAcTADEJMAcGA1UECBMAMRowGAYDVQQDExFUZW1wbGFyIFRl" - + "c3QgMTAyNDEiMCAGCSqGSIb3DQEJARYTdGVtcGxhcnRlc3RAY2R3LmNvbTAeFw0wNjA1MjIwNTAw" - + "MDBaFw0xMDA1MjIwNTAwMDBaMHwxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNDRFcxCTAHBgNVBAsT" - + "ADEJMAcGA1UEBxMAMQkwBwYDVQQIEwAxGjAYBgNVBAMTEVRlbXBsYXIgVGVzdCAxMDI0MSIwIAYJ" - + "KoZIhvcNAQkBFhN0ZW1wbGFydGVzdEBjZHcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" - + "gQDH3aJpJBfM+A3d84j5YcU6zEQaQ76u5xO9NSBmHjZykKS2kCcUqPpvVOPDA5WgV22dtKPh+lYV" - + "iUp7wyCVwAKibq8HIbihHceFqMKzjwC639rMoDJ7bi/yzQWz1Zg+075a4FGPlUKn7Yfu89wKkjdW" - + "wDpRPXc/agqBnrx5pJTXzQIDAQABow8wDTALBgNVHQ8EBAMCALEwDQYJKoZIhvcNAQEEBQADgYEA" - + "RRsRsjse3i2/KClFVd6YLZ+7K1BE0WxFyY2bbytkwQJSxvv3vLSuweFUbhNxutb68wl/yW4GLy4b" - + "1QdyswNxrNDXTuu5ILKhRDDuWeocz83aG2KGtr3JlFyr3biWGEyn5WUOE6tbONoQDJ0oPYgI6CAc" - + "EHdUp0lioOCt6UOw7Cs="); - - private static readonly byte[] gostRFC4491_94 = Base64.Decode( - "MIICCzCCAboCECMO42BGlSTOxwvklBgufuswCAYGKoUDAgIEMGkxHTAbBgNVBAMM" + + private static readonly byte[] uncompressedPtEC = Base64.Decode( + "MIIDKzCCAsGgAwIBAgICA+kwCwYHKoZIzj0EAQUAMGYxCzAJBgNVBAYTAkpQ" + + "MRUwEwYDVQQKEwxuaXRlY2guYWMuanAxDjAMBgNVBAsTBWFpbGFiMQ8wDQYD" + + "VQQDEwZ0ZXN0Y2ExHzAdBgkqhkiG9w0BCQEWEHRlc3RjYUBsb2NhbGhvc3Qw" + + "HhcNMDExMDEzMTE1MzE3WhcNMjAxMjEyMTE1MzE3WjBmMQswCQYDVQQGEwJK" + + "UDEVMBMGA1UEChMMbml0ZWNoLmFjLmpwMQ4wDAYDVQQLEwVhaWxhYjEPMA0G" + + "A1UEAxMGdGVzdGNhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0Y2FAbG9jYWxob3N0" + + "MIIBczCCARsGByqGSM49AgEwggEOAgEBMDMGByqGSM49AQECKEdYWnajFmnZ" + + "tzrukK2XWdle2v+GsD9l1ZiR6g7ozQDbhFH/bBiMDQcwVAQoJ5EQKrI54/CT" + + "xOQ2pMsd/fsXD+EX8YREd8bKHWiLz8lIVdD5cBNeVwQoMKSc6HfI7vKZp8Q2" + + "zWgIFOarx1GQoWJbMcSt188xsl30ncJuJT2OoARRBAqJ4fD+q6hbqgNSjTQ7" + + "htle1KO3eiaZgcJ8rrnyN8P+5A8+5K+H9aQ/NbBR4Gs7yto5PXIUZEUgodHA" + + "TZMSAcSq5ZYt4KbnSYaLY0TtH9CqAigEwZ+hglbT21B7ZTzYX2xj0x+qooJD" + + "hVTLtIPaYJK2HrMPxTw6/zfrAgEPA1IABAnvfFcFDgD/JicwBGn6vR3N8MIn" + + "mptZf/mnJ1y649uCF60zOgdwIyI7pVSxBFsJ7ohqXEHW0x7LrGVkdSEiipiH" + + "LYslqh3xrqbAgPbl93GUo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB" + + "/wQEAwIBxjAdBgNVHQ4EFgQUAEo62Xm9H6DcsE0zUDTza4BRG90wCwYHKoZI" + + "zj0EAQUAA1cAMFQCKAQsCHHSNOqfJXLgt3bg5+k49hIBGVr/bfG0B9JU3rNt" + + "Ycl9Y2zfRPUCKAK2ccOQXByAWfsasDu8zKHxkZv7LVDTFjAIffz3HaCQeVhD" + + "z+fauEg="); + + private static readonly byte[] keyUsage = Base64.Decode( + "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE" + + "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50" + + "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs" + + "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp" + + "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0" + + "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa" + + "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV" + + "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw" + + "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50" + + "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50" + + "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL" + + "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv" + + "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV" + + "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173" + + "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw" + + "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50" + + "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff" + + "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE" + + "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50" + + "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD" + + "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D" + + "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx" + + "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW" + + "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG" + + "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI" + + "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ" + + "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU" + + "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE" + + "PHayXOw="); + + private static readonly byte[] nameCert = Base64.Decode( + "MIIEFjCCA3+gAwIBAgIEdS8BozANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJE"+ + "RTERMA8GA1UEChQIREFURVYgZUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRQ0Eg"+ + "REFURVYgRDAzIDE6UE4wIhgPMjAwMTA1MTAxMDIyNDhaGA8yMDA0MDUwOTEwMjI0"+ + "OFowgYQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIFAZCYXllcm4xEjAQBgNVBAcUCU7I"+ + "dXJuYmVyZzERMA8GA1UEChQIREFURVYgZUcxHTAbBgNVBAUTFDAwMDAwMDAwMDA4"+ + "OTU3NDM2MDAxMR4wHAYDVQQDFBVEaWV0bWFyIFNlbmdlbmxlaXRuZXIwgaEwDQYJ"+ + "KoZIhvcNAQEBBQADgY8AMIGLAoGBAJLI/LJLKaHoMk8fBECW/od8u5erZi6jI8Ug"+ + "C0a/LZyQUO/R20vWJs6GrClQtXB+AtfiBSnyZOSYzOdfDI8yEKPEv8qSuUPpOHps"+ + "uNCFdLZF1vavVYGEEWs2+y+uuPmg8q1oPRyRmUZ+x9HrDvCXJraaDfTEd9olmB/Z"+ + "AuC/PqpjAgUAwAAAAaOCAcYwggHCMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUD"+ + "AwdAADAxBgNVHSAEKjAoMCYGBSskCAEBMB0wGwYIKwYBBQUHAgEWD3d3dy56cy5k"+ + "YXRldi5kZTApBgNVHREEIjAggR5kaWV0bWFyLnNlbmdlbmxlaXRuZXJAZGF0ZXYu"+ + "ZGUwgYQGA1UdIwR9MHuhc6RxMG8xCzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1"+ + "bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0"+ + "MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjVSLUNBIDE6UE6CBACm8LkwDgYHAoIG"+ + "AQoMAAQDAQEAMEcGA1UdHwRAMD4wPKAUoBKGEHd3dy5jcmwuZGF0ZXYuZGWiJKQi"+ + "MCAxCzAJBgNVBAYTAkRFMREwDwYDVQQKFAhEQVRFViBlRzAWBgUrJAgDBAQNMAsT"+ + "A0VVUgIBBQIBATAdBgNVHQ4EFgQUfv6xFP0xk7027folhy+ziZvBJiwwLAYIKwYB"+ + "BQUHAQEEIDAeMBwGCCsGAQUFBzABhhB3d3cuZGlyLmRhdGV2LmRlMA0GCSqGSIb3"+ + "DQEBBQUAA4GBAEOVX6uQxbgtKzdgbTi6YLffMftFr2mmNwch7qzpM5gxcynzgVkg"+ + "pnQcDNlm5AIbS6pO8jTCLfCd5TZ5biQksBErqmesIl3QD+VqtB+RNghxectZ3VEs"+ + "nCUtcE7tJ8O14qwCb3TxS9dvIUFiVi4DjbxX46TdcTbTaK8/qr6AIf+l"); + + private static readonly byte[] probSelfSignedCert = Base64.Decode( + "MIICxTCCAi6gAwIBAgIQAQAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQUFADBF" + + "MScwJQYDVQQKEx4gRElSRUNUSU9OIEdFTkVSQUxFIERFUyBJTVBPVFMxGjAYBgNV" + + "BAMTESBBQyBNSU5FRkkgQiBURVNUMB4XDTA0MDUwNzEyMDAwMFoXDTE0MDUwNzEy" + + "MDAwMFowRTEnMCUGA1UEChMeIERJUkVDVElPTiBHRU5FUkFMRSBERVMgSU1QT1RT" + + "MRowGAYDVQQDExEgQUMgTUlORUZJIEIgVEVTVDCBnzANBgkqhkiG9w0BAQEFAAOB" + + "jQAwgYkCgYEAveoCUOAukZdcFCs2qJk76vSqEX0ZFzHqQ6faBPZWjwkgUNwZ6m6m" + + "qWvvyq1cuxhoDvpfC6NXILETawYc6MNwwxsOtVVIjuXlcF17NMejljJafbPximEt" + + "DQ4LcQeSp4K7FyFlIAMLyt3BQ77emGzU5fjFTvHSUNb3jblx0sV28c0CAwEAAaOB" + + "tTCBsjAfBgNVHSMEGDAWgBSEJ4bLbvEQY8cYMAFKPFD1/fFXlzAdBgNVHQ4EFgQU" + + "hCeGy27xEGPHGDABSjxQ9f3xV5cwDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIB" + + "AQQEAwIBBjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vYWRvbmlzLnBrNy5jZXJ0" + + "cGx1cy5uZXQvZGdpLXRlc3QuY3JsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" + + "AQEFBQADgYEAmToHJWjd3+4zknfsP09H6uMbolHNGG0zTS2lrLKpzcmkQfjhQpT9" + + "LUTBvfs1jdjo9fGmQLvOG+Sm51Rbjglb8bcikVI5gLbclOlvqLkm77otjl4U4Z2/" + + "Y0vP14Aov3Sn3k+17EfReYUZI4liuB95ncobC4e8ZM++LjQcIM0s+Vs="); + + + private static readonly byte[] gost34102001base = Base64.Decode( + "MIIB1DCCAYECEEjpVKXP6Wn1yVz3VeeDQa8wCgYGKoUDAgIDBQAwbTEfMB0G" + + "A1UEAwwWR29zdFIzNDEwLTIwMDEgZXhhbXBsZTESMBAGA1UECgwJQ3J5cHRv" + + "UHJvMQswCQYDVQQGEwJSVTEpMCcGCSqGSIb3DQEJARYaR29zdFIzNDEwLTIw" + + "MDFAZXhhbXBsZS5jb20wHhcNMDUwMjAzMTUxNjQ2WhcNMTUwMjAzMTUxNjQ2" + + "WjBtMR8wHQYDVQQDDBZHb3N0UjM0MTAtMjAwMSBleGFtcGxlMRIwEAYDVQQK" + + "DAlDcnlwdG9Qcm8xCzAJBgNVBAYTAlJVMSkwJwYJKoZIhvcNAQkBFhpHb3N0" + + "UjM0MTAtMjAwMUBleGFtcGxlLmNvbTBjMBwGBiqFAwICEzASBgcqhQMCAiQA" + + "BgcqhQMCAh4BA0MABECElWh1YAIaQHUIzROMMYks/eUFA3pDXPRtKw/nTzJ+" + + "V4/rzBa5lYgD0Jp8ha4P5I3qprt+VsfLsN8PZrzK6hpgMAoGBiqFAwICAwUA" + + "A0EAHw5dw/aw/OiNvHyOE65kvyo4Hp0sfz3csM6UUkp10VO247ofNJK3tsLb" + + "HOLjUaqzefrlGb11WpHYrvWFg+FcLA=="); + + private static readonly byte[] gost341094base = Base64.Decode( + "MIICDzCCAbwCEBcxKsIb0ghYvAQeUjfQdFAwCgYGKoUDAgIEBQAwaTEdMBsG" + + "A1UEAwwUR29zdFIzNDEwLTk0IGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1By" + + "bzELMAkGA1UEBhMCUlUxJzAlBgkqhkiG9w0BCQEWGEdvc3RSMzQxMC05NEBl" + + "eGFtcGxlLmNvbTAeFw0wNTAyMDMxNTE2NTFaFw0xNTAyMDMxNTE2NTFaMGkx" + + "HTAbBgNVBAMMFEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlw" + + "dG9Qcm8xCzAJBgNVBAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAt" + + "OTRAZXhhbXBsZS5jb20wgaUwHAYGKoUDAgIUMBIGByqFAwICIAIGByqFAwIC" + + "HgEDgYQABIGAu4Rm4XmeWzTYLIB/E6gZZnFX/oxUJSFHbzALJ3dGmMb7R1W+" + + "t7Lzk2w5tUI3JoTiDRCKJA4fDEJNKzsRK6i/ZjkyXJSLwaj+G2MS9gklh8x1" + + "G/TliYoJgmjTXHemD7aQEBON4z58nJHWrA0ILD54wbXCtrcaqCqLRYGTMjJ2" + + "+nswCgYGKoUDAgIEBQADQQBxKNhOmjgz/i5CEgLOyKyz9pFGkDcaymsWYQWV" + + "v7CZ0pTM8IzMzkUBW3GHsUjCFpanFZDfg2zuN+3kT+694n9B"); + + private static readonly byte[] gost341094A = Base64.Decode( + "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOZGVmYXVsdDM0MTAtOTQx" + + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1vbGExDDAKBgNVBAgT" + + "A01FTDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + + "MzExNTdaFw0wNjAzMjkxMzExNTdaMIGBMRcwFQYDVQQDEw5kZWZhdWx0MzQxMC05NDENMAsGA1UE" + + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLW9sYTEMMAoGA1UECBMDTUVMMQsw" + + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + + "hQMCAiACBgcqhQMCAh4BA4GEAASBgIQACDLEuxSdRDGgdZxHmy30g/DUYkRxO9Mi/uSHX5NjvZ31" + + "b7JMEMFqBtyhql1HC5xZfUwZ0aT3UnEFDfFjLP+Bf54gA+LPkQXw4SNNGOj+klnqgKlPvoqMGlwa" + + "+hLPKbS561WpvB2XSTgbV+pqqXR3j6j30STmybelEV3RdS2Now8wDTALBgNVHQ8EBAMCB4AwCgYG" + + "KoUDAgIEBQADQQBCFy7xWRXtNVXflKvDs0pBdBuPzjCMeZAXVxK8vUxsxxKu76d9CsvhgIFknFRi" + + "wWTPiZenvNoJ4R1uzeX+vREm"); + + private static readonly byte[] gost341094B = Base64.Decode( + "MIICSDCCAfWgAwIBAgIBATAKBgYqhQMCAgQFADCBgTEXMBUGA1UEAxMOcGFyYW0xLTM0MTAtOTQx" + + "DTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNVBAgT" + + "A01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAzMjkx" + + "MzEzNTZaFw0wNjAzMjkxMzEzNTZaMIGBMRcwFQYDVQQDEw5wYXJhbTEtMzQxMC05NDENMAsGA1UE" + + "ChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMDTWVsMQsw" + + "CQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MIGlMBwGBiqFAwICFDASBgcq" + + "hQMCAiADBgcqhQMCAh4BA4GEAASBgEa+AAcZmijWs1M9x5Pn9efE8D9ztG1NMoIt0/hNZNqln3+j" + + "lMZjyqPt+kTLIjtmvz9BRDmIDk6FZz+4LhG2OTL7yGpWfrMxMRr56nxomTN9aLWRqbyWmn3brz9Y" + + "AUD3ifnwjjIuW7UM84JNlDTOdxx0XRUfLQIPMCXe9cO02Xskow8wDTALBgNVHQ8EBAMCB4AwCgYG" + + "KoUDAgIEBQADQQBzFcnuYc/639OTW+L5Ecjw9KxGr+dwex7lsS9S1BUgKa3m1d5c+cqI0B2XUFi5" + + "4iaHHJG0dCyjtQYLJr0OZjRw"); + + private static readonly byte[] gost34102001A = Base64.Decode( + "MIICCzCCAbigAwIBAgIBATAKBgYqhQMCAgMFADCBhDEaMBgGA1UEAxMRZGVmYXVsdC0zNDEwLTIw" + + "MDExDTALBgNVBAoTBERpZ3QxDzANBgNVBAsTBkNyeXB0bzEOMAwGA1UEBxMFWS1PbGExDDAKBgNV" + + "BAgTA01lbDELMAkGA1UEBhMCcnUxGzAZBgkqhkiG9w0BCQEWDHRlc3RAdGVzdC5ydTAeFw0wNTAz" + + "MjkxMzE4MzFaFw0wNjAzMjkxMzE4MzFaMIGEMRowGAYDVQQDExFkZWZhdWx0LTM0MTAtMjAwMTEN" + + "MAsGA1UEChMERGlndDEPMA0GA1UECxMGQ3J5cHRvMQ4wDAYDVQQHEwVZLU9sYTEMMAoGA1UECBMD" + + "TWVsMQswCQYDVQQGEwJydTEbMBkGCSqGSIb3DQEJARYMdGVzdEB0ZXN0LnJ1MGMwHAYGKoUDAgIT" + + "MBIGByqFAwICIwEGByqFAwICHgEDQwAEQG/4c+ZWb10IpeHfmR+vKcbpmSOClJioYmCVgnojw0Xn" + + "ned0KTg7TJreRUc+VX7vca4hLQaZ1o/TxVtfEApK/O6jDzANMAsGA1UdDwQEAwIHgDAKBgYqhQMC" + + "AgMFAANBAN8y2b6HuIdkD3aWujpfQbS1VIA/7hro4vLgDhjgVmev/PLzFB8oTh3gKhExpDo82IEs" + + "ZftGNsbbyp1NFg7zda0="); + + private static readonly byte[] gostCA1 = Base64.Decode( + "MIIDNDCCAuGgAwIBAgIQZLcKDcWcQopF+jp4p9jylDAKBgYqhQMCAgQFADBm" + + "MQswCQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MRcwFQYDVQQKEw5PT08g" + + "Q3J5cHRvLVBybzEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFzAVBgNVBAMTDkNQ" + + "IENTUCBUZXN0IENBMB4XDTAyMDYwOTE1NTIyM1oXDTA5MDYwOTE1NTkyOVow" + + "ZjELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEXMBUGA1UEChMOT09P" + + "IENyeXB0by1Qcm8xFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5D" + + "UCBDU1AgVGVzdCBDQTCBpTAcBgYqhQMCAhQwEgYHKoUDAgIgAgYHKoUDAgIe" + + "AQOBhAAEgYAYglywKuz1nMc9UiBYOaulKy53jXnrqxZKbCCBSVaJ+aCKbsQm" + + "glhRFrw6Mwu8Cdeabo/ojmea7UDMZd0U2xhZFRti5EQ7OP6YpqD0alllo7za" + + "4dZNXdX+/ag6fOORSLFdMpVx5ganU0wHMPk67j+audnCPUj/plbeyccgcdcd" + + "WaOCASIwggEeMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + + "DgQWBBTe840gTo4zt2twHilw3PD9wJaX0TCBygYDVR0fBIHCMIG/MDygOqA4" + + "hjYtaHR0cDovL2ZpZXdhbGwvQ2VydEVucm9sbC9DUCUyMENTUCUyMFRlc3Ql" + + "MjBDQSgzKS5jcmwwRKBCoECGPmh0dHA6Ly93d3cuY3J5cHRvcHJvLnJ1L0Nl" + + "cnRFbnJvbGwvQ1AlMjBDU1AlMjBUZXN0JTIwQ0EoMykuY3JsMDmgN6A1hjMt" + + "ZmlsZTovL1xcZmlld2FsbFxDZXJ0RW5yb2xsXENQIENTUCBUZXN0IENBKDMp" + + "LmNybC8wEgYJKwYBBAGCNxUBBAUCAwMAAzAKBgYqhQMCAgQFAANBAIJi7ni7" + + "9rwMR5rRGTFftt2k70GbqyUEfkZYOzrgdOoKiB4IIsIstyBX0/ne6GsL9Xan" + + "G2IN96RB7KrowEHeW+k="); + + private static readonly byte[] gostCA2 = Base64.Decode( + "MIIC2DCCAoWgAwIBAgIQe9ZCugm42pRKNcHD8466zTAKBgYqhQMCAgMFADB+" + + "MRowGAYJKoZIhvcNAQkBFgtzYmFAZGlndC5ydTELMAkGA1UEBhMCUlUxDDAK" + + "BgNVBAgTA01FTDEUMBIGA1UEBxMLWW9zaGthci1PbGExDTALBgNVBAoTBERp" + + "Z3QxDzANBgNVBAsTBkNyeXB0bzEPMA0GA1UEAxMGc2JhLUNBMB4XDTA0MDgw" + + "MzEzMzE1OVoXDTE0MDgwMzEzNDAxMVowfjEaMBgGCSqGSIb3DQEJARYLc2Jh" + + "QGRpZ3QucnUxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNNRUwxFDASBgNVBAcT" + + "C1lvc2hrYXItT2xhMQ0wCwYDVQQKEwREaWd0MQ8wDQYDVQQLEwZDcnlwdG8x" + + "DzANBgNVBAMTBnNiYS1DQTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMC" + + "Ah4BA0MABEDMSy10CuOH+i8QKG2UWA4XmCt6+BFrNTZQtS6bOalyDY8Lz+G7" + + "HybyipE3PqdTB4OIKAAPsEEeZOCZd2UXGQm5o4HaMIHXMBMGCSsGAQQBgjcU" + + "AgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud" + + "DgQWBBRJJl3LcNMxkZI818STfoi3ng1xoDBxBgNVHR8EajBoMDGgL6Athito" + + "dHRwOi8vc2JhLmRpZ3QubG9jYWwvQ2VydEVucm9sbC9zYmEtQ0EuY3JsMDOg" + + "MaAvhi1maWxlOi8vXFxzYmEuZGlndC5sb2NhbFxDZXJ0RW5yb2xsXHNiYS1D" + + "QS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwCgYGKoUDAgIDBQADQQA+BRJHbc/p" + + "q8EYl6iJqXCuR+ozRmH7hPAP3c4KqYSC38TClCgBloLapx/3/WdatctFJW/L" + + "mcTovpq088927shE"); + + private static readonly byte[] inDirectCrl = Base64.Decode( + "MIIdXjCCHMcCAQEwDQYJKoZIhvcNAQEFBQAwdDELMAkGA1UEBhMCREUxHDAaBgNV" + +"BAoUE0RldXRzY2hlIFRlbGVrb20gQUcxFzAVBgNVBAsUDlQtVGVsZVNlYyBUZXN0" + +"MS4wDAYHAoIGAQoHFBMBMTAeBgNVBAMUF1QtVGVsZVNlYyBUZXN0IERJUiA4OlBO" + +"Fw0wNjA4MDQwODQ1MTRaFw0wNjA4MDQxNDQ1MTRaMIIbfzB+AgQvrj/pFw0wMzA3" + +"MjIwNTQxMjhaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" + +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" + +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+oXDTAzMDcyMjA1NDEyOFowZzBlBgNV" + +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" + +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" + +"UE4wfgIEL64/5xcNMDQwNDA1MTMxODE3WjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" + +"CQYDVQQGEwJERTEcMBoGA1UEChQTRGV1dHNjaGUgVGVsZWtvbSBBRzEoMAwGBwKC" + +"BgEKBxQTATEwGAYDVQQDFBFTaWdHIFRlc3QgQ0EgNDpQTjB+AgQvrj/oFw0wNDA0" + +"MDUxMzE4MTdaMGcwZQYDVR0dAQH/BFswWaRXMFUxCzAJBgNVBAYTAkRFMRwwGgYD" + +"VQQKFBNEZXV0c2NoZSBUZWxla29tIEFHMSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMU" + +"EVNpZ0cgVGVzdCBDQSA0OlBOMH4CBC+uP+UXDTAzMDExMzExMTgxMVowZzBlBgNV" + +"HR0BAf8EWzBZpFcwVTELMAkGA1UEBhMCREUxHDAaBgNVBAoUE0RldXRzY2hlIFRl" + +"bGVrb20gQUcxKDAMBgcCggYBCgcUEwExMBgGA1UEAxQRU2lnRyBUZXN0IENBIDQ6" + +"UE4wfgIEL64/5hcNMDMwMTEzMTExODExWjBnMGUGA1UdHQEB/wRbMFmkVzBVMQsw" + +"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"); + + private static readonly byte[] directCRL = Base64.Decode( + "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" + +"MQ=="); + + private static readonly byte[] pkcs7CrlProblem = Base64.Decode( + "MIIwSAYJKoZIhvcNAQcCoIIwOTCCMDUCAQExCzAJBgUrDgMCGgUAMAsGCSqG" + + "SIb3DQEHAaCCEsAwggP4MIIC4KADAgECAgF1MA0GCSqGSIb3DQEBBQUAMEUx" + + "CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQD" + + "ExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUwHhcNMDQxMjAyMjEyNTM5WhcNMDYx" + + "MjMwMjEyNTM5WjBMMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMR2VvVHJ1c3Qg" + + "SW5jMSYwJAYDVQQDEx1HZW9UcnVzdCBBZG9iZSBPQ1NQIFJlc3BvbmRlcjCB" + + "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4gnNYhtw7U6QeVXZODnGhHMj" + + "+OgZ0DB393rEk6a2q9kq129IA2e03yKBTfJfQR9aWKc2Qj90dsSqPjvTDHFG" + + "Qsagm2FQuhnA3fb1UWhPzeEIdm6bxDsnQ8nWqKqxnWZzELZbdp3I9bBLizIq" + + "obZovzt60LNMghn/unvvuhpeVSsCAwEAAaOCAW4wggFqMA4GA1UdDwEB/wQE" + + "AwIE8DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8BAgEwgcYwgZAGCCsG" + + "AQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMgYmVlbiBpc3N1ZWQg" + + "aW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENyZWRlbnRpYWxzIENQ" + + "UyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNl" + + "cy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jl" + + "c291cmNlcy9jcHMwEwYDVR0lBAwwCgYIKwYBBQUHAwkwOgYDVR0fBDMwMTAv" + + "oC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5j" + + "cmwwHwYDVR0jBBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwDQYJKoZIhvcN" + + "AQEFBQADggEBAENJf1BD7PX5ivuaawt90q1OGzXpIQL/ClzEeFVmOIxqPc1E" + + "TFRq92YuxG5b6+R+k+tGkmCwPLcY8ipg6ZcbJ/AirQhohzjlFuT6YAXsTfEj" + + "CqEZfWM2sS7crK2EYxCMmKE3xDfPclYtrAoz7qZvxfQj0TuxHSstHZv39wu2" + + "ZiG1BWiEcyDQyTgqTOXBoZmfJtshuAcXmTpgkrYSrS37zNlPTGh+pMYQ0yWD" + + "c8OQRJR4OY5ZXfdna01mjtJTOmj6/6XPoLPYTq2gQrc2BCeNJ4bEhLb7sFVB" + + "PbwPrpzTE/HRbQHDrzj0YimDxeOUV/UXctgvYwHNtEkcBLsOm/uytMYwggSh" + + "MIIDiaADAgECAgQ+HL0oMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVT" + + "MSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UE" + + "CxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3Qg" + + "Q0EwHhcNMDMwMTA4MjMzNzIzWhcNMjMwMTA5MDAwNzIzWjBpMQswCQYDVQQG" + + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + + "b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE9UhPen" + + "ouczU38/nBKIayyZR2d+Dx65rRSI+cMQ2B3w8NWfaQovWTWwzGypTJwVoJ/O" + + "IL+gz1Ti4CBmRT85hjh+nMSOByLGJPYBErA131XqaZCw24U3HuJOB7JCoWoT" + + "aaBm6oCREVkqmwh5WiBELcm9cziLPC/gQxtdswvwrzUaKf7vppLdgUydPVmO" + + "rTE8QH6bkTYG/OJcjdGNJtVcRc+vZT+xqtJilvSoOOq6YEL09BxKNRXO+E4i" + + "Vg+VGMX4lp+f+7C3eCXpgGu91grwxnSUnfMPUNuad85LcIMjjaDKeCBEXDxU" + + "ZPHqojAZn+pMBk0GeEtekt8i0slns3rSAQIDAQABo4IBTzCCAUswEQYJYIZI" + + "AYb4QgEBBAQDAgAHMIGOBgNVHR8EgYYwgYMwgYCgfqB8pHoweDELMAkGA1UE" + + "BhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkMR0w" + + "GwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UEAxMNQWRvYmUg" + + "Um9vdCBDQTENMAsGA1UEAxMEQ1JMMTArBgNVHRAEJDAigA8yMDAzMDEwODIz" + + "MzcyM1qBDzIwMjMwMTA5MDAwNzIzWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgw" + + "FoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFIK3OEqTqpsQ74C7" + + "2VTi8Q/7gJzeMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjYu" + + "MDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQAy2p9DdcH6b8lv26sdNjc+" + + "vGEZNrcCPB0jWZhsnu5NhedUyCAfp9S74r8Ad30ka3AvXME6dkm10+AjhCpx" + + "aiLzwScpmBX2NZDkBEzDjbyfYRzn/SSM0URDjBa6m02l1DUvvBHOvfdRN42f" + + "kOQU8Rg/vulZEjX5M5LznuDVa5pxm5lLyHHD4bFhCcTl+pHwQjo3fTT5cujN" + + "qmIcIenV9IIQ43sFti1oVgt+fpIsb01yggztVnSynbmrLSsdEF/bJ3Vwj/0d" + + "1+ICoHnlHOX/r2RAUS2em0fbQqV8H8KmSLDXvpJpTaT2KVfFeBEY3IdRyhOy" + + "Yp1PKzK9MaXB+lKrBYjIMIIEyzCCA7OgAwIBAgIEPhy9tTANBgkqhkiG9w0B" + + "AQUFADBpMQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJ" + + "bmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYw" + + "FAYDVQQDEw1BZG9iZSBSb290IENBMB4XDTA0MDExNzAwMDMzOVoXDTE1MDEx" + + "NTA4MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTCCASIwDQYJKoZI" + + "hvcNAQEBBQADggEPADCCAQoCggEBAKfld+BkeFrnOYW8r9L1WygTDlTdSfrO" + + "YvWS/Z6Ye5/l+HrBbOHqQCXBcSeCpz7kB2WdKMh1FOE4e9JlmICsHerBLdWk" + + "emU+/PDb69zh8E0cLoDfxukF6oVPXj6WSThdSG7H9aXFzRr6S3XGCuvgl+Qw" + + "DTLiLYW+ONF6DXwt3TQQtKReJjOJZk46ZZ0BvMStKyBaeB6DKZsmiIo89qso" + + "13VDZINH2w1KvXg0ygDizoNtbvgAPFymwnsINS1klfQlcvn0x0RJm9bYQXK3" + + "5GNZAgL3M7Lqrld0jMfIUaWvuHCLyivytRuzq1dJ7E8rmidjDEk/G+27pf13" + + "fNZ7vR7M+IkCAwEAAaOCAZ0wggGZMBIGA1UdEwEB/wQIMAYBAf8CAQEwUAYD" + + "VR0gBEkwRzBFBgkqhkiG9y8BAgEwODA2BggrBgEFBQcCARYqaHR0cHM6Ly93" + + "d3cuYWRvYmUuY29tL21pc2MvcGtpL2Nkc19jcC5odG1sMBQGA1UdJQQNMAsG" + + "CSqGSIb3LwEBBTCBsgYDVR0fBIGqMIGnMCKgIKAehhxodHRwOi8vY3JsLmFk" + + "b2JlLmNvbS9jZHMuY3JsMIGAoH6gfKR6MHgxCzAJBgNVBAYTAlVTMSMwIQYD" + + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0ExDTAL" + + "BgNVBAMTBENSTDEwCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFIK3OEqTqpsQ" + + "74C72VTi8Q/7gJzeMB0GA1UdDgQWBBSrgFnDZYNtHX0TvRnD7BqPDUdqozAZ" + + "BgkqhkiG9n0HQQAEDDAKGwRWNi4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA" + + "PzlZLqIAjrFeEWEs0uC29YyJhkXOE9mf3YSaFGsITF+Gl1j0pajTjyH4R35Q" + + "r3floW2q3HfNzTeZ90Jnr1DhVERD6zEMgJpCtJqVuk0sixuXJHghS/KicKf4" + + "YXJJPx9epuIRF1siBRnznnF90svmOJMXApc0jGnYn3nQfk4kaShSnDaYaeYR" + + "DJKcsiWhl6S5zfwS7Gg8hDeyckhMQKKWnlG1CQrwlSFisKCduoodwRtWgft8" + + "kx13iyKK3sbalm6vnVc+5nufS4vI+TwMXoV63NqYaSroafBWk0nL53zGXPEy" + + "+A69QhzEViJKn2Wgqt5gt++jMMNImbRObIqgfgF1VjCCBUwwggQ0oAMCAQIC" + + "AgGDMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1H" + + "ZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUw" + + "HhcNMDYwMzI0MTU0MjI5WhcNMDkwNDA2MTQ0MjI5WjBzMQswCQYDVQQGEwJV" + + "UzELMAkGA1UECBMCTUExETAPBgNVBAoTCEdlb1RydXN0MR0wGwYDVQQDExRN" + + "YXJrZXRpbmcgRGVwYXJ0bWVudDElMCMGCSqGSIb3DQEJARYWbWFya2V0aW5n" + + "QGdlb3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB" + + "ANmvajTO4XJvAU2nVcLmXeCnAQX7RZt+7+ML3InmqQ3LCGo1weop09zV069/" + + "1x/Nmieol7laEzeXxd2ghjGzwfXafqQEqHn6+vBCvqdNPoSi63fSWhnuDVWp" + + "KVDOYgxOonrXl+Cc43lu4zRSq+Pi5phhrjDWcH74a3/rdljUt4c4GFezFXfa" + + "w2oTzWkxj2cTSn0Szhpr17+p66UNt8uknlhmu4q44Speqql2HwmCEnpLYJrK" + + "W3fOq5D4qdsvsLR2EABLhrBezamLI3iGV8cRHOUTsbTMhWhv/lKfHAyf4XjA" + + "z9orzvPN5jthhIfICOFq/nStTgakyL4Ln+nFAB/SMPkCAwEAAaOCAhYwggIS" + + "MA4GA1UdDwEB/wQEAwIF4DCB5QYDVR0gAQH/BIHaMIHXMIHUBgkqhkiG9y8B" + + "AgEwgcYwgZAGCCsGAQUFBwICMIGDGoGAVGhpcyBjZXJ0aWZpY2F0ZSBoYXMg" + + "YmVlbiBpc3N1ZWQgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBBY3JvYmF0IENy" + + "ZWRlbnRpYWxzIENQUyBsb2NhdGVkIGF0IGh0dHA6Ly93d3cuZ2VvdHJ1c3Qu" + + "Y29tL3Jlc291cmNlcy9jcHMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2Vv" + + "dHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwOgYDVR0fBDMwMTAvoC2gK4YpaHR0" + + "cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9hZG9iZWNhMS5jcmwwHwYDVR0j" + + "BBgwFoAUq4BZw2WDbR19E70Zw+wajw1HaqMwRAYIKwYBBQUHAQEEODA2MDQG" + + "CCsGAQUFBzABhihodHRwOi8vYWRvYmUtb2NzcC5nZW90cnVzdC5jb20vcmVz" + + "cG9uZGVyMBQGA1UdJQQNMAsGCSqGSIb3LwEBBTA8BgoqhkiG9y8BAQkBBC4w" + + "LAIBAYYnaHR0cDovL2Fkb2JlLXRpbWVzdGFtcC5nZW90cnVzdC5jb20vdHNh" + + "MBMGCiqGSIb3LwEBCQIEBTADAgEBMAwGA1UdEwQFMAMCAQAwDQYJKoZIhvcN" + + "AQEFBQADggEBAAOhy6QxOo+i3h877fvDvTa0plGD2bIqK7wMdNqbMDoSWied" + + "FIcgcBOIm2wLxOjZBAVj/3lDq59q2rnVeNnfXM0/N0MHI9TumHRjU7WNk9e4" + + "+JfJ4M+c3anrWOG3NE5cICDVgles+UHjXetHWql/LlP04+K2ZOLb6LE2xGnI" + + "YyLW9REzCYNAVF+/WkYdmyceHtaBZdbyVAJq0NAJPsfgY1pWcBo31Mr1fpX9" + + "WrXNTYDCqMyxMImJTmN3iI68tkXlNrhweQoArKFqBysiBkXzG/sGKYY6tWKU" + + "pzjLc3vIp/LrXC5zilROes8BSvwu1w9qQrJNcGwo7O4uijoNtyYil1Exgh1Q" + + "MIIdTAIBATBLMEUxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ" + + "bmMuMR4wHAYDVQQDExVHZW9UcnVzdCBDQSBmb3IgQWRvYmUCAgGDMAkGBSsO" + + "AwIaBQCgggxMMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwIwYJKoZIhvcN" + + "AQkEMRYEFP4R6qIdpQJzWyzrqO8X1ZfJOgChMIIMCQYJKoZIhvcvAQEIMYIL" + + "+jCCC/agggZ5MIIGdTCCA6gwggKQMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV" + + "BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR4wHAYDVQQDExVHZW9U" + + "cnVzdCBDQSBmb3IgQWRvYmUXDTA2MDQwNDE3NDAxMFoXDTA2MDQwNTE3NDAx" + + "MFowggIYMBMCAgC5Fw0wNTEwMTEyMDM2MzJaMBICAVsXDTA0MTEwNDE1MDk0" + + "MVowEwICALgXDTA1MTIxMjIyMzgzOFowEgIBWhcNMDQxMTA0MTUwOTMzWjAT" + + "AgIA5hcNMDUwODI3MDQwOTM4WjATAgIAtxcNMDYwMTE2MTc1NTEzWjATAgIA" + + "hhcNMDUxMjEyMjIzODU1WjATAgIAtRcNMDUwNzA2MTgzODQwWjATAgIA4BcN" + + "MDYwMzIwMDc0ODM0WjATAgIAgRcNMDUwODAyMjIzMTE1WjATAgIA3xcNMDUx" + + "MjEyMjIzNjUwWjASAgFKFw0wNDExMDQxNTA5MTZaMBICAUQXDTA0MTEwNDE1" + + "MDg1M1owEgIBQxcNMDQxMDAzMDEwMDQwWjASAgFsFw0wNDEyMDYxOTQ0MzFa" + + "MBMCAgEoFw0wNjAzMDkxMjA3MTJaMBMCAgEkFw0wNjAxMTYxNzU1MzRaMBIC" + + "AWcXDTA1MDMxODE3NTYxNFowEwICAVEXDTA2MDEzMTExMjcxMVowEgIBZBcN" + + "MDQxMTExMjI0ODQxWjATAgIA8RcNMDUwOTE2MTg0ODAxWjATAgIBThcNMDYw" + + "MjIxMjAxMDM2WjATAgIAwRcNMDUxMjEyMjIzODE2WjASAgFiFw0wNTAxMTAx" + + "NjE5MzRaMBICAWAXDTA1MDExMDE5MDAwNFowEwICAL4XDTA1MDUxNzE0NTYx" + + "MFowDQYJKoZIhvcNAQEFBQADggEBAEKhRMS3wVho1U3EvEQJZC8+JlUngmZQ" + + "A78KQbHPWNZWFlNvPuf/b0s7Lu16GfNHXh1QAW6Y5Hi1YtYZ3YOPyMd4Xugt" + + "gCdumbB6xtKsDyN5RvTht6ByXj+CYlYqsL7RX0izJZ6mJn4fjMkqzPKNOjb8" + + "kSn5T6rn93BjlATtCE8tPVOM8dnqGccRE0OV59+nDBXc90UMt5LdEbwaUOap" + + "snVB0oLcNm8d/HnlVH6RY5LnDjrT4vwfe/FApZtTecEWsllVUXDjSpwfcfD/" + + "476/lpGySB2otALqzImlA9R8Ok3hJ8dnF6hhQ5Oe6OJMnGYgdhkKbxsKkdib" + + "tTVl3qmH5QAwggLFMIIBrQIBATANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQG" + + "EwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAb" + + "BgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMRYwFAYDVQQDEw1BZG9iZSBS" + + "b290IENBFw0wNjAxMjcxODMzMzFaFw0wNzAxMjcwMDAwMDBaMIHeMCMCBD4c" + + "vUAXDTAzMDEyMTIzNDY1NlowDDAKBgNVHRUEAwoBBDAjAgQ+HL1BFw0wMzAx" + + "MjEyMzQ3MjJaMAwwCgYDVR0VBAMKAQQwIwIEPhy9YhcNMDMwMTIxMjM0NzQy" + + "WjAMMAoGA1UdFQQDCgEEMCMCBD4cvWEXDTA0MDExNzAxMDg0OFowDDAKBgNV" + + "HRUEAwoBBDAjAgQ+HL2qFw0wNDAxMTcwMTA5MDVaMAwwCgYDVR0VBAMKAQQw" + + "IwIEPhy9qBcNMDQwMTE3MDEzOTI5WjAMMAoGA1UdFQQDCgEEoC8wLTAKBgNV" + + "HRQEAwIBDzAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jANBgkq" + + "hkiG9w0BAQUFAAOCAQEAwtXF9042wG39icUlsotn5tpE3oCusLb/hBpEONhx" + + "OdfEQOq0w5hf/vqaxkcf71etA+KpbEUeSVaHMHRPhx/CmPrO9odE139dJdbt" + + "9iqbrC9iZokFK3h/es5kg73xujLKd7C/u5ngJ4mwBtvhMLjFjF2vJhPKHL4C" + + "IgMwdaUAhrcNzy16v+mw/VGJy3Fvc6oCESW1K9tvFW58qZSNXrMlsuidgunM" + + "hPKG+z0SXVyCqL7pnqKiaGddcgujYGOSY4S938oVcfZeZQEODtSYGlzldojX" + + "C1U1hCK5+tHAH0Ox/WqRBIol5VCZQwJftf44oG8oviYq52aaqSejXwmfT6zb" + + "76GCBXUwggVxMIIFbQoBAKCCBWYwggViBgkrBgEFBQcwAQEEggVTMIIFTzCB" + + "taIWBBS+8EpykfXdl4h3z7m/NZfdkAQQERgPMjAwNjA0MDQyMDIwMTVaMGUw" + + "YzA7MAkGBSsOAwIaBQAEFEb4BuZYkbjBjOjT6VeA/00fBvQaBBT3fTSQniOp" + + "BbHBSkz4xridlX0bsAICAYOAABgPMjAwNjA0MDQyMDIwMTVaoBEYDzIwMDYw" + + "NDA1MDgyMDE1WqEjMCEwHwYJKwYBBQUHMAECBBIEEFqooq/R2WltD7TposkT" + + "BhMwDQYJKoZIhvcNAQEFBQADgYEAMig6lty4b0JDsT/oanfQG5x6jVKPACpp" + + "1UA9SJ0apJJa7LeIdDFmu5C2S/CYiKZm4A4P9cAu0YzgLHxE4r6Op+HfVlAG" + + "6bzUe1P/hi1KCJ8r8wxOZAktQFPSzs85RAZwkHMfB0lP2e/h666Oye+Zf8VH" + + "RaE+/xZ7aswE89HXoumgggQAMIID/DCCA/gwggLgoAMCAQICAXUwDQYJKoZI" + + "hvcNAQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu" + + "Yy4xHjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNDEyMDIy" + + "MTI1MzlaFw0wNjEyMzAyMTI1MzlaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK" + + "EwxHZW9UcnVzdCBJbmMxJjAkBgNVBAMTHUdlb1RydXN0IEFkb2JlIE9DU1Ag" + + "UmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiCc1iG3Dt" + + "TpB5Vdk4OcaEcyP46BnQMHf3esSTprar2SrXb0gDZ7TfIoFN8l9BH1pYpzZC" + + "P3R2xKo+O9MMcUZCxqCbYVC6GcDd9vVRaE/N4Qh2bpvEOydDydaoqrGdZnMQ" + + "tlt2ncj1sEuLMiqhtmi/O3rQs0yCGf+6e++6Gl5VKwIDAQABo4IBbjCCAWow" + + "DgYDVR0PAQH/BAQDAgTwMIHlBgNVHSABAf8EgdowgdcwgdQGCSqGSIb3LwEC" + + "ATCBxjCBkAYIKwYBBQUHAgIwgYMagYBUaGlzIGNlcnRpZmljYXRlIGhhcyBi" + + "ZWVuIGlzc3VlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIEFjcm9iYXQgQ3Jl" + + "ZGVudGlhbHMgQ1BTIGxvY2F0ZWQgYXQgaHR0cDovL3d3dy5nZW90cnVzdC5j" + + "b20vcmVzb3VyY2VzL2NwczAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90" + + "cnVzdC5jb20vcmVzb3VyY2VzL2NwczATBgNVHSUEDDAKBggrBgEFBQcDCTA6" + + "BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxz" + + "L2Fkb2JlY2ExLmNybDAfBgNVHSMEGDAWgBSrgFnDZYNtHX0TvRnD7BqPDUdq" + + "ozANBgkqhkiG9w0BAQUFAAOCAQEAQ0l/UEPs9fmK+5prC33SrU4bNekhAv8K" + + "XMR4VWY4jGo9zURMVGr3Zi7Eblvr5H6T60aSYLA8txjyKmDplxsn8CKtCGiH" + + "OOUW5PpgBexN8SMKoRl9YzaxLtysrYRjEIyYoTfEN89yVi2sCjPupm/F9CPR" + + "O7EdKy0dm/f3C7ZmIbUFaIRzINDJOCpM5cGhmZ8m2yG4BxeZOmCSthKtLfvM" + + "2U9MaH6kxhDTJYNzw5BElHg5jlld92drTWaO0lM6aPr/pc+gs9hOraBCtzYE" + + "J40nhsSEtvuwVUE9vA+unNMT8dFtAcOvOPRiKYPF45RX9Rdy2C9jAc20SRwE" + + "uw6b+7K0xjANBgkqhkiG9w0BAQEFAASCAQC7a4yICFGCEMPlJbydK5qLG3rV" + + "sip7Ojjz9TB4nLhC2DgsIHds8jjdq2zguInluH2nLaBCVS+qxDVlTjgbI2cB" + + "TaWS8nglC7nNjzkKAsa8vThA8FZUVXTW0pb74jNJJU2AA27bb4g+4WgunCrj" + + "fpYp+QjDyMmdrJVqRmt5eQN+dpVxMS9oq+NrhOSEhyIb4/rejgNg9wnVK1ms" + + "l5PxQ4x7kpm7+Ua41//owkJVWykRo4T1jo4eHEz1DolPykAaKie2VKH/sMqR" + + "Spjh4E5biKJLOV9fKivZWKAXByXfwUbbMsJvz4v/2yVHFy9xP+tqB5ZbRoDK" + + "k8PzUyCprozn+/22oYIPijCCD4YGCyqGSIb3DQEJEAIOMYIPdTCCD3EGCSqG" + + "SIb3DQEHAqCCD2Iwgg9eAgEDMQswCQYFKw4DAhoFADCB+gYLKoZIhvcNAQkQ" + + "AQSggeoEgecwgeQCAQEGAikCMCEwCQYFKw4DAhoFAAQUoT97qeCv3FXYaEcS" + + "gY8patCaCA8CAiMHGA8yMDA2MDQwNDIwMjA1N1owAwIBPAEB/wIIO0yRre3L" + + "8/6ggZCkgY0wgYoxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNl" + + "dHRzMRAwDgYDVQQHEwdOZWVkaGFtMRUwEwYDVQQKEwxHZW9UcnVzdCBJbmMx" + + "EzARBgNVBAsTClByb2R1Y3Rpb24xJTAjBgNVBAMTHGFkb2JlLXRpbWVzdGFt" + + "cC5nZW90cnVzdC5jb22gggzJMIIDUTCCAjmgAwIBAgICAI8wDQYJKoZIhvcN" + + "AQEFBQAwRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4x" + + "HjAcBgNVBAMTFUdlb1RydXN0IENBIGZvciBBZG9iZTAeFw0wNTAxMTAwMTI5" + + "MTBaFw0xNTAxMTUwODAwMDBaMIGKMQswCQYDVQQGEwJVUzEWMBQGA1UECBMN" + + "TWFzc2FjaHVzZXR0czEQMA4GA1UEBxMHTmVlZGhhbTEVMBMGA1UEChMMR2Vv" + + "VHJ1c3QgSW5jMRMwEQYDVQQLEwpQcm9kdWN0aW9uMSUwIwYDVQQDExxhZG9i" + + "ZS10aW1lc3RhbXAuZ2VvdHJ1c3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GN" + + "ADCBiQKBgQDRbxJotLFPWQuuEDhKtOMaBUJepGxIvWxeahMbq1DVmqnk88+j" + + "w/5lfPICPzQZ1oHrcTLSAFM7Mrz3pyyQKQKMqUyiemzuG/77ESUNfBNSUfAF" + + "PdtHuDMU8Is8ABVnFk63L+wdlvvDIlKkE08+VTKCRdjmuBVltMpQ6QcLFQzm" + + "AQIDAQABo4GIMIGFMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwuZ2Vv" + + "dHJ1c3QuY29tL2NybHMvYWRvYmVjYTEuY3JsMB8GA1UdIwQYMBaAFKuAWcNl" + + "g20dfRO9GcPsGo8NR2qjMA4GA1UdDwEB/wQEAwIGwDAWBgNVHSUBAf8EDDAK" + + "BggrBgEFBQcDCDANBgkqhkiG9w0BAQUFAAOCAQEAmnyXjdtX+F79Nf0KggTd" + + "6YC2MQD9s09IeXTd8TP3rBmizfM+7f3icggeCGakNfPRmIUMLoa0VM5Kt37T" + + "2X0TqzBWusfbKx7HnX4v1t/G8NJJlT4SShSHv+8bjjU4lUoCmW2oEcC5vXwP" + + "R5JfjCyois16npgcO05ZBT+LLDXyeBijE6qWmwLDfEpLyILzVRmyU4IE7jvm" + + "rgb3GXwDUvd3yQXGRRHbPCh3nj9hBGbuzyt7GnlqnEie3wzIyMG2ET/wvTX5" + + "4BFXKNe7lDLvZj/MXvd3V7gMTSVW0kAszKao56LfrVTgp1VX3UBQYwmQqaoA" + + "UwFezih+jEvjW6cYJo/ErDCCBKEwggOJoAMCAQICBD4cvSgwDQYJKoZIhvcN" + + "AQEFBQAwaTELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMg" + + "SW5jb3Jwb3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEW" + + "MBQGA1UEAxMNQWRvYmUgUm9vdCBDQTAeFw0wMzAxMDgyMzM3MjNaFw0yMzAx" + + "MDkwMDA3MjNaMGkxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0" + + "ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2Vydmlj" + + "ZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA" + + "A4IBDwAwggEKAoIBAQDMT1SE96ei5zNTfz+cEohrLJlHZ34PHrmtFIj5wxDY" + + "HfDw1Z9pCi9ZNbDMbKlMnBWgn84gv6DPVOLgIGZFPzmGOH6cxI4HIsYk9gES" + + "sDXfVeppkLDbhTce4k4HskKhahNpoGbqgJERWSqbCHlaIEQtyb1zOIs8L+BD" + + "G12zC/CvNRop/u+mkt2BTJ09WY6tMTxAfpuRNgb84lyN0Y0m1VxFz69lP7Gq" + + "0mKW9Kg46rpgQvT0HEo1Fc74TiJWD5UYxfiWn5/7sLd4JemAa73WCvDGdJSd" + + "8w9Q25p3zktwgyONoMp4IERcPFRk8eqiMBmf6kwGTQZ4S16S3yLSyWezetIB" + + "AgMBAAGjggFPMIIBSzARBglghkgBhvhCAQEEBAMCAAcwgY4GA1UdHwSBhjCB" + + "gzCBgKB+oHykejB4MQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lz" + + "dGVtcyBJbmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZp" + + "Y2VzMRYwFAYDVQQDEw1BZG9iZSBSb290IENBMQ0wCwYDVQQDEwRDUkwxMCsG" + + "A1UdEAQkMCKADzIwMDMwMTA4MjMzNzIzWoEPMjAyMzAxMDkwMDA3MjNaMAsG" + + "A1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSCtzhKk6qbEO+Au9lU4vEP+4Cc3jAd" + + "BgNVHQ4EFgQUgrc4SpOqmxDvgLvZVOLxD/uAnN4wDAYDVR0TBAUwAwEB/zAd" + + "BgkqhkiG9n0HQQAEEDAOGwhWNi4wOjQuMAMCBJAwDQYJKoZIhvcNAQEFBQAD" + + "ggEBADLan0N1wfpvyW/bqx02Nz68YRk2twI8HSNZmGye7k2F51TIIB+n1Lvi" + + "vwB3fSRrcC9cwTp2SbXT4COEKnFqIvPBJymYFfY1kOQETMONvJ9hHOf9JIzR" + + "REOMFrqbTaXUNS+8Ec6991E3jZ+Q5BTxGD++6VkSNfkzkvOe4NVrmnGbmUvI" + + "ccPhsWEJxOX6kfBCOjd9NPly6M2qYhwh6dX0ghDjewW2LWhWC35+kixvTXKC" + + "DO1WdLKduastKx0QX9sndXCP/R3X4gKgeeUc5f+vZEBRLZ6bR9tCpXwfwqZI" + + "sNe+kmlNpPYpV8V4ERjch1HKE7JinU8rMr0xpcH6UqsFiMgwggTLMIIDs6AD" + + "AgECAgQ+HL21MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNVBAYTAlVTMSMwIQYD" + + "VQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRv" + + "YmUgVHJ1c3QgU2VydmljZXMxFjAUBgNVBAMTDUFkb2JlIFJvb3QgQ0EwHhcN" + + "MDQwMTE3MDAwMzM5WhcNMTUwMTE1MDgwMDAwWjBFMQswCQYDVQQGEwJVUzEW" + + "MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0Eg" + + "Zm9yIEFkb2JlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp+V3" + + "4GR4Wuc5hbyv0vVbKBMOVN1J+s5i9ZL9nph7n+X4esFs4epAJcFxJ4KnPuQH" + + "ZZ0oyHUU4Th70mWYgKwd6sEt1aR6ZT788Nvr3OHwTRwugN/G6QXqhU9ePpZJ" + + "OF1Ibsf1pcXNGvpLdcYK6+CX5DANMuIthb440XoNfC3dNBC0pF4mM4lmTjpl" + + "nQG8xK0rIFp4HoMpmyaIijz2qyjXdUNkg0fbDUq9eDTKAOLOg21u+AA8XKbC" + + "ewg1LWSV9CVy+fTHREmb1thBcrfkY1kCAvczsuquV3SMx8hRpa+4cIvKK/K1" + + "G7OrV0nsTyuaJ2MMST8b7bul/Xd81nu9Hsz4iQIDAQABo4IBnTCCAZkwEgYD" + + "VR0TAQH/BAgwBgEB/wIBATBQBgNVHSAESTBHMEUGCSqGSIb3LwECATA4MDYG" + + "CCsGAQUFBwIBFipodHRwczovL3d3dy5hZG9iZS5jb20vbWlzYy9wa2kvY2Rz" + + "X2NwLmh0bWwwFAYDVR0lBA0wCwYJKoZIhvcvAQEFMIGyBgNVHR8Egaowgacw" + + "IqAgoB6GHGh0dHA6Ly9jcmwuYWRvYmUuY29tL2Nkcy5jcmwwgYCgfqB8pHow" + + "eDELMAkGA1UEBhMCVVMxIzAhBgNVBAoTGkFkb2JlIFN5c3RlbXMgSW5jb3Jw" + + "b3JhdGVkMR0wGwYDVQQLExRBZG9iZSBUcnVzdCBTZXJ2aWNlczEWMBQGA1UE" + + "AxMNQWRvYmUgUm9vdCBDQTENMAsGA1UEAxMEQ1JMMTALBgNVHQ8EBAMCAQYw" + + "HwYDVR0jBBgwFoAUgrc4SpOqmxDvgLvZVOLxD/uAnN4wHQYDVR0OBBYEFKuA" + + "WcNlg20dfRO9GcPsGo8NR2qjMBkGCSqGSIb2fQdBAAQMMAobBFY2LjADAgSQ" + + "MA0GCSqGSIb3DQEBBQUAA4IBAQA/OVkuogCOsV4RYSzS4Lb1jImGRc4T2Z/d" + + "hJoUawhMX4aXWPSlqNOPIfhHflCvd+Whbarcd83NN5n3QmevUOFUREPrMQyA" + + "mkK0mpW6TSyLG5ckeCFL8qJwp/hhckk/H16m4hEXWyIFGfOecX3Sy+Y4kxcC" + + "lzSMadifedB+TiRpKFKcNphp5hEMkpyyJaGXpLnN/BLsaDyEN7JySExAopae" + + "UbUJCvCVIWKwoJ26ih3BG1aB+3yTHXeLIorextqWbq+dVz7me59Li8j5PAxe" + + "hXrc2phpKuhp8FaTScvnfMZc8TL4Dr1CHMRWIkqfZaCq3mC376Mww0iZtE5s" + + "iqB+AXVWMYIBgDCCAXwCAQEwSzBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN" + + "R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgQ0EgZm9yIEFkb2Jl" + + "AgIAjzAJBgUrDgMCGgUAoIGMMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB" + + "BDAcBgkqhkiG9w0BCQUxDxcNMDYwNDA0MjAyMDU3WjAjBgkqhkiG9w0BCQQx" + + "FgQUp7AnXBqoNcarvO7fMJut1og2U5AwKwYLKoZIhvcNAQkQAgwxHDAaMBgw" + + "FgQU1dH4eZTNhgxdiSABrat6zsPdth0wDQYJKoZIhvcNAQEBBQAEgYCinr/F" + + "rMiQz/MRm9ZD5YGcC0Qo2dRTPd0Aop8mZ4g1xAhKFLnp7lLsjCbkSDpVLDBh" + + "cnCk7CV+3FT5hlvt8OqZlR0CnkSnCswLFhrppiWle6cpxlwGqyAteC8uKtQu" + + "wjE5GtBKLcCOAzQYyyuNZZeB6oCZ+3mPhZ62FxrvvEGJCgAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); + + private static readonly byte[] emptyDNCert = Base64.Decode( + "MIICfTCCAeagAwIBAgIBajANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJVUzEMMAoGA1UEChMD" + + "Q0RXMQkwBwYDVQQLEwAxCTAHBgNVBAcTADEJMAcGA1UECBMAMRowGAYDVQQDExFUZW1wbGFyIFRl" + + "c3QgMTAyNDEiMCAGCSqGSIb3DQEJARYTdGVtcGxhcnRlc3RAY2R3LmNvbTAeFw0wNjA1MjIwNTAw" + + "MDBaFw0xMDA1MjIwNTAwMDBaMHwxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNDRFcxCTAHBgNVBAsT" + + "ADEJMAcGA1UEBxMAMQkwBwYDVQQIEwAxGjAYBgNVBAMTEVRlbXBsYXIgVGVzdCAxMDI0MSIwIAYJ" + + "KoZIhvcNAQkBFhN0ZW1wbGFydGVzdEBjZHcuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" + + "gQDH3aJpJBfM+A3d84j5YcU6zEQaQ76u5xO9NSBmHjZykKS2kCcUqPpvVOPDA5WgV22dtKPh+lYV" + + "iUp7wyCVwAKibq8HIbihHceFqMKzjwC639rMoDJ7bi/yzQWz1Zg+075a4FGPlUKn7Yfu89wKkjdW" + + "wDpRPXc/agqBnrx5pJTXzQIDAQABow8wDTALBgNVHQ8EBAMCALEwDQYJKoZIhvcNAQEEBQADgYEA" + + "RRsRsjse3i2/KClFVd6YLZ+7K1BE0WxFyY2bbytkwQJSxvv3vLSuweFUbhNxutb68wl/yW4GLy4b" + + "1QdyswNxrNDXTuu5ILKhRDDuWeocz83aG2KGtr3JlFyr3biWGEyn5WUOE6tbONoQDJ0oPYgI6CAc" + + "EHdUp0lioOCt6UOw7Cs="); + + private static readonly byte[] gostRFC4491_94 = Base64.Decode( + "MIICCzCCAboCECMO42BGlSTOxwvklBgufuswCAYGKoUDAgIEMGkxHTAbBgNVBAMM" + "FEdvc3RSMzQxMC05NCBleGFtcGxlMRIwEAYDVQQKDAlDcnlwdG9Qcm8xCzAJBgNV" + "BAYTAlJVMScwJQYJKoZIhvcNAQkBFhhHb3N0UjM0MTAtOTRAZXhhbXBsZS5jb20w" + "HhcNMDUwODE2MTIzMjUwWhcNMTUwODE2MTIzMjUwWjBpMR0wGwYDVQQDDBRHb3N0" + @@ -964,7 +964,7 @@ namespace Org.BouncyCastle.Tests "eMG1wra3Gqgqi0WBkzIydvp7MAgGBiqFAwICBANBABHHCH4S3ALxAiMpR3aPRyqB" + "g1DjB8zy5DEjiULIc+HeIveF81W9lOxGkZxnrFjXBSqnjLeFKgF1hffXOAP7zUM="); - private static readonly byte[] gostRFC4491_2001 = Base64.Decode( + private static readonly byte[] gostRFC4491_2001 = Base64.Decode( "MIIB0DCCAX8CECv1xh7CEb0Xx9zUYma0LiEwCAYGKoUDAgIDMG0xHzAdBgNVBAMM" + "Fkdvc3RSMzQxMC0yMDAxIGV4YW1wbGUxEjAQBgNVBAoMCUNyeXB0b1BybzELMAkG" + "A1UEBhMCUlUxKTAnBgkqhkiG9w0BCQEWGkdvc3RSMzQxMC0yMDAxQGV4YW1wbGUu" + @@ -976,153 +976,153 @@ namespace Org.BouncyCastle.Tests "D2a8yuoaYDAIBgYqhQMCAgMDQQA8L8kJRLcnqeyn1en7U23Sw6pkfEQu3u0xFkVP" + "vFQ/3cHeF26NG+xxtZPz3TaTVXdoiYkXYiD02rEx1bUcM97i"); - private class DudPublicKey - : AsymmetricKeyParameter - { - public DudPublicKey() - : base(false) - { - } - - public string Algorithm - { - get { return null; } - } - - public string Format - { - get { return null; } - } - - public byte[] GetEncoded() - { - return null; - } - } - - private AsymmetricKeyParameter dudPublicKey = new DudPublicKey(); - - public override string Name - { - get { return "CertTest"; } - } - - internal void checkCertificate( - int id, - byte[] bytes) - { - string dump = ""; - - try - { - X509Certificate cert = new X509CertificateParser().ReadCertificate(bytes); - - AsymmetricKeyParameter k = cert.GetPublicKey(); - // Console.WriteLine(cert); - } - catch (Exception e) - { - Fail(dump + SimpleTest.NewLine + Name + ": "+ id + " failed - exception " + e.Message, e); - } - } - - internal void checkNameCertificate( - int id, - byte[] bytes) - { - string dump = ""; - - try - { - X509Certificate cert = new X509CertificateParser().ReadCertificate(bytes); - - AsymmetricKeyParameter k = cert.GetPublicKey(); - if (!cert.IssuerDN.ToString().Equals("C=DE,O=DATEV eG,0.2.262.1.10.7.20=1+CN=CA DATEV D03 1:PN")) - { - Fail(id + " failed - name test."); - } - // Console.WriteLine(cert); - } - catch (Exception e) - { - Fail(dump + SimpleTest.NewLine + Name + ": "+ id + " failed - exception " + e.Message, e); - } - - } - - internal void checkKeyUsage( - int id, - byte[] bytes) - { - string dump = ""; - - try - { - X509Certificate cert = new X509CertificateParser().ReadCertificate(bytes); - - AsymmetricKeyParameter k = cert.GetPublicKey(); - - if (cert.GetKeyUsage()[7]) - { - Fail("error generating cert - key usage wrong."); - } - - // Console.WriteLine(cert); - } - catch (Exception e) - { - Fail(dump + SimpleTest.NewLine + Name + ": "+ id + " failed - exception " + e.Message, e); - } - - } - - internal void checkSelfSignedCertificate( - int id, - byte[] bytes) - { - string dump = ""; - - try - { - X509Certificate cert = new X509CertificateParser().ReadCertificate(bytes); - - AsymmetricKeyParameter k = cert.GetPublicKey(); - - cert.Verify(k); - // Console.WriteLine(cert); - } - catch (Exception e) - { - Fail(dump + SimpleTest.NewLine + Name + ": "+ id + " failed - exception " + e.Message, e); - } - } - - /** - * we Generate a self signed certificate for the sake of testing - RSA - */ - internal void checkCreation1() - { - // - // a sample key pair. - // - RsaKeyParameters pubKey = new RsaKeyParameters( - false, - new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), - new BigInteger("11", 16)); - - RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters( - new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), - new BigInteger("11", 16), - new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), - new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), - new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), - new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), - new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), - new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); - - // - // set up the keys - // + private class DudPublicKey + : AsymmetricKeyParameter + { + public DudPublicKey() + : base(false) + { + } + + public string Algorithm + { + get { return null; } + } + + public string Format + { + get { return null; } + } + + public byte[] GetEncoded() + { + return null; + } + } + + private AsymmetricKeyParameter dudPublicKey = new DudPublicKey(); + + public override string Name + { + get { return "CertTest"; } + } + + internal void checkCertificate( + int id, + byte[] bytes) + { + string dump = ""; + + try + { + X509Certificate cert = new X509CertificateParser().ReadCertificate(bytes); + + AsymmetricKeyParameter k = cert.GetPublicKey(); + // Console.WriteLine(cert); + } + catch (Exception e) + { + Fail(dump + SimpleTest.NewLine + Name + ": "+ id + " failed - exception " + e.Message, e); + } + } + + internal void checkNameCertificate( + int id, + byte[] bytes) + { + string dump = ""; + + try + { + X509Certificate cert = new X509CertificateParser().ReadCertificate(bytes); + + AsymmetricKeyParameter k = cert.GetPublicKey(); + if (!cert.IssuerDN.ToString().Equals("C=DE,O=DATEV eG,0.2.262.1.10.7.20=1+CN=CA DATEV D03 1:PN")) + { + Fail(id + " failed - name test."); + } + // Console.WriteLine(cert); + } + catch (Exception e) + { + Fail(dump + SimpleTest.NewLine + Name + ": "+ id + " failed - exception " + e.Message, e); + } + + } + + internal void checkKeyUsage( + int id, + byte[] bytes) + { + string dump = ""; + + try + { + X509Certificate cert = new X509CertificateParser().ReadCertificate(bytes); + + AsymmetricKeyParameter k = cert.GetPublicKey(); + + if (cert.GetKeyUsage()[7]) + { + Fail("error generating cert - key usage wrong."); + } + + // Console.WriteLine(cert); + } + catch (Exception e) + { + Fail(dump + SimpleTest.NewLine + Name + ": "+ id + " failed - exception " + e.Message, e); + } + + } + + internal void checkSelfSignedCertificate( + int id, + byte[] bytes) + { + string dump = ""; + + try + { + X509Certificate cert = new X509CertificateParser().ReadCertificate(bytes); + + AsymmetricKeyParameter k = cert.GetPublicKey(); + + cert.Verify(k); + // Console.WriteLine(cert); + } + catch (Exception e) + { + Fail(dump + SimpleTest.NewLine + Name + ": "+ id + " failed - exception " + e.Message, e); + } + } + + /** + * we Generate a self signed certificate for the sake of testing - RSA + */ + internal void checkCreation1() + { + // + // a sample key pair. + // + RsaKeyParameters pubKey = new RsaKeyParameters( + false, + new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), + new BigInteger("11", 16)); + + RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters( + new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), + new BigInteger("11", 16), + new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), + new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), + new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), + new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), + new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), + new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); + + // + // set up the keys + // // AsymmetricKeyParameter privKey; // AsymmetricKeyParameter pubKey; @@ -1131,288 +1131,288 @@ namespace Org.BouncyCastle.Tests // privKey = fact.generatePrivate(privKeySpec); // pubKey = fact.generatePublic(pubKeySpec); - // - // distinguished name table. - // - IList ord = new ArrayList(); - ord.Add(X509Name.C); - ord.Add(X509Name.O); - ord.Add(X509Name.L); - ord.Add(X509Name.ST); - ord.Add(X509Name.E); - - IList values = new ArrayList(); - values.Add("AU"); - values.Add("The Legion of the Bouncy Castle"); - values.Add("Melbourne"); - values.Add("Victoria"); - values.Add("feedback-crypto@bouncycastle.org"); - - // - // extensions - // - - // - // create the certificate - version 3 - without extensions - // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.SetSerialNumber(BigInteger.One); - certGen.SetIssuerDN(new X509Name(ord, values)); - certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen.SetSubjectDN(new X509Name(ord, values)); - certGen.SetPublicKey(pubKey); - certGen.SetSignatureAlgorithm("SHA256WithRSAEncryption"); - - X509Certificate cert = certGen.Generate(privKey); - - cert.CheckValidity(DateTime.UtcNow); - - cert.Verify(pubKey); - - ISet dummySet = cert.GetNonCriticalExtensionOids(); - if (dummySet != null) - { - Fail("non-critical oid set should be null"); - } - dummySet = cert.GetCriticalExtensionOids(); - if (dummySet != null) - { - Fail("critical oid set should be null"); - } - - // - // create the certificate - version 3 - with extensions - // - certGen = new X509V3CertificateGenerator(); - - certGen.SetSerialNumber(BigInteger.One); - certGen.SetIssuerDN(new X509Name(ord, values)); - certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen.SetSubjectDN(new X509Name(ord, values)); - certGen.SetPublicKey(pubKey); - certGen.SetSignatureAlgorithm("MD5WithRSAEncryption"); - certGen.AddExtension("2.5.29.15", true, - new X509KeyUsage(X509KeyUsage.EncipherOnly)); - certGen.AddExtension("2.5.29.37", true, - new DerSequence(KeyPurposeID.AnyExtendedKeyUsage)); - certGen.AddExtension("2.5.29.17", true, - new GeneralNames(new GeneralName(GeneralName.Rfc822Name, "test@test.test"))); - - cert = certGen.Generate(privKey); - - cert.CheckValidity(DateTime.UtcNow); - - cert.Verify(pubKey); - - cert = new X509CertificateParser().ReadCertificate(cert.GetEncoded()); - - if (!cert.GetKeyUsage()[7]) - { - Fail("error generating cert - key usage wrong."); - } - - IList l = cert.GetExtendedKeyUsage(); - if (!l[0].Equals(KeyPurposeID.AnyExtendedKeyUsage.Id)) - { - Fail("failed extended key usage test"); - } - - foreach (IList gn in cert.GetSubjectAlternativeNames()) - { - if (!gn[1].Equals("test@test.test")) - { - Fail("failed subject alternative names test"); - } - } - - // Console.WriteLine(cert); - - // - // create the certificate - version 1 - // - X509V1CertificateGenerator certGen1 = new X509V1CertificateGenerator(); - - certGen1.SetSerialNumber(BigInteger.One); - certGen1.SetIssuerDN(new X509Name(ord, values)); - certGen1.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen1.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen1.SetSubjectDN(new X509Name(ord, values)); - certGen1.SetPublicKey(pubKey); - certGen1.SetSignatureAlgorithm("MD5WithRSAEncryption"); - - cert = certGen1.Generate(privKey); - - cert.CheckValidity(DateTime.UtcNow); - - cert.Verify(pubKey); - - cert = new X509CertificateParser().ReadCertificate(cert.GetEncoded()); - - // Console.WriteLine(cert); - if (!cert.IssuerDN.Equivalent(cert.SubjectDN)) - { - Fail("name comparison fails"); - } - } - - /** - * we Generate a self signed certificate for the sake of testing - DSA - */ - internal void checkCreation2() - { - // - // set up the keys - // - AsymmetricKeyParameter privKey; - AsymmetricKeyParameter pubKey; - - try - { + // + // distinguished name table. + // + IList ord = new ArrayList(); + ord.Add(X509Name.C); + ord.Add(X509Name.O); + ord.Add(X509Name.L); + ord.Add(X509Name.ST); + ord.Add(X509Name.E); + + IList values = new ArrayList(); + values.Add("AU"); + values.Add("The Legion of the Bouncy Castle"); + values.Add("Melbourne"); + values.Add("Victoria"); + values.Add("feedback-crypto@bouncycastle.org"); + + // + // extensions + // + + // + // create the certificate - version 3 - without extensions + // + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + + certGen.SetSerialNumber(BigInteger.One); + certGen.SetIssuerDN(new X509Name(ord, values)); + certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen.SetSubjectDN(new X509Name(ord, values)); + certGen.SetPublicKey(pubKey); + certGen.SetSignatureAlgorithm("SHA256WithRSAEncryption"); + + X509Certificate cert = certGen.Generate(privKey); + + cert.CheckValidity(DateTime.UtcNow); + + cert.Verify(pubKey); + + ISet dummySet = cert.GetNonCriticalExtensionOids(); + if (dummySet != null) + { + Fail("non-critical oid set should be null"); + } + dummySet = cert.GetCriticalExtensionOids(); + if (dummySet != null) + { + Fail("critical oid set should be null"); + } + + // + // create the certificate - version 3 - with extensions + // + certGen = new X509V3CertificateGenerator(); + + certGen.SetSerialNumber(BigInteger.One); + certGen.SetIssuerDN(new X509Name(ord, values)); + certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen.SetSubjectDN(new X509Name(ord, values)); + certGen.SetPublicKey(pubKey); + certGen.SetSignatureAlgorithm("MD5WithRSAEncryption"); + certGen.AddExtension("2.5.29.15", true, + new X509KeyUsage(X509KeyUsage.EncipherOnly)); + certGen.AddExtension("2.5.29.37", true, + new DerSequence(KeyPurposeID.AnyExtendedKeyUsage)); + certGen.AddExtension("2.5.29.17", true, + new GeneralNames(new GeneralName(GeneralName.Rfc822Name, "test@test.test"))); + + cert = certGen.Generate(privKey); + + cert.CheckValidity(DateTime.UtcNow); + + cert.Verify(pubKey); + + cert = new X509CertificateParser().ReadCertificate(cert.GetEncoded()); + + if (!cert.GetKeyUsage()[7]) + { + Fail("error generating cert - key usage wrong."); + } + + IList l = cert.GetExtendedKeyUsage(); + if (!l[0].Equals(KeyPurposeID.AnyExtendedKeyUsage.Id)) + { + Fail("failed extended key usage test"); + } + + foreach (IList gn in cert.GetSubjectAlternativeNames()) + { + if (!gn[1].Equals("test@test.test")) + { + Fail("failed subject alternative names test"); + } + } + + // Console.WriteLine(cert); + + // + // create the certificate - version 1 + // + X509V1CertificateGenerator certGen1 = new X509V1CertificateGenerator(); + + certGen1.SetSerialNumber(BigInteger.One); + certGen1.SetIssuerDN(new X509Name(ord, values)); + certGen1.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen1.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen1.SetSubjectDN(new X509Name(ord, values)); + certGen1.SetPublicKey(pubKey); + certGen1.SetSignatureAlgorithm("MD5WithRSAEncryption"); + + cert = certGen1.Generate(privKey); + + cert.CheckValidity(DateTime.UtcNow); + + cert.Verify(pubKey); + + cert = new X509CertificateParser().ReadCertificate(cert.GetEncoded()); + + // Console.WriteLine(cert); + if (!cert.IssuerDN.Equivalent(cert.SubjectDN)) + { + Fail("name comparison fails"); + } + } + + /** + * we Generate a self signed certificate for the sake of testing - DSA + */ + internal void checkCreation2() + { + // + // set up the keys + // + AsymmetricKeyParameter privKey; + AsymmetricKeyParameter pubKey; + + try + { // KeyPairGenerator g = KeyPairGenerator.GetInstance("DSA", "SUN"); // g.initialize(512, new SecureRandom()); // KeyPair p = g.generateKeyPair(); - IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("DSA"); - DsaParametersGenerator dpg = new DsaParametersGenerator(); - dpg.Init(512, 25, new SecureRandom()); - g.Init(new DsaKeyGenerationParameters(new SecureRandom(), dpg.GenerateParameters())); - AsymmetricCipherKeyPair p = g.GenerateKeyPair(); - - privKey = p.Private; - pubKey = p.Public; - } - catch (Exception e) - { - Fail("error setting up keys - " + e.ToString()); - return; - } - - // - // distinguished name table. - // - IList ord = new ArrayList(); - ord.Add(X509Name.C); - ord.Add(X509Name.O); - ord.Add(X509Name.L); - ord.Add(X509Name.ST); - ord.Add(X509Name.E); - - IList values = new ArrayList(); - values.Add("AU"); - values.Add("The Legion of the Bouncy Castle"); - values.Add("Melbourne"); - values.Add("Victoria"); - values.Add("feedback-crypto@bouncycastle.org"); - - // - // extensions - // - - // - // create the certificate - version 3 - // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.SetSerialNumber(BigInteger.One); - certGen.SetIssuerDN(new X509Name(ord, values)); - certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen.SetSubjectDN(new X509Name(ord, values)); - certGen.SetPublicKey(pubKey); - certGen.SetSignatureAlgorithm("SHA1withDSA"); - - try - { - X509Certificate cert = certGen.Generate(privKey); - - cert.CheckValidity(DateTime.UtcNow); - - cert.Verify(pubKey); - - cert = new X509CertificateParser().ReadCertificate(cert.GetEncoded()); - - // Console.WriteLine(cert); - } - catch (Exception e) - { - Fail("error setting generating cert - " + e.ToString()); - } - - // - // create the certificate - version 1 - // - X509V1CertificateGenerator certGen1 = new X509V1CertificateGenerator(); - - certGen1.SetSerialNumber(BigInteger.One); - certGen1.SetIssuerDN(new X509Name(ord, values)); - certGen1.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen1.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen1.SetSubjectDN(new X509Name(ord, values)); - certGen1.SetPublicKey(pubKey); - certGen1.SetSignatureAlgorithm("SHA1withDSA"); - - try - { - X509Certificate cert = certGen1.Generate(privKey); - - cert.CheckValidity(DateTime.UtcNow); - - cert.Verify(pubKey); - - cert = new X509CertificateParser().ReadCertificate(cert.GetEncoded()); - - //Console.WriteLine(cert); - } - catch (Exception e) - { - Fail("error setting generating cert - " + e.ToString()); - } - - // - // exception test - // - try - { - certGen.SetPublicKey(dudPublicKey); - - Fail("key without encoding not detected in v1"); - } - catch (ArgumentException) - { - // expected - } - } - - /** - * we Generate a self signed certificate for the sake of testing - ECDSA - */ - internal void checkCreation3() - { - 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 privKey = new ECPrivateKeyParameters( - "ECDSA", - new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d - spec); - - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( - "ECDSA", - curve.DecodePoint(Hex.Decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q - spec); - - // - // set up the keys - // + IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("DSA"); + DsaParametersGenerator dpg = new DsaParametersGenerator(); + dpg.Init(512, 25, new SecureRandom()); + g.Init(new DsaKeyGenerationParameters(new SecureRandom(), dpg.GenerateParameters())); + AsymmetricCipherKeyPair p = g.GenerateKeyPair(); + + privKey = p.Private; + pubKey = p.Public; + } + catch (Exception e) + { + Fail("error setting up keys - " + e.ToString()); + return; + } + + // + // distinguished name table. + // + IList ord = new ArrayList(); + ord.Add(X509Name.C); + ord.Add(X509Name.O); + ord.Add(X509Name.L); + ord.Add(X509Name.ST); + ord.Add(X509Name.E); + + IList values = new ArrayList(); + values.Add("AU"); + values.Add("The Legion of the Bouncy Castle"); + values.Add("Melbourne"); + values.Add("Victoria"); + values.Add("feedback-crypto@bouncycastle.org"); + + // + // extensions + // + + // + // create the certificate - version 3 + // + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + + certGen.SetSerialNumber(BigInteger.One); + certGen.SetIssuerDN(new X509Name(ord, values)); + certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen.SetSubjectDN(new X509Name(ord, values)); + certGen.SetPublicKey(pubKey); + certGen.SetSignatureAlgorithm("SHA1withDSA"); + + try + { + X509Certificate cert = certGen.Generate(privKey); + + cert.CheckValidity(DateTime.UtcNow); + + cert.Verify(pubKey); + + cert = new X509CertificateParser().ReadCertificate(cert.GetEncoded()); + + // Console.WriteLine(cert); + } + catch (Exception e) + { + Fail("error setting generating cert - " + e.ToString()); + } + + // + // create the certificate - version 1 + // + X509V1CertificateGenerator certGen1 = new X509V1CertificateGenerator(); + + certGen1.SetSerialNumber(BigInteger.One); + certGen1.SetIssuerDN(new X509Name(ord, values)); + certGen1.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen1.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen1.SetSubjectDN(new X509Name(ord, values)); + certGen1.SetPublicKey(pubKey); + certGen1.SetSignatureAlgorithm("SHA1withDSA"); + + try + { + X509Certificate cert = certGen1.Generate(privKey); + + cert.CheckValidity(DateTime.UtcNow); + + cert.Verify(pubKey); + + cert = new X509CertificateParser().ReadCertificate(cert.GetEncoded()); + + //Console.WriteLine(cert); + } + catch (Exception e) + { + Fail("error setting generating cert - " + e.ToString()); + } + + // + // exception test + // + try + { + certGen.SetPublicKey(dudPublicKey); + + Fail("key without encoding not detected in v1"); + } + catch (ArgumentException) + { + // expected + } + } + + /** + * we Generate a self signed certificate for the sake of testing - ECDSA + */ + internal void checkCreation3() + { + 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 privKey = new ECPrivateKeyParameters( + "ECDSA", + new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d + spec); + + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + "ECDSA", + curve.DecodePoint(Hex.Decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q + spec); + + // + // set up the keys + // // AsymmetricKeyParameter privKey; // AsymmetricKeyParameter pubKey; // @@ -1429,130 +1429,130 @@ namespace Org.BouncyCastle.Tests // return; // } - // - // distinguished name table. - // - IDictionary attrs = new Hashtable(); - IList order = new ArrayList(); - - attrs.Add(X509Name.C, "AU"); - attrs.Add(X509Name.O, "The Legion of the Bouncy Castle"); - attrs.Add(X509Name.L, "Melbourne"); - attrs.Add(X509Name.ST, "Victoria"); - attrs.Add(X509Name.E, "feedback-crypto@bouncycastle.org"); - - order.Add(X509Name.C); - order.Add(X509Name.O); - order.Add(X509Name.L); - order.Add(X509Name.ST); - order.Add(X509Name.E); - - - // - // ToString test - // - X509Name p = new X509Name(order, attrs); - string s = p.ToString(); - - if (!s.Equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne,ST=Victoria,E=feedback-crypto@bouncycastle.org")) - { - Fail("ordered X509Principal test failed - s = " + s + "."); - } - - // - // create the certificate - version 3 - // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.SetSerialNumber(BigInteger.One); - certGen.SetIssuerDN(new X509Name(order, attrs)); - certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen.SetSubjectDN(new X509Name(order, attrs)); - certGen.SetPublicKey(pubKey); - certGen.SetSignatureAlgorithm("SHA1withECDSA"); - - try - { - X509Certificate cert = certGen.Generate(privKey); - - cert.CheckValidity(DateTime.UtcNow); - - cert.Verify(pubKey); - - X509CertificateParser fact = new X509CertificateParser(); - cert = fact.ReadCertificate(cert.GetEncoded()); - - // - // try with point compression turned off - // + // + // distinguished name table. + // + IDictionary attrs = new Hashtable(); + IList order = new ArrayList(); + + attrs.Add(X509Name.C, "AU"); + attrs.Add(X509Name.O, "The Legion of the Bouncy Castle"); + attrs.Add(X509Name.L, "Melbourne"); + attrs.Add(X509Name.ST, "Victoria"); + attrs.Add(X509Name.E, "feedback-crypto@bouncycastle.org"); + + order.Add(X509Name.C); + order.Add(X509Name.O); + order.Add(X509Name.L); + order.Add(X509Name.ST); + order.Add(X509Name.E); + + + // + // ToString test + // + X509Name p = new X509Name(order, attrs); + string s = p.ToString(); + + if (!s.Equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne,ST=Victoria,E=feedback-crypto@bouncycastle.org")) + { + Fail("ordered X509Principal test failed - s = " + s + "."); + } + + // + // create the certificate - version 3 + // + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + + certGen.SetSerialNumber(BigInteger.One); + certGen.SetIssuerDN(new X509Name(order, attrs)); + certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen.SetSubjectDN(new X509Name(order, attrs)); + certGen.SetPublicKey(pubKey); + certGen.SetSignatureAlgorithm("SHA1withECDSA"); + + try + { + X509Certificate cert = certGen.Generate(privKey); + + cert.CheckValidity(DateTime.UtcNow); + + cert.Verify(pubKey); + + X509CertificateParser fact = new X509CertificateParser(); + cert = fact.ReadCertificate(cert.GetEncoded()); + + // + // try with point compression turned off + // // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); - FpPoint q = (FpPoint) pubKey.Q; - pubKey = new ECPublicKeyParameters( - pubKey.AlgorithmName, - new FpPoint(q.Curve, q.X, q.Y, false), - pubKey.Parameters); - - certGen.SetPublicKey(pubKey); - - cert = certGen.Generate(privKey); - - cert.CheckValidity(DateTime.UtcNow); - - cert.Verify(pubKey); - - cert = fact.ReadCertificate(cert.GetEncoded()); - - // Console.WriteLine(cert); - } - catch (Exception e) - { - Fail("error setting generating cert - " + e.ToString()); - } - - X509Name pr = new X509Name("O=\"The Bouncy Castle, The Legion of\",E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); - - if (!pr.ToString().Equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) - { - Fail("string based X509Principal test failed."); - } - - pr = new X509Name("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); - - if (!pr.ToString().Equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) - { - Fail("string based X509Principal test failed."); - } - } - - /** - * we Generate a self signed certificate for the sake of testing - SHA224withECDSA - */ - private void createECCert( - string algorithm, - DerObjectIdentifier algOid) - { - FpCurve curve = new FpCurve( - new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) - new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a - new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b - - ECDomainParameters spec = new ECDomainParameters( - curve, + ECPoint q = pubKey.Q.Normalize(); + pubKey = new ECPublicKeyParameters( + pubKey.AlgorithmName, + q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger(), false), + pubKey.Parameters); + + certGen.SetPublicKey(pubKey); + + cert = certGen.Generate(privKey); + + cert.CheckValidity(DateTime.UtcNow); + + cert.Verify(pubKey); + + cert = fact.ReadCertificate(cert.GetEncoded()); + + // Console.WriteLine(cert); + } + catch (Exception e) + { + Fail("error setting generating cert - " + e.ToString()); + } + + X509Name pr = new X509Name("O=\"The Bouncy Castle, The Legion of\",E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); + + if (!pr.ToString().Equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) + { + Fail("string based X509Principal test failed."); + } + + pr = new X509Name("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU"); + + if (!pr.ToString().Equals("O=The Bouncy Castle\\, The Legion of,E=feedback-crypto@bouncycastle.org,ST=Victoria,L=Melbourne,C=AU")) + { + Fail("string based X509Principal test failed."); + } + } + + /** + * we Generate a self signed certificate for the sake of testing - SHA224withECDSA + */ + private void createECCert( + string algorithm, + DerObjectIdentifier algOid) + { + FpCurve curve = new FpCurve( + new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) + new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a + new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b + + ECDomainParameters spec = new ECDomainParameters( + curve, // curve.DecodePoint(Hex.Decode("02C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G - curve.DecodePoint(Hex.Decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G - new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n + curve.DecodePoint(Hex.Decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G + new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n - ECPrivateKeyParameters privKey = new ECPrivateKeyParameters( - "ECDSA", - new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d - spec); + ECPrivateKeyParameters privKey = new ECPrivateKeyParameters( + "ECDSA", + new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d + spec); - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( - "ECDSA", + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + "ECDSA", // curve.DecodePoint(Hex.Decode("026BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q - curve.DecodePoint(Hex.Decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q - spec); + curve.DecodePoint(Hex.Decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q + spec); // // // // set up the keys @@ -1566,528 +1566,528 @@ namespace Org.BouncyCastle.Tests // pubKey = fact.generatePublic(pubKeySpec); - // - // distinguished name table. - // - IDictionary attrs = new Hashtable(); - IList order = new ArrayList(); + // + // distinguished name table. + // + IDictionary attrs = new Hashtable(); + IList order = new ArrayList(); - attrs.Add(X509Name.C, "AU"); - attrs.Add(X509Name.O, "The Legion of the Bouncy Castle"); - attrs.Add(X509Name.L, "Melbourne"); - attrs.Add(X509Name.ST, "Victoria"); - attrs.Add(X509Name.E, "feedback-crypto@bouncycastle.org"); + attrs.Add(X509Name.C, "AU"); + attrs.Add(X509Name.O, "The Legion of the Bouncy Castle"); + attrs.Add(X509Name.L, "Melbourne"); + attrs.Add(X509Name.ST, "Victoria"); + attrs.Add(X509Name.E, "feedback-crypto@bouncycastle.org"); - order.Add(X509Name.C); - order.Add(X509Name.O); - order.Add(X509Name.L); - order.Add(X509Name.ST); - order.Add(X509Name.E); + order.Add(X509Name.C); + order.Add(X509Name.O); + order.Add(X509Name.L); + order.Add(X509Name.ST); + order.Add(X509Name.E); - // - // create the certificate - version 3 - // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + // + // create the certificate - version 3 + // + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - certGen.SetSerialNumber(BigInteger.One); - certGen.SetIssuerDN(new X509Name(order, attrs)); - certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen.SetSubjectDN(new X509Name(order, attrs)); - certGen.SetPublicKey(pubKey); - certGen.SetSignatureAlgorithm(algorithm); + certGen.SetSerialNumber(BigInteger.One); + certGen.SetIssuerDN(new X509Name(order, attrs)); + certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen.SetSubjectDN(new X509Name(order, attrs)); + certGen.SetPublicKey(pubKey); + certGen.SetSignatureAlgorithm(algorithm); - X509Certificate cert = certGen.Generate(privKey); + X509Certificate cert = certGen.Generate(privKey); - cert.CheckValidity(DateTime.UtcNow); + cert.CheckValidity(DateTime.UtcNow); - cert.Verify(pubKey); + cert.Verify(pubKey); - X509CertificateParser fact = new X509CertificateParser(); - cert = fact.ReadCertificate(cert.GetEncoded()); + X509CertificateParser fact = new X509CertificateParser(); + cert = fact.ReadCertificate(cert.GetEncoded()); - // - // try with point compression turned off - // + // + // try with point compression turned off + // // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); - FpPoint q = (FpPoint) pubKey.Q; - pubKey = new ECPublicKeyParameters( - pubKey.AlgorithmName, - new FpPoint(q.Curve, q.X, q.Y, false), - pubKey.Parameters); + ECPoint q = pubKey.Q.Normalize(); + pubKey = new ECPublicKeyParameters( + pubKey.AlgorithmName, + q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger(), false), + pubKey.Parameters); - certGen.SetPublicKey(pubKey); + certGen.SetPublicKey(pubKey); - cert = certGen.Generate(privKey); + cert = certGen.Generate(privKey); - cert.CheckValidity(DateTime.UtcNow); + cert.CheckValidity(DateTime.UtcNow); - cert.Verify(pubKey); + cert.Verify(pubKey); - cert = fact.ReadCertificate(cert.GetEncoded()); + cert = fact.ReadCertificate(cert.GetEncoded()); - if (!cert.SigAlgOid.Equals(algOid.ToString())) - { - Fail("ECDSA oid incorrect."); - } + if (!cert.SigAlgOid.Equals(algOid.ToString())) + { + Fail("ECDSA oid incorrect."); + } - if (cert.GetSigAlgParams() != null) - { - Fail("sig parameters present"); - } + if (cert.GetSigAlgParams() != null) + { + Fail("sig parameters present"); + } - ISigner sig = SignerUtilities.GetSigner(algorithm); + ISigner sig = SignerUtilities.GetSigner(algorithm); - sig.Init(false, pubKey); + sig.Init(false, pubKey); - byte[] b = cert.GetTbsCertificate(); - sig.BlockUpdate(b, 0, b.Length); + byte[] b = cert.GetTbsCertificate(); + sig.BlockUpdate(b, 0, b.Length); - if (!sig.VerifySignature(cert.GetSignature())) - { - Fail("EC certificate signature not mapped correctly."); - } - // Console.WriteLine(cert); - } + if (!sig.VerifySignature(cert.GetSignature())) + { + Fail("EC certificate signature not mapped correctly."); + } + // Console.WriteLine(cert); + } - private void checkCrl( - int id, - byte[] bytes) - { - string dump = ""; + private void checkCrl( + int id, + byte[] bytes) + { + string dump = ""; - try - { - X509Crl cert = new X509CrlParser().ReadCrl(bytes); + try + { + X509Crl cert = new X509CrlParser().ReadCrl(bytes); - // Console.WriteLine(cert); - } - catch (Exception e) - { - Fail(dump + SimpleTest.NewLine + Name + ": "+ id + " failed - exception " + e.Message, e); - } + // Console.WriteLine(cert); + } + catch (Exception e) + { + Fail(dump + SimpleTest.NewLine + Name + ": "+ id + " failed - exception " + e.Message, e); + } - } + } - private void checkCrlCreation1() - { - IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA"); - kpGen.Init( - new RsaKeyGenerationParameters( - BigInteger.ValueOf(0x10001), new SecureRandom(), 768, 25)); + private void checkCrlCreation1() + { + IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA"); + kpGen.Init( + new RsaKeyGenerationParameters( + BigInteger.ValueOf(0x10001), new SecureRandom(), 768, 25)); - X509V2CrlGenerator crlGen = new X509V2CrlGenerator(); - DateTime now = DateTime.UtcNow; - AsymmetricCipherKeyPair pair = kpGen.GenerateKeyPair(); + X509V2CrlGenerator crlGen = new X509V2CrlGenerator(); + DateTime now = DateTime.UtcNow; + AsymmetricCipherKeyPair pair = kpGen.GenerateKeyPair(); - crlGen.SetIssuerDN(new X509Name("CN=Test CA")); + crlGen.SetIssuerDN(new X509Name("CN=Test CA")); - crlGen.SetThisUpdate(now); - crlGen.SetNextUpdate(now.AddSeconds(100)); - crlGen.SetSignatureAlgorithm("SHA256WithRSAEncryption"); + crlGen.SetThisUpdate(now); + crlGen.SetNextUpdate(now.AddSeconds(100)); + crlGen.SetSignatureAlgorithm("SHA256WithRSAEncryption"); - crlGen.AddCrlEntry(BigInteger.One, now, CrlReason.PrivilegeWithdrawn); + crlGen.AddCrlEntry(BigInteger.One, now, CrlReason.PrivilegeWithdrawn); - crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, - new AuthorityKeyIdentifierStructure(pair.Public)); + crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, + new AuthorityKeyIdentifierStructure(pair.Public)); - X509Crl crl = crlGen.Generate(pair.Private); + X509Crl crl = crlGen.Generate(pair.Private); - if (!crl.IssuerDN.Equivalent(new X509Name("CN=Test CA"), true)) - { - Fail("failed CRL issuer test"); - } + if (!crl.IssuerDN.Equivalent(new X509Name("CN=Test CA"), true)) + { + Fail("failed CRL issuer test"); + } - Asn1OctetString authExt = crl.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier); + Asn1OctetString authExt = crl.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier); - if (authExt == null) - { - Fail("failed to find CRL extension"); - } + if (authExt == null) + { + Fail("failed to find CRL extension"); + } - AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); + AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); - X509CrlEntry entry = crl.GetRevokedCertificate(BigInteger.One); + X509CrlEntry entry = crl.GetRevokedCertificate(BigInteger.One); - if (entry == null) - { - Fail("failed to find CRL entry"); - } + if (entry == null) + { + Fail("failed to find CRL entry"); + } - if (!entry.SerialNumber.Equals(BigInteger.One)) - { - Fail("CRL cert serial number does not match"); - } + if (!entry.SerialNumber.Equals(BigInteger.One)) + { + Fail("CRL cert serial number does not match"); + } - if (!entry.HasExtensions) - { - Fail("CRL entry extension not found"); - } + if (!entry.HasExtensions) + { + Fail("CRL entry extension not found"); + } - Asn1OctetString ext = entry.GetExtensionValue(X509Extensions.ReasonCode); + Asn1OctetString ext = entry.GetExtensionValue(X509Extensions.ReasonCode); - if (ext != null) - { - DerEnumerated reasonCode = (DerEnumerated)X509ExtensionUtilities.FromExtensionValue(ext); + if (ext != null) + { + DerEnumerated reasonCode = (DerEnumerated)X509ExtensionUtilities.FromExtensionValue(ext); - if (reasonCode.Value.IntValue != CrlReason.PrivilegeWithdrawn) - { - Fail("CRL entry reasonCode wrong"); - } - } - else - { - Fail("CRL entry reasonCode not found"); - } - } - - private void checkCrlCreation2() - { - IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA"); - kpGen.Init( - new RsaKeyGenerationParameters( - BigInteger.ValueOf(0x10001), new SecureRandom(), 768, 25)); - - X509V2CrlGenerator crlGen = new X509V2CrlGenerator(); - DateTime now = DateTime.UtcNow; - AsymmetricCipherKeyPair pair = kpGen.GenerateKeyPair(); + if (reasonCode.Value.IntValue != CrlReason.PrivilegeWithdrawn) + { + Fail("CRL entry reasonCode wrong"); + } + } + else + { + Fail("CRL entry reasonCode not found"); + } + } + + private void checkCrlCreation2() + { + IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA"); + kpGen.Init( + new RsaKeyGenerationParameters( + BigInteger.ValueOf(0x10001), new SecureRandom(), 768, 25)); + + X509V2CrlGenerator crlGen = new X509V2CrlGenerator(); + DateTime now = DateTime.UtcNow; + AsymmetricCipherKeyPair pair = kpGen.GenerateKeyPair(); - crlGen.SetIssuerDN(new X509Name("CN=Test CA")); + crlGen.SetIssuerDN(new X509Name("CN=Test CA")); - crlGen.SetThisUpdate(now); - crlGen.SetNextUpdate(now.AddSeconds(100)); - crlGen.SetSignatureAlgorithm("SHA256WithRSAEncryption"); - - IList extOids = new ArrayList(); - IList extValues = new ArrayList(); - - CrlReason crlReason = new CrlReason(CrlReason.PrivilegeWithdrawn); + crlGen.SetThisUpdate(now); + crlGen.SetNextUpdate(now.AddSeconds(100)); + crlGen.SetSignatureAlgorithm("SHA256WithRSAEncryption"); + + IList extOids = new ArrayList(); + IList extValues = new ArrayList(); + + CrlReason crlReason = new CrlReason(CrlReason.PrivilegeWithdrawn); - try - { - extOids.Add(X509Extensions.ReasonCode); - extValues.Add(new X509Extension(false, new DerOctetString(crlReason.GetEncoded()))); - } - catch (IOException e) - { - throw new ArgumentException("error encoding reason: " + e); - } + try + { + extOids.Add(X509Extensions.ReasonCode); + extValues.Add(new X509Extension(false, new DerOctetString(crlReason.GetEncoded()))); + } + catch (IOException e) + { + throw new ArgumentException("error encoding reason: " + e); + } - X509Extensions entryExtensions = new X509Extensions(extOids, extValues); + X509Extensions entryExtensions = new X509Extensions(extOids, extValues); - crlGen.AddCrlEntry(BigInteger.One, now, entryExtensions); + crlGen.AddCrlEntry(BigInteger.One, now, entryExtensions); - crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.Public)); + crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.Public)); - X509Crl crl = crlGen.Generate(pair.Private); + X509Crl crl = crlGen.Generate(pair.Private); - if (!crl.IssuerDN.Equivalent(new X509Name("CN=Test CA"), true)) - { - Fail("failed CRL issuer test"); - } + if (!crl.IssuerDN.Equivalent(new X509Name("CN=Test CA"), true)) + { + Fail("failed CRL issuer test"); + } - Asn1OctetString authExt = crl.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier); + Asn1OctetString authExt = crl.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier); - if (authExt == null) - { - Fail("failed to find CRL extension"); - } + if (authExt == null) + { + Fail("failed to find CRL extension"); + } - AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); + AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); - X509CrlEntry entry = crl.GetRevokedCertificate(BigInteger.One); + X509CrlEntry entry = crl.GetRevokedCertificate(BigInteger.One); - if (entry == null) - { - Fail("failed to find CRL entry"); - } + if (entry == null) + { + Fail("failed to find CRL entry"); + } - if (!entry.SerialNumber.Equals(BigInteger.One)) - { - Fail("CRL cert serial number does not match"); - } + if (!entry.SerialNumber.Equals(BigInteger.One)) + { + Fail("CRL cert serial number does not match"); + } - if (!entry.HasExtensions) - { - Fail("CRL entry extension not found"); - } - - Asn1OctetString ext = entry.GetExtensionValue(X509Extensions.ReasonCode); - - if (ext != null) - { - DerEnumerated reasonCode = (DerEnumerated)X509ExtensionUtilities.FromExtensionValue(ext); - - if (reasonCode.Value.IntValue != CrlReason.PrivilegeWithdrawn) - { - Fail("CRL entry reasonCode wrong"); - } - } - else - { - Fail("CRL entry reasonCode not found"); - } - } - - private void checkCrlCreation3() - { - IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA"); - kpGen.Init( - new RsaKeyGenerationParameters( - BigInteger.ValueOf(0x10001), new SecureRandom(), 768, 25)); + if (!entry.HasExtensions) + { + Fail("CRL entry extension not found"); + } + + Asn1OctetString ext = entry.GetExtensionValue(X509Extensions.ReasonCode); + + if (ext != null) + { + DerEnumerated reasonCode = (DerEnumerated)X509ExtensionUtilities.FromExtensionValue(ext); + + if (reasonCode.Value.IntValue != CrlReason.PrivilegeWithdrawn) + { + Fail("CRL entry reasonCode wrong"); + } + } + else + { + Fail("CRL entry reasonCode not found"); + } + } + + private void checkCrlCreation3() + { + IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA"); + kpGen.Init( + new RsaKeyGenerationParameters( + BigInteger.ValueOf(0x10001), new SecureRandom(), 768, 25)); - X509V2CrlGenerator crlGen = new X509V2CrlGenerator(); - DateTime now = DateTime.UtcNow; - AsymmetricCipherKeyPair pair = kpGen.GenerateKeyPair(); + X509V2CrlGenerator crlGen = new X509V2CrlGenerator(); + DateTime now = DateTime.UtcNow; + AsymmetricCipherKeyPair pair = kpGen.GenerateKeyPair(); - crlGen.SetIssuerDN(new X509Name("CN=Test CA")); + crlGen.SetIssuerDN(new X509Name("CN=Test CA")); - crlGen.SetThisUpdate(now); - crlGen.SetNextUpdate(now.AddSeconds(100)); - crlGen.SetSignatureAlgorithm("SHA256WithRSAEncryption"); + crlGen.SetThisUpdate(now); + crlGen.SetNextUpdate(now.AddSeconds(100)); + crlGen.SetSignatureAlgorithm("SHA256WithRSAEncryption"); - IList extOids = new ArrayList(); - IList extValues = new ArrayList(); + IList extOids = new ArrayList(); + IList extValues = new ArrayList(); - CrlReason crlReason = new CrlReason(CrlReason.PrivilegeWithdrawn); + CrlReason crlReason = new CrlReason(CrlReason.PrivilegeWithdrawn); - try - { - extOids.Add(X509Extensions.ReasonCode); - extValues.Add(new X509Extension(false, new DerOctetString(crlReason.GetEncoded()))); - } - catch (IOException e) - { - throw new ArgumentException("error encoding reason: " + e); - } + try + { + extOids.Add(X509Extensions.ReasonCode); + extValues.Add(new X509Extension(false, new DerOctetString(crlReason.GetEncoded()))); + } + catch (IOException e) + { + throw new ArgumentException("error encoding reason: " + e); + } - X509Extensions entryExtensions = new X509Extensions(extOids, extValues); + X509Extensions entryExtensions = new X509Extensions(extOids, extValues); - crlGen.AddCrlEntry(BigInteger.One, now, entryExtensions); + crlGen.AddCrlEntry(BigInteger.One, now, entryExtensions); - crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.Public)); + crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.Public)); - X509Crl crl = crlGen.Generate(pair.Private); + X509Crl crl = crlGen.Generate(pair.Private); - if (!crl.IssuerDN.Equivalent(new X509Name("CN=Test CA"), true)) - { - Fail("failed CRL issuer test"); - } + if (!crl.IssuerDN.Equivalent(new X509Name("CN=Test CA"), true)) + { + Fail("failed CRL issuer test"); + } - Asn1OctetString authExt = crl.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier); + Asn1OctetString authExt = crl.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier); - if (authExt == null) - { - Fail("failed to find CRL extension"); - } + if (authExt == null) + { + Fail("failed to find CRL extension"); + } - AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); - - X509CrlEntry entry = crl.GetRevokedCertificate(BigInteger.One); + AuthorityKeyIdentifier authId = new AuthorityKeyIdentifierStructure(authExt); + + X509CrlEntry entry = crl.GetRevokedCertificate(BigInteger.One); - if (entry == null) - { - Fail("failed to find CRL entry"); - } - - if (!entry.SerialNumber.Equals(BigInteger.One)) - { - Fail("CRL cert serial number does not match"); - } - - if (!entry.HasExtensions) - { - Fail("CRL entry extension not found"); - } - - Asn1OctetString ext = entry.GetExtensionValue(X509Extensions.ReasonCode); - - if (ext != null) - { - DerEnumerated reasonCode = (DerEnumerated)X509ExtensionUtilities.FromExtensionValue(ext); - - if (reasonCode.Value.IntValue != CrlReason.PrivilegeWithdrawn) - { - Fail("CRL entry reasonCode wrong"); - } - } - else - { - Fail("CRL entry reasonCode not found"); - } - - // - // check loading of existing CRL - // - crlGen = new X509V2CrlGenerator(); - now = DateTime.UtcNow; - - crlGen.SetIssuerDN(new X509Name("CN=Test CA")); + if (entry == null) + { + Fail("failed to find CRL entry"); + } + + if (!entry.SerialNumber.Equals(BigInteger.One)) + { + Fail("CRL cert serial number does not match"); + } + + if (!entry.HasExtensions) + { + Fail("CRL entry extension not found"); + } + + Asn1OctetString ext = entry.GetExtensionValue(X509Extensions.ReasonCode); + + if (ext != null) + { + DerEnumerated reasonCode = (DerEnumerated)X509ExtensionUtilities.FromExtensionValue(ext); + + if (reasonCode.Value.IntValue != CrlReason.PrivilegeWithdrawn) + { + Fail("CRL entry reasonCode wrong"); + } + } + else + { + Fail("CRL entry reasonCode not found"); + } + + // + // check loading of existing CRL + // + crlGen = new X509V2CrlGenerator(); + now = DateTime.UtcNow; + + crlGen.SetIssuerDN(new X509Name("CN=Test CA")); - crlGen.SetThisUpdate(now); - crlGen.SetNextUpdate(now.AddSeconds(100)); - crlGen.SetSignatureAlgorithm("SHA256WithRSAEncryption"); + crlGen.SetThisUpdate(now); + crlGen.SetNextUpdate(now.AddSeconds(100)); + crlGen.SetSignatureAlgorithm("SHA256WithRSAEncryption"); - crlGen.AddCrl(crl); + crlGen.AddCrl(crl); - crlGen.AddCrlEntry(BigInteger.Two, now, entryExtensions); + crlGen.AddCrlEntry(BigInteger.Two, now, entryExtensions); - crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.Public)); + crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.Public)); - X509Crl newCrl = crlGen.Generate(pair.Private); + X509Crl newCrl = crlGen.Generate(pair.Private); - int count = 0; - bool oneFound = false; - bool twoFound = false; + int count = 0; + bool oneFound = false; + bool twoFound = false; - foreach (X509CrlEntry crlEnt in newCrl.GetRevokedCertificates()) - { - if (crlEnt.SerialNumber.IntValue == 1) - { - oneFound = true; - } - else if (crlEnt.SerialNumber.IntValue == 2) - { - twoFound = true; - } + foreach (X509CrlEntry crlEnt in newCrl.GetRevokedCertificates()) + { + if (crlEnt.SerialNumber.IntValue == 1) + { + oneFound = true; + } + else if (crlEnt.SerialNumber.IntValue == 2) + { + twoFound = true; + } - count++; - } + count++; + } - if (count != 2) - { - Fail("wrong number of CRLs found"); - } + if (count != 2) + { + Fail("wrong number of CRLs found"); + } - if (!oneFound || !twoFound) - { - Fail("wrong CRLs found in copied list"); - } + if (!oneFound || !twoFound) + { + Fail("wrong CRLs found in copied list"); + } - // - // check factory read back - // - X509Crl readCrl = new X509CrlParser().ReadCrl(newCrl.GetEncoded()); + // + // check factory read back + // + X509Crl readCrl = new X509CrlParser().ReadCrl(newCrl.GetEncoded()); - if (readCrl == null) - { - Fail("crl not returned!"); - } + if (readCrl == null) + { + Fail("crl not returned!"); + } // ICollection col = cFact.generateCRLs(new ByteArrayInputStream(newCrl.getEncoded())); - ICollection col = new X509CrlParser().ReadCrls(newCrl.GetEncoded()); - - if (col.Count != 1) - { - Fail("wrong number of CRLs found in collection"); - } - } - - /** - * we Generate a self signed certificate for the sake of testing - GOST3410 - */ - internal void checkCreation4() - { - // - // set up the keys - // - AsymmetricKeyParameter privKey; - AsymmetricKeyParameter pubKey; + ICollection col = new X509CrlParser().ReadCrls(newCrl.GetEncoded()); + + if (col.Count != 1) + { + Fail("wrong number of CRLs found in collection"); + } + } + + /** + * we Generate a self signed certificate for the sake of testing - GOST3410 + */ + internal void checkCreation4() + { + // + // set up the keys + // + AsymmetricKeyParameter privKey; + AsymmetricKeyParameter pubKey; // GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec("GostR3410-94-CryptoPro-A"); // g.initialize(gost3410P, new SecureRandom()); - IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("GOST3410"); - g.Init( - new Gost3410KeyGenerationParameters( - new SecureRandom(), - CryptoProObjectIdentifiers.GostR3410x94CryptoProA)); - - AsymmetricCipherKeyPair p = g.GenerateKeyPair(); - - privKey = p.Private; - pubKey = p.Public; - - // - // distinguished name table. - // - IDictionary attrs = new Hashtable(); - attrs.Add(X509Name.C, "AU"); - attrs.Add(X509Name.O, "The Legion of the Bouncy Castle"); - attrs.Add(X509Name.L, "Melbourne"); - attrs.Add(X509Name.ST, "Victoria"); - attrs.Add(X509Name.E, "feedback-crypto@bouncycastle.org"); - - IList order = new ArrayList(); - order.Add(X509Name.C); - order.Add(X509Name.O); - order.Add(X509Name.L); - order.Add(X509Name.ST); - order.Add(X509Name.E); - - // - // extensions - // - - // - // create the certificate - version 3 - // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.SetSerialNumber(BigInteger.One); - certGen.SetIssuerDN(new X509Name(order, attrs)); - certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen.SetSubjectDN(new X509Name(order, attrs)); - certGen.SetPublicKey(pubKey); - certGen.SetSignatureAlgorithm("GOST3411withGOST3410"); - - X509Certificate cert = certGen.Generate(privKey); - - cert.CheckValidity(DateTime.UtcNow); - - // - // check verifies in general - // - cert.Verify(pubKey); - - // - // check verifies with contained key - // - cert.Verify(cert.GetPublicKey()); - - cert = new X509CertificateParser().ReadCertificate(cert.GetEncoded()); - - //Console.WriteLine(cert); - - //check getEncoded() - byte[] bytesch = cert.GetEncoded(); - } - - internal void checkCreation5() - { - // - // a sample key pair. - // - RsaKeyParameters pubKey = new RsaKeyParameters( - false, - new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), - new BigInteger("11", 16)); - - RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters( - new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), - new BigInteger("11", 16), - new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), - new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), - new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), - new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), - new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), - new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); - - // - // set up the keys - // - SecureRandom rand = new SecureRandom(); + IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("GOST3410"); + g.Init( + new Gost3410KeyGenerationParameters( + new SecureRandom(), + CryptoProObjectIdentifiers.GostR3410x94CryptoProA)); + + AsymmetricCipherKeyPair p = g.GenerateKeyPair(); + + privKey = p.Private; + pubKey = p.Public; + + // + // distinguished name table. + // + IDictionary attrs = new Hashtable(); + attrs.Add(X509Name.C, "AU"); + attrs.Add(X509Name.O, "The Legion of the Bouncy Castle"); + attrs.Add(X509Name.L, "Melbourne"); + attrs.Add(X509Name.ST, "Victoria"); + attrs.Add(X509Name.E, "feedback-crypto@bouncycastle.org"); + + IList order = new ArrayList(); + order.Add(X509Name.C); + order.Add(X509Name.O); + order.Add(X509Name.L); + order.Add(X509Name.ST); + order.Add(X509Name.E); + + // + // extensions + // + + // + // create the certificate - version 3 + // + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + + certGen.SetSerialNumber(BigInteger.One); + certGen.SetIssuerDN(new X509Name(order, attrs)); + certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen.SetSubjectDN(new X509Name(order, attrs)); + certGen.SetPublicKey(pubKey); + certGen.SetSignatureAlgorithm("GOST3411withGOST3410"); + + X509Certificate cert = certGen.Generate(privKey); + + cert.CheckValidity(DateTime.UtcNow); + + // + // check verifies in general + // + cert.Verify(pubKey); + + // + // check verifies with contained key + // + cert.Verify(cert.GetPublicKey()); + + cert = new X509CertificateParser().ReadCertificate(cert.GetEncoded()); + + //Console.WriteLine(cert); + + //check getEncoded() + byte[] bytesch = cert.GetEncoded(); + } + + internal void checkCreation5() + { + // + // a sample key pair. + // + RsaKeyParameters pubKey = new RsaKeyParameters( + false, + new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), + new BigInteger("11", 16)); + + RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters( + new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), + new BigInteger("11", 16), + new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), + new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), + new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), + new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), + new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), + new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); + + // + // set up the keys + // + SecureRandom rand = new SecureRandom(); // AsymmetricKeyParameter privKey; // AsymmetricKeyParameter pubKey; // @@ -2096,449 +2096,449 @@ namespace Org.BouncyCastle.Tests // privKey = fact.generatePrivate(privKeySpec); // pubKey = fact.generatePublic(pubKeySpec); - // - // distinguished name table. - // - IList ord = new ArrayList(); - ord.Add(X509Name.C); - ord.Add(X509Name.O); - ord.Add(X509Name.L); - ord.Add(X509Name.ST); - ord.Add(X509Name.E); - - IList values = new ArrayList(); - values.Add("AU"); - values.Add("The Legion of the Bouncy Castle"); - values.Add("Melbourne"); - values.Add("Victoria"); - values.Add("feedback-crypto@bouncycastle.org"); - - // - // create base certificate - version 3 - // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.SetSerialNumber(BigInteger.One); - certGen.SetIssuerDN(new X509Name(ord, values)); - certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen.SetSubjectDN(new X509Name(ord, values)); - certGen.SetPublicKey(pubKey); - certGen.SetSignatureAlgorithm("MD5WithRSAEncryption"); - certGen.AddExtension("2.5.29.15", true, - new X509KeyUsage(X509KeyUsage.EncipherOnly)); - certGen.AddExtension("2.5.29.37", true, - new DerSequence(KeyPurposeID.AnyExtendedKeyUsage)); - certGen.AddExtension("2.5.29.17", true, - new GeneralNames(new GeneralName(GeneralName.Rfc822Name, "test@test.test"))); - - X509Certificate baseCert = certGen.Generate(privKey); - - // - // copy certificate - // - certGen = new X509V3CertificateGenerator(); - - certGen.SetSerialNumber(BigInteger.One); - certGen.SetIssuerDN(new X509Name(ord, values)); - certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen.SetSubjectDN(new X509Name(ord, values)); - certGen.SetPublicKey(pubKey); - certGen.SetSignatureAlgorithm("MD5WithRSAEncryption"); - - certGen.CopyAndAddExtension(new DerObjectIdentifier("2.5.29.15"), true, baseCert); - certGen.CopyAndAddExtension("2.5.29.37", false, baseCert); - - X509Certificate cert = certGen.Generate(privKey); - - cert.CheckValidity(DateTime.UtcNow); - - cert.Verify(pubKey); - - DerObjectIdentifier oid1 = new DerObjectIdentifier("2.5.29.15"); - if (!baseCert.GetExtensionValue(oid1).Equals(cert.GetExtensionValue(oid1))) - { - Fail("2.5.29.15 differs"); - } - - DerObjectIdentifier oid2 = new DerObjectIdentifier("2.5.29.37"); - if (!baseCert.GetExtensionValue(oid2).Equals(cert.GetExtensionValue(oid2))) - { - Fail("2.5.29.37 differs"); - } - - // - // exception test - // - try - { - certGen.CopyAndAddExtension("2.5.99.99", true, baseCert); - - Fail("exception not thrown on dud extension copy"); - } - catch (CertificateParsingException) - { - // expected - } - - try - { - certGen.SetPublicKey(dudPublicKey); - - certGen.Generate(privKey); - - Fail("key without encoding not detected in v3"); - } - catch (ArgumentException) - { - // expected - } - } - - private void doTestForgedSignature() - { - string cert = "MIIBsDCCAVoCAQYwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV" - + "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD" - + "VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw0wNjA5MTEyMzU4NTVa" - + "Fw0wNjEwMTEyMzU4NTVaMGMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNs" - + "YW5kMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEjMCEGA1UEAxMaU2VydmVy" - + "IHRlc3QgY2VydCAoNTEyIGJpdCkwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PD" - + "hCeV/xIxUg8V70YRxK2A5jZbD92A12GN4PxyRQk0/lVmRUNMaJdq/qigpd9feP/u" - + "12S4PwTLb/8q/v657QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAbynCRIlUQgaqyNgU" - + "DF6P14yRKUtX8akOP2TwStaSiVf/akYqfLFm3UGka5XbPj4rifrZ0/sOoZEEBvHQ" - + "e20sRA=="; - - X509Certificate x509 = new X509CertificateParser().ReadCertificate(Base64.Decode(cert)); - - try - { - x509.Verify(x509.GetPublicKey()); - - Fail("forged RSA signature passed"); - } - catch (Exception) - { - // expected - } - } - - private void pemTest() - { - X509Certificate cert = readPemCert(PemData.CERTIFICATE_1); - if (cert == null) - { - Fail("PEM cert not read"); - } - cert = readPemCert("-----BEGIN CERTIFICATE-----" + PemData.CERTIFICATE_2); - if (cert == null) - { - Fail("PEM cert with extraneous header not read"); - } - X509Crl crl = new X509CrlParser().ReadCrl(Encoding.ASCII.GetBytes(PemData.CRL_1)); - if (crl == null) - { - Fail("PEM crl not read"); - } - ArrayList col = new ArrayList( - new X509CertificateParser().ReadCertificates(Encoding.ASCII.GetBytes(PemData.CERTIFICATE_2))); - if (col.Count != 1 || !col.Contains(cert)) - { - Fail("PEM cert collection not right"); - } - col = new ArrayList( - new X509CrlParser().ReadCrls(Encoding.ASCII.GetBytes(PemData.CRL_2))); - if (col.Count != 1 || !col.Contains(crl)) - { - Fail("PEM crl collection not right"); - } - } - - private static X509Certificate readPemCert( - string pemData) - { - return new X509CertificateParser().ReadCertificate(Encoding.ASCII.GetBytes(pemData)); - } - - private void pkcs7Test() - { - Asn1Encodable rootCert = Asn1Object.FromByteArray(CertPathTest.rootCertBin); - Asn1Encodable rootCrl = Asn1Object.FromByteArray(CertPathTest.rootCrlBin); - - X509CertificateParser certParser = new X509CertificateParser(); - X509CrlParser crlParser = new X509CrlParser(); - - SignedData sigData = new SignedData( - DerSet.Empty, - new ContentInfo(CmsObjectIdentifiers.Data, null), - new DerSet( - rootCert, - new DerTaggedObject(false, 2, Asn1Object.FromByteArray(AttrCertTest.attrCert))), - new DerSet(rootCrl), - DerSet.Empty); - - ContentInfo info = new ContentInfo(CmsObjectIdentifiers.SignedData, sigData); - - X509Certificate cert = certParser.ReadCertificate(info.GetEncoded()); - if (cert == null || !AreEqual(cert.GetEncoded(), rootCert.ToAsn1Object().GetEncoded())) - { - Fail("PKCS7 cert not read"); - } - X509Crl crl = crlParser.ReadCrl(info.GetEncoded()); - if (crl == null || !AreEqual(crl.GetEncoded(), rootCrl.ToAsn1Object().GetEncoded())) - { - Fail("PKCS7 crl not read"); - } - ArrayList col = new ArrayList(certParser.ReadCertificates(info.GetEncoded())); - if (col.Count != 1 || !col.Contains(cert)) - { - Fail("PKCS7 cert collection not right"); - } - col = new ArrayList(crlParser.ReadCrls(info.GetEncoded())); - if (col.Count != 1 || !col.Contains(crl)) - { - Fail("PKCS7 crl collection not right"); - } - - // data with no certificates or CRLs - - sigData = new SignedData(DerSet.Empty, new ContentInfo(CmsObjectIdentifiers.Data, null), DerSet.Empty, DerSet.Empty, DerSet.Empty); - - info = new ContentInfo(CmsObjectIdentifiers.SignedData, sigData); - - cert = certParser.ReadCertificate(info.GetEncoded()); - if (cert != null) - { - Fail("PKCS7 cert present"); - } - crl = crlParser.ReadCrl(info.GetEncoded()); - if (crl != null) - { - Fail("PKCS7 crl present"); - } - - // data with absent certificates and CRLS - - sigData = new SignedData(DerSet.Empty, new ContentInfo(CmsObjectIdentifiers.Data, null), null, null, DerSet.Empty); - - info = new ContentInfo(CmsObjectIdentifiers.SignedData, sigData); - - cert = certParser.ReadCertificate(info.GetEncoded()); - if (cert != null) - { - Fail("PKCS7 cert present"); - } - crl = crlParser.ReadCrl(info.GetEncoded()); - if (crl != null) - { - Fail("PKCS7 crl present"); - } - - // - // sample message - // - ICollection certCol = certParser.ReadCertificates(pkcs7CrlProblem); - ICollection crlCol = crlParser.ReadCrls(pkcs7CrlProblem); - - if (crlCol.Count != 0) - { - Fail("wrong number of CRLs: " + crlCol.Count); - } - - if (certCol.Count != 4) - { - Fail("wrong number of Certs: " + certCol.Count); - } - } - - private void createPssCert( - string algorithm) - { - AsymmetricCipherKeyPair keyPair = GenerateLongFixedKeys(); - - AsymmetricKeyParameter privKey = keyPair.Private; - AsymmetricKeyParameter pubKey = keyPair.Public; - - // - // distinguished name table. - // - IList ord = new ArrayList(); - ord.Add(X509Name.C); - ord.Add(X509Name.O); - ord.Add(X509Name.L); - ord.Add(X509Name.ST); - ord.Add(X509Name.E); - - IList values = new ArrayList(); - values.Add("AU"); - values.Add("The Legion of the Bouncy Castle"); - values.Add("Melbourne"); - values.Add("Victoria"); - values.Add("feedback-crypto@bouncycastle.org"); - - // - // create base certificate - version 3 - // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.SetSerialNumber(BigInteger.One); - certGen.SetIssuerDN(new X509Name(ord, values)); - certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen.SetSubjectDN(new X509Name(ord, values)); - certGen.SetPublicKey(pubKey); - certGen.SetSignatureAlgorithm(algorithm); - certGen.AddExtension("2.5.29.15", true, - new X509KeyUsage(X509KeyUsage.EncipherOnly)); - certGen.AddExtension("2.5.29.37", true, - new DerSequence(KeyPurposeID.AnyExtendedKeyUsage)); - certGen.AddExtension("2.5.29.17", true, - new GeneralNames(new GeneralName(GeneralName.Rfc822Name, "test@test.test"))); - - X509Certificate baseCert = certGen.Generate(privKey); - - baseCert.Verify(pubKey); - } - - private static AsymmetricCipherKeyPair GenerateLongFixedKeys() - { + // + // distinguished name table. + // + IList ord = new ArrayList(); + ord.Add(X509Name.C); + ord.Add(X509Name.O); + ord.Add(X509Name.L); + ord.Add(X509Name.ST); + ord.Add(X509Name.E); + + IList values = new ArrayList(); + values.Add("AU"); + values.Add("The Legion of the Bouncy Castle"); + values.Add("Melbourne"); + values.Add("Victoria"); + values.Add("feedback-crypto@bouncycastle.org"); + + // + // create base certificate - version 3 + // + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + + certGen.SetSerialNumber(BigInteger.One); + certGen.SetIssuerDN(new X509Name(ord, values)); + certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen.SetSubjectDN(new X509Name(ord, values)); + certGen.SetPublicKey(pubKey); + certGen.SetSignatureAlgorithm("MD5WithRSAEncryption"); + certGen.AddExtension("2.5.29.15", true, + new X509KeyUsage(X509KeyUsage.EncipherOnly)); + certGen.AddExtension("2.5.29.37", true, + new DerSequence(KeyPurposeID.AnyExtendedKeyUsage)); + certGen.AddExtension("2.5.29.17", true, + new GeneralNames(new GeneralName(GeneralName.Rfc822Name, "test@test.test"))); + + X509Certificate baseCert = certGen.Generate(privKey); + + // + // copy certificate + // + certGen = new X509V3CertificateGenerator(); + + certGen.SetSerialNumber(BigInteger.One); + certGen.SetIssuerDN(new X509Name(ord, values)); + certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen.SetSubjectDN(new X509Name(ord, values)); + certGen.SetPublicKey(pubKey); + certGen.SetSignatureAlgorithm("MD5WithRSAEncryption"); + + certGen.CopyAndAddExtension(new DerObjectIdentifier("2.5.29.15"), true, baseCert); + certGen.CopyAndAddExtension("2.5.29.37", false, baseCert); + + X509Certificate cert = certGen.Generate(privKey); + + cert.CheckValidity(DateTime.UtcNow); + + cert.Verify(pubKey); + + DerObjectIdentifier oid1 = new DerObjectIdentifier("2.5.29.15"); + if (!baseCert.GetExtensionValue(oid1).Equals(cert.GetExtensionValue(oid1))) + { + Fail("2.5.29.15 differs"); + } + + DerObjectIdentifier oid2 = new DerObjectIdentifier("2.5.29.37"); + if (!baseCert.GetExtensionValue(oid2).Equals(cert.GetExtensionValue(oid2))) + { + Fail("2.5.29.37 differs"); + } + + // + // exception test + // + try + { + certGen.CopyAndAddExtension("2.5.99.99", true, baseCert); + + Fail("exception not thrown on dud extension copy"); + } + catch (CertificateParsingException) + { + // expected + } + + try + { + certGen.SetPublicKey(dudPublicKey); + + certGen.Generate(privKey); + + Fail("key without encoding not detected in v3"); + } + catch (ArgumentException) + { + // expected + } + } + + private void doTestForgedSignature() + { + string cert = "MIIBsDCCAVoCAQYwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV" + + "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD" + + "VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw0wNjA5MTEyMzU4NTVa" + + "Fw0wNjEwMTEyMzU4NTVaMGMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNs" + + "YW5kMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEjMCEGA1UEAxMaU2VydmVy" + + "IHRlc3QgY2VydCAoNTEyIGJpdCkwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAn7PD" + + "hCeV/xIxUg8V70YRxK2A5jZbD92A12GN4PxyRQk0/lVmRUNMaJdq/qigpd9feP/u" + + "12S4PwTLb/8q/v657QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAbynCRIlUQgaqyNgU" + + "DF6P14yRKUtX8akOP2TwStaSiVf/akYqfLFm3UGka5XbPj4rifrZ0/sOoZEEBvHQ" + + "e20sRA=="; + + X509Certificate x509 = new X509CertificateParser().ReadCertificate(Base64.Decode(cert)); + + try + { + x509.Verify(x509.GetPublicKey()); + + Fail("forged RSA signature passed"); + } + catch (Exception) + { + // expected + } + } + + private void pemTest() + { + X509Certificate cert = readPemCert(PemData.CERTIFICATE_1); + if (cert == null) + { + Fail("PEM cert not read"); + } + cert = readPemCert("-----BEGIN CERTIFICATE-----" + PemData.CERTIFICATE_2); + if (cert == null) + { + Fail("PEM cert with extraneous header not read"); + } + X509Crl crl = new X509CrlParser().ReadCrl(Encoding.ASCII.GetBytes(PemData.CRL_1)); + if (crl == null) + { + Fail("PEM crl not read"); + } + ArrayList col = new ArrayList( + new X509CertificateParser().ReadCertificates(Encoding.ASCII.GetBytes(PemData.CERTIFICATE_2))); + if (col.Count != 1 || !col.Contains(cert)) + { + Fail("PEM cert collection not right"); + } + col = new ArrayList( + new X509CrlParser().ReadCrls(Encoding.ASCII.GetBytes(PemData.CRL_2))); + if (col.Count != 1 || !col.Contains(crl)) + { + Fail("PEM crl collection not right"); + } + } + + private static X509Certificate readPemCert( + string pemData) + { + return new X509CertificateParser().ReadCertificate(Encoding.ASCII.GetBytes(pemData)); + } + + private void pkcs7Test() + { + Asn1Encodable rootCert = Asn1Object.FromByteArray(CertPathTest.rootCertBin); + Asn1Encodable rootCrl = Asn1Object.FromByteArray(CertPathTest.rootCrlBin); + + X509CertificateParser certParser = new X509CertificateParser(); + X509CrlParser crlParser = new X509CrlParser(); + + SignedData sigData = new SignedData( + DerSet.Empty, + new ContentInfo(CmsObjectIdentifiers.Data, null), + new DerSet( + rootCert, + new DerTaggedObject(false, 2, Asn1Object.FromByteArray(AttrCertTest.attrCert))), + new DerSet(rootCrl), + DerSet.Empty); + + ContentInfo info = new ContentInfo(CmsObjectIdentifiers.SignedData, sigData); + + X509Certificate cert = certParser.ReadCertificate(info.GetEncoded()); + if (cert == null || !AreEqual(cert.GetEncoded(), rootCert.ToAsn1Object().GetEncoded())) + { + Fail("PKCS7 cert not read"); + } + X509Crl crl = crlParser.ReadCrl(info.GetEncoded()); + if (crl == null || !AreEqual(crl.GetEncoded(), rootCrl.ToAsn1Object().GetEncoded())) + { + Fail("PKCS7 crl not read"); + } + ArrayList col = new ArrayList(certParser.ReadCertificates(info.GetEncoded())); + if (col.Count != 1 || !col.Contains(cert)) + { + Fail("PKCS7 cert collection not right"); + } + col = new ArrayList(crlParser.ReadCrls(info.GetEncoded())); + if (col.Count != 1 || !col.Contains(crl)) + { + Fail("PKCS7 crl collection not right"); + } + + // data with no certificates or CRLs + + sigData = new SignedData(DerSet.Empty, new ContentInfo(CmsObjectIdentifiers.Data, null), DerSet.Empty, DerSet.Empty, DerSet.Empty); + + info = new ContentInfo(CmsObjectIdentifiers.SignedData, sigData); + + cert = certParser.ReadCertificate(info.GetEncoded()); + if (cert != null) + { + Fail("PKCS7 cert present"); + } + crl = crlParser.ReadCrl(info.GetEncoded()); + if (crl != null) + { + Fail("PKCS7 crl present"); + } + + // data with absent certificates and CRLS + + sigData = new SignedData(DerSet.Empty, new ContentInfo(CmsObjectIdentifiers.Data, null), null, null, DerSet.Empty); + + info = new ContentInfo(CmsObjectIdentifiers.SignedData, sigData); + + cert = certParser.ReadCertificate(info.GetEncoded()); + if (cert != null) + { + Fail("PKCS7 cert present"); + } + crl = crlParser.ReadCrl(info.GetEncoded()); + if (crl != null) + { + Fail("PKCS7 crl present"); + } + + // + // sample message + // + ICollection certCol = certParser.ReadCertificates(pkcs7CrlProblem); + ICollection crlCol = crlParser.ReadCrls(pkcs7CrlProblem); + + if (crlCol.Count != 0) + { + Fail("wrong number of CRLs: " + crlCol.Count); + } + + if (certCol.Count != 4) + { + Fail("wrong number of Certs: " + certCol.Count); + } + } + + private void createPssCert( + string algorithm) + { + AsymmetricCipherKeyPair keyPair = GenerateLongFixedKeys(); + + AsymmetricKeyParameter privKey = keyPair.Private; + AsymmetricKeyParameter pubKey = keyPair.Public; + + // + // distinguished name table. + // + IList ord = new ArrayList(); + ord.Add(X509Name.C); + ord.Add(X509Name.O); + ord.Add(X509Name.L); + ord.Add(X509Name.ST); + ord.Add(X509Name.E); + + IList values = new ArrayList(); + values.Add("AU"); + values.Add("The Legion of the Bouncy Castle"); + values.Add("Melbourne"); + values.Add("Victoria"); + values.Add("feedback-crypto@bouncycastle.org"); + + // + // create base certificate - version 3 + // + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + + certGen.SetSerialNumber(BigInteger.One); + certGen.SetIssuerDN(new X509Name(ord, values)); + certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen.SetSubjectDN(new X509Name(ord, values)); + certGen.SetPublicKey(pubKey); + certGen.SetSignatureAlgorithm(algorithm); + certGen.AddExtension("2.5.29.15", true, + new X509KeyUsage(X509KeyUsage.EncipherOnly)); + certGen.AddExtension("2.5.29.37", true, + new DerSequence(KeyPurposeID.AnyExtendedKeyUsage)); + certGen.AddExtension("2.5.29.17", true, + new GeneralNames(new GeneralName(GeneralName.Rfc822Name, "test@test.test"))); + + X509Certificate baseCert = certGen.Generate(privKey); + + baseCert.Verify(pubKey); + } + + private static AsymmetricCipherKeyPair GenerateLongFixedKeys() + { // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( - RsaKeyParameters pubKey = new RsaKeyParameters(false, - new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), - new BigInteger("010001",16)); + RsaKeyParameters pubKey = new RsaKeyParameters(false, + new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), + new BigInteger("010001",16)); // RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( - RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters( - new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), - new BigInteger("010001",16), - new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), - new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), - new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), - new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), - new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), - new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); + RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters( + new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), + new BigInteger("010001",16), + new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), + new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), + new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), + new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), + new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), + new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); // KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); // // PrivateKey privKey = fact.generatePrivate(privKeySpec); // PublicKey pubKey = fact.generatePublic(pubKeySpec); - return new AsymmetricCipherKeyPair(pubKey, privKey); - } - - private void doTestNullDerNullCert() - { - AsymmetricCipherKeyPair keyPair = GenerateLongFixedKeys(); - - AsymmetricKeyParameter pubKey = keyPair.Public; - AsymmetricKeyParameter privKey = keyPair.Private; - - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.SetSerialNumber(BigInteger.One); - certGen.SetIssuerDN(new X509Name("CN=Test")); - certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen.SetSubjectDN(new X509Name("CN=Test")); - certGen.SetPublicKey(pubKey); - certGen.SetSignatureAlgorithm("MD5WithRSAEncryption"); - X509Certificate cert = certGen.Generate(privKey); - - X509CertificateStructure certStruct = X509CertificateStructure.GetInstance( - Asn1Object.FromByteArray(cert.GetEncoded())); - - Asn1Encodable tbsCertificate = certStruct.TbsCertificate; - AlgorithmIdentifier sig = certStruct.SignatureAlgorithm; - - DerSequence seq = new DerSequence( - tbsCertificate, - new AlgorithmIdentifier(sig.ObjectID), - certStruct.Signature); - - try - { - // verify - byte[] encoded = seq.GetEncoded(); - X509CertificateParser fact = new X509CertificateParser(); - cert = fact.ReadCertificate(encoded); - cert.Verify(cert.GetPublicKey()); - } - catch (Exception e) - { - Fail("doTestNullDerNull failed - exception " + e.ToString(), e); - } - } - - public override void PerformTest() - { - checkCertificate(1, cert1); - checkCertificate(2, cert2); - checkCertificate(3, cert3); - checkCertificate(4, cert4); - checkCertificate(5, cert5); - // This cert uses an incorrect encoding (compressed wrapped in extra octet string) - // which the Java build supports backwards, but we choose not to for C# build + return new AsymmetricCipherKeyPair(pubKey, privKey); + } + + private void doTestNullDerNullCert() + { + AsymmetricCipherKeyPair keyPair = GenerateLongFixedKeys(); + + AsymmetricKeyParameter pubKey = keyPair.Public; + AsymmetricKeyParameter privKey = keyPair.Private; + + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + + certGen.SetSerialNumber(BigInteger.One); + certGen.SetIssuerDN(new X509Name("CN=Test")); + certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen.SetSubjectDN(new X509Name("CN=Test")); + certGen.SetPublicKey(pubKey); + certGen.SetSignatureAlgorithm("MD5WithRSAEncryption"); + X509Certificate cert = certGen.Generate(privKey); + + X509CertificateStructure certStruct = X509CertificateStructure.GetInstance( + Asn1Object.FromByteArray(cert.GetEncoded())); + + Asn1Encodable tbsCertificate = certStruct.TbsCertificate; + AlgorithmIdentifier sig = certStruct.SignatureAlgorithm; + + DerSequence seq = new DerSequence( + tbsCertificate, + new AlgorithmIdentifier(sig.ObjectID), + certStruct.Signature); + + try + { + // verify + byte[] encoded = seq.GetEncoded(); + X509CertificateParser fact = new X509CertificateParser(); + cert = fact.ReadCertificate(encoded); + cert.Verify(cert.GetPublicKey()); + } + catch (Exception e) + { + Fail("doTestNullDerNull failed - exception " + e.ToString(), e); + } + } + + public override void PerformTest() + { + checkCertificate(1, cert1); + checkCertificate(2, cert2); + checkCertificate(3, cert3); + checkCertificate(4, cert4); + checkCertificate(5, cert5); + // This cert uses an incorrect encoding (compressed wrapped in extra octet string) + // which the Java build supports backwards, but we choose not to for C# build // checkCertificate(6, oldEcdsa); - checkCertificate(7, cert7); - - checkKeyUsage(8, keyUsage); - checkSelfSignedCertificate(9, uncompressedPtEC); - checkNameCertificate(10, nameCert); - - checkSelfSignedCertificate(11, probSelfSignedCert); - checkSelfSignedCertificate(12, gostCA1); - checkSelfSignedCertificate(13, gostCA2); - checkSelfSignedCertificate(14, gost341094base); - checkSelfSignedCertificate(15, gost34102001base); - checkSelfSignedCertificate(16, gost341094A); - checkSelfSignedCertificate(17, gost341094B); - checkSelfSignedCertificate(17, gost34102001A); - - checkCrl(1, crl1); - - checkCreation1(); - checkCreation2(); - checkCreation3(); - checkCreation4(); - checkCreation5(); - - createECCert("SHA1withECDSA", X9ObjectIdentifiers.ECDsaWithSha1); - createECCert("SHA224withECDSA", X9ObjectIdentifiers.ECDsaWithSha224); - createECCert("SHA256withECDSA", X9ObjectIdentifiers.ECDsaWithSha256); - createECCert("SHA384withECDSA", X9ObjectIdentifiers.ECDsaWithSha384); - createECCert("SHA512withECDSA", X9ObjectIdentifiers.ECDsaWithSha512); - - createPssCert("SHA1withRSAandMGF1"); - createPssCert("SHA224withRSAandMGF1"); - createPssCert("SHA256withRSAandMGF1"); - createPssCert("SHA384withRSAandMGF1"); - - checkCrlCreation1(); - checkCrlCreation2(); - checkCrlCreation3(); - - pemTest(); - pkcs7Test(); - - doTestForgedSignature(); - - doTestNullDerNullCert(); - - checkCertificate(18, emptyDNCert); - } - - public static void Main( - string[] args) - { - RunTest(new CertTest()); - } - - [Test] - public void TestFunction() - { - string resultText = Perform().ToString(); - - Assert.AreEqual(Name + ": Okay", resultText); - } - } + checkCertificate(7, cert7); + + checkKeyUsage(8, keyUsage); + checkSelfSignedCertificate(9, uncompressedPtEC); + checkNameCertificate(10, nameCert); + + checkSelfSignedCertificate(11, probSelfSignedCert); + checkSelfSignedCertificate(12, gostCA1); + checkSelfSignedCertificate(13, gostCA2); + checkSelfSignedCertificate(14, gost341094base); + checkSelfSignedCertificate(15, gost34102001base); + checkSelfSignedCertificate(16, gost341094A); + checkSelfSignedCertificate(17, gost341094B); + checkSelfSignedCertificate(17, gost34102001A); + + checkCrl(1, crl1); + + checkCreation1(); + checkCreation2(); + checkCreation3(); + checkCreation4(); + checkCreation5(); + + createECCert("SHA1withECDSA", X9ObjectIdentifiers.ECDsaWithSha1); + createECCert("SHA224withECDSA", X9ObjectIdentifiers.ECDsaWithSha224); + createECCert("SHA256withECDSA", X9ObjectIdentifiers.ECDsaWithSha256); + createECCert("SHA384withECDSA", X9ObjectIdentifiers.ECDsaWithSha384); + createECCert("SHA512withECDSA", X9ObjectIdentifiers.ECDsaWithSha512); + + createPssCert("SHA1withRSAandMGF1"); + createPssCert("SHA224withRSAandMGF1"); + createPssCert("SHA256withRSAandMGF1"); + createPssCert("SHA384withRSAandMGF1"); + + checkCrlCreation1(); + checkCrlCreation2(); + checkCrlCreation3(); + + pemTest(); + pkcs7Test(); + + doTestForgedSignature(); + + doTestNullDerNullCert(); + + checkCertificate(18, emptyDNCert); + } + + public static void Main( + string[] args) + { + RunTest(new CertTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } } diff --git a/crypto/test/src/test/DHTest.cs b/crypto/test/src/test/DHTest.cs index 9a3610c18..18a0d84d6 100644 --- a/crypto/test/src/test/DHTest.cs +++ b/crypto/test/src/test/DHTest.cs @@ -15,146 +15,146 @@ using Org.BouncyCastle.X509; namespace Org.BouncyCastle.Tests { - [TestFixture] - public class DHTest - : SimpleTest - { - private static readonly BigInteger g512 = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); - private static readonly BigInteger p512 = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); - - private static readonly BigInteger g768 = new BigInteger("7c240073c1316c621df461b71ebb0cdcc90a6e5527e5e126633d131f87461c4dc4afc60c2cb0f053b6758871489a69613e2a8b4c8acde23954c08c81cbd36132cfd64d69e4ed9f8e51ed6e516297206672d5c0a69135df0a5dcf010d289a9ca1", 16); - private static readonly BigInteger p768 = new BigInteger("8c9dd223debed1b80103b8b309715be009d48860ed5ae9b9d5d8159508efd802e3ad4501a7f7e1cfec78844489148cd72da24b21eddd01aa624291c48393e277cfc529e37075eccef957f3616f962d15b44aeab4039d01b817fde9eaa12fd73f", 16); - - private static readonly BigInteger g1024 = new BigInteger("1db17639cdf96bc4eabba19454f0b7e5bd4e14862889a725c96eb61048dcd676ceb303d586e30f060dbafd8a571a39c4d823982117da5cc4e0f89c77388b7a08896362429b94a18a327604eb7ff227bffbc83459ade299e57b5f77b50fb045250934938efa145511166e3197373e1b5b1e52de713eb49792bedde722c6717abf", 16); - private static readonly BigInteger p1024 = new BigInteger("a00e283b3c624e5b2b4d9fbc2653b5185d99499b00fd1bf244c6f0bb817b4d1c451b2958d62a0f8a38caef059fb5ecd25d75ed9af403f5b5bdab97a642902f824e3c13789fed95fa106ddfe0ff4a707c85e2eb77d49e68f2808bcea18ce128b178cd287c6bc00efa9a1ad2a673fe0dceace53166f75b81d6709d5f8af7c66bb7", 16); - - // public key with mismatched oid/parameters - private byte[] oldPubEnc = Base64.Decode( - "MIIBnzCCARQGByqGSM4+AgEwggEHAoGBAPxSrN417g43VAM9sZRf1dt6AocAf7D6" + - "WVCtqEDcBJrMzt63+g+BNJzhXVtbZ9kp9vw8L/0PHgzv0Ot/kOLX7Khn+JalOECW" + - "YlkyBhmOVbjR79TY5u2GAlvG6pqpizieQNBCEMlUuYuK1Iwseil6VoRuA13Zm7uw" + - "WO1eZmaJtY7LAoGAQaPRCFKM5rEdkMrV9FNzeSsYRs8m3DqPnnJHpuySpyO9wUcX" + - "OOJcJY5qvHbDO5SxHXu/+bMgXmVT6dXI5o0UeYqJR7fj6pR4E6T0FwG55RFr5Ok4" + - "3C4cpXmaOu176SyWuoDqGs1RDGmYQjwbZUi23DjaaTFUly9LCYXMliKrQfEDgYQA" + - "AoGAQUGCBN4TaBw1BpdBXdTvTfCU69XDB3eyU2FOBE3UWhpx9D8XJlx4f5DpA4Y6" + - "6sQMuCbhfmjEph8W7/sbMurM/awR+PSR8tTY7jeQV0OkmAYdGK2nzh0ZSifMO1oE" + - "NNhN2O62TLs67msxT28S4/S89+LMtc98mevQ2SX+JF3wEVU="); - - // bogus key with full PKCS parameter set - private byte[] oldFullParams = Base64.Decode( - "MIIBIzCCARgGByqGSM4+AgEwggELAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E" + - "AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f" + - "6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv" + - "8iIDGZ3RSAHHAoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlX" + - "jrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6j" + - "fwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqAgFk" + - "AwUAAgIH0A=="); - - private byte[] samplePubEnc = Base64.Decode( - "MIIBpjCCARsGCSqGSIb3DQEDATCCAQwCgYEA/X9TgR11EilS30qcLuzk5/YRt1I8" + - "70QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWk" + - "n5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HX" + - "Ku/yIgMZndFIAccCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdR" + - "WVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWR" + - "bqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoC" + - "AgIAA4GEAAKBgEIiqxoUW6E6GChoOgcfNbVFclW91ITf5MFSUGQwt2R0RHoOhxvO" + - "lZhNs++d0VPATLAyXovjfgENT9SGCbuZttYcqqLdKTbMXBWPek+rfnAl9E4iEMED" + - "IDd83FJTKs9hQcPAm7zmp0Xm1bGF9CbUFjP5G02265z7eBmHDaT0SNlB"); - - private byte[] samplePrivEnc = Base64.Decode( - "MIIBZgIBADCCARsGCSqGSIb3DQEDATCCAQwCgYEA/X9TgR11EilS30qcLuzk5/YR" + - "t1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZ" + - "UKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOu" + - "K2HXKu/yIgMZndFIAccCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0H" + - "gmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuz" + - "pnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7P" + - "SSoCAgIABEICQAZYXnBHazxXUUdFP4NIf2Ipu7du0suJPZQKKff81wymi2zfCfHh" + - "uhe9gQ9xdm4GpzeNtrQ8/MzpTy+ZVrtd29Q="); - - public override string Name - { - get { return "DH"; } - } - - private void doTestGP( - string algName, - int size, - int privateValueSize, - BigInteger g, - BigInteger p) - { - IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator(algName); - - DHParameters dhParams = new DHParameters(p, g, null, privateValueSize); - KeyGenerationParameters kgp = new DHKeyGenerationParameters(new SecureRandom(), dhParams); - - keyGen.Init(kgp); - - // - // a side - // - AsymmetricCipherKeyPair aKeyPair = keyGen.GenerateKeyPair(); - - IBasicAgreement aKeyAgreeBasic = AgreementUtilities.GetBasicAgreement(algName); - - checkKeySize(privateValueSize, aKeyPair); - - aKeyAgreeBasic.Init(aKeyPair.Private); - - // - // b side - // - AsymmetricCipherKeyPair bKeyPair = keyGen.GenerateKeyPair(); - - IBasicAgreement bKeyAgreeBasic = AgreementUtilities.GetBasicAgreement(algName); - - checkKeySize(privateValueSize, bKeyPair); - - bKeyAgreeBasic.Init(bKeyPair.Private); - - // - // agreement - // + [TestFixture] + public class DHTest + : SimpleTest + { + private static readonly BigInteger g512 = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); + private static readonly BigInteger p512 = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); + + private static readonly BigInteger g768 = new BigInteger("7c240073c1316c621df461b71ebb0cdcc90a6e5527e5e126633d131f87461c4dc4afc60c2cb0f053b6758871489a69613e2a8b4c8acde23954c08c81cbd36132cfd64d69e4ed9f8e51ed6e516297206672d5c0a69135df0a5dcf010d289a9ca1", 16); + private static readonly BigInteger p768 = new BigInteger("8c9dd223debed1b80103b8b309715be009d48860ed5ae9b9d5d8159508efd802e3ad4501a7f7e1cfec78844489148cd72da24b21eddd01aa624291c48393e277cfc529e37075eccef957f3616f962d15b44aeab4039d01b817fde9eaa12fd73f", 16); + + private static readonly BigInteger g1024 = new BigInteger("1db17639cdf96bc4eabba19454f0b7e5bd4e14862889a725c96eb61048dcd676ceb303d586e30f060dbafd8a571a39c4d823982117da5cc4e0f89c77388b7a08896362429b94a18a327604eb7ff227bffbc83459ade299e57b5f77b50fb045250934938efa145511166e3197373e1b5b1e52de713eb49792bedde722c6717abf", 16); + private static readonly BigInteger p1024 = new BigInteger("a00e283b3c624e5b2b4d9fbc2653b5185d99499b00fd1bf244c6f0bb817b4d1c451b2958d62a0f8a38caef059fb5ecd25d75ed9af403f5b5bdab97a642902f824e3c13789fed95fa106ddfe0ff4a707c85e2eb77d49e68f2808bcea18ce128b178cd287c6bc00efa9a1ad2a673fe0dceace53166f75b81d6709d5f8af7c66bb7", 16); + + // public key with mismatched oid/parameters + private byte[] oldPubEnc = Base64.Decode( + "MIIBnzCCARQGByqGSM4+AgEwggEHAoGBAPxSrN417g43VAM9sZRf1dt6AocAf7D6" + + "WVCtqEDcBJrMzt63+g+BNJzhXVtbZ9kp9vw8L/0PHgzv0Ot/kOLX7Khn+JalOECW" + + "YlkyBhmOVbjR79TY5u2GAlvG6pqpizieQNBCEMlUuYuK1Iwseil6VoRuA13Zm7uw" + + "WO1eZmaJtY7LAoGAQaPRCFKM5rEdkMrV9FNzeSsYRs8m3DqPnnJHpuySpyO9wUcX" + + "OOJcJY5qvHbDO5SxHXu/+bMgXmVT6dXI5o0UeYqJR7fj6pR4E6T0FwG55RFr5Ok4" + + "3C4cpXmaOu176SyWuoDqGs1RDGmYQjwbZUi23DjaaTFUly9LCYXMliKrQfEDgYQA" + + "AoGAQUGCBN4TaBw1BpdBXdTvTfCU69XDB3eyU2FOBE3UWhpx9D8XJlx4f5DpA4Y6" + + "6sQMuCbhfmjEph8W7/sbMurM/awR+PSR8tTY7jeQV0OkmAYdGK2nzh0ZSifMO1oE" + + "NNhN2O62TLs67msxT28S4/S89+LMtc98mevQ2SX+JF3wEVU="); + + // bogus key with full PKCS parameter set + private byte[] oldFullParams = Base64.Decode( + "MIIBIzCCARgGByqGSM4+AgEwggELAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E" + + "AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f" + + "6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv" + + "8iIDGZ3RSAHHAoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlX" + + "jrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6j" + + "fwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqAgFk" + + "AwUAAgIH0A=="); + + private byte[] samplePubEnc = Base64.Decode( + "MIIBpjCCARsGCSqGSIb3DQEDATCCAQwCgYEA/X9TgR11EilS30qcLuzk5/YRt1I8" + + "70QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWk" + + "n5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HX" + + "Ku/yIgMZndFIAccCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdR" + + "WVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWR" + + "bqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoC" + + "AgIAA4GEAAKBgEIiqxoUW6E6GChoOgcfNbVFclW91ITf5MFSUGQwt2R0RHoOhxvO" + + "lZhNs++d0VPATLAyXovjfgENT9SGCbuZttYcqqLdKTbMXBWPek+rfnAl9E4iEMED" + + "IDd83FJTKs9hQcPAm7zmp0Xm1bGF9CbUFjP5G02265z7eBmHDaT0SNlB"); + + private byte[] samplePrivEnc = Base64.Decode( + "MIIBZgIBADCCARsGCSqGSIb3DQEDATCCAQwCgYEA/X9TgR11EilS30qcLuzk5/YR" + + "t1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZ" + + "UKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOu" + + "K2HXKu/yIgMZndFIAccCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0H" + + "gmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuz" + + "pnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7P" + + "SSoCAgIABEICQAZYXnBHazxXUUdFP4NIf2Ipu7du0suJPZQKKff81wymi2zfCfHh" + + "uhe9gQ9xdm4GpzeNtrQ8/MzpTy+ZVrtd29Q="); + + public override string Name + { + get { return "DH"; } + } + + private void doTestGP( + string algName, + int size, + int privateValueSize, + BigInteger g, + BigInteger p) + { + IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator(algName); + + DHParameters dhParams = new DHParameters(p, g, null, privateValueSize); + KeyGenerationParameters kgp = new DHKeyGenerationParameters(new SecureRandom(), dhParams); + + keyGen.Init(kgp); + + // + // a side + // + AsymmetricCipherKeyPair aKeyPair = keyGen.GenerateKeyPair(); + + IBasicAgreement aKeyAgreeBasic = AgreementUtilities.GetBasicAgreement(algName); + + checkKeySize(privateValueSize, aKeyPair); + + aKeyAgreeBasic.Init(aKeyPair.Private); + + // + // b side + // + AsymmetricCipherKeyPair bKeyPair = keyGen.GenerateKeyPair(); + + IBasicAgreement bKeyAgreeBasic = AgreementUtilities.GetBasicAgreement(algName); + + checkKeySize(privateValueSize, bKeyPair); + + bKeyAgreeBasic.Init(bKeyPair.Private); + + // + // agreement + // // aKeyAgreeBasic.doPhase(bKeyPair.Public, true); // bKeyAgreeBasic.doPhase(aKeyPair.Public, true); // // BigInteger k1 = new BigInteger(aKeyAgreeBasic.generateSecret()); // BigInteger k2 = new BigInteger(bKeyAgreeBasic.generateSecret()); - BigInteger k1 = aKeyAgreeBasic.CalculateAgreement(bKeyPair.Public); - BigInteger k2 = bKeyAgreeBasic.CalculateAgreement(aKeyPair.Public); + BigInteger k1 = aKeyAgreeBasic.CalculateAgreement(bKeyPair.Public); + BigInteger k2 = bKeyAgreeBasic.CalculateAgreement(aKeyPair.Public); - if (!k1.Equals(k2)) - { - Fail(size + " bit 2-way test failed"); - } + if (!k1.Equals(k2)) + { + Fail(size + " bit 2-way test failed"); + } - // - // public key encoding test - // + // + // public key encoding test + // // byte[] pubEnc = aKeyPair.Public.GetEncoded(); - byte[] pubEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(aKeyPair.Public).GetDerEncoded(); + byte[] pubEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(aKeyPair.Public).GetDerEncoded(); // KeyFactory keyFac = KeyFactory.getInstance(algName); // X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); // DHPublicKey pubKey = (DHPublicKey)keyFac.generatePublic(pubX509); - DHPublicKeyParameters pubKey = (DHPublicKeyParameters) PublicKeyFactory.CreateKey(pubEnc); + DHPublicKeyParameters pubKey = (DHPublicKeyParameters) PublicKeyFactory.CreateKey(pubEnc); // DHParameterSpec spec = pubKey.Parameters; - DHParameters spec = pubKey.Parameters; - - if (!spec.G.Equals(dhParams.G) || !spec.P.Equals(dhParams.P)) - { - Fail(size + " bit public key encoding/decoding test failed on parameters"); - } - - if (!((DHPublicKeyParameters)aKeyPair.Public).Y.Equals(pubKey.Y)) - { - Fail(size + " bit public key encoding/decoding test failed on y value"); - } - - // - // public key serialisation test - // - // TODO Put back in + DHParameters spec = pubKey.Parameters; + + if (!spec.G.Equals(dhParams.G) || !spec.P.Equals(dhParams.P)) + { + Fail(size + " bit public key encoding/decoding test failed on parameters"); + } + + if (!((DHPublicKeyParameters)aKeyPair.Public).Y.Equals(pubKey.Y)) + { + Fail(size + " bit public key encoding/decoding test failed on y value"); + } + + // + // public key serialisation test + // + // TODO Put back in // MemoryStream bOut = new MemoryStream(); // ObjectOutputStream oOut = new ObjectOutputStream(bOut); // @@ -164,43 +164,43 @@ namespace Org.BouncyCastle.Tests // ObjectInputStream oIn = new ObjectInputStream(bIn); // // pubKey = (DHPublicKeyParameters)oIn.ReadObject(); - spec = pubKey.Parameters; + spec = pubKey.Parameters; - if (!spec.G.Equals(dhParams.G) || !spec.P.Equals(dhParams.P)) - { - Fail(size + " bit public key serialisation test failed on parameters"); - } + if (!spec.G.Equals(dhParams.G) || !spec.P.Equals(dhParams.P)) + { + Fail(size + " bit public key serialisation test failed on parameters"); + } - if (!((DHPublicKeyParameters)aKeyPair.Public).Y.Equals(pubKey.Y)) - { - Fail(size + " bit public key serialisation test failed on y value"); - } + if (!((DHPublicKeyParameters)aKeyPair.Public).Y.Equals(pubKey.Y)) + { + Fail(size + " bit public key serialisation test failed on y value"); + } - // - // private key encoding test - // + // + // private key encoding test + // // byte[] privEnc = aKeyPair.Private.GetEncoded(); - byte[] privEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(aKeyPair.Private).GetDerEncoded(); + byte[] privEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(aKeyPair.Private).GetDerEncoded(); // PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); // DHPrivateKeyParameters privKey = (DHPrivateKey)keyFac.generatePrivate(privPKCS8); - DHPrivateKeyParameters privKey = (DHPrivateKeyParameters) PrivateKeyFactory.CreateKey(privEnc); + DHPrivateKeyParameters privKey = (DHPrivateKeyParameters) PrivateKeyFactory.CreateKey(privEnc); - spec = privKey.Parameters; + spec = privKey.Parameters; - if (!spec.G.Equals(dhParams.G) || !spec.P.Equals(dhParams.P)) - { - Fail(size + " bit private key encoding/decoding test failed on parameters"); - } + if (!spec.G.Equals(dhParams.G) || !spec.P.Equals(dhParams.P)) + { + Fail(size + " bit private key encoding/decoding test failed on parameters"); + } - if (!((DHPrivateKeyParameters)aKeyPair.Private).X.Equals(privKey.X)) - { - Fail(size + " bit private key encoding/decoding test failed on y value"); - } + if (!((DHPrivateKeyParameters)aKeyPair.Private).X.Equals(privKey.X)) + { + Fail(size + " bit private key encoding/decoding test failed on y value"); + } - // - // private key serialisation test - // - // TODO Put back in + // + // private key serialisation test + // + // TODO Put back in // bOut = new MemoryStream(); // oOut = new ObjectOutputStream(bOut); // @@ -210,42 +210,42 @@ namespace Org.BouncyCastle.Tests // oIn = new ObjectInputStream(bIn); // // privKey = (DHPrivateKeyParameters)oIn.ReadObject(); - spec = privKey.Parameters; + spec = privKey.Parameters; - if (!spec.G.Equals(dhParams.G) || !spec.P.Equals(dhParams.P)) - { - Fail(size + " bit private key serialisation test failed on parameters"); - } + if (!spec.G.Equals(dhParams.G) || !spec.P.Equals(dhParams.P)) + { + Fail(size + " bit private key serialisation test failed on parameters"); + } - if (!((DHPrivateKeyParameters)aKeyPair.Private).X.Equals(privKey.X)) - { - Fail(size + " bit private key serialisation test failed on y value"); - } + if (!((DHPrivateKeyParameters)aKeyPair.Private).X.Equals(privKey.X)) + { + Fail(size + " bit private key serialisation test failed on y value"); + } - // - // three party test - // - IAsymmetricCipherKeyPairGenerator aPairGen = GeneratorUtilities.GetKeyPairGenerator(algName); - aPairGen.Init(new DHKeyGenerationParameters(new SecureRandom(), spec)); - AsymmetricCipherKeyPair aPair = aPairGen.GenerateKeyPair(); + // + // three party test + // + IAsymmetricCipherKeyPairGenerator aPairGen = GeneratorUtilities.GetKeyPairGenerator(algName); + aPairGen.Init(new DHKeyGenerationParameters(new SecureRandom(), spec)); + AsymmetricCipherKeyPair aPair = aPairGen.GenerateKeyPair(); - IAsymmetricCipherKeyPairGenerator bPairGen = GeneratorUtilities.GetKeyPairGenerator(algName); - bPairGen.Init(new DHKeyGenerationParameters(new SecureRandom(), spec)); - AsymmetricCipherKeyPair bPair = bPairGen.GenerateKeyPair(); + IAsymmetricCipherKeyPairGenerator bPairGen = GeneratorUtilities.GetKeyPairGenerator(algName); + bPairGen.Init(new DHKeyGenerationParameters(new SecureRandom(), spec)); + AsymmetricCipherKeyPair bPair = bPairGen.GenerateKeyPair(); - IAsymmetricCipherKeyPairGenerator cPairGen = GeneratorUtilities.GetKeyPairGenerator(algName); - cPairGen.Init(new DHKeyGenerationParameters(new SecureRandom(), spec)); - AsymmetricCipherKeyPair cPair = cPairGen.GenerateKeyPair(); + IAsymmetricCipherKeyPairGenerator cPairGen = GeneratorUtilities.GetKeyPairGenerator(algName); + cPairGen.Init(new DHKeyGenerationParameters(new SecureRandom(), spec)); + AsymmetricCipherKeyPair cPair = cPairGen.GenerateKeyPair(); - IBasicAgreement aKeyAgree = AgreementUtilities.GetBasicAgreement(algName); - aKeyAgree.Init(aPair.Private); + IBasicAgreement aKeyAgree = AgreementUtilities.GetBasicAgreement(algName); + aKeyAgree.Init(aPair.Private); - IBasicAgreement bKeyAgree = AgreementUtilities.GetBasicAgreement(algName); - bKeyAgree.Init(bPair.Private); + IBasicAgreement bKeyAgree = AgreementUtilities.GetBasicAgreement(algName); + bKeyAgree.Init(bPair.Private); - IBasicAgreement cKeyAgree = AgreementUtilities.GetBasicAgreement(algName); - cKeyAgree.Init(cPair.Private); + IBasicAgreement cKeyAgree = AgreementUtilities.GetBasicAgreement(algName); + cKeyAgree.Init(cPair.Private); // Key ac = aKeyAgree.doPhase(cPair.Public, false); // Key ba = bKeyAgree.doPhase(aPair.Public, false); @@ -259,92 +259,92 @@ namespace Org.BouncyCastle.Tests // BigInteger bShared = new BigInteger(bKeyAgree.generateSecret()); // BigInteger cShared = new BigInteger(cKeyAgree.generateSecret()); - DHPublicKeyParameters ac = new DHPublicKeyParameters(aKeyAgree.CalculateAgreement(cPair.Public), spec); - DHPublicKeyParameters ba = new DHPublicKeyParameters(bKeyAgree.CalculateAgreement(aPair.Public), spec); - DHPublicKeyParameters cb = new DHPublicKeyParameters(cKeyAgree.CalculateAgreement(bPair.Public), spec); + DHPublicKeyParameters ac = new DHPublicKeyParameters(aKeyAgree.CalculateAgreement(cPair.Public), spec); + DHPublicKeyParameters ba = new DHPublicKeyParameters(bKeyAgree.CalculateAgreement(aPair.Public), spec); + DHPublicKeyParameters cb = new DHPublicKeyParameters(cKeyAgree.CalculateAgreement(bPair.Public), spec); - BigInteger aShared = aKeyAgree.CalculateAgreement(cb); - BigInteger bShared = bKeyAgree.CalculateAgreement(ac); - BigInteger cShared = cKeyAgree.CalculateAgreement(ba); + BigInteger aShared = aKeyAgree.CalculateAgreement(cb); + BigInteger bShared = bKeyAgree.CalculateAgreement(ac); + BigInteger cShared = cKeyAgree.CalculateAgreement(ba); - if (!aShared.Equals(bShared)) - { - Fail(size + " bit 3-way test failed (a and b differ)"); - } + if (!aShared.Equals(bShared)) + { + Fail(size + " bit 3-way test failed (a and b differ)"); + } - if (!cShared.Equals(bShared)) - { - Fail(size + " bit 3-way test failed (c and b differ)"); - } - } + if (!cShared.Equals(bShared)) + { + Fail(size + " bit 3-way test failed (c and b differ)"); + } + } - private void doTestExplicitWrapping( - int size, - int privateValueSize, - BigInteger g, - BigInteger p) - { - DHParameters dhParams = new DHParameters(p, g, null, privateValueSize); + private void doTestExplicitWrapping( + int size, + int privateValueSize, + BigInteger g, + BigInteger p) + { + DHParameters dhParams = new DHParameters(p, g, null, privateValueSize); - IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("DH"); + IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("DH"); - keyGen.Init(new DHKeyGenerationParameters(new SecureRandom(), dhParams)); + keyGen.Init(new DHKeyGenerationParameters(new SecureRandom(), dhParams)); - // - // a side - // - AsymmetricCipherKeyPair aKeyPair = keyGen.GenerateKeyPair(); + // + // a side + // + AsymmetricCipherKeyPair aKeyPair = keyGen.GenerateKeyPair(); - IBasicAgreement aKeyAgree = AgreementUtilities.GetBasicAgreement("DH"); + IBasicAgreement aKeyAgree = AgreementUtilities.GetBasicAgreement("DH"); - checkKeySize(privateValueSize, aKeyPair); + checkKeySize(privateValueSize, aKeyPair); - aKeyAgree.Init(aKeyPair.Private); + aKeyAgree.Init(aKeyPair.Private); - // - // b side - // - AsymmetricCipherKeyPair bKeyPair = keyGen.GenerateKeyPair(); + // + // b side + // + AsymmetricCipherKeyPair bKeyPair = keyGen.GenerateKeyPair(); - IBasicAgreement bKeyAgree = AgreementUtilities.GetBasicAgreement("DH"); + IBasicAgreement bKeyAgree = AgreementUtilities.GetBasicAgreement("DH"); - checkKeySize(privateValueSize, bKeyPair); + checkKeySize(privateValueSize, bKeyPair); - bKeyAgree.Init(bKeyPair.Private); + bKeyAgree.Init(bKeyPair.Private); - // - // agreement - // + // + // agreement + // // aKeyAgree.doPhase(bKeyPair.Public, true); // bKeyAgree.doPhase(aKeyPair.Public, true); // // SecretKey k1 = aKeyAgree.generateSecret(PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id); // SecretKey k2 = bKeyAgree.generateSecret(PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id); - // TODO Does this really test the same thing as the above code? - BigInteger b1 = aKeyAgree.CalculateAgreement(bKeyPair.Public); - BigInteger b2 = bKeyAgree.CalculateAgreement(aKeyPair.Public); - - if (!b1.Equals(b2)) - { - Fail("Explicit wrapping test failed"); - } - } - - private void checkKeySize( - int privateValueSize, - AsymmetricCipherKeyPair aKeyPair) - { - if (privateValueSize != 0) - { - DHPrivateKeyParameters key = (DHPrivateKeyParameters)aKeyPair.Private; - - if (key.X.BitLength != privateValueSize) - { - Fail("limited key check failed for key size " + privateValueSize); - } - } - } + // TODO Does this really test the same thing as the above code? + BigInteger b1 = aKeyAgree.CalculateAgreement(bKeyPair.Public); + BigInteger b2 = bKeyAgree.CalculateAgreement(aKeyPair.Public); + + if (!b1.Equals(b2)) + { + Fail("Explicit wrapping test failed"); + } + } + + private void checkKeySize( + int privateValueSize, + AsymmetricCipherKeyPair aKeyPair) + { + if (privateValueSize != 0) + { + DHPrivateKeyParameters key = (DHPrivateKeyParameters)aKeyPair.Private; + + if (key.X.BitLength != privateValueSize) + { + Fail("limited key check failed for key size " + privateValueSize); + } + } + } // TODO Put back in // private void doTestRandom( @@ -372,175 +372,176 @@ namespace Org.BouncyCastle.Tests // doTestGP("DH", size, 0, dhP.G, dhP.P); // } - [Test] - public void TestECDH() - { - doTestECDH("ECDH"); - } + [Test] + public void TestECDH() + { + doTestECDH("ECDH"); + } - [Test] - public void TestECDHC() - { - doTestECDH("ECDHC"); - } + [Test] + public void TestECDHC() + { + doTestECDH("ECDHC"); + } - private void doTestECDH( - string algorithm) - { - IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator(algorithm); + private void doTestECDH( + string algorithm) + { + IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator(algorithm); // EllipticCurve curve = new EllipticCurve( // new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q // new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a // new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b - ECCurve curve = new FpCurve( - new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q - new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a - new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b + ECCurve curve = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b - ECDomainParameters ecSpec = new ECDomainParameters( - curve, + ECDomainParameters ecSpec = new ECDomainParameters( + curve, // ECPointUtil.DecodePoint(curve, Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G - curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G - new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n - BigInteger.One); //1); // h + curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G + new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n + BigInteger.One); //1); // h // g.initialize(ecSpec, new SecureRandom()); - g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom())); + g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom())); - // - // a side - // - AsymmetricCipherKeyPair aKeyPair = g.GenerateKeyPair(); + // + // a side + // + AsymmetricCipherKeyPair aKeyPair = g.GenerateKeyPair(); - IBasicAgreement aKeyAgreeBasic = AgreementUtilities.GetBasicAgreement(algorithm); + IBasicAgreement aKeyAgreeBasic = AgreementUtilities.GetBasicAgreement(algorithm); - aKeyAgreeBasic.Init(aKeyPair.Private); + aKeyAgreeBasic.Init(aKeyPair.Private); - // - // b side - // - AsymmetricCipherKeyPair bKeyPair = g.GenerateKeyPair(); + // + // b side + // + AsymmetricCipherKeyPair bKeyPair = g.GenerateKeyPair(); - IBasicAgreement bKeyAgreeBasic = AgreementUtilities.GetBasicAgreement(algorithm); + IBasicAgreement bKeyAgreeBasic = AgreementUtilities.GetBasicAgreement(algorithm); - bKeyAgreeBasic.Init(bKeyPair.Private); + bKeyAgreeBasic.Init(bKeyPair.Private); - // - // agreement - // + // + // agreement + // // aKeyAgreeBasic.doPhase(bKeyPair.Public, true); // bKeyAgreeBasic.doPhase(aKeyPair.Public, true); // // BigInteger k1 = new BigInteger(aKeyAgreeBasic.generateSecret()); // BigInteger k2 = new BigInteger(bKeyAgreeBasic.generateSecret()); - BigInteger k1 = aKeyAgreeBasic.CalculateAgreement(bKeyPair.Public); - BigInteger k2 = bKeyAgreeBasic.CalculateAgreement(aKeyPair.Public); + BigInteger k1 = aKeyAgreeBasic.CalculateAgreement(bKeyPair.Public); + BigInteger k2 = bKeyAgreeBasic.CalculateAgreement(aKeyPair.Public); - if (!k1.Equals(k2)) - { - Fail(algorithm + " 2-way test failed"); - } + if (!k1.Equals(k2)) + { + Fail(algorithm + " 2-way test failed"); + } - // - // public key encoding test - // + // + // public key encoding test + // // byte[] pubEnc = aKeyPair.Public.GetEncoded(); - byte[] pubEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(aKeyPair.Public).GetDerEncoded(); + byte[] pubEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(aKeyPair.Public).GetDerEncoded(); // KeyFactory keyFac = KeyFactory.getInstance(algorithm); // X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc); // ECPublicKey pubKey = (ECPublicKey)keyFac.generatePublic(pubX509); - ECPublicKeyParameters pubKey = (ECPublicKeyParameters) PublicKeyFactory.CreateKey(pubEnc); + ECPublicKeyParameters pubKey = (ECPublicKeyParameters) PublicKeyFactory.CreateKey(pubEnc); - ECDomainParameters ecDP = pubKey.Parameters; + ECDomainParameters ecDP = pubKey.Parameters; // if (!pubKey.getW().Equals(((ECPublicKeyParameters)aKeyPair.Public).getW())) - if (!pubKey.Q.Equals(((ECPublicKeyParameters)aKeyPair.Public).Q)) - { + ECPoint pq1 = pubKey.Q.Normalize(), pq2 = ((ECPublicKeyParameters)aKeyPair.Public).Q.Normalize(); + if (!pq1.Equals(pq2)) + { // Console.WriteLine(" expected " + pubKey.getW().getAffineX() + " got " + ((ECPublicKey)aKeyPair.Public).getW().getAffineX()); // Console.WriteLine(" expected " + pubKey.getW().getAffineY() + " got " + ((ECPublicKey)aKeyPair.Public).getW().getAffineY()); // Fail(algorithm + " public key encoding (W test) failed"); - Console.WriteLine(" expected " + pubKey.Q.X.ToBigInteger() - + " got " + ((ECPublicKeyParameters)aKeyPair.Public).Q.X.ToBigInteger()); - Console.WriteLine(" expected " + pubKey.Q.Y.ToBigInteger() - + " got " + ((ECPublicKeyParameters)aKeyPair.Public).Q.Y.ToBigInteger()); - Fail(algorithm + " public key encoding (Q test) failed"); - } + Console.WriteLine(" expected " + pq1.AffineXCoord.ToBigInteger() + + " got " + pq2.AffineXCoord.ToBigInteger()); + Console.WriteLine(" expected " + pq1.AffineYCoord.ToBigInteger() + + " got " + pq2.AffineYCoord.ToBigInteger()); + Fail(algorithm + " public key encoding (Q test) failed"); + } // if (!pubKey.Parameters.getGenerator().Equals(((ECPublicKeyParameters)aKeyPair.Public).Parameters.getGenerator())) - if (!pubKey.Parameters.G.Equals(((ECPublicKeyParameters)aKeyPair.Public).Parameters.G)) - { - Fail(algorithm + " public key encoding (G test) failed"); - } - - // - // private key encoding test - // + if (!pubKey.Parameters.G.Equals(((ECPublicKeyParameters)aKeyPair.Public).Parameters.G)) + { + Fail(algorithm + " public key encoding (G test) failed"); + } + + // + // private key encoding test + // // byte[] privEnc = aKeyPair.Private.GetEncoded(); - byte[] privEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(aKeyPair.Private).GetDerEncoded(); + byte[] privEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(aKeyPair.Private).GetDerEncoded(); // PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc); // ECPrivateKey privKey = (ECPrivateKey)keyFac.generatePrivate(privPKCS8); - ECPrivateKeyParameters privKey = (ECPrivateKeyParameters) PrivateKeyFactory.CreateKey(privEnc); + ECPrivateKeyParameters privKey = (ECPrivateKeyParameters) PrivateKeyFactory.CreateKey(privEnc); // if (!privKey.getS().Equals(((ECPrivateKey)aKeyPair.Private).getS())) - if (!privKey.D.Equals(((ECPrivateKeyParameters)aKeyPair.Private).D)) - { + if (!privKey.D.Equals(((ECPrivateKeyParameters)aKeyPair.Private).D)) + { // Fail(algorithm + " private key encoding (S test) failed"); - Fail(algorithm + " private key encoding (D test) failed"); - } + Fail(algorithm + " private key encoding (D test) failed"); + } // if (!privKey.Parameters.getGenerator().Equals(((ECPrivateKey)aKeyPair.Private).Parameters.getGenerator())) - if (!privKey.Parameters.G.Equals(((ECPrivateKeyParameters)aKeyPair.Private).Parameters.G)) - { - Fail(algorithm + " private key encoding (G test) failed"); - } - } + if (!privKey.Parameters.G.Equals(((ECPrivateKeyParameters)aKeyPair.Private).Parameters.G)) + { + Fail(algorithm + " private key encoding (G test) failed"); + } + } - [Test] - public void TestExceptions() - { - DHParameters dhParams = new DHParameters(p512, g512); + [Test] + public void TestExceptions() + { + DHParameters dhParams = new DHParameters(p512, g512); - try - { - IBasicAgreement aKeyAgreeBasic = AgreementUtilities.GetBasicAgreement("DH"); + try + { + IBasicAgreement aKeyAgreeBasic = AgreementUtilities.GetBasicAgreement("DH"); // aKeyAgreeBasic.generateSecret("DES"); - aKeyAgreeBasic.CalculateAgreement(null); - } - catch (InvalidOperationException) - { - // okay - } - catch (Exception e) - { - Fail("Unexpected exception: " + e, e); - } - } + aKeyAgreeBasic.CalculateAgreement(null); + } + catch (InvalidOperationException) + { + // okay + } + catch (Exception e) + { + Fail("Unexpected exception: " + e, e); + } + } - private void doTestDesAndDesEde( - BigInteger g, - BigInteger p) - { - DHParameters dhParams = new DHParameters(p, g, null, 256); + private void doTestDesAndDesEde( + BigInteger g, + BigInteger p) + { + DHParameters dhParams = new DHParameters(p, g, null, 256); - IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("DH"); + IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("DH"); - keyGen.Init(new DHKeyGenerationParameters(new SecureRandom(), dhParams)); + keyGen.Init(new DHKeyGenerationParameters(new SecureRandom(), dhParams)); - AsymmetricCipherKeyPair kp = keyGen.GenerateKeyPair(); + AsymmetricCipherKeyPair kp = keyGen.GenerateKeyPair(); - IBasicAgreement keyAgreement = AgreementUtilities.GetBasicAgreement("DH"); + IBasicAgreement keyAgreement = AgreementUtilities.GetBasicAgreement("DH"); - keyAgreement.Init(kp.Private); - BigInteger agreed = keyAgreement.CalculateAgreement(kp.Public); - byte[] agreedBytes = agreed.ToByteArrayUnsigned(); + keyAgreement.Init(kp.Private); + BigInteger agreed = keyAgreement.CalculateAgreement(kp.Public); + byte[] agreedBytes = agreed.ToByteArrayUnsigned(); - // TODO Figure out where the magic happens of choosing the right - // bytes from 'agreedBytes' for each key type - need C# equivalent? - // (see JCEDHKeyAgreement.engineGenerateSecret) + // TODO Figure out where the magic happens of choosing the right + // bytes from 'agreedBytes' for each key type - need C# equivalent? + // (see JCEDHKeyAgreement.engineGenerateSecret) // SecretKey key = keyAgreement.generateSecret("DES"); // @@ -572,79 +573,79 @@ namespace Org.BouncyCastle.Tests // { // Fail("Blowfish length wrong"); // } - } - - [Test] - public void TestFunction() - { - doTestGP("DH", 512, 0, g512, p512); - doTestGP("DiffieHellman", 768, 0, g768, p768); - doTestGP("DIFFIEHELLMAN", 1024, 0, g1024, p1024); - doTestGP("DH", 512, 64, g512, p512); - doTestGP("DiffieHellman", 768, 128, g768, p768); - doTestGP("DIFFIEHELLMAN", 1024, 256, g1024, p1024); - doTestExplicitWrapping(512, 0, g512, p512); - doTestDesAndDesEde(g768, p768); - - // TODO Put back in - //doTestRandom(256); - } - - [Test] - public void TestEnc() - { + } + + [Test] + public void TestFunction() + { + doTestGP("DH", 512, 0, g512, p512); + doTestGP("DiffieHellman", 768, 0, g768, p768); + doTestGP("DIFFIEHELLMAN", 1024, 0, g1024, p1024); + doTestGP("DH", 512, 64, g512, p512); + doTestGP("DiffieHellman", 768, 128, g768, p768); + doTestGP("DIFFIEHELLMAN", 1024, 256, g1024, p1024); + doTestExplicitWrapping(512, 0, g512, p512); + doTestDesAndDesEde(g768, p768); + + // TODO Put back in + //doTestRandom(256); + } + + [Test] + public void TestEnc() + { // KeyFactory kFact = KeyFactory.getInstance("DH", "BC"); // // Key k = kFact.generatePrivate(new PKCS8EncodedKeySpec(samplePrivEnc)); - AsymmetricKeyParameter k = PrivateKeyFactory.CreateKey(samplePrivEnc); - byte[] encoded = PrivateKeyInfoFactory.CreatePrivateKeyInfo(k).GetEncoded(); + AsymmetricKeyParameter k = PrivateKeyFactory.CreateKey(samplePrivEnc); + byte[] encoded = PrivateKeyInfoFactory.CreatePrivateKeyInfo(k).GetEncoded(); - if (!Arrays.AreEqual(samplePrivEnc, encoded)) - { - Fail("private key re-encode failed"); - } + if (!Arrays.AreEqual(samplePrivEnc, encoded)) + { + Fail("private key re-encode failed"); + } // k = kFact.generatePublic(new X509EncodedKeySpec(samplePubEnc)); - k = PublicKeyFactory.CreateKey(samplePubEnc); - encoded = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(k).GetEncoded(); + k = PublicKeyFactory.CreateKey(samplePubEnc); + encoded = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(k).GetEncoded(); - if (!Arrays.AreEqual(samplePubEnc, encoded)) - { - Fail("public key re-encode failed"); - } + if (!Arrays.AreEqual(samplePubEnc, encoded)) + { + Fail("public key re-encode failed"); + } // k = kFact.generatePublic(new X509EncodedKeySpec(oldPubEnc)); - k = PublicKeyFactory.CreateKey(oldPubEnc); - encoded = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(k).GetEncoded(); + k = PublicKeyFactory.CreateKey(oldPubEnc); + encoded = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(k).GetEncoded(); - if (!Arrays.AreEqual(oldPubEnc, encoded)) - { - Fail("old public key re-encode failed"); - } + if (!Arrays.AreEqual(oldPubEnc, encoded)) + { + Fail("old public key re-encode failed"); + } // k = kFact.generatePublic(new X509EncodedKeySpec(oldFullParams)); - k = PublicKeyFactory.CreateKey(oldFullParams); - encoded = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(k).GetEncoded(); - - if (!Arrays.AreEqual(oldFullParams, encoded)) - { - Fail("old full public key re-encode failed"); - } - } - - public override void PerformTest() - { - TestEnc(); - TestFunction(); - TestECDH(); - TestECDHC(); - TestExceptions(); - } - - public static void Main( - string[] args) - { - RunTest(new DHTest()); - } - } + k = PublicKeyFactory.CreateKey(oldFullParams); + encoded = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(k).GetEncoded(); + + if (!Arrays.AreEqual(oldFullParams, encoded)) + { + Fail("old full public key re-encode failed"); + } + } + + public override void PerformTest() + { + TestEnc(); + TestFunction(); + TestECDH(); + TestECDHC(); + TestExceptions(); + } + + public static void Main( + string[] args) + { + RunTest(new DHTest()); + } + } } diff --git a/crypto/test/src/test/ECDSA5Test.cs b/crypto/test/src/test/ECDSA5Test.cs index bbde6b446..3bf746edb 100644 --- a/crypto/test/src/test/ECDSA5Test.cs +++ b/crypto/test/src/test/ECDSA5Test.cs @@ -13,288 +13,288 @@ using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.Tests { - [TestFixture] - public class ECDsa5Test - : SimpleTest - { + [TestFixture] + public class ECDsa5Test + : SimpleTest + { // private static readonly byte[] k1 = Hex.Decode("d5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); // private static readonly byte[] k2 = Hex.Decode("345e8d05c075c3a508df729a1685690e68fcfb8c8117847e89063bca1f85d968fd281540b6e13bd1af989a1fbf17e06462bf511f9d0b140fb48ac1b1baa5bded"); // // private SecureRandom random = FixedSecureRandom.From(k1, k2); - [Test] - public void DecodeTest() - { + [Test] + public void DecodeTest() + { // EllipticCurve curve = new EllipticCurve( // new ECFieldFp(new BigInteger("6277101735386680763835789423207666416083908700390324961279")), // q // new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a // new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b - ECCurve curve = new FpCurve( - new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q - new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a - new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b + ECCurve curve = new FpCurve( + new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q + new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a + new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b // ECPoint p = ECPointUtil.DecodePoint(curve, Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")); - ECPoint p = curve.DecodePoint(Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")); + ECPoint p = curve.DecodePoint(Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")); - BigInteger x = p.X.ToBigInteger(); //p.getAffineX(); + BigInteger x = p.XCoord.ToBigInteger(); //p.getAffineX(); - if (!x.Equals(new BigInteger("188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", 16))) - { - Fail("x uncompressed incorrectly"); - } + if (!x.Equals(new BigInteger("188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", 16))) + { + Fail("x uncompressed incorrectly"); + } - BigInteger y = p.Y.ToBigInteger(); //p.getAffineX(); - if (!y.Equals(new BigInteger("7192b95ffc8da78631011ed6b24cdd573f977a11e794811", 16))) - { - Fail("y uncompressed incorrectly"); - } - } + BigInteger y = p.YCoord.ToBigInteger(); //p.getAffineX(); + if (!y.Equals(new BigInteger("7192b95ffc8da78631011ed6b24cdd573f977a11e794811", 16))) + { + Fail("y uncompressed incorrectly"); + } + } - /** - * X9.62 - 1998,
- * J.3.2, Page 155, ECDSA over the field Fp
- * an example with 239 bit prime - */ - [Test] - public void TestECDsa239BitPrime() - { - BigInteger r = new BigInteger("308636143175167811492622547300668018854959378758531778147462058306432176"); - BigInteger s = new BigInteger("323813553209797357708078776831250505931891051755007842781978505179448783"); + /** + * X9.62 - 1998,
+ * J.3.2, Page 155, ECDSA over the field Fp
+ * an example with 239 bit prime + */ + [Test] + public void TestECDsa239BitPrime() + { + BigInteger r = new BigInteger("308636143175167811492622547300668018854959378758531778147462058306432176"); + BigInteger s = new BigInteger("323813553209797357708078776831250505931891051755007842781978505179448783"); - byte[] kData = new BigInteger("700000017569056646655505781757157107570501575775705779575555657156756655").ToByteArrayUnsigned(); + byte[] kData = new BigInteger("700000017569056646655505781757157107570501575775705779575555657156756655").ToByteArrayUnsigned(); - SecureRandom k = FixedSecureRandom.From(kData); + SecureRandom k = FixedSecureRandom.From(kData); // EllipticCurve curve = new EllipticCurve( // new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q // new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a // new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b - ECCurve curve = new FpCurve( - new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q - new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a - new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b + ECCurve curve = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b - ECDomainParameters spec = new ECDomainParameters( - curve, + ECDomainParameters spec = new ECDomainParameters( + curve, // ECPointUtil.DecodePoint(curve, Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G - curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G - new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n - BigInteger.One); //1); // h + curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G + new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n + BigInteger.One); //1); // h - ECPrivateKeyParameters sKey = new ECPrivateKeyParameters( - "ECDSA", - new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d - spec); + ECPrivateKeyParameters sKey = new ECPrivateKeyParameters( + "ECDSA", + new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d + spec); - ECPublicKeyParameters vKey = new ECPublicKeyParameters( - "ECDSA", + ECPublicKeyParameters vKey = new ECPublicKeyParameters( + "ECDSA", // ECPointUtil.DecodePoint(curve, Hex.Decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q - curve.DecodePoint(Hex.Decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q - spec); + curve.DecodePoint(Hex.Decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q + spec); - ISigner sgr = SignerUtilities.GetSigner("ECDSA"); + ISigner sgr = SignerUtilities.GetSigner("ECDSA"); // KeyFactory f = KeyFactory.getInstance("ECDSA"); // AsymmetricKeyParameter sKey = f.generatePrivate(priKey); // AsymmetricKeyParameter vKey = f.generatePublic(pubKey); - sgr.Init(true, new ParametersWithRandom(sKey, k)); + sgr.Init(true, new ParametersWithRandom(sKey, k)); - byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; + byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; - sgr.BlockUpdate(message, 0, message.Length); + sgr.BlockUpdate(message, 0, message.Length); - byte[] sigBytes = sgr.GenerateSignature(); + byte[] sigBytes = sgr.GenerateSignature(); - sgr.Init(false, vKey); + sgr.Init(false, vKey); - sgr.BlockUpdate(message, 0, message.Length); + sgr.BlockUpdate(message, 0, message.Length); - if (!sgr.VerifySignature(sigBytes)) - { - Fail("239 Bit EC verification failed"); - } + if (!sgr.VerifySignature(sigBytes)) + { + Fail("239 Bit EC verification failed"); + } - BigInteger[] sig = derDecode(sigBytes); + BigInteger[] sig = derDecode(sigBytes); - if (!r.Equals(sig[0])) - { - Fail("r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } + if (!r.Equals(sig[0])) + { + Fail("r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } - if (!s.Equals(sig[1])) - { - Fail("s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - } + if (!s.Equals(sig[1])) + { + Fail("s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + } - /** - * X9.62 - 1998,
- * J.2.1, Page 100, ECDSA over the field F2m
- * an example with 191 bit binary field - */ - [Test] - public void TestECDsa239BitBinary() - { - BigInteger r = new BigInteger("21596333210419611985018340039034612628818151486841789642455876922391552"); - BigInteger s = new BigInteger("197030374000731686738334997654997227052849804072198819102649413465737174"); - - byte[] kData = new BigInteger("171278725565216523967285789236956265265265235675811949404040041670216363").ToByteArrayUnsigned(); + /** + * X9.62 - 1998,
+ * J.2.1, Page 100, ECDSA over the field F2m
+ * an example with 191 bit binary field + */ + [Test] + public void TestECDsa239BitBinary() + { + BigInteger r = new BigInteger("21596333210419611985018340039034612628818151486841789642455876922391552"); + BigInteger s = new BigInteger("197030374000731686738334997654997227052849804072198819102649413465737174"); + + byte[] kData = new BigInteger("171278725565216523967285789236956265265265235675811949404040041670216363").ToByteArrayUnsigned(); - SecureRandom k = FixedSecureRandom.From(kData); + SecureRandom k = FixedSecureRandom.From(kData); // EllipticCurve curve = new EllipticCurve( // new ECFieldF2m(239, // m // new int[] { 36 }), // k // new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a // new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b - ECCurve curve = new F2mCurve( - 239, // m - 36, // k - new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a - new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b - - ECDomainParameters parameters = new ECDomainParameters( - curve, + ECCurve curve = new F2mCurve( + 239, // m + 36, // k + new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a + new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b + + ECDomainParameters parameters = new ECDomainParameters( + curve, // ECPointUtil.DecodePoint(curve, Hex.Decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G - curve.DecodePoint(Hex.Decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G - new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n - BigInteger.ValueOf(4)); //4); // h + curve.DecodePoint(Hex.Decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G + new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n + BigInteger.ValueOf(4)); //4); // h - ECPrivateKeyParameters sKey = new ECPrivateKeyParameters( - "ECDSA", - new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d - parameters); + ECPrivateKeyParameters sKey = new ECPrivateKeyParameters( + "ECDSA", + new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d + parameters); - ECPublicKeyParameters vKey = new ECPublicKeyParameters( - "ECDSA", + ECPublicKeyParameters vKey = new ECPublicKeyParameters( + "ECDSA", // ECPointUtil.DecodePoint(curve, Hex.Decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q - curve.DecodePoint(Hex.Decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q - parameters); + curve.DecodePoint(Hex.Decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q + parameters); - ISigner sgr = SignerUtilities.GetSigner("ECDSA"); + ISigner sgr = SignerUtilities.GetSigner("ECDSA"); // KeyFactory f = KeyFactory.getInstance("ECDSA"); // AsymmetricKeyParameter sKey = f.generatePrivate(priKeySpec); // AsymmetricKeyParameter vKey = f.generatePublic(pubKeySpec); - byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; + byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; - sgr.Init(true, new ParametersWithRandom(sKey, k)); + sgr.Init(true, new ParametersWithRandom(sKey, k)); - sgr.BlockUpdate(message, 0, message.Length); + sgr.BlockUpdate(message, 0, message.Length); - byte[] sigBytes = sgr.GenerateSignature(); + byte[] sigBytes = sgr.GenerateSignature(); - sgr.Init(false, vKey); + sgr.Init(false, vKey); - sgr.BlockUpdate(message, 0, message.Length); + sgr.BlockUpdate(message, 0, message.Length); - if (!sgr.VerifySignature(sigBytes)) - { - Fail("239 Bit EC verification failed"); - } + if (!sgr.VerifySignature(sigBytes)) + { + Fail("239 Bit EC verification failed"); + } - BigInteger[] sig = derDecode(sigBytes); + BigInteger[] sig = derDecode(sigBytes); - if (!r.Equals(sig[0])) - { - Fail("r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } + if (!r.Equals(sig[0])) + { + Fail("r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } - if (!s.Equals(sig[1])) - { - Fail("s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - } + if (!s.Equals(sig[1])) + { + Fail("s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + } - [Test] - public void TestGeneration() - { - // - // ECDSA generation test - // - byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; - ISigner s = SignerUtilities.GetSigner("ECDSA"); - IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("ECDSA"); + [Test] + public void TestGeneration() + { + // + // ECDSA generation test + // + byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; + ISigner s = SignerUtilities.GetSigner("ECDSA"); + IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("ECDSA"); // EllipticCurve curve = new EllipticCurve( // new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q // new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a // new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b - ECCurve curve = new FpCurve( - new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q - new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a - new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b + ECCurve curve = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b - ECDomainParameters ecSpec = new ECDomainParameters( - curve, + ECDomainParameters ecSpec = new ECDomainParameters( + curve, // ECPointUtil.DecodePoint(curve, - curve.DecodePoint( - Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G - new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n - BigInteger.One); //1); // h + curve.DecodePoint( + Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G + new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n + BigInteger.One); //1); // h - g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom())); + g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom())); - AsymmetricCipherKeyPair p = g.GenerateKeyPair(); + AsymmetricCipherKeyPair p = g.GenerateKeyPair(); - AsymmetricKeyParameter sKey = p.Private; - AsymmetricKeyParameter vKey = p.Public; + AsymmetricKeyParameter sKey = p.Private; + AsymmetricKeyParameter vKey = p.Public; - s.Init(true, sKey); + s.Init(true, sKey); - s.BlockUpdate(data, 0, data.Length); + s.BlockUpdate(data, 0, data.Length); - byte[] sigBytes = s.GenerateSignature(); + byte[] sigBytes = s.GenerateSignature(); - s = SignerUtilities.GetSigner("ECDSA"); + s = SignerUtilities.GetSigner("ECDSA"); - s.Init(false, vKey); + s.Init(false, vKey); - s.BlockUpdate(data, 0, data.Length); + s.BlockUpdate(data, 0, data.Length); - if (!s.VerifySignature(sigBytes)) - { - Fail("ECDSA verification failed"); - } - } + if (!s.VerifySignature(sigBytes)) + { + Fail("ECDSA verification failed"); + } + } - protected BigInteger[] derDecode( - byte[] encoding) - { - Asn1Sequence s = (Asn1Sequence) Asn1Object.FromByteArray(encoding); + protected BigInteger[] derDecode( + byte[] encoding) + { + Asn1Sequence s = (Asn1Sequence) Asn1Object.FromByteArray(encoding); - return new BigInteger[] - { - ((DerInteger)s[0]).Value, - ((DerInteger)s[1]).Value - }; - } + return new BigInteger[] + { + ((DerInteger)s[0]).Value, + ((DerInteger)s[1]).Value + }; + } - public override string Name - { - get { return "ECDSA5"; } - } + public override string Name + { + get { return "ECDSA5"; } + } - public override void PerformTest() - { - DecodeTest(); - TestECDsa239BitPrime(); - TestECDsa239BitBinary(); - TestGeneration(); - } + public override void PerformTest() + { + DecodeTest(); + TestECDsa239BitPrime(); + TestECDsa239BitBinary(); + TestGeneration(); + } - public static void Main( - string[] args) - { - RunTest(new ECDsa5Test()); - } - } + public static void Main( + string[] args) + { + RunTest(new ECDsa5Test()); + } + } } diff --git a/crypto/test/src/test/ECEncodingTest.cs b/crypto/test/src/test/ECEncodingTest.cs index 0e80d611a..f1a4d5e3a 100644 --- a/crypto/test/src/test/ECEncodingTest.cs +++ b/crypto/test/src/test/ECEncodingTest.cs @@ -112,8 +112,8 @@ namespace Org.BouncyCastle.Tests pubKey = SetPublicUncompressed(pubKey, false); } - byte[] x = pubKey.Q.X.ToBigInteger().ToByteArrayUnsigned(); - byte[] y = pubKey.Q.Y.ToBigInteger().ToByteArrayUnsigned(); + byte[] x = pubKey.Q.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(); + byte[] y = pubKey.Q.AffineYCoord.ToBigInteger().ToByteArrayUnsigned(); if (x.Length == y.Length) { success = true; @@ -219,10 +219,10 @@ namespace Org.BouncyCastle.Tests ECPublicKeyParameters key, bool withCompression) { - ECPoint p = key.Q; + ECPoint p = key.Q.Normalize(); return new ECPublicKeyParameters( key.AlgorithmName, - p.Curve.CreatePoint(p.X.ToBigInteger(), p.Y.ToBigInteger(), withCompression), + p.Curve.CreatePoint(p.XCoord.ToBigInteger(), p.YCoord.ToBigInteger(), withCompression), key.Parameters); } diff --git a/crypto/test/src/test/PKCS10CertRequestTest.cs b/crypto/test/src/test/PKCS10CertRequestTest.cs index b1fe4f50f..8af43b2e4 100644 --- a/crypto/test/src/test/PKCS10CertRequestTest.cs +++ b/crypto/test/src/test/PKCS10CertRequestTest.cs @@ -20,131 +20,131 @@ using Org.BouncyCastle.X509.Extension; namespace Org.BouncyCastle.Tests { - [TestFixture] - public class Pkcs10CertRequestTest - : SimpleTest - { - private static readonly byte[] gost3410EC_A = Base64.Decode( - "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" - +"BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" - +"MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4B" - +"A0MABEBYx0P2D7YuuZo5HgdIAUKAXcLBDZ+4LYFgbKjrfStVfH59lc40BQ2FZ7M703hLpXK8GiBQ" - +"GEYpKaAuQZnMIpByoAAwCAYGKoUDAgIDA0EAgXMcTrhdOY2Er2tHOSAgnMezqrYxocZTWhxmW5Rl" - +"JY6lbXH5rndCn4swFzXU+YhgAsJv1wQBaoZEWRl5WV4/nA=="); - - private static readonly byte[] gost3410EC_B = Base64.Decode( - "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" - +"A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" - +"MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICIwIGByqFAwIC" - +"HgEDQwAEQI5SLoWT7dZVilbV9j5B/fyIDuDs6x4pjqNC2TtFYbpRHrk/Wc5g/mcHvD80tsm5o1C7" - +"7cizNzkvAVUM4VT4Dz6gADAIBgYqhQMCAgMDQQAoT5TwJ8o+bSrxckymyo3diwG7ZbSytX4sRiKy" - +"wXPWRS9LlBvPO2NqwpS2HUnxSU8rzfL9fJcybATf7Yt1OEVq"); - - private static readonly byte[] gost3410EC_C = Base64.Decode( - "MIIBRDCB9AIBADCBhzEVMBMGA1UEAxMMdGVzdCByZXF1ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBM" - +"dGQxHjAcBgNVBAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYD" - +"VQQGEwJydTEZMBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMD" - +"BgcqhQMCAh4BA0MABEBcmGh7OmR4iqqj+ycYo1S1fS7r5PhisSQU2Ezuz8wmmmR2zeTZkdMYCOBa" - +"UTMNms0msW3wuYDho7nTDNscHTB5oAAwCAYGKoUDAgIDA0EAVoOMbfyo1Un4Ss7WQrUjHJoiaYW8" - +"Ime5LeGGU2iW3ieAv6es/FdMrwTKkqn5dhd3aL/itFg5oQbhyfXw5yw/QQ=="); - - private static readonly byte[] gost3410EC_ExA = Base64.Decode( - "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" - + "BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" - + "MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiQABgcqhQMCAh4B" - + "A0MABEDkqNT/3f8NHj6EUiWnK4JbVZBh31bEpkwq9z3jf0u8ZndG56Vt+K1ZB6EpFxLT7hSIos0w" - + "weZ2YuTZ4w43OgodoAAwCAYGKoUDAgIDA0EASk/IUXWxoi6NtcUGVF23VRV1L3undB4sRZLp4Vho" - + "gQ7m3CMbZFfJ2cPu6QyarseXGYHmazoirH5lGjEo535c1g=="); - - private static readonly byte[] gost3410EC_ExB = Base64.Decode( - "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" - + "A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" - + "MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICJAEGByqFAwIC" - + "HgEDQwAEQMBWYUKPy/1Kxad9ChAmgoSWSYOQxRnXo7KEGLU5RNSXA4qMUvArWzvhav+EYUfTbWLh" - + "09nELDyHt2XQcvgQHnSgADAIBgYqhQMCAgMDQQAdaNhgH/ElHp64mbMaEo1tPCg9Q22McxpH8rCz" - + "E0QBpF4H5mSSQVGI5OAXHToetnNuh7gHHSynyCupYDEHTbkZ"); - - public override string Name - { - get { return "PKCS10CertRequest"; } - } - - private void generationTest( - int keySize, - string keyName, - string sigName) - { - IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator(keyName); + [TestFixture] + public class Pkcs10CertRequestTest + : SimpleTest + { + private static readonly byte[] gost3410EC_A = Base64.Decode( + "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" + +"BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" + +"MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4B" + +"A0MABEBYx0P2D7YuuZo5HgdIAUKAXcLBDZ+4LYFgbKjrfStVfH59lc40BQ2FZ7M703hLpXK8GiBQ" + +"GEYpKaAuQZnMIpByoAAwCAYGKoUDAgIDA0EAgXMcTrhdOY2Er2tHOSAgnMezqrYxocZTWhxmW5Rl" + +"JY6lbXH5rndCn4swFzXU+YhgAsJv1wQBaoZEWRl5WV4/nA=="); + + private static readonly byte[] gost3410EC_B = Base64.Decode( + "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" + +"A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" + +"MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICIwIGByqFAwIC" + +"HgEDQwAEQI5SLoWT7dZVilbV9j5B/fyIDuDs6x4pjqNC2TtFYbpRHrk/Wc5g/mcHvD80tsm5o1C7" + +"7cizNzkvAVUM4VT4Dz6gADAIBgYqhQMCAgMDQQAoT5TwJ8o+bSrxckymyo3diwG7ZbSytX4sRiKy" + +"wXPWRS9LlBvPO2NqwpS2HUnxSU8rzfL9fJcybATf7Yt1OEVq"); + + private static readonly byte[] gost3410EC_C = Base64.Decode( + "MIIBRDCB9AIBADCBhzEVMBMGA1UEAxMMdGVzdCByZXF1ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBM" + +"dGQxHjAcBgNVBAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYD" + +"VQQGEwJydTEZMBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMD" + +"BgcqhQMCAh4BA0MABEBcmGh7OmR4iqqj+ycYo1S1fS7r5PhisSQU2Ezuz8wmmmR2zeTZkdMYCOBa" + +"UTMNms0msW3wuYDho7nTDNscHTB5oAAwCAYGKoUDAgIDA0EAVoOMbfyo1Un4Ss7WQrUjHJoiaYW8" + +"Ime5LeGGU2iW3ieAv6es/FdMrwTKkqn5dhd3aL/itFg5oQbhyfXw5yw/QQ=="); + + private static readonly byte[] gost3410EC_ExA = Base64.Decode( + "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" + + "BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" + + "MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiQABgcqhQMCAh4B" + + "A0MABEDkqNT/3f8NHj6EUiWnK4JbVZBh31bEpkwq9z3jf0u8ZndG56Vt+K1ZB6EpFxLT7hSIos0w" + + "weZ2YuTZ4w43OgodoAAwCAYGKoUDAgIDA0EASk/IUXWxoi6NtcUGVF23VRV1L3undB4sRZLp4Vho" + + "gQ7m3CMbZFfJ2cPu6QyarseXGYHmazoirH5lGjEo535c1g=="); + + private static readonly byte[] gost3410EC_ExB = Base64.Decode( + "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" + + "A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" + + "MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICJAEGByqFAwIC" + + "HgEDQwAEQMBWYUKPy/1Kxad9ChAmgoSWSYOQxRnXo7KEGLU5RNSXA4qMUvArWzvhav+EYUfTbWLh" + + "09nELDyHt2XQcvgQHnSgADAIBgYqhQMCAgMDQQAdaNhgH/ElHp64mbMaEo1tPCg9Q22McxpH8rCz" + + "E0QBpF4H5mSSQVGI5OAXHToetnNuh7gHHSynyCupYDEHTbkZ"); + + public override string Name + { + get { return "PKCS10CertRequest"; } + } + + private void generationTest( + int keySize, + string keyName, + string sigName) + { + IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator(keyName); // kpg.initialize(keySize); - kpg.Init(new KeyGenerationParameters(new SecureRandom(), keySize)); - - AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair(); - - IDictionary attrs = new Hashtable(); - attrs.Add(X509Name.C, "AU"); - attrs.Add(X509Name.O, "The Legion of the Bouncy Castle"); - attrs.Add(X509Name.L, "Melbourne"); - attrs.Add(X509Name.ST, "Victoria"); - attrs.Add(X509Name.EmailAddress, "feedback-crypto@bouncycastle.org"); - - IList order = new ArrayList(); - order.Add(X509Name.C); - order.Add(X509Name.O); - order.Add(X509Name.L); - order.Add(X509Name.ST); - order.Add(X509Name.EmailAddress); - - X509Name subject = new X509Name(order, attrs); - - Pkcs10CertificationRequest req1 = new Pkcs10CertificationRequest( - sigName, - subject, - kp.Public, - null, - kp.Private); - - byte[] bytes = req1.GetEncoded(); - - Pkcs10CertificationRequest req2 = new Pkcs10CertificationRequest(bytes); - - if (!req2.Verify()) - { - Fail(sigName + ": Failed Verify check."); - } - - if (!req2.GetPublicKey().Equals(req1.GetPublicKey())) - { - Fail(keyName + ": Failed public key check."); - } - } - - /* - * we generate a self signed certificate for the sake of testing - SHA224withECDSA - */ - private void createECRequest( - string algorithm, - DerObjectIdentifier algOid) - { - FpCurve curve = new FpCurve( - new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) - new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a - new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b - - ECDomainParameters spec = new ECDomainParameters( - curve, + kpg.Init(new KeyGenerationParameters(new SecureRandom(), keySize)); + + AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair(); + + IDictionary attrs = new Hashtable(); + attrs.Add(X509Name.C, "AU"); + attrs.Add(X509Name.O, "The Legion of the Bouncy Castle"); + attrs.Add(X509Name.L, "Melbourne"); + attrs.Add(X509Name.ST, "Victoria"); + attrs.Add(X509Name.EmailAddress, "feedback-crypto@bouncycastle.org"); + + IList order = new ArrayList(); + order.Add(X509Name.C); + order.Add(X509Name.O); + order.Add(X509Name.L); + order.Add(X509Name.ST); + order.Add(X509Name.EmailAddress); + + X509Name subject = new X509Name(order, attrs); + + Pkcs10CertificationRequest req1 = new Pkcs10CertificationRequest( + sigName, + subject, + kp.Public, + null, + kp.Private); + + byte[] bytes = req1.GetEncoded(); + + Pkcs10CertificationRequest req2 = new Pkcs10CertificationRequest(bytes); + + if (!req2.Verify()) + { + Fail(sigName + ": Failed Verify check."); + } + + if (!req2.GetPublicKey().Equals(req1.GetPublicKey())) + { + Fail(keyName + ": Failed public key check."); + } + } + + /* + * we generate a self signed certificate for the sake of testing - SHA224withECDSA + */ + private void createECRequest( + string algorithm, + DerObjectIdentifier algOid) + { + FpCurve curve = new FpCurve( + new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p) + new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), // a + new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)); // b + + ECDomainParameters spec = new ECDomainParameters( + curve, // curve.DecodePoint(Hex.Decode("02C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G - curve.DecodePoint(Hex.Decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G - new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n + curve.DecodePoint(Hex.Decode("0200C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G + new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16)); // n - ECPrivateKeyParameters privKey = new ECPrivateKeyParameters( - new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d - spec); + ECPrivateKeyParameters privKey = new ECPrivateKeyParameters( + new BigInteger("5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d + spec); - ECPublicKeyParameters pubKey = new ECPublicKeyParameters( + ECPublicKeyParameters pubKey = new ECPublicKeyParameters( // curve.DecodePoint(Hex.Decode("026BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q - curve.DecodePoint(Hex.Decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q - spec); + curve.DecodePoint(Hex.Decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q + spec); // // // // set up the keys @@ -157,314 +157,314 @@ namespace Org.BouncyCastle.Tests // privKey = fact.generatePrivate(privKeySpec); // pubKey = fact.generatePublic(pubKeySpec); - Pkcs10CertificationRequest req = new Pkcs10CertificationRequest( - algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); - if (!req.Verify()) - { - Fail("Failed Verify check EC."); - } - - req = new Pkcs10CertificationRequest(req.GetEncoded()); - if (!req.Verify()) - { - Fail("Failed Verify check EC encoded."); - } - - // - // try with point compression turned off - // + Pkcs10CertificationRequest req = new Pkcs10CertificationRequest( + algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); + if (!req.Verify()) + { + Fail("Failed Verify check EC."); + } + + req = new Pkcs10CertificationRequest(req.GetEncoded()); + if (!req.Verify()) + { + Fail("Failed Verify check EC encoded."); + } + + // + // try with point compression turned off + // // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); - FpPoint q = (FpPoint) pubKey.Q; - pubKey = new ECPublicKeyParameters( - pubKey.AlgorithmName, - new FpPoint(q.Curve, q.X, q.Y, false), - pubKey.Parameters); - - req = new Pkcs10CertificationRequest( - algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); - if (!req.Verify()) - { - Fail("Failed Verify check EC uncompressed."); - } - - req = new Pkcs10CertificationRequest(req.GetEncoded()); - if (!req.Verify()) - { - Fail("Failed Verify check EC uncompressed encoded."); - } - - if (!req.SignatureAlgorithm.ObjectID.Equals(algOid)) - { - Fail("ECDSA oid incorrect."); - } - - if (req.SignatureAlgorithm.Parameters != null) - { - Fail("ECDSA parameters incorrect."); - } - - ISigner sig = SignerUtilities.GetSigner(algorithm); - - sig.Init(false, pubKey); - - byte[] b = req.GetCertificationRequestInfo().GetEncoded(); - sig.BlockUpdate(b, 0, b.Length); - - if (!sig.VerifySignature(req.Signature.GetBytes())) - { - Fail("signature not mapped correctly."); - } - } - - private void createECGostRequest() - { - string algorithm = "GOST3411withECGOST3410"; - IAsymmetricCipherKeyPairGenerator ecGostKpg = GeneratorUtilities.GetKeyPairGenerator("ECGOST3410"); - - ecGostKpg.Init( - new ECKeyGenerationParameters( - CryptoProObjectIdentifiers.GostR3410x2001CryptoProA, - new SecureRandom())); - - // - // set up the keys - // - AsymmetricCipherKeyPair pair = ecGostKpg.GenerateKeyPair(); - AsymmetricKeyParameter privKey = pair.Private; - AsymmetricKeyParameter pubKey = pair.Public; - - Pkcs10CertificationRequest req = new Pkcs10CertificationRequest( - algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); - - if (!req.Verify()) - { - Fail("Failed Verify check EC."); - } - - req = new Pkcs10CertificationRequest(req.GetEncoded()); - if (!req.Verify()) - { - Fail("Failed Verify check EC encoded."); - } - - if (!req.SignatureAlgorithm.ObjectID.Equals(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001)) - { - Fail("ECGOST oid incorrect."); - } - - if (req.SignatureAlgorithm.Parameters != null) - { - Fail("ECGOST parameters incorrect."); - } - - ISigner sig = SignerUtilities.GetSigner(algorithm); - - sig.Init(false, pubKey); - - byte[] b = req.GetCertificationRequestInfo().GetEncoded(); - sig.BlockUpdate(b, 0, b.Length); - - if (!sig.VerifySignature(req.Signature.GetBytes())) - { - Fail("signature not mapped correctly."); - } - } - - private void createPssTest( - string algorithm) - { + ECPoint q = pubKey.Q.Normalize(); + pubKey = new ECPublicKeyParameters( + pubKey.AlgorithmName, + q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger(), false), + pubKey.Parameters); + + req = new Pkcs10CertificationRequest( + algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); + if (!req.Verify()) + { + Fail("Failed Verify check EC uncompressed."); + } + + req = new Pkcs10CertificationRequest(req.GetEncoded()); + if (!req.Verify()) + { + Fail("Failed Verify check EC uncompressed encoded."); + } + + if (!req.SignatureAlgorithm.ObjectID.Equals(algOid)) + { + Fail("ECDSA oid incorrect."); + } + + if (req.SignatureAlgorithm.Parameters != null) + { + Fail("ECDSA parameters incorrect."); + } + + ISigner sig = SignerUtilities.GetSigner(algorithm); + + sig.Init(false, pubKey); + + byte[] b = req.GetCertificationRequestInfo().GetEncoded(); + sig.BlockUpdate(b, 0, b.Length); + + if (!sig.VerifySignature(req.Signature.GetBytes())) + { + Fail("signature not mapped correctly."); + } + } + + private void createECGostRequest() + { + string algorithm = "GOST3411withECGOST3410"; + IAsymmetricCipherKeyPairGenerator ecGostKpg = GeneratorUtilities.GetKeyPairGenerator("ECGOST3410"); + + ecGostKpg.Init( + new ECKeyGenerationParameters( + CryptoProObjectIdentifiers.GostR3410x2001CryptoProA, + new SecureRandom())); + + // + // set up the keys + // + AsymmetricCipherKeyPair pair = ecGostKpg.GenerateKeyPair(); + AsymmetricKeyParameter privKey = pair.Private; + AsymmetricKeyParameter pubKey = pair.Public; + + Pkcs10CertificationRequest req = new Pkcs10CertificationRequest( + algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); + + if (!req.Verify()) + { + Fail("Failed Verify check EC."); + } + + req = new Pkcs10CertificationRequest(req.GetEncoded()); + if (!req.Verify()) + { + Fail("Failed Verify check EC encoded."); + } + + if (!req.SignatureAlgorithm.ObjectID.Equals(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001)) + { + Fail("ECGOST oid incorrect."); + } + + if (req.SignatureAlgorithm.Parameters != null) + { + Fail("ECGOST parameters incorrect."); + } + + ISigner sig = SignerUtilities.GetSigner(algorithm); + + sig.Init(false, pubKey); + + byte[] b = req.GetCertificationRequestInfo().GetEncoded(); + sig.BlockUpdate(b, 0, b.Length); + + if (!sig.VerifySignature(req.Signature.GetBytes())) + { + Fail("signature not mapped correctly."); + } + } + + private void createPssTest( + string algorithm) + { // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( - RsaKeyParameters pubKey = new RsaKeyParameters(false, - new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), - new BigInteger("010001",16)); + RsaKeyParameters pubKey = new RsaKeyParameters(false, + new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), + new BigInteger("010001",16)); // RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( - RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters( - new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), - new BigInteger("010001",16), - new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), - new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), - new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), - new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), - new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), - new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); + RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters( + new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), + new BigInteger("010001",16), + new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), + new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), + new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), + new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), + new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), + new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); // KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); // // PrivateKey privKey = fact.generatePrivate(privKeySpec); // PublicKey pubKey = fact.generatePublic(pubKeySpec); - Pkcs10CertificationRequest req = new Pkcs10CertificationRequest( - algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); - - if (!req.Verify()) - { - Fail("Failed verify check PSS."); - } - - req = new Pkcs10CertificationRequest(req.GetEncoded()); - if (!req.Verify()) - { - Fail("Failed verify check PSS encoded."); - } - - if (!req.SignatureAlgorithm.ObjectID.Equals(PkcsObjectIdentifiers.IdRsassaPss)) - { - Fail("PSS oid incorrect."); - } - - if (req.SignatureAlgorithm.Parameters == null) - { - Fail("PSS parameters incorrect."); - } - - ISigner sig = SignerUtilities.GetSigner(algorithm); - - sig.Init(false, pubKey); - - byte[] encoded = req.GetCertificationRequestInfo().GetEncoded(); - sig.BlockUpdate(encoded, 0, encoded.Length); - - if (!sig.VerifySignature(req.Signature.GetBytes())) - { - Fail("signature not mapped correctly."); - } - } - - // previous code found to cause a NullPointerException - private void nullPointerTest() - { - IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("RSA"); - keyGen.Init(new KeyGenerationParameters(new SecureRandom(), 1024)); - - AsymmetricCipherKeyPair pair = keyGen.GenerateKeyPair(); - - IList oids = new ArrayList(); - IList values = new ArrayList(); - oids.Add(X509Extensions.BasicConstraints); - values.Add(new X509Extension(true, new DerOctetString(new BasicConstraints(true)))); - oids.Add(X509Extensions.KeyUsage); - values.Add(new X509Extension(true, new DerOctetString( - new KeyUsage(KeyUsage.KeyCertSign | KeyUsage.CrlSign)))); - SubjectKeyIdentifier subjectKeyIdentifier = new SubjectKeyIdentifierStructure(pair.Public); - X509Extension ski = new X509Extension(false, new DerOctetString(subjectKeyIdentifier)); - oids.Add(X509Extensions.SubjectKeyIdentifier); - values.Add(ski); - - AttributePkcs attribute = new AttributePkcs(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, - new DerSet(new X509Extensions(oids, values))); - - Pkcs10CertificationRequest p1 = new Pkcs10CertificationRequest( - "SHA1WithRSA", new X509Name("cn=csr"), pair.Public, new DerSet(attribute), pair.Private); - Pkcs10CertificationRequest p2 = new Pkcs10CertificationRequest( - "SHA1WithRSA", new X509Name("cn=csr"), pair.Public, new DerSet(attribute), pair.Private); - - if (!p1.Equals(p2)) - { - Fail("cert request comparison failed"); - } - } - - public override void PerformTest() - { - generationTest(512, "RSA", "SHA1withRSA"); - generationTest(512, "GOST3410", "GOST3411withGOST3410"); - - // if (Security.getProvider("SunRsaSign") != null) - // { - // generationTest(512, "RSA", "SHA1withRSA", "SunRsaSign"); - // } - - // elliptic curve GOST A parameter set - Pkcs10CertificationRequest req = new Pkcs10CertificationRequest(gost3410EC_A); - if (!req.Verify()) - { - Fail("Failed Verify check gost3410EC_A."); - } - - // elliptic curve GOST B parameter set - req = new Pkcs10CertificationRequest(gost3410EC_B); - if (!req.Verify()) - { - Fail("Failed Verify check gost3410EC_B."); - } - - // elliptic curve GOST C parameter set - req = new Pkcs10CertificationRequest(gost3410EC_C); - if (!req.Verify()) - { - Fail("Failed Verify check gost3410EC_C."); - } - - // elliptic curve GOST ExA parameter set - req = new Pkcs10CertificationRequest(gost3410EC_ExA); - if (!req.Verify()) - { - Fail("Failed Verify check gost3410EC_ExA."); - } - - // elliptic curve GOST ExB parameter set - req = new Pkcs10CertificationRequest(gost3410EC_ExB); - if (!req.Verify()) - { - Fail("Failed Verify check gost3410EC_ExA."); - } - - // elliptic curve openSSL - IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("ECDSA"); - - ECCurve curve = new FpCurve( - new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q - new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a - new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b - - ECDomainParameters ecSpec = new ECDomainParameters( - curve, - curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G - new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n + Pkcs10CertificationRequest req = new Pkcs10CertificationRequest( + algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); + + if (!req.Verify()) + { + Fail("Failed verify check PSS."); + } + + req = new Pkcs10CertificationRequest(req.GetEncoded()); + if (!req.Verify()) + { + Fail("Failed verify check PSS encoded."); + } + + if (!req.SignatureAlgorithm.ObjectID.Equals(PkcsObjectIdentifiers.IdRsassaPss)) + { + Fail("PSS oid incorrect."); + } + + if (req.SignatureAlgorithm.Parameters == null) + { + Fail("PSS parameters incorrect."); + } + + ISigner sig = SignerUtilities.GetSigner(algorithm); + + sig.Init(false, pubKey); + + byte[] encoded = req.GetCertificationRequestInfo().GetEncoded(); + sig.BlockUpdate(encoded, 0, encoded.Length); + + if (!sig.VerifySignature(req.Signature.GetBytes())) + { + Fail("signature not mapped correctly."); + } + } + + // previous code found to cause a NullPointerException + private void nullPointerTest() + { + IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("RSA"); + keyGen.Init(new KeyGenerationParameters(new SecureRandom(), 1024)); + + AsymmetricCipherKeyPair pair = keyGen.GenerateKeyPair(); + + IList oids = new ArrayList(); + IList values = new ArrayList(); + oids.Add(X509Extensions.BasicConstraints); + values.Add(new X509Extension(true, new DerOctetString(new BasicConstraints(true)))); + oids.Add(X509Extensions.KeyUsage); + values.Add(new X509Extension(true, new DerOctetString( + new KeyUsage(KeyUsage.KeyCertSign | KeyUsage.CrlSign)))); + SubjectKeyIdentifier subjectKeyIdentifier = new SubjectKeyIdentifierStructure(pair.Public); + X509Extension ski = new X509Extension(false, new DerOctetString(subjectKeyIdentifier)); + oids.Add(X509Extensions.SubjectKeyIdentifier); + values.Add(ski); + + AttributePkcs attribute = new AttributePkcs(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, + new DerSet(new X509Extensions(oids, values))); + + Pkcs10CertificationRequest p1 = new Pkcs10CertificationRequest( + "SHA1WithRSA", new X509Name("cn=csr"), pair.Public, new DerSet(attribute), pair.Private); + Pkcs10CertificationRequest p2 = new Pkcs10CertificationRequest( + "SHA1WithRSA", new X509Name("cn=csr"), pair.Public, new DerSet(attribute), pair.Private); + + if (!p1.Equals(p2)) + { + Fail("cert request comparison failed"); + } + } + + public override void PerformTest() + { + generationTest(512, "RSA", "SHA1withRSA"); + generationTest(512, "GOST3410", "GOST3411withGOST3410"); + + // if (Security.getProvider("SunRsaSign") != null) + // { + // generationTest(512, "RSA", "SHA1withRSA", "SunRsaSign"); + // } + + // elliptic curve GOST A parameter set + Pkcs10CertificationRequest req = new Pkcs10CertificationRequest(gost3410EC_A); + if (!req.Verify()) + { + Fail("Failed Verify check gost3410EC_A."); + } + + // elliptic curve GOST B parameter set + req = new Pkcs10CertificationRequest(gost3410EC_B); + if (!req.Verify()) + { + Fail("Failed Verify check gost3410EC_B."); + } + + // elliptic curve GOST C parameter set + req = new Pkcs10CertificationRequest(gost3410EC_C); + if (!req.Verify()) + { + Fail("Failed Verify check gost3410EC_C."); + } + + // elliptic curve GOST ExA parameter set + req = new Pkcs10CertificationRequest(gost3410EC_ExA); + if (!req.Verify()) + { + Fail("Failed Verify check gost3410EC_ExA."); + } + + // elliptic curve GOST ExB parameter set + req = new Pkcs10CertificationRequest(gost3410EC_ExB); + if (!req.Verify()) + { + Fail("Failed Verify check gost3410EC_ExA."); + } + + // elliptic curve openSSL + IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("ECDSA"); + + ECCurve curve = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b + + ECDomainParameters ecSpec = new ECDomainParameters( + curve, + curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G + new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n // g.initialize(ecSpec, new SecureRandom()); - g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom())); + g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom())); - AsymmetricCipherKeyPair kp = g.GenerateKeyPair(); + AsymmetricCipherKeyPair kp = g.GenerateKeyPair(); - req = new Pkcs10CertificationRequest( - "ECDSAWITHSHA1", new X509Name("CN=XXX"), kp.Public, null, kp.Private); + req = new Pkcs10CertificationRequest( + "ECDSAWITHSHA1", new X509Name("CN=XXX"), kp.Public, null, kp.Private); - if (!req.Verify()) - { - Fail("Failed Verify check EC."); - } + if (!req.Verify()) + { + Fail("Failed Verify check EC."); + } - createECRequest("SHA1withECDSA", X9ObjectIdentifiers.ECDsaWithSha1); - createECRequest("SHA224withECDSA", X9ObjectIdentifiers.ECDsaWithSha224); - createECRequest("SHA256withECDSA", X9ObjectIdentifiers.ECDsaWithSha256); - createECRequest("SHA384withECDSA", X9ObjectIdentifiers.ECDsaWithSha384); - createECRequest("SHA512withECDSA", X9ObjectIdentifiers.ECDsaWithSha512); + createECRequest("SHA1withECDSA", X9ObjectIdentifiers.ECDsaWithSha1); + createECRequest("SHA224withECDSA", X9ObjectIdentifiers.ECDsaWithSha224); + createECRequest("SHA256withECDSA", X9ObjectIdentifiers.ECDsaWithSha256); + createECRequest("SHA384withECDSA", X9ObjectIdentifiers.ECDsaWithSha384); + createECRequest("SHA512withECDSA", X9ObjectIdentifiers.ECDsaWithSha512); - createECGostRequest(); + createECGostRequest(); - // TODO The setting of parameters for MGF algorithms is not implemented + // TODO The setting of parameters for MGF algorithms is not implemented // createPssTest("SHA1withRSAandMGF1"); // createPssTest("SHA224withRSAandMGF1"); // createPssTest("SHA256withRSAandMGF1"); // createPssTest("SHA384withRSAandMGF1"); - nullPointerTest(); - } + nullPointerTest(); + } - public static void Main( - string[] args) - { - RunTest(new Pkcs10CertRequestTest()); - } + public static void Main( + string[] args) + { + RunTest(new Pkcs10CertRequestTest()); + } - [Test] - public void TestFunction() - { - string resultText = Perform().ToString(); + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); - Assert.AreEqual(Name + ": Okay", resultText); - } - } + Assert.AreEqual(Name + ": Okay", resultText); + } + } } -- cgit 1.4.1