55 lines
1.1 KiB
Go
55 lines
1.1 KiB
Go
///
|
|
/// Copyright (c) 2018 xdx. All rights reserved.
|
|
///
|
|
/// \file: kdf.go
|
|
///
|
|
/// \brief: SM2和SM9标准中定义的密钥扩展函数,哈希函数使用SM3。
|
|
///
|
|
/// \author: xdx
|
|
///
|
|
|
|
package kdf
|
|
|
|
import (
|
|
"encoding/binary"
|
|
|
|
"xdx.jelly/xgcl/sm/sm3"
|
|
)
|
|
|
|
type smKDF struct {
|
|
}
|
|
|
|
// Kdf 密钥派生函数
|
|
// 省略了检查len(out)-out是调用者已分配好,几乎不会出现len(out)=128G的情况。
|
|
// const maxKDFLen = 0x1fffffffe0 //( (1 << 32) - 1 ) * 32
|
|
// out必须分配好空间。KDF填充out[:len(out)],输入ins可以包括多组
|
|
// 函数内部不会对out的底层数组做重分配
|
|
// 目前不返回错误
|
|
func (*smKDF) Kdf(out []byte, inputs ...[]byte) error {
|
|
s0 := sm3.NewDigest()
|
|
for _, in := range inputs {
|
|
s0.Write(in)
|
|
}
|
|
|
|
buf := make([]byte, 4)
|
|
var ct uint32 = 1
|
|
pos := 0
|
|
s := sm3.NewDigest()
|
|
for pos <= int(len(out))-sm3.Size {
|
|
// make a copy
|
|
*s = *s0
|
|
binary.BigEndian.PutUint32(buf, ct)
|
|
ct++
|
|
s.Write(buf[:4])
|
|
s.Sum(out[:pos])
|
|
pos += sm3.Size
|
|
}
|
|
if pos < len(out) {
|
|
binary.BigEndian.PutUint32(buf, ct)
|
|
s0.Write(buf[:4])
|
|
d := s0.Sum(nil)
|
|
copy(out[pos:], d)
|
|
}
|
|
return nil
|
|
}
|