1
2
3
4
5 package subtle_test
6
7 import (
8 "bytes"
9 "crypto/rand"
10 . "crypto/subtle"
11 "fmt"
12 "io"
13 "testing"
14 )
15
16 func TestXORBytes(t *testing.T) {
17 for n := 1; n <= 1024; n++ {
18 if n > 16 && testing.Short() {
19 n += n >> 3
20 }
21 for alignP := 0; alignP < 8; alignP++ {
22 for alignQ := 0; alignQ < 8; alignQ++ {
23 for alignD := 0; alignD < 8; alignD++ {
24 p := make([]byte, alignP+n, alignP+n+10)[alignP:]
25 q := make([]byte, alignQ+n, alignQ+n+10)[alignQ:]
26 if n&1 != 0 {
27 p = p[:n]
28 } else {
29 q = q[:n]
30 }
31 if _, err := io.ReadFull(rand.Reader, p); err != nil {
32 t.Fatal(err)
33 }
34 if _, err := io.ReadFull(rand.Reader, q); err != nil {
35 t.Fatal(err)
36 }
37
38 d := make([]byte, alignD+n, alignD+n+10)
39 for i := range d {
40 d[i] = 0xdd
41 }
42 want := make([]byte, len(d), cap(d))
43 copy(want[:cap(want)], d[:cap(d)])
44 for i := 0; i < n; i++ {
45 want[alignD+i] = p[i] ^ q[i]
46 }
47
48 if XORBytes(d[alignD:], p, q); !bytes.Equal(d, want) {
49 t.Fatalf("n=%d alignP=%d alignQ=%d alignD=%d:\n\tp = %x\n\tq = %x\n\td = %x\n\twant %x\n", n, alignP, alignQ, alignD, p, q, d, want)
50 }
51 }
52 }
53 }
54 }
55 }
56
57 func TestXorBytesPanic(t *testing.T) {
58 mustPanic(t, "subtle.XORBytes: dst too short", func() {
59 XORBytes(nil, make([]byte, 1), make([]byte, 1))
60 })
61 mustPanic(t, "subtle.XORBytes: dst too short", func() {
62 XORBytes(make([]byte, 1), make([]byte, 2), make([]byte, 3))
63 })
64 }
65
66 func BenchmarkXORBytes(b *testing.B) {
67 dst := make([]byte, 1<<15)
68 data0 := make([]byte, 1<<15)
69 data1 := make([]byte, 1<<15)
70 sizes := []int64{1 << 3, 1 << 7, 1 << 11, 1 << 15}
71 for _, size := range sizes {
72 b.Run(fmt.Sprintf("%dBytes", size), func(b *testing.B) {
73 s0 := data0[:size]
74 s1 := data1[:size]
75 b.SetBytes(int64(size))
76 for i := 0; i < b.N; i++ {
77 XORBytes(dst, s0, s1)
78 }
79 })
80 }
81 }
82
83 func mustPanic(t *testing.T, expected string, f func()) {
84 t.Helper()
85 defer func() {
86 switch msg := recover().(type) {
87 case nil:
88 t.Errorf("expected panic(%q), but did not panic", expected)
89 case string:
90 if msg != expected {
91 t.Errorf("expected panic(%q), but got panic(%q)", expected, msg)
92 }
93 default:
94 t.Errorf("expected panic(%q), but got panic(%T%v)", expected, msg, msg)
95 }
96 }()
97 f()
98 }
99
View as plain text