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

本文详细介绍了SM2椭圆曲线公钥密码算法在Go语言中的实现过程,包括KDF函数的详细步骤、加密和解密函数的工作原理,并提供了原创代码库的链接。文章还强调了在实现过程中遵循的国标规范和注意事项。
摘要由CSDN通过智能技术生成

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


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

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

对原创代码的修改内容

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

注释者及联系邮箱

Paul Lee
paul_lee0919@163.com

// xor 函数是将国标3-6.1.A5和3-6.1.A6两步结合到一起的异或函数,
// 其计算结果返回调用来源函数kdf(),
// 从而可在计算中间变量t的同时异或、拼接获得C2:
// (1) data 为输入明文消息M
// (2) kdfOut[] 为秘钥派生函数输出缓存buf[]
// (3) dRemaining 为KDF()函数中标注输入消息数组encData[]每次调用xor()时,
// 阶段性“读”动作读取的字节数组元素个数
func xor(data []byte, kdfOut []byte, dRemaining int) {
   
	for i := 0; i != dRemaining; i++ {
   
		data[i] ^= kdfOut[i]
	}
}

// kdf 为SM2公钥加密算法中调用秘钥派生函数的操作步骤(国标4-6.1.A5):
// (1) 按照哈希摘要字节长度创设缓存切片buf[]
// (2) 以公钥P的k倍点坐标(c1x, c1y)和输入明文消息M(长度为klen位)为输入参数
// (3) 按照国标4-5.4.3定义的秘钥派生函KDF()和国标第4-6.1.A5规定的算法推算中间变量t
// (4) t=KDF(c1x||c1y, klen), 该算法核心是迭代调用Hash(c1x||c1y||ct),其中:
//     (a) ct为32位整数计数器, 从1起算
//     (b) 调用次数为klen/v向上取整次
//     (c) v代表哈希摘要的位数长度(SM3为256位)
//     (d) 最后一次调用若明文M剩余长度小于v, 则取有值的字节
// (5) C2=M^t, 即通过xor()在计算中间变量t的过程中将中间结果与M的对应字节进行异或运算
func kdf(digest hash.Hash, c1x *big.Int, c1y *big.Int, encData []byte) {
   
	// 4个字节为32位字长
	bufSize := 4
	if bufSize < digest.Size() {
   
		// SM3哈希算法的摘要长度为32字节(256位),所以,此处取值将为32
		bufSize = digest.Size()
	}
	buf := make([]byte, bufSize)

	// 输入消息的字节数组长度,根据国标第2部分5.4.3定义,其值应小于(2^32-1)*v
	// 鉴于SM3的哈希值长度v为256位,所以,klen应当小于(2^32-1)*2^8
	encDataLen := len(encData)

	// 加密算法中,(c1x, c1y)为公钥P的k倍点(k为加密过程中产生随机整数)
	c1xBytes := c1x.Bytes()
	c1yBytes := c1y.Bytes()

	// encData[]元素序号“读”指针
	off := 0
	// 32位计数器
	ct := uint32(0)
	for off < encDataLen {
   
		digest.Reset()
		digest.Write(c1xBytes)
		digest.Write(c1yBytes)
		ct++
		binary.BigEndian.PutUint32(buf, ct)
		//ct为32位计数器,占4个字节,所以Write()方法仅需要读取到buf[:4]
		digest.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值