test_TurboSHAKE.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. """Self-test suite for Crypto.Hash.TurboSHAKE128 and TurboSHAKE256"""
  2. import unittest
  3. from binascii import unhexlify
  4. from Crypto.SelfTest.st_common import list_test_cases
  5. from Crypto.Hash import TurboSHAKE128, TurboSHAKE256
  6. from Crypto.Util.py3compat import bchr
  7. class TurboSHAKETest(unittest.TestCase):
  8. def test_new_positive(self):
  9. xof1 = self.TurboSHAKE.new()
  10. xof1.update(b'90')
  11. xof2 = self.TurboSHAKE.new(domain=0x1F)
  12. xof2.update(b'90')
  13. xof3 = self.TurboSHAKE.new(data=b'90')
  14. out1 = xof1.read(128)
  15. out2 = xof2.read(128)
  16. out3 = xof3.read(128)
  17. self.assertEqual(out1, out2)
  18. self.assertEqual(out1, out3)
  19. def test_new_domain(self):
  20. xof1 = self.TurboSHAKE.new(domain=0x1D)
  21. xof2 = self.TurboSHAKE.new(domain=0x20)
  22. self.assertNotEqual(xof1.read(128), xof2.read(128))
  23. def test_update(self):
  24. pieces = [bchr(10) * 200, bchr(20) * 300]
  25. xof1 = self.TurboSHAKE.new()
  26. xof1.update(pieces[0]).update(pieces[1])
  27. digest1 = xof1.read(10)
  28. xof2 = self.TurboSHAKE.new()
  29. xof2.update(pieces[0] + pieces[1])
  30. digest2 = xof2.read(10)
  31. self.assertEqual(digest1, digest2)
  32. def test_update_negative(self):
  33. xof1 = self.TurboSHAKE.new()
  34. self.assertRaises(TypeError, xof1.update, u"string")
  35. def test_read(self):
  36. xof1 = self.TurboSHAKE.new()
  37. digest = xof1.read(90)
  38. # read returns a byte string of the right length
  39. self.assertTrue(isinstance(digest, bytes))
  40. self.assertEqual(len(digest), 90)
  41. def test_update_after_read(self):
  42. xof1 = self.TurboSHAKE.new()
  43. xof1.update(b"rrrr")
  44. xof1.read(90)
  45. self.assertRaises(TypeError, xof1.update, b"ttt")
  46. def test_new(self):
  47. xof1 = self.TurboSHAKE.new(domain=0x07)
  48. xof1.update(b'90')
  49. digest1 = xof1.read(100)
  50. xof2 = xof1.new()
  51. xof2.update(b'90')
  52. digest2 = xof2.read(100)
  53. self.assertEqual(digest1, digest2)
  54. self.assertRaises(TypeError, xof1.new, domain=0x07)
  55. class TurboSHAKE128Test(TurboSHAKETest):
  56. TurboSHAKE = TurboSHAKE128
  57. class TurboSHAKE256Test(TurboSHAKETest):
  58. TurboSHAKE = TurboSHAKE256
  59. def txt2bin(txt):
  60. clean = txt.replace(" ", "").replace("\n", "").replace("\r", "")
  61. return unhexlify(clean)
  62. def ptn(n):
  63. res = bytearray(n)
  64. pattern = b"".join([bchr(x) for x in range(0, 0xFB)])
  65. for base in range(0, n - 0xFB, 0xFB):
  66. res[base:base + 0xFB] = pattern
  67. remain = n % 0xFB
  68. if remain:
  69. base = (n // 0xFB) * 0xFB
  70. res[base:] = pattern[:remain]
  71. assert len(res) == n
  72. return res
  73. def chunked(source, size):
  74. for i in range(0, len(source), size):
  75. yield source[i:i+size]
  76. class TurboSHAKE128TV(unittest.TestCase):
  77. def test_zero_1(self):
  78. tv = """1E 41 5F 1C 59 83 AF F2 16 92 17 27 7D 17 BB 53
  79. 8C D9 45 A3 97 DD EC 54 1F 1C E4 1A F2 C1 B7 4C"""
  80. btv = txt2bin(tv)
  81. res = TurboSHAKE128.new().read(32)
  82. self.assertEqual(res, btv)
  83. def test_zero_2(self):
  84. tv = """1E 41 5F 1C 59 83 AF F2 16 92 17 27 7D 17 BB 53
  85. 8C D9 45 A3 97 DD EC 54 1F 1C E4 1A F2 C1 B7 4C
  86. 3E 8C CA E2 A4 DA E5 6C 84 A0 4C 23 85 C0 3C 15
  87. E8 19 3B DF 58 73 73 63 32 16 91 C0 54 62 C8 DF"""
  88. btv = txt2bin(tv)
  89. res = TurboSHAKE128.new().read(64)
  90. self.assertEqual(res, btv)
  91. def test_zero_3(self):
  92. tv = """A3 B9 B0 38 59 00 CE 76 1F 22 AE D5 48 E7 54 DA
  93. 10 A5 24 2D 62 E8 C6 58 E3 F3 A9 23 A7 55 56 07"""
  94. btv = txt2bin(tv)
  95. res = TurboSHAKE128.new().read(10032)[-32:]
  96. self.assertEqual(res, btv)
  97. def test_ptn_1(self):
  98. tv = """55 CE DD 6F 60 AF 7B B2 9A 40 42 AE 83 2E F3 F5
  99. 8D B7 29 9F 89 3E BB 92 47 24 7D 85 69 58 DA A9"""
  100. btv = txt2bin(tv)
  101. res = TurboSHAKE128.new(data=ptn(1)).read(32)
  102. self.assertEqual(res, btv)
  103. def test_ptn_17(self):
  104. tv = """9C 97 D0 36 A3 BA C8 19 DB 70 ED E0 CA 55 4E C6
  105. E4 C2 A1 A4 FF BF D9 EC 26 9C A6 A1 11 16 12 33"""
  106. btv = txt2bin(tv)
  107. res = TurboSHAKE128.new(data=ptn(17)).read(32)
  108. self.assertEqual(res, btv)
  109. def test_ptn_17_2(self):
  110. tv = """96 C7 7C 27 9E 01 26 F7 FC 07 C9 B0 7F 5C DA E1
  111. E0 BE 60 BD BE 10 62 00 40 E7 5D 72 23 A6 24 D2"""
  112. btv = txt2bin(tv)
  113. res = TurboSHAKE128.new(data=ptn(17**2)).read(32)
  114. self.assertEqual(res, btv)
  115. def test_ptn_17_3(self):
  116. tv = """D4 97 6E B5 6B CF 11 85 20 58 2B 70 9F 73 E1 D6
  117. 85 3E 00 1F DA F8 0E 1B 13 E0 D0 59 9D 5F B3 72"""
  118. btv = txt2bin(tv)
  119. res = TurboSHAKE128.new(data=ptn(17**3)).read(32)
  120. self.assertEqual(res, btv)
  121. def test_ptn_17_4(self):
  122. tv = """DA 67 C7 03 9E 98 BF 53 0C F7 A3 78 30 C6 66 4E
  123. 14 CB AB 7F 54 0F 58 40 3B 1B 82 95 13 18 EE 5C"""
  124. btv = txt2bin(tv)
  125. data = ptn(17**4)
  126. # All at once
  127. res = TurboSHAKE128.new(data=data).read(32)
  128. self.assertEqual(res, btv)
  129. # Byte by byte
  130. xof = TurboSHAKE128.new()
  131. for x in data:
  132. xof.update(bchr(x))
  133. res = xof.read(32)
  134. self.assertEqual(res, btv)
  135. # Chunks of various prime sizes
  136. for chunk_size in (13, 17, 19, 23, 31):
  137. xof = TurboSHAKE128.new()
  138. for x in chunked(data, chunk_size):
  139. xof.update(x)
  140. res = xof.read(32)
  141. self.assertEqual(res, btv)
  142. def test_ptn_17_5(self):
  143. tv = """B9 7A 90 6F BF 83 EF 7C 81 25 17 AB F3 B2 D0 AE
  144. A0 C4 F6 03 18 CE 11 CF 10 39 25 12 7F 59 EE CD"""
  145. btv = txt2bin(tv)
  146. data = ptn(17**5)
  147. # All at once
  148. res = TurboSHAKE128.new(data=data).read(32)
  149. self.assertEqual(res, btv)
  150. # Chunks
  151. xof = TurboSHAKE128.new()
  152. for chunk in chunked(data, 8192):
  153. xof.update(chunk)
  154. res = xof.read(32)
  155. self.assertEqual(res, btv)
  156. def test_ptn_17_6(self):
  157. tv = """35 CD 49 4A DE DE D2 F2 52 39 AF 09 A7 B8 EF 0C
  158. 4D 1C A4 FE 2D 1A C3 70 FA 63 21 6F E7 B4 C2 B1"""
  159. btv = txt2bin(tv)
  160. data = ptn(17**6)
  161. res = TurboSHAKE128.new(data=data).read(32)
  162. self.assertEqual(res, btv)
  163. def test_ffffff_d01(self):
  164. tv = """BF 32 3F 94 04 94 E8 8E E1 C5 40 FE 66 0B E8 A0
  165. C9 3F 43 D1 5E C0 06 99 84 62 FA 99 4E ED 5D AB"""
  166. btv = txt2bin(tv)
  167. res = TurboSHAKE128.new(data=b"\xff\xff\xff", domain=0x01).read(32)
  168. self.assertEqual(res, btv)
  169. def test_ff_d06(self):
  170. tv = """8E C9 C6 64 65 ED 0D 4A 6C 35 D1 35 06 71 8D 68
  171. 7A 25 CB 05 C7 4C CA 1E 42 50 1A BD 83 87 4A 67"""
  172. btv = txt2bin(tv)
  173. res = TurboSHAKE128.new(data=b'\xFF', domain=0x06).read(32)
  174. self.assertEqual(res, btv)
  175. def test_ffffff_d07(self):
  176. tv = """B6 58 57 60 01 CA D9 B1 E5 F3 99 A9 F7 77 23 BB
  177. A0 54 58 04 2D 68 20 6F 72 52 68 2D BA 36 63 ED"""
  178. btv = txt2bin(tv)
  179. res = TurboSHAKE128.new(data=b'\xFF' * 3, domain=0x07).read(32)
  180. self.assertEqual(res, btv)
  181. def test_ffffffffffff_d0b(self):
  182. tv = """8D EE AA 1A EC 47 CC EE 56 9F 65 9C 21 DF A8 E1
  183. 12 DB 3C EE 37 B1 81 78 B2 AC D8 05 B7 99 CC 37"""
  184. btv = txt2bin(tv)
  185. res = TurboSHAKE128.new(data=b'\xFF' * 7, domain=0x0B).read(32)
  186. self.assertEqual(res, btv)
  187. def test_ff_d30(self):
  188. tv = """55 31 22 E2 13 5E 36 3C 32 92 BE D2 C6 42 1F A2
  189. 32 BA B0 3D AA 07 C7 D6 63 66 03 28 65 06 32 5B"""
  190. btv = txt2bin(tv)
  191. res = TurboSHAKE128.new(data=b'\xFF', domain=0x30).read(32)
  192. self.assertEqual(res, btv)
  193. def test_ffffff_d7f(self):
  194. tv = """16 27 4C C6 56 D4 4C EF D4 22 39 5D 0F 90 53 BD
  195. A6 D2 8E 12 2A BA 15 C7 65 E5 AD 0E 6E AF 26 F9"""
  196. btv = txt2bin(tv)
  197. res = TurboSHAKE128.new(data=b'\xFF' * 3, domain=0x7F).read(32)
  198. self.assertEqual(res, btv)
  199. class TurboSHAKE256TV(unittest.TestCase):
  200. def test_zero_1(self):
  201. tv = """36 7A 32 9D AF EA 87 1C 78 02 EC 67 F9 05 AE 13
  202. C5 76 95 DC 2C 66 63 C6 10 35 F5 9A 18 F8 E7 DB
  203. 11 ED C0 E1 2E 91 EA 60 EB 6B 32 DF 06 DD 7F 00
  204. 2F BA FA BB 6E 13 EC 1C C2 0D 99 55 47 60 0D B0"""
  205. btv = txt2bin(tv)
  206. res = TurboSHAKE256.new().read(64)
  207. self.assertEqual(res, btv)
  208. def test_zero_2(self):
  209. tv = """AB EF A1 16 30 C6 61 26 92 49 74 26 85 EC 08 2F
  210. 20 72 65 DC CF 2F 43 53 4E 9C 61 BA 0C 9D 1D 75"""
  211. btv = txt2bin(tv)
  212. res = TurboSHAKE256.new().read(10032)[-32:]
  213. self.assertEqual(res, btv)
  214. def test_ptn_1(self):
  215. tv = """3E 17 12 F9 28 F8 EA F1 05 46 32 B2 AA 0A 24 6E
  216. D8 B0 C3 78 72 8F 60 BC 97 04 10 15 5C 28 82 0E
  217. 90 CC 90 D8 A3 00 6A A2 37 2C 5C 5E A1 76 B0 68
  218. 2B F2 2B AE 74 67 AC 94 F7 4D 43 D3 9B 04 82 E2"""
  219. btv = txt2bin(tv)
  220. res = TurboSHAKE256.new(data=ptn(1)).read(64)
  221. self.assertEqual(res, btv)
  222. def test_ptn_17(self):
  223. tv = """B3 BA B0 30 0E 6A 19 1F BE 61 37 93 98 35 92 35
  224. 78 79 4E A5 48 43 F5 01 10 90 FA 2F 37 80 A9 E5
  225. CB 22 C5 9D 78 B4 0A 0F BF F9 E6 72 C0 FB E0 97
  226. 0B D2 C8 45 09 1C 60 44 D6 87 05 4D A5 D8 E9 C7"""
  227. btv = txt2bin(tv)
  228. res = TurboSHAKE256.new(data=ptn(17)).read(64)
  229. self.assertEqual(res, btv)
  230. def test_ptn_17_2(self):
  231. tv = """66 B8 10 DB 8E 90 78 04 24 C0 84 73 72 FD C9 57
  232. 10 88 2F DE 31 C6 DF 75 BE B9 D4 CD 93 05 CF CA
  233. E3 5E 7B 83 E8 B7 E6 EB 4B 78 60 58 80 11 63 16
  234. FE 2C 07 8A 09 B9 4A D7 B8 21 3C 0A 73 8B 65 C0"""
  235. btv = txt2bin(tv)
  236. res = TurboSHAKE256.new(data=ptn(17**2)).read(64)
  237. self.assertEqual(res, btv)
  238. def test_ptn_17_3(self):
  239. tv = """C7 4E BC 91 9A 5B 3B 0D D1 22 81 85 BA 02 D2 9E
  240. F4 42 D6 9D 3D 42 76 A9 3E FE 0B F9 A1 6A 7D C0
  241. CD 4E AB AD AB 8C D7 A5 ED D9 66 95 F5 D3 60 AB
  242. E0 9E 2C 65 11 A3 EC 39 7D A3 B7 6B 9E 16 74 FB"""
  243. btv = txt2bin(tv)
  244. res = TurboSHAKE256.new(data=ptn(17**3)).read(64)
  245. self.assertEqual(res, btv)
  246. def test_ptn_17_4(self):
  247. tv = """02 CC 3A 88 97 E6 F4 F6 CC B6 FD 46 63 1B 1F 52
  248. 07 B6 6C 6D E9 C7 B5 5B 2D 1A 23 13 4A 17 0A FD
  249. AC 23 4E AB A9 A7 7C FF 88 C1 F0 20 B7 37 24 61
  250. 8C 56 87 B3 62 C4 30 B2 48 CD 38 64 7F 84 8A 1D"""
  251. btv = txt2bin(tv)
  252. data = ptn(17**4)
  253. # All at once
  254. res = TurboSHAKE256.new(data=data).read(64)
  255. self.assertEqual(res, btv)
  256. # Byte by byte
  257. xof = TurboSHAKE256.new()
  258. for x in data:
  259. xof.update(bchr(x))
  260. res = xof.read(64)
  261. self.assertEqual(res, btv)
  262. # Chunks of various prime sizes
  263. for chunk_size in (13, 17, 19, 23, 31):
  264. xof = TurboSHAKE256.new()
  265. for x in chunked(data, chunk_size):
  266. xof.update(x)
  267. res = xof.read(64)
  268. self.assertEqual(res, btv)
  269. def test_ptn_17_5(self):
  270. tv = """AD D5 3B 06 54 3E 58 4B 58 23 F6 26 99 6A EE 50
  271. FE 45 ED 15 F2 02 43 A7 16 54 85 AC B4 AA 76 B4
  272. FF DA 75 CE DF 6D 8C DC 95 C3 32 BD 56 F4 B9 86
  273. B5 8B B1 7D 17 78 BF C1 B1 A9 75 45 CD F4 EC 9F"""
  274. btv = txt2bin(tv)
  275. data = ptn(17**5)
  276. # All at once
  277. res = TurboSHAKE256.new(data=data).read(64)
  278. self.assertEqual(res, btv)
  279. # Chunks
  280. xof = TurboSHAKE256.new()
  281. for chunk in chunked(data, 8192):
  282. xof.update(chunk)
  283. res = xof.read(64)
  284. self.assertEqual(res, btv)
  285. def test_ptn_17_6(self):
  286. tv = """9E 11 BC 59 C2 4E 73 99 3C 14 84 EC 66 35 8E F7
  287. 1D B7 4A EF D8 4E 12 3F 78 00 BA 9C 48 53 E0 2C
  288. FE 70 1D 9E 6B B7 65 A3 04 F0 DC 34 A4 EE 3B A8
  289. 2C 41 0F 0D A7 0E 86 BF BD 90 EA 87 7C 2D 61 04"""
  290. btv = txt2bin(tv)
  291. data = ptn(17**6)
  292. res = TurboSHAKE256.new(data=data).read(64)
  293. self.assertEqual(res, btv)
  294. def test_ffffff_d01(self):
  295. tv = """D2 1C 6F BB F5 87 FA 22 82 F2 9A EA 62 01 75 FB
  296. 02 57 41 3A F7 8A 0B 1B 2A 87 41 9C E0 31 D9 33
  297. AE 7A 4D 38 33 27 A8 A1 76 41 A3 4F 8A 1D 10 03
  298. AD 7D A6 B7 2D BA 84 BB 62 FE F2 8F 62 F1 24 24"""
  299. btv = txt2bin(tv)
  300. res = TurboSHAKE256.new(data=b"\xff\xff\xff", domain=0x01).read(64)
  301. self.assertEqual(res, btv)
  302. def test_ff_d06(self):
  303. tv = """73 8D 7B 4E 37 D1 8B 7F 22 AD 1B 53 13 E3 57 E3
  304. DD 7D 07 05 6A 26 A3 03 C4 33 FA 35 33 45 52 80
  305. F4 F5 A7 D4 F7 00 EF B4 37 FE 6D 28 14 05 E0 7B
  306. E3 2A 0A 97 2E 22 E6 3A DC 1B 09 0D AE FE 00 4B"""
  307. btv = txt2bin(tv)
  308. res = TurboSHAKE256.new(data=b'\xFF', domain=0x06).read(64)
  309. self.assertEqual(res, btv)
  310. def test_ffffff_d07(self):
  311. tv = """18 B3 B5 B7 06 1C 2E 67 C1 75 3A 00 E6 AD 7E D7
  312. BA 1C 90 6C F9 3E FB 70 92 EA F2 7F BE EB B7 55
  313. AE 6E 29 24 93 C1 10 E4 8D 26 00 28 49 2B 8E 09
  314. B5 50 06 12 B8 F2 57 89 85 DE D5 35 7D 00 EC 67"""
  315. btv = txt2bin(tv)
  316. res = TurboSHAKE256.new(data=b'\xFF' * 3, domain=0x07).read(64)
  317. self.assertEqual(res, btv)
  318. def test_ffffffffffff_d0b(self):
  319. tv = """BB 36 76 49 51 EC 97 E9 D8 5F 7E E9 A6 7A 77 18
  320. FC 00 5C F4 25 56 BE 79 CE 12 C0 BD E5 0E 57 36
  321. D6 63 2B 0D 0D FB 20 2D 1B BB 8F FE 3D D7 4C B0
  322. 08 34 FA 75 6C B0 34 71 BA B1 3A 1E 2C 16 B3 C0"""
  323. btv = txt2bin(tv)
  324. res = TurboSHAKE256.new(data=b'\xFF' * 7, domain=0x0B).read(64)
  325. self.assertEqual(res, btv)
  326. def test_ff_d30(self):
  327. tv = """F3 FE 12 87 3D 34 BC BB 2E 60 87 79 D6 B7 0E 7F
  328. 86 BE C7 E9 0B F1 13 CB D4 FD D0 C4 E2 F4 62 5E
  329. 14 8D D7 EE 1A 52 77 6C F7 7F 24 05 14 D9 CC FC
  330. 3B 5D DA B8 EE 25 5E 39 EE 38 90 72 96 2C 11 1A"""
  331. btv = txt2bin(tv)
  332. res = TurboSHAKE256.new(data=b'\xFF', domain=0x30).read(64)
  333. self.assertEqual(res, btv)
  334. def test_ffffff_d7f(self):
  335. tv = """AB E5 69 C1 F7 7E C3 40 F0 27 05 E7 D3 7C 9A B7
  336. E1 55 51 6E 4A 6A 15 00 21 D7 0B 6F AC 0B B4 0C
  337. 06 9F 9A 98 28 A0 D5 75 CD 99 F9 BA E4 35 AB 1A
  338. CF 7E D9 11 0B A9 7C E0 38 8D 07 4B AC 76 87 76"""
  339. btv = txt2bin(tv)
  340. res = TurboSHAKE256.new(data=b'\xFF' * 3, domain=0x7F).read(64)
  341. self.assertEqual(res, btv)
  342. def get_tests(config={}):
  343. tests = []
  344. tests += list_test_cases(TurboSHAKE128Test)
  345. tests += list_test_cases(TurboSHAKE256Test)
  346. tests += list_test_cases(TurboSHAKE128TV)
  347. tests += list_test_cases(TurboSHAKE256TV)
  348. return tests
  349. if __name__ == '__main__':
  350. def suite():
  351. return unittest.TestSuite(get_tests())
  352. unittest.main(defaultTest='suite')