github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/crypto/subtle/xor_test.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 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 min(a, b []byte) int { 67 n := len(a) 68 if len(b) < n { 69 n = len(b) 70 } 71 return n 72 } 73 74 func BenchmarkXORBytes(b *testing.B) { 75 dst := make([]byte, 1<<15) 76 data0 := make([]byte, 1<<15) 77 data1 := make([]byte, 1<<15) 78 sizes := []int64{1 << 3, 1 << 7, 1 << 11, 1 << 15} 79 for _, size := range sizes { 80 b.Run(fmt.Sprintf("%dBytes", size), func(b *testing.B) { 81 s0 := data0[:size] 82 s1 := data1[:size] 83 b.SetBytes(int64(size)) 84 for i := 0; i < b.N; i++ { 85 XORBytes(dst, s0, s1) 86 } 87 }) 88 } 89 } 90 91 func mustPanic(t *testing.T, expected string, f func()) { 92 t.Helper() 93 defer func() { 94 switch msg := recover().(type) { 95 case nil: 96 t.Errorf("expected panic(%q), but did not panic", expected) 97 case string: 98 if msg != expected { 99 t.Errorf("expected panic(%q), but got panic(%q)", expected, msg) 100 } 101 default: 102 t.Errorf("expected panic(%q), but got panic(%T%v)", expected, msg, msg) 103 } 104 }() 105 f() 106 }