gmsm/slhdsa/hash.go

162 lines
4.5 KiB
Go
Raw Permalink Normal View History

2025-05-21 11:10:44 +08:00
// Copyright 2025 Sun Yimin. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
//go:build go1.24
package slhdsa
import (
"crypto/hmac"
"hash"
)
type hashOperations interface {
f(pk *PublicKey, address adrsOperations, m1, out []byte)
h(pk *PublicKey, address adrsOperations, m1, m2, out []byte)
t(pk *PublicKey, address adrsOperations, ml, out []byte)
hMsg(pk *PublicKey, R, mPrefix, M, out []byte)
prf(sk *PrivateKey, address adrsOperations, out []byte)
prfMsg(sk *PrivateKey, optRand, mPrefix, m, out []byte)
}
type shakeOperations struct{}
func (shakeOperations) f(pk *PublicKey, address adrsOperations, m1, out []byte) {
pk.shake.Reset()
pk.shake.Write(pk.seed[:pk.params.n])
pk.shake.Write(address.bytes())
pk.shake.Write(m1[:pk.params.n])
pk.shake.Read(out[:pk.params.n])
}
func (shakeOperations) h(pk *PublicKey, address adrsOperations, m1, m2, out []byte) {
pk.shake.Reset()
pk.shake.Write(pk.seed[:pk.params.n])
pk.shake.Write(address.bytes())
pk.shake.Write(m1[:pk.params.n])
pk.shake.Write(m2[:pk.params.n])
pk.shake.Read(out[:pk.params.n])
}
func (shakeOperations) t(pk *PublicKey, address adrsOperations, ml, out []byte) {
pk.shake.Reset()
pk.shake.Write(pk.seed[:pk.params.n])
pk.shake.Write(address.bytes())
pk.shake.Write(ml)
pk.shake.Read(out[:pk.params.n])
}
func (shakeOperations) hMsg(pk *PublicKey, R, mPrefix, M, out []byte) {
pk.shake.Reset()
pk.shake.Write(R[:pk.params.n])
pk.shake.Write(pk.seed[:pk.params.n])
pk.shake.Write(pk.root[:pk.params.n])
pk.shake.Write(mPrefix)
pk.shake.Write(M)
pk.shake.Read(out[:pk.params.m])
}
func (shakeOperations) prf(sk *PrivateKey, address adrsOperations, out []byte) {
sk.shake.Reset()
sk.shake.Write(sk.PublicKey.seed[:sk.params.n])
sk.shake.Write(address.bytes())
sk.shake.Write(sk.seed[:sk.params.n])
sk.shake.Read(out[:sk.params.n])
}
func (shakeOperations) prfMsg(sk *PrivateKey, optRand, mPrefix, m, out []byte) {
sk.shake.Reset()
sk.shake.Write(sk.prf[:sk.params.n])
sk.shake.Write(optRand)
sk.shake.Write(mPrefix)
sk.shake.Write(m)
sk.shake.Read(out[:sk.params.n])
}
type sha2Operations struct{}
func (sha2Operations) f(pk *PublicKey, address adrsOperations, m1, out []byte) {
var zeros [64]byte
pk.md.Reset()
pk.md.Write(pk.seed[:pk.params.n])
pk.md.Write(zeros[:64-pk.params.n])
pk.md.Write(address.bytes())
pk.md.Write(m1[:pk.params.n])
pk.md.Sum(zeros[:0])
copy(out, zeros[:pk.params.n])
}
func (sha2Operations) h(pk *PublicKey, address adrsOperations, m1, m2, out []byte) {
var zeros [128]byte
pk.mdBig.Reset()
pk.mdBig.Write(pk.seed[:pk.params.n])
pk.mdBig.Write(zeros[:uint32(pk.mdBig.BlockSize())-pk.params.n])
pk.mdBig.Write(address.bytes())
pk.mdBig.Write(m1[:pk.params.n])
pk.mdBig.Write(m2[:pk.params.n])
pk.mdBig.Sum(zeros[:0])
copy(out, zeros[:pk.params.n])
}
func (sha2Operations) t(pk *PublicKey, address adrsOperations, ml, out []byte) {
var zeros [128]byte
pk.mdBig.Reset()
pk.mdBig.Write(pk.seed[:pk.params.n])
pk.mdBig.Write(zeros[:uint32(pk.mdBig.BlockSize())-pk.params.n])
pk.mdBig.Write(address.bytes())
pk.mdBig.Write(ml)
pk.mdBig.Sum(zeros[:0])
copy(out, zeros[:pk.params.n])
}
func (sha2Operations) prfMsg(sk *PrivateKey, optRand, mPrefix, m, out []byte) {
var buf [128]byte
mac := hmac.New(sk.mdBigFactory, sk.prf[:sk.params.n])
mac.Write(optRand)
mac.Write(mPrefix)
mac.Write(m)
mac.Sum(buf[:0])
copy(out, buf[:sk.params.n])
}
func (sha2Operations) prf(sk *PrivateKey, address adrsOperations, out []byte) {
var zeros [128]byte
sk.md.Reset()
sk.md.Write(sk.PublicKey.seed[:sk.params.n])
sk.md.Write(zeros[:64-sk.params.n])
sk.md.Write(address.bytes())
sk.md.Write(sk.seed[:sk.params.n])
sk.md.Sum(zeros[:0])
copy(out, zeros[:sk.params.n])
}
func (sha2Operations) hMsg(pk *PublicKey, R, mPrefix, M, out []byte) {
var buf [128]byte
pk.mdBig.Reset()
pk.mdBig.Write(R[:pk.params.n])
pk.mdBig.Write(pk.seed[:pk.params.n])
pk.mdBig.Write(pk.root[:pk.params.n])
pk.mdBig.Write(mPrefix)
pk.mdBig.Write(M)
pk.mdBig.Sum(buf[:0])
mgf1([][]byte{R[:pk.params.n], pk.seed[:pk.params.n], buf[:pk.mdBig.Size()]}, pk.mdBig, out[:pk.params.m])
}
func mgf1(seeds [][]byte, h hash.Hash, out []byte) {
var counter uint32
var buff [128]byte
size := h.Size()
maskLen := len(out)
for i := 0; i < maskLen; i += size {
h.Reset()
for _, seed := range seeds {
h.Write(seed)
}
h.Write([]byte{byte(counter >> 24), byte(counter >> 16), byte(counter >> 8), byte(counter)})
h.Sum(buff[:0])
copy(out[i:], buff[:size])
counter++
}
}