Compare commits
	
		
			47 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2e7ef7285e | |||
| dbb68b5fb1 | |||
| df513d4465 | |||
| 00ecea2bd6 | |||
| c068d6dbd3 | |||
| 578857997e | |||
| 56081dcb6f | |||
| b68c2226d9 | |||
| 925e312608 | |||
| 74275ddab4 | |||
| 0dafde8a4c | |||
| a5cf27744a | |||
| f46a211a8d | |||
| 57fff5c09b | |||
| e39264632f | |||
| 630f9993d6 | |||
| 9249f34038 | |||
| b14442d722 | |||
| 58e2dcfaf8 | |||
| a7559066f4 | |||
| 10eb3c88fc | |||
| 90720804ba | |||
| 4975a8273c | |||
| ed4ab31837 | |||
| 21391f1f01 | |||
| 21f97e9bc3 | |||
| d715d50dfb | |||
| a2cd38fbd5 | |||
| c7cd0843b8 | |||
| 83b2105c38 | |||
| 510695bf6e | |||
| 7258684a33 | |||
| 15cc2ece6f | |||
| 3e0eaba231 | |||
| 4bd2111c93 | |||
| f99db9409f | |||
| 87539a8433 | |||
| de4cf8f35a | |||
| 7d4bcea3ba | |||
| 74c2ec2014 | |||
| 339d6b0f2c | |||
| 36cb401420 | |||
| f3dc9aea54 | |||
| 2f675e9bdd | |||
| 3114cb265a | |||
| fca9f04264 | |||
| fe1136c7ce | 
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -151,6 +151,4 @@ compile_commands.json | ||||
| CTestTestfile.cmake | ||||
| *.dump | ||||
|  | ||||
| .vscode/c_cpp_properties.json | ||||
| semihosting_test/build/semihosting_test | ||||
| semihosting_test/build/Makefile | ||||
| build | ||||
| @@ -0,0 +1,23 @@ | ||||
| if (NOT DEFINED BOARD) | ||||
| 	set(BOARD iss) | ||||
| endif() | ||||
| if (NOT DEFINED ISA) | ||||
| 	set(ISA imc) | ||||
| endif() | ||||
| if(DEFINED LINK_TARGET) | ||||
|     set(LNK LINK_TARGET=${LINK_TARGET}) | ||||
| endif() | ||||
| message(STATUS "Building firmware using ${BOARD} board configuration and isa ${ISA}") | ||||
| add_custom_target(fw-common ALL  | ||||
| 	COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}/hello-world BOARD=${BOARD} ISA=${ISA} ${LNK} | ||||
| 	COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/dhrystone BOARD=${BOARD} ISA=${ISA} ${LNK} | ||||
| 	COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/coremark BOARD=${BOARD} ISA=${ISA} ${LNK} | ||||
|     USES_TERMINAL | ||||
|     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | ||||
| add_custom_target(fw-common-clean  | ||||
| 	COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}/hello-world BOARD=${BOARD} ISA=${ISA} ${LNK} clean | ||||
| 	COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/dhrystone BOARD=${BOARD} ISA=${ISA} ${LNK} clean | ||||
| 	COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/coremark BOARD=${BOARD} ISA=${ISA} ${LNK} clean | ||||
|     USES_TERMINAL | ||||
|     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | ||||
|      | ||||
							
								
								
									
										122
									
								
								Jenkinsfile
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										122
									
								
								Jenkinsfile
									
									
									
									
										vendored
									
									
								
							| @@ -2,7 +2,7 @@ void checkout_project() { | ||||
|     checkout([ | ||||
|         $class: 'GitSCM', | ||||
|         branches: [ | ||||
|             [name: '*/main'] | ||||
|             [name: '*/develop'] | ||||
|         ], | ||||
|         extensions: [ | ||||
|             [$class: 'CleanBeforeCheckout'], | ||||
| @@ -15,6 +15,24 @@ void checkout_project() { | ||||
|     ]) | ||||
| } | ||||
|  | ||||
|  | ||||
| void checkout_iss_project(String repoUrl, String branch = 'develop') { | ||||
|     checkout([ | ||||
|         $class: 'GitSCM', | ||||
|         branches: [ | ||||
|             [name: "*/${branch}"] | ||||
|         ], | ||||
|         extensions: [ | ||||
|             [$class: 'CleanBeforeCheckout'], | ||||
|             [$class: 'SubmoduleOption', disableSubmodules: false, parentCredentials: true, recursiveSubmodules: true, reference: '', trackingSubmodules: false, shallow: true] | ||||
|         ], | ||||
|         submoduleCfg: [], | ||||
|         userRemoteConfigs: [ | ||||
|             [credentialsId: 'gitea-jenkins', url: repoUrl] | ||||
|         ] | ||||
|     ]) | ||||
| } | ||||
|  | ||||
| void checkout_develop() { | ||||
|     dir("bare-metal-bsp") { | ||||
|         withCredentials([usernamePassword(credentialsId: 'gitea-jenkins', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD')]) { | ||||
| @@ -29,6 +47,14 @@ void make_hello(board) { | ||||
|     sh("make -C hello-world/ clean") | ||||
| } | ||||
|  | ||||
| void cmake_hello(board,build_type,core_type) {   | ||||
|     def flavor ="${board}_${build_type}_${core_type}" | ||||
|     if (core_type=="32") | ||||
|         flavor ="${board}_${build_type}" | ||||
|     sh("cmake -B ${flavor}  --preset=${flavor}")  | ||||
|     sh("cmake --build ${flavor}")     | ||||
| } | ||||
|  | ||||
| pipeline { | ||||
|     agent { docker {  | ||||
|         image 'ubuntu-riscv' | ||||
| @@ -48,12 +74,13 @@ pipeline { | ||||
|         stage('make rtl') {steps { make_hello("rtl")}} | ||||
|         stage('make ehrenberg') {steps { make_hello("ehrenberg")}} | ||||
|         stage('make tgc_vp') {steps { make_hello("tgc_vp")}}*/ | ||||
|          | ||||
|         stage('make hello-world') { | ||||
|             matrix { | ||||
|                 axes { | ||||
|                     axis{ | ||||
|                         name 'BOARD' | ||||
|                         values 'iss', 'hifive1', 'TGCP', 'ehrenberg', 'rtl', 'tgc_vp' | ||||
|                         values 'iss',  'moonlight',  'tgc_vp' | ||||
|                     } | ||||
|                 } | ||||
|                 stages { | ||||
| @@ -72,10 +99,91 @@ pipeline { | ||||
|                 } | ||||
|             }  | ||||
|         } | ||||
|     } | ||||
|     post { | ||||
|         failure { | ||||
|             sh("make -C hello-world/ clean")        | ||||
|          | ||||
|         stage('CMAKE flow for hello-world') { | ||||
|             matrix { | ||||
|                 axes { | ||||
|                     axis{ | ||||
|                         name 'BOARD' | ||||
|                         values 'ISS',  'Moonlight', 'TGC_VP' | ||||
|                     } | ||||
|                     axis{ | ||||
|                         name 'BUILD_TYPE' | ||||
|                         values 'Debug',  'Release' | ||||
|                     } | ||||
|                     axis{ | ||||
|                         name 'CORE_TYPE' | ||||
|                         values '32',  '64' | ||||
|                     } | ||||
|                 } | ||||
|                 stages { | ||||
|                     stage('Force sequential') { | ||||
|                         options { | ||||
|                             lock("One Board at a time") | ||||
|                         } | ||||
|                         when{ | ||||
|                             not { | ||||
|                                 anyOf { | ||||
|                                     expression { BOARD == 'Moonlight' && CORE_TYPE =='64'} | ||||
|                                     expression { BOARD == 'TGC_VP' && CORE_TYPE =='64'} | ||||
|                                 }                                 | ||||
|                             } | ||||
|                         } | ||||
|                         stages { | ||||
|                             stage("CMAKE") { | ||||
|                                 steps { | ||||
|                                     dir("hello-world"){ | ||||
|                                         cmake_hello("${BOARD}","${BUILD_TYPE}","${CORE_TYPE}") | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }  | ||||
|         } | ||||
|     } | ||||
|         stage("Checkout TGC-ISS, TGC-Compliance and TGC-GEN"){ | ||||
|             steps {                                        | ||||
|                 dir("TGC-ISS"){                     | ||||
|                     sh 'rm -rf * .??* ' | ||||
|                     checkout_iss_project("https://git.minres.com/TGFS/TGC-ISS.git", "develop") | ||||
|                     dir("TGC-COMPLIANCE"){                         | ||||
|                         checkout_iss_project("https://git.minres.com/TGFS/TGC-COMPLIANCE.git", "master") | ||||
|                     } | ||||
|                     dir("TGC-GEN"){                         | ||||
|                         checkout_iss_project("https://git.minres.com/TGFS/TGC-GEN.git", "develop") | ||||
|                         }                             | ||||
|                     }  | ||||
|                 } | ||||
|         } | ||||
|         stage("Generate cores and build TGC-ISS"){ | ||||
|             steps {                 | ||||
|                 sh 'rm -rf *@tmp'                      | ||||
|                 sh ''' | ||||
|                 for core in RV32GC; do  | ||||
|                     for backend in interp; do  | ||||
|                             TGC-ISS/TGC-GEN/scripts/generate_iss.sh -o TGC-ISS/dbt-rise-tgc/ -c $core -b ${backend} TGC-ISS/TGC-GEN/CoreDSL/${core}.core_desc | ||||
|                     done | ||||
|                 done | ||||
|                 for core in RV64GC; do | ||||
|                     for backend in interp; do  | ||||
|                         TGC-ISS/TGC-GEN/scripts/generate_iss.sh -o TGC-ISS/dbt-rise-tgc/ -c $core -b ${backend} TGC-ISS/TGC-GEN/CoreDSL/${core}.core_desc | ||||
|                     done | ||||
|                 done | ||||
|                 ''' | ||||
|                 sh 'conan profile detect --force' | ||||
|                 sh 'rm -rf TGC-ISS/build' | ||||
|                 sh 'cmake -S TGC-ISS/. -B TGC-ISS/build --preset Release -DWITH_ASMJIT=ON -DWITH_TCC=ON -DWITH_LLVM=OFF'                 | ||||
|                 sh 'cmake --build TGC-ISS/build -j' | ||||
|                 sh 'TGC-ISS/build/dbt-rise-tgc/tgc-sim --isa ?'                        | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|         stage("start to run hello FW on ISS") { | ||||
|             steps {                 | ||||
|                 sh 'TGC-ISS/build/dbt-rise-tgc/tgc-sim -f hello-world/ISS_Debug/hello.elf' | ||||
|                 sh 'TGC-ISS/build/dbt-rise-tgc/tgc-sim -f hello-world/ISS_Debug_64/hello.elf --isa=rv64gc'                 | ||||
|             } | ||||
|         } | ||||
|     }     | ||||
| } | ||||
|   | ||||
 Submodule bare-metal-bsp updated: 540397494a...bf0e4ec057
									
								
							| @@ -1,15 +1,7 @@ | ||||
| cmake_minimum_required(VERSION 3.21) | ||||
| project(coremark C) | ||||
| set(TARGET coremark) | ||||
| #set(CMAKE_BUILD_TYPE Release) | ||||
|  | ||||
| option(HAVE_NO_INIT_FINI "Enable NO_INIT_FINI" OFF) | ||||
|  | ||||
| if(HAVE_NO_INIT_FINI) | ||||
|   #if HAVE_NO_INIT_FINI is ON | ||||
|   add_definitions(-DHAVE_NO_INIT_FINI) | ||||
| endif() | ||||
|  | ||||
| set(CMAKE_BUILD_TYPE Release) | ||||
|  | ||||
| # Source files | ||||
| set(SOURCES | ||||
| @@ -23,7 +15,6 @@ set(SOURCES | ||||
|     cm/core_util.c | ||||
| ) | ||||
|  | ||||
|  | ||||
| # Create executable | ||||
| add_executable(coremark ${SOURCES}) | ||||
| target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/cm) | ||||
| @@ -33,13 +24,7 @@ target_compile_definitions(${TARGET} PRIVATE PERFORMANCE_RUN=1 CLOCKS_PER_SEC=10 | ||||
| set(BOARD "iss" CACHE STRING "Target board") | ||||
| add_subdirectory(../../bare-metal-bsp bsp) | ||||
| target_link_libraries(${TARGET} PRIVATE bsp) | ||||
| target_link_options(${TARGET} PRIVATE -Wl,-Map=${TARGET}.map)   | ||||
|  | ||||
| include(CMakePrintHelpers) | ||||
| cmake_print_properties(TARGETS ${TARGET} PROPERTIES COMPILE_DEFINITIONS COMPILE_OPTIONS LINK_OPTIONS INTERFACE_LINK_OPTIONS) | ||||
|  | ||||
| #message(STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}") | ||||
| #message(STATUS "CMAKE_C_FLAGS = ${CMAKE_C_FLAGS}") | ||||
| target_link_options(${TARGET} PRIVATE LINKER:-Map=${TARGET}.map)   | ||||
|  | ||||
| add_custom_command(TARGET ${TARGET} POST_BUILD | ||||
|         COMMAND ${CMAKE_OBJDUMP} -S  ${TARGET}.elf > ${TARGET}.dis | ||||
|   | ||||
| @@ -9,62 +9,110 @@ | ||||
|         "patch": 0 | ||||
|     }, | ||||
|     "configurePresets": [ | ||||
|         { | ||||
|             "name": "32imc", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "64imc", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "iss", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "BOARD": "iss" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "moonlight", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "BOARD": "moonlight" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "tgc_vp", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "BOARD": "tgc_vp" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "rtl", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "BOARD": "rtl" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",        | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_moon", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",   | ||||
|                 "BOARD": "moonlight", | ||||
|                 "HAVE_NO_INIT_FINI": "ON",    | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_tgc", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",   | ||||
|                 "BOARD": "tgc_vp",    | ||||
|                 "HAVE_NO_INIT_FINI": "ON", | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_64", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",        | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_64_moon", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",   | ||||
|                 "BOARD": "moonlight", | ||||
|                 "HAVE_NO_INIT_FINI": "ON",    | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_64_tgc", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",   | ||||
|                 "BOARD": "tgc_vp",    | ||||
|                 "HAVE_NO_INIT_FINI": "ON", | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" | ||||
|             } | ||||
|                 "CMAKE_BUILD_TYPE": "Debug" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "release", | ||||
|             "cacheVariables": { | ||||
|                 "CMAKE_BUILD_TYPE": "Release",     | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             } | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Release" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "ISS_Debug", | ||||
|             "inherits": ["iss", "debug", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Moonlight_Debug", | ||||
|             "inherits": ["moonlight", "debug", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "TGC_VP_Debug", | ||||
|             "inherits": ["tgc_vp", "debug", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "ISS_Debug_64", | ||||
|             "inherits": ["iss", "debug", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Moonlight_Debug_64", | ||||
|             "inherits": ["moonlight", "debug", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "TGC_VP_Debug_64", | ||||
|             "inherits": ["tgc_vp", "debug", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "ISS_Release", | ||||
|             "inherits": ["iss", "release", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Moonlight_Release", | ||||
|             "inherits": ["moonlight", "release", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "TGC_VP_Release", | ||||
|             "inherits": ["tgc_vp", "release", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "ISS_Release_64", | ||||
|             "inherits": ["iss", "release", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Moonlight_Release_64", | ||||
|             "inherits": ["moonlight", "release", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "TGC_VP_Release_64", | ||||
|             "inherits": ["tgc_vp", "release", "64imc"] | ||||
|         } | ||||
|                   | ||||
|     ] | ||||
| } | ||||
| @@ -571,33 +571,7 @@ static int ee_vsprintf(char *buf, const char *fmt, va_list args) { | ||||
|  | ||||
| #include <platform.h> | ||||
|  | ||||
| void uart_send_char(char c) { | ||||
|   write(STDOUT_FILENO, &c, 1); // write or puts ?? | ||||
|   /* | ||||
| #if defined(BOARD_ehrenberg) | ||||
| while (get_uart_rx_tx_reg_tx_free(uart) == 0) | ||||
| ; | ||||
| uart_write(uart, c); | ||||
| if (c == '\n') { | ||||
| while (get_uart_rx_tx_reg_tx_free(uart) == 0) | ||||
|   ; | ||||
| uart_write(uart, '\r'); | ||||
| } | ||||
| #elif defined(BOARD_iss) | ||||
| *((uint32_t *)0xFFFF0000) = c; | ||||
| #else | ||||
| while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) | ||||
| ; | ||||
| UART0_REG(UART_REG_TXFIFO) = c; | ||||
| if (c == '\n') { | ||||
| while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) | ||||
|   ; | ||||
| UART0_REG(UART_REG_TXFIFO) = '\r'; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| */ | ||||
| } | ||||
| void uart_send_char(char c) { write(STDOUT_FILENO, &c, 1); } | ||||
|  | ||||
| int ee_printf(const char *fmt, ...) { | ||||
|   char buf[1024], *p; | ||||
|   | ||||
| @@ -2,30 +2,27 @@ cmake_minimum_required(VERSION 3.21) | ||||
| project(dhrystone C) | ||||
| set(TARGET dhrystone) | ||||
|  | ||||
| option(HAVE_NO_INIT_FINI "Enable NO_INIT_FINI" OFF) | ||||
| set(ITERATIONS 50000 CACHE STRING "") | ||||
| set(FREQ 100e6 CACHE STRING "") | ||||
|  | ||||
| if(HAVE_NO_INIT_FINI) | ||||
|   #if HAVE_NO_INIT_FINI is ON | ||||
|   add_definitions(-DHAVE_NO_INIT_FINI) | ||||
| endif() | ||||
|  | ||||
| set(ITERATIONS 50000) # 20000 for TGC | ||||
| set(CMAKE_C_FLAGS_RELEASE -O3) | ||||
|  | ||||
| add_executable(${TARGET} dhry_1.c dhry_2.c dhry_stubs.c) | ||||
| target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) | ||||
| target_compile_options(${TARGET} PRIVATE -fno-inline -fno-builtin-printf -fno-common -Wno-implicit -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las) | ||||
| target_compile_definitions(${TARGET} PRIVATE ITERATIONS=${ITERATIONS} HZ=32768 TIME NO_INIT) | ||||
| target_compile_options(${TARGET} PRIVATE  | ||||
|         -Wno-implicit -fno-builtin-printf  | ||||
|         -finline -fno-common -funroll-loops -fpeel-loops  | ||||
|         -finline-functions -finline-limit=1000 | ||||
|         -fgcse-sm -fgcse-las  | ||||
|         -falign-functions=16 -falign-jumps=4 -falign-loops=4  | ||||
|         -freorder-blocks-and-partition -fno-if-conversion2 -fno-crossjumping) | ||||
| target_compile_definitions(${TARGET} PRIVATE ITERATIONS=${ITERATIONS} HZ=${FREQ} TIME NO_INIT) | ||||
|  | ||||
| set(BOARD "iss" CACHE STRING "Target board") | ||||
| add_subdirectory(../../bare-metal-bsp bsp) | ||||
| target_link_libraries(${TARGET} PRIVATE bsp) | ||||
| target_link_options(${TARGET} PRIVATE LINKER:--wrap=scanf) | ||||
| #target_link_options(${TARGET} PRIVATE LINKER:--wrap=scanf -Wl,--no-gc-sections) | ||||
|  | ||||
| target_link_options(${TARGET} PRIVATE -Wl,-Map=${TARGET}.map)   | ||||
| include(CMakePrintHelpers) | ||||
| cmake_print_properties(TARGETS ${TARGET} PROPERTIES COMPILE_DEFINITIONS COMPILE_OPTIONS LINK_OPTIONS INTERFACE_LINK_OPTIONS) | ||||
| target_link_options(${TARGET} PRIVATE LINKER:-Map=${TARGET}.map -Wl,--wrap=scanf) | ||||
|  | ||||
| add_custom_command(TARGET ${TARGET} POST_BUILD | ||||
|         COMMAND ${CMAKE_OBJDUMP} -S  ${TARGET}.elf > ${TARGET}.dis | ||||
|         COMMAND ${CMAKE_OBJDUMP} -S ${TARGET}.elf > ${TARGET}.dis | ||||
|         COMMENT "Creating disassembly for ${TARGET}") | ||||
|   | ||||
| @@ -9,62 +9,110 @@ | ||||
|         "patch": 0 | ||||
|     }, | ||||
|     "configurePresets": [ | ||||
|         { | ||||
|             "name": "32imc", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "64imc", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "iss", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "BOARD": "iss" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "moonlight", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "BOARD": "moonlight" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "tgc_vp", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "BOARD": "tgc_vp" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "rtl", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "BOARD": "rtl" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",        | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_moon", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",   | ||||
|                 "BOARD": "moonlight", | ||||
|                 "HAVE_NO_INIT_FINI": "ON",    | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_tgc", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",   | ||||
|                 "BOARD": "tgc_vp",    | ||||
|                 "HAVE_NO_INIT_FINI": "ON", | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_64", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",        | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_64_moon", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",   | ||||
|                 "BOARD": "moonlight", | ||||
|                 "HAVE_NO_INIT_FINI": "ON",    | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_64_tgc", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",   | ||||
|                 "BOARD": "tgc_vp",    | ||||
|                 "HAVE_NO_INIT_FINI": "ON", | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" | ||||
|             } | ||||
|                 "CMAKE_BUILD_TYPE": "Debug" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "release", | ||||
|             "cacheVariables": { | ||||
|                 "CMAKE_BUILD_TYPE": "Release",     | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             } | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Release" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "ISS_Debug", | ||||
|             "inherits": ["iss", "debug", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Moonlight_Debug", | ||||
|             "inherits": ["moonlight", "debug", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "TGC_VP_Debug", | ||||
|             "inherits": ["tgc_vp", "debug", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "ISS_Debug_64", | ||||
|             "inherits": ["iss", "debug", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Moonlight_Debug_64", | ||||
|             "inherits": ["moonlight", "debug", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "TGC_VP_Debug_64", | ||||
|             "inherits": ["tgc_vp", "debug", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "ISS_Release", | ||||
|             "inherits": ["iss", "release", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Moonlight_Release", | ||||
|             "inherits": ["moonlight", "release", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "TGC_VP_Release", | ||||
|             "inherits": ["tgc_vp", "release", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "ISS_Release_64", | ||||
|             "inherits": ["iss", "release", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Moonlight_Release_64", | ||||
|             "inherits": ["moonlight", "release", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "TGC_VP_Release_64", | ||||
|             "inherits": ["tgc_vp", "release", "64imc"] | ||||
|         } | ||||
|                   | ||||
|     ] | ||||
| } | ||||
| @@ -9,7 +9,7 @@ HEADERS := dhry.h | ||||
| BOARD?=iss | ||||
| LINK_TARGET=link | ||||
| RISCV_ARCH:=rv32$(ISA) | ||||
| ifeq ($(ISA),e) | ||||
| ifneq (,$(findstring e,$(ISA))) | ||||
|     RISCV_ABI:=ilp32e | ||||
| else | ||||
|     RISCV_ABI:=ilp32 | ||||
| @@ -18,7 +18,6 @@ endif | ||||
| CFLAGS  := -g -O3 -DITERATIONS=$(ITERATIONS) -DHZ=32768 -DTIME -DNO_INIT -fno-inline -fno-builtin-printf -fno-common -Wno-implicit \ | ||||
|  -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las | ||||
| LDFLAGS := -Wl,--wrap=scanf | ||||
|  | ||||
| TOOL_DIR=$(dir $(compiler)) | ||||
|  | ||||
| BSP_BASE = ../../bare-metal-bsp | ||||
|   | ||||
| @@ -212,7 +212,7 @@ main () | ||||
|   printf ("Arr_2_Glob[8][7]:    %d\n", Arr_2_Glob[8][7]); | ||||
|   printf ("        should be:   Number_Of_Runs + 10\n"); | ||||
|   printf ("Ptr_Glob->\n"); | ||||
|   printf ("  Ptr_Comp:          %d\n", (int) Ptr_Glob->Ptr_Comp); | ||||
|   printf ("  Ptr_Comp:          %d\n", (long) Ptr_Glob->Ptr_Comp); | ||||
|   printf ("        should be:   (implementation-dependent)\n"); | ||||
|   printf ("  Discr:             %d\n", Ptr_Glob->Discr); | ||||
|   printf ("        should be:   %d\n", 0); | ||||
| @@ -223,7 +223,7 @@ main () | ||||
|   printf ("  Str_Comp:          %s\n", Ptr_Glob->variant.var_1.Str_Comp); | ||||
|   printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n"); | ||||
|   printf ("Next_Ptr_Glob->\n"); | ||||
|   printf ("  Ptr_Comp:          %d\n", (int) Next_Ptr_Glob->Ptr_Comp); | ||||
|   printf ("  Ptr_Comp:          %d\n", (long) Next_Ptr_Glob->Ptr_Comp); | ||||
|   printf ("        should be:   (implementation-dependent), same as above\n"); | ||||
|   printf ("  Discr:             %d\n", Next_Ptr_Glob->Discr); | ||||
|   printf ("        should be:   %d\n", 0); | ||||
|   | ||||
| @@ -1,22 +1,12 @@ | ||||
| cmake_minimum_required(VERSION 3.21) | ||||
| project(hello-world C) | ||||
| set(TARGET hello) | ||||
| option(HAVE_NO_INIT_FINI "Enable NO_INIT_FINI" OFF) | ||||
|  | ||||
| if(HAVE_NO_INIT_FINI) | ||||
|   #if HAVE_NO_INIT_FINI is ON | ||||
|   add_definitions(-DHAVE_NO_INIT_FINI) | ||||
| endif() | ||||
|  | ||||
| add_executable(${TARGET} hello.c) | ||||
|  | ||||
|  | ||||
|  | ||||
| set(BOARD "iss" CACHE STRING "Target board") | ||||
| message(" BOARD = ${BOARD}") | ||||
| add_subdirectory(../bare-metal-bsp bsp) | ||||
| add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../bare-metal-bsp bsp) | ||||
| target_link_libraries(${TARGET} PRIVATE bsp) | ||||
| target_link_options(${TARGET} PRIVATE -Wl,-Map=${TARGET}.map)   | ||||
| target_link_options(${TARGET} PRIVATE LINKER:-Map=${TARGET}.map)   | ||||
|  | ||||
| add_custom_command(TARGET ${TARGET} POST_BUILD | ||||
|         COMMAND ${CMAKE_OBJDUMP} -S  ${TARGET}.elf > ${TARGET}.dis | ||||
|   | ||||
| @@ -9,62 +9,114 @@ | ||||
|         "patch": 0 | ||||
|     }, | ||||
|     "configurePresets": [ | ||||
|         { | ||||
|             "name": "32imc", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "64imc", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/../bare-metal-bsp/cmake/rv64gc.cmake" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "iss", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "BOARD": "iss" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "moonlight", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "BOARD": "moonlight" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "tgc_vp", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "BOARD": "tgc_vp" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "rtl", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "BOARD": "rtl" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug", | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",        | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_moon", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",   | ||||
|                 "BOARD": "moonlight", | ||||
|                 "HAVE_NO_INIT_FINI": "ON",    | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_tgc", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",   | ||||
|                 "BOARD": "tgc_vp",    | ||||
|                 "HAVE_NO_INIT_FINI": "ON", | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_64", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",        | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_64_moon", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",   | ||||
|                 "BOARD": "moonlight", | ||||
|                 "HAVE_NO_INIT_FINI": "ON",    | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "debug_64_tgc", | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Debug",   | ||||
|                 "BOARD": "tgc_vp",    | ||||
|                 "HAVE_NO_INIT_FINI": "ON", | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" | ||||
|             } | ||||
|                 "CMAKE_BUILD_TYPE": "Debug" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "release", | ||||
|             "cacheVariables": { | ||||
|                 "CMAKE_BUILD_TYPE": "Release",     | ||||
|                 "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" | ||||
|             } | ||||
|             "hidden": true, | ||||
|             "cacheVariables": {     | ||||
|                 "CMAKE_BUILD_TYPE": "Release" | ||||
|             }   | ||||
|         }, | ||||
|         { | ||||
|             "name": "ISS_Debug", | ||||
|             "inherits": ["iss", "debug", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Moonlight_Debug", | ||||
|             "inherits": ["moonlight", "debug", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "TGC_VP_Debug", | ||||
|             "inherits": ["tgc_vp", "debug", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "ISS_Debug_64", | ||||
|             "inherits": ["iss", "debug", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Moonlight_Debug_64", | ||||
|             "hidden": true, | ||||
|             "inherits": ["moonlight", "debug", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "TGC_VP_Debug_64", | ||||
|             "hidden": true, | ||||
|             "inherits": ["tgc_vp", "debug", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "ISS_Release", | ||||
|             "inherits": ["iss", "release", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Moonlight_Release", | ||||
|             "inherits": ["moonlight", "release", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "TGC_VP_Release", | ||||
|             "inherits": ["tgc_vp", "release", "32imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "ISS_Release_64",         | ||||
|             "inherits": ["iss", "release", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Moonlight_Release_64", | ||||
|             "hidden": true, | ||||
|             "inherits": ["moonlight", "release", "64imc"] | ||||
|         }, | ||||
|         { | ||||
|             "name": "TGC_VP_Release_64", | ||||
|             "hidden": true, | ||||
|             "inherits": ["tgc_vp", "release", "64imc"] | ||||
|         } | ||||
|                   | ||||
|     ] | ||||
| } | ||||
| @@ -1,4 +1,3 @@ | ||||
|  | ||||
| TARGET  = hello | ||||
| ISA?=imc | ||||
|  | ||||
|   | ||||
| @@ -3,35 +3,19 @@ | ||||
| #include <sys/types.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #include "encoding.h" | ||||
| #include "platform.h" | ||||
| #include <string.h> | ||||
|  | ||||
| int factorial(int i) { | ||||
|  | ||||
|   volatile int result = 1; | ||||
|   for (int ii = 1; ii <= i; ii++) { | ||||
|     result = result * ii; | ||||
|   } | ||||
|   return result; | ||||
| } | ||||
| extern volatile uintptr_t tohost; | ||||
|  | ||||
| void write_tohost(char *string) { | ||||
|   volatile uint64_t payload[4] = {64, 0, (uintptr_t)string, | ||||
|                                   (strlen(string) + 1)}; | ||||
|   tohost = (uintptr_t)payload; | ||||
| } | ||||
|  | ||||
| int main() { | ||||
|   char string[] = "hello world with write in hello"; | ||||
|  | ||||
|   write_tohost(string); | ||||
|  | ||||
|   write(STDOUT_FILENO, string, sizeof(string)); | ||||
|  | ||||
|   int result = factorial(10); | ||||
|   printf("Factorial is %d", result); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
							
								
								
									
										36
									
								
								lwc/Makefile
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								lwc/Makefile
									
									
									
									
									
								
							| @@ -1,36 +0,0 @@ | ||||
| # Copyright (C) 2021 SCARV project <info@scarv.org> | ||||
| # | ||||
| # Use of this source code is restricted per the MIT license, a copy of which  | ||||
| # can be found at https://opensource.org/licenses/MIT (or should be included  | ||||
| # as LICENSE.txt within the associated archive or repository). | ||||
|  | ||||
| export  REPO_HOME = ${PWD} | ||||
|  | ||||
| # ============================================================================= | ||||
|  | ||||
| export ALG  ?= ascon | ||||
|  | ||||
| export API  ?= aead | ||||
| export ARCH ?= generic | ||||
| export IMP  ?= nist | ||||
| export ISE  ?= xalu | ||||
|  | ||||
| export CONF ?= | ||||
|  | ||||
| # ----------------------------------------------------------------------------- | ||||
|  | ||||
| sw-build : | ||||
| 	@make --directory="${REPO_HOME}/src" build | ||||
| sw-run   : | ||||
| 	@make --directory="${REPO_HOME}/src" run | ||||
| sw-scan  : | ||||
| 	@make --directory="${REPO_HOME}/src" scan | ||||
| sw-clean : | ||||
| 	@make --directory="${REPO_HOME}/src" clean | ||||
|  | ||||
| # ----------------------------------------------------------------------------- | ||||
|  | ||||
| clean : | ||||
| 	@rm --force --recursive ${REPO_HOME}/build/* | ||||
|  | ||||
| # ============================================================================= | ||||
							
								
								
									
										110
									
								
								lwc/src/Makefile
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								lwc/src/Makefile
									
									
									
									
									
								
							| @@ -1,110 +0,0 @@ | ||||
| # Copyright (C) 2021 SCARV project <info@scarv.org> | ||||
| # | ||||
| # Use of this source code is restricted per the MIT license, a copy of which  | ||||
| # can be found at https://opensource.org/licenses/MIT (or should be included  | ||||
| # as LICENSE.txt within the associated archive or repository). | ||||
|  | ||||
| ifndef REPO_HOME | ||||
|   $(error "execute 'source ./bin/conf.sh' to configure environment") | ||||
| endif | ||||
| ifndef REPO_VERSION | ||||
|   $(error "execute 'source ./bin/conf.sh' to configure environment") | ||||
| endif | ||||
|  | ||||
| export API  ?= aead | ||||
|  | ||||
| # ============================================================================= | ||||
|  | ||||
| # include build-related content for algorithm | ||||
| include ./${ALG}/Makefile.in | ||||
|  | ||||
| # include build-related content for architecture | ||||
| include ./share/arch/${ARCH}/Makefile.in | ||||
|  | ||||
| # parameterise source code using environment variables | ||||
| ifeq "${API}" "aead" | ||||
| GCC_FLAGS += -DAPI_AEAD | ||||
| endif | ||||
| ifeq "${API}" "hash" | ||||
| GCC_FLAGS += -DAPI_HASH | ||||
| endif | ||||
| ifeq "${IMP}" "nist" | ||||
| GCC_FLAGS += -DALG="\"${ALG}\"" -DAPI="\"${API}\"" ${CONF} -DARCH="\"${ARCH}\"" -DIMP="\"${IMP}\"" | ||||
| else | ||||
| GCC_FLAGS += -DALG="\"${ALG}\"" -DAPI="\"${API}\"" ${CONF} -DARCH="\"${ARCH}\"" -DIMP="\"${IMP}\"" -DLWISE | ||||
| endif | ||||
|  | ||||
| # ----------------------------------------------------------------------------- | ||||
|  | ||||
| ifeq "${IMP}" "nist" | ||||
| export LWISE_INCLUDES += ${REPO_HOME}/build/${ALG} ./share ./share/nist ./share/arch/${ARCH} | ||||
| else | ||||
| export LWISE_INCLUDES += ${REPO_HOME}/build/${ALG} ./share ./share/nist ./share/arch/${ARCH} ./${ALG}/arch/${ARCH} ./${ALG}/imp/${IMP} ./${ALG}/imp/share | ||||
| endif | ||||
|  | ||||
| export LWISE_SOURCES  += $(wildcard $(addsuffix /*.c,   ${LWISE_INCLUDES}))  | ||||
| export LWISE_SOURCES  += $(wildcard $(addsuffix /*.cpp, ${LWISE_INCLUDES}))  | ||||
| export LWISE_SOURCES  += $(wildcard $(addsuffix /*.s,   ${LWISE_INCLUDES})) | ||||
| export LWISE_SOURCES  += $(wildcard $(addsuffix /*.S,   ${LWISE_INCLUDES})) | ||||
| export LWISE_HEADERS  += $(wildcard $(addsuffix /*.h,   ${LWISE_INCLUDES})) | ||||
|  | ||||
| export       INCLUDES := ${LWISE_INCLUDES} ${NIST_INCLUDES} | ||||
|  | ||||
| export       SOURCES  := ${LWISE_SOURCES}  ${NIST_SOURCES} ${REPO_HOME}/build/${ALG}/kat_${API}.c  | ||||
| export       HEADERS  := ${LWISE_HEADERS}  ${NIST_HEADERS} ${REPO_HOME}/build/${ALG}/kat_${API}.h  | ||||
|  | ||||
| export       TARGETS  += ${REPO_HOME}/build/${ALG} | ||||
| export       TARGETS  += ${REPO_HOME}/build/${ALG}/kat_${API}.h | ||||
| export       TARGETS  += ${REPO_HOME}/build/${ALG}/kat_${API}.c | ||||
| export       TARGETS  += ${REPO_HOME}/build/${ALG}/driver-${API}_${ARCH}_${IMP}.elf | ||||
| export       TARGETS  += ${REPO_HOME}/build/${ALG}/driver-${API}_${ARCH}_${IMP}.asm | ||||
|  | ||||
| # ----------------------------------------------------------------------------- | ||||
|  | ||||
| ${REPO_HOME}/build/${ALG}       : | ||||
| 	@mkdir --parents ${@} | ||||
|  | ||||
| ${REPO_HOME}/build/${ALG}/kat_${API}.h : ${NIST_KAT} | ||||
| 	@python3 ./share/kat.py --api="${API}" --header < ${<} > ${@} | ||||
| ${REPO_HOME}/build/${ALG}/kat_${API}.c : ${NIST_KAT} | ||||
| 	@python3 ./share/kat.py --api="${API}" --source < ${<} > ${@} | ||||
|  | ||||
| ${REPO_HOME}/build/${ALG}/driver-${API}_${ARCH}_${IMP}.elf : ${SOURCES}  | ||||
| 	@${GCC_PREFIX}-gcc ${GCC_FLAGS} ${GCC_PATHS} $(addprefix -I ,${INCLUDES}) -std='gnu99' -O3 -o ${@} $(filter %.c, ${^}) $(filter %.cpp, ${^}) $(filter %.S, ${^}) ${GCC_LIBS} | ||||
|  | ||||
| ${REPO_HOME}/build/${ALG}/driver-${API}_${ARCH}_${IMP}.asm : ${REPO_HOME}/build/${ALG}/driver-${API}_${ARCH}_${IMP}.elf | ||||
| 	@${GCC_PREFIX}-objdump --disassemble-all ${<} > ${@} | ||||
|  | ||||
| # ----------------------------------------------------------------------------- | ||||
|  | ||||
| .PHONY : run debug scan | ||||
|  | ||||
| dump  : | ||||
| 	@echo "ALG        = ${ALG}" | ||||
|  | ||||
| 	@echo "API        = ${API}" | ||||
| 	@echo "ARCH       = ${ARCH}" | ||||
| 	@echo "IMP        = ${IMP}" | ||||
|  | ||||
| 	@echo "CONF       = ${CONF}" | ||||
|  | ||||
| 	@echo "NIST_HOME  = ${NIST_HOME}" | ||||
| 	@echo "NIST_IMP   = ${NIST_IMP}" | ||||
| 	@echo "NIST_KAT   = ${NIST_KAT}" | ||||
|  | ||||
| 	@echo "GCC_PREFIX = ${GCC_PREFIX}" | ||||
| 	@echo "GCC_PATHS  = ${GCC_PATHS}" | ||||
| 	@echo "GCC_FLAGS  = ${GCC_FLAGS}" | ||||
| 	@echo "GCC_LIBS   = ${GCC_LIBS}" | ||||
|  | ||||
| 	@echo "INCLUDES   = ${INCLUDES}" | ||||
| 	@echo "SOURCES    = ${SOURCES}" | ||||
| 	@echo "HEADERS    = ${HEADERS}" | ||||
| 	@echo "TARGETS    = ${TARGETS}" | ||||
|  | ||||
| build : ${TARGETS} | ||||
|  | ||||
| clean :  | ||||
| 	@rm --force --recursive ${TARGETS} | ||||
|  | ||||
| # ============================================================================= | ||||
| @@ -1,39 +0,0 @@ | ||||
| # Copyright (C) 2021 SCARV project <info@scarv.org> | ||||
| # | ||||
| # Use of this source code is restricted per the MIT license, a copy of which  | ||||
| # can be found at https://opensource.org/licenses/MIT (or should be included  | ||||
| # as LICENSE.txt within the associated archive or repository). | ||||
|  | ||||
| # ============================================================================= | ||||
|  | ||||
| ifeq "${API}" "aead" | ||||
| export NIST_HOME     ?= ${REPO_HOME}/src/ascon/nist/Implementations/crypto_aead/ascon128v12 | ||||
| export NIST_IMP      ?= ref | ||||
| export NIST_KAT      ?= ${NIST_HOME}/LWC_AEAD_KAT_128_128.txt | ||||
|  | ||||
| export NIST_INCLUDES  = ${NIST_HOME}/${NIST_IMP} | ||||
|  | ||||
| export NIST_SOURCES   = $(wildcard ${NIST_HOME}/${NIST_IMP}/*.c  ) | ||||
| export NIST_SOURCES  += $(wildcard ${NIST_HOME}/${NIST_IMP}/*.cpp)  | ||||
| export NIST_SOURCES  += $(wildcard ${NIST_HOME}/${NIST_IMP}/*.s  )  | ||||
| export NIST_SOURCES  += $(wildcard ${NIST_HOME}/${NIST_IMP}/*.S  ) | ||||
| export NIST_HEADERS   = $(wildcard ${NIST_HOME}/${NIST_IMP}/*.h  ) | ||||
| endif | ||||
|  | ||||
| # ----------------------------------------------------------------------------- | ||||
|  | ||||
| ifeq "${API}" "hash" | ||||
| export NIST_HOME     ?= ${REPO_HOME}/src/ascon/nist/Implementations/crypto_hash/asconhashv12 | ||||
| export NIST_IMP      ?= ref | ||||
| export NIST_KAT      ?= ${NIST_HOME}/LWC_HASH_KAT_256.txt | ||||
|  | ||||
| export NIST_INCLUDES  = ${NIST_HOME}/${NIST_IMP} | ||||
|  | ||||
| export NIST_SOURCES   = $(wildcard ${NIST_HOME}/${NIST_IMP}/*.c  ) | ||||
| export NIST_SOURCES  += $(wildcard ${NIST_HOME}/${NIST_IMP}/*.cpp)  | ||||
| export NIST_SOURCES  += $(wildcard ${NIST_HOME}/${NIST_IMP}/*.s  )  | ||||
| export NIST_SOURCES  += $(wildcard ${NIST_HOME}/${NIST_IMP}/*.S  ) | ||||
| export NIST_HEADERS   = $(wildcard ${NIST_HOME}/${NIST_IMP}/*.h  ) | ||||
| endif | ||||
|  | ||||
| # ============================================================================= | ||||
| @@ -1,18 +0,0 @@ | ||||
| // Copyright (C) 2021 SCARV project <info@scarv.org> | ||||
| // | ||||
| // Use of this source code is restricted per the MIT license, a copy of which  | ||||
| // can be found at https://opensource.org/licenses/MIT (or should be included  | ||||
| // as LICENSE.txt within the associated archive or repository). | ||||
|  | ||||
| // ============================================================================ | ||||
|  | ||||
| #if ( ASCON_RV32_TYPE2 ) | ||||
| .macro ascon.sigma.lo       rd, rs1, rs2, imm | ||||
| .insn r CUSTOM_1, 7, \imm+( 0*32), \rd, \rs1, \rs2 | ||||
| .endm | ||||
| .macro ascon.sigma.hi       rd, rs1, rs2, imm | ||||
| .insn r CUSTOM_1, 7, \imm+( 1*32), \rd, \rs1, \rs2 | ||||
| .endm | ||||
| #endif | ||||
|  | ||||
| // ============================================================================ | ||||
| @@ -1,15 +0,0 @@ | ||||
| // Copyright (C) 2021 SCARV project <info@scarv.org> | ||||
| // | ||||
| // Use of this source code is restricted per the MIT license, a copy of which  | ||||
| // can be found at https://opensource.org/licenses/MIT (or should be included  | ||||
| // as LICENSE.txt within the associated archive or repository). | ||||
|  | ||||
| // ============================================================================ | ||||
|  | ||||
| #if ( ASCON_RV64_TYPE2 ) | ||||
| .macro ascon.sigma          rd, rs1,      imm | ||||
| .insn r CUSTOM_1, 6, \imm+( 2*32), \rd, \rs1,   x0 | ||||
| .endm | ||||
| #endif | ||||
|  | ||||
| // ============================================================================ | ||||
| @@ -1,35 +0,0 @@ | ||||
| # Copyright (C) 2021 SCARV project <info@scarv.org> | ||||
| # | ||||
| # Use of this source code is restricted per the MIT license, a copy of which  | ||||
| # can be found at https://opensource.org/licenses/MIT (or should be included  | ||||
| # as LICENSE.txt within the associated archive or repository). | ||||
|  | ||||
| import driver, itertools | ||||
|  | ||||
| # ============================================================================= | ||||
|  | ||||
| def rv32( args ) : | ||||
|   if ( args.prog ) : | ||||
|     driver.program_fpga( args, 'ascon', 'rv32', 'xalu' ) | ||||
|   if ( args.nist ) : | ||||
|     CONF = ['DRIVER_BYPASS_TEST'] | ||||
|     driver.run( args, 'ascon', CONF, 'rv32', 'nist', NIST_IMP = 'ref' ) | ||||
|  | ||||
|   for TYPE in [ 'ASCON_RV32_TYPE1', 'ASCON_RV32_TYPE2' ] : | ||||
|     CONF = [ TYPE ] | ||||
|     # there is only unrolled implementation for Ascon on rv32 | ||||
|     CONF += ['ASCON_RV32_UNROLL'] | ||||
|     CONF += ['DRIVER_BYPASS_TEST'] | ||||
|     driver.run( args, 'ascon', CONF, 'rv32', 'rv32' ) | ||||
|  | ||||
| # ----------------------------------------------------------------------------- | ||||
|  | ||||
| def rv64( args ) : | ||||
|     pass | ||||
|  | ||||
| # ----------------------------------------------------------------------------- | ||||
|  | ||||
| if ( __name__ == '__main__' ) : | ||||
|   driver.main( rv32, rv64 ) | ||||
|  | ||||
| # ============================================================================= | ||||
| @@ -1,272 +0,0 @@ | ||||
| #include "zbkb.h" | ||||
| #include "zbkx.h" | ||||
| #include "ise.h" | ||||
|  | ||||
|  | ||||
| // ---------------------------------------------------------------------------- | ||||
| // Register Allocation | ||||
| // (use caller-saved registers to save push/pop instructions)   | ||||
| // | ||||
| // a0:           the address of state | ||||
| // a2-a7, t2-t5: state | ||||
| // t0-t1, t6:    temp registers | ||||
| //  | ||||
| // Comments:  | ||||
| // Excluding resigers storing the state, this implementation needs only three | ||||
| // additional registers for temp use, which might be useful for other platforms | ||||
| // with smaller register space (e.g., AVR, ARM Cortex-M).   | ||||
| // ---------------------------------------------------------------------------- | ||||
|  | ||||
|  | ||||
| // prologue + epilogue  | ||||
|  | ||||
| .macro ASCON_PROLOGUE | ||||
| .endm | ||||
|  | ||||
| .macro ASCON_EPILOGUE | ||||
|   ret | ||||
| .endm | ||||
|  | ||||
|  | ||||
| // load state + store state   | ||||
|  | ||||
| .macro ASCON_LDSTATE x0l, x0h, x1l, x1h, x2l, x2h, x3l, x3h, x4l, x4h | ||||
|   lw   \x0l,  0(a0) | ||||
|   lw   \x0h,  4(a0) | ||||
|   lw   \x1l,  8(a0) | ||||
|   lw   \x1h, 12(a0) | ||||
|   lw   \x2l, 16(a0) | ||||
|   lw   \x2h, 20(a0) | ||||
|   lw   \x3l, 24(a0) | ||||
|   lw   \x3h, 28(a0) | ||||
|   lw   \x4l, 32(a0) | ||||
|   lw   \x4h, 36(a0) | ||||
| .endm | ||||
|  | ||||
| .macro ASCON_STSTATE x0l, x0h, x1l, x1h, x2l, x2h, x3l, x3h, x4l, x4h | ||||
|   sw   \x0l,  0(a0) | ||||
|   sw   \x0h,  4(a0) | ||||
|   sw   \x1l,  8(a0) | ||||
|   sw   \x1h, 12(a0) | ||||
|   sw   \x2l, 16(a0) | ||||
|   sw   \x2h, 20(a0) | ||||
|   sw   \x3l, 24(a0) | ||||
|   sw   \x3h, 28(a0) | ||||
|   sw   \x4l, 32(a0) | ||||
|   sw   \x4h, 36(a0) | ||||
| .endm | ||||
|  | ||||
|  | ||||
| // layers: PC + PS + PL | ||||
|  | ||||
| // PC: addition of constants | ||||
|  | ||||
| .macro ASCON_PC x2l, rci | ||||
|   xori \x2l, \x2l, \rci | ||||
| .endm | ||||
|  | ||||
| // PS: SBox x0 x1 x2 x3 x4 -> x3 x1 x2 x0 x4 | ||||
|  | ||||
| .macro ASCON_PS x0, x1, x2, x3, x4, t0, t1, t2, t3 | ||||
|   xor  \t2, \x1, \x2    // t2 = x1 ^ x2 | ||||
|   xor  \t0, \x0, \x4    // t0 = x0 ^ x4 | ||||
|   xor  \t1, \x3, \x4    // t1 = x3 ^ x4  | ||||
|  | ||||
|   orn  \x2, \x3, \x4    // x2 = x3 | ~x4 | ||||
|   xor  \x2, \x2, \t2    // x2 = x1 ^ x2 ^ (x3 | ~x4) | ||||
|  | ||||
|   andn \x4, \x1, \t0    // x4 = x1 & ~(x0 ^ x4) | ||||
|   xor  \x4, \x4, \t1    // x4 = x3 ^ x4 ^ (x1 & ~(x0 ^ x4)) | ||||
|  | ||||
|   or   \x0, \x0, \t1    // x0 = x0 | (x3 ^ x4) | ||||
|   xor  \x3, \x1, \x3    // x3 = x1 ^ x3 | ||||
|   xor  \x0, \x0, \t2    // x0 = x1 ^ x2 ^ (x0 | (x3 ^ x4)) | ||||
|  | ||||
|   or   \x3, \x3, \t2    // x3 = (x1 ^ x3) | (x1 ^ x2) | ||||
|   xor  \t2, \t2, \t0    // t2 =  x0 ^ x4 ^ x1 ^ x2 | ||||
|   or   \t2, \t2, \x1    // t2 = x1 | (x0 ^ x4 ^ x1 ^ x2) | ||||
|  | ||||
|   xor  \x1, \t0, \x3    // x1 = x0 ^ x4 ^ ((x1 ^ x3) | (x1 ^ x2)) | ||||
|   xor  \x3, \t1, \t2    // x3 = x3 ^ x4 ^ (x1 | (x0 ^ x4 ^ x1 ^ x2))  | ||||
| .endm  | ||||
|  | ||||
| // PL: linear diffusion | ||||
|  | ||||
| #if (ASCON_RV32_TYPE1) | ||||
| // 64-bit rotate right (immediate) | ||||
|  | ||||
| .macro ASCON_RORI64L dl, sl, sh, imm, t0 | ||||
|   srli \t0, \sl, \imm | ||||
|   slli \dl, \sh, 32-\imm | ||||
|   xor  \dl, \t0, \dl   | ||||
| .endm  | ||||
|  | ||||
| .macro ASCON_RORI64H_0 dh, sl, sh, imm, t0 | ||||
|   slli \t0, \sl, 32-\imm | ||||
|   srli \dh, \sh, \imm | ||||
|   xor  \dh, \t0, \dh   | ||||
| .endm  | ||||
|  | ||||
| .macro ASCON_RORI64H_1 dh, sl, sh, imm, t0, t1 | ||||
|   slli \t0, \sl, 32-\imm | ||||
|   xor  \sl, \sl, \t1  | ||||
|   srli \t1, \sh, \imm | ||||
|   xor  \dh, \t0, \t1   | ||||
| .endm  | ||||
|  | ||||
| // 64-bit rotate left (immediate) | ||||
|  | ||||
| .macro ASCON_ROLI64L dl, sl, sh, imm, t0 | ||||
|   slli \t0, \sl, \imm | ||||
|   srli \dl, \sh, 32-\imm | ||||
|   xor  \dl, \t0, \dl  | ||||
| .endm  | ||||
|  | ||||
| .macro ASCON_ROLI64H_0 dh, sl, sh, imm, t0 | ||||
|   srli \t0, \sl, 32-\imm | ||||
|   slli \dh, \sh, \imm | ||||
|   xor  \dh, \t0, \dh | ||||
| .endm  | ||||
|  | ||||
| .macro ASCON_ROLI64H_1 dh, sl, sh, imm, t0, t1 | ||||
|   srli \t0, \sl, 32-\imm | ||||
|   xor  \sl, \sl, \t1  | ||||
|   slli \t1, \sh, \imm | ||||
|   xor  \dh, \t0, \t1 | ||||
| .endm  | ||||
|  | ||||
| .macro ASCON_PL_STEP_0 xl, xh, imm0, imm1, t0, t1, t2  | ||||
|   ASCON_RORI64L   \t1, \xl, \xh, \imm0, \t0  | ||||
|   ASCON_RORI64L   \t2, \xl, \xh, \imm1, \t0  | ||||
|   xor             \t1, \t1, \t2 | ||||
|   ASCON_RORI64H_0 \t2, \xl, \xh, \imm0, \t0 | ||||
|   ASCON_RORI64H_1 \t1, \xl, \xh, \imm1, \t0, \t1 | ||||
|   xor             \t1, \t2, \t1 | ||||
|   xor             \xh, \xh, \t1 | ||||
| .endm  | ||||
|  | ||||
| .macro ASCON_PL_STEP_1 xl, xh, imm0, imm1, t0, t1, t2  | ||||
|   ASCON_ROLI64L   \t1, \xl, \xh, \imm0, \t0  | ||||
|   ASCON_ROLI64L   \t2, \xl, \xh, \imm1, \t0  | ||||
|   xor             \t1, \t1, \t2 | ||||
|   ASCON_ROLI64H_0 \t2, \xl, \xh, \imm0, \t0 | ||||
|   ASCON_ROLI64H_1 \t1, \xl, \xh, \imm1, \t0, \t1 | ||||
|   xor             \t1, \t2, \t1 | ||||
|   xor             \xh, \xh, \t1 | ||||
| .endm  | ||||
|  | ||||
| .macro ASCON_PL_STEP_2 xl, xh, imm0, imm1, t0, t1, t2  | ||||
|   ASCON_RORI64L   \t1, \xl, \xh, \imm0, \t0  | ||||
|   ASCON_ROLI64L   \t2, \xl, \xh, \imm1, \t0  | ||||
|   xor             \t1, \t1, \t2 | ||||
|   ASCON_RORI64H_0 \t2, \xl, \xh, \imm0, \t0 | ||||
|   ASCON_ROLI64H_1 \t1, \xl, \xh, \imm1, \t0, \t1 | ||||
|   xor             \t1, \t2, \t1 | ||||
|   xor             \xh, \xh, \t1 | ||||
| .endm  | ||||
|  | ||||
| .macro ASCON_PL x0l, x0h, x1l, x1h, x2l, x2h, x3l, x3h, x4l, x4h, t0, t1, t2 | ||||
|   ASCON_PL_STEP_0 \x0l, \x0h, 19, 28, \t0, \t1, \t2 | ||||
|   ASCON_PL_STEP_1 \x1l, \x1h,  3, 25, \t0, \t1, \t2 | ||||
|   ASCON_PL_STEP_0 \x2l, \x2h,  1,  6, \t0, \t1, \t2 | ||||
|   ASCON_PL_STEP_0 \x3l, \x3h, 10, 17, \t0, \t1, \t2 | ||||
|   ASCON_PL_STEP_2 \x4l, \x4h,  7, 23, \t0, \t1, \t2 | ||||
| .endm | ||||
| #elif (ASCON_RV32_TYPE2) | ||||
| //  x0l, x0h, x1l, x1h, x2l, x2h, x3l, x3h, x4l, x4h ->  | ||||
| //  t0l, t0h, x0l, x0h, x1l, x1h, x2l, x2h, x3l, x3h  | ||||
|  | ||||
| .macro ASCON_PL x0l, x0h, x1l, x1h, x2l, x2h, x3l, x3h, x4l, x4h, t0l, t0h, t2 | ||||
|   ascon.sigma.lo \t0l, \x0l, \x0h, 0 | ||||
|   ascon.sigma.hi \t0h, \x0l, \x0h, 0 | ||||
|   ascon.sigma.lo \x0l, \x1l, \x1h, 1 | ||||
|   ascon.sigma.hi \x0h, \x1l, \x1h, 1 | ||||
|   ascon.sigma.lo \x1l, \x2l, \x2h, 2 | ||||
|   ascon.sigma.hi \x1h, \x2l, \x2h, 2 | ||||
|   ascon.sigma.lo \x2l, \x3l, \x3h, 3 | ||||
|   ascon.sigma.hi \x2h, \x3l, \x3h, 3 | ||||
|   ascon.sigma.lo \x3l, \x4l, \x4h, 4 | ||||
|   ascon.sigma.hi \x3h, \x4l, \x4h, 4 | ||||
| .endm | ||||
| #endif | ||||
|  | ||||
|  | ||||
| // operations in each round   | ||||
|  | ||||
| .macro ASCON_ROUND x0l, x0h, x1l, x1h, x2l, x2h, x3l, x3h, x4l, x4h, rci, t0, t1, t2 | ||||
|   ASCON_PC \x2l, \rci | ||||
|   ASCON_PS \x0l, \x1l, \x2l, \x3l, \x4l, \t0, \t1, \t2 | ||||
|   ASCON_PS \x0h, \x1h, \x2h, \x3h, \x4h, \t0, \t1, \t2 | ||||
|   ASCON_PL \x3l, \x3h, \x1l, \x1h, \x2l, \x2h, \x0l, \x0h, \x4l, \x4h, \t0, \t1, \t2 | ||||
| .endm  | ||||
|  | ||||
|  | ||||
| // Ascon permutation  | ||||
|  | ||||
| .section .text | ||||
|  | ||||
| .global P6 | ||||
|  | ||||
| P6: | ||||
|   ASCON_PROLOGUE | ||||
|   ASCON_LDSTATE a2, a3, a4, a5, a6, a7, t2, t3, t4, t5 | ||||
|   // | ||||
| #if (ASCON_RV32_TYPE1) | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0x96, t0, t1, t6  | ||||
|   ASCON_ROUND   t2, t3, a4, a5, a6, a7, a2, a3, t4, t5, 0x87, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0x78, t0, t1, t6  | ||||
|   ASCON_ROUND   t2, t3, a4, a5, a6, a7, a2, a3, t4, t5, 0x69, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0x5A, t0, t1, t6  | ||||
|   ASCON_ROUND   t2, t3, a4, a5, a6, a7, a2, a3, t4, t5, 0x4B, t0, t1, t6  | ||||
| #elif (ASCON_RV32_TYPE2) | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0x96, t0, t1, t6  | ||||
|   ASCON_ROUND   t0, t1, t2, t3, a4, a5, a6, a7, a2, a3, 0x87, t4, t5, t6  | ||||
|   ASCON_ROUND   t4, t5, a6, a7, t2, t3, a4, a5, t0, t1, 0x78, a2, a3, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0x69, t0, t1, t6  | ||||
|   ASCON_ROUND   t0, t1, t2, t3, a4, a5, a6, a7, a2, a3, 0x5A, t4, t5, t6  | ||||
|   ASCON_ROUND   t4, t5, a6, a7, t2, t3, a4, a5, t0, t1, 0x4B, a2, a3, t6  | ||||
| #endif | ||||
|   // | ||||
|   ASCON_STSTATE a2, a3, a4, a5, a6, a7, t2, t3, t4, t5 | ||||
|   ASCON_EPILOGUE | ||||
|  | ||||
|  | ||||
| .section .text | ||||
|  | ||||
| .global P12 | ||||
|  | ||||
| P12: | ||||
|   ASCON_PROLOGUE | ||||
|   ASCON_LDSTATE a2, a3, a4, a5, a6, a7, t2, t3, t4, t5 | ||||
|   // | ||||
| #if (ASCON_RV32_TYPE1) | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0xF0, t0, t1, t6  | ||||
|   ASCON_ROUND   t2, t3, a4, a5, a6, a7, a2, a3, t4, t5, 0xE1, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0xD2, t0, t1, t6  | ||||
|   ASCON_ROUND   t2, t3, a4, a5, a6, a7, a2, a3, t4, t5, 0xC3, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0xB4, t0, t1, t6  | ||||
|   ASCON_ROUND   t2, t3, a4, a5, a6, a7, a2, a3, t4, t5, 0xA5, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0x96, t0, t1, t6  | ||||
|   ASCON_ROUND   t2, t3, a4, a5, a6, a7, a2, a3, t4, t5, 0x87, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0x78, t0, t1, t6  | ||||
|   ASCON_ROUND   t2, t3, a4, a5, a6, a7, a2, a3, t4, t5, 0x69, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0x5A, t0, t1, t6  | ||||
|   ASCON_ROUND   t2, t3, a4, a5, a6, a7, a2, a3, t4, t5, 0x4B, t0, t1, t6  | ||||
| #elif (ASCON_RV32_TYPE2) | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0xF0, t0, t1, t6  | ||||
|   ASCON_ROUND   t0, t1, t2, t3, a4, a5, a6, a7, a2, a3, 0xE1, t4, t5, t6  | ||||
|   ASCON_ROUND   t4, t5, a6, a7, t2, t3, a4, a5, t0, t1, 0xD2, a2, a3, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0xC3, t0, t1, t6  | ||||
|   ASCON_ROUND   t0, t1, t2, t3, a4, a5, a6, a7, a2, a3, 0xB4, t4, t5, t6  | ||||
|   ASCON_ROUND   t4, t5, a6, a7, t2, t3, a4, a5, t0, t1, 0xA5, a2, a3, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0x96, t0, t1, t6  | ||||
|   ASCON_ROUND   t0, t1, t2, t3, a4, a5, a6, a7, a2, a3, 0x87, t4, t5, t6  | ||||
|   ASCON_ROUND   t4, t5, a6, a7, t2, t3, a4, a5, t0, t1, 0x78, a2, a3, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, a7, t2, t3, t4, t5, 0x69, t0, t1, t6  | ||||
|   ASCON_ROUND   t0, t1, t2, t3, a4, a5, a6, a7, a2, a3, 0x5A, t4, t5, t6  | ||||
|   ASCON_ROUND   t4, t5, a6, a7, t2, t3, a4, a5, t0, t1, 0x4B, a2, a3, t6  | ||||
| #endif | ||||
|   // | ||||
|   ASCON_STSTATE a2, a3, a4, a5, a6, a7, t2, t3, t4, t5 | ||||
|   ASCON_EPILOGUE | ||||
|      | ||||
| @@ -1,158 +0,0 @@ | ||||
| #include "zbkb.h" | ||||
| #include "zbkx.h" | ||||
| #include "ise.h" | ||||
|  | ||||
|  | ||||
| // ---------------------------------------------------------------------------- | ||||
| // Register Allocation | ||||
| // (use caller-saved registers to save push/pop instructions)   | ||||
| // | ||||
| // a0:         the address of state | ||||
| // a2-a6:      state | ||||
| // t0-t1, t6:  temp registers | ||||
| // ---------------------------------------------------------------------------- | ||||
|  | ||||
|  | ||||
| // prologue + epilogue  | ||||
|  | ||||
| .macro ASCON_PROLOGUE | ||||
| .endm | ||||
|  | ||||
| .macro ASCON_EPILOGUE | ||||
|   ret | ||||
| .endm | ||||
|  | ||||
|  | ||||
| // load state + store state   | ||||
|  | ||||
| .macro ASCON_LDSTATE x0, x1, x2, x3, x4 | ||||
|   ld   \x0,  0(a0) | ||||
|   ld   \x1,  8(a0) | ||||
|   ld   \x2, 16(a0) | ||||
|   ld   \x3, 24(a0) | ||||
|   ld   \x4, 32(a0) | ||||
| .endm | ||||
|  | ||||
| .macro ASCON_STSTATE x0, x1, x2, x3, x4 | ||||
|   sd   \x0,  0(a0) | ||||
|   sd   \x1,  8(a0) | ||||
|   sd   \x2, 16(a0) | ||||
|   sd   \x3, 24(a0) | ||||
|   sd   \x4, 32(a0) | ||||
| .endm | ||||
|  | ||||
|  | ||||
| // layers: PC + PS + PL | ||||
|  | ||||
| // PC: addition of constants | ||||
|  | ||||
| .macro ASCON_PC x2, rci | ||||
|   xori \x2, \x2, \rci | ||||
| .endm | ||||
|  | ||||
| // PS: SBox x0 x1 x2 x3 x4 -> x3 x1 x2 x0 x4 | ||||
|  | ||||
| .macro ASCON_PS x0, x1, x2, x3, x4, t0, t1, t2 | ||||
|   xor  \t2, \x1, \x2    // t2 = x1 ^ x2 | ||||
|   xor  \t0, \x0, \x4    // t0 = x0 ^ x4 | ||||
|   xor  \t1, \x3, \x4    // t1 = x3 ^ x4  | ||||
|  | ||||
|   orn  \x2, \x3, \x4    // x2 = x3 | ~x4 | ||||
|   xor  \x2, \x2, \t2    // x2 = x1 ^ x2 ^ (x3 | ~x4) | ||||
|  | ||||
|   andn \x4, \x1, \t0    // x4 = x1 & ~(x0 ^ x4) | ||||
|   xor  \x4, \x4, \t1    // x4 = x3 ^ x4 ^ (x1 & ~(x0 ^ x4)) | ||||
|  | ||||
|   or   \x0, \x0, \t1    // x0 = x0 | (x3 ^ x4) | ||||
|   xor  \x3, \x1, \x3    // x3 = x1 ^ x3 | ||||
|   xor  \x0, \x0, \t2    // x0 = x1 ^ x2 ^ (x0 | (x3 ^ x4)) | ||||
|  | ||||
|   or   \x3, \x3, \t2    // x3 = (x1 ^ x3) | (x1 ^ x2) | ||||
|   xor  \t2, \t2, \t0    // t2 =  x0 ^ x4 ^ x1 ^ x2 | ||||
|   or   \t2, \t2, \x1    // t2 = x1 | (x0 ^ x4 ^ x1 ^ x2) | ||||
|  | ||||
|   xor  \x1, \t0, \x3    // x1 = x0 ^ x4 ^ ((x1 ^ x3) | (x1 ^ x2)) | ||||
|   xor  \x3, \t1, \t2    // x3 = x3 ^ x4 ^ (x1 | (x0 ^ x4 ^ x1 ^ x2))  | ||||
| .endm  | ||||
|  | ||||
| // PL: linear diffusion | ||||
|  | ||||
| #if (ASCON_RV64_TYPE1) | ||||
| .macro ASCON_PL_STEP x0, imm0, imm1, t0 | ||||
|   rori \t0, \x0, \imm0 | ||||
|   xor  \t0, \x0, \t0 | ||||
|   rori \x0, \x0, \imm1 | ||||
|   xor  \x0, \t0, \x0 | ||||
| .endm | ||||
|  | ||||
| .macro ASCON_PL x0, x1, x2, x3, x4, t0 | ||||
|   ASCON_PL_STEP \x0, 19, 28, \t0 | ||||
|   ASCON_PL_STEP \x1, 61, 39, \t0 | ||||
|   ASCON_PL_STEP \x2,  1,  6, \t0 | ||||
|   ASCON_PL_STEP \x3, 10, 17, \t0 | ||||
|   ASCON_PL_STEP \x4,  7, 41, \t0 | ||||
| .endm | ||||
| #elif (ASCON_RV64_TYPE2) | ||||
| .macro ASCON_PL x0, x1, x2, x3, x4, t0 | ||||
|   ascon.sigma \x0, \x0, 0 | ||||
|   ascon.sigma \x1, \x1, 1 | ||||
|   ascon.sigma \x2, \x2, 2 | ||||
|   ascon.sigma \x3, \x3, 3 | ||||
|   ascon.sigma \x4, \x4, 4 | ||||
| .endm | ||||
| #endif | ||||
|  | ||||
|  | ||||
| // operations in each round    | ||||
|  | ||||
| .macro ASCON_ROUND x0, x1, x2, x3, x4, rci, t0, t1, t2 | ||||
|   ASCON_PC \x2, \rci | ||||
|   ASCON_PS \x0, \x1, \x2, \x3, \x4, \t0, \t1, \t2 | ||||
|   ASCON_PL \x3, \x1, \x2, \x0, \x4, \t0 | ||||
| .endm  | ||||
|  | ||||
|  | ||||
| // Ascon permutation  | ||||
|  | ||||
| .section .text | ||||
|  | ||||
| .global P6 | ||||
|  | ||||
| P6: | ||||
|   ASCON_PROLOGUE | ||||
|   ASCON_LDSTATE a2, a3, a4, a5, a6 | ||||
|   // | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, 0x96, t0, t1, t6  | ||||
|   ASCON_ROUND   a5, a3, a4, a2, a6, 0x87, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, 0x78, t0, t1, t6  | ||||
|   ASCON_ROUND   a5, a3, a4, a2, a6, 0x69, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, 0x5A, t0, t1, t6  | ||||
|   ASCON_ROUND   a5, a3, a4, a2, a6, 0x4B, t0, t1, t6  | ||||
|   // | ||||
|   ASCON_STSTATE a2, a3, a4, a5, a6 | ||||
|   ASCON_EPILOGUE | ||||
|  | ||||
|  | ||||
| .section .text | ||||
|  | ||||
| .global P12 | ||||
|  | ||||
| P12: | ||||
|   ASCON_PROLOGUE | ||||
|   ASCON_LDSTATE a2, a3, a4, a5, a6 | ||||
|   // | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, 0xF0, t0, t1, t6  | ||||
|   ASCON_ROUND   a5, a3, a4, a2, a6, 0xE1, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, 0xD2, t0, t1, t6  | ||||
|   ASCON_ROUND   a5, a3, a4, a2, a6, 0xC3, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, 0xB4, t0, t1, t6  | ||||
|   ASCON_ROUND   a5, a3, a4, a2, a6, 0xA5, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, 0x96, t0, t1, t6  | ||||
|   ASCON_ROUND   a5, a3, a4, a2, a6, 0x87, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, 0x78, t0, t1, t6  | ||||
|   ASCON_ROUND   a5, a3, a4, a2, a6, 0x69, t0, t1, t6  | ||||
|   ASCON_ROUND   a2, a3, a4, a5, a6, 0x5A, t0, t1, t6  | ||||
|   ASCON_ROUND   a5, a3, a4, a2, a6, 0x4B, t0, t1, t6  | ||||
|   // | ||||
|   ASCON_STSTATE a2, a3, a4, a5, a6 | ||||
|   ASCON_EPILOGUE | ||||
| @@ -1 +0,0 @@ | ||||
| https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-submissions/ascon.zip | ||||
| @@ -1,3 +0,0 @@ | ||||
| version https://git-lfs.github.com/spec/v1 | ||||
| oid sha256:07a2bc8432612d260cef0945e6a16ff9aa94c9279a2e83b76ae984fdbe8b1a5d | ||||
| size 2032754 | ||||
| @@ -1,3 +0,0 @@ | ||||
| version https://git-lfs.github.com/spec/v1 | ||||
| oid sha256:49403e24b9cd05a234d27c5a7f37e3f28de52c8f8db07ac744515be225bd7aa6 | ||||
| size 485542 | ||||
| @@ -1,3 +0,0 @@ | ||||
| version https://git-lfs.github.com/spec/v1 | ||||
| oid sha256:68eb5de5bbe2c1d19a212827f9daaec22b49777e93f4fed6300764bbbd5aa480 | ||||
| size 153824 | ||||
| @@ -1,3 +0,0 @@ | ||||
| version https://git-lfs.github.com/spec/v1 | ||||
| oid sha256:ffbefd2edd8d997de9157c2bf6ea6bfaa53e03e8ce26f1ee136108ae924b127e | ||||
| size 164033 | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,237 +0,0 @@ | ||||
| #include "api.h" | ||||
| #include "ascon.h" | ||||
| #include "crypto_aead.h" | ||||
| #include "permutations.h" | ||||
| #include "printstate.h" | ||||
|  | ||||
| #define AVX512_SHUFFLE_U64BIG                                  \ | ||||
|   _mm512_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, /* word 7 */ \ | ||||
|                   -1, -1, -1, -1, -1, -1, -1, -1, /* word 6 */ \ | ||||
|                   -1, -1, -1, -1, -1, -1, -1, -1, /* word 5 */ \ | ||||
|                   -1, -1, -1, -1, -1, -1, -1, -1, /* word 4 */ \ | ||||
|                   -1, -1, -1, -1, -1, -1, -1, -1, /* word 3 */ \ | ||||
|                   -1, -1, -1, -1, -1, -1, -1, -1, /* word 2 */ \ | ||||
|                   8, 9, 10, 11, 12, 13, 14, 15,   /* word 1 */ \ | ||||
|                   0, 1, 2, 3, 4, 5, 6, 7)         /* word 0 */ | ||||
|  | ||||
| #if !ASCON_INLINE_MODE | ||||
| #undef forceinline | ||||
| #define forceinline | ||||
| #endif | ||||
|  | ||||
| forceinline void ascon_loadkey(word_t* K0, word_t* K1, word_t* K2, | ||||
|                                const uint8_t* k) { | ||||
|   KINIT(K0, K1, K2); | ||||
|   if (CRYPTO_KEYBYTES == 16) { | ||||
|     *K1 = XOR(*K1, LOAD(k, 8)); | ||||
|     *K2 = XOR(*K2, LOAD(k + 8, 8)); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 20) { | ||||
|     *K0 = XOR(*K0, KEYROT(WORD_T(0), LOADBYTES(k, 4))); | ||||
|     *K1 = XOR(*K1, LOADBYTES(k + 4, 8)); | ||||
|     *K2 = XOR(*K2, LOADBYTES(k + 12, 8)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| forceinline void ascon_aeadinit(state_t* s, const uint8_t* npub, | ||||
|                                 const uint8_t* k) { | ||||
|   /* load nonce */ | ||||
|   word_t N0 = LOAD(npub, 8); | ||||
|   word_t N1 = LOAD(npub + 8, 8); | ||||
|   /* load key */ | ||||
|   word_t K0, K1, K2; | ||||
|   ascon_loadkey(&K0, &K1, &K2, k); | ||||
|   /* initialize */ | ||||
|   PINIT(s); | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 8) | ||||
|     s->x0 = XOR(s->x0, ASCON_128_IV); | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 16) | ||||
|     s->x0 = XOR(s->x0, ASCON_128A_IV); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x0 = XOR(s->x0, ASCON_80PQ_IV); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x0 = XOR(s->x0, K0); | ||||
|   s->x1 = XOR(s->x1, K1); | ||||
|   s->x2 = XOR(s->x2, K2); | ||||
|   s->x3 = XOR(s->x3, N0); | ||||
|   s->x4 = XOR(s->x4, N1); | ||||
|   P(s, 12); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x2 = XOR(s->x2, K0); | ||||
|   s->x3 = XOR(s->x3, K1); | ||||
|   s->x4 = XOR(s->x4, K2); | ||||
|   printstate("initialization", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_adata(state_t* s, const uint8_t* ad, uint64_t adlen) { | ||||
|   const __m512i u64big = AVX512_SHUFFLE_U64BIG; | ||||
|   const int mask = (ASCON_AEAD_RATE == 8) ? 0xff : 0xffff; | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   state_t r = *s, t; | ||||
|   if (adlen) { | ||||
|     /* full associated data blocks */ | ||||
|     while (adlen >= ASCON_AEAD_RATE) { | ||||
|       t.z = _mm512_maskz_loadu_epi8(mask, ad); | ||||
|       t.z = _mm512_maskz_shuffle_epi8(mask, t.z, u64big); | ||||
|       r.z = _mm512_xor_epi64(r.z, t.z); | ||||
|       P(&r, nr); | ||||
|       ad += ASCON_AEAD_RATE; | ||||
|       adlen -= ASCON_AEAD_RATE; | ||||
|     } | ||||
|     *s = r; | ||||
|     /* final associated data block */ | ||||
|     word_t* px = &s->x0; | ||||
|     if (ASCON_AEAD_RATE == 16 && adlen >= 8) { | ||||
|       s->x0 = XOR(s->x0, LOAD(ad, 8)); | ||||
|       px = &s->x1; | ||||
|       ad += 8; | ||||
|       adlen -= 8; | ||||
|     } | ||||
|     *px = XOR(*px, PAD(adlen)); | ||||
|     if (adlen) *px = XOR(*px, LOAD(ad, adlen)); | ||||
|     P(s, nr); | ||||
|   } | ||||
|   /* domain separation */ | ||||
|   s->x4 = XOR(s->x4, WORD_T(1)); | ||||
|   printstate("process associated data", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_encrypt(state_t* s, uint8_t* c, const uint8_t* m, | ||||
|                                uint64_t mlen) { | ||||
|   const __m512i u64big = AVX512_SHUFFLE_U64BIG; | ||||
|   const int mask = (ASCON_AEAD_RATE == 8) ? 0xff : 0xffff; | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   state_t r = *s, t; | ||||
|   /* full plaintext blocks */ | ||||
|   while (mlen >= ASCON_AEAD_RATE) { | ||||
|     t.z = _mm512_maskz_loadu_epi8(mask, m); | ||||
|     t.z = _mm512_maskz_shuffle_epi8(mask, t.z, u64big); | ||||
|     r.z = _mm512_xor_epi64(r.z, t.z); | ||||
|     t.z = _mm512_maskz_shuffle_epi8(mask, r.z, u64big); | ||||
|     _mm512_mask_storeu_epi8(c, mask, t.z); | ||||
|     P(&r, nr); | ||||
|     m += ASCON_AEAD_RATE; | ||||
|     c += ASCON_AEAD_RATE; | ||||
|     mlen -= ASCON_AEAD_RATE; | ||||
|   } | ||||
|   *s = r; | ||||
|   /* final plaintext block */ | ||||
|   word_t* px = &s->x0; | ||||
|   if (ASCON_AEAD_RATE == 16 && mlen >= 8) { | ||||
|     s->x0 = XOR(s->x0, LOAD(m, 8)); | ||||
|     STORE(c, s->x0, 8); | ||||
|     px = &s->x1; | ||||
|     m += 8; | ||||
|     c += 8; | ||||
|     mlen -= 8; | ||||
|   } | ||||
|   *px = XOR(*px, PAD(mlen)); | ||||
|   if (mlen) { | ||||
|     *px = XOR(*px, LOAD(m, mlen)); | ||||
|     STORE(c, *px, mlen); | ||||
|   } | ||||
|   printstate("process plaintext", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_decrypt(state_t* s, uint8_t* m, const uint8_t* c, | ||||
|                                uint64_t clen) { | ||||
|   const __m512i u64big = AVX512_SHUFFLE_U64BIG; | ||||
|   const int mask = (ASCON_AEAD_RATE == 8) ? 0xff : 0xffff; | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   state_t r = *s, t, u; | ||||
|   /* full ciphertext blocks */ | ||||
|   while (clen >= ASCON_AEAD_RATE) { | ||||
|     t.z = _mm512_maskz_loadu_epi8(mask, c); | ||||
|     t.z = _mm512_maskz_shuffle_epi8(mask, t.z, u64big); | ||||
|     r.z = _mm512_xor_epi64(r.z, t.z); | ||||
|     u.z = _mm512_maskz_shuffle_epi8(mask, r.z, u64big); | ||||
|     r.z = _mm512_mask_blend_epi8(mask, r.z, t.z); | ||||
|     _mm512_mask_storeu_epi8(m, mask, u.z); | ||||
|     P(&r, nr); | ||||
|     m += ASCON_AEAD_RATE; | ||||
|     c += ASCON_AEAD_RATE; | ||||
|     clen -= ASCON_AEAD_RATE; | ||||
|   } | ||||
|   *s = r; | ||||
|   /* final ciphertext block */ | ||||
|   word_t* px = &s->x0; | ||||
|   if (ASCON_AEAD_RATE == 16 && clen >= 8) { | ||||
|     word_t cx = LOAD(c, 8); | ||||
|     s->x0 = XOR(s->x0, cx); | ||||
|     STORE(m, s->x0, 8); | ||||
|     s->x0 = cx; | ||||
|     px = &s->x1; | ||||
|     m += 8; | ||||
|     c += 8; | ||||
|     clen -= 8; | ||||
|   } | ||||
|   *px = XOR(*px, PAD(clen)); | ||||
|   if (clen) { | ||||
|     word_t cx = LOAD(c, clen); | ||||
|     *px = XOR(*px, cx); | ||||
|     STORE(m, *px, clen); | ||||
|     *px = CLEAR(*px, clen); | ||||
|     *px = XOR(*px, cx); | ||||
|   } | ||||
|   printstate("process ciphertext", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_final(state_t* s, const uint8_t* k) { | ||||
|   /* load key */ | ||||
|   word_t K0, K1, K2; | ||||
|   ascon_loadkey(&K0, &K1, &K2, k); | ||||
|   /* finalize */ | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 8) { | ||||
|     s->x1 = XOR(s->x1, K1); | ||||
|     s->x2 = XOR(s->x2, K2); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 16) { | ||||
|     s->x2 = XOR(s->x2, K1); | ||||
|     s->x3 = XOR(s->x3, K2); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 20) { | ||||
|     s->x1 = XOR(s->x1, KEYROT(K0, K1)); | ||||
|     s->x2 = XOR(s->x2, KEYROT(K1, K2)); | ||||
|     s->x3 = XOR(s->x3, KEYROT(K2, WORD_T(0))); | ||||
|   } | ||||
|   P(s, 12); | ||||
|   s->x3 = XOR(s->x3, K1); | ||||
|   s->x4 = XOR(s->x4, K2); | ||||
|   printstate("finalization", s); | ||||
| } | ||||
|  | ||||
| int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen, | ||||
|                         const unsigned char* m, unsigned long long mlen, | ||||
|                         const unsigned char* ad, unsigned long long adlen, | ||||
|                         const unsigned char* nsec, const unsigned char* npub, | ||||
|                         const unsigned char* k) { | ||||
|   state_t s; | ||||
|   (void)nsec; | ||||
|   *clen = mlen + CRYPTO_ABYTES; | ||||
|   /* perform ascon computation */ | ||||
|   ascon_aeadinit(&s, npub, k); | ||||
|   ascon_adata(&s, ad, adlen); | ||||
|   ascon_encrypt(&s, c, m, mlen); | ||||
|   ascon_final(&s, k); | ||||
|   /* set tag */ | ||||
|   STOREBYTES(c + mlen, s.x3, 8); | ||||
|   STOREBYTES(c + mlen + 8, s.x4, 8); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int crypto_aead_decrypt(unsigned char* m, unsigned long long* mlen, | ||||
|                         unsigned char* nsec, const unsigned char* c, | ||||
|                         unsigned long long clen, const unsigned char* ad, | ||||
|                         unsigned long long adlen, const unsigned char* npub, | ||||
|                         const unsigned char* k) { | ||||
|   state_t s; | ||||
|   (void)nsec; | ||||
|   if (clen < CRYPTO_ABYTES) return -1; | ||||
|   *mlen = clen = clen - CRYPTO_ABYTES; | ||||
|   /* perform ascon computation */ | ||||
|   ascon_aeadinit(&s, npub, k); | ||||
|   ascon_adata(&s, ad, adlen); | ||||
|   ascon_decrypt(&s, m, c, clen); | ||||
|   ascon_final(&s, k); | ||||
|   /* verify tag (should be constant time, check compiler output) */ | ||||
|   s.x3 = XOR(s.x3, LOADBYTES(c + clen, 8)); | ||||
|   s.x4 = XOR(s.x4, LOADBYTES(c + clen + 8, 8)); | ||||
|   return NOTZERO(s.x3, s.x4); | ||||
| } | ||||
| @@ -1,7 +0,0 @@ | ||||
| #define CRYPTO_VERSION "1.2.5" | ||||
| #define CRYPTO_KEYBYTES 16 | ||||
| #define CRYPTO_NSECBYTES 0 | ||||
| #define CRYPTO_NPUBBYTES 16 | ||||
| #define CRYPTO_ABYTES 16 | ||||
| #define CRYPTO_NOOVERLAP 1 | ||||
| #define ASCON_AEAD_RATE 16 | ||||
| @@ -1,2 +0,0 @@ | ||||
| amd64 | ||||
| x86 | ||||
| @@ -1,22 +0,0 @@ | ||||
| #ifndef ASCON_H_ | ||||
| #define ASCON_H_ | ||||
|  | ||||
| #include <immintrin.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "word.h" | ||||
|  | ||||
| typedef union { | ||||
|   __m512i z; | ||||
|   struct { | ||||
|     word_t x0, x1, x2, x3, x4, x5, x6, x7; | ||||
|   }; | ||||
| } state_t; | ||||
|  | ||||
| void ascon_aeadinit(state_t* s, const uint8_t* npub, const uint8_t* k); | ||||
| void ascon_adata(state_t* s, const uint8_t* ad, uint64_t adlen); | ||||
| void ascon_encrypt(state_t* s, uint8_t* c, const uint8_t* m, uint64_t mlen); | ||||
| void ascon_decrypt(state_t* s, uint8_t* m, const uint8_t* c, uint64_t clen); | ||||
| void ascon_final(state_t* s, const uint8_t* k); | ||||
|  | ||||
| #endif /* ASCON_H */ | ||||
| @@ -1,19 +0,0 @@ | ||||
| #ifndef CONFIG_H_ | ||||
| #define CONFIG_H_ | ||||
|  | ||||
| /* inline the ascon mode */ | ||||
| #ifndef ASCON_INLINE_MODE | ||||
| #define ASCON_INLINE_MODE 1 | ||||
| #endif | ||||
|  | ||||
| /* inline all permutations */ | ||||
| #ifndef ASCON_INLINE_PERM | ||||
| #define ASCON_INLINE_PERM 1 | ||||
| #endif | ||||
|  | ||||
| /* unroll permutation loops */ | ||||
| #ifndef ASCON_UNROLL_LOOPS | ||||
| #define ASCON_UNROLL_LOOPS 1 | ||||
| #endif | ||||
|  | ||||
| #endif /* CONFIG_H_ */ | ||||
| @@ -1,39 +0,0 @@ | ||||
| #ifndef ENDIAN_H_ | ||||
| #define ENDIAN_H_ | ||||
|  | ||||
| #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | ||||
|  | ||||
| /* macros for big endian machines */ | ||||
| #ifdef PRAGMA_ENDIAN | ||||
| #pragma message("Using macros for big endian machines") | ||||
| #endif | ||||
| #define U64BIG(x) (x) | ||||
| #define U32BIG(x) (x) | ||||
| #define U16BIG(x) (x) | ||||
|  | ||||
| #elif defined(_MSC_VER) || \ | ||||
|     (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) | ||||
|  | ||||
| /* macros for little endian machines */ | ||||
| #ifdef PRAGMA_ENDIAN | ||||
| #pragma message("Using macros for little endian machines") | ||||
| #endif | ||||
| #define U64BIG(x)                          \ | ||||
|   (((0x00000000000000FFULL & (x)) << 56) | \ | ||||
|    ((0x000000000000FF00ULL & (x)) << 40) | \ | ||||
|    ((0x0000000000FF0000ULL & (x)) << 24) | \ | ||||
|    ((0x00000000FF000000ULL & (x)) << 8) |  \ | ||||
|    ((0x000000FF00000000ULL & (x)) >> 8) |  \ | ||||
|    ((0x0000FF0000000000ULL & (x)) >> 24) | \ | ||||
|    ((0x00FF000000000000ULL & (x)) >> 40) | \ | ||||
|    ((0xFF00000000000000ULL & (x)) >> 56)) | ||||
| #define U32BIG(x)                                           \ | ||||
|   (((0x000000FF & (x)) << 24) | ((0x0000FF00 & (x)) << 8) | \ | ||||
|    ((0x00FF0000 & (x)) >> 8) | ((0xFF000000 & (x)) >> 24)) | ||||
| #define U16BIG(x) (((0x00FF & (x)) << 8) | ((0xFF00 & (x)) >> 8)) | ||||
|  | ||||
| #else | ||||
| #error "Ascon byte order macros not defined in endian.h" | ||||
| #endif | ||||
|  | ||||
| #endif /* ENDIAN_H_ */ | ||||
| @@ -1,19 +0,0 @@ | ||||
| #ifndef FORCEINLINE_H_ | ||||
| #define FORCEINLINE_H_ | ||||
|  | ||||
| /* define forceinline macro */ | ||||
| #ifdef _MSC_VER | ||||
| #define forceinline __forceinline | ||||
| #elif defined(__GNUC__) | ||||
| #define forceinline inline __attribute__((__always_inline__)) | ||||
| #elif defined(__CLANG__) | ||||
| #if __has_attribute(__always_inline__) | ||||
| #define forceinline inline __attribute__((__always_inline__)) | ||||
| #else | ||||
| #define forceinline inline | ||||
| #endif | ||||
| #else | ||||
| #define forceinline inline | ||||
| #endif | ||||
|  | ||||
| #endif /* FORCEINLINE_H_ */ | ||||
| @@ -1 +0,0 @@ | ||||
| Branches reviewed 2020-11-13 by Martin Schläffer. | ||||
| @@ -1 +0,0 @@ | ||||
| Addresses reviewed 2020-11-13 by Martin Schläffer. | ||||
| @@ -1,2 +0,0 @@ | ||||
| Christoph Dobraunig | ||||
| Martin Schläffer | ||||
| @@ -1,15 +0,0 @@ | ||||
| #include "permutations.h" | ||||
|  | ||||
| #if !ASCON_INLINE_PERM && ASCON_UNROLL_LOOPS | ||||
|  | ||||
| void P12(state_t* s) { P12ROUNDS(s); } | ||||
| void P8(state_t* s) { P8ROUNDS(s); } | ||||
| void P6(state_t* s) { P6ROUNDS(s); } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if !ASCON_INLINE_PERM && !ASCON_UNROLL_LOOPS | ||||
|  | ||||
| void P(state_t* s, int nr) { PROUNDS(s, nr); } | ||||
|  | ||||
| #endif | ||||
| @@ -1,138 +0,0 @@ | ||||
| #ifndef PERMUTATIONS_H_ | ||||
| #define PERMUTATIONS_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "api.h" | ||||
| #include "ascon.h" | ||||
| #include "config.h" | ||||
| #include "printstate.h" | ||||
| #include "round.h" | ||||
|  | ||||
| #define ASCON_128_KEYBYTES 16 | ||||
| #define ASCON_128A_KEYBYTES 16 | ||||
| #define ASCON_80PQ_KEYBYTES 20 | ||||
|  | ||||
| #define ASCON_128_RATE 8 | ||||
| #define ASCON_128A_RATE 16 | ||||
| #define ASCON_HASH_RATE 8 | ||||
|  | ||||
| #define ASCON_128_PA_ROUNDS 12 | ||||
| #define ASCON_128_PB_ROUNDS 6 | ||||
|  | ||||
| #define ASCON_128A_PA_ROUNDS 12 | ||||
| #define ASCON_128A_PB_ROUNDS 8 | ||||
|  | ||||
| #define ASCON_HASH_PA_ROUNDS 12 | ||||
| #define ASCON_HASH_PB_ROUNDS 12 | ||||
|  | ||||
| #define ASCON_HASHA_PA_ROUNDS 12 | ||||
| #define ASCON_HASHA_PB_ROUNDS 8 | ||||
|  | ||||
| #define ASCON_HASH_BYTES 32 | ||||
|  | ||||
| #define ASCON_128_IV WORD_T(0x80400c0600000000ull) | ||||
| #define ASCON_128A_IV WORD_T(0x80800c0800000000ull) | ||||
| #define ASCON_80PQ_IV WORD_T(0xa0400c0600000000ull) | ||||
| #define ASCON_HASH_IV WORD_T(0x00400c0000000100ull) | ||||
| #define ASCON_HASHA_IV WORD_T(0x00400c0400000100ull) | ||||
| #define ASCON_XOF_IV WORD_T(0x00400c0000000000ull) | ||||
| #define ASCON_XOFA_IV WORD_T(0x00400c0400000000ull) | ||||
|  | ||||
| #define ASCON_HASH_IV0 WORD_T(0xee9398aadb67f03dull) | ||||
| #define ASCON_HASH_IV1 WORD_T(0x8bb21831c60f1002ull) | ||||
| #define ASCON_HASH_IV2 WORD_T(0xb48a92db98d5da62ull) | ||||
| #define ASCON_HASH_IV3 WORD_T(0x43189921b8f8e3e8ull) | ||||
| #define ASCON_HASH_IV4 WORD_T(0x348fa5c9d525e140ull) | ||||
|  | ||||
| #define ASCON_HASHA_IV0 WORD_T(0x01470194fc6528a6ull) | ||||
| #define ASCON_HASHA_IV1 WORD_T(0x738ec38ac0adffa7ull) | ||||
| #define ASCON_HASHA_IV2 WORD_T(0x2ec8e3296c76384cull) | ||||
| #define ASCON_HASHA_IV3 WORD_T(0xd6f6a54d7f52377dull) | ||||
| #define ASCON_HASHA_IV4 WORD_T(0xa13c42a223be8d87ull) | ||||
|  | ||||
| #define ASCON_XOF_IV0 WORD_T(0xb57e273b814cd416ull) | ||||
| #define ASCON_XOF_IV1 WORD_T(0x2b51042562ae2420ull) | ||||
| #define ASCON_XOF_IV2 WORD_T(0x66a3a7768ddf2218ull) | ||||
| #define ASCON_XOF_IV3 WORD_T(0x5aad0a7a8153650cull) | ||||
| #define ASCON_XOF_IV4 WORD_T(0x4f3e0e32539493b6ull) | ||||
|  | ||||
| #define ASCON_XOFA_IV0 WORD_T(0x44906568b77b9832ull) | ||||
| #define ASCON_XOFA_IV1 WORD_T(0xcd8d6cae53455532ull) | ||||
| #define ASCON_XOFA_IV2 WORD_T(0xf7b5212756422129ull) | ||||
| #define ASCON_XOFA_IV3 WORD_T(0x246885e1de0d225bull) | ||||
| #define ASCON_XOFA_IV4 WORD_T(0xa8cb5ce33449973full) | ||||
|  | ||||
| #define START(n) ((3 + (n)) << 4 | (12 - (n))) | ||||
| #define RC(c) WORD_T(c) | ||||
|  | ||||
| forceinline void P12ROUNDS(state_t* s) { | ||||
|   ROUND(s, RC(0xf0)); | ||||
|   ROUND(s, RC(0xe1)); | ||||
|   ROUND(s, RC(0xd2)); | ||||
|   ROUND(s, RC(0xc3)); | ||||
|   ROUND(s, RC(0xb4)); | ||||
|   ROUND(s, RC(0xa5)); | ||||
|   ROUND(s, RC(0x96)); | ||||
|   ROUND(s, RC(0x87)); | ||||
|   ROUND(s, RC(0x78)); | ||||
|   ROUND(s, RC(0x69)); | ||||
|   ROUND(s, RC(0x5a)); | ||||
|   ROUND(s, RC(0x4b)); | ||||
| } | ||||
|  | ||||
| forceinline void P8ROUNDS(state_t* s) { | ||||
|   ROUND(s, RC(0xb4)); | ||||
|   ROUND(s, RC(0xa5)); | ||||
|   ROUND(s, RC(0x96)); | ||||
|   ROUND(s, RC(0x87)); | ||||
|   ROUND(s, RC(0x78)); | ||||
|   ROUND(s, RC(0x69)); | ||||
|   ROUND(s, RC(0x5a)); | ||||
|   ROUND(s, RC(0x4b)); | ||||
| } | ||||
|  | ||||
| forceinline void P6ROUNDS(state_t* s) { | ||||
|   ROUND(s, RC(0x96)); | ||||
|   ROUND(s, RC(0x87)); | ||||
|   ROUND(s, RC(0x78)); | ||||
|   ROUND(s, RC(0x69)); | ||||
|   ROUND(s, RC(0x5a)); | ||||
|   ROUND(s, RC(0x4b)); | ||||
| } | ||||
|  | ||||
| forceinline void PROUNDS(state_t* s, int nr) { | ||||
|   for (int i = START(nr); i > 0x4a; i -= 0x0f) ROUND(s, RC(i)); | ||||
| } | ||||
|  | ||||
| #if ASCON_INLINE_PERM && ASCON_UNROLL_LOOPS | ||||
|  | ||||
| forceinline void P(state_t* s, int nr) { | ||||
|   if (nr == 12) P12ROUNDS(s); | ||||
|   if (nr == 8) P8ROUNDS(s); | ||||
|   if (nr == 6) P6ROUNDS(s); | ||||
| } | ||||
|  | ||||
| #elif !ASCON_INLINE_PERM && ASCON_UNROLL_LOOPS | ||||
|  | ||||
| void P12(state_t* s); | ||||
| void P8(state_t* s); | ||||
| void P6(state_t* s); | ||||
|  | ||||
| forceinline void P(state_t* s, int nr) { | ||||
|   if (nr == 12) P12(s); | ||||
|   if (nr == 8) P8(s); | ||||
|   if (nr == 6) P6(s); | ||||
| } | ||||
|  | ||||
| #elif ASCON_INLINE_PERM && !ASCON_UNROLL_LOOPS | ||||
|  | ||||
| forceinline void P(state_t* s, int nr) { PROUNDS(s, nr); } | ||||
|  | ||||
| #else /* !ASCON_INLINE_PERM && !ASCON_UNROLL_LOOPS */ | ||||
|  | ||||
| void P(state_t* s, int nr); | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif /* PERMUTATIONS_H_ */ | ||||
| @@ -1,21 +0,0 @@ | ||||
| #ifdef ASCON_PRINTSTATE | ||||
|  | ||||
| #include "printstate.h" | ||||
|  | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| void printword(const char* text, const word_t x) { | ||||
|   printf("%s=%016" PRIx64 "\n", text, WORDTOU64(x)); | ||||
| } | ||||
|  | ||||
| void printstate(const char* text, const state_t* s) { | ||||
|   printf("%s:\n", text); | ||||
|   printword("  x0", s->x0); | ||||
|   printword("  x1", s->x1); | ||||
|   printword("  x2", s->x2); | ||||
|   printword("  x3", s->x3); | ||||
|   printword("  x4", s->x4); | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -1,24 +0,0 @@ | ||||
| #ifndef PRINTSTATE_H_ | ||||
| #define PRINTSTATE_H_ | ||||
|  | ||||
| #ifdef ASCON_PRINTSTATE | ||||
|  | ||||
| #include "ascon.h" | ||||
| #include "word.h" | ||||
|  | ||||
| void printword(const char* text, const word_t x); | ||||
| void printstate(const char* text, const state_t* s); | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define printword(text, w) \ | ||||
|   do {                     \ | ||||
|   } while (0) | ||||
|  | ||||
| #define printstate(text, s) \ | ||||
|   do {                      \ | ||||
|   } while (0) | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif /* PRINTSTATE_H_ */ | ||||
| @@ -1,51 +0,0 @@ | ||||
| #ifndef ROUND_H_ | ||||
| #define ROUND_H_ | ||||
|  | ||||
| #include "ascon.h" | ||||
| #include "printstate.h" | ||||
|  | ||||
| forceinline void KINIT(word_t* K0, word_t* K1, word_t* K2) { | ||||
|   *K0 = WORD_T(0); | ||||
|   *K1 = WORD_T(0); | ||||
|   *K2 = WORD_T(0); | ||||
| } | ||||
|  | ||||
| forceinline void PINIT(state_t* s) { | ||||
|   s->x0 = WORD_T(0); | ||||
|   s->x1 = WORD_T(0); | ||||
|   s->x2 = WORD_T(0); | ||||
|   s->x3 = WORD_T(0); | ||||
|   s->x4 = WORD_T(0); | ||||
| } | ||||
|  | ||||
| forceinline void ROUND(state_t* s, word_t C) { | ||||
|   uint64_t x = 0; | ||||
|   __mmask8 mxor1 = 0x15; | ||||
|   __mmask8 mxor2 = 0x0b; | ||||
|   __m512i pxor1 = _mm512_set_epi64(x, x, x, 3, x, 1, x, 4); | ||||
|   __m512i pxor2 = _mm512_set_epi64(x, x, x, x, 2, x, 0, 4); | ||||
|   __m512i c = _mm512_set_epi64(x, x, x, 0, 0, C, 0, 0); | ||||
|   __m512i n = _mm512_set_epi64(x, x, x, 0, 0, ~0ull, 0, 0); | ||||
|   __m512i pchi1 = _mm512_set_epi64(x, x, x, 0, 4, 3, 2, 1); | ||||
|   __m512i pchi2 = _mm512_set_epi64(x, x, x, 1, 0, 4, 3, 2); | ||||
|   __m512i rot1 = _mm512_set_epi64(x, x, x, 7, 10, 1, 61, 19); | ||||
|   __m512i rot2 = _mm512_set_epi64(x, x, x, 41, 17, 6, 39, 28); | ||||
|   __m512i t0, t1, t2; | ||||
|   /* round constant + s-box layer */ | ||||
|   t0 = _mm512_maskz_permutexvar_epi64(mxor1, pxor1, s->z); | ||||
|   t0 = _mm512_ternarylogic_epi64(s->z, t0, c, 0x96); | ||||
|   /* keccak s-box start */ | ||||
|   t1 = _mm512_permutexvar_epi64(pchi1, t0); | ||||
|   t2 = _mm512_permutexvar_epi64(pchi2, t0); | ||||
|   t0 = _mm512_ternarylogic_epi64(t0, t1, t2, 0xd2); | ||||
|   /* keccak s-box end */ | ||||
|   t1 = _mm512_maskz_permutexvar_epi64(mxor2, pxor2, t0); | ||||
|   t0 = _mm512_ternarylogic_epi64(t0, t1, n, 0x96); | ||||
|   /* linear layer */ | ||||
|   t1 = _mm512_rorv_epi64(t0, rot1); | ||||
|   t2 = _mm512_rorv_epi64(t0, rot2); | ||||
|   s->z = _mm512_ternarylogic_epi64(t0, t1, t2, 0x96); | ||||
|   printstate(" round output", s); | ||||
| } | ||||
|  | ||||
| #endif /* ROUND_H_ */ | ||||
| @@ -1,69 +0,0 @@ | ||||
| #ifndef WORD_H_ | ||||
| #define WORD_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "endian.h" | ||||
| #include "forceinline.h" | ||||
|  | ||||
| typedef uint64_t word_t; | ||||
|  | ||||
| #define WORD_T | ||||
| #define UINT64_T | ||||
| #define U64TOWORD | ||||
| #define WORDTOU64 | ||||
|  | ||||
| forceinline word_t ROR(word_t x, int n) { return x >> n | x << (64 - n); } | ||||
|  | ||||
| forceinline word_t NOT(word_t a) { return ~a; } | ||||
|  | ||||
| forceinline word_t XOR(word_t a, word_t b) { return a ^ b; } | ||||
|  | ||||
| forceinline word_t AND(word_t a, word_t b) { return a & b; } | ||||
|  | ||||
| forceinline word_t KEYROT(word_t lo2hi, word_t hi2lo) { | ||||
|   return lo2hi << 32 | hi2lo >> 32; | ||||
| } | ||||
|  | ||||
| forceinline int NOTZERO(word_t a, word_t b) { | ||||
|   uint64_t result = a | b; | ||||
|   result |= result >> 32; | ||||
|   result |= result >> 16; | ||||
|   result |= result >> 8; | ||||
|   return ((((int)(result & 0xff) - 1) >> 8) & 1) - 1; | ||||
| } | ||||
|  | ||||
| forceinline word_t PAD(int i) { return 0x80ull << (56 - 8 * i); } | ||||
|  | ||||
| forceinline word_t CLEAR(word_t w, int n) { | ||||
|   /* undefined for n == 0 */ | ||||
|   uint64_t mask = 0x00ffffffffffffffull >> (n * 8 - 8); | ||||
|   return w & mask; | ||||
| } | ||||
|  | ||||
| forceinline uint64_t MASK(int n) { | ||||
|   /* undefined for n == 0 */ | ||||
|   return ~0ull >> (64 - 8 * n); | ||||
| } | ||||
|  | ||||
| forceinline word_t LOAD(const uint8_t* bytes, int n) { | ||||
|   uint64_t x = *(uint64_t*)bytes & MASK(n); | ||||
|   return U64BIG(x); | ||||
| } | ||||
|  | ||||
| forceinline void STORE(uint8_t* bytes, word_t w, int n) { | ||||
|   *(uint64_t*)bytes &= ~MASK(n); | ||||
|   *(uint64_t*)bytes |= U64BIG(w); | ||||
| } | ||||
|  | ||||
| forceinline word_t LOADBYTES(const uint8_t* bytes, int n) { | ||||
|   uint64_t x = 0; | ||||
|   for (int i = 0; i < n; ++i) ((uint8_t*)&x)[7 - i] = bytes[i]; | ||||
|   return x; | ||||
| } | ||||
|  | ||||
| forceinline void STOREBYTES(uint8_t* bytes, word_t w, int n) { | ||||
|   for (int i = 0; i < n; ++i) bytes[i] = ((uint8_t*)&w)[7 - i]; | ||||
| } | ||||
|  | ||||
| #endif /* WORD_H_ */ | ||||
| @@ -1,219 +0,0 @@ | ||||
| #include "api.h" | ||||
| #include "ascon.h" | ||||
| #include "crypto_aead.h" | ||||
| #include "permutations.h" | ||||
| #include "printstate.h" | ||||
|  | ||||
| #if !ASCON_INLINE_MODE | ||||
| #undef forceinline | ||||
| #define forceinline | ||||
| #endif | ||||
|  | ||||
| forceinline void ascon_loadkey(word_t* K0, word_t* K1, word_t* K2, | ||||
|                                const uint8_t* k) { | ||||
|   KINIT(K0, K1, K2); | ||||
|   if (CRYPTO_KEYBYTES == 16) { | ||||
|     *K1 = XOR(*K1, LOAD(k, 8)); | ||||
|     *K2 = XOR(*K2, LOAD(k + 8, 8)); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 20) { | ||||
|     *K0 = XOR(*K0, KEYROT(WORD_T(0), LOADBYTES(k, 4))); | ||||
|     *K1 = XOR(*K1, LOADBYTES(k + 4, 8)); | ||||
|     *K2 = XOR(*K2, LOADBYTES(k + 12, 8)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| forceinline void ascon_aeadinit(state_t* s, const uint8_t* npub, | ||||
|                                 const uint8_t* k) { | ||||
|   /* load nonce */ | ||||
|   word_t N0 = LOAD(npub, 8); | ||||
|   word_t N1 = LOAD(npub + 8, 8); | ||||
|   /* load key */ | ||||
|   word_t K0, K1, K2; | ||||
|   ascon_loadkey(&K0, &K1, &K2, k); | ||||
|   /* initialize */ | ||||
|   PINIT(s); | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 8) | ||||
|     s->x0 = XOR(s->x0, ASCON_128_IV); | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 16) | ||||
|     s->x0 = XOR(s->x0, ASCON_128A_IV); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x0 = XOR(s->x0, ASCON_80PQ_IV); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x0 = XOR(s->x0, K0); | ||||
|   s->x1 = XOR(s->x1, K1); | ||||
|   s->x2 = XOR(s->x2, K2); | ||||
|   s->x3 = XOR(s->x3, N0); | ||||
|   s->x4 = XOR(s->x4, N1); | ||||
|   P(s, 12); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x2 = XOR(s->x2, K0); | ||||
|   s->x3 = XOR(s->x3, K1); | ||||
|   s->x4 = XOR(s->x4, K2); | ||||
|   printstate("initialization", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_adata(state_t* s, const uint8_t* ad, uint64_t adlen) { | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   if (adlen) { | ||||
|     /* full associated data blocks */ | ||||
|     while (adlen >= ASCON_AEAD_RATE) { | ||||
|       s->x0 = XOR(s->x0, LOAD(ad, 8)); | ||||
|       if (ASCON_AEAD_RATE == 16) s->x1 = XOR(s->x1, LOAD(ad + 8, 8)); | ||||
|       P(s, nr); | ||||
|       ad += ASCON_AEAD_RATE; | ||||
|       adlen -= ASCON_AEAD_RATE; | ||||
|     } | ||||
|     /* final associated data block */ | ||||
|     word_t* px = &s->x0; | ||||
|     if (ASCON_AEAD_RATE == 16 && adlen >= 8) { | ||||
|       s->x0 = XOR(s->x0, LOAD(ad, 8)); | ||||
|       px = &s->x1; | ||||
|       ad += 8; | ||||
|       adlen -= 8; | ||||
|     } | ||||
|     *px = XOR(*px, PAD(adlen)); | ||||
|     if (adlen) *px = XOR(*px, LOAD(ad, adlen)); | ||||
|     P(s, nr); | ||||
|   } | ||||
|   /* domain separation */ | ||||
|   s->x4 = XOR(s->x4, WORD_T(1)); | ||||
|   printstate("process associated data", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_encrypt(state_t* s, uint8_t* c, const uint8_t* m, | ||||
|                                uint64_t mlen) { | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   /* full plaintext blocks */ | ||||
|   while (mlen >= ASCON_AEAD_RATE) { | ||||
|     s->x0 = XOR(s->x0, LOAD(m, 8)); | ||||
|     STORE(c, s->x0, 8); | ||||
|     if (ASCON_AEAD_RATE == 16) { | ||||
|       s->x1 = XOR(s->x1, LOAD(m + 8, 8)); | ||||
|       STORE(c + 8, s->x1, 8); | ||||
|     } | ||||
|     P(s, nr); | ||||
|     m += ASCON_AEAD_RATE; | ||||
|     c += ASCON_AEAD_RATE; | ||||
|     mlen -= ASCON_AEAD_RATE; | ||||
|   } | ||||
|   /* final plaintext block */ | ||||
|   word_t* px = &s->x0; | ||||
|   if (ASCON_AEAD_RATE == 16 && mlen >= 8) { | ||||
|     s->x0 = XOR(s->x0, LOAD(m, 8)); | ||||
|     STORE(c, s->x0, 8); | ||||
|     px = &s->x1; | ||||
|     m += 8; | ||||
|     c += 8; | ||||
|     mlen -= 8; | ||||
|   } | ||||
|   *px = XOR(*px, PAD(mlen)); | ||||
|   if (mlen) { | ||||
|     *px = XOR(*px, LOAD(m, mlen)); | ||||
|     STORE(c, *px, mlen); | ||||
|   } | ||||
|   printstate("process plaintext", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_decrypt(state_t* s, uint8_t* m, const uint8_t* c, | ||||
|                                uint64_t clen) { | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   /* full ciphertext blocks */ | ||||
|   while (clen >= ASCON_AEAD_RATE) { | ||||
|     word_t cx = LOAD(c, 8); | ||||
|     s->x0 = XOR(s->x0, cx); | ||||
|     STORE(m, s->x0, 8); | ||||
|     s->x0 = cx; | ||||
|     if (ASCON_AEAD_RATE == 16) { | ||||
|       cx = LOAD(c + 8, 8); | ||||
|       s->x1 = XOR(s->x1, cx); | ||||
|       STORE(m + 8, s->x1, 8); | ||||
|       s->x1 = cx; | ||||
|     } | ||||
|     P(s, nr); | ||||
|     m += ASCON_AEAD_RATE; | ||||
|     c += ASCON_AEAD_RATE; | ||||
|     clen -= ASCON_AEAD_RATE; | ||||
|   } | ||||
|   /* final ciphertext block */ | ||||
|   word_t* px = &s->x0; | ||||
|   if (ASCON_AEAD_RATE == 16 && clen >= 8) { | ||||
|     word_t cx = LOAD(c, 8); | ||||
|     s->x0 = XOR(s->x0, cx); | ||||
|     STORE(m, s->x0, 8); | ||||
|     s->x0 = cx; | ||||
|     px = &s->x1; | ||||
|     m += 8; | ||||
|     c += 8; | ||||
|     clen -= 8; | ||||
|   } | ||||
|   *px = XOR(*px, PAD(clen)); | ||||
|   if (clen) { | ||||
|     word_t cx = LOAD(c, clen); | ||||
|     *px = XOR(*px, cx); | ||||
|     STORE(m, *px, clen); | ||||
|     *px = CLEAR(*px, clen); | ||||
|     *px = XOR(*px, cx); | ||||
|   } | ||||
|   printstate("process ciphertext", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_final(state_t* s, const uint8_t* k) { | ||||
|   /* load key */ | ||||
|   word_t K0, K1, K2; | ||||
|   ascon_loadkey(&K0, &K1, &K2, k); | ||||
|   /* finalize */ | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 8) { | ||||
|     s->x1 = XOR(s->x1, K1); | ||||
|     s->x2 = XOR(s->x2, K2); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 16) { | ||||
|     s->x2 = XOR(s->x2, K1); | ||||
|     s->x3 = XOR(s->x3, K2); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 20) { | ||||
|     s->x1 = XOR(s->x1, KEYROT(K0, K1)); | ||||
|     s->x2 = XOR(s->x2, KEYROT(K1, K2)); | ||||
|     s->x3 = XOR(s->x3, KEYROT(K2, WORD_T(0))); | ||||
|   } | ||||
|   P(s, 12); | ||||
|   s->x3 = XOR(s->x3, K1); | ||||
|   s->x4 = XOR(s->x4, K2); | ||||
|   printstate("finalization", s); | ||||
| } | ||||
|  | ||||
| int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen, | ||||
|                         const unsigned char* m, unsigned long long mlen, | ||||
|                         const unsigned char* ad, unsigned long long adlen, | ||||
|                         const unsigned char* nsec, const unsigned char* npub, | ||||
|                         const unsigned char* k) { | ||||
|   state_t s; | ||||
|   (void)nsec; | ||||
|   *clen = mlen + CRYPTO_ABYTES; | ||||
|   /* perform ascon computation */ | ||||
|   ascon_aeadinit(&s, npub, k); | ||||
|   ascon_adata(&s, ad, adlen); | ||||
|   ascon_encrypt(&s, c, m, mlen); | ||||
|   ascon_final(&s, k); | ||||
|   /* set tag */ | ||||
|   STOREBYTES(c + mlen, s.x3, 8); | ||||
|   STOREBYTES(c + mlen + 8, s.x4, 8); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int crypto_aead_decrypt(unsigned char* m, unsigned long long* mlen, | ||||
|                         unsigned char* nsec, const unsigned char* c, | ||||
|                         unsigned long long clen, const unsigned char* ad, | ||||
|                         unsigned long long adlen, const unsigned char* npub, | ||||
|                         const unsigned char* k) { | ||||
|   state_t s; | ||||
|   (void)nsec; | ||||
|   if (clen < CRYPTO_ABYTES) return -1; | ||||
|   *mlen = clen = clen - CRYPTO_ABYTES; | ||||
|   /* perform ascon computation */ | ||||
|   ascon_aeadinit(&s, npub, k); | ||||
|   ascon_adata(&s, ad, adlen); | ||||
|   ascon_decrypt(&s, m, c, clen); | ||||
|   ascon_final(&s, k); | ||||
|   /* verify tag (should be constant time, check compiler output) */ | ||||
|   s.x3 = XOR(s.x3, LOADBYTES(c + clen, 8)); | ||||
|   s.x4 = XOR(s.x4, LOADBYTES(c + clen + 8, 8)); | ||||
|   return NOTZERO(s.x3, s.x4); | ||||
| } | ||||
| @@ -1,7 +0,0 @@ | ||||
| #define CRYPTO_VERSION "1.2.5" | ||||
| #define CRYPTO_KEYBYTES 16 | ||||
| #define CRYPTO_NSECBYTES 0 | ||||
| #define CRYPTO_NPUBBYTES 16 | ||||
| #define CRYPTO_ABYTES 16 | ||||
| #define CRYPTO_NOOVERLAP 1 | ||||
| #define ASCON_AEAD_RATE 16 | ||||
| @@ -1,18 +0,0 @@ | ||||
| #ifndef ASCON_H_ | ||||
| #define ASCON_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "word.h" | ||||
|  | ||||
| typedef struct { | ||||
|   word_t x0, x1, x2, x3, x4; | ||||
| } state_t; | ||||
|  | ||||
| void ascon_aeadinit(state_t* s, const uint8_t* npub, const uint8_t* k); | ||||
| void ascon_adata(state_t* s, const uint8_t* ad, uint64_t adlen); | ||||
| void ascon_encrypt(state_t* s, uint8_t* c, const uint8_t* m, uint64_t mlen); | ||||
| void ascon_decrypt(state_t* s, uint8_t* m, const uint8_t* c, uint64_t clen); | ||||
| void ascon_final(state_t* s, const uint8_t* k); | ||||
|  | ||||
| #endif /* ASCON_H */ | ||||
| @@ -1,19 +0,0 @@ | ||||
| #ifndef CONFIG_H_ | ||||
| #define CONFIG_H_ | ||||
|  | ||||
| /* inline the ascon mode */ | ||||
| #ifndef ASCON_INLINE_MODE | ||||
| #define ASCON_INLINE_MODE 1 | ||||
| #endif | ||||
|  | ||||
| /* inline all permutations */ | ||||
| #ifndef ASCON_INLINE_PERM | ||||
| #define ASCON_INLINE_PERM 0 | ||||
| #endif | ||||
|  | ||||
| /* unroll permutation loops */ | ||||
| #ifndef ASCON_UNROLL_LOOPS | ||||
| #define ASCON_UNROLL_LOOPS 1 | ||||
| #endif | ||||
|  | ||||
| #endif /* CONFIG_H_ */ | ||||
| @@ -1,39 +0,0 @@ | ||||
| #ifndef ENDIAN_H_ | ||||
| #define ENDIAN_H_ | ||||
|  | ||||
| #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | ||||
|  | ||||
| /* macros for big endian machines */ | ||||
| #ifdef PRAGMA_ENDIAN | ||||
| #pragma message("Using macros for big endian machines") | ||||
| #endif | ||||
| #define U64BIG(x) (x) | ||||
| #define U32BIG(x) (x) | ||||
| #define U16BIG(x) (x) | ||||
|  | ||||
| #elif defined(_MSC_VER) || \ | ||||
|     (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) | ||||
|  | ||||
| /* macros for little endian machines */ | ||||
| #ifdef PRAGMA_ENDIAN | ||||
| #pragma message("Using macros for little endian machines") | ||||
| #endif | ||||
| #define U64BIG(x)                          \ | ||||
|   (((0x00000000000000FFULL & (x)) << 56) | \ | ||||
|    ((0x000000000000FF00ULL & (x)) << 40) | \ | ||||
|    ((0x0000000000FF0000ULL & (x)) << 24) | \ | ||||
|    ((0x00000000FF000000ULL & (x)) << 8) |  \ | ||||
|    ((0x000000FF00000000ULL & (x)) >> 8) |  \ | ||||
|    ((0x0000FF0000000000ULL & (x)) >> 24) | \ | ||||
|    ((0x00FF000000000000ULL & (x)) >> 40) | \ | ||||
|    ((0xFF00000000000000ULL & (x)) >> 56)) | ||||
| #define U32BIG(x)                                           \ | ||||
|   (((0x000000FF & (x)) << 24) | ((0x0000FF00 & (x)) << 8) | \ | ||||
|    ((0x00FF0000 & (x)) >> 8) | ((0xFF000000 & (x)) >> 24)) | ||||
| #define U16BIG(x) (((0x00FF & (x)) << 8) | ((0xFF00 & (x)) >> 8)) | ||||
|  | ||||
| #else | ||||
| #error "Ascon byte order macros not defined in endian.h" | ||||
| #endif | ||||
|  | ||||
| #endif /* ENDIAN_H_ */ | ||||
| @@ -1,19 +0,0 @@ | ||||
| #ifndef FORCEINLINE_H_ | ||||
| #define FORCEINLINE_H_ | ||||
|  | ||||
| /* define forceinline macro */ | ||||
| #ifdef _MSC_VER | ||||
| #define forceinline __forceinline | ||||
| #elif defined(__GNUC__) | ||||
| #define forceinline inline __attribute__((__always_inline__)) | ||||
| #elif defined(__CLANG__) | ||||
| #if __has_attribute(__always_inline__) | ||||
| #define forceinline inline __attribute__((__always_inline__)) | ||||
| #else | ||||
| #define forceinline inline | ||||
| #endif | ||||
| #else | ||||
| #define forceinline inline | ||||
| #endif | ||||
|  | ||||
| #endif /* FORCEINLINE_H_ */ | ||||
| @@ -1 +0,0 @@ | ||||
| Branches reviewed 2020-11-13 by Martin Schläffer. | ||||
| @@ -1 +0,0 @@ | ||||
| Addresses reviewed 2020-11-13 by Martin Schläffer. | ||||
| @@ -1,2 +0,0 @@ | ||||
| Christoph Dobraunig | ||||
| Martin Schläffer | ||||
| @@ -1,49 +0,0 @@ | ||||
| #ifndef INTERLEAVE_H_ | ||||
| #define INTERLEAVE_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "forceinline.h" | ||||
|  | ||||
| forceinline uint32_t deinterleave_uint32(uint32_t x) { | ||||
|   uint32_t t; | ||||
|   t = (x ^ (x >> 1)) & 0x22222222, x ^= t ^ (t << 1); | ||||
|   t = (x ^ (x >> 2)) & 0x0C0C0C0C, x ^= t ^ (t << 2); | ||||
|   t = (x ^ (x >> 4)) & 0x00F000F0, x ^= t ^ (t << 4); | ||||
|   t = (x ^ (x >> 8)) & 0x0000FF00, x ^= t ^ (t << 8); | ||||
|   return x; | ||||
| } | ||||
|  | ||||
| forceinline uint32_t interleave_uint32(uint32_t x) { | ||||
|   uint32_t t; | ||||
|   t = (x ^ (x >> 8)) & 0x0000FF00, x ^= t ^ (t << 8); | ||||
|   t = (x ^ (x >> 4)) & 0x00F000F0, x ^= t ^ (t << 4); | ||||
|   t = (x ^ (x >> 2)) & 0x0C0C0C0C, x ^= t ^ (t << 2); | ||||
|   t = (x ^ (x >> 1)) & 0x22222222, x ^= t ^ (t << 1); | ||||
|   return x; | ||||
| } | ||||
|  | ||||
| /* credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ | ||||
| forceinline uint64_t deinterleave32(uint64_t in) { | ||||
|   uint32_t hi = in >> 32; | ||||
|   uint32_t lo = in; | ||||
|   uint32_t r0, r1; | ||||
|   lo = deinterleave_uint32(lo); | ||||
|   hi = deinterleave_uint32(hi); | ||||
|   r0 = (lo & 0x0000FFFF) | (hi << 16); | ||||
|   r1 = (lo >> 16) | (hi & 0xFFFF0000); | ||||
|   return (uint64_t)r1 << 32 | r0; | ||||
| } | ||||
|  | ||||
| /* credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ | ||||
| forceinline uint64_t interleave32(uint64_t in) { | ||||
|   uint32_t r0 = in; | ||||
|   uint32_t r1 = in >> 32; | ||||
|   uint32_t lo = (r0 & 0x0000FFFF) | (r1 << 16); | ||||
|   uint32_t hi = (r0 >> 16) | (r1 & 0xFFFF0000); | ||||
|   lo = interleave_uint32(lo); | ||||
|   hi = interleave_uint32(hi); | ||||
|   return (uint64_t)hi << 32 | lo; | ||||
| } | ||||
|  | ||||
| #endif /* INTERLEAVE_H_ */ | ||||
| @@ -1,23 +0,0 @@ | ||||
| #include "permutations.h" | ||||
|  | ||||
| #if !ASCON_UNROLL_LOOPS | ||||
|  | ||||
| const uint8_t constants[][2] = {{0xc, 0xc}, {0x9, 0xc}, {0xc, 0x9}, {0x9, 0x9}, | ||||
|                                 {0x6, 0xc}, {0x3, 0xc}, {0x6, 0x9}, {0x3, 0x9}, | ||||
|                                 {0xc, 0x6}, {0x9, 0x6}, {0xc, 0x3}, {0x9, 0x3}}; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if !ASCON_INLINE_PERM && ASCON_UNROLL_LOOPS | ||||
|  | ||||
| void P12(state_t* s) { P12ROUNDS(s); } | ||||
| void P8(state_t* s) { P8ROUNDS(s); } | ||||
| void P6(state_t* s) { P6ROUNDS(s); } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if !ASCON_INLINE_PERM && !ASCON_UNROLL_LOOPS | ||||
|  | ||||
| void P(state_t* s, int nr) { PROUNDS(s, nr); } | ||||
|  | ||||
| #endif | ||||
| @@ -1,139 +0,0 @@ | ||||
| #ifndef PERMUTATIONS_H_ | ||||
| #define PERMUTATIONS_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "api.h" | ||||
| #include "ascon.h" | ||||
| #include "config.h" | ||||
| #include "printstate.h" | ||||
| #include "round.h" | ||||
|  | ||||
| #define ASCON_128_KEYBYTES 16 | ||||
| #define ASCON_128A_KEYBYTES 16 | ||||
| #define ASCON_80PQ_KEYBYTES 20 | ||||
|  | ||||
| #define ASCON_128_RATE 8 | ||||
| #define ASCON_128A_RATE 16 | ||||
| #define ASCON_HASH_RATE 8 | ||||
|  | ||||
| #define ASCON_128_PA_ROUNDS 12 | ||||
| #define ASCON_128_PB_ROUNDS 6 | ||||
|  | ||||
| #define ASCON_128A_PA_ROUNDS 12 | ||||
| #define ASCON_128A_PB_ROUNDS 8 | ||||
|  | ||||
| #define ASCON_HASH_PA_ROUNDS 12 | ||||
| #define ASCON_HASH_PB_ROUNDS 12 | ||||
|  | ||||
| #define ASCON_HASHA_PA_ROUNDS 12 | ||||
| #define ASCON_HASHA_PB_ROUNDS 8 | ||||
|  | ||||
| #define ASCON_HASH_BYTES 32 | ||||
|  | ||||
| #define ASCON_128_IV WORD_T(0x8021000008220000ull) | ||||
| #define ASCON_128A_IV WORD_T(0x8822000000200000ull) | ||||
| #define ASCON_80PQ_IV WORD_T(0xc021000008220000ull) | ||||
| #define ASCON_HASH_IV WORD_T(0x0020000008020010ull) | ||||
| #define ASCON_XOF_IV WORD_T(0x0020000008020000ull) | ||||
|  | ||||
| #define ASCON_HASH_IV0 WORD_T(0xf9afb5c6a540dbc7ull) | ||||
| #define ASCON_HASH_IV1 WORD_T(0xbd2493011445a340ull) | ||||
| #define ASCON_HASH_IV2 WORD_T(0xcb9ba8b5604d4fc8ull) | ||||
| #define ASCON_HASH_IV3 WORD_T(0x12a4eede94514c98ull) | ||||
| #define ASCON_HASH_IV4 WORD_T(0x4bca84c06339f398ull) | ||||
|  | ||||
| #define ASCON_HASHA_IV0 WORD_T(0x0108e46d1b16eb02ull) | ||||
| #define ASCON_HASHA_IV1 WORD_T(0x5b9b8efdd29083f3ull) | ||||
| #define ASCON_HASHA_IV2 WORD_T(0x7ad665622891ae4aull) | ||||
| #define ASCON_HASHA_IV3 WORD_T(0x9dc27156ee3bfc7full) | ||||
| #define ASCON_HASHA_IV4 WORD_T(0xc61d5fa916801633ull) | ||||
|  | ||||
| #define ASCON_XOF_IV0 WORD_T(0xc75782817e351ae6ull) | ||||
| #define ASCON_XOF_IV1 WORD_T(0x70045f441d238220ull) | ||||
| #define ASCON_XOF_IV2 WORD_T(0x5dd5ab52a13e3f04ull) | ||||
| #define ASCON_XOF_IV3 WORD_T(0x3e378142c30c1db2ull) | ||||
| #define ASCON_XOF_IV4 WORD_T(0x3735189db624d656ull) | ||||
|  | ||||
| #define ASCON_XOFA_IV0 WORD_T(0x0846d7a5a4b87d44ull) | ||||
| #define ASCON_XOFA_IV1 WORD_T(0xaa6f1005b3a2dbf4ull) | ||||
| #define ASCON_XOFA_IV2 WORD_T(0xdc451146f713e811ull) | ||||
| #define ASCON_XOFA_IV3 WORD_T(0x468cb2532839e30dull) | ||||
| #define ASCON_XOFA_IV4 WORD_T(0xeb2d429709e96977ull) | ||||
|  | ||||
| #define START(n) (12 - n) | ||||
| #define RC(e, o) WORD_T((uint64_t)o << 32 | e) | ||||
|  | ||||
| forceinline void P12ROUNDS(state_t* s) { | ||||
|   ROUND(s, RC(0xc, 0xc)); | ||||
|   ROUND(s, RC(0x9, 0xc)); | ||||
|   ROUND(s, RC(0xc, 0x9)); | ||||
|   ROUND(s, RC(0x9, 0x9)); | ||||
|   ROUND(s, RC(0x6, 0xc)); | ||||
|   ROUND(s, RC(0x3, 0xc)); | ||||
|   ROUND(s, RC(0x6, 0x9)); | ||||
|   ROUND(s, RC(0x3, 0x9)); | ||||
|   ROUND(s, RC(0xc, 0x6)); | ||||
|   ROUND(s, RC(0x9, 0x6)); | ||||
|   ROUND(s, RC(0xc, 0x3)); | ||||
|   ROUND(s, RC(0x9, 0x3)); | ||||
| } | ||||
|  | ||||
| forceinline void P8ROUNDS(state_t* s) { | ||||
|   ROUND(s, RC(0x6, 0xc)); | ||||
|   ROUND(s, RC(0x3, 0xc)); | ||||
|   ROUND(s, RC(0x6, 0x9)); | ||||
|   ROUND(s, RC(0x3, 0x9)); | ||||
|   ROUND(s, RC(0xc, 0x6)); | ||||
|   ROUND(s, RC(0x9, 0x6)); | ||||
|   ROUND(s, RC(0xc, 0x3)); | ||||
|   ROUND(s, RC(0x9, 0x3)); | ||||
| } | ||||
|  | ||||
| forceinline void P6ROUNDS(state_t* s) { | ||||
|   ROUND(s, RC(0x6, 0x9)); | ||||
|   ROUND(s, RC(0x3, 0x9)); | ||||
|   ROUND(s, RC(0xc, 0x6)); | ||||
|   ROUND(s, RC(0x9, 0x6)); | ||||
|   ROUND(s, RC(0xc, 0x3)); | ||||
|   ROUND(s, RC(0x9, 0x3)); | ||||
| } | ||||
|  | ||||
| extern const uint8_t constants[][2]; | ||||
|  | ||||
| forceinline void PROUNDS(state_t* s, int nr) { | ||||
|   for (int i = START(nr); i < 12; i++) | ||||
|     ROUND(s, RC(constants[i][0], constants[i][1])); | ||||
| } | ||||
|  | ||||
| #if ASCON_INLINE_PERM && ASCON_UNROLL_LOOPS | ||||
|  | ||||
| forceinline void P(state_t* s, int nr) { | ||||
|   if (nr == 12) P12ROUNDS(s); | ||||
|   if (nr == 8) P8ROUNDS(s); | ||||
|   if (nr == 6) P6ROUNDS(s); | ||||
| } | ||||
|  | ||||
| #elif !ASCON_INLINE_PERM && ASCON_UNROLL_LOOPS | ||||
|  | ||||
| void P12(state_t* s); | ||||
| void P8(state_t* s); | ||||
| void P6(state_t* s); | ||||
|  | ||||
| forceinline void P(state_t* s, int nr) { | ||||
|   if (nr == 12) P12(s); | ||||
|   if (nr == 8) P8(s); | ||||
|   if (nr == 6) P6(s); | ||||
| } | ||||
|  | ||||
| #elif ASCON_INLINE_PERM && !ASCON_UNROLL_LOOPS | ||||
|  | ||||
| forceinline void P(state_t* s, int nr) { PROUNDS(s, nr); } | ||||
|  | ||||
| #else /* !ASCON_INLINE_PERM && !ASCON_UNROLL_LOOPS */ | ||||
|  | ||||
| void P(state_t* s, int nr); | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif /* PERMUTATIONS_H_ */ | ||||
| @@ -1,21 +0,0 @@ | ||||
| #ifdef ASCON_PRINTSTATE | ||||
|  | ||||
| #include "printstate.h" | ||||
|  | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| void printword(const char* text, const word_t x) { | ||||
|   printf("%s=%016" PRIx64 "\n", text, WORDTOU64(x)); | ||||
| } | ||||
|  | ||||
| void printstate(const char* text, const state_t* s) { | ||||
|   printf("%s:\n", text); | ||||
|   printword("  x0", s->x0); | ||||
|   printword("  x1", s->x1); | ||||
|   printword("  x2", s->x2); | ||||
|   printword("  x3", s->x3); | ||||
|   printword("  x4", s->x4); | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -1,24 +0,0 @@ | ||||
| #ifndef PRINTSTATE_H_ | ||||
| #define PRINTSTATE_H_ | ||||
|  | ||||
| #ifdef ASCON_PRINTSTATE | ||||
|  | ||||
| #include "ascon.h" | ||||
| #include "word.h" | ||||
|  | ||||
| void printword(const char* text, const word_t x); | ||||
| void printstate(const char* text, const state_t* s); | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define printword(text, w) \ | ||||
|   do {                     \ | ||||
|   } while (0) | ||||
|  | ||||
| #define printstate(text, s) \ | ||||
|   do {                      \ | ||||
|   } while (0) | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif /* PRINTSTATE_H_ */ | ||||
| @@ -1,52 +0,0 @@ | ||||
| #ifndef ROUND_H_ | ||||
| #define ROUND_H_ | ||||
|  | ||||
| #include "ascon.h" | ||||
| #include "printstate.h" | ||||
|  | ||||
| forceinline void KINIT(word_t* K0, word_t* K1, word_t* K2) { | ||||
|   *K0 = WORD_T(0); | ||||
|   *K1 = WORD_T(0); | ||||
|   *K2 = WORD_T(0); | ||||
| } | ||||
|  | ||||
| forceinline void PINIT(state_t* s) { | ||||
|   s->x0 = WORD_T(0); | ||||
|   s->x1 = WORD_T(0); | ||||
|   s->x2 = WORD_T(0); | ||||
|   s->x3 = WORD_T(0); | ||||
|   s->x4 = WORD_T(0); | ||||
| } | ||||
|  | ||||
| forceinline void ROUND(state_t* s, word_t C) { | ||||
|   state_t t; | ||||
|   /* round constant */ | ||||
|   s->x2 = XOR(s->x2, C); | ||||
|   /* s-box layer */ | ||||
|   s->x0 = XOR(s->x0, s->x4); | ||||
|   s->x4 = XOR(s->x4, s->x3); | ||||
|   s->x2 = XOR(s->x2, s->x1); | ||||
|   t.x0 = XOR(s->x0, AND(NOT(s->x1), s->x2)); | ||||
|   t.x2 = XOR(s->x2, AND(NOT(s->x3), s->x4)); | ||||
|   t.x4 = XOR(s->x4, AND(NOT(s->x0), s->x1)); | ||||
|   t.x1 = XOR(s->x1, AND(NOT(s->x2), s->x3)); | ||||
|   t.x3 = XOR(s->x3, AND(NOT(s->x4), s->x0)); | ||||
|   t.x1 = XOR(t.x1, t.x0); | ||||
|   t.x3 = XOR(t.x3, t.x2); | ||||
|   t.x0 = XOR(t.x0, t.x4); | ||||
|   /* linear layer */ | ||||
|   s->x2 = XOR(t.x2, ROR(t.x2, 6 - 1)); | ||||
|   s->x3 = XOR(t.x3, ROR(t.x3, 17 - 10)); | ||||
|   s->x4 = XOR(t.x4, ROR(t.x4, 41 - 7)); | ||||
|   s->x0 = XOR(t.x0, ROR(t.x0, 28 - 19)); | ||||
|   s->x1 = XOR(t.x1, ROR(t.x1, 61 - 39)); | ||||
|   s->x2 = XOR(t.x2, ROR(s->x2, 1)); | ||||
|   s->x3 = XOR(t.x3, ROR(s->x3, 10)); | ||||
|   s->x4 = XOR(t.x4, ROR(s->x4, 7)); | ||||
|   s->x0 = XOR(t.x0, ROR(s->x0, 19)); | ||||
|   s->x1 = XOR(t.x1, ROR(s->x1, 39)); | ||||
|   s->x2 = NOT(s->x2); | ||||
|   printstate(" round output", s); | ||||
| } | ||||
|  | ||||
| #endif /* ROUND_H_ */ | ||||
| @@ -1,105 +0,0 @@ | ||||
| #ifndef WORD_H_ | ||||
| #define WORD_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "endian.h" | ||||
| #include "forceinline.h" | ||||
| #include "interleave.h" | ||||
|  | ||||
| typedef struct { | ||||
|   uint32_t e; | ||||
|   uint32_t o; | ||||
| } word_t; | ||||
|  | ||||
| forceinline uint32_t ROR32(uint32_t x, int n) { | ||||
|   return (n == 0) ? x : x >> n | x << (32 - n); | ||||
| } | ||||
|  | ||||
| forceinline word_t ROR(word_t x, int n) { | ||||
|   word_t r; | ||||
|   r.e = (n % 2) ? ROR32(x.o, (n - 1) / 2) : ROR32(x.e, n / 2); | ||||
|   r.o = (n % 2) ? ROR32(x.e, (n + 1) / 2) : ROR32(x.o, n / 2); | ||||
|   return r; | ||||
| } | ||||
|  | ||||
| forceinline word_t WORD_T(uint64_t x) { return (word_t){.o = x >> 32, .e = x}; } | ||||
|  | ||||
| forceinline uint64_t UINT64_T(word_t x) { return (uint64_t)x.o << 32 | x.e; } | ||||
|  | ||||
| forceinline word_t U64TOWORD(uint64_t x) { return WORD_T(deinterleave32(x)); } | ||||
|  | ||||
| forceinline uint64_t WORDTOU64(word_t w) { return interleave32(UINT64_T(w)); } | ||||
|  | ||||
| forceinline word_t NOT(word_t a) { | ||||
|   a.e = ~a.e; | ||||
|   a.o = ~a.o; | ||||
|   return a; | ||||
| } | ||||
|  | ||||
| forceinline word_t XOR(word_t a, word_t b) { | ||||
|   a.e ^= b.e; | ||||
|   a.o ^= b.o; | ||||
|   return a; | ||||
| } | ||||
|  | ||||
| forceinline word_t AND(word_t a, word_t b) { | ||||
|   a.e &= b.e; | ||||
|   a.o &= b.o; | ||||
|   return a; | ||||
| } | ||||
|  | ||||
| forceinline word_t KEYROT(word_t lo2hi, word_t hi2lo) { | ||||
|   word_t r; | ||||
|   r.e = lo2hi.e << 16 | hi2lo.e >> 16; | ||||
|   r.o = lo2hi.o << 16 | hi2lo.o >> 16; | ||||
|   return r; | ||||
| } | ||||
|  | ||||
| forceinline int NOTZERO(word_t a, word_t b) { | ||||
|   uint32_t result = a.e | a.o | b.e | b.o; | ||||
|   result |= result >> 16; | ||||
|   result |= result >> 8; | ||||
|   return ((((int)(result & 0xff) - 1) >> 8) & 1) - 1; | ||||
| } | ||||
|  | ||||
| forceinline word_t PAD(int i) { | ||||
|   return WORD_T((uint64_t)(0x8ul << (28 - 4 * i)) << 32); | ||||
| } | ||||
|  | ||||
| forceinline word_t CLEAR(word_t w, int n) { | ||||
|   /* undefined for n == 0 */ | ||||
|   uint32_t mask = 0x0fffffff >> (n * 4 - 4); | ||||
|   w.e &= mask; | ||||
|   w.o &= mask; | ||||
|   return w; | ||||
| } | ||||
|  | ||||
| forceinline uint64_t MASK(int n) { | ||||
|   /* undefined for n == 0 */ | ||||
|   return ~0ull >> (64 - 8 * n); | ||||
| } | ||||
|  | ||||
| forceinline word_t LOAD(const uint8_t* bytes, int n) { | ||||
|   uint64_t x = *(uint64_t*)bytes & MASK(n); | ||||
|   return U64TOWORD(U64BIG(x)); | ||||
| } | ||||
|  | ||||
| forceinline void STORE(uint8_t* bytes, word_t w, int n) { | ||||
|   uint64_t x = WORDTOU64(w); | ||||
|   *(uint64_t*)bytes &= ~MASK(n); | ||||
|   *(uint64_t*)bytes |= U64BIG(x); | ||||
| } | ||||
|  | ||||
| forceinline word_t LOADBYTES(const uint8_t* bytes, int n) { | ||||
|   uint64_t x = 0; | ||||
|   for (int i = 0; i < n; ++i) ((uint8_t*)&x)[7 - i] = bytes[i]; | ||||
|   return U64TOWORD(x); | ||||
| } | ||||
|  | ||||
| forceinline void STOREBYTES(uint8_t* bytes, word_t w, int n) { | ||||
|   uint64_t x = WORDTOU64(w); | ||||
|   for (int i = 0; i < n; ++i) bytes[i] = ((uint8_t*)&x)[7 - i]; | ||||
| } | ||||
|  | ||||
| #endif /* WORD_H_ */ | ||||
| @@ -1,219 +0,0 @@ | ||||
| #include "api.h" | ||||
| #include "ascon.h" | ||||
| #include "crypto_aead.h" | ||||
| #include "permutations.h" | ||||
| #include "printstate.h" | ||||
|  | ||||
| #if !ASCON_INLINE_MODE | ||||
| #undef forceinline | ||||
| #define forceinline | ||||
| #endif | ||||
|  | ||||
| forceinline void ascon_loadkey(word_t* K0, word_t* K1, word_t* K2, | ||||
|                                const uint8_t* k) { | ||||
|   KINIT(K0, K1, K2); | ||||
|   if (CRYPTO_KEYBYTES == 16) { | ||||
|     *K1 = XOR(*K1, LOAD(k, 8)); | ||||
|     *K2 = XOR(*K2, LOAD(k + 8, 8)); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 20) { | ||||
|     *K0 = XOR(*K0, KEYROT(WORD_T(0), LOADBYTES(k, 4))); | ||||
|     *K1 = XOR(*K1, LOADBYTES(k + 4, 8)); | ||||
|     *K2 = XOR(*K2, LOADBYTES(k + 12, 8)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| forceinline void ascon_aeadinit(state_t* s, const uint8_t* npub, | ||||
|                                 const uint8_t* k) { | ||||
|   /* load nonce */ | ||||
|   word_t N0 = LOAD(npub, 8); | ||||
|   word_t N1 = LOAD(npub + 8, 8); | ||||
|   /* load key */ | ||||
|   word_t K0, K1, K2; | ||||
|   ascon_loadkey(&K0, &K1, &K2, k); | ||||
|   /* initialize */ | ||||
|   PINIT(s); | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 8) | ||||
|     s->x0 = XOR(s->x0, ASCON_128_IV); | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 16) | ||||
|     s->x0 = XOR(s->x0, ASCON_128A_IV); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x0 = XOR(s->x0, ASCON_80PQ_IV); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x0 = XOR(s->x0, K0); | ||||
|   s->x1 = XOR(s->x1, K1); | ||||
|   s->x2 = XOR(s->x2, K2); | ||||
|   s->x3 = XOR(s->x3, N0); | ||||
|   s->x4 = XOR(s->x4, N1); | ||||
|   P(s, 12); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x2 = XOR(s->x2, K0); | ||||
|   s->x3 = XOR(s->x3, K1); | ||||
|   s->x4 = XOR(s->x4, K2); | ||||
|   printstate("initialization", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_adata(state_t* s, const uint8_t* ad, uint64_t adlen) { | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   if (adlen) { | ||||
|     /* full associated data blocks */ | ||||
|     while (adlen >= ASCON_AEAD_RATE) { | ||||
|       s->x0 = XOR(s->x0, LOAD(ad, 8)); | ||||
|       if (ASCON_AEAD_RATE == 16) s->x1 = XOR(s->x1, LOAD(ad + 8, 8)); | ||||
|       P(s, nr); | ||||
|       ad += ASCON_AEAD_RATE; | ||||
|       adlen -= ASCON_AEAD_RATE; | ||||
|     } | ||||
|     /* final associated data block */ | ||||
|     word_t* px = &s->x0; | ||||
|     if (ASCON_AEAD_RATE == 16 && adlen >= 8) { | ||||
|       s->x0 = XOR(s->x0, LOAD(ad, 8)); | ||||
|       px = &s->x1; | ||||
|       ad += 8; | ||||
|       adlen -= 8; | ||||
|     } | ||||
|     *px = XOR(*px, PAD(adlen)); | ||||
|     if (adlen) *px = XOR(*px, LOAD(ad, adlen)); | ||||
|     P(s, nr); | ||||
|   } | ||||
|   /* domain separation */ | ||||
|   s->x4 = XOR(s->x4, WORD_T(1)); | ||||
|   printstate("process associated data", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_encrypt(state_t* s, uint8_t* c, const uint8_t* m, | ||||
|                                uint64_t mlen) { | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   /* full plaintext blocks */ | ||||
|   while (mlen >= ASCON_AEAD_RATE) { | ||||
|     s->x0 = XOR(s->x0, LOAD(m, 8)); | ||||
|     STORE(c, s->x0, 8); | ||||
|     if (ASCON_AEAD_RATE == 16) { | ||||
|       s->x1 = XOR(s->x1, LOAD(m + 8, 8)); | ||||
|       STORE(c + 8, s->x1, 8); | ||||
|     } | ||||
|     P(s, nr); | ||||
|     m += ASCON_AEAD_RATE; | ||||
|     c += ASCON_AEAD_RATE; | ||||
|     mlen -= ASCON_AEAD_RATE; | ||||
|   } | ||||
|   /* final plaintext block */ | ||||
|   word_t* px = &s->x0; | ||||
|   if (ASCON_AEAD_RATE == 16 && mlen >= 8) { | ||||
|     s->x0 = XOR(s->x0, LOAD(m, 8)); | ||||
|     STORE(c, s->x0, 8); | ||||
|     px = &s->x1; | ||||
|     m += 8; | ||||
|     c += 8; | ||||
|     mlen -= 8; | ||||
|   } | ||||
|   *px = XOR(*px, PAD(mlen)); | ||||
|   if (mlen) { | ||||
|     *px = XOR(*px, LOAD(m, mlen)); | ||||
|     STORE(c, *px, mlen); | ||||
|   } | ||||
|   printstate("process plaintext", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_decrypt(state_t* s, uint8_t* m, const uint8_t* c, | ||||
|                                uint64_t clen) { | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   /* full ciphertext blocks */ | ||||
|   while (clen >= ASCON_AEAD_RATE) { | ||||
|     word_t cx = LOAD(c, 8); | ||||
|     s->x0 = XOR(s->x0, cx); | ||||
|     STORE(m, s->x0, 8); | ||||
|     s->x0 = cx; | ||||
|     if (ASCON_AEAD_RATE == 16) { | ||||
|       cx = LOAD(c + 8, 8); | ||||
|       s->x1 = XOR(s->x1, cx); | ||||
|       STORE(m + 8, s->x1, 8); | ||||
|       s->x1 = cx; | ||||
|     } | ||||
|     P(s, nr); | ||||
|     m += ASCON_AEAD_RATE; | ||||
|     c += ASCON_AEAD_RATE; | ||||
|     clen -= ASCON_AEAD_RATE; | ||||
|   } | ||||
|   /* final ciphertext block */ | ||||
|   word_t* px = &s->x0; | ||||
|   if (ASCON_AEAD_RATE == 16 && clen >= 8) { | ||||
|     word_t cx = LOAD(c, 8); | ||||
|     s->x0 = XOR(s->x0, cx); | ||||
|     STORE(m, s->x0, 8); | ||||
|     s->x0 = cx; | ||||
|     px = &s->x1; | ||||
|     m += 8; | ||||
|     c += 8; | ||||
|     clen -= 8; | ||||
|   } | ||||
|   *px = XOR(*px, PAD(clen)); | ||||
|   if (clen) { | ||||
|     word_t cx = LOAD(c, clen); | ||||
|     *px = XOR(*px, cx); | ||||
|     STORE(m, *px, clen); | ||||
|     *px = CLEAR(*px, clen); | ||||
|     *px = XOR(*px, cx); | ||||
|   } | ||||
|   printstate("process ciphertext", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_final(state_t* s, const uint8_t* k) { | ||||
|   /* load key */ | ||||
|   word_t K0, K1, K2; | ||||
|   ascon_loadkey(&K0, &K1, &K2, k); | ||||
|   /* finalize */ | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 8) { | ||||
|     s->x1 = XOR(s->x1, K1); | ||||
|     s->x2 = XOR(s->x2, K2); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 16) { | ||||
|     s->x2 = XOR(s->x2, K1); | ||||
|     s->x3 = XOR(s->x3, K2); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 20) { | ||||
|     s->x1 = XOR(s->x1, KEYROT(K0, K1)); | ||||
|     s->x2 = XOR(s->x2, KEYROT(K1, K2)); | ||||
|     s->x3 = XOR(s->x3, KEYROT(K2, WORD_T(0))); | ||||
|   } | ||||
|   P(s, 12); | ||||
|   s->x3 = XOR(s->x3, K1); | ||||
|   s->x4 = XOR(s->x4, K2); | ||||
|   printstate("finalization", s); | ||||
| } | ||||
|  | ||||
| int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen, | ||||
|                         const unsigned char* m, unsigned long long mlen, | ||||
|                         const unsigned char* ad, unsigned long long adlen, | ||||
|                         const unsigned char* nsec, const unsigned char* npub, | ||||
|                         const unsigned char* k) { | ||||
|   state_t s; | ||||
|   (void)nsec; | ||||
|   *clen = mlen + CRYPTO_ABYTES; | ||||
|   /* perform ascon computation */ | ||||
|   ascon_aeadinit(&s, npub, k); | ||||
|   ascon_adata(&s, ad, adlen); | ||||
|   ascon_encrypt(&s, c, m, mlen); | ||||
|   ascon_final(&s, k); | ||||
|   /* set tag */ | ||||
|   STOREBYTES(c + mlen, s.x3, 8); | ||||
|   STOREBYTES(c + mlen + 8, s.x4, 8); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int crypto_aead_decrypt(unsigned char* m, unsigned long long* mlen, | ||||
|                         unsigned char* nsec, const unsigned char* c, | ||||
|                         unsigned long long clen, const unsigned char* ad, | ||||
|                         unsigned long long adlen, const unsigned char* npub, | ||||
|                         const unsigned char* k) { | ||||
|   state_t s; | ||||
|   (void)nsec; | ||||
|   if (clen < CRYPTO_ABYTES) return -1; | ||||
|   *mlen = clen = clen - CRYPTO_ABYTES; | ||||
|   /* perform ascon computation */ | ||||
|   ascon_aeadinit(&s, npub, k); | ||||
|   ascon_adata(&s, ad, adlen); | ||||
|   ascon_decrypt(&s, m, c, clen); | ||||
|   ascon_final(&s, k); | ||||
|   /* verify tag (should be constant time, check compiler output) */ | ||||
|   s.x3 = XOR(s.x3, LOADBYTES(c + clen, 8)); | ||||
|   s.x4 = XOR(s.x4, LOADBYTES(c + clen + 8, 8)); | ||||
|   return NOTZERO(s.x3, s.x4); | ||||
| } | ||||
| @@ -1,7 +0,0 @@ | ||||
| #define CRYPTO_VERSION "1.2.5" | ||||
| #define CRYPTO_KEYBYTES 16 | ||||
| #define CRYPTO_NSECBYTES 0 | ||||
| #define CRYPTO_NPUBBYTES 16 | ||||
| #define CRYPTO_ABYTES 16 | ||||
| #define CRYPTO_NOOVERLAP 1 | ||||
| #define ASCON_AEAD_RATE 16 | ||||
| @@ -1,3 +0,0 @@ | ||||
| aarch64 | ||||
| armeabi | ||||
| arm | ||||
| @@ -1,18 +0,0 @@ | ||||
| #ifndef ASCON_H_ | ||||
| #define ASCON_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "word.h" | ||||
|  | ||||
| typedef struct { | ||||
|   word_t x0, x1, x2, x3, x4; | ||||
| } state_t; | ||||
|  | ||||
| void ascon_aeadinit(state_t* s, const uint8_t* npub, const uint8_t* k); | ||||
| void ascon_adata(state_t* s, const uint8_t* ad, uint64_t adlen); | ||||
| void ascon_encrypt(state_t* s, uint8_t* c, const uint8_t* m, uint64_t mlen); | ||||
| void ascon_decrypt(state_t* s, uint8_t* m, const uint8_t* c, uint64_t clen); | ||||
| void ascon_final(state_t* s, const uint8_t* k); | ||||
|  | ||||
| #endif /* ASCON_H */ | ||||
| @@ -1,19 +0,0 @@ | ||||
| #ifndef CONFIG_H_ | ||||
| #define CONFIG_H_ | ||||
|  | ||||
| /* inline the ascon mode */ | ||||
| #ifndef ASCON_INLINE_MODE | ||||
| #define ASCON_INLINE_MODE 0 | ||||
| #endif | ||||
|  | ||||
| /* inline all permutations */ | ||||
| #ifndef ASCON_INLINE_PERM | ||||
| #define ASCON_INLINE_PERM 0 | ||||
| #endif | ||||
|  | ||||
| /* unroll permutation loops */ | ||||
| #ifndef ASCON_UNROLL_LOOPS | ||||
| #define ASCON_UNROLL_LOOPS 1 | ||||
| #endif | ||||
|  | ||||
| #endif /* CONFIG_H_ */ | ||||
| @@ -1,39 +0,0 @@ | ||||
| #ifndef ENDIAN_H_ | ||||
| #define ENDIAN_H_ | ||||
|  | ||||
| #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | ||||
|  | ||||
| /* macros for big endian machines */ | ||||
| #ifdef PRAGMA_ENDIAN | ||||
| #pragma message("Using macros for big endian machines") | ||||
| #endif | ||||
| #define U64BIG(x) (x) | ||||
| #define U32BIG(x) (x) | ||||
| #define U16BIG(x) (x) | ||||
|  | ||||
| #elif defined(_MSC_VER) || \ | ||||
|     (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) | ||||
|  | ||||
| /* macros for little endian machines */ | ||||
| #ifdef PRAGMA_ENDIAN | ||||
| #pragma message("Using macros for little endian machines") | ||||
| #endif | ||||
| #define U64BIG(x)                          \ | ||||
|   (((0x00000000000000FFULL & (x)) << 56) | \ | ||||
|    ((0x000000000000FF00ULL & (x)) << 40) | \ | ||||
|    ((0x0000000000FF0000ULL & (x)) << 24) | \ | ||||
|    ((0x00000000FF000000ULL & (x)) << 8) |  \ | ||||
|    ((0x000000FF00000000ULL & (x)) >> 8) |  \ | ||||
|    ((0x0000FF0000000000ULL & (x)) >> 24) | \ | ||||
|    ((0x00FF000000000000ULL & (x)) >> 40) | \ | ||||
|    ((0xFF00000000000000ULL & (x)) >> 56)) | ||||
| #define U32BIG(x)                                           \ | ||||
|   (((0x000000FF & (x)) << 24) | ((0x0000FF00 & (x)) << 8) | \ | ||||
|    ((0x00FF0000 & (x)) >> 8) | ((0xFF000000 & (x)) >> 24)) | ||||
| #define U16BIG(x) (((0x00FF & (x)) << 8) | ((0xFF00 & (x)) >> 8)) | ||||
|  | ||||
| #else | ||||
| #error "Ascon byte order macros not defined in endian.h" | ||||
| #endif | ||||
|  | ||||
| #endif /* ENDIAN_H_ */ | ||||
| @@ -1,19 +0,0 @@ | ||||
| #ifndef FORCEINLINE_H_ | ||||
| #define FORCEINLINE_H_ | ||||
|  | ||||
| /* define forceinline macro */ | ||||
| #ifdef _MSC_VER | ||||
| #define forceinline __forceinline | ||||
| #elif defined(__GNUC__) | ||||
| #define forceinline inline __attribute__((__always_inline__)) | ||||
| #elif defined(__CLANG__) | ||||
| #if __has_attribute(__always_inline__) | ||||
| #define forceinline inline __attribute__((__always_inline__)) | ||||
| #else | ||||
| #define forceinline inline | ||||
| #endif | ||||
| #else | ||||
| #define forceinline inline | ||||
| #endif | ||||
|  | ||||
| #endif /* FORCEINLINE_H_ */ | ||||
| @@ -1 +0,0 @@ | ||||
| Branches reviewed 2020-11-13 by Martin Schläffer. | ||||
| @@ -1 +0,0 @@ | ||||
| Addresses reviewed 2020-11-13 by Martin Schläffer. | ||||
| @@ -1,2 +0,0 @@ | ||||
| Christoph Dobraunig | ||||
| Martin Schläffer | ||||
| @@ -1,49 +0,0 @@ | ||||
| #ifndef INTERLEAVE_H_ | ||||
| #define INTERLEAVE_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "forceinline.h" | ||||
|  | ||||
| forceinline uint32_t deinterleave_uint32(uint32_t x) { | ||||
|   uint32_t t; | ||||
|   t = (x ^ (x >> 1)) & 0x22222222, x ^= t ^ (t << 1); | ||||
|   t = (x ^ (x >> 2)) & 0x0C0C0C0C, x ^= t ^ (t << 2); | ||||
|   t = (x ^ (x >> 4)) & 0x00F000F0, x ^= t ^ (t << 4); | ||||
|   t = (x ^ (x >> 8)) & 0x0000FF00, x ^= t ^ (t << 8); | ||||
|   return x; | ||||
| } | ||||
|  | ||||
| forceinline uint32_t interleave_uint32(uint32_t x) { | ||||
|   uint32_t t; | ||||
|   t = (x ^ (x >> 8)) & 0x0000FF00, x ^= t ^ (t << 8); | ||||
|   t = (x ^ (x >> 4)) & 0x00F000F0, x ^= t ^ (t << 4); | ||||
|   t = (x ^ (x >> 2)) & 0x0C0C0C0C, x ^= t ^ (t << 2); | ||||
|   t = (x ^ (x >> 1)) & 0x22222222, x ^= t ^ (t << 1); | ||||
|   return x; | ||||
| } | ||||
|  | ||||
| /* credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ | ||||
| forceinline uint64_t deinterleave32(uint64_t in) { | ||||
|   uint32_t hi = in >> 32; | ||||
|   uint32_t lo = in; | ||||
|   uint32_t r0, r1; | ||||
|   lo = deinterleave_uint32(lo); | ||||
|   hi = deinterleave_uint32(hi); | ||||
|   r0 = (lo & 0x0000FFFF) | (hi << 16); | ||||
|   r1 = (lo >> 16) | (hi & 0xFFFF0000); | ||||
|   return (uint64_t)r1 << 32 | r0; | ||||
| } | ||||
|  | ||||
| /* credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ | ||||
| forceinline uint64_t interleave32(uint64_t in) { | ||||
|   uint32_t r0 = in; | ||||
|   uint32_t r1 = in >> 32; | ||||
|   uint32_t lo = (r0 & 0x0000FFFF) | (r1 << 16); | ||||
|   uint32_t hi = (r0 >> 16) | (r1 & 0xFFFF0000); | ||||
|   lo = interleave_uint32(lo); | ||||
|   hi = interleave_uint32(hi); | ||||
|   return (uint64_t)hi << 32 | lo; | ||||
| } | ||||
|  | ||||
| #endif /* INTERLEAVE_H_ */ | ||||
| @@ -1,23 +0,0 @@ | ||||
| #include "permutations.h" | ||||
|  | ||||
| #if !ASCON_UNROLL_LOOPS | ||||
|  | ||||
| const uint8_t constants[][2] = {{0xc, 0xc}, {0x9, 0xc}, {0xc, 0x9}, {0x9, 0x9}, | ||||
|                                 {0x6, 0xc}, {0x3, 0xc}, {0x6, 0x9}, {0x3, 0x9}, | ||||
|                                 {0xc, 0x6}, {0x9, 0x6}, {0xc, 0x3}, {0x9, 0x3}}; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if !ASCON_INLINE_PERM && ASCON_UNROLL_LOOPS | ||||
|  | ||||
| void P12(state_t* s) { P12ROUNDS(s); } | ||||
| void P8(state_t* s) { P8ROUNDS(s); } | ||||
| void P6(state_t* s) { P6ROUNDS(s); } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if !ASCON_INLINE_PERM && !ASCON_UNROLL_LOOPS | ||||
|  | ||||
| void P(state_t* s, int nr) { PROUNDS(s, nr); } | ||||
|  | ||||
| #endif | ||||
| @@ -1,139 +0,0 @@ | ||||
| #ifndef PERMUTATIONS_H_ | ||||
| #define PERMUTATIONS_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "api.h" | ||||
| #include "ascon.h" | ||||
| #include "config.h" | ||||
| #include "printstate.h" | ||||
| #include "round.h" | ||||
|  | ||||
| #define ASCON_128_KEYBYTES 16 | ||||
| #define ASCON_128A_KEYBYTES 16 | ||||
| #define ASCON_80PQ_KEYBYTES 20 | ||||
|  | ||||
| #define ASCON_128_RATE 8 | ||||
| #define ASCON_128A_RATE 16 | ||||
| #define ASCON_HASH_RATE 8 | ||||
|  | ||||
| #define ASCON_128_PA_ROUNDS 12 | ||||
| #define ASCON_128_PB_ROUNDS 6 | ||||
|  | ||||
| #define ASCON_128A_PA_ROUNDS 12 | ||||
| #define ASCON_128A_PB_ROUNDS 8 | ||||
|  | ||||
| #define ASCON_HASH_PA_ROUNDS 12 | ||||
| #define ASCON_HASH_PB_ROUNDS 12 | ||||
|  | ||||
| #define ASCON_HASHA_PA_ROUNDS 12 | ||||
| #define ASCON_HASHA_PB_ROUNDS 8 | ||||
|  | ||||
| #define ASCON_HASH_BYTES 32 | ||||
|  | ||||
| #define ASCON_128_IV WORD_T(0x8021000008220000ull) | ||||
| #define ASCON_128A_IV WORD_T(0x8822000000200000ull) | ||||
| #define ASCON_80PQ_IV WORD_T(0xc021000008220000ull) | ||||
| #define ASCON_HASH_IV WORD_T(0x0020000008020010ull) | ||||
| #define ASCON_XOF_IV WORD_T(0x0020000008020000ull) | ||||
|  | ||||
| #define ASCON_HASH_IV0 WORD_T(0xf9afb5c6a540dbc7ull) | ||||
| #define ASCON_HASH_IV1 WORD_T(0xbd2493011445a340ull) | ||||
| #define ASCON_HASH_IV2 WORD_T(0xcb9ba8b5604d4fc8ull) | ||||
| #define ASCON_HASH_IV3 WORD_T(0x12a4eede94514c98ull) | ||||
| #define ASCON_HASH_IV4 WORD_T(0x4bca84c06339f398ull) | ||||
|  | ||||
| #define ASCON_HASHA_IV0 WORD_T(0x0108e46d1b16eb02ull) | ||||
| #define ASCON_HASHA_IV1 WORD_T(0x5b9b8efdd29083f3ull) | ||||
| #define ASCON_HASHA_IV2 WORD_T(0x7ad665622891ae4aull) | ||||
| #define ASCON_HASHA_IV3 WORD_T(0x9dc27156ee3bfc7full) | ||||
| #define ASCON_HASHA_IV4 WORD_T(0xc61d5fa916801633ull) | ||||
|  | ||||
| #define ASCON_XOF_IV0 WORD_T(0xc75782817e351ae6ull) | ||||
| #define ASCON_XOF_IV1 WORD_T(0x70045f441d238220ull) | ||||
| #define ASCON_XOF_IV2 WORD_T(0x5dd5ab52a13e3f04ull) | ||||
| #define ASCON_XOF_IV3 WORD_T(0x3e378142c30c1db2ull) | ||||
| #define ASCON_XOF_IV4 WORD_T(0x3735189db624d656ull) | ||||
|  | ||||
| #define ASCON_XOFA_IV0 WORD_T(0x0846d7a5a4b87d44ull) | ||||
| #define ASCON_XOFA_IV1 WORD_T(0xaa6f1005b3a2dbf4ull) | ||||
| #define ASCON_XOFA_IV2 WORD_T(0xdc451146f713e811ull) | ||||
| #define ASCON_XOFA_IV3 WORD_T(0x468cb2532839e30dull) | ||||
| #define ASCON_XOFA_IV4 WORD_T(0xeb2d429709e96977ull) | ||||
|  | ||||
| #define START(n) (12 - n) | ||||
| #define RC(e, o) WORD_T((uint64_t)o << 32 | e) | ||||
|  | ||||
| forceinline void P12ROUNDS(state_t* s) { | ||||
|   ROUND(s, RC(0xc, 0xc)); | ||||
|   ROUND(s, RC(0x9, 0xc)); | ||||
|   ROUND(s, RC(0xc, 0x9)); | ||||
|   ROUND(s, RC(0x9, 0x9)); | ||||
|   ROUND(s, RC(0x6, 0xc)); | ||||
|   ROUND(s, RC(0x3, 0xc)); | ||||
|   ROUND(s, RC(0x6, 0x9)); | ||||
|   ROUND(s, RC(0x3, 0x9)); | ||||
|   ROUND(s, RC(0xc, 0x6)); | ||||
|   ROUND(s, RC(0x9, 0x6)); | ||||
|   ROUND(s, RC(0xc, 0x3)); | ||||
|   ROUND(s, RC(0x9, 0x3)); | ||||
| } | ||||
|  | ||||
| forceinline void P8ROUNDS(state_t* s) { | ||||
|   ROUND(s, RC(0x6, 0xc)); | ||||
|   ROUND(s, RC(0x3, 0xc)); | ||||
|   ROUND(s, RC(0x6, 0x9)); | ||||
|   ROUND(s, RC(0x3, 0x9)); | ||||
|   ROUND(s, RC(0xc, 0x6)); | ||||
|   ROUND(s, RC(0x9, 0x6)); | ||||
|   ROUND(s, RC(0xc, 0x3)); | ||||
|   ROUND(s, RC(0x9, 0x3)); | ||||
| } | ||||
|  | ||||
| forceinline void P6ROUNDS(state_t* s) { | ||||
|   ROUND(s, RC(0x6, 0x9)); | ||||
|   ROUND(s, RC(0x3, 0x9)); | ||||
|   ROUND(s, RC(0xc, 0x6)); | ||||
|   ROUND(s, RC(0x9, 0x6)); | ||||
|   ROUND(s, RC(0xc, 0x3)); | ||||
|   ROUND(s, RC(0x9, 0x3)); | ||||
| } | ||||
|  | ||||
| extern const uint8_t constants[][2]; | ||||
|  | ||||
| forceinline void PROUNDS(state_t* s, int nr) { | ||||
|   for (int i = START(nr); i < 12; i++) | ||||
|     ROUND(s, RC(constants[i][0], constants[i][1])); | ||||
| } | ||||
|  | ||||
| #if ASCON_INLINE_PERM && ASCON_UNROLL_LOOPS | ||||
|  | ||||
| forceinline void P(state_t* s, int nr) { | ||||
|   if (nr == 12) P12ROUNDS(s); | ||||
|   if (nr == 8) P8ROUNDS(s); | ||||
|   if (nr == 6) P6ROUNDS(s); | ||||
| } | ||||
|  | ||||
| #elif !ASCON_INLINE_PERM && ASCON_UNROLL_LOOPS | ||||
|  | ||||
| void P12(state_t* s); | ||||
| void P8(state_t* s); | ||||
| void P6(state_t* s); | ||||
|  | ||||
| forceinline void P(state_t* s, int nr) { | ||||
|   if (nr == 12) P12(s); | ||||
|   if (nr == 8) P8(s); | ||||
|   if (nr == 6) P6(s); | ||||
| } | ||||
|  | ||||
| #elif ASCON_INLINE_PERM && !ASCON_UNROLL_LOOPS | ||||
|  | ||||
| forceinline void P(state_t* s, int nr) { PROUNDS(s, nr); } | ||||
|  | ||||
| #else /* !ASCON_INLINE_PERM && !ASCON_UNROLL_LOOPS */ | ||||
|  | ||||
| void P(state_t* s, int nr); | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif /* PERMUTATIONS_H_ */ | ||||
| @@ -1,21 +0,0 @@ | ||||
| #ifdef ASCON_PRINTSTATE | ||||
|  | ||||
| #include "printstate.h" | ||||
|  | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| void printword(const char* text, const word_t x) { | ||||
|   printf("%s=%016" PRIx64 "\n", text, WORDTOU64(x)); | ||||
| } | ||||
|  | ||||
| void printstate(const char* text, const state_t* s) { | ||||
|   printf("%s:\n", text); | ||||
|   printword("  x0", s->x0); | ||||
|   printword("  x1", s->x1); | ||||
|   printword("  x2", s->x2); | ||||
|   printword("  x3", s->x3); | ||||
|   printword("  x4", s->x4); | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -1,24 +0,0 @@ | ||||
| #ifndef PRINTSTATE_H_ | ||||
| #define PRINTSTATE_H_ | ||||
|  | ||||
| #ifdef ASCON_PRINTSTATE | ||||
|  | ||||
| #include "ascon.h" | ||||
| #include "word.h" | ||||
|  | ||||
| void printword(const char* text, const word_t x); | ||||
| void printstate(const char* text, const state_t* s); | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define printword(text, w) \ | ||||
|   do {                     \ | ||||
|   } while (0) | ||||
|  | ||||
| #define printstate(text, s) \ | ||||
|   do {                      \ | ||||
|   } while (0) | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif /* PRINTSTATE_H_ */ | ||||
| @@ -1,102 +0,0 @@ | ||||
| #ifndef ROUND_H_ | ||||
| #define ROUND_H_ | ||||
|  | ||||
| #include "ascon.h" | ||||
| #include "printstate.h" | ||||
|  | ||||
| forceinline void KINIT(word_t* K0, word_t* K1, word_t* K2) { | ||||
|   *K0 = WORD_T(0); | ||||
|   *K1 = WORD_T(0); | ||||
|   *K2 = WORD_T(0); | ||||
| } | ||||
|  | ||||
| forceinline void PINIT(state_t* s) { | ||||
|   s->x0 = WORD_T(0); | ||||
|   s->x1 = WORD_T(0); | ||||
|   s->x2 = WORD_T(0); | ||||
|   s->x3 = WORD_T(0); | ||||
|   s->x4 = WORD_T(0); | ||||
| } | ||||
|  | ||||
| forceinline void ROUND(state_t* s, word_t C) { | ||||
|   uint32_t tmp0, tmp1, tmp2, tmp3; | ||||
|   /* clang-format off */ | ||||
|   __asm__ __volatile__(                            \ | ||||
|       "eor %[x2_e], %[x2_e], %[C_e]\n\t"           \ | ||||
|       "eor %[x2_o], %[x2_o], %[C_o]\n\t"           \ | ||||
|       "eor %[x0_e], %[x0_e], %[x4_e]\n\t"          \ | ||||
|       "eor %[x0_o], %[x0_o], %[x4_o]\n\t"          \ | ||||
|       "eor %[x4_e], %[x4_e], %[x3_e]\n\t"          \ | ||||
|       "eor %[x4_o], %[x4_o], %[x3_o]\n\t"          \ | ||||
|       "eor %[x2_e], %[x2_e], %[x1_e]\n\t"          \ | ||||
|       "eor %[x2_o], %[x2_o], %[x1_o]\n\t"          \ | ||||
|       "bic %[tmp0], %[x0_e], %[x4_e]\n\t"          \ | ||||
|       "bic %[tmp1], %[x4_e], %[x3_e]\n\t"          \ | ||||
|       "bic %[tmp2], %[x2_e], %[x1_e]\n\t"          \ | ||||
|       "bic %[tmp3], %[x1_e], %[x0_e]\n\t"          \ | ||||
|       "eor %[x2_e], %[x2_e], %[tmp1]\n\t"          \ | ||||
|       "eor %[x0_e], %[x0_e], %[tmp2]\n\t"          \ | ||||
|       "eor %[x4_e], %[x4_e], %[tmp3]\n\t"          \ | ||||
|       "bic %[tmp3], %[x3_e], %[x2_e]\n\t"          \ | ||||
|       "eor %[x3_e], %[x3_e], %[tmp0]\n\t"          \ | ||||
|       "bic %[tmp2], %[x0_o], %[x4_o]\n\t"          \ | ||||
|       "bic %[tmp0], %[x2_o], %[x1_o]\n\t"          \ | ||||
|       "bic %[tmp1], %[x4_o], %[x3_o]\n\t"          \ | ||||
|       "eor %[x1_e], %[x1_e], %[tmp3]\n\t"          \ | ||||
|       "eor %[x0_o], %[x0_o], %[tmp0]\n\t"          \ | ||||
|       "eor %[x2_o], %[x2_o], %[tmp1]\n\t"          \ | ||||
|       "bic %[tmp3], %[x1_o], %[x0_o]\n\t"          \ | ||||
|       "bic %[tmp0], %[x3_o], %[x2_o]\n\t"          \ | ||||
|       "eor %[x3_o], %[x3_o], %[tmp2]\n\t"          \ | ||||
|       "eor %[x3_o], %[x3_o], %[x2_o]\n\t"          \ | ||||
|       "eor %[x4_o], %[x4_o], %[tmp3]\n\t"          \ | ||||
|       "eor %[x1_o], %[x1_o], %[tmp0]\n\t"          \ | ||||
|       "eor %[x3_e], %[x3_e], %[x2_e]\n\t"          \ | ||||
|       "eor %[x1_e], %[x1_e], %[x0_e]\n\t"          \ | ||||
|       "eor %[x1_o], %[x1_o], %[x0_o]\n\t"          \ | ||||
|       "eor %[x0_e], %[x0_e], %[x4_e]\n\t"          \ | ||||
|       "eor %[x0_o], %[x0_o], %[x4_o]\n\t"          \ | ||||
|       "mvn %[x2_e], %[x2_e]\n\t"                   \ | ||||
|       "mvn %[x2_o], %[x2_o]\n\t"                   \ | ||||
|       "eor %[tmp0], %[x0_e], %[x0_o], ror #4\n\t"  \ | ||||
|       "eor %[tmp1], %[x0_o], %[x0_e], ror #5\n\t"  \ | ||||
|       "eor %[tmp2], %[x1_e], %[x1_e], ror #11\n\t" \ | ||||
|       "eor %[tmp3], %[x1_o], %[x1_o], ror #11\n\t" \ | ||||
|       "eor %[x0_e], %[x0_e], %[tmp1], ror #9\n\t"  \ | ||||
|       "eor %[x0_o], %[x0_o], %[tmp0], ror #10\n\t" \ | ||||
|       "eor %[x1_e], %[x1_e], %[tmp3], ror #19\n\t" \ | ||||
|       "eor %[x1_o], %[x1_o], %[tmp2], ror #20\n\t" \ | ||||
|       "eor %[tmp0], %[x2_e], %[x2_o], ror #2\n\t"  \ | ||||
|       "eor %[tmp1], %[x2_o], %[x2_e], ror #3\n\t"  \ | ||||
|       "eor %[tmp2], %[x3_e], %[x3_o], ror #3\n\t"  \ | ||||
|       "eor %[tmp3], %[x3_o], %[x3_e], ror #4\n\t"  \ | ||||
|       "eor %[x2_e], %[x2_e], %[tmp1]\n\t"          \ | ||||
|       "eor %[x2_o], %[x2_o], %[tmp0], ror #1\n\t"  \ | ||||
|       "eor %[x3_e], %[x3_e], %[tmp2], ror #5\n\t"  \ | ||||
|       "eor %[x3_o], %[x3_o], %[tmp3], ror #5\n\t"  \ | ||||
|       "eor %[tmp0], %[x4_e], %[x4_e], ror #17\n\t" \ | ||||
|       "eor %[tmp1], %[x4_o], %[x4_o], ror #17\n\t" \ | ||||
|       "eor %[x4_e], %[x4_e], %[tmp1], ror #3\n\t"  \ | ||||
|       "eor %[x4_o], %[x4_o], %[tmp0], ror #4\n\t"  \ | ||||
|       : [ x0_e ] "+r"(s->x0.e),                    \ | ||||
|         [ x1_e ] "+r"(s->x1.e),                    \ | ||||
|         [ x2_e ] "+r"(s->x2.e),                    \ | ||||
|         [ x3_e ] "+r"(s->x3.e),                    \ | ||||
|         [ x4_e ] "+r"(s->x4.e),                    \ | ||||
|         [ x0_o ] "+r"(s->x0.o),                    \ | ||||
|         [ x1_o ] "+r"(s->x1.o),                    \ | ||||
|         [ x2_o ] "+r"(s->x2.o),                    \ | ||||
|         [ x3_o ] "+r"(s->x3.o),                    \ | ||||
|         [ x4_o ] "+r"(s->x4.o),                    \ | ||||
|         [ tmp0 ] "=r"(tmp0),                       \ | ||||
|         [ tmp1 ] "=r"(tmp1),                       \ | ||||
|         [ tmp2 ] "=r"(tmp2),                       \ | ||||
|         [ tmp3 ] "=r"(tmp3)                        \ | ||||
|       : [ C_e ] "ri"(C.e),                         \ | ||||
|         [ C_o ] "ri"(C.o)                          \ | ||||
|       : ); | ||||
|   /* clang-format on */ | ||||
|   printstate(" round output", s); | ||||
| } | ||||
|  | ||||
| #endif /* ROUND_H_ */ | ||||
| @@ -1,105 +0,0 @@ | ||||
| #ifndef WORD_H_ | ||||
| #define WORD_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "endian.h" | ||||
| #include "forceinline.h" | ||||
| #include "interleave.h" | ||||
|  | ||||
| typedef struct { | ||||
|   uint32_t e; | ||||
|   uint32_t o; | ||||
| } word_t; | ||||
|  | ||||
| forceinline uint32_t ROR32(uint32_t x, int n) { | ||||
|   return (n == 0) ? x : x >> n | x << (32 - n); | ||||
| } | ||||
|  | ||||
| forceinline word_t ROR(word_t x, int n) { | ||||
|   word_t r; | ||||
|   r.e = (n % 2) ? ROR32(x.o, (n - 1) / 2) : ROR32(x.e, n / 2); | ||||
|   r.o = (n % 2) ? ROR32(x.e, (n + 1) / 2) : ROR32(x.o, n / 2); | ||||
|   return r; | ||||
| } | ||||
|  | ||||
| forceinline word_t WORD_T(uint64_t x) { return (word_t){.o = x >> 32, .e = x}; } | ||||
|  | ||||
| forceinline uint64_t UINT64_T(word_t x) { return (uint64_t)x.o << 32 | x.e; } | ||||
|  | ||||
| forceinline word_t U64TOWORD(uint64_t x) { return WORD_T(deinterleave32(x)); } | ||||
|  | ||||
| forceinline uint64_t WORDTOU64(word_t w) { return interleave32(UINT64_T(w)); } | ||||
|  | ||||
| forceinline word_t NOT(word_t a) { | ||||
|   a.e = ~a.e; | ||||
|   a.o = ~a.o; | ||||
|   return a; | ||||
| } | ||||
|  | ||||
| forceinline word_t XOR(word_t a, word_t b) { | ||||
|   a.e ^= b.e; | ||||
|   a.o ^= b.o; | ||||
|   return a; | ||||
| } | ||||
|  | ||||
| forceinline word_t AND(word_t a, word_t b) { | ||||
|   a.e &= b.e; | ||||
|   a.o &= b.o; | ||||
|   return a; | ||||
| } | ||||
|  | ||||
| forceinline word_t KEYROT(word_t lo2hi, word_t hi2lo) { | ||||
|   word_t r; | ||||
|   r.e = lo2hi.e << 16 | hi2lo.e >> 16; | ||||
|   r.o = lo2hi.o << 16 | hi2lo.o >> 16; | ||||
|   return r; | ||||
| } | ||||
|  | ||||
| forceinline int NOTZERO(word_t a, word_t b) { | ||||
|   uint32_t result = a.e | a.o | b.e | b.o; | ||||
|   result |= result >> 16; | ||||
|   result |= result >> 8; | ||||
|   return ((((int)(result & 0xff) - 1) >> 8) & 1) - 1; | ||||
| } | ||||
|  | ||||
| forceinline word_t PAD(int i) { | ||||
|   return WORD_T((uint64_t)(0x8ul << (28 - 4 * i)) << 32); | ||||
| } | ||||
|  | ||||
| forceinline word_t CLEAR(word_t w, int n) { | ||||
|   /* undefined for n == 0 */ | ||||
|   uint32_t mask = 0x0fffffff >> (n * 4 - 4); | ||||
|   w.e &= mask; | ||||
|   w.o &= mask; | ||||
|   return w; | ||||
| } | ||||
|  | ||||
| forceinline uint64_t MASK(int n) { | ||||
|   /* undefined for n == 0 */ | ||||
|   return ~0ull >> (64 - 8 * n); | ||||
| } | ||||
|  | ||||
| forceinline word_t LOAD(const uint8_t* bytes, int n) { | ||||
|   uint64_t x = *(uint64_t*)bytes & MASK(n); | ||||
|   return U64TOWORD(U64BIG(x)); | ||||
| } | ||||
|  | ||||
| forceinline void STORE(uint8_t* bytes, word_t w, int n) { | ||||
|   uint64_t x = WORDTOU64(w); | ||||
|   *(uint64_t*)bytes &= ~MASK(n); | ||||
|   *(uint64_t*)bytes |= U64BIG(x); | ||||
| } | ||||
|  | ||||
| forceinline word_t LOADBYTES(const uint8_t* bytes, int n) { | ||||
|   uint64_t x = 0; | ||||
|   for (int i = 0; i < n; ++i) ((uint8_t*)&x)[7 - i] = bytes[i]; | ||||
|   return U64TOWORD(x); | ||||
| } | ||||
|  | ||||
| forceinline void STOREBYTES(uint8_t* bytes, word_t w, int n) { | ||||
|   uint64_t x = WORDTOU64(w); | ||||
|   for (int i = 0; i < n; ++i) bytes[i] = ((uint8_t*)&x)[7 - i]; | ||||
| } | ||||
|  | ||||
| #endif /* WORD_H_ */ | ||||
| @@ -1,219 +0,0 @@ | ||||
| #include "api.h" | ||||
| #include "ascon.h" | ||||
| #include "crypto_aead.h" | ||||
| #include "permutations.h" | ||||
| #include "printstate.h" | ||||
|  | ||||
| #if !ASCON_INLINE_MODE | ||||
| #undef forceinline | ||||
| #define forceinline | ||||
| #endif | ||||
|  | ||||
| forceinline void ascon_loadkey(word_t* K0, word_t* K1, word_t* K2, | ||||
|                                const uint8_t* k) { | ||||
|   KINIT(K0, K1, K2); | ||||
|   if (CRYPTO_KEYBYTES == 16) { | ||||
|     *K1 = XOR(*K1, LOAD(k, 8)); | ||||
|     *K2 = XOR(*K2, LOAD(k + 8, 8)); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 20) { | ||||
|     *K0 = XOR(*K0, KEYROT(WORD_T(0), LOADBYTES(k, 4))); | ||||
|     *K1 = XOR(*K1, LOADBYTES(k + 4, 8)); | ||||
|     *K2 = XOR(*K2, LOADBYTES(k + 12, 8)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| forceinline void ascon_aeadinit(state_t* s, const uint8_t* npub, | ||||
|                                 const uint8_t* k) { | ||||
|   /* load nonce */ | ||||
|   word_t N0 = LOAD(npub, 8); | ||||
|   word_t N1 = LOAD(npub + 8, 8); | ||||
|   /* load key */ | ||||
|   word_t K0, K1, K2; | ||||
|   ascon_loadkey(&K0, &K1, &K2, k); | ||||
|   /* initialize */ | ||||
|   PINIT(s); | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 8) | ||||
|     s->x0 = XOR(s->x0, ASCON_128_IV); | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 16) | ||||
|     s->x0 = XOR(s->x0, ASCON_128A_IV); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x0 = XOR(s->x0, ASCON_80PQ_IV); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x0 = XOR(s->x0, K0); | ||||
|   s->x1 = XOR(s->x1, K1); | ||||
|   s->x2 = XOR(s->x2, K2); | ||||
|   s->x3 = XOR(s->x3, N0); | ||||
|   s->x4 = XOR(s->x4, N1); | ||||
|   P(s, 12); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x2 = XOR(s->x2, K0); | ||||
|   s->x3 = XOR(s->x3, K1); | ||||
|   s->x4 = XOR(s->x4, K2); | ||||
|   printstate("initialization", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_adata(state_t* s, const uint8_t* ad, uint64_t adlen) { | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   if (adlen) { | ||||
|     /* full associated data blocks */ | ||||
|     while (adlen >= ASCON_AEAD_RATE) { | ||||
|       s->x0 = XOR(s->x0, LOAD(ad, 8)); | ||||
|       if (ASCON_AEAD_RATE == 16) s->x1 = XOR(s->x1, LOAD(ad + 8, 8)); | ||||
|       P(s, nr); | ||||
|       ad += ASCON_AEAD_RATE; | ||||
|       adlen -= ASCON_AEAD_RATE; | ||||
|     } | ||||
|     /* final associated data block */ | ||||
|     word_t* px = &s->x0; | ||||
|     if (ASCON_AEAD_RATE == 16 && adlen >= 8) { | ||||
|       s->x0 = XOR(s->x0, LOAD(ad, 8)); | ||||
|       px = &s->x1; | ||||
|       ad += 8; | ||||
|       adlen -= 8; | ||||
|     } | ||||
|     *px = XOR(*px, PAD(adlen)); | ||||
|     if (adlen) *px = XOR(*px, LOAD(ad, adlen)); | ||||
|     P(s, nr); | ||||
|   } | ||||
|   /* domain separation */ | ||||
|   s->x4 = XOR(s->x4, WORD_T(1)); | ||||
|   printstate("process associated data", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_encrypt(state_t* s, uint8_t* c, const uint8_t* m, | ||||
|                                uint64_t mlen) { | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   /* full plaintext blocks */ | ||||
|   while (mlen >= ASCON_AEAD_RATE) { | ||||
|     s->x0 = XOR(s->x0, LOAD(m, 8)); | ||||
|     STORE(c, s->x0, 8); | ||||
|     if (ASCON_AEAD_RATE == 16) { | ||||
|       s->x1 = XOR(s->x1, LOAD(m + 8, 8)); | ||||
|       STORE(c + 8, s->x1, 8); | ||||
|     } | ||||
|     P(s, nr); | ||||
|     m += ASCON_AEAD_RATE; | ||||
|     c += ASCON_AEAD_RATE; | ||||
|     mlen -= ASCON_AEAD_RATE; | ||||
|   } | ||||
|   /* final plaintext block */ | ||||
|   word_t* px = &s->x0; | ||||
|   if (ASCON_AEAD_RATE == 16 && mlen >= 8) { | ||||
|     s->x0 = XOR(s->x0, LOAD(m, 8)); | ||||
|     STORE(c, s->x0, 8); | ||||
|     px = &s->x1; | ||||
|     m += 8; | ||||
|     c += 8; | ||||
|     mlen -= 8; | ||||
|   } | ||||
|   *px = XOR(*px, PAD(mlen)); | ||||
|   if (mlen) { | ||||
|     *px = XOR(*px, LOAD(m, mlen)); | ||||
|     STORE(c, *px, mlen); | ||||
|   } | ||||
|   printstate("process plaintext", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_decrypt(state_t* s, uint8_t* m, const uint8_t* c, | ||||
|                                uint64_t clen) { | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   /* full ciphertext blocks */ | ||||
|   while (clen >= ASCON_AEAD_RATE) { | ||||
|     word_t cx = LOAD(c, 8); | ||||
|     s->x0 = XOR(s->x0, cx); | ||||
|     STORE(m, s->x0, 8); | ||||
|     s->x0 = cx; | ||||
|     if (ASCON_AEAD_RATE == 16) { | ||||
|       cx = LOAD(c + 8, 8); | ||||
|       s->x1 = XOR(s->x1, cx); | ||||
|       STORE(m + 8, s->x1, 8); | ||||
|       s->x1 = cx; | ||||
|     } | ||||
|     P(s, nr); | ||||
|     m += ASCON_AEAD_RATE; | ||||
|     c += ASCON_AEAD_RATE; | ||||
|     clen -= ASCON_AEAD_RATE; | ||||
|   } | ||||
|   /* final ciphertext block */ | ||||
|   word_t* px = &s->x0; | ||||
|   if (ASCON_AEAD_RATE == 16 && clen >= 8) { | ||||
|     word_t cx = LOAD(c, 8); | ||||
|     s->x0 = XOR(s->x0, cx); | ||||
|     STORE(m, s->x0, 8); | ||||
|     s->x0 = cx; | ||||
|     px = &s->x1; | ||||
|     m += 8; | ||||
|     c += 8; | ||||
|     clen -= 8; | ||||
|   } | ||||
|   *px = XOR(*px, PAD(clen)); | ||||
|   if (clen) { | ||||
|     word_t cx = LOAD(c, clen); | ||||
|     *px = XOR(*px, cx); | ||||
|     STORE(m, *px, clen); | ||||
|     *px = CLEAR(*px, clen); | ||||
|     *px = XOR(*px, cx); | ||||
|   } | ||||
|   printstate("process ciphertext", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_final(state_t* s, const uint8_t* k) { | ||||
|   /* load key */ | ||||
|   word_t K0, K1, K2; | ||||
|   ascon_loadkey(&K0, &K1, &K2, k); | ||||
|   /* finalize */ | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 8) { | ||||
|     s->x1 = XOR(s->x1, K1); | ||||
|     s->x2 = XOR(s->x2, K2); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 16) { | ||||
|     s->x2 = XOR(s->x2, K1); | ||||
|     s->x3 = XOR(s->x3, K2); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 20) { | ||||
|     s->x1 = XOR(s->x1, KEYROT(K0, K1)); | ||||
|     s->x2 = XOR(s->x2, KEYROT(K1, K2)); | ||||
|     s->x3 = XOR(s->x3, KEYROT(K2, WORD_T(0))); | ||||
|   } | ||||
|   P(s, 12); | ||||
|   s->x3 = XOR(s->x3, K1); | ||||
|   s->x4 = XOR(s->x4, K2); | ||||
|   printstate("finalization", s); | ||||
| } | ||||
|  | ||||
| int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen, | ||||
|                         const unsigned char* m, unsigned long long mlen, | ||||
|                         const unsigned char* ad, unsigned long long adlen, | ||||
|                         const unsigned char* nsec, const unsigned char* npub, | ||||
|                         const unsigned char* k) { | ||||
|   state_t s; | ||||
|   (void)nsec; | ||||
|   *clen = mlen + CRYPTO_ABYTES; | ||||
|   /* perform ascon computation */ | ||||
|   ascon_aeadinit(&s, npub, k); | ||||
|   ascon_adata(&s, ad, adlen); | ||||
|   ascon_encrypt(&s, c, m, mlen); | ||||
|   ascon_final(&s, k); | ||||
|   /* set tag */ | ||||
|   STOREBYTES(c + mlen, s.x3, 8); | ||||
|   STOREBYTES(c + mlen + 8, s.x4, 8); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int crypto_aead_decrypt(unsigned char* m, unsigned long long* mlen, | ||||
|                         unsigned char* nsec, const unsigned char* c, | ||||
|                         unsigned long long clen, const unsigned char* ad, | ||||
|                         unsigned long long adlen, const unsigned char* npub, | ||||
|                         const unsigned char* k) { | ||||
|   state_t s; | ||||
|   (void)nsec; | ||||
|   if (clen < CRYPTO_ABYTES) return -1; | ||||
|   *mlen = clen = clen - CRYPTO_ABYTES; | ||||
|   /* perform ascon computation */ | ||||
|   ascon_aeadinit(&s, npub, k); | ||||
|   ascon_adata(&s, ad, adlen); | ||||
|   ascon_decrypt(&s, m, c, clen); | ||||
|   ascon_final(&s, k); | ||||
|   /* verify tag (should be constant time, check compiler output) */ | ||||
|   s.x3 = XOR(s.x3, LOADBYTES(c + clen, 8)); | ||||
|   s.x4 = XOR(s.x4, LOADBYTES(c + clen + 8, 8)); | ||||
|   return NOTZERO(s.x3, s.x4); | ||||
| } | ||||
| @@ -1,7 +0,0 @@ | ||||
| #define CRYPTO_VERSION "1.2.5" | ||||
| #define CRYPTO_KEYBYTES 16 | ||||
| #define CRYPTO_NSECBYTES 0 | ||||
| #define CRYPTO_NPUBBYTES 16 | ||||
| #define CRYPTO_ABYTES 16 | ||||
| #define CRYPTO_NOOVERLAP 1 | ||||
| #define ASCON_AEAD_RATE 16 | ||||
| @@ -1,18 +0,0 @@ | ||||
| #ifndef ASCON_H_ | ||||
| #define ASCON_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "word.h" | ||||
|  | ||||
| typedef struct { | ||||
|   word_t x0, x1, x2, x3, x4; | ||||
| } state_t; | ||||
|  | ||||
| void ascon_aeadinit(state_t* s, const uint8_t* npub, const uint8_t* k); | ||||
| void ascon_adata(state_t* s, const uint8_t* ad, uint64_t adlen); | ||||
| void ascon_encrypt(state_t* s, uint8_t* c, const uint8_t* m, uint64_t mlen); | ||||
| void ascon_decrypt(state_t* s, uint8_t* m, const uint8_t* c, uint64_t clen); | ||||
| void ascon_final(state_t* s, const uint8_t* k); | ||||
|  | ||||
| #endif /* ASCON_H */ | ||||
| @@ -1,19 +0,0 @@ | ||||
| #ifndef CONFIG_H_ | ||||
| #define CONFIG_H_ | ||||
|  | ||||
| /* inline the ascon mode */ | ||||
| #ifndef ASCON_INLINE_MODE | ||||
| #define ASCON_INLINE_MODE 0 | ||||
| #endif | ||||
|  | ||||
| /* inline all permutations */ | ||||
| #ifndef ASCON_INLINE_PERM | ||||
| #define ASCON_INLINE_PERM 1 | ||||
| #endif | ||||
|  | ||||
| /* unroll permutation loops */ | ||||
| #ifndef ASCON_UNROLL_LOOPS | ||||
| #define ASCON_UNROLL_LOOPS 0 | ||||
| #endif | ||||
|  | ||||
| #endif /* CONFIG_H_ */ | ||||
| @@ -1,39 +0,0 @@ | ||||
| #ifndef ENDIAN_H_ | ||||
| #define ENDIAN_H_ | ||||
|  | ||||
| #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | ||||
|  | ||||
| /* macros for big endian machines */ | ||||
| #ifdef PRAGMA_ENDIAN | ||||
| #pragma message("Using macros for big endian machines") | ||||
| #endif | ||||
| #define U64BIG(x) (x) | ||||
| #define U32BIG(x) (x) | ||||
| #define U16BIG(x) (x) | ||||
|  | ||||
| #elif defined(_MSC_VER) || \ | ||||
|     (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) | ||||
|  | ||||
| /* macros for little endian machines */ | ||||
| #ifdef PRAGMA_ENDIAN | ||||
| #pragma message("Using macros for little endian machines") | ||||
| #endif | ||||
| #define U64BIG(x)                          \ | ||||
|   (((0x00000000000000FFULL & (x)) << 56) | \ | ||||
|    ((0x000000000000FF00ULL & (x)) << 40) | \ | ||||
|    ((0x0000000000FF0000ULL & (x)) << 24) | \ | ||||
|    ((0x00000000FF000000ULL & (x)) << 8) |  \ | ||||
|    ((0x000000FF00000000ULL & (x)) >> 8) |  \ | ||||
|    ((0x0000FF0000000000ULL & (x)) >> 24) | \ | ||||
|    ((0x00FF000000000000ULL & (x)) >> 40) | \ | ||||
|    ((0xFF00000000000000ULL & (x)) >> 56)) | ||||
| #define U32BIG(x)                                           \ | ||||
|   (((0x000000FF & (x)) << 24) | ((0x0000FF00 & (x)) << 8) | \ | ||||
|    ((0x00FF0000 & (x)) >> 8) | ((0xFF000000 & (x)) >> 24)) | ||||
| #define U16BIG(x) (((0x00FF & (x)) << 8) | ((0xFF00 & (x)) >> 8)) | ||||
|  | ||||
| #else | ||||
| #error "Ascon byte order macros not defined in endian.h" | ||||
| #endif | ||||
|  | ||||
| #endif /* ENDIAN_H_ */ | ||||
| @@ -1,19 +0,0 @@ | ||||
| #ifndef FORCEINLINE_H_ | ||||
| #define FORCEINLINE_H_ | ||||
|  | ||||
| /* define forceinline macro */ | ||||
| #ifdef _MSC_VER | ||||
| #define forceinline __forceinline | ||||
| #elif defined(__GNUC__) | ||||
| #define forceinline inline __attribute__((__always_inline__)) | ||||
| #elif defined(__CLANG__) | ||||
| #if __has_attribute(__always_inline__) | ||||
| #define forceinline inline __attribute__((__always_inline__)) | ||||
| #else | ||||
| #define forceinline inline | ||||
| #endif | ||||
| #else | ||||
| #define forceinline inline | ||||
| #endif | ||||
|  | ||||
| #endif /* FORCEINLINE_H_ */ | ||||
| @@ -1 +0,0 @@ | ||||
| Branches reviewed 2020-11-13 by Martin Schläffer. | ||||
| @@ -1 +0,0 @@ | ||||
| Addresses reviewed 2020-11-13 by Martin Schläffer. | ||||
| @@ -1,2 +0,0 @@ | ||||
| Christoph Dobraunig | ||||
| Martin Schläffer | ||||
| @@ -1,49 +0,0 @@ | ||||
| #ifndef INTERLEAVE_H_ | ||||
| #define INTERLEAVE_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "forceinline.h" | ||||
|  | ||||
| forceinline uint32_t deinterleave_uint32(uint32_t x) { | ||||
|   uint32_t t; | ||||
|   t = (x ^ (x >> 1)) & 0x22222222, x ^= t ^ (t << 1); | ||||
|   t = (x ^ (x >> 2)) & 0x0C0C0C0C, x ^= t ^ (t << 2); | ||||
|   t = (x ^ (x >> 4)) & 0x00F000F0, x ^= t ^ (t << 4); | ||||
|   t = (x ^ (x >> 8)) & 0x0000FF00, x ^= t ^ (t << 8); | ||||
|   return x; | ||||
| } | ||||
|  | ||||
| forceinline uint32_t interleave_uint32(uint32_t x) { | ||||
|   uint32_t t; | ||||
|   t = (x ^ (x >> 8)) & 0x0000FF00, x ^= t ^ (t << 8); | ||||
|   t = (x ^ (x >> 4)) & 0x00F000F0, x ^= t ^ (t << 4); | ||||
|   t = (x ^ (x >> 2)) & 0x0C0C0C0C, x ^= t ^ (t << 2); | ||||
|   t = (x ^ (x >> 1)) & 0x22222222, x ^= t ^ (t << 1); | ||||
|   return x; | ||||
| } | ||||
|  | ||||
| /* credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ | ||||
| forceinline uint64_t deinterleave32(uint64_t in) { | ||||
|   uint32_t hi = in >> 32; | ||||
|   uint32_t lo = in; | ||||
|   uint32_t r0, r1; | ||||
|   lo = deinterleave_uint32(lo); | ||||
|   hi = deinterleave_uint32(hi); | ||||
|   r0 = (lo & 0x0000FFFF) | (hi << 16); | ||||
|   r1 = (lo >> 16) | (hi & 0xFFFF0000); | ||||
|   return (uint64_t)r1 << 32 | r0; | ||||
| } | ||||
|  | ||||
| /* credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ | ||||
| forceinline uint64_t interleave32(uint64_t in) { | ||||
|   uint32_t r0 = in; | ||||
|   uint32_t r1 = in >> 32; | ||||
|   uint32_t lo = (r0 & 0x0000FFFF) | (r1 << 16); | ||||
|   uint32_t hi = (r0 >> 16) | (r1 & 0xFFFF0000); | ||||
|   lo = interleave_uint32(lo); | ||||
|   hi = interleave_uint32(hi); | ||||
|   return (uint64_t)hi << 32 | lo; | ||||
| } | ||||
|  | ||||
| #endif /* INTERLEAVE_H_ */ | ||||
| @@ -1,23 +0,0 @@ | ||||
| #include "permutations.h" | ||||
|  | ||||
| #if !ASCON_UNROLL_LOOPS | ||||
|  | ||||
| const uint8_t constants[][2] = {{0xc, 0xc}, {0x9, 0xc}, {0xc, 0x9}, {0x9, 0x9}, | ||||
|                                 {0x6, 0xc}, {0x3, 0xc}, {0x6, 0x9}, {0x3, 0x9}, | ||||
|                                 {0xc, 0x6}, {0x9, 0x6}, {0xc, 0x3}, {0x9, 0x3}}; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if !ASCON_INLINE_PERM && ASCON_UNROLL_LOOPS | ||||
|  | ||||
| void P12(state_t* s) { P12ROUNDS(s); } | ||||
| void P8(state_t* s) { P8ROUNDS(s); } | ||||
| void P6(state_t* s) { P6ROUNDS(s); } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if !ASCON_INLINE_PERM && !ASCON_UNROLL_LOOPS | ||||
|  | ||||
| void P(state_t* s, int nr) { PROUNDS(s, nr); } | ||||
|  | ||||
| #endif | ||||
| @@ -1,139 +0,0 @@ | ||||
| #ifndef PERMUTATIONS_H_ | ||||
| #define PERMUTATIONS_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "api.h" | ||||
| #include "ascon.h" | ||||
| #include "config.h" | ||||
| #include "printstate.h" | ||||
| #include "round.h" | ||||
|  | ||||
| #define ASCON_128_KEYBYTES 16 | ||||
| #define ASCON_128A_KEYBYTES 16 | ||||
| #define ASCON_80PQ_KEYBYTES 20 | ||||
|  | ||||
| #define ASCON_128_RATE 8 | ||||
| #define ASCON_128A_RATE 16 | ||||
| #define ASCON_HASH_RATE 8 | ||||
|  | ||||
| #define ASCON_128_PA_ROUNDS 12 | ||||
| #define ASCON_128_PB_ROUNDS 6 | ||||
|  | ||||
| #define ASCON_128A_PA_ROUNDS 12 | ||||
| #define ASCON_128A_PB_ROUNDS 8 | ||||
|  | ||||
| #define ASCON_HASH_PA_ROUNDS 12 | ||||
| #define ASCON_HASH_PB_ROUNDS 12 | ||||
|  | ||||
| #define ASCON_HASHA_PA_ROUNDS 12 | ||||
| #define ASCON_HASHA_PB_ROUNDS 8 | ||||
|  | ||||
| #define ASCON_HASH_BYTES 32 | ||||
|  | ||||
| #define ASCON_128_IV WORD_T(0x8021000008220000ull) | ||||
| #define ASCON_128A_IV WORD_T(0x8822000000200000ull) | ||||
| #define ASCON_80PQ_IV WORD_T(0xc021000008220000ull) | ||||
| #define ASCON_HASH_IV WORD_T(0x0020000008020010ull) | ||||
| #define ASCON_XOF_IV WORD_T(0x0020000008020000ull) | ||||
|  | ||||
| #define ASCON_HASH_IV0 WORD_T(0xf9afb5c6a540dbc7ull) | ||||
| #define ASCON_HASH_IV1 WORD_T(0xbd2493011445a340ull) | ||||
| #define ASCON_HASH_IV2 WORD_T(0xcb9ba8b5604d4fc8ull) | ||||
| #define ASCON_HASH_IV3 WORD_T(0x12a4eede94514c98ull) | ||||
| #define ASCON_HASH_IV4 WORD_T(0x4bca84c06339f398ull) | ||||
|  | ||||
| #define ASCON_HASHA_IV0 WORD_T(0x0108e46d1b16eb02ull) | ||||
| #define ASCON_HASHA_IV1 WORD_T(0x5b9b8efdd29083f3ull) | ||||
| #define ASCON_HASHA_IV2 WORD_T(0x7ad665622891ae4aull) | ||||
| #define ASCON_HASHA_IV3 WORD_T(0x9dc27156ee3bfc7full) | ||||
| #define ASCON_HASHA_IV4 WORD_T(0xc61d5fa916801633ull) | ||||
|  | ||||
| #define ASCON_XOF_IV0 WORD_T(0xc75782817e351ae6ull) | ||||
| #define ASCON_XOF_IV1 WORD_T(0x70045f441d238220ull) | ||||
| #define ASCON_XOF_IV2 WORD_T(0x5dd5ab52a13e3f04ull) | ||||
| #define ASCON_XOF_IV3 WORD_T(0x3e378142c30c1db2ull) | ||||
| #define ASCON_XOF_IV4 WORD_T(0x3735189db624d656ull) | ||||
|  | ||||
| #define ASCON_XOFA_IV0 WORD_T(0x0846d7a5a4b87d44ull) | ||||
| #define ASCON_XOFA_IV1 WORD_T(0xaa6f1005b3a2dbf4ull) | ||||
| #define ASCON_XOFA_IV2 WORD_T(0xdc451146f713e811ull) | ||||
| #define ASCON_XOFA_IV3 WORD_T(0x468cb2532839e30dull) | ||||
| #define ASCON_XOFA_IV4 WORD_T(0xeb2d429709e96977ull) | ||||
|  | ||||
| #define START(n) (12 - n) | ||||
| #define RC(e, o) WORD_T((uint64_t)o << 32 | e) | ||||
|  | ||||
| forceinline void P12ROUNDS(state_t* s) { | ||||
|   ROUND(s, RC(0xc, 0xc)); | ||||
|   ROUND(s, RC(0x9, 0xc)); | ||||
|   ROUND(s, RC(0xc, 0x9)); | ||||
|   ROUND(s, RC(0x9, 0x9)); | ||||
|   ROUND(s, RC(0x6, 0xc)); | ||||
|   ROUND(s, RC(0x3, 0xc)); | ||||
|   ROUND(s, RC(0x6, 0x9)); | ||||
|   ROUND(s, RC(0x3, 0x9)); | ||||
|   ROUND(s, RC(0xc, 0x6)); | ||||
|   ROUND(s, RC(0x9, 0x6)); | ||||
|   ROUND(s, RC(0xc, 0x3)); | ||||
|   ROUND(s, RC(0x9, 0x3)); | ||||
| } | ||||
|  | ||||
| forceinline void P8ROUNDS(state_t* s) { | ||||
|   ROUND(s, RC(0x6, 0xc)); | ||||
|   ROUND(s, RC(0x3, 0xc)); | ||||
|   ROUND(s, RC(0x6, 0x9)); | ||||
|   ROUND(s, RC(0x3, 0x9)); | ||||
|   ROUND(s, RC(0xc, 0x6)); | ||||
|   ROUND(s, RC(0x9, 0x6)); | ||||
|   ROUND(s, RC(0xc, 0x3)); | ||||
|   ROUND(s, RC(0x9, 0x3)); | ||||
| } | ||||
|  | ||||
| forceinline void P6ROUNDS(state_t* s) { | ||||
|   ROUND(s, RC(0x6, 0x9)); | ||||
|   ROUND(s, RC(0x3, 0x9)); | ||||
|   ROUND(s, RC(0xc, 0x6)); | ||||
|   ROUND(s, RC(0x9, 0x6)); | ||||
|   ROUND(s, RC(0xc, 0x3)); | ||||
|   ROUND(s, RC(0x9, 0x3)); | ||||
| } | ||||
|  | ||||
| extern const uint8_t constants[][2]; | ||||
|  | ||||
| forceinline void PROUNDS(state_t* s, int nr) { | ||||
|   for (int i = START(nr); i < 12; i++) | ||||
|     ROUND(s, RC(constants[i][0], constants[i][1])); | ||||
| } | ||||
|  | ||||
| #if ASCON_INLINE_PERM && ASCON_UNROLL_LOOPS | ||||
|  | ||||
| forceinline void P(state_t* s, int nr) { | ||||
|   if (nr == 12) P12ROUNDS(s); | ||||
|   if (nr == 8) P8ROUNDS(s); | ||||
|   if (nr == 6) P6ROUNDS(s); | ||||
| } | ||||
|  | ||||
| #elif !ASCON_INLINE_PERM && ASCON_UNROLL_LOOPS | ||||
|  | ||||
| void P12(state_t* s); | ||||
| void P8(state_t* s); | ||||
| void P6(state_t* s); | ||||
|  | ||||
| forceinline void P(state_t* s, int nr) { | ||||
|   if (nr == 12) P12(s); | ||||
|   if (nr == 8) P8(s); | ||||
|   if (nr == 6) P6(s); | ||||
| } | ||||
|  | ||||
| #elif ASCON_INLINE_PERM && !ASCON_UNROLL_LOOPS | ||||
|  | ||||
| forceinline void P(state_t* s, int nr) { PROUNDS(s, nr); } | ||||
|  | ||||
| #else /* !ASCON_INLINE_PERM && !ASCON_UNROLL_LOOPS */ | ||||
|  | ||||
| void P(state_t* s, int nr); | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif /* PERMUTATIONS_H_ */ | ||||
| @@ -1,21 +0,0 @@ | ||||
| #ifdef ASCON_PRINTSTATE | ||||
|  | ||||
| #include "printstate.h" | ||||
|  | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| void printword(const char* text, const word_t x) { | ||||
|   printf("%s=%016" PRIx64 "\n", text, WORDTOU64(x)); | ||||
| } | ||||
|  | ||||
| void printstate(const char* text, const state_t* s) { | ||||
|   printf("%s:\n", text); | ||||
|   printword("  x0", s->x0); | ||||
|   printword("  x1", s->x1); | ||||
|   printword("  x2", s->x2); | ||||
|   printword("  x3", s->x3); | ||||
|   printword("  x4", s->x4); | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -1,24 +0,0 @@ | ||||
| #ifndef PRINTSTATE_H_ | ||||
| #define PRINTSTATE_H_ | ||||
|  | ||||
| #ifdef ASCON_PRINTSTATE | ||||
|  | ||||
| #include "ascon.h" | ||||
| #include "word.h" | ||||
|  | ||||
| void printword(const char* text, const word_t x); | ||||
| void printstate(const char* text, const state_t* s); | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define printword(text, w) \ | ||||
|   do {                     \ | ||||
|   } while (0) | ||||
|  | ||||
| #define printstate(text, s) \ | ||||
|   do {                      \ | ||||
|   } while (0) | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif /* PRINTSTATE_H_ */ | ||||
| @@ -1,53 +0,0 @@ | ||||
| #ifndef ROUND_H_ | ||||
| #define ROUND_H_ | ||||
|  | ||||
| #include "ascon.h" | ||||
| #include "printstate.h" | ||||
|  | ||||
| forceinline void KINIT(word_t* K0, word_t* K1, word_t* K2) { | ||||
|   *K0 = WORD_T(0); | ||||
|   *K1 = WORD_T(0); | ||||
|   *K2 = WORD_T(0); | ||||
| } | ||||
|  | ||||
| forceinline void PINIT(state_t* s) { | ||||
|   s->x0 = WORD_T(0); | ||||
|   s->x1 = WORD_T(0); | ||||
|   s->x2 = WORD_T(0); | ||||
|   s->x3 = WORD_T(0); | ||||
|   s->x4 = WORD_T(0); | ||||
| } | ||||
|  | ||||
| forceinline void ROUND(state_t* s, word_t C) { | ||||
|   word_t xtemp; | ||||
|   /* round constant */ | ||||
|   s->x2 = XOR(s->x2, C); | ||||
|   /* s-box layer */ | ||||
|   s->x0 = XOR(s->x0, s->x4); | ||||
|   s->x4 = XOR(s->x4, s->x3); | ||||
|   s->x2 = XOR(s->x2, s->x1); | ||||
|   xtemp = AND(s->x0, NOT(s->x4)); | ||||
|   s->x0 = XOR(s->x0, AND(s->x2, NOT(s->x1))); | ||||
|   s->x2 = XOR(s->x2, AND(s->x4, NOT(s->x3))); | ||||
|   s->x4 = XOR(s->x4, AND(s->x1, NOT(s->x0))); | ||||
|   s->x1 = XOR(s->x1, AND(s->x3, NOT(s->x2))); | ||||
|   s->x3 = XOR(s->x3, xtemp); | ||||
|   s->x1 = XOR(s->x1, s->x0); | ||||
|   s->x3 = XOR(s->x3, s->x2); | ||||
|   s->x0 = XOR(s->x0, s->x4); | ||||
|   /* linear layer */ | ||||
|   xtemp = XOR(s->x0, ROR(s->x0, 28 - 19)); | ||||
|   s->x0 = XOR(s->x0, ROR(xtemp, 19)); | ||||
|   xtemp = XOR(s->x1, ROR(s->x1, 61 - 39)); | ||||
|   s->x1 = XOR(s->x1, ROR(xtemp, 39)); | ||||
|   xtemp = XOR(s->x2, ROR(s->x2, 6 - 1)); | ||||
|   s->x2 = XOR(s->x2, ROR(xtemp, 1)); | ||||
|   xtemp = XOR(s->x3, ROR(s->x3, 17 - 10)); | ||||
|   s->x3 = XOR(s->x3, ROR(xtemp, 10)); | ||||
|   xtemp = XOR(s->x4, ROR(s->x4, 41 - 7)); | ||||
|   s->x4 = XOR(s->x4, ROR(xtemp, 7)); | ||||
|   s->x2 = NOT(s->x2); | ||||
|   printstate(" round output", s); | ||||
| } | ||||
|  | ||||
| #endif /* ROUND_H_ */ | ||||
| @@ -1,105 +0,0 @@ | ||||
| #ifndef WORD_H_ | ||||
| #define WORD_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "endian.h" | ||||
| #include "forceinline.h" | ||||
| #include "interleave.h" | ||||
|  | ||||
| typedef struct { | ||||
|   uint32_t e; | ||||
|   uint32_t o; | ||||
| } word_t; | ||||
|  | ||||
| forceinline uint32_t ROR32(uint32_t x, int n) { | ||||
|   return (n == 0) ? x : x >> n | x << (32 - n); | ||||
| } | ||||
|  | ||||
| forceinline word_t ROR(word_t x, int n) { | ||||
|   word_t r; | ||||
|   r.e = (n % 2) ? ROR32(x.o, (n - 1) / 2) : ROR32(x.e, n / 2); | ||||
|   r.o = (n % 2) ? ROR32(x.e, (n + 1) / 2) : ROR32(x.o, n / 2); | ||||
|   return r; | ||||
| } | ||||
|  | ||||
| forceinline word_t WORD_T(uint64_t x) { return (word_t){.o = x >> 32, .e = x}; } | ||||
|  | ||||
| forceinline uint64_t UINT64_T(word_t x) { return (uint64_t)x.o << 32 | x.e; } | ||||
|  | ||||
| forceinline word_t U64TOWORD(uint64_t x) { return WORD_T(deinterleave32(x)); } | ||||
|  | ||||
| forceinline uint64_t WORDTOU64(word_t w) { return interleave32(UINT64_T(w)); } | ||||
|  | ||||
| forceinline word_t NOT(word_t a) { | ||||
|   a.e = ~a.e; | ||||
|   a.o = ~a.o; | ||||
|   return a; | ||||
| } | ||||
|  | ||||
| forceinline word_t XOR(word_t a, word_t b) { | ||||
|   a.e ^= b.e; | ||||
|   a.o ^= b.o; | ||||
|   return a; | ||||
| } | ||||
|  | ||||
| forceinline word_t AND(word_t a, word_t b) { | ||||
|   a.e &= b.e; | ||||
|   a.o &= b.o; | ||||
|   return a; | ||||
| } | ||||
|  | ||||
| forceinline word_t KEYROT(word_t lo2hi, word_t hi2lo) { | ||||
|   word_t r; | ||||
|   r.e = lo2hi.e << 16 | hi2lo.e >> 16; | ||||
|   r.o = lo2hi.o << 16 | hi2lo.o >> 16; | ||||
|   return r; | ||||
| } | ||||
|  | ||||
| forceinline int NOTZERO(word_t a, word_t b) { | ||||
|   uint32_t result = a.e | a.o | b.e | b.o; | ||||
|   result |= result >> 16; | ||||
|   result |= result >> 8; | ||||
|   return ((((int)(result & 0xff) - 1) >> 8) & 1) - 1; | ||||
| } | ||||
|  | ||||
| forceinline word_t PAD(int i) { | ||||
|   return WORD_T((uint64_t)(0x8ul << (28 - 4 * i)) << 32); | ||||
| } | ||||
|  | ||||
| forceinline word_t CLEAR(word_t w, int n) { | ||||
|   /* undefined for n == 0 */ | ||||
|   uint32_t mask = 0x0fffffff >> (n * 4 - 4); | ||||
|   w.e &= mask; | ||||
|   w.o &= mask; | ||||
|   return w; | ||||
| } | ||||
|  | ||||
| forceinline uint64_t MASK(int n) { | ||||
|   /* undefined for n == 0 */ | ||||
|   return ~0ull >> (64 - 8 * n); | ||||
| } | ||||
|  | ||||
| forceinline word_t LOAD(const uint8_t* bytes, int n) { | ||||
|   uint64_t x = *(uint64_t*)bytes & MASK(n); | ||||
|   return U64TOWORD(U64BIG(x)); | ||||
| } | ||||
|  | ||||
| forceinline void STORE(uint8_t* bytes, word_t w, int n) { | ||||
|   uint64_t x = WORDTOU64(w); | ||||
|   *(uint64_t*)bytes &= ~MASK(n); | ||||
|   *(uint64_t*)bytes |= U64BIG(x); | ||||
| } | ||||
|  | ||||
| forceinline word_t LOADBYTES(const uint8_t* bytes, int n) { | ||||
|   uint64_t x = 0; | ||||
|   for (int i = 0; i < n; ++i) ((uint8_t*)&x)[7 - i] = bytes[i]; | ||||
|   return U64TOWORD(x); | ||||
| } | ||||
|  | ||||
| forceinline void STOREBYTES(uint8_t* bytes, word_t w, int n) { | ||||
|   uint64_t x = WORDTOU64(w); | ||||
|   for (int i = 0; i < n; ++i) bytes[i] = ((uint8_t*)&x)[7 - i]; | ||||
| } | ||||
|  | ||||
| #endif /* WORD_H_ */ | ||||
| @@ -1,79 +0,0 @@ | ||||
| #include "api.h" | ||||
| #include "ascon.h" | ||||
| #include "permutations.h" | ||||
| #include "printstate.h" | ||||
|  | ||||
| forceinline void ascon_loadkey(word_t* K0, word_t* K1, word_t* K2, | ||||
|                                const uint8_t* k) { | ||||
|   KINIT(K0, K1, K2); | ||||
|   if (CRYPTO_KEYBYTES == 16) { | ||||
|     *K1 = XOR(*K1, LOAD(k, 8)); | ||||
|     *K2 = XOR(*K2, LOAD(k + 8, 8)); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 20) { | ||||
|     *K0 = XOR(*K0, KEYROT(WORD_T(0), LOADBYTES(k, 4))); | ||||
|     *K1 = XOR(*K1, LOADBYTES(k + 4, 8)); | ||||
|     *K2 = XOR(*K2, LOADBYTES(k + 12, 8)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| forceinline void ascon_aeadinit(state_t* s, const uint8_t* npub, word_t K0, | ||||
|                                 word_t K1, word_t K2) { | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 8) s->x0 = ASCON_128_IV; | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 16) s->x0 = ASCON_128A_IV; | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x0 = ASCON_80PQ_IV; | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x0 = XOR(s->x0, K0); | ||||
|   s->x1 = K1; | ||||
|   s->x2 = K2; | ||||
|   s->x3 = LOAD(npub, 8); | ||||
|   s->x4 = LOAD(npub + 8, 8); | ||||
|   P(s, 12); | ||||
|   if (CRYPTO_KEYBYTES == 20) s->x2 = XOR(s->x2, K0); | ||||
|   s->x3 = XOR(s->x3, K1); | ||||
|   s->x4 = XOR(s->x4, K2); | ||||
|   printstate("initialization", s); | ||||
| } | ||||
|  | ||||
| forceinline void ascon_final(state_t* s, word_t K0, word_t K1, word_t K2) { | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 8) { | ||||
|     s->x1 = XOR(s->x1, K1); | ||||
|     s->x2 = XOR(s->x2, K2); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 16 && ASCON_AEAD_RATE == 16) { | ||||
|     s->x2 = XOR(s->x2, K1); | ||||
|     s->x3 = XOR(s->x3, K2); | ||||
|   } | ||||
|   if (CRYPTO_KEYBYTES == 20) { | ||||
|     s->x1 = XOR(s->x1, KEYROT(K0, K1)); | ||||
|     s->x2 = XOR(s->x2, KEYROT(K1, K2)); | ||||
|     s->x3 = XOR(s->x3, KEYROT(K2, WORD_T(0))); | ||||
|   } | ||||
|   P(s, 12); | ||||
|   s->x3 = XOR(s->x3, K1); | ||||
|   s->x4 = XOR(s->x4, K2); | ||||
|   printstate("finalization", s); | ||||
| } | ||||
|  | ||||
| void ascon_aead(state_t* s, uint8_t* out, const uint8_t* in, uint64_t tlen, | ||||
|                 const uint8_t* ad, uint64_t adlen, const uint8_t* npub, | ||||
|                 const uint8_t* k, uint8_t mode) { | ||||
|   const int nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; | ||||
|   word_t K0, K1, K2; | ||||
|   ascon_loadkey(&K0, &K1, &K2, k); | ||||
|   /* initialize */ | ||||
|   ascon_aeadinit(s, npub, K0, K1, K2); | ||||
|   /* process associated data */ | ||||
|   if (adlen) { | ||||
|     ascon_update(s, (void*)0, ad, adlen, ASCON_ABSORB); | ||||
|     P(s, nr); | ||||
|   } | ||||
|   /* domain separation */ | ||||
|   s->x4 = XOR(s->x4, WORD_T(1)); | ||||
|   printstate("process associated data", s); | ||||
|   /* process plaintext/ciphertext */ | ||||
|   ascon_update(s, out, in, tlen, mode); | ||||
|   if (mode == ASCON_ENCRYPT) printstate("process plaintext", s); | ||||
|   if (mode == ASCON_DECRYPT) printstate("process ciphertext", s); | ||||
|   /* finalize */ | ||||
|   ascon_final(s, K0, K1, K2); | ||||
| } | ||||
| @@ -1,7 +0,0 @@ | ||||
| #define CRYPTO_VERSION "1.2.5" | ||||
| #define CRYPTO_KEYBYTES 16 | ||||
| #define CRYPTO_NSECBYTES 0 | ||||
| #define CRYPTO_NPUBBYTES 16 | ||||
| #define CRYPTO_ABYTES 16 | ||||
| #define CRYPTO_NOOVERLAP 1 | ||||
| #define ASCON_AEAD_RATE 16 | ||||
| @@ -1,26 +0,0 @@ | ||||
| #ifndef ASCON_H_ | ||||
| #define ASCON_H_ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "word.h" | ||||
|  | ||||
| typedef struct { | ||||
|   word_t x0, x1, x2, x3, x4; | ||||
| } state_t; | ||||
|  | ||||
| #define ASCON_ABSORB 0x1 | ||||
| #define ASCON_SQUEEZE 0x2 | ||||
| #define ASCON_INSERT 0x4 | ||||
| #define ASCON_HASH 0x8 | ||||
| #define ASCON_ENCRYPT (ASCON_ABSORB | ASCON_SQUEEZE) | ||||
| #define ASCON_DECRYPT (ASCON_ABSORB | ASCON_SQUEEZE | ASCON_INSERT) | ||||
|  | ||||
| void ascon_update(state_t* s, uint8_t* out, const uint8_t* in, uint64_t len, | ||||
|                   uint8_t mode); | ||||
|  | ||||
| void ascon_aead(state_t* s, uint8_t* out, const uint8_t* in, uint64_t tlen, | ||||
|                 const uint8_t* ad, uint64_t adlen, const uint8_t* npub, | ||||
|                 const uint8_t* k, uint8_t mode); | ||||
|  | ||||
| #endif /* ASCON_H */ | ||||
| @@ -1,19 +0,0 @@ | ||||
| #ifndef CONFIG_H_ | ||||
| #define CONFIG_H_ | ||||
|  | ||||
| /* inline the ascon mode */ | ||||
| #ifndef ASCON_INLINE_MODE | ||||
| #define ASCON_INLINE_MODE 0 | ||||
| #endif | ||||
|  | ||||
| /* inline all permutations */ | ||||
| #ifndef ASCON_INLINE_PERM | ||||
| #define ASCON_INLINE_PERM 0 | ||||
| #endif | ||||
|  | ||||
| /* unroll permutation loops */ | ||||
| #ifndef ASCON_UNROLL_LOOPS | ||||
| #define ASCON_UNROLL_LOOPS 0 | ||||
| #endif | ||||
|  | ||||
| #endif /* CONFIG_H_ */ | ||||
| @@ -1,27 +0,0 @@ | ||||
| #include "api.h" | ||||
| #include "ascon.h" | ||||
| #include "crypto_aead.h" | ||||
| #include "permutations.h" | ||||
| #include "printstate.h" | ||||
|  | ||||
| void ascon_aead(state_t* s, uint8_t* out, const uint8_t* in, uint64_t tlen, | ||||
|                 const uint8_t* ad, uint64_t adlen, const uint8_t* npub, | ||||
|                 const uint8_t* k, uint8_t mode); | ||||
|  | ||||
| int crypto_aead_decrypt(unsigned char* m, unsigned long long* mlen, | ||||
|                         unsigned char* nsec, const unsigned char* c, | ||||
|                         unsigned long long clen, const unsigned char* ad, | ||||
|                         unsigned long long adlen, const unsigned char* npub, | ||||
|                         const unsigned char* k) { | ||||
|   state_t s; | ||||
|   (void)nsec; | ||||
|   if (clen < CRYPTO_ABYTES) return -1; | ||||
|   /* set plaintext size */ | ||||
|   *mlen = clen - CRYPTO_ABYTES; | ||||
|   /* ascon decryption */ | ||||
|   ascon_aead(&s, m, c, *mlen, ad, adlen, npub, k, ASCON_DECRYPT); | ||||
|   /* verify tag (should be constant time, check compiler output) */ | ||||
|   s.x3 = XOR(s.x3, LOADBYTES(c + *mlen, 8)); | ||||
|   s.x4 = XOR(s.x4, LOADBYTES(c + *mlen + 8, 8)); | ||||
|   return NOTZERO(s.x3, s.x4); | ||||
| } | ||||
| @@ -1,26 +0,0 @@ | ||||
| #include "api.h" | ||||
| #include "ascon.h" | ||||
| #include "crypto_aead.h" | ||||
| #include "permutations.h" | ||||
| #include "printstate.h" | ||||
|  | ||||
| void ascon_aead(state_t* s, uint8_t* out, const uint8_t* in, uint64_t tlen, | ||||
|                 const uint8_t* ad, uint64_t adlen, const uint8_t* npub, | ||||
|                 const uint8_t* k, uint8_t mode); | ||||
|  | ||||
| int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen, | ||||
|                         const unsigned char* m, unsigned long long mlen, | ||||
|                         const unsigned char* ad, unsigned long long adlen, | ||||
|                         const unsigned char* nsec, const unsigned char* npub, | ||||
|                         const unsigned char* k) { | ||||
|   state_t s; | ||||
|   (void)nsec; | ||||
|   /* set ciphertext size */ | ||||
|   *clen = mlen + CRYPTO_ABYTES; | ||||
|   /* ascon encryption */ | ||||
|   ascon_aead(&s, c, m, mlen, ad, adlen, npub, k, ASCON_ENCRYPT); | ||||
|   /* set tag */ | ||||
|   STOREBYTES(c + mlen, s.x3, 8); | ||||
|   STOREBYTES(c + mlen + 8, s.x4, 8); | ||||
|   return 0; | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user