chacha20_test.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. // chacha20_test.go - ChaCha stream cipher implementation tests.
  2. //
  3. // To the extent possible under law, Yawning Angel waived all copyright
  4. // and related or neighboring rights to chacha20, using the Creative
  5. // Commons "CC0" public domain dedication. See LICENSE or
  6. // <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
  7. package chacha20
  8. import (
  9. "bytes"
  10. "crypto/aes"
  11. "crypto/cipher"
  12. "crypto/rand"
  13. "encoding/hex"
  14. "testing"
  15. )
  16. // Test vectors taken from:
  17. // https://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-01
  18. var draftTestVectors = []struct {
  19. name string
  20. key []byte
  21. iv []byte
  22. stream []byte
  23. seekOffset uint64
  24. }{
  25. {
  26. name: "IETF Draft: TC1: All zero key and IV.",
  27. key: []byte{
  28. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  29. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  30. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  31. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  32. },
  33. iv: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  34. stream: []byte{
  35. 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
  36. 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
  37. 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
  38. 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
  39. 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
  40. 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
  41. 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
  42. 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
  43. 0x9f, 0x07, 0xe7, 0xbe, 0x55, 0x51, 0x38, 0x7a,
  44. 0x98, 0xba, 0x97, 0x7c, 0x73, 0x2d, 0x08, 0x0d,
  45. 0xcb, 0x0f, 0x29, 0xa0, 0x48, 0xe3, 0x65, 0x69,
  46. 0x12, 0xc6, 0x53, 0x3e, 0x32, 0xee, 0x7a, 0xed,
  47. 0x29, 0xb7, 0x21, 0x76, 0x9c, 0xe6, 0x4e, 0x43,
  48. 0xd5, 0x71, 0x33, 0xb0, 0x74, 0xd8, 0x39, 0xd5,
  49. 0x31, 0xed, 0x1f, 0x28, 0x51, 0x0a, 0xfb, 0x45,
  50. 0xac, 0xe1, 0x0a, 0x1f, 0x4b, 0x79, 0x4d, 0x6f,
  51. },
  52. },
  53. {
  54. name: "IETF Draft: TC2: Single bit in key set. All zero IV.",
  55. key: []byte{
  56. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  57. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  58. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  59. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  60. },
  61. iv: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  62. stream: []byte{
  63. 0xc5, 0xd3, 0x0a, 0x7c, 0xe1, 0xec, 0x11, 0x93,
  64. 0x78, 0xc8, 0x4f, 0x48, 0x7d, 0x77, 0x5a, 0x85,
  65. 0x42, 0xf1, 0x3e, 0xce, 0x23, 0x8a, 0x94, 0x55,
  66. 0xe8, 0x22, 0x9e, 0x88, 0x8d, 0xe8, 0x5b, 0xbd,
  67. 0x29, 0xeb, 0x63, 0xd0, 0xa1, 0x7a, 0x5b, 0x99,
  68. 0x9b, 0x52, 0xda, 0x22, 0xbe, 0x40, 0x23, 0xeb,
  69. 0x07, 0x62, 0x0a, 0x54, 0xf6, 0xfa, 0x6a, 0xd8,
  70. 0x73, 0x7b, 0x71, 0xeb, 0x04, 0x64, 0xda, 0xc0,
  71. 0x10, 0xf6, 0x56, 0xe6, 0xd1, 0xfd, 0x55, 0x05,
  72. 0x3e, 0x50, 0xc4, 0x87, 0x5c, 0x99, 0x30, 0xa3,
  73. 0x3f, 0x6d, 0x02, 0x63, 0xbd, 0x14, 0xdf, 0xd6,
  74. 0xab, 0x8c, 0x70, 0x52, 0x1c, 0x19, 0x33, 0x8b,
  75. 0x23, 0x08, 0xb9, 0x5c, 0xf8, 0xd0, 0xbb, 0x7d,
  76. 0x20, 0x2d, 0x21, 0x02, 0x78, 0x0e, 0xa3, 0x52,
  77. 0x8f, 0x1c, 0xb4, 0x85, 0x60, 0xf7, 0x6b, 0x20,
  78. 0xf3, 0x82, 0xb9, 0x42, 0x50, 0x0f, 0xce, 0xac,
  79. },
  80. },
  81. {
  82. name: "IETF Draft: TC3: Single bit in IV set. All zero key.",
  83. key: []byte{
  84. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  85. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  86. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  87. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  88. },
  89. iv: []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  90. stream: []byte{
  91. 0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
  92. 0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
  93. 0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
  94. 0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
  95. 0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
  96. 0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
  97. 0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
  98. 0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
  99. 0x53, 0x05, 0xe5, 0xe4, 0x4a, 0xff, 0x19, 0xb2,
  100. 0x35, 0x93, 0x61, 0x44, 0x67, 0x5e, 0xfb, 0xe4,
  101. 0x40, 0x9e, 0xb7, 0xe8, 0xe5, 0xf1, 0x43, 0x0f,
  102. 0x5f, 0x58, 0x36, 0xae, 0xb4, 0x9b, 0xb5, 0x32,
  103. 0x8b, 0x01, 0x7c, 0x4b, 0x9d, 0xc1, 0x1f, 0x8a,
  104. 0x03, 0x86, 0x3f, 0xa8, 0x03, 0xdc, 0x71, 0xd5,
  105. 0x72, 0x6b, 0x2b, 0x6b, 0x31, 0xaa, 0x32, 0x70,
  106. 0x8a, 0xfe, 0x5a, 0xf1, 0xd6, 0xb6, 0x90, 0x58,
  107. },
  108. },
  109. {
  110. name: "IETF Draft: TC4: All bits in key and IV are set.",
  111. key: []byte{
  112. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  113. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  114. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  115. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  116. },
  117. iv: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
  118. stream: []byte{
  119. 0xd9, 0xbf, 0x3f, 0x6b, 0xce, 0x6e, 0xd0, 0xb5,
  120. 0x42, 0x54, 0x55, 0x77, 0x67, 0xfb, 0x57, 0x44,
  121. 0x3d, 0xd4, 0x77, 0x89, 0x11, 0xb6, 0x06, 0x05,
  122. 0x5c, 0x39, 0xcc, 0x25, 0xe6, 0x74, 0xb8, 0x36,
  123. 0x3f, 0xea, 0xbc, 0x57, 0xfd, 0xe5, 0x4f, 0x79,
  124. 0x0c, 0x52, 0xc8, 0xae, 0x43, 0x24, 0x0b, 0x79,
  125. 0xd4, 0x90, 0x42, 0xb7, 0x77, 0xbf, 0xd6, 0xcb,
  126. 0x80, 0xe9, 0x31, 0x27, 0x0b, 0x7f, 0x50, 0xeb,
  127. 0x5b, 0xac, 0x2a, 0xcd, 0x86, 0xa8, 0x36, 0xc5,
  128. 0xdc, 0x98, 0xc1, 0x16, 0xc1, 0x21, 0x7e, 0xc3,
  129. 0x1d, 0x3a, 0x63, 0xa9, 0x45, 0x13, 0x19, 0xf0,
  130. 0x97, 0xf3, 0xb4, 0xd6, 0xda, 0xb0, 0x77, 0x87,
  131. 0x19, 0x47, 0x7d, 0x24, 0xd2, 0x4b, 0x40, 0x3a,
  132. 0x12, 0x24, 0x1d, 0x7c, 0xca, 0x06, 0x4f, 0x79,
  133. 0x0f, 0x1d, 0x51, 0xcc, 0xaf, 0xf6, 0xb1, 0x66,
  134. 0x7d, 0x4b, 0xbc, 0xa1, 0x95, 0x8c, 0x43, 0x06,
  135. },
  136. },
  137. {
  138. name: "IETF Draft: TC5: Every even bit set in key and IV.",
  139. key: []byte{
  140. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  141. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  142. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  143. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  144. },
  145. iv: []byte{0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55},
  146. stream: []byte{
  147. 0xbe, 0xa9, 0x41, 0x1a, 0xa4, 0x53, 0xc5, 0x43,
  148. 0x4a, 0x5a, 0xe8, 0xc9, 0x28, 0x62, 0xf5, 0x64,
  149. 0x39, 0x68, 0x55, 0xa9, 0xea, 0x6e, 0x22, 0xd6,
  150. 0xd3, 0xb5, 0x0a, 0xe1, 0xb3, 0x66, 0x33, 0x11,
  151. 0xa4, 0xa3, 0x60, 0x6c, 0x67, 0x1d, 0x60, 0x5c,
  152. 0xe1, 0x6c, 0x3a, 0xec, 0xe8, 0xe6, 0x1e, 0xa1,
  153. 0x45, 0xc5, 0x97, 0x75, 0x01, 0x7b, 0xee, 0x2f,
  154. 0xa6, 0xf8, 0x8a, 0xfc, 0x75, 0x80, 0x69, 0xf7,
  155. 0xe0, 0xb8, 0xf6, 0x76, 0xe6, 0x44, 0x21, 0x6f,
  156. 0x4d, 0x2a, 0x34, 0x22, 0xd7, 0xfa, 0x36, 0xc6,
  157. 0xc4, 0x93, 0x1a, 0xca, 0x95, 0x0e, 0x9d, 0xa4,
  158. 0x27, 0x88, 0xe6, 0xd0, 0xb6, 0xd1, 0xcd, 0x83,
  159. 0x8e, 0xf6, 0x52, 0xe9, 0x7b, 0x14, 0x5b, 0x14,
  160. 0x87, 0x1e, 0xae, 0x6c, 0x68, 0x04, 0xc7, 0x00,
  161. 0x4d, 0xb5, 0xac, 0x2f, 0xce, 0x4c, 0x68, 0xc7,
  162. 0x26, 0xd0, 0x04, 0xb1, 0x0f, 0xca, 0xba, 0x86,
  163. },
  164. },
  165. {
  166. name: "IETF Draft: TC6: Every odd bit set in key and IV.",
  167. key: []byte{
  168. 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  169. 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  170. 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  171. 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  172. },
  173. iv: []byte{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa},
  174. stream: []byte{
  175. 0x9a, 0xa2, 0xa9, 0xf6, 0x56, 0xef, 0xde, 0x5a,
  176. 0xa7, 0x59, 0x1c, 0x5f, 0xed, 0x4b, 0x35, 0xae,
  177. 0xa2, 0x89, 0x5d, 0xec, 0x7c, 0xb4, 0x54, 0x3b,
  178. 0x9e, 0x9f, 0x21, 0xf5, 0xe7, 0xbc, 0xbc, 0xf3,
  179. 0xc4, 0x3c, 0x74, 0x8a, 0x97, 0x08, 0x88, 0xf8,
  180. 0x24, 0x83, 0x93, 0xa0, 0x9d, 0x43, 0xe0, 0xb7,
  181. 0xe1, 0x64, 0xbc, 0x4d, 0x0b, 0x0f, 0xb2, 0x40,
  182. 0xa2, 0xd7, 0x21, 0x15, 0xc4, 0x80, 0x89, 0x06,
  183. 0x72, 0x18, 0x44, 0x89, 0x44, 0x05, 0x45, 0xd0,
  184. 0x21, 0xd9, 0x7e, 0xf6, 0xb6, 0x93, 0xdf, 0xe5,
  185. 0xb2, 0xc1, 0x32, 0xd4, 0x7e, 0x6f, 0x04, 0x1c,
  186. 0x90, 0x63, 0x65, 0x1f, 0x96, 0xb6, 0x23, 0xe6,
  187. 0x2a, 0x11, 0x99, 0x9a, 0x23, 0xb6, 0xf7, 0xc4,
  188. 0x61, 0xb2, 0x15, 0x30, 0x26, 0xad, 0x5e, 0x86,
  189. 0x6a, 0x2e, 0x59, 0x7e, 0xd0, 0x7b, 0x84, 0x01,
  190. 0xde, 0xc6, 0x3a, 0x09, 0x34, 0xc6, 0xb2, 0xa9,
  191. },
  192. },
  193. {
  194. name: "IETF Draft: TC7: Sequence patterns in key and IV.",
  195. key: []byte{
  196. 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
  197. 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
  198. 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
  199. 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00,
  200. },
  201. iv: []byte{0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78},
  202. stream: []byte{
  203. 0x9f, 0xad, 0xf4, 0x09, 0xc0, 0x08, 0x11, 0xd0,
  204. 0x04, 0x31, 0xd6, 0x7e, 0xfb, 0xd8, 0x8f, 0xba,
  205. 0x59, 0x21, 0x8d, 0x5d, 0x67, 0x08, 0xb1, 0xd6,
  206. 0x85, 0x86, 0x3f, 0xab, 0xbb, 0x0e, 0x96, 0x1e,
  207. 0xea, 0x48, 0x0f, 0xd6, 0xfb, 0x53, 0x2b, 0xfd,
  208. 0x49, 0x4b, 0x21, 0x51, 0x01, 0x50, 0x57, 0x42,
  209. 0x3a, 0xb6, 0x0a, 0x63, 0xfe, 0x4f, 0x55, 0xf7,
  210. 0xa2, 0x12, 0xe2, 0x16, 0x7c, 0xca, 0xb9, 0x31,
  211. 0xfb, 0xfd, 0x29, 0xcf, 0x7b, 0xc1, 0xd2, 0x79,
  212. 0xed, 0xdf, 0x25, 0xdd, 0x31, 0x6b, 0xb8, 0x84,
  213. 0x3d, 0x6e, 0xde, 0xe0, 0xbd, 0x1e, 0xf1, 0x21,
  214. 0xd1, 0x2f, 0xa1, 0x7c, 0xbc, 0x2c, 0x57, 0x4c,
  215. 0xcc, 0xab, 0x5e, 0x27, 0x51, 0x67, 0xb0, 0x8b,
  216. 0xd6, 0x86, 0xf8, 0xa0, 0x9d, 0xf8, 0x7e, 0xc3,
  217. 0xff, 0xb3, 0x53, 0x61, 0xb9, 0x4e, 0xbf, 0xa1,
  218. 0x3f, 0xec, 0x0e, 0x48, 0x89, 0xd1, 0x8d, 0xa5,
  219. },
  220. },
  221. {
  222. name: "IETF Draft: TC8: key: 'All your base are belong to us!, IV: 'IETF2013'",
  223. key: []byte{
  224. 0xc4, 0x6e, 0xc1, 0xb1, 0x8c, 0xe8, 0xa8, 0x78,
  225. 0x72, 0x5a, 0x37, 0xe7, 0x80, 0xdf, 0xb7, 0x35,
  226. 0x1f, 0x68, 0xed, 0x2e, 0x19, 0x4c, 0x79, 0xfb,
  227. 0xc6, 0xae, 0xbe, 0xe1, 0xa6, 0x67, 0x97, 0x5d,
  228. },
  229. iv: []byte{0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21},
  230. stream: []byte{
  231. 0xf6, 0x3a, 0x89, 0xb7, 0x5c, 0x22, 0x71, 0xf9,
  232. 0x36, 0x88, 0x16, 0x54, 0x2b, 0xa5, 0x2f, 0x06,
  233. 0xed, 0x49, 0x24, 0x17, 0x92, 0x30, 0x2b, 0x00,
  234. 0xb5, 0xe8, 0xf8, 0x0a, 0xe9, 0xa4, 0x73, 0xaf,
  235. 0xc2, 0x5b, 0x21, 0x8f, 0x51, 0x9a, 0xf0, 0xfd,
  236. 0xd4, 0x06, 0x36, 0x2e, 0x8d, 0x69, 0xde, 0x7f,
  237. 0x54, 0xc6, 0x04, 0xa6, 0xe0, 0x0f, 0x35, 0x3f,
  238. 0x11, 0x0f, 0x77, 0x1b, 0xdc, 0xa8, 0xab, 0x92,
  239. 0xe5, 0xfb, 0xc3, 0x4e, 0x60, 0xa1, 0xd9, 0xa9,
  240. 0xdb, 0x17, 0x34, 0x5b, 0x0a, 0x40, 0x27, 0x36,
  241. 0x85, 0x3b, 0xf9, 0x10, 0xb0, 0x60, 0xbd, 0xf1,
  242. 0xf8, 0x97, 0xb6, 0x29, 0x0f, 0x01, 0xd1, 0x38,
  243. 0xae, 0x2c, 0x4c, 0x90, 0x22, 0x5b, 0xa9, 0xea,
  244. 0x14, 0xd5, 0x18, 0xf5, 0x59, 0x29, 0xde, 0xa0,
  245. 0x98, 0xca, 0x7a, 0x6c, 0xcf, 0xe6, 0x12, 0x27,
  246. 0x05, 0x3c, 0x84, 0xe4, 0x9a, 0x4a, 0x33, 0x32,
  247. },
  248. },
  249. {
  250. name: "XChaCha20 Test",
  251. key: []byte{
  252. 0x1b, 0x27, 0x55, 0x64, 0x73, 0xe9, 0x85, 0xd4,
  253. 0x62, 0xcd, 0x51, 0x19, 0x7a, 0x9a, 0x46, 0xc7,
  254. 0x60, 0x09, 0x54, 0x9e, 0xac, 0x64, 0x74, 0xf2,
  255. 0x06, 0xc4, 0xee, 0x08, 0x44, 0xf6, 0x83, 0x89,
  256. },
  257. iv: []byte{
  258. 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73,
  259. 0xcd, 0x62, 0xbd, 0xa8, 0x75, 0xfc, 0x73, 0xd6,
  260. 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37,
  261. },
  262. stream: []byte{
  263. 0x4f, 0xeb, 0xf2, 0xfe, 0x4b, 0x35, 0x9c, 0x50,
  264. 0x8d, 0xc5, 0xe8, 0xb5, 0x98, 0x0c, 0x88, 0xe3,
  265. 0x89, 0x46, 0xd8, 0xf1, 0x8f, 0x31, 0x34, 0x65,
  266. 0xc8, 0x62, 0xa0, 0x87, 0x82, 0x64, 0x82, 0x48,
  267. 0x01, 0x8d, 0xac, 0xdc, 0xb9, 0x04, 0x17, 0x88,
  268. 0x53, 0xa4, 0x6d, 0xca, 0x3a, 0x0e, 0xaa, 0xee,
  269. 0x74, 0x7c, 0xba, 0x97, 0x43, 0x4e, 0xaf, 0xfa,
  270. 0xd5, 0x8f, 0xea, 0x82, 0x22, 0x04, 0x7e, 0x0d,
  271. 0xe6, 0xc3, 0xa6, 0x77, 0x51, 0x06, 0xe0, 0x33,
  272. 0x1a, 0xd7, 0x14, 0xd2, 0xf2, 0x7a, 0x55, 0x64,
  273. 0x13, 0x40, 0xa1, 0xf1, 0xdd, 0x9f, 0x94, 0x53,
  274. 0x2e, 0x68, 0xcb, 0x24, 0x1c, 0xbd, 0xd1, 0x50,
  275. 0x97, 0x0d, 0x14, 0xe0, 0x5c, 0x5b, 0x17, 0x31,
  276. 0x93, 0xfb, 0x14, 0xf5, 0x1c, 0x41, 0xf3, 0x93,
  277. 0x83, 0x5b, 0xf7, 0xf4, 0x16, 0xa7, 0xe0, 0xbb,
  278. 0xa8, 0x1f, 0xfb, 0x8b, 0x13, 0xaf, 0x0e, 0x21,
  279. 0x69, 0x1d, 0x7e, 0xce, 0xc9, 0x3b, 0x75, 0xe6,
  280. 0xe4, 0x18, 0x3a,
  281. },
  282. },
  283. {
  284. name: "RFC 7539 Test Vector (96 bit nonce)",
  285. key: []byte{
  286. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  287. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  288. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  289. 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  290. },
  291. iv: []byte{
  292. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a,
  293. 0x00, 0x00, 0x00, 0x00,
  294. },
  295. stream: []byte{
  296. 0x22, 0x4f, 0x51, 0xf3, 0x40, 0x1b, 0xd9, 0xe1,
  297. 0x2f, 0xde, 0x27, 0x6f, 0xb8, 0x63, 0x1d, 0xed,
  298. 0x8c, 0x13, 0x1f, 0x82, 0x3d, 0x2c, 0x06, 0xe2,
  299. 0x7e, 0x4f, 0xca, 0xec, 0x9e, 0xf3, 0xcf, 0x78,
  300. 0x8a, 0x3b, 0x0a, 0xa3, 0x72, 0x60, 0x0a, 0x92,
  301. 0xb5, 0x79, 0x74, 0xcd, 0xed, 0x2b, 0x93, 0x34,
  302. 0x79, 0x4c, 0xba, 0x40, 0xc6, 0x3e, 0x34, 0xcd,
  303. 0xea, 0x21, 0x2c, 0x4c, 0xf0, 0x7d, 0x41, 0xb7,
  304. 0x69, 0xa6, 0x74, 0x9f, 0x3f, 0x63, 0x0f, 0x41,
  305. 0x22, 0xca, 0xfe, 0x28, 0xec, 0x4d, 0xc4, 0x7e,
  306. 0x26, 0xd4, 0x34, 0x6d, 0x70, 0xb9, 0x8c, 0x73,
  307. 0xf3, 0xe9, 0xc5, 0x3a, 0xc4, 0x0c, 0x59, 0x45,
  308. 0x39, 0x8b, 0x6e, 0xda, 0x1a, 0x83, 0x2c, 0x89,
  309. 0xc1, 0x67, 0xea, 0xcd, 0x90, 0x1d, 0x7e, 0x2b,
  310. 0xf3, 0x63,
  311. },
  312. seekOffset: 1,
  313. },
  314. }
  315. func TestChaCha20(t *testing.T) {
  316. for _, v := range draftTestVectors {
  317. c, err := NewCipher(v.key, v.iv)
  318. if err != nil {
  319. t.Errorf("[%s]: New(k, iv) returned: %s", v.name, err)
  320. continue
  321. }
  322. if v.seekOffset != 0 {
  323. if err = c.Seek(v.seekOffset); err != nil {
  324. t.Errorf("[%s]: Seek(seekOffset) returned: %s", v.name, err)
  325. continue
  326. }
  327. }
  328. out := make([]byte, len(v.stream))
  329. c.XORKeyStream(out, out)
  330. if !bytes.Equal(out, v.stream) {
  331. t.Errorf("[%s]: out != stream (%x != %x)", v.name, out, v.stream)
  332. }
  333. }
  334. }
  335. func TestChaCha20Vectorized(t *testing.T) {
  336. if !usingVectors {
  337. t.Skip("vectorized ChaCha20 support not enabled")
  338. }
  339. // Save the batch blocks processing routine so we can mess with it, and
  340. // restore it when we're done.
  341. oldBlocksFn := blocksFn
  342. defer func() {
  343. blocksFn = oldBlocksFn
  344. }()
  345. const testSz = 1024 * 16
  346. // Generate a random key, nonce and input.
  347. var key [KeySize]byte
  348. var nonce [NonceSize]byte
  349. var input [testSz]byte
  350. var vecOut [testSz]byte
  351. var refOut [testSz]byte
  352. rand.Read(key[:])
  353. rand.Read(nonce[:])
  354. rand.Read(input[:])
  355. for i := 0; i < testSz; i++ {
  356. // Encrypt with the vectorized implementation.
  357. c, err := NewCipher(key[:], nonce[:])
  358. if err != nil {
  359. t.Fatal(err)
  360. }
  361. c.XORKeyStream(vecOut[:], input[:i])
  362. c, err = NewCipher(key[:], nonce[:])
  363. if err != nil {
  364. t.Fatal(err)
  365. }
  366. blocksFn = blocksRef
  367. c.XORKeyStream(refOut[:], input[:i])
  368. if !bytes.Equal(refOut[:i], vecOut[:i]) {
  369. for j, v := range refOut {
  370. if vecOut[j] != v {
  371. t.Errorf("[%d] mismatch at offset: %d %x != %x", i, j, vecOut[j], v)
  372. break
  373. }
  374. }
  375. t.Errorf("ref: %s", hex.Dump(refOut[:i]))
  376. t.Errorf("vec: %s", hex.Dump(vecOut[:i]))
  377. t.Errorf("refOut != vecOut")
  378. break
  379. }
  380. blocksFn = oldBlocksFn
  381. }
  382. }
  383. func TestChaCha20VectorizedIncremental(t *testing.T) {
  384. if !usingVectors {
  385. t.Skip("vectorized ChaCha20 support not enabled")
  386. }
  387. // Save the batch blocks processing routine so we can mess with it, and
  388. // restore it when we're done.
  389. oldBlocksFn := blocksFn
  390. defer func() {
  391. blocksFn = oldBlocksFn
  392. }()
  393. const (
  394. maxBlocks = 256
  395. testSz = (maxBlocks * (maxBlocks + 1) / 2) * BlockSize
  396. )
  397. // Generate a random key, nonce and input.
  398. var key [KeySize]byte
  399. var nonce [NonceSize]byte
  400. var input [testSz]byte
  401. var vecOut [testSz]byte
  402. var refOut [testSz]byte
  403. rand.Read(key[:])
  404. rand.Read(nonce[:])
  405. rand.Read(input[:])
  406. // Using the vectorized version, encrypt an ever increasing number of
  407. // blocks at a time.
  408. c, err := NewCipher(key[:], nonce[:])
  409. if err != nil {
  410. t.Fatal(err)
  411. }
  412. off := 0
  413. for nrBlocks := 0; nrBlocks <= maxBlocks; nrBlocks++ {
  414. cnt := nrBlocks * BlockSize
  415. c.XORKeyStream(vecOut[off:off+cnt], input[off:off+cnt])
  416. off += cnt
  417. }
  418. // Encrypt an equivalent amount of data with a one shot call to the
  419. // reference implementation.
  420. c, err = NewCipher(key[:], nonce[:])
  421. if err != nil {
  422. t.Fatal(err)
  423. }
  424. blocksFn = blocksRef
  425. c.XORKeyStream(refOut[:], input[:])
  426. // And compare the output.
  427. if !bytes.Equal(refOut[:], vecOut[:]) {
  428. for j, v := range refOut {
  429. if vecOut[j] != v {
  430. t.Errorf("incremental mismatch at offset: %d %x != %x", j, vecOut[j], v)
  431. break
  432. }
  433. }
  434. // t.Errorf("ref: %s", hex.Dump(refOut[:]))
  435. // t.Errorf("vec: %s", hex.Dump(vecOut[:]))
  436. t.Errorf("refOut != vecOut")
  437. }
  438. }
  439. func doBenchN(b *testing.B, n int) {
  440. var key [KeySize]byte
  441. var nonce [NonceSize]byte
  442. s := make([]byte, n)
  443. c, err := NewCipher(key[:], nonce[:])
  444. if err != nil {
  445. b.Fatal(err)
  446. }
  447. b.SetBytes(int64(n))
  448. b.ResetTimer()
  449. for i := 0; i < b.N; i++ {
  450. c.XORKeyStream(s, s)
  451. }
  452. }
  453. func BenchmarkChaCha20_16(b *testing.B) {
  454. doBenchN(b, 16)
  455. }
  456. func BenchmarkChaCha20_64(b *testing.B) {
  457. doBenchN(b, 64)
  458. }
  459. func BenchmarkChaCha20_128(b *testing.B) {
  460. doBenchN(b, 128)
  461. }
  462. func BenchmarkChaCha20_192(b *testing.B) {
  463. doBenchN(b, 192)
  464. }
  465. func BenchmarkChaCha20_256(b *testing.B) {
  466. doBenchN(b, 256)
  467. }
  468. func BenchmarkChaCha20_384(b *testing.B) {
  469. doBenchN(b, 384)
  470. }
  471. func BenchmarkChaCha20_512(b *testing.B) {
  472. doBenchN(b, 512)
  473. }
  474. func BenchmarkChaCha20_1k(b *testing.B) {
  475. doBenchN(b, 1024)
  476. }
  477. func BenchmarkChaCha20_64k(b *testing.B) {
  478. doBenchN(b, 65536)
  479. }
  480. func BenchmarkCTRAES256_64k(b *testing.B) {
  481. const sz = 64 * 1024
  482. var key [32]byte
  483. var iv [16]byte
  484. s := make([]byte, sz)
  485. blk, err := aes.NewCipher(key[:])
  486. if err != nil {
  487. b.Fatal(err)
  488. }
  489. c := cipher.NewCTR(blk, iv[:])
  490. b.SetBytes(sz)
  491. b.ResetTimer()
  492. for i := 0; i < b.N; i++ {
  493. c.XORKeyStream(s, s)
  494. }
  495. }