教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 国密算法Go语言实现(详解)(六) ——SM2(椭圆曲线公钥密码算法)

国密算法Go语言实现(详解)(六) ——SM2(椭圆曲线公钥密码算法)

发布时间:2021-12-08   编辑:jiaochengji.com
教程集为您提供国密算法Go语言实现(详解)(六) ——SM2(椭圆曲线公钥密码算法)等资源,欢迎您收藏本站,我们将为您提供最新的国密算法Go语言实现(详解)(六) ——SM2(椭圆曲线公钥密码算法)资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg><h1>国密算法Go语言实现(详解)(六) ——SM2(椭圆曲线公钥密码算法)</h1>

原创代码:https://github.com/ZZMarquis/gm

<mark>引用时,请导入原创代码库。本文仅以注释方式详解代码逻辑,供学习研究使用。</mark>

对原创代码的修改内容

<ol><li>修改了部分常量、变量、结构体属性的名称, 以便与GO语言标准包规范相统一</li><li>加入中文注释,解释代码逻辑</li></ol>

注释者及联系邮箱

<blockquote>

Paul Lee
paul_lee0919@163.com

</blockquote> <pre><code class="lang-go hljs"><span class="token keyword">const</span> <span class="token punctuation">(</span> <span class="token comment">// BitSize 代表曲线基础域的比特长度</span> BitSize <span class="token operator">=</span> <span class="token number">256</span> <span class="token comment">// KeyBytes 代表秘钥的字节长度,其中加7整除8其实是“向上取整”,用以兼容基础域位数不是8的整数倍的情况。</span> KeyBytes <span class="token operator">=</span> <span class="token punctuation">(</span>BitSize <span class="token operator"> </span> <span class="token number">7</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">8</span> <span class="token comment">// UnCompress 代表椭圆曲线上的点采用“未压缩”的形式存储,占1个字节,详见国标1-4.1.(b)的定义。</span> UnCompress <span class="token operator">=</span> <span class="token number">0x04</span> <span class="token punctuation">)</span> </code></pre>

以上为SM2算法定义的三个常数:

<ol><li>BitSize 代表曲线基础域的比特长度</li><li>KeyBytes 代表秘钥的字节长度,其中加7整除8其实是“向上取整”,用以兼容基础域位数不是8的整数倍的情况</li><li>UnCompress 代表椭圆曲线上的点采用“未压缩”的形式存储,占1个字节,详见国标1-4.1.(b)的定义</li></ol><pre><code class="lang-go hljs"><span class="token comment">// CipherTextType 是为了区分两个版本SM2国标在密文形式上的区别而创设的枚举类</span> <span class="token keyword">type</span> CipherTextType <span class="token builtin">int32</span> <span class="token keyword">const</span> <span class="token punctuation">(</span> <span class="token comment">//C1C2C3 代表旧标准[GM/T 0009-2012]的密文顺序</span> C1C2C3 CipherTextType <span class="token operator">=</span> <span class="token number">1</span> <span class="token comment">//C1C3C2 代表新标准[GB/T 32918-2016]的密文顺序</span> C1C3C2 CipherTextType <span class="token operator">=</span> <span class="token number">2</span> <span class="token punctuation">)</span> </code></pre>

CipherTextType是为了区分新旧两个版本的国标规范而设置的密文顺序标识枚举类,其中:

<ol><li>C1C2C3 代表旧标准[GM/T 0009-2012]的密文顺序</li><li>C1C3C2 代表新标准[GB/T 32918-2016]的密文顺序</li></ol><pre><code class="lang-go hljs"><span class="token keyword">var</span> <span class="token punctuation">(</span> <span class="token comment">// sm2H 代表SM2推荐曲线的余因子h=1</span> <span class="token comment">// 椭圆曲线方程符合 y^2 = x^3 - 3x b (mod p)</span> sm2H <span class="token operator">=</span> <span class="token function">new</span><span class="token punctuation">(</span>big<span class="token punctuation">.</span>Int<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">SetInt64</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment">// sm2SignDefaultUserID 代表sm2算法默认的加密操作用户A的ID编码(详见国标5-A.1)和SM2使用规范(GB/T 35276-2017第10部分)</span> sm2SignDefaultUserID <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">{</span> <span class="token number">0x31</span><span class="token punctuation">,</span> <span class="token number">0x32</span><span class="token punctuation">,</span> <span class="token number">0x33</span><span class="token punctuation">,</span> <span class="token number">0x34</span><span class="token punctuation">,</span> <span class="token number">0x35</span><span class="token punctuation">,</span> <span class="token number">0x36</span><span class="token punctuation">,</span> <span class="token number">0x37</span><span class="token punctuation">,</span> <span class="token number">0x38</span><span class="token punctuation">,</span> <span class="token number">0x31</span><span class="token punctuation">,</span> <span class="token number">0x32</span><span class="token punctuation">,</span> <span class="token number">0x33</span><span class="token punctuation">,</span> <span class="token number">0x34</span><span class="token punctuation">,</span> <span class="token number">0x35</span><span class="token punctuation">,</span> <span class="token number">0x36</span><span class="token punctuation">,</span> <span class="token number">0x37</span><span class="token punctuation">,</span> <span class="token number">0x38</span><span class="token punctuation">}</span> <span class="token punctuation">)</span> </code></pre>

以上为SM2算法定义的两个变量:

<ol><li>sm2H 代表基域F<sub>p</sub>上椭圆曲线E的余因子h</li><li>由于SM2推荐曲线的余因子h=1, 即#E(F<sub>p</sub>) = n</li></ol><pre><code class="lang-go hljs"><span class="token comment">// sm2P256V1 代表国密SM2推荐参数定义的椭圆曲线</span> <span class="token keyword">var</span> sm2P256V1 P256V1Curve <span class="token comment">// P256V1Curve 代表国密SM2推荐参数定义的椭圆曲线:</span> <span class="token comment">// (1) 素数域256位椭圆曲线</span> <span class="token comment">// (2) 曲线方程为 Y^2 = X^3 aX b</span> <span class="token comment">// (3) 其他参数: p, a, b, n, Gx, Gy 详见国标SM2推荐曲线参数</span> <span class="token comment">// (4) 在GO语言标准库通用椭圆曲线参数类elliptic.CurveParams的基础上增加了参数a的属性</span> <span class="token comment">// (5) 由于SM2推荐曲线符合a=p-3, 所以上述曲线可简化为等价曲线 Y^2 = X^3 - 3X b (mod p),</span> <span class="token comment">// 可直接适用GO语言elliptic标准库的一些公共方法。(没有完成严格的数学验证,请大牛指教)</span> <span class="token keyword">type</span> P256V1Curve <span class="token keyword">struct</span> <span class="token punctuation">{</span> <span class="token operator">*</span>elliptic<span class="token punctuation">.</span>CurveParams A <span class="token operator">*</span>big<span class="token punctuation">.</span>Int <span class="token punctuation">}</span> <span class="token comment">// init() 初始化国密SM2推荐参数计算得出的椭圆曲线。</span> <span class="token keyword">func</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">initSm2P256V1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// initSm2P256V1 为初始化国密SM2推荐参数计算得出的椭圆曲线:</span> <span class="token comment">// (1) 基域F(p)为素数域</span> <span class="token comment">// (2) 一次元x的系数a=p-3, 所以曲线方程等价于 y^2 = x^3 - 3x^2 b (mod p) (即符合FIPS186-3标准预设函数)</span> <span class="token comment">// (3) 余因子h=1</span> <span class="token keyword">func</span> <span class="token function">initSm2P256V1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sm2P<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> <span class="token function">new</span><span class="token punctuation">(</span>big<span class="token punctuation">.</span>Int<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">SetString</span><span class="token punctuation">(</span><span class="token string">"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF"</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span> sm2A<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> <span class="token function">new</span><span class="token punctuation">(</span>big<span class="token punctuation">.</span>Int<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">SetString</span><span class="token punctuation">(</span><span class="token string">"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC"</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span> sm2B<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> <span class="token function">new</span><span class="token punctuation">(</span>big<span class="token punctuation">.</span>Int<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">SetString</span><span class="token punctuation">(</span><span class="token string">"28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93"</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span> sm2N<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> <span class="token function">new</span><span class="token punctuation">(</span>big<span class="token punctuation">.</span>Int<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">SetString</span><span class="token punctuation">(</span><span class="token string">"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span> sm2Gx<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> <span class="token function">new</span><span class="token punctuation">(</span>big<span class="token punctuation">.</span>Int<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">SetString</span><span class="token punctuation">(</span><span class="token string">"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7"</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span> sm2Gy<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> <span class="token function">new</span><span class="token punctuation">(</span>big<span class="token punctuation">.</span>Int<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">SetString</span><span class="token punctuation">(</span><span class="token string">"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span> sm2P256V1<span class="token punctuation">.</span>CurveParams <span class="token operator">=</span> <span class="token operator">&</span>elliptic<span class="token punctuation">.</span>CurveParams<span class="token punctuation">{</span>Name<span class="token punctuation">:</span> <span class="token string">"SM2-P-256-V1"</span><span class="token punctuation">}</span> sm2P256V1<span class="token punctuation">.</span>P <span class="token operator">=</span> sm2P sm2P256V1<span class="token punctuation">.</span>A <span class="token operator">=</span> sm2A sm2P256V1<span class="token punctuation">.</span>B <span class="token operator">=</span> sm2B sm2P256V1<span class="token punctuation">.</span>N <span class="token operator">=</span> sm2N sm2P256V1<span class="token punctuation">.</span>Gx <span class="token operator">=</span> sm2Gx sm2P256V1<span class="token punctuation">.</span>Gy <span class="token operator">=</span> sm2Gy sm2P256V1<span class="token punctuation">.</span>BitSize <span class="token operator">=</span> BitSize <span class="token punctuation">}</span> <span class="token comment">// GetSm2P256V1 为获取国密SM2椭圆曲线定义的函数。</span> <span class="token keyword">func</span> <span class="token function">GetSm2P256V1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> P256V1Curve <span class="token punctuation">{</span> <span class="token keyword">return</span> sm2P256V1 <span class="token punctuation">}</span> </code></pre>

P256V1Curve 代表国密SM2推荐参数定义的椭圆曲线:

<ol><li>素数域256位椭圆曲线</li><li>曲线方程为 Y<sup>2</sup> = X<sup>3</sup> aX b</li><li>其他参数: p, a, b, n, Gx, Gy 详见国标SM2推荐曲线参数</li><li>在GO语言标准库通用椭圆曲线参数类elliptic.CurveParams的基础上增加了参数a的属性</li><li>由于SM2推荐曲线符合a=p-3, 所以上述曲线可简化为等价曲线 Y^2 = X^3 - 3X b (mod p)</li><li>可直接适用GO语言elliptic标准库的公共方法。(<mark>没有完成严谨的数学验证,请大牛指教</mark>)</li></ol>

(未完待续)

到此这篇关于“国密算法Go语言实现(详解)(六) ——SM2(椭圆曲线公钥密码算法)”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
国密算法Go语言实现(详解)(六) ——SM2(椭圆曲线公钥密码算法)
国密算法Go语言实现(详解)(九) ——SM2(椭圆曲线公钥密码算法)
【go密码学】-非对称加密算法
php5 字符串处理函数汇总
专家教你如何有效的学习Drupal - Drupal问答
Python:常见的加密方式
Javascript 到 PHP 加密通讯的简单实现
密码学之对称加密
php实现简单用户登录功能程序代码
PHP加密扩展库Mcrypt的例子

[关闭]
~ ~