You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

133 lines
2.9 KiB

  1. // Copyright 2012 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. package poly1305
  5. import (
  6. "encoding/hex"
  7. "flag"
  8. "testing"
  9. "unsafe"
  10. )
  11. var stressFlag = flag.Bool("stress", false, "run slow stress tests")
  12. type test struct {
  13. in string
  14. key string
  15. tag string
  16. }
  17. func (t *test) Input() []byte {
  18. in, err := hex.DecodeString(t.in)
  19. if err != nil {
  20. panic(err)
  21. }
  22. return in
  23. }
  24. func (t *test) Key() [32]byte {
  25. buf, err := hex.DecodeString(t.key)
  26. if err != nil {
  27. panic(err)
  28. }
  29. var key [32]byte
  30. copy(key[:], buf[:32])
  31. return key
  32. }
  33. func (t *test) Tag() [16]byte {
  34. buf, err := hex.DecodeString(t.tag)
  35. if err != nil {
  36. panic(err)
  37. }
  38. var tag [16]byte
  39. copy(tag[:], buf[:16])
  40. return tag
  41. }
  42. func testSum(t *testing.T, unaligned bool, sumImpl func(tag *[TagSize]byte, msg []byte, key *[32]byte)) {
  43. var tag [16]byte
  44. for i, v := range testData {
  45. in := v.Input()
  46. if unaligned {
  47. in = unalignBytes(in)
  48. }
  49. key := v.Key()
  50. sumImpl(&tag, in, &key)
  51. if tag != v.Tag() {
  52. t.Errorf("%d: expected %x, got %x", i, v.Tag(), tag[:])
  53. }
  54. }
  55. }
  56. func TestBurnin(t *testing.T) {
  57. // This test can be used to sanity-check significant changes. It can
  58. // take about many minutes to run, even on fast machines. It's disabled
  59. // by default.
  60. if !*stressFlag {
  61. t.Skip("skipping without -stress")
  62. }
  63. var key [32]byte
  64. var input [25]byte
  65. var output [16]byte
  66. for i := range key {
  67. key[i] = 1
  68. }
  69. for i := range input {
  70. input[i] = 2
  71. }
  72. for i := uint64(0); i < 1e10; i++ {
  73. Sum(&output, input[:], &key)
  74. copy(key[0:], output[:])
  75. copy(key[16:], output[:])
  76. copy(input[:], output[:])
  77. copy(input[16:], output[:])
  78. }
  79. const expected = "5e3b866aea0b636d240c83c428f84bfa"
  80. if got := hex.EncodeToString(output[:]); got != expected {
  81. t.Errorf("expected %s, got %s", expected, got)
  82. }
  83. }
  84. func TestSum(t *testing.T) { testSum(t, false, Sum) }
  85. func TestSumUnaligned(t *testing.T) { testSum(t, true, Sum) }
  86. func TestSumGeneric(t *testing.T) { testSum(t, false, sumGeneric) }
  87. func TestSumGenericUnaligned(t *testing.T) { testSum(t, true, sumGeneric) }
  88. func benchmark(b *testing.B, size int, unaligned bool) {
  89. var out [16]byte
  90. var key [32]byte
  91. in := make([]byte, size)
  92. if unaligned {
  93. in = unalignBytes(in)
  94. }
  95. b.SetBytes(int64(len(in)))
  96. b.ResetTimer()
  97. for i := 0; i < b.N; i++ {
  98. Sum(&out, in, &key)
  99. }
  100. }
  101. func Benchmark64(b *testing.B) { benchmark(b, 64, false) }
  102. func Benchmark1K(b *testing.B) { benchmark(b, 1024, false) }
  103. func Benchmark64Unaligned(b *testing.B) { benchmark(b, 64, true) }
  104. func Benchmark1KUnaligned(b *testing.B) { benchmark(b, 1024, true) }
  105. func Benchmark2M(b *testing.B) { benchmark(b, 2097152, true) }
  106. func unalignBytes(in []byte) []byte {
  107. out := make([]byte, len(in)+1)
  108. if uintptr(unsafe.Pointer(&out[0]))&(unsafe.Alignof(uint32(0))-1) == 0 {
  109. out = out[1:]
  110. } else {
  111. out = out[:len(in)]
  112. }
  113. copy(out, in)
  114. return out
  115. }