C#实现SM2国密加密
<p><img src="https://img2020.cnblogs.com/blog/82863/202005/82863-20200507142133300-509867814.png" alt=""></p><p> </p>
<p> </p>
<p>本文主要讲解“国密加密算法”SM系列的C#实现方法,不涉及具体的算法剖析,在网络上找到的java实现方法比较少,切在跨语言加密解密上会存在一些问题,所以整理此文志之。JAVA实现参考http://blog.csdn.net/ererfei/article/details/50998162</p>
<p>1.SM2 & SM3<br>由于SM2算法中需要使用SM3摘要算法,所以把他们放在一起</p>
<p>项目目录结构如下:</p>
<p> </p>
<p>首先要下载一个dll包——BouncyCastle.Crypto.dll,并将此dll引用到项目中。实现代码如下(每个工具类都有Main可以运行测试):</p>
<p>a. SM2主类</p>
<p>【SM2.cs】</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Crypto.Generators;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Math.EC;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Math;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Crypto;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Crypto.Parameters;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Security;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Text;
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> Com.Mlq.SM
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> SM2
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> SM2 Instance
{
</span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM2();
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> SM2 InstanceTest
{
</span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM2();
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> <span style="color: rgba(0, 0, 255, 1)">string</span>[] sm2_param =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> p,0</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> a,1</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> b,2</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> n,3</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> gx,4</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> gy,5</span>
<span style="color: rgba(0, 0, 0, 1)"> };
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">string</span>[] ecc_param =<span style="color: rgba(0, 0, 0, 1)"> sm2_param;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> BigInteger ecc_p;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> BigInteger ecc_a;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> BigInteger ecc_b;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> BigInteger ecc_n;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> BigInteger ecc_gx;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> BigInteger ecc_gy;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> ECCurve ecc_curve;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> ECPoint ecc_point_g;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> ECDomainParameters ecc_bc_spec;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> ECKeyPairGenerator ecc_key_pair_generator;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> SM2()
{
ecc_param </span>=<span style="color: rgba(0, 0, 0, 1)"> sm2_param;
ECFieldElement ecc_gx_fieldelement;
ECFieldElement ecc_gy_fieldelement;
ecc_p </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> BigInteger(ecc_param[<span style="color: rgba(128, 0, 128, 1)">0</span>], <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
ecc_a </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> BigInteger(ecc_param[<span style="color: rgba(128, 0, 128, 1)">1</span>], <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
ecc_b </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> BigInteger(ecc_param[<span style="color: rgba(128, 0, 128, 1)">2</span>], <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
ecc_n </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> BigInteger(ecc_param[<span style="color: rgba(128, 0, 128, 1)">3</span>], <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
ecc_gx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> BigInteger(ecc_param[<span style="color: rgba(128, 0, 128, 1)">4</span>], <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
ecc_gy </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> BigInteger(ecc_param[<span style="color: rgba(128, 0, 128, 1)">5</span>], <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
ecc_gx_fieldelement </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> FpFieldElement(ecc_p, ecc_gx);
ecc_gy_fieldelement </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> FpFieldElement(ecc_p, ecc_gy);
ecc_curve </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> FpCurve(ecc_p, ecc_a, ecc_b);
ecc_point_g </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> FpPoint(ecc_curve, ecc_gx_fieldelement, ecc_gy_fieldelement);
ecc_bc_spec </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ECDomainParameters(ecc_curve, ecc_point_g, ecc_n);
ECKeyGenerationParameters ecc_ecgenparam;
ecc_ecgenparam </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> ECKeyGenerationParameters(ecc_bc_spec, <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SecureRandom());
ecc_key_pair_generator </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ECKeyPairGenerator();
ecc_key_pair_generator.Init(ecc_ecgenparam);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] Sm2GetZ(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] userId, ECPoint userKey)
{
SM3Digest sm3 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM3Digest();
</span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] p;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> userId length</span>
<span style="color: rgba(0, 0, 255, 1)">int</span> len = userId.Length * <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">;
sm3.Update((</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) (len >> <span style="color: rgba(128, 0, 128, 1)">8</span> & <span style="color: rgba(128, 0, 128, 1)">0x00ff</span><span style="color: rgba(0, 0, 0, 1)">));
sm3.Update((</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) (len & <span style="color: rgba(128, 0, 128, 1)">0x00ff</span><span style="color: rgba(0, 0, 0, 1)">));
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> userId</span>
sm3.BlockUpdate(userId, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, userId.Length);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> a,b</span>
p =<span style="color: rgba(0, 0, 0, 1)"> ecc_a.ToByteArray();
sm3.BlockUpdate(p, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, p.Length);
p </span>=<span style="color: rgba(0, 0, 0, 1)"> ecc_b.ToByteArray();
sm3.BlockUpdate(p, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, p.Length);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> gx,gy</span>
p =<span style="color: rgba(0, 0, 0, 1)"> ecc_gx.ToByteArray();
sm3.BlockUpdate(p, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, p.Length);
p </span>=<span style="color: rgba(0, 0, 0, 1)"> ecc_gy.ToByteArray();
sm3.BlockUpdate(p, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, p.Length);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> x,y</span>
p =<span style="color: rgba(0, 0, 0, 1)"> userKey.X.ToBigInteger().ToByteArray();
sm3.BlockUpdate(p, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, p.Length);
p </span>=<span style="color: rgba(0, 0, 0, 1)"> userKey.Y.ToBigInteger().ToByteArray();
sm3.BlockUpdate(p, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, p.Length);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Z</span>
<span style="color: rgba(0, 0, 255, 1)">byte</span>[] md = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">;
sm3.DoFinal(md, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> md;
}
}
}</span></pre>
</div>
<p>b. SM2工具类</p>
<p>【SM2Utils.cs】</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Com.Mlq.SM;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Crypto;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Crypto.Parameters;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Math;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Math.EC;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Utilities.Encoders;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Collections.Generic;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Linq;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Text;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Threading.Tasks;
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> Com.Mlq.SM
{
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> SM2Utils
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> GenerateKeyPair()
{
SM2 sm2 </span>=<span style="color: rgba(0, 0, 0, 1)"> SM2.Instance;
AsymmetricCipherKeyPair key </span>=<span style="color: rgba(0, 0, 0, 1)"> sm2.ecc_key_pair_generator.GenerateKeyPair();
ECPrivateKeyParameters ecpriv </span>=<span style="color: rgba(0, 0, 0, 1)"> (ECPrivateKeyParameters) key.Private;
ECPublicKeyParameters ecpub </span>=<span style="color: rgba(0, 0, 0, 1)"> (ECPublicKeyParameters) key.Public;
BigInteger privateKey </span>=<span style="color: rgba(0, 0, 0, 1)"> ecpriv.D;
ECPoint publicKey </span>=<span style="color: rgba(0, 0, 0, 1)"> ecpub.Q;
System.Console.Out.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">公钥: </span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(Hex.Encode(publicKey.GetEncoded())).ToUpper());
System.Console.Out.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">私钥: </span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(Hex.Encode(privateKey.ToByteArray())).ToUpper());
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> String Encrypt(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] publicKey,<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] data)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">null</span> == publicKey || publicKey.Length == <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (data == <span style="color: rgba(0, 0, 255, 1)">null</span> || data.Length == <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] source = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">;
Array.Copy(data, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, source, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, data.Length);
Cipher cipher </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Cipher();
SM2 sm2 </span>=<span style="color: rgba(0, 0, 0, 1)"> SM2.Instance;
ECPoint userKey </span>=<span style="color: rgba(0, 0, 0, 1)"> sm2.ecc_curve.DecodePoint(publicKey);
ECPoint c1 </span>=<span style="color: rgba(0, 0, 0, 1)"> cipher.Init_enc(sm2, userKey);
cipher.Encrypt(source);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] c3 = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">32</span><span style="color: rgba(0, 0, 0, 1)">];
cipher.Dofinal(c3);
String sc1 </span>=<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(Hex.Encode(c1.GetEncoded()));
String sc2 </span>=<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(Hex.Encode(source));
String sc3 </span>=<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(Hex.Encode(c3));
</span><span style="color: rgba(0, 0, 255, 1)">return</span> (sc1 + sc2 +<span style="color: rgba(0, 0, 0, 1)"> sc3).ToUpper();
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] Decrypt(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] privateKey, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] encryptedData)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">null</span> == privateKey || privateKey.Length == <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (encryptedData == <span style="color: rgba(0, 0, 255, 1)">null</span> || encryptedData.Length == <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
}
String data </span>=<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(Hex.Encode(encryptedData));
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] c1Bytes = Hex.Decode(Encoding.Default.GetBytes(data.Substring(<span style="color: rgba(128, 0, 128, 1)">0</span> , <span style="color: rgba(128, 0, 128, 1)">130</span><span style="color: rgba(0, 0, 0, 1)">)));
</span><span style="color: rgba(0, 0, 255, 1)">int</span> c2Len = encryptedData.Length - <span style="color: rgba(128, 0, 128, 1)">97</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] c2 = Hex.Decode(Encoding.Default.GetBytes(data.Substring(<span style="color: rgba(128, 0, 128, 1)">130</span> , <span style="color: rgba(128, 0, 128, 1)">2</span> *<span style="color: rgba(0, 0, 0, 1)"> c2Len)));
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] c3 = Hex.Decode(Encoding.Default.GetBytes(data.Substring(<span style="color: rgba(128, 0, 128, 1)">130</span> + <span style="color: rgba(128, 0, 128, 1)">2</span> * c2Len , <span style="color: rgba(128, 0, 128, 1)">64</span><span style="color: rgba(0, 0, 0, 1)">)));
SM2 sm2 </span>=<span style="color: rgba(0, 0, 0, 1)"> SM2.Instance;
BigInteger userD </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> BigInteger(<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">, privateKey);
ECPoint c1 </span>=<span style="color: rgba(0, 0, 0, 1)"> sm2.ecc_curve.DecodePoint(c1Bytes);
Cipher cipher </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Cipher();
cipher.Init_dec(userD, c1);
cipher.Decrypt(c2);
cipher.Dofinal(c3);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> c2;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">public static void Main()
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> GenerateKeyPair();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> String plainText = "ererfeiisgod";
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> byte[] sourceData = Encoding.Default.GetBytes(plainText);
</span><span style="color: rgba(0, 128, 0, 1)">//</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">下面的秘钥可以使用generateKeyPair()生成的秘钥内容
</span><span style="color: rgba(0, 128, 0, 1)">//</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 国密规范正式私钥
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> String prik = "3690655E33D5EA3D9A4AE1A1ADD766FDEA045CDEAA43A9206FB8C430CEFE0D94";
</span><span style="color: rgba(0, 128, 0, 1)">//</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 国密规范正式公钥
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> String pubk = "04F6E0C3345AE42B51E06BF50B98834988D54EBC7460FE135A48171BC0629EAE205EEDE253A530608178A98F1E19BB737302813BA39ED3FA3C51639D7A20C7391A";
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine("加密: ");
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> String cipherText = SM2Utils.Encrypt(Hex.Decode(pubk), sourceData);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine(cipherText);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine("解密: ");
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> plainText = Encoding.Default.GetString(SM2Utils.Decrypt(Hex.Decode(prik), Hex.Decode(cipherText)));
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine(plainText);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Console.ReadLine();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 0, 1)"> }
}</span></pre>
</div>
<p>c. SM3工具类</p>
<p>【SM3Digest.cs】</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Utilities.Encoders;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Text;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Crypto;
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> Com.Mlq.SM
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">abstract</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> GeneralDigest : IDigest
{
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> BYTE_LENGTH = <span style="color: rgba(128, 0, 128, 1)">64</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] xBuf;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> xBufOff;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)"> byteCount;
</span><span style="color: rgba(0, 0, 255, 1)">internal</span><span style="color: rgba(0, 0, 0, 1)"> GeneralDigest()
{
xBuf </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
}
</span><span style="color: rgba(0, 0, 255, 1)">internal</span><span style="color: rgba(0, 0, 0, 1)"> GeneralDigest(GeneralDigest t)
{
xBuf </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">;
Array.Copy(t.xBuf, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, xBuf, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, t.xBuf.Length);
xBufOff </span>=<span style="color: rgba(0, 0, 0, 1)"> t.xBufOff;
byteCount </span>=<span style="color: rgba(0, 0, 0, 1)"> t.byteCount;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Update(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)"> input)
{
xBuf =<span style="color: rgba(0, 0, 0, 1)"> input;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (xBufOff ==<span style="color: rgba(0, 0, 0, 1)"> xBuf.Length)
{
ProcessWord(xBuf, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
xBufOff </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
}
byteCount</span>++<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> BlockUpdate(
</span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] input,
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> inOff,
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> length)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> fill the current word
</span><span style="color: rgba(0, 128, 0, 1)">//
</span> <span style="color: rgba(0, 0, 255, 1)">while</span> ((xBufOff != <span style="color: rgba(128, 0, 128, 1)">0</span>) && (length > <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">))
{
Update(input);
inOff</span>++<span style="color: rgba(0, 0, 0, 1)">;
length</span>--<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> process whole words.
</span><span style="color: rgba(0, 128, 0, 1)">//
</span> <span style="color: rgba(0, 0, 255, 1)">while</span> (length ><span style="color: rgba(0, 0, 0, 1)"> xBuf.Length)
{
ProcessWord(input, inOff);
inOff </span>+=<span style="color: rgba(0, 0, 0, 1)"> xBuf.Length;
length </span>-=<span style="color: rgba(0, 0, 0, 1)"> xBuf.Length;
byteCount </span>+=<span style="color: rgba(0, 0, 0, 1)"> xBuf.Length;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> load in the remainder.
</span><span style="color: rgba(0, 128, 0, 1)">//
</span> <span style="color: rgba(0, 0, 255, 1)">while</span> (length > <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
Update(input);
inOff</span>++<span style="color: rgba(0, 0, 0, 1)">;
length</span>--<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Finish()
{
</span><span style="color: rgba(0, 0, 255, 1)">long</span> bitLength = (byteCount << <span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> add the pad bytes.
</span><span style="color: rgba(0, 128, 0, 1)">//
</span> Update(<span style="color: rgba(0, 0, 255, 1)">unchecked</span>((<span style="color: rgba(0, 0, 255, 1)">byte</span>)<span style="color: rgba(128, 0, 128, 1)">128</span><span style="color: rgba(0, 0, 0, 1)">));
</span><span style="color: rgba(0, 0, 255, 1)">while</span> (xBufOff != <span style="color: rgba(128, 0, 128, 1)">0</span>) Update(<span style="color: rgba(0, 0, 255, 1)">unchecked</span>((<span style="color: rgba(0, 0, 255, 1)">byte</span>)<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">));
ProcessLength(bitLength);
ProcessBlock();
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Reset()
{
byteCount </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
xBufOff </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
Array.Clear(xBuf, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, xBuf.Length);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> GetByteLength()
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> BYTE_LENGTH;
}
</span><span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">abstract</span> <span style="color: rgba(0, 0, 255, 1)">void</span> ProcessWord(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] input, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> inOff);
</span><span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">abstract</span> <span style="color: rgba(0, 0, 255, 1)">void</span> ProcessLength(<span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)"> bitLength);
</span><span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">abstract</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> ProcessBlock();
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">abstract</span> <span style="color: rgba(0, 0, 255, 1)">string</span> AlgorithmName { <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">abstract</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> GetDigestSize();
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">abstract</span> <span style="color: rgba(0, 0, 255, 1)">int</span> DoFinal(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] output, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> outOff);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> SupportClass
{
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> Performs an unsigned bitwise right shift with the specified number
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="number"></span><span style="color: rgba(0, 128, 0, 1)">Number to operate on</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="bits"></span><span style="color: rgba(0, 128, 0, 1)">Ammount of bits to shift</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">The resulting number from the shift operation</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> URShift(<span style="color: rgba(0, 0, 255, 1)">int</span> number, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> bits)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (number >= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">return</span> number >><span style="color: rgba(0, 0, 0, 1)"> bits;
</span><span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> (number >> bits) + (<span style="color: rgba(128, 0, 128, 1)">2</span> << ~<span style="color: rgba(0, 0, 0, 1)">bits);
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> Performs an unsigned bitwise right shift with the specified number
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="number"></span><span style="color: rgba(0, 128, 0, 1)">Number to operate on</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="bits"></span><span style="color: rgba(0, 128, 0, 1)">Ammount of bits to shift</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">The resulting number from the shift operation</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> URShift(<span style="color: rgba(0, 0, 255, 1)">int</span> number, <span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)"> bits)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> URShift(number, (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)bits);
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> Performs an unsigned bitwise right shift with the specified number
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="number"></span><span style="color: rgba(0, 128, 0, 1)">Number to operate on</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="bits"></span><span style="color: rgba(0, 128, 0, 1)">Ammount of bits to shift</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">The resulting number from the shift operation</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">long</span> URShift(<span style="color: rgba(0, 0, 255, 1)">long</span> number, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> bits)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (number >= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">return</span> number >><span style="color: rgba(0, 0, 0, 1)"> bits;
</span><span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> (number >> bits) + (<span style="color: rgba(128, 0, 128, 1)">2L</span> << ~<span style="color: rgba(0, 0, 0, 1)">bits);
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> Performs an unsigned bitwise right shift with the specified number
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="number"></span><span style="color: rgba(0, 128, 0, 1)">Number to operate on</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="bits"></span><span style="color: rgba(0, 128, 0, 1)">Ammount of bits to shift</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">The resulting number from the shift operation</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">long</span> URShift(<span style="color: rgba(0, 0, 255, 1)">long</span> number, <span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)"> bits)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> URShift(number, (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)bits);
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> SM3Digest : GeneralDigest
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> AlgorithmName
{
</span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">SM3</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> GetDigestSize()
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> DIGEST_LENGTH;
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> DIGEST_LENGTH = <span style="color: rgba(128, 0, 128, 1)">32</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[] v0 = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[]{<span style="color: rgba(128, 0, 128, 1)">0x7380166f</span>, <span style="color: rgba(128, 0, 128, 1)">0x4914b2b9</span>, <span style="color: rgba(128, 0, 128, 1)">0x172442d7</span>, <span style="color: rgba(0, 0, 255, 1)">unchecked</span>((<span style="color: rgba(0, 0, 255, 1)">int</span>) <span style="color: rgba(128, 0, 128, 1)">0xda8a0600</span>), <span style="color: rgba(0, 0, 255, 1)">unchecked</span>((<span style="color: rgba(0, 0, 255, 1)">int</span>) <span style="color: rgba(128, 0, 128, 1)">0xa96f30bc</span>), <span style="color: rgba(128, 0, 128, 1)">0x163138aa</span>, <span style="color: rgba(0, 0, 255, 1)">unchecked</span>((<span style="color: rgba(0, 0, 255, 1)">int</span>) <span style="color: rgba(128, 0, 128, 1)">0xe38dee4d</span>), <span style="color: rgba(0, 0, 255, 1)">unchecked</span>((<span style="color: rgba(0, 0, 255, 1)">int</span>) <span style="color: rgba(128, 0, 128, 1)">0xb0fb0e4e</span><span style="color: rgba(0, 0, 0, 1)">)};
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[] v = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[<span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[] v_ = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[<span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[] X0 = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[]{<span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">};
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[] X = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[<span style="color: rgba(128, 0, 128, 1)">68</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> xOff;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> T_00_15 = <span style="color: rgba(128, 0, 128, 1)">0x79cc4519</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> T_16_63 = <span style="color: rgba(128, 0, 128, 1)">0x7a879d8a</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> SM3Digest()
{
Reset();
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> SM3Digest(SM3Digest t):<span style="color: rgba(0, 0, 255, 1)">base</span><span style="color: rgba(0, 0, 0, 1)">(t)
{
Array.Copy(t.X, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, X, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, t.X.Length);
xOff </span>=<span style="color: rgba(0, 0, 0, 1)"> t.xOff;
Array.Copy(t.v, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, v, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, t.v.Length);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">Reset()
{
</span><span style="color: rgba(0, 0, 255, 1)">base</span><span style="color: rgba(0, 0, 0, 1)">.Reset();
Array.Copy(v0, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, v, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, v0.Length);
xOff </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
Array.Copy(X0, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, X, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, X0.Length);
}
</span><span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> ProcessBlock()
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> i;
</span><span style="color: rgba(0, 0, 255, 1)">int</span>[] ww =<span style="color: rgba(0, 0, 0, 1)"> X;
</span><span style="color: rgba(0, 0, 255, 1)">int</span>[] ww_ = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">int</span>[<span style="color: rgba(128, 0, 128, 1)">64</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = <span style="color: rgba(128, 0, 128, 1)">16</span>; i < <span style="color: rgba(128, 0, 128, 1)">68</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
ww </span>= P1(ww ^ ww ^ (ROTATE(ww, <span style="color: rgba(128, 0, 128, 1)">15</span>))) ^ (ROTATE(ww, <span style="color: rgba(128, 0, 128, 1)">7</span>)) ^ ww;
}
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < <span style="color: rgba(128, 0, 128, 1)">64</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
ww_ </span>= ww ^ ww;
}
</span><span style="color: rgba(0, 0, 255, 1)">int</span>[] vv =<span style="color: rgba(0, 0, 0, 1)"> v;
</span><span style="color: rgba(0, 0, 255, 1)">int</span>[] vv_ =<span style="color: rgba(0, 0, 0, 1)"> v_;
Array.Copy(vv, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, vv_, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, v0.Length);
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> SS1, SS2, TT1, TT2, aaa;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < <span style="color: rgba(128, 0, 128, 1)">16</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
aaa </span>= ROTATE(vv_[<span style="color: rgba(128, 0, 128, 1)">0</span>], <span style="color: rgba(128, 0, 128, 1)">12</span><span style="color: rgba(0, 0, 0, 1)">);
SS1 </span>= aaa + vv_[<span style="color: rgba(128, 0, 128, 1)">4</span>] +<span style="color: rgba(0, 0, 0, 1)"> ROTATE(T_00_15, i);
SS1 </span>= ROTATE(SS1, <span style="color: rgba(128, 0, 128, 1)">7</span><span style="color: rgba(0, 0, 0, 1)">);
SS2 </span>= SS1 ^<span style="color: rgba(0, 0, 0, 1)"> aaa;
TT1 </span>= FF_00_15(vv_[<span style="color: rgba(128, 0, 128, 1)">0</span>], vv_[<span style="color: rgba(128, 0, 128, 1)">1</span>], vv_[<span style="color: rgba(128, 0, 128, 1)">2</span>]) + vv_[<span style="color: rgba(128, 0, 128, 1)">3</span>] + SS2 +<span style="color: rgba(0, 0, 0, 1)"> ww_;
TT2 </span>= GG_00_15(vv_[<span style="color: rgba(128, 0, 128, 1)">4</span>], vv_[<span style="color: rgba(128, 0, 128, 1)">5</span>], vv_[<span style="color: rgba(128, 0, 128, 1)">6</span>]) + vv_[<span style="color: rgba(128, 0, 128, 1)">7</span>] + SS1 +<span style="color: rgba(0, 0, 0, 1)"> ww;
vv_[</span><span style="color: rgba(128, 0, 128, 1)">3</span>] = vv_[<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">];
vv_[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = ROTATE(vv_[<span style="color: rgba(128, 0, 128, 1)">1</span>], <span style="color: rgba(128, 0, 128, 1)">9</span><span style="color: rgba(0, 0, 0, 1)">);
vv_[</span><span style="color: rgba(128, 0, 128, 1)">1</span>] = vv_[<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">];
vv_[</span><span style="color: rgba(128, 0, 128, 1)">0</span>] =<span style="color: rgba(0, 0, 0, 1)"> TT1;
vv_[</span><span style="color: rgba(128, 0, 128, 1)">7</span>] = vv_[<span style="color: rgba(128, 0, 128, 1)">6</span><span style="color: rgba(0, 0, 0, 1)">];
vv_[</span><span style="color: rgba(128, 0, 128, 1)">6</span>] = ROTATE(vv_[<span style="color: rgba(128, 0, 128, 1)">5</span>], <span style="color: rgba(128, 0, 128, 1)">19</span><span style="color: rgba(0, 0, 0, 1)">);
vv_[</span><span style="color: rgba(128, 0, 128, 1)">5</span>] = vv_[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
vv_[</span><span style="color: rgba(128, 0, 128, 1)">4</span>] =<span style="color: rgba(0, 0, 0, 1)"> P0(TT2);
}
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = <span style="color: rgba(128, 0, 128, 1)">16</span>; i < <span style="color: rgba(128, 0, 128, 1)">64</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
aaa </span>= ROTATE(vv_[<span style="color: rgba(128, 0, 128, 1)">0</span>], <span style="color: rgba(128, 0, 128, 1)">12</span><span style="color: rgba(0, 0, 0, 1)">);
SS1 </span>= aaa + vv_[<span style="color: rgba(128, 0, 128, 1)">4</span>] +<span style="color: rgba(0, 0, 0, 1)"> ROTATE(T_16_63, i);
SS1 </span>= ROTATE(SS1, <span style="color: rgba(128, 0, 128, 1)">7</span><span style="color: rgba(0, 0, 0, 1)">);
SS2 </span>= SS1 ^<span style="color: rgba(0, 0, 0, 1)"> aaa;
TT1 </span>= FF_16_63(vv_[<span style="color: rgba(128, 0, 128, 1)">0</span>], vv_[<span style="color: rgba(128, 0, 128, 1)">1</span>], vv_[<span style="color: rgba(128, 0, 128, 1)">2</span>]) + vv_[<span style="color: rgba(128, 0, 128, 1)">3</span>] + SS2 +<span style="color: rgba(0, 0, 0, 1)"> ww_;
TT2 </span>= GG_16_63(vv_[<span style="color: rgba(128, 0, 128, 1)">4</span>], vv_[<span style="color: rgba(128, 0, 128, 1)">5</span>], vv_[<span style="color: rgba(128, 0, 128, 1)">6</span>]) + vv_[<span style="color: rgba(128, 0, 128, 1)">7</span>] + SS1 +<span style="color: rgba(0, 0, 0, 1)"> ww;
vv_[</span><span style="color: rgba(128, 0, 128, 1)">3</span>] = vv_[<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">];
vv_[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = ROTATE(vv_[<span style="color: rgba(128, 0, 128, 1)">1</span>], <span style="color: rgba(128, 0, 128, 1)">9</span><span style="color: rgba(0, 0, 0, 1)">);
vv_[</span><span style="color: rgba(128, 0, 128, 1)">1</span>] = vv_[<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">];
vv_[</span><span style="color: rgba(128, 0, 128, 1)">0</span>] =<span style="color: rgba(0, 0, 0, 1)"> TT1;
vv_[</span><span style="color: rgba(128, 0, 128, 1)">7</span>] = vv_[<span style="color: rgba(128, 0, 128, 1)">6</span><span style="color: rgba(0, 0, 0, 1)">];
vv_[</span><span style="color: rgba(128, 0, 128, 1)">6</span>] = ROTATE(vv_[<span style="color: rgba(128, 0, 128, 1)">5</span>], <span style="color: rgba(128, 0, 128, 1)">19</span><span style="color: rgba(0, 0, 0, 1)">);
vv_[</span><span style="color: rgba(128, 0, 128, 1)">5</span>] = vv_[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
vv_[</span><span style="color: rgba(128, 0, 128, 1)">4</span>] =<span style="color: rgba(0, 0, 0, 1)"> P0(TT2);
}
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < <span style="color: rgba(128, 0, 128, 1)">8</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
vv </span>^=<span style="color: rgba(0, 0, 0, 1)"> vv_;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Reset</span>
xOff = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
Array.Copy(X0, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, X, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, X0.Length);
}
</span><span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span>ProcessWord(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] in_Renamed, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> inOff)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> n = in_Renamed << <span style="color: rgba(128, 0, 128, 1)">24</span><span style="color: rgba(0, 0, 0, 1)">;
n </span>|= (in_Renamed[++inOff] & <span style="color: rgba(128, 0, 128, 1)">0xff</span>) << <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">;
n </span>|= (in_Renamed[++inOff] & <span style="color: rgba(128, 0, 128, 1)">0xff</span>) << <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">;
n </span>|= (in_Renamed[++inOff] & <span style="color: rgba(128, 0, 128, 1)">0xff</span><span style="color: rgba(0, 0, 0, 1)">);
X </span>=<span style="color: rgba(0, 0, 0, 1)"> n;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (++xOff == <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">)
{
ProcessBlock();
}
}
</span><span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span> ProcessLength(<span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)"> bitLength)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (xOff > <span style="color: rgba(128, 0, 128, 1)">14</span><span style="color: rgba(0, 0, 0, 1)">)
{
ProcessBlock();
}
X[</span><span style="color: rgba(128, 0, 128, 1)">14</span>] = (<span style="color: rgba(0, 0, 255, 1)">int</span>) (SupportClass.URShift(bitLength, <span style="color: rgba(128, 0, 128, 1)">32</span><span style="color: rgba(0, 0, 0, 1)">));
X[</span><span style="color: rgba(128, 0, 128, 1)">15</span>] = (<span style="color: rgba(0, 0, 255, 1)">int</span>) (bitLength & <span style="color: rgba(0, 0, 255, 1)">unchecked</span>((<span style="color: rgba(0, 0, 255, 1)">int</span>) <span style="color: rgba(128, 0, 128, 1)">0xffffffff</span><span style="color: rgba(0, 0, 0, 1)">));
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span>IntToBigEndian(<span style="color: rgba(0, 0, 255, 1)">int</span> n, <span style="color: rgba(0, 0, 255, 1)">byte</span>[] bs, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> off)
{
bs </span>= (<span style="color: rgba(0, 0, 255, 1)">byte</span>) (SupportClass.URShift(n, <span style="color: rgba(128, 0, 128, 1)">24</span><span style="color: rgba(0, 0, 0, 1)">));
bs[</span>++off] = (<span style="color: rgba(0, 0, 255, 1)">byte</span>) (SupportClass.URShift(n, <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">));
bs[</span>++off] = (<span style="color: rgba(0, 0, 255, 1)">byte</span>) (SupportClass.URShift(n, <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">));
bs[</span>++off] = (<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">) (n);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">int</span> DoFinal(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] out_Renamed, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> outOff)
{
Finish();
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < <span style="color: rgba(128, 0, 128, 1)">8</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
IntToBigEndian(v, out_Renamed, outOff </span>+ i * <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">);
}
Reset();
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> DIGEST_LENGTH;
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> ROTATE(<span style="color: rgba(0, 0, 255, 1)">int</span> x, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> n)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> (x << n) | (SupportClass.URShift(x, (<span style="color: rgba(128, 0, 128, 1)">32</span> -<span style="color: rgba(0, 0, 0, 1)"> n)));
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> P0(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> X)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> ((X) ^ ROTATE((X), <span style="color: rgba(128, 0, 128, 1)">9</span>) ^ ROTATE((X), <span style="color: rgba(128, 0, 128, 1)">17</span><span style="color: rgba(0, 0, 0, 1)">));
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> P1(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> X)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> ((X) ^ ROTATE((X), <span style="color: rgba(128, 0, 128, 1)">15</span>) ^ ROTATE((X), <span style="color: rgba(128, 0, 128, 1)">23</span><span style="color: rgba(0, 0, 0, 1)">));
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> FF_00_15(<span style="color: rgba(0, 0, 255, 1)">int</span> X, <span style="color: rgba(0, 0, 255, 1)">int</span> Y, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> Z)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> (X ^ Y ^<span style="color: rgba(0, 0, 0, 1)"> Z);
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> FF_16_63(<span style="color: rgba(0, 0, 255, 1)">int</span> X, <span style="color: rgba(0, 0, 255, 1)">int</span> Y, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> Z)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> ((X & Y) | (X & Z) | (Y &<span style="color: rgba(0, 0, 0, 1)"> Z));
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> GG_00_15(<span style="color: rgba(0, 0, 255, 1)">int</span> X, <span style="color: rgba(0, 0, 255, 1)">int</span> Y, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> Z)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> (X ^ Y ^<span style="color: rgba(0, 0, 0, 1)"> Z);
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> GG_16_63(<span style="color: rgba(0, 0, 255, 1)">int</span> X, <span style="color: rgba(0, 0, 255, 1)">int</span> Y, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> Z)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> ((X & Y) | (~ X &<span style="color: rgba(0, 0, 0, 1)"> Z));
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">public static voidMain()
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> byte[] md = new byte;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> byte[] msg1 = Encoding.Default.GetBytes("ererfeiisgod");
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> SM3Digest sm3 = new SM3Digest();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> sm3.BlockUpdate(msg1, 0, msg1.Length);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> sm3.DoFinal(md, 0);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.String s = new UTF8Encoding().GetString(Hex.Encode(md));
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine(s.ToUpper());
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Console.ReadLine();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 0, 1)"> }
}</span></pre>
</div>
<h1>2.SM4</h1>
<p>直接上代码:</p>
<p>a. SM4主类</p>
<p>【SM4.cs】</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Collections.Generic;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.IO;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Linq;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Text;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Threading.Tasks;
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> Com.Mlq.SM
{
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> SM4
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> SM4_ENCRYPT = <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> SM4_DECRYPT = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">long</span> GET_ULONG_BE(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] b, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> i)
{
</span><span style="color: rgba(0, 0, 255, 1)">long</span> n = (<span style="color: rgba(0, 0, 255, 1)">long</span>)(b & <span style="color: rgba(128, 0, 128, 1)">0xff</span>) << <span style="color: rgba(128, 0, 128, 1)">24</span> | (<span style="color: rgba(0, 0, 255, 1)">long</span>)((b & <span style="color: rgba(128, 0, 128, 1)">0xff</span>) << <span style="color: rgba(128, 0, 128, 1)">16</span>) | (<span style="color: rgba(0, 0, 255, 1)">long</span>)((b & <span style="color: rgba(128, 0, 128, 1)">0xff</span>) << <span style="color: rgba(128, 0, 128, 1)">8</span>) | (<span style="color: rgba(0, 0, 255, 1)">long</span>)(b & <span style="color: rgba(128, 0, 128, 1)">0xff</span>) & <span style="color: rgba(128, 0, 128, 1)">0xffffffffL</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> n;
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> PUT_ULONG_BE(<span style="color: rgba(0, 0, 255, 1)">long</span> n, <span style="color: rgba(0, 0, 255, 1)">byte</span>[] b, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> i)
{
b </span>= (<span style="color: rgba(0, 0, 255, 1)">byte</span>)(<span style="color: rgba(0, 0, 255, 1)">int</span>)(<span style="color: rgba(128, 0, 128, 1)">0xFF</span> & n >> <span style="color: rgba(128, 0, 128, 1)">24</span><span style="color: rgba(0, 0, 0, 1)">);
b = (<span style="color: rgba(0, 0, 255, 1)">byte</span>)(<span style="color: rgba(0, 0, 255, 1)">int</span>)(<span style="color: rgba(128, 0, 128, 1)">0xFF</span> & n >> <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
b = (<span style="color: rgba(0, 0, 255, 1)">byte</span>)(<span style="color: rgba(0, 0, 255, 1)">int</span>)(<span style="color: rgba(128, 0, 128, 1)">0xFF</span> & n >> <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">);
b = (<span style="color: rgba(0, 0, 255, 1)">byte</span>)(<span style="color: rgba(0, 0, 255, 1)">int</span>)(<span style="color: rgba(128, 0, 128, 1)">0xFF</span> &<span style="color: rgba(0, 0, 0, 1)"> n);
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">long</span> SHL(<span style="color: rgba(0, 0, 255, 1)">long</span> x, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> n)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> (x & <span style="color: rgba(128, 0, 128, 1)">0xFFFFFFFF</span>) <<<span style="color: rgba(0, 0, 0, 1)"> n;
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">long</span> ROTL(<span style="color: rgba(0, 0, 255, 1)">long</span> x, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> n)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> SHL(x, n) | x >> (<span style="color: rgba(128, 0, 128, 1)">32</span> -<span style="color: rgba(0, 0, 0, 1)"> n);
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SWAP(<span style="color: rgba(0, 0, 255, 1)">long</span>[] sk, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> i)
{
</span><span style="color: rgba(0, 0, 255, 1)">long</span> t =<span style="color: rgba(0, 0, 0, 1)"> sk;
sk </span>= sk[(<span style="color: rgba(128, 0, 128, 1)">31</span> -<span style="color: rgba(0, 0, 0, 1)"> i)];
sk[(</span><span style="color: rgba(128, 0, 128, 1)">31</span> - i)] =<span style="color: rgba(0, 0, 0, 1)"> t;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] SboxTable = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] { (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xd6</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x90</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xe9</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xfe</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xcc</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xe1</span>, <span style="color: rgba(128, 0, 128, 1)">0x3d</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xb7</span>, <span style="color: rgba(128, 0, 128, 1)">0x16</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xb6</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x14</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xc2</span>, <span style="color: rgba(128, 0, 128, 1)">0x28</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xfb</span>, <span style="color: rgba(128, 0, 128, 1)">0x2c</span>, <span style="color: rgba(128, 0, 128, 1)">0x05</span>, <span style="color: rgba(128, 0, 128, 1)">0x2b</span>, <span style="color: rgba(128, 0, 128, 1)">0x67</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x9a</span>, <span style="color: rgba(128, 0, 128, 1)">0x76</span>, <span style="color: rgba(128, 0, 128, 1)">0x2a</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xbe</span>, <span style="color: rgba(128, 0, 128, 1)">0x04</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xc3</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xaa</span>, <span style="color: rgba(128, 0, 128, 1)">0x44</span>, <span style="color: rgba(128, 0, 128, 1)">0x13</span>, <span style="color: rgba(128, 0, 128, 1)">0x26</span>, <span style="color: rgba(128, 0, 128, 1)">0x49</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x86</span>, <span style="color: rgba(128, 0, 128, 1)">0x06</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x99</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x9c</span>, <span style="color: rgba(128, 0, 128, 1)">0x42</span>, <span style="color: rgba(128, 0, 128, 1)">0x50</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xf4</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x91</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xef</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x98</span>, <span style="color: rgba(128, 0, 128, 1)">0x7a</span>, <span style="color: rgba(128, 0, 128, 1)">0x33</span>, <span style="color: rgba(128, 0, 128, 1)">0x54</span>, <span style="color: rgba(128, 0, 128, 1)">0x0b</span>, <span style="color: rgba(128, 0, 128, 1)">0x43</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xed</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xcf</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xac</span>, <span style="color: rgba(128, 0, 128, 1)">0x62</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xe4</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xb3</span>, <span style="color: rgba(128, 0, 128, 1)">0x1c</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xa9</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xc9</span>, <span style="color: rgba(128, 0, 128, 1)">0x08</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xe8</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x95</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x80</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xdf</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x94</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xfa</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x75</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x8f</span>, <span style="color: rgba(128, 0, 128, 1)">0x3f</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xa6</span>, <span style="color: rgba(128, 0, 128, 1)">0x47</span>, <span style="color: rgba(128, 0, 128, 1)">0x07</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xa7</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xfc</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xf3</span>, <span style="color: rgba(128, 0, 128, 1)">0x73</span>, <span style="color: rgba(128, 0, 128, 1)">0x17</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xba</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x83</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x59</span>, <span style="color: rgba(128, 0, 128, 1)">0x3c</span>, <span style="color: rgba(128, 0, 128, 1)">0x19</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xe6</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x85</span>, <span style="color: rgba(128, 0, 128, 1)">0x4f</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xa8</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x68</span>, <span style="color: rgba(128, 0, 128, 1)">0x6b</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x81</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xb2</span>, <span style="color: rgba(128, 0, 128, 1)">0x71</span>, <span style="color: rgba(128, 0, 128, 1)">0x64</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xda</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x8b</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xf8</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xeb</span>, <span style="color: rgba(128, 0, 128, 1)">0x0f</span>, <span style="color: rgba(128, 0, 128, 1)">0x4b</span>, <span style="color: rgba(128, 0, 128, 1)">0x70</span>, <span style="color: rgba(128, 0, 128, 1)">0x56</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x9d</span>, <span style="color: rgba(128, 0, 128, 1)">0x35</span>, <span style="color: rgba(128, 0, 128, 1)">0x1e</span>, <span style="color: rgba(128, 0, 128, 1)">0x24</span>, <span style="color: rgba(128, 0, 128, 1)">0x0e</span>, <span style="color: rgba(128, 0, 128, 1)">0x5e</span>, <span style="color: rgba(128, 0, 128, 1)">0x63</span>, <span style="color: rgba(128, 0, 128, 1)">0x58</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xd1</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xa2</span>, <span style="color: rgba(128, 0, 128, 1)">0x25</span>, <span style="color: rgba(128, 0, 128, 1)">0x22</span>, <span style="color: rgba(128, 0, 128, 1)">0x7c</span>, <span style="color: rgba(128, 0, 128, 1)">0x3b</span>, <span style="color: rgba(128, 0, 128, 1)">0x01</span>, <span style="color: rgba(128, 0, 128, 1)">0x21</span>, <span style="color: rgba(128, 0, 128, 1)">0x78</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x87</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xd4</span>, <span style="color: rgba(128, 0, 128, 1)">0x00</span>, <span style="color: rgba(128, 0, 128, 1)">0x46</span>, <span style="color: rgba(128, 0, 128, 1)">0x57</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x9f</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xd3</span>, <span style="color: rgba(128, 0, 128, 1)">0x27</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x52</span>, <span style="color: rgba(128, 0, 128, 1)">0x4c</span>, <span style="color: rgba(128, 0, 128, 1)">0x36</span>, <span style="color: rgba(128, 0, 128, 1)">0x02</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xe7</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xa0</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xc4</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xc8</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x9e</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xea</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xbf</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x8a</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xd2</span>, <span style="color: rgba(128, 0, 128, 1)">0x40</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xc7</span>, <span style="color: rgba(128, 0, 128, 1)">0x38</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xb5</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xa3</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xf7</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xf2</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xce</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xf9</span>, <span style="color: rgba(128, 0, 128, 1)">0x61</span>, <span style="color: rgba(128, 0, 128, 1)">0x15</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xa1</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xe0</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xae</span>, <span style="color: rgba(128, 0, 128, 1)">0x5d</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xa4</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x9b</span>, <span style="color: rgba(128, 0, 128, 1)">0x34</span>, <span style="color: rgba(128, 0, 128, 1)">0x1a</span>, <span style="color: rgba(128, 0, 128, 1)">0x55</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xad</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x93</span>, <span style="color: rgba(128, 0, 128, 1)">0x32</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x30</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xf5</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x8c</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xb1</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xe3</span>, <span style="color: rgba(128, 0, 128, 1)">0x1d</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xf6</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xe2</span>, <span style="color: rgba(128, 0, 128, 1)">0x2e</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x82</span>, <span style="color: rgba(128, 0, 128, 1)">0x66</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xca</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x60</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xc0</span>, <span style="color: rgba(128, 0, 128, 1)">0x29</span>, <span style="color: rgba(128, 0, 128, 1)">0x23</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xab</span>, <span style="color: rgba(128, 0, 128, 1)">0x0d</span>, <span style="color: rgba(128, 0, 128, 1)">0x53</span>, <span style="color: rgba(128, 0, 128, 1)">0x4e</span>, <span style="color: rgba(128, 0, 128, 1)">0x6f</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xd5</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xdb</span>, <span style="color: rgba(128, 0, 128, 1)">0x37</span>, <span style="color: rgba(128, 0, 128, 1)">0x45</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xde</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xfd</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x8e</span>, <span style="color: rgba(128, 0, 128, 1)">0x2f</span>, <span style="color: rgba(128, 0, 128, 1)">0x03</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xff</span>, <span style="color: rgba(128, 0, 128, 1)">0x6a</span>, <span style="color: rgba(128, 0, 128, 1)">0x72</span>, <span style="color: rgba(128, 0, 128, 1)">0x6d</span>, <span style="color: rgba(128, 0, 128, 1)">0x6c</span>, <span style="color: rgba(128, 0, 128, 1)">0x5b</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x51</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x8d</span>, <span style="color: rgba(128, 0, 128, 1)">0x1b</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xaf</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x92</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xbb</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xdd</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xbc</span>, <span style="color: rgba(128, 0, 128, 1)">0x7f</span>, <span style="color: rgba(128, 0, 128, 1)">0x11</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xd9</span>, <span style="color: rgba(128, 0, 128, 1)">0x5c</span>, <span style="color: rgba(128, 0, 128, 1)">0x41</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x1f</span>, <span style="color: rgba(128, 0, 128, 1)">0x10</span>, <span style="color: rgba(128, 0, 128, 1)">0x5a</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xd8</span>, <span style="color: rgba(128, 0, 128, 1)">0x0a</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xc1</span>, <span style="color: rgba(128, 0, 128, 1)">0x31</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x88</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xa5</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xcd</span>, <span style="color: rgba(128, 0, 128, 1)">0x7b</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xbd</span>, <span style="color: rgba(128, 0, 128, 1)">0x2d</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x74</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xd0</span>, <span style="color: rgba(128, 0, 128, 1)">0x12</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xb8</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xe5</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xb4</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xb0</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x89</span>, <span style="color: rgba(128, 0, 128, 1)">0x69</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x97</span>, <span style="color: rgba(128, 0, 128, 1)">0x4a</span>, <span style="color: rgba(128, 0, 128, 1)">0x0c</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x96</span>, <span style="color: rgba(128, 0, 128, 1)">0x77</span>, <span style="color: rgba(128, 0, 128, 1)">0x7e</span>, <span style="color: rgba(128, 0, 128, 1)">0x65</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xb9</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xf1</span>, <span style="color: rgba(128, 0, 128, 1)">0x09</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xc5</span>, <span style="color: rgba(128, 0, 128, 1)">0x6e</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xc6</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0x84</span>, <span style="color: rgba(128, 0, 128, 1)">0x18</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xf0</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x7d</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xec</span>, <span style="color: rgba(128, 0, 128, 1)">0x3a</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xdc</span>, <span style="color: rgba(128, 0, 128, 1)">0x4d</span>, <span style="color: rgba(128, 0, 128, 1)">0x20</span>, <span style="color: rgba(128, 0, 128, 1)">0x79</span><span style="color: rgba(0, 0, 0, 1)">,
(</span><span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xee</span>, <span style="color: rgba(128, 0, 128, 1)">0x5f</span>, <span style="color: rgba(128, 0, 128, 1)">0x3e</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xd7</span>, (<span style="color: rgba(0, 0, 255, 1)">byte</span>) <span style="color: rgba(128, 0, 128, 1)">0xcb</span>, <span style="color: rgba(128, 0, 128, 1)">0x39</span>, <span style="color: rgba(128, 0, 128, 1)">0x48</span><span style="color: rgba(0, 0, 0, 1)"> };
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">uint</span>[] FK = { <span style="color: rgba(128, 0, 128, 1)">0xa3b1bac6</span>, <span style="color: rgba(128, 0, 128, 1)">0x56aa3350</span>, <span style="color: rgba(128, 0, 128, 1)">0x677d9197</span>, <span style="color: rgba(128, 0, 128, 1)">0xb27022dc</span><span style="color: rgba(0, 0, 0, 1)"> };
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">uint</span>[] CK = { <span style="color: rgba(128, 0, 128, 1)">0x00070e15</span>,<span style="color: rgba(128, 0, 128, 1)">0x1c232a31</span>,<span style="color: rgba(128, 0, 128, 1)">0x383f464d</span>,<span style="color: rgba(128, 0, 128, 1)">0x545b6269</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x70777e85</span>,<span style="color: rgba(128, 0, 128, 1)">0x8c939aa1</span>,<span style="color: rgba(128, 0, 128, 1)">0xa8afb6bd</span>,<span style="color: rgba(128, 0, 128, 1)">0xc4cbd2d9</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0xe0e7eef5</span>,<span style="color: rgba(128, 0, 128, 1)">0xfc030a11</span>,<span style="color: rgba(128, 0, 128, 1)">0x181f262d</span>,<span style="color: rgba(128, 0, 128, 1)">0x343b4249</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x50575e65</span>,<span style="color: rgba(128, 0, 128, 1)">0x6c737a81</span>,<span style="color: rgba(128, 0, 128, 1)">0x888f969d</span>,<span style="color: rgba(128, 0, 128, 1)">0xa4abb2b9</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0xc0c7ced5</span>,<span style="color: rgba(128, 0, 128, 1)">0xdce3eaf1</span>,<span style="color: rgba(128, 0, 128, 1)">0xf8ff060d</span>,<span style="color: rgba(128, 0, 128, 1)">0x141b2229</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x30373e45</span>,<span style="color: rgba(128, 0, 128, 1)">0x4c535a61</span>,<span style="color: rgba(128, 0, 128, 1)">0x686f767d</span>,<span style="color: rgba(128, 0, 128, 1)">0x848b9299</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0xa0a7aeb5</span>,<span style="color: rgba(128, 0, 128, 1)">0xbcc3cad1</span>,<span style="color: rgba(128, 0, 128, 1)">0xd8dfe6ed</span>,<span style="color: rgba(128, 0, 128, 1)">0xf4fb0209</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x10171e25</span>,<span style="color: rgba(128, 0, 128, 1)">0x2c333a41</span>,<span style="color: rgba(128, 0, 128, 1)">0x484f565d</span>,<span style="color: rgba(128, 0, 128, 1)">0x646b7279</span><span style="color: rgba(0, 0, 0, 1)"> };
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">byte</span> sm4Sbox(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)"> inch)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> i = inch & <span style="color: rgba(128, 0, 128, 1)">0xFF</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span> retVal =<span style="color: rgba(0, 0, 0, 1)"> SboxTable;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> retVal;
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">long</span> sm4Lt(<span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)"> ka)
{
</span><span style="color: rgba(0, 0, 255, 1)">long</span> bb = <span style="color: rgba(128, 0, 128, 1)">0L</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">long</span> c = <span style="color: rgba(128, 0, 128, 1)">0L</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] a = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] b = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
PUT_ULONG_BE(ka, a, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
b[</span><span style="color: rgba(128, 0, 128, 1)">0</span>] = sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">]);
b[</span><span style="color: rgba(128, 0, 128, 1)">1</span>] = sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">]);
b[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">]);
b[</span><span style="color: rgba(128, 0, 128, 1)">3</span>] = sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">]);
bb </span>= GET_ULONG_BE(b, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
c </span>= bb ^ ROTL(bb, <span style="color: rgba(128, 0, 128, 1)">2</span>) ^ ROTL(bb, <span style="color: rgba(128, 0, 128, 1)">10</span>) ^ ROTL(bb, <span style="color: rgba(128, 0, 128, 1)">18</span>) ^ ROTL(bb, <span style="color: rgba(128, 0, 128, 1)">24</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> c;
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">long</span> sm4F(<span style="color: rgba(0, 0, 255, 1)">long</span> x0, <span style="color: rgba(0, 0, 255, 1)">long</span> x1, <span style="color: rgba(0, 0, 255, 1)">long</span> x2, <span style="color: rgba(0, 0, 255, 1)">long</span> x3, <span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)"> rk)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^<span style="color: rgba(0, 0, 0, 1)"> rk);
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">long</span> sm4CalciRK(<span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)"> ka)
{
</span><span style="color: rgba(0, 0, 255, 1)">long</span> bb = <span style="color: rgba(128, 0, 128, 1)">0L</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">long</span> rk = <span style="color: rgba(128, 0, 128, 1)">0L</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] a = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] b = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
PUT_ULONG_BE(ka, a, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
b[</span><span style="color: rgba(128, 0, 128, 1)">0</span>] = sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">]);
b[</span><span style="color: rgba(128, 0, 128, 1)">1</span>] = sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">]);
b[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">]);
b[</span><span style="color: rgba(128, 0, 128, 1)">3</span>] = sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">]);
bb </span>= GET_ULONG_BE(b, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
rk </span>= bb ^ ROTL(bb, <span style="color: rgba(128, 0, 128, 1)">13</span>) ^ ROTL(bb, <span style="color: rgba(128, 0, 128, 1)">23</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> rk;
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> sm4_setkey(<span style="color: rgba(0, 0, 255, 1)">long</span>[] SK, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] key)
{
</span><span style="color: rgba(0, 0, 255, 1)">long</span>[] MK = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">long</span>[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">long</span>[] k = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">long</span>[<span style="color: rgba(128, 0, 128, 1)">36</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
MK[</span><span style="color: rgba(128, 0, 128, 1)">0</span>] = GET_ULONG_BE(key, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
MK[</span><span style="color: rgba(128, 0, 128, 1)">1</span>] = GET_ULONG_BE(key, <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">);
MK[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = GET_ULONG_BE(key, <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">);
MK[</span><span style="color: rgba(128, 0, 128, 1)">3</span>] = GET_ULONG_BE(key, <span style="color: rgba(128, 0, 128, 1)">12</span><span style="color: rgba(0, 0, 0, 1)">);
k[</span><span style="color: rgba(128, 0, 128, 1)">0</span>] = MK[<span style="color: rgba(128, 0, 128, 1)">0</span>] ^ (<span style="color: rgba(0, 0, 255, 1)">long</span>) FK[<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">];
k[</span><span style="color: rgba(128, 0, 128, 1)">1</span>] = MK[<span style="color: rgba(128, 0, 128, 1)">1</span>] ^ (<span style="color: rgba(0, 0, 255, 1)">long</span>) FK[<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">];
k[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = MK[<span style="color: rgba(128, 0, 128, 1)">2</span>] ^ (<span style="color: rgba(0, 0, 255, 1)">long</span>) FK[<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">];
k[</span><span style="color: rgba(128, 0, 128, 1)">3</span>] = MK[<span style="color: rgba(128, 0, 128, 1)">3</span>] ^ (<span style="color: rgba(0, 0, 255, 1)">long</span>) FK[<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (; i < <span style="color: rgba(128, 0, 128, 1)">32</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
k[(i </span>+ <span style="color: rgba(128, 0, 128, 1)">4</span>)] = (k ^ sm4CalciRK(k[(i + <span style="color: rgba(128, 0, 128, 1)">1</span>)] ^ k[(i + <span style="color: rgba(128, 0, 128, 1)">2</span>)] ^ k[(i + <span style="color: rgba(128, 0, 128, 1)">3</span>)] ^ (<span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)">) CK));
SK </span>= k[(i + <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">)];
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> sm4_one_round(<span style="color: rgba(0, 0, 255, 1)">long</span>[] sk, <span style="color: rgba(0, 0, 255, 1)">byte</span>[] input, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] output)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">long</span>[] ulbuf = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">long</span>[<span style="color: rgba(128, 0, 128, 1)">36</span><span style="color: rgba(0, 0, 0, 1)">];
ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">0</span>] = GET_ULONG_BE(input, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">1</span>] = GET_ULONG_BE(input, <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">);
ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = GET_ULONG_BE(input, <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">);
ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">3</span>] = GET_ULONG_BE(input, <span style="color: rgba(128, 0, 128, 1)">12</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">while</span> (i < <span style="color: rgba(128, 0, 128, 1)">32</span><span style="color: rgba(0, 0, 0, 1)">)
{
ulbuf[(i </span>+ <span style="color: rgba(128, 0, 128, 1)">4</span>)] = sm4F(ulbuf, ulbuf[(i + <span style="color: rgba(128, 0, 128, 1)">1</span>)], ulbuf[(i + <span style="color: rgba(128, 0, 128, 1)">2</span>)], ulbuf[(i + <span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">)], sk);
i</span>++<span style="color: rgba(0, 0, 0, 1)">;
}
PUT_ULONG_BE(ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">35</span>], output, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
PUT_ULONG_BE(ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">34</span>], output, <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">);
PUT_ULONG_BE(ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">33</span>], output, <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">);
PUT_ULONG_BE(ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">32</span>], output, <span style="color: rgba(128, 0, 128, 1)">12</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] padding(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] input, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> mode)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (input == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] ret = (<span style="color: rgba(0, 0, 255, 1)">byte</span>[]) <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (mode ==<span style="color: rgba(0, 0, 0, 1)"> SM4_ENCRYPT)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> p = <span style="color: rgba(128, 0, 128, 1)">16</span> - input.Length % <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">;
ret </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>;
Array.Copy(input, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, ret, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, input.Length);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < p; i++<span style="color: rgba(0, 0, 0, 1)">)
{
ret = (<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">) p;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> p = input;
ret </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>;
Array.Copy(input, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, ret, <span style="color: rgba(128, 0, 128, 1)">0</span>, input.Length -<span style="color: rgba(0, 0, 0, 1)"> p);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> ret;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> sm4_setkey_enc(SM4_Context ctx, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] key)
{
ctx.mode </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4_ENCRYPT;
sm4_setkey(ctx.sk, key);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> sm4_setkey_dec(SM4_Context ctx, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] key)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
ctx.mode </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4_DECRYPT;
sm4_setkey(ctx.sk, key);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < <span style="color: rgba(128, 0, 128, 1)">16</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
SWAP(ctx.sk, i);
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] sm4_crypt_ecb(SM4_Context ctx, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] input)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> ((ctx.isPadding) && (ctx.mode ==<span style="color: rgba(0, 0, 0, 1)"> SM4_ENCRYPT))
{
input </span>=<span style="color: rgba(0, 0, 0, 1)"> padding(input, SM4_ENCRYPT);
}
</span><span style="color: rgba(0, 0, 255, 1)">int</span> length =<span style="color: rgba(0, 0, 0, 1)"> input.Length;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] bins = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">;
Array.Copy(input,</span><span style="color: rgba(128, 0, 128, 1)">0</span>,bins,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">,length);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] bous = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span> ; length > <span style="color: rgba(128, 0, 128, 1)">0</span>; length -= <span style="color: rgba(128, 0, 128, 1)">16</span>,i ++<span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] inBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] outBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
Array.Copy(bins, i </span>* <span style="color: rgba(128, 0, 128, 1)">16</span>, inBytes, <span style="color: rgba(128, 0, 128, 1)">0</span>, length > <span style="color: rgba(128, 0, 128, 1)">16</span> ? <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)"> : length);
sm4_one_round(ctx.sk, inBytes, outBytes);
Array.Copy(outBytes, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, bous, i * <span style="color: rgba(128, 0, 128, 1)">16</span>, length > <span style="color: rgba(128, 0, 128, 1)">16</span> ? <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)"> : length);
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.isPadding && ctx.mode ==<span style="color: rgba(0, 0, 0, 1)"> SM4_DECRYPT)
{
bous </span>=<span style="color: rgba(0, 0, 0, 1)"> padding(bous, SM4_DECRYPT);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bous;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] sm4_crypt_cbc(SM4_Context ctx, <span style="color: rgba(0, 0, 255, 1)">byte</span>[] iv, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] input)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.isPadding && ctx.mode ==<span style="color: rgba(0, 0, 0, 1)"> SM4_ENCRYPT)
{
input </span>=<span style="color: rgba(0, 0, 0, 1)"> padding(input, SM4_ENCRYPT);
}
</span><span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> length =<span style="color: rgba(0, 0, 0, 1)"> input.Length;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] bins = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">;
Array.Copy(input,</span><span style="color: rgba(128, 0, 128, 1)">0</span>,bins,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">,length);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] bous = <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
List</span><<span style="color: rgba(0, 0, 255, 1)">byte</span>> bousList = <span style="color: rgba(0, 0, 255, 1)">new</span> List<<span style="color: rgba(0, 0, 255, 1)">byte</span>><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.mode ==<span style="color: rgba(0, 0, 0, 1)"> SM4_ENCRYPT)
{
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">int</span> j = <span style="color: rgba(128, 0, 128, 1)">0</span>; length > <span style="color: rgba(128, 0, 128, 1)">0</span>; length -= <span style="color: rgba(128, 0, 128, 1)">16</span> , j ++<span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] inBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] outBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] out1 = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
Array.Copy(bins, i </span>* <span style="color: rgba(128, 0, 128, 1)">16</span>, inBytes, <span style="color: rgba(128, 0, 128, 1)">0</span>, length > <span style="color: rgba(128, 0, 128, 1)">16</span> ? <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)"> : length);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < <span style="color: rgba(128, 0, 128, 1)">16</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
outBytes </span>= ((<span style="color: rgba(0, 0, 255, 1)">byte</span>) (inBytes ^<span style="color: rgba(0, 0, 0, 1)"> iv));
}
sm4_one_round(ctx.sk, outBytes, out1);
Array.Copy(out1, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, iv, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">int</span> k = <span style="color: rgba(128, 0, 128, 1)">0</span>;k < <span style="color: rgba(128, 0, 128, 1)">16</span>;k ++<span style="color: rgba(0, 0, 0, 1)">){
bousList.Add(out1);
}
}
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] temp = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">int</span> j = <span style="color: rgba(128, 0, 128, 1)">0</span>; length > <span style="color: rgba(128, 0, 128, 1)">0</span>; length -= <span style="color: rgba(128, 0, 128, 1)">16</span> , j ++<span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] inBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] outBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] out1 = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
Array.Copy(bins, i </span>* <span style="color: rgba(128, 0, 128, 1)">16</span>, inBytes, <span style="color: rgba(128, 0, 128, 1)">0</span>, length > <span style="color: rgba(128, 0, 128, 1)">16</span> ? <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)"> : length);
Array.Copy(inBytes, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, temp, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
sm4_one_round(ctx.sk, inBytes, outBytes);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < <span style="color: rgba(128, 0, 128, 1)">16</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
out1 </span>= ((<span style="color: rgba(0, 0, 255, 1)">byte</span>) (outBytes ^<span style="color: rgba(0, 0, 0, 1)"> iv));
}
Array.Copy(temp, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, iv, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> k = <span style="color: rgba(128, 0, 128, 1)">0</span>; k < <span style="color: rgba(128, 0, 128, 1)">16</span>; k++<span style="color: rgba(0, 0, 0, 1)">)
{
bousList.Add(out1);
}
}
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.isPadding && ctx.mode ==<span style="color: rgba(0, 0, 0, 1)"> SM4_DECRYPT)
{
bous </span>=<span style="color: rgba(0, 0, 0, 1)"> padding(bousList.ToArray(), SM4_DECRYPT);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bous;
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bousList.ToArray();
}
}
}
}</span></pre>
</div>
<p>b. SM4实体类</p>
<p>【SM4_Context.cs】</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Collections.Generic;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Linq;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Text;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Threading.Tasks;
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> Com.Mlq.SM
{
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> SM4_Context
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> mode;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)">[] sk;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> isPadding;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> SM4_Context()
{
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.mode = <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.isPadding = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sk = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">long</span>[<span style="color: rgba(128, 0, 128, 1)">32</span><span style="color: rgba(0, 0, 0, 1)">];
}
}
}</span></pre>
</div>
<p>c. SM4工具类</p>
<p>【SM4Utils.cs】</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Utilities.Encoders;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Collections.Generic;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Linq;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Text;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Threading.Tasks;
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> Com.Mlq.SM
{
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> SM4Utils
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> String secretKey = <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> String iv = <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> hexString = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String Encrypt_ECB(String plainText)
{
SM4_Context ctx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4_Context();
ctx.isPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
ctx.mode </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4.SM4_ENCRYPT;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] keyBytes;
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (hexString)
{
keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Hex.Decode(secretKey);
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetBytes(secretKey);
}
SM4 sm4 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
sm4.sm4_setkey_enc(ctx, keyBytes);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] encrypted =<span style="color: rgba(0, 0, 0, 1)"> sm4.sm4_crypt_ecb(ctx, Encoding.Default.GetBytes(plainText));
String cipherText </span>=<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(Hex.Encode(encrypted));
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> cipherText;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String Decrypt_ECB(String cipherText)
{
SM4_Context ctx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4_Context();
ctx.isPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
ctx.mode </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4.SM4_DECRYPT;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] keyBytes;
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (hexString)
{
keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Hex.Decode(secretKey);
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetBytes(secretKey);
}
SM4 sm4 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
sm4.sm4_setkey_dec(ctx, keyBytes);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] decrypted =<span style="color: rgba(0, 0, 0, 1)"> sm4.sm4_crypt_ecb(ctx, Hex.Decode(cipherText));
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(decrypted);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String Encrypt_CBC(String plainText)
{
SM4_Context ctx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4_Context();
ctx.isPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
ctx.mode </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4.SM4_ENCRYPT;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] keyBytes;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] ivBytes;
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (hexString)
{
keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Hex.Decode(secretKey);
ivBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Hex.Decode(iv);
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetBytes(secretKey);
ivBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetBytes(iv);
}
SM4 sm4 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
sm4.sm4_setkey_enc(ctx, keyBytes);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] encrypted =<span style="color: rgba(0, 0, 0, 1)"> sm4.sm4_crypt_cbc(ctx, ivBytes, Encoding.Default.GetBytes(plainText));
String cipherText </span>=<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(Hex.Encode(encrypted));
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> cipherText;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String Decrypt_CBC(String cipherText)
{
SM4_Context ctx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4_Context();
ctx.isPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
ctx.mode </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4.SM4_DECRYPT;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] keyBytes;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] ivBytes;
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (hexString)
{
keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Hex.Decode(secretKey);
ivBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Hex.Decode(iv);
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetBytes(secretKey);
ivBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetBytes(iv);
}
SM4 sm4 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
sm4.sm4_setkey_dec(ctx, keyBytes);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] decrypted =<span style="color: rgba(0, 0, 0, 1)"> sm4.sm4_crypt_cbc(ctx, ivBytes, Hex.Decode(cipherText));
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(decrypted);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">public static void Main()
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> String plainText = "ererfeiisgod";
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> SM4Utils sm4 = new SM4Utils();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> sm4.secretKey = "JeF8U9wHFOMfs2Y8";
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> sm4.hexString = false;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine("ECB模式");
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> String cipherText = sm4.Encrypt_ECB(plainText);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine("密文: " + cipherText);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine("");
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> plainText = sm4.Decrypt_ECB(cipherText);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine("明文: " + plainText);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine("");
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine("CBC模式");
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> sm4.iv = "UISwD9fW6cFh9SNS";
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> cipherText = sm4.Encrypt_CBC(plainText);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine("密文: " + cipherText);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine("");
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> plainText = sm4.Decrypt_CBC(cipherText);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.Console.Out.WriteLine("明文: " + plainText);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Console.ReadLine();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 0, 1)"> }
}</span></pre>
</div>
<p>【Cipher.cs】</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Com.Mlq.SM;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Crypto;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Crypto.Parameters;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Math;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Math.EC;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Collections.Generic;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Linq;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Text;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Threading.Tasks;
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> Com.Mlq.SM
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Cipher
{
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> ct = <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> ECPoint p2;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> SM3Digest sm3keybase;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> SM3Digest sm3c3;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] key = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">32</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">byte</span> keyOff = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Cipher()
{
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Reset()
{
sm3keybase </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM3Digest();
sm3c3 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM3Digest();
</span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] p;
p </span>=<span style="color: rgba(0, 0, 0, 1)"> p2.X.ToBigInteger().ToByteArray();
sm3keybase.BlockUpdate(p, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, p.Length);
sm3c3.BlockUpdate(p, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, p.Length);
p </span>=<span style="color: rgba(0, 0, 0, 1)"> p2.Y.ToBigInteger().ToByteArray();
sm3keybase.BlockUpdate(p, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, p.Length);
ct </span>= <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
NextKey();
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> NextKey()
{
SM3Digest sm3keycur </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM3Digest(sm3keybase);
sm3keycur.Update((</span><span style="color: rgba(0, 0, 255, 1)">byte</span>)(ct >> <span style="color: rgba(128, 0, 128, 1)">24</span> & <span style="color: rgba(128, 0, 128, 1)">0x00ff</span><span style="color: rgba(0, 0, 0, 1)">));
sm3keycur.Update((</span><span style="color: rgba(0, 0, 255, 1)">byte</span>)(ct >> <span style="color: rgba(128, 0, 128, 1)">16</span> & <span style="color: rgba(128, 0, 128, 1)">0x00ff</span><span style="color: rgba(0, 0, 0, 1)">));
sm3keycur.Update((</span><span style="color: rgba(0, 0, 255, 1)">byte</span>)(ct >> <span style="color: rgba(128, 0, 128, 1)">8</span> & <span style="color: rgba(128, 0, 128, 1)">0x00ff</span><span style="color: rgba(0, 0, 0, 1)">));
sm3keycur.Update((</span><span style="color: rgba(0, 0, 255, 1)">byte</span>)(ct & <span style="color: rgba(128, 0, 128, 1)">0x00ff</span><span style="color: rgba(0, 0, 0, 1)">));
sm3keycur.DoFinal(key, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
keyOff </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
ct</span>++<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span><span style="color: rgba(0, 0, 0, 1)"> ECPoint Init_enc(SM2 sm2, ECPoint userKey)
{
BigInteger k </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
ECPoint c1 </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
AsymmetricCipherKeyPair key </span>=<span style="color: rgba(0, 0, 0, 1)"> sm2.ecc_key_pair_generator.GenerateKeyPair();
ECPrivateKeyParameters ecpriv </span>=<span style="color: rgba(0, 0, 0, 1)"> (ECPrivateKeyParameters)key.Private;
ECPublicKeyParameters ecpub </span>=<span style="color: rgba(0, 0, 0, 1)"> (ECPublicKeyParameters)key.Public;
k </span>=<span style="color: rgba(0, 0, 0, 1)"> ecpriv.D;
c1 </span>=<span style="color: rgba(0, 0, 0, 1)"> ecpub.Q;
p2 </span>=<span style="color: rgba(0, 0, 0, 1)"> userKey.Multiply(k);
Reset();
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> c1;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Encrypt(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] data)
{
sm3c3.BlockUpdate(data, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, data.Length);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < data.Length; i++<span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (keyOff ==<span style="color: rgba(0, 0, 0, 1)"> key.Length)
NextKey();
data </span>^= key;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Init_dec(BigInteger userD, ECPoint c1)
{
p2 </span>=<span style="color: rgba(0, 0, 0, 1)"> c1.Multiply(userD);
Reset();
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Decrypt(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] data)
{
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < data.Length; i++<span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (keyOff ==<span style="color: rgba(0, 0, 0, 1)"> key.Length)
NextKey();
data </span>^= key;
}
sm3c3.BlockUpdate(data, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, data.Length);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Dofinal(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] c3)
{
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] p =<span style="color: rgba(0, 0, 0, 1)"> p2.Y.ToBigInteger().ToByteArray();
sm3c3.BlockUpdate(p, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, p.Length);
sm3c3.DoFinal(c3, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
Reset();
}
}
}</span></pre>
</div>
<p> 引用地址:https://blog.csdn.net/ererfei/article/details/50999820</p><br><br>
来源:https://www.cnblogs.com/valu/p/12842778.html
頁:
[1]