Compare commits
	
		
			27 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0a2ac69250 | |||
| 599e8019c6 | |||
| 625f3a5e30 | |||
| 28d442db03 | |||
| 2d8b8dc34a | |||
| 74c2ec2014 | |||
| bccfc67926 | |||
| 8b3dc54e5c | |||
| 9909769c0a | |||
| 071d9cc8eb | |||
| a5825bfd67 | |||
| 36404dd7e0 | |||
| 658ffbb405 | |||
| c6bfaf0546 | |||
| e88c1148fb | |||
| 686d01ab3e | |||
| 884d445cb9 | |||
| eee14af478 | |||
| 727fdcb7bb | |||
| 3def42153f | |||
| 75ba2e7588 | |||
| 1629b165b5 | |||
| a2e932c56f | |||
| cde5ae627c | |||
| 85304d1a43 | |||
| fddf608418 | |||
| 90c45d7c3c | 
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -12,6 +12,8 @@
 | 
			
		||||
*.ilk
 | 
			
		||||
*.map
 | 
			
		||||
*.exp
 | 
			
		||||
# Objdump output
 | 
			
		||||
*.dis
 | 
			
		||||
 | 
			
		||||
# Precompiled Headers
 | 
			
		||||
*.gch
 | 
			
		||||
@@ -154,3 +156,5 @@ CTestTestfile.cmake
 | 
			
		||||
.vscode/c_cpp_properties.json
 | 
			
		||||
semihosting_test/build/semihosting_test
 | 
			
		||||
semihosting_test/build/Makefile
 | 
			
		||||
 | 
			
		||||
.cache
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
if (NOT DEFINED BOARD)
 | 
			
		||||
	set(BOARD iss)
 | 
			
		||||
endif()
 | 
			
		||||
if (NOT DEFINED ISA)
 | 
			
		||||
	set(ISA imc)
 | 
			
		||||
endif()
 | 
			
		||||
message(STATUS "Building firmware using ${BOARD} board configuration and isa ${ISA}")
 | 
			
		||||
add_custom_target(fw-common ALL 
 | 
			
		||||
	COMMAND make -C hello-world BOARD=${BOARD} ISA=${ISA} && make -C benchmarks/dhrystone BOARD=${BOARD} ISA=${ISA} && make -C benchmarks/coremark BOARD=${BOARD} ISA=${ISA}
 | 
			
		||||
    USES_TERMINAL
 | 
			
		||||
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 | 
			
		||||
 
 | 
			
		||||
 Submodule bare-metal-bsp updated: 87dc0ec230...540397494a
									
								
							
							
								
								
									
										46
									
								
								benchmarks/coremark/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								benchmarks/coremark/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
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()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Source files
 | 
			
		||||
set(SOURCES
 | 
			
		||||
    core_portme.c
 | 
			
		||||
    cvt.c
 | 
			
		||||
    ee_printf.c
 | 
			
		||||
    cm/core_list_join.c
 | 
			
		||||
    cm/core_main.c
 | 
			
		||||
    cm/core_matrix.c
 | 
			
		||||
    cm/core_state.c
 | 
			
		||||
    cm/core_util.c
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Create executable
 | 
			
		||||
add_executable(coremark ${SOURCES})
 | 
			
		||||
target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/cm)
 | 
			
		||||
target_compile_options(${TARGET} PRIVATE  -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -fno-builtin-strnlen -fno-common -funroll-loops -finline-functions -falign-functions=16 -falign-jumps=4 -falign-loops=4 -finline-limit=1000 -fno-if-conversion2 -fselective-scheduling -fno-crossjumping -freorder-blocks-and-partition -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -fno-common -funroll-loops -finline-functions -falign-functions=16 -falign-jumps=4 -falign-loops=4 -finline-limit=1000 -fno-if-conversion2 -fselective-scheduling -fno-crossjumping -freorder-blocks-and-partition )
 | 
			
		||||
target_compile_definitions(${TARGET} PRIVATE PERFORMANCE_RUN=1 CLOCKS_PER_SEC=10000000 FLAGS_STR="" PERFORMANCE_RUN=1 CLOCKS_PER_SEC=10000000 ITERATIONS=600)
 | 
			
		||||
 | 
			
		||||
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}")
 | 
			
		||||
 | 
			
		||||
add_custom_command(TARGET ${TARGET} POST_BUILD
 | 
			
		||||
        COMMAND ${CMAKE_OBJDUMP} -S  ${TARGET}.elf > ${TARGET}.dis
 | 
			
		||||
        COMMENT "Creating disassembly for ${TARGET}")
 | 
			
		||||
							
								
								
									
										70
									
								
								benchmarks/coremark/CMakePresets.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								benchmarks/coremark/CMakePresets.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
{
 | 
			
		||||
    "version": 3,
 | 
			
		||||
    "vendor": {
 | 
			
		||||
        "conan": {}
 | 
			
		||||
    },
 | 
			
		||||
    "cmakeMinimumRequired": {
 | 
			
		||||
        "major": 3,
 | 
			
		||||
        "minor": 24,
 | 
			
		||||
        "patch": 0
 | 
			
		||||
    },
 | 
			
		||||
    "configurePresets": [
 | 
			
		||||
        {
 | 
			
		||||
            "name": "debug",
 | 
			
		||||
            "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"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "release",
 | 
			
		||||
            "cacheVariables": {
 | 
			
		||||
                "CMAKE_BUILD_TYPE": "Release",    
 | 
			
		||||
                "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
@@ -15,37 +15,40 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
Original Author: Shay Gal-on
 | 
			
		||||
*/
 | 
			
		||||
#include "coremark.h"
 | 
			
		||||
#include "core_portme.h"
 | 
			
		||||
#include "coremark.h"
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
// Read cycle CSR
 | 
			
		||||
unsigned long long _read_cycle()
 | 
			
		||||
{
 | 
			
		||||
unsigned long long _read_cycle() {
 | 
			
		||||
  unsigned long long result;
 | 
			
		||||
  unsigned long lower;
 | 
			
		||||
  unsigned long upper1;
 | 
			
		||||
  unsigned long upper2;
 | 
			
		||||
 | 
			
		||||
    asm volatile (
 | 
			
		||||
        "repeat_cycle_%=: csrr %0, cycleh;\n"
 | 
			
		||||
  asm volatile("repeat_cycle_%=: csrr %0, cycleh;\n"
 | 
			
		||||
               "        csrr %1, cycle;\n"
 | 
			
		||||
               "        csrr %2, cycleh;\n"
 | 
			
		||||
               "        bne %0, %2, repeat_cycle_%=;\n"
 | 
			
		||||
        : "=r" (upper1),"=r" (lower),"=r" (upper2)    // Outputs   : temp variable for load result
 | 
			
		||||
               : "=r"(upper1), "=r"(lower),
 | 
			
		||||
                 "=r"(upper2) // Outputs   : temp variable for load result
 | 
			
		||||
               :
 | 
			
		||||
        :
 | 
			
		||||
    );
 | 
			
		||||
               :);
 | 
			
		||||
  *(unsigned long *)(&result) = lower;
 | 
			
		||||
  *((unsigned long *)(&result) + 1) = upper1;
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
volatile int tohost;
 | 
			
		||||
volatile int fromhost;
 | 
			
		||||
// extern volatile int tohost;
 | 
			
		||||
// extern volatile int fromhost;
 | 
			
		||||
 | 
			
		||||
void write_hex(int fd, uint32_t hex);
 | 
			
		||||
 | 
			
		||||
void exit(int n) {
 | 
			
		||||
      tohost = 0x1;
 | 
			
		||||
      for (;;);
 | 
			
		||||
  write_hex(STDERR_FILENO, 1);
 | 
			
		||||
  // tohost = 0x1;
 | 
			
		||||
  for (;;)
 | 
			
		||||
    ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void __libc_init_array(void) {
 | 
			
		||||
@@ -89,10 +92,7 @@ volatile ee_s32 seed5_volatile = 0;
 | 
			
		||||
   time.h and windows.h definitions included.
 | 
			
		||||
*/
 | 
			
		||||
CORETIMETYPE
 | 
			
		||||
barebones_clock()
 | 
			
		||||
{
 | 
			
		||||
    return (CORETIMETYPE)_read_cycle();
 | 
			
		||||
}
 | 
			
		||||
barebones_clock() { return (CORETIMETYPE)_read_cycle(); }
 | 
			
		||||
/* Define : TIMER_RES_DIVIDER
 | 
			
		||||
        Divider to trade off timer resolution and total time that can be
 | 
			
		||||
   measured.
 | 
			
		||||
@@ -118,11 +118,7 @@ static CORETIMETYPE start_time_val, stop_time_val;
 | 
			
		||||
   example code) or zeroing some system parameters - e.g. setting the cpu clocks
 | 
			
		||||
   cycles to 0.
 | 
			
		||||
*/
 | 
			
		||||
void
 | 
			
		||||
start_time(void)
 | 
			
		||||
{
 | 
			
		||||
    GETMYTIME(&start_time_val);
 | 
			
		||||
}
 | 
			
		||||
void start_time(void) { GETMYTIME(&start_time_val); }
 | 
			
		||||
/* Function : stop_time
 | 
			
		||||
        This function will be called right after ending the timed portion of the
 | 
			
		||||
   benchmark.
 | 
			
		||||
@@ -131,11 +127,7 @@ start_time(void)
 | 
			
		||||
   example code) or other system parameters - e.g. reading the current value of
 | 
			
		||||
   cpu cycles counter.
 | 
			
		||||
*/
 | 
			
		||||
void
 | 
			
		||||
stop_time(void)
 | 
			
		||||
{
 | 
			
		||||
    GETMYTIME(&stop_time_val);
 | 
			
		||||
}
 | 
			
		||||
void stop_time(void) { GETMYTIME(&stop_time_val); }
 | 
			
		||||
/* Function : get_time
 | 
			
		||||
        Return an abstract "ticks" number that signifies time on the system.
 | 
			
		||||
 | 
			
		||||
@@ -146,10 +138,8 @@ stop_time(void)
 | 
			
		||||
   controlled by <TIMER_RES_DIVIDER>
 | 
			
		||||
*/
 | 
			
		||||
CORE_TICKS
 | 
			
		||||
get_time(void)
 | 
			
		||||
{
 | 
			
		||||
    CORE_TICKS elapsed
 | 
			
		||||
        = (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
 | 
			
		||||
get_time(void) {
 | 
			
		||||
  CORE_TICKS elapsed = (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
 | 
			
		||||
  return elapsed;
 | 
			
		||||
}
 | 
			
		||||
/* Function : time_in_secs
 | 
			
		||||
@@ -159,9 +149,7 @@ get_time(void)
 | 
			
		||||
   floating point. Default implementation implemented by the EE_TICKS_PER_SEC
 | 
			
		||||
   macro above.
 | 
			
		||||
*/
 | 
			
		||||
secs_ret
 | 
			
		||||
time_in_secs(CORE_TICKS ticks)
 | 
			
		||||
{
 | 
			
		||||
secs_ret time_in_secs(CORE_TICKS ticks) {
 | 
			
		||||
  secs_ret retval = ((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
 | 
			
		||||
  return retval;
 | 
			
		||||
}
 | 
			
		||||
@@ -172,17 +160,12 @@ ee_u32 default_num_contexts = 1;
 | 
			
		||||
        Target specific initialization code
 | 
			
		||||
        Test for some common mistakes.
 | 
			
		||||
*/
 | 
			
		||||
void
 | 
			
		||||
portable_init(core_portable *p, int *argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    if (sizeof(ee_ptr_int) != sizeof(ee_u8 *))
 | 
			
		||||
    {
 | 
			
		||||
        ee_printf(
 | 
			
		||||
            "ERROR! Please define ee_ptr_int to a type that holds a "
 | 
			
		||||
void portable_init(core_portable *p, int *argc, char *argv[]) {
 | 
			
		||||
  if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) {
 | 
			
		||||
    ee_printf("ERROR! Please define ee_ptr_int to a type that holds a "
 | 
			
		||||
              "pointer!\n");
 | 
			
		||||
  }
 | 
			
		||||
    if (sizeof(ee_u32) != 4)
 | 
			
		||||
    {
 | 
			
		||||
  if (sizeof(ee_u32) != 4) {
 | 
			
		||||
    ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
 | 
			
		||||
  }
 | 
			
		||||
  p->portable_id = 1;
 | 
			
		||||
@@ -191,8 +174,4 @@ portable_init(core_portable *p, int *argc, char *argv[])
 | 
			
		||||
/* Function : portable_fini
 | 
			
		||||
        Target specific final code
 | 
			
		||||
*/
 | 
			
		||||
void
 | 
			
		||||
portable_fini(core_portable *p)
 | 
			
		||||
{
 | 
			
		||||
    p->portable_id = 0;
 | 
			
		||||
}
 | 
			
		||||
void portable_fini(core_portable *p) { p->portable_id = 0; }
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
#include <coremark.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#define ZEROPAD (1 << 0)   /* Pad with zero */
 | 
			
		||||
#define SIGN (1 << 1)      /* Unsigned/signed long */
 | 
			
		||||
@@ -31,27 +32,22 @@ static char *    digits       = "0123456789abcdefghijklmnopqrstuvwxyz";
 | 
			
		||||
static char *upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 | 
			
		||||
static ee_size_t strnlen(const char *s, ee_size_t count);
 | 
			
		||||
 | 
			
		||||
static ee_size_t
 | 
			
		||||
strnlen(const char *s, ee_size_t count)
 | 
			
		||||
{
 | 
			
		||||
static ee_size_t strnlen(const char *s, ee_size_t count) {
 | 
			
		||||
  const char *sc;
 | 
			
		||||
  for (sc = s; *sc != '\0' && count--; ++sc)
 | 
			
		||||
    ;
 | 
			
		||||
  return sc - s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
skip_atoi(const char **s)
 | 
			
		||||
{
 | 
			
		||||
static int skip_atoi(const char **s) {
 | 
			
		||||
  int i = 0;
 | 
			
		||||
  while (is_digit(**s))
 | 
			
		||||
    i = i * 10 + *((*s)++) - '0';
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
number(char *str, long num, int base, int size, int precision, int type)
 | 
			
		||||
{
 | 
			
		||||
static char *number(char *str, long num, int base, int size, int precision,
 | 
			
		||||
                    int type) {
 | 
			
		||||
  char c, sign, tmp[66];
 | 
			
		||||
  char *dig = digits;
 | 
			
		||||
  int i;
 | 
			
		||||
@@ -65,28 +61,21 @@ number(char *str, long num, int base, int size, int precision, int type)
 | 
			
		||||
 | 
			
		||||
  c = (type & ZEROPAD) ? '0' : ' ';
 | 
			
		||||
  sign = 0;
 | 
			
		||||
    if (type & SIGN)
 | 
			
		||||
    {
 | 
			
		||||
        if (num < 0)
 | 
			
		||||
        {
 | 
			
		||||
  if (type & SIGN) {
 | 
			
		||||
    if (num < 0) {
 | 
			
		||||
      sign = '-';
 | 
			
		||||
      num = -num;
 | 
			
		||||
      size--;
 | 
			
		||||
        }
 | 
			
		||||
        else if (type & PLUS)
 | 
			
		||||
        {
 | 
			
		||||
    } else if (type & PLUS) {
 | 
			
		||||
      sign = '+';
 | 
			
		||||
      size--;
 | 
			
		||||
        }
 | 
			
		||||
        else if (type & SPACE)
 | 
			
		||||
        {
 | 
			
		||||
    } else if (type & SPACE) {
 | 
			
		||||
      sign = ' ';
 | 
			
		||||
      size--;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    if (type & HEX_PREP)
 | 
			
		||||
    {
 | 
			
		||||
  if (type & HEX_PREP) {
 | 
			
		||||
    if (base == 16)
 | 
			
		||||
      size -= 2;
 | 
			
		||||
    else if (base == 8)
 | 
			
		||||
@@ -97,10 +86,8 @@ number(char *str, long num, int base, int size, int precision, int type)
 | 
			
		||||
 | 
			
		||||
  if (num == 0)
 | 
			
		||||
    tmp[i++] = '0';
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        while (num != 0)
 | 
			
		||||
        {
 | 
			
		||||
  else {
 | 
			
		||||
    while (num != 0) {
 | 
			
		||||
      tmp[i++] = dig[((unsigned long)num) % (unsigned)base];
 | 
			
		||||
      num = ((unsigned long)num) / (unsigned)base;
 | 
			
		||||
    }
 | 
			
		||||
@@ -115,12 +102,10 @@ number(char *str, long num, int base, int size, int precision, int type)
 | 
			
		||||
  if (sign)
 | 
			
		||||
    *str++ = sign;
 | 
			
		||||
 | 
			
		||||
    if (type & HEX_PREP)
 | 
			
		||||
    {
 | 
			
		||||
  if (type & HEX_PREP) {
 | 
			
		||||
    if (base == 8)
 | 
			
		||||
      *str++ = '0';
 | 
			
		||||
        else if (base == 16)
 | 
			
		||||
        {
 | 
			
		||||
    else if (base == 16) {
 | 
			
		||||
      *str++ = '0';
 | 
			
		||||
      *str++ = digits[33];
 | 
			
		||||
    }
 | 
			
		||||
@@ -139,9 +124,8 @@ number(char *str, long num, int base, int size, int precision, int type)
 | 
			
		||||
  return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
eaddr(char *str, unsigned char *addr, int size, int precision, int type)
 | 
			
		||||
{
 | 
			
		||||
static char *eaddr(char *str, unsigned char *addr, int size, int precision,
 | 
			
		||||
                   int type) {
 | 
			
		||||
  char tmp[24];
 | 
			
		||||
  char *dig = digits;
 | 
			
		||||
  int i, len;
 | 
			
		||||
@@ -149,8 +133,7 @@ eaddr(char *str, unsigned char *addr, int size, int precision, int type)
 | 
			
		||||
  if (type & UPPERCASE)
 | 
			
		||||
    dig = upper_digits;
 | 
			
		||||
  len = 0;
 | 
			
		||||
    for (i = 0; i < 6; i++)
 | 
			
		||||
    {
 | 
			
		||||
  for (i = 0; i < 6; i++) {
 | 
			
		||||
    if (i != 0)
 | 
			
		||||
      tmp[len++] = ':';
 | 
			
		||||
    tmp[len++] = dig[addr[i] >> 4];
 | 
			
		||||
@@ -168,32 +151,26 @@ eaddr(char *str, unsigned char *addr, int size, int precision, int type)
 | 
			
		||||
  return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
iaddr(char *str, unsigned char *addr, int size, int precision, int type)
 | 
			
		||||
{
 | 
			
		||||
static char *iaddr(char *str, unsigned char *addr, int size, int precision,
 | 
			
		||||
                   int type) {
 | 
			
		||||
  char tmp[24];
 | 
			
		||||
  int i, n, len;
 | 
			
		||||
 | 
			
		||||
  len = 0;
 | 
			
		||||
    for (i = 0; i < 4; i++)
 | 
			
		||||
    {
 | 
			
		||||
  for (i = 0; i < 4; i++) {
 | 
			
		||||
    if (i != 0)
 | 
			
		||||
      tmp[len++] = '.';
 | 
			
		||||
    n = addr[i];
 | 
			
		||||
 | 
			
		||||
    if (n == 0)
 | 
			
		||||
      tmp[len++] = digits[0];
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (n >= 100)
 | 
			
		||||
            {
 | 
			
		||||
    else {
 | 
			
		||||
      if (n >= 100) {
 | 
			
		||||
        tmp[len++] = digits[n / 100];
 | 
			
		||||
        n = n % 100;
 | 
			
		||||
        tmp[len++] = digits[n / 10];
 | 
			
		||||
        n = n % 10;
 | 
			
		||||
            }
 | 
			
		||||
            else if (n >= 10)
 | 
			
		||||
            {
 | 
			
		||||
      } else if (n >= 10) {
 | 
			
		||||
        tmp[len++] = digits[n / 10];
 | 
			
		||||
        n = n % 10;
 | 
			
		||||
      }
 | 
			
		||||
@@ -219,47 +196,37 @@ char *      ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
 | 
			
		||||
char *fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
 | 
			
		||||
static void ee_bufcpy(char *d, char *s, int count);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ee_bufcpy(char *pd, char *ps, int count)
 | 
			
		||||
{
 | 
			
		||||
void ee_bufcpy(char *pd, char *ps, int count) {
 | 
			
		||||
  char *pe = ps + count;
 | 
			
		||||
  while (ps != pe)
 | 
			
		||||
    *pd++ = *ps++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
parse_float(double value, char *buffer, char fmt, int precision)
 | 
			
		||||
{
 | 
			
		||||
static void parse_float(double value, char *buffer, char fmt, int precision) {
 | 
			
		||||
  int decpt, sign, exp, pos;
 | 
			
		||||
  char *digits = NULL;
 | 
			
		||||
  char cvtbuf[80];
 | 
			
		||||
  int capexp = 0;
 | 
			
		||||
  int magnitude;
 | 
			
		||||
 | 
			
		||||
    if (fmt == 'G' || fmt == 'E')
 | 
			
		||||
    {
 | 
			
		||||
  if (fmt == 'G' || fmt == 'E') {
 | 
			
		||||
    capexp = 1;
 | 
			
		||||
    fmt += 'a' - 'A';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    if (fmt == 'g')
 | 
			
		||||
    {
 | 
			
		||||
  if (fmt == 'g') {
 | 
			
		||||
    digits = ecvtbuf(value, precision, &decpt, &sign, cvtbuf);
 | 
			
		||||
    magnitude = decpt - 1;
 | 
			
		||||
        if (magnitude < -4 || magnitude > precision - 1)
 | 
			
		||||
        {
 | 
			
		||||
    if (magnitude < -4 || magnitude > precision - 1) {
 | 
			
		||||
      fmt = 'e';
 | 
			
		||||
      precision -= 1;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
    } else {
 | 
			
		||||
      fmt = 'f';
 | 
			
		||||
      precision -= decpt;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    if (fmt == 'e')
 | 
			
		||||
    {
 | 
			
		||||
  if (fmt == 'e') {
 | 
			
		||||
    digits = ecvtbuf(value, precision + 1, &decpt, &sign, cvtbuf);
 | 
			
		||||
 | 
			
		||||
    if (sign)
 | 
			
		||||
@@ -271,22 +238,18 @@ parse_float(double value, char *buffer, char fmt, int precision)
 | 
			
		||||
    buffer += precision;
 | 
			
		||||
    *buffer++ = capexp ? 'E' : 'e';
 | 
			
		||||
 | 
			
		||||
        if (decpt == 0)
 | 
			
		||||
        {
 | 
			
		||||
    if (decpt == 0) {
 | 
			
		||||
      if (value == 0.0)
 | 
			
		||||
        exp = 0;
 | 
			
		||||
      else
 | 
			
		||||
        exp = -1;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
    } else
 | 
			
		||||
      exp = decpt - 1;
 | 
			
		||||
 | 
			
		||||
        if (exp < 0)
 | 
			
		||||
        {
 | 
			
		||||
    if (exp < 0) {
 | 
			
		||||
      *buffer++ = '-';
 | 
			
		||||
      exp = -exp;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
    } else
 | 
			
		||||
      *buffer++ = '+';
 | 
			
		||||
 | 
			
		||||
    buffer[2] = (exp % 10) + '0';
 | 
			
		||||
@@ -295,39 +258,29 @@ parse_float(double value, char *buffer, char fmt, int precision)
 | 
			
		||||
    exp = exp / 10;
 | 
			
		||||
    buffer[0] = (exp % 10) + '0';
 | 
			
		||||
    buffer += 3;
 | 
			
		||||
    }
 | 
			
		||||
    else if (fmt == 'f')
 | 
			
		||||
    {
 | 
			
		||||
  } else if (fmt == 'f') {
 | 
			
		||||
    digits = fcvtbuf(value, precision, &decpt, &sign, cvtbuf);
 | 
			
		||||
    if (sign)
 | 
			
		||||
      *buffer++ = '-';
 | 
			
		||||
        if (*digits)
 | 
			
		||||
        {
 | 
			
		||||
            if (decpt <= 0)
 | 
			
		||||
            {
 | 
			
		||||
    if (*digits) {
 | 
			
		||||
      if (decpt <= 0) {
 | 
			
		||||
        *buffer++ = '0';
 | 
			
		||||
        *buffer++ = '.';
 | 
			
		||||
        for (pos = 0; pos < -decpt; pos++)
 | 
			
		||||
          *buffer++ = '0';
 | 
			
		||||
        while (*digits)
 | 
			
		||||
          *buffer++ = *digits++;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
      } else {
 | 
			
		||||
        pos = 0;
 | 
			
		||||
                while (*digits)
 | 
			
		||||
                {
 | 
			
		||||
        while (*digits) {
 | 
			
		||||
          if (pos++ == decpt)
 | 
			
		||||
            *buffer++ = '.';
 | 
			
		||||
          *buffer++ = *digits++;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
    } else {
 | 
			
		||||
      *buffer++ = '0';
 | 
			
		||||
            if (precision > 0)
 | 
			
		||||
            {
 | 
			
		||||
      if (precision > 0) {
 | 
			
		||||
        *buffer++ = '.';
 | 
			
		||||
        for (pos = 0; pos < precision; pos++)
 | 
			
		||||
          *buffer++ = '0';
 | 
			
		||||
@@ -338,11 +291,8 @@ parse_float(double value, char *buffer, char fmt, int precision)
 | 
			
		||||
  *buffer = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
decimal_point(char *buffer)
 | 
			
		||||
{
 | 
			
		||||
    while (*buffer)
 | 
			
		||||
    {
 | 
			
		||||
static void decimal_point(char *buffer) {
 | 
			
		||||
  while (*buffer) {
 | 
			
		||||
    if (*buffer == '.')
 | 
			
		||||
      return;
 | 
			
		||||
    if (*buffer == 'e' || *buffer == 'E')
 | 
			
		||||
@@ -350,33 +300,26 @@ decimal_point(char *buffer)
 | 
			
		||||
    buffer++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    if (*buffer)
 | 
			
		||||
    {
 | 
			
		||||
  if (*buffer) {
 | 
			
		||||
    int n = strnlen(buffer, 256);
 | 
			
		||||
        while (n > 0)
 | 
			
		||||
        {
 | 
			
		||||
    while (n > 0) {
 | 
			
		||||
      buffer[n + 1] = buffer[n];
 | 
			
		||||
      n--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *buffer = '.';
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
  } else {
 | 
			
		||||
    *buffer++ = '.';
 | 
			
		||||
    *buffer = '\0';
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cropzeros(char *buffer)
 | 
			
		||||
{
 | 
			
		||||
static void cropzeros(char *buffer) {
 | 
			
		||||
  char *stop;
 | 
			
		||||
 | 
			
		||||
  while (*buffer && *buffer != '.')
 | 
			
		||||
    buffer++;
 | 
			
		||||
    if (*buffer++)
 | 
			
		||||
    {
 | 
			
		||||
  if (*buffer++) {
 | 
			
		||||
    while (*buffer && *buffer != 'e' && *buffer != 'E')
 | 
			
		||||
      buffer++;
 | 
			
		||||
    stop = buffer--;
 | 
			
		||||
@@ -389,9 +332,8 @@ cropzeros(char *buffer)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
flt(char *str, double num, int size, int precision, char fmt, int flags)
 | 
			
		||||
{
 | 
			
		||||
static char *flt(char *str, double num, int size, int precision, char fmt,
 | 
			
		||||
                 int flags) {
 | 
			
		||||
  char tmp[80];
 | 
			
		||||
  char c, sign;
 | 
			
		||||
  int n, i;
 | 
			
		||||
@@ -403,21 +345,15 @@ flt(char *str, double num, int size, int precision, char fmt, int flags)
 | 
			
		||||
  // Determine padding and sign char
 | 
			
		||||
  c = (flags & ZEROPAD) ? '0' : ' ';
 | 
			
		||||
  sign = 0;
 | 
			
		||||
    if (flags & SIGN)
 | 
			
		||||
    {
 | 
			
		||||
        if (num < 0.0)
 | 
			
		||||
        {
 | 
			
		||||
  if (flags & SIGN) {
 | 
			
		||||
    if (num < 0.0) {
 | 
			
		||||
      sign = '-';
 | 
			
		||||
      num = -num;
 | 
			
		||||
      size--;
 | 
			
		||||
        }
 | 
			
		||||
        else if (flags & PLUS)
 | 
			
		||||
        {
 | 
			
		||||
    } else if (flags & PLUS) {
 | 
			
		||||
      sign = '+';
 | 
			
		||||
      size--;
 | 
			
		||||
        }
 | 
			
		||||
        else if (flags & SPACE)
 | 
			
		||||
        {
 | 
			
		||||
    } else if (flags & SPACE) {
 | 
			
		||||
      sign = ' ';
 | 
			
		||||
      size--;
 | 
			
		||||
    }
 | 
			
		||||
@@ -457,9 +393,7 @@ flt(char *str, double num, int size, int precision, char fmt, int flags)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
ee_vsprintf(char *buf, const char *fmt, va_list args)
 | 
			
		||||
{
 | 
			
		||||
static int ee_vsprintf(char *buf, const char *fmt, va_list args) {
 | 
			
		||||
  int len;
 | 
			
		||||
  unsigned long num;
 | 
			
		||||
  int i, base;
 | 
			
		||||
@@ -473,10 +407,8 @@ ee_vsprintf(char *buf, const char *fmt, va_list args)
 | 
			
		||||
                   // from string
 | 
			
		||||
  int qualifier;   // 'h', 'l', or 'L' for integer fields
 | 
			
		||||
 | 
			
		||||
    for (str = buf; *fmt; fmt++)
 | 
			
		||||
    {
 | 
			
		||||
        if (*fmt != '%')
 | 
			
		||||
        {
 | 
			
		||||
  for (str = buf; *fmt; fmt++) {
 | 
			
		||||
    if (*fmt != '%') {
 | 
			
		||||
      *str++ = *fmt;
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
@@ -485,8 +417,7 @@ ee_vsprintf(char *buf, const char *fmt, va_list args)
 | 
			
		||||
    flags = 0;
 | 
			
		||||
  repeat:
 | 
			
		||||
    fmt++; // This also skips first '%'
 | 
			
		||||
        switch (*fmt)
 | 
			
		||||
        {
 | 
			
		||||
    switch (*fmt) {
 | 
			
		||||
    case '-':
 | 
			
		||||
      flags |= LEFT;
 | 
			
		||||
      goto repeat;
 | 
			
		||||
@@ -508,12 +439,10 @@ ee_vsprintf(char *buf, const char *fmt, va_list args)
 | 
			
		||||
    field_width = -1;
 | 
			
		||||
    if (is_digit(*fmt))
 | 
			
		||||
      field_width = skip_atoi(&fmt);
 | 
			
		||||
        else if (*fmt == '*')
 | 
			
		||||
        {
 | 
			
		||||
    else if (*fmt == '*') {
 | 
			
		||||
      fmt++;
 | 
			
		||||
      field_width = va_arg(args, int);
 | 
			
		||||
            if (field_width < 0)
 | 
			
		||||
            {
 | 
			
		||||
      if (field_width < 0) {
 | 
			
		||||
        field_width = -field_width;
 | 
			
		||||
        flags |= LEFT;
 | 
			
		||||
      }
 | 
			
		||||
@@ -521,13 +450,11 @@ ee_vsprintf(char *buf, const char *fmt, va_list args)
 | 
			
		||||
 | 
			
		||||
    // Get the precision
 | 
			
		||||
    precision = -1;
 | 
			
		||||
        if (*fmt == '.')
 | 
			
		||||
        {
 | 
			
		||||
    if (*fmt == '.') {
 | 
			
		||||
      ++fmt;
 | 
			
		||||
      if (is_digit(*fmt))
 | 
			
		||||
        precision = skip_atoi(&fmt);
 | 
			
		||||
            else if (*fmt == '*')
 | 
			
		||||
            {
 | 
			
		||||
      else if (*fmt == '*') {
 | 
			
		||||
        ++fmt;
 | 
			
		||||
        precision = va_arg(args, int);
 | 
			
		||||
      }
 | 
			
		||||
@@ -537,8 +464,7 @@ ee_vsprintf(char *buf, const char *fmt, va_list args)
 | 
			
		||||
 | 
			
		||||
    // Get the conversion qualifier
 | 
			
		||||
    qualifier = -1;
 | 
			
		||||
        if (*fmt == 'l' || *fmt == 'L')
 | 
			
		||||
        {
 | 
			
		||||
    if (*fmt == 'l' || *fmt == 'L') {
 | 
			
		||||
      qualifier = *fmt;
 | 
			
		||||
      fmt++;
 | 
			
		||||
    }
 | 
			
		||||
@@ -546,8 +472,7 @@ ee_vsprintf(char *buf, const char *fmt, va_list args)
 | 
			
		||||
    // Default base
 | 
			
		||||
    base = 10;
 | 
			
		||||
 | 
			
		||||
        switch (*fmt)
 | 
			
		||||
        {
 | 
			
		||||
    switch (*fmt) {
 | 
			
		||||
    case 'c':
 | 
			
		||||
      if (!(flags & LEFT))
 | 
			
		||||
        while (--field_width > 0)
 | 
			
		||||
@@ -572,17 +497,12 @@ ee_vsprintf(char *buf, const char *fmt, va_list args)
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
    case 'p':
 | 
			
		||||
                if (field_width == -1)
 | 
			
		||||
                {
 | 
			
		||||
      if (field_width == -1) {
 | 
			
		||||
        field_width = 2 * sizeof(void *);
 | 
			
		||||
        flags |= ZEROPAD;
 | 
			
		||||
      }
 | 
			
		||||
                str = number(str,
 | 
			
		||||
                             (unsigned long)va_arg(args, void *),
 | 
			
		||||
                             16,
 | 
			
		||||
                             field_width,
 | 
			
		||||
                             precision,
 | 
			
		||||
                             flags);
 | 
			
		||||
      str = number(str, (unsigned long)va_arg(args, void *), 16, field_width,
 | 
			
		||||
                   precision, flags);
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
    case 'A':
 | 
			
		||||
@@ -590,16 +510,10 @@ ee_vsprintf(char *buf, const char *fmt, va_list args)
 | 
			
		||||
 | 
			
		||||
    case 'a':
 | 
			
		||||
      if (qualifier == 'l')
 | 
			
		||||
                    str = eaddr(str,
 | 
			
		||||
                                va_arg(args, unsigned char *),
 | 
			
		||||
                                field_width,
 | 
			
		||||
                                precision,
 | 
			
		||||
        str = eaddr(str, va_arg(args, unsigned char *), field_width, precision,
 | 
			
		||||
                    flags);
 | 
			
		||||
      else
 | 
			
		||||
                    str = iaddr(str,
 | 
			
		||||
                                va_arg(args, unsigned char *),
 | 
			
		||||
                                field_width,
 | 
			
		||||
                                precision,
 | 
			
		||||
        str = iaddr(str, va_arg(args, unsigned char *), field_width, precision,
 | 
			
		||||
                    flags);
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
@@ -625,11 +539,7 @@ ee_vsprintf(char *buf, const char *fmt, va_list args)
 | 
			
		||||
#if HAS_FLOAT
 | 
			
		||||
 | 
			
		||||
    case 'f':
 | 
			
		||||
                str = flt(str,
 | 
			
		||||
                          va_arg(args, double),
 | 
			
		||||
                          field_width,
 | 
			
		||||
                          precision,
 | 
			
		||||
                          *fmt,
 | 
			
		||||
      str = flt(str, va_arg(args, double), field_width, precision, *fmt,
 | 
			
		||||
                flags | SIGN);
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
@@ -661,31 +571,9 @@ ee_vsprintf(char *buf, const char *fmt, va_list args)
 | 
			
		||||
 | 
			
		||||
#include <platform.h>
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
uart_send_char(char c)
 | 
			
		||||
{
 | 
			
		||||
#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, ...)
 | 
			
		||||
{
 | 
			
		||||
int ee_printf(const char *fmt, ...) {
 | 
			
		||||
  char buf[1024], *p;
 | 
			
		||||
  va_list args;
 | 
			
		||||
  int n = 0;
 | 
			
		||||
@@ -694,8 +582,7 @@ ee_printf(const char *fmt, ...)
 | 
			
		||||
  ee_vsprintf(buf, fmt, args);
 | 
			
		||||
  va_end(args);
 | 
			
		||||
  p = buf;
 | 
			
		||||
    while (*p)
 | 
			
		||||
    {
 | 
			
		||||
  while (*p) {
 | 
			
		||||
    uart_send_char(*p);
 | 
			
		||||
    n++;
 | 
			
		||||
    p++;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								benchmarks/dhrystone/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								benchmarks/dhrystone/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +1,3 @@
 | 
			
		||||
dhrystone
 | 
			
		||||
/dhrystone.dis
 | 
			
		||||
build/
 | 
			
		||||
							
								
								
									
										31
									
								
								benchmarks/dhrystone/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								benchmarks/dhrystone/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
cmake_minimum_required(VERSION 3.21)
 | 
			
		||||
project(dhrystone C)
 | 
			
		||||
set(TARGET dhrystone)
 | 
			
		||||
 | 
			
		||||
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(ITERATIONS 50000) # 20000 for TGC
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
 | 
			
		||||
add_custom_command(TARGET ${TARGET} POST_BUILD
 | 
			
		||||
        COMMAND ${CMAKE_OBJDUMP} -S  ${TARGET}.elf > ${TARGET}.dis
 | 
			
		||||
        COMMENT "Creating disassembly for ${TARGET}")
 | 
			
		||||
							
								
								
									
										70
									
								
								benchmarks/dhrystone/CMakePresets.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								benchmarks/dhrystone/CMakePresets.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
{
 | 
			
		||||
    "version": 3,
 | 
			
		||||
    "vendor": {
 | 
			
		||||
        "conan": {}
 | 
			
		||||
    },
 | 
			
		||||
    "cmakeMinimumRequired": {
 | 
			
		||||
        "major": 3,
 | 
			
		||||
        "minor": 24,
 | 
			
		||||
        "patch": 0
 | 
			
		||||
    },
 | 
			
		||||
    "configurePresets": [
 | 
			
		||||
        {
 | 
			
		||||
            "name": "debug",
 | 
			
		||||
            "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"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "release",
 | 
			
		||||
            "cacheVariables": {
 | 
			
		||||
                "CMAKE_BUILD_TYPE": "Release",    
 | 
			
		||||
                "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
@@ -17,6 +17,7 @@ endif
 | 
			
		||||
# '-lgcc -lm' are needed to add softfloat routines
 | 
			
		||||
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))
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#ifndef ITERATIONS
 | 
			
		||||
#define ITERATIONS 20000
 | 
			
		||||
#endif
 | 
			
		||||
@@ -6,20 +7,16 @@
 | 
			
		||||
/* The functions in this file are only meant to support Dhrystone on an
 | 
			
		||||
 * embedded RV32 system and are obviously incorrect in general. */
 | 
			
		||||
 | 
			
		||||
long time(void)
 | 
			
		||||
{
 | 
			
		||||
  return get_timer_value();
 | 
			
		||||
}
 | 
			
		||||
long time(void) { return get_timer_value(); }
 | 
			
		||||
 | 
			
		||||
// set the number of dhrystone iterations
 | 
			
		||||
void __wrap_scanf(const char* fmt, int* n)
 | 
			
		||||
{
 | 
			
		||||
  *n = ITERATIONS;
 | 
			
		||||
}
 | 
			
		||||
void __wrap_scanf(const char *fmt, int *n) { *n = ITERATIONS; }
 | 
			
		||||
 | 
			
		||||
extern volatile uint32_t tohost;
 | 
			
		||||
// extern volatile uint64_t tohost;
 | 
			
		||||
 | 
			
		||||
void exit(int n) {
 | 
			
		||||
      tohost = 0x1;
 | 
			
		||||
      for (;;);
 | 
			
		||||
  // tohost = 0x1;
 | 
			
		||||
  write_hex(STDERR_FILENO, 1);
 | 
			
		||||
  for (;;)
 | 
			
		||||
    ;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								hello-world/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								hello-world/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +1,3 @@
 | 
			
		||||
/hello
 | 
			
		||||
/hello.dis
 | 
			
		||||
build/
 | 
			
		||||
							
								
								
									
										23
									
								
								hello-world/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								hello-world/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
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)
 | 
			
		||||
target_link_libraries(${TARGET} PRIVATE bsp)
 | 
			
		||||
target_link_options(${TARGET} PRIVATE -Wl,-Map=${TARGET}.map)  
 | 
			
		||||
 | 
			
		||||
add_custom_command(TARGET ${TARGET} POST_BUILD
 | 
			
		||||
        COMMAND ${CMAKE_OBJDUMP} -S  ${TARGET}.elf > ${TARGET}.dis
 | 
			
		||||
        COMMENT "Creating disassembly for ${TARGET}")
 | 
			
		||||
							
								
								
									
										70
									
								
								hello-world/CMakePresets.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								hello-world/CMakePresets.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
{
 | 
			
		||||
    "version": 3,
 | 
			
		||||
    "vendor": {
 | 
			
		||||
        "conan": {}
 | 
			
		||||
    },
 | 
			
		||||
    "cmakeMinimumRequired": {
 | 
			
		||||
        "major": 3,
 | 
			
		||||
        "minor": 24,
 | 
			
		||||
        "patch": 0
 | 
			
		||||
    },
 | 
			
		||||
    "configurePresets": [
 | 
			
		||||
        {
 | 
			
		||||
            "name": "debug",
 | 
			
		||||
            "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"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "release",
 | 
			
		||||
            "cacheVariables": {
 | 
			
		||||
                "CMAKE_BUILD_TYPE": "Release",    
 | 
			
		||||
                "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +1,11 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "encoding.h"
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
int factorial(int i) {
 | 
			
		||||
 | 
			
		||||
@@ -12,13 +14,24 @@ int factorial(int i){
 | 
			
		||||
    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()
 | 
			
		||||
{
 | 
			
		||||
	volatile int result = factorial (10);
 | 
			
		||||
	printf("Factorial is %d\n", result);
 | 
			
		||||
	printf("End of execution");
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								lwc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								lwc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
build/
 | 
			
		||||
							
								
								
									
										54
									
								
								lwc/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								lwc/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
# 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
 | 
			
		||||
 | 
			
		||||
#hash or aead
 | 
			
		||||
export API  ?= aead
 | 
			
		||||
#generic, rv32 or rv64
 | 
			
		||||
export ARCH ?= rv32
 | 
			
		||||
#nist, rv32 or rv64m if imp is nist does not allow for ASCON_RVXX_TYPE
 | 
			
		||||
export IMP  ?= rv32
 | 
			
		||||
#rvxx requires a ACSCON_RVXX_TYPEX
 | 
			
		||||
#export CONF ?= -DASCON_RV32_TYPE1 # -DASCON_RV32_TYPE1 or -DASCON_RV32_TYPE2 (with custom instrs)
 | 
			
		||||
 | 
			
		||||
TARGET  = ascon
 | 
			
		||||
ISA?=gc_zbb_zbkb_zbkx
 | 
			
		||||
 | 
			
		||||
C_SRCS  = $(wildcard *.c) 
 | 
			
		||||
HEADERS = $(wildcard *.h)
 | 
			
		||||
OPT ?= -O0
 | 
			
		||||
CFLAGS += $(OPT) -g
 | 
			
		||||
#CFLAGS += -DDRIVER_BYPASS_TEST
 | 
			
		||||
CFLAGS += -DDRIVER_BYPASS_TIME #Time throws a trap somewhere
 | 
			
		||||
 | 
			
		||||
BOARD=iss
 | 
			
		||||
LINK_TARGET=link
 | 
			
		||||
RISCV_ARCH:=rv32$(ISA)
 | 
			
		||||
ifeq ($(ISA),e)
 | 
			
		||||
    RISCV_ABI:=ilp32e
 | 
			
		||||
else
 | 
			
		||||
    RISCV_ABI:=ilp32
 | 
			
		||||
endif
 | 
			
		||||
LDFLAGS += -g -Wl,--wrap=printf
 | 
			
		||||
 | 
			
		||||
compiler := $(shell which riscv64-unknown-elf-gcc)
 | 
			
		||||
TOOL_DIR=$(dir $(compiler))
 | 
			
		||||
 | 
			
		||||
TRIPLET=riscv64-unknown-elf
 | 
			
		||||
BSP_BASE = ../bare-metal-bsp
 | 
			
		||||
 | 
			
		||||
all: ${TARGET}.elf
 | 
			
		||||
 | 
			
		||||
include  ${REPO_HOME}/src/Makefile
 | 
			
		||||
CFLAGS += ${GCC_FLAGS}
 | 
			
		||||
 | 
			
		||||
include $(BSP_BASE)/env/common-gcc.mk
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										95
									
								
								lwc/src/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								lwc/src/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
# 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).
 | 
			
		||||
 | 
			
		||||
# include build-related content for algorithm
 | 
			
		||||
include ${REPO_HOME}/src/${ALG}/Makefile.in
 | 
			
		||||
 | 
			
		||||
# include build-related content for architecture
 | 
			
		||||
#include ${REPO_HOME}/src/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} ${REPO_HOME}/src/share ${REPO_HOME}/src/share/nist ${REPO_HOME}/src/share/arch/${ARCH}
 | 
			
		||||
else
 | 
			
		||||
export LWISE_INCLUDES += ${REPO_HOME}/build/${ALG} ${REPO_HOME}/src/share ${REPO_HOME}/src/share/nist ${REPO_HOME}/src/share/arch/${ARCH} ${REPO_HOME}/src/${ALG}/arch/${ARCH} ${REPO_HOME}/src/${ALG}/imp/${IMP} ${REPO_HOME}/src/${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       ALL_INCLUDES := ${LWISE_INCLUDES} ${NIST_INCLUDES} ${REPO_HOME}/build/${ALG}
 | 
			
		||||
INCLUDES += $(foreach dir,$(ALL_INCLUDES),-I$(dir))
 | 
			
		||||
 | 
			
		||||
export       SOURCES  := ${LWISE_SOURCES}  ${NIST_SOURCES}
 | 
			
		||||
export       HEADERS  := ${LWISE_HEADERS}  ${NIST_HEADERS}
 | 
			
		||||
 | 
			
		||||
# -----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
${REPO_HOME}/build/${ALG}       :
 | 
			
		||||
	@mkdir --parents ${@}
 | 
			
		||||
 | 
			
		||||
${SOURCES} : ${REPO_HOME}/build/${ALG}/kat_${API}.c ${REPO_HOME}/build/${ALG}/kat_${API}.h
 | 
			
		||||
 | 
			
		||||
${REPO_HOME}/build/${ALG}/kat_${API}.h : ${NIST_KAT}
 | 
			
		||||
	@python3 ${REPO_HOME}/src/share/kat.py --api="${API}" --header < ${<} > ${@}
 | 
			
		||||
${REPO_HOME}/build/${ALG}/kat_${API}.c : ${NIST_KAT}
 | 
			
		||||
	@python3 ${REPO_HOME}/src/share/kat.py --api="${API}" --source < ${<} > ${@}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
C_SRCS += $(filter %.c, ${SOURCES})
 | 
			
		||||
CXX_SRCS += $(filter %.cpp, ${SOURCES})
 | 
			
		||||
ASM_SRCS += $(filter %.S, ${SOURCES})
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
# -----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
.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}"
 | 
			
		||||
 | 
			
		||||
	@echo "ASM_SRCS = ${ASM_SRCS}"
 | 
			
		||||
 | 
			
		||||
# =============================================================================
 | 
			
		||||
							
								
								
									
										39
									
								
								lwc/src/ascon/Makefile.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								lwc/src/ascon/Makefile.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
# 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
 | 
			
		||||
 | 
			
		||||
# =============================================================================
 | 
			
		||||
							
								
								
									
										18
									
								
								lwc/src/ascon/arch/rv32/ise.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								lwc/src/ascon/arch/rv32/ise.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// ============================================================================
 | 
			
		||||
							
								
								
									
										15
									
								
								lwc/src/ascon/arch/rv64/ise.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								lwc/src/ascon/arch/rv64/ise.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
// ============================================================================
 | 
			
		||||
							
								
								
									
										35
									
								
								lwc/src/ascon/fpga-scan.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								lwc/src/ascon/fpga-scan.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
# 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 )
 | 
			
		||||
 | 
			
		||||
# =============================================================================
 | 
			
		||||
							
								
								
									
										272
									
								
								lwc/src/ascon/imp/rv32/ascon_imp.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										272
									
								
								lwc/src/ascon/imp/rv32/ascon_imp.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,272 @@
 | 
			
		||||
#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
 | 
			
		||||
    
 | 
			
		||||
							
								
								
									
										158
									
								
								lwc/src/ascon/imp/rv64/ascon_imp.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								lwc/src/ascon/imp/rv64/ascon_imp.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,158 @@
 | 
			
		||||
#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
									
								
								lwc/src/ascon/nist.url
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								lwc/src/ascon/nist.url
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-submissions/ascon.zip
 | 
			
		||||
							
								
								
									
										3
									
								
								lwc/src/ascon/nist.zip
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								lwc/src/ascon/nist.zip
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
version https://git-lfs.github.com/spec/v1
 | 
			
		||||
oid sha256:07a2bc8432612d260cef0945e6a16ff9aa94c9279a2e83b76ae984fdbe8b1a5d
 | 
			
		||||
size 2032754
 | 
			
		||||
							
								
								
									
										3
									
								
								lwc/src/ascon/nist/Documents/asconv12.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								lwc/src/ascon/nist/Documents/asconv12.pdf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
version https://git-lfs.github.com/spec/v1
 | 
			
		||||
oid sha256:49403e24b9cd05a234d27c5a7f37e3f28de52c8f8db07ac744515be225bd7aa6
 | 
			
		||||
size 485542
 | 
			
		||||
							
								
								
									
										3
									
								
								lwc/src/ascon/nist/Documents/changelog.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								lwc/src/ascon/nist/Documents/changelog.pdf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
version https://git-lfs.github.com/spec/v1
 | 
			
		||||
oid sha256:68eb5de5bbe2c1d19a212827f9daaec22b49777e93f4fed6300764bbbd5aa480
 | 
			
		||||
size 153824
 | 
			
		||||
							
								
								
									
										3
									
								
								lwc/src/ascon/nist/Documents/coversheet.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								lwc/src/ascon/nist/Documents/coversheet.pdf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
version https://git-lfs.github.com/spec/v1
 | 
			
		||||
oid sha256:ffbefd2edd8d997de9157c2bf6ea6bfaa53e03e8ce26f1ee136108ae924b127e
 | 
			
		||||
size 164033
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,237 @@
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,2 @@
 | 
			
		||||
amd64
 | 
			
		||||
x86
 | 
			
		||||
@@ -0,0 +1,22 @@
 | 
			
		||||
#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 */
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
Branches reviewed 2020-11-13 by Martin Schläffer.
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
Addresses reviewed 2020-11-13 by Martin Schläffer.
 | 
			
		||||
@@ -0,0 +1,2 @@
 | 
			
		||||
Christoph Dobraunig
 | 
			
		||||
Martin Schläffer
 | 
			
		||||
@@ -0,0 +1,15 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,138 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,21 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,24 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,51 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,69 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,219 @@
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,18 @@
 | 
			
		||||
#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 */
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
Branches reviewed 2020-11-13 by Martin Schläffer.
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
Addresses reviewed 2020-11-13 by Martin Schläffer.
 | 
			
		||||
@@ -0,0 +1,2 @@
 | 
			
		||||
Christoph Dobraunig
 | 
			
		||||
Martin Schläffer
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,23 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,139 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,21 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,24 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,52 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,105 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,219 @@
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,3 @@
 | 
			
		||||
aarch64
 | 
			
		||||
armeabi
 | 
			
		||||
arm
 | 
			
		||||
@@ -0,0 +1,18 @@
 | 
			
		||||
#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 */
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
Branches reviewed 2020-11-13 by Martin Schläffer.
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
Addresses reviewed 2020-11-13 by Martin Schläffer.
 | 
			
		||||
@@ -0,0 +1,2 @@
 | 
			
		||||
Christoph Dobraunig
 | 
			
		||||
Martin Schläffer
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,23 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,139 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,21 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,24 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,102 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,105 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,219 @@
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,18 @@
 | 
			
		||||
#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 */
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
Branches reviewed 2020-11-13 by Martin Schläffer.
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
Addresses reviewed 2020-11-13 by Martin Schläffer.
 | 
			
		||||
@@ -0,0 +1,2 @@
 | 
			
		||||
Christoph Dobraunig
 | 
			
		||||
Martin Schläffer
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,23 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,139 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,21 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,24 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,53 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,105 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
@@ -0,0 +1,79 @@
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -0,0 +1,26 @@
 | 
			
		||||
#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 */
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
#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_ */
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user