| package org.bouncycastle.crypto.test; |
| |
| import java.io.IOException; |
| import java.math.BigInteger; |
| |
| import org.bouncycastle.asn1.ASN1Encodable; |
| import org.bouncycastle.asn1.ASN1Integer; |
| import org.bouncycastle.asn1.ASN1Sequence; |
| import org.bouncycastle.asn1.DERSequence; |
| import org.bouncycastle.crypto.AsymmetricCipherKeyPair; |
| import org.bouncycastle.crypto.generators.ECKeyPairGenerator; |
| import org.bouncycastle.crypto.params.ECDomainParameters; |
| import org.bouncycastle.crypto.params.ECKeyGenerationParameters; |
| import org.bouncycastle.crypto.params.ECPrivateKeyParameters; |
| import org.bouncycastle.crypto.params.ECPublicKeyParameters; |
| import org.bouncycastle.crypto.params.ParametersWithID; |
| import org.bouncycastle.crypto.params.ParametersWithRandom; |
| import org.bouncycastle.crypto.signers.SM2Signer; |
| import org.bouncycastle.math.ec.ECConstants; |
| import org.bouncycastle.math.ec.ECCurve; |
| import org.bouncycastle.math.ec.ECPoint; |
| import org.bouncycastle.util.Strings; |
| import org.bouncycastle.util.test.SimpleTest; |
| import org.bouncycastle.util.test.TestRandomBigInteger; |
| |
| public class SM2SignerTest |
| extends SimpleTest |
| { |
| public String getName() |
| { |
| return "SM2Signer"; |
| } |
| |
| private void doSignerTestFp() |
| throws Exception |
| { |
| 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 = ECConstants.ONE; |
| BigInteger SM2_ECC_GX = new BigInteger("421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", 16); |
| BigInteger SM2_ECC_GY = new BigInteger("0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", 16); |
| |
| ECCurve curve = new ECCurve.Fp(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.getPublic(); |
| ECPrivateKeyParameters ecPriv = (ECPrivateKeyParameters)kp.getPrivate(); |
| |
| 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.update(msg, 0, msg.length); |
| |
| byte[] sig = signer.generateSignature(); |
| |
| BigInteger[] rs = decode(sig); |
| |
| isTrue("r wrong", rs[0].equals(new BigInteger("40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1", 16))); |
| isTrue("s wrong", rs[1].equals(new BigInteger("6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7", 16))); |
| |
| signer = new SM2Signer(); |
| |
| signer.init(false, new ParametersWithID(ecPub, Strings.toByteArray("ALICE123@YAHOO.COM"))); |
| |
| signer.update(msg, 0, msg.length); |
| |
| isTrue("verification failed", signer.verifySignature(sig)); |
| } |
| |
| private void doSignerTestF2m() |
| throws Exception |
| { |
| 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 ECCurve.F2m(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(); |
| |
| keyPairGenerator.init(keyGenerationParams); |
| AsymmetricCipherKeyPair kp = keyPairGenerator.generateKeyPair(); |
| |
| ECPublicKeyParameters ecPub = (ECPublicKeyParameters)kp.getPublic(); |
| ECPrivateKeyParameters ecPriv = (ECPrivateKeyParameters)kp.getPrivate(); |
| |
| SM2Signer signer = new SM2Signer(); |
| |
| signer.init(true, |
| new ParametersWithID(new ParametersWithRandom(ecPriv, |
| new TestRandomBigInteger("36CD79FC8E24B7357A8A7B4A46D454C397703D6498158C605399B341ADA186D6", 16)), |
| Strings.toByteArray("ALICE123@YAHOO.COM"))); |
| |
| byte[] msg = Strings.toByteArray("message digest"); |
| |
| signer.update(msg, 0, msg.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))); |
| |
| signer.init(false, new ParametersWithID(ecPub, Strings.toByteArray("ALICE123@YAHOO.COM"))); |
| |
| signer.update(msg, 0, msg.length); |
| |
| isTrue("verification failed", signer.verifySignature(sig)); |
| } |
| |
| private void doVerifyBoundsCheck() |
| throws IOException |
| { |
| 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 ECCurve.F2m(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(); |
| |
| keyPairGenerator.init(keyGenerationParams); |
| AsymmetricCipherKeyPair kp = keyPairGenerator.generateKeyPair(); |
| |
| ECPublicKeyParameters ecPub = (ECPublicKeyParameters)kp.getPublic(); |
| |
| SM2Signer signer = new SM2Signer(); |
| |
| signer.init(false, ecPub); |
| |
| signer.update(new byte[20], 0, 20); |
| isTrue(!signer.verifySignature(encode(ECConstants.ZERO, ECConstants.EIGHT))); |
| |
| signer.update(new byte[20], 0, 20); |
| isTrue(!signer.verifySignature(encode(ECConstants.EIGHT, ECConstants.ZERO))); |
| |
| signer.update(new byte[20], 0, 20); |
| isTrue(!signer.verifySignature(encode(SM2_ECC_N, ECConstants.EIGHT))); |
| |
| signer.update(new byte[20], 0, 20); |
| isTrue(!signer.verifySignature(encode(ECConstants.EIGHT, SM2_ECC_N))); |
| } |
| |
| public void performTest() |
| throws Exception |
| { |
| doSignerTestFp(); |
| doSignerTestF2m(); |
| doVerifyBoundsCheck(); |
| } |
| |
| private static BigInteger[] decode(byte[] sig) |
| { |
| ASN1Sequence s = ASN1Sequence.getInstance(sig); |
| |
| return new BigInteger[] { ASN1Integer.getInstance(s.getObjectAt(0)).getValue(), |
| ASN1Integer.getInstance(s.getObjectAt(1)).getValue() }; |
| } |
| |
| private static byte[] encode(BigInteger r, BigInteger s) |
| throws IOException |
| { |
| return new DERSequence(new ASN1Encodable[] { new ASN1Integer(r), new ASN1Integer(s)}).getEncoded(); |
| } |
| |
| public static void main(String[] args) |
| { |
| runTest(new SM2SignerTest()); |
| } |
| } |