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.

182 lines
4.4 KiB

  1. // Copyright 2016 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 chacha20poly1305
  5. import (
  6. "bytes"
  7. cr "crypto/rand"
  8. "encoding/hex"
  9. mr "math/rand"
  10. "testing"
  11. )
  12. func TestVectors(t *testing.T) {
  13. for i, test := range chacha20Poly1305Tests {
  14. key, _ := hex.DecodeString(test.key)
  15. nonce, _ := hex.DecodeString(test.nonce)
  16. ad, _ := hex.DecodeString(test.aad)
  17. plaintext, _ := hex.DecodeString(test.plaintext)
  18. aead, err := New(key)
  19. if err != nil {
  20. t.Fatal(err)
  21. }
  22. ct := aead.Seal(nil, nonce, plaintext, ad)
  23. if ctHex := hex.EncodeToString(ct); ctHex != test.out {
  24. t.Errorf("#%d: got %s, want %s", i, ctHex, test.out)
  25. continue
  26. }
  27. plaintext2, err := aead.Open(nil, nonce, ct, ad)
  28. if err != nil {
  29. t.Errorf("#%d: Open failed", i)
  30. continue
  31. }
  32. if !bytes.Equal(plaintext, plaintext2) {
  33. t.Errorf("#%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext)
  34. continue
  35. }
  36. if len(ad) > 0 {
  37. alterAdIdx := mr.Intn(len(ad))
  38. ad[alterAdIdx] ^= 0x80
  39. if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
  40. t.Errorf("#%d: Open was successful after altering additional data", i)
  41. }
  42. ad[alterAdIdx] ^= 0x80
  43. }
  44. alterNonceIdx := mr.Intn(aead.NonceSize())
  45. nonce[alterNonceIdx] ^= 0x80
  46. if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
  47. t.Errorf("#%d: Open was successful after altering nonce", i)
  48. }
  49. nonce[alterNonceIdx] ^= 0x80
  50. alterCtIdx := mr.Intn(len(ct))
  51. ct[alterCtIdx] ^= 0x80
  52. if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
  53. t.Errorf("#%d: Open was successful after altering ciphertext", i)
  54. }
  55. ct[alterCtIdx] ^= 0x80
  56. }
  57. }
  58. func TestRandom(t *testing.T) {
  59. // Some random tests to verify Open(Seal) == Plaintext
  60. for i := 0; i < 256; i++ {
  61. var nonce [12]byte
  62. var key [32]byte
  63. al := mr.Intn(128)
  64. pl := mr.Intn(16384)
  65. ad := make([]byte, al)
  66. plaintext := make([]byte, pl)
  67. cr.Read(key[:])
  68. cr.Read(nonce[:])
  69. cr.Read(ad)
  70. cr.Read(plaintext)
  71. aead, err := New(key[:])
  72. if err != nil {
  73. t.Fatal(err)
  74. }
  75. ct := aead.Seal(nil, nonce[:], plaintext, ad)
  76. plaintext2, err := aead.Open(nil, nonce[:], ct, ad)
  77. if err != nil {
  78. t.Errorf("Random #%d: Open failed", i)
  79. continue
  80. }
  81. if !bytes.Equal(plaintext, plaintext2) {
  82. t.Errorf("Random #%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext)
  83. continue
  84. }
  85. if len(ad) > 0 {
  86. alterAdIdx := mr.Intn(len(ad))
  87. ad[alterAdIdx] ^= 0x80
  88. if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
  89. t.Errorf("Random #%d: Open was successful after altering additional data", i)
  90. }
  91. ad[alterAdIdx] ^= 0x80
  92. }
  93. alterNonceIdx := mr.Intn(aead.NonceSize())
  94. nonce[alterNonceIdx] ^= 0x80
  95. if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
  96. t.Errorf("Random #%d: Open was successful after altering nonce", i)
  97. }
  98. nonce[alterNonceIdx] ^= 0x80
  99. alterCtIdx := mr.Intn(len(ct))
  100. ct[alterCtIdx] ^= 0x80
  101. if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
  102. t.Errorf("Random #%d: Open was successful after altering ciphertext", i)
  103. }
  104. ct[alterCtIdx] ^= 0x80
  105. }
  106. }
  107. func benchamarkChaCha20Poly1305Seal(b *testing.B, buf []byte) {
  108. b.SetBytes(int64(len(buf)))
  109. var key [32]byte
  110. var nonce [12]byte
  111. var ad [13]byte
  112. var out []byte
  113. aead, _ := New(key[:])
  114. b.ResetTimer()
  115. for i := 0; i < b.N; i++ {
  116. out = aead.Seal(out[:0], nonce[:], buf[:], ad[:])
  117. }
  118. }
  119. func benchamarkChaCha20Poly1305Open(b *testing.B, buf []byte) {
  120. b.SetBytes(int64(len(buf)))
  121. var key [32]byte
  122. var nonce [12]byte
  123. var ad [13]byte
  124. var ct []byte
  125. var out []byte
  126. aead, _ := New(key[:])
  127. ct = aead.Seal(ct[:0], nonce[:], buf[:], ad[:])
  128. b.ResetTimer()
  129. for i := 0; i < b.N; i++ {
  130. out, _ = aead.Open(out[:0], nonce[:], ct[:], ad[:])
  131. }
  132. }
  133. func BenchmarkChacha20Poly1305Open_64(b *testing.B) {
  134. benchamarkChaCha20Poly1305Open(b, make([]byte, 64))
  135. }
  136. func BenchmarkChacha20Poly1305Seal_64(b *testing.B) {
  137. benchamarkChaCha20Poly1305Seal(b, make([]byte, 64))
  138. }
  139. func BenchmarkChacha20Poly1305Open_1350(b *testing.B) {
  140. benchamarkChaCha20Poly1305Open(b, make([]byte, 1350))
  141. }
  142. func BenchmarkChacha20Poly1305Seal_1350(b *testing.B) {
  143. benchamarkChaCha20Poly1305Seal(b, make([]byte, 1350))
  144. }
  145. func BenchmarkChacha20Poly1305Open_8K(b *testing.B) {
  146. benchamarkChaCha20Poly1305Open(b, make([]byte, 8*1024))
  147. }
  148. func BenchmarkChacha20Poly1305Seal_8K(b *testing.B) {
  149. benchamarkChaCha20Poly1305Seal(b, make([]byte, 8*1024))
  150. }