diff --git a/.gitignore b/.gitignore index d62c06b..4428804 100644 --- a/.gitignore +++ b/.gitignore @@ -3,23 +3,10 @@ *.ii *.s -# binary compiler output -code_blocks/obj -code_blocks/bin -code_blocks/libEnigma/obj -code_blocks/libEnigma/bin -tests/obj -tests/bin +#CMake +/build/ +/lib/ +/bin/ -# Code::Blocks -code_blocks/enigma-opt.depend -code_blocks/enigma-opt.layout -enigma-opt.cscope_file_list -tests/enigma-optima.tests.depend -tests/enigma-optima.tests.layout -enigma-optima.workspace.layout - -# CCCC -code_blocks/.cccc - -code_blocks/libEnigma/libEnigma\.depend +# generated files +optima/config/releaseVersion.cpp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1ad27fb --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "extern/gbench"] + path = extern/gbench + url = ../../google/benchmark.git +[submodule "extern/gtest"] + path = extern/gtest + url = ../../abseil/googletest.git diff --git a/BOINC/CMakeLists.txt b/BOINC/CMakeLists.txt new file mode 100644 index 0000000..ca85fb7 --- /dev/null +++ b/BOINC/CMakeLists.txt @@ -0,0 +1,7 @@ +if(CMAKE_SYSTEM_NAME STREQUAL Windows) + add_subdirectory(Windows) +elseif(CMAKE_SYSTEM_NAME STREQUAL Linux) + add_subdirectory(Linux) +endif() + + diff --git a/BOINC/Linux/CMakeLists.txt b/BOINC/Linux/CMakeLists.txt new file mode 100644 index 0000000..767fec8 --- /dev/null +++ b/BOINC/Linux/CMakeLists.txt @@ -0,0 +1,4 @@ +configure_file ( + "app_info.in.xml" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/app_info.xml" +) \ No newline at end of file diff --git a/BOINC/Linux/app_info.xml b/BOINC/Linux/app_info.in.xml similarity index 91% rename from BOINC/Linux/app_info.xml rename to BOINC/Linux/app_info.in.xml index 1cfc24f..563c31e 100644 --- a/BOINC/Linux/app_info.xml +++ b/BOINC/Linux/app_info.in.xml @@ -1,12 +1,12 @@ enigma_m4_2 - Enigma Optima v1.1.0 + Enigma Optima ${ENIGMA_GIT_DESCRIBE_VERSION} 0 enigma_m4_3 - Enigma Optima AV v1.1.0 + Enigma Optima AV ${ENIGMA_GIT_DESCRIBE_VERSION} 0 diff --git a/BOINC/Windows/CMakeLists.txt b/BOINC/Windows/CMakeLists.txt new file mode 100644 index 0000000..fa88d54 --- /dev/null +++ b/BOINC/Windows/CMakeLists.txt @@ -0,0 +1,10 @@ +if(ENIGMA_BUILD_32_BIT) + set(APP_INFO_FOLDER x86) +else() + set(APP_INFO_FOLDER x64) +endif() + +configure_file ( + "${APP_INFO_FOLDER}/app_info.in.xml" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/app_info.xml" +) \ No newline at end of file diff --git a/BOINC/Windows/x64/app_info.xml b/BOINC/Windows/x64/app_info.in.xml similarity index 91% rename from BOINC/Windows/x64/app_info.xml rename to BOINC/Windows/x64/app_info.in.xml index bad845a..ac881b2 100644 --- a/BOINC/Windows/x64/app_info.xml +++ b/BOINC/Windows/x64/app_info.in.xml @@ -1,12 +1,12 @@ enigma_m4_2 - Enigma Optima v1.1.0 + Enigma Optima ${ENIGMA_GIT_DESCRIBE_VERSION} 0 enigma_m4_3 - Enigma Optima AV v1.1.0 + Enigma Optima AV ${ENIGMA_GIT_DESCRIBE_VERSION} 0 diff --git a/BOINC/Windows/x86/app_info.xml b/BOINC/Windows/x86/app_info.in.xml similarity index 91% rename from BOINC/Windows/x86/app_info.xml rename to BOINC/Windows/x86/app_info.in.xml index c8993b7..a79e654 100644 --- a/BOINC/Windows/x86/app_info.xml +++ b/BOINC/Windows/x86/app_info.in.xml @@ -1,12 +1,12 @@ enigma_m4_2 - Enigma Optima v1.1.0 + Enigma Optima ${ENIGMA_GIT_DESCRIBE_VERSION} 0 enigma_m4_3 - Enigma Optima AV v1.1.0 + Enigma Optima AV ${ENIGMA_GIT_DESCRIBE_VERSION} 0 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..04655dd --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,133 @@ +cmake_minimum_required(VERSION 3.0) + +project(enigma_optima_suite + VERSION 1.1.1 + LANGUAGES C CXX) + +set(default_build_type "RelWithDebInfo") +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_CONFIGURATION_TYPES "Debug RelWithDebInfo") + message(STATUS "Setting build type to '${default_build_type}' as none was specified.") + set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE + STRING "Choose the type of build." FORCE) + # Set the possible values of build type for cmake-gui + # set_property accepts a semicolon separated list + set(CMAKE_CONFIGURATION_TYPE_LIST "${CMAKE_CONFIGURATION_TYPES}") + separate_arguments(CMAKE_CONFIGURATION_TYPE_LIST) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPE_LIST}) +endif() + +# Substitute default flags (use -O3 instead of -O2) +if(CMAKE_C_COMPILER_ID MATCHES "GNU" + AND CMAKE_CXX_COMPILER_ID MATCHES "GNU" + AND NOT ENIGMA_DEFAULT_FLAGS_SET) + if(NOT ENIGMA_DEFAULT_FLAGS_RELWITHDEBINFO) + set(ENIGMA_DEFAULT_FLAGS_RELWITHDEBINFO "-O3 -g -DNDEBUG") + endif() + set(CMAKE_C_FLAGS_RELWITHDEBINFO "${ENIGMA_DEFAULT_FLAGS_RELWITHDEBINFO}" CACHE STRING "" FORCE) + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${ENIGMA_DEFAULT_FLAGS_RELWITHDEBINFO}" CACHE STRING "" FORCE) + set(ENIGMA_DEFAULT_FLAGS_SET ON CACHE BOOL "Whether C/CXX_FLAGS_RELWITHDEBINFO has been changed" FORCE) + mark_as_advanced(ENIGMA_DEFAULT_FLAGS_SET) +endif() + +if(CMAKE_C_COMPILER_ID MATCHES "GNU") + option(ENIGMA_BUILD_32_BIT "Build 32 bit artifacts (x86)" OFF) + if(ENIGMA_BUILD_32_BIT) + set(ENIGMA_BITS_DIRECTORY_NAME "/x86") + else() + set(ENIGMA_BITS_DIRECTORY_NAME "/x64") + endif() +else() + set(ENIGMA_BITS_DIRECTORY_NAME "") +endif() + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib/${ENIGMA_BITS_DIRECTORY_NAME}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib/${ENIGMA_BITS_DIRECTORY_NAME}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin/${ENIGMA_BITS_DIRECTORY_NAME}") + +if(CMAKE_C_COMPILER_ID MATCHES "GNU") + include(CheckCCompilerFlag) + include(CheckCXXCompilerFlag) + if(ENIGMA_BUILD_32_BIT) + add_compile_options(-m32 -march=pentium3) + # Disable position independent code generation + # * default on Windows + # * without it Linux code is significantly slower + add_compile_options(-fno-pic -fno-pie) + # add_link_options in CMake 3.13 + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") + + check_cxx_compiler_flag(-no-pie GCC_HAS_NO_PIE_OPTION) + if(GCC_HAS_NO_PIE_OPTION) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie") + endif() + else() + # Official MinGW-w64 builds have changed arch + add_compile_options(-m64 -march=x86-64) + # add_link_options in CMake 3.13 + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m64") + endif() + # Official MinGW-w64 builds have changed tune + add_compile_options(-mtune=generic) + + check_c_compiler_flag(-Wimplicit-fallthrough=5 GCC_HAS_IMPLICIT_FALLTHROUGH) + if(GCC_HAS_IMPLICIT_FALLTHROUGH) + list(APPEND ENIGMA_COMPILE_OPTIONS -Wimplicit-fallthrough=5) + endif() + + # treat some warnings as errors + list(APPEND ENIGMA_COMPILE_OPTIONS + -Werror=implicit-function-declaration + -Werror=return-type) + # add some warnings + list(APPEND ENIGMA_COMPILE_OPTIONS + -Wall + -Wcast-align + -Wextra + -Wfloat-equal + -Wmissing-declarations + -Wredundant-decls + -Wshadow + -Wunsafe-loop-optimizations + -Wvector-operation-performance) + # and change call convention for all targets + add_compile_options( + -fcall-used-xmm6 + -fcall-used-xmm7 + -fcall-used-xmm8 + -fcall-used-xmm9 + -fcall-used-xmm10 + -fcall-used-xmm11 + -fcall-used-xmm12 + -fcall-used-xmm13 + -fcall-used-xmm14 + -fcall-used-xmm15) + + set(ENIGMA_CXX_COMPILE_OPTIONS + -Wnon-virtual-dtor) +endif() + +find_package(Git REQUIRED) +execute_process(COMMAND ${GIT_EXECUTABLE} describe --dirty + OUTPUT_VARIABLE ENIGMA_GIT_DESCRIBE_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + +add_subdirectory(libEnigma) + +add_subdirectory(optima) + +add_subdirectory(benchmark) + +add_subdirectory(BOINC) + +enable_testing() +add_subdirectory(tests) + +set(BENCHMARK_BUILD_32_BITS ${ENIGMA_BUILD_32_BIT} CACHE BOOL "" FORCE) +set(BENCHMARK_ENABLE_INSTALL OFF CACHE BOOL "") +set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "") +add_subdirectory(extern/gbench) + +set(INSTALL_GTEST OFF CACHE BOOL "") +set(BUILD_GMOCK OFF CACHE BOOL "") +add_subdirectory(extern/gtest) diff --git a/benchmark/00bigr.cur b/benchmark/00bigr.cur new file mode 100644 index 0000000..c22b5c8 --- /dev/null +++ b/benchmark/00bigr.cur @@ -0,0 +1,568 @@ +ER 456 +EN 375 +IN 341 +EI 332 +ST 264 +IE 245 +BE 210 +UN 204 +NS 202 +GE 188 +AN 179 +TE 173 +UE 165 +OR 156 +RE 147 +ES 138 +XS 137 +ND 137 +NG 136 +RI 135 +NA 130 +LL 124 +NX 123 +SE 121 +TX 118 +DE 118 +FU 117 +NU 113 +QT 111 +NF 109 +XE 109 +AU 107 +WO 107 +RO 105 +EL 105 +TA 102 +RA 102 +RX 101 +AX 101 +AR 98 +EG 98 +LE 98 +ZW 96 +UL 96 +XA 96 +ET 95 +AQ 95 +SI 94 +TR 92 +XK 92 +EX 90 +NE 90 +IQ 89 +CH 88 +ON 87 +SX 84 +SS 84 +VI 89 +LA 83 +NI 82 +MA 81 +LX 79 +RS 77 +ME 77 +EH 76 +XD 76 +EB 76 +DR 75 +TO 75 +IT 74 +EQ 74 +EM 74 +KO 73 +RT 72 +OE 70 +LI 68 +DI 68 +AB 68 +OS 66 +NN 66 +ED 66 +XM 65 +ZU 63 +WE 63 +XV 65 +FX 61 +XB 61 +VO 60 +ZE 60 +VE 60 +SA 60 +MX 59 +HR 59 +RU 58 +AM 58 +QS 57 +NO 57 +RD 56 +HE 55 +YY 54 +OX 53 +NT 53 +XN 53 +AL 53 +XF 53 +US 52 +OP 52 +FE 52 +TS 51 +IS 51 +XZ 50 +XH 50 +SQ 49 +FL 49 +SC 48 +GA 48 +KX 47 +IX 47 +OM 47 +HA 47 +WA 46 +EU 45 +TT 45 +DO 45 +UM 45 +TZ 44 +XP 44 +TI 43 +SZ 42 +NZ 42 +XR 42 +MO 42 +KE 42 +KA 42 +AS 41 +AE 41 +IV 40 +GU 40 +MI 39 +UF 39 +GX 38 +XU 38 +OT 38 +FR 38 +UR 37 +RP 37 +FF 37 +HO 36 +XL 36 +XG 36 +IG 36 +EF 36 +LN 35 +SP 34 +AF 34 +JE 34 +RB 34 +PA 34 +WX 33 +XI 33 +QX 32 +RW 32 +MM 32 +KL 32 +RK 32 +AG 32 +PF 32 +ZX 31 +TU 31 +NM 31 +FA 31 +BA 31 +PR 30 +SK 30 +LF 30 +XW 29 +DU 29 +GS 29 +RM 29 +OL 29 +RZ 28 +RN 28 +IM 28 +HL 28 +LD 28 +DX 27 +LU 27 +FS 27 +SO 27 +NK 27 +OF 27 +DA 27 +YX 26 +OW 26 +LT 26 +GR 26 +XO 26 +AH 26 +SG 26 +FZ 25 +VX 25 +TW 25 +HX 24 +RV 24 +NR 24 +HN 24 +BI 24 +RF 24 +UT 23 +EE 23 +EZ 22 +AZ 22 +MU 22 +DS 22 +IL 22 +SF 22 +JA 22 +SU 21 +AT 21 +SN 21 +OK 21 +AK 21 +RG 21 +PE 21 +EA 21 +EW 20 +QU 20 +PO 20 +LO 20 +BO 20 +DN 20 +UG 20 +GF 20 +EC 20 +KU 19 +ZT 19 +BS 19 +RL 19 +ZA 19 +GT 18 +IR 18 +BR 18 +GL 18 +QE 18 +KD 18 +ID 18 +MB 18 +OZ 17 +PX 17 +SV 17 +PT 17 +UQ 17 +UP 17 +PP 17 +FO 17 +TL 17 +EK 17 +NB 17 +DW 16 +EV 16 +ZO 16 +TN 16 +AJ 16 +KI 16 +UH 16 +TD 16 +AD 16 +XC 16 +UB 16 +IA 16 +RY 15 +MT 15 +FT 15 +QL 15 +TK 15 +FK 15 +IF 15 +SD 15 +OD 15 +XT 14 +PS 14 +RQ 14 +TM 14 +DL 14 +TH 14 +OG 14 +LG 14 +TB 14 +SB 14 +ZY 13 +LS 13 +MP 13 +IK 13 +AI 13 +QF 13 +KF 13 +GD 13 +MZ 12 +HT 12 +WI 12 +HI 12 +QG 12 +TY 11 +NY 11 +AV 11 +OQ 11 +EP 11 +GO 11 +MK 11 +ZI 11 +TG 11 +MF 11 +IC 11 +KW 10 +DT 10 +RR 10 +IO 10 +QM 10 +KM 10 +NL 10 +OH 10 +IB 10 +CB 10 +YA 10 +DY 9 +YV 9 +OV 9 +MV 9 +YR 9 +QN 9 +UK 9 +PK 9 +TJ 9 +SH 9 +FH 9 +MG 9 +QD 9 +OB 9 +ZZ 8 +IZ 8 +DZ 8 +GY 8 +NW 8 +TV 8 +QV 8 +HU 8 +QR 8 +BM 8 +QK 8 +LK 8 +TF 8 +YE 8 +RC 8 +AC 8 +FB 8 +DB 8 +OA 8 +LZ 7 +GZ 7 +LY 7 +NV 7 +WU 7 +KT 7 +KR 7 +FN 7 +SM 7 +HM 7 +SL 7 +BL 7 +CK 7 +YI 7 +BH 7 +PG 7 +BG 7 +UA 7 +PY 6 +BX 6 +MW 6 +LV 6 +GV 6 +PU 6 +JU 6 +BU 6 +BT 6 +CS 6 +MR 6 +HP 6 +AP 6 +WK 6 +XJ 6 +YH 6 +NH 6 +ZG 6 +FD 6 +DD 6 +OC 6 +VA 6 +QZ 5 +BZ 5 +FV 5 +WS 5 +HS 5 +NP 5 +MN 5 +KN 5 +GM 5 +PI 5 +GI 5 +FI 5 +YF 5 +UD 5 +MD 5 +ZB 5 +LB 5 +QA 5 +XY 4 +EY 4 +XX 4 +JX 4 +UW 4 +QW 4 +BW 4 +MS 4 +KS 4 +TP 4 +AO 4 +ZN 4 +JN 4 +BN 4 +PM 4 +PL 4 +GK 4 +WJ 4 +UJ 4 +SJ 4 +OJ 4 +NJ 4 +LJ 4 +RH 4 +YG 4 +FG 4 +HF 4 +CE 4 +ZD 4 +QB 4 +PB 4 +UZ 3 +WY 3 +FY 3 +AY 3 +CX 3 +PW 3 +GW 3 +FW 3 +AW 3 +XQ 3 +LP 3 +IP 3 +DP 3 +QO 3 +EO 3 +GN 3 +LM 3 +ML 3 +YK 3 +RJ 3 +MJ 3 +DH 3 +VD 3 +UC 3 +TC 3 +KB 3 +CA 3 +YZ 2 +PZ 2 +UY 2 +UX 2 +UV 2 +DV 2 +YU 2 +VU 2 +OU 2 +YT 2 +YS 2 +ZR 2 +VR 2 +SR 2 +PQ 2 +QP 2 +OO 2 +JO 2 +YN 2 +PN 2 +WL 2 +ZK 2 +HK 2 +YJ 2 +PJ 2 +IJ 2 +FJ 2 +DJ 2 +QI 2 +CI 2 +QH 2 +IH 2 +GG 2 +BF 2 +WB 2 +KZ 1 +HZ 1 +CZ 1 +OY 1 +KY 1 +IY 1 +BY 1 +WW 1 +VW 1 +SW 1 +HW 1 +ZV 1 +KV 1 +HV 1 +BV 1 +UU 1 +CU 1 +WT 1 +WR 1 +LR 1 +JR 1 +YQ 1 +TQ 1 +GQ 1 +ZP 1 +YP 1 +GP 1 +UO 1 +CN 1 +YM 1 +WM 1 +VM 1 +FM 1 +CM 1 +ZL 1 +DK 1 +GJ 1 +BJ 1 +UI 1 +OI 1 +PH 1 +LH 1 +KH 1 +GH 1 +WG 1 +VG 1 +KG 1 +WF 1 +VF 1 +CF 1 +PD 1 +BD 1 +WC 1 +NC 1 +LC 1 +GC 1 +DC 1 +YB 1 +GB 1 +BB 1 diff --git a/benchmark/00trigr.AVv1 b/benchmark/00trigr.AVv1 new file mode 100644 index 0000000..6278714 --- /dev/null +++ b/benchmark/00trigr.AVv1 @@ -0,0 +1,4277 @@ +AAF 666 +AAL 666 +AAQ 666 +AAR 666 +ABA 390 +ABE 674 +ABF 281 +ABG 580 +ABH 564 +ABI 350 +ABK 281 +ABM 460 +ABN 350 +ABR 350 +ABS 570 +ABT 614 +ABU 281 +ABW 520 +ABX 529 +ABZ 537 +ACE 453 +ACH 801 +ADA 530 +ADE 725 +ADF 461 +ADM 461 +ADO 461 +ADR 461 +ADS 461 +ADU 461 +ADX 571 +ADY 640 +AEC 468 +AED 446 +AEF 468 +AEG 538 +AEH 486 +AEI 468 +AEL 564 +AEM 377 +AEN 657 +AEQ 607 +AER 591 +AES 527 +AET 564 +AEU 377 +AFC 398 +AFF 698 +AFI 398 +AFT 628 +AFU 537 +AFX 707 +AGA 416 +AGE 774 +AGG 307 +AGL 526 +AGN 416 +AGO 376 +AGR 307 +AGS 570 +AGV 307 +AGW 307 +AGX 307 +AGZ 376 +AHE 366 +AHL 660 +AHM 623 +AHN 586 +AHR 730 +AIL 561 +AIN 729 +AIX 722 +AJA 788 +AJE 443 +AJN 512 +AJO 484 +AJS 443 +AKE 554 +AKI 623 +AKL 415 +AKM 415 +AKN 415 +AKO 623 +AKT 484 +AKX 733 +ALD 544 +ALE 544 +ALF 405 +ALG 515 +ALI 630 +ALJ 405 +ALK 336 +ALL 640 +ALN 405 +ALS 446 +ALT 658 +ALU 475 +ALV 336 +ALW 336 +ALX 446 +ALY 405 +AMA 431 +AMB 321 +AMD 321 +AME 541 +AMG 321 +AMI 460 +AML 391 +AMM 690 +AMN 321 +AMP 431 +AMS 460 +AMT 578 +AMU 321 +AMX 655 +AMZ 585 +ANA 296 +ANB 296 +AND 636 +ANE 227 +ANF 447 +ANG 613 +ANH 428 +ANI 414 +ANK 510 +ANL 227 +ANM 227 +ANN 555 +ANO 441 +ANP 296 +ANQ 158 +ANR 441 +ANS 536 +ANT 575 +ANV 377 +ANW 319 +ANX 536 +ANY 158 +ANZ 588 +AOK 804 +APE 764 +APU 694 +AQA 377 +AQB 336 +AQD 267 +AQE 446 +AQF 267 +AQG 267 +AQH 377 +AQK 267 +AQM 461 +AQN 405 +AQO 336 +AQR 475 +AQS 596 +AQT 735 +AQU 336 +AQV 267 +AQX 619 +AQZ 428 +ARA 601 +ARB 440 +ARE 526 +ARF 408 +ARG 270 +ARI 380 +ARJ 270 +ARK 395 +ARL 270 +ARM 559 +ARO 310 +ARS 613 +ART 670 +ARU 567 +ARX 408 +ARY 408 +ARZ 556 +ASC 529 +ASD 321 +ASE 460 +ASH 391 +ASI 482 +ASK 431 +ASL 391 +ASM 460 +ASO 321 +ASQ 501 +ASS 578 +AST 698 +ASW 391 +ASX 460 +ASZ 651 +ATA 477 +ATB 367 +ATE 437 +ATF 367 +ATH 437 +ATI 367 +ATK 437 +ATL 528 +ATS 587 +ATT 631 +ATU 437 +ATV 367 +ATX 598 +ATZ 693 +AUB 270 +AUD 339 +AUE 518 +AUF 687 +AUG 270 +AUK 379 +AUM 559 +AUN 379 +AUP 518 +AUQ 509 +AUR 449 +AUS 697 +AUT 379 +AUX 270 +AVD 679 +AVO 748 +AVX 610 +AWA 666 +AWE 666 +AWL 735 +AXA 520 +AXB 537 +AXC 404 +AXD 491 +AXE 499 +AXF 422 +AXG 404 +AXH 243 +AXI 451 +AXK 507 +AXL 422 +AXM 576 +AXN 463 +AXO 451 +AXP 451 +AXQ 243 +AXR 473 +AXS 644 +AXT 404 +AXU 463 +AXV 463 +AXW 483 +AXY 312 +AXZ 507 +AYE 804 +AZA 779 +AZE 461 +AZU 571 +AZW 571 +BAC 668 +BAD 331 +BAE 492 +BAF 649 +BAH 551 +BAJ 470 +BAK 441 +BAL 441 +BAN 470 +BAQ 331 +BAR 595 +BAS 401 +BAT 551 +BAU 492 +BBE 804 +BDA 610 +BDI 771 +BDX 610 +BEA 423 +BEB 305 +BEC 532 +BED 345 +BEE 166 +BEF 551 +BEH 305 +BEI 594 +BEK 276 +BEL 470 +BEN 614 +BEO 235 +BEP 166 +BER 654 +BES 589 +BET 561 +BEU 415 +BEV 166 +BEW 361 +BEX 276 +BEZ 430 +BFH 603 +BFU 782 +BFX 533 +BGA 735 +BGE 715 +BGU 564 +BHE 560 +BHF 670 +BHO 761 +BIL 377 +BIN 585 +BIS 706 +BIT 735 +BJA 694 +BJE 764 +BKO 764 +BKX 694 +BLE 735 +BLI 679 +BLO 540 +BLT 610 +BMA 640 +BMB 461 +BMI 461 +BMR 461 +BMU 461 +BMX 765 +BNA 713 +BNI 753 +BOB 484 +BOC 484 +BOG 484 +BOL 484 +BOR 779 +BOT 415 +BOW 484 +BRA 662 +BRE 475 +BRI 662 +BRO 683 +BRU 636 +BSA 452 +BSC 452 +BSE 521 +BSF 382 +BSI 492 +BSM 382 +BSO 492 +BSQ 492 +BSS 735 +BST 653 +BTA 518 +BTE 587 +BTL 610 +BTQ 449 +BTR 610 +BTT 449 +BTX 726 +BTZ 449 +BUC 625 +BUN 625 +BUQ 556 +BUR 556 +BUS 735 +BVI 694 +BVO 764 +BWA 625 +BWE 556 +BWI 556 +BWU 764 +BXA 505 +BXB 615 +BXE 615 +BXF 505 +BXK 505 +BXL 505 +BXM 505 +BXN 615 +BXR 505 +BXS 505 +BXU 505 +BXW 574 +BXZ 505 +BYT 804 +BZE 533 +BZU 728 +BZW 728 +CBM 804 +CET 804 +CFR 804 +CHA 428 +CHB 538 +CHD 180 +CHE 614 +CHG 249 +CHI 575 +CHK 420 +CHL 494 +CHM 180 +CHN 597 +CHO 581 +CHR 375 +CHS 451 +CHT 541 +CHU 538 +CHW 290 +CHX 619 +CKB 417 +CKE 688 +CKS 486 +CKT 486 +CKW 417 +CKX 743 +CKZ 417 +CMX 804 +CON 804 +CUK 804 +CXD 735 +CXK 735 +DAB 574 +DAD 379 +DAE 379 +DAF 379 +DAH 379 +DAI 574 +DAK 379 +DAL 489 +DAM 610 +DAN 628 +DAQ 379 +DAR 574 +DAS 518 +DAU 540 +DAV 489 +DAW 379 +DAX 540 +DBE 783 +DBI 500 +DBR 610 +DDI 596 +DDO 666 +DDR 757 +DEA 204 +DEB 204 +DED 365 +DEE 273 +DEF 273 +DEI 365 +DEK 204 +DEM 553 +DEN 611 +DEO 398 +DEQ 313 +DER 741 +DES 537 +DET 550 +DEU 342 +DEV 273 +DEX 365 +DEZ 204 +DFA 654 +DFE 585 +DFL 585 +DFO 585 +DFU 694 +DFW 585 +DGE 735 +DGR 735 +DHE 764 +DHS 694 +DIE 640 +DIG 456 +DIN 525 +DIS 386 +DIV 768 +DIX 276 +DJA 643 +DJE 713 +DJI 643 +DJW 643 +DKA 625 +DKE 625 +DKR 694 +DKU 694 +DLA 715 +DLI 554 +DLO 415 +DLU 415 +DLX 724 +DLZ 415 +DMA 723 +DME 723 +DMI 585 +DNA 625 +DNI 446 +DNO 759 +DNU 625 +DOB 456 +DOC 415 +DOD 415 +DOF 346 +DOI 415 +DOK 415 +DOP 456 +DOQ 415 +DOR 719 +DOS 640 +DOV 346 +DOW 484 +DOX 617 +DPE 610 +DPL 719 +DPO 719 +DQU 804 +DRA 277 +DRE 768 +DRI 641 +DRO 416 +DRU 346 +DRV 277 +DRX 533 +DSC 433 +DSE 612 +DSI 710 +DSK 502 +DSO 502 +DSP 594 +DSQ 502 +DST 543 +DSU 502 +DSX 502 +DTA 617 +DTE 548 +DTO 778 +DUB 481 +DUE 453 +DUN 745 +DUR 706 +DVE 723 +DVI 694 +DVO 654 +DWA 452 +DWE 715 +DWI 729 +DWO 561 +DXA 475 +DXB 424 +DXD 453 +DXE 522 +DXF 509 +DXG 424 +DXH 475 +DXI 494 +DXK 522 +DXL 494 +DXM 424 +DXN 609 +DXO 384 +DXP 453 +DXR 475 +DXS 614 +DXT 494 +DXU 475 +DXV 522 +DXW 424 +DXZ 453 +DYN 610 +DYX 789 +DZA 564 +DZE 703 +DZU 703 +DZW 634 +EAB 698 +EAK 415 +EAM 554 +EAN 704 +EAR 554 +EAU 576 +EBA 378 +EBE 772 +EBI 268 +EBL 268 +EBN 378 +EBO 337 +EBR 378 +EBS 644 +EBT 268 +EBW 268 +ECH 757 +ECK 699 +ECX 450 +EDA 564 +EDD 315 +EDE 633 +EDG 385 +EDI 476 +EDJ 385 +EDL 476 +EDN 385 +EDO 555 +EDR 610 +EDS 592 +EDT 535 +EDU 510 +EDW 494 +EDX 564 +EEA 455 +EEB 524 +EEI 711 +EEK 524 +EEM 455 +EEN 455 +EER 663 +EES 455 +EET 455 +EEV 455 +EEX 524 +EFA 643 +EFE 677 +EFF 643 +EFI 491 +EFO 568 +EFR 407 +EFS 366 +EFT 458 +EFU 516 +EFX 527 +EGA 445 +EGB 336 +EGE 699 +EGF 635 +EGI 336 +EGL 580 +EGO 336 +EGR 336 +EGS 515 +EGT 515 +EGU 630 +EGX 336 +EHA 383 +EHB 273 +EHE 606 +EHI 383 +EHL 679 +EHM 493 +EHN 481 +EHO 342 +EHR 699 +EHS 273 +EHT 481 +EHU 383 +EHW 342 +EHX 412 +EHZ 342 +EIA 251 +EIB 352 +EIC 291 +EID 529 +EIE 291 +EIF 320 +EIG 434 +EIH 222 +EII 181 +EIK 406 +EIL 465 +EIM 368 +EIN 746 +EIO 181 +EIP 112 +EIQ 401 +EIR 222 +EIS 495 +EIT 538 +EIU 181 +EIV 291 +EIW 251 +EIX 565 +EIZ 291 +EJE 804 +EKA 603 +EKE 574 +EKL 603 +EKO 643 +EKR 704 +EKU 464 +EKX 464 +ELA 514 +ELB 419 +ELD 682 +ELE 455 +ELF 386 +ELG 386 +ELH 225 +ELI 508 +ELJ 294 +ELK 386 +ELL 662 +ELM 404 +ELN 225 +ELO 495 +ELP 294 +ELQ 334 +ELR 225 +ELS 419 +ELT 386 +ELV 294 +ELW 225 +ELX 591 +ELZ 225 +EMA 467 +EMB 369 +EMD 259 +EME 684 +EMF 530 +EMI 508 +EMJ 568 +EML 328 +EMM 398 +EMO 420 +EMP 559 +EMR 328 +EMS 259 +EMU 328 +EMV 581 +EMW 259 +EMX 615 +EMZ 420 +ENA 511 +ENB 471 +ENC 100 +END 569 +ENE 503 +ENF 592 +ENG 404 +ENH 308 +ENI 513 +ENJ 100 +ENK 430 +ENL 295 +ENM 453 +ENN 528 +ENO 348 +ENP 210 +ENR 356 +ENS 591 +ENT 471 +ENU 433 +ENV 394 +ENW 330 +ENX 639 +ENY 169 +ENZ 414 +EOE 617 +EON 727 +EOO 548 +EOR 548 +EOT 658 +EPA 735 +EPO 515 +EPP 654 +EPT 625 +EPU 515 +EQA 292 +EQE 563 +EQF 430 +EQG 402 +EQM 402 +EQN 471 +EQS 752 +EQT 625 +EQU 453 +EQW 361 +EQX 292 +ERA 497 +ERB 506 +ERD 489 +ERE 565 +ERF 460 +ERG 426 +ERH 319 +ERI 405 +ERJ 274 +ERK 475 +ERL 494 +ERM 416 +ERN 482 +ERO 259 +ERP 482 +ERQ 189 +ERR 350 +ERS 581 +ERT 527 +ERU 443 +ERV 405 +ERW 451 +ERX 641 +ERZ 490 +ESA 443 +ESB 235 +ESC 345 +ESD 345 +ESE 609 +ESF 235 +ESG 374 +ESH 414 +ESI 430 +ESJ 414 +ESK 430 +ESM 430 +ESN 305 +ESO 506 +ESP 512 +ESQ 430 +ESR 305 +ESS 535 +EST 703 +ESU 396 +ESV 305 +ESW 235 +ESX 455 +ESZ 499 +ETA 258 +ETB 258 +ETE 608 +ETI 437 +ETJ 258 +ETL 328 +ETM 419 +ETR 687 +ETS 478 +ETT 591 +ETU 437 +ETW 397 +ETX 489 +ETY 328 +ETZ 657 +EUE 521 +EUF 273 +EUG 582 +EUM 537 +EUN 744 +EUQ 342 +EUR 273 +EUS 452 +EUT 602 +EUX 412 +EUZ 383 +EVE 702 +EVI 588 +EVL 393 +EVO 737 +EWA 716 +EWE 629 +EWI 601 +EWO 582 +EWS 601 +EWX 491 +EXA 512 +EXB 464 +EXD 450 +EXE 533 +EXF 512 +EXG 464 +EXH 475 +EXI 464 +EXJ 256 +EXK 545 +EXL 394 +EXM 394 +EXN 464 +EXO 450 +EXP 417 +EXQ 325 +EXR 560 +EXS 602 +EXT 325 +EXU 417 +EXV 366 +EXW 592 +EXX 325 +EXY 256 +EXZ 527 +EYY 804 +EZA 381 +EZE 381 +EZI 519 +EZK 450 +EZO 601 +EZT 381 +EZU 694 +EZW 560 +EZX 690 +FAE 581 +FAH 693 +FAL 540 +FAN 699 +FAQ 402 +FAR 471 +FAS 332 +FAU 552 +FBE 789 +FBR 610 +FCB 764 +FCO 694 +FDE 699 +FDI 724 +FDL 574 +FDR 574 +FED 416 +FEF 277 +FEH 655 +FEI 507 +FEL 674 +FEM 416 +FEN 662 +FEQ 497 +FER 548 +FES 387 +FET 346 +FEU 277 +FEX 277 +FEY 277 +FFA 569 +FFE 749 +FFF 312 +FFI 382 +FFK 382 +FFL 473 +FFM 382 +FFN 382 +FFS 312 +FFT 473 +FFU 473 +FFV 422 +FFW 312 +FFX 507 +FFZ 532 +FGE 804 +FHR 617 +FHX 788 +FIG 426 +FIN 682 +FIS 766 +FJA 804 +FKL 688 +FKM 666 +FKO 637 +FKR 666 +FLA 648 +FLE 730 +FLI 567 +FLL 359 +FLU 520 +FLX 615 +FMA 764 +FME 585 +FMI 654 +FNA 704 +FNE 574 +FNU 741 +FOH 562 +FOL 624 +FON 437 +FOR 772 +FPL 804 +FRA 682 +FRE 459 +FRG 625 +FRI 714 +FRO 390 +FRU 560 +FSB 461 +FSE 755 +FSI 461 +FSQ 530 +FST 669 +FTB 495 +FTD 426 +FTE 656 +FTF 564 +FTH 495 +FTI 564 +FTL 536 +FTN 426 +FTO 426 +FTR 495 +FTS 620 +FTV 426 +FTW 495 +FTX 495 +FTZ 495 +FUE 794 +FUN 571 +FVE 764 +FVO 694 +FWE 764 +FWK 625 +FWU 625 +FXA 445 +FXB 501 +FXC 416 +FXD 563 +FXE 416 +FXF 467 +FXG 467 +FXH 570 +FXI 307 +FXK 501 +FXL 445 +FXM 514 +FXN 537 +FXO 307 +FXP 486 +FXR 467 +FXS 636 +FXT 467 +FXU 526 +FXV 376 +FXW 376 +FXX 307 +FXZ 416 +FZD 507 +FZE 438 +FZU 599 +FZW 507 +FZX 775 +GAB 712 +GAD 443 +GAE 443 +GAI 443 +GAL 403 +GAM 528 +GAN 692 +GAQ 333 +GAT 403 +GAU 528 +GAX 443 +GBA 666 +GBE 757 +GBI 596 +GDA 478 +GDE 756 +GDJ 478 +GDO 478 +GDR 548 +GDU 639 +GEA 236 +GEB 480 +GED 166 +GEE 305 +GEF 553 +GEG 510 +GEH 423 +GEI 345 +GEK 415 +GEL 396 +GEM 461 +GEN 684 +GEO 236 +GEP 374 +GEQ 166 +GER 577 +GES 574 +GET 503 +GEU 374 +GEV 276 +GEW 396 +GEX 530 +GEY 166 +GEZ 484 +GFI 409 +GFO 409 +GFR 783 +GFU 617 +GGE 775 +GGO 556 +GGR 625 +GHE 804 +GID 674 +GIE 564 +GIG 495 +GIM 495 +GIN 725 +GIS 564 +GKE 643 +GKL 643 +GKO 713 +GKW 643 +GLE 659 +GLI 756 +GLJ 558 +GLM 419 +GLU 419 +GLV 419 +GMA 722 +GMI 735 +GMU 527 +GNA 701 +GNE 679 +GNI 540 +GNO 650 +GNU 540 +GOH 464 +GON 464 +GOR 735 +GOS 684 +GOW 533 +GOX 533 +GRA 501 +GRE 392 +GRI 611 +GRO 691 +GRU 721 +GRW 461 +GSA 670 +GSB 522 +GSD 522 +GSE 430 +GSF 430 +GSG 540 +GSI 500 +GSK 361 +GSL 500 +GSM 361 +GSN 361 +GSO 361 +GSR 361 +GSS 500 +GST 540 +GSU 471 +GSV 361 +GSW 430 +GSX 591 +GSZ 471 +GTB 395 +GTD 556 +GTE 464 +GTF 464 +GTH 395 +GTR 395 +GTS 395 +GTW 556 +GTX 764 +GTZ 464 +GUE 528 +GUM 528 +GUN 782 +GUS 367 +GUT 528 +GVE 625 +GVO 786 +GWE 679 +GWI 748 +GWU 610 +GXA 484 +GXB 484 +GXD 565 +GXE 594 +GXF 525 +GXG 346 +GXH 525 +GXI 415 +GXJ 346 +GXK 576 +GXL 484 +GXM 346 +GXN 456 +GXO 346 +GXR 456 +GXS 586 +GXT 415 +GXU 415 +GXV 484 +GXW 484 +GXZ 554 +GYM 666 +GYY 775 +GZE 603 +GZU 713 +GZW 713 +GZZ 533 +HAB 375 +HAD 306 +HAE 595 +HAF 306 +HAJ 375 +HAL 536 +HAN 467 +HAR 742 +HAT 546 +HAU 577 +HAX 416 +HBA 784 +HBE 510 +HBF 440 +HBU 579 +HDR 804 +HED 479 +HEE 394 +HEF 394 +HEG 354 +HEI 634 +HEL 492 +HEM 354 +HEN 645 +HER 667 +HET 284 +HEU 548 +HEV 284 +HEW 492 +HEX 548 +HEZ 354 +HFX 804 +HGE 735 +HGR 735 +HIA 435 +HIE 606 +HIG 366 +HIL 435 +HIM 596 +HIN 732 +HIQ 366 +HIS 366 +HIX 561 +HIZ 545 +HKA 804 +HLA 677 +HLB 337 +HLD 406 +HLE 646 +HLF 498 +HLH 337 +HLI 498 +HLK 447 +HLM 447 +HLN 447 +HLO 337 +HLR 337 +HLS 447 +HLU 447 +HLV 532 +HLW 337 +HLX 585 +HLY 476 +HME 770 +HMI 596 +HMM 486 +HMO 486 +HMU 486 +HMX 486 +HND 349 +HNE 781 +HNH 510 +HNI 349 +HNK 349 +HNR 418 +HNV 349 +HNW 459 +HNX 510 +HNY 349 +HOC 639 +HOE 663 +HOF 491 +HOG 399 +HOH 399 +HOL 643 +HOR 509 +HOW 659 +HPT 804 +HRA 417 +HRB 527 +HRE 710 +HRF 307 +HRI 468 +HRL 417 +HRM 377 +HRN 377 +HRP 307 +HRS 417 +HRT 527 +HRU 502 +HRW 307 +HRX 621 +HRY 377 +HRZ 591 +HSA 430 +HSC 610 +HSD 430 +HSF 430 +HSG 430 +HSH 500 +HSN 500 +HST 744 +HSX 591 +HTA 424 +HTB 424 +HTE 585 +HTF 424 +HTL 493 +HTM 493 +HTN 424 +HTS 694 +HTV 424 +HTX 694 +HTZ 424 +HUB 601 +HUE 491 +HUH 421 +HUK 421 +HUM 616 +HUN 560 +HUR 601 +HUS 716 +HWA 643 +HWE 782 +HXA 485 +HXB 416 +HXC 347 +HXD 457 +HXE 541 +HXF 656 +HXG 347 +HXH 595 +HXI 508 +HXL 555 +HXM 416 +HXN 457 +HXP 347 +HXR 347 +HXS 587 +HXU 526 +HXV 457 +HXW 347 +HXZ 485 +HZU 804 +IAA 464 +IAI 713 +IAL 603 +IAN 533 +IAR 464 +IAS 464 +IAT 659 +IAU 533 +IBA 527 +IBE 706 +IBT 637 +IBU 596 +IBV 596 +IBX 596 +ICH 800 +ICK 477 +IDA 432 +IDE 787 +IDI 542 +IDX 501 +IDZ 362 +IEA 243 +IEB 640 +IED 575 +IEE 284 +IEF 335 +IEG 577 +IEH 457 +IEI 382 +IEL 353 +IEM 174 +IEN 559 +IER 692 +IES 451 +IET 243 +IEV 353 +IEX 530 +IEZ 313 +IFA 495 +IFE 495 +IFF 735 +IFT 634 +IFU 656 +IGA 566 +IGB 358 +IGE 719 +IGF 358 +IGG 427 +IGI 358 +IGK 427 +IGM 358 +IGN 358 +IGS 552 +IGT 552 +IGU 427 +IGV 358 +IGX 628 +IGZ 358 +IHE 679 +IHM 610 +IHR 748 +IIN 804 +IJE 804 +IKA 493 +IKF 493 +IKM 493 +IKO 749 +IKR 424 +IKT 672 +ILA 396 +ILD 506 +ILE 660 +ILF 396 +ILH 506 +ILI 506 +ILJ 466 +ILK 466 +ILL 591 +ILM 396 +ILN 396 +ILO 396 +ILS 506 +ILT 576 +ILU 627 +ILX 396 +IMA 629 +IMB 531 +IMD 421 +IME 560 +IMF 421 +IMK 491 +IML 491 +IMM 560 +IMN 421 +IMP 421 +IMR 531 +IMS 652 +IMU 421 +IMV 421 +IMW 491 +IMX 491 +INA 565 +INB 226 +IND 513 +INE 477 +INF 509 +ING 554 +INH 346 +INI 452 +INJ 254 +INK 335 +INL 254 +INM 474 +INN 254 +INO 425 +INP 185 +INR 459 +INS 692 +INT 429 +INU 459 +INV 310 +INW 310 +INX 599 +INZ 185 +IOL 426 +ION 787 +IOS 495 +IOX 564 +IPA 625 +IPO 786 +IQA 405 +IQB 428 +IQD 405 +IQE 603 +IQF 336 +IQG 377 +IQH 336 +IQI 336 +IQK 428 +IQM 405 +IQN 428 +IQO 267 +IQP 267 +IQR 446 +IQS 506 +IQT 684 +IQU 377 +IQV 267 +IQW 267 +IQX 667 +IQY 267 +IQZ 446 +IRD 757 +IRG 458 +IRK 527 +IRM 458 +IRO 568 +IRR 568 +IRS 458 +IRT 458 +ISA 349 +ISC 648 +ISE 536 +ISF 280 +ISH 349 +ISI 487 +ISJ 389 +ISK 349 +ISL 280 +ISN 349 +ISO 349 +ISQ 519 +ISS 519 +IST 691 +ISU 499 +ISV 280 +ISW 280 +ISX 510 +ISZ 510 +ITA 499 +ITB 422 +ITD 382 +ITE 580 +ITF 463 +ITG 404 +ITH 353 +ITI 589 +ITK 451 +ITL 243 +ITM 404 +ITN 382 +ITP 353 +ITR 353 +ITS 561 +ITT 677 +ITU 438 +ITV 382 +ITW 353 +ITX 532 +ITZ 520 +IUN 764 +IUS 694 +IVA 576 +IVC 305 +IVD 305 +IVE 500 +IVF 305 +IVG 444 +IVI 535 +IVK 444 +IVM 375 +IVR 305 +IVS 305 +IVU 305 +IVV 305 +IVW 375 +IVX 762 +IWE 735 +IWI 666 +IWO 666 +IXA 598 +IXB 528 +IXD 592 +IXE 408 +IXF 367 +IXG 298 +IXH 298 +IXI 506 +IXJ 367 +IXK 575 +IXL 518 +IXM 518 +IXN 546 +IXO 437 +IXP 367 +IXQ 298 +IXR 493 +IXS 546 +IXT 367 +IXU 459 +IXV 477 +IXW 437 +IXX 298 +IXZ 367 +IZU 475 +IZW 636 +IZY 774 +IZZ 475 +JAD 546 +JAI 407 +JAJ 407 +JAK 477 +JAN 647 +JAR 704 +JAS 558 +JAX 637 +JBR 804 +JEB 301 +JED 480 +JEE 301 +JEG 440 +JEH 301 +JEL 480 +JEN 734 +JER 440 +JES 531 +JET 480 +JEW 509 +JEX 641 +JIA 666 +JIE 666 +JIN 735 +JNI 735 +JNO 735 +JOR 753 +JOS 713 +JST 735 +JSZ 735 +JUB 654 +JUL 585 +JUN 694 +JUR 585 +JUS 654 +JWE 804 +JXW 735 +JXX 735 +KAB 422 +KAE 463 +KAI 532 +KAJ 422 +KAL 642 +KAM 492 +KAN 617 +KAP 353 +KAR 573 +KAS 573 +KAU 463 +KAV 463 +KAX 636 +KBA 735 +KBE 735 +KCH 804 +KDO 746 +KDR 722 +KEA 517 +KEB 517 +KED 564 +KEH 564 +KEI 656 +KEN 596 +KER 613 +KES 426 +KET 426 +KEV 356 +KEX 517 +KEZ 564 +KFZ 804 +KGE 527 +KGX 798 +KIN 748 +KIR 443 +KIS 582 +KIX 673 +KIZ 443 +KLA 793 +KLE 510 +KLX 510 +KME 491 +KMN 616 +KMO 421 +KMS 616 +KMU 421 +KMW 531 +KMX 743 +KNE 735 +KNO 735 +KOB 430 +KOC 320 +KOE 470 +KOJ 528 +KOK 389 +KOL 619 +KOM 702 +KON 430 +KOP 389 +KOR 642 +KOS 411 +KOT 458 +KOW 507 +KPX 804 +KRA 775 +KRE 540 +KRI 471 +KRK 471 +KRU 471 +KRX 540 +KSE 574 +KSP 713 +KST 713 +KSX 574 +KTA 478 +KTE 548 +KTG 478 +KTI 478 +KTK 548 +KTO 727 +KTR 548 +KTW 588 +KTX 548 +KUC 452 +KUE 660 +KUG 452 +KUN 751 +KUP 452 +KUR 561 +KWA 415 +KWI 415 +KWK 554 +KWX 791 +KXA 504 +KXB 587 +KXD 538 +KXE 522 +KXF 504 +KXG 435 +KXH 530 +KXI 494 +KXK 453 +KXL 514 +KXM 453 +KXN 482 +KXP 435 +KXR 435 +KXS 557 +KXU 468 +KXV 468 +KXW 603 +KXX 343 +KXZ 413 +KZU 694 +KZW 694 +KZX 694 +LAB 405 +LAC 336 +LAD 461 +LAE 555 +LAG 635 +LAJ 474 +LAK 515 +LAL 266 +LAM 630 +LAN 599 +LAQ 376 +LAR 266 +LAS 506 +LAT 405 +LAU 427 +LAX 405 +LAY 461 +LAZ 584 +LBA 615 +LBE 666 +LBI 505 +LBL 615 +LBR 684 +LBS 574 +LCB 804 +LDB 328 +LDE 692 +LDI 397 +LDK 397 +LDL 628 +LDO 328 +LDR 523 +LDS 328 +LDU 699 +LDX 397 +LDZ 397 +LEA 453 +LEB 489 +LED 420 +LEE 328 +LEF 369 +LEG 654 +LEI 599 +LEK 259 +LEN 659 +LEP 397 +LEQ 369 +LER 530 +LES 420 +LEU 467 +LEV 369 +LEW 259 +LEX 585 +LEZ 397 +LFB 467 +LFE 467 +LFH 716 +LFK 467 +LFL 537 +LFO 467 +LFR 537 +LFU 662 +LFX 537 +LGA 537 +LGE 675 +LGO 647 +LGT 662 +LGU 647 +LHE 764 +LHS 625 +LHU 625 +LIA 410 +LIB 300 +LIC 494 +LIE 594 +LIG 300 +LIJ 369 +LIK 548 +LIN 618 +LIQ 702 +LIS 530 +LIT 540 +LIU 300 +LIX 369 +LIZ 479 +LJA 719 +LJE 679 +LJU 679 +LKA 493 +LKD 424 +LKI 493 +LKL 493 +LKM 493 +LKO 585 +LKR 424 +LKW 764 +LLA 410 +LLB 377 +LLC 285 +LLD 410 +LLE 643 +LLF 285 +LLG 325 +LLI 395 +LLK 354 +LLM 395 +LLN 643 +LLO 285 +LLS 486 +LLT 541 +LLU 525 +LLV 325 +LLX 680 +LLZ 285 +LMA 568 +LMD 458 +LME 767 +LMI 527 +LMT 458 +LMX 568 +LNA 504 +LNE 522 +LNK 652 +LNU 765 +LOE 492 +LOG 463 +LOI 353 +LOJ 422 +LOK 422 +LON 700 +LOQ 353 +LOS 667 +LOT 353 +LOV 353 +LOW 573 +LOX 602 +LPK 804 +LQE 804 +LRO 735 +LRU 735 +LSC 577 +LSE 646 +LSG 438 +LSI 507 +LSQ 507 +LST 715 +LSV 438 +LSW 507 +LSX 507 +LSZ 438 +LTA 482 +LTB 372 +LTE 682 +LTF 372 +LTG 372 +LTK 442 +LTN 482 +LTO 567 +LTR 603 +LTS 372 +LTU 580 +LTW 482 +LTX 612 +LTZ 442 +LUD 619 +LUE 556 +LUF 348 +LUG 417 +LUH 568 +LUJ 417 +LUK 417 +LUN 700 +LUS 647 +LUT 417 +LUU 348 +LVE 706 +LVI 596 +LVO 735 +LWO 694 +LWU 764 +LXA 574 +LXB 455 +LXC 440 +LXD 500 +LXE 491 +LXF 440 +LXG 399 +LXH 468 +LXI 455 +LXK 555 +LXL 468 +LXM 524 +LXN 480 +LXO 399 +LXP 549 +LXR 531 +LXS 578 +LXT 399 +LXU 491 +LXV 440 +LXW 421 +LXX 260 +LXZ 500 +LYJ 694 +LYX 764 +LZB 643 +LZU 753 +LZW 643 +MAA 332 +MAB 424 +MAC 424 +MAD 401 +MAE 502 +MAF 372 +MAG 263 +MAI 263 +MAJ 372 +MAL 527 +MAM 263 +MAN 648 +MAQ 332 +MAR 690 +MAS 621 +MAT 471 +MAU 332 +MAW 263 +MAX 372 +MAZ 401 +MBA 603 +MBE 753 +MBI 603 +MBU 603 +MDE 500 +MDI 771 +MDO 610 +MDR 569 +MEA 244 +MEB 313 +MED 354 +MEE 439 +MEH 493 +MEI 667 +MEL 680 +MEM 244 +MEN 597 +MER 641 +MES 313 +MET 313 +MEV 405 +MEX 313 +MFA 515 +MFD 515 +MFE 515 +MFR 515 +MFU 779 +MGE 804 +MIE 440 +MIG 331 +MIN 492 +MIP 492 +MIT 791 +MJA 788 +MJE 617 +MKA 521 +MKD 521 +MKL 521 +MKO 777 +MKR 521 +MLA 735 +MLE 596 +MLU 596 +MLX 666 +MMA 701 +MMD 334 +MME 729 +MMI 513 +MML 403 +MMN 444 +MMT 495 +MMU 403 +MNA 515 +MNE 625 +MNI 676 +MNO 735 +MOE 648 +MOH 514 +MOL 422 +MON 422 +MOR 740 +MOS 422 +MOT 593 +MOW 422 +MPA 579 +MPB 400 +MPF 709 +MPL 400 +MPR 400 +MPX 726 +MRA 679 +MRO 748 +MRU 610 +MSI 610 +MSK 719 +MST 610 +MSU 679 +MTA 552 +MTE 662 +MTN 482 +MTP 482 +MTR 552 +MTS 552 +MTU 552 +MTV 482 +MTW 552 +MTX 662 +MUE 501 +MUM 461 +MUN 790 +MUS 501 +MVE 581 +MVI 793 +MWA 706 +MWE 757 +MXA 396 +MXB 356 +MXC 495 +MXD 570 +MXE 630 +MXF 481 +MXG 287 +MXI 287 +MXK 633 +MXL 396 +MXM 425 +MXN 425 +MXO 506 +MXP 356 +MXR 287 +MXS 466 +MXT 356 +MXU 287 +MXV 551 +MXW 425 +MXZ 609 +MYT 804 +MZE 464 +MZU 603 +MZW 786 +NAB 473 +NAC 528 +NAE 473 +NAG 372 +NAH 497 +NAI 303 +NAL 428 +NAM 428 +NAN 412 +NAQ 699 +NAR 343 +NAS 343 +NAT 233 +NAU 517 +NAX 683 +NAZ 303 +NBA 512 +NBE 773 +NBI 563 +NBR 581 +NBV 402 +NCM 804 +NDA 512 +NDB 467 +NDD 385 +NDE 663 +NDF 385 +NDG 351 +NDH 300 +NDI 520 +NDK 329 +NDL 410 +NDM 398 +NDN 430 +NDO 551 +NDP 351 +NDQ 190 +NDR 485 +NDS 461 +NDT 300 +NDU 490 +NDV 454 +NDW 447 +NDX 647 +NDZ 369 +NEA 314 +NEB 412 +NEC 343 +NED 314 +NEE 204 +NEG 314 +NEH 399 +NEI 637 +NEJ 274 +NEK 204 +NEL 365 +NEM 461 +NEN 625 +NER 614 +NES 412 +NET 365 +NEU 671 +NEV 384 +NEW 274 +NEX 493 +NEZ 365 +NFA 536 +NFB 259 +NFC 328 +NFD 489 +NFE 507 +NFF 328 +NFG 259 +NFH 328 +NFI 259 +NFK 420 +NFL 453 +NFN 568 +NFO 453 +NFR 605 +NFS 553 +NFT 523 +NFU 548 +NFV 259 +NFX 666 +NFZ 369 +NGA 514 +NGB 340 +NGD 514 +NGE 698 +NGF 431 +NGG 270 +NGH 201 +NGI 431 +NGK 340 +NGL 201 +NGM 396 +NGN 421 +NGO 201 +NGR 441 +NGS 594 +NGT 201 +NGU 449 +NGV 510 +NGW 380 +NGX 614 +NGY 311 +NGZ 431 +NHA 730 +NHE 679 +NHI 500 +NHO 638 +NIA 488 +NIB 396 +NIC 367 +NID 437 +NIE 642 +NIG 465 +NIH 327 +NIM 396 +NIN 626 +NIQ 607 +NIS 541 +NIT 587 +NIX 591 +NIZ 465 +NJE 625 +NJN 764 +NJU 625 +NKA 545 +NKD 486 +NKE 659 +NKF 325 +NKI 435 +NKL 464 +NKM 533 +NKN 325 +NKO 615 +NKP 464 +NKR 435 +NKS 464 +NKT 505 +NKU 325 +NKW 325 +NKX 639 +NKZ 325 +NLA 694 +NLE 533 +NLI 643 +NLK 533 +NLO 533 +NLU 643 +NLX 533 +NMA 715 +NME 654 +NMI 600 +NMO 600 +NMU 580 +NNA 559 +NND 345 +NNE 734 +NNF 385 +NNG 345 +NNH 275 +NNI 575 +NNL 275 +NNM 275 +NNN 436 +NNO 414 +NNS 345 +NNT 414 +NNU 589 +NNV 345 +NNW 345 +NNX 515 +NOB 304 +NOC 373 +NOD 373 +NOE 581 +NOH 373 +NOJ 373 +NOM 442 +NOP 304 +NOQ 626 +NOR 633 +NOS 498 +NOT 373 +NOV 373 +NOW 633 +NOX 641 +NPA 654 +NPF 694 +NPI 654 +NPO 654 +NQU 804 +NRA 631 +NRE 492 +NRI 719 +NRJ 452 +NRO 682 +NRU 452 +NSA 567 +NSB 539 +NSC 317 +NSD 373 +NSE 492 +NSF 483 +NSG 339 +NSI 409 +NSK 522 +NSM 178 +NSN 537 +NSO 418 +NSP 467 +NSQ 409 +NSS 522 +NST 646 +NSU 288 +NSV 427 +NSX 628 +NSZ 462 +NTA 428 +NTB 289 +NTE 696 +NTF 450 +NTH 289 +NTL 450 +NTO 670 +NTR 599 +NTS 484 +NTU 359 +NTV 289 +NTW 509 +NTX 529 +NTZ 289 +NUE 347 +NUH 307 +NUJ 307 +NUL 784 +NUM 376 +NUN 587 +NUR 376 +NUT 376 +NVD 419 +NVE 756 +NVI 558 +NVO 676 +NWA 711 +NWE 691 +NWI 650 +NWO 471 +NWU 471 +NXA 502 +NXB 462 +NXC 185 +NXD 537 +NXE 494 +NXF 502 +NXG 441 +NXH 502 +NXI 424 +NXJ 254 +NXK 531 +NXL 404 +NXM 494 +NXN 510 +NXO 393 +NXP 441 +NXQ 254 +NXR 558 +NXS 605 +NXT 415 +NXU 448 +NXV 553 +NXW 424 +NXX 185 +NXZ 498 +NYY 804 +NZA 337 +NZD 577 +NZE 677 +NZG 545 +NZI 406 +NZK 516 +NZP 337 +NZU 637 +NZW 567 +NZX 601 +NZY 406 +NZZ 406 +OAN 674 +OAQ 759 +OAR 564 +OBA 449 +OBB 449 +OBD 449 +OBE 697 +OBF 449 +OBI 449 +OBK 559 +OBL 610 +OBM 449 +OBR 518 +OBS 518 +OBX 449 +OBY 587 +OCB 461 +OCH 640 +OCK 779 +ODA 424 +ODB 562 +ODE 585 +ODI 493 +ODN 493 +ODO 493 +ODR 718 +ODS 493 +ODU 493 +ODX 603 +OEF 530 +OEG 575 +OEH 474 +OEI 486 +OEK 266 +OEL 474 +OEM 742 +OEN 543 +OEQ 266 +OER 530 +OES 336 +OET 376 +OEW 336 +OFE 339 +OFF 753 +OFO 672 +OFS 339 +OFU 547 +OFX 477 +OGE 718 +OGG 658 +OGI 588 +OGO 658 +OHE 571 +OHI 599 +OHL 669 +OHN 691 +OHO 461 +OHR 622 +OIN 804 +OJE 804 +OKA 400 +OKL 400 +OKM 539 +OKO 671 +OKR 400 +OKX 755 +OLA 514 +OLB 319 +OLE 568 +OLF 388 +OLG 590 +OLI 429 +OLL 549 +OLO 716 +OLS 480 +OLT 498 +OLU 539 +OLX 480 +OMA 542 +OMD 381 +OME 381 +OMI 472 +OMK 381 +OMM 709 +OMN 381 +OMP 658 +OMS 312 +OMX 621 +OMY 381 +OMZ 472 +ONA 497 +ONB 379 +OND 524 +ONE 562 +ONF 420 +ONG 310 +ONH 350 +ONI 549 +ONJ 240 +ONK 350 +ONL 240 +ONM 379 +ONN 634 +ONO 350 +ONQ 240 +ONR 401 +ONS 518 +ONU 566 +ONV 350 +ONW 240 +ONX 667 +ONZ 350 +OOH 804 +OPE 574 +OPF 672 +OPI 533 +OPO 704 +OPP 643 +OQE 603 +OQG 464 +OQH 464 +OQI 574 +OQK 574 +OQM 464 +OQN 684 +OQS 464 +OQV 533 +OQW 464 +OQX 533 +OQZ 533 +ORA 423 +ORB 331 +ORC 511 +ORD 599 +ORE 354 +ORF 193 +ORG 554 +ORH 354 +ORI 564 +ORK 449 +ORL 331 +ORM 423 +ORN 262 +ORO 586 +ORP 571 +ORR 193 +ORS 413 +ORT 656 +ORV 387 +ORW 262 +ORX 464 +ORY 262 +ORZ 331 +OSA 427 +OSC 530 +OSE 560 +OSG 266 +OSH 445 +OSI 522 +OSN 427 +OSQ 335 +OSS 653 +OST 686 +OSV 335 +OSX 404 +OSY 496 +OSZ 575 +OTA 556 +OTE 666 +OTI 361 +OTK 430 +OTO 522 +OTS 601 +OTT 644 +OTV 430 +OTW 471 +OTX 581 +OTZ 540 +OUN 804 +OVA 613 +OVE 544 +OVI 779 +OWA 702 +OWE 494 +OWI 597 +OWK 472 +OWO 622 +OWS 472 +OWX 659 +OXA 547 +OXB 571 +OXD 515 +OXE 502 +OXF 446 +OXG 377 +OXH 446 +OXI 486 +OXK 527 +OXL 377 +OXM 417 +OXN 515 +OXO 417 +OXP 527 +OXQ 307 +OXR 527 +OXS 607 +OXT 377 +OXU 486 +OXV 417 +OXW 515 +OXY 307 +OXZ 446 +OZE 713 +OZW 753 +PAC 432 +PAE 582 +PAK 557 +PAN 768 +PAR 523 +PAW 432 +PBE 804 +PEC 395 +PEE 395 +PEI 395 +PEL 574 +PEN 625 +PER 738 +PEU 464 +PEV 505 +PEX 505 +PEZ 464 +PFA 642 +PFD 359 +PFE 579 +PFI 359 +PFL 750 +PFM 359 +PFT 359 +PFU 469 +PFW 359 +PFX 428 +PIO 775 +PIS 666 +PKT 610 +PKW 780 +PKZ 540 +PLA 713 +PLE 574 +PLJ 643 +PLU 643 +PLX 574 +PMI 804 +POD 544 +POG 434 +POL 664 +POR 739 +POT 605 +PPE 783 +PPL 461 +PPM 461 +PPT 461 +PPW 461 +PPX 530 +PRA 507 +PRE 632 +PRO 694 +PRU 721 +PSA 650 +PSE 540 +PSI 540 +PSK 430 +PSL 500 +PSM 500 +PSN 569 +PSQ 500 +PSU 569 +PSV 430 +PSX 661 +PSZ 430 +PTE 521 +PTM 660 +PTR 590 +PTS 715 +PTV 590 +PTX 521 +PUL 625 +PUN 694 +PUP 694 +PUZ 625 +PWA 804 +PXA 515 +PXD 446 +PXE 446 +PXG 446 +PXH 446 +PXI 607 +PXK 515 +PXM 446 +PXN 654 +PXR 446 +PXS 585 +PXU 446 +PXV 446 +PXW 556 +PXX 446 +PXZ 556 +PYS 804 +PZX 804 +QAB 569 +QAE 500 +QAF 610 +QAM 638 +QAN 569 +QAR 569 +QAS 500 +QAU 638 +QAX 569 +QBA 610 +QBE 760 +QBR 610 +QBX 540 +QDA 684 +QDE 684 +QDI 574 +QDO 643 +QDR 574 +QEB 375 +QEF 444 +QEG 375 +QEH 375 +QEI 514 +QEM 485 +QEN 684 +QER 712 +QES 536 +QET 375 +QEU 375 +QEX 444 +QEZ 375 +QFA 495 +QFD 495 +QFE 564 +QFI 495 +QFL 495 +QFR 495 +QFU 766 +QGE 789 +QGL 471 +QGO 471 +QGR 540 +QHA 610 +QHE 679 +QHI 748 +QIE 603 +QIL 533 +QIM 533 +QIN 741 +QIR 643 +QKE 709 +QKO 756 +QLA 643 +QLE 694 +QLI 603 +QLO 533 +QLU 672 +QMA 585 +QME 676 +QMI 694 +QMO 585 +QMU 625 +QNA 643 +QNE 659 +QNI 704 +QNK 464 +QNO 574 +QNU 464 +QNX 464 +QOB 654 +QON 694 +QOS 723 +QPA 804 +QQU 804 +QRE 574 +QRI 713 +QRO 615 +QRU 643 +QRX 615 +QSA 477 +QSB 298 +QSC 367 +QSD 459 +QSE 607 +QSF 408 +QSI 408 +QSK 298 +QSM 298 +QSN 538 +QSP 437 +QSQ 631 +QST 562 +QSU 298 +QSV 298 +QSX 685 +QSZ 493 +QTA 452 +QTB 412 +QTD 434 +QTE 599 +QTF 434 +QTG 342 +QTH 273 +QTI 493 +QTK 434 +QTL 452 +QTM 412 +QTN 452 +QTP 273 +QTR 434 +QTS 529 +QTU 503 +QTV 383 +QTW 342 +QTX 718 +QTZ 412 +QUA 616 +QUB 699 +QUE 649 +QUL 385 +QUM 385 +QUN 605 +QUS 495 +QUX 546 +QVE 706 +QVO 757 +QWA 540 +QWE 760 +QWI 610 +QWU 610 +QXA 471 +QXB 610 +QXC 332 +QXD 572 +QXE 493 +QXF 402 +QXG 332 +QXH 493 +QXK 512 +QXL 442 +QXM 527 +QXN 402 +QXO 442 +QXP 527 +QXR 581 +QXS 596 +QXT 402 +QXU 332 +QXV 332 +QXW 442 +QXZ 512 +QYY 804 +QZA 486 +QZE 486 +QZI 625 +QZU 757 +QZW 596 +RAB 459 +RAD 408 +RAE 538 +RAF 437 +RAG 616 +RAJ 618 +RAK 298 +RAL 368 +RAM 229 +RAN 648 +RAQ 477 +RAR 390 +RAS 566 +RAT 424 +RAU 607 +RAX 298 +RBA 610 +RBE 704 +RBI 668 +RBL 415 +RBO 456 +RBR 617 +RBT 415 +RBZ 346 +RCH 804 +RDA 502 +RDE 713 +RDF 307 +RDG 307 +RDI 621 +RDL 564 +RDN 527 +RDO 515 +RDP 377 +RDR 417 +RDT 307 +RDU 307 +RDV 377 +RDW 468 +RDX 515 +RDY 307 +RDZ 307 +REA 330 +REB 260 +REC 191 +RED 191 +REF 480 +REG 260 +REI 732 +REK 301 +REL 191 +REM 370 +REN 597 +REO 191 +REP 260 +REQ 455 +RER 595 +RES 505 +RET 521 +REU 386 +REV 191 +REW 352 +REX 301 +RFA 551 +RFB 390 +RFD 390 +RFE 459 +RFF 390 +RFG 390 +RFK 500 +RFL 500 +RFO 684 +RFP 390 +RFR 390 +RFS 390 +RFU 689 +RFV 459 +RFX 459 +RGA 559 +RGE 682 +RGL 477 +RGO 533 +RGR 408 +RGT 691 +RGU 603 +RGX 477 +RHA 757 +RHE 596 +RHI 527 +RHO 637 +RIA 220 +RIC 582 +RIE 685 +RIF 484 +RIG 400 +RIJ 290 +RIL 220 +RIM 290 +RIN 667 +RIO 220 +RIQ 652 +RIS 220 +RIT 469 +RJA 625 +RJE 750 +RJI 625 +RJU 556 +RKA 600 +RKB 370 +RKE 641 +RKF 370 +RKI 439 +RKM 370 +RKO 618 +RKR 549 +RKS 508 +RKT 439 +RKU 679 +RKX 370 +RLA 640 +RLE 633 +RLH 377 +RLI 690 +RLS 486 +RLU 660 +RLX 377 +RMA 570 +RME 662 +RMI 646 +RMK 593 +RMO 472 +RMS 472 +RMU 501 +RMV 362 +RMX 646 +RNA 588 +RND 503 +RNE 588 +RNF 462 +RNG 393 +RNI 601 +RNN 393 +RNO 554 +RNS 532 +RNU 676 +RNX 503 +RNZ 503 +ROB 337 +ROD 476 +ROE 706 +ROF 522 +ROG 407 +ROH 297 +ROK 564 +ROL 297 +ROM 447 +ROP 337 +ROQ 227 +ROS 651 +ROT 484 +ROW 545 +ROZ 435 +RPA 537 +RPB 343 +RPF 732 +RPL 343 +RPS 719 +RQB 438 +RQD 507 +RQF 686 +RQG 438 +RQK 438 +RQM 438 +RQN 438 +RQO 438 +RQP 438 +RQQ 438 +RQR 438 +RQS 577 +RQU 548 +RQV 438 +RQX 632 +RQZ 438 +RRA 510 +RRE 704 +RRM 579 +RRO 648 +RRT 579 +RRU 620 +RSA 524 +RSB 370 +RSC 440 +RSD 260 +RSE 480 +RSF 260 +RSI 509 +RSO 586 +RSP 330 +RSQ 676 +RST 676 +RSU 399 +RSV 260 +RSX 574 +RTA 648 +RTB 369 +RTD 461 +RTE 567 +RTF 300 +RTG 230 +RTH 391 +RTI 586 +RTJ 661 +RTL 300 +RTM 391 +RTN 300 +RTO 300 +RTR 409 +RTS 470 +RTT 300 +RTU 300 +RTV 369 +RTW 340 +RTX 583 +RTY 369 +RTZ 450 +RUC 341 +RUE 643 +RUM 432 +RUN 659 +RUP 571 +RUQ 571 +RUS 677 +RUT 341 +RUV 341 +RUX 479 +RVE 780 +RVI 512 +RVO 622 +RWA 710 +RWE 661 +RWI 560 +RWO 421 +RWU 652 +RWX 491 +RXA 558 +RXB 485 +RXC 228 +RXD 492 +RXE 492 +RXF 459 +RXG 423 +RXH 550 +RXI 298 +RXJ 228 +RXK 499 +RXL 506 +RXM 485 +RXN 477 +RXO 468 +RXP 389 +RXR 568 +RXS 613 +RXT 298 +RXU 512 +RXV 338 +RXW 506 +RXZ 506 +RYJ 756 +RYT 548 +RYX 617 +RYY 617 +RZA 434 +RZB 650 +RZE 628 +RZG 393 +RZI 434 +RZL 324 +RZO 434 +RZT 679 +RZU 601 +RZW 554 +RZX 393 +SAB 483 +SAC 385 +SAE 436 +SAG 275 +SAK 454 +SAL 469 +SAM 574 +SAN 608 +SAQ 523 +SAR 531 +SAS 275 +SAT 593 +SAU 601 +SAX 656 +SBE 794 +SBI 521 +SBR 411 +SBU 411 +SCH 804 +SCU 298 +SDE 540 +SDI 610 +SDR 760 +SDU 581 +SDX 471 +SEA 244 +SEB 423 +SEC 501 +SEE 354 +SEG 244 +SEH 354 +SEI 600 +SEL 527 +SEN 618 +SEP 244 +SEQ 692 +SER 474 +SET 618 +SEU 244 +SEV 313 +SEX 383 +SEZ 313 +SFA 608 +SFE 482 +SFH 621 +SFJ 552 +SFL 413 +SFR 482 +SFU 739 +SGA 741 +SGE 662 +SGL 552 +SGR 586 +SGU 461 +SHA 643 +SHE 699 +SHI 615 +SHN 574 +SHS 574 +SHX 574 +SIA 267 +SIE 751 +SIG 446 +SIL 336 +SIN 589 +SIO 446 +SIQ 619 +SIR 267 +SIS 497 +SIT 405 +SJE 804 +SKA 578 +SKE 384 +SKG 384 +SKI 545 +SKL 563 +SKM 384 +SKO 624 +SKR 453 +SKX 733 +SLA 753 +SLI 666 +SLO 615 +SMA 660 +SME 741 +SMI 660 +SNA 543 +SNE 602 +SNI 543 +SNO 521 +SNS 452 +SNU 758 +SOD 461 +SOE 420 +SOF 684 +SOK 546 +SOL 512 +SON 645 +SOP 351 +SOR 651 +SOS 351 +SOT 351 +SOV 420 +SOW 490 +SPA 650 +SPE 572 +SPI 393 +SPO 657 +SPR 719 +SPX 393 +SQA 517 +SQB 477 +SQD 297 +SQE 537 +SQF 367 +SQG 586 +SQH 297 +SQI 528 +SQK 407 +SQL 568 +SQM 297 +SQN 458 +SQO 458 +SQR 436 +SQS 528 +SQU 641 +SQV 367 +SQW 528 +SQX 458 +SQZ 528 +SRA 764 +SRE 585 +SRO 585 +SRU 585 +SSA 650 +SSB 253 +SSD 253 +SSE 632 +SSF 253 +SSG 253 +SSH 323 +SSI 661 +SSJ 253 +SSL 414 +SSN 392 +SSO 448 +SSP 461 +SSQ 253 +SSS 323 +SST 627 +SSU 363 +SSV 253 +SSX 432 +SSY 392 +SSZ 253 +STA 657 +STB 201 +STD 241 +STE 684 +STF 311 +STG 292 +STH 131 +STI 270 +STK 326 +STL 441 +STM 339 +STN 292 +STO 525 +STR 594 +STS 270 +STU 600 +STV 311 +STW 409 +STX 500 +STZ 241 +SUC 415 +SUE 724 +SUH 415 +SUN 724 +SUQ 525 +SVA 560 +SVE 629 +SVI 739 +SVO 652 +SWA 643 +SWE 684 +SWI 643 +SWO 574 +SWY 643 +SXA 627 +SXB 538 +SXD 399 +SXE 531 +SXF 455 +SXG 330 +SXH 421 +SXI 517 +SXJ 260 +SXK 538 +SXL 260 +SXM 421 +SXN 509 +SXO 330 +SXP 491 +SXQ 260 +SXR 421 +SXS 586 +SXT 440 +SXU 370 +SXV 549 +SXW 480 +SXZ 524 +SYT 679 +SYX 760 +SYZ 540 +SZA 537 +SZB 497 +SZE 705 +SZF 427 +SZH 317 +SZI 478 +SZJ 456 +SZK 387 +SZL 387 +SZN 387 +SZS 387 +SZT 456 +SZU 557 +SZV 497 +SZW 627 +SZX 427 +TAB 537 +TAE 468 +TAF 512 +TAG 581 +TAH 298 +TAL 408 +TAM 448 +TAN 679 +TAQ 228 +TAR 646 +TAS 367 +TAT 423 +TAU 533 +TAV 228 +TAX 554 +TBA 585 +TBE 764 +TBI 585 +TBL 475 +TBR 544 +TDA 571 +TDE 681 +TDI 599 +TDO 461 +TDR 599 +TDU 691 +TEA 383 +TEB 342 +TED 342 +TEE 302 +TEF 403 +TEG 163 +TEH 371 +TEI 647 +TEK 342 +TEL 569 +TEM 324 +TEN 627 +TEP 232 +TEQ 163 +TER 665 +TES 446 +TET 357 +TEU 434 +TEV 467 +TEW 273 +TEX 548 +TEZ 163 +TFA 692 +TFE 574 +TFL 574 +TFO 505 +TFR 545 +TFU 675 +TFX 545 +TGE 790 +TGR 603 +THA 666 +THE 574 +THI 724 +THU 643 +TIA 498 +TIE 567 +TIG 646 +TIH 337 +TIK 406 +TIL 498 +TIM 406 +TIN 667 +TIO 674 +TIS 406 +TIV 337 +TIX 337 +TJE 803 +TJI 372 +TKA 521 +TKD 452 +TKE 452 +TKF 452 +TKI 700 +TKL 521 +TKO 700 +TKR 521 +TKU 452 +TLA 608 +TLB 400 +TLE 400 +TLI 677 +TLO 469 +TLU 400 +TLV 469 +TLX 722 +TLZ 400 +TMA 590 +TME 671 +TMI 631 +TMO 660 +TMU 631 +TMX 452 +TNA 654 +TNE 475 +TNI 694 +TNO 613 +TNU 669 +TOB 401 +TOE 291 +TOF 663 +TOK 361 +TOL 361 +TON 727 +TOP 470 +TOR 600 +TOT 291 +TOU 291 +TOX 531 +TOZ 291 +TPA 625 +TPE 735 +TPI 625 +TPU 625 +TQU 804 +TRA 641 +TRE 582 +TRF 252 +TRG 321 +TRI 720 +TRM 252 +TRN 252 +TRO 631 +TRU 447 +TRX 482 +TSA 418 +TSB 308 +TSC 737 +TSD 308 +TSE 503 +TSI 528 +TSK 377 +TSO 418 +TSP 377 +TSQ 447 +TSR 447 +TSS 503 +TST 602 +TSU 377 +TSX 487 +TTA 627 +TTB 379 +TTD 379 +TTE 725 +TTF 379 +TTI 540 +TTK 379 +TTL 448 +TTN 419 +TTO 566 +TTR 309 +TTU 309 +TTX 549 +TTZ 379 +TUB 613 +TUE 644 +TUF 710 +TUH 304 +TUM 442 +TUN 633 +TUR 465 +TUS 304 +TUZ 304 +TVE 727 +TVI 548 +TVO 727 +TWA 693 +TWE 652 +TWI 542 +TWK 403 +TWO 634 +TWV 403 +TWX 623 +TXA 539 +TXB 512 +TXC 218 +TXD 474 +TXE 551 +TXF 535 +TXG 437 +TXH 527 +TXI 437 +TXJ 218 +TXK 495 +TXL 507 +TXM 558 +TXN 466 +TXO 287 +TXP 527 +TXR 437 +TXS 586 +TXT 287 +TXU 466 +TXV 488 +TXW 327 +TXX 218 +TXZ 517 +TYL 694 +TYY 764 +TZA 453 +TZB 424 +TZD 384 +TZE 651 +TZG 314 +TZI 453 +TZK 314 +TZL 314 +TZM 314 +TZO 424 +TZS 314 +TZT 655 +TZU 640 +TZW 522 +TZX 522 +TZY 545 +TZZ 384 +UAB 610 +UAN 540 +UAQ 540 +UAR 771 +UBA 702 +UBD 568 +UBE 568 +UBF 637 +UBG 458 +UBJ 527 +UBR 498 +UBS 498 +UBX 527 +UBZ 388 +UCH 804 +UDO 579 +UDS 689 +UDV 579 +UDW 718 +UDZ 510 +UEB 555 +UEC 385 +UED 500 +UEG 414 +UEH 621 +UEI 206 +UEL 462 +UEN 687 +UEQ 523 +UER 656 +UES 425 +UET 385 +UEU 206 +UEZ 206 +UFA 430 +UFB 458 +UFD 514 +UFE 430 +UFF 514 +UFG 481 +UFI 320 +UFK 481 +UFL 320 +UFM 499 +UFN 499 +UFR 320 +UFS 514 +UFT 481 +UFU 430 +UFW 430 +UFX 724 +UFZ 430 +UGA 654 +UGB 390 +UGD 459 +UGE 712 +UGF 390 +UGG 390 +UGK 529 +UGL 390 +UGM 598 +UGN 390 +UGX 500 +UGZ 459 +UHA 500 +UHN 500 +UHO 569 +UHR 783 +UIH 804 +UJA 735 +UJX 735 +UKD 564 +UKE 564 +UKI 634 +UKO 759 +ULA 246 +ULB 407 +ULE 246 +ULI 246 +ULL 795 +ULM 517 +ULO 246 +UMA 553 +UMB 528 +UMD 597 +UME 541 +UMF 403 +UMG 541 +UMI 403 +UMK 443 +UMM 541 +UMN 443 +UMO 494 +UMP 333 +UMR 333 +UMS 403 +UMT 512 +UMU 443 +UMV 333 +UMW 403 +UMX 633 +UMZ 512 +UNA 275 +UNB 304 +UND 659 +UNE 234 +UNF 429 +UNG 704 +UNI 539 +UNK 465 +UNM 373 +UNN 436 +UNO 385 +UNS 165 +UNT 536 +UNU 275 +UNV 344 +UNX 587 +UNZ 234 +UPO 654 +UPP 728 +UPT 672 +UPY 493 +UQA 582 +UQD 512 +UQE 604 +UQF 443 +UQG 443 +UQM 443 +UQR 443 +UQS 604 +UQT 553 +UQU 443 +UQV 443 +UQX 683 +UQY 443 +URA 488 +URB 437 +URC 396 +URD 506 +URE 506 +URF 535 +URG 437 +URJ 327 +URK 327 +URM 396 +URO 506 +URQ 686 +URS 466 +URT 437 +URU 547 +URV 437 +URX 598 +URZ 488 +USA 407 +USB 268 +USC 476 +USD 268 +USE 525 +USF 447 +USG 629 +USL 447 +USN 268 +USQ 407 +USR 337 +USS 681 +UST 651 +USU 268 +USX 378 +USZ 557 +UTB 405 +UTE 761 +UTF 405 +UTN 405 +UTO 613 +UTR 475 +UTS 475 +UTT 405 +UTX 475 +UTZ 405 +UUE 775 +UUL 666 +UVE 735 +UVI 735 +UWE 804 +UXA 615 +UXD 615 +UXH 505 +UXK 505 +UXQ 615 +UXS 574 +UXV 615 +UXX 643 +UZD 625 +UZI 694 +UZU 625 +UZW 625 +UZX 625 +VAI 569 +VAM 500 +VAN 569 +VAR 748 +VAX 638 +VCF 804 +VDI 666 +VDR 666 +VDW 735 +VEB 282 +VEI 282 +VEN 421 +VER 800 +VEU 282 +VFE 804 +VGE 804 +VIE 790 +VIK 540 +VIL 361 +VIM 361 +VIN 292 +VIS 471 +VKD 804 +VLE 804 +VMI 735 +VMO 735 +VOE 295 +VOL 364 +VOM 632 +VON 717 +VOR 709 +VRE 804 +VST 804 +VUN 804 +VVI 804 +VWE 735 +VWI 735 +VXA 619 +VXB 527 +VXD 417 +VXE 527 +VXF 458 +VXG 596 +VXH 417 +VXI 588 +VXK 604 +VXM 527 +VXN 458 +VXR 417 +VXS 509 +VXU 417 +VXV 348 +VXW 486 +VXZ 458 +WAE 568 +WAF 484 +WAG 588 +WAH 465 +WAJ 443 +WAK 443 +WAL 568 +WAN 524 +WAP 374 +WAQ 465 +WAR 512 +WAS 561 +WAX 687 +WAZ 305 +WEB 378 +WEG 626 +WEH 378 +WEI 670 +WEL 565 +WEN 557 +WEO 309 +WEQ 447 +WER 622 +WES 618 +WET 309 +WEX 309 +WIE 663 +WIG 583 +WIL 572 +WIN 433 +WIQ 433 +WIR 681 +WIS 502 +WIT 620 +WJA 643 +WJE 782 +WKA 458 +WKI 498 +WKP 458 +WKX 793 +WLA 804 +WOA 469 +WOB 368 +WOC 229 +WOD 524 +WOE 478 +WOF 437 +WOG 299 +WOH 437 +WOI 229 +WOK 424 +WOL 507 +WOM 339 +WON 596 +WOQ 229 +WOR 493 +WOS 598 +WOT 543 +WOV 534 +WOX 658 +WOZ 469 +WSC 723 +WSF 654 +WSG 654 +WSO 515 +WST 515 +WUE 482 +WUN 713 +WUR 746 +WVO 804 +WXA 502 +WXB 433 +WXD 364 +WXE 502 +WXF 364 +WXG 433 +WXH 364 +WXI 502 +WXK 525 +WXL 627 +WXM 473 +WXN 433 +WXO 558 +WXP 627 +WXR 364 +WXS 543 +WXU 502 +WXV 473 +WXW 364 +WXX 364 +WXZ 433 +WYS 735 +WYX 735 +XAA 247 +XAB 628 +XAC 442 +XAK 455 +XAL 408 +XAM 524 +XAN 611 +XAO 386 +XAQ 660 +XAR 621 +XAS 247 +XAU 600 +XBA 570 +XBE 738 +XBH 455 +XBI 564 +XBJ 345 +XBK 345 +XBL 345 +XBO 649 +XBR 385 +XBT 345 +XCB 769 +XCH 683 +XDA 521 +XDE 631 +XDI 680 +XDJ 334 +XDN 513 +XDO 459 +XDR 693 +XDU 495 +XDX 264 +XEI 780 +XEM 467 +XEN 398 +XER 612 +XES 329 +XET 260 +XEV 260 +XFE 615 +XFH 362 +XFI 630 +XFL 533 +XFO 432 +XFR 646 +XFU 701 +XFX 362 +XGA 352 +XGD 352 +XGE 749 +XGI 531 +XGL 462 +XGO 491 +XGR 652 +XGU 462 +XGY 352 +XHA 732 +XHB 289 +XHE 644 +XHI 358 +XHO 626 +XHP 289 +XHS 572 +XHU 358 +XHX 358 +XIA 327 +XID 506 +XIM 506 +XIN 769 +XIS 610 +XIV 466 +XIX 327 +XJA 643 +XJE 684 +XJO 643 +XJU 684 +XKA 615 +XKD 541 +XKE 503 +XKF 541 +XKG 517 +XKL 477 +XKM 560 +XKN 316 +XKO 695 +XKP 316 +XKR 555 +XKU 441 +XKW 385 +XLA 646 +XLE 524 +XLF 564 +XLI 455 +XLJ 385 +XLK 649 +XLN 625 +XLO 536 +XLT 524 +XLU 564 +XMA 705 +XME 551 +XMI 592 +XMJ 426 +XMO 684 +XMU 582 +XNA 668 +XND 571 +XNE 700 +XNF 426 +XNI 287 +XNK 426 +XNO 596 +XNU 582 +XNX 356 +XOB 603 +XOD 372 +XOE 442 +XOF 511 +XOH 372 +XOM 442 +XON 442 +XOP 612 +XOR 442 +XOS 713 +XOT 603 +XPA 683 +XPE 616 +XPF 455 +XPI 386 +XPK 565 +XPL 427 +XPO 672 +XPR 565 +XPU 427 +XPZ 317 +XQU 804 +XRA 497 +XRE 655 +XRG 472 +XRI 456 +XRO 748 +XRU 560 +XRY 277 +XSA 488 +XSC 677 +XSD 258 +XSE 532 +XSF 396 +XSG 258 +XSI 569 +XSK 327 +XSO 483 +XSP 258 +XSQ 419 +XSS 445 +XST 702 +XSU 327 +XSW 258 +XSZ 408 +XTA 598 +XTE 513 +XTH 542 +XTI 403 +XTO 674 +XTR 643 +XTS 667 +XUD 390 +XUE 482 +XUF 390 +XUH 459 +XUL 634 +XUM 551 +XUN 727 +XUP 551 +XUS 459 +XUT 529 +XVE 679 +XVI 723 +XVO 674 +XWA 615 +XWE 637 +XWI 553 +XWJ 527 +XWK 696 +XWO 591 +XWS 505 +XWY 366 +XXA 603 +XXB 603 +XXD 603 +XXE 533 +XXF 603 +XXI 533 +XXK 533 +XXO 533 +XXS 603 +XXU 533 +XYY 804 +XZA 491 +XZE 587 +XZI 283 +XZU 652 +XZW 756 +YBE 735 +YBR 735 +YEI 596 +YER 791 +YFE 804 +YJB 713 +YJE 713 +YJS 643 +YKD 804 +YLA 735 +YLE 735 +YMN 804 +YPA 804 +YRO 804 +YSA 610 +YSC 679 +YSE 610 +YSI 610 +YSS 679 +YTI 634 +YTK 703 +YTS 703 +YTT 564 +YXB 409 +YXD 519 +YXE 478 +YXH 548 +YXJ 409 +YXK 588 +YXL 519 +YXM 548 +YXR 570 +YXS 649 +YXT 519 +YXU 570 +YXW 548 +YYB 521 +YYE 521 +YYF 521 +YYK 590 +YYL 590 +YYP 521 +YYR 682 +YYS 631 +YYZ 521 +YZU 735 +YZW 735 +ZAH 650 +ZAK 402 +ZAN 632 +ZAR 719 +ZAX 621 +ZBE 796 +ZBO 446 +ZBU 515 +ZDE 666 +ZDI 775 +ZEB 291 +ZED 360 +ZEE 291 +ZEF 291 +ZEH 452 +ZEI 637 +ZEL 547 +ZEM 574 +ZEN 678 +ZER 561 +ZEU 590 +ZEV 429 +ZEX 530 +ZFR 804 +ZGA 634 +ZGE 564 +ZGR 772 +ZHE 804 +ZIA 552 +ZIE 731 +ZIG 482 +ZIM 552 +ZIN 592 +ZIS 552 +ZIV 482 +ZIX 552 +ZJE 804 +ZKC 564 +ZKO 744 +ZKX 703 +ZLI 775 +ZLU 666 +ZMA 804 +ZNA 764 +ZNO 694 +ZOE 643 +ZOG 753 +ZOR 643 +ZPA 804 +ZSC 643 +ZSI 713 +ZSO 643 +ZST 643 +ZTA 497 +ZTD 387 +ZTE 548 +ZTF 387 +ZTI 387 +ZTM 387 +ZTN 387 +ZTP 387 +ZTR 497 +ZTS 456 +ZTU 387 +ZTX 758 +ZTZ 525 +ZUA 416 +ZUB 456 +ZUE 525 +ZUF 416 +ZUG 638 +ZUH 387 +ZUI 277 +ZUK 387 +ZUL 346 +ZUM 646 +ZUN 517 +ZUR 643 +ZUS 548 +ZUT 387 +ZUU 387 +ZUV 346 +ZUW 472 +ZUX 346 +ZUZ 277 +ZVI 804 +ZWE 448 +ZWI 323 +ZWO 801 +ZXA 366 +ZXB 527 +ZXD 586 +ZXE 574 +ZXF 505 +ZXG 586 +ZXH 586 +ZXI 366 +ZXK 606 +ZXL 435 +ZXM 435 +ZXN 366 +ZXO 366 +ZXR 476 +ZXS 596 +ZXW 476 +ZXZ 366 +ZYB 461 +ZYX 801 +ZZE 625 +ZZN 625 +ZZS 694 +ZZU 694 diff --git a/benchmark/00unigr.AVv1 b/benchmark/00unigr.AVv1 new file mode 100644 index 0000000..6e0b4d6 --- /dev/null +++ b/benchmark/00unigr.AVv1 @@ -0,0 +1,26 @@ +A 424 +B 326 +C 258 +D 349 +E 498 +F 344 +G 341 +H 327 +I 422 +J 188 +K 312 +L 375 +M 341 +N 459 +O 391 +P 244 +Q 297 +R 439 +S 428 +T 413 +U 389 +V 267 +W 298 +X 444 +Y 100 +Z 309 diff --git a/benchmark/AlignedAllocationTrait.h b/benchmark/AlignedAllocationTrait.h new file mode 100644 index 0000000..b16e8f6 --- /dev/null +++ b/benchmark/AlignedAllocationTrait.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include + +template +struct AlignedAllocationTrait +{ + static void* operator new( std::size_t size ){ + void* ptr; +#if defined _WIN32 + ptr = _aligned_malloc( size , alignof(T) ); +#else + ptr = aligned_alloc( alignof(T), size ); +#endif + if( !ptr ) throw std::bad_alloc(); + return ptr; + } + + static void operator delete( void* ptr ){ +#if defined _WIN32 + _aligned_free( ptr ); +#else + free( ptr ); +#endif + } +}; diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt new file mode 100644 index 0000000..5346df9 --- /dev/null +++ b/benchmark/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.1) + +set(CMAKE_THREAD_PREFER_PTHREAD ON) +set(THREADS_PREFER_PTHREAD_FLAG ON) +include(FindThreads) + +add_executable(EnigmaBenchmark "") +include(sourceList.cmake) + +set_target_properties(EnigmaBenchmark + PROPERTIES OUTPUT_NAME "enigma-optima-benchmark") + +target_compile_features(EnigmaBenchmark PUBLIC cxx_std_11 c_std_99) +target_compile_options(EnigmaBenchmark PUBLIC $<$:-fexceptions>) +target_compile_options(EnigmaBenchmark + PRIVATE + $<$:${ENIGMA_CXX_COMPILE_OPTIONS}> + ${ENIGMA_COMPILE_OPTIONS}) + + +if(CMAKE_C_COMPILER_ID MATCHES "GNU") + set_target_properties(EnigmaBenchmark PROPERTIES C_EXTENSIONS ON) +endif() + + +target_link_libraries(EnigmaBenchmark Enigma benchmark Threads::Threads) +target_link_libraries(EnigmaBenchmark + -static-libgcc + -static-libstdc++) + +if(WIN32) + target_link_libraries(EnigmaBenchmark shlwapi) +endif() diff --git a/benchmark/MessageAndKeyBasedFixture.cpp b/benchmark/MessageAndKeyBasedFixture.cpp new file mode 100644 index 0000000..8d54c8c --- /dev/null +++ b/benchmark/MessageAndKeyBasedFixture.cpp @@ -0,0 +1,50 @@ +#include "MessageAndKeyBasedFixture.h" + +extern "C"{ +#include "charmap.h" +#include "ciphertext.h" +#include "input.h" +#include "stecker.h" +} + +void +MessageAndKeyBasedFixture::SetUp( benchmark::State& st UNUSED ) +{ + init_charmap(); + + LoadDictionary(); + + // Score: 46438 + // UKW: B // ukwnum + // W/0: 532 // slot + // Stecker: AXBZCNDPEOJMLSQV + // Rings: AAA + // Message key: AVA + + const unsigned char ct[] = "pbnxasmdaxnooyhrczgvvzcbigibgwhm" + "xkrrvqcfjczptunswaddstigqqcsagpk" + "rxxlomgfxaphhmrfsdkytmypmvrohasq" + "yrwfwvavgccudbibxxdyzsacjsyotmwu" + "cnwomhhjpywdcclupgswclmbczssyxpg" + "mgmqxaufulnozeqenheizzaklc"; + + for( size_t i = 0 ; i < sizeof ct; ++i ) + { + ciphertext.plain[i] = code[ct[i]]; + } + + + key.slot = { /*.g:*/ 0, /*.l:*/ 5, /*.m:*/3, /*.r:*/ 2 }; + key.ring = { /*.g:*/ 0, /*.l:*/ 0, /*.m:*/0, /*.r:*/ 0 }; // AAA + key.mesg = { /*.g:*/ 0, /*.l:*/ 0, /*.m:*/'V' - 'A', /*.r:*/ 0 }; // AVA + key.ukwnum = 'B' - 'A'; + key.model = EnigmaModel_M3; + + Fill0To25( key.stbrett.letters ); + Fill0To25( key.sf ); + char stecker[] = "AXBZCNDPEOJMLSQV"; + set_stecker( &key, stecker ); + get_stecker( &key ); + + len = sizeof ct - 1; +} diff --git a/benchmark/MessageAndKeyBasedFixture.h b/benchmark/MessageAndKeyBasedFixture.h new file mode 100644 index 0000000..c2241cc --- /dev/null +++ b/benchmark/MessageAndKeyBasedFixture.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +#include "AlignedAllocationTrait.h" + +extern "C" { +#include "key.h" +} + +struct MessageAndKeyBasedFixture + : benchmark::Fixture + , public AlignedAllocationTrait { + size_t len = 0; + Key key {}; + + void SetUp( benchmark::State& st ) final; + +protected: + virtual void LoadDictionary() = 0; +}; diff --git a/benchmark/biscore.tests.cpp b/benchmark/biscore.tests.cpp new file mode 100644 index 0000000..622828a --- /dev/null +++ b/benchmark/biscore.tests.cpp @@ -0,0 +1,124 @@ +#include +#include "MessageAndKeyBasedFixture.h" + +extern "C" { +#include "dict.h" +#include "scoreBasic.h" +#include "scoreNoInterleave.h" +#include "scoreSimple.h" +#include "x86/cipherSsse3.h" +#include "x86/scoreSsse3.h" +#include "x86/scoreAvx.h" +#include "x86/cipherAvx2.h" +#include "x86/scoreAvx2.h" +} + +struct biscore + : public MessageAndKeyBasedFixture +{ + const int expectedScore = 7913; +protected: + void LoadDictionary() override { + load_bidict( "00bigr.cur" ); + } +}; + +BENCHMARK_DEFINE_F( biscore, simple )( benchmark::State& state ) { + + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreSimple.biscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( biscore, basic_no_interleave )( benchmark::State& state ) { + + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreOptNoInterleave.biscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( biscore, basic )( benchmark::State& state ) { + + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreBasic.biscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( biscore, ssse3 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("ssse3") ) { + state.SkipWithError("SSSE3 not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreSsse3.biscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( biscore, avx ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx") ) { + state.SkipWithError("AVX not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreAvx.biscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( biscore, avx2 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx2") ) { + state.SkipWithError("AVX2 not supported"); + return; + } + enigma_cipher_DecoderLookupAvx2.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreAvx2.biscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_REGISTER_F( biscore, simple ); +BENCHMARK_REGISTER_F( biscore, basic_no_interleave ); +BENCHMARK_REGISTER_F( biscore, basic ); +BENCHMARK_REGISTER_F( biscore, ssse3 ); +BENCHMARK_REGISTER_F( biscore, avx ); +BENCHMARK_REGISTER_F( biscore, avx2 ); diff --git a/benchmark/cipherAvx2_ni.c b/benchmark/cipherAvx2_ni.c new file mode 100644 index 0000000..cb5950e --- /dev/null +++ b/benchmark/cipherAvx2_ni.c @@ -0,0 +1,22 @@ +#pragma GCC target ("avx2") + +#ifndef __AVX2__ +# error AVX2 not defined +#endif + +#include + +#include "cipherAvx2_ni.h" +#include "score_inlines.h" +#include "x86/cipherAvx2_inlines.h" +#include "x86/scoreAvx2.h" + +__attribute__ ((flatten)) +void DecodeMessageAvx2( const Key* const restrict key, int len ) { + DecodeScoredMessagePartAvx2( key, len, &decodedMsgPartAvx2 ); +} + +__attribute__ ((flatten)) +int IcscoreAvx2( scoreLength_t len ){ + return ComputeIcscoreFromDecodedMsgAvx2( &decodedMsgPartAvx2, len ); +} diff --git a/benchmark/cipherAvx2_ni.h b/benchmark/cipherAvx2_ni.h new file mode 100644 index 0000000..f35bed3 --- /dev/null +++ b/benchmark/cipherAvx2_ni.h @@ -0,0 +1,7 @@ +#pragma once + +#include "key.h" +#include "score.h" + +void DecodeMessageAvx2( const Key* const restrict key, int len ); +int IcscoreAvx2( scoreLength_t len ); diff --git a/benchmark/cipherAvx_ni.c b/benchmark/cipherAvx_ni.c new file mode 100644 index 0000000..d79df17 --- /dev/null +++ b/benchmark/cipherAvx_ni.c @@ -0,0 +1,32 @@ +#pragma GCC target ("avx") + +#ifndef __AVX__ +# error AVX not defined +#endif + +#include + +#include "cipherAvx_ni.h" +#include "score_inlines.h" +#include "x86/cipherSsse3_inlines.h" +#include "x86/scoreAvx.h" + +__attribute__ ((flatten)) +void DecodeMessageAvx( const Key* const restrict key, int len ) { + DecodeScoredMessagePartSsse3( key, len, &decodedMsgPartAvx ); +} + +__attribute__ ((flatten)) +int IcscoreAvx( scoreLength_t len ){ + return ComputeIcscoreFromDecodedMsgSsse3( &decodedMsgPartAvx, len ); +} + +__attribute__ ((flatten)) +int BiscoreAvx( scoreLength_t len ){ + return ComputeBiscoreFromDecodedMsgSse2( &decodedMsgPartAvx, len ); +} + +__attribute__ ((flatten)) +int TriscoreAvx( scoreLength_t len ){ + return ComputeTriscoreFromDecodedMsgSse2( &decodedMsgPartAvx, len ); +} diff --git a/benchmark/cipherAvx_ni.h b/benchmark/cipherAvx_ni.h new file mode 100644 index 0000000..58f5efa --- /dev/null +++ b/benchmark/cipherAvx_ni.h @@ -0,0 +1,9 @@ +#pragma once + +#include "key.h" +#include "score.h" + +void DecodeMessageAvx( const Key* const restrict key, int len ); +int IcscoreAvx( scoreLength_t len ); +int BiscoreAvx( scoreLength_t len ); +int TriscoreAvx( scoreLength_t len ); diff --git a/benchmark/cipherSimple_ni.c b/benchmark/cipherSimple_ni.c new file mode 100644 index 0000000..516bc1f --- /dev/null +++ b/benchmark/cipherSimple_ni.c @@ -0,0 +1,24 @@ +#include "cipherSimple_ni.h" +#include "score_inlines.h" +#include "scoreNoInterleave.h" +#include "scoreNoInterleave_inlines.h" + +void DecodeMessageBasicNoInterleave( const Key* const restrict key, int len ){ + DecodeScoredMessagePartNoInterleave( key, len, &decodedMsgPartNoInterleave ); +} + +int BiscoreSimple( scoreLength_t len ){ + return ComputeBiscoreFromDecodedMsg( &decodedMsgPartNoInterleave, len ); +} + +uint16_t IcscoreSimple( scoreLength_t len ){ + return ComputeIcscoreFromDecodedMsg( &decodedMsgPartNoInterleave, len ); +} + +int TriscoreBasicNoInterleave( scoreLength_t len ){ + return ComputeTriscoreFromDecodedMsg( &decodedMsgPartNoInterleave, len ); +} + +int UniscoreBasicNoInterleave( scoreLength_t len ){ + return ComputeUniscoreFromDecodedMsg( &decodedMsgPartNoInterleave, len ); +} diff --git a/benchmark/cipherSimple_ni.h b/benchmark/cipherSimple_ni.h new file mode 100644 index 0000000..d472b68 --- /dev/null +++ b/benchmark/cipherSimple_ni.h @@ -0,0 +1,11 @@ +#pragma once + +#include "key.h" +#include "score.h" + +void DecodeMessageBasicNoInterleave( const Key* const restrict key, int len ); +int BiscoreSimple( scoreLength_t len ); +int TriscoreBasicNoInterleave( scoreLength_t len ); +int UniscoreBasicNoInterleave( scoreLength_t len ); + +uint16_t IcscoreSimple( scoreLength_t len ); diff --git a/benchmark/cipherSse2_ni.c b/benchmark/cipherSse2_ni.c new file mode 100644 index 0000000..0e6c2ab --- /dev/null +++ b/benchmark/cipherSse2_ni.c @@ -0,0 +1,21 @@ +#pragma GCC target ("sse2") + +#ifndef __SSE2__ +# error SSE2 not defined +#endif + +#include + +#include "cipherSse2_ni.h" +#include "score_inlines.h" +#include "x86/cipherSsse3_inlines.h" + +__attribute__ ((flatten)) +int TriscoreSse2( scoreLength_t len ) { + return ComputeTriscoreFromDecodedMsgSse2( &decodedMsgPartSsse3, len ); +} + +__attribute__ ((flatten)) +int BiscoreSse2( scoreLength_t len ) { + return ComputeBiscoreFromDecodedMsgSse2( &decodedMsgPartSsse3, len ); +} diff --git a/benchmark/cipherSse2_ni.h b/benchmark/cipherSse2_ni.h new file mode 100644 index 0000000..25ac29a --- /dev/null +++ b/benchmark/cipherSse2_ni.h @@ -0,0 +1,7 @@ +#pragma once + +#include "key.h" +#include "score.h" + +int BiscoreSse2( scoreLength_t len ); +int TriscoreSse2( scoreLength_t len ); diff --git a/benchmark/cipherSsse3_ni.c b/benchmark/cipherSsse3_ni.c new file mode 100644 index 0000000..815de7c --- /dev/null +++ b/benchmark/cipherSsse3_ni.c @@ -0,0 +1,22 @@ +#pragma GCC target ("ssse3") + +#ifndef __SSSE3__ +# error SSSE3 not defined +#endif + + +#include + +#include "cipherSsse3_ni.h" +#include "score_inlines.h" +#include "x86/cipherSsse3_inlines.h" + +__attribute__ ((flatten)) +void DecodeMessageSsse3( const Key* const restrict key, int len ) { + DecodeScoredMessagePartSsse3( key, len, &decodedMsgPartSsse3 ); +} + +__attribute__ ((flatten)) +int IcscoreSsse3( scoreLength_t len ){ + return ComputeIcscoreFromDecodedMsgSsse3( &decodedMsgPartSsse3, len ); +} diff --git a/benchmark/cipherSsse3_ni.h b/benchmark/cipherSsse3_ni.h new file mode 100644 index 0000000..77a821e --- /dev/null +++ b/benchmark/cipherSsse3_ni.h @@ -0,0 +1,7 @@ +#pragma once + +#include "key.h" +#include "score.h" + +void DecodeMessageSsse3( const Key* const restrict key, int len ); +int IcscoreSsse3( scoreLength_t len ); diff --git a/benchmark/compute_biscore.tests.cpp b/benchmark/compute_biscore.tests.cpp new file mode 100644 index 0000000..dfe57bd --- /dev/null +++ b/benchmark/compute_biscore.tests.cpp @@ -0,0 +1,84 @@ +#include +#include "MessageAndKeyBasedFixture.h" + +extern "C" { +#include "dict.h" +#include "x86/cipherSsse3.h" +#include "x86/cipherAvx2.h" +#include "cipherSimple_ni.h" +#include "cipherSse2_ni.h" +#include "cipherSsse3_ni.h" +#include "cipherAvx_ni.h" +#include "cipherAvx2_ni.h" +} + +struct compute_biscore + : public MessageAndKeyBasedFixture +{ + const int expectedScore = 7913; +protected: + void LoadDictionary() override { + load_bidict( "00bigr.cur" ); + } +}; + +BENCHMARK_DEFINE_F( compute_biscore, simple ) ( benchmark::State& state ){ + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + DecodeMessageBasicNoInterleave( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = BiscoreSimple( len ); + } + + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( compute_biscore, sse2 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("sse2") ) { + state.SkipWithError("SSE2 not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + DecodeMessageSsse3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = BiscoreSse2( len ); + } + + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( compute_biscore, sse2_avx ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx") ) { + state.SkipWithError("AVX not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + DecodeMessageSsse3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = BiscoreAvx( len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_REGISTER_F( compute_biscore, simple ); +BENCHMARK_REGISTER_F( compute_biscore, sse2 ); +BENCHMARK_REGISTER_F( compute_biscore, sse2_avx ); + diff --git a/benchmark/compute_icscore.tests.cpp b/benchmark/compute_icscore.tests.cpp new file mode 100644 index 0000000..894f0ce --- /dev/null +++ b/benchmark/compute_icscore.tests.cpp @@ -0,0 +1,98 @@ +#include +#include "MessageAndKeyBasedFixture.h" + +extern "C" { +#include "x86/cipherSsse3.h" +#include "x86/cipherAvx2.h" +#include "cipherSimple_ni.h" +#include "cipherSsse3_ni.h" +#include "cipherAvx_ni.h" +#include "cipherAvx2_ni.h" +} + +struct compute_icscore + : public MessageAndKeyBasedFixture +{ + const int expectedScore = 1344; +protected: + void LoadDictionary() override {} +}; + +BENCHMARK_DEFINE_F( compute_icscore, simple ) ( benchmark::State& state ){ + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + DecodeMessageBasicNoInterleave( &key, len ); + int score = 0; + for( auto _ : state ) { + score = IcscoreSimple( len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( compute_icscore, ssse3 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("ssse3") ) { + state.SkipWithError("SSSE3 not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + DecodeMessageSsse3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = IcscoreSsse3( len ); + } + + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( compute_icscore, avx ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx") ) { + state.SkipWithError("AVX not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + DecodeMessageAvx( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = IcscoreAvx( len ); + } + + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( compute_icscore, avx2 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx2") ) { + state.SkipWithError("AVX2 not supported"); + return; + } + enigma_cipher_DecoderLookupAvx2.prepare_decoder_lookup_M_H3( &key, len ); + DecodeMessageAvx2( &key, len ); + int score = 0; + for( auto _ : state ) { + score = IcscoreAvx2( len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_REGISTER_F( compute_icscore, simple ); +BENCHMARK_REGISTER_F( compute_icscore, ssse3 ); +BENCHMARK_REGISTER_F( compute_icscore, avx ); +BENCHMARK_REGISTER_F( compute_icscore, avx2 ); + diff --git a/benchmark/compute_triscore.tests.cpp b/benchmark/compute_triscore.tests.cpp new file mode 100644 index 0000000..8882064 --- /dev/null +++ b/benchmark/compute_triscore.tests.cpp @@ -0,0 +1,79 @@ +#include +#include "MessageAndKeyBasedFixture.h" + +extern "C" { +#include "dict.h" +#include "x86/cipherSsse3.h" +#include "x86/cipherAvx2.h" +#include "cipherSimple_ni.h" +#include "cipherSse2_ni.h" +#include "cipherSsse3_ni.h" +#include "cipherAvx_ni.h" +#include "cipherAvx2_ni.h" +} + +struct compute_triscore + : public MessageAndKeyBasedFixture +{ + const int expectedScore = 46438; +protected: + void LoadDictionary() override { + load_tridict( "00trigr.AVv1" ); + } +}; + +BENCHMARK_DEFINE_F( compute_triscore, simple ) ( benchmark::State& state ){ + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + DecodeMessageBasicNoInterleave( &key, len ); + int score = 0; + for( auto _ : state ){ + score = TriscoreBasicNoInterleave( len ); + } + if( score != expectedScore ){ + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( compute_triscore, sse2 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("sse2") ) { + state.SkipWithError("SSE2 not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + DecodeMessageSsse3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = TriscoreSse2( len ); + } + + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( compute_triscore, sse2_avx ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx") ) { + state.SkipWithError("AVX not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + DecodeMessageSsse3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = TriscoreAvx( len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_REGISTER_F( compute_triscore, simple ); +BENCHMARK_REGISTER_F( compute_triscore, sse2 ); +BENCHMARK_REGISTER_F( compute_triscore, sse2_avx ); diff --git a/benchmark/compute_uniscore.tests.cpp b/benchmark/compute_uniscore.tests.cpp new file mode 100644 index 0000000..80aa111 --- /dev/null +++ b/benchmark/compute_uniscore.tests.cpp @@ -0,0 +1,41 @@ +#include +#include "MessageAndKeyBasedFixture.h" + +extern "C" { +#include "dict.h" +#include "x86/cipherSsse3.h" +#include "x86/cipherAvx2.h" +#include "cipherSimple_ni.h" +#include "cipherSsse3_ni.h" +#include "cipherAvx_ni.h" +#include "cipherAvx2_ni.h" +} + +struct compute_uniscore + : public MessageAndKeyBasedFixture +{ + const int expectedScore = 66593; +protected: + void LoadDictionary() override { + load_unidict( "00unigr.AVv1" ); + } +}; + +BENCHMARK_DEFINE_F( compute_uniscore, simple ) ( benchmark::State& state ){ + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + DecodeMessageBasicNoInterleave( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = UniscoreBasicNoInterleave( len ); + } + + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_REGISTER_F( compute_uniscore, simple ); diff --git a/benchmark/decoding.tests.cpp b/benchmark/decoding.tests.cpp new file mode 100644 index 0000000..705fad2 --- /dev/null +++ b/benchmark/decoding.tests.cpp @@ -0,0 +1,84 @@ +#include + +#include "MessageAndKeyBasedFixture.h" + +extern "C" { +#include "x86/cipherAvx2.h" +#include "x86/cipherSsse3.h" +#include "cipherAvx_ni.h" +#include "cipherAvx2_ni.h" +#include "cipherSsse3_ni.h" +#include "scoreNoInterleave.h" +#include "scoreNoInterleave_inlines.h" +} + +struct decoding + : public MessageAndKeyBasedFixture +{ +protected: + void LoadDictionary() override {} +}; + +BENCHMARK_DEFINE_F( decoding, simple )( benchmark::State& state ) { + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + for( auto _ : state ) { + DecodeScoredMessagePartNoInterleaveSimple( &key, len, &decodedMsgPartNoInterleave ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( decoding, basic_no_interleave )( benchmark::State& state ) { + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + for( auto _ : state ) { + DecodeScoredMessagePartNoInterleave( &key, len, &decodedMsgPartNoInterleave ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( decoding, ssse3 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("ssse3") ) { + state.SkipWithError("SSSE3 not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + for( auto _ : state ) { + DecodeMessageSsse3( &key, len ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( decoding, avx ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx") ) { + state.SkipWithError("AVX not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + for( auto _ : state ) { + DecodeMessageAvx( &key, len ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( decoding, avx2 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx2") ) { + state.SkipWithError("AVX2 not supported"); + return; + } + enigma_cipher_DecoderLookupAvx2.prepare_decoder_lookup_M_H3( &key, len ); + for( auto _ : state ) { + DecodeMessageAvx2( &key, len ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_REGISTER_F( decoding, simple ); +BENCHMARK_REGISTER_F( decoding, basic_no_interleave); +BENCHMARK_REGISTER_F( decoding, ssse3 ); +BENCHMARK_REGISTER_F( decoding, avx ); +BENCHMARK_REGISTER_F( decoding, avx2 ); diff --git a/benchmark/enigmaError.c b/benchmark/enigmaError.c new file mode 100644 index 0000000..a6489de --- /dev/null +++ b/benchmark/enigmaError.c @@ -0,0 +1,24 @@ +#include "error.h" + +NO_RETURN +void err_illegal_char_fatal( UNUSED const char *s ) { + exit( 2 ); +} + +NO_RETURN +void err_open_fatal_resume( UNUSED const char *s ) { + exit( 3 ); +} + +NO_RETURN +void err_open_fatal( UNUSED const char *s ) { + exit( 4 ); +} + +NO_RETURN +void err_input_fatal( UNUSED int type ) { + exit( 5 ); +} + +extern inline +void exit_d( int errorCode UNUSED ); diff --git a/benchmark/icscore.tests.cpp b/benchmark/icscore.tests.cpp new file mode 100644 index 0000000..fdc1d90 --- /dev/null +++ b/benchmark/icscore.tests.cpp @@ -0,0 +1,121 @@ +#include +#include "MessageAndKeyBasedFixture.h" + +extern "C" { +#include "scoreBasic.h" +#include "scoreNoInterleave.h" +#include "scoreSimple.h" +#include "x86/cipherSsse3.h" +#include "x86/scoreSsse3.h" +#include "x86/scoreAvx.h" +#include "x86/cipherAvx2.h" +#include "x86/scoreAvx2.h" +} + +struct icscore + : public MessageAndKeyBasedFixture +{ + const int expectedScore = 1344; +protected: + void LoadDictionary() override {} +}; + +BENCHMARK_DEFINE_F( icscore, simple )( benchmark::State& state ) { + + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreSimple.icscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( icscore, basic_no_interleave )( benchmark::State& state ) { + + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreOptNoInterleave.icscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( icscore, basic )( benchmark::State& state ) { + + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreBasic.icscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( icscore, ssse3 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("ssse3") ) { + state.SkipWithError("SSSE3 not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreSsse3.icscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( icscore, avx ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx") ) { + state.SkipWithError("AVX not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreAvx.icscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( icscore, avx2 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx2") ) { + state.SkipWithError("AVX2 not supported"); + return; + } + enigma_cipher_DecoderLookupAvx2.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreAvx2.icscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_REGISTER_F( icscore, simple ); +BENCHMARK_REGISTER_F( icscore, basic_no_interleave ); +BENCHMARK_REGISTER_F( icscore, basic ); +BENCHMARK_REGISTER_F( icscore, ssse3 ); +BENCHMARK_REGISTER_F( icscore, avx ); +BENCHMARK_REGISTER_F( icscore, avx2 ); diff --git a/benchmark/main.cpp b/benchmark/main.cpp new file mode 100644 index 0000000..1d3863d --- /dev/null +++ b/benchmark/main.cpp @@ -0,0 +1,3 @@ +#include + +BENCHMARK_MAIN() diff --git a/benchmark/sourceList.cmake b/benchmark/sourceList.cmake new file mode 100644 index 0000000..5283cfc --- /dev/null +++ b/benchmark/sourceList.cmake @@ -0,0 +1,27 @@ +target_sources(EnigmaBenchmark +PRIVATE + "main.cpp" + "MessageAndKeyBasedFixture.cpp" + "enigmaError.c" + + # "No Inline" + "cipherAvx_ni.c" + "cipherAvx2_ni.c" + "cipherSimple_ni.c" + "cipherSse2_ni.c" + "cipherSsse3_ni.c" + + "decoding.tests.cpp" + + # decode+score tests + "biscore.tests.cpp" + "triscore.tests.cpp" + "uniscore.tests.cpp" + "icscore.tests.cpp" + + # compute score only + "compute_icscore.tests.cpp" + "compute_biscore.tests.cpp" + "compute_triscore.tests.cpp" + "compute_uniscore.tests.cpp" +) \ No newline at end of file diff --git a/benchmark/triscore.tests.cpp b/benchmark/triscore.tests.cpp new file mode 100644 index 0000000..f447859 --- /dev/null +++ b/benchmark/triscore.tests.cpp @@ -0,0 +1,131 @@ +#include +#include "MessageAndKeyBasedFixture.h" + +extern "C" { +#include "dict.h" +#include "scoreBasic.h" +#include "scoreNoInterleave.h" +#include "scoreSimple.h" +#include "x86/cipherSsse3.h" +#include "x86/scoreSsse3.h" +#include "x86/scoreAvx.h" +#include "x86/cipherAvx2.h" +#include "x86/scoreAvx2.h" +} + +struct triscore + : public MessageAndKeyBasedFixture +{ + const int expectedScore = 46438; +protected: + void LoadDictionary() override { + load_tridict( "00trigr.AVv1" ); + } +}; + +BENCHMARK_DEFINE_F( triscore, simple )( benchmark::State& state ) { + + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreSimple.triscore( &key, len ); + } + + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( triscore, basic_no_interleave )( benchmark::State& state ) { + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreOptNoInterleave.triscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( triscore, basic )( benchmark::State& state ) { + + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreBasic.triscore( &key, len ); + } + + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( triscore, ssse3 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("ssse3") ) { + state.SkipWithError("SSSE3 not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreSsse3.triscore( &key, len ); + } + + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( triscore, avx ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx") ) { + state.SkipWithError("AVX not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreAvx.triscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( triscore, avx2 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx2") ) { + state.SkipWithError("AVX2 not supported"); + return; + } + enigma_cipher_DecoderLookupAvx2.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreAvx2.triscore( &key, len ); + } + + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_REGISTER_F( triscore, simple ); +BENCHMARK_REGISTER_F( triscore, basic_no_interleave ); +BENCHMARK_REGISTER_F( triscore, basic ); +BENCHMARK_REGISTER_F( triscore, ssse3 ); +BENCHMARK_REGISTER_F( triscore, avx ); +BENCHMARK_REGISTER_F( triscore, avx2 ); diff --git a/benchmark/uniscore.tests.cpp b/benchmark/uniscore.tests.cpp new file mode 100644 index 0000000..a664dbc --- /dev/null +++ b/benchmark/uniscore.tests.cpp @@ -0,0 +1,124 @@ +#include +#include "MessageAndKeyBasedFixture.h" + +extern "C" { +#include "dict.h" +#include "scoreBasic.h" +#include "scoreNoInterleave.h" +#include "scoreSimple.h" +#include "x86/cipherSsse3.h" +#include "x86/scoreSsse3.h" +#include "x86/scoreAvx.h" +#include "x86/cipherAvx2.h" +#include "x86/scoreAvx2.h" +} + +struct uniscore + : public MessageAndKeyBasedFixture +{ + const int expectedScore = 66593; +protected: + void LoadDictionary() override { + load_unidict( "00unigr.AVv1" ); + } +}; + +BENCHMARK_DEFINE_F( uniscore, simple )( benchmark::State& state ) { + + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreSimple.uniscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( uniscore, basic_no_interleave )( benchmark::State& state ) { + + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreOptNoInterleave.uniscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( uniscore, basic )( benchmark::State& state ) { + + enigma_cipher_decoder_lookup.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreBasic.uniscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( uniscore, ssse3 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("ssse3") ) { + state.SkipWithError("SSSE3 not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreSsse3.uniscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( uniscore, avx ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx") ) { + state.SkipWithError("AVX not supported"); + return; + } + enigma_cipher_decoder_lookup_ssse3.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreAvx.uniscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_DEFINE_F( uniscore, avx2 ) ( benchmark::State& state ){ + if( !__builtin_cpu_supports("avx2") ) { + state.SkipWithError("AVX2 not supported"); + return; + } + enigma_cipher_DecoderLookupAvx2.prepare_decoder_lookup_M_H3( &key, len ); + + int score = 0; + for( auto _ : state ) { + score = enigmaScoreAvx2.uniscore( &key, len ); + } + if( score != expectedScore ) { + state.SkipWithError( "Wrong score!" ); + } + state.SetBytesProcessed( state.iterations() * len ); +} + +BENCHMARK_REGISTER_F( uniscore, simple ); +BENCHMARK_REGISTER_F( uniscore, basic_no_interleave ); +BENCHMARK_REGISTER_F( uniscore, basic ); +BENCHMARK_REGISTER_F( uniscore, ssse3 ); +BENCHMARK_REGISTER_F( uniscore, avx ); +BENCHMARK_REGISTER_F( uniscore, avx2 ); diff --git a/code_blocks/enigma-opt.cbp b/code_blocks/enigma-opt.cbp deleted file mode 100644 index fdadc75..0000000 --- a/code_blocks/enigma-opt.cbp +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - diff --git a/code_blocks/libEnigma/libEnigma.cbp b/code_blocks/libEnigma/libEnigma.cbp deleted file mode 100644 index 99d56d1..0000000 --- a/code_blocks/libEnigma/libEnigma.cbp +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - diff --git a/config/releaseVersion.cpp b/config/releaseVersion.cpp deleted file mode 100644 index e1a7eb1..0000000 --- a/config/releaseVersion.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "releaseVersion.h" - -char const* releaseVersion = "v1.1.0"; diff --git a/enigma-optima.workspace b/enigma-optima.workspace deleted file mode 100644 index 8991fc5..0000000 --- a/enigma-optima.workspace +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/extern/gbench b/extern/gbench new file mode 160000 index 0000000..336bb8d --- /dev/null +++ b/extern/gbench @@ -0,0 +1 @@ +Subproject commit 336bb8db986cc52cdf0cefa0a7378b9567d1afee diff --git a/extern/gtest b/extern/gtest new file mode 160000 index 0000000..2fe3bd9 --- /dev/null +++ b/extern/gtest @@ -0,0 +1 @@ +Subproject commit 2fe3bd994b3189899d93f1d5a881e725e046fdc2 diff --git a/libEnigma/CMakeLists.txt b/libEnigma/CMakeLists.txt new file mode 100644 index 0000000..9126be4 --- /dev/null +++ b/libEnigma/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.1) + +add_library(Enigma "") + +include(commonSources.cmake) +if(WIN32) + target_sources(Enigma PRIVATE "src/randomNumbers.Windows.c") +elseif(UNIX) + target_sources(Enigma PRIVATE "src/randomNumbers.Linux.c") +endif() + +target_include_directories(Enigma PUBLIC $) + +target_compile_features(Enigma PUBLIC c_std_99) +target_compile_options(Enigma + PRIVATE + ${ENIGMA_COMPILE_OPTIONS}) + + +if(CMAKE_C_COMPILER_ID MATCHES "GNU") + set_target_properties(Enigma PROPERTIES C_EXTENSIONS ON) + target_link_libraries(Enigma + -static-libgcc + -static-libstdc++) +endif() \ No newline at end of file diff --git a/libEnigma/commonSources.cmake b/libEnigma/commonSources.cmake new file mode 100644 index 0000000..e8da4d1 --- /dev/null +++ b/libEnigma/commonSources.cmake @@ -0,0 +1,31 @@ +target_sources(Enigma +PRIVATE + "src/charmap.c" + "src/cipher.c" + "src/ciphertext.c" + "src/cpu.c" + "src/date.c" + "src/dict.c" + "src/hillclimb.c" + "src/hillclimb2.c" + "src/input.c" + "src/key.c" + "src/optimizer.c" + "src/randomNumbers.c" + "src/result.c" + "src/resume_in.c" + "src/resume_out.c" + "src/scan.c" + "src/score.c" + "src/scoreBasic.c" + "src/scoreNoInterleave.c" + "src/scoreSimple.c" + "src/stecker.c" + + + "src/x86/cipherAvx2.c" + "src/x86/cipherSsse3.c" + "src/x86/scoreAvx.c" + "src/x86/scoreAvx2.c" + "src/x86/scoreSsse3.c" +) \ No newline at end of file diff --git a/libEnigma/include/ModMath.h b/libEnigma/include/ModMath.h index c082b39..360de99 100644 --- a/libEnigma/include/ModMath.h +++ b/libEnigma/include/ModMath.h @@ -14,7 +14,7 @@ * \return int8_t Difference modulo 26 */ CONST_FUNCTION -inline +static inline int8_t SubMod26( int8_t a, int8_t b ) { int8_t value = a - b; @@ -29,7 +29,7 @@ int8_t SubMod26( int8_t a, int8_t b ) * \return int8_t Sum modulo 26. */ CONST_FUNCTION -inline +static inline int8_t AddMod26( int8_t a, int8_t b ) { int8_t value = a + b; @@ -37,7 +37,7 @@ int8_t AddMod26( int8_t a, int8_t b ) return value; } -inline +static inline void IncrementMod(int8_t* number, int8_t modulo) { if( ++*number == modulo ) *number = 0; @@ -46,7 +46,7 @@ void IncrementMod(int8_t* number, int8_t modulo) /* v16qi * * * * * */ CONST_FUNCTION -inline +static inline v16qi AddMod26_v16qi_int8( v16qi a, int8_t b ){ v16qi value = a + b; value -= ( value >= 26 ) & 26; @@ -54,7 +54,7 @@ v16qi AddMod26_v16qi_int8( v16qi a, int8_t b ){ } CONST_FUNCTION -inline +static inline v16qi AddMod26_v16qi( v16qi a, v16qi b ){ v16qi value = a + b; value -= ( value >= 26 ) & 26; @@ -62,7 +62,7 @@ v16qi AddMod26_v16qi( v16qi a, v16qi b ){ } CONST_FUNCTION -inline +static inline v16qi SubMod26_v16qi_int8( v16qi a, int8_t b ){ v16qi value = a - b; value += ( value < 0 ) & 26; @@ -70,7 +70,7 @@ v16qi SubMod26_v16qi_int8( v16qi a, int8_t b ){ } CONST_FUNCTION -inline +static inline v16qi SubMod26_v16qi( v16qi a, v16qi b ){ v16qi value = a - b; value += ( value < 0 ) & 26; @@ -80,7 +80,7 @@ v16qi SubMod26_v16qi( v16qi a, v16qi b ){ /* v32qi * * * * * */ CONST_FUNCTION -inline +static inline v32qi AddMod26_v32qi_int8( v32qi a, int8_t b ){ v32qi value = a + b; value -= ( value >= 26 ) & 26; @@ -88,7 +88,7 @@ v32qi AddMod26_v32qi_int8( v32qi a, int8_t b ){ } CONST_FUNCTION -inline +static inline v32qi AddMod26_v32qi( v32qi a, v32qi b ){ v32qi value = a + b; value -= ( value >= 26 ) & 26; @@ -96,7 +96,7 @@ v32qi AddMod26_v32qi( v32qi a, v32qi b ){ } CONST_FUNCTION -inline +static inline v32qi SubMod26_v32qi_int8( v32qi a, int8_t b ){ v32qi value = a - b; value += ( value < 0 ) & 26; @@ -104,7 +104,7 @@ v32qi SubMod26_v32qi_int8( v32qi a, int8_t b ){ } CONST_FUNCTION -inline +static inline v32qi SubMod26_v32qi( v32qi a, v32qi b ){ v32qi value = a - b; value += ( value < 0 ) & 26; diff --git a/libEnigma/include/cipher.h b/libEnigma/include/cipher.h index 7a442ff..ad6ee65 100644 --- a/libEnigma/include/cipher.h +++ b/libEnigma/include/cipher.h @@ -46,23 +46,169 @@ extern text_t rev_wal[11][78]; extern text_t ukw[5][52]; extern text_t etw[52]; -// (&ciphertext[x])[i]; is a synonyme to: ciphertext[x+i]; -// and is useful where ciphertext[x] can be calculated at compilation time. -// -// path_lookup[Offset][(Index)*(LAST_DIMENSION)+(Cx)]; -// is synonyme to -// path_lookup[Offset+Index][(Cx)]; -inline -text_t decode(size_t offset,size_t index, const PermutationMap_t* const stbrett) +static inline +size_t decode( size_t offset,size_t index, const PermutationMap_t* const stbrett ); + +static inline +v4pis decode4( size_t offset, size_t index, const PermutationMap_t* const stbrett ); + +#ifdef __i386__ + +static inline +size_t decode( size_t offset,size_t index, const PermutationMap_t* const stbrett ) { - text_t c; - c = (&ciphertext.plain[offset])[index]; + size_t c; + asm( + "movsb%z[c] %[ctext] + %c[offset] ( %[ind] ), %[c] \n\t" + : [c] "=&r" ( c ) + : [ctext] "m" ( ciphertext ) + , [ind] "r" ( index ) + , [offset] "i" ( offset )); + c = stbrett->letters[c]; - c = path_lookup[offset][index*LAST_DIMENSION+c]; + + // path_lookup[Offset+Index][(Cx)] + asm( + "movsb%z[c] %[path_lookup] + %c[offset] * %c[ld]( %[index], %[c] ), %[c] \n\t" + : [c] "+&r" ( c ) + : [path_lookup] "m" ( path_lookup ) + , [index] "r" ( index * LAST_DIMENSION ) + , [offset] "i" ( offset ) + , [ld] "i" ( LAST_DIMENSION )); + return stbrett->letters[c]; } -inline +static inline +v4pis decode4( size_t offset, size_t index, const PermutationMap_t* const stbrett ) +{ + size_t c; + size_t d; + size_t e; + size_t f; + asm( + "movsb%z[c] %[ctext] + %c[offset] + 0( %[ind] ), %[c] \n\t" + "movsb%z[d] %[ctext] + %c[offset] + 1( %[ind] ), %[d] \n\t" + "movsb%z[e] %[ctext] + %c[offset] + 2( %[ind] ), %[e] \n\t" + "movsb%z[f] %[ctext] + %c[offset] + 3( %[ind] ), %[f] \n\t" + : [c] "=&r" ( c ) + , [d] "=&r" ( d ) + , [e] "=&r" ( e ) + , [f] "=&r" ( f ) + : [ctext] "m" ( ciphertext ) + , [ind] "r" ( index ) + , [offset] "i" ( offset )); + + c = stbrett->letters[c]; + d = stbrett->letters[d]; + e = stbrett->letters[e]; + f = stbrett->letters[f]; + + // path_lookup[Offset+Index][(Cx)] + asm( + "movsb%z[c] %[path_lookup] + ( %c[offset] + 0 ) * %c[ld]( %[index], %[c] ), %[c] \n\t" + "movsb%z[d] %[path_lookup] + ( %c[offset] + 1 ) * %c[ld]( %[index], %[d] ), %[d] \n\t" + "movsb%z[e] %[path_lookup] + ( %c[offset] + 2 ) * %c[ld]( %[index], %[e] ), %[e] \n\t" + "movsb%z[f] %[path_lookup] + ( %c[offset] + 3 ) * %c[ld]( %[index], %[f] ), %[f] \n\t" + + : [c] "+&r" ( c ) + , [d] "+&r" ( d ) + , [e] "+&r" ( e ) + , [f] "+&r" ( f ) + : [path_lookup] "m" ( path_lookup ) + , [index] "r" ( index * LAST_DIMENSION ) + , [offset] "i" ( offset ) + , [ld] "i" ( LAST_DIMENSION )); + + v4pis ret = { stbrett->letters[c] + , stbrett->letters[d] + , stbrett->letters[e] + , stbrett->letters[f] + }; + return ret; +} + +#endif + +#ifdef __amd64__ + +static inline +size_t decode( size_t offset,size_t index, const PermutationMap_t* const stbrett ) +{ + size_t c; + asm( + "movsb%z[c] %c[offset] ( %[ctext], %[ind] ), %[c] \n\t" + + : [c] "=&r" ( c ) + : [ctext] "r" ( &ciphertext ) + , [ind] "r" ( index ) + , [offset] "i" ( offset )); + + c = stbrett->letters[c]; + + // path_lookup[Offset+Index][(Cx)] + asm( + "movsb%z[c] ( %c[offset] + 0 ) * %c[ld]( %[p_lookup_ind], %[c] ), %[c] \n\t" + + : [c] "+&r" ( c ) + : [p_lookup_ind]"r" ( path_lookup + index ) + , [offset] "i" ( offset ) + , [ld] "i" ( LAST_DIMENSION )); + + return stbrett->letters[c]; +} + +static inline +v4pis decode4( size_t offset, size_t index, const PermutationMap_t* const stbrett ) +{ + size_t c; + size_t d; + size_t e; + size_t f; + asm( + "movsb%z[c] %c[offset] + 0( %[ctext], %[ind] ), %[c] \n\t" + "movsb%z[d] %c[offset] + 1( %[ctext], %[ind] ), %[d] \n\t" + "movsb%z[e] %c[offset] + 2( %[ctext], %[ind] ), %[e] \n\t" + "movsb%z[f] %c[offset] + 3( %[ctext], %[ind] ), %[f] \n\t" + : [c] "=&r" ( c ) + , [d] "=&r" ( d ) + , [e] "=&r" ( e ) + , [f] "=&r" ( f ) + : [ctext] "r" ( &ciphertext ) + , [ind] "r" ( index ) + , [offset] "i" ( offset )); + + c = stbrett->letters[c]; + d = stbrett->letters[d]; + e = stbrett->letters[e]; + f = stbrett->letters[f]; + + // path_lookup[Offset+Index][(Cx)] + asm( + "movsb%z[c] ( %c[offset] + 0 ) * %c[ld]( %[p_lookup_ind], %[c] ), %[c] \n\t" + "movsb%z[d] ( %c[offset] + 1 ) * %c[ld]( %[p_lookup_ind], %[d] ), %[d] \n\t" + "movsb%z[e] ( %c[offset] + 2 ) * %c[ld]( %[p_lookup_ind], %[e] ), %[e] \n\t" + "movsb%z[f] ( %c[offset] + 3 ) * %c[ld]( %[p_lookup_ind], %[f] ), %[f] \n\t" + + : [c] "+&r" ( c ) + , [d] "+&r" ( d ) + , [e] "+&r" ( e ) + , [f] "+&r" ( f ) + : [p_lookup_ind]"r" ( path_lookup + index ) + , [offset] "i" ( offset ) + , [ld] "i" ( LAST_DIMENSION )); + + v4pis ret = { stbrett->letters[c] + , stbrett->letters[d] + , stbrett->letters[e] + , stbrett->letters[f] + }; + return ret; +} + +#endif + +static inline void Step1( int8_t* ringOffset ) { IncrementMod( ringOffset, 26 ); diff --git a/libEnigma/include/cipher_inlines.h b/libEnigma/include/cipher_inlines.h index 77dfebc..eebae32 100644 --- a/libEnigma/include/cipher_inlines.h +++ b/libEnigma/include/cipher_inlines.h @@ -7,7 +7,7 @@ #include "common.h" #include "key.h" -inline +static inline void StepAllRings( struct RingsState* const restrict rings, const struct Turnovers_t turns ) { // check if m,l rings will be turned @@ -30,7 +30,7 @@ void StepAllRings( struct RingsState* const restrict rings, const struct Turnove } } -inline +static inline void CopyRRing2Lookup( const Key* const restrict key, PermutationMap_t rRings[2] ) { // setup r_rings forward and backward. @@ -39,7 +39,7 @@ void CopyRRing2Lookup( const Key* const restrict key, PermutationMap_t rRings[2] } //! \brief Return position of R ring on next turnover -inline +static inline int8_t GetNextTurnover( const struct RingsState rings, const struct Turnovers_t turns ) { // turnover caused by M-ring (double step) @@ -65,8 +65,7 @@ int8_t GetNextTurnover( const struct RingsState rings, const struct Turnovers_t } } - -inline +static inline void CalculatePermutationMap3Rotors( PermutationMap_t* const restrict map, struct RingsState rings, const Key* const restrict key ) { int k; for( k = 0; k < 26; k++ ) { @@ -84,7 +83,7 @@ void CalculatePermutationMap3Rotors( PermutationMap_t* const restrict map, struc FixPermutationMapTail( map ); } -inline +static inline void CalculatePermutationMap4Rotors( PermutationMap_t* const restrict map, struct RingsState rings, const Key* const restrict key ) { int k; for( k = 0; k < 26; k++ ) { diff --git a/libEnigma/include/config/types.h b/libEnigma/include/config/types.h index db7f5a2..2eb61bf 100644 --- a/libEnigma/include/config/types.h +++ b/libEnigma/include/config/types.h @@ -20,6 +20,7 @@ l: length of element, coded as: s: single 32 int, float double word d: double 64 long long, double quad word t: tetra 128 __i128, long double + p: pointer 32 or 64 bits t: type i: integer (default) f: floating point @@ -29,6 +30,22 @@ I extend type to allow: as sometimes it is convenient ie. unsigned right shuffles, etc. * * * * * * * * * * */ + /* + * Target dependent size vectors + */ +typedef intptr_t v4pis __attribute__ ((vector_size(4*sizeof( intptr_t )))) ; +typedef uintptr_t v4piu __attribute__ ((vector_size(4*sizeof( intptr_t )))) ; + + /* + * 16 bit vectors + */ +typedef signed char v2qs __attribute__ ((vector_size(2))); + + /* + * 32 bit vectors + */ +typedef signed char v4qs __attribute__ ((vector_size(4))); + /* * 128 bit vectors */ diff --git a/libEnigma/include/error.h b/libEnigma/include/error.h index 6c067dc..9605d4e 100644 --- a/libEnigma/include/error.h +++ b/libEnigma/include/error.h @@ -1,5 +1,4 @@ -#ifndef ERROR_H -#define ERROR_H +#pragma once #include #include "global.h" @@ -36,8 +35,6 @@ void exit_d( int errorCode UNUSED ){ exit( errorCode ); #endif } -#endif - /* * This file is part of enigma-suite-0.76, which is distributed under the terms diff --git a/libEnigma/include/global.h b/libEnigma/include/global.h index d6ed0be..8effdb6 100644 --- a/libEnigma/include/global.h +++ b/libEnigma/include/global.h @@ -45,6 +45,12 @@ enum { SW_ONSTART, SW_OTHER, SW_ALL, SW_NONE, SINGLE_KEY }; #define UNUSED __attribute__ ((unused)) #define NO_INLINE __attribute__ ((noinline)) +#if __GNUC__ >= 7 +# define FALLTHROUGH() __attribute__((fallthrough)) +#else +# define FALLTHROUGH() +#endif + #define UNREACHABLE() __builtin_unreachable() diff --git a/libEnigma/include/key.h b/libEnigma/include/key.h index e1fc831..8e5f13c 100644 --- a/libEnigma/include/key.h +++ b/libEnigma/include/key.h @@ -17,7 +17,7 @@ typedef union _PermutationMap_t text_t letters[32]; } PermutationMap_t; -inline +static inline void FixPermutationMapTail(PermutationMap_t* mapping){ int k = 26; for(; k < 32; k++) @@ -27,7 +27,7 @@ void FixPermutationMapTail(PermutationMap_t* mapping){ } __attribute__((optimize("unroll-loops"))) -inline +static inline void Fill0To25(text_t array[26]) { int32_t* arrayInt = (int32_t*)array; diff --git a/libEnigma/include/score.h b/libEnigma/include/score.h index 1d7696e..054a2ed 100644 --- a/libEnigma/include/score.h +++ b/libEnigma/include/score.h @@ -1,5 +1,4 @@ -#ifndef SCORE_H -#define SCORE_H +#pragma once #include #include @@ -80,8 +79,6 @@ void DecodeScoredMessagePartStandard(const Key* const restrict key, int len, uni bool GetDifferences( union ScoringDecodedMessage* restrict reference, union ScoringDecodedMessage* restrict tested, char* restrict output, int len ); -#endif - /* * This file is part of enigma-suite-0.76, which is distributed under the terms * of the General Public License (GPL), version 2. See doc/COPYING for details. diff --git a/libEnigma/include/scoreBasic.h b/libEnigma/include/scoreBasic.h index e33d0c7..952343c 100644 --- a/libEnigma/include/scoreBasic.h +++ b/libEnigma/include/scoreBasic.h @@ -1,9 +1,8 @@ -#ifndef ENIGMA_SCORE_OPTIMIZED_HEADER_INCLUDED -#define ENIGMA_SCORE_OPTIMIZED_HEADER_INCLUDED +#pragma once + +#include "score.h" /** \brief Uses optimized version of original code. Gives minor performance improvement. */ extern enigma_score_function_t enigmaScoreBasic; extern union ScoringDecodedMessage decodedMsgPartBasic; - -#endif diff --git a/libEnigma/include/scoreNoInterleave.h b/libEnigma/include/scoreNoInterleave.h index fa25c63..e403a5b 100644 --- a/libEnigma/include/scoreNoInterleave.h +++ b/libEnigma/include/scoreNoInterleave.h @@ -1,9 +1,6 @@ -#ifndef SCORE_OPTIMIZED_NO_INTERLEAVE_HEADER_INCLUDED -#define SCORE_OPTIMIZED_NO_INTERLEAVE_HEADER_INCLUDED +#pragma once #include "score.h" extern enigma_score_function_t enigmaScoreOptNoInterleave; extern union ScoringDecodedMessage decodedMsgPartNoInterleave; - -#endif diff --git a/libEnigma/include/scoreNoInterleave_inlines.h b/libEnigma/include/scoreNoInterleave_inlines.h new file mode 100644 index 0000000..1c72ff8 --- /dev/null +++ b/libEnigma/include/scoreNoInterleave_inlines.h @@ -0,0 +1,49 @@ +#pragma once +#include +#include "cipher.h" +#include "dict.h" +#include "key.h" + +__attribute__ (( optimize( "sched-stalled-insns=0,sched-stalled-insns-dep=16,unroll-loops" ) )) +static inline +void DecodeScoredMessagePartNoInterleave( const Key* const restrict key, scoreLength_t len, union ScoringDecodedMessage* output ){ + const PermutationMap_t* const restrict stbrett = &key->stbrett; + int i; + for( i = 0; i < len - 15; i += 16 ) { + output->plain[ 0 + i] = decode( 0, i, stbrett ); + output->plain[ 1 + i] = decode( 1, i, stbrett ); + output->plain[ 2 + i] = decode( 2, i, stbrett ); + output->plain[ 3 + i] = decode( 3, i, stbrett ); + output->plain[ 4 + i] = decode( 4, i, stbrett ); + output->plain[ 5 + i] = decode( 5, i, stbrett ); + output->plain[ 6 + i] = decode( 6, i, stbrett ); + output->plain[ 7 + i] = decode( 7, i, stbrett ); + output->plain[ 8 + i] = decode( 8, i, stbrett ); + output->plain[ 9 + i] = decode( 9, i, stbrett ); + output->plain[10 + i] = decode( 10, i, stbrett ); + output->plain[11 + i] = decode( 11, i, stbrett ); + output->plain[12 + i] = decode( 12, i, stbrett ); + output->plain[13 + i] = decode( 13, i, stbrett ); + output->plain[14 + i] = decode( 14, i, stbrett ); + output->plain[15 + i] = decode( 15, i, stbrett ); + } + for ( ; i < len - 3; i += 4 ) { + output->plain[ 0 + i] = decode( 0, i, stbrett ); + output->plain[ 1 + i] = decode( 1, i, stbrett ); + output->plain[ 2 + i] = decode( 2, i, stbrett ); + output->plain[ 3 + i] = decode( 3, i, stbrett ); + } + for ( ; i < len; i++ ) { + output->plain[i] = decode( 0, i, stbrett ); + } +} + +__attribute__ (( optimize( "sched-stalled-insns=0,sched-stalled-insns-dep=16,unroll-loops" ) )) +static inline +void DecodeScoredMessagePartNoInterleaveSimple( const Key* const restrict key, scoreLength_t len, union ScoringDecodedMessage* output ){ + const PermutationMap_t* const restrict stbrett = &key->stbrett; + int i; + for ( i = 0 ; i < len; i++ ) { + output->plain[i] = decode( 0, i, stbrett ); + } +} diff --git a/libEnigma/include/scoreSimple.h b/libEnigma/include/scoreSimple.h index f20ea60..5f21bc8 100644 --- a/libEnigma/include/scoreSimple.h +++ b/libEnigma/include/scoreSimple.h @@ -1,10 +1,7 @@ -#ifndef SCORE_SIMPLE_H -#define SCORE_SIMPLE_H +#pragma once #include "score.h" /** \brief Uses original code, but no unrolled version. */ extern enigma_score_function_t enigmaScoreSimple; - -#endif // SCORE_SIMPLE_H diff --git a/libEnigma/include/score_inlines.h b/libEnigma/include/score_inlines.h index 3553da7..c8e6a6f 100644 --- a/libEnigma/include/score_inlines.h +++ b/libEnigma/include/score_inlines.h @@ -1,10 +1,10 @@ -#ifndef SCORE_INLINES_HEADER_INCLUDED -#define SCORE_INLINES_HEADER_INCLUDED +#pragma once +#include "dict.h" #include "score.h" __attribute__ ((optimize("unroll-loops"))) -inline +static inline int ComputeTriscoreFromDecodedMsg( union ScoringDecodedMessage* msg, scoreLength_t len ){ int x, score = 0; for( x = 0; x < len - 2; ++x ) { @@ -14,7 +14,7 @@ int ComputeTriscoreFromDecodedMsg( union ScoringDecodedMessage* msg, scoreLength } __attribute__ ((optimize("unroll-loops"))) -inline +static inline int ComputeBiscoreFromDecodedMsg( union ScoringDecodedMessage* msg, scoreLength_t len ) { int score = 0, x; for( x = 0; x < len - 1; ++x ) { @@ -24,7 +24,7 @@ int ComputeBiscoreFromDecodedMsg( union ScoringDecodedMessage* msg, scoreLength_ } __attribute__ ((optimize("unroll-loops"))) -inline +static inline int ComputeUniscoreFromDecodedMsg( union ScoringDecodedMessage* msg, scoreLength_t len ){ int score = 0, i; for( i = 0; i < len; i++ ) { @@ -36,7 +36,7 @@ int ComputeUniscoreFromDecodedMsg( union ScoringDecodedMessage* msg, scoreLength #include "config/types.h" __attribute__ ((optimize("unroll-loops"))) __attribute__ ((optimize("unroll-loops,sched-stalled-insns=0,sched-stalled-insns-dep=16"))) -inline +static inline uint16_t ComputeIcscoreFromDecodedMsg( union ScoringDecodedMessage* msg, scoreLength_t len ){ uint8_t f[32] = {0}; int i; @@ -51,5 +51,3 @@ uint16_t ComputeIcscoreFromDecodedMsg( union ScoringDecodedMessage* msg, scoreLe return sum; } - -#endif diff --git a/libEnigma/include/stecker.h b/libEnigma/include/stecker.h index 26dfb57..f9e40c0 100644 --- a/libEnigma/include/stecker.h +++ b/libEnigma/include/stecker.h @@ -14,7 +14,7 @@ void set_to_ct_freq(text_t var[], int len); * \param k int Letter to swap with i * \return void */ -inline +static inline void SwapStbrett(Key* const key, int i, int k) { text_t store = key->stbrett.letters[i]; key->stbrett.letters[i] = key->stbrett.letters[k]; diff --git a/libEnigma/include/x86/cipherAvx2_inlines.h b/libEnigma/include/x86/cipherAvx2_inlines.h index 0023144..cda3f32 100644 --- a/libEnigma/include/x86/cipherAvx2_inlines.h +++ b/libEnigma/include/x86/cipherAvx2_inlines.h @@ -1,7 +1,9 @@ -#ifndef CIPHER_AVX2_INLINES_H_INCLUDED -#define CIPHER_AVX2_INLINES_H_INCLUDED +#pragma once -inline +#include "error.h" +#include "cipherAvx2.h" + +static inline v32qi PermuteV32qi(const PermutationMap_t* map, v32qi vec ){ /* Following line is needed to behave like __builtin_shuffle for all inputs and still being faster, but our data is always in interval [0,25] = [0,0x1A). */ @@ -15,7 +17,7 @@ v32qi PermuteV32qi(const PermutationMap_t* map, v32qi vec ){ return ret1 | ret2; } -inline +static inline v32qi DecodeBiteForwardCommonAvx2( v32qi bite, v32qi rRingOffset, const Key* const restrict key ) { // stbrett forward bite = PermuteV32qi ( &key->stbrett, bite ); @@ -26,7 +28,7 @@ v32qi DecodeBiteForwardCommonAvx2( v32qi bite, v32qi rRingOffset, const Key* con return bite; } -inline +static inline v32qi DecodeBiteMaskedPartAvx2( v32qi predecodedBite, int lookupNumber ) { v32qi bite = predecodedBite; // m+l rings and ukw @@ -35,7 +37,7 @@ v32qi DecodeBiteMaskedPartAvx2( v32qi predecodedBite, int lookupNumber ) { return bite; } -inline +static inline v32qi DecodeBiteBackwardCommonAvx2( v32qi bite, v32qi rRingOffset, const Key* const restrict key ) { // right ring backwards bite = AddMod26_v32qi( bite, rRingOffset ); @@ -46,9 +48,64 @@ v32qi DecodeBiteBackwardCommonAvx2( v32qi bite, v32qi rRingOffset, const Key* c return bite; } +__attribute__ ((optimize("unroll-loops,sched-stalled-insns=0,sched-stalled-insns-dep=16"))) +static inline +void DecodeScoredMessagePartAvx2( const Key* const restrict key, int len, union ScoringDecodedMessage* output ) +{ + uint16_t messageBite = 0; + uint_least16_t lookupNumber = 0; + v32qi currentRRingOffset = PathLookupAvx2.firstRRingOffset; + while( messageBite < ( len + 31 ) / 32 ) + { + /* Worst case: + * P0123456789ABCDEFGHIJKLMNOP01234 R-ring position (turnovers on 12 & 25, coded C & P) + * 0123456789ABCDEF0123456789ABCDEF characters in bite + * ||| | | + * ||| | + + * ||| +- turnover on second notch of R ring + * ||+- turnover caused by M-ring (turning L- & M- rings). + * |+-- turnover setting M-ring to turnover position + * +--- last character from previous bite + * + * In the worst case there are 5 lookups per bite. + */ + uint_least16_t lookupsToNextBite = PathLookupAvx2.nextBite[messageBite] - lookupNumber; + v32qi cBite = {0}; + lookupNumber += lookupsToNextBite; + v32qi currentBite = ciphertext.vector32[messageBite]; + v32qi predecoded = DecodeBiteForwardCommonAvx2( currentBite, currentRRingOffset, key ); + + switch( lookupsToNextBite ) { + case 5: + cBite = DecodeBiteMaskedPartAvx2( predecoded, lookupNumber - 5 ); + FALLTHROUGH(); + case 4: + cBite |= DecodeBiteMaskedPartAvx2( predecoded, lookupNumber - 4 ); + FALLTHROUGH(); + case 3: + cBite |= DecodeBiteMaskedPartAvx2( predecoded, lookupNumber - 3 ); + FALLTHROUGH(); + case 2: + cBite |= DecodeBiteMaskedPartAvx2( predecoded, lookupNumber - 2 ); + FALLTHROUGH(); + case 1: + cBite |= DecodeBiteMaskedPartAvx2( predecoded, lookupNumber - 1 ); + break; + default: + exit_d(5); + UNREACHABLE(); + } + cBite = DecodeBiteBackwardCommonAvx2( cBite, currentRRingOffset, key ); + // store whole decoded bite + output -> vector32[messageBite] = cBite; + messageBite++; + currentRRingOffset = AddMod26_v32qi_int8( currentRRingOffset, 32 % 26 ); + } +} + __attribute__ ((optimize("unroll-loops"))) __attribute__ ((optimize("unroll-loops,sched-stalled-insns=0,sched-stalled-insns-dep=16"))) -inline +static inline uint16_t ComputeIcscoreFromDecodedMsgAvx2( union ScoringDecodedMessage* msg, scoreLength_t len ){ ALIGNED_32( uint8_t f[32] ) = {0}; int i; @@ -83,6 +140,3 @@ uint16_t ComputeIcscoreFromDecodedMsgAvx2( union ScoringDecodedMessage* msg, sco uint16_t sum = 256 *( high[0] + high[4] + high[8] + high[12] ) + low[0] + low[4] + low[8] + low[12]; return sum; } - - -#endif diff --git a/libEnigma/include/x86/cipherSsse3_inlines.h b/libEnigma/include/x86/cipherSsse3_inlines.h index 4781ee4..b4441f5 100644 --- a/libEnigma/include/x86/cipherSsse3_inlines.h +++ b/libEnigma/include/x86/cipherSsse3_inlines.h @@ -1,12 +1,10 @@ -#ifndef CIPHER_SSSE3_INLINES_H_INCLUDED -#define CIPHER_SSSE3_INLINES_H_INCLUDED +#pragma once #include "error.h" #include "dict.h" #include "cipherSsse3.h" - -inline +static inline v16qi PermuteV16qi(const PermutationMap_t* map, v16qi vec ){ /* Following line is needed to behave like __builtin_shuffle for all inputs and still being faster, but our data is always in interval [0,25] = [0,0x1A). */ @@ -18,7 +16,7 @@ v16qi PermuteV16qi(const PermutationMap_t* map, v16qi vec ){ } -inline +static inline v16qi DecodeBiteForwardCommonSsse3( v16qi bite, v16qi rRingOffset, const Key* const restrict key ){ // stbrett forward bite = PermuteV16qi ( &key->stbrett, bite ); @@ -29,7 +27,7 @@ v16qi DecodeBiteForwardCommonSsse3( v16qi bite, v16qi rRingOffset, const Key* c return bite; } -inline +static inline v16qi DecodeBiteMaskedPartSsse3( v16qi predecodedBite, int lookupNumber ) { v16qi bite = predecodedBite; // m+l rings and ukw @@ -38,7 +36,7 @@ v16qi DecodeBiteMaskedPartSsse3( v16qi predecodedBite, int lookupNumber ) { return bite; } -inline +static inline v16qi DecodeBiteBackwardCommonSsse3( v16qi bite, v16qi rRingOffset, const Key* const restrict key ) { // right ring backwards bite = AddMod26_v16qi( bite, rRingOffset ); @@ -50,7 +48,7 @@ v16qi DecodeBiteBackwardCommonSsse3( v16qi bite, v16qi rRingOffset, const Key* } __attribute__ ((optimize("unroll-loops,sched-stalled-insns=0,sched-stalled-insns-dep=16"))) -inline +static inline void DecodeScoredMessagePartSsse3( const Key* const restrict key, int len, union ScoringDecodedMessage* output ) { uint16_t messageBite = 0; @@ -78,10 +76,13 @@ void DecodeScoredMessagePartSsse3( const Key* const restrict key, int len, union switch( lookupsToNextBite ) { case 4: cBite = DecodeBiteMaskedPartSsse3( predecoded, lookupNumber - 4 ); + FALLTHROUGH(); case 3: cBite |= DecodeBiteMaskedPartSsse3( predecoded, lookupNumber - 3 ); + FALLTHROUGH(); case 2: cBite |= DecodeBiteMaskedPartSsse3( predecoded, lookupNumber - 2 ); + FALLTHROUGH(); case 1: cBite |= DecodeBiteMaskedPartSsse3( predecoded, lookupNumber - 1 ); break; @@ -99,7 +100,7 @@ void DecodeScoredMessagePartSsse3( const Key* const restrict key, int len, union __attribute__ ((optimize("unroll-loops"))) __attribute__ ((optimize("unroll-loops,sched-stalled-insns=0,sched-stalled-insns-dep=16"))) -inline +static inline uint16_t ComputeIcscoreFromDecodedMsgSsse3( union ScoringDecodedMessage* msg, scoreLength_t len ){ uint8_t ALIGNED_32( f[32] ) = {0}; int i; @@ -140,32 +141,27 @@ uint16_t ComputeIcscoreFromDecodedMsgSsse3( union ScoringDecodedMessage* msg, sc return sum; } -inline +static inline void Unpack_v16qi( v16qi in, v8hi* lo, v8hi *hi ){ v16qi zero = { 0 }; *lo = (v8hi) __builtin_ia32_punpcklbw128 ( in, zero ); *hi = (v8hi) __builtin_ia32_punpckhbw128 ( in, zero ); } -inline +static inline void Unpack_v8hi( v8hi in, v4si* lo, v4si* hi ){ v8hi zero = { 0 }; *lo = (v4si) __builtin_ia32_punpcklwd128( in, zero ); *hi = (v4si) __builtin_ia32_punpckhwd128( in, zero ); } -inline +static inline v16qi MOVDQU( v16qi* p ){ - v16qi ret; - asm( "MOVDQU %1, %0": - "=x" (ret) : - "m" (*p) - ); - return ret; + return __builtin_ia32_loaddqu( (char*) p ); } __attribute__ ((optimize("unroll-loops"))) -inline +static inline int ComputeTriscoreFromDecodedMsgSse2( union ScoringDecodedMessage* msg, scoreLength_t len ){ int score = 0; int i; @@ -201,7 +197,7 @@ int ComputeTriscoreFromDecodedMsgSse2( union ScoringDecodedMessage* msg, scoreLe __attribute__ ((optimize("unroll-loops"))) -inline +static inline int ComputeBiscoreFromDecodedMsgSse2( union ScoringDecodedMessage* msg, scoreLength_t len ){ int score = 0; int i; @@ -229,6 +225,3 @@ int ComputeBiscoreFromDecodedMsgSse2( union ScoringDecodedMessage* msg, scoreLen } return score; } - - -#endif diff --git a/libEnigma/src/ModMath.c b/libEnigma/src/ModMath.c deleted file mode 100644 index ad6d0e7..0000000 --- a/libEnigma/src/ModMath.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "ModMath.h" - - -extern inline -int8_t SubMod26( int8_t a, int8_t b ); - -extern inline -int8_t AddMod26( int8_t a, int8_t b ); - -extern inline -void IncrementMod( int8_t* number, int8_t modulo ); - -extern inline -v16qi AddMod26_v16qi_int8( v16qi a, int8_t b ); -extern inline -v16qi AddMod26_v16qi( v16qi a, v16qi b ); -extern inline -v16qi SubMod26_v16qi_int8( v16qi a, int8_t b ); -extern inline -v16qi SubMod26_v16qi( v16qi a, v16qi b ); - -extern inline -v32qi AddMod26_v32qi_int8( v32qi a, int8_t b ); -extern inline -v32qi SubMod26_v32qi_int8( v32qi a, int8_t b ); -extern inline -v32qi AddMod26_v32qi( v32qi a, v32qi b ); -extern inline -v32qi SubMod26_v32qi( v32qi a, v32qi b ); diff --git a/libEnigma/src/cipher.c b/libEnigma/src/cipher.c index dd6ba54..7fbdf90 100644 --- a/libEnigma/src/cipher.c +++ b/libEnigma/src/cipher.c @@ -16,9 +16,6 @@ void init_path_lookup_H_M3(const Key *key, int len); void init_path_lookup_ALL(const Key *key, int len); void enigma_prepare_decoder_lookups(const Key* key, int len); -extern inline -text_t decode(size_t offset,size_t index, const PermutationMap_t* const stbrett); - /* Eintrittswalze */ text_t etw[52] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25, @@ -166,7 +163,6 @@ void enigma_prepare_decoder_lookups(const Key* key, int len) } } -__attribute__(( unused )) static void CipherInit(enigma_cpu_flags_t cpu, enum ModelType_t machine_type, enigma_prepare_decoder_lookup_function_pt* cf ) { enigma_cipher_function_t* fun = &enigma_cipher_decoder_lookup; @@ -190,71 +186,6 @@ void CipherInit(enigma_cpu_flags_t cpu, enum ModelType_t machine_type, enigma_pr } } -__attribute__(( unused )) -static -void CipherInitScoreTesting(enigma_cpu_flags_t cpu, enum ModelType_t machine_type, enigma_prepare_decoder_lookup_function_pt* cf ) { - enigma_cipher_function_t* fs[2] = { &enigma_cipher_decoder_lookup }; - if ( cpu & ( enigma_cpu_ssse3 | enigma_cpu_avx ) ) { - fs[1] = &enigma_cipher_decoder_lookup_ssse3; - } - if ( cpu & enigma_cpu_avx2 ) { - fs[1] = &enigma_cipher_DecoderLookupAvx2; - } - int j; - for ( j = 0 ; j < 2; j++ ) { - switch( machine_type ) { - case EnigmaModel_H: - case EnigmaModel_M3: - enigma_cipher_decoder_lookups_list[j] = fs[j]->prepare_decoder_lookup_M_H3; - break; - case EnigmaModel_M4: - enigma_cipher_decoder_lookups_list[j] = fs[j]->prepare_decoder_lookup_ALL; - break; - case EnigmaModel_Error: - *cf = 0; - return; - } - } - *cf = enigma_prepare_decoder_lookups; -} - -__attribute__ (( unused )) -static -void CipherInitMulti(enigma_cpu_flags_t cpu, enum ModelType_t machine_type, enigma_prepare_decoder_lookup_function_pt* cf) -{ - enigma_cipher_function_t* fs[4]; - int i = 0; - - // FIXME: It is not very smart to always call all of them. - fs[i++] = &enigma_cipher_decoder_lookup; - if ( cpu & ( enigma_cpu_ssse3 | enigma_cpu_avx ) ) { - fs[i++] = &enigma_cipher_decoder_lookup_ssse3; - } - if ( cpu & enigma_cpu_avx2 ) { - fs[i++] = &enigma_cipher_DecoderLookupAvx2; - } - - int j=0; - for (; jprepare_decoder_lookup_M_H3; - break; - case EnigmaModel_M4: - enigma_cipher_decoder_lookups_list[j] = fs[j]->prepare_decoder_lookup_ALL; - break; - case EnigmaModel_Error: - *cf = 0; - return; - } - } - - *cf = enigma_prepare_decoder_lookups; -} - void enigma_cipher_init(enigma_cpu_flags_t cpu, enum ModelType_t machine_type, enigma_prepare_decoder_lookup_function_pt* cf){ CipherInit( cpu, machine_type, cf ); } @@ -589,15 +520,6 @@ double dgetic_ALL(const Key *key, int len) } -extern inline void Step1( int8_t* ringOffset ); - -extern inline void CalculatePermutationMap3Rotors( PermutationMap_t* const restrict map, struct RingsState rings, const Key* const restrict key ); -extern inline void CalculatePermutationMap4Rotors( PermutationMap_t* const restrict map, struct RingsState rings, const Key* const restrict key ); - -extern inline void CopyRRing2Lookup( const Key* const restrict key, PermutationMap_t rRings[2] ); -extern inline void StepAllRings( struct RingsState* const restrict rings, const struct Turnovers_t turns ); -extern inline int8_t GetNextTurnover( const struct RingsState rings, const struct Turnovers_t turns ); - /* * This file is part of enigma-suite-0.76, which is distributed under the terms * of the General Public License (GPL), version 2. See doc/COPYING for details. diff --git a/libEnigma/src/key.c b/libEnigma/src/key.c index e9e829c..d3bcc9b 100644 --- a/libEnigma/src/key.c +++ b/libEnigma/src/key.c @@ -101,12 +101,6 @@ int keycmp(const Key *k1, const Key *k2) } -extern inline -void FixPermutationMapTail(PermutationMap_t* mapping); - -extern inline -void Fill0To25(text_t array[static 26]); - /* * This file is part of enigma-suite-0.76, which is distributed under the terms * of the General Public License (GPL), version 2. See doc/COPYING for details. diff --git a/libEnigma/src/score.c b/libEnigma/src/score.c index a5bcb4e..dcfa387 100644 --- a/libEnigma/src/score.c +++ b/libEnigma/src/score.c @@ -20,13 +20,6 @@ /* declaration of internal functions */ void enigma_score_function_copy(enigma_score_function_t* restrict to, const enigma_score_function_t* restrict from); -inline extern -int ComputeUniscoreFromDecodedMsg( union ScoringDecodedMessage* msg, scoreLength_t len ); -inline extern -int ComputeBiscoreFromDecodedMsg( union ScoringDecodedMessage* msg, scoreLength_t len ); -inline extern -int ComputeTriscoreFromDecodedMsg( union ScoringDecodedMessage* msg, scoreLength_t len ); - inline void enigma_score_function_copy(enigma_score_function_t* restrict to, const enigma_score_function_t* restrict prototype) { diff --git a/libEnigma/src/scoreBasic.c b/libEnigma/src/scoreBasic.c index f1cf83a..9e99289 100644 --- a/libEnigma/src/scoreBasic.c +++ b/libEnigma/src/scoreBasic.c @@ -26,7 +26,6 @@ __attribute__ ((optimize("sched-stalled-insns=0,sched-stalled-insns-dep=16,unrol static uint16_t icscoreBasic( const Key* const restrict key, scoreLength_t len ) { int f[26] = {0}; - text_t c1; int i; if (len < 2) @@ -35,69 +34,40 @@ static uint16_t icscoreBasic( const Key* const restrict key, scoreLength_t len ) const PermutationMap_t* stbrett = &key->stbrett; for (i = 0; i < len-15; i += 16) { - c1 = decode(0,i,stbrett); - f[c1]++; - - c1 = decode(1,i,stbrett); - f[c1]++; - - c1 = decode(2,i,stbrett); - f[c1]++; - - c1 = decode(3,i,stbrett); - f[c1]++; - - c1 = decode(4,i,stbrett); - f[c1]++; - - c1 = decode(5,i,stbrett); - f[c1]++; - - c1 = decode(6,i,stbrett); - f[c1]++; - - c1 = decode(7,i,stbrett); - f[c1]++; - - c1 = decode(8,i,stbrett); - f[c1]++; - - c1 = decode(9,i,stbrett); - f[c1]++; - - c1 = decode(10,i,stbrett); - f[c1]++; - - c1 = decode(11,i,stbrett); - f[c1]++; - - c1 = decode(12,i,stbrett); - f[c1]++; - - c1 = decode(13,i,stbrett); - f[c1]++; - - c1 = decode(14,i,stbrett); - f[c1]++; - - c1 = decode(15,i,stbrett); - f[c1]++; + v4pis c; + c = decode4(0,i,stbrett); + f[c[0]]++; + f[c[1]]++; + f[c[2]]++; + f[c[3]]++; + + c = decode4(4,i,stbrett); + f[c[0]]++; + f[c[1]]++; + f[c[2]]++; + f[c[3]]++; + + c = decode4(8,i,stbrett); + f[c[0]]++; + f[c[1]]++; + f[c[2]]++; + f[c[3]]++; + + c = decode4(12,i,stbrett); + f[c[0]]++; + f[c[1]]++; + f[c[2]]++; + f[c[3]]++; } for (; i < len-3; i += 4) { - c1 = decode(0,i,stbrett); - f[c1]++; - - c1 = decode(1,i,stbrett); - f[c1]++; - - c1 = decode(2,i,stbrett); - f[c1]++; - - c1 = decode(3,i,stbrett); - f[c1]++; + v4pis c = decode4(0,i,stbrett); + f[c[0]]++; + f[c[1]]++; + f[c[2]]++; + f[c[3]]++; } for (; i < len; i++) { - c1 = decode(0,i,stbrett); + text_t c1 = decode(0,i,stbrett); f[c1]++; } @@ -115,263 +85,221 @@ static uint16_t icscoreBasic( const Key* const restrict key, scoreLength_t len ) return (S0+S1) + (S2+S3); } +#define UNISCORE_ADD(S,A)\ + asm( "add %1, %0": "+q"( (S) ): "m"( unidict[(A)] ) ) static int uniscoreBasic( const Key* key, scoreLength_t len ) { int i; - text_t c; int s; const PermutationMap_t* stbrett = &key->stbrett; s = 0; for (i = 0; i < len-15; i += 16) { - c = decode(0,i,stbrett); - s += unidict[c]; - - c = decode(1,i,stbrett); - s += unidict[c]; - - c = decode(2,i,stbrett); - s += unidict[c]; - - c = decode(3,i,stbrett); - s += unidict[c]; - - c = decode(4,i,stbrett); - s += unidict[c]; - - c = decode(5,i,stbrett); - s += unidict[c]; - - c = decode(6,i,stbrett); - s += unidict[c]; - - c = decode(7,i,stbrett); - s += unidict[c]; - - c = decode(8,i,stbrett); - s += unidict[c]; - - c = decode(9,i,stbrett); - s += unidict[c]; - - c = decode(10,i,stbrett); - s += unidict[c]; - - c = decode(11,i,stbrett); - s += unidict[c]; - - c = decode(12,i,stbrett); - s += unidict[c]; - - c = decode(13,i,stbrett); - s += unidict[c]; - - c = decode(14,i,stbrett); - s += unidict[c]; - - c = decode(15,i,stbrett); - s += unidict[c]; + v4pis c; + c = decode4( 0, i, stbrett ); + UNISCORE_ADD( s, c[0] ); + UNISCORE_ADD( s, c[1] ); + UNISCORE_ADD( s, c[2] ); + UNISCORE_ADD( s, c[3] ); + + c = decode4( 4, i, stbrett ); + UNISCORE_ADD( s, c[0] ); + UNISCORE_ADD( s, c[1] ); + UNISCORE_ADD( s, c[2] ); + UNISCORE_ADD( s, c[3] ); + + c = decode4( 8, i, stbrett ); + UNISCORE_ADD( s, c[0] ); + UNISCORE_ADD( s, c[1] ); + UNISCORE_ADD( s, c[2] ); + UNISCORE_ADD( s, c[3] ); + + c = decode4( 12, i, stbrett ); + UNISCORE_ADD( s, c[0] ); + UNISCORE_ADD( s, c[1] ); + UNISCORE_ADD( s, c[2] ); + UNISCORE_ADD( s, c[3] ); } for (; i < len-3; i += 4) { - c = decode(0,i,stbrett); - s += unidict[c]; - - c = decode(1,i,stbrett); - s += unidict[c]; - - c = decode(2,i,stbrett); - s += unidict[c]; - - c = decode(3,i,stbrett); - s += unidict[c]; + v4pis c; + c = decode4( 0, i, stbrett ); + UNISCORE_ADD( s, c[0] ); + UNISCORE_ADD( s, c[1] ); + UNISCORE_ADD( s, c[2] ); + UNISCORE_ADD( s, c[3] ); } for (; i < len; i++) { - c = decode(0,i,stbrett); - s += unidict[c]; + text_t c = decode(0,i,stbrett); + UNISCORE_ADD( s, c ); } return s; - } -__attribute__ ((optimize("sched-stalled-insns=0,sched-stalled-insns-dep=16,unroll-loops"))) +#define BISCORE_ADD(S,A,B)\ + asm( "add %1, %0": "+q"( (S) ): "m"( bidict[(A)][(B)] ) ) +__attribute__ ((optimize("sched-stalled-insns=0" + ",sched-stalled-insns-dep=16"))) int biscoreBasic( const Key* const restrict key, scoreLength_t len ) { - int i; - text_t c1, c2; - int s = 0; - - const PermutationMap_t* const stbrett = &key->stbrett; - - c1 = decode(0,0,stbrett); - - for (i = 1; i < len-15; i += 16) { - c2 = decode(0,i,stbrett); - s += bidict[c1][c2]; - - c1 = decode(1,i,stbrett); - s += bidict[c2][c1]; - - c2 = decode(2,i,stbrett); - s += bidict[c1][c2]; - - c1 = decode(3,i,stbrett); - s += bidict[c2][c1]; - - c2 = decode(4,i,stbrett); - s += bidict[c1][c2]; - - c1 = decode(5,i,stbrett); - s += bidict[c2][c1]; - - c2 = decode(6,i,stbrett); - s += bidict[c1][c2]; - - c1 = decode(7,i,stbrett); - s += bidict[c2][c1]; - - c2 = decode(8,i,stbrett); - s += bidict[c1][c2]; - - c1 = decode(9,i,stbrett); - s += bidict[c2][c1]; - - c2 = decode(10,i,stbrett); - s += bidict[c1][c2]; - - c1 = decode(11,i,stbrett); - s += bidict[c2][c1]; - - c2 = decode(12,i,stbrett); - s += bidict[c1][c2]; - - c1 = decode(13,i,stbrett); - s += bidict[c2][c1]; - - c2 = decode(14,i,stbrett); - s += bidict[c1][c2]; - - c1 = decode(15,i,stbrett); - s += bidict[c2][c1]; - } - for (; i < len-3; i += 4) { - c2 = decode(0,i,stbrett); - s += bidict[c1][c2]; - - c1 = decode(1,i,stbrett); - s += bidict[c2][c1]; - - c2 = decode(2,i,stbrett); - s += bidict[c1][c2]; - - c1 = decode(3,i,stbrett); - s += bidict[c2][c1]; - } - for (; i < len; i++) { - c2 = decode(0,i,stbrett); - s += bidict[c1][c2]; - - c1 = c2; - } - - return s; - + const PermutationMap_t* const stbrett = &key->stbrett; + int s = 0; + + size_t c1 = decode(0,0,stbrett); + + int i = 1; + for( ; i < len - 15; i += 16 ) { + v4pis d; + size_t c2; + d = decode4( 0, i, stbrett ); + c2 = d[0]; + BISCORE_ADD( s , c1, c2 ); + c1 = d[1]; + BISCORE_ADD( s , c2, c1 ); + c2 = d[2]; + BISCORE_ADD( s , c1, c2 ); + c1 = d[3]; + BISCORE_ADD( s , c2, c1 ); + + d = decode4( 4, i, stbrett ); + c2 = d[0]; + BISCORE_ADD( s , c1, c2 ); + c1 = d[1]; + BISCORE_ADD( s , c2, c1 ); + c2 = d[2]; + BISCORE_ADD( s , c1, c2 ); + c1 = d[3]; + BISCORE_ADD( s , c2, c1 ); + + d = decode4( 8, i, stbrett ); + c2 = d[0]; + BISCORE_ADD( s , c1, c2 ); + c1 = d[1]; + BISCORE_ADD( s , c2, c1 ); + c2 = d[2]; + BISCORE_ADD( s , c1, c2 ); + c1 = d[3]; + BISCORE_ADD( s , c2, c1 ); + + d = decode4( 12, i, stbrett ); + c2 = d[0]; + BISCORE_ADD( s , c1, c2 ); + c1 = d[1]; + BISCORE_ADD( s , c2, c1 ); + c2 = d[2]; + BISCORE_ADD( s , c1, c2 ); + c1 = d[3]; + BISCORE_ADD( s , c2, c1 ); + } + for( ; i < len - 3; i += 4 ) { + v4pis d = decode4( 0, i, stbrett ); + size_t c2 = d[0]; + BISCORE_ADD( s , c1, c2 ); + c1 = d[1]; + BISCORE_ADD( s , c2, c1 ); + c2 = d[2]; + BISCORE_ADD( s , c1, c2 ); + c1 = d[3]; + BISCORE_ADD( s , c2, c1 ); + } + for( ; i < len; i++ ) { + size_t c2 = decode( 0, i, stbrett ); + BISCORE_ADD( s , c1, c2 ); + c1 = c2; + } + return s; } -__attribute__ ((optimize("sched-stalled-insns=0,sched-stalled-insns-dep=16,unroll-loops"))) +#define TRISCORE_ADD(S,A,B,C) \ + asm( "add %1, %0": "+q"( (s) ): "m"( tridict[(A)][(B)][(C)] ) ) + +__attribute__ ((optimize("sched-stalled-insns=0" + ",sched-stalled-insns-dep=16" + ))) int triscoreBasic( const Key* const restrict key, scoreLength_t len ) { - int i; - text_t c1, c2, c3; - int s; - - const PermutationMap_t* const stbrett = &key->stbrett; - - s=0; - - c1 = decode(0,0,stbrett); - - c2 = decode(1,0,stbrett); - - for (i = 2; i < len-15; i += 16) { - c3 = decode(0,i,stbrett); - s += tridict[c1][c2][c3]; - - c1 = decode(1,i,stbrett); - s += tridict[c2][c3][c1]; - - c2 = decode(2,i,stbrett); - s += tridict[c3][c1][c2]; - - c3 = decode(3,i,stbrett); - s += tridict[c1][c2][c3]; - - c1 = decode(4,i,stbrett); - s += tridict[c2][c3][c1]; - - c2 = decode(5,i,stbrett); - s += tridict[c3][c1][c2]; - - c3 = decode(6,i,stbrett); - s += tridict[c1][c2][c3]; - - c1 = decode(7,i,stbrett); - s += tridict[c2][c3][c1]; - - c2 = decode(8,i,stbrett); - s += tridict[c3][c1][c2]; - - c3 = decode(9,i,stbrett); - s += tridict[c1][c2][c3]; - - c1 = decode(10,i,stbrett); - s += tridict[c2][c3][c1]; - - c2 = decode(11,i,stbrett); - s += tridict[c3][c1][c2]; - - c3 = decode(12,i,stbrett); - s += tridict[c1][c2][c3]; - - c1 = decode(13,i,stbrett); - s += tridict[c2][c3][c1]; - - c2 = decode(14,i,stbrett); - s += tridict[c3][c1][c2]; - - c3 = decode(15,i,stbrett); - s += tridict[c1][c2][c3]; - - c1 = c2; - c2 = c3; - } - for (; i < len-3; i += 4) { - c3 = decode(0,i,stbrett); - s += tridict[c1][c2][c3]; - - c1 = decode(1,i,stbrett); - s += tridict[c2][c3][c1]; - - c2 = decode(2,i,stbrett); - s += tridict[c3][c1][c2]; - - c3 = decode(3,i,stbrett); - s += tridict[c1][c2][c3]; - - c1 = c2; - c2 = c3; - } - for (; i < len; i++) { - c3 = decode(0,i,stbrett); - s += tridict[c1][c2][c3]; - - c1 = c2; - c2 = c3; - } - - return s; - + int s = 0; + + const PermutationMap_t* const stbrett = &key->stbrett; + + size_t c1 = decode(0,0,stbrett); + size_t c2 = decode(1,0,stbrett); + + int i = 2; + for( ; i < len - 15; i += 16 ) { + size_t c3; + v4pis d; + d = decode4( 0, i, stbrett ); + c3 = d[0]; + TRISCORE_ADD( s, c1, c2, c3 ); + c1 = d[1]; + TRISCORE_ADD( s, c2, c3, c1 ); + c2 = d[2]; + TRISCORE_ADD( s, c3, c1, c2 ); + c3 = d[3]; + TRISCORE_ADD( s, c1, c2, c3 ); + + d = decode4( 4, i, stbrett ); + c1 = d[0]; + TRISCORE_ADD( s, c2, c3, c1 ); + c2 = d[1]; + TRISCORE_ADD( s, c3, c1, c2 ); + c3 = d[2]; + TRISCORE_ADD( s, c1, c2, c3 ); + c1 = d[3]; + TRISCORE_ADD( s, c2, c3, c1 ); + + d = decode4( 8, i, stbrett ); + c2 = d[0]; + TRISCORE_ADD( s, c3, c1, c2 ); + c3 = d[1]; + TRISCORE_ADD( s, c1, c2, c3 ); + c1 = d[2]; + TRISCORE_ADD( s, c2, c3, c1 ); + c2 = d[3]; + TRISCORE_ADD( s, c3, c1, c2 ); + + d = decode4( 12, i, stbrett ); + c3 = d[0]; + TRISCORE_ADD( s, c1, c2, c3 ); + c1 = d[1]; + TRISCORE_ADD( s, c2, c3, c1 ); + c2 = d[2]; + TRISCORE_ADD( s, c3, c1, c2 ); + c3 = d[3]; + TRISCORE_ADD( s, c1, c2, c3 ); + + c1 = c2; + c2 = c3; + } + for( ; i < len - 3; i += 4 ) { + size_t c3; + v4pis d = decode4( 0, i, stbrett ); + c3 = d[0]; + TRISCORE_ADD( s, c1, c2, c3 ); + + c1 = d[1]; + TRISCORE_ADD( s, c2, c3, c1 ); + + c2 = d[2]; + TRISCORE_ADD( s, c3, c1, c2 ); + + c3 = d[3]; + TRISCORE_ADD( s, c1, c2, c3 ); + + c1 = c2; + c2 = c3; + } + for( ; i < len; ++i ) { + size_t c3; + c3 = decode( 0, i, stbrett ); + TRISCORE_ADD( s, c1, c2, c3 ); + + c1 = c2; + c2 = c3; + } + return s; } /* diff --git a/libEnigma/src/scoreNoInterleave.c b/libEnigma/src/scoreNoInterleave.c index e57f24d..61ceed2 100644 --- a/libEnigma/src/scoreNoInterleave.c +++ b/libEnigma/src/scoreNoInterleave.c @@ -1,6 +1,9 @@ #include "dict.h" #include "key.h" #include "score.h" +#include "score_inlines.h" +#include "scoreNoInterleave.h" +#include "scoreNoInterleave_inlines.h" // default scores static int uniscoreNoInterleave( const Key* const restrict key, scoreLength_t len ); @@ -16,50 +19,10 @@ enigma_score_function_t enigmaScoreOptNoInterleave = { icscoreNoInterleave, uniscoreNoInterleave }; -__attribute__ (( optimize( "sched-stalled-insns=0,sched-stalled-insns-dep=16,unroll-loops" ) )) -static inline -void DecodeScoredMessagePartNoInterleave( const Key* const restrict key, scoreLength_t len, union ScoringDecodedMessage* output ){ - const PermutationMap_t* const restrict stbrett = &key->stbrett; - int i; - for( i = 0; i < len - 15; i += 16 ) { - output->plain[ 0 + i] = decode( 0, i, stbrett ); - output->plain[ 1 + i] = decode( 1, i, stbrett ); - output->plain[ 2 + i] = decode( 2, i, stbrett ); - output->plain[ 3 + i] = decode( 3, i, stbrett ); - output->plain[ 4 + i] = decode( 4, i, stbrett ); - output->plain[ 5 + i] = decode( 5, i, stbrett ); - output->plain[ 6 + i] = decode( 6, i, stbrett ); - output->plain[ 7 + i] = decode( 7, i, stbrett ); - output->plain[ 8 + i] = decode( 8, i, stbrett ); - output->plain[ 9 + i] = decode( 9, i, stbrett ); - output->plain[10 + i] = decode( 10, i, stbrett ); - output->plain[11 + i] = decode( 11, i, stbrett ); - output->plain[12 + i] = decode( 12, i, stbrett ); - output->plain[13 + i] = decode( 13, i, stbrett ); - output->plain[14 + i] = decode( 14, i, stbrett ); - output->plain[15 + i] = decode( 15, i, stbrett ); - } - for ( ; i < len - 3; i += 4 ) { - output->plain[ 0 + i] = decode( 0, i, stbrett ); - output->plain[ 1 + i] = decode( 1, i, stbrett ); - output->plain[ 2 + i] = decode( 2, i, stbrett ); - output->plain[ 3 + i] = decode( 3, i, stbrett ); - } - for ( ; i < len; i++ ) { - output->plain[i] = decode( 0, i, stbrett ); - } -} - __attribute__ ((optimize("sched-stalled-insns=0,sched-stalled-insns-dep=16,unroll-loops"))) int triscoreNoInterleave( const Key* const restrict key, scoreLength_t len ) { DecodeScoredMessagePartNoInterleave( key, len, &decodedMsgPartNoInterleave ); - uint8_t length = len; - int s = 0; - uint8_t i; - for ( i = 0; i < length - 2; ++i ){ - s += tridict[decodedMsgPartNoInterleave.plain[i]][decodedMsgPartNoInterleave.plain[i+1]][decodedMsgPartNoInterleave.plain[i+2]]; - } - return s; + return ComputeTriscoreFromDecodedMsg( &decodedMsgPartNoInterleave, len ); } __attribute__ ((optimize("sched-stalled-insns=0,sched-stalled-insns-dep=16,unroll-loops"))) @@ -105,13 +68,7 @@ static int uniscoreNoInterleave( const Key* key, scoreLength_t len ) { __attribute__ ((optimize("sched-stalled-insns=0,sched-stalled-insns-dep=16,unroll-loops"))) static int biscoreNoInterleave( const Key* const restrict key, scoreLength_t len ) { DecodeScoredMessagePartNoInterleave( key, len, &decodedMsgPartNoInterleave ); - uint8_t i; - uint8_t length = len; - int s = 0; - for( i = 0; i < length - 1; i++ ) { - s += bidict[decodedMsgPartNoInterleave.plain[i]][decodedMsgPartNoInterleave.plain[i + 1]]; - } - return s; + return ComputeBiscoreFromDecodedMsg( &decodedMsgPartNoInterleave, len ); } diff --git a/libEnigma/src/stecker.c b/libEnigma/src/stecker.c index 5a5ea34..29ea6ef 100644 --- a/libEnigma/src/stecker.c +++ b/libEnigma/src/stecker.c @@ -3,9 +3,6 @@ #include "ciphertext.h" #include "randomNumbers.h" -// extern definition for external linkage. -extern inline void SwapStbrett(Key* const key, int i, int k); - /* extracts stecker from key->stbrett to key->sf */ void get_stecker(Key *key) { diff --git a/libEnigma/src/x86/cipherAvx2.c b/libEnigma/src/x86/cipherAvx2.c index 47f3337..19a269b 100644 --- a/libEnigma/src/x86/cipherAvx2.c +++ b/libEnigma/src/x86/cipherAvx2.c @@ -14,16 +14,6 @@ void prepare_decoder_lookup_M_H3_avx2( const Key *key, int len ); void prepare_decoder_lookup_ALL_avx2( const Key *key, int len ); -inline extern -v32qi DecodeBiteForwardCommonAvx2( v32qi bite, v32qi rRingOffset, const Key* const restrict key ); -inline extern -v32qi DecodeBiteMaskedPartAvx2( v32qi predecodedBite, int lookupNumber ); -inline extern -v32qi DecodeBiteBackwardCommonAvx2( v32qi bite, v32qi rRingOffset, const Key* const restrict key ); -inline extern -v32qi PermuteV32qi( const PermutationMap_t* map, v32qi vec ); -inline extern -uint16_t ComputeIcscoreFromDecodedMsgAvx2( union ScoringDecodedMessage* msg, scoreLength_t len ); enigma_cipher_function_t enigma_cipher_DecoderLookupAvx2 = { prepare_decoder_lookup_M_H3_avx2, prepare_decoder_lookup_ALL_avx2 }; diff --git a/libEnigma/src/x86/cipherSsse3.c b/libEnigma/src/x86/cipherSsse3.c index db44151..ff3d006 100644 --- a/libEnigma/src/x86/cipherSsse3.c +++ b/libEnigma/src/x86/cipherSsse3.c @@ -14,20 +14,6 @@ void prepare_decoder_lookup_M_H3_ssse3( const Key *key, int len ); void prepare_decoder_lookup_ALL_ssse3( const Key *key, int len ); -inline extern -v16qi DecodeBiteForwardCommonSsse3( v16qi bite, v16qi rRingOffset, const Key* const restrict key ); -inline extern -v16qi DecodeBiteMaskedPartSsse3( v16qi bite, int lookupNumber ); -inline extern -v16qi DecodeBiteBackwardCommonSsse3( v16qi bite, v16qi rRingOffset, const Key* const restrict key ); -inline extern -v16qi PermuteV16qi(const PermutationMap_t* map, v16qi vec ); -inline extern -void DecodeScoredMessagePartSsse3( const Key* const restrict key, int len, union ScoringDecodedMessage* output ); -inline extern -uint16_t ComputeIcscoreFromDecodedMsgSsse3( union ScoringDecodedMessage* msg, scoreLength_t len ); -inline extern -int ComputeBiscoreFromDecodedMsgSse2( union ScoringDecodedMessage* msg, scoreLength_t len ); enigma_cipher_function_t enigma_cipher_decoder_lookup_ssse3 = {prepare_decoder_lookup_M_H3_ssse3, prepare_decoder_lookup_ALL_ssse3}; diff --git a/libEnigma/src/x86/scoreAvx.c b/libEnigma/src/x86/scoreAvx.c index c81f974..c8f635f 100644 --- a/libEnigma/src/x86/scoreAvx.c +++ b/libEnigma/src/x86/scoreAvx.c @@ -42,12 +42,12 @@ __attribute__ ((flatten)) __attribute__ ((optimize("unroll-loops"))) static int biscoreAvx( const Key* const restrict key, scoreLength_t len ) { DecodeScoredMessagePartSsse3( key, len, &decodedMsgPartAvx ); - return ComputeBiscoreFromDecodedMsg( &decodedMsgPartAvx, len ); + return ComputeBiscoreFromDecodedMsgSse2( &decodedMsgPartAvx, len ); } __attribute__ ((flatten)) __attribute__ ((optimize("unroll-loops"))) static int triscoreAvx( const Key* const restrict key, scoreLength_t len ) { DecodeScoredMessagePartSsse3( key, len, &decodedMsgPartAvx ); - return ComputeTriscoreFromDecodedMsg( &decodedMsgPartAvx, len ); + return ComputeTriscoreFromDecodedMsgSse2( &decodedMsgPartAvx, len ); } diff --git a/libEnigma/src/x86/scoreAvx2.c b/libEnigma/src/x86/scoreAvx2.c index 216e52b..005eecd 100644 --- a/libEnigma/src/x86/scoreAvx2.c +++ b/libEnigma/src/x86/scoreAvx2.c @@ -24,57 +24,6 @@ enigma_score_function_t enigmaScoreAvx2 = { triscoreAvx2, biscoreAvx2 , icscore union ScoringDecodedMessage decodedMsgPartAvx2; -__attribute__ ((optimize("unroll-loops,sched-stalled-insns=0,sched-stalled-insns-dep=16"))) -inline -static void DecodeScoredMessagePartAvx2( const Key* const restrict key, int len, union ScoringDecodedMessage* output ) -{ - uint16_t messageBite = 0; - uint_least16_t lookupNumber = 0; - v32qi currentRRingOffset = PathLookupAvx2.firstRRingOffset; - while( messageBite < ( len + 31 ) / 32 ) - { - /* Worst case: - * P0123456789ABCDEFGHIJKLMNOP01234 R-ring position (turnovers on 12 & 25, coded C & P) - * 0123456789ABCDEF0123456789ABCDEF characters in bite - * ||| | | - * ||| | + - * ||| +- turnover on second notch of R ring - * ||+- turnover caused by M-ring (turning L- & M- rings). - * |+-- turnover setting M-ring to turnover position - * +--- last character from previous bite - * - * In the worst case there are 5 lookups per bite. - */ - uint_least16_t lookupsToNextBite = PathLookupAvx2.nextBite[messageBite] - lookupNumber; - v32qi cBite = {0}; - lookupNumber += lookupsToNextBite; - v32qi currentBite = ciphertext.vector32[messageBite]; - v32qi predecoded = DecodeBiteForwardCommonAvx2( currentBite, currentRRingOffset, key ); - - switch( lookupsToNextBite ) { - case 5: - cBite = DecodeBiteMaskedPartAvx2( predecoded, lookupNumber - 5 ); - case 4: - cBite |= DecodeBiteMaskedPartAvx2( predecoded, lookupNumber - 4 ); - case 3: - cBite |= DecodeBiteMaskedPartAvx2( predecoded, lookupNumber - 3 ); - case 2: - cBite |= DecodeBiteMaskedPartAvx2( predecoded, lookupNumber - 2 ); - case 1: - cBite |= DecodeBiteMaskedPartAvx2( predecoded, lookupNumber - 1 ); - break; - default: - exit_d(5); - UNREACHABLE(); - } - cBite = DecodeBiteBackwardCommonAvx2( cBite, currentRRingOffset, key ); - // store whole decoded bite - output -> vector32[messageBite] = cBite; - messageBite++; - currentRRingOffset = AddMod26_v32qi_int8( currentRRingOffset, 32 % 26 ); - } -} - __attribute__ ((flatten)) __attribute__ ((optimize("unroll-loops"))) static uint16_t icscoreAvx2( const Key* const restrict key, scoreLength_t len ) { @@ -100,5 +49,5 @@ __attribute__ ((flatten)) __attribute__ ((optimize("unroll-loops"))) static int triscoreAvx2( const Key* const restrict key, scoreLength_t len ) { DecodeScoredMessagePartAvx2( key, len, &decodedMsgPartAvx2 ); - return ComputeTriscoreFromDecodedMsg( &decodedMsgPartAvx2, len ); + return ComputeTriscoreFromDecodedMsgSse2( &decodedMsgPartAvx2, len ); } diff --git a/libEnigma/src/x86/scoreSsse3.c b/libEnigma/src/x86/scoreSsse3.c index 6ee2a3e..b33e824 100644 --- a/libEnigma/src/x86/scoreSsse3.c +++ b/libEnigma/src/x86/scoreSsse3.c @@ -19,13 +19,6 @@ static int uniscoreSsse3( const Key* const restrict key, scoreLength_t len ) static int biscoreSsse3( const Key* const restrict key, scoreLength_t len ); static int triscoreSsse3( const Key* const restrict key, scoreLength_t len ); -inline extern -int ComputeTriscoreFromDecodedMsgSse2( union ScoringDecodedMessage* msg, scoreLength_t len ); -inline extern -void Unpack_v16qi( v16qi in, v8hi* lo, v8hi *hi ); -inline extern -v16qi MOVDQU( v16qi* p ); - enigma_score_function_t enigmaScoreSsse3 = { triscoreSsse3, biscoreSsse3 , icscoreSsse3, uniscoreSsse3 } ; union ScoringDecodedMessage decodedMsgPartSsse3; diff --git a/optima/CMakeLists.txt b/optima/CMakeLists.txt new file mode 100644 index 0000000..91525a8 --- /dev/null +++ b/optima/CMakeLists.txt @@ -0,0 +1,30 @@ +add_executable(EnigmaOptima "enigma.c") + +target_sources(EnigmaOptima +PRIVATE + "banner.c" + "display.c" + "error.c" + "config/releaseVersion.cpp" + "OS/OsDefault.c" + "OS/OsWindows.c" +) +set_target_properties(EnigmaOptima + PROPERTIES OUTPUT_NAME "enigma-optima") + +target_compile_features(EnigmaOptima PUBLIC c_std_99 cxx_std_11) +target_compile_options(EnigmaOptima + PRIVATE + ${ENIGMA_COMPILE_OPTIONS}) + + +if(CMAKE_C_COMPILER_ID MATCHES "GNU") + set_target_properties(EnigmaOptima PROPERTIES C_EXTENSIONS ON) +endif() + +target_link_libraries(EnigmaOptima Enigma) + +configure_file ( + "${CMAKE_CURRENT_SOURCE_DIR}/config/releaseVersion.cpp.in" + "${CMAKE_CURRENT_SOURCE_DIR}/config/releaseVersion.cpp" +) diff --git a/OS/OsDefault.c b/optima/OS/OsDefault.c similarity index 100% rename from OS/OsDefault.c rename to optima/OS/OsDefault.c diff --git a/OS/OsWindows.c b/optima/OS/OsWindows.c similarity index 100% rename from OS/OsWindows.c rename to optima/OS/OsWindows.c diff --git a/banner.c b/optima/banner.c similarity index 93% rename from banner.c rename to optima/banner.c index f8ffe6c..f718a99 100644 --- a/banner.c +++ b/optima/banner.c @@ -42,10 +42,11 @@ static char* osName = OS_NAME; void WriteStartupBanner( void ){ fprintf(stderr, - "Enigma Optima %s %s%d\n" + "Enigma Optima %s %s%d (%s)\n" "Best ISA: %s\n" , releaseVersion , osName , pointerSize + , compilerVersion , cpuFlagsToString( enigma_cpu_flags )); } diff --git a/banner.h b/optima/banner.h similarity index 100% rename from banner.h rename to optima/banner.h diff --git a/optima/config/releaseVersion.cpp.in b/optima/config/releaseVersion.cpp.in new file mode 100644 index 0000000..66ae130 --- /dev/null +++ b/optima/config/releaseVersion.cpp.in @@ -0,0 +1,4 @@ +#include "releaseVersion.h" + +char const* releaseVersion = "@ENIGMA_GIT_DESCRIBE_VERSION@"; +char const* compilerVersion = "${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}"; diff --git a/config/releaseVersion.h b/optima/config/releaseVersion.h similarity index 57% rename from config/releaseVersion.h rename to optima/config/releaseVersion.h index 12b88dd..9ee1238 100644 --- a/config/releaseVersion.h +++ b/optima/config/releaseVersion.h @@ -1,4 +1,4 @@ #pragma once extern char const* releaseVersion; - +extern char const* compilerVersion; diff --git a/display.c b/optima/display.c similarity index 100% rename from display.c rename to optima/display.c diff --git a/display.h b/optima/display.h similarity index 100% rename from display.h rename to optima/display.h diff --git a/enigma.c b/optima/enigma.c similarity index 100% rename from enigma.c rename to optima/enigma.c diff --git a/error.c b/optima/error.c similarity index 94% rename from error.c rename to optima/error.c index d437446..e05e972 100644 --- a/error.c +++ b/optima/error.c @@ -73,7 +73,7 @@ void hillclimb_log(const char *s) fflush(stderr); } -extern +extern inline void exit_d( int errorCode ); /* diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..991012c --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,23 @@ +set(CMAKE_THREAD_PREFER_PTHREAD ON) +set(THREADS_PREFER_PTHREAD_FLAG ON) +include(FindThreads) + +add_executable(EnigmaUnitTests "main.cpp") +target_sources(EnigmaUnitTests +PRIVATE + "cipher.tests.cpp" + "GetRSeed.tests.cpp" +) + +target_compile_features(EnigmaUnitTests PUBLIC cxx_std_11 c_std_99) +target_compile_options(EnigmaUnitTests PUBLIC $<$:-fexceptions>) +target_compile_options(EnigmaUnitTests + PRIVATE + $<$:${ENIGMA_CXX_COMPILE_OPTIONS}> + ${ENIGMA_COMPILE_OPTIONS}) + +target_link_libraries(EnigmaUnitTests Enigma gtest Threads::Threads) + +add_test( + NAME Units + COMMAND EnigmaUnitTests) diff --git a/tests/enigma-optima.tests.cbp b/tests/enigma-optima.tests.cbp deleted file mode 100644 index ab67f57..0000000 --- a/tests/enigma-optima.tests.cbp +++ /dev/null @@ -1,77 +0,0 @@ - - - - - -