forked from cloudflare/circl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
xof.go
85 lines (67 loc) · 1.9 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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Package xof provides an interface for eXtendable-Output Functions.
//
// # Available Functions
//
// SHAKE functions are defined in FIPS-202, see https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf.
// BLAKE2Xb and BLAKE2Xs are defined in https://www.blake2.net/blake2x.pdf.
package xof
import (
"io"
"github.com/linckode/circl/internal/sha3"
"github.com/linckode/circl/xof/k12"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/blake2s"
)
// XOF defines the interface to hash functions that support arbitrary-length output.
type XOF interface {
// Write absorbs more data into the XOF's state. It panics if called
// after Read.
io.Writer
// Read reads more output from the XOF. It returns io.EOF if the limit
// has been reached.
io.Reader
// Clone returns a copy of the XOF in its current state.
Clone() XOF
// Reset restores the XOF to its initial state and discards all data appended by Write.
Reset()
}
type ID uint
const (
SHAKE128 ID = iota + 1
SHAKE256
BLAKE2XB
BLAKE2XS
K12D10
)
func (x ID) New() XOF {
switch x {
case SHAKE128:
s := sha3.NewShake128()
return shakeBody{&s}
case SHAKE256:
s := sha3.NewShake256()
return shakeBody{&s}
case BLAKE2XB:
x, _ := blake2b.NewXOF(blake2b.OutputLengthUnknown, nil)
return blake2xb{x}
case BLAKE2XS:
x, _ := blake2s.NewXOF(blake2s.OutputLengthUnknown, nil)
return blake2xs{x}
case K12D10:
x := k12.NewDraft10([]byte{})
return k12d10{&x}
default:
panic("crypto: requested unavailable XOF function")
}
}
type shakeBody struct{ sha3.ShakeHash }
func (s shakeBody) Clone() XOF { return shakeBody{s.ShakeHash.Clone()} }
type blake2xb struct{ blake2b.XOF }
func (s blake2xb) Clone() XOF { return blake2xb{s.XOF.Clone()} }
type blake2xs struct{ blake2s.XOF }
func (s blake2xs) Clone() XOF { return blake2xs{s.XOF.Clone()} }
type k12d10 struct{ *k12.State }
func (s k12d10) Clone() XOF {
x := s.State.Clone()
return k12d10{&x}
}