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