forked from slon/shad-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpsycher_test.go
107 lines (85 loc) · 1.84 KB
/
psycher_test.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
98
99
100
101
102
103
104
105
106
107
//go:build !change
package psycher
import (
"crypto/cipher"
"crypto/rand"
"slices"
"testing"
"github.com/stretchr/testify/require"
)
type slowCipher struct {
keys [][]byte
}
var _ cipher.Block = (*slowCipher)(nil)
func (c slowCipher) BlockSize() int {
return 16
}
func (c slowCipher) Encrypt(dst, src []byte) {
var idx int
for srcI, b := range src {
for ; b != 0; b /= 2 {
if b%2 == 1 {
for i := range dst {
dst[i] ^= c.keys[idx][i]
}
}
idx++
}
idx = (srcI + 1) * 8
}
}
func (c slowCipher) Decrypt(_, _ []byte) {
panic("something nerdy")
}
func genKeys() [][]byte {
var keys [][]byte
for i := range 128 {
keys = append(keys, make([]byte, 16))
_, _ = rand.Read(keys[i])
}
return keys
}
func TestCorrectness(t *testing.T) {
keys := genKeys()
solCipher, correctCipher := New(keys), slowCipher{keys: keys}
for range 1000 {
src := make([]byte, 16)
_, _ = rand.Read(src)
srcCopy := slices.Clone(src)
dst1, dst2 := make([]byte, 16), make([]byte, 16)
correctCipher.Encrypt(dst1, src)
solCipher.Encrypt(dst2, srcCopy)
require.Equal(t, src, srcCopy, "shouldn't modify src")
require.Equal(t, dst1, dst2, "wrong Encrypt output")
}
}
func benchCipher(b *testing.B, constructor func([][]byte) cipher.Block) {
keys := genKeys()
c := constructor(keys)
const blocksLen = 1_000_000
var blocks [][]byte
for range blocksLen {
src := make([]byte, 16)
_, _ = rand.Read(src)
blocks = append(blocks, src)
}
dst := make([]byte, 16)
b.ReportAllocs()
b.SetBytes(16)
b.ResetTimer()
for i := range b.N {
c.Encrypt(dst, blocks[i%blocksLen])
}
}
func BenchmarkSlowCipher(b *testing.B) {
benchCipher(b, func(keys [][]byte) cipher.Block {
c := slowCipher{keys: keys}
return c
})
}
func BenchmarkCipher(b *testing.B) {
benchCipher(b, func(keys [][]byte) cipher.Block {
c := New(keys)
return c
})
}