diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2019-06-01 18:58:01 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2019-06-01 18:58:01 +0700 |
commit | 17dbcd1de2147c407f30f84d29ac6e223baf5d73 (patch) | |
tree | 95a935970c10b2d180a0aae388d60b431ed745ce | |
parent | Merge branch 'rastrup-patch-4' (diff) | |
download | BouncyCastle.NET-ed25519-17dbcd1de2147c407f30f84d29ac6e223baf5d73.tar.xz |
Support SM2 in SignerUtilities
- including support for non-standard SHA256withSM2
-rw-r--r-- | crypto/src/cms/CMSSignedGenerator.cs | 6 | ||||
-rw-r--r-- | crypto/src/crypto/signers/SM2Signer.cs | 28 | ||||
-rw-r--r-- | crypto/src/security/SignerUtilities.cs | 16 | ||||
-rw-r--r-- | crypto/test/src/crypto/test/SM2SignerTest.cs | 260 | ||||
-rw-r--r-- | crypto/test/src/security/test/TestSignerUtil.cs | 39 |
5 files changed, 240 insertions, 109 deletions
diff --git a/crypto/src/cms/CMSSignedGenerator.cs b/crypto/src/cms/CMSSignedGenerator.cs index c7bc4ea43..b618ae3d4 100644 --- a/crypto/src/cms/CMSSignedGenerator.cs +++ b/crypto/src/cms/CMSSignedGenerator.cs @@ -134,6 +134,8 @@ namespace Org.BouncyCastle.Cms algorithms["SHA512WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_512; algorithms["SHA3-512WITHSPHINCS256"] = BCObjectIdentifiers.sphincs256_with_SHA3_512; algorithms["SHA512WITHSPHINCS256"] = BCObjectIdentifiers.sphincs256_with_SHA512; + + algorithms["SHA256WITHSM2"] = GMObjectIdentifiers.sm2sign_with_sha256; algorithms["SM3WITHSM2"] = GMObjectIdentifiers.sm2sign_with_sm3; algorithms["SHA256WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHA256; @@ -200,6 +202,7 @@ namespace Org.BouncyCastle.Cms // // SM2 // + noParams.Add((object)GMObjectIdentifiers.sm2sign_with_sha256); noParams.Add((object)GMObjectIdentifiers.sm2sign_with_sm3); // @@ -283,8 +286,9 @@ namespace Org.BouncyCastle.Cms digestOids[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001] = CryptoProObjectIdentifiers.GostR3411; digestOids[RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256; digestOids[RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512; - digestOids[GMObjectIdentifiers.sm2sign_with_sm3] = GMObjectIdentifiers.sm3; + digestOids[GMObjectIdentifiers.sm2sign_with_sha256] = NistObjectIdentifiers.IdSha256; + digestOids[GMObjectIdentifiers.sm2sign_with_sm3] = GMObjectIdentifiers.sm3; } private static AlgorithmIdentifier Generate(string signatureAlgorithm) diff --git a/crypto/src/crypto/signers/SM2Signer.cs b/crypto/src/crypto/signers/SM2Signer.cs index d9ec20525..56ec17cf3 100644 --- a/crypto/src/crypto/signers/SM2Signer.cs +++ b/crypto/src/crypto/signers/SM2Signer.cs @@ -15,7 +15,7 @@ namespace Org.BouncyCastle.Crypto.Signers : ISigner { private readonly IDsaKCalculator kCalculator = new RandomDsaKCalculator(); - private readonly SM3Digest digest = new SM3Digest(); + private readonly IDigest digest; private readonly IDsaEncoding encoding; private ECDomainParameters ecParams; @@ -24,13 +24,24 @@ namespace Org.BouncyCastle.Crypto.Signers private byte[] z; public SM2Signer() + : this(StandardDsaEncoding.Instance, new SM3Digest()) + { + } + + public SM2Signer(IDigest digest) + : this(StandardDsaEncoding.Instance, digest) { - this.encoding = StandardDsaEncoding.Instance; } public SM2Signer(IDsaEncoding encoding) + : this(encoding, new SM3Digest()) + { + } + + public SM2Signer(IDsaEncoding encoding, IDigest digest) { this.encoding = encoding; + this.digest = digest; } public virtual string AlgorithmName @@ -47,11 +58,15 @@ namespace Org.BouncyCastle.Crypto.Signers { baseParam = ((ParametersWithID)parameters).Parameters; userID = ((ParametersWithID)parameters).GetID(); + + if (userID.Length >= 8192) + throw new ArgumentException("SM2 user ID must be less than 2^16 bits long"); } else { baseParam = parameters; - userID = Hex.Decode("31323334353637383132333435363738"); // the default value (ASCII "1234567812345678") + // the default value, string value is "1234567812345678" + userID = Hex.Decode("31323334353637383132333435363738"); } if (forSigning) @@ -124,7 +139,7 @@ namespace Org.BouncyCastle.Crypto.Signers byte[] eHash = DigestUtilities.DoFinal(digest); BigInteger n = ecParams.N; - BigInteger e = CalculateE(eHash); + BigInteger e = CalculateE(n, eHash); BigInteger d = ((ECPrivateKeyParameters)ecKey).D; BigInteger r, s; @@ -184,7 +199,7 @@ namespace Org.BouncyCastle.Crypto.Signers byte[] eHash = DigestUtilities.DoFinal(digest); // B4 - BigInteger e = CalculateE(eHash); + BigInteger e = CalculateE(n, eHash); // B5 BigInteger t = r.Add(s).Mod(n); @@ -229,8 +244,9 @@ namespace Org.BouncyCastle.Crypto.Signers digest.BlockUpdate(p, 0, p.Length); } - protected virtual BigInteger CalculateE(byte[] message) + protected virtual BigInteger CalculateE(BigInteger n, byte[] message) { + // TODO Should hashes larger than the order be truncated as with ECDSA? return new BigInteger(1, message); } diff --git a/crypto/src/security/SignerUtilities.cs b/crypto/src/security/SignerUtilities.cs index ae8d21f0a..93d20a697 100644 --- a/crypto/src/security/SignerUtilities.cs +++ b/crypto/src/security/SignerUtilities.cs @@ -7,6 +7,7 @@ using Org.BouncyCastle.Asn1.Bsi; using Org.BouncyCastle.Asn1.CryptoPro; using Org.BouncyCastle.Asn1.Eac; using Org.BouncyCastle.Asn1.EdEC; +using Org.BouncyCastle.Asn1.GM; using Org.BouncyCastle.Asn1.Nist; using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; @@ -344,6 +345,11 @@ namespace Org.BouncyCastle.Security algorithms[EdECObjectIdentifiers.id_Ed448.Id] = "Ed448"; algorithms["ED448PH"] = "Ed448ph"; + algorithms["SHA256WITHSM2"] = "SHA256withSM2"; + algorithms[GMObjectIdentifiers.sm2sign_with_sha256.Id] = "SHA256withSM2"; + algorithms["SM3WITHSM2"] = "SM3withSM2"; + algorithms[GMObjectIdentifiers.sm2sign_with_sm3.Id] = "SM3withSM2"; + oids["MD2withRSA"] = PkcsObjectIdentifiers.MD2WithRsaEncryption; oids["MD4withRSA"] = PkcsObjectIdentifiers.MD4WithRsaEncryption; oids["MD5withRSA"] = PkcsObjectIdentifiers.MD5WithRsaEncryption; @@ -392,6 +398,9 @@ namespace Org.BouncyCastle.Security oids["Ed25519"] = EdECObjectIdentifiers.id_Ed25519; oids["Ed448"] = EdECObjectIdentifiers.id_Ed448; + + oids["SHA256withSM2"] = GMObjectIdentifiers.sm2sign_with_sha256; + oids["SM3withSM2"] = GMObjectIdentifiers.sm2sign_with_sm3; } /// <summary> @@ -570,6 +579,13 @@ namespace Org.BouncyCastle.Security return new DsaDigestSigner(new ECNRSigner(), digest); } + if (Platform.EndsWith(mechanism, "withSM2")) + { + string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with")); + IDigest digest = DigestUtilities.GetDigest(digestName); + return new SM2Signer(digest); + } + if (mechanism.Equals("GOST3410")) { return new Gost3410DigestSigner(new Gost3410Signer(), new Gost3411Digest()); diff --git a/crypto/test/src/crypto/test/SM2SignerTest.cs b/crypto/test/src/crypto/test/SM2SignerTest.cs index e3c9c21ae..67cb1a443 100644 --- a/crypto/test/src/crypto/test/SM2SignerTest.cs +++ b/crypto/test/src/crypto/test/SM2SignerTest.cs @@ -4,6 +4,8 @@ using System.IO; using NUnit.Framework; using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Signers; @@ -18,132 +20,157 @@ namespace Org.BouncyCastle.Crypto.Tests public class SM2SignerTest : SimpleTest { + private static readonly ECDomainParameters ParametersFpDraft = CreateParamsFpDraft(); + private static readonly ECDomainParameters ParametersF2m = CreateParamsF2m(); + public override string Name { get { return "SM2Signer"; } } - private void DoSignerTestFp() + private void DoSignerTestFpDraftSM3() { - BigInteger SM2_ECC_P = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", 16); - BigInteger SM2_ECC_A = new BigInteger("787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", 16); - BigInteger SM2_ECC_B = new BigInteger("63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", 16); - BigInteger SM2_ECC_N = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", 16); - BigInteger SM2_ECC_H = BigInteger.ValueOf(4); - BigInteger SM2_ECC_GX = new BigInteger("421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", 16); - BigInteger SM2_ECC_GY = new BigInteger("0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", 16); - - ECCurve curve = new FpCurve(SM2_ECC_P, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H); - - ECPoint g = curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY); - ECDomainParameters domainParams = new ECDomainParameters(curve, g, SM2_ECC_N); - - ECKeyGenerationParameters keyGenerationParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263", 16)); - ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator(); - - keyPairGenerator.Init(keyGenerationParams); - AsymmetricCipherKeyPair kp = keyPairGenerator.GenerateKeyPair(); - - ECPublicKeyParameters ecPub = (ECPublicKeyParameters)kp.Public; - ECPrivateKeyParameters ecPriv = (ECPrivateKeyParameters)kp.Private; - - SM2Signer signer = new SM2Signer(); - - signer.Init(true, - new ParametersWithID(new ParametersWithRandom(ecPriv, - new TestRandomBigInteger("6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F", 16)), - Strings.ToByteArray("ALICE123@YAHOO.COM"))); - - byte[] msg = Strings.ToByteArray("message digest"); - - signer.BlockUpdate(msg, 0, msg.Length); - - byte[] sig = signer.GenerateSignature(); + DoSignerTest( + ParametersFpDraft, + new SM3Digest(), + "ALICE123@YAHOO.COM", + "message digest", + "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263", + "6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F", + "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1", + "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7" + ); + } - BigInteger[] rs = Decode(sig); + private void DoSignerTestFpDraftSha256() + { + DoSignerTest( + ParametersFpDraft, + new Sha256Digest(), + "ALICE123@YAHOO.COM", + "message digest", + "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263", + "6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F", + "7D62A5EDBDDC8AF4D69C9E37A60D31F5CEFE8727709117E0869648D0A9AE4F57", + "1E5E89718B716AAFC6253443168E4F7CF7E1B7B3934307686CE5947C1BD55EDA" + ); + } - IsTrue("r wrong", rs[0].Equals(new BigInteger("40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1", 16))); - IsTrue("s wrong", rs[1].Equals(new BigInteger("6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7", 16))); + private void DoSignerTestFpStandardSM3() + { + DoSignerTest( + "sm2p256v1", + new SM3Digest(), + "sm2test@example.com", + "hi chappy", + "110E7973206F68C19EE5F7328C036F26911C8C73B4E4F36AE3291097F8984FFC", + "3174C6FFC3C279D2422F3FC0A9F3E574674A4490FE45A5325CAF7D3EC4C8F96C", + "05890B9077B92E47B17A1FF42A814280E556AFD92B4A98B9670BF8B1A274C2FA", + "E3ABBB8DB2B6ECD9B24ECCEA7F679FB9A4B1DB52F4AA985E443AD73237FA1993" + ); + } - signer.Init(false, new ParametersWithID(ecPub, Strings.ToByteArray("ALICE123@YAHOO.COM"))); + private void DoSignerTestFpStandardSha256() + { + DoSignerTest( + "sm2p256v1", + new Sha256Digest(), + "sm2test@example.com", + "hi chappy", + "110E7973206F68C19EE5F7328C036F26911C8C73B4E4F36AE3291097F8984FFC", + "3174C6FFC3C279D2422F3FC0A9F3E574674A4490FE45A5325CAF7D3EC4C8F96C", + "94DA20EA69E4FC70692158BF3D30F87682A4B2F84DF4A4829A1EFC5D9C979D3F", + "EE15AF8D455B728AB80E592FCB654BF5B05620B2F4D25749D263D5C01FAD365F" + ); + } - signer.BlockUpdate(msg, 0, msg.Length); + private void DoSignerTestFpP256SM3() + { + DoSignerTest( + "P-256", + new SM3Digest(), + "sm2_p256_test@example.com", + "no backdoors here", + "110E7973206F68C19EE5F7328C036F26911C8C73B4E4F36AE3291097F8984FFC", + "3174C6FFC3C279D2422F3FC0A9F3E574674A4490FE45A5325CAF7D3EC4C8F96C", + "96AA39A0C4A5C454653F394E86386F2E38BE14C57D0E555F3A27A5CEF30E51BD", + "62372BE4AC97DBE725AC0B279BB8FD15883858D814FD792DDB0A401DCC988E70" + ); + } - IsTrue("verification failed", signer.VerifySignature(sig)); + private void DoSignerTestFpP256Sha256() + { + DoSignerTest( + "P-256", + new Sha256Digest(), + "sm2_p256_test@example.com", + "no backdoors here", + "110E7973206F68C19EE5F7328C036F26911C8C73B4E4F36AE3291097F8984FFC", + "3174C6FFC3C279D2422F3FC0A9F3E574674A4490FE45A5325CAF7D3EC4C8F96C", + "503D234A22123D7029271EB9E0D763619A69868DE8296C13EDD4CA32D280CFDE", + "0BDE97699B77268584DDD238DA120095F01130AD2DB37184270F37C02FB2E86B" + ); } private void DoSignerTestF2m() { - BigInteger SM2_ECC_A = new BigInteger("00", 16); - BigInteger SM2_ECC_B = new BigInteger("E78BCD09746C202378A7E72B12BCE00266B9627ECB0B5A25367AD1AD4CC6242B", 16); - BigInteger SM2_ECC_N = new BigInteger("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC972CF7E6B6F900945B3C6A0CF6161D", 16); - BigInteger SM2_ECC_H = BigInteger.ValueOf(4); - BigInteger SM2_ECC_GX = new BigInteger("00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD", 16); - BigInteger SM2_ECC_GY = new BigInteger("013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E", 16); - - ECCurve curve = new F2mCurve(257, 12, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H); - - ECPoint g = curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY); - ECDomainParameters domainParams = new ECDomainParameters(curve, g, SM2_ECC_N); - - ECKeyGenerationParameters keyGenerationParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("771EF3DBFF5F1CDC32B9C572930476191998B2BF7CB981D7F5B39202645F0931", 16)); - ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator(); + DoSignerTest( + ParametersF2m, + new SM3Digest(), + "ALICE123@YAHOO.COM", + "message digest", + "771EF3DBFF5F1CDC32B9C572930476191998B2BF7CB981D7F5B39202645F0931", + "36CD79FC8E24B7357A8A7B4A46D454C397703D6498158C605399B341ADA186D6", + "6D3FBA26EAB2A1054F5D198332E335817C8AC453ED26D3391CD4439D825BF25B", + "3124C5688D95F0A10252A9BED033BEC84439DA384621B6D6FAD77F94B74A9556" + ); + } - keyPairGenerator.Init(keyGenerationParams); - AsymmetricCipherKeyPair kp = keyPairGenerator.GenerateKeyPair(); + private void DoSignerTest(string curveName, IDigest d, string ident, string msg, string x, string nonce, string r, string s) + { + X9ECParameters x9 = ECNamedCurveTable.GetByName(curveName); + ECDomainParameters domainParams = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()); - ECPublicKeyParameters ecPub = (ECPublicKeyParameters)kp.Public; - ECPrivateKeyParameters ecPriv = (ECPrivateKeyParameters)kp.Private; + DoSignerTest(domainParams, d, ident, msg, x, nonce, r, s); + } - SM2Signer signer = new SM2Signer(); + private void DoSignerTest(ECDomainParameters domainParams, IDigest d, string ident, string msg, string x, string nonce, string r, string s) + { + byte[] idBytes = Strings.ToByteArray(ident); + byte[] msgBytes = Strings.ToByteArray(msg); + AsymmetricCipherKeyPair kp = GenerateKeyPair(domainParams, x); - signer.Init(true, - new ParametersWithID(new ParametersWithRandom(ecPriv, - new TestRandomBigInteger("36CD79FC8E24B7357A8A7B4A46D454C397703D6498158C605399B341ADA186D6", 16)), - Strings.ToByteArray("ALICE123@YAHOO.COM"))); + SM2Signer signer = new SM2Signer(d); - byte[] msg = Strings.ToByteArray("message digest"); + signer.Init(true, new ParametersWithID( + new ParametersWithRandom(kp.Private, new TestRandomBigInteger(nonce, 16)), + idBytes)); - signer.BlockUpdate(msg, 0, msg.Length); + signer.BlockUpdate(msgBytes, 0, msgBytes.Length); byte[] sig = signer.GenerateSignature(); BigInteger[] rs = Decode(sig); - IsTrue("F2m r wrong", rs[0].Equals(new BigInteger("6D3FBA26EAB2A1054F5D198332E335817C8AC453ED26D3391CD4439D825BF25B", 16))); - IsTrue("F2m s wrong", rs[1].Equals(new BigInteger("3124C5688D95F0A10252A9BED033BEC84439DA384621B6D6FAD77F94B74A9556", 16))); + IsTrue("r wrong", rs[0].Equals(new BigInteger(r, 16))); + IsTrue("s wrong", rs[1].Equals(new BigInteger(s, 16))); - signer.Init(false, new ParametersWithID(ecPub, Strings.ToByteArray("ALICE123@YAHOO.COM"))); + signer.Init(false, new ParametersWithID(kp.Public, idBytes)); - signer.BlockUpdate(msg, 0, msg.Length); + signer.BlockUpdate(msgBytes, 0, msgBytes.Length); IsTrue("verification failed", signer.VerifySignature(sig)); } private void DoVerifyBoundsCheck() { - BigInteger SM2_ECC_A = new BigInteger("00", 16); - BigInteger SM2_ECC_B = new BigInteger("E78BCD09746C202378A7E72B12BCE00266B9627ECB0B5A25367AD1AD4CC6242B", 16); - BigInteger SM2_ECC_N = new BigInteger("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC972CF7E6B6F900945B3C6A0CF6161D", 16); - BigInteger SM2_ECC_GX = new BigInteger("00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD", 16); - BigInteger SM2_ECC_GY = new BigInteger("013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E", 16); - - ECCurve curve = new F2mCurve(257, 12, SM2_ECC_A, SM2_ECC_B); + ECDomainParameters domainParams = ParametersF2m; - ECPoint g = curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY); - ECDomainParameters domainParams = new ECDomainParameters(curve, g, SM2_ECC_N); - - ECKeyGenerationParameters keyGenerationParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("771EF3DBFF5F1CDC32B9C572930476191998B2BF7CB981D7F5B39202645F0931", 16)); - ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator(); - - keyPairGenerator.Init(keyGenerationParams); - AsymmetricCipherKeyPair kp = keyPairGenerator.GenerateKeyPair(); - - ECPublicKeyParameters ecPub = (ECPublicKeyParameters)kp.Public; + AsymmetricCipherKeyPair kp = GenerateKeyPair(domainParams, "771EF3DBFF5F1CDC32B9C572930476191998B2BF7CB981D7F5B39202645F0931"); SM2Signer signer = new SM2Signer(); - signer.Init(false, ecPub); + signer.Init(false, kp.Public); signer.BlockUpdate(new byte[20], 0, 20); IsTrue(!signer.VerifySignature(Encode(BigInteger.Zero, BigInteger.ValueOf(8)))); @@ -152,25 +179,65 @@ namespace Org.BouncyCastle.Crypto.Tests IsTrue(!signer.VerifySignature(Encode(BigInteger.ValueOf(8), BigInteger.Zero))); signer.BlockUpdate(new byte[20], 0, 20); - IsTrue(!signer.VerifySignature(Encode(SM2_ECC_N, BigInteger.ValueOf(8)))); + IsTrue(!signer.VerifySignature(Encode(domainParams.N, BigInteger.ValueOf(8)))); signer.BlockUpdate(new byte[20], 0, 20); - IsTrue(!signer.VerifySignature(Encode(BigInteger.ValueOf(8), SM2_ECC_N))); + IsTrue(!signer.VerifySignature(Encode(BigInteger.ValueOf(8), domainParams.N))); } public override void PerformTest() { - DoSignerTestFp(); + DoSignerTestFpDraftSM3(); + DoSignerTestFpDraftSha256(); + DoSignerTestFpStandardSM3(); + DoSignerTestFpStandardSha256(); + DoSignerTestFpP256SM3(); + DoSignerTestFpP256Sha256(); DoSignerTestF2m(); DoVerifyBoundsCheck(); } + private static ECDomainParameters CreateParamsFpDraft() + { + BigInteger SM2_ECC_P = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", 16); + BigInteger SM2_ECC_A = new BigInteger("787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", 16); + BigInteger SM2_ECC_B = new BigInteger("63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", 16); + BigInteger SM2_ECC_N = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", 16); + BigInteger SM2_ECC_H = BigInteger.One; + BigInteger SM2_ECC_GX = new BigInteger("421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", 16); + BigInteger SM2_ECC_GY = new BigInteger("0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", 16); + + ECCurve curve = new FpCurve(SM2_ECC_P, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H); + ECPoint g = curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY); + return new ECDomainParameters(curve, g, SM2_ECC_N, SM2_ECC_H); + } + + private static ECDomainParameters CreateParamsF2m() + { + BigInteger SM2_ECC_A = new BigInteger("00", 16); + BigInteger SM2_ECC_B = new BigInteger("E78BCD09746C202378A7E72B12BCE00266B9627ECB0B5A25367AD1AD4CC6242B", 16); + BigInteger SM2_ECC_N = new BigInteger("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC972CF7E6B6F900945B3C6A0CF6161D", 16); + BigInteger SM2_ECC_H = BigInteger.ValueOf(4); + BigInteger SM2_ECC_GX = new BigInteger("00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD", 16); + BigInteger SM2_ECC_GY = new BigInteger("013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E", 16); + + ECCurve curve = new F2mCurve(257, 12, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H); + ECPoint g = curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY); + return new ECDomainParameters(curve, g, SM2_ECC_N, SM2_ECC_H); + } + private static BigInteger[] Decode(byte[] sig) { Asn1Sequence s = Asn1Sequence.GetInstance(sig); - return new BigInteger[] { DerInteger.GetInstance(s[0]).Value, - DerInteger.GetInstance(s[1]).Value }; + return new BigInteger[] { + DecodeValue(s[0]), + DecodeValue(s[1]) }; + } + + private static BigInteger DecodeValue(Asn1Encodable e) + { + return DerInteger.GetInstance(e).Value; } private static byte[] Encode(BigInteger r, BigInteger s) @@ -178,6 +245,13 @@ namespace Org.BouncyCastle.Crypto.Tests return new DerSequence(new DerInteger(r), new DerInteger(s)).GetEncoded(); } + private static AsymmetricCipherKeyPair GenerateKeyPair(ECDomainParameters domainParams, string x) + { + ECKeyPairGenerator kpg = new ECKeyPairGenerator(); + kpg.Init(new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger(x, 16))); + return kpg.GenerateKeyPair(); + } + public static void Main( string[] args) { diff --git a/crypto/test/src/security/test/TestSignerUtil.cs b/crypto/test/src/security/test/TestSignerUtil.cs index 48bf49a63..8088f21fd 100644 --- a/crypto/test/src/security/test/TestSignerUtil.cs +++ b/crypto/test/src/security/test/TestSignerUtil.cs @@ -25,6 +25,8 @@ namespace Org.BouncyCastle.Security.Tests [Test] public void TestAlgorithms() { + SecureRandom RANDOM = new SecureRandom(); + // // RSA parameters // @@ -90,29 +92,43 @@ namespace Org.BouncyCastle.Security.Tests ecGostKpg.Init( new ECKeyGenerationParameters( CryptoProObjectIdentifiers.GostR3410x2001CryptoProA, - new SecureRandom())); + RANDOM)); AsymmetricCipherKeyPair ecGostPair = ecGostKpg.GenerateKeyPair(); IAsymmetricCipherKeyPairGenerator ed25519Kpg = GeneratorUtilities.GetKeyPairGenerator("Ed25519"); - ed25519Kpg.Init(new Ed25519KeyGenerationParameters(new SecureRandom())); + ed25519Kpg.Init(new Ed25519KeyGenerationParameters(RANDOM)); AsymmetricCipherKeyPair ed25519Pair = ed25519Kpg.GenerateKeyPair(); IAsymmetricCipherKeyPairGenerator ed448Kpg = GeneratorUtilities.GetKeyPairGenerator("Ed448"); - ed448Kpg.Init(new Ed448KeyGenerationParameters(new SecureRandom())); + ed448Kpg.Init(new Ed448KeyGenerationParameters(RANDOM)); AsymmetricCipherKeyPair ed448Pair = ed448Kpg.GenerateKeyPair(); // // GOST3410 parameters // IAsymmetricCipherKeyPairGenerator gostKpg = GeneratorUtilities.GetKeyPairGenerator("GOST3410"); - gostKpg.Init( - new Gost3410KeyGenerationParameters( - new SecureRandom(), - CryptoProObjectIdentifiers.GostR3410x94CryptoProA)); - + gostKpg.Init(new Gost3410KeyGenerationParameters(RANDOM, CryptoProObjectIdentifiers.GostR3410x94CryptoProA)); AsymmetricCipherKeyPair gostPair = gostKpg.GenerateKeyPair(); + // + // SM2 parameters + // + BigInteger SM2_ECC_P = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", 16); + BigInteger SM2_ECC_A = new BigInteger("787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", 16); + BigInteger SM2_ECC_B = new BigInteger("63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", 16); + BigInteger SM2_ECC_N = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", 16); + BigInteger SM2_ECC_H = BigInteger.One; + BigInteger SM2_ECC_GX = new BigInteger("421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", 16); + BigInteger SM2_ECC_GY = new BigInteger("0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", 16); + + ECCurve sm2Curve = new FpCurve(SM2_ECC_P, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H); + ECPoint sm2G = sm2Curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY); + ECDomainParameters sm2Domain = new ECDomainParameters(sm2Curve, sm2G, SM2_ECC_N, SM2_ECC_H); + + ECKeyPairGenerator sm2Kpg = new ECKeyPairGenerator(); + sm2Kpg.Init(new ECKeyGenerationParameters(sm2Domain, RANDOM)); + AsymmetricCipherKeyPair sm2Pair = sm2Kpg.GenerateKeyPair(); // @@ -120,7 +136,7 @@ namespace Org.BouncyCastle.Security.Tests // byte[] shortMsg = new byte[] { 1, 4, 5, 6, 8, 8, 4, 2, 1, 3 }; byte[] longMsg = new byte[100]; - new SecureRandom().NextBytes(longMsg); + RANDOM.NextBytes(longMsg); foreach (string algorithm in SignerUtilities.Algorithms) { @@ -172,6 +188,11 @@ namespace Org.BouncyCastle.Security.Tests signParams = gostPair.Private; verifyParams = gostPair.Public; } + else if (cipherName == "SM2") + { + signParams = sm2Pair.Private; + verifyParams = sm2Pair.Public; + } else { Assert.Fail("Unknown algorithm encountered: " + cipherName); |