forked from dedis/kyber
-
Notifications
You must be signed in to change notification settings - Fork 10
/
blake.go
85 lines (74 loc) · 1.73 KB
/
blake.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 blake2xs provides an implementation of kyber.XOF based on the
// Blake2xs construction.
package blake2xs
import (
"github.com/drand/kyber"
"golang.org/x/crypto/blake2s"
)
type xof struct {
impl blake2s.XOF
// key is here to not make excess garbage during repeated calls
// to XORKeyStream.
key []byte
}
// New creates a new XOF using the blake2s hash.
func New(seed []byte) kyber.XOF {
seed1 := seed
var seed2 []byte
if len(seed) > blake2s.Size {
seed1 = seed[0:blake2s.Size]
seed2 = seed[blake2s.Size:]
}
b, err := blake2s.NewXOF(blake2s.OutputLengthUnknown, seed1)
if err != nil {
panic("blake2s.NewXOF should not return error: " + err.Error())
}
if seed2 != nil {
_, err := b.Write(seed2)
if err != nil {
panic("blake2s.XOF.Write should not return error: " + err.Error())
}
}
return &xof{impl: b}
}
func (x *xof) Clone() kyber.XOF {
return &xof{impl: x.impl.Clone()}
}
func (x *xof) Read(dst []byte) (int, error) {
return x.impl.Read(dst)
}
func (x *xof) Write(src []byte) (int, error) {
return x.impl.Write(src)
}
func (x *xof) Reseed() {
// Use New to create a new one seeded with output from the old one.
if len(x.key) < 128 {
x.key = make([]byte, 128)
} else {
x.key = x.key[0:128]
}
x.Read(x.key)
y := New(x.key)
// Steal the XOF implementation, and put it inside of x.
x.impl = y.(*xof).impl
}
func (x *xof) XORKeyStream(dst, src []byte) {
if len(dst) < len(src) {
panic("dst too short")
}
if len(x.key) < len(src) {
x.key = make([]byte, len(src))
} else {
x.key = x.key[0:len(src)]
}
n, err := x.Read(x.key)
if err != nil {
panic("blake xof error: " + err.Error())
}
if n != len(src) {
panic("short read on key")
}
for i := range src {
dst[i] = src[i] ^ x.key[i]
}
}