You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
3.2 KiB
110 lines
3.2 KiB
5 days ago
|
using Org.BouncyCastle.Crypto.Generators;
|
||
|
using Org.BouncyCastle.Crypto.Parameters;
|
||
|
using Org.BouncyCastle.Math;
|
||
|
using Org.BouncyCastle.Math.EC;
|
||
|
using Org.BouncyCastle.Security;
|
||
|
|
||
|
namespace Admin.NET.Core;
|
||
|
|
||
|
public class SM2
|
||
|
{
|
||
|
public static SM2 Instance
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return new SM2();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static SM2 InstanceTest
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return new SM2();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static readonly string[] sm2_param = {
|
||
|
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",// p,0
|
||
|
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",// a,1
|
||
|
"28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",// b,2
|
||
|
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",// n,3
|
||
|
"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",// gx,4
|
||
|
"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0" // gy,5
|
||
|
};
|
||
|
|
||
|
public string[] ecc_param = sm2_param;
|
||
|
|
||
|
public readonly BigInteger ecc_p;
|
||
|
public readonly BigInteger ecc_a;
|
||
|
public readonly BigInteger ecc_b;
|
||
|
public readonly BigInteger ecc_n;
|
||
|
public readonly BigInteger ecc_gx;
|
||
|
public readonly BigInteger ecc_gy;
|
||
|
|
||
|
public readonly ECCurve ecc_curve;
|
||
|
public readonly ECPoint ecc_point_g;
|
||
|
|
||
|
public readonly ECDomainParameters ecc_bc_spec;
|
||
|
|
||
|
public readonly ECKeyPairGenerator ecc_key_pair_generator;
|
||
|
|
||
|
private SM2()
|
||
|
{
|
||
|
ecc_param = sm2_param;
|
||
|
|
||
|
ecc_p = new BigInteger(ecc_param[0], 16);
|
||
|
ecc_a = new BigInteger(ecc_param[1], 16);
|
||
|
ecc_b = new BigInteger(ecc_param[2], 16);
|
||
|
ecc_n = new BigInteger(ecc_param[3], 16);
|
||
|
ecc_gx = new BigInteger(ecc_param[4], 16);
|
||
|
ecc_gy = new BigInteger(ecc_param[5], 16);
|
||
|
|
||
|
ecc_curve = new FpCurve(ecc_p, ecc_a, ecc_b, null, null);
|
||
|
ecc_point_g = ecc_curve.CreatePoint(ecc_gx, ecc_gy);
|
||
|
|
||
|
ecc_bc_spec = new ECDomainParameters(ecc_curve, ecc_point_g, ecc_n);
|
||
|
|
||
|
ECKeyGenerationParameters ecc_ecgenparam;
|
||
|
ecc_ecgenparam = new ECKeyGenerationParameters(ecc_bc_spec, new SecureRandom());
|
||
|
|
||
|
ecc_key_pair_generator = new ECKeyPairGenerator();
|
||
|
ecc_key_pair_generator.Init(ecc_ecgenparam);
|
||
|
}
|
||
|
|
||
|
public virtual byte[] Sm2GetZ(byte[] userId, ECPoint userKey)
|
||
|
{
|
||
|
var sm3 = new SM3Digest();
|
||
|
byte[] p;
|
||
|
// userId length
|
||
|
int len = userId.Length * 8;
|
||
|
sm3.Update((byte)(len >> 8 & 0x00ff));
|
||
|
sm3.Update((byte)(len & 0x00ff));
|
||
|
|
||
|
// userId
|
||
|
sm3.BlockUpdate(userId, 0, userId.Length);
|
||
|
|
||
|
// a,b
|
||
|
p = ecc_a.ToByteArray();
|
||
|
sm3.BlockUpdate(p, 0, p.Length);
|
||
|
p = ecc_b.ToByteArray();
|
||
|
sm3.BlockUpdate(p, 0, p.Length);
|
||
|
// gx,gy
|
||
|
p = ecc_gx.ToByteArray();
|
||
|
sm3.BlockUpdate(p, 0, p.Length);
|
||
|
p = ecc_gy.ToByteArray();
|
||
|
sm3.BlockUpdate(p, 0, p.Length);
|
||
|
|
||
|
// x,y
|
||
|
p = userKey.AffineXCoord.ToBigInteger().ToByteArray();
|
||
|
sm3.BlockUpdate(p, 0, p.Length);
|
||
|
p = userKey.AffineYCoord.ToBigInteger().ToByteArray();
|
||
|
sm3.BlockUpdate(p, 0, p.Length);
|
||
|
|
||
|
// Z
|
||
|
byte[] md = new byte[sm3.GetDigestSize()];
|
||
|
sm3.DoFinal(md, 0);
|
||
|
|
||
|
return md;
|
||
|
}
|
||
|
}
|