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.

229 lines
7.2 KiB

  1. // Copyright 2009 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 xtea
  5. import (
  6. "testing"
  7. )
  8. // A sample test key for when we just want to initialize a cipher
  9. var testKey = []byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}
  10. // Test that the block size for XTEA is correct
  11. func TestBlocksize(t *testing.T) {
  12. if BlockSize != 8 {
  13. t.Errorf("BlockSize constant - expected 8, got %d", BlockSize)
  14. return
  15. }
  16. c, err := NewCipher(testKey)
  17. if err != nil {
  18. t.Errorf("NewCipher(%d bytes) = %s", len(testKey), err)
  19. return
  20. }
  21. result := c.BlockSize()
  22. if result != 8 {
  23. t.Errorf("BlockSize function - expected 8, got %d", result)
  24. return
  25. }
  26. }
  27. // A series of test values to confirm that the Cipher.table array was initialized correctly
  28. var testTable = []uint32{
  29. 0x00112233, 0x6B1568B8, 0xE28CE030, 0xC5089E2D, 0xC5089E2D, 0x1EFBD3A2, 0xA7845C2A, 0x78EF0917,
  30. 0x78EF0917, 0x172682D0, 0x5B6AC714, 0x822AC955, 0x3DE68511, 0xDC1DFECA, 0x2062430E, 0x3611343F,
  31. 0xF1CCEFFB, 0x900469B4, 0xD448ADF8, 0x2E3BE36D, 0xB6C46BF5, 0x994029F2, 0x994029F2, 0xF3335F67,
  32. 0x6AAAD6DF, 0x4D2694DC, 0x4D2694DC, 0xEB5E0E95, 0x2FA252D9, 0x4551440A, 0x121E10D6, 0xB0558A8F,
  33. 0xE388BDC3, 0x0A48C004, 0xC6047BC0, 0x643BF579, 0xA88039BD, 0x02736F32, 0x8AFBF7BA, 0x5C66A4A7,
  34. 0x5C66A4A7, 0xC76AEB2C, 0x3EE262A4, 0x215E20A1, 0x215E20A1, 0x7B515616, 0x03D9DE9E, 0x1988CFCF,
  35. 0xD5448B8B, 0x737C0544, 0xB7C04988, 0xDE804BC9, 0x9A3C0785, 0x3873813E, 0x7CB7C582, 0xD6AAFAF7,
  36. 0x4E22726F, 0x309E306C, 0x309E306C, 0x8A9165E1, 0x1319EE69, 0xF595AC66, 0xF595AC66, 0x4F88E1DB,
  37. }
  38. // Test that the cipher context is initialized correctly
  39. func TestCipherInit(t *testing.T) {
  40. c, err := NewCipher(testKey)
  41. if err != nil {
  42. t.Errorf("NewCipher(%d bytes) = %s", len(testKey), err)
  43. return
  44. }
  45. for i := 0; i < len(c.table); i++ {
  46. if c.table[i] != testTable[i] {
  47. t.Errorf("NewCipher() failed to initialize Cipher.table[%d] correctly. Expected %08X, got %08X", i, testTable[i], c.table[i])
  48. break
  49. }
  50. }
  51. }
  52. // Test that invalid key sizes return an error
  53. func TestInvalidKeySize(t *testing.T) {
  54. // Test a long key
  55. key := []byte{
  56. 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
  57. 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
  58. }
  59. _, err := NewCipher(key)
  60. if err == nil {
  61. t.Errorf("Invalid key size %d didn't result in an error.", len(key))
  62. }
  63. // Test a short key
  64. key = []byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}
  65. _, err = NewCipher(key)
  66. if err == nil {
  67. t.Errorf("Invalid key size %d didn't result in an error.", len(key))
  68. }
  69. }
  70. // Test that we can correctly decode some bytes we have encoded
  71. func TestEncodeDecode(t *testing.T) {
  72. original := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}
  73. input := original
  74. output := make([]byte, BlockSize)
  75. c, err := NewCipher(testKey)
  76. if err != nil {
  77. t.Errorf("NewCipher(%d bytes) = %s", len(testKey), err)
  78. return
  79. }
  80. // Encrypt the input block
  81. c.Encrypt(output, input)
  82. // Check that the output does not match the input
  83. differs := false
  84. for i := 0; i < len(input); i++ {
  85. if output[i] != input[i] {
  86. differs = true
  87. break
  88. }
  89. }
  90. if differs == false {
  91. t.Error("Cipher.Encrypt: Failed to encrypt the input block.")
  92. return
  93. }
  94. // Decrypt the block we just encrypted
  95. input = output
  96. output = make([]byte, BlockSize)
  97. c.Decrypt(output, input)
  98. // Check that the output from decrypt matches our initial input
  99. for i := 0; i < len(input); i++ {
  100. if output[i] != original[i] {
  101. t.Errorf("Decrypted byte %d differed. Expected %02X, got %02X\n", i, original[i], output[i])
  102. return
  103. }
  104. }
  105. }
  106. // Test Vectors
  107. type CryptTest struct {
  108. key []byte
  109. plainText []byte
  110. cipherText []byte
  111. }
  112. var CryptTests = []CryptTest{
  113. // These were sourced from http://www.freemedialibrary.com/index.php/XTEA_test_vectors
  114. {
  115. []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
  116. []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
  117. []byte{0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5},
  118. },
  119. {
  120. []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
  121. []byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41},
  122. []byte{0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8},
  123. },
  124. {
  125. []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
  126. []byte{0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f},
  127. []byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41},
  128. },
  129. {
  130. []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  131. []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
  132. []byte{0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5},
  133. },
  134. {
  135. []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  136. []byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41},
  137. []byte{0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d},
  138. },
  139. {
  140. []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  141. []byte{0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55},
  142. []byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41},
  143. },
  144. // These vectors are from http://wiki.secondlife.com/wiki/XTEA_Strong_Encryption_Implementation#Bouncy_Castle_C.23_API
  145. {
  146. []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  147. []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  148. []byte{0xDE, 0xE9, 0xD4, 0xD8, 0xF7, 0x13, 0x1E, 0xD9},
  149. },
  150. {
  151. []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  152. []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
  153. []byte{0x06, 0x5C, 0x1B, 0x89, 0x75, 0xC6, 0xA8, 0x16},
  154. },
  155. {
  156. []byte{0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A},
  157. []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  158. []byte{0x1F, 0xF9, 0xA0, 0x26, 0x1A, 0xC6, 0x42, 0x64},
  159. },
  160. {
  161. []byte{0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A},
  162. []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
  163. []byte{0x8C, 0x67, 0x15, 0x5B, 0x2E, 0xF9, 0x1E, 0xAD},
  164. },
  165. }
  166. // Test encryption
  167. func TestCipherEncrypt(t *testing.T) {
  168. for i, tt := range CryptTests {
  169. c, err := NewCipher(tt.key)
  170. if err != nil {
  171. t.Errorf("NewCipher(%d bytes), vector %d = %s", len(tt.key), i, err)
  172. continue
  173. }
  174. out := make([]byte, len(tt.plainText))
  175. c.Encrypt(out, tt.plainText)
  176. for j := 0; j < len(out); j++ {
  177. if out[j] != tt.cipherText[j] {
  178. t.Errorf("Cipher.Encrypt %d: out[%d] = %02X, expected %02X", i, j, out[j], tt.cipherText[j])
  179. break
  180. }
  181. }
  182. }
  183. }
  184. // Test decryption
  185. func TestCipherDecrypt(t *testing.T) {
  186. for i, tt := range CryptTests {
  187. c, err := NewCipher(tt.key)
  188. if err != nil {
  189. t.Errorf("NewCipher(%d bytes), vector %d = %s", len(tt.key), i, err)
  190. continue
  191. }
  192. out := make([]byte, len(tt.cipherText))
  193. c.Decrypt(out, tt.cipherText)
  194. for j := 0; j < len(out); j++ {
  195. if out[j] != tt.plainText[j] {
  196. t.Errorf("Cipher.Decrypt %d: out[%d] = %02X, expected %02X", i, j, out[j], tt.plainText[j])
  197. break
  198. }
  199. }
  200. }
  201. }