From 785d36daf1d125b3fba16e1d92719e2a0f67698e Mon Sep 17 00:00:00 2001 From: Megan Woods Date: Mon, 14 Jan 2019 00:17:24 +1100 Subject: Added ECGOST3410_2012Signer Updated encoding of SubjectPublicKeyInfo and PrivateKeyInfo --- crypto/test/src/crypto/test/ECGOST3410_2012Test.cs | 597 +++++++++++++++++++++ .../src/crypto/test/EGOST3410_2012SignatureTest.cs | 187 +++++++ 2 files changed, 784 insertions(+) create mode 100644 crypto/test/src/crypto/test/ECGOST3410_2012Test.cs create mode 100644 crypto/test/src/crypto/test/EGOST3410_2012SignatureTest.cs (limited to 'crypto/test/src') diff --git a/crypto/test/src/crypto/test/ECGOST3410_2012Test.cs b/crypto/test/src/crypto/test/ECGOST3410_2012Test.cs new file mode 100644 index 000000000..94726bc92 --- /dev/null +++ b/crypto/test/src/crypto/test/ECGOST3410_2012Test.cs @@ -0,0 +1,597 @@ +using System; +using NUnit.Framework; +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Crypto.Tests +{ + [TestFixture] + public class ECGOST3410_2012Test:SimpleTest + { + public override string Name + { + get { return "ECGOST3410-2012-Test"; } + } + + public SimpleTestResult EncodeRecodePublicKey() + { + + DerObjectIdentifier oid = ECGost3410NamedCurves.GetOid("Tc26-Gost-3410-12-512-paramSetA"); + ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOid(oid)); + ECGOST3410Parameters gostParams = new ECGOST3410Parameters(ecp, oid, RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512,null); + ECKeyGenerationParameters paramameters = new ECKeyGenerationParameters(gostParams, new SecureRandom()); + ECKeyPairGenerator engine = new ECKeyPairGenerator(); + engine.Init(paramameters); + AsymmetricCipherKeyPair pair = engine.GenerateKeyPair(); + + ECPublicKeyParameters generatedKeyParameters = (ECPublicKeyParameters)pair.Public; + ECPublicKeyParameters keyParameters = generatedKeyParameters; + + + // + // Continuously encode/decode the key and check for loss of information. + // + for (int t = 0; t < 3; t++) + { + + SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyParameters); + keyParameters = (ECPublicKeyParameters)PublicKeyFactory.CreateKey(info); + + { // Specifically cast and test gost parameters. + ECGOST3410Parameters gParam = (ECGOST3410Parameters)generatedKeyParameters.Parameters; + ECGOST3410Parameters rParam = (ECGOST3410Parameters)keyParameters.Parameters; + + + bool ok = SafeEquals(gParam.DigestParamSet, rParam.DigestParamSet) && + SafeEquals(gParam.EncryptionParamSet, rParam.EncryptionParamSet) && + SafeEquals(gParam.PublicKeyParamSet, rParam.PublicKeyParamSet); + + if (!ok) + { + return new SimpleTestResult(false, "GOST parameters does not match"); + } + + } + + if (!((ECGOST3410Parameters)keyParameters.Parameters).Name.Equals( + ((ECGOST3410Parameters)generatedKeyParameters.Parameters).Name)) + { + return new SimpleTestResult(false, "Name does not match"); + } + + + if (keyParameters.IsPrivate != generatedKeyParameters.IsPrivate) + { + return new SimpleTestResult(false, "isPrivate does not match"); + } + + if (!Arrays.AreEqual(keyParameters.Q.GetEncoded(true), generatedKeyParameters.Q.GetEncoded(true))) + { + return new SimpleTestResult(false, "Q does not match"); + } + + if (!keyParameters.Parameters.Curve.Equals(generatedKeyParameters.Parameters.Curve)) + { + return new SimpleTestResult(false, "Curve does not match"); + } + + if (!Arrays.AreEqual( + keyParameters.Parameters.G.GetEncoded(true), + generatedKeyParameters.Parameters.G.GetEncoded(true))) + { + return new SimpleTestResult(false, "G does not match"); + } + + if (!keyParameters.Parameters.H.Equals(generatedKeyParameters.Parameters.H)) + { + return new SimpleTestResult(false, "H does not match"); + } + + if (!keyParameters.Parameters.HInv.Equals(generatedKeyParameters.Parameters.HInv)) + { + return new SimpleTestResult(false, "Hinv does not match"); + } + + if (!keyParameters.Parameters.N.Equals(generatedKeyParameters.Parameters.N)) + { + return new SimpleTestResult(false, "N does not match"); + } + + if (!Arrays.AreEqual(keyParameters.Parameters.GetSeed(), generatedKeyParameters.Parameters.GetSeed())) + { + return new SimpleTestResult(false, "Seed does not match"); + } + } + return new SimpleTestResult(true, null); + + + } + + + private SimpleTestResult EncodeRecodePrivateKey() + { + + DerObjectIdentifier oid = ECGost3410NamedCurves.GetOid("Tc26-Gost-3410-12-512-paramSetA"); + ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOid(oid)); + ECGOST3410Parameters gostParams = new ECGOST3410Parameters(ecp, oid, RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512,null); + ECKeyGenerationParameters parameters = new ECKeyGenerationParameters(gostParams, new SecureRandom()); + ECKeyPairGenerator engine = new ECKeyPairGenerator(); + engine.Init(parameters); + AsymmetricCipherKeyPair pair = engine.GenerateKeyPair(); + + ECPrivateKeyParameters generatedKeyParameters = (ECPrivateKeyParameters)pair.Private; + ECPrivateKeyParameters keyParameters = generatedKeyParameters; + + + // + // Continuously encode/decode the key and check for loss of information. + // + + + for (int t = 0; t < 3; t++) + { + PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyParameters); + keyParameters = (ECPrivateKeyParameters)PrivateKeyFactory.CreateKey(info); + + { // Specifically cast and test gost parameters. + ECGOST3410Parameters gParam = (ECGOST3410Parameters)generatedKeyParameters.Parameters; + ECGOST3410Parameters rParam = (ECGOST3410Parameters)keyParameters.Parameters; + + bool ok = SafeEquals(gParam.DigestParamSet, rParam.DigestParamSet) && + SafeEquals(gParam.EncryptionParamSet, rParam.EncryptionParamSet) && + SafeEquals(gParam.PublicKeyParamSet, rParam.PublicKeyParamSet); + + if (!ok) + { + return new SimpleTestResult(false, "GOST parameters does not match"); + } + + } + + if (keyParameters.IsPrivate != generatedKeyParameters.IsPrivate) + { + return new SimpleTestResult(false, "isPrivate does not match"); + } + + if (!keyParameters.D.Equals(generatedKeyParameters.D)) + { + return new SimpleTestResult(false, "D does not match"); + } + + if (!((ECGOST3410Parameters)keyParameters.Parameters).Name.Equals( + ((ECGOST3410Parameters)generatedKeyParameters.Parameters).Name)) + { + return new SimpleTestResult(false, "Name does not match"); + } + + if (!keyParameters.Parameters.Curve.Equals(generatedKeyParameters.Parameters.Curve)) + { + return new SimpleTestResult(false, "Curve does not match"); + } + + if (!Arrays.AreEqual( + keyParameters.Parameters.G.GetEncoded(true), + generatedKeyParameters.Parameters.G.GetEncoded(true))) + { + return new SimpleTestResult(false, "G does not match"); + } + + if (!keyParameters.Parameters.H.Equals(generatedKeyParameters.Parameters.H)) + { + return new SimpleTestResult(false, "H does not match"); + } + + if (!keyParameters.Parameters.HInv.Equals(generatedKeyParameters.Parameters.HInv)) + { + return new SimpleTestResult(false, "Hinv does not match"); + } + + if (!keyParameters.Parameters.N.Equals(generatedKeyParameters.Parameters.N)) + { + return new SimpleTestResult(false, "N does not match"); + } + + if (!Arrays.AreEqual(keyParameters.Parameters.GetSeed(), generatedKeyParameters.Parameters.GetSeed())) + { + return new SimpleTestResult(false, "Seed does not match"); + } + } + + + + return new SimpleTestResult(true, null); + } + + private SimpleTestResult DecodeJCEPublic() + { + byte[] pub256 = Hex.Decode("3068302106082a85030701010101301506092a850307010201010106082a850307010102020343000440292335c87d892510c35a033819a13e2b0dc606d911676af2bad8872d74a4b7bae6c729e98ace04c3dee626343f794731e1489edb7bc26f1c8c56e1448c96501a"); + + ECPublicKeyParameters pkInfo = (ECPublicKeyParameters)PublicKeyFactory.CreateKey(pub256); + + if (pkInfo.IsPrivate) + { + return new SimpleTestResult(false, "isPrivate should be false"); + } + + if ( + !Arrays.AreEqual( + pkInfo.Q.GetEncoded(true), + Hex.Decode("02bab7a4742d87d8baf26a6711d906c60d2b3ea11938035ac31025897dc8352329"))) + { + return new SimpleTestResult(false, "Q does not match"); + } + + if (!((ECGOST3410Parameters)pkInfo.Parameters).PublicKeyParamSet.ToString().Equals("1.2.643.7.1.2.1.1.1")) + { + return new SimpleTestResult(false, "PublicKeyParamSet does not match"); + } + + if (!((ECGOST3410Parameters)pkInfo.Parameters).DigestParamSet.ToString().Equals("1.2.643.7.1.1.2.2")) + { + return new SimpleTestResult(false, "DigestParamSet does not match"); + } + + if (((ECGOST3410Parameters)pkInfo.Parameters).EncryptionParamSet != null) + { + return new SimpleTestResult(false, "EncryptionParamSet is not null"); + } + + + byte[] pub512 = Hex.Decode("3081aa302106082a85030701010102301506092a850307010201020106082a850307010102030381840004818043ccc22692ee8a1870c7c9de0566d7e3a494cf0e3c80f9e8852a3d1ec10d2a829d357253e0864aee2eaacd5e2d327578dee771f62f24decfd6358e06199efe540e7912db43c4c80fe0fd31f7f67a862f9d44fd0075cfee6e3d638c7520063d26311ef962547e8129fb8c5b194e129370cd30313884b4a60872254a10772fe595"); + + pkInfo = (ECPublicKeyParameters)PublicKeyFactory.CreateKey(pub512); + + if (pkInfo.IsPrivate) + { + return new SimpleTestResult(false, "isPrivate should be true"); + } + + if ( + !Arrays.AreEqual( + pkInfo.Q.GetEncoded(true), + Hex.Decode("0254fe9e19068e35d6cfde242ff671e7de7875322d5ecdaa2eee4a86e05372359d822a0dc11e3d2a85e8f9803c0ecf94a4e3d76605dec9c770188aee9226c2cc43"))) + { + return new SimpleTestResult(false, "Q does not match"); + } + + + if (!((ECGOST3410Parameters)pkInfo.Parameters).PublicKeyParamSet.ToString().Equals("1.2.643.7.1.2.1.2.1")) + { + return new SimpleTestResult(false, "PublicKeyParamSet does not match"); + } + + if (!((ECGOST3410Parameters)pkInfo.Parameters).DigestParamSet.ToString().Equals("1.2.643.7.1.1.2.3")) + { + return new SimpleTestResult(false, "DigestParamSet does not match"); + } + + if (((ECGOST3410Parameters)pkInfo.Parameters).EncryptionParamSet != null) + { + return new SimpleTestResult(false, "EncryptionParamSet is not null"); + } + + + + return new SimpleTestResult(true, null); + } + + private SimpleTestResult DecodeJCEPrivate() + { + byte[] priv256 = Hex.Decode("304a020100302106082a85030701010101301506092a850307010201010106082a8503070101020204220420fe75ba328d5439ed4859e6dc7e6ca2e9aab0818f094eddeb0d57d1c16a90762b"); + ECPrivateKeyParameters pkInfo = (ECPrivateKeyParameters)PrivateKeyFactory.CreateKey(priv256); + + if (!pkInfo.IsPrivate) + { + return new SimpleTestResult(false, "isPrivate should be true"); + } + + if ( + !Arrays.AreEqual( + Hex.Decode("2b76906ac1d1570debdd4e098f81b0aae9a26c7edce65948ed39548d32ba75fe"), + pkInfo.D.ToByteArray())) + { + return new SimpleTestResult(false, "D does not match"); + } + + if (!((ECGOST3410Parameters)pkInfo.Parameters).PublicKeyParamSet.ToString().Equals("1.2.643.7.1.2.1.1.1")) + { + return new SimpleTestResult(false, "PublicKeyParamSet does not match"); + } + + if (!((ECGOST3410Parameters)pkInfo.Parameters).DigestParamSet.ToString().Equals("1.2.643.7.1.1.2.2")) + { + return new SimpleTestResult(false, "DigestParamSet does not match"); + } + + if (((ECGOST3410Parameters)pkInfo.Parameters).EncryptionParamSet != null) + { + return new SimpleTestResult(false, "EncryptionParamSet is not null"); + } + + + byte[] priv512 = Hex.Decode("306a020100302106082a85030701010102301506092a850307010201020106082a85030701010203044204402fc35576152f6e873236608b592b4b98d0793bf5184f8dc4a99512be703716991a96061ef46aceeae5319b5c69e6fcbfa7e339207878597ce50f9b7cbf857ff1"); + + pkInfo = (ECPrivateKeyParameters)PrivateKeyFactory.CreateKey(priv512); + + if (!pkInfo.IsPrivate) + { + return new SimpleTestResult(false, "isPrivate should be true"); + } + + if ( + !Arrays.AreEqual( + Hex.Decode("00f17f85bf7c9b0fe57c5978782039e3a7bffce6695c9b31e5eace6af41e06961a99163770be1295a9c48d4f18f53b79d0984b2b598b603632876e2f157655c32f"), + pkInfo.D.ToByteArray())) + { + return new SimpleTestResult(false, "D does not match"); + } + + if (!((ECGOST3410Parameters)pkInfo.Parameters).PublicKeyParamSet.ToString().Equals("1.2.643.7.1.2.1.2.1")) + { + return new SimpleTestResult(false, "PublicKeyParamSet does not match"); + } + + if (!((ECGOST3410Parameters)pkInfo.Parameters).DigestParamSet.ToString().Equals("1.2.643.7.1.1.2.3")) + { + return new SimpleTestResult(false, "DigestParamSet does not match"); + } + + if (((ECGOST3410Parameters)pkInfo.Parameters).EncryptionParamSet != null) + { + return new SimpleTestResult(false, "EncryptionParamSet is not null"); + } + + + + return new SimpleTestResult(true, null); + } + + + + public SimpleTestResult EncodeDecodePrivateLW(String oidStr, DerObjectIdentifier digest) + { + DerObjectIdentifier oid = ECGost3410NamedCurves.GetOid(oidStr); + ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOid(oid)); + ECGOST3410Parameters gostParams = new ECGOST3410Parameters(ecp, oid, digest, null); + ECKeyGenerationParameters parameters = new ECKeyGenerationParameters(gostParams, new SecureRandom()); + ECKeyPairGenerator engine = new ECKeyPairGenerator(); + engine.Init(parameters); + AsymmetricCipherKeyPair pair = engine.GenerateKeyPair(); + + + ECPrivateKeyParameters generatedKeyParameters = (ECPrivateKeyParameters) pair.Private; + + PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(generatedKeyParameters); + + ECPrivateKeyParameters recoveredKeyParameters = (ECPrivateKeyParameters)PrivateKeyFactory.CreateKey(info); + + + { // Specifically cast and test gost parameters. + ECGOST3410Parameters gParam = (ECGOST3410Parameters)generatedKeyParameters.Parameters; + ECGOST3410Parameters rParam = (ECGOST3410Parameters)recoveredKeyParameters.Parameters; + + bool ok = SafeEquals(gParam.DigestParamSet, rParam.DigestParamSet) && + SafeEquals(gParam.EncryptionParamSet, rParam.EncryptionParamSet) && + SafeEquals(gParam.PublicKeyParamSet, rParam.PublicKeyParamSet); + + if (!ok) + { + return new SimpleTestResult(false, "GOST parameters does not match"); + } + + } + + + if (recoveredKeyParameters.IsPrivate != generatedKeyParameters.IsPrivate) + { + return new SimpleTestResult(false, "isPrivate does not match"); + } + + if (!((ECGOST3410Parameters)recoveredKeyParameters.Parameters).Name.Equals( + ((ECGOST3410Parameters)generatedKeyParameters.Parameters).Name)) + { + return new SimpleTestResult(false, "Name does not match"); + } + + + if (!recoveredKeyParameters.D.Equals(generatedKeyParameters.D)) + { + return new SimpleTestResult(false, "D does not match"); + } + + if (!recoveredKeyParameters.Parameters.Curve.Equals(generatedKeyParameters.Parameters.Curve)) + { + return new SimpleTestResult(false, "Curve does not match"); + } + + if (!Arrays.AreEqual( + recoveredKeyParameters.Parameters.G.GetEncoded(true), + generatedKeyParameters.Parameters.G.GetEncoded(true))) + { + return new SimpleTestResult(false, "G does not match"); + } + + if (!recoveredKeyParameters.Parameters.H.Equals(generatedKeyParameters.Parameters.H)) + { + return new SimpleTestResult(false, "H does not match"); + } + + if (!recoveredKeyParameters.Parameters.HInv.Equals(generatedKeyParameters.Parameters.HInv)) + { + return new SimpleTestResult(false, "Hinv does not match"); + } + + if (!recoveredKeyParameters.Parameters.N.Equals(generatedKeyParameters.Parameters.N)) + { + return new SimpleTestResult(false, "N does not match"); + } + + if (!Arrays.AreEqual(recoveredKeyParameters.Parameters.GetSeed(), generatedKeyParameters.Parameters.GetSeed())) + { + return new SimpleTestResult(false, "Seed does not match"); + } + + return new SimpleTestResult(true, null); + } + + public SimpleTestResult EncodeDecodePublicLW(string oidStr, DerObjectIdentifier digest) + { + DerObjectIdentifier oid = ECGost3410NamedCurves.GetOid(oidStr); + ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOid(oid)); + ECGOST3410Parameters gostParams = new ECGOST3410Parameters(ecp,oid,digest,null); + ECKeyGenerationParameters parameters = new ECKeyGenerationParameters(gostParams, new SecureRandom()); + ECKeyPairGenerator engine = new ECKeyPairGenerator(); + engine.Init(parameters); + AsymmetricCipherKeyPair pair = engine.GenerateKeyPair(); + ECPublicKeyParameters generatedKeyParameters = (ECPublicKeyParameters)pair.Public; + + SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(generatedKeyParameters); + + ECPublicKeyParameters recoveredKeyParameters = (ECPublicKeyParameters)PublicKeyFactory.CreateKey(info); + + { // Specifically cast and test gost parameters. + ECGOST3410Parameters gParam = (ECGOST3410Parameters)generatedKeyParameters.Parameters; + ECGOST3410Parameters rParam = (ECGOST3410Parameters)recoveredKeyParameters.Parameters; + + + bool ok = SafeEquals(gParam.DigestParamSet, rParam.DigestParamSet) && + SafeEquals(gParam.EncryptionParamSet, rParam.EncryptionParamSet) && + SafeEquals(gParam.PublicKeyParamSet, rParam.PublicKeyParamSet); + + if (!ok) + { + return new SimpleTestResult(false, "GOST parameters does not match"); + } + + } + + if (!((ECGOST3410Parameters)recoveredKeyParameters.Parameters).Name.Equals( + ((ECGOST3410Parameters)generatedKeyParameters.Parameters).Name)) + { + return new SimpleTestResult(false, "Name does not match"); + } + + + if (recoveredKeyParameters.IsPrivate != generatedKeyParameters.IsPrivate) + { + return new SimpleTestResult(false, "isPrivate does not match"); + } + + if (!Arrays.AreEqual(recoveredKeyParameters.Q.GetEncoded(true), generatedKeyParameters.Q.GetEncoded(true))) + { + return new SimpleTestResult(false, "Q does not match"); + } + + if (!recoveredKeyParameters.Parameters.Curve.Equals(generatedKeyParameters.Parameters.Curve)) + { + return new SimpleTestResult(false, "Curve does not match"); + } + + if (!Arrays.AreEqual( + recoveredKeyParameters.Parameters.G.GetEncoded(true), + generatedKeyParameters.Parameters.G.GetEncoded(true))) + { + return new SimpleTestResult(false, "G does not match"); + } + + if (!recoveredKeyParameters.Parameters.H.Equals(generatedKeyParameters.Parameters.H)) + { + return new SimpleTestResult(false, "H does not match"); + } + + if (!recoveredKeyParameters.Parameters.HInv.Equals(generatedKeyParameters.Parameters.HInv)) + { + return new SimpleTestResult(false, "Hinv does not match"); + } + + if (!recoveredKeyParameters.Parameters.N.Equals(generatedKeyParameters.Parameters.N)) + { + return new SimpleTestResult(false, "N does not match"); + } + + if (!Arrays.AreEqual(recoveredKeyParameters.Parameters.GetSeed(), generatedKeyParameters.Parameters.GetSeed())) + { + return new SimpleTestResult(false, "Seed does not match"); + } + + return new SimpleTestResult(true, null); + } + + [Test] + public override void PerformTest() + { + + SimpleTestResult str = EncodeDecodePublicLW("Tc26-Gost-3410-12-512-paramSetA", RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512); + if (!str.IsSuccessful()) + { + Fail(str.ToString(), str.GetException()); + } + + str = EncodeDecodePrivateLW("Tc26-Gost-3410-12-512-paramSetA", RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512); + if (!str.IsSuccessful()) + { + Fail(str.ToString(), str.GetException()); + } + + + str = EncodeDecodePublicLW("Tc26-Gost-3410-12-256-paramSetA", RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256); + if (!str.IsSuccessful()) + { + Fail(str.ToString(), str.GetException()); + } + + str = EncodeDecodePrivateLW("Tc26-Gost-3410-12-256-paramSetA", RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256); + if (!str.IsSuccessful()) + { + Fail(str.ToString(), str.GetException()); + } + + + str = DecodeJCEPrivate(); + if (!str.IsSuccessful()) + { + Fail(str.ToString(), str.GetException()); + } + + str = DecodeJCEPublic(); + if (!str.IsSuccessful()) + { + Fail(str.ToString(), str.GetException()); + } + + str = EncodeRecodePrivateKey(); + if (!str.IsSuccessful()) + { + Fail(str.ToString(), str.GetException()); + } + + str = EncodeRecodePublicKey(); + if (!str.IsSuccessful()) + { + Fail(str.ToString(), str.GetException()); + } + + } + + private bool SafeEquals(object left, object right) + { + if (left == null || right == null) + { + return left == null && right == null; + } + + return left.Equals(right); + } + } +} \ No newline at end of file diff --git a/crypto/test/src/crypto/test/EGOST3410_2012SignatureTest.cs b/crypto/test/src/crypto/test/EGOST3410_2012SignatureTest.cs new file mode 100644 index 000000000..0065174ed --- /dev/null +++ b/crypto/test/src/crypto/test/EGOST3410_2012SignatureTest.cs @@ -0,0 +1,187 @@ +using System; +using System.Security.Cryptography.X509Certificates; +using NUnit.Framework; +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Crypto.Tests +{ + [TestFixture] + public class EGOST3410_2012SignatureTest : SimpleTest + { + public override string Name { get; } + + [Test] + public override void PerformTest() + { + EcGOST34102012256Test(); + } + + + public void EcGOST34102012256Test() + { + BigInteger r = new BigInteger("29700980915817952874371204983938256990422752107994319651632687982059210933395"); + BigInteger s = new BigInteger("574973400270084654178925310019147038455227042649098563933718999175515839552"); + + BigInteger e = new BigInteger("20798893674476452017134061561508270130637142515379653289952617252661468872421"); + + byte[] kData = BigIntegers.AsUnsignedByteArray(new BigInteger("53854137677348463731403841147996619241504003434302020712960838528893196233395")); + SecureRandom k = new TestRandomBigInteger(kData); + + BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); + BigInteger mod_q = new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619"); + + + ECCurve curve = new FpCurve( + mod_p, + new BigInteger("7"), // a + new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414"), // b + mod_q, BigInteger.One); + + ECDomainParameters spec = new ECDomainParameters(curve, + curve.CreatePoint( + new BigInteger("2"), // x + new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280")), // y + mod_q, BigInteger.One); + + ECPrivateKeyParameters privateKey = new ECPrivateKeyParameters( + new BigInteger("55441196065363246126355624130324183196576709222340016572108097750006097525544"), // d + spec); + + ECPublicKeyParameters publicKey = new ECPublicKeyParameters(curve.CreatePoint( + new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403"), // x + new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994")), // y + spec); + + ECGOST3410_2012Signer signer = new ECGOST3410_2012Signer(); + signer.Init(true, new ParametersWithRandom(privateKey, k)); + + byte[] rev = e.ToByteArray(); + byte[] message = new byte[rev.Length]; + for (int i = 0; i != rev.Length; i++) + { + message[i] = rev[rev.Length - 1 - i]; + } + BigInteger[] sig = signer.GenerateSignature(message); + + signer.Init(false, publicKey); + + if (!signer.VerifySignature(message, sig[0], sig[1])) + { + Fail("ECGOST3410 2012 verification failed"); + } + + if (!r.Equals(sig[0])) + { + Fail( + ": r component wrong." + Environment.NewLine + + " expecting: " + r + Environment.NewLine + + " got : " + sig[0]); + } + + if (!s.Equals(sig[1])) + { + Fail( + ": s component wrong." + Environment.NewLine + + " expecting: " + s + Environment.NewLine + + " got : " + sig[1]); + } + + + // 256Bit + { + DerObjectIdentifier oid = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetA; + ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOid(oid)); + ECGOST3410Parameters gostParams = new ECGOST3410Parameters(ecp, oid, + RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256, null); + ECKeyGenerationParameters parameters = new ECKeyGenerationParameters(gostParams, new SecureRandom()); + ECKeyPairGenerator engine = new ECKeyPairGenerator(); + engine.Init(parameters); + AsymmetricCipherKeyPair pair = engine.GenerateKeyPair(); + SignatureGost12Test("ECGOST3410-2012-256", 64, pair); + } + + // 512Bit + + + { + DerObjectIdentifier oid = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetA; + ECNamedDomainParameters ecp = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOid(oid)); + ECGOST3410Parameters gostParams = new ECGOST3410Parameters(ecp, oid, + RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512, null); + ECKeyGenerationParameters parameters = new ECKeyGenerationParameters(gostParams, new SecureRandom()); + ECKeyPairGenerator engine = new ECKeyPairGenerator(); + engine.Init(parameters); + AsymmetricCipherKeyPair pair = engine.GenerateKeyPair(); + + SignatureGost12Test("ECGOST3410-2012-512", 128, pair); + + } + } + + + + private void SignatureGost12Test(String signatureAlg, int expectedSignLen, AsymmetricCipherKeyPair p) + + { + byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; + + ECPrivateKeyParameters sKey = (ECPrivateKeyParameters)p.Private; + ECPublicKeyParameters vKey = (ECPublicKeyParameters)p.Public; + + ECGOST3410_2012Signer s = new ECGOST3410_2012Signer(); + + s.Init(true, sKey); + BigInteger[] sig = s.GenerateSignature(data); + + + s = new ECGOST3410_2012Signer(); + s.Init(false, vKey); + + if (!s.VerifySignature(data, sig[0], sig[1])) + { + Fail("Signature " + signatureAlg + " did not verify"); + } + + // + // Test with Digest signer. + // + Gost3410DigestSigner digestSigner = new Gost3410DigestSigner( + new ECGOST3410_2012Signer(), + DigestUtilities.GetDigest(((ECGOST3410Parameters)vKey.Parameters).DigestParamSet)); + digestSigner.Init(true, sKey); + digestSigner.BlockUpdate(data, 0, data.Length); + byte[] sigBytes = digestSigner.GenerateSignature(); + + if (sigBytes.Length != expectedSignLen) + { + Fail(signatureAlg + " signature failed at expected length"); + } + + digestSigner = new Gost3410DigestSigner( + new ECGOST3410_2012Signer(), + DigestUtilities.GetDigest(((ECGOST3410Parameters)vKey.Parameters).DigestParamSet)); + digestSigner.Init(false, vKey); + digestSigner.BlockUpdate(data, 0, data.Length); + + if (!digestSigner.VerifySignature(sigBytes)) + { + Fail("Signature " + signatureAlg + " did not verify"); + } + } + + + } +} \ No newline at end of file -- cgit 1.4.1