sha3-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +29 -0
  5. data/Rakefile +7 -0
  6. data/ext/sha3/KeccakReferenceAndOptimized/KeccakCompact.vcproj +207 -0
  7. data/ext/sha3/KeccakReferenceAndOptimized/KeccakCompact8.vcproj +207 -0
  8. data/ext/sha3/KeccakReferenceAndOptimized/KeccakInplace.vcproj +203 -0
  9. data/ext/sha3/KeccakReferenceAndOptimized/KeccakInplace32BI.vcproj +201 -0
  10. data/ext/sha3/KeccakReferenceAndOptimized/KeccakOptimized32.vcproj +267 -0
  11. data/ext/sha3/KeccakReferenceAndOptimized/KeccakOptimized64.vcproj +267 -0
  12. data/ext/sha3/KeccakReferenceAndOptimized/KeccakReference.vcproj +243 -0
  13. data/ext/sha3/KeccakReferenceAndOptimized/KeccakReference32BI.vcproj +243 -0
  14. data/ext/sha3/KeccakReferenceAndOptimized/KeccakReferenceAndOptimized.sln +62 -0
  15. data/ext/sha3/KeccakReferenceAndOptimized/KeccakSimple.vcproj +203 -0
  16. data/ext/sha3/KeccakReferenceAndOptimized/KeccakSimple32BI.vcproj +201 -0
  17. data/ext/sha3/KeccakReferenceAndOptimized/Sources/AVR8-rotate64.h +27 -0
  18. data/ext/sha3/KeccakReferenceAndOptimized/Sources/AVR8-rotate64.s +285 -0
  19. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-avr8-settings.h +2 -0
  20. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-avr8-test.c +142 -0
  21. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-avr8-util.h +15 -0
  22. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-avr8-util.s +119 -0
  23. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-avr8.c +184 -0
  24. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-avr8.h +25 -0
  25. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-compact-settings.h +3 -0
  26. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-compact-test.c +317 -0
  27. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-compact.c +341 -0
  28. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-compact.h +50 -0
  29. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-compact8-settings.h +2 -0
  30. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-compact8-test.c +192 -0
  31. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-compact8.c +375 -0
  32. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-compact8.h +47 -0
  33. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-crypto_hash-inplace-armgcc-ARMv7A-NEON.s +406 -0
  34. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-inplace-minimal-test.c +231 -0
  35. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-inplace-settings.h +3 -0
  36. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-inplace-test.c +221 -0
  37. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-inplace.c +445 -0
  38. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-inplace32BI-armgcc-ARMv6M.s +844 -0
  39. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-inplace32BI-armgcc-ARMv7A.s +687 -0
  40. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-inplace32BI-armgcc-ARMv7M.s +687 -0
  41. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-inplace32BI.c +849 -0
  42. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-simple-settings.h +3 -0
  43. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-simple-test.c +221 -0
  44. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-simple.c +403 -0
  45. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccak-simple32BI.c +673 -0
  46. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakDuplex.c +68 -0
  47. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakDuplex.h +59 -0
  48. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-32-rvk.macros +555 -0
  49. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-32-s1.macros +1187 -0
  50. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-32-s2.macros +1187 -0
  51. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-32.macros +26 -0
  52. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-64.macros +728 -0
  53. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-arm.c +123 -0
  54. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-armcc.s +653 -0
  55. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-armgcc.s +686 -0
  56. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-avr8.c +163 -0
  57. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-avr8asm-compact.s +647 -0
  58. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-avr8asm-fast.s +934 -0
  59. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-inplace-armgcc-ARMv7A-NEON.s +446 -0
  60. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-int-set.h +6 -0
  61. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-interface.h +46 -0
  62. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-opt32-settings.h +4 -0
  63. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-opt32.c +524 -0
  64. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-opt64-settings.h +7 -0
  65. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-opt64.c +504 -0
  66. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-reference.c +300 -0
  67. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-reference.h +20 -0
  68. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-reference.o +0 -0
  69. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-reference32BI.c +371 -0
  70. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-simd128.macros +651 -0
  71. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-simd64.macros +517 -0
  72. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-unrolling.macros +124 -0
  73. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-x86-64-asm.c +62 -0
  74. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-x86-64-gas.s +766 -0
  75. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-x86-64-shld-gas.s +766 -0
  76. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakF-1600-xop.macros +573 -0
  77. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakNISTInterface.c +81 -0
  78. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakNISTInterface.h +70 -0
  79. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakNISTInterface.o +0 -0
  80. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakSponge.c +266 -0
  81. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakSponge.h +76 -0
  82. data/ext/sha3/KeccakReferenceAndOptimized/Sources/KeccakSponge.o +0 -0
  83. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccakc1024-crypto_hash-inplace-armgcc-ARMv7A-NEON.s +296 -0
  84. data/ext/sha3/KeccakReferenceAndOptimized/Sources/Keccakc512-crypto_hash-inplace-armgcc-ARMv7A-NEON.s +429 -0
  85. data/ext/sha3/KeccakReferenceAndOptimized/Sources/brg_endian.h +142 -0
  86. data/ext/sha3/KeccakReferenceAndOptimized/Sources/crypto_hash.h +0 -0
  87. data/ext/sha3/KeccakReferenceAndOptimized/Sources/displayIntermediateValues.c +117 -0
  88. data/ext/sha3/KeccakReferenceAndOptimized/Sources/displayIntermediateValues.h +29 -0
  89. data/ext/sha3/KeccakReferenceAndOptimized/Sources/displayIntermediateValues.o +0 -0
  90. data/ext/sha3/KeccakReferenceAndOptimized/Sources/genKAT.c +692 -0
  91. data/ext/sha3/KeccakReferenceAndOptimized/Sources/mainARM.c +88 -0
  92. data/ext/sha3/KeccakReferenceAndOptimized/Sources/mainOptimized.c +23 -0
  93. data/ext/sha3/KeccakReferenceAndOptimized/Sources/mainReference.c +381 -0
  94. data/ext/sha3/KeccakReferenceAndOptimized/Sources/timing.c +436 -0
  95. data/ext/sha3/KeccakReferenceAndOptimized/Sources/timing.h +13 -0
  96. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/Sources/DoublePermutation-config.h +2 -0
  97. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/Sources/DoublePermutation.c +572 -0
  98. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/Sources/DoublePermutation.h +38 -0
  99. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/Sources/KeccakF-1600-unrolling.macros +124 -0
  100. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/Sources/Keccakc256TreeD2.c +81 -0
  101. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/Sources/Keccakc256TreeD2.h +18 -0
  102. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/Sources/Keccakc512TreeD2.c +81 -0
  103. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/Sources/Keccakc512TreeD2.h +18 -0
  104. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/Sources/crypto_hash.h +0 -0
  105. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/Sources/mainOptimized.c +112 -0
  106. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/Sources/timing-Double.c +225 -0
  107. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/Sources/timing-Double.h +20 -0
  108. data/ext/sha3/KeccakReferenceAndOptimized/TreeHashing/makefile +68 -0
  109. data/ext/sha3/KeccakReferenceAndOptimized/bin/KeccakCompact +0 -0
  110. data/ext/sha3/KeccakReferenceAndOptimized/bin/KeccakOptimized32 +0 -0
  111. data/ext/sha3/KeccakReferenceAndOptimized/bin/KeccakOptimized64 +0 -0
  112. data/ext/sha3/KeccakReferenceAndOptimized/bin/KeccakReference +0 -0
  113. data/ext/sha3/KeccakReferenceAndOptimized/bin/KeccakReference32BI +0 -0
  114. data/ext/sha3/KeccakReferenceAndOptimized/bin/KeccakSimple +0 -0
  115. data/ext/sha3/KeccakReferenceAndOptimized/bin/KeccakSimple32BI +0 -0
  116. data/ext/sha3/KeccakReferenceAndOptimized/bin/compact/Keccak-compact-test.o +0 -0
  117. data/ext/sha3/KeccakReferenceAndOptimized/bin/compact/Keccak-compact.o +0 -0
  118. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized32/KeccakDuplex.o +0 -0
  119. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized32/KeccakF-1600-opt32.o +0 -0
  120. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized32/KeccakNISTInterface.o +0 -0
  121. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized32/KeccakSponge.o +0 -0
  122. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized32/genKAT.o +0 -0
  123. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized32/mainOptimized.o +0 -0
  124. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized32/timing.o +0 -0
  125. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized64/KeccakDuplex.o +0 -0
  126. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized64/KeccakF-1600-opt64.o +0 -0
  127. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized64/KeccakNISTInterface.o +0 -0
  128. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized64/KeccakSponge.o +0 -0
  129. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized64/genKAT.o +0 -0
  130. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized64/mainOptimized.o +0 -0
  131. data/ext/sha3/KeccakReferenceAndOptimized/bin/optimized64/timing.o +0 -0
  132. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference/KeccakDuplex.o +0 -0
  133. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference/KeccakF-1600-reference.o +0 -0
  134. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference/KeccakNISTInterface.o +0 -0
  135. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference/KeccakSponge.o +0 -0
  136. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference/displayIntermediateValues.o +0 -0
  137. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference/genKAT.o +0 -0
  138. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference/mainReference.o +0 -0
  139. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference32bi/KeccakDuplex.o +0 -0
  140. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference32bi/KeccakF-1600-reference32BI.o +0 -0
  141. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference32bi/KeccakNISTInterface.o +0 -0
  142. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference32bi/KeccakSponge.o +0 -0
  143. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference32bi/displayIntermediateValues.o +0 -0
  144. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference32bi/genKAT.o +0 -0
  145. data/ext/sha3/KeccakReferenceAndOptimized/bin/reference32bi/mainReference.o +0 -0
  146. data/ext/sha3/KeccakReferenceAndOptimized/bin/simple/Keccak-simple-test.o +0 -0
  147. data/ext/sha3/KeccakReferenceAndOptimized/bin/simple/Keccak-simple.o +0 -0
  148. data/ext/sha3/KeccakReferenceAndOptimized/bin/simple32BI/Keccak-simple-test.o +0 -0
  149. data/ext/sha3/KeccakReferenceAndOptimized/bin/simple32BI/Keccak-simple32BI.o +0 -0
  150. data/ext/sha3/KeccakReferenceAndOptimized/compile64.bat +1 -0
  151. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/checksum-keccak +1 -0
  152. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/checksum-keccakc1024 +1 -0
  153. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/checksum-keccakc256 +1 -0
  154. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/checksum-keccakc256treed2 +1 -0
  155. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/checksum-keccakc448 +1 -0
  156. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/checksum-keccakc512 +1 -0
  157. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/checksum-keccakc512treed2 +1 -0
  158. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/checksum-keccakc768 +1 -0
  159. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/hash-keccak.c +11 -0
  160. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/hash-keccakc1024.c +11 -0
  161. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/hash-keccakc256.c +11 -0
  162. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/hash-keccakc448.c +11 -0
  163. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/hash-keccakc512.c +11 -0
  164. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/hash-keccakc768.c +11 -0
  165. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/int-set-keccak.h +1 -0
  166. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/int-set-keccakc1024.h +1 -0
  167. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/int-set-keccakc256.h +1 -0
  168. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/int-set-keccakc448.h +1 -0
  169. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/int-set-keccakc512.h +1 -0
  170. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/int-set-keccakc768.h +1 -0
  171. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/populate.py +506 -0
  172. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/simple-keccak.h +2 -0
  173. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/simple-keccakc1024.h +2 -0
  174. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/simple-keccakc256.h +2 -0
  175. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/simple-keccakc448.h +2 -0
  176. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/simple-keccakc512.h +2 -0
  177. data/ext/sha3/KeccakReferenceAndOptimized/eBASH/simple-keccakc768.h +2 -0
  178. data/ext/sha3/KeccakReferenceAndOptimized/makefile +327 -0
  179. data/ext/sha3/Makefile +240 -0
  180. data/ext/sha3/depend +28 -0
  181. data/ext/sha3/extconf.rb +21 -0
  182. data/ext/sha3/sha3.c +95 -0
  183. data/lib/sha3-ruby.rb +27 -0
  184. data/lib/sha3-ruby/version.rb +5 -0
  185. data/sha3-ruby.gemspec +21 -0
  186. metadata +233 -0
@@ -0,0 +1,3 @@
1
+ #define cKeccakB 1600
2
+ #define cKeccakR 1024
3
+ //#define cKeccakFixedOutputLengthInBytes 64
@@ -0,0 +1,221 @@
1
+ /*
2
+ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
3
+ Michaël Peeters and Gilles Van Assche. For more information, feedback or
4
+ questions, please refer to our website: http://keccak.noekeon.org/
5
+
6
+ Implementation by Ronny Van Keer,
7
+ hereby denoted as "the implementer".
8
+
9
+ To the extent possible under law, the implementer has waived all copyright
10
+ and related or neighboring rights to the source code in this file.
11
+ http://creativecommons.org/publicdomain/zero/1.0/
12
+ */
13
+
14
+ #include "Keccak-simple-settings.h"
15
+ #define cKeccakR_SizeInBytes (cKeccakR / 8)
16
+ #include <string.h>
17
+ #include <stdio.h>
18
+ #include <ctype.h>
19
+
20
+ #if defined(__GNUC__)
21
+ #define ALIGN __attribute__ ((aligned(32)))
22
+ #elif defined(_MSC_VER)
23
+ #define ALIGN __declspec(align(32))
24
+ #else
25
+ #define ALIGN
26
+ #endif
27
+
28
+ #if (cKeccakB == 1600) && (cKeccakR == 1024)
29
+ const char * testVectorFile = "ShortMsgKAT_0.txt";
30
+ #elif (cKeccakB == 1600) && (cKeccakR == 1152) && (cKeccakFixedOutputLengthInBytes == 28)
31
+ const char * testVectorFile = "ShortMsgKAT_224.txt";
32
+ #elif (cKeccakB == 1600) && (cKeccakR == 1088) && (cKeccakFixedOutputLengthInBytes == 32)
33
+ const char * testVectorFile = "ShortMsgKAT_256.txt";
34
+ #elif (cKeccakB == 1600) && (cKeccakR == 832) && (cKeccakFixedOutputLengthInBytes == 48)
35
+ const char * testVectorFile = "ShortMsgKAT_384.txt";
36
+ #elif (cKeccakB == 1600) && (cKeccakR == 576) && (cKeccakFixedOutputLengthInBytes == 64)
37
+ const char * testVectorFile = "ShortMsgKAT_512.txt";
38
+ #elif (cKeccakB == 1600) && (cKeccakR == 1344)
39
+ const char * testVectorFile = "ShortMsgKAT_r1344c256.txt";
40
+ #elif (cKeccakB == 800) && (cKeccakR == 544)
41
+ const char * testVectorFile = "ShortMsgKAT_r544c256.txt";
42
+ #elif (cKeccakB == 800) && (cKeccakR == 512)
43
+ const char * testVectorFile = "ShortMsgKAT_r512c288.txt";
44
+ #elif (cKeccakB == 800) && (cKeccakR == 256)
45
+ const char * testVectorFile = "ShortMsgKAT_r256c544.txt";
46
+ #elif (cKeccakB == 400) && (cKeccakR == 144)
47
+ const char * testVectorFile = "ShortMsgKAT_r144c256.txt";
48
+ #elif (cKeccakB == 400) && (cKeccakR == 128)
49
+ const char * testVectorFile = "ShortMsgKAT_r128c272.txt";
50
+ #elif (cKeccakB == 200) && (cKeccakR == 40)
51
+ const char * testVectorFile = "ShortMsgKAT_r40c160.txt";
52
+ #else
53
+ #error "Please set the vector file name here."
54
+ #endif
55
+
56
+ #define cKeccakMaxMessageSizeInBytes (2047/8)
57
+
58
+ ALIGN unsigned char input[cKeccakMaxMessageSizeInBytes];
59
+ ALIGN unsigned char output[cKeccakR_SizeInBytes];
60
+
61
+ //
62
+ // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.)
63
+ //
64
+ #define MAX_MARKER_LEN 50
65
+
66
+ typedef unsigned char BitSequence;
67
+
68
+ int FindMarker(FILE *infile, const char *marker);
69
+ int FindMarker(FILE *infile, const char *marker)
70
+ {
71
+ char line[MAX_MARKER_LEN];
72
+ int i, len;
73
+
74
+ len = (int)strlen(marker);
75
+ if ( len > MAX_MARKER_LEN-1 )
76
+ len = MAX_MARKER_LEN-1;
77
+
78
+ for ( i=0; i<len; i++ )
79
+ if ( (line[i] = fgetc(infile)) == EOF )
80
+ return 0;
81
+ line[len] = '\0';
82
+
83
+ while ( 1 ) {
84
+ if ( !strncmp(line, marker, len) )
85
+ return 1;
86
+
87
+ for ( i=0; i<len-1; i++ )
88
+ line[i] = line[i+1];
89
+ if ( (line[len-1] = fgetc(infile)) == EOF )
90
+ return 0;
91
+ line[len] = '\0';
92
+ }
93
+
94
+ // shouldn't get here
95
+ return 0;
96
+ }
97
+
98
+ //
99
+ // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.)
100
+ //
101
+ int ReadHex(FILE *infile, BitSequence *A, int Length, char *str);
102
+ int ReadHex(FILE *infile, BitSequence *A, int Length, char *str)
103
+ {
104
+ int i, ch, started;
105
+ BitSequence ich;
106
+
107
+ if ( Length == 0 ) {
108
+ A[0] = 0x00;
109
+ return 1;
110
+ }
111
+ memset(A, 0x00, Length);
112
+ started = 0;
113
+ i = 0;
114
+ if ( FindMarker(infile, str) )
115
+ while ( (ch = fgetc(infile)) != EOF )
116
+ {
117
+ if ( !isxdigit(ch) ) {
118
+ if ( !started ) {
119
+ if ( ch == '\n' )
120
+ break;
121
+ else
122
+ continue;
123
+ }
124
+ else
125
+ break;
126
+ }
127
+ started = 1;
128
+ if ( (ch >= '0') && (ch <= '9') )
129
+ ich = ch - '0';
130
+ else if ( (ch >= 'A') && (ch <= 'F') )
131
+ ich = ch - 'A' + 10;
132
+ else if ( (ch >= 'a') && (ch <= 'f') )
133
+ ich = ch - 'a' + 10;
134
+
135
+ A[i / 2] = (A[i / 2] << 4) | ich;
136
+ if ( (++i / 2) == Length )
137
+ break;
138
+ }
139
+ else
140
+ return 0;
141
+
142
+ return 1;
143
+ }
144
+
145
+ int main( void )
146
+ {
147
+ unsigned long long inlen;
148
+ int result = 0;
149
+ FILE *fp_in;
150
+ char marker[20];
151
+ int refLen;
152
+
153
+ #ifdef cKeccakFixedOutputLengthInBytes
154
+ refLen = cKeccakFixedOutputLengthInBytes;
155
+ #else
156
+ refLen = cKeccakR_SizeInBytes;
157
+ #endif
158
+
159
+ printf( "Testing Keccak[r=%u, c=%u] against %s over %d squeezed bytes\n", cKeccakR, cKeccakB - cKeccakR, testVectorFile, refLen );
160
+ if ( (fp_in = fopen(testVectorFile, "r")) == NULL )
161
+ {
162
+ printf("Couldn't open <%s> for read\n", testVectorFile);
163
+ return 1;
164
+ }
165
+
166
+ for ( inlen = 0; inlen <= cKeccakMaxMessageSizeInBytes; ++inlen )
167
+ {
168
+ sprintf( marker, "Len = %u", inlen * 8 );
169
+ if ( !FindMarker(fp_in, marker) )
170
+ {
171
+ printf("ERROR: no test vector found (%u bytes)\n", inlen );
172
+ result = 1;
173
+ break;
174
+ }
175
+ if ( !ReadHex(fp_in, input, (int)inlen, "Msg = ") )
176
+ {
177
+ printf("ERROR: unable to read 'Msg' (%u bytes)\n", inlen );
178
+ result = 1;
179
+ break;
180
+ }
181
+
182
+ result = crypto_hash( output, input, inlen );
183
+ if ( result != 0 )
184
+ {
185
+ printf("ERROR: crypto_hash() (%u bytes)\n", inlen);
186
+ result = 1;
187
+ break;
188
+ }
189
+
190
+ #ifdef cKeccakFixedOutputLengthInBytes
191
+ if ( !ReadHex(fp_in, input, refLen, "MD = ") )
192
+ #else
193
+ if ( !ReadHex(fp_in, input, refLen, "Squeezed = ") )
194
+ #endif
195
+ {
196
+ printf("ERROR: unable to read 'Squeezed/MD' (%u bytes)\n", inlen );
197
+ result = 1;
198
+ break;
199
+ }
200
+ if ( memcmp( output, input, refLen ) != 0)
201
+ {
202
+ printf("ERROR: hash verification (%u bytes)\n", inlen );
203
+ for(result=0; result<refLen; result++)
204
+ printf("%02X ", output[result]);
205
+ printf("\n");
206
+ result = 1;
207
+ break;
208
+ }
209
+ }
210
+
211
+ fclose( fp_in );
212
+ if ( !result )
213
+ printf( "\nSuccess!\n");
214
+
215
+ //printf( "\nPress a key ...");
216
+ //getchar();
217
+ //printf( "\n");
218
+ return ( result );
219
+ }
220
+
221
+
@@ -0,0 +1,403 @@
1
+ /*
2
+ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
3
+ Michaël Peeters and Gilles Van Assche. For more information, feedback or
4
+ questions, please refer to our website: http://keccak.noekeon.org/
5
+
6
+ Implementation by Ronny Van Keer,
7
+ hereby denoted as "the implementer".
8
+
9
+ To the extent possible under law, the implementer has waived all copyright
10
+ and related or neighboring rights to the source code in this file.
11
+ http://creativecommons.org/publicdomain/zero/1.0/
12
+ */
13
+
14
+ // WARNING: This implementation assumes a little-endian platform. Support for big-endinanness is not yet implemented.
15
+
16
+ #include <string.h>
17
+ #include "Keccak-simple-settings.h"
18
+ #define cKeccakR_SizeInBytes (cKeccakR / 8)
19
+ #include "crypto_hash.h"
20
+ #ifndef crypto_hash_BYTES
21
+ #ifdef cKeccakFixedOutputLengthInBytes
22
+ #define crypto_hash_BYTES cKeccakFixedOutputLengthInBytes
23
+ #else
24
+ #define crypto_hash_BYTES cKeccakR_SizeInBytes
25
+ #endif
26
+ #endif
27
+ #if (crypto_hash_BYTES > cKeccakR_SizeInBytes)
28
+ #error "Full squeezing not yet implemented"
29
+ #endif
30
+
31
+ #if (cKeccakB == 1600)
32
+ typedef unsigned long long UINT64;
33
+ typedef UINT64 tKeccakLane;
34
+ #define cKeccakNumberOfRounds 24
35
+ #elif (cKeccakB == 800)
36
+ typedef unsigned int UINT32;
37
+ // WARNING: on 8-bit and 16-bit platforms, this should be replaced by:
38
+ //typedef unsigned long UINT32;
39
+ typedef UINT32 tKeccakLane;
40
+ #define cKeccakNumberOfRounds 22
41
+ #elif (cKeccakB == 400)
42
+ typedef unsigned short UINT16;
43
+ typedef UINT16 tKeccakLane;
44
+ #define cKeccakNumberOfRounds 20
45
+ #elif (cKeccakB == 200)
46
+ typedef unsigned char UINT8;
47
+ typedef UINT8 tKeccakLane;
48
+ #define cKeccakNumberOfRounds 18
49
+ #else
50
+ #error "Unsupported Keccak-f width"
51
+ #endif
52
+
53
+ #define cKeccakLaneSizeInBits (sizeof(tKeccakLane) * 8)
54
+
55
+ #define ROL(a, offset) ((((tKeccakLane)a) << ((offset) % cKeccakLaneSizeInBits)) ^ (((tKeccakLane)a) >> (cKeccakLaneSizeInBits-((offset) % cKeccakLaneSizeInBits))))
56
+ #if ((cKeccakB/25) == 8)
57
+ #define ROL_mult8(a, offset) ((tKeccakLane)a)
58
+ #else
59
+ #define ROL_mult8(a, offset) ROL(a, offset)
60
+ #endif
61
+ void KeccakF( tKeccakLane * state, const tKeccakLane *in, int laneCount );
62
+
63
+ int crypto_hash( unsigned char *out, const unsigned char *in, unsigned long long inlen )
64
+ {
65
+ tKeccakLane state[5 * 5];
66
+ #if (crypto_hash_BYTES >= cKeccakR_SizeInBytes)
67
+ #define temp out
68
+ #else
69
+ unsigned char temp[cKeccakR_SizeInBytes];
70
+ #endif
71
+
72
+ memset( state, 0, sizeof(state) );
73
+
74
+ for ( /* empty */; inlen >= cKeccakR_SizeInBytes; inlen -= cKeccakR_SizeInBytes, in += cKeccakR_SizeInBytes )
75
+ {
76
+ KeccakF( state, (const tKeccakLane*)in, cKeccakR_SizeInBytes / sizeof(tKeccakLane) );
77
+ }
78
+
79
+ // padding
80
+ memcpy( temp, in, (size_t)inlen );
81
+ temp[inlen++] = 1;
82
+ memset( temp+inlen, 0, cKeccakR_SizeInBytes - (size_t)inlen );
83
+ temp[cKeccakR_SizeInBytes-1] |= 0x80;
84
+ KeccakF( state, (const tKeccakLane*)temp, cKeccakR_SizeInBytes / sizeof(tKeccakLane) );
85
+ memcpy( out, state, crypto_hash_BYTES );
86
+ #if (crypto_hash_BYTES >= cKeccakR_SizeInBytes)
87
+ #undef temp
88
+ #endif
89
+
90
+ return ( 0 );
91
+ }
92
+
93
+
94
+ const tKeccakLane KeccakF_RoundConstants[cKeccakNumberOfRounds] =
95
+ {
96
+ (tKeccakLane)0x0000000000000001ULL,
97
+ (tKeccakLane)0x0000000000008082ULL,
98
+ (tKeccakLane)0x800000000000808aULL,
99
+ (tKeccakLane)0x8000000080008000ULL,
100
+ (tKeccakLane)0x000000000000808bULL,
101
+ (tKeccakLane)0x0000000080000001ULL,
102
+ (tKeccakLane)0x8000000080008081ULL,
103
+ (tKeccakLane)0x8000000000008009ULL,
104
+ (tKeccakLane)0x000000000000008aULL,
105
+ (tKeccakLane)0x0000000000000088ULL,
106
+ (tKeccakLane)0x0000000080008009ULL,
107
+ (tKeccakLane)0x000000008000000aULL,
108
+ (tKeccakLane)0x000000008000808bULL,
109
+ (tKeccakLane)0x800000000000008bULL,
110
+ (tKeccakLane)0x8000000000008089ULL,
111
+ (tKeccakLane)0x8000000000008003ULL,
112
+ (tKeccakLane)0x8000000000008002ULL,
113
+ (tKeccakLane)0x8000000000000080ULL
114
+ #if (cKeccakB >= 400)
115
+ , (tKeccakLane)0x000000000000800aULL,
116
+ (tKeccakLane)0x800000008000000aULL
117
+ #if (cKeccakB >= 800)
118
+ , (tKeccakLane)0x8000000080008081ULL,
119
+ (tKeccakLane)0x8000000000008080ULL
120
+ #if (cKeccakB == 1600)
121
+ , (tKeccakLane)0x0000000080000001ULL,
122
+ (tKeccakLane)0x8000000080008008ULL
123
+ #endif
124
+ #endif
125
+ #endif
126
+ };
127
+
128
+ void KeccakF( tKeccakLane * state, const tKeccakLane *in, int laneCount )
129
+ {
130
+
131
+ {
132
+ while ( --laneCount >= 0 )
133
+ {
134
+ state[laneCount] ^= in[laneCount];
135
+ }
136
+ }
137
+
138
+ {
139
+ tKeccakLane Aba, Abe, Abi, Abo, Abu;
140
+ tKeccakLane Aga, Age, Agi, Ago, Agu;
141
+ tKeccakLane Aka, Ake, Aki, Ako, Aku;
142
+ tKeccakLane Ama, Ame, Ami, Amo, Amu;
143
+ tKeccakLane Asa, Ase, Asi, Aso, Asu;
144
+ tKeccakLane BCa, BCe, BCi, BCo, BCu;
145
+ tKeccakLane Da, De, Di, Do, Du;
146
+ tKeccakLane Eba, Ebe, Ebi, Ebo, Ebu;
147
+ tKeccakLane Ega, Ege, Egi, Ego, Egu;
148
+ tKeccakLane Eka, Eke, Eki, Eko, Eku;
149
+ tKeccakLane Ema, Eme, Emi, Emo, Emu;
150
+ tKeccakLane Esa, Ese, Esi, Eso, Esu;
151
+ #define round laneCount
152
+
153
+ //copyFromState(A, state)
154
+ Aba = state[ 0];
155
+ Abe = state[ 1];
156
+ Abi = state[ 2];
157
+ Abo = state[ 3];
158
+ Abu = state[ 4];
159
+ Aga = state[ 5];
160
+ Age = state[ 6];
161
+ Agi = state[ 7];
162
+ Ago = state[ 8];
163
+ Agu = state[ 9];
164
+ Aka = state[10];
165
+ Ake = state[11];
166
+ Aki = state[12];
167
+ Ako = state[13];
168
+ Aku = state[14];
169
+ Ama = state[15];
170
+ Ame = state[16];
171
+ Ami = state[17];
172
+ Amo = state[18];
173
+ Amu = state[19];
174
+ Asa = state[20];
175
+ Ase = state[21];
176
+ Asi = state[22];
177
+ Aso = state[23];
178
+ Asu = state[24];
179
+
180
+ for( round = 0; round < cKeccakNumberOfRounds; round += 2 )
181
+ {
182
+ // prepareTheta
183
+ BCa = Aba^Aga^Aka^Ama^Asa;
184
+ BCe = Abe^Age^Ake^Ame^Ase;
185
+ BCi = Abi^Agi^Aki^Ami^Asi;
186
+ BCo = Abo^Ago^Ako^Amo^Aso;
187
+ BCu = Abu^Agu^Aku^Amu^Asu;
188
+
189
+ //thetaRhoPiChiIotaPrepareTheta(round , A, E)
190
+ Da = BCu^ROL(BCe, 1);
191
+ De = BCa^ROL(BCi, 1);
192
+ Di = BCe^ROL(BCo, 1);
193
+ Do = BCi^ROL(BCu, 1);
194
+ Du = BCo^ROL(BCa, 1);
195
+
196
+ Aba ^= Da;
197
+ BCa = Aba;
198
+ Age ^= De;
199
+ BCe = ROL(Age, 44);
200
+ Aki ^= Di;
201
+ BCi = ROL(Aki, 43);
202
+ Amo ^= Do;
203
+ BCo = ROL(Amo, 21);
204
+ Asu ^= Du;
205
+ BCu = ROL(Asu, 14);
206
+ Eba = BCa ^((~BCe)& BCi );
207
+ Eba ^= (tKeccakLane)KeccakF_RoundConstants[round];
208
+ Ebe = BCe ^((~BCi)& BCo );
209
+ Ebi = BCi ^((~BCo)& BCu );
210
+ Ebo = BCo ^((~BCu)& BCa );
211
+ Ebu = BCu ^((~BCa)& BCe );
212
+
213
+ Abo ^= Do;
214
+ BCa = ROL(Abo, 28);
215
+ Agu ^= Du;
216
+ BCe = ROL(Agu, 20);
217
+ Aka ^= Da;
218
+ BCi = ROL(Aka, 3);
219
+ Ame ^= De;
220
+ BCo = ROL(Ame, 45);
221
+ Asi ^= Di;
222
+ BCu = ROL(Asi, 61);
223
+ Ega = BCa ^((~BCe)& BCi );
224
+ Ege = BCe ^((~BCi)& BCo );
225
+ Egi = BCi ^((~BCo)& BCu );
226
+ Ego = BCo ^((~BCu)& BCa );
227
+ Egu = BCu ^((~BCa)& BCe );
228
+
229
+ Abe ^= De;
230
+ BCa = ROL(Abe, 1);
231
+ Agi ^= Di;
232
+ BCe = ROL(Agi, 6);
233
+ Ako ^= Do;
234
+ BCi = ROL(Ako, 25);
235
+ Amu ^= Du;
236
+ BCo = ROL_mult8(Amu, 8);
237
+ Asa ^= Da;
238
+ BCu = ROL(Asa, 18);
239
+ Eka = BCa ^((~BCe)& BCi );
240
+ Eke = BCe ^((~BCi)& BCo );
241
+ Eki = BCi ^((~BCo)& BCu );
242
+ Eko = BCo ^((~BCu)& BCa );
243
+ Eku = BCu ^((~BCa)& BCe );
244
+
245
+ Abu ^= Du;
246
+ BCa = ROL(Abu, 27);
247
+ Aga ^= Da;
248
+ BCe = ROL(Aga, 36);
249
+ Ake ^= De;
250
+ BCi = ROL(Ake, 10);
251
+ Ami ^= Di;
252
+ BCo = ROL(Ami, 15);
253
+ Aso ^= Do;
254
+ BCu = ROL_mult8(Aso, 56);
255
+ Ema = BCa ^((~BCe)& BCi );
256
+ Eme = BCe ^((~BCi)& BCo );
257
+ Emi = BCi ^((~BCo)& BCu );
258
+ Emo = BCo ^((~BCu)& BCa );
259
+ Emu = BCu ^((~BCa)& BCe );
260
+
261
+ Abi ^= Di;
262
+ BCa = ROL(Abi, 62);
263
+ Ago ^= Do;
264
+ BCe = ROL(Ago, 55);
265
+ Aku ^= Du;
266
+ BCi = ROL(Aku, 39);
267
+ Ama ^= Da;
268
+ BCo = ROL(Ama, 41);
269
+ Ase ^= De;
270
+ BCu = ROL(Ase, 2);
271
+ Esa = BCa ^((~BCe)& BCi );
272
+ Ese = BCe ^((~BCi)& BCo );
273
+ Esi = BCi ^((~BCo)& BCu );
274
+ Eso = BCo ^((~BCu)& BCa );
275
+ Esu = BCu ^((~BCa)& BCe );
276
+
277
+ // prepareTheta
278
+ BCa = Eba^Ega^Eka^Ema^Esa;
279
+ BCe = Ebe^Ege^Eke^Eme^Ese;
280
+ BCi = Ebi^Egi^Eki^Emi^Esi;
281
+ BCo = Ebo^Ego^Eko^Emo^Eso;
282
+ BCu = Ebu^Egu^Eku^Emu^Esu;
283
+
284
+ //thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
285
+ Da = BCu^ROL(BCe, 1);
286
+ De = BCa^ROL(BCi, 1);
287
+ Di = BCe^ROL(BCo, 1);
288
+ Do = BCi^ROL(BCu, 1);
289
+ Du = BCo^ROL(BCa, 1);
290
+
291
+ Eba ^= Da;
292
+ BCa = Eba;
293
+ Ege ^= De;
294
+ BCe = ROL(Ege, 44);
295
+ Eki ^= Di;
296
+ BCi = ROL(Eki, 43);
297
+ Emo ^= Do;
298
+ BCo = ROL(Emo, 21);
299
+ Esu ^= Du;
300
+ BCu = ROL(Esu, 14);
301
+ Aba = BCa ^((~BCe)& BCi );
302
+ Aba ^= (tKeccakLane)KeccakF_RoundConstants[round+1];
303
+ Abe = BCe ^((~BCi)& BCo );
304
+ Abi = BCi ^((~BCo)& BCu );
305
+ Abo = BCo ^((~BCu)& BCa );
306
+ Abu = BCu ^((~BCa)& BCe );
307
+
308
+ Ebo ^= Do;
309
+ BCa = ROL(Ebo, 28);
310
+ Egu ^= Du;
311
+ BCe = ROL(Egu, 20);
312
+ Eka ^= Da;
313
+ BCi = ROL(Eka, 3);
314
+ Eme ^= De;
315
+ BCo = ROL(Eme, 45);
316
+ Esi ^= Di;
317
+ BCu = ROL(Esi, 61);
318
+ Aga = BCa ^((~BCe)& BCi );
319
+ Age = BCe ^((~BCi)& BCo );
320
+ Agi = BCi ^((~BCo)& BCu );
321
+ Ago = BCo ^((~BCu)& BCa );
322
+ Agu = BCu ^((~BCa)& BCe );
323
+
324
+ Ebe ^= De;
325
+ BCa = ROL(Ebe, 1);
326
+ Egi ^= Di;
327
+ BCe = ROL(Egi, 6);
328
+ Eko ^= Do;
329
+ BCi = ROL(Eko, 25);
330
+ Emu ^= Du;
331
+ BCo = ROL_mult8(Emu, 8);
332
+ Esa ^= Da;
333
+ BCu = ROL(Esa, 18);
334
+ Aka = BCa ^((~BCe)& BCi );
335
+ Ake = BCe ^((~BCi)& BCo );
336
+ Aki = BCi ^((~BCo)& BCu );
337
+ Ako = BCo ^((~BCu)& BCa );
338
+ Aku = BCu ^((~BCa)& BCe );
339
+
340
+ Ebu ^= Du;
341
+ BCa = ROL(Ebu, 27);
342
+ Ega ^= Da;
343
+ BCe = ROL(Ega, 36);
344
+ Eke ^= De;
345
+ BCi = ROL(Eke, 10);
346
+ Emi ^= Di;
347
+ BCo = ROL(Emi, 15);
348
+ Eso ^= Do;
349
+ BCu = ROL_mult8(Eso, 56);
350
+ Ama = BCa ^((~BCe)& BCi );
351
+ Ame = BCe ^((~BCi)& BCo );
352
+ Ami = BCi ^((~BCo)& BCu );
353
+ Amo = BCo ^((~BCu)& BCa );
354
+ Amu = BCu ^((~BCa)& BCe );
355
+
356
+ Ebi ^= Di;
357
+ BCa = ROL(Ebi, 62);
358
+ Ego ^= Do;
359
+ BCe = ROL(Ego, 55);
360
+ Eku ^= Du;
361
+ BCi = ROL(Eku, 39);
362
+ Ema ^= Da;
363
+ BCo = ROL(Ema, 41);
364
+ Ese ^= De;
365
+ BCu = ROL(Ese, 2);
366
+ Asa = BCa ^((~BCe)& BCi );
367
+ Ase = BCe ^((~BCi)& BCo );
368
+ Asi = BCi ^((~BCo)& BCu );
369
+ Aso = BCo ^((~BCu)& BCa );
370
+ Asu = BCu ^((~BCa)& BCe );
371
+ }
372
+
373
+ //copyToState(state, A)
374
+ state[ 0] = Aba;
375
+ state[ 1] = Abe;
376
+ state[ 2] = Abi;
377
+ state[ 3] = Abo;
378
+ state[ 4] = Abu;
379
+ state[ 5] = Aga;
380
+ state[ 6] = Age;
381
+ state[ 7] = Agi;
382
+ state[ 8] = Ago;
383
+ state[ 9] = Agu;
384
+ state[10] = Aka;
385
+ state[11] = Ake;
386
+ state[12] = Aki;
387
+ state[13] = Ako;
388
+ state[14] = Aku;
389
+ state[15] = Ama;
390
+ state[16] = Ame;
391
+ state[17] = Ami;
392
+ state[18] = Amo;
393
+ state[19] = Amu;
394
+ state[20] = Asa;
395
+ state[21] = Ase;
396
+ state[22] = Asi;
397
+ state[23] = Aso;
398
+ state[24] = Asu;
399
+
400
+ #undef round
401
+ }
402
+
403
+ }