1 Star 0 Fork 0

wmdng/sm234

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
sm3hash.go 4.29 KB
一键复制 编辑 原始数据 按行查看 历史
wmdng 提交于 2023-07-17 16:16 . some fix for dbg
package sm234
import (
"encoding/binary"
"hash"
"math/bits"
)
/*
// hash.Hash
type Hash interface {
io.Writer
Sum(b []byte) []byte
Reset()
Size() int
BlockSize() int
}
*/
type sm3ctx struct {
digest [8]uint32
block [64]byte
offs int // block 中等待处理的字节数.
nblk int // 已经处理过的 block 个数.
}
func NewSM3Hash() hash.Hash {
var nctx sm3ctx
nctx.Reset()
return &nctx
}
func (ctx *sm3ctx) Size() int {
return 32
}
func (ctx *sm3ctx) BlockSize() int {
return 64
}
func (ctx *sm3ctx) Reset() {
ctx.digest[0] = 0x7380166F
ctx.digest[1] = 0x4914B2B9
ctx.digest[2] = 0x172442D7
ctx.digest[3] = 0xDA8A0600
ctx.digest[4] = 0xA96F30BC
ctx.digest[5] = 0x163138AA
ctx.digest[6] = 0xE38DEE4D
ctx.digest[7] = 0xB0FB0E4E
ctx.offs = 0
ctx.nblk = 0
}
// block
func (ctx *sm3ctx) round(blk []byte) {
var A, B, C, D, E, F, G, H uint32
var W [68]uint32
var SS1, SS2, TT1, TT2 uint32
//
A = ctx.digest[0]
B = ctx.digest[1]
C = ctx.digest[2]
D = ctx.digest[3]
E = ctx.digest[4]
F = ctx.digest[5]
G = ctx.digest[6]
H = ctx.digest[7]
// 64 bytes per BLOCK.
for i := 0; i < 16; i++ {
W[i] = binary.BigEndian.Uint32(blk[i*4:])
}
for i := 16; i < 68; i++ {
// P1(x) = ((x) ^ ROTL((x),15) ^ ROTL((x),23))
temp := W[i-16] ^ W[i-9] ^ bits.RotateLeft32(W[i-3], 15)
temp = temp ^ bits.RotateLeft32(temp, 15) ^ bits.RotateLeft32(temp, 23)
W[i] = temp ^ bits.RotateLeft32(W[i-13], 7) ^ W[i-6]
}
//
for i := 0; i < 16; i++ {
KK := bits.RotateLeft32(A, 12) + E + bits.RotateLeft32(0x79cc4519, i)
SS1 = bits.RotateLeft32(KK, 7)
SS2 = SS1 ^ bits.RotateLeft32(A, 12)
TT1 = (A ^ B ^ C) + D + SS2 + (W[i] ^ W[i+4])
TT2 = (E ^ F ^ G) + H + SS1 + W[i]
D = C
C = bits.RotateLeft32(B, 9)
B = A
A = TT1
H = G
G = bits.RotateLeft32(F, 19)
F = E
E = TT2 ^ bits.RotateLeft32(TT2, 9) ^ bits.RotateLeft32(TT2, 17)
}
for i := 16; i < 64; i++ {
KK := bits.RotateLeft32(A, 12) + E + bits.RotateLeft32(0x7a879d8a, i)
SS1 = bits.RotateLeft32(KK, 7)
SS2 = SS1 ^ bits.RotateLeft32(A, 12)
TT1 = ((A & B) | (A & C) | (B & C)) + D + SS2 + (W[i] ^ W[i+4])
TT2 = (((F ^ G) & E) ^ G) + H + SS1 + W[i]
D = C
C = bits.RotateLeft32(B, 9)
B = A
A = TT1
H = G
G = bits.RotateLeft32(F, 19)
F = E
E = TT2 ^ bits.RotateLeft32(TT2, 9) ^ bits.RotateLeft32(TT2, 17)
}
//
ctx.digest[0] ^= A
ctx.digest[1] ^= B
ctx.digest[2] ^= C
ctx.digest[3] ^= D
ctx.digest[4] ^= E
ctx.digest[5] ^= F
ctx.digest[6] ^= G
ctx.digest[7] ^= H
}
// adds more data to the running hash.
// It never returns an error.
func (ctx *sm3ctx) Write(p []byte) (n int, err error) {
var tsiz int
for i := 0; i < len(p); i += tsiz {
tsiz = copy(ctx.block[ctx.offs:], p[i:])
ctx.offs += tsiz
if ctx.offs < 64 {
break
}
// block is full..
ctx.round(ctx.block[:])
ctx.offs = 0
ctx.nblk += 1
}
return len(p), nil
}
// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.
func (ctx *sm3ctx) Sum(b []byte) []byte {
// copy a new context
nctx := *ctx
spad := make([]byte, 64)
// padding tail, add bytes count...
nctx.block[nctx.offs] = 0x80
copy(spad[:], nctx.block[0:nctx.offs+1])
//fmt.Printf("tail: %v\n", nctx.offs)
//fmt.Println(hex.EncodeToString(spad))
if nctx.offs > (64 - 9) {
nctx.round(spad[:])
// zero 56 bytes.
for i := 0; i < 56; i++ {
spad[i] = 0
}
}
//
binary.BigEndian.PutUint32(spad[56:], uint32(nctx.nblk)>>23)
binary.BigEndian.PutUint32(spad[60:], (uint32(nctx.nblk)<<9)+(uint32(nctx.offs)<<3))
nctx.round(spad[:])
//
tofs := len(b)
rult := make([]byte, tofs+32)
if tofs > 0 {
copy(rult[0:], b[:])
}
binary.BigEndian.PutUint32(rult[tofs:], nctx.digest[0])
binary.BigEndian.PutUint32(rult[tofs+4:], nctx.digest[1])
binary.BigEndian.PutUint32(rult[tofs+8:], nctx.digest[2])
binary.BigEndian.PutUint32(rult[tofs+12:], nctx.digest[3])
binary.BigEndian.PutUint32(rult[tofs+16:], nctx.digest[4])
binary.BigEndian.PutUint32(rult[tofs+20:], nctx.digest[5])
binary.BigEndian.PutUint32(rult[tofs+24:], nctx.digest[6])
binary.BigEndian.PutUint32(rult[tofs+28:], nctx.digest[7])
return rult
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/wmdng/sm234.git
git@gitee.com:wmdng/sm234.git
wmdng
sm234
sm234
master

搜索帮助