国密算法Go语言实现(详解)(九) ——SM2(椭圆曲线公钥密码算法)
原创代码:https://github.com/ZZMarquis/gm
引用时,请导入原创代码库。本文仅以注释方式详解代码逻辑,供学习研究使用。
对原创代码的修改内容
- 修改了部分常量、变量、结构体属性的名称, 以便与GO语言标准包规范相统一
- 加入中文注释,解释代码逻辑
- 将PublicKey设置为PrivateKey的成员属性,与GO语言标准包规范统一
注释者及联系邮箱
Paul Lee
paul_lee0919@163.com
// sm2Signature 代表SM2算法的数字签名类。
type sm2Signature struct {
R, S *big.Int
}
// MarshalCipher 为SM2算法密文对象序列化公共函数:
// (1) 将字节数组中保存的SM2密文对象截取出来
// (2) 将截取出来的数据赋值给SM2密文对象的各相关属性
// (3) 将SM2密文对象序列化为符合ASN.1标准DER编码规则的密文字节串
// (4) SM2密文对象的具体规范请见国标(GB/T 35276-2017)
func MarshalCipher(in []byte, cipherTextType CipherTextType) ([]byte, error) {
// 将椭圆曲线的位数转化为字节数
byteLen := (sm2P256V1.Params().BitSize + 7) >> 3
c1x := make([]byte, byteLen)
c1y := make([]byte, byteLen)
// 将in[]按C1,C2,C3长度进行拆分
c2Len := len(in) - (1 + byteLen*2) - sm3.Size
c2 := make([]byte, c2Len)
c3 := make([]byte, sm3.Size)
pos := 1
// 拆分获取c1x, c1y
copy(c1x, in[pos:pos+byteLen])
pos += byteLen
copy(c1y, in[pos:pos+byteLen])
pos += byteLen
nc1x := new(big.Int).SetBytes(c1x)
nc1y := new(big.Int).SetBytes(c1y)
// 根据新旧国标的格式标识拆分C2和C3
if cipherTextType == C1C2C3 {
copy(c2, in[pos:pos+c2Len])
pos += c2Len
copy(c3, in[pos:pos+sm3.Size])
result, err := asn1.Marshal(sm2CipherC1C2C3{
nc1x, nc1y, c2, c3})
if err != nil {
return nil, err
}
return result, nil
} else if cipherTextType == C1C3C2 {
copy(c3, in[pos:pos+sm3.Size])
pos += sm3.Size
copy(c2, in[pos:pos+c2Len])
result, err := asn1.Marshal(sm2CipherC1C3C2{
nc1x, nc1y, c3, c2})
if err != nil {
return nil, err
}
return result, nil
} else {
return nil, errors.New("unknown cipherTextType:" + string(cipherTextType))
}
}
MarshalCipher( ) 为SM2算法密文对象序列化公共函数:
- (1) 将字节数组中保存的SM2密文对象截取出来
- (2) 将截取出来的数据赋值给SM2密文对象的各相关属性
- (3) 将SM2密文对象序列化为符合ASN.1标准DER编码规则的密文字节串
- (4) SM2密文对象的具体规范请见国标(GB/T 35276-2017)
// UnmarshalCipher 为SM2算法密文对象反序列化公共函数:
// (1) 将符合ASN.1标准DER编码规则的密文字节串反序列化为SM2密文对象
// (2) 将SM2密文对象的各相关属性的值读出来并按规范存入字节数组
// (3) SM2密文对象的具体规范请见国标(GB/T 35276-2017)
func UnmarshalCipher(in []byte, cipherTextType CipherTextType) (out []byte, err error) {
if cipherTextType == C1C2C3 {
cipher :=</