-
Notifications
You must be signed in to change notification settings - Fork 0
/
xof.go
56 lines (43 loc) · 1.5 KB
/
xof.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// SPDX-License-Identifier: MIT
//
// Copyright (C) 2024 Daniel Bourdrez. All Rights Reserved.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree or at
// https://spdx.org/licenses/MIT.html
// Package internal values, structures, and functions that are not part of the public API.
package internal
import (
"errors"
"math"
"github.com/bytemare/hash"
)
var errXOFHighOutput = errors.New("XOF dst hashing is too long")
// ExpandXOF implements expand_message_xof as specified in RFC 9380 section 5.3.2.
func ExpandXOF(ext *hash.ExtendableHash, input, dst []byte, length uint) []byte {
if length > math.MaxUint16 {
panic(errLengthTooLarge)
}
dst = VetXofDST(ext, dst)
len2o := I2osp(length, 2)
dstLen2o := I2osp(uint(len(dst)), 1)
return ext.Hash(length, input, len2o, dst, dstLen2o)
}
// VetXofDST computes a shorter tag for dst if the tag length exceeds 255 bytes.
func VetXofDST(x *hash.ExtendableHash, dst []byte) []byte {
if len(dst) <= dstMaxLength {
return dst
}
size := checkXOFSecurityLevel(x)
return x.Hash(size, []byte(dstLongPrefix), dst)
}
// checkXOFSecurityLength return the desired output length to shorten the DST, or panics if the XOFs security level is
// too high for the expected output length.
func checkXOFSecurityLevel(x *hash.ExtendableHash) uint {
k := x.Algorithm().SecurityLevel()
size := uint(math.Ceil(float64(2*k) / float64(8)))
if size > uint(x.Size()*8) {
panic(errXOFHighOutput)
}
return size
}