| | |
| | |
| | |
| |
|
| | package subtle |
| |
|
| | import ( |
| | "testing" |
| | "testing/quick" |
| | ) |
| |
|
| | type TestConstantTimeCompareStruct struct { |
| | a, b []byte |
| | out int |
| | } |
| |
|
| | var testConstantTimeCompareData = []TestConstantTimeCompareStruct{ |
| | {[]byte{}, []byte{}, 1}, |
| | {[]byte{0x11}, []byte{0x11}, 1}, |
| | {[]byte{0x12}, []byte{0x11}, 0}, |
| | {[]byte{0x11}, []byte{0x11, 0x12}, 0}, |
| | {[]byte{0x11, 0x12}, []byte{0x11}, 0}, |
| | } |
| |
|
| | func TestConstantTimeCompare(t *testing.T) { |
| | for i, test := range testConstantTimeCompareData { |
| | if r := ConstantTimeCompare(test.a, test.b); r != test.out { |
| | t.Errorf("#%d bad result (got %x, want %x)", i, r, test.out) |
| | } |
| | } |
| | } |
| |
|
| | type TestConstantTimeByteEqStruct struct { |
| | a, b uint8 |
| | out int |
| | } |
| |
|
| | var testConstandTimeByteEqData = []TestConstantTimeByteEqStruct{ |
| | {0, 0, 1}, |
| | {0, 1, 0}, |
| | {1, 0, 0}, |
| | {0xff, 0xff, 1}, |
| | {0xff, 0xfe, 0}, |
| | } |
| |
|
| | func byteEq(a, b uint8) int { |
| | if a == b { |
| | return 1 |
| | } |
| | return 0 |
| | } |
| |
|
| | func TestConstantTimeByteEq(t *testing.T) { |
| | for i, test := range testConstandTimeByteEqData { |
| | if r := ConstantTimeByteEq(test.a, test.b); r != test.out { |
| | t.Errorf("#%d bad result (got %x, want %x)", i, r, test.out) |
| | } |
| | } |
| | err := quick.CheckEqual(ConstantTimeByteEq, byteEq, nil) |
| | if err != nil { |
| | t.Error(err) |
| | } |
| | } |
| |
|
| | func eq(a, b int32) int { |
| | if a == b { |
| | return 1 |
| | } |
| | return 0 |
| | } |
| |
|
| | func TestConstantTimeEq(t *testing.T) { |
| | err := quick.CheckEqual(ConstantTimeEq, eq, nil) |
| | if err != nil { |
| | t.Error(err) |
| | } |
| | } |
| |
|
| | func makeCopy(v int, x, y []byte) []byte { |
| | if len(x) > len(y) { |
| | x = x[:len(y)] |
| | } else { |
| | y = y[:len(x)] |
| | } |
| | if v == 1 { |
| | copy(x, y) |
| | } |
| | return x |
| | } |
| |
|
| | func constantTimeCopyWrapper(v int, x, y []byte) []byte { |
| | if len(x) > len(y) { |
| | x = x[:len(y)] |
| | } else { |
| | y = y[:len(x)] |
| | } |
| | v &= 1 |
| | ConstantTimeCopy(v, x, y) |
| | return x |
| | } |
| |
|
| | func TestConstantTimeCopy(t *testing.T) { |
| | err := quick.CheckEqual(constantTimeCopyWrapper, makeCopy, nil) |
| | if err != nil { |
| | t.Error(err) |
| | } |
| | } |
| |
|
| | var lessOrEqTests = []struct { |
| | x, y, result int |
| | }{ |
| | {0, 0, 1}, |
| | {1, 0, 0}, |
| | {0, 1, 1}, |
| | {10, 20, 1}, |
| | {20, 10, 0}, |
| | {10, 10, 1}, |
| | } |
| |
|
| | func TestConstantTimeLessOrEq(t *testing.T) { |
| | for i, test := range lessOrEqTests { |
| | result := ConstantTimeLessOrEq(test.x, test.y) |
| | if result != test.result { |
| | t.Errorf("#%d: %d <= %d gave %d, expected %d", i, test.x, test.y, result, test.result) |
| | } |
| | } |
| | } |
| |
|
| | var benchmarkGlobal uint8 |
| |
|
| | func BenchmarkConstantTimeSelect(b *testing.B) { |
| | x := int(benchmarkGlobal) |
| | var y, z int |
| |
|
| | for range b.N { |
| | y, z, x = ConstantTimeSelect(x, y, z), y, z |
| | } |
| |
|
| | benchmarkGlobal = uint8(x) |
| | } |
| |
|
| | func BenchmarkConstantTimeByteEq(b *testing.B) { |
| | var x, y uint8 |
| |
|
| | for i := 0; i < b.N; i++ { |
| | x, y = uint8(ConstantTimeByteEq(x, y)), x |
| | } |
| |
|
| | benchmarkGlobal = x |
| | } |
| |
|
| | func BenchmarkConstantTimeEq(b *testing.B) { |
| | var x, y int |
| |
|
| | for i := 0; i < b.N; i++ { |
| | x, y = ConstantTimeEq(int32(x), int32(y)), x |
| | } |
| |
|
| | benchmarkGlobal = uint8(x) |
| | } |
| |
|
| | func BenchmarkConstantTimeLessOrEq(b *testing.B) { |
| | var x, y int |
| |
|
| | for i := 0; i < b.N; i++ { |
| | x, y = ConstantTimeLessOrEq(x, y), x |
| | } |
| |
|
| | benchmarkGlobal = uint8(x) |
| | } |
| |
|