-
Notifications
You must be signed in to change notification settings - Fork 0
/
keyed.go
97 lines (76 loc) · 1.98 KB
/
keyed.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
86
87
88
89
90
91
92
93
94
95
96
97
package xoodyak
type KeyedXoodyak struct {
xoodyak Xoodyak
}
func NewKeyed(key, id, counter []byte) *KeyedXoodyak {
if len(key) == 0 {
panic("xoodyak: key is empty")
}
x := KeyedXoodyak{
Xoodyak{
rates: struct {
absorb int
squeeze int
}{
absorb: rateKeyedInput,
squeeze: rateKeyedOutput,
},
isPhaseUp: true,
isModeHash: false,
},
}
var buffer []byte
buffer = append(buffer, key...)
buffer = append(buffer, id...)
buffer = append(buffer, byte(len(id)))
if !(len(buffer) <= rateKeyedInput) {
panic("xoodyak: length of key+id exceeds 43 bytes")
}
x.xoodyak.absorbAny(buffer, x.xoodyak.rates.absorb, flagAbsorbKey)
if len(counter) > 0 {
x.xoodyak.absorbAny(counter, rateCounter, flagZero)
}
return &x
}
func (x *KeyedXoodyak) crypt(input, output []byte, decrypt bool) []byte {
flag := flagCrypt
offset := len(output)
for {
block := input[:min(rateKeyedOutput, len(input))]
input = input[len(block):]
x.xoodyak.up(nil, 0, flag)
flag = flagZero
for i, b := range block {
output = append(output, b^x.xoodyak.state[i])
}
if decrypt {
x.xoodyak.down(output[offset:offset+len(block)], flagZero)
} else {
x.xoodyak.down(block, flagZero)
}
offset += len(block)
if len(input) == 0 {
break
}
}
return output
}
func (x *KeyedXoodyak) Absorb(input []byte) {
x.xoodyak.Absorb(input)
}
func (x *KeyedXoodyak) Encrypt(plaintext, ciphertext []byte) []byte {
return x.crypt(plaintext, ciphertext, false)
}
func (x *KeyedXoodyak) Decrypt(ciphertext, plaintext []byte) []byte {
return x.crypt(ciphertext, plaintext, true)
}
func (x *KeyedXoodyak) Squeeze(output []byte, count int) []byte {
return x.xoodyak.Squeeze(output, count)
}
func (x *KeyedXoodyak) SqueezeKey(output []byte, count int) []byte {
return x.xoodyak.squeezeAny(output, count, flagSqueezeKey)
}
func (x *KeyedXoodyak) Ratchet() {
buffer := x.xoodyak.squeezeAny(nil, rateRatchet, flagRatchet)
x.xoodyak.absorbAny(buffer, x.xoodyak.rates.absorb, flagZero)
}