焦稚清 發表於 2020-5-7 14:21:00

C#实现SM2国密加密

<p><img src="https://img2020.cnblogs.com/blog/82863/202005/82863-20200507142133300-509867814.png" alt=""></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>本文主要讲解“国密加密算法”SM系列的C#实现方法,不涉及具体的算法剖析,在网络上找到的java实现方法比较少,切在跨语言加密解密上会存在一些问题,所以整理此文志之。JAVA实现参考http://blog.csdn.net/ererfei/article/details/50998162</p>
<p>1.SM2 &amp; SM3<br>由于SM2算法中需要使用SM3摘要算法,所以把他们放在一起</p>
<p>项目目录结构如下:</p>
<p>&nbsp;</p>
<p>首先要下载一个dll包——BouncyCastle.Crypto.dll,并将此dll引用到项目中。实现代码如下(每个工具类都有Main可以运行测试):</p>
<p>a.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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 &gt;&gt; <span style="color: rgba(128, 0, 128, 1)">8</span> &amp; <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 &amp; <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.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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>) &amp;&amp; (length &gt; <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 &gt;<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 &gt; <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 &lt;&lt; <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)">&lt;summary&gt;</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)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="number"&gt;</span><span style="color: rgba(0, 128, 0, 1)">Number to operate on</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="bits"&gt;</span><span style="color: rgba(0, 128, 0, 1)">Ammount of bits to shift</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;</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)">&lt;/returns&gt;</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 &gt;= <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 &gt;&gt;<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 &gt;&gt; bits) + (<span style="color: rgba(128, 0, 128, 1)">2</span> &lt;&lt; ~<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)">&lt;summary&gt;</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)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="number"&gt;</span><span style="color: rgba(0, 128, 0, 1)">Number to operate on</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="bits"&gt;</span><span style="color: rgba(0, 128, 0, 1)">Ammount of bits to shift</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;</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)">&lt;/returns&gt;</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)">&lt;summary&gt;</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)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="number"&gt;</span><span style="color: rgba(0, 128, 0, 1)">Number to operate on</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="bits"&gt;</span><span style="color: rgba(0, 128, 0, 1)">Ammount of bits to shift</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;</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)">&lt;/returns&gt;</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 &gt;= <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 &gt;&gt;<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 &gt;&gt; bits) + (<span style="color: rgba(128, 0, 128, 1)">2L</span> &lt;&lt; ~<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)">&lt;summary&gt;</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)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="number"&gt;</span><span style="color: rgba(0, 128, 0, 1)">Number to operate on</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="bits"&gt;</span><span style="color: rgba(0, 128, 0, 1)">Ammount of bits to shift</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;</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)">&lt;/returns&gt;</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 &lt; <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 &lt; <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 &lt; <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 &lt; <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 &lt; <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 &lt;&lt; <span style="color: rgba(128, 0, 128, 1)">24</span><span style="color: rgba(0, 0, 0, 1)">;
            n </span>|= (in_Renamed[++inOff] &amp; <span style="color: rgba(128, 0, 128, 1)">0xff</span>) &lt;&lt; <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">;
            n </span>|= (in_Renamed[++inOff] &amp; <span style="color: rgba(128, 0, 128, 1)">0xff</span>) &lt;&lt; <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">;
            n </span>|= (in_Renamed[++inOff] &amp; <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 &gt; <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 &amp; <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 &lt; <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 &lt;&lt; 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 &amp; Y) | (X &amp; Z) | (Y &amp;<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 &amp; Y) | (~ X &amp;<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.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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 &amp; <span style="color: rgba(128, 0, 128, 1)">0xff</span>) &lt;&lt; <span style="color: rgba(128, 0, 128, 1)">24</span> | (<span style="color: rgba(0, 0, 255, 1)">long</span>)((b &amp; <span style="color: rgba(128, 0, 128, 1)">0xff</span>) &lt;&lt; <span style="color: rgba(128, 0, 128, 1)">16</span>) | (<span style="color: rgba(0, 0, 255, 1)">long</span>)((b &amp; <span style="color: rgba(128, 0, 128, 1)">0xff</span>) &lt;&lt; <span style="color: rgba(128, 0, 128, 1)">8</span>) | (<span style="color: rgba(0, 0, 255, 1)">long</span>)(b &amp; <span style="color: rgba(128, 0, 128, 1)">0xff</span>) &amp; <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> &amp; n &gt;&gt; <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> &amp; n &gt;&gt; <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> &amp; n &gt;&gt; <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> &amp;<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 &amp; <span style="color: rgba(128, 0, 128, 1)">0xFFFFFFFF</span>) &lt;&lt;<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 &gt;&gt; (<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 &amp; <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 &lt; <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 &lt; <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 &lt; 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 &lt; <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) &amp;&amp; (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 &gt; <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 &gt; <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 &gt; <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 &amp;&amp; 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 &amp;&amp; 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>&lt;<span style="color: rgba(0, 0, 255, 1)">byte</span>&gt; bousList = <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;<span style="color: rgba(0, 0, 255, 1)">byte</span>&gt;<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 &gt; <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 &gt; <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 &lt; <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 &lt; <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 &gt; <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 &gt; <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 &lt; <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 &lt; <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 &amp;&amp; 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.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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 &gt;&gt; <span style="color: rgba(128, 0, 128, 1)">24</span> &amp; <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 &gt;&gt; <span style="color: rgba(128, 0, 128, 1)">16</span> &amp; <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 &gt;&gt; <span style="color: rgba(128, 0, 128, 1)">8</span> &amp; <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 &amp; <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 &lt; 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 &lt; 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>&nbsp;引用地址:https://blog.csdn.net/ererfei/article/details/50999820</p><br><br>
来源:https://www.cnblogs.com/valu/p/12842778.html
頁: [1]
查看完整版本: C#实现SM2国密加密