init: v1.0.0

This commit is contained in:
yaole
2026-05-27 23:03:00 +08:00
commit 8d97f750eb
466 changed files with 80067 additions and 0 deletions
+165
View File
@@ -0,0 +1,165 @@
/*
Package sm3 implements the SM3 Hash algorithms
*/
package sm3
import (
"hash"
"xdx.jelly/xgcl/sm"
)
func init() {
// 注册sm.SM3、sm.SM3WithID到sm.hashs中去.
sm.RegisterHash(sm.SM3, New)
sm.RegisterHash(sm.SM3WithID, New)
}
type digest struct {
h [8]uint32
x [chunk]byte
nx int
len uint64
}
// NewDigest return a new digest type, void change `digest` to `Digest`.
// 相比标准库,增加此函数。
// 在上下文明确使用sm3的时候,可以显示用这个函数来获取sm3的digest实例,
// 而不是通过New()得到Hash接口。
func NewDigest() *digest {
d := new(digest)
d.Reset()
return d
}
// New returns a new hash.Hash computing the SM3 checksum. The Hash also
// implements encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to
// marshal and unmarshal the internal state of the hash.
func New() hash.Hash {
return NewDigest()
}
// Reset reset the states
func (d *digest) Reset() {
d.h[0] = init0
d.h[1] = init1
d.h[2] = init2
d.h[3] = init3
d.h[4] = init4
d.h[5] = init5
d.h[6] = init6
d.h[7] = init7
d.nx = 0
d.len = 0
}
/*
MarshalBinary和UnmarshalBinary实现了encoding.BinaryMarshaler和
encoding.BinaryMarshaler接口,可以对Sm3的中间状态转化为byte序列存储。
比如kdf函数要计算SM3(z||cnt) cnt = 1,2,3,4...,可以先update(z),保存此时
状态。
用法:
dig := New()
io.WriteString(dig, "a")
// New 返回的是hash接口, 转换为BinaryMarshaler接口
state, _ := dig.(encoding.BinaryMarshaler).MarshalBinary()
// dig do something
dig.(encoding.BinaryUnmarshaler).UnmarshalBinary(state)
补充:我们增加了NewDigest(), 返回*digest,因此可以直接用赋值保存。
d1 := NewDigest()
// ...
*d2 := *d1
*/
// MarshalBinary implements the encoding.BinaryMarshaler interface
// marshal a digest to []byte to save
// no error return.
func (d *digest) MarshalBinary() ([]byte, error) {
b := make([]byte, 0, marshaledSize)
b = append(b, magic...)
b = appendUint32(b, d.h[0])
b = appendUint32(b, d.h[1])
b = appendUint32(b, d.h[2])
b = appendUint32(b, d.h[3])
b = appendUint32(b, d.h[4])
b = appendUint32(b, d.h[5])
b = appendUint32(b, d.h[6])
b = appendUint32(b, d.h[7])
b = append(b, d.x[:]...)
b = appendUint64(b, d.len)
return b, nil
}
// UnmarshalBinary implements the encoding.BinaryMarshaler interface
// recover a digest from []byte
func (d *digest) UnmarshalBinary(b []byte) error {
if len(b) < marshaledSize || string(b[:len(magic)]) != magic {
return ErrInvalidInput
}
b = b[len(magic):]
b, d.h[0] = consumeUint32(b)
b, d.h[1] = consumeUint32(b)
b, d.h[2] = consumeUint32(b)
b, d.h[3] = consumeUint32(b)
b, d.h[4] = consumeUint32(b)
b, d.h[5] = consumeUint32(b)
b, d.h[6] = consumeUint32(b)
b, d.h[7] = consumeUint32(b)
b = b[copy(d.x[:], b):]
_, d.len = consumeUint64(b)
d.nx = int(d.len) % chunk
return nil
}
// Size returns the size of hash digest
func (d *digest) Size() int { return Size }
// BlockSize return the bytes of one block
func (d *digest) BlockSize() int { return BlockSize }
func (d *digest) Write(p []byte) (nn int, err error) {
nn = len(p)
d.len += uint64(nn)
// try to clear d.x
if d.nx > 0 {
n := copy(d.x[d.nx:], p)
d.nx += n
if d.nx == chunk {
block(d, d.x[:])
d.nx = 0
}
p = p[n:]
}
if len(p) >= chunk {
// n is multiple of chunk
n := len(p) &^ (chunk - 1)
block(d, p[:n])
p = p[n:]
}
if len(p) > 0 {
d.nx = copy(d.x[:], p)
}
return
}
// Sum returns the digest without change the intenal states
func (d *digest) Sum(in []byte) []byte {
// make a copy
d0 := *d
hash := d0.checkSum()
return append(in, hash[:]...)
}
// Sum returns the SM3 checksum of the data.
func Sum(data ...[]byte) [Size]byte {
var d digest
d.Reset()
for _, x := range data {
d.Write(x)
}
return d.checkSum()
}