mirror of
https://github.com/emmansun/gmsm.git
synced 2025-06-03 01:44:54 +00:00
65 lines
1.9 KiB
Go
65 lines
1.9 KiB
Go
// 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/subtle"
|
|
|
|
// htSign generates a hypertree signature.
|
|
//
|
|
// See FIPS 205 Algorithm 12 ht_sign
|
|
func (sk *PrivateKey) htSign(pkFors []byte, treeIdx uint64, leafIdx uint32, signature []byte) {
|
|
adrs := sk.addressCreator()
|
|
|
|
sigLenPerLayer := (sk.params.hm + sk.params.len) * sk.params.n
|
|
mask := sk.params.leafIdxMask()
|
|
|
|
var rootBuf [MAX_N]byte
|
|
root := rootBuf[:sk.params.n]
|
|
copy(root, pkFors)
|
|
tmpBuf := make([]byte, sk.params.n*sk.params.len)
|
|
for j := range sk.params.d {
|
|
adrs.setLayerAddress(j)
|
|
adrs.setTreeAddress(treeIdx)
|
|
sk.xmssSign(root, tmpBuf, leafIdx, adrs, signature)
|
|
|
|
if j < sk.params.d-1 {
|
|
sk.xmssPkFromSig(leafIdx, signature, root, tmpBuf, adrs, root)
|
|
// hm least significant bits of treeIdx
|
|
leafIdx = uint32(treeIdx & mask)
|
|
// remove least significant hm bits from treeIdx
|
|
treeIdx >>= sk.params.hm
|
|
signature = signature[sigLenPerLayer:]
|
|
}
|
|
}
|
|
}
|
|
|
|
// htVerify verifies a hypertree signature.
|
|
//
|
|
// See FIPS 205 Algorithm 13 ht_verify
|
|
func (pk *PublicKey) htVerify(pkFors []byte, signature []byte, treeIdx uint64, leafIdx uint32) bool {
|
|
adrs := pk.addressCreator()
|
|
|
|
sigLenPerLayer := (pk.params.hm + pk.params.len) * pk.params.n
|
|
mask := pk.params.leafIdxMask()
|
|
|
|
var rootBuf [MAX_N]byte
|
|
root := rootBuf[:pk.params.n]
|
|
copy(root, pkFors)
|
|
tmpBuf := make([]byte, pk.params.n*pk.params.len)
|
|
for j := range pk.params.d {
|
|
adrs.setLayerAddress(j)
|
|
adrs.setTreeAddress(treeIdx)
|
|
pk.xmssPkFromSig(leafIdx, signature, root, tmpBuf, adrs, root)
|
|
// hm least significant bits of treeIdx
|
|
leafIdx = uint32(treeIdx & mask)
|
|
// remove least significant hm bits from treeIdx
|
|
treeIdx >>= pk.params.hm
|
|
signature = signature[sigLenPerLayer:]
|
|
}
|
|
return subtle.ConstantTimeCompare(pk.root[:pk.params.n], root) == 1
|
|
}
|